Compare commits
65 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9fcd805ed5 | |||
| eccfb96c22 | |||
| a6ddaa8bbd | |||
| bb82dcb724 | |||
| d58be78868 | |||
| 1cb9104404 | |||
| 19a47115ea | |||
| 6da682dfed | |||
| 08d3f7ff6d | |||
| 229e98cf9d | |||
| d7096a8a68 | |||
| b0f26bdea2 | |||
| 2586407ec9 | |||
| a34a62d635 | |||
| 44215b3b4e | |||
| a2b49fdf3e | |||
| 21b73e0031 | |||
| 54c86774b7 | |||
| 80c5a5a393 | |||
| 13ae86b6a7 | |||
| 8119643221 | |||
| 941954825d | |||
| 8d1286dd71 | |||
| 4abc2c01af | |||
| 7e6d8f4172 | |||
| 5aa2b5ac4d | |||
| ae4c3f9156 | |||
| a4f6e10dc3 | |||
| fc047c2350 | |||
| 28946a0291 | |||
| 9375cd0868 | |||
| 8bd772c96d | |||
| 2fff4438c0 | |||
| a17c62c15f | |||
| 20c8518f1d | |||
| 730d37c917 | |||
| 184a78d34c | |||
| a33e794b1e | |||
| f212c0cede | |||
| 38fdaca7bf | |||
| 7b580b24bb | |||
| 23bbd938fc | |||
| 21dd75b4a6 | |||
| a8ec76f451 | |||
| 9b5bb25c76 | |||
| b9c492fe5a | |||
| fdcb428002 | |||
| 91c883b87c | |||
| 8e151758b1 | |||
| 1132369f1e | |||
| b9bb1aefdd | |||
| 2b9113347a | |||
| 7c80c4d3d8 | |||
| 69fc865452 | |||
| 88bc848966 | |||
| 81a274563f | |||
| 32fa372012 | |||
| 21da5f633d | |||
| c24fef22a7 | |||
| 35e8ef2482 | |||
| 23d5f82403 | |||
| ec734ca99d | |||
| 34c5ecc5ec | |||
| 362f3fd2b0 | |||
| 9acd52ea10 |
@@ -13,20 +13,39 @@ local BeamData = require( 'BeamData')
|
||||
local ID = require( 'Identity')
|
||||
|
||||
|
||||
|
||||
-- TODO tabella da compleatare man mano che si inseriscono le varie strategie
|
||||
-- ESEMPIO SCRITTURA TABELLA CON STRATEGIE DISPONIBILI
|
||||
---------------------------------------------------------------------
|
||||
-- Feature : Cut
|
||||
-- if ID.TipoFeature( Proc) then
|
||||
-- if Proc.Topology.sName == 'QQQQQQQQQ' then
|
||||
-- Strategies = {
|
||||
-- { sStrategyId = 'STR9999',
|
||||
-- Parameters = {
|
||||
-- { sName = 'Val_1', sValue = '15', sType = 'd'},
|
||||
-- { sName = 'Val_2', sValue = 'false', sType = 'b'}
|
||||
-- }
|
||||
-- }
|
||||
-- { sStrategyId = 'STR9998'}
|
||||
-- }
|
||||
-- end
|
||||
-- end
|
||||
|
||||
----------------------------------------------------------------------------------
|
||||
-- *** EGALWARE ***
|
||||
----------------------------------------------------------------------------------
|
||||
local function GetStrategies_Egalware( Proc)
|
||||
local Strategies = {}
|
||||
|
||||
-- TODO tabella da compleatare man mano che si inseriscono le varie strategie
|
||||
|
||||
---------------------------------------------------------------------
|
||||
-- Feature : Cut
|
||||
if ID.IsHeadCut( Proc) then
|
||||
Strategies = { { sStrategyId = 'HEADCUT'}}
|
||||
---------------------------------------------------------------------
|
||||
-- Feature : Cut
|
||||
elseif ID.IsSplitCut( Proc) then
|
||||
Strategies = { { sStrategyId = 'SPLITCUT'}}
|
||||
---------------------------------------------------------------------
|
||||
-- Feature : Cut
|
||||
elseif ID.IsCut( Proc) then
|
||||
@@ -46,13 +65,13 @@ local function GetStrategies_Egalware( Proc)
|
||||
-- Feature : Slot
|
||||
elseif ID.IsSlot( Proc) then
|
||||
if Proc.Topology.sName == 'Pocket-5-Blind' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Groove-4-Blind' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Groove-3-Through' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Groove-3-Blind' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}}
|
||||
elseif Proc.Topology.sName == 'Rabbet-2-Through' then
|
||||
@@ -62,13 +81,13 @@ local function GetStrategies_Egalware( Proc)
|
||||
-- Feature : Front Slot
|
||||
elseif ID.IsFrontSlot( Proc) then
|
||||
if Proc.Topology.sName == 'Pocket-5-Blind' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Groove-4-Blind' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Groove-3-Through' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Groove-3-Blind' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}}
|
||||
elseif Proc.Topology.sName == 'Rabbet-2-Through' then
|
||||
@@ -84,13 +103,13 @@ local function GetStrategies_Egalware( Proc)
|
||||
-- Feature : Ridge Lap
|
||||
elseif ID.IsRidgeLap( Proc) then
|
||||
if Proc.Topology.sName == 'Pocket-5-Blind' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Groove-4-Blind' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Groove-3-Through' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Groove-3-Blind' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}}
|
||||
elseif Proc.Topology.sName == 'Rabbet-2-Through' then
|
||||
@@ -100,13 +119,13 @@ local function GetStrategies_Egalware( Proc)
|
||||
-- Feature : Lap Joint
|
||||
elseif ID.IsLapJoint( Proc) then
|
||||
if Proc.Topology.sName == 'Pocket-5-Blind' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Groove-4-Blind' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Groove-3-Through' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Groove-3-Blind' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}}
|
||||
elseif Proc.Topology.sName == 'Rabbet-2-Through' then
|
||||
@@ -116,13 +135,13 @@ local function GetStrategies_Egalware( Proc)
|
||||
-- Feature : Notch/Rabbet
|
||||
elseif ID.IsNotchRabbet( Proc) then
|
||||
if Proc.Topology.sName == 'Pocket-5-Blind' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Groove-4-Blind' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Groove-3-Through' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Groove-3-Blind' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}}
|
||||
elseif Proc.Topology.sName == 'Rabbet-2-Through' then
|
||||
@@ -135,13 +154,13 @@ local function GetStrategies_Egalware( Proc)
|
||||
-- Feature : Notch
|
||||
elseif ID.IsNotch( Proc) then
|
||||
if Proc.Topology.sName == 'Pocket-5-Blind' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Groove-4-Blind' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Groove-3-Through' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Groove-3-Blind' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}}
|
||||
elseif Proc.Topology.sName == 'Rabbet-2-Through' then
|
||||
@@ -163,13 +182,13 @@ local function GetStrategies_Egalware( Proc)
|
||||
-- Feature : Pocket
|
||||
elseif ID.IsPocket( Proc) then
|
||||
if Proc.Topology.sName == 'Pocket-5-Blind' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Groove-4-Blind' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Groove-3-Through' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Groove-3-Blind' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}}
|
||||
elseif Proc.Topology.sName == 'Rabbet-2-Through' then
|
||||
@@ -277,24 +296,14 @@ end
|
||||
local function GetStrategies_Essetre( Proc)
|
||||
local Strategies = {}
|
||||
|
||||
-- TODO tabella da compleatare man mano che si inseriscono le varie strategie
|
||||
|
||||
---------------------------------------------------------------------
|
||||
-- Feature : Cut
|
||||
if ID.IsHeadCut( Proc) then -- TODO TOGLIERE STRATEGIA. Inserita solo per mostrare come devono essere scritti i dati
|
||||
if Proc.Topology.sName == 'QQQQQQQQQ' then
|
||||
Strategies = {
|
||||
{ sStrategyId = 'STR9999',
|
||||
Parameters = {
|
||||
{ sName = 'Step', sValue = '15', sType = 'd'},
|
||||
{ sName = 'AntiSplint', sValue = 'false', sType = 'b'}
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
if ID.IsHeadCut( Proc) then
|
||||
Strategies = { { sStrategyId = 'HEADCUT'}}
|
||||
---------------------------------------------------------------------
|
||||
-- Feature : Cut
|
||||
elseif ID.IsSplitCut( Proc) then
|
||||
Strategies = { { sStrategyId = 'SPLITCUT'}}
|
||||
---------------------------------------------------------------------
|
||||
-- Feature : Cut
|
||||
elseif ID.IsCut( Proc) then
|
||||
@@ -314,13 +323,13 @@ local function GetStrategies_Essetre( Proc)
|
||||
-- Feature : Slot
|
||||
elseif ID.IsSlot( Proc) then
|
||||
if Proc.Topology.sName == 'Pocket-5-Blind' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Groove-4-Blind' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Groove-3-Through' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Groove-3-Blind' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}}
|
||||
elseif Proc.Topology.sName == 'Rabbet-2-Through' then
|
||||
@@ -330,13 +339,13 @@ local function GetStrategies_Essetre( Proc)
|
||||
-- Feature : Front Slot
|
||||
elseif ID.IsFrontSlot( Proc) then
|
||||
if Proc.Topology.sName == 'Pocket-5-Blind' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Groove-4-Blind' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Groove-3-Through' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Groove-3-Blind' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}}
|
||||
elseif Proc.Topology.sName == 'Rabbet-2-Through' then
|
||||
@@ -352,13 +361,13 @@ local function GetStrategies_Essetre( Proc)
|
||||
-- Feature : Ridge Lap
|
||||
elseif ID.IsRidgeLap( Proc) then
|
||||
if Proc.Topology.sName == 'Pocket-5-Blind' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Groove-4-Blind' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Groove-3-Through' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Groove-3-Blind' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}}
|
||||
elseif Proc.Topology.sName == 'Rabbet-2-Through' then
|
||||
@@ -368,13 +377,13 @@ local function GetStrategies_Essetre( Proc)
|
||||
-- Feature : Lap Joint
|
||||
elseif ID.IsLapJoint( Proc) then
|
||||
if Proc.Topology.sName == 'Pocket-5-Blind' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Groove-4-Blind' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Groove-3-Through' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Groove-3-Blind' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}}
|
||||
elseif Proc.Topology.sName == 'Rabbet-2-Through' then
|
||||
@@ -384,13 +393,13 @@ local function GetStrategies_Essetre( Proc)
|
||||
-- Feature : Notch/Rabbet
|
||||
elseif ID.IsNotchRabbet( Proc) then
|
||||
if Proc.Topology.sName == 'Pocket-5-Blind' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Groove-4-Blind' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Groove-3-Through' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Groove-3-Blind' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}}
|
||||
elseif Proc.Topology.sName == 'Rabbet-2-Through' then
|
||||
@@ -403,13 +412,13 @@ local function GetStrategies_Essetre( Proc)
|
||||
-- Feature : Notch
|
||||
elseif ID.IsNotch( Proc) then
|
||||
if Proc.Topology.sName == 'Pocket-5-Blind' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Groove-4-Blind' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Groove-3-Through' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Groove-3-Blind' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}}
|
||||
elseif Proc.Topology.sName == 'Rabbet-2-Through' then
|
||||
@@ -431,13 +440,13 @@ local function GetStrategies_Essetre( Proc)
|
||||
-- Feature : Pocket
|
||||
elseif ID.IsPocket( Proc) then
|
||||
if Proc.Topology.sName == 'Pocket-5-Blind' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Groove-4-Blind' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Groove-3-Through' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
|
||||
elseif Proc.Topology.sName == 'Groove-3-Blind' then
|
||||
Strategies = { { sStrategyId = 'STR0002'}}
|
||||
elseif Proc.Topology.sName == 'Rabbet-2-Through' then
|
||||
|
||||
+614
-174
@@ -15,9 +15,10 @@ local BeamData = require( 'BeamData')
|
||||
local BeamLib = require( 'BeamLib')
|
||||
local ID = require( 'Identity')
|
||||
local BCS = require( 'BasicCustomerStrategies')
|
||||
local FeatureData = require( 'FeatureData')
|
||||
local FeatureLib = require( 'FeatureLib')
|
||||
local FaceData = require( 'FaceData')
|
||||
local MachiningLib = require( 'MachiningLib')
|
||||
local Logs = require( 'Logs')
|
||||
|
||||
|
||||
EgtOutLog( ' BeamExec started', 1)
|
||||
@@ -27,9 +28,9 @@ EgtMdbSave()
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- *** variabili globali ***
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
TOOLS = nil
|
||||
STRATEGIES = nil
|
||||
MACHININGS = nil
|
||||
TOOLS = {} -- tabella contenente tutti gli utensili
|
||||
STRATEGIES = nil -- tabella contenente le strategie disponibili per ogni feature
|
||||
MACHININGS = {} -- tabella contenente le lavorazioni da applicare
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- *** COSTANTI *** TODO -> DA SPOSTARE IN BEAMDATA???
|
||||
@@ -85,8 +86,6 @@ end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function BeamExec.GetToolsFromDB()
|
||||
-- creo lista globale utensili disponibili
|
||||
TOOLS = {}
|
||||
-- lista appoggio utensile
|
||||
local Tool = {}
|
||||
|
||||
@@ -103,9 +102,6 @@ function BeamExec.GetToolsFromDB()
|
||||
|
||||
-- se verifica condizioni minime, recupero tutti gli altri dati
|
||||
if bToolLoadedOnSetup and sToolType then
|
||||
-- TODO Tool.AName -> da rimuovere perchè non serve. Per il momento lo manteniamo solo perchè è più facile vedere e interpretare la lista utensili nella watch di zerobrane
|
||||
-- Nell'utilizzo, si legge sempre il Tool.Name
|
||||
Tool.AName = Tool.sName
|
||||
Tool.sTcPos = sToolTCPos
|
||||
Tool.sFamily = sToolFamily
|
||||
Tool.sType = sToolType
|
||||
@@ -130,8 +126,8 @@ function BeamExec.GetToolsFromDB()
|
||||
Tool.ToolHolder.dDiameter = EgtTdbGetCurrToolThDiam() or TH_DIAMETER_HSK63 -- diametro standard HSK63
|
||||
Tool.ToolHolder.dLength = EgtTdbGetCurrToolThLength() or TH_LENGTH_HSK63 -- lunghezza standard HSK63
|
||||
-- parametri scritti nelle note
|
||||
Tool.nDouble = EgtGetValInNotes( Tool.sUserNotes, 'DOUBLE')
|
||||
Tool.bIsProfiledTool = EgtTdbIsCurrToolStandardDraw()
|
||||
Tool.nDouble = EgtGetValInNotes( Tool.sUserNotes, 'DOUBLE', 'd')
|
||||
Tool.bIsProfiledTool = not EgtTdbIsCurrToolStandardDraw()
|
||||
|
||||
-- lettura parametri non comuni ( famiglia DRILLBIT non ha parametri specifici)
|
||||
if sToolFamily ~= 'DRILLBIT' then
|
||||
@@ -145,23 +141,23 @@ function BeamExec.GetToolsFromDB()
|
||||
-- verifico che parametri siano compatibili con una fresa a coda di rondine ( angolo di fianco standard Coda di rondine -> 15°)
|
||||
Tool.bIsDoveTail = Tool.Type == 'MILL_NOTIP' and abs( abs( Tool.dSideAngle) - SIDEANGLE_DOVETAIL) < 1
|
||||
-- verifico che sia una fresa tipo T-Mill o BlockHaus
|
||||
Tool.dSideDepth = EgtGetValInNotes( Tool.sUserNotes, 'SIDEDEPTH') or 0 -- se non settato nell'utensile, dico che non ha massimo affondamento laterale
|
||||
Tool.dSideDepth = EgtGetValInNotes( Tool.sUserNotes, 'SIDEDEPTH', 'd') or 0 -- se non settato nell'utensile, dico che non ha massimo affondamento laterale
|
||||
Tool.bIsTMill = Tool.dSideDepth > 0
|
||||
Tool.dStep = EgtGetValInNotes( Tool.sUserNotes, 'STEP') or ( Tool.dMaxMaterial / 3) -- se non settato nell'utensile, considero metà del tagliente
|
||||
Tool.dSideStep = EgtGetValInNotes( Tool.sUserNotes, 'SIDESTEP') or floor( Tool.dDiameter / 3) -- se non settato nell'utensile, considero metà del diametro
|
||||
Tool.dStep = EgtGetValInNotes( Tool.sUserNotes, 'STEP', 'd') or ( Tool.dMaxMaterial / 3) -- se non settato nell'utensile, considero metà del tagliente
|
||||
Tool.dSideStep = EgtGetValInNotes( Tool.sUserNotes, 'SIDESTEP', 'd') or floor( Tool.dDiameter / 3) -- se non settato nell'utensile, considero metà del diametro
|
||||
Tool.bIsPen = abs( Tool.dSpeed) < 5
|
||||
-- recupero parametri propri delle lame
|
||||
elseif sToolFamily == 'SAWBLADE' then
|
||||
Tool.bIsUsedForLongCut = EgtGetValInNotes( Tool.sUserNotes, 'LONGCUT') == 1 or false -- false coem valore di default
|
||||
Tool.dStep = EgtGetValInNotes( Tool.sUserNotes, 'STEP') or Tool.dThickness -- se non settato nell'utensile, considero lo spessore lama
|
||||
Tool.dSideStep = EgtGetValInNotes( Tool.sUserNotes, 'SIDESTEP') or Tool.dMaxMaterial -- se non settato nell'utensile, considero un quarto del diametro
|
||||
Tool.bIsUsedForLongCut = EgtGetValInNotes( Tool.sUserNotes, 'LONGCUT') == 1 or false -- false come valore di default
|
||||
Tool.dStep = EgtGetValInNotes( Tool.sUserNotes, 'STEP', 'd') or Tool.dThickness -- se non settato nell'utensile, considero lo spessore lama
|
||||
Tool.dSideStep = EgtGetValInNotes( Tool.sUserNotes, 'SIDESTEP', 'd') or Tool.dMaxMaterial -- se non settato nell'utensile, considero un quarto del diametro
|
||||
-- recupero parametri propri delle motoseghe
|
||||
elseif sToolFamily == 'MORTISE' then
|
||||
Tool.dDistance = EgtTdbGetCurrToolParam( MCH_TP.DIST) or 90 -- 90mm dimensione standard aggregato catena
|
||||
Tool.bIsMortise = EgtGetValInNotes( Tool.sUserNotes, 'MORTISE') == 1
|
||||
Tool.bIsChainSaw = not Tool.bIsMortise
|
||||
Tool.dStep = EgtGetValInNotes( Tool.sUserNotes, 'STEP') or floor( Tool.dMaxMaterial / 3) -- se non settato nell'utensile, considero un terzo della lunghezza
|
||||
Tool.dSideStep = EgtGetValInNotes( Tool.sUserNotes, 'SIDESTEP') or ( Tool.dThickness - 1) -- se non settato nell'utensile, considero spessore catena meno 1mm di sicurezza
|
||||
Tool.dStep = EgtGetValInNotes( Tool.sUserNotes, 'STEP', 'd') or floor( Tool.dMaxMaterial / 3) -- se non settato nell'utensile, considero un terzo della lunghezza
|
||||
Tool.dSideStep = EgtGetValInNotes( Tool.sUserNotes, 'SIDESTEP', 'd') or ( Tool.dThickness - 1) -- se non settato nell'utensile, considero spessore catena meno 1mm di sicurezza
|
||||
Tool.dCornerRadius = EgtTdbGetCurrToolParam( MCH_TP.CORNRAD)
|
||||
Tool.dWidth = Tool.dDiameter
|
||||
end
|
||||
@@ -220,6 +216,111 @@ function BeamExec.GetStrategiesFromJSONinBD()
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- funzione che controlla validità delle combinazioni proposte
|
||||
local function IsCombinationAvailable( sCombination, nUnloadPos, bSquareSection)
|
||||
-- se non utilizzo BEAMWALL, forzo comportamento BASIC
|
||||
if not BEAM.BeamWall or not BEAM.Rotation then
|
||||
BEAM.Rotation = {}
|
||||
BEAM.Rotation.Basic = true
|
||||
end
|
||||
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
-- TODO scelta combinazione forzato DA RIMUOVERE!! Serve modifica al BEAM.
|
||||
BEAM.BeamWall = true
|
||||
BEAM.Rotation = {}
|
||||
BEAM.Rotation.bBasic = true
|
||||
BEAM.Rotation.bNoRotation = false
|
||||
BEAM.Rotation.bAdvanced = false
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
-- BASIC : posizione di scarico come posizionamento iniziale
|
||||
if not BEAM.BeamWall or BEAM.Rotation.bBasic then
|
||||
local ExtraRotation = nUnloadPos + 3
|
||||
if nUnloadPos ~= 1 then
|
||||
return false
|
||||
elseif string.sub( sCombination, nUnloadPos, nUnloadPos) == '1' and string.sub( sCombination, ExtraRotation, ExtraRotation) == '0' then
|
||||
if not BeamData.ROT90 and string.sub( sCombination, nUnloadPos+1, nUnloadPos+1) == '1' then
|
||||
return false
|
||||
elseif not BeamData.ROT180 and string.sub( sCombination, nUnloadPos+2, nUnloadPos+2) == '1' then
|
||||
return false
|
||||
else
|
||||
return true
|
||||
end
|
||||
else
|
||||
return false
|
||||
end
|
||||
-- NO ROTATION : solo posizione di partenza
|
||||
elseif BEAM.Rotation.bNoRotation then
|
||||
if sCombination == '1000' and nUnloadPos == 1 then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
-- ADVANCED : come BASIC ma ammesse anche le prerotazioni (posizione di scarico può essere diversa da posizione iniziale)
|
||||
elseif BEAM.Rotation.bAdvanced then
|
||||
local nRotation90 = EgtIf( nUnloadPos + 1 > 4, nUnloadPos + 1 - 4, nUnloadPos + 1)
|
||||
local nRotation180 = EgtIf( nUnloadPos + 2 > 4, nUnloadPos + 2 - 4, nUnloadPos + 2)
|
||||
local nExtraRotation = EgtIf( nUnloadPos + 3 > 4, nUnloadPos + 3 - 4, nUnloadPos + 3)
|
||||
|
||||
if not bSquareSection and ( nUnloadPos == 2 or nUnloadPos == 4) then
|
||||
return false
|
||||
else
|
||||
if string.sub( sCombination, nUnloadPos, nUnloadPos) ~= '1' or string.sub( sCombination, nExtraRotation, nExtraRotation) == '1' then
|
||||
return false
|
||||
else
|
||||
if not BeamData.ROT90 and string.sub( sCombination, nRotation90, nRotation90) == '1' then
|
||||
return false
|
||||
elseif not BeamData.ROT180 and string.sub( sCombination, nRotation180, nRotation180) == '1' then
|
||||
return false
|
||||
else
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function GetAvailableCombinations( PartInfo)
|
||||
local CombinationList = {}
|
||||
CombinationList.Rotations = {0, 0, 0, 0} -- indice rotazione attiva, per calcolo collect feature
|
||||
|
||||
-- verifico tutte le combinazioni che possono essere considerate
|
||||
for nUnloadPos = 1, 4 do
|
||||
for i = 1, BeamLib.BinaryToDecimal( 1111) do
|
||||
local nBitIndexCombination = BeamLib.DecimalToBinary( i)
|
||||
local sBitIndexCombination = BeamLib.CalculateStringBinaryFormat( nBitIndexCombination, 4)
|
||||
-- si calcolano le combinazioni all'inizio, ottimizzando calcolo della collect solo nelle rotazioni che possono essere considerate
|
||||
if IsCombinationAvailable( sBitIndexCombination, nUnloadPos, PartInfo.bSquareSection) then
|
||||
local Combination = {}
|
||||
Combination.sBitIndexCombination = sBitIndexCombination
|
||||
Combination.nUnloadPos = nUnloadPos
|
||||
table.insert( CombinationList, Combination)
|
||||
|
||||
-- se posizionamento iniziale attivo
|
||||
if string.sub( sBitIndexCombination, 1, 1) == '1' then
|
||||
CombinationList.Rotations[1] = 1
|
||||
end
|
||||
-- se attiva rotazione 90
|
||||
if string.sub( sBitIndexCombination, 2, 2) == '1' then
|
||||
CombinationList.Rotations[2] = 1
|
||||
end
|
||||
-- se attiva rotazione 180
|
||||
if string.sub( sBitIndexCombination, 3, 3) == '1' then
|
||||
CombinationList.Rotations[3] = 1
|
||||
end
|
||||
-- se attiva rotazione 270
|
||||
if string.sub( sBitIndexCombination, 4, 4) == '1' then
|
||||
CombinationList.Rotations[4] = 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return CombinationList
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- *** funzioni posizionamento pezzi all'interno della barra ***
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
@@ -281,7 +382,7 @@ function BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, dOvmMid, PARTS)
|
||||
local dPartLen = PARTS[i].b3Box:getDimX()
|
||||
local dPartWidth = PARTS[i].b3Box:getDimY()
|
||||
local dPartHeight = PARTS[i].b3Box:getDimZ()
|
||||
local dNextLen = dLen - dDeltaS - dPartLen - dDeltaE
|
||||
local dNextLen = dLen - EgtIf( i == 1, dDeltaS, 0) - dPartLen - dDeltaE
|
||||
if (( abs( dPartWidth - dRawW) < 100 * GEO.EPS_SMALL and abs( dPartHeight - dRawH) < 100 * GEO.EPS_SMALL) or
|
||||
( abs( dPartHeight - dRawW) < 100 * GEO.EPS_SMALL and abs( dPartWidth - dRawH) < 100 * GEO.EPS_SMALL)) and
|
||||
dNextLen + dDeltaE >= 0 then
|
||||
@@ -341,10 +442,17 @@ function BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, dOvmMid, PARTS)
|
||||
-- aggiorno grezzo precedente
|
||||
idPrevRaw = PARTS[i].idRaw
|
||||
dPrevDelta = dDelta
|
||||
PARTS[i].bIsLastPart = ( i == #PARTS)
|
||||
PARTS[i].dDistanceToNextPiece = dDelta
|
||||
PARTS[i].dRestLength = dLen
|
||||
PARTS[i].b3Raw = EgtGetRawPartBBox( PARTS[i].idRaw)
|
||||
PARTS[i].dLength = PARTS[i].b3Raw:getDimX()
|
||||
PARTS[i].dWidth = PARTS[i].b3Raw:getDimY()
|
||||
PARTS[i].dHeight = PARTS[i].b3Raw:getDimZ()
|
||||
PARTS[i].bSquareSection = abs( PARTS[i].dWidth - PARTS[i].dHeight) < 100 * GEO.EPS_SMALL
|
||||
PARTS[i].b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( PARTS[i].id, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
|
||||
PARTS[i].nIndexInParts = i
|
||||
PARTS[i].CombinationList = GetAvailableCombinations( PARTS[i])
|
||||
else
|
||||
local sOut = 'Error: part L(' .. EgtNumToString( dPartLen, 1) .. ') too big for raw part L(' .. EgtNumToString( dLen - 0.1, 1) .. ')'
|
||||
return false, sOut
|
||||
@@ -358,14 +466,20 @@ function BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, dOvmMid, PARTS)
|
||||
end
|
||||
|
||||
-- Se rimasto materiale aggiungo grezzo dell'avanzo
|
||||
-- TODO valutare se ridurre la dLen minima perchè crea discrepanze tra lunghezza inserita e VMill
|
||||
if dLen > 10 then
|
||||
PARTS[#PARTS].bNextIsRaw = true
|
||||
local idRaw = EgtAddRawPart( Point3d(0,0,0), dLen, dRawW, dRawH, BeamData.RAWCOL)
|
||||
EgtMoveToCornerRawPart( idRaw, BeamData.ptOriXR, BeamData.dPosXR)
|
||||
EgtMoveRawPart( idRaw, Vector3d( dLen - dRawL, 0, 0))
|
||||
-- assegno ordine in lavorazione
|
||||
nCnt = nCnt + 1
|
||||
EgtSetInfo( idRaw, 'ORD', nCnt)
|
||||
-- aggiorno distanza dell'ultimo pezzo dall'eventuale grezzo scaricabile
|
||||
if EgtGetRawPartBBox( idRaw):getDimX() < BeamData.dMinRaw then
|
||||
PARTS[#PARTS].dDistanceToNextPiece = 10000
|
||||
end
|
||||
else
|
||||
PARTS[#PARTS].dDistanceToNextPiece = 10000
|
||||
end
|
||||
|
||||
return true
|
||||
@@ -373,6 +487,7 @@ end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function BeamExec.CalcMinUnloadableRaw( dRawW, dRawH)
|
||||
-- TODO convertire in GetMinUnloadableRaw che viene richiamata all'inizio delle funzioni che necessitano di dMinRaw
|
||||
if BeamData.GetMinUnloadableRaw then
|
||||
BeamData.dMinRaw = BeamData.GetMinUnloadableRaw( dRawW, dRawH)
|
||||
else
|
||||
@@ -447,11 +562,11 @@ local function GetFeatureForcedStrategy( Proc)
|
||||
|
||||
-- cerco e aggiorno i parametri come sono settati nel processing
|
||||
for i = 1, #StrategyData.Parameters do
|
||||
local sParameterToRead = StrategyData.sStrategyId .. '_' .. StrategyData.Parameters[i].sName
|
||||
ForcedParameterForProc = EgtGetInfo( Proc.id, sParameterToRead, 's')
|
||||
local sParameterToRead = StrategyData.sStrategyId .. '_' .. StrategyData.Parameters[i].sNameNge
|
||||
local sForcedParameterForProc = EgtGetInfo( Proc.id, sParameterToRead, 's')
|
||||
-- se ho trovato il valore, lo sovrascrivo al default
|
||||
if ForcedParameterForProc then
|
||||
StrategyData.Parameters[i].sValue = ForcedParameterForProc
|
||||
if sForcedParameterForProc then
|
||||
StrategyData.Parameters[i].sValue = sForcedParameterForProc
|
||||
end
|
||||
end
|
||||
|
||||
@@ -482,6 +597,8 @@ local function CollectFeatures( Part)
|
||||
if nGrp and nPrc and nDo == 1 then
|
||||
local Proc = {}
|
||||
Proc.idPart = Part.id
|
||||
Proc.idRaw = Part.idRaw
|
||||
Proc.nIndexPartInParts = Part.nIndexInParts
|
||||
Proc.id = ProcId
|
||||
-- id della feature btl ( se non presente info, si prende id dell'entità geometrica)
|
||||
Proc.idFeature = EgtGetInfo( Proc.id, 'PRID', 's') or Proc.id
|
||||
@@ -499,16 +616,16 @@ local function CollectFeatures( Part)
|
||||
-- se foro calcolo altri dati
|
||||
if ID.IsDrilling( Proc) then
|
||||
-- assegno diametro e facce di ingresso e uscita (dati tabelle sempre per riferimento)
|
||||
Proc.dDiam, Proc.dLen, Proc.nFcs, Proc.nFce = FeatureData.GetDrillingData( Proc)
|
||||
Proc.dDiam, Proc.dLen, Proc.nFcs, Proc.nFce = FeatureLib.GetDrillingData( Proc)
|
||||
end
|
||||
-- informazioni facce e topologia
|
||||
Proc.AffectedFaces = BeamLib.GetAffectedFaces( Proc, Part)
|
||||
-- calcolo topologia solo se necessario, altrimenti si sfruttano le informazioni della feature BTL
|
||||
Proc.Topology = {}
|
||||
if FeatureData.NeedTopologyFeature( Proc) then
|
||||
if FeatureLib.NeedTopologyFeature( Proc) then
|
||||
Proc.AdjacencyMatrix = FaceData.GetAdjacencyMatrix( Proc)
|
||||
Proc.Faces = FaceData.GetFacesInfo( Proc, Part)
|
||||
Proc.Topology = FeatureData.ClassifyTopology( Proc, Part)
|
||||
Proc.Topology = FeatureLib.ClassifyTopology( Proc, Part)
|
||||
else
|
||||
Proc.Topology.sFamily = 'FEATURE'
|
||||
Proc.Topology.sName = 'FEATURE'
|
||||
@@ -669,6 +786,8 @@ local function GetIndexBestStrategyFromComparison( AvailableStrategies, nIndex1,
|
||||
-- controllo indici
|
||||
if nIndex1 == 0 and nIndex2 == 0 then
|
||||
dChosenIndex = 0
|
||||
elseif nIndex1 == nIndex2 then
|
||||
dChosenIndex = nIndex1
|
||||
elseif nIndex1 == 0 then
|
||||
-- basta che sia applicabile
|
||||
if AvailableStrategies[nIndex2].Result and ( AvailableStrategies[nIndex2].Result.sStatus == 'Completed' or AvailableStrategies[nIndex2].Result.sStatus == 'Not-Completed') then
|
||||
@@ -691,8 +810,8 @@ local function GetIndexBestStrategyFromComparison( AvailableStrategies, nIndex1,
|
||||
-- se le due strategie hanno stesso stato e sono entrambe applicabili (quindi entrambe complete o entrambe non-complete)
|
||||
if AvailableStrategies[nIndex1].Result.sStatus ~= 'Not-Applicable' and AvailableStrategies[nIndex2].Result.sStatus ~= 'Not-Applicable' and
|
||||
AvailableStrategies[nIndex1].Result.sStatus == AvailableStrategies[nIndex2].Result.sStatus then
|
||||
local dCompositeRatingStrategy1 = AvailableStrategies[nIndex1].Result.nQuality * AvailableStrategies[nIndex1].Result.nCompletionIndex * AvailableStrategies[nIndex1].Result.dMRR
|
||||
local dCompositeRatingStrategy2 = AvailableStrategies[nIndex2].Result.nQuality * AvailableStrategies[nIndex2].Result.nCompletionIndex * AvailableStrategies[nIndex2].Result.dMRR
|
||||
local dCompositeRatingStrategy1 = AvailableStrategies[nIndex1].Result.dCompositeRating
|
||||
local dCompositeRatingStrategy2 = AvailableStrategies[nIndex2].Result.dCompositeRating
|
||||
-- si predilige strategia con rating composito più alto
|
||||
if dCompositeRatingStrategy1 > dCompositeRatingStrategy2 then
|
||||
dChosenIndex = nIndex1
|
||||
@@ -708,8 +827,34 @@ local function GetIndexBestStrategyFromComparison( AvailableStrategies, nIndex1,
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- funzione che processa tutte le feature sul pezzo e trova la miglior strategia di lavorazione tra quelle disponibili
|
||||
local function GetBestStrategy( vProcSingleRot, Part)
|
||||
-- funzione che trova la strategia migliore tra quelle disponibili
|
||||
local function GetBestStrategy( vProcSingleRot)
|
||||
for i = 1, #vProcSingleRot do
|
||||
-- processo tutte le feature attive
|
||||
local Proc = vProcSingleRot[i]
|
||||
if Proc.nFlg ~= 0 then
|
||||
local nIndexBestStrategy = 0
|
||||
-- controllo se ci sono strategie disponibili
|
||||
if Proc.AvailableStrategies and #Proc.AvailableStrategies > 0 then
|
||||
-- ciclo tutte le strategie della feature
|
||||
for nIndexCurrentStrategy = 1, #Proc.AvailableStrategies do
|
||||
-- scelgo la migliore strategia tra le due
|
||||
nIndexBestStrategy = GetIndexBestStrategyFromComparison( Proc.AvailableStrategies, nIndexCurrentStrategy, nIndexBestStrategy)
|
||||
-- salvo sulla proc la migliore strategia
|
||||
end
|
||||
if nIndexBestStrategy ~= 0 then
|
||||
Proc.ChosenStrategy = Proc.AvailableStrategies[nIndexBestStrategy]
|
||||
Proc.nIndexBestStrategy = nIndexBestStrategy
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return vProcSingleRot
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- funzione che processa tutte le feature del pezzo
|
||||
local function CalculateStrategies( vProcSingleRot, Part)
|
||||
-- per ogni feature
|
||||
for i = 1, #vProcSingleRot do
|
||||
-- processo tutte le feature attive
|
||||
@@ -717,7 +862,6 @@ local function GetBestStrategy( vProcSingleRot, Part)
|
||||
if Proc.nFlg ~= 0 then
|
||||
-- controllo se ci sono strategie disponibili
|
||||
if Proc.AvailableStrategies and #Proc.AvailableStrategies > 0 then
|
||||
local nIndexBestStrategy = 0
|
||||
-- ciclo tutte le strategie della feature
|
||||
for nIndexCurrentStrategy = 1, #Proc.AvailableStrategies do
|
||||
-- eseguo file config con i parametri di default
|
||||
@@ -725,30 +869,23 @@ local function GetBestStrategy( vProcSingleRot, Part)
|
||||
CurrentStrategy = RunStrategyLibraries( Proc.AvailableStrategies[nIndexCurrentStrategy].sStrategyId)
|
||||
-- controllo che le librerie siano state effettivamente caricate
|
||||
if CurrentStrategy.Config and CurrentStrategy.Script then
|
||||
local bStrategyOk
|
||||
-- eseguo la strategia solo come calcolo fattibilità e voto. Non si applicano le lavorazioni. Si passa la Proc e i parametri personalizzati
|
||||
_, Proc.AvailableStrategies[nIndexCurrentStrategy].Result = CurrentStrategy.Script.Make( false, Proc, Part, Proc.AvailableStrategies[nIndexCurrentStrategy].Parameters)
|
||||
-- scelgo la migliore strategia tra le due
|
||||
nIndexBestStrategy = GetIndexBestStrategyFromComparison( Proc.AvailableStrategies, nIndexCurrentStrategy, nIndexBestStrategy)
|
||||
|
||||
-- se scelta strategia standard, esco subito alla prima che trovo completa
|
||||
Proc.AvailableStrategies[nIndexCurrentStrategy].Result = FeatureLib.CalculateCompositeRating( Proc.AvailableStrategies[nIndexCurrentStrategy].Result)
|
||||
-- se scelta strategia in modalità base o standard, esco subito alla prima che trovo completa
|
||||
-- TODO serve paraemtro da Beam&Wall ( oppure da confirgurazione) !!!!!!!!
|
||||
if BEAM.GetFirstCompletedStrategy and nIndexBestStrategy > 0 then
|
||||
if Proc.AvailableStrategies[nIndexBestStrategy].Result.sStatus == 'Complete' then
|
||||
break
|
||||
end
|
||||
if BEAM.GetFirstCompletedStrategy and Proc.AvailableStrategies[nIndexCurrentStrategy].Result.sStatus == 'Complete' then
|
||||
break
|
||||
end
|
||||
|
||||
-- se non trovo i file della strategia, scrivo che non è più disponibile
|
||||
else
|
||||
Proc.AvailableStrategies[nIndexCurrentStrategy].Result = {}
|
||||
Proc.AvailableStrategies[nIndexCurrentStrategy].Result.sInfo = 'Strategy not found'
|
||||
Proc.AvailableStrategies[nIndexCurrentStrategy].Result.sStatus = 'Not-Applicable'
|
||||
end
|
||||
end
|
||||
-- salvo sulla proc la migliore strategia
|
||||
if nIndexBestStrategy ~= 0 then
|
||||
Proc.ChosenStrategy = Proc.AvailableStrategies[nIndexBestStrategy]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -758,7 +895,7 @@ end
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- Ordina le feature in base a fase di lavorazione
|
||||
-- 1) Head : ( intestatura)
|
||||
-- 2) Standard : ( lavorazioni standard che non impattano sulal coda)
|
||||
-- 2) Standard : ( lavorazioni standard che non impattano sulla coda)
|
||||
-- 3) AdvanceTail : ( lavorazioni che richiedono taglio di separazione, ma che devono essere fatte prima perchè il taglio di separazione farebbe cadere il pezzo)
|
||||
-- 4) Split : ( taglio di separazione)
|
||||
-- 5) Tail : ( lavorazioni di coda, fatte dopo il taglio di separazione)
|
||||
@@ -832,7 +969,6 @@ end
|
||||
-- esegue le strategie migliori che ha precedentemente scelto
|
||||
local function CalculateMachinings( vProc, Part)
|
||||
local bAreAllApplyOk = true
|
||||
MACHININGS = {}
|
||||
-- applico le strategie scelte
|
||||
for i = 1, #vProc do
|
||||
-- processo tutte le feature attive applicando le lavorazioni
|
||||
@@ -845,63 +981,49 @@ local function CalculateMachinings( vProc, Part)
|
||||
bAreAllApplyOk, _ = StrategyScript.Make( true, Proc, Part, Proc.ChosenStrategy.Parameters)
|
||||
end
|
||||
end
|
||||
return vProc
|
||||
return MACHININGS
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function PrintFeatures( vProc, Part)
|
||||
EgtOutLog( ' RawBox=' .. tostring( Part.RawBox))
|
||||
for i = 1, #vProc do
|
||||
local Proc = vProc[i]
|
||||
local sOut = string.format( ' Id=%3d Grp=%1d Prc=%3d TC=%2d/%d Flg=%2d Down=%s Side=%s Head=%s Tail=%s Fcse=%1d,%1d Diam=%.2f Fct=%2d Box=%s TopoName=%s',
|
||||
Proc.id, Proc.nGrp, Proc.nPrc, Proc.idTask, Proc.idCut,
|
||||
Proc.nFlg, EgtIf( Proc.bDown, 'T', 'F'), EgtIf( Proc.bSide, 'T', 'F'),
|
||||
EgtIf( Proc.bHead, 'T', 'F'), EgtIf( Proc.bTail, 'T', EgtIf( Proc.bAdvTail, 'A', 'F')),
|
||||
Proc.nFcs, Proc.nFce, Proc.dDiam, Proc.nFct, tostring( Proc.b3Box), Proc.Topology.sName or '')
|
||||
-- info speciali per Block Haus Half Lap
|
||||
if Proc.nPrc == 37 then
|
||||
local sSpec = string.format( ' N=%s Hd=%s', tostring( Proc.vtN or V_NULL()), EgtIf( Proc.bHeadDir, 'T', 'F'))
|
||||
sOut = sOut .. sSpec
|
||||
if vProc then
|
||||
EgtOutLog( ' RawBox=' .. tostring( Part.b3Box))
|
||||
for i = 1, #vProc do
|
||||
local Proc = vProc[i]
|
||||
local sOut = string.format( ' Id=%3d Grp=%1d Prc=%3d Flg=%2d Fct=%2d TopoName=%s',
|
||||
Proc.id, Proc.nGrp, Proc.nPrc, Proc.nFlg, Proc.nFct, Proc.Topology.sName or '')
|
||||
EgtOutLog( sOut)
|
||||
end
|
||||
EgtOutLog( sOut)
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function BeamExec.ProcessFeatures( PARTS)
|
||||
-- ciclo sui pezzi
|
||||
local nTotErr = 0
|
||||
local Stats = {}
|
||||
local nOrd = 1
|
||||
local Part = {}
|
||||
|
||||
function BeamExec.GetProcessings( PROCESSINGS, PARTS)
|
||||
-- recupero tutti i processing di tutti i pezzi in tutte le rotazioni
|
||||
-- TODO calcolo tempi da rimuovere o lasciare solo per debug
|
||||
-- if EgtGetDebugLevel() >= 3 then
|
||||
-- EgtStartCounter()
|
||||
-- end
|
||||
for nPart = 1, #PARTS do
|
||||
if not PARTS[nPart].id and PARTS[nPart].b3Raw:getDimX() < BeamData.dMinRaw then break end
|
||||
|
||||
-- per ogni rotazione, calcolo come lavorare le feature per decidere posizionamento iniziale e in che rotazione verranno lavorate le singole feature
|
||||
local vProcRot = {}
|
||||
-- lista contenente le feature da eseguire
|
||||
local vProc = {}
|
||||
|
||||
|
||||
-- TODO da rimuovere o lasciare solo per debug
|
||||
if EgtGetDebugLevel() >= 3 then
|
||||
EgtStartCounter()
|
||||
end
|
||||
|
||||
|
||||
-- TODO Il numero di rotazioni da calcolare deve dipendere dalle impostazionei del cliente. Per adesso si calcolano tutte e 4, ma può essere ottimizzato
|
||||
for dRotIndex = 1, 4 do
|
||||
|
||||
-- recupero le feature di lavorazione della trave
|
||||
table.insert( vProcRot, CollectFeatures( PARTS[nPart]))
|
||||
|
||||
-- recupero informazioni ausiliarie feature e dipendenze tra feature stesse
|
||||
-- TODO le dipendenze cambiano in base alla rotazione del pezzo? probabilmente no
|
||||
vProcRot[dRotIndex] = GetFeatureInfoAndDependency( vProcRot[dRotIndex], PARTS[nPart])
|
||||
-- si calcolano le feature solo se la rotazione può essere presa in considerazione
|
||||
if PARTS[nPart].CombinationList.Rotations[dRotIndex] == 1 then
|
||||
-- recupero le feature di lavorazione della trave
|
||||
table.insert( vProcRot, CollectFeatures( PARTS[nPart]))
|
||||
|
||||
-- recupero informazioni ausiliarie feature e dipendenze tra feature stesse
|
||||
-- TODO le dipendenze cambiano in base alla rotazione del pezzo? probabilmente no
|
||||
vProcRot[dRotIndex] = GetFeatureInfoAndDependency( vProcRot[dRotIndex], PARTS[nPart])
|
||||
|
||||
-- sceglie la strategia migliore tra quelle disponibili ( presenti nella tabella vProcRot[dRotIndex].AvailableStrategies)
|
||||
vProcRot[dRotIndex] = GetBestStrategy( vProcRot[dRotIndex], PARTS[nPart])
|
||||
-- calcola le strategie applicabili ( presenti nella tabella vProcRot[dRotIndex].AvailableStrategies)
|
||||
vProcRot[dRotIndex] = CalculateStrategies( vProcRot[dRotIndex], PARTS[nPart])
|
||||
else
|
||||
-- inserisco una tabella vuota
|
||||
table.insert( vProcRot, {})
|
||||
end
|
||||
|
||||
-- ruoto il grezzo per calcolare la fattibilità delle lavorazioni nella prossima rotazione
|
||||
-- vettore movimento grezzi per rotazione di 90deg ogni step
|
||||
@@ -920,99 +1042,417 @@ end
|
||||
PARTS[nPart].b3Raw = EgtGetRawPartBBox( PARTS[nPart].idRaw)
|
||||
PARTS[nPart].b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( PARTS[nPart].id, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
|
||||
end
|
||||
|
||||
|
||||
-- TODO da rimuovere o lasciare solo per debug
|
||||
if EgtGetDebugLevel() >= 3 then
|
||||
local timeCollect = EgtStopCounter()
|
||||
timeCollect = timeCollect + 0
|
||||
EgtOutBox( timeCollect, 'Collect calculation time')
|
||||
EgtStartCounter()
|
||||
local Part = {}
|
||||
Part.Rotation = vProcRot
|
||||
-- recupero le feature di lavorazione della trave
|
||||
table.insert( PROCESSINGS, Part)
|
||||
end
|
||||
-- TODO calcolo tempi da rimuovere o lasciare solo per debug
|
||||
-- if EgtGetDebugLevel() >= 3 then
|
||||
-- local timeGetProcessings = EgtStopCounter()
|
||||
-- timeGetProcessings = timeGetProcessings + 0
|
||||
-- EgtOutBox( timeGetProcessings, 'GetProcessings calculation time')
|
||||
-- EgtStartCounter()
|
||||
-- end
|
||||
return PROCESSINGS
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- funzione che decide la migliore tra le combinazioni di rotazione disponibili
|
||||
local function GetBestCombination( ListToCompare)
|
||||
-- TODO da completare
|
||||
local nIndexBestCombination = 1
|
||||
if #ListToCompare == 1 then
|
||||
nIndexBestCombination = 1
|
||||
else
|
||||
for ListIndex = 2, #ListToCompare do
|
||||
local bBestComplete = ListToCompare[nIndexBestCombination].nNotComplete == 0 and ListToCompare[nIndexBestCombination].nNotExecute == 0
|
||||
local bOtherComplete = ListToCompare[ListIndex].nNotComplete == 0 and ListToCompare[ListIndex].nNotExecute == 0
|
||||
|
||||
-- TODO decidere come lavorare ogni feature in base alla matrice delle rotazioni
|
||||
-- la matrice delle rotazioni deve già salvare sulla proc la strategia da utilizzare
|
||||
-- Conviene salvarsi tutti i dati fino alla lavorazione e il ciclo di applicazione va ad applicare senza calcolare?
|
||||
|
||||
-- aggiungo la fase, se non è la prima
|
||||
if nOrd == 1 then
|
||||
EgtSetCurrPhase( 1)
|
||||
else
|
||||
BeamLib.AddPhaseWithRawParts( PARTS[nPart], BeamData.ptOriXR, BeamData.dPosXR, 0)
|
||||
end
|
||||
local nPhase = EgtGetCurrPhase()
|
||||
local nDispId = EgtGetPhaseDisposition( nPhase)
|
||||
EgtSetInfo( nDispId, 'TYPE', EgtIf( PARTS[nPart].id, 'START', 'REST'))
|
||||
EgtSetInfo( nDispId, 'ORD', nOrd)
|
||||
EgtOutLog( ' *** Phase=' .. tostring( nPhase) .. ' Raw=' .. tostring( PARTS[nPart].idRaw) .. ' Part=' .. tostring( PARTS[nPart].id) .. ' ***', 1)
|
||||
|
||||
-- debug
|
||||
if EgtGetDebugLevel() >= 1 then
|
||||
PrintFeatures( vProc, PARTS[nPart])
|
||||
end
|
||||
EgtOutLog( ' *** AddMachinings ***', 1)
|
||||
|
||||
-- TODO PROVVISORIO in attesa di scelta lavorazione in fase opportuna
|
||||
vProc = vProcRot[1]
|
||||
|
||||
-- ordino le features
|
||||
vProc = OrderFeatures( vProc)
|
||||
|
||||
-- TODO da fare
|
||||
MACHININGS = {}
|
||||
-- esegue le strategie migliori che ha precedentemente scelto e salva le lavorazioni nella lista globale
|
||||
CalculateMachinings( vProc, PARTS[nPart])
|
||||
|
||||
-- TODO riordinare lavorazioni ottimizzando cambio utensile/spezzone ecc..., mantenendo dipendenze definite prima
|
||||
-- ordino le lavorazioni
|
||||
-- OrderMachining( vProc, PARTS[nPart])
|
||||
|
||||
-- aggiunge effettivamente le lavorazioni
|
||||
MachiningLib.AddOperations( vProc, PARTS[nPart])
|
||||
|
||||
|
||||
-- TODO da rimuovere o lasciare solo per debug
|
||||
if EgtGetDebugLevel() >= 3 then
|
||||
local timeMachining = EgtStopCounter()
|
||||
timeMachining = timeMachining + 0
|
||||
EgtOutBox( timeMachining, 'Machining calculation time')
|
||||
end
|
||||
|
||||
|
||||
EgtOutLog( ' *** End AddMachinings ***', 1)
|
||||
-- passo al grezzo successivo
|
||||
nOrd = nOrd + 1
|
||||
end
|
||||
|
||||
-- Aggiornamento finale di tutto
|
||||
EgtSetCurrPhase( 1)
|
||||
local bApplOk, sApplErrors, sApplWarns = EgtApplyAllMachinings()
|
||||
-- eventuale ricalcolo per macchine tipo PF (ma tengo warning del primo calcolo)
|
||||
if EgtExistsInfo( EgtGetCurrMachGroup(), 'RECALC') then
|
||||
EgtOutLog( ' **** RECALC ****')
|
||||
bApplOk, sApplErrors, _ = EgtApplyAllMachinings()
|
||||
EgtRemoveInfo( EgtGetCurrMachGroup(), 'RECALC')
|
||||
end
|
||||
if not bApplOk then
|
||||
nTotErr = nTotErr + 1
|
||||
table.insert( Stats, {nErr = 1, sMsg=sApplErrors, nRot=0, idCut=0, idTask=0})
|
||||
elseif sApplWarns and #sApplWarns > 0 then
|
||||
local vLine = EgtSplitString( sApplWarns, '\r\n')
|
||||
for i = 1, #vLine do
|
||||
local nPos = vLine[i]:find( '(WRN', 1, true)
|
||||
if nPos then
|
||||
local sData = vLine[i]:sub( nPos + 1, -2)
|
||||
local vVal = EgtSplitString( sData, ',')
|
||||
local nWarn = EgtGetVal( vVal[1] or '', 'WRN', 'i')
|
||||
local nCutId = EgtGetVal( vVal[2] or '', 'CUTID', 'i')
|
||||
if nWarn and nCutId then
|
||||
table.insert( Stats, { nErr=-nWarn, sMsg=vLine[i], nRot=0, idCut=nCutId, idTask=0})
|
||||
-- prediligo combinazione completa
|
||||
if bBestComplete and not bOtherComplete then
|
||||
; -- la migliore resta la stessa
|
||||
elseif not bBestComplete and bOtherComplete then
|
||||
nIndexBestCombination = ListIndex
|
||||
-- altrimenti guardo il voto
|
||||
else
|
||||
-- se stesso voto
|
||||
if ListToCompare[nIndexBestCombination].dTotalRating == ListToCompare[ListIndex].dTotalRating then
|
||||
-- TODO il voto dovrebbe essere considerato già pesando le rotazioni, con un coefficiente o un peso fisso aggiuntivo
|
||||
-- scelgo soluzione con meno rotazioni
|
||||
if ListToCompare[nIndexBestCombination].nRotations > ListToCompare[ListIndex].nRotations then
|
||||
nIndexBestCombination = ListIndex
|
||||
-- se anche le rotazioni sono le stesse, prendo la soluzione con più lavorazioni alla fine
|
||||
elseif #ListToCompare[nIndexBestCombination].Rot0 < #ListToCompare[ListIndex].Rot0 then
|
||||
nIndexBestCombination = ListIndex
|
||||
end
|
||||
-- se voto diverso
|
||||
else
|
||||
-- scelgo soluzione con voto più alto
|
||||
if ListToCompare[nIndexBestCombination].dTotalRating < ListToCompare[ListIndex].dTotalRating then
|
||||
nIndexBestCombination = ListIndex
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ChosenCombination = ListToCompare[nIndexBestCombination]
|
||||
return ChosenCombination
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- funzione che decide le combinazioni di rotazione per lavorare la trave
|
||||
local function GetProcessingListFromCombination( BestCombination)
|
||||
local vProc = {}
|
||||
local bSomeFeatureDown = false
|
||||
local bSomeFeatureSide = false
|
||||
local nInitialPosition = BestCombination.nIndexRotation
|
||||
|
||||
-- aggiungo processing da fare in fase ribaltata
|
||||
if #BestCombination.Rot180 > 0 then
|
||||
bSomeFeatureDown = true
|
||||
for i = 1, #BestCombination.Rot180 do
|
||||
BestCombination.Rot180[i].bDown = true
|
||||
table.insert( vProc, BestCombination.Rot180[i])
|
||||
end
|
||||
end
|
||||
|
||||
-- aggiungo processing da fare in fase ruotata
|
||||
if #BestCombination.Rot90 > 0 then
|
||||
bSomeFeatureSide = true
|
||||
for i = 1, #BestCombination.Rot90 do
|
||||
BestCombination.Rot90[i].bSide = true
|
||||
table.insert( vProc, BestCombination.Rot90[i])
|
||||
end
|
||||
end
|
||||
|
||||
-- aggiungo processing da fare in ultima fase
|
||||
if #BestCombination.Rot0 > 0 then
|
||||
for i = 1, #BestCombination.Rot0 do
|
||||
table.insert( vProc, BestCombination.Rot0[i])
|
||||
end
|
||||
end
|
||||
|
||||
return vProc, nInitialPosition, bSomeFeatureDown, bSomeFeatureSide
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- funzione che ritorna la Proc nella rotazione scelta
|
||||
local function GetProcBestMachRotationFromList( ListToCompare)
|
||||
local Data = {}
|
||||
local Proc = {}
|
||||
local nIndexChosenProcInRot = 1
|
||||
|
||||
-- se ci sono almeno 2 possibili soluzioni, scelgo la posizione migliore di lavorazione
|
||||
if #ListToCompare > 1 then
|
||||
-- formatto lista strategie disponibili come se le aspetta la funzione di compare
|
||||
local AvailableStrategiesInRot = {}
|
||||
for i = 1, #ListToCompare do
|
||||
table.insert( AvailableStrategiesInRot, ListToCompare[i][1].ChosenStrategy)
|
||||
end
|
||||
for nIndexCurrentStrategy = 1, #AvailableStrategiesInRot do
|
||||
-- la scelta tra le differenti strategie tra le rotazioni utilizza gli stessi criteri della scelta strategie all'interno della feature stessa
|
||||
nIndexChosenProcInRot = GetIndexBestStrategyFromComparison( AvailableStrategiesInRot, nIndexCurrentStrategy, nIndexChosenProcInRot)
|
||||
end
|
||||
-- altrimenti prendo la prima
|
||||
else
|
||||
nIndexChosenProcInRot = 1
|
||||
end
|
||||
|
||||
Proc = ListToCompare[nIndexChosenProcInRot][1]
|
||||
Data.nIndexRotation = ListToCompare[nIndexChosenProcInRot].nRotation
|
||||
Data.dCompositeRating = ListToCompare[nIndexChosenProcInRot][1].ChosenStrategy.Result.dCompositeRating
|
||||
Data.bComplete = ListToCompare[nIndexChosenProcInRot][1].ChosenStrategy.Result.sStatus == 'Completed'
|
||||
Data.bNotComplete = ListToCompare[nIndexChosenProcInRot][1].ChosenStrategy.Result.sStatus == 'Not-Completed'
|
||||
Data.bNotApplicable = ListToCompare[nIndexChosenProcInRot][1].ChosenStrategy.Result.sStatus == 'Not-Applicable'
|
||||
return Proc, Data
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- funzione che calcola le combinazioni di rotazione per lavorare la trave e sceglie la migliore
|
||||
local function GetBestResultFromCombinationsMatrix( ProcessingsOnPart, PartInfo)
|
||||
local BestCombination = {}
|
||||
local CombinationsList = {}
|
||||
|
||||
-- scrittura nel log della matrice delle rotazioni
|
||||
if EgtGetDebugLevel() >= 3 then
|
||||
Logs.WriteMatrixLog( ProcessingsOnPart, PartInfo)
|
||||
end
|
||||
|
||||
-- per ogni posizione di scarico
|
||||
for nUnloadPos = 1, 4 do
|
||||
-- calcolo per tutte le combinazioni disponibili precedentemente verificate
|
||||
for i = 1, #PartInfo.CombinationList do
|
||||
-- controllo che la combinazione abbia ultima fase come quella calcolata in fase di definizione combinazioni
|
||||
if PartInfo.CombinationList[i].nUnloadPos == nUnloadPos then
|
||||
local bRot90, bRot180
|
||||
local SingleCombination = {}
|
||||
SingleCombination.nRotations = 0
|
||||
SingleCombination.dTotalRating = 0
|
||||
SingleCombination.nComplete = 0
|
||||
SingleCombination.nNotComplete = 0
|
||||
SingleCombination.nNotExecute = 0
|
||||
SingleCombination.sBitIndexCombination = PartInfo.CombinationList[i].sBitIndexCombination
|
||||
SingleCombination.nUnloadPos = nUnloadPos
|
||||
-- creo liste dei proc suddivisi per rotazione
|
||||
SingleCombination.Rot0 = {}
|
||||
SingleCombination.Rot90 = {}
|
||||
SingleCombination.Rot180 = {}
|
||||
|
||||
-- ciclo su tutte le feature
|
||||
for nProc = 1, #ProcessingsOnPart.Rotation[1] do
|
||||
-- ciclo sulle rotazioni
|
||||
local nNextRot = nUnloadPos
|
||||
local ResultsList = {}
|
||||
for nRotation = 1, 3 do
|
||||
-- se rotazione abilitata da combinazione
|
||||
if string.sub( PartInfo.CombinationList[i].sBitIndexCombination, nNextRot, nNextRot) == '1' then
|
||||
-- controllo se è stata scelta una strategia
|
||||
if ProcessingsOnPart.Rotation[nNextRot][nProc].ChosenStrategy then
|
||||
local Proc = {}
|
||||
Proc.nRotation = nNextRot
|
||||
table.insert( Proc, ProcessingsOnPart.Rotation[nNextRot][nProc])
|
||||
table.insert( ResultsList, Proc)
|
||||
end
|
||||
end
|
||||
nNextRot = EgtIf( nNextRot + 1 > 4, nNextRot + 1 - 4, nNextRot + 1)
|
||||
end
|
||||
|
||||
-- se la feature può essere lavorata in almeno una rotazione
|
||||
if #ResultsList > 0 then
|
||||
local Proc, Data = GetProcBestMachRotationFromList( ResultsList)
|
||||
-- inserisco la Proc nell'apposita lista
|
||||
if Data.nIndexRotation == nUnloadPos then
|
||||
table.insert( SingleCombination.Rot0, Proc)
|
||||
elseif Data.nIndexRotation == nUnloadPos + 1 then
|
||||
table.insert( SingleCombination.Rot90, Proc)
|
||||
bRot90 = true
|
||||
else
|
||||
table.insert( SingleCombination.Rot180, Proc)
|
||||
bRot180 = true
|
||||
end
|
||||
|
||||
SingleCombination.dTotalRating = SingleCombination.dTotalRating + Data.dCompositeRating
|
||||
SingleCombination.nComplete = SingleCombination.nComplete + EgtIf( Data.bComplete, 1, 0)
|
||||
SingleCombination.nNotComplete = SingleCombination.nNotComplete + EgtIf( Data.bNotComplete, 1, 0)
|
||||
SingleCombination.nNotExecute = SingleCombination.nNotExecute + EgtIf( Data.bNotApplicable, 1, 0)
|
||||
SingleCombination.nIndexRotation = nUnloadPos
|
||||
else
|
||||
SingleCombination.nNotExecute = SingleCombination.nNotExecute + 1
|
||||
end
|
||||
end
|
||||
-- aggiungo rotazioni
|
||||
SingleCombination.nRotations = EgtIf( bRot90, 1, 0) + EgtIf( bRot180, 1, 0)
|
||||
-- aggiungo la combinazione all'elenco delle combinazioni disponibili
|
||||
table.insert( CombinationsList, SingleCombination)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- ci deve essere almeno una combinazione, altrimenti errore
|
||||
if #CombinationsList < 1 then
|
||||
error( 'UNEXPECTED ERROR: NO combinations available')
|
||||
end
|
||||
BestCombination = GetBestCombination( CombinationsList)
|
||||
|
||||
-- scrittura nel log delle combinazioni possibili
|
||||
if EgtGetDebugLevel() >= 3 then
|
||||
Logs.WriteCombinationLog( CombinationsList, BestCombination)
|
||||
end
|
||||
|
||||
local vFinalProc, nInitialPosition, bSomeFeatureDown, bSomeFeatureSide = GetProcessingListFromCombination( BestCombination)
|
||||
|
||||
return vFinalProc, nInitialPosition, bSomeFeatureDown, bSomeFeatureSide
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function BeamExec.ProcessMachinings( PROCESSINGS, PARTS)
|
||||
-- ciclo sui pezzi
|
||||
local nTotErr = 0
|
||||
local Stats = {}
|
||||
local nOrd = 1
|
||||
local ProcessCompleted = false
|
||||
local nMaxLoops = 5
|
||||
|
||||
-- TODO da rimuovere o lasciare solo per debug
|
||||
--if EgtGetDebugLevel() >= 3 then
|
||||
-- EgtStartCounter()
|
||||
--end
|
||||
-- TODO da rimuovere o lasciare solo per debug
|
||||
--if EgtGetDebugLevel() >= 3 then
|
||||
-- local timeCollect = EgtStopCounter()
|
||||
-- timeCollect = timeCollect + 0
|
||||
-- EgtOutBox( timeCollect, 'Collect calculation time')
|
||||
-- EgtStartCounter()
|
||||
--end
|
||||
-- TODO da rimuovere o lasciare solo per debug
|
||||
--if EgtGetDebugLevel() >= 3 then
|
||||
-- local timeMachining = EgtStopCounter()
|
||||
-- timeMachining = timeMachining + 0
|
||||
-- EgtOutBox( timeMachining, 'Machining calculation time')
|
||||
--end
|
||||
|
||||
local nCurrLoop = 0
|
||||
-- ciclo fino a che tutte le applicazioni delle lavorazioni sono corrette
|
||||
while not ProcessCompleted do
|
||||
-- aumento numero loop nel quale siamo
|
||||
nCurrLoop = nCurrLoop + 1
|
||||
-- ricerca strategia di lavorazione per ogni pezzo e applicazione lavorazioni
|
||||
for nPart = 1, #PARTS do
|
||||
-- calcolo della migliore strategia per ogni rotazione del pezzo
|
||||
for dRotIndex = 1, 4 do
|
||||
PROCESSINGS[nPart].Rotation[dRotIndex] = GetBestStrategy( PROCESSINGS[nPart].Rotation[dRotIndex])
|
||||
end
|
||||
|
||||
-- scrittura nel log del risultato della scelta della strategia migliore tra quelle disponibili
|
||||
if EgtGetDebugLevel() >= 3 then
|
||||
Logs.WriteFeaturesLog( PROCESSINGS[nPart], PARTS[nPart])
|
||||
end
|
||||
|
||||
-- si calcola la combinazione di lavorazione migliore
|
||||
local vProc, nInitialPosition, bSomeFeatureDown, bSomeFeatureSide = GetBestResultFromCombinationsMatrix( PROCESSINGS[nPart], PARTS[nPart])
|
||||
-- salvo sul PART la posizione di partenza che è stata scelta
|
||||
PARTS[nPart].nInitialPosition = nInitialPosition
|
||||
|
||||
-- debug
|
||||
if EgtGetDebugLevel() >= 1 then
|
||||
PrintFeatures( vProc, PARTS[nPart])
|
||||
end
|
||||
EgtOutLog( ' *** AddMachinings ***', 1)
|
||||
|
||||
-- ordino le features
|
||||
vProc = OrderFeatures( vProc)
|
||||
|
||||
-- esegue le strategie migliori che ha precedentemente scelto e salva le lavorazioni nella lista globale
|
||||
MACHININGS = CalculateMachinings( vProc, PARTS[nPart])
|
||||
|
||||
-- TODO riordinare lavorazioni ottimizzando cambio utensile/spezzone ecc..., mantenendo dipendenze definite prima
|
||||
-- ordino le lavorazioni
|
||||
-- MACHININGS = OrderMachining( MACHININGS, PARTS[nPart])
|
||||
|
||||
-- aggiungo la fase, se non è la prima
|
||||
if nOrd == 1 then
|
||||
EgtSetCurrPhase( 1)
|
||||
else
|
||||
BeamLib.AddPhaseWithRawParts( PARTS[nPart].idRaw, BeamData.ptOriXR, BeamData.dPosXR, 0)
|
||||
end
|
||||
local bAreAllMachiningApplyOk
|
||||
local sErr
|
||||
local bSplitAlreadyExecuted = false
|
||||
local bSplitExecutedOnRot = false
|
||||
local nPhase = EgtGetCurrPhase()
|
||||
local nDispId = EgtGetPhaseDisposition( nPhase)
|
||||
EgtSetInfo( nDispId, 'TYPE', 'START')
|
||||
EgtSetInfo( nDispId, 'ORD', nOrd)
|
||||
EgtOutLog( ' *** Phase=' .. tostring( nPhase) .. ' Raw=' .. tostring( PARTS[nPart].idRaw) .. ' Part=' .. tostring( PARTS[nPart].id) .. ' ***', 1)
|
||||
|
||||
-- creazione effettiva delle lavorazioni
|
||||
-- se c'è almeno una lavorazione in posizionamento con trave ribaltata
|
||||
if bSomeFeatureDown then
|
||||
local nRotation = EgtIf( nInitialPosition + 2 > 4, nInitialPosition + 2 - 4, nInitialPosition + 2)
|
||||
BeamLib.RotatePart( PARTS[nPart], nRotation)
|
||||
EgtSetInfo( nDispId, 'ROT', -2)
|
||||
bAreAllMachiningApplyOk, sErr, bSplitExecutedOnRot = MachiningLib.AddOperations( MACHININGS, PARTS[nPart], 'DOWN')
|
||||
bSplitAlreadyExecuted = bSplitAlreadyExecuted or bSplitExecutedOnRot
|
||||
end
|
||||
|
||||
-- se c'è almeno una lavorazione in posizionamento con trave ribaltata
|
||||
if bSomeFeatureSide then
|
||||
-- se ci sono state lavorazioni in rotazione precedente devo creare altra fase. Altrimenti già creata da prima
|
||||
if bSomeFeatureDown then
|
||||
BeamLib.AddPhaseWithRawParts( PARTS[nPart].idRaw, BeamData.ptOriXR, BeamData.dPosXR, 0)
|
||||
nPhase = EgtGetCurrPhase()
|
||||
nDispId = EgtGetPhaseDisposition( nPhase)
|
||||
EgtSetInfo( nDispId, 'ORD', nOrd)
|
||||
-- se c'è già stata seoparazione
|
||||
if bSplitAlreadyExecuted then
|
||||
EgtSetInfo( nDispId, 'TYPE', 'MID2')
|
||||
else
|
||||
EgtSetInfo( nDispId, 'TYPE', 'MID')
|
||||
end
|
||||
end
|
||||
local nRotation = EgtIf( nInitialPosition + 1 > 4, nInitialPosition + 1 - 4, nInitialPosition + 1)
|
||||
BeamLib.RotatePart( PARTS[nPart], nRotation)
|
||||
EgtSetInfo( nDispId, 'ROT', -1)
|
||||
bAreAllMachiningApplyOk, sErr, bSplitExecutedOnRot = MachiningLib.AddOperations( MACHININGS, PARTS[nPart], 'SIDE')
|
||||
bSplitAlreadyExecuted = bSplitAlreadyExecuted or bSplitExecutedOnRot
|
||||
end
|
||||
|
||||
-- se ci sono state lavorazioni in rotazione precedente devo creare altra fase. Altrimenti già creata da prima
|
||||
if bSomeFeatureDown or bSomeFeatureSide then
|
||||
BeamLib.AddPhaseWithRawParts( PARTS[nPart].idRaw, BeamData.ptOriXR, BeamData.dPosXR, 0)
|
||||
nPhase = EgtGetCurrPhase()
|
||||
nDispId = EgtGetPhaseDisposition( nPhase)
|
||||
EgtSetInfo( nDispId, 'ORD', nOrd)
|
||||
-- se c'è già stata seoparazione
|
||||
if bSplitAlreadyExecuted then
|
||||
EgtSetInfo( nDispId, 'TYPE', 'END2')
|
||||
else
|
||||
EgtSetInfo( nDispId, 'TYPE', 'MID')
|
||||
end
|
||||
end
|
||||
|
||||
BeamLib.RotatePart( PARTS[nPart], nInitialPosition)
|
||||
|
||||
-- aggiunta lavorazioni in ultima fase
|
||||
MachiningLib.AddOperations( MACHININGS, PARTS[nPart], 'STD')
|
||||
|
||||
EgtOutLog( ' *** End AddMachinings ***', 1)
|
||||
-- azzero lavorazioni per pezzo successivo
|
||||
MACHININGS = {}
|
||||
-- indice pezzo successivo
|
||||
nOrd = nOrd + 1
|
||||
end
|
||||
|
||||
-- ===== finiti i pezzi, si scarica il restante =====
|
||||
local idRestPart = EgtGetNextRawPart( PARTS[#PARTS].idRaw)
|
||||
if idRestPart and EgtGetRawPartBBox( idRestPart):getDimX() >= BeamData.dMinRaw then
|
||||
BeamLib.AddPhaseWithRawParts( idRestPart, BeamData.ptOriXR, BeamData.dPosXR, 0)
|
||||
local nPhase = EgtGetCurrPhase()
|
||||
local nDispId = EgtGetPhaseDisposition( nPhase)
|
||||
EgtSetInfo( nDispId, 'TYPE', 'REST')
|
||||
EgtSetInfo( nDispId, 'ORD', nOrd)
|
||||
end
|
||||
|
||||
-- Aggiornamento finale di tutto
|
||||
EgtSetCurrPhase( 1)
|
||||
local bApplOk, sApplErrors, sApplWarns = EgtApplyAllMachinings()
|
||||
-- TODO a cosa serve questo ricalcolo? Con nuovo sistema si può eliminare?
|
||||
-- eventuale ricalcolo per macchine tipo PF (ma tengo warning del primo calcolo)
|
||||
if EgtExistsInfo( EgtGetCurrMachGroup(), 'RECALC') then
|
||||
EgtOutLog( ' **** RECALC ****')
|
||||
bApplOk, sApplErrors, _ = EgtApplyAllMachinings()
|
||||
EgtRemoveInfo( EgtGetCurrMachGroup(), 'RECALC')
|
||||
end
|
||||
if not bApplOk then
|
||||
nTotErr = nTotErr + 1
|
||||
table.insert( Stats, {nErr = 1, sMsg=sApplErrors, nRot=0, idCut=0, idTask=0})
|
||||
elseif sApplWarns and #sApplWarns > 0 then
|
||||
local vLine = EgtSplitString( sApplWarns, '\r\n')
|
||||
for i = 1, #vLine do
|
||||
local nPos = vLine[i]:find( '(WRN', 1, true)
|
||||
if nPos then
|
||||
local sData = vLine[i]:sub( nPos + 1, -2)
|
||||
local vVal = EgtSplitString( sData, ',')
|
||||
local nWarn = EgtGetVal( vVal[1] or '', 'WRN', 'i')
|
||||
local nCutId = EgtGetVal( vVal[2] or '', 'CUTID', 'i')
|
||||
if nWarn and nCutId then
|
||||
table.insert( Stats, { nErr=-nWarn, sMsg=vLine[i], nRot=0, idCut=nCutId, idTask=0})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- TODO per il momento non si cicla mai una seconda volta. Controllare anche parametro modalità scelta strategia
|
||||
-- Gestione da fare completamente. La strategia che ha generato una lavorazione con errore deve essere annullata
|
||||
-- si fa un reset del MACH e poi si ritorna a inizio ciclo e si rifà tutto
|
||||
-- se i cicli superano il massimo si esce (nell'ultimo ciclo possibile si potrebbe escludere la feature e basta, anche se avesse altre strategie da provare)
|
||||
if true or nCurrLoop > nMaxLoops then
|
||||
ProcessCompleted = true
|
||||
end
|
||||
end
|
||||
|
||||
return ( nTotErr == 0), Stats
|
||||
end
|
||||
|
||||
|
||||
+126
-4
@@ -91,9 +91,8 @@ function BeamLib.AddPartEndFace( PartId, b3Solid)
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function BeamLib.AddPhaseWithRawParts( Part, OriXR, PosXR, dDeltaSucc)
|
||||
function BeamLib.AddPhaseWithRawParts( nRawId, OriXR, PosXR, dDeltaSucc)
|
||||
EgtAddPhase()
|
||||
local nRawId = Part.idRaw
|
||||
local dRawMove = 0
|
||||
while nRawId do
|
||||
EgtKeepRawPart( nRawId)
|
||||
@@ -105,6 +104,49 @@ function BeamLib.AddPhaseWithRawParts( Part, OriXR, PosXR, dDeltaSucc)
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
--- funzione che ruota il pezzo, da lanciare per creare la disposizione corretta
|
||||
function BeamLib.RotatePart( Part, nPosition)
|
||||
-- primo posizionamento
|
||||
if nPosition == 1 then
|
||||
; -- il pezzo è già in posizione
|
||||
-- rotazione 90°
|
||||
elseif nPosition == 2 then
|
||||
local dDeltaYZ = EgtGetRawPartBBox( Part.idRaw):getDimY() - EgtGetRawPartBBox( Part.idRaw):getDimZ()
|
||||
local vtMove = Vector3d( 0, dDeltaYZ / 2 * EgtIf( BeamData.RIGHT_LOAD, -1, 1), dDeltaYZ / 2)
|
||||
local bPreMove = dDeltaYZ < 0
|
||||
-- ruoto le travi della fase corrente
|
||||
local nRId = Part.idRaw
|
||||
while nRId do
|
||||
if bPreMove then EgtMoveRawPart( nRId, vtMove) end
|
||||
EgtRotateRawPart( nRId, X_AX(), EgtIf( BeamData.RIGHT_LOAD, -90, 90))
|
||||
if not bPreMove then EgtMoveRawPart( nRId, vtMove) end
|
||||
nRId = EgtGetNextRawPart( nRId)
|
||||
end
|
||||
-- rotazione 180°
|
||||
elseif nPosition == 3 then
|
||||
-- ribalto le travi della fase corrente
|
||||
local nRId = Part.idRaw
|
||||
while nRId do
|
||||
EgtRotateRawPart( nRId, X_AX(), 180)
|
||||
nRId = EgtGetNextRawPart( nRId)
|
||||
end
|
||||
-- rotazione 270°
|
||||
elseif nPosition == 4 then
|
||||
local dDeltaYZ = EgtGetRawPartBBox( Part.idRaw):getDimY() - EgtGetRawPartBBox( Part.idRaw):getDimZ()
|
||||
local vtMove = Vector3d( 0, dDeltaYZ / 2 * EgtIf( BeamData.RIGHT_LOAD, -1, 1), dDeltaYZ / 2)
|
||||
local bPreMove = dDeltaYZ < 0
|
||||
-- ruoto le travi della fase corrente
|
||||
local nRId = Part.idRaw
|
||||
while nRId do
|
||||
if bPreMove then EgtMoveRawPart( nRId, vtMove) end
|
||||
EgtRotateRawPart( nRId, X_AX(), EgtIf( BeamData.RIGHT_LOAD, 90, -90))
|
||||
if not bPreMove then EgtMoveRawPart( nRId, vtMove) end
|
||||
nRId = EgtGetNextRawPart( nRId)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function BeamLib.CreateOrEmptyAddGroup( PartId)
|
||||
-- recupero i dati del gruppo aggiuntivo
|
||||
@@ -302,9 +344,9 @@ function BeamLib.LoadCustomParametersInStrategy( CustomParameters)
|
||||
for i=1, #CustomParameters do
|
||||
if CustomParameters[i].sType == 'b' then
|
||||
Parameters[CustomParameters[i].sName] = CustomParameters[i].sValue == 'true'
|
||||
elseif CustomParameters[i].Type == 'd' then
|
||||
elseif CustomParameters[i].sType == 'd' then
|
||||
Parameters[CustomParameters[i].sName] = tonumber( CustomParameters[i].sValue)
|
||||
else -- CustomParameters.Type == 's'
|
||||
else --CustomParameters[i].sType == 's' or CustomParameters[i].sType == 'combo'
|
||||
Parameters[CustomParameters[i].sName] = CustomParameters[i].sValue
|
||||
end
|
||||
end
|
||||
@@ -351,5 +393,85 @@ function BeamLib.GetBlockedAxis( nToolIndex, sBlockedAxis, b3Raw, vtTool, vtOut)
|
||||
return ''
|
||||
end
|
||||
|
||||
---------------------------------------------------------------------
|
||||
function BeamLib.BinaryToDecimal( dNumber)
|
||||
local sNumberToConvert = tostring( dNumber)
|
||||
local dResult = 0
|
||||
local k = 0
|
||||
|
||||
for i = #sNumberToConvert, 1, -1 do
|
||||
k = k + 1
|
||||
local n = string.sub(sNumberToConvert, k, k)
|
||||
dResult = dResult + n*(2^(i-1))
|
||||
end
|
||||
|
||||
return dResult
|
||||
end
|
||||
|
||||
---------------------------------------------------------------------
|
||||
function BeamLib.DecimalToBinary( dNumber)
|
||||
local sNumberToConvert = tostring( dNumber)
|
||||
local n = sNumberToConvert
|
||||
local tmp = {}
|
||||
local sResult = ""
|
||||
|
||||
for i = sNumberToConvert, 0, -1 do
|
||||
local q = math.modf(n)
|
||||
n = n/2
|
||||
local b = q%2
|
||||
table.insert(tmp, b)
|
||||
|
||||
if (q == 1) then
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
for i = #tmp, 1, -1 do
|
||||
sResult = sResult..tmp[i]
|
||||
end
|
||||
|
||||
return tonumber( sResult)
|
||||
end
|
||||
|
||||
---------------------------------------------------------------------
|
||||
function BeamLib.CalculateStringBinaryFormat( dNumber, CharNumber)
|
||||
local NumberString = tostring( dNumber)
|
||||
while #NumberString < CharNumber do
|
||||
NumberString = '0' .. NumberString
|
||||
end
|
||||
|
||||
return NumberString
|
||||
end
|
||||
|
||||
---------------------------------------------------------------------
|
||||
--- copia una tabella lua in modo ricorsivo, ossia mantiene indipendenti anche tutte le sottotabelle
|
||||
--- ATTENZIONE: in caso di modifiche vanno gestiti anche i tipi custom; sarebbe meglio metterla nel LuaLibs
|
||||
function BeamLib.TableCopyDeep( OriginalTable)
|
||||
local CopiedTable = {}
|
||||
for key, value in pairs( OriginalTable) do
|
||||
if type( value) == "table" then
|
||||
if isBBox3d( value) then
|
||||
CopiedTable[ key] = BBox3d( value)
|
||||
elseif isColor3d( value) then
|
||||
CopiedTable[ key] = Color3d( value)
|
||||
elseif isFrame3d( value) then
|
||||
CopiedTable[ key] = Frame3d( value)
|
||||
elseif isPoint3d( value) then
|
||||
CopiedTable[ key] = Point3d( value)
|
||||
elseif isQuaternion( value) then
|
||||
CopiedTable[ key] = Quaternion( value)
|
||||
elseif isVector3d( value) then
|
||||
CopiedTable[ key] = Vector3d( value)
|
||||
else
|
||||
CopiedTable[ key] = BeamLib.TableCopyDeep( value)
|
||||
end
|
||||
else
|
||||
CopiedTable[ key] = value
|
||||
end
|
||||
end
|
||||
|
||||
return CopiedTable
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
return BeamLib
|
||||
|
||||
+22
-29
@@ -7,6 +7,7 @@ local FaceData = {}
|
||||
|
||||
-- carico librerie
|
||||
local BeamLib = require( 'BeamLib')
|
||||
local Logs = require( 'Logs')
|
||||
|
||||
|
||||
---------------------------------------------------------------------
|
||||
@@ -81,7 +82,7 @@ end
|
||||
function FaceData.GetFacesByAdjacencyNumber( Proc)
|
||||
-- se la feature ha una sola faccia, esco subito
|
||||
if Proc.nFct <= 1 then
|
||||
return
|
||||
return {}
|
||||
end
|
||||
|
||||
local FacesByAdjacencyNumber = {}
|
||||
@@ -178,16 +179,25 @@ local function GetTunnelFaces( Proc, Part)
|
||||
return TunnelAddedFaces
|
||||
end
|
||||
|
||||
-- faccia centrale, si crea larga come la parte e poi si trimma
|
||||
TunnelAddedFaces.MiddleFaceTm = {}
|
||||
TunnelAddedFaces.MiddleFaceTm.id = EgtSurfTmPlaneInBBox( nAddGrpId, ptTunnelCenter, vtTunnelDirection, Part.b3Solid, GDB_ID.ROOT)
|
||||
-- faccia centrale
|
||||
local nMiddleTmId = EgtSurfTmPlaneInBBox( nAddGrpId, ptTunnelCenter, vtTunnelDirection, Part.b3Solid, GDB_ID.ROOT)
|
||||
-- TODO se non si riesce a costruire la faccia bisogna dare errore o semplicemente non ritornarla??
|
||||
for i = 1, Proc.nFct do
|
||||
EgtCutSurfTmPlane( TunnelAddedFaces.MiddleFaceTm.id, Proc.Faces[i].ptCenter, -Proc.Faces[i].vtN, false, GDB_ID.ROOT)
|
||||
EgtCutSurfTmPlane( nMiddleTmId, Proc.Faces[i].ptCenter, -Proc.Faces[i].vtN, false, GDB_ID.ROOT)
|
||||
end
|
||||
|
||||
-- facce laterali
|
||||
local nLateralTmId = EgtCopyGlob( Proc.id, nAddGrpId) or GDB_ID.NULL
|
||||
EgtCutSurfTmPlane( nLateralTmId, ptTunnelCenter, -vtTunnelDirection, false, GDB_ID.ROOT)
|
||||
|
||||
-- unione facce
|
||||
-- TODO cambiare nome alla trimesh?? non contiene più solamente la faccia di mezzo
|
||||
TunnelAddedFaces.MiddleFaceTm = {}
|
||||
TunnelAddedFaces.MiddleFaceTm.id = EgtSurfTmBySewing( nAddGrpId, { nMiddleTmId, nLateralTmId}, true)
|
||||
|
||||
-- TODO c'è un modo più elegante per raccogliere le informazioni delle facce aggiunte
|
||||
TunnelAddedFaces.MiddleFaceTm.sType = 'Tunnel'
|
||||
TunnelAddedFaces.MiddleFaceTm.nFct = 1
|
||||
TunnelAddedFaces.MiddleFaceTm.nFct = Proc.nFct + 1
|
||||
TunnelAddedFaces.MiddleFaceTm.Faces = FaceData.GetFacesInfo( TunnelAddedFaces.MiddleFaceTm, Part)
|
||||
|
||||
return TunnelAddedFaces
|
||||
@@ -255,6 +265,7 @@ local function GetBottomFaces( Proc)
|
||||
CurrentEdge.idAdjacentFace = BottomFaces[1].Edges[i].Adj
|
||||
CurrentEdge.vtToolDirection = Vector3d( BottomFaces[1].Edges[i].Norm)
|
||||
CurrentEdge.dLength = BottomFaces[1].Edges[i].Len
|
||||
CurrentEdge.dLengthOnX = CurrentEdge.dLength * CurrentEdge.vtToolDirection:getY()
|
||||
CurrentEdge.dElevation = BottomFaces[1].Edges[i].Elev
|
||||
CurrentEdge.bIsOpen = BottomFaces[1].Edges[i].Open
|
||||
CurrentEdge.bIsStartOpen = BottomFaces[1].Edges[nPreviousEdgeIndex].Open
|
||||
@@ -340,6 +351,7 @@ local function GetLongFaces( Proc, MainFaces)
|
||||
CurrentEdge.idAdjacentFace = LongFaces[i].Edges[j].Adj
|
||||
CurrentEdge.vtToolDirection = Vector3d( LongFaces[i].Edges[j].Norm)
|
||||
CurrentEdge.dLength = LongFaces[i].Edges[j].Len
|
||||
CurrentEdge.dLengthOnX = CurrentEdge.dLength * CurrentEdge.vtToolDirection:getY()
|
||||
CurrentEdge.dElevation = LongFaces[i].Edges[j].Elev
|
||||
CurrentEdge.bIsOpen = LongFaces[i].Edges[j].Open
|
||||
CurrentEdge.bIsStartOpen = LongFaces[i].Edges[nPreviousEdgeIndex].Open
|
||||
@@ -426,6 +438,7 @@ local function GetSideFaces( Proc, MainFaces)
|
||||
CurrentEdge.idAdjacentFace = SideFaces[i].Edges[j].Adj
|
||||
CurrentEdge.vtToolDirection = Vector3d( SideFaces[i].Edges[j].Norm)
|
||||
CurrentEdge.dLength = SideFaces[i].Edges[j].Len
|
||||
CurrentEdge.dLengthOnX = CurrentEdge.dLength * CurrentEdge.vtToolDirection:getY()
|
||||
CurrentEdge.dElevation = SideFaces[i].Edges[j].Elev
|
||||
CurrentEdge.bIsOpen = SideFaces[i].Edges[j].Open
|
||||
CurrentEdge.bIsStartOpen = SideFaces[i].Edges[nPreviousEdgeIndex].Open
|
||||
@@ -475,35 +488,15 @@ function FaceData.GetMainFaces( Proc, Part)
|
||||
MainFaces.BottomFaces = GetBottomFaces( Proc)
|
||||
MainFaces.LongFaces = GetLongFaces( Proc, MainFaces)
|
||||
MainFaces.SideFaces = GetSideFaces( Proc, MainFaces)
|
||||
-- TODO funzione apposita per informazioni log?
|
||||
|
||||
-- scrivo informazioni delle facce nel log
|
||||
if EgtGetDebugLevel() >= 3 then
|
||||
if MainFaces.BottomFaces then
|
||||
for i = 1, #MainFaces.BottomFaces do
|
||||
EgtOutLog( 'Bottom Face : ' .. MainFaces.BottomFaces[i].id)
|
||||
end
|
||||
-- colore differente per la faccia di fondo principale
|
||||
EgtSurfTmSetFaceColor( Proc.id, MainFaces.BottomFaces[1].id, 1)
|
||||
end
|
||||
if MainFaces.LongFaces then
|
||||
for i = 1, #MainFaces.LongFaces do
|
||||
EgtOutLog( 'Long Face : ' .. MainFaces.LongFaces[i].id)
|
||||
end
|
||||
end
|
||||
if MainFaces.SideFaces then
|
||||
for i = 1, #MainFaces.SideFaces do
|
||||
EgtOutLog( 'Side Face : ' .. MainFaces.SideFaces[i].id)
|
||||
end
|
||||
end
|
||||
if MainFaces.TunnelAddedFaces then
|
||||
EgtOutLog( 'Middle Face (Trimesh): ' .. MainFaces.TunnelAddedFaces.MiddleFaceTm.id)
|
||||
end
|
||||
Logs.WriteMainFacesLog( Proc, MainFaces)
|
||||
end
|
||||
else
|
||||
EgtOutLog( '---MainFaces NOT NEEDED---')
|
||||
end
|
||||
|
||||
|
||||
|
||||
EgtOutLog( '---MainFaces END---')
|
||||
return MainFaces
|
||||
end
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
-- FeatureData.lua by Egalware s.r.l. 2024/04/02
|
||||
-- FeatureLib.lua by Egalware s.r.l. 2024/04/02
|
||||
-- Libreria lettura o calcolo dati e proprietà della feature
|
||||
-- 2024/04/02 PRIMA VERSIONE CALCOLO LAVORAZIONI CON STRATEGIE
|
||||
|
||||
-- Tabella per definizione modulo
|
||||
local FeatureData = {}
|
||||
local FeatureLib = {}
|
||||
|
||||
-- Carico i dati globali
|
||||
local BeamData = require( 'BeamData')
|
||||
@@ -16,10 +16,14 @@ local ID = require( 'Identity')
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- recupero topologia della feature
|
||||
function FeatureData.NeedTopologyFeature( Proc)
|
||||
function FeatureLib.NeedTopologyFeature( Proc)
|
||||
-- features tipo taglio
|
||||
if ID.IsCut( Proc) then
|
||||
return true
|
||||
elseif ID.IsHeadCut( Proc) then
|
||||
return true
|
||||
elseif ID.IsSplitCut( Proc) then
|
||||
return true
|
||||
elseif ID.IsDoubleCut( Proc) then
|
||||
return true
|
||||
elseif ID.IsSawCut( Proc) then
|
||||
@@ -130,7 +134,7 @@ end
|
||||
|
||||
---------------------------------------------------------------------
|
||||
-- recupera topologia feature
|
||||
function FeatureData.ClassifyTopology( Proc, Part)
|
||||
function FeatureLib.ClassifyTopology( Proc, Part)
|
||||
local FeatureTopology = {}
|
||||
|
||||
if not Proc.AffectedFaces then Proc.AffectedFaces = BeamLib.GetAffectedFaces( Proc, Part) end
|
||||
@@ -209,7 +213,7 @@ end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- Recupero dati foro e adattamento se speciale
|
||||
function FeatureData.GetDrillingData( Proc)
|
||||
function FeatureLib.GetDrillingData( Proc)
|
||||
local AuxId = EgtGetInfo( Proc.id, 'AUXID', 'i')
|
||||
|
||||
-- verifico se foro da adattare
|
||||
@@ -230,7 +234,7 @@ end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- funzione che restituisce indice di completamento in base alla percentuale di volume lavorato
|
||||
function FeatureData.GetFeatureCompletionIndex( dCompletionPercentage)
|
||||
function FeatureLib.GetFeatureCompletionIndex( dCompletionPercentage)
|
||||
-- indice di completamento
|
||||
local nCompletionIndex = 0
|
||||
|
||||
@@ -253,7 +257,7 @@ end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- funzione che restituisce qualità della lavorazione in base agli utensili utilizzati
|
||||
function FeatureData.GetFeatureQuality( sTypeTools)
|
||||
function FeatureLib.GetFeatureQuality( sTypeTools)
|
||||
local nQuality = 5
|
||||
local TypeTools = EgtSplitString( sTypeTools)
|
||||
|
||||
@@ -271,12 +275,126 @@ function FeatureData.GetFeatureQuality( sTypeTools)
|
||||
end
|
||||
-- se si utilizzano più utensili si perde in qualità
|
||||
if #TypeTools > 1 then
|
||||
nQuality = nQuality - 1
|
||||
nQuality = max( nQuality - 1, 0.5)
|
||||
end
|
||||
|
||||
return nQuality
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- funzione che calcola il 'CompositeRating' di ogni strategia
|
||||
function FeatureLib.CalculateCompositeRating( StrategyResult)
|
||||
-- se ho tutti i dati che mi servono calcolo il rating della strategia applicato alla feature
|
||||
if StrategyResult and StrategyResult.nQuality and StrategyResult.nCompletionIndex and StrategyResult.dMRR then
|
||||
StrategyResult.dCompositeRating = ceil( StrategyResult.nQuality * StrategyResult.nCompletionIndex * StrategyResult.dMRR)
|
||||
else
|
||||
StrategyResult.dCompositeRating = 0
|
||||
end
|
||||
|
||||
return FeatureData
|
||||
return StrategyResult
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function FeatureLib.MachiningNeedsSplitting( dMachiningLengthOnX, Part, OptionalParameters)
|
||||
local bMachiningNeedsSplitting
|
||||
|
||||
-- parametri opzionali
|
||||
if not OptionalParameters then
|
||||
OptionalParameters = {}
|
||||
end
|
||||
local dMaxSegmentLength = OptionalParameters.dMaxSegmentLength or BeamData.LONGCUT_MAXLEN
|
||||
|
||||
bMachiningNeedsSplitting = ( dMachiningLengthOnX > dMaxSegmentLength + 10 * GEO.EPS_SMALL)
|
||||
or ( dMachiningLengthOnX > 0.7 * Part.b3Solid:getDimX() + 10 * GEO.EPS_SMALL)
|
||||
|
||||
return bMachiningNeedsSplitting
|
||||
end
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function FeatureLib.GetFeatureSplittingPoints( Proc, Part, OptionalParameters)
|
||||
local vFeatureSplittingPoints = {}
|
||||
local bFeatureStartsOnEdgeLeft = false
|
||||
local bFeatureStartsOnEdgeRight = false
|
||||
local dSplitXLeft = Proc.b3Box:getMin():getX()
|
||||
local dSplitXRight = Proc.b3Box:getMax():getX()
|
||||
local dFeatureCentralLength = Proc.b3Box:getDimX()
|
||||
|
||||
-- parametri opzionali
|
||||
if not OptionalParameters then
|
||||
OptionalParameters = {}
|
||||
end
|
||||
local dMaxSegmentLength = OptionalParameters.dMaxSegmentLength or BeamData.LONGCUT_MAXLEN
|
||||
local dMaxSegmentLengthOnEdges = OptionalParameters.dMaxSegmentLengthOnEdges or BeamData.LONGCUT_ENDLEN
|
||||
local dMinSegmentLength = OptionalParameters.dMinSegmentLength or dMaxSegmentLengthOnEdges / 2
|
||||
local dToolOverlapBetweenSegments = OptionalParameters.dToolOverlapBetweenSegments or BeamData.MILL_OVERLAP
|
||||
|
||||
-- verifica spezzatura necessaria
|
||||
if not FeatureLib.MachiningNeedsSplitting( Proc.b3Box:getDimX(), Part) then
|
||||
return {}
|
||||
end
|
||||
|
||||
-- verifica se necessari spezzoni differenti sugli estremi
|
||||
if Proc.b3Box:getMin():getX() < Part.b3Solid:getMin():getX() + dMaxSegmentLengthOnEdges - 10 * GEO.EPS_SMALL then
|
||||
bFeatureStartsOnEdgeLeft = true
|
||||
end
|
||||
if Proc.b3Box:getMax():getX() > Part.b3Solid:getMax():getX() - dMaxSegmentLengthOnEdges + 10 * GEO.EPS_SMALL then
|
||||
bFeatureStartsOnEdgeRight = true
|
||||
end
|
||||
|
||||
-- calcolo punto estremo sinistro
|
||||
local ptSplitXLeft
|
||||
if bFeatureStartsOnEdgeLeft then
|
||||
-- decido punto spezzatura verso la coda
|
||||
if Proc.b3Box:getDimX() > dMaxSegmentLengthOnEdges * 2 then
|
||||
dSplitXLeft = max( Part.b3Solid:getMin():getX() + dMaxSegmentLengthOnEdges, Proc.b3Box:getMin():getX() + dMinSegmentLength)
|
||||
else
|
||||
-- se pezzo abbastanza piccolo, spezzo in mezzo al 'pezzo + grezzo restante'
|
||||
if Part.dRestLength + Part.b3Solid:getDimX() < BeamData.dMinRaw * 1.5 then
|
||||
dSplitXLeft = Part.b3Solid:getMax():getX() - ( ( Part.dRestLength + Part.b3Solid:getDimX()) / 2)
|
||||
else
|
||||
dSplitXLeft = max( Proc.b3Box:getMin():getX() + ( BeamData.dMinRaw)/2 + 150, Part.b3Solid:getMax():getX() - dMaxSegmentLengthOnEdges)
|
||||
end
|
||||
end
|
||||
dFeatureCentralLength = abs( dSplitXRight - dSplitXLeft)
|
||||
ptSplitXLeft = Point3d( dSplitXLeft, 0, 0)
|
||||
end
|
||||
|
||||
-- calcolo punto estremo destro
|
||||
local ptSplitXRight
|
||||
if bFeatureStartsOnEdgeRight then
|
||||
dSplitXRight = min( ( Proc.b3Box:getMax():getX() - dMinSegmentLength), Part.b3Solid:getMax():getX() - dMaxSegmentLengthOnEdges)
|
||||
if dSplitXRight - dSplitXLeft < 500 * GEO.EPS_SMALL then
|
||||
dSplitXRight = dSplitXLeft - dToolOverlapBetweenSegments
|
||||
dFeatureCentralLength = 0
|
||||
else
|
||||
dFeatureCentralLength = dSplitXRight - dSplitXLeft
|
||||
end
|
||||
ptSplitXRight = Point3d( dSplitXRight, 0, 0)
|
||||
end
|
||||
|
||||
-- aggiungo eventuale punto estremo destro
|
||||
if bFeatureStartsOnEdgeRight then
|
||||
table.insert( vFeatureSplittingPoints, ptSplitXRight)
|
||||
end
|
||||
|
||||
-- aggiungo punti centrali della feature
|
||||
if dFeatureCentralLength > 0 then
|
||||
local nSplitParts = max( ceil( dFeatureCentralLength / dMaxSegmentLength + 10 * GEO.EPS_SMALL), 1)
|
||||
local dSplitPartsLen = dFeatureCentralLength / nSplitParts
|
||||
for i = 1, ( nSplitParts - 1) do
|
||||
local ptOn
|
||||
local dCurrentPointX = dSplitXRight - i * dSplitPartsLen
|
||||
ptOn = Point3d( dCurrentPointX, 0, 0)
|
||||
table.insert( vFeatureSplittingPoints, ptOn)
|
||||
end
|
||||
end
|
||||
|
||||
-- aggiungo eventuale punto estemo sinistro
|
||||
if bFeatureStartsOnEdgeLeft then
|
||||
table.insert( vFeatureSplittingPoints, ptSplitXLeft)
|
||||
end
|
||||
|
||||
return vFeatureSplittingPoints
|
||||
end
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
|
||||
return FeatureLib
|
||||
@@ -0,0 +1,213 @@
|
||||
-- Logs.lua by Egalware s.r.l. 2024/11/20
|
||||
-- Libreria per logs vari
|
||||
|
||||
-- Tabella per definizione modulo
|
||||
local Logs = {}
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function Logs.WriteFeaturesLog( ProcessingsOnPart, PartInfo)
|
||||
EgtOutLog( ' === === === === === === === === === === FEATURES STRATEGIES === === === === === === === === === === === ===')
|
||||
EgtOutLog( ' Feature ID | BTL POSITION | 90 ROTATION | 180 ROTATION | 270 ROTATION |')
|
||||
EgtOutLog( '----------------------------------------------------------------------------------------------------------')
|
||||
|
||||
local nProcessingsNumber
|
||||
local nFirstAvailableRotation
|
||||
-- ricerco prima rotazione effettivamente calcolata. In genere è sempre la prima
|
||||
for i = 1, 4 do
|
||||
if PartInfo.CombinationList.Rotations[i] == 1 then
|
||||
nProcessingsNumber = #ProcessingsOnPart.Rotation[i]
|
||||
nFirstAvailableRotation = i
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
-- per ogni feature
|
||||
for ProcLog = 1, nProcessingsNumber do
|
||||
-- ricavo il massimo numero di strategie per feature
|
||||
local nMaxStrategiesPerFeature = 0
|
||||
for nRotLog = 1, 4 do
|
||||
if PartInfo.CombinationList.Rotations[nRotLog] == 1 and ProcessingsOnPart.Rotation[nRotLog][ProcLog].AvailableStrategies then
|
||||
nMaxStrategiesPerFeature = max( nMaxStrategiesPerFeature, #ProcessingsOnPart.Rotation[nRotLog][ProcLog].AvailableStrategies)
|
||||
end
|
||||
end
|
||||
|
||||
-- ciclo su tutte le strategie
|
||||
for nCountStrategies = 1, nMaxStrategiesPerFeature do
|
||||
local sLogLine = ''
|
||||
-- al primo ciclo scrivo ID feature
|
||||
if nCountStrategies == 1 then
|
||||
sLogLine = ' ' .. tostring( ProcessingsOnPart.Rotation[nFirstAvailableRotation][ProcLog].id)
|
||||
while string.len( sLogLine) <= 20 do
|
||||
sLogLine = sLogLine .. ' '
|
||||
end
|
||||
sLogLine = sLogLine .. '|'
|
||||
else
|
||||
sLogLine = ' |'
|
||||
end
|
||||
|
||||
for nRotLog = 1, 4 do
|
||||
-- se rotazione abilitata
|
||||
if PartInfo.CombinationList.Rotations[nRotLog] == 1 then
|
||||
-- se ci sono strategie
|
||||
if ProcessingsOnPart.Rotation[nRotLog][ProcLog].AvailableStrategies and ProcessingsOnPart.Rotation[nRotLog][ProcLog].AvailableStrategies[nCountStrategies] then
|
||||
-- se la strategia è stat processata e ha un risultato
|
||||
if ProcessingsOnPart.Rotation[nRotLog][ProcLog].AvailableStrategies[nCountStrategies].Result then
|
||||
-- leggo lo stato della strategia per aggiungere un suffisso
|
||||
local sStatusStrategy = ' '
|
||||
if not ProcessingsOnPart.Rotation[nRotLog][ProcLog].AvailableStrategies[nCountStrategies].Result.sStatus or
|
||||
ProcessingsOnPart.Rotation[nRotLog][ProcLog].AvailableStrategies[nCountStrategies].Result.sStatus == 'Not-Applicable' then
|
||||
sStatusStrategy = 'N'
|
||||
elseif ProcessingsOnPart.Rotation[nRotLog][ProcLog].AvailableStrategies[nCountStrategies].Result.sStatus == 'Completed' then
|
||||
sStatusStrategy = 'C'
|
||||
elseif ProcessingsOnPart.Rotation[nRotLog][ProcLog].AvailableStrategies[nCountStrategies].Result.sStatus == 'Not-Completed' then
|
||||
sStatusStrategy = 'P'
|
||||
end
|
||||
-- se c'è una chosen strategy, si aggiunge prefisso '*' per indicare nel log qual è la strategia che è stata scelta
|
||||
local nIndexBestStrategy = ProcessingsOnPart.Rotation[nRotLog][ProcLog].nIndexBestStrategy or 0
|
||||
local sLogLineProc = EgtIf( nIndexBestStrategy == nCountStrategies, '*', '') ..
|
||||
tostring( ProcessingsOnPart.Rotation[nRotLog][ProcLog].AvailableStrategies[nCountStrategies].Result.dCompositeRating) ..' (' ..
|
||||
tostring( ProcessingsOnPart.Rotation[nRotLog][ProcLog].AvailableStrategies[nCountStrategies].sStrategyId) .. ')' ..
|
||||
sStatusStrategy .. ' |'
|
||||
while string.len( sLogLineProc) <= 20 do
|
||||
sLogLineProc = ' ' .. sLogLineProc
|
||||
end
|
||||
sLogLine = sLogLine .. sLogLineProc
|
||||
else
|
||||
sLogLine = sLogLine .. ' 0 (STR----)- |'
|
||||
end
|
||||
else
|
||||
sLogLine = sLogLine .. ' |'
|
||||
end
|
||||
-- rotazione non presa in considerazione
|
||||
else
|
||||
if nCountStrategies == 1 then
|
||||
sLogLine = sLogLine .. ' ---------- |'
|
||||
else
|
||||
sLogLine = sLogLine .. ' |'
|
||||
end
|
||||
end
|
||||
end
|
||||
EgtOutLog( sLogLine)
|
||||
end
|
||||
|
||||
end
|
||||
EgtOutLog( '----------------------------------------------------------------------------------------------------------')
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function Logs.WriteMatrixLog( ProcessingsOnPart, PartInfo)
|
||||
EgtOutLog( ' === === === === === === === === === === ROTATION MATRIX === === === === === === === === === === === === ===')
|
||||
EgtOutLog( ' Feature ID | BTL POSITION | 90 ROTATION | 180 ROTATION | 270 ROTATION |')
|
||||
EgtOutLog( '----------------------------------------------------------------------------------------------------------')
|
||||
|
||||
local nProcessingsNumber
|
||||
local nFirstAvailableRotation
|
||||
-- ricerco prima rotazione effettivamente calcolata. In genere è sempre la prima
|
||||
for i = 1, 4 do
|
||||
if PartInfo.CombinationList.Rotations[i] == 1 then
|
||||
nProcessingsNumber = #ProcessingsOnPart.Rotation[i]
|
||||
nFirstAvailableRotation = i
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
for ProcLog = 1, nProcessingsNumber do
|
||||
local sLogLine = ' ' .. tostring( ProcessingsOnPart.Rotation[nFirstAvailableRotation][ProcLog].id)
|
||||
while string.len( sLogLine) <= 20 do
|
||||
sLogLine = sLogLine .. ' '
|
||||
end
|
||||
sLogLine = sLogLine .. '|'
|
||||
for nRotLog = 1, 4 do
|
||||
if PartInfo.CombinationList.Rotations[nRotLog] == 1 then
|
||||
if ProcessingsOnPart.Rotation[nRotLog][ProcLog].ChosenStrategy then
|
||||
local sStatusStrategy = EgtIf( ProcessingsOnPart.Rotation[nRotLog][ProcLog].ChosenStrategy.Result.sStatus == 'Completed', 'C', 'P')
|
||||
local sLogLineProc = tostring( ProcessingsOnPart.Rotation[nRotLog][ProcLog].ChosenStrategy.Result.dCompositeRating) ..
|
||||
' (' .. tostring( ProcessingsOnPart.Rotation[nRotLog][ProcLog].ChosenStrategy.sStrategyId) .. ')' .. sStatusStrategy .. ' |'
|
||||
while string.len( sLogLineProc) <= 20 do
|
||||
sLogLineProc = ' ' .. sLogLineProc
|
||||
end
|
||||
sLogLine = sLogLine .. sLogLineProc
|
||||
else
|
||||
sLogLine = sLogLine .. ' 0 (STR----)- |'
|
||||
end
|
||||
else
|
||||
sLogLine = sLogLine .. ' ---------- |'
|
||||
end
|
||||
end
|
||||
EgtOutLog( sLogLine)
|
||||
end
|
||||
EgtOutLog( '----------------------------------------------------------------------------------------------------------')
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function Logs.WriteCombinationLog( CombinationsList, BestCombination)
|
||||
EgtOutLog( ' === === === === === === === === === === COMBINATIONS === === === === === === ')
|
||||
EgtOutLog( ' COMBI (UNL) | RATING | COMPLETE | NO COMPL | NO EXEC | ROTATE |')
|
||||
EgtOutLog( '---------------------------------------------------------------------------')
|
||||
|
||||
for CombiLog = 1, #CombinationsList do
|
||||
local sLogLine = ' ' .. CombinationsList[CombiLog].sBitIndexCombination .. ' (' .. CombinationsList[CombiLog].nUnloadPos .. ') |'
|
||||
-- rating
|
||||
local sOtherField = tostring( CombinationsList[CombiLog].dTotalRating) .. ' |'
|
||||
while string.len( sOtherField) <= 11 do
|
||||
sOtherField = ' ' .. sOtherField
|
||||
end
|
||||
sLogLine = sLogLine .. sOtherField
|
||||
-- completed
|
||||
sOtherField = tostring( CombinationsList[CombiLog].nComplete) .. ' |'
|
||||
while string.len( sOtherField) <= 11 do
|
||||
sOtherField = ' ' .. sOtherField
|
||||
end
|
||||
sLogLine = sLogLine .. sOtherField
|
||||
-- not completed
|
||||
sOtherField = tostring( CombinationsList[CombiLog].nNotComplete) .. ' |'
|
||||
while string.len( sOtherField) <= 11 do
|
||||
sOtherField = ' ' .. sOtherField
|
||||
end
|
||||
sLogLine = sLogLine .. sOtherField
|
||||
-- not executed
|
||||
sOtherField = tostring( CombinationsList[CombiLog].nNotExecute) .. ' |'
|
||||
while string.len( sOtherField) <= 11 do
|
||||
sOtherField = ' ' .. sOtherField
|
||||
end
|
||||
sLogLine = sLogLine .. sOtherField
|
||||
-- rotations
|
||||
sOtherField = tostring( CombinationsList[CombiLog].nRotations) .. ' |'
|
||||
while string.len( sOtherField) <= 11 do
|
||||
sOtherField = ' ' .. sOtherField
|
||||
end
|
||||
sLogLine = sLogLine .. sOtherField
|
||||
|
||||
EgtOutLog( sLogLine)
|
||||
end
|
||||
EgtOutLog( '---------------------------------------------------------------------------')
|
||||
EgtOutLog( ' BEST ROTATION : ' .. BestCombination.sBitIndexCombination .. ' (' .. BestCombination.nUnloadPos .. ')')
|
||||
EgtOutLog( '---------------------------')
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function Logs.WriteMainFacesLog( Proc, MainFaces)
|
||||
if MainFaces.BottomFaces then
|
||||
for i = 1, #MainFaces.BottomFaces do
|
||||
EgtOutLog( 'Bottom Face : ' .. MainFaces.BottomFaces[i].id)
|
||||
end
|
||||
-- colore differente per la faccia di fondo principale
|
||||
EgtSurfTmSetFaceColor( Proc.id, MainFaces.BottomFaces[1].id, 1)
|
||||
end
|
||||
if MainFaces.LongFaces then
|
||||
for i = 1, #MainFaces.LongFaces do
|
||||
EgtOutLog( 'Long Face : ' .. MainFaces.LongFaces[i].id)
|
||||
end
|
||||
end
|
||||
if MainFaces.SideFaces then
|
||||
for i = 1, #MainFaces.SideFaces do
|
||||
EgtOutLog( 'Side Face : ' .. MainFaces.SideFaces[i].id)
|
||||
end
|
||||
end
|
||||
if MainFaces.TunnelAddedFaces then
|
||||
EgtOutLog( 'Middle Face (Trimesh): ' .. MainFaces.TunnelAddedFaces.MiddleFaceTm.id)
|
||||
end
|
||||
end
|
||||
---------------------------------------------------------------------
|
||||
|
||||
return Logs
|
||||
+281
-114
@@ -10,6 +10,8 @@ require( 'EgtBase')
|
||||
|
||||
-- Carico i dati globali
|
||||
local BeamData = require( 'BeamData')
|
||||
local BeamLib = require( 'BeamLib')
|
||||
local FeatureLib = require( 'FeatureLib')
|
||||
|
||||
EgtOutLog( ' MachiningLib started', 1)
|
||||
|
||||
@@ -58,11 +60,40 @@ local function GetToolEntryAngle( Proc, vtTool)
|
||||
Angle.dTan = dTanAngle
|
||||
|
||||
return Angle
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function MachiningLib.StartsLeftSide( Machining)
|
||||
local bStartsLeftSide = ( Machining.vtEdgeDirection:getX() > 10 * GEO.EPS_SMALL and not Machining.bInvert)
|
||||
or ( not( Machining.vtEdgeDirection:getX() > 10 * GEO.EPS_SMALL) and Machining.bInvert)
|
||||
|
||||
return bStartsLeftSide
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- TODO valutare se c'è un modo più preciso di prevedere i casi in cui le lavorazioni dopo separazione sono da saltare
|
||||
function MachiningLib.CanMoveAfterSplitcut( dLengthOnX, Part)
|
||||
local bCanMoveAfterSplitcut = ( Part.dLength > BeamData.dMinRaw + 10 * GEO.EPS_SMALL)
|
||||
and ( dLengthOnX < 0.7 * Part.dLength - 10 * GEO.EPS_SMALL)
|
||||
|
||||
return bCanMoveAfterSplitcut
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function MachiningLib.CanExtendAfterTail( sCanDamageNextPiece, Part)
|
||||
local bCanExtendAfterTail = false
|
||||
|
||||
if sCanDamageNextPiece == 'ALWAYS' then
|
||||
bCanExtendAfterTail = true
|
||||
elseif sCanDamageNextPiece == 'ONLY_IF_RAWPART' then
|
||||
bCanExtendAfterTail = Part.bIsLastPart
|
||||
end
|
||||
|
||||
return bCanExtendAfterTail
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function MachiningLib.GetMachiningSteps( dMachiningDepth, dStep)
|
||||
|
||||
local MachiningSteps = {}
|
||||
MachiningSteps.dStep = 0
|
||||
MachiningSteps.nCount = ceil( ( dMachiningDepth - 10 * GEO.EPS_SMALL) / dStep)
|
||||
@@ -73,6 +104,83 @@ function MachiningLib.GetMachiningSteps( dMachiningDepth, dStep)
|
||||
return MachiningSteps
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function MachiningLib.GetSplitMachinings( Machinings, vSplittingPoints, Part )
|
||||
for i = #Machinings, 1, -1 do
|
||||
local nParts = #vSplittingPoints + 1
|
||||
local dEdgeMaxX = Machinings[i].ptEdge1:getX()
|
||||
local dEdgeMinX = Machinings[i].ptEdge2:getX()
|
||||
if Machinings[i].ptEdge1:getX() < Machinings[i].ptEdge2:getX() - 10 * GEO.EPS_SMALL then
|
||||
dEdgeMaxX = Machinings[i].ptEdge2:getX()
|
||||
dEdgeMinX = Machinings[i].ptEdge1:getX()
|
||||
end
|
||||
local dOriginalStartAddLength = Machinings[i].LeadIn.dStartAddLength
|
||||
local dOriginalEndAddLength = Machinings[i].LeadOut.dEndAddLength
|
||||
if FeatureLib.MachiningNeedsSplitting( Machinings[i].dLengthOnX, Part) then
|
||||
local nCurrentMachiningIndex = i
|
||||
-- lo spezzone attivo è quello precedente al punto di spezzatura corrente
|
||||
for j = 1, nParts do
|
||||
-- check ultimo segmento della lavorazione (NON della feature)
|
||||
local bIsLastSegment = ( nParts == 1)
|
||||
or ( ( ( j ~= 1) and vSplittingPoints[j - 1]:getX() > dEdgeMinX + 10 * GEO.EPS_SMALL)
|
||||
and ( j == nParts or vSplittingPoints[j]:getX() < dEdgeMinX + 10 * GEO.EPS_SMALL))
|
||||
-- se non è l'ultimo segmento della lavorazione, il punto di spezzatura deve essere all'interno del lato che si sta lavorando
|
||||
if ( j ~= nParts and ( vSplittingPoints[j]:getX() > dEdgeMinX + 10 * GEO.EPS_SMALL and vSplittingPoints[j]:getX() < dEdgeMaxX - 10 * GEO.EPS_SMALL))
|
||||
or bIsLastSegment then
|
||||
if j > 1 then
|
||||
nCurrentMachiningIndex = nCurrentMachiningIndex + 1
|
||||
table.insert( Machinings, nCurrentMachiningIndex, BeamLib.TableCopyDeep( Machinings[i]))
|
||||
end
|
||||
local dStartAddLength = dOriginalStartAddLength
|
||||
local dEndAddLength = dOriginalEndAddLength
|
||||
if MachiningLib.StartsLeftSide( Machinings[i]) then
|
||||
dStartAddLength, dEndAddLength = dEndAddLength, dStartAddLength
|
||||
end
|
||||
if j == 1 then
|
||||
dEndAddLength = - ( vSplittingPoints[j]:getX() - dEdgeMinX) + BeamData.MILL_OVERLAP
|
||||
elseif j == nParts then
|
||||
dStartAddLength = - ( dEdgeMaxX - vSplittingPoints[j - 1]:getX()) + BeamData.MILL_OVERLAP
|
||||
else
|
||||
dStartAddLength = - ( dEdgeMaxX - vSplittingPoints[j - 1]:getX()) + BeamData.MILL_OVERLAP
|
||||
dEndAddLength = - ( vSplittingPoints[j]:getX() - dEdgeMinX) + BeamData.MILL_OVERLAP
|
||||
end
|
||||
if MachiningLib.StartsLeftSide( Machinings[nCurrentMachiningIndex]) then
|
||||
dStartAddLength, dEndAddLength = dEndAddLength, dStartAddLength
|
||||
end
|
||||
|
||||
Machinings[nCurrentMachiningIndex].LeadIn.dStartAddLength = dStartAddLength
|
||||
Machinings[nCurrentMachiningIndex].LeadOut.dEndAddLength = dEndAddLength
|
||||
end
|
||||
if not bIsLastSegment then
|
||||
Machinings[nCurrentMachiningIndex].bMoveAfterSplitcut = false
|
||||
end
|
||||
Machinings[nCurrentMachiningIndex].nSegment = j
|
||||
end
|
||||
-- anche le lavorazioni non splittate necessitano del segmento assegnato
|
||||
else
|
||||
local dRightAddLength = dOriginalStartAddLength
|
||||
local dLeftAddLength = dOriginalEndAddLength
|
||||
if MachiningLib.StartsLeftSide( Machinings[i]) then
|
||||
dRightAddLength, dLeftAddLength = dLeftAddLength, dRightAddLength
|
||||
end
|
||||
for j = 1, nParts do
|
||||
local dNextSplitX = dEdgeMinX
|
||||
local dPreviousSplitX = dEdgeMaxX
|
||||
if j ~= 1 then
|
||||
dPreviousSplitX = vSplittingPoints[j - 1]:getX()
|
||||
elseif j ~= nParts then
|
||||
dNextSplitX = vSplittingPoints[j]:getX()
|
||||
end
|
||||
if ( dEdgeMinX - dLeftAddLength) > dNextSplitX - 10 * GEO.EPS_SMALL and ( dEdgeMaxX + dRightAddLength) < dPreviousSplitX + 10 * GEO.EPS_SMALL then
|
||||
Machinings[i].nSegment = j
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return Machinings
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- funzione per cercare utensile tipo FRESA con certe caratteristiche
|
||||
function MachiningLib.FindMill( Proc, ToolSearchParameters)
|
||||
@@ -206,8 +314,14 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters)
|
||||
end
|
||||
|
||||
if bIsToolCompatible then
|
||||
nBestToolIndex = i
|
||||
break
|
||||
if not nBestToolIndex then
|
||||
nBestToolIndex = i
|
||||
else
|
||||
-- prediligo utensile per tagli lunghi, se richiesto
|
||||
if ToolSearchParameters.bForceLongcutBlade and not TOOLS[nBestToolIndex].bIsUsedForLongCut and TOOLS[i].bIsUsedForLongCut then
|
||||
nBestToolIndex = i
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -307,27 +421,27 @@ function MachiningLib.AddNewMachining( ProcToAdd, MachiningToAdd, AuxiliaryDataT
|
||||
return false
|
||||
end
|
||||
|
||||
-- Drilling
|
||||
if MachiningToAdd.nType == MCH_MY.DRILLING then
|
||||
MachiningToAdd.sTypeName = 'Drill_'
|
||||
-- Milling
|
||||
elseif MachiningToAdd.nType == MCH_MY.MILLING then
|
||||
-- se utensile lama
|
||||
if TOOLS[MachiningToAdd.nToolIndex].sFamily == 'SAWBLADE' then
|
||||
MachiningToAdd.sTypeName = 'Cut_'
|
||||
else
|
||||
MachiningToAdd.sTypeName = 'Mill_'
|
||||
end
|
||||
-- Pocketing
|
||||
elseif MachiningToAdd.nType == MCH_MY.POCKETING then
|
||||
MachiningToAdd.sTypeName = 'Pocket_'
|
||||
-- Mortising
|
||||
elseif MachiningToAdd.nType == MCH_MY.MORTISING then
|
||||
MachiningToAdd.sTypeName = 'ChSaw_'
|
||||
end
|
||||
-- se nome non definito, assegno alla lavorazioen un nome standard
|
||||
if not MachiningToAdd.sOperationName then
|
||||
MachiningToAdd.sOperationName = MachiningToAdd.sTypeName .. ( EgtGetName( ProcToAdd.id) or tostring( ProcToAdd.id)) .. '_' .. tostring( MachiningToAdd.Geometry[1][2])
|
||||
-- Drilling
|
||||
if MachiningToAdd.nType == MCH_MY.DRILLING then
|
||||
MachiningToAdd.sTypeName = 'Drill_'
|
||||
-- Milling
|
||||
elseif MachiningToAdd.nType == MCH_MY.MILLING then
|
||||
-- se utensile lama
|
||||
if TOOLS[MachiningToAdd.nToolIndex].sFamily == 'SAWBLADE' then
|
||||
MachiningToAdd.sTypeName = 'Cut_'
|
||||
else
|
||||
MachiningToAdd.sTypeName = 'Mill_'
|
||||
end
|
||||
-- Pocketing
|
||||
elseif MachiningToAdd.nType == MCH_MY.POCKETING then
|
||||
MachiningToAdd.sTypeName = 'Pocket_'
|
||||
-- Mortising
|
||||
elseif MachiningToAdd.nType == MCH_MY.MORTISING then
|
||||
MachiningToAdd.sTypeName = 'ChSaw_'
|
||||
end
|
||||
MachiningToAdd.sOperationName = MachiningToAdd.sTypeName .. ( EgtGetName( ProcToAdd.id) or tostring( ProcToAdd.id)) -- .. '_' .. tostring( MachiningToAdd.Geometry)
|
||||
end
|
||||
if not MachiningToAdd.sToolName then
|
||||
MachiningToAdd.sToolName = TOOLS[MachiningToAdd.nToolIndex].sName
|
||||
@@ -337,15 +451,17 @@ function MachiningLib.AddNewMachining( ProcToAdd, MachiningToAdd, AuxiliaryDataT
|
||||
Machining.Machining = MachiningToAdd
|
||||
Machining.AuxiliaryData = AuxiliaryDataToAdd or {}
|
||||
table.insert( MACHININGS, Machining)
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- funzione per aggiungere una nuova lavorazione
|
||||
function MachiningLib.AddOperations( vProc, Part)
|
||||
function MachiningLib.AddOperations( vProc, Part, sRotation)
|
||||
local nErr
|
||||
local sErr = ''
|
||||
local bAreAllMachiningApplyOk = true
|
||||
local bSplitExecuted = false
|
||||
|
||||
-- parametri generali lavorazione
|
||||
local MachiningParameters = {
|
||||
@@ -401,7 +517,13 @@ function MachiningLib.AddOperations( vProc, Part)
|
||||
|
||||
-- parametri da scrivere nelle note utente
|
||||
local UserNotes = {
|
||||
{ sName = 'dMaxElev', sMchParam = 'MaxElev'}
|
||||
{ sName = 'dMaxElev', sMchParam = 'MaxElev'},
|
||||
{ sName = 'dOpenMinSafe', sMchParam = 'OpenMinSafe'},
|
||||
{ sName = 'nVMRS', sMchParam = 'VMRS'},
|
||||
{ sName = 'dStartZmax', sMchParam = 'StartZmax'},
|
||||
{ sName = 'nOutRaw', sMchParam = 'OutRaw'},
|
||||
{ sName = 'nOpenOutRaw', sMchParam = 'OpenOutRaw'},
|
||||
{ sName = 'nPlunge', sMchParam = 'Plunge'}
|
||||
}
|
||||
|
||||
-- parametri da scrivere nelle note di sistema
|
||||
@@ -409,114 +531,159 @@ function MachiningLib.AddOperations( vProc, Part)
|
||||
}
|
||||
|
||||
for i = 1, #MACHININGS do
|
||||
local nClonesToAdd = 1
|
||||
if MACHININGS[i].AuxiliaryData.Clones then
|
||||
nClonesToAdd = #MACHININGS[i].AuxiliaryData.Clones
|
||||
end
|
||||
for j = 1, nClonesToAdd do
|
||||
-- creazione lavorazione
|
||||
local nOperationId = EgtCreateMachining( MACHININGS[i].Machining.sOperationName, MACHININGS[i].Machining.nType, MACHININGS[i].Machining.sToolName)
|
||||
-- si aggiungono solo quelle della fase richiesta
|
||||
if ( sRotation == 'STD' and not MACHININGS[i].Proc.bDown and not MACHININGS[i].Proc.bSide) or
|
||||
( MACHININGS[i].Proc.bDown and sRotation == 'DOWN') or
|
||||
( MACHININGS[i].Proc.bSide and sRotation == 'SIDE') then
|
||||
local nClonesToAdd = 1
|
||||
if MACHININGS[i].AuxiliaryData.Clones then
|
||||
nClonesToAdd = #MACHININGS[i].AuxiliaryData.Clones
|
||||
end
|
||||
for j = 1, nClonesToAdd do
|
||||
-- creazione lavorazione
|
||||
local nOperationId = EgtCreateMachining( MACHININGS[i].Machining.sOperationName, MACHININGS[i].Machining.nType, MACHININGS[i].Machining.sToolName)
|
||||
|
||||
if nOperationId then
|
||||
-- impostazione geometria
|
||||
EgtSetMachiningGeometry( MACHININGS[i].Machining.Geometry)
|
||||
if nOperationId then
|
||||
-- impostazione geometria
|
||||
local Geometry
|
||||
if MACHININGS[i].AuxiliaryData.Clones and MACHININGS[i].AuxiliaryData.Clones[j].Geometry then
|
||||
Geometry = MACHININGS[i].AuxiliaryData.Clones[j].Geometry
|
||||
elseif MACHININGS[i].Machining.Geometry then
|
||||
Geometry = MACHININGS[i].Machining.Geometry
|
||||
end
|
||||
EgtSetMachiningGeometry( Geometry)
|
||||
|
||||
-- impostazione parametri lavorazione
|
||||
-- TODO scrivere sempre Steps, LeadIn, LeadOut nelle tabelle in modo da non dover controllare ogni volta che ci siano
|
||||
for k = 1, #MachiningParameters do
|
||||
local sValue
|
||||
if MACHININGS[i].AuxiliaryData.Clones and MACHININGS[i].AuxiliaryData.Clones[j][MachiningParameters[k].sName] then
|
||||
sValue = MACHININGS[i].AuxiliaryData.Clones[j][MachiningParameters[k].sName]
|
||||
elseif MACHININGS[i].Machining[MachiningParameters[k].sName] then
|
||||
sValue = MACHININGS[i].Machining[MachiningParameters[k].sName]
|
||||
-- impostazione parametri lavorazione
|
||||
-- TODO scrivere sempre Steps, LeadIn, LeadOut nelle tabelle in modo da non dover controllare ogni volta che ci siano
|
||||
for k = 1, #MachiningParameters do
|
||||
local sValue
|
||||
if MACHININGS[i].AuxiliaryData.Clones and MACHININGS[i].AuxiliaryData.Clones[j][MachiningParameters[k].sName] then
|
||||
sValue = MACHININGS[i].AuxiliaryData.Clones[j][MachiningParameters[k].sName]
|
||||
elseif MACHININGS[i].Machining[MachiningParameters[k].sName] then
|
||||
sValue = MACHININGS[i].Machining[MachiningParameters[k].sName]
|
||||
end
|
||||
if sValue then
|
||||
EgtSetMachiningParam( MachiningParameters[k].nMchParam, sValue)
|
||||
end
|
||||
end
|
||||
if sValue then
|
||||
EgtSetMachiningParam( MachiningParameters[k].nMchParam, sValue)
|
||||
for k = 1, #MachiningParameters.Steps do
|
||||
local sValue
|
||||
if MACHININGS[i].AuxiliaryData.Clones and MACHININGS[i].AuxiliaryData.Clones[j].Steps and MACHININGS[i].AuxiliaryData.Clones[j].Steps[MachiningParameters.Steps[k].sName] then
|
||||
sValue = MACHININGS[i].AuxiliaryData.Clones[j].Steps[MachiningParameters.Steps[k].sName]
|
||||
elseif MACHININGS[i].Machining.Steps and MACHININGS[i].Machining.Steps[MachiningParameters.Steps[k].sName] then
|
||||
sValue = MACHININGS[i].Machining.Steps[MachiningParameters.Steps[k].sName]
|
||||
end
|
||||
if sValue then
|
||||
EgtSetMachiningParam( MachiningParameters.Steps[k].nMchParam, sValue)
|
||||
end
|
||||
end
|
||||
end
|
||||
for k = 1, #MachiningParameters.Steps do
|
||||
local sValue
|
||||
if MACHININGS[i].AuxiliaryData.Clones and MACHININGS[i].AuxiliaryData.Clones[j].Steps and MACHININGS[i].AuxiliaryData.Clones[j].Steps[MachiningParameters.Steps[k].sName] then
|
||||
sValue = MACHININGS[i].AuxiliaryData.Clones[j].Steps[MachiningParameters.Steps[k].sName]
|
||||
elseif MACHININGS[i].Machining.Steps and MACHININGS[i].Machining.Steps[MachiningParameters.Steps[k].sName] then
|
||||
sValue = MACHININGS[i].Machining.Steps[MachiningParameters.Steps[k].sName]
|
||||
for k = 1, #MachiningParameters.LeadIn do
|
||||
local sValue
|
||||
if MACHININGS[i].AuxiliaryData.Clones and MACHININGS[i].AuxiliaryData.Clones[j].LeadIn and MACHININGS[i].AuxiliaryData.Clones[j].LeadIn[MachiningParameters.LeadIn[k].sName] then
|
||||
sValue = MACHININGS[i].AuxiliaryData.Clones[j].LeadIn[MachiningParameters.LeadIn[k].sName]
|
||||
elseif MACHININGS[i].Machining.LeadIn and MACHININGS[i].Machining.LeadIn[MachiningParameters.LeadIn[k].sName] then
|
||||
sValue = MACHININGS[i].Machining.LeadIn[MachiningParameters.LeadIn[k].sName]
|
||||
end
|
||||
if sValue then
|
||||
EgtSetMachiningParam( MachiningParameters.LeadIn[k].nMchParam, sValue)
|
||||
end
|
||||
end
|
||||
if sValue then
|
||||
EgtSetMachiningParam( MachiningParameters.Steps[k].nMchParam, sValue)
|
||||
for k = 1, #MachiningParameters.LeadOut do
|
||||
local sValue
|
||||
if MACHININGS[i].AuxiliaryData.Clones and MACHININGS[i].AuxiliaryData.Clones[j].LeadOut and MACHININGS[i].AuxiliaryData.Clones[j].LeadOut[MachiningParameters.LeadOut[k].sName] then
|
||||
sValue = MACHININGS[i].AuxiliaryData.Clones[j].LeadOut[MachiningParameters.LeadOut[k].sName]
|
||||
elseif MACHININGS[i].Machining.LeadOut and MACHININGS[i].Machining.LeadOut[MachiningParameters.LeadOut[k].sName] then
|
||||
sValue = MACHININGS[i].Machining.LeadOut[MachiningParameters.LeadOut[k].sName]
|
||||
end
|
||||
if sValue then
|
||||
EgtSetMachiningParam( MachiningParameters.LeadOut[k].nMchParam, sValue)
|
||||
end
|
||||
end
|
||||
end
|
||||
for k = 1, #MachiningParameters.LeadIn do
|
||||
local sValue
|
||||
if MACHININGS[i].AuxiliaryData.Clones and MACHININGS[i].AuxiliaryData.Clones[j].LeadIn and MACHININGS[i].AuxiliaryData.Clones[j].LeadIn[MachiningParameters.LeadIn[k].sName] then
|
||||
sValue = MACHININGS[i].AuxiliaryData.Clones[j].LeadIn[MachiningParameters.LeadIn[k].sName]
|
||||
elseif MACHININGS[i].Machining.LeadIn and MACHININGS[i].Machining.LeadIn[MachiningParameters.LeadIn[k].sName] then
|
||||
sValue = MACHININGS[i].Machining.LeadIn[MachiningParameters.LeadIn[k].sName]
|
||||
for k = 1, #UserNotes do
|
||||
local sValue
|
||||
if MACHININGS[i].AuxiliaryData.Clones and MACHININGS[i].AuxiliaryData.Clones[j][UserNotes[k].sName] then
|
||||
sValue = MACHININGS[i].AuxiliaryData.Clones[j][UserNotes[k].sName]
|
||||
elseif MACHININGS[i].Machining[UserNotes[k].sName] then
|
||||
sValue = MACHININGS[i].Machining[UserNotes[k].sName]
|
||||
end
|
||||
if sValue then
|
||||
local sUserNotes = ''
|
||||
sUserNotes = EgtGetMachiningParam( MCH_MP.USERNOTES)
|
||||
sUserNotes = EgtSetValInNotes( sUserNotes, UserNotes[k].sMchParam, sValue)
|
||||
EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes)
|
||||
end
|
||||
end
|
||||
if sValue then
|
||||
EgtSetMachiningParam( MachiningParameters.LeadIn[k].nMchParam, sValue)
|
||||
-- parametri da settare nelle note di sistema
|
||||
-- TODO da decidere quali sono le note da salvare qui. Probabilmente tutte quelle relative all'ordine delle lavorazioni
|
||||
--if MACHININGS[i].Machining.nMachiningOrder then
|
||||
-- sSystemNotes = EgtSetValInNotes( sSystemNotes, 'MachiningOrder', MACHININGS[i].Machining.nMachiningOrder)
|
||||
--end
|
||||
for k = 1, #SystemNotes do
|
||||
local sValue
|
||||
if MACHININGS[i].AuxiliaryData.Clones and MACHININGS[i].AuxiliaryData.Clones[j][SystemNotes[k].sName] then
|
||||
sValue = MACHININGS[i].AuxiliaryData.Clones[j][SystemNotes[k].sName]
|
||||
elseif MACHININGS[i].Machining[SystemNotes[k].sName] then
|
||||
sValue = MACHININGS[i].Machining[SystemNotes[k].sName]
|
||||
end
|
||||
if sValue then
|
||||
local sSystemNotes = ''
|
||||
sSystemNotes = EgtGetMachiningParam( MCH_MP.SYSNOTES)
|
||||
sSystemNotes = EgtSetValInNotes( sSystemNotes, SystemNotes[k].sMchParam, sValue)
|
||||
EgtSetMachiningParam( MCH_MP.SYSNOTES, sSystemNotes)
|
||||
end
|
||||
end
|
||||
end
|
||||
for k = 1, #MachiningParameters.LeadOut do
|
||||
local sValue
|
||||
if MACHININGS[i].AuxiliaryData.Clones and MACHININGS[i].AuxiliaryData.Clones[j].LeadOut and MACHININGS[i].AuxiliaryData.Clones[j].LeadOut[MachiningParameters.LeadOut[k].sName] then
|
||||
sValue = MACHININGS[i].AuxiliaryData.Clones[j].LeadOut[MachiningParameters.LeadOut[k].sName]
|
||||
elseif MACHININGS[i].Machining.LeadOut and MACHININGS[i].Machining.LeadOut[MachiningParameters.LeadOut[k].sName] then
|
||||
sValue = MACHININGS[i].Machining.LeadOut[MachiningParameters.LeadOut[k].sName]
|
||||
end
|
||||
if sValue then
|
||||
EgtSetMachiningParam( MachiningParameters.LeadOut[k].nMchParam, sValue)
|
||||
end
|
||||
end
|
||||
for k = 1, #UserNotes do
|
||||
local sValue
|
||||
if MACHININGS[i].AuxiliaryData.Clones and MACHININGS[i].AuxiliaryData.Clones[j][UserNotes[k].sName] then
|
||||
sValue = MACHININGS[i].AuxiliaryData.Clones[j][UserNotes[k].sName]
|
||||
elseif MACHININGS[i].Machining[UserNotes[k].sName] then
|
||||
sValue = MACHININGS[i].Machining[UserNotes[k].sName]
|
||||
end
|
||||
if sValue then
|
||||
local sUserNotes = ''
|
||||
sUserNotes = EgtSetValInNotes( sUserNotes, UserNotes[k].sMchParam, sValue)
|
||||
EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes)
|
||||
end
|
||||
end
|
||||
-- parametri da settare nelle note di sistema
|
||||
-- TODO da decidere quali sono le note da salvare qui. Probabilmente tutte quelle relative all'ordine delle lavorazioni
|
||||
--if MACHININGS[i].Machining.nMachiningOrder then
|
||||
-- sSystemNotes = EgtSetValInNotes( sSystemNotes, 'MachiningOrder', MACHININGS[i].Machining.nMachiningOrder)
|
||||
--end
|
||||
for k = 1, #SystemNotes do
|
||||
local sValue
|
||||
if MACHININGS[i].AuxiliaryData.Clones and MACHININGS[i].AuxiliaryData.Clones[j][SystemNotes[k].sName] then
|
||||
sValue = MACHININGS[i].AuxiliaryData.Clones[j][SystemNotes[k].sName]
|
||||
elseif MACHININGS[i].Machining[SystemNotes[k].sName] then
|
||||
sValue = MACHININGS[i].Machining[SystemNotes[k].sName]
|
||||
end
|
||||
if sValue then
|
||||
local sSystemNotes = ''
|
||||
sSystemNotes = EgtSetValInNotes( sSystemNotes, SystemNotes[k].sMchParam, sValue)
|
||||
EgtSetMachiningParam( MCH_MP.SYSNOTES, sSystemNotes)
|
||||
end
|
||||
end
|
||||
|
||||
local bIsApplyOk = MachiningLib.ApplyMachining( true, false)
|
||||
if not bIsApplyOk then
|
||||
bAreAllMachiningApplyOk = false
|
||||
nErr, sErr = EgtGetLastMachMgrError()
|
||||
EgtSetOperationMode( nOperationId, false)
|
||||
local bIsApplyOk = MachiningLib.ApplyMachining( true, false)
|
||||
if not bIsApplyOk then
|
||||
bAreAllMachiningApplyOk = false
|
||||
nErr, sErr = EgtGetLastMachMgrError()
|
||||
EgtSetOperationMode( nOperationId, false)
|
||||
end
|
||||
|
||||
-- TODO è giusto inserire queste info alla fine della lavorazione? oppure conviene creare un record in MACHININGS apposito per la disposizione?
|
||||
-- se era taglio di separazione, aggiungo nuova fase
|
||||
if MACHININGS[i].AuxiliaryData.bAddNewPhase then
|
||||
bSplitExecuted = true
|
||||
BeamLib.AddPhaseWithRawParts( MACHININGS[i].Proc.idRaw, BeamData.ptOriXR, BeamData.dPosXR, BeamData.RAW_OFFSET)
|
||||
-- se grezzo successivo senza pezzi e finale, va tolto
|
||||
local nNextRawId = EgtGetNextRawPart( MACHININGS[i].Proc.idRaw)
|
||||
if nNextRawId and EgtGetPartInRawPartCount( nNextRawId) == 0 and EgtGetRawPartBBox( nNextRawId):getDimX() < BeamData.dMinRaw then
|
||||
EgtRemoveRawPartFromCurrPhase( nNextRawId)
|
||||
end
|
||||
local nPhase = EgtGetCurrPhase()
|
||||
local nDispId = EgtGetPhaseDisposition( nPhase)
|
||||
|
||||
if sRotation == 'DOWN' then
|
||||
local nRotation = EgtIf( Part.nInitialPosition + 2 > 4, Part.nInitialPosition + 2 - 4, Part.nInitialPosition + 2)
|
||||
BeamLib.RotatePart( Part, nRotation)
|
||||
EgtSetInfo( nDispId, 'ROT', -2)
|
||||
EgtSetInfo( nDispId, 'TYPE', 'MID2')
|
||||
elseif sRotation == 'SIDE' then
|
||||
local nRotation = EgtIf( Part.nInitialPosition + 1 > 4, Part.nInitialPosition + 1 - 4, Part.nInitialPosition + 1)
|
||||
BeamLib.RotatePart( Part, nRotation)
|
||||
EgtSetInfo( nDispId, 'ROT', -1)
|
||||
EgtSetInfo( nDispId, 'TYPE', 'MID2')
|
||||
else
|
||||
local nRotation = Part.nInitialPosition
|
||||
BeamLib.RotatePart( Part, nRotation)
|
||||
EgtSetInfo( nDispId, 'TYPE', 'END')
|
||||
end
|
||||
EgtSetInfo( nDispId, 'ORD', MACHININGS[i].Proc.nIndexPartInParts)
|
||||
end
|
||||
else
|
||||
return false, 'UNEXPECTED ERROR: Error on creating machining', bSplitExecuted
|
||||
end
|
||||
else
|
||||
return false, 'UNEXPECTED ERROR: Error on creating machining'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return bAreAllMachiningApplyOk, sErr
|
||||
return bAreAllMachiningApplyOk, sErr, bSplitExecuted
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function MachiningLib.ApplyMachining( bRecalc, bApplyPost)
|
||||
local bResult = EgtApplyMachining( bRecalc, bApplyPost)
|
||||
|
||||
return bResult
|
||||
end
|
||||
|
||||
|
||||
+13
-4
@@ -7,7 +7,7 @@
|
||||
-- Intestazioni
|
||||
require( 'EgtBase')
|
||||
_ENV = EgtProtectGlobal()
|
||||
EgtEnableDebug( false)
|
||||
EgtEnableDebug( true)
|
||||
|
||||
-- Imposto direttorio libreria specializzata per Travi
|
||||
EgtAddToPackagePath( BEAM.BASEDIR .. '\\LuaLibs\\?.lua')
|
||||
@@ -39,9 +39,15 @@ _G.package.loaded.BeamLib = nil
|
||||
_G.package.loaded.BeamData = nil
|
||||
_G.package.loaded.Identity = nil
|
||||
_G.package.loaded.BasicCustomerStrategies = nil
|
||||
_G.package.loaded.FeatureData = nil
|
||||
_G.package.loaded.FeatureLib = nil
|
||||
_G.package.loaded.FaceData = nil
|
||||
_G.package.loaded.MachiningLib = nil
|
||||
_G.package.loaded.Logs = nil
|
||||
-- strategie di base sempre presenti
|
||||
_G.package.loaded['SPLITCUT\\SPLITCUT'] = nil
|
||||
_G.package.loaded['SPLITCUT\\SPLITCUTConfig'] = nil
|
||||
_G.package.loaded['HEADCUT\\HEADCUT'] = nil
|
||||
_G.package.loaded['HEADCUT\\HEADCUTConfig'] = nil
|
||||
|
||||
-- TODO controllare se c'è un modo migliore per resettare librerie delle strategie caricate precedentemente
|
||||
-- Per ottimizzare potremmo anche ciclare solo fino al numero di strategie raggiunto per il momento.
|
||||
@@ -66,10 +72,12 @@ for i = 1, #vtCoreStrategiesNames do
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local BeamExec = require( 'BeamExec')
|
||||
|
||||
-- Variabili globali
|
||||
PARTS = {}
|
||||
PARTS = {} -- tabella contenente tutte le informazioni di ogni pezzo
|
||||
PROCESSINGS = {} -- tabella contenente tutte le informazioni di ogni feature, processate per ogni rotazione
|
||||
|
||||
-- Carico i dati globali
|
||||
local BeamData = require( 'BeamData')
|
||||
@@ -298,7 +306,8 @@ end
|
||||
-- *** Inserimento delle lavorazioni nelle travi ***
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function MyProcessFeatures()
|
||||
local bOk, Stats = BeamExec.ProcessFeatures( PARTS)
|
||||
local PROCESSINGS = BeamExec.GetProcessings( PROCESSINGS, PARTS)
|
||||
local bOk, Stats = BeamExec.ProcessMachinings( PROCESSINGS, PARTS)
|
||||
local nErrCnt = 0
|
||||
local nWarnCnt = 0
|
||||
local sOutput = ''
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
-- Strategia: FACEBYBLADE
|
||||
-- Descrizione
|
||||
-- Strategia di base per la lavorazione di una faccia con lama
|
||||
-- Feature: tutte
|
||||
|
||||
-- carico librerie
|
||||
local BeamLib = require( 'BeamLib')
|
||||
local BeamData = require( 'BeamData')
|
||||
local MachiningLib = require( 'MachiningLib')
|
||||
|
||||
-- Tabella per definizione modulo
|
||||
local FACEBYBLADE = {}
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function CalculateLeadInOut( EdgeToMachine)
|
||||
local LeadIn = {}
|
||||
local LeadOut = {}
|
||||
LeadIn.dStartAddLength = 0
|
||||
LeadOut.dEndAddLength = 0
|
||||
LeadIn.nType = MCH_MILL_LI.LINEAR
|
||||
LeadOut.nType = MCH_MILL_LI.LINEAR
|
||||
LeadIn.dTangentDistance = 0
|
||||
LeadOut.dTangentDistance = 0
|
||||
-- elevazione sempre in negativo
|
||||
if EdgeToMachine.Elev < 10 * GEO.EPS_SMALL then
|
||||
LeadIn.dPerpDistance = BeamData.CUT_SIC - EdgeToMachine.Elev
|
||||
LeadOut.dPerpDistance = BeamData.CUT_SIC - EdgeToMachine.Elev
|
||||
else
|
||||
LeadIn.dPerpDistance = BeamData.CUT_SIC
|
||||
LeadOut.dPerpDistance = BeamData.CUT_SIC
|
||||
end
|
||||
LeadIn.dElevation = 0
|
||||
LeadOut.dElevation = 0
|
||||
LeadIn.dCompLength = 0
|
||||
LeadOut.dCompLength = 0
|
||||
LeadIn.dStartAddLength = BeamData.CUT_EXTRA
|
||||
LeadOut.dEndAddLength = BeamData.CUT_EXTRA
|
||||
|
||||
return LeadIn, LeadOut
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- TODO da sistemare
|
||||
local function GetSCC( vtMachiningDirection)
|
||||
local nSCC = MCH_SCC.NONE
|
||||
|
||||
if vtMachiningDirection:getZ() < -0.9 then
|
||||
nSCC = MCH_SCC.ADIR_ZM
|
||||
elseif vtMachiningDirection:getZ() > 0.9 then
|
||||
nSCC = MCH_SCC.ADIR_ZP
|
||||
elseif vtMachiningDirection:getY() < -0.707 then
|
||||
nSCC = MCH_SCC.ADIR_YM
|
||||
elseif vtMachiningDirection:getY() > 0.707 then
|
||||
nSCC = MCH_SCC.ADIR_YP
|
||||
elseif vtMachiningDirection:getX() < -0.707 then
|
||||
nSCC = MCH_SCC.ADIR_XM
|
||||
elseif vtMachiningDirection:getX() > 0.707 then
|
||||
nSCC = MCH_SCC.ADIR_XP
|
||||
end
|
||||
|
||||
return nSCC
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- TODO da sistemare
|
||||
function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalParameters)
|
||||
local Cutting = {}
|
||||
|
||||
local vtMachiningDirection = EdgeToMachine.Norm
|
||||
local vtN = Proc.Faces[FaceToMachine+1].vtN
|
||||
Cutting.sDepth = OptionalParameters.sDepth or 0
|
||||
Cutting.dRadialOffset = OptionalParameters.dRadialOffset or 0
|
||||
|
||||
Cutting.nType = MCH_MY.MILLING
|
||||
Cutting.nToolIndex = OptionalParameters.nToolIndex
|
||||
Cutting.Geometry = {{ Proc.id, FaceToMachine}}
|
||||
Cutting.id = Proc.id
|
||||
|
||||
|
||||
-- ===== calcolo LeadIn/out =====
|
||||
if OptionalParameters.LeadIn and OptionalParameters.LeadOut then
|
||||
Cutting.LeadIn, Cutting.LeadOut = OptionalParameters.LeadIn, OptionalParameters.LeadOut
|
||||
else
|
||||
Cutting.LeadIn, Cutting.LeadOut = CalculateLeadInOut( EdgeToMachine)
|
||||
end
|
||||
|
||||
-- ===== scelta soluzione braccio C del motore =====
|
||||
Cutting.nSCC = GetSCC( vtMachiningDirection)
|
||||
|
||||
-- ===== parametri da settare in UserNotes =====
|
||||
Cutting.nFaceuse = OptionalParameters.nFaceuse
|
||||
Cutting.sUserNotes = EgtSetValInNotes( Cutting.sUserNotes, 'VtFaceUse', vtMachiningDirection)
|
||||
if OptionalParameters.sUserNotes then
|
||||
Cutting.sUserNotes = Cutting.sUserNotes .. OptionalParameters.sUserNotes
|
||||
end
|
||||
|
||||
-- ===== scelta senso di lavorazione =====
|
||||
local bIsSawCCW = TOOLS[Cutting.nToolIndex].bIsCCW
|
||||
local bInvert
|
||||
-- se la lama ruota in senso antiorario inverto la direzione di lavorazione, per avere rotazione lama opposta a avanzamento
|
||||
if bInvert == nil then
|
||||
bInvert = ( not bIsSawCCW)
|
||||
if bIsSawCCW then
|
||||
bInvert = (( Cutting.nFaceuse == MCH_MILL_FU.ORTHO_FRONT and vtN:getX() < 0) or ( Cutting.nFaceuse == MCH_MILL_FU.ORTHO_BACK and vtN:getX() > 0))
|
||||
else
|
||||
bInvert = (( Cutting.nFaceuse == MCH_MILL_FU.ORTHO_FRONT and vtN:getX() > 0) or ( Cutting.nFaceuse == MCH_MILL_FU.ORTHO_BACK and vtN:getX() < 0))
|
||||
end
|
||||
end
|
||||
Cutting.bInvert = bInvert
|
||||
Cutting.nWorkside = EgtIf( bInvert, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT)
|
||||
|
||||
return Cutting
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
|
||||
return FACEBYBLADE
|
||||
@@ -17,8 +17,7 @@ local function CalculateLeadInOut( Machining, EdgeToMachine)
|
||||
-- TODO implementare le funzioni di Tool Collision Avoidance (vedi wiki e FacesBysaw -> CalcLeadInOutPerpGeom)
|
||||
|
||||
-- si determina l'eventuale riduzione da applicare in caso di inizio o fine chiusi
|
||||
local dAddLengthToReduce = 0
|
||||
dAddLengthToReduce = sqrt( Machining.dDepthToMachine * TOOLS[Machining.nToolIndex].dDiameter - Machining.dDepthToMachine * Machining.dDepthToMachine)
|
||||
local dAddLengthToReduce = sqrt( Machining.dDepthToMachine * TOOLS[Machining.nToolIndex].dDiameter - Machining.dDepthToMachine * Machining.dDepthToMachine)
|
||||
|
||||
if Machining.bInvert then
|
||||
Machining.bIsStartClosed, Machining.bIsEndClosed = Machining.bIsEndClosed, Machining.bIsStartClosed
|
||||
@@ -94,9 +93,21 @@ function SLOTBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
|
||||
Cutting.dResidualDepth = abs( EdgeToMachine.dElevation)
|
||||
Cutting.dBladeMarkLength = 0
|
||||
Cutting.sEdgeType = EdgeToMachine.sType
|
||||
Cutting. nSegment = 1
|
||||
|
||||
-- parametri opzionali
|
||||
if not OptionalParameters then
|
||||
OptionalParameters = {}
|
||||
end
|
||||
local bForceLongcutBlade = OptionalParameters.bForceLongcutBlade or false
|
||||
local dExtendAfterTail = OptionalParameters.dExtendAfterTail or 10000
|
||||
|
||||
-- lunghezze e punti caratteristici della lavorazione e del lato lavorato
|
||||
Cutting.dLengthToMachine = EdgeToMachine.dLength
|
||||
Cutting.dLengthOnX = abs( EdgeToMachine.dLength * EdgeToMachine.vtToolDirection:getY())
|
||||
Cutting.dEdgeLength = EdgeToMachine.dLength
|
||||
Cutting.ptEdge1, _, Cutting.ptEdge2 = EgtSurfTmFacetOppositeSide( Proc.id, FaceToMachine.id, -EdgeToMachine.vtToolDirection, GDB_ID.ROOT)
|
||||
Cutting.vtEdgeDirection = EdgeToMachine.vtToolDirection ^ FaceToMachine.vtN
|
||||
|
||||
local dPocketHeight = 0
|
||||
if Proc.Topology.sFamily == 'Tunnel' then
|
||||
@@ -235,18 +246,33 @@ function SLOTBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
|
||||
-- nome operazione
|
||||
Cutting.sOperationName = 'Cut_' .. ( EgtGetName( Cutting.idProc) or tostring( Cutting.idProc)) .. '_' .. tostring( FaceToMachine.id + 1)
|
||||
|
||||
-- eventuale avviso di danneggiamento pezzo successivo
|
||||
-- TODO da sostituire con check se si riesce a separare e il grezzo dietro è lungo a sufficienza
|
||||
-- local dOffsideLength = max( Cutting.LeadIn.dStartAddLength, Cutting.LeadOut.dEndAddLength) + TOOLS[Cutting.nToolIndex].dDiameter / 2 + 10 * GEO.EPS_SMALL
|
||||
-- if ( not Proc.bTail or Proc.bAdvTail) and Proc.AffectedFaces.bLeft and ( Proc.dDistanceToNextPart < dOffsideLength) then
|
||||
-- local sDamageNextPieceMessage = 'Feature '.. Proc.idFeature .. ' : sawblade can damage next piece.'
|
||||
-- if #Cutting.sMessage > 0 then
|
||||
-- Cutting.sMessage = Cutting.sMessage .. '\n' .. sDamageNextPieceMessage
|
||||
-- else
|
||||
-- Cutting.sMessage = sDamageNextPieceMessage
|
||||
-- end
|
||||
-- EgtOutLog( sDamageNextPieceMessage)
|
||||
-- end
|
||||
-- se lavorazione aperta sulla coda, eventuali aggiustamenti
|
||||
-- TODO valutare se fare funzione a parte
|
||||
if Proc.AffectedFaces.bLeft then
|
||||
local bStartLeft = MachiningLib.StartsLeftSide( Cutting)
|
||||
local dAddLengthLeftSide = Cutting.LeadOut.dEndAddLength
|
||||
local dAddLengthToReduce = sqrt( Cutting.dDepthToMachine * TOOLS[Cutting.nToolIndex].dDiameter - Cutting.dDepthToMachine * Cutting.dDepthToMachine)
|
||||
if bStartLeft then
|
||||
dAddLengthLeftSide = Cutting.LeadIn.dStartAddLength
|
||||
end
|
||||
if not AreSameOrOppositeVectorApprox( EdgeToMachine.vtToolDirection, Y_AX()) then
|
||||
if MachiningLib.CanMoveAfterSplitcut( Cutting.dLengthOnX, Part) then
|
||||
Cutting.bMoveAfterSplitcut = true
|
||||
else
|
||||
Cutting.bIsApplicable = false
|
||||
end
|
||||
elseif dAddLengthLeftSide + dAddLengthToReduce > dExtendAfterTail then
|
||||
if MachiningLib.CanMoveAfterSplitcut( Cutting.dLengthOnX, Part) then
|
||||
Cutting.bMoveAfterSplitcut = true
|
||||
else
|
||||
if bStartLeft then
|
||||
Cutting.LeadIn.dStartAddLength = - dAddLengthToReduce + dExtendAfterTail
|
||||
else
|
||||
Cutting.LeadOut.dEndAddLength = - dAddLengthToReduce + dExtendAfterTail
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return Cutting
|
||||
|
||||
|
||||
@@ -56,13 +56,25 @@ function SLOTBYCHAINSAW.Make( Proc, Part, FaceToMachine, EdgeToMachine, Optional
|
||||
Mortising.sMessage = ''
|
||||
Mortising.idProc = Proc.id
|
||||
Mortising.sEdgeType = EdgeToMachine.sType
|
||||
Mortising.nSegment = 1
|
||||
|
||||
-- parametri opzionali
|
||||
if not OptionalParameters then
|
||||
OptionalParameters = {}
|
||||
end
|
||||
local bUseZigZagMortising = OptionalParameters.bUseZigZagMortising or false
|
||||
local sSideToMachine = OptionalParameters.sSideToMachine or ''
|
||||
local dLengthToMachine = OptionalParameters.dLengthToMachine or EdgeToMachine.dLength
|
||||
local dCustomMaxElev = OptionalParameters.dMaxElev or abs( EdgeToMachine.dElevation)
|
||||
local bStopAtHalfElevation = OptionalParameters.bStopAtHalfElevation or false
|
||||
local dExtendAfterTail = OptionalParameters.dExtendAfterTail or 10000
|
||||
|
||||
-- lunghezze e punti caratteristici della lavorazione e del lato lavorato
|
||||
Mortising.dLengthToMachine = dLengthToMachine
|
||||
Mortising.dLengthOnX = abs( dLengthToMachine * EdgeToMachine.vtToolDirection:getY())
|
||||
Mortising.dEdgeLength = EdgeToMachine.dLength
|
||||
Mortising.ptEdge1, _, Mortising.ptEdge2 = EgtSurfTmFacetOppositeSide( Proc.id, FaceToMachine.id, -EdgeToMachine.vtToolDirection, GDB_ID.ROOT)
|
||||
Mortising.vtEdgeDirection = EdgeToMachine.vtToolDirection ^ FaceToMachine.vtN
|
||||
|
||||
-- altezza tasca, in base alla topologia
|
||||
local dPocketHeight = 0
|
||||
@@ -168,7 +180,7 @@ function SLOTBYCHAINSAW.Make( Proc, Part, FaceToMachine, EdgeToMachine, Optional
|
||||
Mortising.dCompletionPercentage = 100 - Mortising.dResidualDepth / Mortising.dDepthToMachine
|
||||
-- massima elevazione
|
||||
if dCustomMaxElev < Mortising.dDepthToMachine - 10 * GEO.EPS_SMALL then
|
||||
Mortising.dMaxElev = dCustomMaxElev
|
||||
Mortising.dMaxElev = max( dCustomMaxElev, dCustomMaxElev - Mortising.dLongitudinalOffset)
|
||||
end
|
||||
-- offset radiale
|
||||
Mortising.dRadialOffset = 0
|
||||
@@ -210,21 +222,34 @@ function SLOTBYCHAINSAW.Make( Proc, Part, FaceToMachine, EdgeToMachine, Optional
|
||||
-- nome operazione
|
||||
Mortising.sOperationName = 'Chainsaw_' .. ( EgtGetName( Mortising.idProc) or tostring( Mortising.idProc)) .. '_' .. tostring( FaceToMachine.id + 1)
|
||||
|
||||
-- eventuale avviso di danneggiamento pezzo successivo
|
||||
-- TODO da sostituire con check se si riesce a separare e il grezzo dietro è lungo a sufficienza
|
||||
-- local dOffsideLength = max( Mortising.LeadIn.dStartAddLength, Mortising.LeadOut.dEndAddLength) + TOOLS[Mortising.nToolIndex].dWidth / 2 + 10 * GEO.EPS_SMALL
|
||||
-- if ( not Proc.bTail or Proc.bAdvTail) and Proc.AffectedFaces.bLeft and ( Proc.dDistanceToNextPart < dOffsideLength) then
|
||||
-- local sDamageNextPieceMessage = 'Feature '.. Proc.idFeature .. ' : chainsaw can damage next piece.'
|
||||
-- if #Mortising.sMessage > 0 then
|
||||
-- Mortising.sMessage = Mortising.sMessage .. '\n' .. sDamageNextPieceMessage
|
||||
-- else
|
||||
-- Mortising.sMessage = sDamageNextPieceMessage
|
||||
-- end
|
||||
-- EgtOutLog( sDamageNextPieceMessage)
|
||||
-- end
|
||||
-- se lavorazione aperta sulla coda, eventuali aggiustamenti
|
||||
-- TODO valutare se fare funzione a parte
|
||||
if Proc.AffectedFaces.bLeft then
|
||||
local bStartLeft = MachiningLib.StartsLeftSide( Mortising)
|
||||
local dAddLengthLeftSide = Mortising.LeadOut.dEndAddLength
|
||||
if bStartLeft then
|
||||
dAddLengthLeftSide = Mortising.LeadIn.dStartAddLength
|
||||
end
|
||||
if not AreSameOrOppositeVectorApprox( EdgeToMachine.vtToolDirection, Y_AX()) then
|
||||
if MachiningLib.CanMoveAfterSplitcut( Mortising.dLengthOnX, Part) then
|
||||
Mortising.bMoveAfterSplitcut = true
|
||||
else
|
||||
Mortising.bIsApplicable = false
|
||||
end
|
||||
elseif dAddLengthLeftSide + TOOLS[Mortising.nToolIndex].dDiameter / 2 > dExtendAfterTail then
|
||||
if MachiningLib.CanMoveAfterSplitcut( Mortising.dLengthOnX, Part) then
|
||||
Mortising.bMoveAfterSplitcut = true
|
||||
else
|
||||
if bStartLeft then
|
||||
Mortising.LeadIn.dStartAddLength = - TOOLS[Mortising.nToolIndex].dDiameter / 2 + dExtendAfterTail
|
||||
else
|
||||
Mortising.LeadOut.dEndAddLength = - TOOLS[Mortising.nToolIndex].dDiameter / 2 + dExtendAfterTail
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return Mortising
|
||||
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,391 @@
|
||||
-- Strategia: HEADCUT
|
||||
-- Descrizione
|
||||
-- HeadCut
|
||||
-- Feature: HeadCut
|
||||
|
||||
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
-- TODO: HEADCUT copiata da SPLITCUT. Da sistemare e capire se fare solo una strategia oppure due divise.
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
-- carico librerie
|
||||
local BeamLib = require( 'BeamLib')
|
||||
local BeamData = require( 'BeamData')
|
||||
local MachiningLib = require( 'MachiningLib')
|
||||
local FeatureLib = require( 'FeatureLib')
|
||||
-- strategie di base
|
||||
local FaceByBlade = require('FACEBYBLADE')
|
||||
|
||||
-- Tabella per definizione modulo
|
||||
local HEADCUT = {}
|
||||
local Strategy = {}
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function LoadStrategyParameters( CustomParameters)
|
||||
local StrategyLib = {}
|
||||
StrategyLib.Config = require( 'HEADCUT\\HEADCUTConfig')
|
||||
Strategy.sName = StrategyLib.Config.sStrategyId
|
||||
CustomParameters = BeamLib.GetUpdateCustomParameters( CustomParameters, StrategyLib.Config.Parameters)
|
||||
Strategy.Parameters = BeamLib.LoadCustomParametersInStrategy( CustomParameters)
|
||||
Strategy.Result = {}
|
||||
Strategy.Machining = {}
|
||||
Strategy.Result.sInfo = ''
|
||||
return Strategy
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function CalculateLeadInOut( Machining, EdgeToMachine)
|
||||
|
||||
local LeadIn = {}
|
||||
local LeadOut = {}
|
||||
LeadIn.dStartAddLength = 0
|
||||
LeadOut.dEndAddLength = 0
|
||||
LeadIn.nType = MCH_MILL_LI.LINEAR
|
||||
LeadOut.nType = MCH_MILL_LI.LINEAR
|
||||
LeadIn.dTangentDistance = 0
|
||||
LeadOut.dTangentDistance = 0
|
||||
-- elevazione sempre in negativo
|
||||
if EdgeToMachine.Elev < 10 * GEO.EPS_SMALL then
|
||||
LeadIn.dPerpDistance = BeamData.CUT_SIC - EdgeToMachine.Elev
|
||||
LeadOut.dPerpDistance = BeamData.CUT_SIC - EdgeToMachine.Elev
|
||||
else
|
||||
LeadIn.dPerpDistance = BeamData.CUT_SIC
|
||||
LeadOut.dPerpDistance = BeamData.CUT_SIC
|
||||
end
|
||||
LeadIn.dElevation = 0
|
||||
LeadOut.dElevation = 0
|
||||
LeadIn.dCompLength = 0
|
||||
LeadOut.dCompLength = 0
|
||||
LeadIn.dStartAddLength = BeamData.CUT_EXTRA
|
||||
LeadOut.dEndAddLength = BeamData.CUT_EXTRA
|
||||
|
||||
return LeadIn, LeadOut
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function MakeChamfer()
|
||||
-- TODO funzionalit� da aggiungere
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function GetEdgeToMachine( Proc, vtEdge)
|
||||
local Edge
|
||||
for i = 1, #Proc.Faces[1].Edges do
|
||||
if AreSameVectorApprox( Proc.Faces[1].Edges[i].Norm, vtEdge) then
|
||||
Edge = Proc.Faces[1].Edges[i]
|
||||
end
|
||||
end
|
||||
return Edge
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function GetSplitStrategy( Proc, Part)
|
||||
-- se non sono stati caricati i parametri, si ricaricano
|
||||
if not Strategy.Parameters then
|
||||
Strategy = LoadStrategyParameters()
|
||||
end
|
||||
|
||||
-- separazione solo se esiste grezzo successivo con pezzi o scaricabile
|
||||
local nNextRawId = EgtGetNextRawPart( Part.idRaw)
|
||||
Strategy.bSplit = ( nNextRawId and ( EgtGetPartInRawPartCount( nNextRawId) > 0 or EgtGetRawPartBBox( nNextRawId):getDimX() >= BeamData.dMinRaw))
|
||||
|
||||
-- imposto paraemtri di ricerca utensile in base a topologia
|
||||
local Machining = {}
|
||||
-- sTypeMachining = BladeSideSingle\ BladeSideDouble\ BladeHorizontalSingle\ BladeHorizontalDouble\ ChainSawHorizontal\ ChainSawSideSingle\ ChainSawSideDouble\ ChainSawPlusBlade\ Mill\ None
|
||||
Machining.sTypeMachining = 'None'
|
||||
local Splitting = {}
|
||||
local ToolSearchParameters = {}
|
||||
ToolSearchParameters.vtToolDirection = Proc.Faces[1].vtN
|
||||
|
||||
|
||||
-- ===== RICERCA UTENSILE =====
|
||||
-- cerco lama sopra
|
||||
Splitting.bIsApplicable = false
|
||||
ToolSearchParameters.bAllowTopHead = true
|
||||
ToolSearchParameters.bAllowBottomHead = false
|
||||
Splitting.ToolInfo = {}
|
||||
Splitting.ToolInfo = MachiningLib.FindBlade( Proc, ToolSearchParameters)
|
||||
if Splitting.ToolInfo.nToolIndex then
|
||||
Splitting.bIsApplicable = true
|
||||
local ParametersMRR = {}
|
||||
ParametersMRR.nToolIndex = Splitting.ToolInfo.nToolIndex
|
||||
Splitting.dMRR = MachiningLib.GetToolMRR( ParametersMRR)
|
||||
end
|
||||
table.insert( Machining, Splitting)
|
||||
|
||||
-- cerco lama sotto
|
||||
Splitting = {}
|
||||
Splitting.bIsApplicable = false
|
||||
ToolSearchParameters.bAllowTopHead = false
|
||||
ToolSearchParameters.bAllowBottomHead = true
|
||||
Splitting.ToolInfo = {}
|
||||
Splitting.ToolInfo = MachiningLib.FindBlade( Proc, ToolSearchParameters)
|
||||
if Splitting.ToolInfo.nToolIndex then
|
||||
Splitting.bIsApplicable = true
|
||||
local ParametersMRR = {}
|
||||
ParametersMRR.nToolIndex = Splitting.ToolInfo.nToolIndex
|
||||
Splitting.dMRR = MachiningLib.GetToolMRR( ParametersMRR)
|
||||
end
|
||||
table.insert( Machining, Splitting)
|
||||
|
||||
-- cerco motosega
|
||||
Splitting = {}
|
||||
Splitting.bIsApplicable = false
|
||||
table.insert( Machining, Splitting)
|
||||
|
||||
-- cerco fresa
|
||||
Splitting = {}
|
||||
Splitting.bIsApplicable = false
|
||||
table.insert( Machining, Splitting)
|
||||
|
||||
-- ===== SCELTA LAVORAZIONI =====
|
||||
-- forzature da parametri
|
||||
if Strategy.Parameters.bForceChainSaw then
|
||||
Machining[1].bIsApplicable = false
|
||||
Machining[2].bIsApplicable = false
|
||||
end
|
||||
|
||||
-- setto valori di default. Impossibile che taglio di separazione sia incompleto
|
||||
Strategy.Result.sStatus = 'Completed'
|
||||
Strategy.Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( 100)
|
||||
Strategy.Result.dMRR = 1
|
||||
|
||||
-- correzioni sul massimo materiale lama, considerando ingombri vari
|
||||
local dMaxMatBladeSideSingle
|
||||
local dMaxMatBladeSideDouble
|
||||
local dMaxMatBladeHorizontalSingle
|
||||
local dMaxMatBladeHorizontalDouble
|
||||
if Machining[1].bIsApplicable then
|
||||
local dMaxMat = TOOLS[Machining[1].ToolInfo.nToolIndex].dMaxMaterial
|
||||
local dRadius = TOOLS[Machining[1].ToolInfo.nToolIndex].dDiameter / 2
|
||||
local sHead = TOOLS[Machining[1].ToolInfo.nToolIndex].sHead
|
||||
-- se taglio di fianco disponibile, si controlla il massimo materiale reale. Per pezzi alti, bisogna controllare anche l'ingombro asse Z nelle 4 direzioni.
|
||||
if Part.dHeight < BeamData.MIN_DIM_HBEAM then
|
||||
dMaxMat = min( dMaxMat, BeamData.MAX_DIM_HTCUT)
|
||||
dMaxMatBladeSideSingle = dMaxMat
|
||||
dMaxMatBladeSideDouble = dMaxMat * 2
|
||||
else
|
||||
if BeamData.GetMaxMatReductionBladeCut then
|
||||
dMaxMatBladeSideSingle = min( max( dRadius - BeamData.GetMaxMatReductionBladeCut( sHead, Y_AX()), dRadius - BeamData.GetMaxMatReductionBladeCut( sHead, -Y_AX())),
|
||||
TOOLS[Machining[1].ToolInfo.nToolIndex].dMaxMaterial)
|
||||
dMaxMatBladeSideDouble = dRadius - BeamData.GetMaxMatReductionBladeCut( sHead, Y_AX()) + dRadius - BeamData.GetMaxMatReductionBladeCut( sHead, -Y_AX())
|
||||
else
|
||||
dMaxMatBladeSideSingle = abs( BeamData.MAX_DIM_HTCUT_HBEAM)
|
||||
dMaxMatBladeSideDouble = abs( BeamData.MAX_DIM_HTCUT_HBEAM) * 2
|
||||
end
|
||||
end
|
||||
-- se taglio orizzontale
|
||||
if BeamData.GetMaxMatReductionBladeCut then
|
||||
dMaxMatBladeHorizontalSingle = min( TOOLS[Machining[1].ToolInfo.nToolIndex].dMaxMaterial, dRadius - BeamData.GetMaxMatReductionBladeCut( TOOLS[Machining[1].ToolInfo.nToolIndex].sHead, -Z_AX()))
|
||||
else
|
||||
dMaxMatBladeHorizontalSingle = TOOLS[Machining[1].ToolInfo.nToolIndex].dMaxMaterial
|
||||
end
|
||||
end
|
||||
if Machining[2].bIsApplicable then
|
||||
if BeamData.GetMaxMatReductionBladeCut then
|
||||
local dRadius = TOOLS[Machining[2].ToolInfo.nToolIndex].dDiameter / 2
|
||||
dMaxMatBladeHorizontalDouble = min( TOOLS[Machining[2].ToolInfo.nToolIndex].dMaxMaterial, dRadius - BeamData.GetMaxMatReductionBladeCut( TOOLS[Machining[2].ToolInfo.nToolIndex].sHead, Z_AX()))
|
||||
else
|
||||
dMaxMatBladeHorizontalDouble = TOOLS[Machining[2].ToolInfo.nToolIndex].dMaxMaterial
|
||||
end
|
||||
end
|
||||
|
||||
-- TODO considerare di tagliare con il massimo materiale possibile per non salire troppo in Z (macchine tipo PF), oppure non scendere troppo (tipo Kairos)
|
||||
-- BladeSideSingle (taglio di lama singolo di fianco)
|
||||
if Machining[1].bIsApplicable and ( dMaxMatBladeSideSingle - BeamData.CUT_EXTRA) > Part.dWidth + 10 * GEO.EPS_SMALL then
|
||||
Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'Blade')
|
||||
Machining.sTypeMachining = 'BladeSideSingle'
|
||||
Machining[2].bIsApplicable = false
|
||||
Machining[3].bIsApplicable = false
|
||||
Machining[4].bIsApplicable = false
|
||||
return Machining
|
||||
-- TODO considerare di tagliare con il massimo materiale possibile per non salire troppo in Z (macchine tipo PF), oppure non scendere troppo (tipo Kairos)
|
||||
-- BladeSideDouble (taglio di lama doppio di fianco)
|
||||
elseif Machining[1].bIsApplicable and ( dMaxMatBladeSideDouble - BeamData.CUT_EXTRA) > Part.dWidth + 10 * GEO.EPS_SMALL then
|
||||
Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'Blade')
|
||||
Strategy.Result.dMRR = Strategy.Result.dMRR/2
|
||||
Machining.sTypeMachining = 'BladeSideDouble'
|
||||
Machining[2].bIsApplicable = false
|
||||
Machining[3].bIsApplicable = false
|
||||
Machining[4].bIsApplicable = false
|
||||
return Machining
|
||||
-- BladeHorizontalSingle (taglio di lama singolo orizzontale)
|
||||
elseif Machining[1].bIsApplicable and ( dMaxMatBladeHorizontalSingle - BeamData.CUT_EXTRA) > Part.dHeight + 10 * GEO.EPS_SMALL then
|
||||
Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'Blade')
|
||||
Machining.sTypeMachining = 'BladeHorizontalSingle'
|
||||
Machining[2].bIsApplicable = false
|
||||
Machining[3].bIsApplicable = false
|
||||
Machining[4].bIsApplicable = false
|
||||
return Machining
|
||||
-- BladeHorizontalDouble (taglio di lama doppio orizzontale)
|
||||
elseif Machining[1].bIsApplicable and Machining[2].bIsApplicable and
|
||||
( dMaxMatBladeHorizontalSingle + dMaxMatBladeHorizontalDouble - BeamData.CUT_EXTRA) > Part.dHeight + 10 * GEO.EPS_SMALL then
|
||||
Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'Blade')
|
||||
Strategy.Result.dMRR = Strategy.Result.dMRR/2
|
||||
Machining.sTypeMachining = 'BladeHorizontalDouble'
|
||||
Machining[1].ToolInfo.dMaxMatBladeFromTop = dMaxMatBladeHorizontalSingle
|
||||
Machining[2].ToolInfo.dMaxMatBladeFromDown = dMaxMatBladeHorizontalDouble
|
||||
Machining[3].bIsApplicable = false
|
||||
Machining[4].bIsApplicable = false
|
||||
return Machining
|
||||
|
||||
-- TODO : casi con motosega da completare
|
||||
-- ChainSawHorizontal (motosega)
|
||||
-- ChainSawSideSingle (motosega)
|
||||
-- ChainSawSideDouble (motosega)
|
||||
-- ChainSawPlusBlade (motosega pi� lama orizzontale)
|
||||
-- Mill (svuotatura)
|
||||
end
|
||||
|
||||
-- se non ho trovato neanche una lavorazione completa, non posso separare
|
||||
if Machining.sTypeMachining == 'None' then
|
||||
Strategy.Result.sStatus = 'Not-Applicable'
|
||||
Strategy.Result.nCompletionIndex = 0
|
||||
Strategy.Result.dMRR = 0
|
||||
Strategy.Result.nQuality = 0
|
||||
Strategy.Result.sInfo = 'Split not possible'
|
||||
end
|
||||
|
||||
return Machining
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function HEADCUT.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
Strategy = LoadStrategyParameters( CustomParameters)
|
||||
local bAreAllMachiningsAdded = true
|
||||
local Splitting = {}
|
||||
local AuxiliaryData = {}
|
||||
|
||||
Strategy.sSplitStrategy = GetSplitStrategy( Proc, Part)
|
||||
if bAddMachining then
|
||||
-- inserimento smussi su spigoli del taglio
|
||||
if Strategy.Parameters.bMakeChamfer then
|
||||
MakeChamfer()
|
||||
end
|
||||
|
||||
local OptionalParameters = {}
|
||||
-- applico le lavorazioni
|
||||
----------------------------------------------------------------------------------
|
||||
if Strategy.sSplitStrategy.sTypeMachining == 'BladeSideSingle' then
|
||||
OptionalParameters = {}
|
||||
OptionalParameters.nToolIndex = Strategy.sSplitStrategy[1].ToolInfo.nToolIndex
|
||||
OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_BACK
|
||||
OptionalParameters.sDepth = 0
|
||||
|
||||
-- TODO gestire lavorazione a cubetti
|
||||
|
||||
local EdgeToMachine = GetEdgeToMachine( Proc, -Y_AX())
|
||||
-- approccio e retrazione
|
||||
OptionalParameters.LeadIn, OptionalParameters.LeadOut = CalculateLeadInOut( Splitting, EdgeToMachine)
|
||||
Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters)
|
||||
MachiningLib.AddNewMachining( Proc, Splitting, AuxiliaryData)
|
||||
----------------------------------------------------------------------------------
|
||||
elseif Strategy.sSplitStrategy.sTypeMachining == 'BladeSideDouble' then
|
||||
OptionalParameters = {}
|
||||
OptionalParameters.nToolIndex = Strategy.sSplitStrategy[1].ToolInfo.nToolIndex
|
||||
-- Taglio lato frontale
|
||||
OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_BACK
|
||||
OptionalParameters.sDepth = 0
|
||||
OptionalParameters.dRadialOffset = ( Part.dWidth - BeamData.CUT_EXTRA) / 2
|
||||
|
||||
-- TODO gestire lavorazione a cubetti
|
||||
|
||||
local EdgeToMachine = GetEdgeToMachine( Proc, -Y_AX())
|
||||
-- approccio e retrazione
|
||||
OptionalParameters.LeadIn, OptionalParameters.LeadOut = CalculateLeadInOut( Splitting, EdgeToMachine)
|
||||
Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters)
|
||||
MachiningLib.AddNewMachining( Proc, Splitting, AuxiliaryData)
|
||||
|
||||
-- Taglio lato dietro
|
||||
OptionalParameters = {}
|
||||
Splitting = {}
|
||||
AuxiliaryData = {}
|
||||
OptionalParameters.nToolIndex = Strategy.sSplitStrategy[1].ToolInfo.nToolIndex
|
||||
OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_FRONT
|
||||
OptionalParameters.sDepth = 0
|
||||
OptionalParameters.dRadialOffset = ( Part.dWidth - BeamData.CUT_EXTRA) / 2
|
||||
|
||||
-- TODO gestire lavorazione a cubetti
|
||||
|
||||
EdgeToMachine = GetEdgeToMachine( Proc, Y_AX())
|
||||
-- approccio e retrazione
|
||||
OptionalParameters.LeadIn, OptionalParameters.LeadOut = CalculateLeadInOut( Splitting, EdgeToMachine)
|
||||
Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters)
|
||||
MachiningLib.AddNewMachining( Proc, Splitting, AuxiliaryData)
|
||||
----------------------------------------------------------------------------------
|
||||
elseif Strategy.sSplitStrategy.sTypeMachining == 'BladeHorizontalSingle' then
|
||||
OptionalParameters = {}
|
||||
OptionalParameters.nToolIndex = Strategy.sSplitStrategy[1].ToolInfo.nToolIndex
|
||||
OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_DOWN
|
||||
OptionalParameters.sDepth = 0
|
||||
OptionalParameters.dRadialOffset = -BeamData.CUT_EXTRA
|
||||
|
||||
-- TODO gestire lavorazione a cubetti
|
||||
|
||||
local EdgeToMachine = GetEdgeToMachine( Proc, Z_AX())
|
||||
-- approccio e retrazione
|
||||
OptionalParameters.LeadIn, OptionalParameters.LeadOut = CalculateLeadInOut( Splitting, EdgeToMachine)
|
||||
Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters)
|
||||
MachiningLib.AddNewMachining( Proc, Splitting, AuxiliaryData)
|
||||
----------------------------------------------------------------------------------
|
||||
elseif Strategy.sSplitStrategy.sTypeMachining == 'BladeHorizontalDouble' then
|
||||
OptionalParameters = {}
|
||||
OptionalParameters.nToolIndex = Strategy.sSplitStrategy[1].ToolInfo.nToolIndex
|
||||
-- Taglio lato frontale
|
||||
OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_DOWN
|
||||
OptionalParameters.sDepth = 0
|
||||
local dExtraMaxMat = ( Strategy.sSplitStrategy[1].ToolInfo.dMaxMatBladeFromTop + Strategy.sSplitStrategy[2].ToolInfo.dMaxMatBladeFromDown - Part.dHeight - BeamData.CUT_EXTRA) / 2
|
||||
OptionalParameters.dRadialOffset = Part.dHeight - Strategy.sSplitStrategy[1].ToolInfo.dMaxMatBladeFromTop + dExtraMaxMat
|
||||
|
||||
-- TODO gestire lavorazione a cubetti
|
||||
|
||||
local EdgeToMachine = GetEdgeToMachine( Proc, Z_AX())
|
||||
-- approccio e retrazione
|
||||
OptionalParameters.LeadIn, OptionalParameters.LeadOut = CalculateLeadInOut( Splitting, EdgeToMachine)
|
||||
Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters)
|
||||
MachiningLib.AddNewMachining( Proc, Splitting, AuxiliaryData)
|
||||
|
||||
-- Taglio lato dietro
|
||||
OptionalParameters = {}
|
||||
Splitting = {}
|
||||
AuxiliaryData = {}
|
||||
OptionalParameters.nToolIndex = Strategy.sSplitStrategy[2].ToolInfo.nToolIndex
|
||||
OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_TOP
|
||||
OptionalParameters.sDepth = 0
|
||||
OptionalParameters.dRadialOffset = Part.dHeight - Strategy.sSplitStrategy[2].ToolInfo.dMaxMatBladeFromDown + dExtraMaxMat
|
||||
|
||||
-- TODO gestire lavorazione a cubetti
|
||||
|
||||
EdgeToMachine = GetEdgeToMachine( Proc, -Z_AX())
|
||||
-- approccio e retrazione
|
||||
OptionalParameters.LeadIn, OptionalParameters.LeadOut = CalculateLeadInOut( Splitting, EdgeToMachine)
|
||||
Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters)
|
||||
MachiningLib.AddNewMachining( Proc, Splitting, AuxiliaryData)
|
||||
----------------------------------------------------------------------------------
|
||||
elseif Strategy.sSplitStrategy.sTypeMachining == 'ChainSawHorizontal' then
|
||||
; -- TODO
|
||||
----------------------------------------------------------------------------------
|
||||
elseif Strategy.sSplitStrategy.sTypeMachining == 'ChainSawSideSingle' then
|
||||
; -- TODO
|
||||
----------------------------------------------------------------------------------
|
||||
elseif Strategy.sSplitStrategy.sTypeMachining == 'ChainSawSideDouble' then
|
||||
; -- TODO
|
||||
----------------------------------------------------------------------------------
|
||||
elseif Strategy.sSplitStrategy.sTypeMachining == 'ChainSawPlusBlade' then
|
||||
; -- TODO
|
||||
----------------------------------------------------------------------------------
|
||||
elseif Strategy.sSplitStrategy.sTypeMachining == 'Mill' then
|
||||
; -- TODO
|
||||
----------------------------------------------------------------------------------
|
||||
end
|
||||
|
||||
return bAreAllMachiningsAdded, Strategy.Result
|
||||
else
|
||||
return nil, Strategy.Result
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
|
||||
return HEADCUT
|
||||
@@ -0,0 +1,12 @@
|
||||
-- Parametri configurabili da cliente per strategia: HEADCUT
|
||||
|
||||
local HEADCUTData = {
|
||||
sStrategyId = 'HEADCUT',
|
||||
Parameters = {
|
||||
{ sName = 'bMakeChamfer', sValue = 'false', sDescriptionShort = 'Execute Chamfer', sDescriptionLong = 'Use the V-Mill to execute chamfers on cut-edges', sType = 'b', sMessageId = '', sMinUserLevel = '1'},
|
||||
{ sName = 'bForceChainSaw', sValue = 'false', sDescriptionShort = 'Force to use chain saw', sDescriptionLong = 'Force to use chain saw', sType = 'b', sMessageId = '', sMinUserLevel = '1'},
|
||||
{ sName = 'bFinishWithMill', sValue = 'true', sDescriptionShort = 'Finish with mill', sDescriptionLong = 'Use a mill to finish the surface if split with chain saw', sType = 'b', sMessageId = '', sMinUserLevel = '1'}
|
||||
}
|
||||
}
|
||||
|
||||
return HEADCUTData
|
||||
@@ -0,0 +1,425 @@
|
||||
-- Strategia: SPLITCUT
|
||||
-- Descrizione
|
||||
-- Taglio di separazione
|
||||
-- Feature: SplitCut
|
||||
|
||||
-- carico librerie
|
||||
local BeamLib = require( 'BeamLib')
|
||||
local BeamData = require( 'BeamData')
|
||||
local MachiningLib = require( 'MachiningLib')
|
||||
local FeatureLib = require( 'FeatureLib')
|
||||
-- strategie di base
|
||||
local FaceByBlade = require('FACEBYBLADE')
|
||||
|
||||
-- Tabella per definizione modulo
|
||||
local SPLITCUT = {}
|
||||
local Strategy = {}
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function LoadStrategyParameters( CustomParameters)
|
||||
local StrategyLib = {}
|
||||
StrategyLib.Config = require( 'SPLITCUT\\SPLITCUTConfig')
|
||||
Strategy.sName = StrategyLib.Config.sStrategyId
|
||||
CustomParameters = BeamLib.GetUpdateCustomParameters( CustomParameters, StrategyLib.Config.Parameters)
|
||||
Strategy.Parameters = BeamLib.LoadCustomParametersInStrategy( CustomParameters)
|
||||
Strategy.Result = {}
|
||||
Strategy.Machining = {}
|
||||
Strategy.Result.sInfo = ''
|
||||
return Strategy
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function CalculateLeadInOut( Machining, EdgeToMachine)
|
||||
|
||||
local LeadIn = {}
|
||||
local LeadOut = {}
|
||||
LeadIn.dStartAddLength = 0
|
||||
LeadOut.dEndAddLength = 0
|
||||
LeadIn.nType = MCH_MILL_LI.LINEAR
|
||||
LeadOut.nType = MCH_MILL_LI.LINEAR
|
||||
LeadIn.dTangentDistance = 0
|
||||
LeadOut.dTangentDistance = 0
|
||||
-- elevazione sempre in negativo
|
||||
if EdgeToMachine.Elev < 10 * GEO.EPS_SMALL then
|
||||
LeadIn.dPerpDistance = BeamData.CUT_SIC - EdgeToMachine.Elev
|
||||
LeadOut.dPerpDistance = BeamData.CUT_SIC - EdgeToMachine.Elev
|
||||
else
|
||||
LeadIn.dPerpDistance = BeamData.CUT_SIC
|
||||
LeadOut.dPerpDistance = BeamData.CUT_SIC
|
||||
end
|
||||
LeadIn.dElevation = 0
|
||||
LeadOut.dElevation = 0
|
||||
LeadIn.dCompLength = 0
|
||||
LeadOut.dCompLength = 0
|
||||
LeadIn.dStartAddLength = BeamData.CUT_EXTRA
|
||||
LeadOut.dEndAddLength = BeamData.CUT_EXTRA
|
||||
|
||||
return LeadIn, LeadOut
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function MakeChamfer()
|
||||
-- TODO funzionalità da aggiungere
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function GetEdgeToMachine( Proc, vtEdge)
|
||||
local Edge
|
||||
for i = 1, #Proc.Faces[1].Edges do
|
||||
if AreSameVectorApprox( Proc.Faces[1].Edges[i].Norm, vtEdge) then
|
||||
Edge = Proc.Faces[1].Edges[i]
|
||||
end
|
||||
end
|
||||
return Edge
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function GetSplitStrategy( Proc, Part)
|
||||
-- se non sono stati caricati i parametri, si ricaricano
|
||||
if not Strategy.Parameters then
|
||||
Strategy = LoadStrategyParameters()
|
||||
end
|
||||
|
||||
-- separazione solo se esiste grezzo successivo con pezzi o scaricabile
|
||||
local nNextRawId = EgtGetNextRawPart( Part.idRaw)
|
||||
Strategy.bSplit = ( nNextRawId and ( EgtGetPartInRawPartCount( nNextRawId) > 0 or EgtGetRawPartBBox( nNextRawId):getDimX() >= BeamData.dMinRaw))
|
||||
|
||||
-- imposto paraemtri di ricerca utensile in base a topologia
|
||||
local Machining = {}
|
||||
-- sTypeMachining = BladeSideSingle\ BladeSideDouble\ BladeHorizontalSingle\ BladeHorizontalDouble\ ChainSawHorizontal\ ChainSawSideSingle\ ChainSawSideDouble\ ChainSawPlusBlade\ Mill\ None
|
||||
Machining.sTypeMachining = 'None'
|
||||
local Splitting = {}
|
||||
local ToolSearchParameters = {}
|
||||
ToolSearchParameters.vtToolDirection = Proc.Faces[1].vtN
|
||||
|
||||
|
||||
-- ===== RICERCA UTENSILE =====
|
||||
-- cerco lama sopra
|
||||
Splitting.bIsApplicable = false
|
||||
ToolSearchParameters.bAllowTopHead = true
|
||||
ToolSearchParameters.bAllowBottomHead = false
|
||||
Splitting.ToolInfo = {}
|
||||
Splitting.ToolInfo = MachiningLib.FindBlade( Proc, ToolSearchParameters)
|
||||
if Splitting.ToolInfo.nToolIndex then
|
||||
Splitting.bIsApplicable = true
|
||||
local ParametersMRR = {}
|
||||
ParametersMRR.nToolIndex = Splitting.ToolInfo.nToolIndex
|
||||
Splitting.dMRR = MachiningLib.GetToolMRR( ParametersMRR)
|
||||
end
|
||||
table.insert( Machining, Splitting)
|
||||
|
||||
-- cerco lama sotto
|
||||
Splitting = {}
|
||||
Splitting.bIsApplicable = false
|
||||
ToolSearchParameters.bAllowTopHead = false
|
||||
ToolSearchParameters.bAllowBottomHead = true
|
||||
Splitting.ToolInfo = {}
|
||||
Splitting.ToolInfo = MachiningLib.FindBlade( Proc, ToolSearchParameters)
|
||||
if Splitting.ToolInfo.nToolIndex then
|
||||
Splitting.bIsApplicable = true
|
||||
local ParametersMRR = {}
|
||||
ParametersMRR.nToolIndex = Splitting.ToolInfo.nToolIndex
|
||||
Splitting.dMRR = MachiningLib.GetToolMRR( ParametersMRR)
|
||||
end
|
||||
table.insert( Machining, Splitting)
|
||||
|
||||
-- cerco motosega
|
||||
Splitting = {}
|
||||
Splitting.bIsApplicable = false
|
||||
table.insert( Machining, Splitting)
|
||||
|
||||
-- cerco fresa
|
||||
Splitting = {}
|
||||
Splitting.bIsApplicable = false
|
||||
table.insert( Machining, Splitting)
|
||||
|
||||
-- ===== SCELTA LAVORAZIONI =====
|
||||
-- forzature da parametri
|
||||
if Strategy.Parameters.bForceChainSaw then
|
||||
Machining[1].bIsApplicable = false
|
||||
Machining[2].bIsApplicable = false
|
||||
end
|
||||
|
||||
-- setto valori di default. Impossibile che taglio di separazione sia incompleto
|
||||
Strategy.Result.sStatus = 'Completed'
|
||||
Strategy.Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( 100)
|
||||
Strategy.Result.dMRR = 1
|
||||
|
||||
-- correzioni sul massimo materiale lama, considerando ingombri vari
|
||||
local dMaxMatBladeSideSingle
|
||||
local dMaxMatBladeSideDouble
|
||||
local dMaxMatBladeHorizontalSingle
|
||||
local dMaxMatBladeHorizontalDouble
|
||||
if Machining[1].bIsApplicable then
|
||||
local dMaxMat = TOOLS[Machining[1].ToolInfo.nToolIndex].dMaxMaterial
|
||||
local dRadius = TOOLS[Machining[1].ToolInfo.nToolIndex].dDiameter / 2
|
||||
local sHead = TOOLS[Machining[1].ToolInfo.nToolIndex].sHead
|
||||
-- se taglio di fianco disponibile, si controlla il massimo materiale reale. Per pezzi alti, bisogna controllare anche l'ingombro asse Z nelle 4 direzioni.
|
||||
if Part.dHeight < BeamData.MIN_DIM_HBEAM then
|
||||
dMaxMat = min( dMaxMat, BeamData.MAX_DIM_HTCUT)
|
||||
dMaxMatBladeSideSingle = dMaxMat
|
||||
dMaxMatBladeSideDouble = dMaxMat * 2
|
||||
else
|
||||
if BeamData.GetMaxMatReductionBladeCut then
|
||||
dMaxMatBladeSideSingle = min( max( dRadius - BeamData.GetMaxMatReductionBladeCut( sHead, Y_AX()), dRadius - BeamData.GetMaxMatReductionBladeCut( sHead, -Y_AX())),
|
||||
TOOLS[Machining[1].ToolInfo.nToolIndex].dMaxMaterial)
|
||||
dMaxMatBladeSideDouble = dRadius - BeamData.GetMaxMatReductionBladeCut( sHead, Y_AX()) + dRadius - BeamData.GetMaxMatReductionBladeCut( sHead, -Y_AX())
|
||||
else
|
||||
dMaxMatBladeSideSingle = abs( BeamData.MAX_DIM_HTCUT_HBEAM)
|
||||
dMaxMatBladeSideDouble = abs( BeamData.MAX_DIM_HTCUT_HBEAM) * 2
|
||||
end
|
||||
end
|
||||
-- se taglio orizzontale
|
||||
if BeamData.GetMaxMatReductionBladeCut then
|
||||
dMaxMatBladeHorizontalSingle = min( TOOLS[Machining[1].ToolInfo.nToolIndex].dMaxMaterial, dRadius - BeamData.GetMaxMatReductionBladeCut( TOOLS[Machining[1].ToolInfo.nToolIndex].sHead, -Z_AX()))
|
||||
else
|
||||
dMaxMatBladeHorizontalSingle = TOOLS[Machining[1].ToolInfo.nToolIndex].dMaxMaterial
|
||||
end
|
||||
end
|
||||
if Machining[2].bIsApplicable then
|
||||
if BeamData.GetMaxMatReductionBladeCut then
|
||||
local dRadius = TOOLS[Machining[2].ToolInfo.nToolIndex].dDiameter / 2
|
||||
dMaxMatBladeHorizontalDouble = min( TOOLS[Machining[2].ToolInfo.nToolIndex].dMaxMaterial, dRadius - BeamData.GetMaxMatReductionBladeCut( TOOLS[Machining[2].ToolInfo.nToolIndex].sHead, Z_AX()))
|
||||
else
|
||||
dMaxMatBladeHorizontalDouble = TOOLS[Machining[2].ToolInfo.nToolIndex].dMaxMaterial
|
||||
end
|
||||
end
|
||||
|
||||
-- TODO considerare di tagliare con il massimo materiale possibile per non salire troppo in Z (macchine tipo PF), oppure non scendere troppo (tipo Kairos)
|
||||
-- BladeSideSingle (taglio di lama singolo di fianco)
|
||||
if Machining[1].bIsApplicable and ( dMaxMatBladeSideSingle - BeamData.CUT_EXTRA) > Part.dWidth + 10 * GEO.EPS_SMALL then
|
||||
Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'Blade')
|
||||
Machining.sTypeMachining = 'BladeSideSingle'
|
||||
Machining[2].bIsApplicable = false
|
||||
Machining[3].bIsApplicable = false
|
||||
Machining[4].bIsApplicable = false
|
||||
return Machining
|
||||
-- TODO considerare di tagliare con il massimo materiale possibile per non salire troppo in Z (macchine tipo PF), oppure non scendere troppo (tipo Kairos)
|
||||
-- BladeSideDouble (taglio di lama doppio di fianco)
|
||||
elseif Machining[1].bIsApplicable and ( dMaxMatBladeSideDouble - BeamData.CUT_EXTRA) > Part.dWidth + 10 * GEO.EPS_SMALL then
|
||||
Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'Blade')
|
||||
Strategy.Result.dMRR = Strategy.Result.dMRR/2
|
||||
Machining.sTypeMachining = 'BladeSideDouble'
|
||||
Machining[2].bIsApplicable = false
|
||||
Machining[3].bIsApplicable = false
|
||||
Machining[4].bIsApplicable = false
|
||||
return Machining
|
||||
-- BladeHorizontalSingle (taglio di lama singolo orizzontale)
|
||||
elseif Machining[1].bIsApplicable and ( dMaxMatBladeHorizontalSingle - BeamData.CUT_EXTRA) > Part.dHeight + 10 * GEO.EPS_SMALL then
|
||||
Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'Blade')
|
||||
Machining.sTypeMachining = 'BladeHorizontalSingle'
|
||||
Machining[2].bIsApplicable = false
|
||||
Machining[3].bIsApplicable = false
|
||||
Machining[4].bIsApplicable = false
|
||||
return Machining
|
||||
-- BladeHorizontalDouble (taglio di lama doppio orizzontale)
|
||||
elseif Machining[1].bIsApplicable and Machining[2].bIsApplicable and
|
||||
( dMaxMatBladeHorizontalSingle + dMaxMatBladeHorizontalDouble - BeamData.CUT_EXTRA) > Part.dHeight + 10 * GEO.EPS_SMALL then
|
||||
Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'Blade')
|
||||
Strategy.Result.dMRR = Strategy.Result.dMRR/2
|
||||
Machining.sTypeMachining = 'BladeHorizontalDouble'
|
||||
Machining[1].ToolInfo.dMaxMatBladeFromTop = dMaxMatBladeHorizontalSingle
|
||||
Machining[2].ToolInfo.dMaxMatBladeFromDown = dMaxMatBladeHorizontalDouble
|
||||
Machining[3].bIsApplicable = false
|
||||
Machining[4].bIsApplicable = false
|
||||
return Machining
|
||||
|
||||
-- TODO : casi con motosega da completare
|
||||
-- ChainSawHorizontal (motosega)
|
||||
-- ChainSawSideSingle (motosega)
|
||||
-- ChainSawSideDouble (motosega)
|
||||
-- ChainSawPlusBlade (motosega più lama orizzontale)
|
||||
-- Mill (svuotatura)
|
||||
end
|
||||
|
||||
-- se non ho trovato neanche una lavorazione completa, non posso separare
|
||||
if Machining.sTypeMachining == 'None' then
|
||||
Strategy.Result.sStatus = 'Not-Applicable'
|
||||
Strategy.Result.nCompletionIndex = 0
|
||||
Strategy.Result.dMRR = 0
|
||||
Strategy.Result.nQuality = 0
|
||||
Strategy.Result.sInfo = 'Split not possible'
|
||||
end
|
||||
|
||||
return Machining
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function SPLITCUT.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
Strategy = LoadStrategyParameters( CustomParameters)
|
||||
local bAreAllMachiningsAdded = true
|
||||
local Splitting = {}
|
||||
local AuxiliaryData = {}
|
||||
|
||||
Strategy.sSplitStrategy = GetSplitStrategy( Proc, Part)
|
||||
if bAddMachining then
|
||||
-- inserimento smussi su spigoli del taglio
|
||||
if Strategy.Parameters.bMakeChamfer then
|
||||
MakeChamfer()
|
||||
end
|
||||
|
||||
local OptionalParameters = {}
|
||||
-- applico le lavorazioni
|
||||
----------------------------------------------------------------------------------
|
||||
if Strategy.sSplitStrategy.sTypeMachining == 'BladeSideSingle' then
|
||||
OptionalParameters = {}
|
||||
OptionalParameters.nToolIndex = Strategy.sSplitStrategy[1].ToolInfo.nToolIndex
|
||||
OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_BACK
|
||||
OptionalParameters.sDepth = 0
|
||||
|
||||
-- TODO gestire lavorazione a cubetti
|
||||
|
||||
if Strategy.bSplit then
|
||||
OptionalParameters.sUserNotes = 'Split;'
|
||||
else
|
||||
OptionalParameters.sUserNotes = 'Cut;'
|
||||
end
|
||||
AuxiliaryData.bAddNewPhase = true
|
||||
|
||||
local EdgeToMachine = GetEdgeToMachine( Proc, -Y_AX())
|
||||
-- approccio e retrazione
|
||||
OptionalParameters.LeadIn, OptionalParameters.LeadOut = CalculateLeadInOut( Splitting, EdgeToMachine)
|
||||
Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters)
|
||||
MachiningLib.AddNewMachining( Proc, Splitting, AuxiliaryData)
|
||||
----------------------------------------------------------------------------------
|
||||
elseif Strategy.sSplitStrategy.sTypeMachining == 'BladeSideDouble' then
|
||||
OptionalParameters = {}
|
||||
OptionalParameters.nToolIndex = Strategy.sSplitStrategy[1].ToolInfo.nToolIndex
|
||||
-- Taglio lato frontale
|
||||
OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_BACK
|
||||
OptionalParameters.sDepth = 0
|
||||
OptionalParameters.dRadialOffset = ( Part.dWidth - BeamData.CUT_EXTRA) / 2
|
||||
|
||||
-- TODO gestire lavorazione a cubetti
|
||||
|
||||
if Strategy.bSplit then
|
||||
OptionalParameters.sUserNotes = 'PreSplit;'
|
||||
else
|
||||
OptionalParameters.sUserNotes = 'PreCut;'
|
||||
end
|
||||
|
||||
local EdgeToMachine = GetEdgeToMachine( Proc, -Y_AX())
|
||||
-- approccio e retrazione
|
||||
OptionalParameters.LeadIn, OptionalParameters.LeadOut = CalculateLeadInOut( Splitting, EdgeToMachine)
|
||||
Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters)
|
||||
MachiningLib.AddNewMachining( Proc, Splitting, AuxiliaryData)
|
||||
|
||||
-- Taglio lato dietro
|
||||
OptionalParameters = {}
|
||||
Splitting = {}
|
||||
AuxiliaryData = {}
|
||||
OptionalParameters.nToolIndex = Strategy.sSplitStrategy[1].ToolInfo.nToolIndex
|
||||
OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_FRONT
|
||||
OptionalParameters.sDepth = 0
|
||||
OptionalParameters.dRadialOffset = ( Part.dWidth - BeamData.CUT_EXTRA) / 2
|
||||
|
||||
-- TODO gestire lavorazione a cubetti
|
||||
|
||||
if Strategy.bSplit then
|
||||
OptionalParameters.sUserNotes = 'Split;'
|
||||
else
|
||||
OptionalParameters.sUserNotes = 'Cut;'
|
||||
end
|
||||
AuxiliaryData.bAddNewPhase = true
|
||||
|
||||
EdgeToMachine = GetEdgeToMachine( Proc, Y_AX())
|
||||
-- approccio e retrazione
|
||||
OptionalParameters.LeadIn, OptionalParameters.LeadOut = CalculateLeadInOut( Splitting, EdgeToMachine)
|
||||
Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters)
|
||||
MachiningLib.AddNewMachining( Proc, Splitting, AuxiliaryData)
|
||||
----------------------------------------------------------------------------------
|
||||
elseif Strategy.sSplitStrategy.sTypeMachining == 'BladeHorizontalSingle' then
|
||||
OptionalParameters = {}
|
||||
OptionalParameters.nToolIndex = Strategy.sSplitStrategy[1].ToolInfo.nToolIndex
|
||||
OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_DOWN
|
||||
OptionalParameters.sDepth = 0
|
||||
OptionalParameters.dRadialOffset = -BeamData.CUT_EXTRA
|
||||
|
||||
-- TODO gestire lavorazione a cubetti
|
||||
|
||||
if Strategy.bSplit then
|
||||
OptionalParameters.sUserNotes = 'Split;'
|
||||
else
|
||||
OptionalParameters.sUserNotes = 'Cut;'
|
||||
end
|
||||
AuxiliaryData.bAddNewPhase = true
|
||||
|
||||
local EdgeToMachine = GetEdgeToMachine( Proc, Z_AX())
|
||||
-- approccio e retrazione
|
||||
OptionalParameters.LeadIn, OptionalParameters.LeadOut = CalculateLeadInOut( Splitting, EdgeToMachine)
|
||||
Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters)
|
||||
MachiningLib.AddNewMachining( Proc, Splitting, AuxiliaryData)
|
||||
----------------------------------------------------------------------------------
|
||||
elseif Strategy.sSplitStrategy.sTypeMachining == 'BladeHorizontalDouble' then
|
||||
OptionalParameters = {}
|
||||
OptionalParameters.nToolIndex = Strategy.sSplitStrategy[1].ToolInfo.nToolIndex
|
||||
-- Taglio lato frontale
|
||||
OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_DOWN
|
||||
OptionalParameters.sDepth = 0
|
||||
local dExtraMaxMat = ( Strategy.sSplitStrategy[1].ToolInfo.dMaxMatBladeFromTop + Strategy.sSplitStrategy[2].ToolInfo.dMaxMatBladeFromDown - Part.dHeight - BeamData.CUT_EXTRA) / 2
|
||||
OptionalParameters.dRadialOffset = Part.dHeight - Strategy.sSplitStrategy[1].ToolInfo.dMaxMatBladeFromTop + dExtraMaxMat
|
||||
|
||||
-- TODO gestire lavorazione a cubetti
|
||||
|
||||
if Strategy.bSplit then
|
||||
OptionalParameters.sUserNotes = 'PreSplit;'
|
||||
else
|
||||
OptionalParameters.sUserNotes = 'PreCut;'
|
||||
end
|
||||
|
||||
local EdgeToMachine = GetEdgeToMachine( Proc, Z_AX())
|
||||
-- approccio e retrazione
|
||||
OptionalParameters.LeadIn, OptionalParameters.LeadOut = CalculateLeadInOut( Splitting, EdgeToMachine)
|
||||
Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters)
|
||||
MachiningLib.AddNewMachining( Proc, Splitting, AuxiliaryData)
|
||||
|
||||
-- Taglio lato dietro
|
||||
OptionalParameters = {}
|
||||
Splitting = {}
|
||||
AuxiliaryData = {}
|
||||
OptionalParameters.nToolIndex = Strategy.sSplitStrategy[2].ToolInfo.nToolIndex
|
||||
OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_TOP
|
||||
OptionalParameters.sDepth = 0
|
||||
OptionalParameters.dRadialOffset = Part.dHeight - Strategy.sSplitStrategy[2].ToolInfo.dMaxMatBladeFromDown + dExtraMaxMat
|
||||
|
||||
-- TODO gestire lavorazione a cubetti
|
||||
|
||||
if Strategy.bSplit then
|
||||
OptionalParameters.sUserNotes = 'Split;'
|
||||
else
|
||||
OptionalParameters.sUserNotes = 'Cut;'
|
||||
end
|
||||
AuxiliaryData.bAddNewPhase = true
|
||||
|
||||
EdgeToMachine = GetEdgeToMachine( Proc, -Z_AX())
|
||||
-- approccio e retrazione
|
||||
OptionalParameters.LeadIn, OptionalParameters.LeadOut = CalculateLeadInOut( Splitting, EdgeToMachine)
|
||||
Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters)
|
||||
MachiningLib.AddNewMachining( Proc, Splitting, AuxiliaryData)
|
||||
----------------------------------------------------------------------------------
|
||||
elseif Strategy.sSplitStrategy.sTypeMachining == 'ChainSawHorizontal' then
|
||||
; -- TODO
|
||||
----------------------------------------------------------------------------------
|
||||
elseif Strategy.sSplitStrategy.sTypeMachining == 'ChainSawSideSingle' then
|
||||
; -- TODO
|
||||
----------------------------------------------------------------------------------
|
||||
elseif Strategy.sSplitStrategy.sTypeMachining == 'ChainSawSideDouble' then
|
||||
; -- TODO
|
||||
----------------------------------------------------------------------------------
|
||||
elseif Strategy.sSplitStrategy.sTypeMachining == 'ChainSawPlusBlade' then
|
||||
; -- TODO
|
||||
----------------------------------------------------------------------------------
|
||||
elseif Strategy.sSplitStrategy.sTypeMachining == 'Mill' then
|
||||
; -- TODO
|
||||
----------------------------------------------------------------------------------
|
||||
end
|
||||
|
||||
return bAreAllMachiningsAdded, Strategy.Result
|
||||
else
|
||||
return nil, Strategy.Result
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
|
||||
return SPLITCUT
|
||||
@@ -0,0 +1,12 @@
|
||||
-- Parametri configurabili da cliente per strategia: SPLITCUT
|
||||
|
||||
local SPLITCUTData = {
|
||||
sStrategyId = 'SPLITCUT',
|
||||
Parameters = {
|
||||
{ sName = 'bMakeChamfer', sValue = 'false', sDescriptionShort = 'Execute Chamfer', sDescriptionLong = 'Use the V-Mill to execute chamfers on cut-edges', sType = 'b', sMessageId = '', sMinUserLevel = '1'},
|
||||
{ sName = 'bForceChainSaw', sValue = 'false', sDescriptionShort = 'Force to use chain saw', sDescriptionLong = 'Force to use chain saw', sType = 'b', sMessageId = '', sMinUserLevel = '1'},
|
||||
{ sName = 'bFinishWithMill', sValue = 'true', sDescriptionShort = 'Finish with mill', sDescriptionLong = 'Use a mill to finish the surface if split with chain saw', sType = 'b', sMessageId = '', sMinUserLevel = '1'}
|
||||
}
|
||||
}
|
||||
|
||||
return SPLITCUTData
|
||||
@@ -3,10 +3,10 @@
|
||||
local STR0001Data = {
|
||||
sStrategyId = 'STR0001',
|
||||
Parameters = {
|
||||
{ sName = 'dOverMatOnLenght', sValue = '0', sDescription = 'Sovramateriale lunghezza tenone', sType = 'd'},
|
||||
{ sName = 'dOverMatOnRadius', sValue = '0', sDescription = 'Sovramateriale larghezza tenone', sType = 'd'},
|
||||
{ sName = 'nMaxMillingPaths', sValue = '3', sDescription = 'Numero massimo di passaggi di fresatura. Se richiesti più passaggi, si fa svuotatura', sType = 'd'},
|
||||
{ sName = 'bUseDTToolOnPocketing', sValue = 'true', sDescription = 'Utilizza utensile a coda di rondimne per fare svuotatura', sType = 'b'}
|
||||
{ sName = 'dOverMatOnLenght', sNameNge = 'OVM_LENGTH', sValue = '0', sDescription = 'Sovramateriale lunghezza tenone', sType = 'd'},
|
||||
{ sName = 'dOverMatOnRadius', sNameNge = 'OVM_RADIUS', sValue = '0', sDescription = 'Sovramateriale larghezza tenone', sType = 'd'},
|
||||
{ sName = 'nMaxMillingPaths', sNameNge = 'MAX_PATHS', sValue = '3', sDescription = 'Numero massimo di passaggi di fresatura. Se richiesti più passaggi, si fa svuotatura', sType = 'd'},
|
||||
{ sName = 'bUseDTToolOnPocketing', sNameNge = 'ALLOW_DT_POCKET', sValue = 'true', sDescription = 'Utilizza utensile a coda di rondine per fare svuotatura', sType = 'b'}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
local BeamLib = require( 'BeamLib')
|
||||
local BeamData = require( 'BeamData')
|
||||
local MachiningLib = require( 'MachiningLib')
|
||||
local FeatureData = require( 'FeatureData')
|
||||
local FeatureLib = require( 'FeatureLib')
|
||||
|
||||
-- Tabella per definizione modulo
|
||||
local STR0002 = {}
|
||||
@@ -82,13 +82,13 @@ end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function GetBestPocketingStrategy( Proc)
|
||||
-- imposto paraemtri di ricerca utensile in base a topologia
|
||||
-- imposto parametri di ricerca utensile in base a topologia
|
||||
local Machining = {}
|
||||
local Milling = {}
|
||||
local ToolSearchParameters = {}
|
||||
ToolSearchParameters.sMillShape = 'STANDARD'
|
||||
Machining.sTypeMachining = 'None' -- Bottom-Side1-Side2\ Bottom-Side1\ Bottom-Side2\ Side1-Side2\ Bottom\ Side1 \ Side2 \ None
|
||||
Strategy.Result.nQuality = FeatureData.GetFeatureQuality( 'Mill')
|
||||
Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'Mill')
|
||||
|
||||
-- caso speciale Tunnel che non ha faccia bottom
|
||||
if Proc.Topology.sName == 'Tunnel-4-Through' then
|
||||
@@ -134,6 +134,10 @@ local function GetBestPocketingStrategy( Proc)
|
||||
Milling.ToolInfo = {}
|
||||
Milling.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
|
||||
if Milling.ToolInfo.nToolIndex then
|
||||
-- se utensile scelto è su aggregato, ricalcolo la qualità
|
||||
if TOOLS[Milling.ToolInfo.nToolIndex].SetupInfo.bToolOnAggregate then
|
||||
Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'MillOnAggregate')
|
||||
end
|
||||
Milling.bIsApplicable = true
|
||||
local ParametersMRR = {}
|
||||
ParametersMRR.nToolIndex = Milling.ToolInfo.nToolIndex
|
||||
@@ -242,7 +246,7 @@ local function GetBestPocketingStrategy( Proc)
|
||||
if Machining[1].bIsApplicable and Machining[1].ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then
|
||||
Machining.sTypeMachining = 'Bottom'
|
||||
Strategy.Result.sStatus = 'Completed'
|
||||
Strategy.Result.nCompletionIndex = FeatureData.GetFeatureCompletionIndex( 100)
|
||||
Strategy.Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( 100)
|
||||
Strategy.Result.dMRR = Machining[1].dMRR
|
||||
Machining[1].ToolInfo.dResidualDepth = 0
|
||||
Machining[2].bIsApplicable = false
|
||||
@@ -253,7 +257,7 @@ local function GetBestPocketingStrategy( Proc)
|
||||
elseif Proc.Topology.sName == 'Rabbet-2-Through' and Machining[2].bIsApplicable and Machining[2].ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then
|
||||
Machining.sTypeMachining = 'Bottom2'
|
||||
Strategy.Result.sStatus = 'Completed'
|
||||
Strategy.Result.nCompletionIndex = FeatureData.GetFeatureCompletionIndex( 100)
|
||||
Strategy.Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( 100)
|
||||
Strategy.Result.dMRR = Machining[2].dMRR
|
||||
Machining[2].ToolInfo.dResidualDepth = 0
|
||||
Machining[1].bIsApplicable = false
|
||||
@@ -264,7 +268,7 @@ local function GetBestPocketingStrategy( Proc)
|
||||
elseif Machining[3].bIsApplicable and Machining[3].ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then
|
||||
Machining.sTypeMachining = 'Side1'
|
||||
Strategy.Result.sStatus = 'Completed'
|
||||
Strategy.Result.nCompletionIndex = FeatureData.GetFeatureCompletionIndex( 100)
|
||||
Strategy.Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( 100)
|
||||
Strategy.Result.dMRR = Machining[3].dMRR
|
||||
if Proc.MainFaces.TunnelAddedFaces then
|
||||
Machining[3].ToolInfo.dResidualDepth = -( Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].dElevation + BeamData.MILL_OVERLAP)
|
||||
@@ -279,7 +283,7 @@ local function GetBestPocketingStrategy( Proc)
|
||||
elseif Machining[4].bIsApplicable and Machining[4].ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then
|
||||
Machining.sTypeMachining = 'Side2'
|
||||
Strategy.Result.sStatus = 'Completed'
|
||||
Strategy.Result.nCompletionIndex = FeatureData.GetFeatureCompletionIndex( 100)
|
||||
Strategy.Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( 100)
|
||||
Strategy.Result.dMRR = Machining[4].dMRR
|
||||
if Proc.MainFaces.TunnelAddedFaces then
|
||||
Machining[4].ToolInfo.dResidualDepth = -( Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].dElevation + BeamData.MILL_OVERLAP)
|
||||
@@ -297,7 +301,7 @@ local function GetBestPocketingStrategy( Proc)
|
||||
Strategy.Result.sStatus = 'Completed'
|
||||
Machining[3].ToolInfo.dResidualDepth = Machining[3].ToolInfo.dResidualDepth - Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].dElevation
|
||||
Machining[4].ToolInfo.dResidualDepth = -Machining[3].ToolInfo.dResidualDepth - BeamData.MILL_OVERLAP
|
||||
Strategy.Result.nCompletionIndex = FeatureData.GetFeatureCompletionIndex( 100)
|
||||
Strategy.Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( 100)
|
||||
Strategy.Result.dMRR = ( Machining[3].dMRR + Machining[4].dMRR) / 2
|
||||
Machining[1].bIsApplicable = false
|
||||
Machining[2].bIsApplicable = false
|
||||
@@ -330,7 +334,7 @@ local function GetBestPocketingStrategy( Proc)
|
||||
end
|
||||
|
||||
local dMachinedPrercentage = CalcMachinedPercentage( Proc, Machining)
|
||||
Strategy.Result.nCompletionIndex = FeatureData.GetFeatureCompletionIndex( dMachinedPrercentage)
|
||||
Strategy.Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( dMachinedPrercentage)
|
||||
Strategy.Result.sInfo = 'Machining not complete, left ' .. tostring( 100 - ceil( dMachinedPrercentage)) .. '%'
|
||||
|
||||
-- se non ho trovato neanche una lavorazione
|
||||
@@ -346,142 +350,53 @@ local function GetBestPocketingStrategy( Proc)
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function VerifySplitMachiningNeeded( Proc, Part)
|
||||
local function GetSplitSurfaces( Proc, Part)
|
||||
local vAddId = {}
|
||||
local vAddIdTunnel = {}
|
||||
local bSplit
|
||||
|
||||
-- la lunghezza richiede spezzatura
|
||||
if Proc.b3Box:getDimX() > BeamData.LONGCUT_MAXLEN or Proc.b3Box:getDimX() > 0.7 * Part.b3Solid:getDimX() then
|
||||
bSplit = true
|
||||
else
|
||||
bSplit = false
|
||||
local nAddGrpId = BeamLib.GetAddGroup( Part.id)
|
||||
local nOriginalTmIdTunnel = GDB_ID.NULL
|
||||
if Proc.MainFaces.TunnelAddedFaces then
|
||||
nOriginalTmIdTunnel = Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.id
|
||||
end
|
||||
|
||||
-- la lunghezza richiede spezzatura
|
||||
if ( bSplit) then
|
||||
-- recupero gruppo per geometria aggiuntiva
|
||||
local nAddGrpId = BeamLib.GetAddGroup( Part.id)
|
||||
local bStartLeft, bStartRight
|
||||
local nIdTunnel = nil
|
||||
if Proc.MainFaces.TunnelAddedFaces then
|
||||
nIdTunnel = Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.id
|
||||
end
|
||||
-- recupero punti di spezzatura - da destra a sinistra
|
||||
local vFeatureSplittingPoints = FeatureLib.GetFeatureSplittingPoints( Proc, Part)
|
||||
|
||||
-- se feature inizia al di sotto del limite sinistro (coda)
|
||||
if Proc.b3Box:getMin():getX() < Part.b3Solid:getMin():getX() + BeamData.LONGCUT_ENDLEN then
|
||||
bStartLeft = true
|
||||
end
|
||||
-- se feature inizia al di sotto del limite destro (testa)
|
||||
if Proc.b3Box:getMax():getX() > Part.b3Solid:getMax():getX() - BeamData.LONGCUT_ENDLEN then
|
||||
bStartRight = true
|
||||
end
|
||||
|
||||
-- recupero utensile con massimo diametro
|
||||
local dMaxDiam = 30
|
||||
for t = 1, #Strategy.Machining do
|
||||
if Strategy.Machining[t].bIsApplicable then
|
||||
dMaxDiam = min( dMaxDiam, TOOLS[Strategy.Machining[t].ToolInfo.nToolIndex].dDiameter)
|
||||
end
|
||||
end
|
||||
-- salvo valori
|
||||
local dNewMinX = Proc.b3Box:getMin():getX()
|
||||
local dNewMaxX = Proc.b3Box:getMax():getX()
|
||||
local dNewRest = Proc.b3Box:getDimX()
|
||||
|
||||
-- creo primo spezzone sulla sinistra
|
||||
if bStartLeft then
|
||||
local AddId = EgtCopyGlob( Proc.id, nAddGrpId) or GDB_ID.NULL
|
||||
-- copio faccia tunnel
|
||||
local AddIdTunnel = EgtCopyGlob( nIdTunnel, nAddGrpId) or GDB_ID.NULL
|
||||
|
||||
-- decido punto spezzatura verso la coda
|
||||
if Proc.b3Box:getDimX() > BeamData.LONGCUT_ENDLEN * 2 then
|
||||
dNewMinX = max( Part.b3Solid:getMin():getX() + BeamData.LONGCUT_ENDLEN, Proc.b3Box:getMin():getX() + dMaxDiam * 3)
|
||||
else
|
||||
-- se pezzo abbastanza piccolo, spezzo in mezzo al 'pezzo + grezzo restante'
|
||||
if Part.dRestLength + Part.b3Solid:getDimX() < BeamData.dMinRaw * 1.5 then
|
||||
dNewMinX = Part.b3Solid:getMax():getX() - ( ( Part.dRestLength + Part.b3Solid:getDimX()) / 2)
|
||||
else
|
||||
dNewMinX = max( Proc.b3Box:getMin():getX() + ( BeamData.dMinRaw)/2 + 150, Part.b3Solid:getMax():getX() - BeamData.LONGCUT_ENDLEN)
|
||||
end
|
||||
end
|
||||
|
||||
local ptOn = Point3d( dNewMinX, 0, 0)
|
||||
dNewRest = abs( dNewMaxX - dNewMinX)
|
||||
-- taglio della superficie lato sinistro
|
||||
EgtCutSurfTmPlane( AddId, ptOn, X_AX(), true, GDB_RT.GLOB)
|
||||
EgtCutSurfTmPlane( AddIdTunnel, ptOn, X_AX(), true, GDB_RT.GLOB)
|
||||
-- eseguo inserimento
|
||||
table.insert( vAddId, AddId)
|
||||
table.insert( vAddIdTunnel, AddIdTunnel)
|
||||
end
|
||||
-- creo spezzone sulla destra
|
||||
if bStartRight then
|
||||
local AddId = EgtCopyGlob( Proc.id, nAddGrpId) or GDB_ID.NULL
|
||||
-- copio faccia tunnel
|
||||
local AddIdTunnel = EgtCopyGlob( nIdTunnel, nAddGrpId) or GDB_ID.NULL
|
||||
dNewMaxX = min( ( Proc.b3Box:getMax():getX() - dMaxDiam * 3), Part.b3Solid:getMax():getX() - BeamData.LONGCUT_ENDLEN)
|
||||
if dNewMaxX - dNewMinX < 500 * GEO.EPS_SMALL then
|
||||
dNewMaxX = dNewMinX - BeamData.MILL_OVERLAP
|
||||
dNewRest = 0
|
||||
else
|
||||
dNewRest = dNewMaxX - dNewMinX
|
||||
end
|
||||
local ptOn = Point3d( dNewMaxX, 0, 0)
|
||||
-- taglio della superficie lato destro
|
||||
EgtCutSurfTmPlane( AddId, ptOn, -X_AX(), true, GDB_RT.GLOB)
|
||||
EgtCutSurfTmPlane( AddIdTunnel, ptOn, -X_AX(), true, GDB_RT.GLOB)
|
||||
-- eseguo inserimento
|
||||
table.insert( vAddId, 1, AddId)
|
||||
table.insert( vAddIdTunnel, AddIdTunnel)
|
||||
end
|
||||
-- lavoro il restante
|
||||
if dNewRest > 0 then
|
||||
local nSplitParts = max( ceil( dNewRest / BeamData.LONGCUT_MAXLEN + 10 * GEO.EPS_SMALL), 1)
|
||||
local dSplitPartsLen = dNewRest / nSplitParts
|
||||
for i = 1, nSplitParts do
|
||||
local AddId = EgtCopyGlob( Proc.id, nAddGrpId) or GDB_ID.NULL
|
||||
-- copio faccia tunnel
|
||||
local AddIdTunnel = EgtCopyGlob( nIdTunnel, nAddGrpId) or GDB_ID.NULL
|
||||
local ptOn
|
||||
-- se un solo spezzone, prendo punto massimo e minimo
|
||||
if nSplitParts == 1 then
|
||||
ptOn = Point3d( dNewMinX, 0, 0)
|
||||
-- taglio della superficie lato sinistro
|
||||
EgtCutSurfTmPlane( AddId, ptOn, -X_AX(), true, GDB_RT.GLOB)
|
||||
EgtCutSurfTmPlane( AddIdTunnel, ptOn, -X_AX(), true, GDB_RT.GLOB)
|
||||
ptOn = Point3d( dNewMaxX, 0, 0)
|
||||
-- taglio della superficie lato destro
|
||||
EgtCutSurfTmPlane( AddId, ptOn, X_AX(), true, GDB_RT.GLOB)
|
||||
EgtCutSurfTmPlane( AddIdTunnel, ptOn, X_AX(), true, GDB_RT.GLOB)
|
||||
else
|
||||
-- eseguo trim sinistro
|
||||
if i ~= 1 or bStartLeft then
|
||||
ptOn = Point3d( dNewMinX, 0, 0)
|
||||
-- taglio della superficie lato sinistro
|
||||
EgtCutSurfTmPlane( AddId, ptOn, -X_AX(), true, GDB_RT.GLOB)
|
||||
EgtCutSurfTmPlane( AddIdTunnel, ptOn, -X_AX(), true, GDB_RT.GLOB)
|
||||
end
|
||||
-- eseguo trim destro
|
||||
dNewMaxX = dNewMinX + dSplitPartsLen
|
||||
if i ~= nSplitParts or bStartRight then
|
||||
ptOn = Point3d( dNewMaxX, 0, 0)
|
||||
-- taglio della superficie lato destro
|
||||
EgtCutSurfTmPlane( AddId, ptOn, X_AX(), true, GDB_RT.GLOB)
|
||||
EgtCutSurfTmPlane( AddIdTunnel, ptOn, X_AX(), true, GDB_RT.GLOB)
|
||||
end
|
||||
-- il nuovo minimo è il punto massimo del precedente
|
||||
dNewMinX = dNewMaxX
|
||||
end
|
||||
-- eseguo inserimento in modo da ordinare da X- a X+
|
||||
table.insert( vAddId, EgtIf( #vAddId == 0 or not bStartRight, 1, 2), AddId)
|
||||
table.insert( vAddIdTunnel, EgtIf( #vAddIdTunnel == 0 or not bStartRight, 1, 2), AddIdTunnel)
|
||||
end
|
||||
end
|
||||
if #vFeatureSplittingPoints == 0 then
|
||||
local nAddId = EgtCopyGlob( Proc.id, nAddGrpId) or GDB_ID.NULL
|
||||
local nAddIdTunnel = EgtCopyGlob( nOriginalTmIdTunnel, nAddGrpId) or GDB_ID.NULL
|
||||
table.insert( vAddId, nAddId)
|
||||
table.insert( vAddIdTunnel, nAddIdTunnel)
|
||||
else
|
||||
-- TODO se è sulla coda, messaggio che posso rovinare
|
||||
table.insert( vAddId, Proc.id)
|
||||
for i = 1, #vFeatureSplittingPoints do
|
||||
local nAddId = EgtCopyGlob( Proc.id, nAddGrpId) or GDB_ID.NULL
|
||||
local nAddIdTunnel = EgtCopyGlob( nOriginalTmIdTunnel, nAddGrpId) or GDB_ID.NULL
|
||||
if i == 1 then
|
||||
-- prima superficie, va tagliata solo a sinistra
|
||||
local ptSplit = vFeatureSplittingPoints[i] + Vector3d( -BeamData.MILL_OVERLAP / 2, 0, 0)
|
||||
EgtCutSurfTmPlane( nAddId, ptSplit, -X_AX(), true, GDB_RT.GLOB)
|
||||
EgtCutSurfTmPlane( nAddIdTunnel, ptSplit, -X_AX(), true, GDB_RT.GLOB)
|
||||
else
|
||||
-- taglio della superficie corrente - lato sinistro
|
||||
local ptSplit = vFeatureSplittingPoints[i] + Vector3d( -BeamData.MILL_OVERLAP / 2, 0, 0)
|
||||
EgtCutSurfTmPlane( nAddId, ptSplit, -X_AX(), true, GDB_RT.GLOB)
|
||||
EgtCutSurfTmPlane( nAddIdTunnel, ptSplit, -X_AX(), true, GDB_RT.GLOB)
|
||||
-- taglio della superficie corrente - lato destro
|
||||
ptSplit = vFeatureSplittingPoints[i - 1] + Vector3d( BeamData.MILL_OVERLAP / 2, 0, 0)
|
||||
EgtCutSurfTmPlane( nAddId, ptSplit, X_AX(), true, GDB_RT.GLOB)
|
||||
EgtCutSurfTmPlane( nAddIdTunnel, ptSplit, X_AX(), true, GDB_RT.GLOB)
|
||||
end
|
||||
table.insert( vAddId, nAddId)
|
||||
table.insert( vAddIdTunnel, nAddIdTunnel)
|
||||
end
|
||||
-- taglio ultima superficie, va tagliata solo a destra
|
||||
local nAddId = EgtCopyGlob( Proc.id, nAddGrpId) or GDB_ID.NULL
|
||||
local nAddIdTunnel = EgtCopyGlob( nOriginalTmIdTunnel, nAddGrpId) or GDB_ID.NULL
|
||||
local ptSplit = vFeatureSplittingPoints[#vFeatureSplittingPoints] + Vector3d( BeamData.MILL_OVERLAP / 2, 0, 0)
|
||||
EgtCutSurfTmPlane( nAddId, ptSplit, X_AX(), true, GDB_RT.GLOB)
|
||||
EgtCutSurfTmPlane( nAddIdTunnel, ptSplit, X_AX(), true, GDB_RT.GLOB)
|
||||
table.insert( vAddId, nAddId)
|
||||
table.insert( vAddIdTunnel, nAddIdTunnel)
|
||||
end
|
||||
|
||||
return vAddId, vAddIdTunnel
|
||||
@@ -509,14 +424,18 @@ function STR0002.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
return false, Strategy.Result
|
||||
end
|
||||
|
||||
local bAreAllApplyOk = true
|
||||
local bAreAllMachiningsAdded = true
|
||||
local ToolInfo = {}
|
||||
local Pocketing = {}
|
||||
|
||||
Strategy.Machining = GetBestPocketingStrategy( Proc)
|
||||
|
||||
if bAddMachining and Strategy.Result.sStatus ~= 'Not-Applicable' then
|
||||
local vAddId, vAddIdTunnel = VerifySplitMachiningNeeded( Proc, Part)
|
||||
local vAddId = {}
|
||||
local vAddIdTunnel = {}
|
||||
|
||||
-- recupero superficie, se necessario trimmata sugli spezzoni
|
||||
vAddId, vAddIdTunnel = GetSplitSurfaces( Proc, Part)
|
||||
|
||||
-- si applicano le lavorazioni
|
||||
for i = 1, #vAddId do
|
||||
@@ -541,16 +460,16 @@ function STR0002.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
-- se ho una sola trimesh, sto lavorando la Proc direttamente e non ho spezzato. Applico direttamente alla geometria calcolata prima
|
||||
if #vAddId == 1 then
|
||||
Pocketing.Geometry = {{ Strategy.Machining[j].idProc, Strategy.Machining[j].idFaceToMachine}}
|
||||
bAreAllApplyOk = MachiningLib.AddNewMachining( Proc, Pocketing)
|
||||
bAreAllMachiningsAdded = MachiningLib.AddNewMachining( Proc, Pocketing)
|
||||
else
|
||||
-- TODO settare parametro per indicare qual è lo spezzone che deve essere fatto dopo il taglio di separazione
|
||||
for k = 1, Proc.nFct do
|
||||
local vtNSplitFace
|
||||
local dIdTm = EgtIf( Strategy.Machining[j].bMachAppliedToTunnelFace, vAddIdTunnel[i], vAddId[i])
|
||||
_, vtNSplitFace = EgtSurfTmFacetCenter( dIdTm, k - 1, GDB_ID.ROOT)
|
||||
local nIdTm = EgtIf( Strategy.Machining[j].bMachAppliedToTunnelFace, vAddIdTunnel[i], vAddId[i])
|
||||
vtNSplitFace = EgtSurfTmFacetNormVersor( nIdTm, k - 1, GDB_ID.ROOT)
|
||||
if vtNSplitFace and AreSameVectorApprox( vtNSplitFace * EgtIf( Pocketing.bToolInvert, -1, 1), Strategy.Machining[j].vtFaceNormal) then
|
||||
Pocketing.Geometry = {{ dIdTm, k - 1}}
|
||||
bAreAllApplyOk = bAreAllApplyOk and MachiningLib.AddNewMachining( Proc, Pocketing)
|
||||
Pocketing.Geometry = {{ nIdTm, k - 1}}
|
||||
bAreAllMachiningsAdded = bAreAllMachiningsAdded and MachiningLib.AddNewMachining( Proc, Pocketing)
|
||||
break
|
||||
end
|
||||
end
|
||||
@@ -559,10 +478,10 @@ function STR0002.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
end
|
||||
end
|
||||
else
|
||||
bAreAllApplyOk = false
|
||||
bAreAllMachiningsAdded = false
|
||||
end
|
||||
|
||||
return bAreAllApplyOk, Strategy.Result
|
||||
return bAreAllMachiningsAdded, Strategy.Result
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
local STR0002Data = {
|
||||
sStrategyId = 'STR0002',
|
||||
Parameters = {
|
||||
{ sName = 'dMaxCornerRadius', sValue = '15', sDescriptionShort = 'Max radius left on corners', sDescriptionLong = 'Radius-limit left by the tool at each corner of the feature', sType = 'd', sMinUserLevel = '1', sMessageId = ''},
|
||||
{ sName = 'bAntiSplint', sValue = 'false', sDescriptionShort = 'Use Anti-Splint strategy', sDescriptionLong = 'The strategy will apply blade cuts on corner to avoid wood splint', sType = 'b', sMinUserLevel = '1', sMessageId = ''}
|
||||
{ sName = 'dMaxCornerRadius', sNameNge = 'MAX_CORNER_RADIUS', sValue = '15', sDescriptionShort = 'Max radius left on corners', sDescriptionLong = 'Radius-limit left by the tool at each corner of the feature', sType = 'd', sMinUserLevel = '1', sMessageId = ''},
|
||||
{ sName = 'bAntiSplint', sNameNge = 'ANTISPLINT', sValue = 'false', sDescriptionShort = 'Use Anti-Splint strategy', sDescriptionLong = 'The strategy will apply blade cuts on corner to avoid wood splint', sType = 'b', sMinUserLevel = '1', sMessageId = ''}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
local BeamLib = require( 'BeamLib')
|
||||
local BeamData = require( 'BeamData')
|
||||
local MachiningLib = require( 'MachiningLib')
|
||||
local FeatureData = require( 'FeatureData')
|
||||
local FeatureLib = require( 'FeatureLib')
|
||||
-- strategie di base
|
||||
local SlotByBlade = require( 'SLOTBYBLADE')
|
||||
local SlotByChainSaw = require( 'SLOTBYCHAINSAW')
|
||||
@@ -60,6 +60,72 @@ local function GetCompletionPercentage( Proc, Result)
|
||||
end
|
||||
|
||||
|
||||
-- TODO si può unificare con eguale funzione in STR0004
|
||||
local function SortMachiningsBySegment( MachiningA, MachiningB)
|
||||
if MachiningA.nSegment > MachiningB.nSegment then
|
||||
return false
|
||||
elseif MachiningB.nSegment > MachiningA.nSegment then
|
||||
return true
|
||||
else
|
||||
if TOOLS[ MachiningA.nToolIndex].sFamily == 'SAWBLADE' and TOOLS[ MachiningB.nToolIndex].sFamily == 'MORTISE' then
|
||||
return true
|
||||
elseif TOOLS[ MachiningA.nToolIndex].sFamily == 'MORTISE' and TOOLS[ MachiningB.nToolIndex].sFamily == 'SAWBLADE' then
|
||||
return false
|
||||
else
|
||||
if MachiningA.sEdgeType == 'Side' and MachiningB.sEdgeType ~= 'Side' then
|
||||
return true
|
||||
elseif MachiningB.sEdgeType == 'Side' and MachiningA.sEdgeType ~= 'Side' then
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function SortMachiningsByTool( MachiningA, MachiningB)
|
||||
if TOOLS[ MachiningA.nToolIndex].sFamily == 'SAWBLADE' and TOOLS[ MachiningB.nToolIndex].sFamily == 'MORTISE' then
|
||||
return true
|
||||
elseif TOOLS[ MachiningA.nToolIndex].sFamily == 'MORTISE' and TOOLS[ MachiningB.nToolIndex].sFamily == 'SAWBLADE' then
|
||||
return false
|
||||
else
|
||||
if MachiningA.nSegment > MachiningB.nSegment then
|
||||
return false
|
||||
elseif MachiningB.nSegment > MachiningA.nSegment then
|
||||
return true
|
||||
else
|
||||
if MachiningA.sEdgeType == 'Side' and MachiningB.sEdgeType ~= 'Side' then
|
||||
return true
|
||||
elseif MachiningB.sEdgeType == 'Side' and MachiningA.sEdgeType ~= 'Side' then
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function MergeResults( Result)
|
||||
local SortedResult = {}
|
||||
|
||||
for i = 1, #Result.Side do
|
||||
if Result.Side[i].bIsApplicable then
|
||||
table.insert( SortedResult, Result.Side[i])
|
||||
end
|
||||
end
|
||||
for i = 1, #Result.Bottom do
|
||||
if Result.Bottom[i].bIsApplicable then
|
||||
table.insert( SortedResult, Result.Bottom[i])
|
||||
end
|
||||
end
|
||||
for i = 1, #Result.Opposite do
|
||||
if Result.Opposite[i].bIsApplicable then
|
||||
table.insert( SortedResult, Result.Opposite[i])
|
||||
end
|
||||
end
|
||||
|
||||
return SortedResult
|
||||
end
|
||||
|
||||
|
||||
local function AddResult( Machining, Result)
|
||||
table.insert( Result, {})
|
||||
if not Result.Bottom then
|
||||
@@ -85,6 +151,34 @@ local function AddResult( Machining, Result)
|
||||
end
|
||||
|
||||
|
||||
local function AddMachinings( Proc, Machinings, bAddMachining)
|
||||
local nIsApplicableCount = 0
|
||||
local bAreAllMachiningsAdded = true
|
||||
|
||||
for i = 1, #Machinings do
|
||||
if Machinings[i].bIsApplicable then
|
||||
nIsApplicableCount = nIsApplicableCount + 1
|
||||
if bAddMachining then
|
||||
local bIsMachiningAdded
|
||||
if TOOLS[ Machinings[i].nToolIndex].sFamily == 'SAWBLADE' then
|
||||
Blade.AddMachiningAllSteps( Proc, Machinings[i])
|
||||
elseif TOOLS[ Machinings[i].nToolIndex].sFamily == 'MORTISE' then
|
||||
Chainsaw.AddMachiningAllSteps( Proc, Machinings[i])
|
||||
else
|
||||
error( 'AddMachinings : tool type not supported')
|
||||
end
|
||||
if not bIsMachiningAdded then
|
||||
bAreAllMachiningsAdded = false
|
||||
end
|
||||
end
|
||||
Strategy.Result.sInfo = Strategy.Result.sInfo .. '\n' .. Machinings[i].sMessage
|
||||
end
|
||||
end
|
||||
|
||||
return bAreAllMachiningsAdded, nIsApplicableCount
|
||||
end
|
||||
|
||||
|
||||
function Blade.AddResult( Cutting)
|
||||
AddResult( Cutting, Blade.Result)
|
||||
end
|
||||
@@ -100,11 +194,11 @@ function Blade.AddMachiningAllSteps( Proc, Cutting, AuxiliaryData)
|
||||
local dOriginalRadialOffset = Cutting.dRadialOffset
|
||||
local dOriginalLeadInPerpDistance = Cutting.LeadIn.dPerpDistance
|
||||
local dOriginalLeadOutPerpDistance = Cutting.LeadOut.dPerpDistance
|
||||
for i = Cutting.HorizontalSteps.nCount, 1, -1 do
|
||||
for i = 1, Cutting.HorizontalSteps.nCount do
|
||||
AuxiliaryData.Clones[i] = {}
|
||||
AuxiliaryData.Clones[i].LeadIn = {}
|
||||
AuxiliaryData.Clones[i].LeadOut = {}
|
||||
AuxiliaryData.Clones[i].dRadialOffset = dOriginalRadialOffset + Cutting.HorizontalSteps.dStep * ( i - 1)
|
||||
AuxiliaryData.Clones[i].dRadialOffset = dOriginalRadialOffset + Cutting.HorizontalSteps.dStep * ( Cutting.HorizontalSteps.nCount - i)
|
||||
-- update distanza perpendicolare attacco per contemplare l'offset applicato
|
||||
AuxiliaryData.Clones[i].LeadIn.dPerpDistance = dOriginalLeadInPerpDistance - Cutting.dRadialOffset
|
||||
AuxiliaryData.Clones[i].LeadOut.dPerpDistance = dOriginalLeadOutPerpDistance - Cutting.dRadialOffset
|
||||
@@ -169,10 +263,14 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
return false, Strategy.Result
|
||||
end
|
||||
|
||||
-- lama
|
||||
-- lavorazione di lama - fondo della tasca o fino a massimo materiale se tunnel
|
||||
local dExtendAfterTail = Strategy.Parameters.dExtendAfterTail or max( Part.dDistanceToNextPiece - BeamData.CUT_EXTRA, 0)
|
||||
if MachiningLib.CanExtendAfterTail( Strategy.Parameters.sCanDamageNextPiece, Part) then
|
||||
dExtendAfterTail = 10000
|
||||
end
|
||||
|
||||
-- lama - calcolo lavorazioni
|
||||
local Cutting = {}
|
||||
local OptionalParameters = { bForceLongcutBlade = Strategy.Parameters.bForceLongcutBlade}
|
||||
local OptionalParameters = { bForceLongcutBlade = Strategy.Parameters.bForceLongcutBlade, dExtendAfterTail = dExtendAfterTail}
|
||||
if Proc.Topology.sFamily == 'Tunnel' then
|
||||
Cutting = SlotByBlade.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[1], OptionalParameters)
|
||||
else
|
||||
@@ -202,63 +300,41 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
Strategy.Parameters.bNotCompleteWithBladeRadius = false
|
||||
end
|
||||
end
|
||||
|
||||
local nIsApplicableCount = 0
|
||||
local dFinalCompletionPercentage = 100
|
||||
local bAreAllMachiningsAdded = true
|
||||
for i = 1, #Blade.Result.Bottom do
|
||||
if Blade.Result.Bottom[i].bIsApplicable then
|
||||
nIsApplicableCount = nIsApplicableCount + 1
|
||||
if bAddMachining then
|
||||
local bIsMachiningAdded = Blade.AddMachiningAllSteps( Proc, Blade.Result.Bottom[i])
|
||||
if not bIsMachiningAdded then
|
||||
bAreAllMachiningsAdded = false
|
||||
end
|
||||
end
|
||||
Strategy.Result.sInfo = Strategy.Result.sInfo .. '\n' .. Blade.Result.Bottom[i].sMessage
|
||||
end
|
||||
-- lama - lavorazioni raggruppate in unica lista
|
||||
Blade.Result.Sorted = MergeResults( Blade.Result)
|
||||
-- lama - aggiunta eventuali lavorazioni splittate
|
||||
local vFeatureSplittingPoints = FeatureLib.GetFeatureSplittingPoints( Proc, Part)
|
||||
if #vFeatureSplittingPoints > 0 then
|
||||
Blade.Result.Sorted = MachiningLib.GetSplitMachinings( Blade.Result.Sorted, vFeatureSplittingPoints, Part)
|
||||
end
|
||||
for i = 1, #Blade.Result.Side do
|
||||
if Blade.Result.Side[i].bIsApplicable then
|
||||
nIsApplicableCount = nIsApplicableCount + 1
|
||||
if bAddMachining then
|
||||
local bIsMachiningAdded = Blade.AddMachiningAllSteps( Proc, Blade.Result.Side[i])
|
||||
if not bIsMachiningAdded then
|
||||
bAreAllMachiningsAdded = false
|
||||
end
|
||||
end
|
||||
Strategy.Result.sInfo = Strategy.Result.sInfo .. '\n' .. Blade.Result.Side[i].sMessage
|
||||
end
|
||||
end
|
||||
for i = 1, #Blade.Result.Opposite do
|
||||
if Blade.Result.Opposite[i].bIsApplicable then
|
||||
nIsApplicableCount = nIsApplicableCount + 1
|
||||
if bAddMachining then
|
||||
local bIsMachiningAdded = Blade.AddMachiningAllSteps( Proc, Blade.Result.Opposite[i])
|
||||
if not bIsMachiningAdded then
|
||||
bAreAllMachiningsAdded = false
|
||||
end
|
||||
end
|
||||
Strategy.Result.sInfo = Strategy.Result.sInfo .. '\n' .. Blade.Result.Opposite[i].sMessage
|
||||
end
|
||||
end
|
||||
if nIsApplicableCount > 0 then
|
||||
-- TODO sistemare il calcolo completamento - implementare calcolo area lavorata
|
||||
if not Strategy.Parameters.bNotCompleteWithBladeRadius and Cutting.dCompletionPercentage > 100 - 10 * GEO.EPS_SMALL then
|
||||
Strategy.Result.sStatus = 'Completed'
|
||||
else
|
||||
Strategy.Result.sStatus = 'Not-Completed'
|
||||
-- TODO al momento si assume che la percentuale di completamento dell'ultima lavorazione sia quella rilevante
|
||||
dFinalCompletionPercentage = Cutting.dCompletionPercentage
|
||||
end
|
||||
else
|
||||
Strategy.Result.sStatus = 'Not-Applicable'
|
||||
Strategy.Parameters.bFinishWithChainSaw = false
|
||||
end
|
||||
|
||||
-- lama - nessuna lavorazione successiva - aggiunta lavorazioni e calcolo risultati
|
||||
if not Strategy.Parameters.bFinishWithChainSaw then
|
||||
Strategy.Result.nCompletionIndex = FeatureData.GetFeatureCompletionIndex( dFinalCompletionPercentage)
|
||||
Strategy.Result.nQuality = FeatureData.GetFeatureQuality( 'Blade')
|
||||
-- ordinamento
|
||||
if Strategy.Parameters.bSortBySegment then
|
||||
table.sort( Blade.Result.Sorted, SortMachiningsBySegment)
|
||||
else
|
||||
table.sort( Blade.Result.Sorted, SortMachiningsByTool)
|
||||
end
|
||||
-- aggiunta lavorazioni
|
||||
local nIsApplicableCount = 0
|
||||
local bAreAllMachiningsAdded = true
|
||||
local dFinalCompletionPercentage = 100
|
||||
bAreAllMachiningsAdded, nIsApplicableCount = AddMachinings( Proc, Blade.Result.Sorted, bAddMachining)
|
||||
if nIsApplicableCount > 0 then
|
||||
-- TODO sistemare il calcolo completamento - implementare calcolo area lavorata
|
||||
if not Strategy.Parameters.bNotCompleteWithBladeRadius and Cutting.dCompletionPercentage > 100 - 10 * GEO.EPS_SMALL then
|
||||
Strategy.Result.sStatus = 'Completed'
|
||||
else
|
||||
Strategy.Result.sStatus = 'Not-Completed'
|
||||
-- TODO al momento si assume che la percentuale di completamento dell'ultima lavorazione sia quella rilevante
|
||||
dFinalCompletionPercentage = Cutting.dCompletionPercentage
|
||||
end
|
||||
else
|
||||
Strategy.Result.sStatus = 'Not-Applicable'
|
||||
Strategy.Parameters.bFinishWithChainSaw = false
|
||||
end
|
||||
Strategy.Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( dFinalCompletionPercentage)
|
||||
Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'Blade')
|
||||
local MRRParametersBlade = {
|
||||
dStep = TOOLS[Cutting.nToolIndex].dThickness,
|
||||
dSideStep = min( TOOLS[Cutting.nToolIndex].dSideStep, Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1].dLength),
|
||||
@@ -269,7 +345,7 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
return bAreAllMachiningsAdded, Strategy.Result
|
||||
end
|
||||
|
||||
-- sega a catena
|
||||
-- sega a catena - calcolo lavorazioni
|
||||
local Mortising = {}
|
||||
OptionalParameters = {}
|
||||
if Proc.Topology.sName == 'Groove-4-Blind' or Proc.Topology.sName == 'Pocket-5-Blind' then
|
||||
@@ -278,18 +354,18 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
( Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.dLength > 3 * Blade.Result.Bottom[1].dBladeMarkLength - 10 * GEO.EPS_SMALL) then
|
||||
|
||||
if not Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.bIsStartOpen then
|
||||
local OptionalParameters = { sSideToMachine = 'Start', dLengthToMachine = Blade.Result.Bottom[1].dBladeMarkLength, dMaxElev = 0}
|
||||
local OptionalParameters = { sSideToMachine = 'Start', dLengthToMachine = Blade.Result.Bottom[1].dBladeMarkLength, dExtendAfterTail = dExtendAfterTail}
|
||||
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge, OptionalParameters)
|
||||
Chainsaw.AddResult( Mortising)
|
||||
end
|
||||
if not Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.bIsEndOpen then
|
||||
local OptionalParameters = { sSideToMachine = 'End', dLengthToMachine = Blade.Result.Bottom[1].dBladeMarkLength, dMaxElev = 0}
|
||||
local OptionalParameters = { sSideToMachine = 'End', dLengthToMachine = Blade.Result.Bottom[1].dBladeMarkLength, dExtendAfterTail = dExtendAfterTail}
|
||||
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge, OptionalParameters)
|
||||
Chainsaw.AddResult( Mortising)
|
||||
end
|
||||
-- si lavora tutto il fondo
|
||||
else
|
||||
local OptionalParameters = { dMaxElev = Blade.Result.Bottom[1].dResidualDepth + BeamData.CUT_EXTRA}
|
||||
local OptionalParameters = { dMaxElev = Blade.Result.Bottom[1].dResidualDepth + BeamData.CUT_EXTRA, dExtendAfterTail = dExtendAfterTail}
|
||||
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge, OptionalParameters)
|
||||
Chainsaw.AddResult( Mortising)
|
||||
end
|
||||
@@ -298,10 +374,10 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
-- si lavora solamente l'impronta lama sul fondo
|
||||
if ( #Blade.Result.Side > 0) and Blade.Result.Side[1].dResidualDepth < 10 * GEO.EPS_SMALL then
|
||||
if ( Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.bIsStartOpen and Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1].dLength > 3 * Blade.Result.Side[1].dBladeMarkLength - 10 * GEO.EPS_SMALL) then
|
||||
local OptionalParameters = { sSideToMachine = 'End', dLengthToMachine = Blade.Result.Side[1].dBladeMarkLength, dMaxElev = 0}
|
||||
local OptionalParameters = { sSideToMachine = 'End', dLengthToMachine = Blade.Result.Side[1].dBladeMarkLength, dExtendAfterTail = dExtendAfterTail}
|
||||
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1], OptionalParameters)
|
||||
elseif ( Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.bIsEndOpen and Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[2].dLength > 3 * Blade.Result.Side[1].dBladeMarkLength - 10 * GEO.EPS_SMALL) then
|
||||
local OptionalParameters = { sSideToMachine = 'Start', dLengthToMachine = Blade.Result.Side[1].dBladeMarkLength, dMaxElev = 0}
|
||||
local OptionalParameters = { sSideToMachine = 'Start', dLengthToMachine = Blade.Result.Side[1].dBladeMarkLength, dExtendAfterTail = dExtendAfterTail}
|
||||
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[2], OptionalParameters)
|
||||
end
|
||||
-- si lavora tutto il lato
|
||||
@@ -313,10 +389,10 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
dBladeResidualDepth = Blade.Result.Bottom[1].dResidualDepth
|
||||
end
|
||||
if Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.bIsStartOpen then
|
||||
local OptionalParameters = { dMaxElev = dBladeResidualDepth + BeamData.CUT_EXTRA}
|
||||
local OptionalParameters = { dMaxElev = dBladeResidualDepth + BeamData.CUT_EXTRA, dExtendAfterTail = dExtendAfterTail}
|
||||
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1], OptionalParameters)
|
||||
elseif Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.bIsEndOpen then
|
||||
local OptionalParameters = { dMaxElev = dBladeResidualDepth + BeamData.CUT_EXTRA}
|
||||
local OptionalParameters = { dMaxElev = dBladeResidualDepth + BeamData.CUT_EXTRA, dExtendAfterTail = dExtendAfterTail}
|
||||
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[2], OptionalParameters)
|
||||
end
|
||||
end
|
||||
@@ -325,7 +401,7 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
elseif Proc.Topology.sName == 'Groove-3-Through' then
|
||||
if Blade.Result.Bottom[1].dResidualDepth > 10 * GEO.EPS_SMALL then
|
||||
-- si lavora tutto il fondo
|
||||
local OptionalParameters = { dMaxElev = Blade.Result.Bottom[1].dResidualDepth + BeamData.CUT_EXTRA}
|
||||
local OptionalParameters = { dMaxElev = Blade.Result.Bottom[1].dResidualDepth + BeamData.CUT_EXTRA, dExtendAfterTail = dExtendAfterTail}
|
||||
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge, OptionalParameters)
|
||||
Chainsaw.AddResult( Mortising)
|
||||
-- ancora materiale residuo - si lavorano i lati
|
||||
@@ -334,16 +410,16 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
if ( Blade.Result.Side[1].dResidualDepth < 10 * GEO.EPS_SMALL and Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1].dLength > 3 * Blade.Result.Side[1].dBladeMarkLength - 10 * GEO.EPS_SMALL) and
|
||||
( Blade.Result.Side[2].dResidualDepth < 10 * GEO.EPS_SMALL and Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[2].dLength > 3 * Blade.Result.Side[2].dBladeMarkLength - 10 * GEO.EPS_SMALL) then
|
||||
|
||||
local OptionalParameters = { sSideToMachine = 'End', dLengthToMachine = Blade.Result.Side[1].dBladeMarkLength, dMaxElev = 0}
|
||||
local OptionalParameters = { sSideToMachine = 'End', dLengthToMachine = Blade.Result.Side[1].dBladeMarkLength, dExtendAfterTail = dExtendAfterTail}
|
||||
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1], OptionalParameters)
|
||||
Chainsaw.AddResult( Mortising)
|
||||
-- ancora materiale residuo - si lavora da entrambi i lati
|
||||
if Chainsaw.Result.Side[1].dResidualDepth > 10 * GEO.EPS_SMALL then
|
||||
local OptionalParameters = { bStopAtHalfElevation = true, sSideToMachine = 'End', dLengthToMachine = Blade.Result.Side[1].dBladeMarkLength, dMaxElev = 0}
|
||||
local OptionalParameters = { bStopAtHalfElevation = true, sSideToMachine = 'End', dLengthToMachine = Blade.Result.Side[1].dBladeMarkLength, dExtendAfterTail = dExtendAfterTail}
|
||||
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1], OptionalParameters)
|
||||
Chainsaw.AddResult( Mortising)
|
||||
OptionalParameters = {}
|
||||
OptionalParameters = { bStopAtHalfElevation = true, sSideToMachine = 'Start', dLengthToMachine = Blade.Result.Side[2].dBladeMarkLength, dMaxElev = 0}
|
||||
OptionalParameters = { bStopAtHalfElevation = true, sSideToMachine = 'Start', dLengthToMachine = Blade.Result.Side[2].dBladeMarkLength, dExtendAfterTail = dExtendAfterTail}
|
||||
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[2], OptionalParameters)
|
||||
Chainsaw.AddResult( Mortising)
|
||||
-- lavorando dai due lati non c'è materiale residuo - si può eliminare la lavorazione del fondo
|
||||
@@ -353,17 +429,17 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
end
|
||||
-- si lavora tutto il lato
|
||||
else
|
||||
local OptionalParameters = { dMaxElev = Blade.Result.Side[1].dResidualDepth + BeamData.CUT_EXTRA}
|
||||
local OptionalParameters = { dMaxElev = Blade.Result.Side[1].dResidualDepth + BeamData.CUT_EXTRA, dExtendAfterTail = dExtendAfterTail}
|
||||
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1], OptionalParameters)
|
||||
Chainsaw.AddResult( Mortising)
|
||||
-- ancora materiale residuo - si lavora da entrambi i lati
|
||||
if Chainsaw.Result.Side[1].dResidualDepth > 10 * GEO.EPS_SMALL then
|
||||
Chainsaw.Result.Side[1].bIsApplicable = false
|
||||
local OptionalParameters = { bStopAtHalfElevation = true, dMaxElev = Blade.Result.Side[1].dResidualDepth + BeamData.CUT_EXTRA}
|
||||
local OptionalParameters = { bStopAtHalfElevation = true, dMaxElev = Blade.Result.Side[1].dResidualDepth + BeamData.CUT_EXTRA, dExtendAfterTail = dExtendAfterTail}
|
||||
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1], OptionalParameters)
|
||||
Chainsaw.AddResult( Mortising)
|
||||
OptionalParameters = {}
|
||||
OptionalParameters = { bStopAtHalfElevation = true, dMaxElev = Blade.Result.Side[2].dResidualDepth + BeamData.CUT_EXTRA}
|
||||
OptionalParameters = { bStopAtHalfElevation = true, dMaxElev = Blade.Result.Side[2].dResidualDepth + BeamData.CUT_EXTRA, dExtendAfterTail = dExtendAfterTail}
|
||||
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[2], OptionalParameters)
|
||||
Chainsaw.AddResult( Mortising)
|
||||
-- lavorando dai due lati non c'è materiale residuo - si può disabilitare la lavorazione del fondo
|
||||
@@ -379,88 +455,74 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
if ( Blade.Result.Opposite[1].dResidualDepth < 10 * GEO.EPS_SMALL and Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[1].dLength > 3 * Blade.Result.Opposite[1].dBladeMarkLength - 10 * GEO.EPS_SMALL) and
|
||||
( Blade.Result.Opposite[2].dResidualDepth < 10 * GEO.EPS_SMALL and Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[2].dLength > 3 * Blade.Result.Opposite[2].dBladeMarkLength - 10 * GEO.EPS_SMALL) then
|
||||
|
||||
local OptionalParameters = { sSideToMachine = 'Start', dLengthToMachine = Blade.Result.Opposite[1].dBladeMarkLength, dMaxElev = 0}
|
||||
local OptionalParameters = { sSideToMachine = 'Start', dLengthToMachine = Blade.Result.Opposite[1].dBladeMarkLength, dExtendAfterTail = dExtendAfterTail}
|
||||
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[1], OptionalParameters)
|
||||
Chainsaw.AddResult( Mortising)
|
||||
OptionalParameters = {}
|
||||
OptionalParameters = { sSideToMachine = 'End', dLengthToMachine = Blade.Result.Opposite[2].dBladeMarkLength, dMaxElev = 0}
|
||||
OptionalParameters = { sSideToMachine = 'End', dLengthToMachine = Blade.Result.Opposite[2].dBladeMarkLength, dExtendAfterTail = dExtendAfterTail}
|
||||
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[1], OptionalParameters)
|
||||
Chainsaw.AddResult( Mortising)
|
||||
if Chainsaw.Result.Opposite[1].dResidualDepth > GEO.EPS_SMALL or Chainsaw.Result.Opposite[2].dResidualDepth > GEO.EPS_SMALL then
|
||||
if Chainsaw.Result.Opposite[1].dResidualDepth > 10 * GEO.EPS_SMALL or Chainsaw.Result.Opposite[2].dResidualDepth > 10 * GEO.EPS_SMALL then
|
||||
Chainsaw.Result.Opposite[1].bIsApplicable = false
|
||||
Chainsaw.Result.Opposite[2].bIsApplicable = false
|
||||
local OptionalParameters = { bStopAtHalfElevation = true, sSideToMachine = 'Start', dLengthToMachine = Blade.Result.Opposite[1].dBladeMarkLength, dMaxElev = 0}
|
||||
local OptionalParameters = { bStopAtHalfElevation = true, sSideToMachine = 'Start', dLengthToMachine = Blade.Result.Opposite[1].dBladeMarkLength, dExtendAfterTail = dExtendAfterTail}
|
||||
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[1], OptionalParameters)
|
||||
Chainsaw.AddResult( Mortising)
|
||||
OptionalParameters = {}
|
||||
OptionalParameters = { bStopAtHalfElevation = true, sSideToMachine = 'End', dLengthToMachine = Blade.Result.Opposite[1].dBladeMarkLength, dMaxElev = 0}
|
||||
OptionalParameters = { bStopAtHalfElevation = true, sSideToMachine = 'End', dLengthToMachine = Blade.Result.Opposite[1].dBladeMarkLength, dExtendAfterTail = dExtendAfterTail}
|
||||
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[1], OptionalParameters)
|
||||
Chainsaw.AddResult( Mortising)
|
||||
OptionalParameters = {}
|
||||
OptionalParameters = { bStopAtHalfElevation = true, sSideToMachine = 'Start', dLengthToMachine = Blade.Result.Opposite[2].dBladeMarkLength, dMaxElev = 0}
|
||||
OptionalParameters = { bStopAtHalfElevation = true, sSideToMachine = 'Start', dLengthToMachine = Blade.Result.Opposite[2].dBladeMarkLength, dExtendAfterTail = dExtendAfterTail}
|
||||
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[2], OptionalParameters)
|
||||
Chainsaw.AddResult( Mortising)
|
||||
OptionalParameters = {}
|
||||
OptionalParameters = { bStopAtHalfElevation = true, sSideToMachine = 'End', dLengthToMachine = Blade.Result.Opposite[2].dBladeMarkLength, dMaxElev = 0}
|
||||
OptionalParameters = { bStopAtHalfElevation = true, sSideToMachine = 'End', dLengthToMachine = Blade.Result.Opposite[2].dBladeMarkLength, dExtendAfterTail = dExtendAfterTail}
|
||||
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[2], OptionalParameters)
|
||||
Chainsaw.AddResult( Mortising)
|
||||
end
|
||||
else
|
||||
local OptionalParameters = { dMaxElev = Blade.Result.Opposite[1].dResidualDepth + BeamData.CUT_EXTRA}
|
||||
local OptionalParameters = { dMaxElev = Blade.Result.Opposite[1].dResidualDepth + BeamData.CUT_EXTRA, dExtendAfterTail = dExtendAfterTail}
|
||||
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[1], OptionalParameters)
|
||||
Chainsaw.AddResult( Mortising)
|
||||
if Chainsaw.Result.Opposite[1].dResidualDepth > GEO.EPS_SMALL then
|
||||
if Chainsaw.Result.Opposite[1].dResidualDepth > 10 * GEO.EPS_SMALL then
|
||||
Chainsaw.Result.Opposite[1].bIsApplicable = false
|
||||
local OptionalParameters = { bStopAtHalfElevation = true, dMaxElev = Blade.Result.Opposite[1].dResidualDepth + BeamData.CUT_EXTRA}
|
||||
local OptionalParameters = { bStopAtHalfElevation = true, dMaxElev = Blade.Result.Opposite[1].dResidualDepth + BeamData.CUT_EXTRA, dExtendAfterTail = dExtendAfterTail}
|
||||
SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[1], OptionalParameters)
|
||||
Chainsaw.AddResult( Mortising)
|
||||
OptionalParameters = {}
|
||||
OptionalParameters = { bStopAtHalfElevation = true, dMaxElev = Blade.Result.Opposite[2].dResidualDepth + BeamData.CUT_EXTRA}
|
||||
OptionalParameters = { bStopAtHalfElevation = true, dMaxElev = Blade.Result.Opposite[2].dResidualDepth + BeamData.CUT_EXTRA, dExtendAfterTail = dExtendAfterTail}
|
||||
SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[2], OptionalParameters)
|
||||
Chainsaw.AddResult( Mortising)
|
||||
end
|
||||
end
|
||||
end
|
||||
-- sega a catena - lavorazioni raggruppate in unica lista
|
||||
Chainsaw.Result.Sorted = MergeResults( Chainsaw.Result)
|
||||
-- sega a catena - aggiunta eventuali lavorazioni splittate
|
||||
if #vFeatureSplittingPoints > 0 then
|
||||
Chainsaw.Result.Sorted = MachiningLib.GetSplitMachinings( Chainsaw.Result.Sorted, vFeatureSplittingPoints, Part)
|
||||
end
|
||||
|
||||
-- tutte le lavorazioni di tutti gli utensili in unica lista
|
||||
local Result = {}
|
||||
for i = 1, #Blade.Result.Sorted do
|
||||
table.insert( Result, Blade.Result.Sorted[i])
|
||||
end
|
||||
for i = 1, #Chainsaw.Result.Sorted do
|
||||
table.insert( Result, Chainsaw.Result.Sorted[i])
|
||||
end
|
||||
-- ordinamento
|
||||
if Strategy.Parameters.bSortBySegment then
|
||||
table.sort( Result, SortMachiningsBySegment)
|
||||
else
|
||||
table.sort( Result, SortMachiningsByTool)
|
||||
end
|
||||
-- aggiunta lavorazioni per tutti gli utensili
|
||||
local nIsApplicableCount = 0
|
||||
local dFinalCompletionPercentage = 100
|
||||
local bAreAllMachiningsAdded = true
|
||||
for i = 1, #Chainsaw.Result.Bottom do
|
||||
if Chainsaw.Result.Bottom[i].bIsApplicable then
|
||||
nIsApplicableCount = nIsApplicableCount + 1
|
||||
if bAddMachining then
|
||||
local bIsMachiningAdded = Chainsaw.AddMachiningAllSteps( Proc, Chainsaw.Result.Bottom[i])
|
||||
if not bIsMachiningAdded then
|
||||
bAreAllMachiningsAdded = false
|
||||
end
|
||||
end
|
||||
Strategy.Result.sInfo = Strategy.Result.sInfo .. '\n' .. Chainsaw.Result.Bottom[i].sMessage
|
||||
end
|
||||
end
|
||||
for i = 1, #Chainsaw.Result.Side do
|
||||
if Chainsaw.Result.Side[i].bIsApplicable then
|
||||
nIsApplicableCount = nIsApplicableCount + 1
|
||||
if bAddMachining then
|
||||
local bIsMachiningAdded = Chainsaw.AddMachiningAllSteps( Proc, Chainsaw.Result.Side[i])
|
||||
if not bIsMachiningAdded then
|
||||
bAreAllMachiningsAdded = false
|
||||
end
|
||||
end
|
||||
Strategy.Result.sInfo = Strategy.Result.sInfo .. '\n' .. Chainsaw.Result.Side[i].sMessage
|
||||
end
|
||||
end
|
||||
for i = 1, #Chainsaw.Result.Opposite do
|
||||
if Chainsaw.Result.Opposite[i].bIsApplicable then
|
||||
nIsApplicableCount = nIsApplicableCount + 1
|
||||
if bAddMachining then
|
||||
local bIsMachiningAdded = Chainsaw.AddMachiningAllSteps( Proc, Chainsaw.Result.Opposite[i])
|
||||
if not bIsMachiningAdded then
|
||||
bAreAllMachiningsAdded = false
|
||||
end
|
||||
end
|
||||
Strategy.Result.sInfo = Strategy.Result.sInfo .. '\n' .. Chainsaw.Result.Opposite[i].sMessage
|
||||
end
|
||||
end
|
||||
local dFinalCompletionPercentage = 100
|
||||
bAreAllMachiningsAdded, nIsApplicableCount = AddMachinings( Proc, Result, bAddMachining)
|
||||
if nIsApplicableCount > 0 then
|
||||
if Mortising.dCompletionPercentage > 100 - 10 * GEO.EPS_SMALL then
|
||||
Strategy.Result.sStatus = 'Completed'
|
||||
@@ -472,8 +534,9 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
else
|
||||
Strategy.Result.sStatus = 'Not-Applicable'
|
||||
end
|
||||
Strategy.Result.nCompletionIndex = FeatureData.GetFeatureCompletionIndex( dFinalCompletionPercentage)
|
||||
Strategy.Result.nQuality = FeatureData.GetFeatureQuality( 'Chainsaw')
|
||||
-- calcolo risultati
|
||||
Strategy.Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( dFinalCompletionPercentage)
|
||||
Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'Chainsaw')
|
||||
local MRRParametersBlade = {
|
||||
dStep = TOOLS[Cutting.nToolIndex].dThickness,
|
||||
dSideStep = min( TOOLS[Cutting.nToolIndex].dSideStep, Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1].dLength),
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
-- Parametri configurabili da cliente per strategia: STR0001
|
||||
-- Parametri configurabili da cliente per strategia: STR0003
|
||||
|
||||
local STR0003Data = {
|
||||
sStrategyId = 'STR0003',
|
||||
Parameters = {
|
||||
{ sName = 'bFinishWithChainSaw', sValue = 'true', sDescriptionShort = 'Finish with chainsaw if needed', sDescriptionLong = 'Finish with chainsaw if needed', sType = 'b', sMessageId = '', sMinUserLevel = '1'},
|
||||
{ sName = 'bForceLongcutBlade', sValue = 'false', sDescriptionShort = 'Force ripping blade', sDescriptionLong = 'Force the use of ripping blade, designed for cuts parallel to the grain', sType = 'b', sMessageId = '', sMinUserLevel = '1'},
|
||||
{ sName = 'bNotCompleteWithBladeRadius', sValue = 'true', sDescriptionShort = '', sDescriptionLong = '', sType = 'b', sMessageId = '', sMinUserLevel = '1'},
|
||||
{ sName = 'bUseZigZagMortising', sValue = 'false', sDescriptionShort = '', sDescriptionLong = '', sType = 'b', sMessageId = '', sMinUserLevel = '1'}
|
||||
{ sName = 'bFinishWithChainSaw', sNameNge = 'ALLOW_FINISH_CHAINSAW', sValue = 'true', sDescriptionShort = 'Finish with chainsaw if needed', sDescriptionLong = 'Finish with chainsaw if needed', sType = 'b', sMessageId = '', sMinUserLevel = '1'},
|
||||
{ sName = 'dExtendAfterTail', sNameNge = 'EXTEND_AFTER_TAIL', sValue = 'false', sDescriptionShort = '', sDescriptionLong = '', sType = 'd', sMessageId = '', sMinUserLevel = '1'},
|
||||
{ sName = 'bForceLongcutBlade', sNameNge = 'USE_LONGCUT_BLADE', sValue = 'false', sDescriptionShort = 'Force ripping blade', sDescriptionLong = 'Force the use of ripping blade, designed for cuts parallel to the grain', sType = 'b', sMessageId = '', sMinUserLevel = '1'},
|
||||
{ sName = 'bNotCompleteWithBladeRadius', sNameNge = 'NOT_COMPLETE_WITH_BLADE_RADIUS', sValue = 'true', sDescriptionShort = '', sDescriptionLong = '', sType = 'b', sMessageId = '', sMinUserLevel = '1'},
|
||||
{ sName = 'bUseZigZagMortising', sNameNge = 'USE_ZIGZAG_CHAINSAW', sValue = 'false', sDescriptionShort = '', sDescriptionLong = '', sType = 'b', sMessageId = '', sMinUserLevel = '1'},
|
||||
{ sName = 'bSortBySegment', sNameNge = 'SORT_BY_SEGMENT', sValue = 'true', sDescriptionShort = '', sDescriptionLong = '', sType = 'b', sMessageId = '', sMinUserLevel = '1'},
|
||||
{ sName = 'sCanDamageNextPiece', sNameNge = 'DAMAGE_NEXT_PIECE', sValue = 'NEVER', sType = 'combo', sMinUserLevel = '1',
|
||||
Choices = { sValue = 'NEVER', sDescriptionShort = '', sDescriptionLong = '', sMessageId = ''},
|
||||
{ sValue = 'ONLY_IF_RAWPART', sDescriptionShort = '', sDescriptionLong = '', sMessageId = ''},
|
||||
{ sValue = 'ALWAYS', sDescriptionShort = '', sDescriptionLong = '', sMessageId = ''}}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,287 @@
|
||||
-- Strategia: STR0004
|
||||
-- Descrizione
|
||||
-- motosega per slot
|
||||
-- Feature: tipo lapjoint
|
||||
|
||||
-- carico librerie
|
||||
local BeamLib = require( 'BeamLib')
|
||||
local BeamData = require( 'BeamData')
|
||||
local MachiningLib = require( 'MachiningLib')
|
||||
local FeatureLib = require( 'FeatureLib')
|
||||
-- strategie di base
|
||||
local SlotByChainSaw = require( 'SLOTBYCHAINSAW')
|
||||
|
||||
-- Tabella per definizione modulo
|
||||
local STR0004 = {}
|
||||
local Strategy = {}
|
||||
local Chainsaw = {}
|
||||
Chainsaw.Result = {}
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
|
||||
local function IsTopologyOk( Proc)
|
||||
if Proc.Topology.bAllRightAngles and
|
||||
( Proc.Topology.sName == 'Pocket-5-Blind' or
|
||||
Proc.Topology.sName == 'Groove-3-Through' or
|
||||
Proc.Topology.sName == 'Groove-4-Blind' or
|
||||
Proc.Topology.sName == 'Tunnel-4-Through') then
|
||||
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function GetCompletionPercentage( Proc, Result)
|
||||
local dNotMachinedArea = 0
|
||||
local dCompletionPercentage = 0
|
||||
|
||||
if Proc.Topology.sFamily == 'Tunnel' then
|
||||
dNotMachinedArea = Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[1].dLength * ( Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1].dLength - Result[1].dDepthMachined)
|
||||
if #Result == 2 then
|
||||
dNotMachinedArea = dNotMachinedArea - Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[1].dLength * ( Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1].dLength - Result[2].dDepthMachined)
|
||||
end
|
||||
else
|
||||
if #Result == 1 then
|
||||
dNotMachinedArea = Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.dLength * ( Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1].dLength - Result[1].dDepthMachined)
|
||||
elseif #Result == 2 then
|
||||
dNotMachinedArea = ( Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.dLength - Result[2].dDepthMachined) * ( Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1].dLength - Result[1].dDepthMachined)
|
||||
elseif #Result == 3 then
|
||||
dNotMachinedArea = ( Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.dLength - Result[2].dDepthMachined - Result[3].dDepthMachined) * ( Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1].dLength - Result[1].dDepthMachined)
|
||||
end
|
||||
end
|
||||
dCompletionPercentage = 100 - dNotMachinedArea / Proc.MainFaces.LongFaces[1].dArea * 100
|
||||
|
||||
return dCompletionPercentage
|
||||
end
|
||||
|
||||
|
||||
local function SortMachiningsBySegment( MachiningA, MachiningB)
|
||||
if MachiningA.nSegment > MachiningB.nSegment then
|
||||
return false
|
||||
elseif MachiningB.nSegment > MachiningA.nSegment then
|
||||
return true
|
||||
else
|
||||
if MachiningA.sEdgeType == 'Side' and MachiningB.sEdgeType ~= 'Side' then
|
||||
return true
|
||||
elseif MachiningB.sEdgeType == 'Side' and MachiningA.sEdgeType ~= 'Side' then
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function AddResult( Machining, Result)
|
||||
table.insert( Result, {})
|
||||
if not Result.Bottom then
|
||||
Result.Bottom = {}
|
||||
end
|
||||
if not Result.Side then
|
||||
Result.Side = {}
|
||||
end
|
||||
if not Result.Opposite then
|
||||
Result.Opposite = {}
|
||||
end
|
||||
if Machining.sEdgeType == 'Bottom' then
|
||||
table.insert( Result.Bottom, Machining)
|
||||
elseif Machining.sEdgeType == 'Side' then
|
||||
table.insert( Result.Side, Machining)
|
||||
elseif Machining.sEdgeType == 'Opposite' then
|
||||
table.insert( Result.Opposite, Machining)
|
||||
else
|
||||
error('AddResult : unknown edge type')
|
||||
end
|
||||
|
||||
return Result
|
||||
end
|
||||
|
||||
|
||||
function Chainsaw.AddResult( Mortising)
|
||||
AddResult( Mortising, Chainsaw.Result)
|
||||
end
|
||||
|
||||
|
||||
function Chainsaw.AddMachiningAllSteps( Proc, Mortising, AuxiliaryData)
|
||||
local bMachiningAdded = false
|
||||
if not AuxiliaryData then
|
||||
AuxiliaryData = {}
|
||||
end
|
||||
AuxiliaryData.Clones = {}
|
||||
|
||||
local dOriginalRadialOffsetMortising = Mortising.dRadialOffset
|
||||
for i = Mortising.VerticalSteps.nCount, 1, -1 do
|
||||
AuxiliaryData.Clones[i] = {}
|
||||
AuxiliaryData.Clones[i].dRadialOffset = dOriginalRadialOffsetMortising + Mortising.VerticalSteps.dStep * ( i - 1)
|
||||
end
|
||||
bMachiningAdded = MachiningLib.AddNewMachining( Proc, Mortising, AuxiliaryData)
|
||||
|
||||
return bMachiningAdded
|
||||
end
|
||||
|
||||
|
||||
function STR0004.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
-- TODO da implementare gestione feature lunghe e spezzatura
|
||||
-- carico parametri da default e li aggiorno con quelli passati dal chiamante (potrebbero non essere congruenti)
|
||||
local StrategyLib = {}
|
||||
StrategyLib.Config = require( 'STR0004\\STR0004Config')
|
||||
Strategy.sName = StrategyLib.Config.sStrategyId
|
||||
CustomParameters = BeamLib.GetUpdateCustomParameters( CustomParameters, StrategyLib.Config.Parameters)
|
||||
Strategy.Parameters = BeamLib.LoadCustomParametersInStrategy( CustomParameters)
|
||||
Strategy.Result = {}
|
||||
Strategy.Result.sInfo = ''
|
||||
Chainsaw.Result = {}
|
||||
|
||||
if not IsTopologyOk( Proc) then
|
||||
local sErr = 'Feature '.. Proc.idFeature .. ' : strategy ' .. Strategy.sName .. ' not implemented'
|
||||
EgtOutLog( sErr)
|
||||
Strategy.Result.sStatus = 'Not-Applicable'
|
||||
Strategy.Result.sInfo = 'Topology'
|
||||
return false, Strategy.Result
|
||||
end
|
||||
|
||||
-- se tasca su faccia sotto la strategia non è applicabile (la sega a catena in generale non può lavorare da sotto)
|
||||
if Proc.AffectedFaces.bBottom and ( Proc.nFct > 3 or not Proc.AffectedFaces.bTop) then
|
||||
local sErr = 'Feature '.. Proc.idFeature .. ' : strategy ' .. Strategy.sName .. ' not applicable - pocket on bottom face'
|
||||
EgtOutLog( sErr)
|
||||
Strategy.Result.sStatus = 'Not-Applicable'
|
||||
Strategy.Result.sInfo = 'Direction'
|
||||
return false, Strategy.Result
|
||||
end
|
||||
|
||||
local dExtendAfterTail = Strategy.Parameters.dExtendAfterTail or max( Part.dDistanceToNextPiece - BeamData.CUT_EXTRA, 0)
|
||||
if MachiningLib.CanExtendAfterTail( Strategy.Parameters.sCanDamageNextPiece, Part) then
|
||||
dExtendAfterTail = 10000
|
||||
end
|
||||
|
||||
-- calcolo lavorazioni
|
||||
local Mortising = {}
|
||||
OptionalParameters = { dExtendAfterTail = dExtendAfterTail}
|
||||
if Proc.Topology.sName == 'Groove-4-Blind' or Proc.Topology.sName == 'Pocket-5-Blind' then
|
||||
-- si lavora tutto il fondo
|
||||
local OptionalParameters = { dExtendAfterTail = dExtendAfterTail}
|
||||
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge, OptionalParameters)
|
||||
Chainsaw.AddResult( Mortising)
|
||||
-- materiale residuo - se possibile si lavora dal lato
|
||||
if ( Chainsaw.Result.Bottom[#Chainsaw.Result.Bottom].dResidualDepth > 10 * GEO.EPS_SMALL or not Chainsaw.Result.Bottom[#Chainsaw.Result.Bottom].bIsApplicable) and #Proc.MainFaces.SideFaces == 1 then
|
||||
if Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.bIsStartOpen then
|
||||
local OptionalParameters = { dExtendAfterTail = dExtendAfterTail}
|
||||
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1], OptionalParameters)
|
||||
elseif Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.bIsEndOpen then
|
||||
local OptionalParameters = { dExtendAfterTail = dExtendAfterTail}
|
||||
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[2], OptionalParameters)
|
||||
end
|
||||
Chainsaw.AddResult( Mortising)
|
||||
end
|
||||
elseif Proc.Topology.sName == 'Groove-3-Through' then
|
||||
-- si lavora tutto il fondo
|
||||
local OptionalParameters = { dExtendAfterTail = dExtendAfterTail}
|
||||
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge, OptionalParameters)
|
||||
Chainsaw.AddResult( Mortising)
|
||||
-- materiale residuo - si lavorano i lati
|
||||
if ( Chainsaw.Result.Bottom[1].dResidualDepth > 10 * GEO.EPS_SMALL or not Chainsaw.Result.Bottom[#Chainsaw.Result.Bottom].bIsApplicable) then
|
||||
local OptionalParameters = { dExtendAfterTail = dExtendAfterTail}
|
||||
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1], OptionalParameters)
|
||||
Chainsaw.AddResult( Mortising)
|
||||
-- ancora materiale residuo - si lavora da entrambi i lati
|
||||
if Chainsaw.Result.Side[1].dResidualDepth > 10 * GEO.EPS_SMALL then
|
||||
Chainsaw.Result.Side[1].bIsApplicable = false
|
||||
local OptionalParameters = { bStopAtHalfElevation = true, dExtendAfterTail = dExtendAfterTail}
|
||||
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1], OptionalParameters)
|
||||
Chainsaw.AddResult( Mortising)
|
||||
OptionalParameters = {}
|
||||
OptionalParameters = { bStopAtHalfElevation = true, dExtendAfterTail = dExtendAfterTail}
|
||||
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[2], OptionalParameters)
|
||||
Chainsaw.AddResult( Mortising)
|
||||
-- lavorando dai due lati non c'è materiale residuo - si può disabilitare la lavorazione del fondo
|
||||
if Chainsaw.Result.Side[2].dResidualDepth < 10 * GEO.EPS_SMALL then
|
||||
Chainsaw.Result.Bottom[1].bIsApplicable = false
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
|
||||
local OptionalParameters = { dExtendAfterTail = dExtendAfterTail}
|
||||
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[1], OptionalParameters)
|
||||
Chainsaw.AddResult( Mortising)
|
||||
if Chainsaw.Result.Opposite[1].dResidualDepth > 10 * GEO.EPS_SMALL then
|
||||
Chainsaw.Result.Opposite[1].bIsApplicable = false
|
||||
local OptionalParameters = { bStopAtHalfElevation = true, dExtendAfterTail = dExtendAfterTail}
|
||||
SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[1], OptionalParameters)
|
||||
Chainsaw.AddResult( Mortising)
|
||||
OptionalParameters = {}
|
||||
OptionalParameters = { bStopAtHalfElevation = true, dExtendAfterTail = dExtendAfterTail}
|
||||
SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[2], OptionalParameters)
|
||||
Chainsaw.AddResult( Mortising)
|
||||
end
|
||||
end
|
||||
|
||||
-- lavorazioni raggruppate in unica lista
|
||||
Chainsaw.Result.Sorted = {}
|
||||
for i = 1, #Chainsaw.Result.Side do
|
||||
if Chainsaw.Result.Side[i].bIsApplicable then
|
||||
table.insert( Chainsaw.Result.Sorted, Chainsaw.Result.Side[i])
|
||||
end
|
||||
end
|
||||
for i = 1, #Chainsaw.Result.Bottom do
|
||||
if Chainsaw.Result.Bottom[i].bIsApplicable then
|
||||
table.insert( Chainsaw.Result.Sorted, Chainsaw.Result.Bottom[i])
|
||||
end
|
||||
end
|
||||
for i = 1, #Chainsaw.Result.Opposite do
|
||||
if Chainsaw.Result.Opposite[i].bIsApplicable then
|
||||
table.insert( Chainsaw.Result.Sorted, Chainsaw.Result.Opposite[i])
|
||||
end
|
||||
end
|
||||
|
||||
-- aggiunta eventuali lavorazioni splittate
|
||||
local vFeatureSplittingPoints = FeatureLib.GetFeatureSplittingPoints( Proc, Part)
|
||||
if #vFeatureSplittingPoints > 0 then
|
||||
Chainsaw.Result.Sorted = MachiningLib.GetSplitMachinings( Chainsaw.Result.Sorted, vFeatureSplittingPoints, Part)
|
||||
end
|
||||
|
||||
-- ordinamento
|
||||
-- TODO aggiungere ordinamento per utensile
|
||||
table.sort( Chainsaw.Result.Sorted, SortMachiningsBySegment)
|
||||
|
||||
-- aggiunta lavorazioni
|
||||
local nIsApplicableCount = 0
|
||||
local dFinalCompletionPercentage = 100
|
||||
local bAreAllMachiningsAdded = true
|
||||
for i = 1, #Chainsaw.Result.Sorted do
|
||||
if Chainsaw.Result.Sorted[i].bIsApplicable then
|
||||
nIsApplicableCount = nIsApplicableCount + 1
|
||||
if bAddMachining then
|
||||
local bIsMachiningAdded = Chainsaw.AddMachiningAllSteps( Proc, Chainsaw.Result.Sorted[i])
|
||||
if not bIsMachiningAdded then
|
||||
bAreAllMachiningsAdded = false
|
||||
end
|
||||
end
|
||||
Strategy.Result.sInfo = Strategy.Result.sInfo .. '\n' .. Chainsaw.Result.Sorted[i].sMessage
|
||||
end
|
||||
end
|
||||
if nIsApplicableCount > 0 then
|
||||
if Mortising.dCompletionPercentage > 100 - 10 * GEO.EPS_SMALL then
|
||||
Strategy.Result.sStatus = 'Completed'
|
||||
else
|
||||
Strategy.Result.sStatus = 'Not-Completed'
|
||||
-- TODO al momento si assume che la percentuale di completamento dell'ultima lavorazione sia quella rilevante
|
||||
dFinalCompletionPercentage = Mortising.dCompletionPercentage
|
||||
end
|
||||
else
|
||||
Strategy.Result.sStatus = 'Not-Applicable'
|
||||
end
|
||||
Strategy.Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( dFinalCompletionPercentage)
|
||||
Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'Chainsaw')
|
||||
local MRRParametersChainsaw = {
|
||||
dStep = min( TOOLS[Mortising.nToolIndex].dStep, Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1].dLength),
|
||||
dSideStep = TOOLS[Mortising.nToolIndex].dThickness,
|
||||
dFeed = TOOLS[Mortising.nToolIndex].Feeds.dFeed}
|
||||
local dMRRChainsaw = MachiningLib.GetToolMRR( MRRParametersChainsaw)
|
||||
Strategy.Result.dMRR = dMRRChainsaw
|
||||
|
||||
return bAreAllMachiningsAdded, Strategy.Result
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
|
||||
return STR0004
|
||||
@@ -0,0 +1,15 @@
|
||||
-- Parametri configurabili da cliente per strategia: STR0004
|
||||
|
||||
local STR0004Data = {
|
||||
sStrategyId = 'STR0004',
|
||||
Parameters = {
|
||||
{ sName = 'bUseZigZagMortising', sNameNge = 'USE_ZIGZAG_CHAINSAW', sValue = 'false', sDescriptionShort = '', sDescriptionLong = '', sType = 'b', sMessageId = '', sMinUserLevel = '1'},
|
||||
{ sName = 'dExtendAfterTail', sNameNge = 'EXTEND_AFTER_TAIL', sValue = 'false', sDescriptionShort = '', sDescriptionLong = '', sType = 'd', sMessageId = '', sMinUserLevel = '1'},
|
||||
{ sName = 'sCanDamageNextPiece', sNameNge = 'DAMAGE_NEXT_PIECE', sValue = 'NEVER', sType = 'combo', sMinUserLevel = '1',
|
||||
Choices = { sValue = 'NEVER', sDescriptionShort = '', sDescriptionLong = '', sMessageId = ''},
|
||||
{ sValue = 'ONLY_IF_RAWPART', sDescriptionShort = '', sDescriptionLong = '', sMessageId = ''},
|
||||
{ sValue = 'ALWAYS', sDescriptionShort = '', sDescriptionLong = '', sMessageId = ''}}
|
||||
}
|
||||
}
|
||||
|
||||
return STR0004Data
|
||||
+32
-28
@@ -17,53 +17,53 @@ STR0003 = Topologia tipo LapJoint. Lama + motosega
|
||||
; Feature : Saw Cut
|
||||
13,0,Feature,
|
||||
; Feature : Slot
|
||||
16,0,Pocket-5-Blind,STR0002,STR0003
|
||||
16,0,Groove-4-Blind,STR0002,STR0003
|
||||
16,0,Groove-3-Through,STR0002,STR0003
|
||||
16,0,Pocket-5-Blind,STR0002,STR0003,STR0004
|
||||
16,0,Groove-4-Blind,STR0002,STR0003,STR0004
|
||||
16,0,Groove-3-Through,STR0002,STR0003,STR0004
|
||||
16,0,Groove-3-Blind,STR0002
|
||||
16,0,Rabbet-2-Through,STR0002
|
||||
16,0,Tunnel-4-Through,STR0003
|
||||
16,0,Tunnel-4-Through,STR0003,STR0004
|
||||
; Feature : Front Slot
|
||||
17,0,Pocket-5-Blind,STR0002,STR0003
|
||||
17,0,Groove-4-Blind,STR0002,STR0003
|
||||
17,0,Pocket-5-Blind,STR0002,STR0003,STR0004
|
||||
17,0,Groove-4-Blind,STR0002,STR0003,STR0004
|
||||
17,0,Groove-3-Blind,STR0002
|
||||
17,0,Groove-3-Through,STR0002,STR0003
|
||||
17,0,Groove-3-Through,STR0002,STR0003,STR0004
|
||||
17,0,Rabbet-2-Through,STR0002
|
||||
17,0,Tunnel-4-Through,STR0003
|
||||
17,0,Tunnel-4-Through,STR0003,STR0004
|
||||
; Feature : Birds Mouth
|
||||
20,0,Feature,
|
||||
; Feature : Hip or Valley Rafter Notch
|
||||
25,0,Feature,
|
||||
; Feature : Ridge Lap
|
||||
30,1,Pocket-5-Blind,STR0002,STR0003
|
||||
30,1,Groove-4-Blind,STR0002,STR0003
|
||||
30,1,Pocket-5-Blind,STR0002,STR0003,STR0004
|
||||
30,1,Groove-4-Blind,STR0002,STR0003,STR0004
|
||||
30,1,Groove-3-Blind,STR0002
|
||||
30,1,Groove-3-Through,STR0002,STR0003
|
||||
30,1,Groove-3-Through,STR0002,STR0003,STR0004
|
||||
30,1,Rabbet-2-Through,STR0002
|
||||
30,1,Tunnel-4-Through,STR0003
|
||||
30,1,Tunnel-4-Through,STR0003,STR0004
|
||||
; Feature : Lap Joint
|
||||
30,0,Pocket-5-Blind,STR0002,STR0003
|
||||
30,0,Groove-4-Blind,STR0002,STR0003
|
||||
30,0,Pocket-5-Blind,STR0002,STR0003,STR0004
|
||||
30,0,Groove-4-Blind,STR0002,STR0003,STR0004
|
||||
30,0,Groove-3-Blind,STR0002
|
||||
30,0,Groove-3-Through,STR0002,STR0003
|
||||
30,0,Groove-3-Through,STR0002,STR0003,STR0004
|
||||
30,0,Rabbet-2-Through,STR0002
|
||||
30,0,Tunnel-4-Through,STR0003
|
||||
30,0,Tunnel-4-Through,STR0003,STR0004
|
||||
; Feature : Notch/Rabbet
|
||||
32,0,Pocket-5-Blind,STR0002,STR0003
|
||||
32,0,Groove-4-Blind,STR0002,STR0003
|
||||
32,0,Pocket-5-Blind,STR0002,STR0003,STR0004
|
||||
32,0,Groove-4-Blind,STR0002,STR0003,STR0004
|
||||
32,0,Groove-3-Blind,STR0002
|
||||
32,0,Groove-3-Through,STR0002,STR0003
|
||||
32,0,Groove-3-Through,STR0002,STR0003,STR0004
|
||||
32,0,Rabbet-2-Through,STR0002
|
||||
32,0,Tunnel-4-Through,STR0003
|
||||
32,0,Tunnel-4-Through,STR0003,STR0004
|
||||
; Feature : Block Haus
|
||||
33,0,Feature,
|
||||
; Feature : Notch
|
||||
34,0,Pocket-5-Blind,STR0002,STR0003
|
||||
34,0,Groove-4-Blind,STR0002,STR0003
|
||||
34,0,Pocket-5-Blind,STR0002,STR0003,STR0004
|
||||
34,0,Groove-4-Blind,STR0002,STR0003,STR0004
|
||||
34,0,Groove-3-Blind,STR0002
|
||||
34,0,Groove-3-Through,STR0002,STR0003
|
||||
34,0,Groove-3-Through,STR0002,STR0003,STR0004
|
||||
34,0,Rabbet-2-Through,STR0002
|
||||
34,0,Tunnel-4-Through,STR0003
|
||||
34,0,Tunnel-4-Through,STR0003,STR0004
|
||||
; Feature : French Ridge Lap
|
||||
35,1,Feature,
|
||||
; Feature : Chamfer
|
||||
@@ -73,12 +73,12 @@ STR0003 = Topologia tipo LapJoint. Lama + motosega
|
||||
; Feature : Block Haus Front
|
||||
38,0,Feature,
|
||||
; Feature : Pocket
|
||||
39,0,Pocket-5-Blind,STR0002,STR0003
|
||||
39,0,Groove-4-Blind,STR0002,STR0003
|
||||
39,0,Pocket-5-Blind,STR0002,STR0003,STR0004
|
||||
39,0,Groove-4-Blind,STR0002,STR0003,STR0004
|
||||
39,0,Groove-3-Blind,STR0002
|
||||
39,0,Groove-3-Through,STR0002,STR0003
|
||||
39,0,Groove-3-Through,STR0002,STR0003,STR0004
|
||||
39,0,Rabbet-2-Through,STR0002
|
||||
39,0,Tunnel-4-Through,STR0003
|
||||
39,0,Tunnel-4-Through,STR0003,STR0004
|
||||
; Feature : Drilling
|
||||
40,0,Feature,
|
||||
; Feature : Tenon
|
||||
@@ -137,6 +137,10 @@ STR0003 = Topologia tipo LapJoint. Lama + motosega
|
||||
251,0,Feature,
|
||||
; Feature : Aperture
|
||||
252,0,Feature,
|
||||
; Feature : HEADCUT
|
||||
340,0,Feature,HEADCUT
|
||||
; Feature : SPLITCUT
|
||||
350,0,Feature,SPLITCUT
|
||||
; Feature : Variant
|
||||
900,0,Feature,
|
||||
; Feature Decor
|
||||
|
||||
Reference in New Issue
Block a user