Compare commits
335 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| dc02047db8 | |||
| 168c72af9e | |||
| a0ba2fb535 | |||
| 43e2c61820 | |||
| fca53e5c4c | |||
| 987ffd30d6 | |||
| 30d29add83 | |||
| b73adc5092 | |||
| ab6380c1c5 | |||
| 38f834c421 | |||
| b0827ad72d | |||
| d2669b0af9 | |||
| cc9a2314eb | |||
| 08856faba2 | |||
| cc949b5dd1 | |||
| 2cee0831d0 | |||
| 4ff1405c8e | |||
| b90ef91edb | |||
| b8d3cd461b | |||
| c506486585 | |||
| a73c0c85ac | |||
| fb3a5ec0be | |||
| e3e7537f8f | |||
| eec6b50985 | |||
| b5cb706ad5 | |||
| 053755e583 | |||
| beedbc71f1 | |||
| 8da693817d | |||
| 19f35ccd61 | |||
| 0806e1bab8 | |||
| 387eda8b4a | |||
| c7045499f4 | |||
| 44478b91f0 | |||
| 1f4aa15af4 | |||
| 476f214b99 | |||
| eacabb5af7 | |||
| 5c7751aebd | |||
| 6649842c70 | |||
| 27475763a2 | |||
| 3fcca044ed | |||
| 630d28bf5b | |||
| 5e5f3d08c4 | |||
| a773e0156a | |||
| 72e3b7dc8f | |||
| 10592ac612 | |||
| a5d606b225 | |||
| 3ba456f72f | |||
| 608f8da033 | |||
| 08397ae102 | |||
| b7dbc7422c | |||
| 974d1abb41 | |||
| c4697fbd6f | |||
| b79617fbe4 | |||
| e5f1abc47d | |||
| 965c6e8f9e | |||
| d59039eae0 | |||
| a404bf2f9e | |||
| 1cde1c94d9 | |||
| a66054a6c8 | |||
| b77e79d0d0 | |||
| cad57b2fd5 | |||
| 5e503762e5 | |||
| f27000b7bc | |||
| f90dd95880 | |||
| 0497877abb | |||
| b8299df247 | |||
| 4a99f2bdf6 | |||
| 1e86180723 | |||
| f6d6043c0e | |||
| b048e2ebe2 | |||
| fc47bca0f1 | |||
| 0274096f57 | |||
| 983609397e | |||
| 05a8d23f6a | |||
| 40580cdc69 | |||
| f6b2477f2b | |||
| 69db74e30e | |||
| f58004dfeb | |||
| 7c485360de | |||
| 967117cc23 | |||
| 64b2e86a2d | |||
| 89b342a564 | |||
| 117e475de5 | |||
| a7b817b211 | |||
| d8c6a8ad55 | |||
| 9026acd9ca | |||
| 204346326f | |||
| 5d6e4c397d | |||
| 64bde8924d | |||
| cb6115d23f | |||
| 771c1367b1 | |||
| 6092063daa | |||
| 44650c303c | |||
| 69fa0d741d | |||
| 8e55ddda1f | |||
| 7a8fb04ebe | |||
| 77c27d911c | |||
| 3a29f273c9 | |||
| bab5b07bd1 | |||
| 683ae78c65 | |||
| 06d9529b7b | |||
| 922a7ac846 | |||
| a21a3979f1 | |||
| fcbed252e1 | |||
| b68bbb2c48 | |||
| 6fe6b41e87 | |||
| 78189631c1 | |||
| 1a6433d5f8 | |||
| 28026358b9 | |||
| b73fb86be9 | |||
| 1032557782 | |||
| 0ca5f92b96 | |||
| 0f58c026d0 | |||
| 70d170b2a3 | |||
| 06bc0f77df | |||
| a40cc026c9 | |||
| 34fb38ac00 | |||
| aaa06c1af5 | |||
| 98a48522ee | |||
| 6fd356f757 | |||
| 83895cc3bf | |||
| d001273704 | |||
| 621c9149b5 | |||
| f6f625c7cc | |||
| 9d8985093d | |||
| fe8275f05a | |||
| d32403f546 | |||
| 63d4ca7176 | |||
| 0889ae5c7a | |||
| 0fc9e1dd09 | |||
| 63308c0349 | |||
| 7e5ab8ecd3 | |||
| bddaf91fb7 | |||
| 2c77277c85 | |||
| 38a6ac237e | |||
| ed4d97ba51 | |||
| 7b12eaf331 | |||
| 3e55af917e | |||
| 73b6d80510 | |||
| 65c2c244d6 | |||
| 2ae547a24e | |||
| aff61f1daa | |||
| 0db6a74f8c | |||
| f68533944c | |||
| 37e08e3f42 | |||
| c6ced91b14 | |||
| 8efb64810a | |||
| 02390c2e9b | |||
| 7f7d75c113 | |||
| ecd50c0fea | |||
| 6f195e7fac | |||
| 626183f310 | |||
| fe6c0bb31c | |||
| 1c24f1046d | |||
| 70cfdd056f | |||
| 9ebb9c77db | |||
| a54fbb1259 | |||
| 1345c5a5cb | |||
| 9add357cb6 | |||
| b1ae9db859 | |||
| 57d555fb0b | |||
| 28a6049c77 | |||
| c8848974a4 | |||
| 6591396009 | |||
| b0531f8df8 | |||
| 67a595e311 | |||
| 7a84f2c396 | |||
| 19f62cdc90 | |||
| 0f20358607 | |||
| 8875fc4c68 | |||
| ee4d443074 | |||
| 995917672c | |||
| d5b9612406 | |||
| 4521910c56 | |||
| 267fc9daa3 | |||
| c997cb4440 | |||
| b98b03adba | |||
| f2f57be09f | |||
| efe7f2e0f9 | |||
| 8f04694232 | |||
| c14377fb67 | |||
| c491d635e7 | |||
| 18fe9ceccb | |||
| 86c36512a0 | |||
| 4bdb1b32b1 | |||
| 0a073ead4c | |||
| 76c8f45284 | |||
| 5c463298da | |||
| 7b16ace7a4 | |||
| 66159b25a8 | |||
| 518ad5e10a | |||
| fc7432a97a | |||
| 583aa789c4 | |||
| 92036b09b4 | |||
| 6d2a1664ce | |||
| 5934b07947 | |||
| 85147dc34a | |||
| 465ffc7e37 | |||
| 31f1f50d04 | |||
| 7867317982 | |||
| ab9ea95b45 | |||
| c52a3f4af6 | |||
| 598d717dbc | |||
| ab606d759e | |||
| a6d9a36dab | |||
| 8c573d25b2 | |||
| 5554977011 | |||
| d3a9284944 | |||
| 90f06cb7ec | |||
| 8897f3f00b | |||
| 1e4e75115c | |||
| d3bf465923 | |||
| 9f6a89d5ae | |||
| 6f730dcaec | |||
| f1cdaa498d | |||
| 217a359ba0 | |||
| da23b96a9c | |||
| fe358e3ca4 | |||
| 6a7f32b5c1 | |||
| 9b9758fd2c | |||
| 667da4e3d1 | |||
| fe309e338b | |||
| 340a249948 | |||
| 0f5a1215f9 | |||
| 5d461bbc39 | |||
| 4986d3bf67 | |||
| d5243cda37 | |||
| e1e46445b0 | |||
| 570e41a40d | |||
| f3938ee0b6 | |||
| 309bae0265 | |||
| c068479ec1 | |||
| 608a9c63c8 | |||
| 38d432fd79 | |||
| 3b65f6233d | |||
| f1805625d3 | |||
| 568de09954 | |||
| 70025d1816 | |||
| fb74d28926 | |||
| 73acee6695 | |||
| c3a82a0804 | |||
| 6d1cae6ff3 | |||
| 2bcaeca91f | |||
| 3136604e14 | |||
| 82cd8f5d8c | |||
| e9493ead6b | |||
| e9417ba322 | |||
| 79417998a2 | |||
| c290254bae | |||
| 604a2676ce | |||
| 827a709af0 | |||
| 05f729df45 | |||
| 646e69e3af | |||
| ef155ad1fb | |||
| 6609c7ee16 | |||
| 5068d75362 | |||
| e646351f3f | |||
| 660cca04ca | |||
| 5d15189d59 | |||
| 50dee06493 | |||
| 3d3ae22f87 | |||
| 21b2e1cd0a | |||
| 7bd18a8fb4 | |||
| 1c4970fdb6 | |||
| 77d6d89e13 | |||
| eb3cf0d7ff | |||
| 5ad9e0bf4f | |||
| c3ea568d99 | |||
| 30f59b0175 | |||
| c18e80a70d | |||
| ae30cb5736 | |||
| cd586673c7 | |||
| f426311b28 | |||
| e2a2d0fd4e | |||
| 69c31e4c2b | |||
| 56ca5a74b9 | |||
| ad1ea741d0 | |||
| 322412a1f3 | |||
| c1a563351a | |||
| 327a5a960d | |||
| fdfefaba74 | |||
| c76eba6e74 | |||
| c6b3b5a003 | |||
| a4fbfcf2c9 | |||
| fa1a12b41c | |||
| d162b27493 | |||
| 68da716da1 | |||
| d6900a2c59 | |||
| 4bbadb8581 | |||
| cb60773216 | |||
| 1e327819c6 | |||
| d5b4edea14 | |||
| 530dce3d0d | |||
| dc8c5e8ba2 | |||
| a2ed6f5789 | |||
| 198fa3a546 | |||
| 1ad5a74a8b | |||
| a8c6424839 | |||
| 9ed315ab9b | |||
| 1c8049d9a9 | |||
| 155fd09ee5 | |||
| 86adb74131 | |||
| 74a12a4a42 | |||
| 06a73a069f | |||
| e6a2ce3702 | |||
| e3cd0d3033 | |||
| eb0a46d545 | |||
| f9b1a957f6 | |||
| 8f2a09e5c7 | |||
| 711ac3930d | |||
| 4ce77a4792 | |||
| 15db75dfad | |||
| 6d319d17b6 | |||
| d8a3f257d8 | |||
| 43b096f531 | |||
| d9d505fc44 | |||
| ddff655240 | |||
| 2536244f1b | |||
| 7b4673acef | |||
| 2d1abbb3cc | |||
| 25dbaed63b | |||
| ecd2147e83 | |||
| 84cd799565 | |||
| 9468e3d013 | |||
| e095806a7a | |||
| f21e1ea557 | |||
| 21bb95c0e9 | |||
| b8b71ff73a | |||
| 0afcd786d1 | |||
| 070ad50d73 | |||
| d6bdbab510 | |||
| 44273e15a7 | |||
| 711e0c82f7 | |||
| c62f1818c7 | |||
| 9fe22368cb |
+143
-29
@@ -32,7 +32,7 @@ if not sMachDir then
|
||||
EgtOutBox( 'Errore nel caricamento della macchina corrente', 'Lavora Travi', 'ERROR')
|
||||
return
|
||||
end
|
||||
if not EgtExistsFile( sMachDir .. '\\Beam\\BeamData.lua') then
|
||||
if not EgtExistsFile( sMachDir .. '\\Beam\\BeamDataNew.lua') then
|
||||
EgtOutBox( 'La macchina corrente non è configurata per lavorare travi', 'Lavora Travi', 'ERROR')
|
||||
BEAM.ERR = 12
|
||||
BEAM.MSG = 'Error not configured for beams machine : ' .. sMachine
|
||||
@@ -58,11 +58,15 @@ _G.package.loaded.FeatureLib = nil
|
||||
_G.package.loaded.Identity = nil
|
||||
_G.package.loaded.Logs = nil
|
||||
_G.package.loaded.MachiningLib = nil
|
||||
_G.package.loaded.PreSimulationLib = nil
|
||||
_G.package.loaded.LeadInOutLib = nil
|
||||
-- strategie di base sempre presenti
|
||||
_G.package.loaded['HEADCUT\\HEADCUT'] = nil
|
||||
_G.package.loaded['TAILCUT\\TAILCUT'] = nil
|
||||
-- libreria macchina
|
||||
_G.package.loaded.BeamData = nil
|
||||
_G.package.loaded.BeamDataNew = nil
|
||||
-- libreria calcolo tempo esecuzione
|
||||
_G.package.loaded.TimeLib = 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.
|
||||
@@ -88,7 +92,7 @@ end
|
||||
PARTS = {} -- tabella contenente tutte le informazioni di ogni pezzo
|
||||
|
||||
-- Carico i dati globali
|
||||
local BeamData = require( 'BeamData')
|
||||
local BeamData = require( 'BeamDataNew')
|
||||
-- carico librerie
|
||||
local BeamExec = require( 'BeamExec')
|
||||
local BeamLib = require( 'BeamLib')
|
||||
@@ -178,6 +182,13 @@ local function WriteResultToJson( RESULT)
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
|
||||
-- calcolo tempo esecuzione
|
||||
TIMER:start()
|
||||
EgtOutLog( ' Execution timer started')
|
||||
|
||||
-- script principale
|
||||
|
||||
local sFlag = ''
|
||||
if BEAM.FLAG == 0 then
|
||||
sFlag = 'GENERATE'
|
||||
@@ -200,12 +211,9 @@ elseif BEAM.FLAG == 10 then
|
||||
else
|
||||
sFlag = 'FLAG='..tostring( BEAM.FLAG)
|
||||
end
|
||||
local sLog = 'BatchProcess : ' .. BEAM.FILE .. ', ' .. BEAM.MACHINE .. ', ' .. sFlag
|
||||
local sLog = 'BatchProcess : ' .. BEAM.FILE .. ', ' .. ( BEAM.MACHINE or EgtGetCurrMachineName()) .. ', ' .. sFlag
|
||||
EgtOutLog( sLog)
|
||||
|
||||
-- TODO forzatura calcolo con prerotazioni. Cancellare dopo che è stata aggiunta la gestione corretta
|
||||
local bCalcBestPieceUnloadPosition = true or BEAM.FLAG == 10
|
||||
|
||||
-- Dati dei file
|
||||
-- TODO spostare a quando flag ~= 6 e 9
|
||||
local sDir, sTitle = EgtSplitPath( BEAM.FILE)
|
||||
@@ -235,11 +243,14 @@ elseif BEAM.FLAG == 9 then
|
||||
|
||||
local Part = {}
|
||||
Part.id = EgtGetParent( EgtGetParent( BEAM.FEATUREID))
|
||||
Part.b3Part = EgtGetBBoxGlob( EgtGetFirstNameInGroup( Part.id, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
|
||||
Part.idBoxTm = EgtGetFirstInGroup( EgtGetFirstNameInGroup( Part.id, 'Box') or GDB_ID.NULL)
|
||||
Part.b3Part = EgtGetBBoxGlob( Part.idBoxTm, GDB_BB.STANDARD)
|
||||
Part.idTempGroup = idTempGroup
|
||||
|
||||
local Proc = FeatureLib.GetProcFromTrimesh( BEAM.FEATUREID, Part)
|
||||
Proc.nGrp = EgtGetInfo( Proc.id, 'GRP', 'i')
|
||||
Proc.nPrc = EgtGetInfo( Proc.id, 'PRC', 'i')
|
||||
Proc.nParts = EgtSurfTmPartCount( Proc.id) or 1
|
||||
|
||||
Proc.Topology = {}
|
||||
if FeatureLib.NeedTopologyFeature( Proc, Part) then
|
||||
@@ -299,6 +310,9 @@ if bToProcess then
|
||||
BEAM.MSG = 'Error opening BWE file : ' .. BEAM.FILE
|
||||
WriteErrToLogFile( BEAM.ERR, BEAM.MSG)
|
||||
PostErrView( BEAM.ERR, BEAM.MSG)
|
||||
BeamExec.AddApplyResultToGlobalList( BEAM.ERR, 0, BEAM.MSG)
|
||||
BEAM.RESULT = BeamLib.TableCopyDeep( RESULT)
|
||||
WriteResultToJson( RESULT)
|
||||
return
|
||||
end
|
||||
-- Faccio copia del file originale
|
||||
@@ -319,6 +333,9 @@ if bToProcess then
|
||||
BEAM.MSG = 'Error no Raw Parts in the file : ' .. BEAM.FILE
|
||||
WriteErrToLogFile( BEAM.ERR, BEAM.MSG)
|
||||
PostErrView( BEAM.ERR, BEAM.MSG)
|
||||
BeamExec.AddApplyResultToGlobalList( BEAM.ERR, 0, BEAM.MSG)
|
||||
BEAM.RESULT = BeamLib.TableCopyDeep( RESULT)
|
||||
WriteResultToJson( RESULT)
|
||||
return
|
||||
end
|
||||
local b3Raw = EgtGetRawPartBBox( nRawId)
|
||||
@@ -343,6 +360,9 @@ if bToProcess then
|
||||
BEAM.MSG = 'Error no beams in the file : ' .. BEAM.FILE
|
||||
WriteErrToLogFile( BEAM.ERR, BEAM.MSG)
|
||||
PostErrView( BEAM.ERR, BEAM.MSG)
|
||||
BeamExec.AddApplyResultToGlobalList( BEAM.ERR, 0, BEAM.MSG)
|
||||
BEAM.RESULT = BeamLib.TableCopyDeep( RESULT)
|
||||
WriteResultToJson( RESULT)
|
||||
return
|
||||
else
|
||||
local sOut = ''
|
||||
@@ -361,10 +381,22 @@ if bToProcess then
|
||||
BEAM.MSG = 'Box undefined for beam ' .. PARTS[i].sName
|
||||
WriteErrToLogFile( BEAM.ERR, BEAM.MSG)
|
||||
PostErrView( BEAM.ERR, BEAM.MSG)
|
||||
BeamExec.AddApplyResultToGlobalList( BEAM.ERR, 0, BEAM.MSG)
|
||||
BEAM.RESULT = BeamLib.TableCopyDeep( RESULT)
|
||||
WriteResultToJson( RESULT)
|
||||
return
|
||||
else
|
||||
PARTS[i].b3PartOriginal = b3Solid
|
||||
end
|
||||
if BeamData.MAX_LENGTH and BeamData.MAX_LENGTH > 10 and b3Solid:getDimX() > BeamData.MAX_LENGTH then
|
||||
local sOut = 'Piece-Length (' .. EgtNumToString( b3Solid:getDimX(), 2) .. ') ' ..
|
||||
'out of machine limits (' .. EgtNumToString( BeamData.MAX_LENGTH, 2) .. ') '
|
||||
BEAM.ERR = 17
|
||||
BEAM.MSG = sOut
|
||||
WriteErrToLogFile( BEAM.ERR, BEAM.MSG)
|
||||
PostErrView( BEAM.ERR, BEAM.MSG)
|
||||
return
|
||||
end
|
||||
end
|
||||
-- Assegno lunghezza della barra
|
||||
dBarLen = PARTS[1].b3PartOriginal:getDimX() + 10
|
||||
@@ -397,6 +429,9 @@ if bToProcess then
|
||||
BEAM.ERR = 14
|
||||
BEAM.MSG = 'Error : no beams in the project'
|
||||
WriteErrToLogFile( BEAM.ERR, BEAM.MSG)
|
||||
BeamExec.AddApplyResultToGlobalList( BEAM.ERR, 0, BEAM.MSG)
|
||||
BEAM.RESULT = BeamLib.TableCopyDeep( RESULT)
|
||||
WriteResultToJson( RESULT)
|
||||
return
|
||||
else
|
||||
local sOut = ''
|
||||
@@ -414,16 +449,31 @@ if bToProcess then
|
||||
BEAM.ERR = 15
|
||||
BEAM.MSG = 'Box undefined for beam ' .. PARTS[i].sName
|
||||
WriteErrToLogFile( BEAM.ERR, BEAM.MSG)
|
||||
BeamExec.AddApplyResultToGlobalList( BEAM.ERR, 0, BEAM.MSG)
|
||||
BEAM.RESULT = BeamLib.TableCopyDeep( RESULT)
|
||||
WriteResultToJson( RESULT)
|
||||
return
|
||||
else
|
||||
PARTS[i].b3PartOriginal = b3Solid
|
||||
end
|
||||
if BeamData.MAX_LENGTH and BeamData.MAX_LENGTH > 10 and b3Solid:getDimX() > BeamData.MAX_LENGTH then
|
||||
local sOut = 'Piece-Length (' .. EgtNumToString( b3Solid:getDimX(), 2) .. ') ' ..
|
||||
'out of machine limits (' .. EgtNumToString( BeamData.MAX_LENGTH, 2) .. ') '
|
||||
BEAM.ERR = 17
|
||||
BEAM.MSG = sOut
|
||||
WriteErrToLogFile( BEAM.ERR, BEAM.MSG)
|
||||
PostErrView( BEAM.ERR, BEAM.MSG)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- recupero parametri generali da progetto
|
||||
BeamExec.GetGeneralParameters()
|
||||
|
||||
-- creo un gruppo temporaneo dove finiranno tutte le entità che non bisogna salvare, alla fine lo si cancella
|
||||
local idTempGroup = BeamLib.CreateTempGroup()
|
||||
|
||||
-- Se devo creare la barra
|
||||
if bCreateBar then
|
||||
if #PARTS == 0 then
|
||||
@@ -460,6 +510,7 @@ if bToProcess then
|
||||
return
|
||||
end
|
||||
|
||||
-- TODO in caso di "GEN_sPiecesLoadingPosition = FULL_PRE_ROTATION" bisogna controllare anche sezione ribaltata di 90°
|
||||
-- Verifico sezione barra non troppo grande
|
||||
if not BeamData.MAX_WIDTH2 or not BeamData.MAX_HEIGHT2 then
|
||||
if ( dRawW > BeamData.MAX_WIDTH + 10 * GEO.EPS_SMALL or dRawH > BeamData.MAX_HEIGHT + 10 * GEO.EPS_SMALL) then
|
||||
@@ -470,6 +521,9 @@ if bToProcess then
|
||||
BEAM.MSG = sOut
|
||||
WriteErrToLogFile( BEAM.ERR, BEAM.MSG)
|
||||
PostErrView( BEAM.ERR, BEAM.MSG)
|
||||
BeamExec.AddApplyResultToGlobalList( BEAM.ERR, 0, BEAM.MSG)
|
||||
BEAM.RESULT = BeamLib.TableCopyDeep( RESULT)
|
||||
WriteResultToJson( RESULT)
|
||||
return
|
||||
end
|
||||
else
|
||||
@@ -483,6 +537,9 @@ if bToProcess then
|
||||
BEAM.MSG = sOut
|
||||
WriteErrToLogFile( BEAM.ERR, BEAM.MSG)
|
||||
PostErrView( BEAM.ERR, BEAM.MSG)
|
||||
BeamExec.AddApplyResultToGlobalList( BEAM.ERR, 0, BEAM.MSG)
|
||||
BEAM.RESULT = BeamLib.TableCopyDeep( RESULT)
|
||||
WriteResultToJson( RESULT)
|
||||
return
|
||||
end
|
||||
end
|
||||
@@ -496,6 +553,9 @@ if bToProcess then
|
||||
BEAM.MSG = sOut
|
||||
WriteErrToLogFile( BEAM.ERR, BEAM.MSG)
|
||||
PostErrView( BEAM.ERR, BEAM.MSG)
|
||||
BeamExec.AddApplyResultToGlobalList( BEAM.ERR, 0, BEAM.MSG)
|
||||
BEAM.RESULT = BeamLib.TableCopyDeep( RESULT)
|
||||
WriteResultToJson( RESULT)
|
||||
return
|
||||
end
|
||||
|
||||
@@ -508,12 +568,15 @@ if bToProcess then
|
||||
end
|
||||
|
||||
-- Sistemo le travi nel grezzo
|
||||
local bPbOk, sPbErr = BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, nil, PARTS, BEAM.FLAG ~= 6, bCalcBestPieceUnloadPosition)
|
||||
local bPbOk, sPbErr = BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, nil, PARTS, BEAM.FLAG ~= 6, BEAM.FLAG == 10)
|
||||
if not bPbOk then
|
||||
BEAM.ERR = 18
|
||||
BEAM.MSG = sPbErr
|
||||
WriteErrToLogFile( BEAM.ERR, BEAM.MSG)
|
||||
PostErrView( BEAM.ERR, BEAM.MSG)
|
||||
BeamExec.AddApplyResultToGlobalList( BEAM.ERR, 0, BEAM.MSG)
|
||||
BEAM.RESULT = BeamLib.TableCopyDeep( RESULT)
|
||||
WriteResultToJson( RESULT)
|
||||
return
|
||||
else
|
||||
-- Scrivo altezza e larghezza barra nel gruppo di lavoro corrente
|
||||
@@ -573,7 +636,8 @@ if bToProcess then
|
||||
PARTS[i].dRawWidth = PARTS[i].b3Raw:getDimY()
|
||||
PARTS[i].dRawHeight = PARTS[i].b3Raw:getDimZ()
|
||||
-- dimensione pezzo finito
|
||||
PARTS[i].b3Part = EgtGetBBoxGlob( EgtGetFirstNameInGroup( PARTS[i].id, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
|
||||
PARTS[i].idBoxTm = EgtGetFirstInGroup( EgtGetFirstNameInGroup( PARTS[i].id, 'Box') or GDB_ID.NULL)
|
||||
PARTS[i].b3Part = EgtGetBBoxGlob( PARTS[i].idBoxTm, GDB_BB.STANDARD)
|
||||
PARTS[i].dLength = PARTS[i].b3Part:getDimX()
|
||||
PARTS[i].dWidth = PARTS[i].b3Part:getDimY()
|
||||
PARTS[i].dHeight = PARTS[i].b3Part:getDimZ()
|
||||
@@ -582,15 +646,19 @@ if bToProcess then
|
||||
PARTS[i].SplittingPoints = BeamLib.GetPartSplittingPoints( PARTS[i])
|
||||
PARTS[i].NotClampableLength = { STD = { dHead = 0, dTail = 0}, SIDE = { dHead = 0, dTail = 0}, DOWN = { dHead = 0, dTail = 0}}
|
||||
PARTS[i].sBTLInfo = EgtGetInfo( PARTS[i].id, 'PROJ', 's') or nil
|
||||
PARTS[i].idTempGroup = idTempGroup
|
||||
|
||||
PARTS[i].sAISetupConfig = EgtGetInfo( PARTS[i].id, 'AISETUP', 's') or
|
||||
( GENERAL_PARAMETERS.BTL[PARTS[i].sBTLInfo] and GENERAL_PARAMETERS.BTL[PARTS[i].sBTLInfo].sAISetupConfig) or -- i parametri BTL potrebbero non esistere
|
||||
GENERAL_PARAMETERS.PROJECT.sAISetupConfig or nil
|
||||
|
||||
-- si carica configurazione lavorazioni
|
||||
TIMER:startElapsed('Json')
|
||||
BeamExec.GetStrategiesFromJSONinBD( PARTS[i].sAISetupConfig)
|
||||
PARTS[i].GeneralParameters = BeamLib.GetPieceGeneralParameters( PARTS[i], GENERAL_PARAMETERS_JSON)
|
||||
PARTS[i].CombinationList = BeamExec.GetAvailableCombinations( PARTS[i], bCalcBestPieceUnloadPosition)
|
||||
TIMER:stopElapsed('Json')
|
||||
-- parametro FlipRot sempre a false perchè a barra già creata non si possono più ruotare i pezzi
|
||||
PARTS[i].CombinationList = BeamExec.GetAvailableCombinations( PARTS[i], false)
|
||||
|
||||
-- sovramateriale in testa al pezzo
|
||||
local dDeltaS = max( PARTS[i].dPosX - ( dBarLen - dLen), 0)
|
||||
@@ -621,6 +689,9 @@ if bToProcess then
|
||||
BEAM.ERR = 0
|
||||
BEAM.MSG = '---'
|
||||
WriteErrToLogFile( BEAM.ERR, BEAM.MSG)
|
||||
BeamExec.AddApplyResultToGlobalList( BEAM.ERR, 0, BEAM.MSG)
|
||||
BEAM.RESULT = BeamLib.TableCopyDeep( RESULT)
|
||||
WriteResultToJson( RESULT)
|
||||
end
|
||||
EgtOutLog( ' +++ BatchProcess completed')
|
||||
return
|
||||
@@ -637,23 +708,15 @@ if bToProcess then
|
||||
EgtImportSetup()
|
||||
|
||||
-- Lavoro le features
|
||||
-- TODO gestire errori e messaggi di ritorno in questo caso
|
||||
if not GetDataConfig() then return end
|
||||
|
||||
-- creo un gruppo temporaneo dove finiranno tutte le entità che non bisogna salvare, alla fine lo si cancella
|
||||
BeamLib.CreateTempGroup()
|
||||
|
||||
BeamExec.GetProcessings( PARTS, bCalcBestPieceUnloadPosition)
|
||||
BeamExec.GetCombinationMatrix( PARTS, bCalcBestPieceUnloadPosition)
|
||||
BeamExec.ProcessMachinings( PARTS)
|
||||
|
||||
-- si cancella gruppo temporaneo contenente entità da cancellare
|
||||
local idTempGroup = BeamLib.GetTempGroup()
|
||||
EgtErase( idTempGroup)
|
||||
BeamExec.GetProcessings( PARTS, BEAM.FLAG == 10)
|
||||
BeamExec.GetCombinationMatrix( PARTS, BEAM.FLAG == 10)
|
||||
BeamExec.ProcessMachinings( PARTS, BEAM.FLAG == 10)
|
||||
|
||||
local sOutput = ''
|
||||
|
||||
-- Scrittura json risultati
|
||||
WriteResultToJson( RESULT)
|
||||
-- scrittura txt risultati
|
||||
for i = 1, #RESULT do
|
||||
local sMsg = ''
|
||||
@@ -670,9 +733,14 @@ if bToProcess then
|
||||
sMsg = string.gsub( sMsg or '', '\r', ' ', 10)
|
||||
-- trovata almeno una strategia e feature lavorata completamente
|
||||
if RESULT[i].sType == 'Feature' and RESULT[i].ChosenStrategy.sStatus == 'Completed' then
|
||||
BEAM.ERR = 0
|
||||
BEAM.MSG = '---'
|
||||
BEAM.ROT = -( RESULT[i].nRotation or 1) + 1
|
||||
if #EgtTrim( sMsg) > 0 then
|
||||
BEAM.ERR = -19
|
||||
BEAM.MSG = sMsg
|
||||
else
|
||||
BEAM.ERR = 0
|
||||
BEAM.MSG = '---'
|
||||
end
|
||||
BEAM.ROT = -( ( RESULT[i].nRotation - ( BEAM.PREROTATE90 or 0)) or 1) + 1
|
||||
BEAM.CUTID = RESULT[i].idCut
|
||||
BEAM.TASKID = RESULT[i].idTask
|
||||
WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.TASKID)
|
||||
@@ -688,7 +756,7 @@ if bToProcess then
|
||||
sOutput = sOutput .. string.format( '[%d,%d] %s\n', RESULT[i].idCut, RESULT[i].idTask, sMsg)
|
||||
BEAM.ERR = 19
|
||||
BEAM.MSG = sMsg
|
||||
BEAM.ROT = -( RESULT[i].nRotation or 1) + 1
|
||||
BEAM.ROT = -( ( RESULT[i].nRotation - ( BEAM.PREROTATE90 or 0)) or 1) + 1
|
||||
BEAM.CUTID = RESULT[i].idCut
|
||||
BEAM.TASKID = RESULT[i].idTask
|
||||
WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.TASKID)
|
||||
@@ -700,13 +768,21 @@ if bToProcess then
|
||||
BEAM.CUTID = RESULT[i].idCut
|
||||
BEAM.FALL = abs( RESULT[i].nErr + 100)
|
||||
WriteFallToLogFile( BEAM.ERR, BEAM.MSG, BEAM.CUTID, BEAM.FALL)
|
||||
-- errore da post apply, al momento non specifico
|
||||
elseif RESULT[i].sType == 'Part' and RESULT[i].nErr > 0 then
|
||||
nErrCnt = nErrCnt + 1
|
||||
sOutput = sOutput .. string.format( '[%d,%d] %s\n', RESULT[i].idCut, RESULT[i].idTask, sMsg)
|
||||
BEAM.ERR = 19
|
||||
BEAM.MSG = 'Clamp impossible'
|
||||
WriteErrToLogFile( BEAM.ERR, BEAM.MSG)
|
||||
return
|
||||
-- feature incompleta e altro
|
||||
elseif RESULT[i].sType == 'Feature' and RESULT[i].ChosenStrategy.sStatus == 'Not-Completed' then
|
||||
nWarnCnt = nWarnCnt + 1
|
||||
sOutput = sOutput .. string.format( '[%d,%d] %s\n', RESULT[i].idCut, RESULT[i].idTask, sMsg)
|
||||
BEAM.ERR = -19
|
||||
BEAM.MSG = 'Incomplete : Completion index ' .. RESULT[i].ChosenStrategy.dCompletionIndex .. '/5\n' .. sMsg
|
||||
BEAM.ROT = -( RESULT[i].nRotation or 1) + 1
|
||||
BEAM.ROT = -( ( RESULT[i].nRotation - ( BEAM.PREROTATE90 or 0)) or 1) + 1
|
||||
BEAM.CUTID = RESULT[i].idCut
|
||||
BEAM.TASKID = RESULT[i].idTask
|
||||
WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.TASKID)
|
||||
@@ -714,6 +790,18 @@ if bToProcess then
|
||||
end
|
||||
end
|
||||
|
||||
-- calcolo alternative (scrive già le variabili globali per interfaccia)
|
||||
if BEAM.FLAG == 10 then
|
||||
TIMER:startElapsed('Alternatives')
|
||||
BeamExec.ProcessAlternatives( PARTS)
|
||||
TIMER:stopElapsed('Alternatives')
|
||||
end
|
||||
|
||||
-- si cancella gruppo temporaneo contenente entità da cancellare
|
||||
EgtErase( idTempGroup)
|
||||
|
||||
-- TODO: se scarico a caduta (-101, -102) le lavorazioni dopo separazione vanno disattivate. Scrivere info feature incompleta su quelle feature
|
||||
|
||||
-- Salvo il progetto
|
||||
EgtSaveFile( sNgeFile)
|
||||
-- copio come originale (per dichiarare progetto ricalcolato)
|
||||
@@ -746,6 +834,11 @@ else
|
||||
end
|
||||
end
|
||||
|
||||
-- log tempi di esecuzione
|
||||
if EgtGetDebugLevel() >= 3 then
|
||||
TIMER:logAllElapsed()
|
||||
end
|
||||
|
||||
-- *** Eseguo simulazione con verifica collisione in cieco ***
|
||||
if ( BEAM.FLAG == 0 and ( bToProcess or bToRecalc)) or BEAM.FLAG == 3 or BEAM.FLAG == 4 then
|
||||
EgtOutLog( ' +++ Simulating with collision check >>>')
|
||||
@@ -759,7 +852,12 @@ if ( BEAM.FLAG == 0 and ( bToProcess or bToRecalc)) or BEAM.FLAG == 3 or BEAM.F
|
||||
sToolsList = sToolsList .. ", "
|
||||
end
|
||||
end
|
||||
WriteErrToLogFile( 19, 'Error in setup: tool/s ' .. sToolsList .. ' not found', 0, 0, 0)
|
||||
BEAM.ERR = 19
|
||||
BEAM.MSG = 'Error in setup: tool/s ' .. sToolsList .. ' not found'
|
||||
WriteErrToLogFile( BEAM.ERR, BEAM.MSG, 0, 0, 0)
|
||||
BeamExec.AddApplyResultToGlobalList( BEAM.ERR, 0, BEAM.MSG)
|
||||
BEAM.RESULT = BeamLib.TableCopyDeep( RESULT)
|
||||
WriteResultToJson( RESULT)
|
||||
return
|
||||
end
|
||||
-- lancio simulazione
|
||||
@@ -794,6 +892,10 @@ if ( BEAM.FLAG == 0 and ( bToProcess or bToRecalc)) or BEAM.FLAG == 3 or BEAM.F
|
||||
end
|
||||
end
|
||||
WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.TASKID)
|
||||
-- TODO gestire collisione su feature specifica!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
BeamExec.AddApplyResultToGlobalList( BEAM.ERR, BEAM.CUTID, BEAM.MSG)
|
||||
BEAM.RESULT = BeamLib.TableCopyDeep( RESULT)
|
||||
WriteResultToJson( RESULT)
|
||||
return
|
||||
end
|
||||
end
|
||||
@@ -813,6 +915,9 @@ if bIsGenerationEnabled and ( BEAM.FLAG == 0 or BEAM.FLAG == 4) then
|
||||
BEAM.MSG = 'Error generating NC part program : ' .. sName
|
||||
WriteErrToLogFile( BEAM.ERR, BEAM.MSG)
|
||||
PostErrView( BEAM.ERR, BEAM.MSG)
|
||||
BeamExec.AddApplyResultToGlobalList( BEAM.ERR, 0, BEAM.MSG)
|
||||
BEAM.RESULT = BeamLib.TableCopyDeep( RESULT)
|
||||
WriteResultToJson( RESULT)
|
||||
return
|
||||
end
|
||||
end
|
||||
@@ -825,6 +930,9 @@ if not EgtEstimate( '', 'EgtCAM5 - ' .. sNgeFile) then
|
||||
BEAM.MSG = 'Error estimating production time : ' .. sName
|
||||
WriteErrToLogFile( BEAM.ERR, BEAM.MSG)
|
||||
PostErrView( BEAM.ERR, BEAM.MSG)
|
||||
BeamExec.AddApplyResultToGlobalList( BEAM.ERR, 0, BEAM.MSG)
|
||||
BEAM.RESULT = BeamLib.TableCopyDeep( RESULT)
|
||||
WriteResultToJson( RESULT)
|
||||
return
|
||||
end
|
||||
local Ttot = EgtGetInfo( EgtGetCurrMachGroup(), 'Ttot', 'd')
|
||||
@@ -847,5 +955,11 @@ end
|
||||
|
||||
-- Scrittura tempo totale stimato di lavorazione
|
||||
WriteTimeToLogFile( Ttot)
|
||||
RESULT[#RESULT+1] = { dTime = Ttot, sType = 'Time'}
|
||||
|
||||
-- Riporto risultati in tabella globale BEAM
|
||||
BEAM.RESULT = BeamLib.TableCopyDeep( RESULT)
|
||||
-- Scrittura json risultati
|
||||
WriteResultToJson( RESULT)
|
||||
|
||||
EgtOutLog( ' +++ BatchProcess completed')
|
||||
|
||||
+247
@@ -0,0 +1,247 @@
|
||||
-- Process.lua by Egalware s.r.l. 2024/04/02
|
||||
-- Gestione calcolo disposizione e lavorazioni per Travi
|
||||
-- Si opera sulla macchina corrente
|
||||
-- 2024/04/02 PRIMA VERSIONE
|
||||
|
||||
|
||||
-- Intestazioni
|
||||
require( 'EgtBase')
|
||||
_ENV = EgtProtectGlobal()
|
||||
EgtEnableDebug( false)
|
||||
|
||||
-- Imposto direttorio libreria specializzata per Travi
|
||||
EgtAddToPackagePath( BEAM.BASEDIR .. '\\LuaLibs\\?.lua')
|
||||
-- Imposto direttorio strategie. N.B. Le strategie dovranno essere caricate con il nome del direttorio padre
|
||||
EgtAddToPackagePath( BEAM.BASEDIR .. '\\Strategies\\Standard\\?.lua')
|
||||
EgtAddToPackagePath( BEAM.BASEDIR .. '\\StrategyLibs\\?.lua')
|
||||
|
||||
-- Verifico che la macchina corrente sia abilitata per la lavorazione delle Travi
|
||||
local sMachDir = EgtGetCurrMachineDir()
|
||||
if not sMachDir then
|
||||
EgtOutBox( 'Errore nel caricamento della macchina corrente', 'Lavora Travi', 'ERROR')
|
||||
return
|
||||
end
|
||||
if not EgtExistsFile( sMachDir .. '\\Beam\\BeamDataNew.lua') then
|
||||
EgtOutBox( 'La macchina corrente non è configurata per lavorare travi', 'Lavora Travi', 'ERROR')
|
||||
return
|
||||
end
|
||||
|
||||
-- Elimino direttori altre macchine e imposto direttorio macchina corrente per ricerca librerie
|
||||
EgtRemoveBaseMachineDirFromPackagePath()
|
||||
EgtAddToPackagePath( sMachDir .. '\\Beam\\?.lua')
|
||||
|
||||
-- Segnalazione avvio
|
||||
EgtOutLog( '*** Beam Process Start ***', 1)
|
||||
|
||||
-- Carico le librerie
|
||||
_G.package.loaded.BasicCustomerStrategies = nil
|
||||
_G.package.loaded.BeamExec = nil
|
||||
_G.package.loaded.BeamLib = nil
|
||||
_G.package.loaded.DiceCut = nil
|
||||
_G.package.loaded.FaceData = nil
|
||||
_G.package.loaded.FeatureLib = nil
|
||||
_G.package.loaded.Identity = nil
|
||||
_G.package.loaded.Logs = nil
|
||||
_G.package.loaded.MachiningLib = nil
|
||||
_G.package.loaded.PreSimulationLib = nil
|
||||
_G.package.loaded.LeadInOutLib = nil
|
||||
-- strategie di base sempre presenti
|
||||
_G.package.loaded['HEADCUT\\HEADCUT'] = nil
|
||||
_G.package.loaded['TAILCUT\\TAILCUT'] = nil
|
||||
-- libreria macchina
|
||||
_G.package.loaded.BeamDataNew = nil
|
||||
-- libreria calcolo tempo esecuzione
|
||||
_G.package.loaded.TimeLib = 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.
|
||||
-- Infatti difficile ci siano 9999 strategie.
|
||||
-- reset strategie caricate come librerie
|
||||
for i = 1, 9999 do
|
||||
local idSTRTemp = EgtReplaceString( EgtNumToString( i/10000, -4), '0.', '')
|
||||
local sLibraryToReload = "STR" .. idSTRTemp .. "\\STR" .. idSTRTemp
|
||||
if _G.package.loaded[sLibraryToReload] then
|
||||
_G.package.loaded[sLibraryToReload] = nil
|
||||
end
|
||||
end
|
||||
local vtCoreStrategiesNames = EgtFindAllFiles( BEAM.BASEDIR .. '\\StrategyLibs\\*.lua')
|
||||
for i = 1, #vtCoreStrategiesNames do
|
||||
local sCurrentName = EgtSplitString( vtCoreStrategiesNames[i], '.')[1]
|
||||
if _G.package.loaded[sCurrentName] then
|
||||
_G.package.loaded[sCurrentName] = nil
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Variabili globali
|
||||
PARTS = {} -- tabella contenente tutte le informazioni di ogni pezzo
|
||||
|
||||
-- Carico i dati globali
|
||||
local BeamData = require( 'BeamDataNew')
|
||||
-- carico librerie
|
||||
local BeamExec = require( 'BeamExec')
|
||||
local BeamLib = require( 'BeamLib')
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- *** Recupero trave (E' SEMPRE E SOLO UNA) ***
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function MyProcessInputData()
|
||||
-- Recupero il pezzo e i suoi dati
|
||||
local nId = EgtGetFirstPart()
|
||||
if nId then
|
||||
table.insert( PARTS, { nInd = #PARTS + 1, id = nId, sName = ( EgtGetName( nId) or ( 'Id=' .. tonumber( nId)))})
|
||||
local Ls = EgtGetFirstNameInGroup( PARTS[1].id, 'Box')
|
||||
local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD)
|
||||
if not b3Solid then
|
||||
return false
|
||||
end
|
||||
PARTS[1].b3PartOriginal = b3Solid
|
||||
else
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function GetDataConfig()
|
||||
-- recupero utensili dal magazzino
|
||||
BeamExec.GetToolsFromDB()
|
||||
-- TODO da gestire eventuali errori bloccanti
|
||||
return true
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- *** Inserimento delle travi nel grezzo ***
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function MyProcessBeams()
|
||||
-- Lunghezza totale delle travi
|
||||
local dLen = PARTS[1].b3PartOriginal:getDimX()
|
||||
local dRawW = PARTS[1].b3PartOriginal:getDimY()
|
||||
local dRawH = PARTS[1].b3PartOriginal:getDimZ()
|
||||
|
||||
-- Determinazione minimo grezzo scaricabile
|
||||
BeamExec.CalcMinUnloadableRaw( dRawW, dRawH)
|
||||
|
||||
local dOvmHead = BeamData.OVM_HEAD or 10
|
||||
local dOvmMid = BeamData.OVM_MID or 10
|
||||
|
||||
local dRawL = max( dLen + dOvmHead + dOvmMid, BeamData.dMinRaw)
|
||||
|
||||
-- Recupero info pezzi
|
||||
local bOk, sErr = BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, dOvmMid, PARTS, nil, true)
|
||||
if not bOk then
|
||||
EgtOutLog( sErr)
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- *** Inserimento delle lavorazioni nelle travi ***
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function MyProcessFeatures()
|
||||
|
||||
BeamExec.GetProcessings( PARTS, true)
|
||||
BeamExec.GetCombinationMatrix( PARTS, true)
|
||||
BeamExec.ProcessMachinings( PARTS, true)
|
||||
|
||||
-- scrittura variabili globali per interfaccia
|
||||
BEAM.PREROTATE90 = PARTS[1].nInitialPosition - 1
|
||||
BEAM.PREINVERT = EgtIf( PARTS[1].bPartInCombiIsInverted, 1, 0)
|
||||
|
||||
local nErrCnt = 0
|
||||
local nWarnCnt = 0
|
||||
local sOutput = ''
|
||||
for i = 1, #RESULT do
|
||||
local sMsg = ''
|
||||
if RESULT[i].sType == 'Feature' then
|
||||
sMsg = RESULT[i].ChosenStrategy.sInfo
|
||||
elseif RESULT[i].sType == 'Part' then
|
||||
sMsg = RESULT[i].sMsg
|
||||
end
|
||||
sMsg = string.gsub( sMsg or '', '\n', ' ', 10)
|
||||
sMsg = string.gsub( sMsg or '', '\r', ' ', 10)
|
||||
-- trovata almeno una strategia e feature lavorata completamente
|
||||
if RESULT[i].sType == 'Feature' and RESULT[i].ChosenStrategy.sStatus == 'Completed' then
|
||||
sOutput = sOutput .. string.format( '[%d,%d] %s\n', RESULT[i].idCut, RESULT[i].idTask, sMsg or '')
|
||||
|
||||
-- trovata almeno una strategia ma nessuna applicabile oppure non trovata alcuna strategia
|
||||
elseif RESULT[i].sType == 'Feature'
|
||||
and ( ( RESULT[i].ChosenStrategy.sStatus == 'Not-Applicable')
|
||||
or ( not RESULT[i].ChosenStrategy.sStrategyName)) then
|
||||
|
||||
nErrCnt = nErrCnt + 1
|
||||
if #sMsg == 0 then
|
||||
sMsg = 'No applicable strategy found'
|
||||
end
|
||||
sOutput = sOutput .. string.format( '[%d,%d] %s\n', RESULT[i].idCut, RESULT[i].idTask, sMsg)
|
||||
else
|
||||
-- segnalazione scarico pezzo standard, incompleto o a caduta
|
||||
if RESULT[i].sType == 'Part' and ( RESULT[i].nErr == -100 or RESULT[i].nErr == -101 or RESULT[i].nErr == -102) then
|
||||
-- nulla da segnalare
|
||||
|
||||
-- feature incompleta e altro
|
||||
elseif RESULT[i].sType == 'Feature' and RESULT[i].ChosenStrategy.sStatus == 'Not-Completed' then
|
||||
nWarnCnt = nWarnCnt + 1
|
||||
sMsg = 'Incomplete : Completion index ' .. RESULT[i].ChosenStrategy.dCompletionIndex .. '/5\n' .. sMsg
|
||||
sOutput = sOutput .. string.format( '[%d,%d] %s\n', RESULT[i].idCut, RESULT[i].idTask, sMsg)
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- si calcolano alternative
|
||||
TIMER:startElapsed('Alternatives')
|
||||
BeamExec.ProcessAlternatives( PARTS)
|
||||
TIMER:stopElapsed('Alternatives')
|
||||
|
||||
-- cancello gruppo temporaneo
|
||||
local idTempGroup = BeamLib.GetTempGroup()
|
||||
EgtErase( idTempGroup)
|
||||
|
||||
if #sOutput > 0 then EgtOutLog( sOutput) end
|
||||
if nErrCnt > 0 then
|
||||
EgtOutBox( sOutput, 'Lavora Travi', 'ERRORS')
|
||||
return false
|
||||
elseif nWarnCnt > 0 then
|
||||
EgtOutBox( sOutput, 'Lavora Travi', 'WARNINGS')
|
||||
return true
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- *** Esecuzione ***
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
|
||||
-- calcolo tempo esecuzione
|
||||
TIMER:start()
|
||||
EgtOutLog( ' Execution timer started')
|
||||
|
||||
-- script principale
|
||||
|
||||
if not MyProcessInputData() then return end
|
||||
|
||||
-- recupero parametri generali da progetto
|
||||
BeamExec.GetGeneralParameters()
|
||||
|
||||
-- creo un gruppo temporaneo dove finiranno tutte le entità che non bisogna salvare, alla fine lo si cancella
|
||||
BeamLib.CreateTempGroup()
|
||||
|
||||
if not MyProcessBeams() then return end
|
||||
|
||||
if not GetDataConfig() then return end
|
||||
|
||||
-- Abilito Vmill
|
||||
EgtSetInfo( EgtGetCurrMachGroup(), 'Vm', '1')
|
||||
|
||||
MyProcessFeatures()
|
||||
|
||||
-- log tempi di esecuzione
|
||||
if EgtGetDebugLevel() >= 3 then
|
||||
TIMER:logAllElapsed()
|
||||
end
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
-- GetWallData.lua by Egaltech s.r.l. 2022/06/28
|
||||
-- Recupero dati da file WallData.lua di macchina
|
||||
|
||||
-- Intestazioni
|
||||
require( 'EgtBase')
|
||||
_ENV = EgtProtectGlobal()
|
||||
EgtEnableDebug( false)
|
||||
|
||||
-- Per test
|
||||
--GWD = {}
|
||||
--GWD.MACHINE = 'Essetre-90480019_MW'
|
||||
|
||||
local sLog = 'GetBeamData : ' .. GWD.MACHINE
|
||||
EgtOutLog( sLog)
|
||||
|
||||
-- Imposto direttorio libreria specializzata per Travi
|
||||
EgtAddToPackagePath( GWD.BASEDIR .. '\\LuaLibs\\?.lua')
|
||||
|
||||
-- Verifico che la macchina corrente sia abilitata per la lavorazione delle Travi
|
||||
local sMachDir = EgtGetCurrMachineDir()
|
||||
if not EgtExistsFile( sMachDir .. '\\Beam\\BeamDataNew.lua') then
|
||||
GWD.ERR = 12
|
||||
GWD.MSG = 'Error not configured for beam machine : ' .. GWD.MACHINE
|
||||
WriteErrToLogFile( GWD.ERR, GWD.MSG)
|
||||
PostErrView( GWD.ERR, GWD.MSG)
|
||||
return
|
||||
end
|
||||
|
||||
-- Elimino direttori altre macchine e imposto direttorio macchina corrente per ricerca librerie
|
||||
EgtRemoveBaseMachineDirFromPackagePath()
|
||||
EgtAddToPackagePath( sMachDir .. '\\Beam\\?.lua')
|
||||
|
||||
-- Carico i dati globali
|
||||
_G.package.loaded.BeamData = nil
|
||||
local BD = require( 'BeamDataNew')
|
||||
|
||||
-- Assegno valori di interesse
|
||||
GWD.SIMUL_VIEW_DIR = BD.SIMUL_VIEW_DIR
|
||||
GWD.OVM_MID = BD.OVM_MID
|
||||
|
||||
-- Tutto ok
|
||||
GWD.ERR = 0
|
||||
|
||||
EgtOutLog( ' +++ GetBeamData completed')
|
||||
@@ -9,7 +9,7 @@ local BasicCustomerStrategies = {}
|
||||
require( 'EgtBase')
|
||||
|
||||
-- Carico i dati globali
|
||||
local BeamData = require( 'BeamData')
|
||||
local BeamData = require( 'BeamDataNew')
|
||||
local BeamLib = require( 'BeamLib')
|
||||
local ID = require( 'Identity')
|
||||
|
||||
@@ -252,6 +252,7 @@ local function GetStrategies_Essetre( Proc)
|
||||
---------------------------------------------------------------------
|
||||
-- Feature : Chamfer (0-36)
|
||||
elseif ID.IsChamfer( Proc) then
|
||||
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0005'}, { sStrategyId = 'STR0010'}}
|
||||
---------------------------------------------------------------------
|
||||
-- Feature : Block Haus Half Lap (0-37)
|
||||
elseif ID.IsHalfBlockHaus( Proc) then
|
||||
|
||||
+1240
-546
File diff suppressed because it is too large
Load Diff
+311
-56
@@ -8,7 +8,7 @@ local BeamLib = {}
|
||||
|
||||
-- Include
|
||||
require( 'EgtBase')
|
||||
local BeamData = require( 'BeamData')
|
||||
local BeamData = require( 'BeamDataNew')
|
||||
|
||||
|
||||
EgtOutLog( ' BeamLib started', 1)
|
||||
@@ -65,6 +65,64 @@ function BeamLib.AddPartEndFace( PartId, b3Solid)
|
||||
return true
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function BeamLib.GetPartBoxWithHeadTail( Part, sSide)
|
||||
local _sSide = sSide or ''
|
||||
|
||||
-- si può usare il box del grezzo che contiene sempre il sovramateriale di testa
|
||||
if _sSide == 'Head' then
|
||||
|
||||
local b3WithHead = BBox3d( Part.b3Raw)
|
||||
return b3WithHead
|
||||
|
||||
-- se è l'ultimo pezzo della barra si aggiunge il box dell'eventuale grezzo successivo
|
||||
-- se non lo è, si estende il box del pezzo fino alla fine della barra
|
||||
elseif _sSide == 'Tail' then
|
||||
|
||||
local b3WithTail = BBox3d( Part.b3Part)
|
||||
if Part.bIsLastPart then
|
||||
local nNextRawId = EgtGetNextRawPart( Part.idRaw)
|
||||
if nNextRawId then
|
||||
local b3Tail = EgtGetRawPartBBox( nNextRawId)
|
||||
b3WithTail:Add( b3Tail)
|
||||
end
|
||||
else
|
||||
-- per il punto di inizio barra si parte dal box del grezzo perchè contiene già il sovramateriale spessore lama/catena in coda (la restLength non lo comprende)
|
||||
local ptXMin = Point3d( Part.b3Raw:getMin():getX() - Part.dRestLength, Part.b3Part:getMin():getY(), Part.b3Part:getMin():getZ())
|
||||
b3WithTail:Add( ptXMin)
|
||||
end
|
||||
|
||||
return b3WithTail
|
||||
|
||||
-- per aggiungere entrambi si procede come per la coda ma partendo dal box del grezzo, che già contiene la testa
|
||||
elseif sSide == 'HeadTail' then
|
||||
|
||||
local b3WithHeadTail = BBox3d( Part.b3Raw)
|
||||
if Part.bIsLastPart then
|
||||
local nNextRawId = EgtGetNextRawPart( Part.idRaw)
|
||||
if nNextRawId then
|
||||
local b3Tail = EgtGetRawPartBBox( nNextRawId)
|
||||
b3WithHeadTail:Add( b3Tail)
|
||||
end
|
||||
else
|
||||
-- per il punto di inizio barra si parte dal box del grezzo perchè contiene già il sovramateriale spessore lama/catena in coda (la restLength non lo comprende)
|
||||
local ptXMin = Point3d( Part.b3Raw:getMin():getX() - Part.dRestLength, Part.b3Part:getMin():getY(), Part.b3Part:getMin():getZ())
|
||||
b3WithHeadTail:Add( ptXMin)
|
||||
end
|
||||
|
||||
return b3WithHeadTail
|
||||
|
||||
-- sSide non definito, si restituisce il box del pezzo con l'aggiunta dello spessore lama/catena in coda
|
||||
else
|
||||
local b3WithSplit = BBox3d( Part.b3Part)
|
||||
-- per il punto di inizio barra si parte dal box del grezzo perchè contiene già il sovramateriale spessore lama/catena in coda (la restLength non lo comprende)
|
||||
local ptXMin = Point3d( Part.b3Raw:getMin():getX(), Part.b3Part:getMin():getY(), Part.b3Part:getMin():getZ())
|
||||
b3WithSplit:Add( ptXMin)
|
||||
|
||||
return b3WithSplit
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function BeamLib.GetPartSplittingPoints( Part)
|
||||
local PartSplittingPoints = {}
|
||||
@@ -103,19 +161,51 @@ function BeamLib.GetPartSplittingPoints( Part)
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function BeamLib.AddPhaseWithRawParts( idRaw, OriXR, PosXR, dDeltaSucc)
|
||||
EgtAddPhase()
|
||||
function BeamLib.AddPhaseWithRawParts( PARTS, nPartIndex, OriXR, PosXR, dDeltaSucc)
|
||||
local nPhase = EgtAddPhase()
|
||||
local Part
|
||||
local idRaw
|
||||
-- se l'indice è oltre significa che è l'ultimo grezzo senza pezzi
|
||||
if nPartIndex > #PARTS then
|
||||
idRaw = EgtGetNextRawPart( PARTS[#PARTS].idRaw)
|
||||
else
|
||||
Part = PARTS[nPartIndex]
|
||||
idRaw = Part.idRaw
|
||||
end
|
||||
-- si aprono i limiti tavola per permettere rotazioni di pezzi più larghi della tavola
|
||||
EgtSetTableAreaOffset( 2000, 2000, 2000, 2000)
|
||||
local dRawMove = 0
|
||||
local bIsFirstRaw = true
|
||||
local dPosXFirst = 0
|
||||
while idRaw do
|
||||
local dPosX
|
||||
for i = 1, #PARTS do
|
||||
local CurrentPart = PARTS[i]
|
||||
if CurrentPart.idRaw == idRaw then
|
||||
dPosX = CurrentPart.dPosX
|
||||
if bIsFirstRaw then
|
||||
dPosXFirst = dPosX
|
||||
end
|
||||
break
|
||||
end
|
||||
if i == #PARTS then
|
||||
dPosX = PARTS[i].dPosX + PARTS[i].b3Raw:getDimX()
|
||||
end
|
||||
end
|
||||
if bIsFirstRaw then
|
||||
bIsFirstRaw = false
|
||||
else
|
||||
dRawMove = dDeltaSucc + dPosX - dPosXFirst
|
||||
end
|
||||
EgtKeepRawPart( idRaw)
|
||||
EgtMoveToCornerRawPart( idRaw, OriXR, PosXR)
|
||||
EgtMoveRawPart( idRaw, Vector3d( - dRawMove, 0, 0))
|
||||
if dRawMove == 0 then dRawMove = dRawMove + dDeltaSucc end
|
||||
dRawMove = dRawMove + EgtGetRawPartBBox( idRaw):getDimX()
|
||||
idRaw = EgtGetNextRawPart( idRaw)
|
||||
end
|
||||
-- salvo info nuova fase aggiunta
|
||||
local MachExtraInfo = { sType = 'DISP',
|
||||
nPhase = nPhase}
|
||||
table.insert( DB_MACH_APPLIED, MachExtraInfo)
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
@@ -266,6 +356,18 @@ function BeamLib.RotateRawPart( Part, nNumberOfRotations)
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function BeamLib.CreateAddGroup( PartId, sGroupName)
|
||||
AddGrpId = EgtGroup( PartId or GDB_ID.NULL)
|
||||
if not AddGrpId then
|
||||
return false
|
||||
end
|
||||
-- assegno nome, flag di layer per gruppo di lavoro e colore
|
||||
EgtSetName( AddGrpId, sGroupName)
|
||||
EgtSetInfo( AddGrpId, GDB_SI.MGRPONLY, EgtGetCurrMachGroup())
|
||||
EgtSetColor( AddGrpId, Color3d( 80, 160, 160, 25))
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function BeamLib.CreateOrEmptyAddGroup( PartId)
|
||||
-- recupero i dati del gruppo aggiuntivo
|
||||
@@ -279,15 +381,9 @@ function BeamLib.CreateOrEmptyAddGroup( PartId)
|
||||
EgtSetInfo( AddGrpId, GDB_SI.MGRPONLY, EgtGetCurrMachGroup())
|
||||
return EgtEmptyGroup( AddGrpId)
|
||||
end
|
||||
|
||||
-- altrimenti lo creo
|
||||
AddGrpId = EgtGroup( PartId or GDB_ID.NULL)
|
||||
if not AddGrpId then
|
||||
return false
|
||||
end
|
||||
-- assegno nome, flag di layer per gruppo di lavoro e colore
|
||||
EgtSetName( AddGrpId, sMchGrp)
|
||||
EgtSetInfo( AddGrpId, GDB_SI.MGRPONLY, EgtGetCurrMachGroup())
|
||||
EgtSetColor( AddGrpId, Color3d( 80, 160, 160, 25))
|
||||
BeamLib.CreateAddGroup( PartId, sMchGrp)
|
||||
|
||||
return true
|
||||
end
|
||||
@@ -299,7 +395,9 @@ function BeamLib.CreateTempGroup()
|
||||
if not idTempGroup then
|
||||
idTempGroup = EgtGroup( GDB_ID.ROOT)
|
||||
EgtSetName( idTempGroup, "#TEMP_GROUP#")
|
||||
EgtSetColor( idTempGroup, Color3d( 80, 160, 160, 1))
|
||||
EgtSetLevel( idTempGroup, GDB_LV.TEMP)
|
||||
EgtSetStatus( idTempGroup, GDB_ST.OFF)
|
||||
end
|
||||
return idTempGroup
|
||||
end
|
||||
@@ -325,6 +423,24 @@ function BeamLib.GetAddGroup( PartId)
|
||||
return AddGrpId, sMchGrp
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- Funzione prossimo nome MachGroup libero (numero intero)
|
||||
function BeamLib.GetNewMachGroupName()
|
||||
local idMachGroup = EgtGetFirstMachGroup()
|
||||
if not idMachGroup then return 1 end
|
||||
local nMaxMachGroup = 0
|
||||
while idMachGroup do
|
||||
local sMachGroupName = EgtGetMachGroupName( idMachGroup)
|
||||
local nMachGroupName = tonumber( sMachGroupName)
|
||||
if nMachGroupName > nMaxMachGroup then
|
||||
nMaxMachGroup = nMachGroupName
|
||||
end
|
||||
idMachGroup = EgtGetNextMachGroup( idMachGroup)
|
||||
end
|
||||
|
||||
return nMaxMachGroup + 1
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- restituisce le facce della parte interessate dalla feature Proc
|
||||
-- TODO da spostare in FeatureLib???
|
||||
@@ -424,6 +540,87 @@ function BeamLib.GetNearestParalOpposite( vtRef, vtNorm)
|
||||
return nil
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- TODO gestire anche altri valori
|
||||
function BeamLib.GetDirectionFromSCC( nSCC)
|
||||
local vtSCC
|
||||
|
||||
if nSCC == MCH_SCC.ADIR_XP then
|
||||
vtSCC = X_AX()
|
||||
elseif nSCC == MCH_SCC.ADIR_XM then
|
||||
vtSCC = -X_AX()
|
||||
elseif nSCC == MCH_SCC.ADIR_YP then
|
||||
vtSCC = Y_AX()
|
||||
elseif nSCC == MCH_SCC.ADIR_YM then
|
||||
vtSCC = -Y_AX()
|
||||
elseif nSCC == MCH_SCC.ADIR_ZP then
|
||||
vtSCC = Z_AX()
|
||||
elseif nSCC == MCH_SCC.ADIR_ZM then
|
||||
vtSCC = -Z_AX()
|
||||
end
|
||||
|
||||
return vtSCC
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- Restituisce una tabella con i punti ai vertici della faccia, in globale
|
||||
-- ordinati partendo da quello ai valori minimi degli assi e i successivi secondo rotazione destrorsa X+;
|
||||
-- solo per Proc a 1 faccia
|
||||
function BeamLib.GetSortedVertices( Proc)
|
||||
local PtVerticesSorted = {}
|
||||
|
||||
-- se più di una faccia si esce subito
|
||||
if Proc.nFct > 1 then
|
||||
return
|
||||
end
|
||||
|
||||
local PtVertices = {}
|
||||
local nFirstIndex
|
||||
local dMinYZ = GEO.INFINITO
|
||||
for i = 1, #Proc.Faces[1].Edges do
|
||||
local Edge = Proc.Faces[1].Edges[i]
|
||||
table.insert( PtVertices, Edge.ptStart)
|
||||
if ( Edge.ptStart:getY() + Edge.ptStart:getZ() < dMinYZ) then
|
||||
nFirstIndex = i
|
||||
dMinYZ = Edge.ptStart:getY() + Edge.ptStart:getZ()
|
||||
end
|
||||
end
|
||||
|
||||
table.insert( PtVerticesSorted, PtVertices[nFirstIndex])
|
||||
local nCurrentIndex = nFirstIndex
|
||||
-- faccia che guarda verso X+, ordine ok
|
||||
if Proc.Faces[1].vtN:getX() > GEO.EPS_SMALL then
|
||||
for _ = 1, #PtVertices - 1 do
|
||||
_, nCurrentIndex = BeamLib.GetAdjacentIndices( nCurrentIndex, #PtVertices)
|
||||
table.insert( PtVerticesSorted, PtVertices[nCurrentIndex])
|
||||
end
|
||||
-- faccia che guarda verso X-, ordine da invertire
|
||||
else
|
||||
for _ = 1, #PtVertices - 1 do
|
||||
nCurrentIndex = BeamLib.GetAdjacentIndices( nCurrentIndex, #PtVertices)
|
||||
table.insert( PtVerticesSorted, PtVertices[nCurrentIndex])
|
||||
end
|
||||
end
|
||||
|
||||
return PtVerticesSorted
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- restituisce il precedente e prossimo indice 1-based, tenendo conto del massimo indice
|
||||
function BeamLib.GetAdjacentIndices( nCurrentIndex, nMaxIndex)
|
||||
local nPreviousIndex, nNextIndex
|
||||
|
||||
if ( nCurrentIndex < 1) or ( nCurrentIndex > nMaxIndex) then
|
||||
return
|
||||
end
|
||||
|
||||
-- circular indexing 1-based
|
||||
nPreviousIndex = ( ( nCurrentIndex - 2 + nMaxIndex) % nMaxIndex) + 1
|
||||
nNextIndex = ( nCurrentIndex % nMaxIndex) + 1
|
||||
|
||||
return nPreviousIndex, nNextIndex
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- Funzione per determinare se la faccia ha lati molto corti (trascurabili) ed è quindi approssimabile ad una 3 facce
|
||||
function BeamLib.Is3EdgesApprox( Proc, idFace, nAddGrpId)
|
||||
@@ -502,7 +699,7 @@ function BeamLib.GetPieceGeneralParameters( Part, DefaultGeneralParamList)
|
||||
else
|
||||
if GENERAL_PARAMETERS.BTL and GENERAL_PARAMETERS.BTL[Part.sBTLInfo] and GENERAL_PARAMETERS.BTL[Part.sBTLInfo][DefaultGeneralParamList[i].sName] ~= nil then
|
||||
GeneralParameters[DefaultGeneralParamList[i].sName] = GENERAL_PARAMETERS.BTL[Part.sBTLInfo][DefaultGeneralParamList[i].sName]
|
||||
elseif GENERAL_PARAMETERS.PROJECT[DefaultGeneralParamList[i].sName] then
|
||||
elseif GENERAL_PARAMETERS.PROJECT[DefaultGeneralParamList[i].sName] ~= nil then
|
||||
GeneralParameters[DefaultGeneralParamList[i].sName] = GENERAL_PARAMETERS.PROJECT[DefaultGeneralParamList[i].sName]
|
||||
end
|
||||
end
|
||||
@@ -593,18 +790,21 @@ function BeamLib.LoadGeneralParametersInList( DefaultGeneralParamList)
|
||||
for i = 1, #DefaultGeneralParamList do
|
||||
local sParamNameNGE = DefaultGeneralParamList[i].sNameNge
|
||||
local xParameterValue = EgtGetInfo( idProjectInfo, sParamNameNGE, 's') or DefaultGeneralParamList[i].sValue
|
||||
-- salvataggio dato su lista con accesso diretto
|
||||
if DefaultGeneralParamList[i].sType == 'b' then
|
||||
UpdatedParameters.PROJECT[DefaultGeneralParamList[i].sName] = xParameterValue == 'true' or xParameterValue == '1' or xParameterValue == true
|
||||
elseif DefaultGeneralParamList[i].sType == 'd' then
|
||||
if #DefaultGeneralParamList[i].sValue > 0 then
|
||||
UpdatedParameters.PROJECT[DefaultGeneralParamList[i].sName] = tonumber( xParameterValue)
|
||||
-- stringa vuota equivale a non passare alcun valore (deciderà la strategia)
|
||||
else
|
||||
UpdatedParameters.PROJECT[DefaultGeneralParamList[i].sName] = nil
|
||||
-- se parametro non trovato si salta tutto. N.B. = I parametri progetto non dovrebbero mai essere nil
|
||||
if xParameterValue then
|
||||
-- salvataggio dato su lista con accesso diretto
|
||||
if DefaultGeneralParamList[i].sType == 'b' then
|
||||
UpdatedParameters.PROJECT[DefaultGeneralParamList[i].sName] = xParameterValue == 'true' or xParameterValue == '1' or xParameterValue == true
|
||||
elseif DefaultGeneralParamList[i].sType == 'd' then
|
||||
if #DefaultGeneralParamList[i].sValue > 0 then
|
||||
UpdatedParameters.PROJECT[DefaultGeneralParamList[i].sName] = tonumber( xParameterValue)
|
||||
-- stringa vuota equivale a non passare alcun valore (deciderà la strategia)
|
||||
else
|
||||
UpdatedParameters.PROJECT[DefaultGeneralParamList[i].sName] = nil
|
||||
end
|
||||
else --DefaultGeneralParamList[i].sType == 's' or DefaultGeneralParamList[i].sType == 'combo'
|
||||
UpdatedParameters.PROJECT[DefaultGeneralParamList[i].sName] = xParameterValue
|
||||
end
|
||||
else --DefaultGeneralParamList[i].sType == 's' or DefaultGeneralParamList[i].sType == 'combo'
|
||||
UpdatedParameters.PROJECT[DefaultGeneralParamList[i].sName] = xParameterValue
|
||||
end
|
||||
end
|
||||
|
||||
@@ -618,18 +818,21 @@ function BeamLib.LoadGeneralParametersInList( DefaultGeneralParamList)
|
||||
for i = 1, #DefaultGeneralParamList do
|
||||
local sParamNameNGE = DefaultGeneralParamList[i].sNameNge
|
||||
local xParameterValue = EgtGetInfo( BTLInfo[j], sParamNameNGE, 's')
|
||||
-- salvataggio dato su lista con accesso diretto
|
||||
if DefaultGeneralParamList[i].sType == 'b' then
|
||||
UpdatedParameters.BTL[BTLName][DefaultGeneralParamList[i].sName] = xParameterValue == 'true' or xParameterValue == '1' or xParameterValue == true
|
||||
elseif DefaultGeneralParamList[i].sType == 'd' then
|
||||
if #DefaultGeneralParamList[i].sValue > 0 then
|
||||
UpdatedParameters.BTL[BTLName][DefaultGeneralParamList[i].sName] = tonumber( xParameterValue)
|
||||
-- stringa vuota equivale a non passare alcun valore (deciderà la strategia)
|
||||
else
|
||||
UpdatedParameters.BTL[BTLName][DefaultGeneralParamList[i].sName] = nil
|
||||
-- se parametro non trovato si salta tutto
|
||||
if xParameterValue then
|
||||
-- salvataggio dato su lista con accesso diretto
|
||||
if DefaultGeneralParamList[i].sType == 'b' then
|
||||
UpdatedParameters.BTL[BTLName][DefaultGeneralParamList[i].sName] = xParameterValue == 'true' or xParameterValue == '1' or xParameterValue == true
|
||||
elseif DefaultGeneralParamList[i].sType == 'd' then
|
||||
if #DefaultGeneralParamList[i].sValue > 0 then
|
||||
UpdatedParameters.BTL[BTLName][DefaultGeneralParamList[i].sName] = tonumber( xParameterValue)
|
||||
-- stringa vuota equivale a non passare alcun valore (deciderà la strategia)
|
||||
else
|
||||
UpdatedParameters.BTL[BTLName][DefaultGeneralParamList[i].sName] = nil
|
||||
end
|
||||
else --DefaultGeneralParamList[i].sType == 's' or DefaultGeneralParamList[i].sType == 'combo'
|
||||
UpdatedParameters.BTL[BTLName][DefaultGeneralParamList[i].sName] = xParameterValue
|
||||
end
|
||||
else --DefaultGeneralParamList[i].sType == 's' or DefaultGeneralParamList[i].sType == 'combo'
|
||||
UpdatedParameters.BTL[BTLName][DefaultGeneralParamList[i].sName] = xParameterValue
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -677,22 +880,28 @@ function BeamLib.GetBlockedAxis( nToolIndex, sBlockedAxis, b3Raw, vtTool, vtOut)
|
||||
return ''
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function BeamLib.StringReplaceChar( sOriginal, nPosition, sChar)
|
||||
return sOriginal:sub( 1, nPosition-1) .. sChar .. sOriginal:sub( nPosition+1)
|
||||
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))
|
||||
local n = string.sub( sNumberToConvert, k, k)
|
||||
dResult = dResult + n * ( 2^( i-1))
|
||||
end
|
||||
|
||||
|
||||
return dResult
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- TODO si può sostituire con funzione EgtNumToBitString
|
||||
function BeamLib.DecimalToBinary( dNumber)
|
||||
local sNumberToConvert = tostring( dNumber)
|
||||
local n = sNumberToConvert
|
||||
@@ -700,12 +909,12 @@ function BeamLib.DecimalToBinary( dNumber)
|
||||
local sResult = ""
|
||||
|
||||
for i = sNumberToConvert, 0, -1 do
|
||||
local q = math.modf(n)
|
||||
n = n/2
|
||||
local b = q%2
|
||||
table.insert(tmp, b)
|
||||
local q = math.modf( n)
|
||||
n = n / 2
|
||||
local b = q % 2
|
||||
table.insert( tmp, b)
|
||||
|
||||
if (q == 1) then
|
||||
if ( q == 1) then
|
||||
break
|
||||
end
|
||||
end
|
||||
@@ -713,7 +922,7 @@ function BeamLib.DecimalToBinary( dNumber)
|
||||
for i = #tmp, 1, -1 do
|
||||
sResult = sResult..tmp[i]
|
||||
end
|
||||
|
||||
|
||||
return tonumber( sResult)
|
||||
end
|
||||
|
||||
@@ -727,6 +936,43 @@ function BeamLib.CalculateStringBinaryFormat( dNumber, CharNumber)
|
||||
return NumberString
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function BeamLib.ConvertBitIndexToRotationIndex( sBitIndexCombination)
|
||||
local nRotationIndex
|
||||
|
||||
if sBitIndexCombination == '1000' then
|
||||
return 1
|
||||
elseif sBitIndexCombination == '0100' then
|
||||
return 2
|
||||
elseif sBitIndexCombination == '0010' then
|
||||
return 3
|
||||
elseif sBitIndexCombination == '0001' then
|
||||
return 4
|
||||
elseif sBitIndexCombination == '1000_INV' then
|
||||
return 5
|
||||
elseif sBitIndexCombination == '0100_INV' then
|
||||
return 6
|
||||
elseif sBitIndexCombination == '0010_INV' then
|
||||
return 7
|
||||
elseif sBitIndexCombination == '0001_INV' then
|
||||
return 8
|
||||
end
|
||||
|
||||
return nRotationIndex
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- reindicizza una tabella passata ripartendo dall'indice nStartIndex e mantenendo l'ordine
|
||||
function BeamLib.RotateTableFromIndex( Table, nStartIndex)
|
||||
local RotatedTable = {}
|
||||
|
||||
for i = 1, #Table do
|
||||
RotatedTable[#RotatedTable + 1] = Table[((RotatedTable + i - 2) % #Table) + 1]
|
||||
end
|
||||
|
||||
return RotatedTable
|
||||
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
|
||||
@@ -852,7 +1098,7 @@ end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function BeamLib.GetStrategiesFromList( Proc, StrategyList)
|
||||
-- cerco tra le feature
|
||||
-- cerco tra le feature
|
||||
for i = 1, #StrategyList.FEATURE do
|
||||
-- se trovo la feature
|
||||
if Proc.nPrc == StrategyList.FEATURE[i].nPrc then
|
||||
@@ -870,16 +1116,25 @@ function BeamLib.GetStrategiesFromList( Proc, StrategyList)
|
||||
|
||||
-- si controlla gruppo
|
||||
if bGroupIsCompatible then
|
||||
if #StrategyList.FEATURE[i].TopologyList == 1 and StrategyList.FEATURE[i].TopologyList[1].sName == 'Feature' then
|
||||
return BeamLib.TableCopyDeep( StrategyList.FEATURE[i].TopologyList[1].StrategyList)
|
||||
else
|
||||
-- cerco tra le topologie
|
||||
for j = 1, #StrategyList.FEATURE[i].TopologyList do
|
||||
-- se trovo la topologia
|
||||
if Proc.Topology.sName == StrategyList.FEATURE[i].TopologyList[j].sName then
|
||||
-- ritorno le strategie disponibili per la feature che sto analizzando
|
||||
return BeamLib.TableCopyDeep( StrategyList.FEATURE[i].TopologyList[j].StrategyList)
|
||||
-- cerco tra le topologie
|
||||
for j = 1, #StrategyList.FEATURE[i].TopologyList do
|
||||
-- non si possono mischiare topologie specifiche con topologia 'Feature'. Se presente topologia 'Feature' allora deve essere esclusiva
|
||||
if StrategyList.FEATURE[i].TopologyList[j].sName == 'Feature' and #StrategyList.FEATURE[i].TopologyList > 1 then
|
||||
error( "UNEXPECTED ERROR: topology 'Feature' can't be mixed with others")
|
||||
end
|
||||
-- se trovo la topologia oppure se è 'Feature'
|
||||
if Proc.Topology.sName == StrategyList.FEATURE[i].TopologyList[j].sName or StrategyList.FEATURE[i].TopologyList[j].sName == 'Feature' then
|
||||
local ActiveStrategyList = {}
|
||||
-- aggiungo in lista solo le strategie attive
|
||||
if StrategyList.FEATURE[i].TopologyList[j].StrategyList then
|
||||
for k = 1, #StrategyList.FEATURE[i].TopologyList[j].StrategyList do
|
||||
if ( not StrategyList.FEATURE[i].TopologyList[j].StrategyList[k].nIndexInList) or ( StrategyList.FEATURE[i].TopologyList[j].StrategyList[k].nIndexInList) >= 0 then
|
||||
table.insert( ActiveStrategyList, BeamLib.TableCopyDeep( StrategyList.FEATURE[i].TopologyList[j].StrategyList[k]))
|
||||
end
|
||||
end
|
||||
end
|
||||
-- ritorno le strategie disponibili per la feature che sto analizzando, altrimenti nil se non ho trovato nulla
|
||||
return EgtIf( #ActiveStrategyList > 0, ActiveStrategyList, nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
+36
-41
@@ -11,12 +11,12 @@ local BeamLib = require( 'BeamLib')
|
||||
EgtOutLog( ' DiceCut started', 1)
|
||||
|
||||
-- Dati
|
||||
local BeamData = require( 'BeamData')
|
||||
local BeamData = require( 'BeamDataNew')
|
||||
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- creo i piani paralleli
|
||||
-- GetParallelPlanes: restituisce un vettore con gli indici delle superfici
|
||||
-- nAddGrpId: il layer
|
||||
-- idAddGroup: il layer
|
||||
-- b3BoxDicing: il grezzo della barra
|
||||
-- ptC: il punto centrale del piano della feature
|
||||
-- vtN: il versore normale del piano della feature
|
||||
@@ -30,7 +30,7 @@ local BeamData = require( 'BeamData')
|
||||
-- vtNCut*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso)
|
||||
-- ptCCut1*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso)
|
||||
-- vtNCut1*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso)
|
||||
local function GetParallelPlanes( nAddGrpId, b3BoxDicing, ptC, vtN, nCopyPlane, dOffset, nStep, Color, dTolerance, bNoTolOnFirstCut, ptCCut, vtNCut, ptCCut1, vtNCut1 )
|
||||
local function GetParallelPlanes( idAddGroup, b3BoxDicing, ptC, vtN, nCopyPlane, dOffset, nStep, Color, dTolerance, bNoTolOnFirstCut, ptCCut, vtNCut, ptCCut1, vtNCut1 )
|
||||
local ptMyCCut
|
||||
local AreaMin = 5*5
|
||||
if ptCCut and vtNCut then
|
||||
@@ -46,7 +46,7 @@ local function GetParallelPlanes( nAddGrpId, b3BoxDicing, ptC, vtN, nCopyPlane,
|
||||
local TabellaTmSurfParallel = {}
|
||||
local i = nCopyPlane
|
||||
while i < nStep do
|
||||
local SurfId = EgtSurfTmPlaneInBBox( nAddGrpId, ptC + ( i * dOffset) * vtN, vtN, b3BoxDicing, GDB_RT.GLOB)
|
||||
local SurfId = EgtSurfTmPlaneInBBox( idAddGroup, ptC + ( i * dOffset) * vtN, vtN, b3BoxDicing, GDB_RT.GLOB)
|
||||
local nFacet = EgtSurfTmFacetCount( SurfId or GDB_ID.NULL)
|
||||
if nFacet == 0 then
|
||||
-- se sono al primo taglio do una possibilità in più di girare
|
||||
@@ -86,11 +86,11 @@ end
|
||||
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- GetOrderedCutTable:
|
||||
-- nAddGrpId: il layer
|
||||
-- idAddGroup: il layer
|
||||
-- TabParallelPlanes: tabella delle superfici dei piani paralleli
|
||||
-- TabOrtoPlanes: tabella delle superfici dei piani ortogonali
|
||||
-- stampo l'ordine dei piani di taglio (prima tagli ortogonali piu' esterni poi taglio parallelo collettivo)
|
||||
local function GetOrderedCutTable( nAddGrpId, TabParallelPlanes, TabOrtoPlanes)
|
||||
local function GetOrderedCutTable( idAddGroup, TabParallelPlanes, TabOrtoPlanes)
|
||||
local StepParallel = #TabParallelPlanes
|
||||
local StepOrto = #TabOrtoPlanes
|
||||
local TabellaOrderParallelCut1 = {}
|
||||
@@ -99,8 +99,8 @@ local function GetOrderedCutTable( nAddGrpId, TabParallelPlanes, TabOrtoPlanes)
|
||||
TabellaOrderParallelCut1[IndexTmP] = {}
|
||||
for IndexOrto=1, StepOrto do
|
||||
local ptOrtoN, vtNOrtoN = EgtSurfTmFacetCenter( TabOrtoPlanes[IndexOrto ], 0, GDB_ID.ROOT)
|
||||
local Copy1Id = EgtCopySurfTmFacet( TabParallelPlanes[IndexTmP], 0, nAddGrpId)
|
||||
local Copy2Id = EgtCopySurfTmFacet( TabParallelPlanes[IndexTmP], 0, nAddGrpId)
|
||||
local Copy1Id = EgtCopySurfTmFacet( TabParallelPlanes[IndexTmP], 0, idAddGroup)
|
||||
local Copy2Id = EgtCopySurfTmFacet( TabParallelPlanes[IndexTmP], 0, idAddGroup)
|
||||
if Copy1Id and ptOrtoN then
|
||||
EgtCutSurfTmPlane( Copy1Id, ptOrtoN, -vtNOrtoN, false, GDB_RT.GLOB)
|
||||
EgtCutSurfTmPlane( Copy2Id, ptOrtoN, vtNOrtoN, false, GDB_RT.GLOB)
|
||||
@@ -134,7 +134,7 @@ end
|
||||
-- vtO: il versore dei piani ortogonali
|
||||
-- dOffsetEff: offset della distanza dal punto centrale
|
||||
-- Verifica se l'asse X del box costruito sopra la superficie è più grande di un certo offset
|
||||
local function GetOrtoCutCenter( FacetId, ptC, vtN, vtO, dOffsetEff, dMinNzDownUp)
|
||||
local function GetOrtoCutCenter( FacetId, ptC, vtN, vtO, dOffsetEff)
|
||||
local FrameLocal = Frame3d( EgtSurfTmFacetCenter( FacetId, 0, GDB_ID.ROOT))
|
||||
EgtSetGridFrame(FrameLocal)
|
||||
local IdAuxLocal = EgtGroup(EgtGetParent( FacetId), FrameLocal)
|
||||
@@ -156,7 +156,7 @@ local function GetOrtoCutCenter( FacetId, ptC, vtN, vtO, dOffsetEff, dMinNzDownU
|
||||
-- TODO si può eliminare questo test dato che vengono verificate già volume e dimensione del cubetto??
|
||||
local dMaxLen = BeamData.MAX_LEN_DICE or 600
|
||||
if dLen < dMaxLen and dWidth < dMaxLen and
|
||||
( dLen < dOffsetEff + 1.0 or dWidth < dOffsetEff + 1.0) and vtN:getZ() > dMinNzDownUp then
|
||||
( dLen < dOffsetEff + 1.0 or dWidth < dOffsetEff + 1.0) then
|
||||
return nil, nil, nil
|
||||
end
|
||||
|
||||
@@ -261,7 +261,7 @@ end
|
||||
-- dOffsetParallel: offset della distanza dal punto centrale
|
||||
-- b3BoxDicing: il grezzo della barra
|
||||
-- Verifica se l'asse X del box costruito sopra le 2 facce è più piccolo di un certo offset e quindi la faccia O è superflua
|
||||
local function VerifyFirstOrthoCut( CutTable, dOffsetParallel, b3BoxDicing, dMinNzDownUp)
|
||||
local function VerifyFirstOrthoCut( CutTable, dOffsetParallel, b3BoxDicing)
|
||||
|
||||
if not CutTable[1] or not CutTable[2] then return end
|
||||
|
||||
@@ -294,9 +294,9 @@ local function VerifyFirstOrthoCut( CutTable, dOffsetParallel, b3BoxDicing, dMin
|
||||
-- lunghezza totale faccia
|
||||
local dLongSize = x1 + x2
|
||||
-- se faccia piccola e non orientata verso il basso, elimino ortogonale e unisco le due parti
|
||||
if dLongSize <= dOffsetParallel + 1.0 and vtN1:getZ() > dMinNzDownUp then
|
||||
local nAddGrpId = EgtGetParent( Cut1Id)
|
||||
local SurfId = EgtSurfTmBySewing( nAddGrpId, { Cut1Id, Cut2Id})
|
||||
if dLongSize <= dOffsetParallel + 1.0 then
|
||||
local idAddGroup = EgtGetParent( Cut1Id)
|
||||
local SurfId = EgtSurfTmBySewing( idAddGroup, { Cut1Id, Cut2Id})
|
||||
--EgtSetColor( SurfId, Color3d( FUCHSIA(), 60))
|
||||
EgtErase( CutOId)
|
||||
table.remove( CutTable[1], 1)
|
||||
@@ -338,7 +338,7 @@ end
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- ricavo l'altezza del BoundingBox assegnati gli estremi del grezzo e la feature
|
||||
-- le funzioni commentate permettono di vedere la creazione di BoundingBox
|
||||
local function DistanzaMassima( nAddGrpId, ptC1, vtN1, ptC2, vtN2, b3BoxDicing, TPoint)
|
||||
local function DistanzaMassima( idAddGroup, ptC1, vtN1, ptC2, vtN2, b3BoxDicing, TPoint)
|
||||
-- calcolo il riferimento nel piano 1
|
||||
local Frame1 = Frame3d( ptC1, vtN1)
|
||||
-- determino l'ingombro in questo riferimento della parte di trave compresa nel o nei piani
|
||||
@@ -353,7 +353,7 @@ local function DistanzaMassima( nAddGrpId, ptC1, vtN1, ptC2, vtN2, b3BoxDicing,
|
||||
end
|
||||
-- eventuale altra faccia
|
||||
if ptC2 and vtN2 then
|
||||
local IdAux = EgtGroup( nAddGrpId)
|
||||
local IdAux = EgtGroup( idAddGroup)
|
||||
local IdSurf2 = EgtSurfTmPlaneInBBox( IdAux, ptC2, vtN2, b3BoxDicing, GDB_RT.GLOB)
|
||||
EgtCutSurfTmPlane( IdSurf2, ptC1, -vtN1, false, GDB_RT.GLOB)
|
||||
if IdSurf2 then
|
||||
@@ -394,7 +394,12 @@ end
|
||||
---------------------------------------------------------------------------------------------------------------
|
||||
function DiceCut.GetDice( Part, Face1, Face2, OptionalParameters)
|
||||
-- gruppo per geometria addizionale
|
||||
local nAddGrpId = BeamLib.GetAddGroup( Part.id)
|
||||
local idAddGroup
|
||||
if OptionalParameters.bSaveAddedGeometries then
|
||||
idAddGroup = BeamLib.GetAddGroup( Part.id)
|
||||
else
|
||||
idAddGroup = Part.idTempGroup
|
||||
end
|
||||
|
||||
-- faccia primaria
|
||||
local ptCMainFace
|
||||
@@ -422,16 +427,12 @@ function DiceCut.GetDice( Part, Face1, Face2, OptionalParameters)
|
||||
local dOffsetParallel = OptionalParameters.dOffsetParallel or BeamData.MAX_DIM_DICE
|
||||
-- distanza tra piani ortogonali
|
||||
local dOffsetOrthogonal = OptionalParameters.dOffsetOrthogonal or BeamData.MAX_DIM_DICE
|
||||
-- distanza ridotta tra piani ortogonali - usato in tagli orizzontali con affondamento verticale
|
||||
local dOffsetOrthogonalReduced = OptionalParameters.dOffsetOrthogonalReduced or BeamData.MAX_DIM_HTCUT
|
||||
-- numero massimo piani paralleli
|
||||
local nStepParallel = OptionalParameters.nStepParallel or 100
|
||||
-- numero massimo piani perpendicolari
|
||||
local nStepOrthogonal = OptionalParameters.nStepOrthogonal or 100
|
||||
-- distanza tra piani paralleli e piani di taglio (era sempre 0, serve???)
|
||||
local dTolerance = OptionalParameters.dTolerance or 0
|
||||
-- inclinazione limite per taglio da sotto
|
||||
local dMinNzDownUp = OptionalParameters.dMinNzDownUp or -2
|
||||
|
||||
--Ricavo le altezze dei BoundingBox contenente feature e estremi del grezzo
|
||||
local TBoxPoint = CalcolaPuntiEstremiBox( b3BoxDicing)
|
||||
@@ -439,18 +440,12 @@ function DiceCut.GetDice( Part, Face1, Face2, OptionalParameters)
|
||||
if ptCSubordinateFace and vtNSubordinateFace then
|
||||
TBoxPoint = VerificaEstremiGrezzo( ptCSubordinateFace, vtNSubordinateFace, TBoxPoint)
|
||||
end
|
||||
local dElevP = DistanzaMassima( nAddGrpId, ptCMainFace, vtNMainFace, ptCSubordinateFace, vtNSubordinateFace, b3BoxDicing, TBoxPoint)
|
||||
local dElevP = DistanzaMassima( idAddGroup, ptCMainFace, vtNMainFace, ptCSubordinateFace, vtNSubordinateFace, b3BoxDicing, TBoxPoint)
|
||||
local dElevO
|
||||
if ptCSubordinateFace and vtNSubordinateFace and not AreOppositeVectorApprox( vtNSubordinateFace, vtNMainFace) then
|
||||
dElevO = DistanzaMassima( nAddGrpId, ptCSubordinateFace, vtNSubordinateFace, ptCMainFace, vtNMainFace, b3BoxDicing, TBoxPoint)
|
||||
dElevO = DistanzaMassima( idAddGroup, ptCSubordinateFace, vtNSubordinateFace, ptCMainFace, vtNMainFace, b3BoxDicing, TBoxPoint)
|
||||
end
|
||||
|
||||
-- TODO parte sotto da aggiungere???? se sì va passata anche la dimensione cubetto ridotta dOffsetOrthogonalReduced
|
||||
-- se non c'è testa da sotto e normali senza componenti in Y con faccia quasi verticale e trave non alta, uso per offset i limiti dei tagli di testa e coda
|
||||
-- if not BD.TURN and not BD.DOWN_HEAD and abs( vtNPlanes:getY()) < 0.1 and vtNPlanes:getZ() < 0.7071 and ( not vtNBond or abs( vtNBond:getY()) < 0.1) and BBoxRawPart:getDimZ() < BD.MIN_DIM_HBEAM then
|
||||
-- dOffsetOrthogonal = dOffsetOrthogonalReduced
|
||||
-- end
|
||||
|
||||
-- aggiungo piccolo extra agli offset
|
||||
dOffsetParallel = dOffsetParallel + 10 * GEO.EPS_SMALL
|
||||
dOffsetOrthogonal = dOffsetOrthogonal + 10 * GEO.EPS_SMALL
|
||||
@@ -458,7 +453,7 @@ function DiceCut.GetDice( Part, Face1, Face2, OptionalParameters)
|
||||
-- se piani non ortogonali, diminuisco la distanza di offset opportunamente
|
||||
local dOffsetParallelOriginal = dOffsetParallel
|
||||
if not bGetOrtoPlanes then
|
||||
local dCoeff = ( vtNMainFace ^ vtNSubordinateFace):len()
|
||||
local dCoeff = max( ( vtNMainFace ^ vtNSubordinateFace):len(), 0.5)
|
||||
dOffsetParallel = dOffsetParallel * dCoeff
|
||||
dOffsetOrthogonal = dOffsetOrthogonal * dCoeff
|
||||
end
|
||||
@@ -476,7 +471,7 @@ function DiceCut.GetDice( Part, Face1, Face2, OptionalParameters)
|
||||
|
||||
-- PIANI PARALLELI alla faccia di taglio
|
||||
local TabellaTmSurfP = {}
|
||||
local TabFromIn = GetParallelPlanes( nAddGrpId, b3BoxDicing, ptCMainFace, vtNMainFace, 0, dOffsetParallel, nStepParallel, Color3d( FUCHSIA(), 60), dTolerance, true, ptCSubordinateFace, vtNSubordinateFace)
|
||||
local TabFromIn = GetParallelPlanes( idAddGroup, b3BoxDicing, ptCMainFace, vtNMainFace, 0, dOffsetParallel, nStepParallel, Color3d( FUCHSIA(), 60), dTolerance, true, ptCSubordinateFace, vtNSubordinateFace)
|
||||
for i = #TabFromIn, 1, -1 do
|
||||
table.insert( TabellaTmSurfP, TabFromIn[i])
|
||||
end
|
||||
@@ -485,12 +480,12 @@ function DiceCut.GetDice( Part, Face1, Face2, OptionalParameters)
|
||||
-- orientamento definito da seconda faccia
|
||||
if not bGetOrtoPlanes then
|
||||
local TabellaTmSurfOrto = {}
|
||||
local TabFromIn = GetParallelPlanes( nAddGrpId, b3BoxDicing, ptCSubordinateFace, vtNSubordinateFace, 0, dOffsetOrthogonal, nStepOrthogonal, Color3d( GREEN(), 60), dTolerance, false, ptCMainFace, vtNMainFace)
|
||||
local TabFromIn = GetParallelPlanes( idAddGroup, b3BoxDicing, ptCSubordinateFace, vtNSubordinateFace, 0, dOffsetOrthogonal, nStepOrthogonal, Color3d( GREEN(), 60), dTolerance, false, ptCMainFace, vtNMainFace)
|
||||
for i = #TabFromIn, 1, -1 do
|
||||
table.insert( TabellaTmSurfOrto, TabFromIn[i])
|
||||
end
|
||||
local TabellaOrderParallelCut = GetOrderedCutTable( nAddGrpId, TabellaTmSurfP, TabellaTmSurfOrto) -- Ottiene la tabella dei tagli paralleli ordinati
|
||||
local TabellaOrderOrtoCut = GetOrderedCutTable( nAddGrpId, TabellaTmSurfOrto, TabellaTmSurfP) -- Ottiene la tabella dei tagli ortogonali da riordinare per strato
|
||||
local TabellaOrderParallelCut = GetOrderedCutTable( idAddGroup, TabellaTmSurfP, TabellaTmSurfOrto) -- Ottiene la tabella dei tagli paralleli ordinati
|
||||
local TabellaOrderOrtoCut = GetOrderedCutTable( idAddGroup, TabellaTmSurfOrto, TabellaTmSurfP) -- Ottiene la tabella dei tagli ortogonali da riordinare per strato
|
||||
|
||||
TabGREEN = SortOrtoCutsByNormalMethod( TabellaOrderParallelCut, TabellaOrderOrtoCut) -- I tagli ortogonali vengono ordinati per strato
|
||||
TabFUCHSIA = TabellaOrderParallelCut -- I tagli paralleli sono già ordinati
|
||||
@@ -508,10 +503,10 @@ function DiceCut.GetDice( Part, Face1, Face2, OptionalParameters)
|
||||
end
|
||||
-- calcolo la direzione dei piani ortogonali
|
||||
local vtO = VectorFromUprightOrtho( vtNInner)
|
||||
if vtNInner:getZ() > -0.0175 or vtNInner:getZ() < dMinNzDownUp or abs( vtNInner:getY()) > 0.8 then
|
||||
if vtNInner:getZ() > -0.0175 or abs( vtNInner:getY()) > 0.8 then
|
||||
vtO:rotate( vtNInner, 90)
|
||||
-- se diretto troppo ortogonalmente all'asse trave e taglio non da sotto, lo ruoto ulteriormente
|
||||
if ( abs( vtO:getY()) > 4 * abs( vtO:getX()) or b3BoxDicing:getDimZ() > 620) and vtNInner:getZ() > dMinNzDownUp then
|
||||
if ( abs( vtO:getY()) > 4 * abs( vtO:getX()) or b3BoxDicing:getDimZ() > 620) then
|
||||
vtO:rotate( vtNInner, 90)
|
||||
-- se faccia principale verso il basso (almeno -3deg), lo inverto per iniziare da sopra
|
||||
if vtNInner:getZ() < -0.05 then
|
||||
@@ -533,16 +528,16 @@ function DiceCut.GetDice( Part, Face1, Face2, OptionalParameters)
|
||||
-- CopyPlane: 0 => crea la prima faccia direttamente sul punto passato
|
||||
-- CopyPlane: 1 => crea la prima faccia e tutte le altre con l'offset passato
|
||||
-- CopyPlane: 0.5 => crea la prima faccia a metà offset e tutte le altre con l'offest intero
|
||||
local OffsetRel, CopyPlane, dCenOffs, ptCStart = GetOrtoCutCenter( TabellaTmSurfP[PlnInd], ptCInner, vtNInner, vtO, dOffsetOrthogonal, dMinNzDownUp)
|
||||
local OffsetRel, CopyPlane, dCenOffs, ptCStart = GetOrtoCutCenter( TabellaTmSurfP[PlnInd], ptCInner, vtNInner, vtO, dOffsetOrthogonal)
|
||||
|
||||
if OffsetRel and CopyPlane and dCenOffs then
|
||||
ptCInner = ptCInner + dCenOffs * vtO
|
||||
local TabRight = GetParallelPlanes( nAddGrpId, b3BoxDicing, ptCStart, vtO, CopyPlane, -OffsetRel, nStepOrthogonal, Color3d( GREEN(), 60),
|
||||
local TabRight = GetParallelPlanes( idAddGroup, b3BoxDicing, ptCStart, vtO, CopyPlane, -OffsetRel, nStepOrthogonal, Color3d( GREEN(), 60),
|
||||
dTolerance, false, ptCInner, vtNInner, ptCOuter, vtNOuter)
|
||||
if CopyPlane == 0 then
|
||||
CopyPlane = 1
|
||||
end
|
||||
local TabLeft = GetParallelPlanes( nAddGrpId, b3BoxDicing, ptCStart, vtO, CopyPlane, OffsetRel, nStepOrthogonal, Color3d( GREEN(), 60),
|
||||
local TabLeft = GetParallelPlanes( idAddGroup, b3BoxDicing, ptCStart, vtO, CopyPlane, OffsetRel, nStepOrthogonal, Color3d( GREEN(), 60),
|
||||
dTolerance, false, ptCInner, vtNInner, ptCOuter, vtNOuter)
|
||||
-- carico la tabella con gli indici riordinati
|
||||
local TempOrtoTab = {}
|
||||
@@ -553,7 +548,7 @@ function DiceCut.GetDice( Part, Face1, Face2, OptionalParameters)
|
||||
table.insert( TempOrtoTab, TabRight[i])
|
||||
end
|
||||
-- creo una tabella per ogni piano per generare i tagli sulla Inner
|
||||
local TempParTab = GetOrderedCutTable( nAddGrpId, {TabellaTmSurfP[PlnInd]}, TempOrtoTab)
|
||||
local TempParTab = GetOrderedCutTable( idAddGroup, {TabellaTmSurfP[PlnInd]}, TempOrtoTab)
|
||||
for i = 1, #TempParTab do
|
||||
table.insert( TabFUCHSIA, TempParTab[i])
|
||||
end
|
||||
@@ -582,7 +577,7 @@ function DiceCut.GetDice( Part, Face1, Face2, OptionalParameters)
|
||||
|
||||
-- Se esiste la superficie limitante (nFacet == 2) verifica se il taglio più esterno è superfluo e quindi viene eliminato
|
||||
if not bGetOrtoPlanes then
|
||||
VerifyFirstOrthoCut( UltimateTable, dOffsetParallelOriginal, b3BoxDicing, dMinNzDownUp)
|
||||
VerifyFirstOrthoCut( UltimateTable, dOffsetParallelOriginal, b3BoxDicing)
|
||||
-- se rimangono due sole facce, devono coincidere con le originali e quindi sono superflue
|
||||
if #UltimateTable == 2 and #UltimateTable[1] == 1 and #UltimateTable[2] == 1 then
|
||||
EgtErase( UltimateTable[1][1])
|
||||
|
||||
+121
-84
@@ -91,7 +91,9 @@ function FaceData.GetFacesByAdjacencyNumber( Proc)
|
||||
FacesByAdjacencyNumber[i] = {}
|
||||
end
|
||||
for i = 1, Proc.nFct do
|
||||
table.insert( FacesByAdjacencyNumber[#Proc.Faces[i].Adjacencies], Proc.Faces[i])
|
||||
if #Proc.Faces[i].Adjacencies > 0 then
|
||||
table.insert( FacesByAdjacencyNumber[#Proc.Faces[i].Adjacencies], Proc.Faces[i])
|
||||
end
|
||||
end
|
||||
|
||||
return FacesByAdjacencyNumber
|
||||
@@ -114,14 +116,8 @@ function FaceData.GetEdgesInfo( ProcOrId, idFace )
|
||||
local nFaceType, EdgesEgt = EgtSurfTmGetFacetOutlineInfo( Proc.id, idFace, GDB_ID.ROOT)
|
||||
|
||||
for i = 1, #EdgesEgt do
|
||||
local nPreviousEdgeIndex = i - 1
|
||||
if i == 1 then
|
||||
nPreviousEdgeIndex = #EdgesEgt
|
||||
end
|
||||
local nNextEdgeIndex = i + 1
|
||||
if i == #EdgesEgt then
|
||||
nNextEdgeIndex = 1
|
||||
end
|
||||
|
||||
local nPreviousEdgeIndex, nNextEdgeIndex = BeamLib.GetAdjacentIndices( i, #EdgesEgt)
|
||||
|
||||
-- l'elevazione si tiene sempre positiva e la normale sempre diretta verso l'interno della faccia
|
||||
-- per sapere se il lato è aperto c'è la proprietà apposita bIsOpen
|
||||
@@ -136,8 +132,20 @@ function FaceData.GetEdgesInfo( ProcOrId, idFace )
|
||||
end
|
||||
CurrentEdge.bIsStartOpen = EdgesEgt[nPreviousEdgeIndex].Open
|
||||
CurrentEdge.bIsEndOpen = EdgesEgt[nNextEdgeIndex].Open
|
||||
CurrentEdge.ptStart = Point3d( EdgesEgt[i].Start)
|
||||
CurrentEdge.ptEnd = Point3d( EdgesEgt[nNextEdgeIndex].Start)
|
||||
CurrentEdge.vtEdge = CurrentEdge.ptEnd - CurrentEdge.ptStart ; CurrentEdge.vtEdge:normalize()
|
||||
CurrentEdge.sType = 'Standard'
|
||||
CurrentEdge.id = i - 1
|
||||
CurrentEdge.nPreviousEdgeIndex = nPreviousEdgeIndex
|
||||
CurrentEdge.nNextEdgeIndex = nNextEdgeIndex
|
||||
|
||||
-- se nella Proc ci sono le adiacenze e il lato ha adiacenza, si salva l'angolo con la faccia adiacente
|
||||
if Proc.AdjacencyMatrix then
|
||||
if CurrentEdge.idAdjacentFace > -1 then
|
||||
CurrentEdge.dAdjacencyAngle = Proc.AdjacencyMatrix[idFace + 1][CurrentEdge.idAdjacentFace + 1]
|
||||
end
|
||||
end
|
||||
|
||||
table.insert( Edges, CurrentEdge)
|
||||
end
|
||||
@@ -147,7 +155,6 @@ end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function FaceData.GetFacesInfo( Proc, Part, FacesToGet)
|
||||
EgtOutLog( '---Faces START---')
|
||||
local Faces = {}
|
||||
|
||||
local function FaceIsToGet( nIndex)
|
||||
@@ -175,10 +182,11 @@ function FaceData.GetFacesInfo( Proc, Part, FacesToGet)
|
||||
for i = 1, Proc.nFct do
|
||||
Faces[i] = {}
|
||||
Faces[i].id = i - 1
|
||||
Faces[i].idTrimesh = Proc.id
|
||||
Faces[i].ptCenter, Faces[i].vtN = EgtSurfTmFacetCenter( Proc.id, i - 1, GDB_ID.ROOT)
|
||||
if Proc.nFct < 6 or FaceIsToGet( i) then
|
||||
if Proc.nFct < 7 or FaceIsToGet( i) then
|
||||
-- frame OCS faccia
|
||||
Faces[i].vtFrameHV = Frame3d( Faces[i].ptCenter, Faces[i].vtN)
|
||||
Faces[i].frFrameHV = Frame3d( Faces[i].ptCenter, Faces[i].vtN)
|
||||
-- elevazione calcolata rispetto al box della parte
|
||||
Faces[i].dElevation = EgtSurfTmFacetElevationInBBox( Proc.id, i - 1, Part.b3Part, true, GDB_ID.ROOT)
|
||||
-- TODO qui sarebbe meglio l'area vera e non quella del rettangolo minimo
|
||||
@@ -186,78 +194,86 @@ function FaceData.GetFacesInfo( Proc, Part, FacesToGet)
|
||||
Faces[i].dArea = dShortDimension * dLongDimension
|
||||
Faces[i].dLMinRectangle = dLongDimension
|
||||
Faces[i].dWMinRectangle = dShortDimension
|
||||
-- volume approssimato di materiale asportato lavorando questa faccia
|
||||
Faces[i].dMachinedVolumeApprox = Faces[i].dArea * Faces[i].dElevation
|
||||
|
||||
local nFaceType, Edges = FaceData.GetEdgesInfo( Proc, i - 1)
|
||||
Faces[i].bIsOkForMachining = nFaceType < 1
|
||||
Faces[i].Edges = Edges
|
||||
|
||||
-- TODO valutare se fare un output unico alla fine o gestire log in altro modo
|
||||
EgtOutLog( 'Facet ' .. Faces[i].id .. ' of ' .. Proc.nFct - 1)
|
||||
EgtOutLog( ' vtN: ' .. tostring( Faces[i].vtN))
|
||||
|
||||
-- adiacenze della faccia
|
||||
-- TODO chiamarle in modo che si capisca che sono solo gli id e non l'intero oggetto faccia
|
||||
Faces[i].Adjacencies = {}
|
||||
for j = 1, Proc.nFct do
|
||||
if vAdj[i][j] and vAdj[i][j] ~= 0 and ( i ~= j) then
|
||||
table.insert( Faces[i].Adjacencies, j - 1)
|
||||
if EgtGetDebugLevel() >= 3 then
|
||||
EgtOutLog( ' Adjacent to facet: ' .. j - 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
EgtOutLog( '---Faces END---')
|
||||
return Faces
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function FaceData.IsFaceRectangular( Proc, idFace)
|
||||
local nAddGrpId = BeamLib.GetAddGroup( Proc.idPart)
|
||||
local nContourId, nContourCnt = EgtExtractSurfTmFacetLoops( Proc.id, idFace, nAddGrpId)
|
||||
function FaceData.IsFaceRectangle( Face)
|
||||
-- recupero gruppo per geometrie temporanee
|
||||
local idTempGroup = BeamLib.GetTempGroup()
|
||||
|
||||
local nContourId, nContourCnt = EgtExtractSurfTmFacetLoops( Face.idTrimesh, Face.id, idTempGroup)
|
||||
if nContourCnt > 1 then
|
||||
error( 'IsFaceRectangular : too many loops')
|
||||
error( 'IsFaceRectangle : too many loops')
|
||||
end
|
||||
|
||||
local bIsRectangular = EgtCurveIsARectangle( nContourId)
|
||||
|
||||
-- elimino curve create
|
||||
for i = 1, nContourCnt do
|
||||
EgtErase( nContourId + i - 1)
|
||||
end
|
||||
|
||||
return bIsRectangular
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function FaceData.IsFaceRhomboid( Proc, idFace)
|
||||
local nAddGrpId = BeamLib.GetAddGroup( Proc.idPart)
|
||||
local nContourId, nContourCnt = EgtExtractSurfTmFacetLoops( Proc.id, idFace, nAddGrpId)
|
||||
function FaceData.IsFaceParallelogram( Face)
|
||||
-- recupero gruppo per geometrie temporanee
|
||||
local idTempGroup = BeamLib.GetTempGroup()
|
||||
|
||||
local nContourId, nContourCnt = EgtExtractSurfTmFacetLoops( Face.idTrimesh, Face.id, idTempGroup)
|
||||
if nContourCnt > 1 then
|
||||
error( 'IsFaceRectangular : too many loops')
|
||||
error( 'IsFaceParallelogram : too many loops')
|
||||
end
|
||||
|
||||
local bIsTrapezoid = EgtCurveIsATrapezoid( nContourId)
|
||||
local bIsRhomboid = false
|
||||
-- un parallelogramma è un trapezoide con i lati paralleli a due a due
|
||||
if bIsTrapezoid
|
||||
and AreOppositeVectorApprox( Proc.Faces[idFace + 1].Edges[1].vtN, Proc.Faces[idFace + 1].Edges[3].vtN)
|
||||
and AreOppositeVectorApprox( Proc.Faces[idFace + 1].Edges[2].vtN, Proc.Faces[idFace + 1].Edges[4].vtN) then
|
||||
and AreOppositeVectorApprox( Face.Edges[1].vtN, Face.Edges[3].vtN)
|
||||
and AreOppositeVectorApprox( Face.Edges[2].vtN, Face.Edges[4].vtN) then
|
||||
|
||||
bIsRhomboid = true
|
||||
end
|
||||
|
||||
-- elimino curve create
|
||||
for i = 1, nContourCnt do
|
||||
EgtErase( nContourId + i - 1)
|
||||
end
|
||||
|
||||
return bIsRhomboid
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function CompareBottomFaces( FaceA, FaceB)
|
||||
local dMaxVolumeRelativeChange = 0.15
|
||||
-- si prende la faccia con volume lavorato maggiore
|
||||
if FaceA.dMachinedVolumeApprox > ( 1 + dMaxVolumeRelativeChange) * FaceB.dMachinedVolumeApprox + 10 * GEO.EPS_SMALL then
|
||||
return true
|
||||
elseif FaceB.dMachinedVolumeApprox > ( 1 + dMaxVolumeRelativeChange) * FaceA.dMachinedVolumeApprox + 10 * GEO.EPS_SMALL then
|
||||
return false
|
||||
-- se volume lavorato simile, si prende la faccia con minore elevazione
|
||||
else
|
||||
if FaceA.dElevation < FaceB.dElevation - 10 * GEO.EPS_SMALL then
|
||||
return true
|
||||
elseif FaceB.dElevation < FaceA.dElevation - 10 * GEO.EPS_SMALL then
|
||||
return false
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function CompareEdgesBottomFace( EdgeA, EdgeB)
|
||||
-- prima i lati con facce adiacenti
|
||||
@@ -349,7 +365,8 @@ local function GetBottomFaces( Proc)
|
||||
|
||||
if Proc.Topology.sFamily == 'Tunnel' then
|
||||
return nil
|
||||
elseif not ( Proc.Topology.sFamily == 'Rabbet'
|
||||
elseif not ( Proc.Topology.sFamily == 'PseudoPocket'
|
||||
or Proc.Topology.sFamily == 'Rabbet'
|
||||
or Proc.Topology.sFamily == 'VGroove'
|
||||
or Proc.Topology.sFamily == 'Groove'
|
||||
or Proc.Topology.sFamily == 'Pocket'
|
||||
@@ -365,10 +382,28 @@ local function GetBottomFaces( Proc)
|
||||
return { Proc.Faces[1]}
|
||||
end
|
||||
|
||||
-- la faccia di fondo ha sempre Fct - 1 adiacenze
|
||||
-- la faccia di fondo ha sempre Fct - 1 adiacenze, tranne caso speciale DoubleBevel con facce di chiusura triangolari
|
||||
local FacesByAdjacencyNumber = FaceData.GetFacesByAdjacencyNumber( Proc)
|
||||
if FacesByAdjacencyNumber then
|
||||
BottomFaces = FacesByAdjacencyNumber[ Proc.nFct - 1]
|
||||
-- caso speciale DoubleBevel
|
||||
if #BottomFaces == 0 then
|
||||
if Proc.nParts == 1 then
|
||||
BottomFaces = FacesByAdjacencyNumber[ Proc.nFct / 2]
|
||||
-- DoubleBevel composto da più parti
|
||||
else
|
||||
for i = #FacesByAdjacencyNumber, 1, -1 do
|
||||
if #FacesByAdjacencyNumber[i] > 0 then
|
||||
BottomFaces = FacesByAdjacencyNumber[i]
|
||||
break
|
||||
end
|
||||
end
|
||||
-- se non sono state trovate facce di fondo significa che nessuna faccia ha adiacenze -> DoubleBevel-2
|
||||
if #BottomFaces == 0 then
|
||||
BottomFaces = Proc.Faces
|
||||
end
|
||||
end
|
||||
end
|
||||
-- si rimuovono le facce non adatte ad essere lavorate
|
||||
local nBottomFaces = #BottomFaces
|
||||
local nCurrentFace = 1
|
||||
@@ -379,8 +414,8 @@ local function GetBottomFaces( Proc)
|
||||
end
|
||||
nCurrentFace = nCurrentFace + 1
|
||||
end
|
||||
-- la BottomFace 1 è sempre quella con minor elevazione
|
||||
table.sort( BottomFaces, function (a, b) return a.dElevation < b.dElevation end)
|
||||
-- la BottomFace 1 è quella che permette di asportare il volume maggiore; nei casi ambigui si sceglie quella a minor elevazione
|
||||
table.sort( BottomFaces, CompareBottomFaces)
|
||||
end
|
||||
|
||||
if #BottomFaces == 0 then
|
||||
@@ -412,14 +447,7 @@ local function GetBottomFaces( Proc)
|
||||
end
|
||||
|
||||
for i = 1, #BottomFaces[1].Edges do
|
||||
local nPreviousEdgeIndex = i - 1
|
||||
if i == 1 then
|
||||
nPreviousEdgeIndex = #BottomFaces[1].Edges
|
||||
end
|
||||
local nNextEdgeIndex = i + 1
|
||||
if i == #BottomFaces[1].Edges then
|
||||
nNextEdgeIndex = 1
|
||||
end
|
||||
local nPreviousEdgeIndex, nNextEdgeIndex = BeamLib.GetAdjacentIndices( i, #BottomFaces[1].Edges)
|
||||
|
||||
local CurrentEdge = {}
|
||||
CurrentEdge.idAdjacentFace = BottomFaces[1].Edges[i].idAdjacentFace
|
||||
@@ -429,6 +457,12 @@ local function GetBottomFaces( Proc)
|
||||
CurrentEdge.dElevation = BottomFaces[1].Edges[i].dElevation
|
||||
CurrentEdge.bIsStartOpen = BottomFaces[1].Edges[i].bIsStartOpen
|
||||
CurrentEdge.bIsEndOpen = BottomFaces[1].Edges[i].bIsEndOpen
|
||||
CurrentEdge.ptStart = BottomFaces[1].Edges[i].ptStart
|
||||
CurrentEdge.ptEnd = BottomFaces[1].Edges[i].ptEnd
|
||||
CurrentEdge.vtEdge = BottomFaces[1].Edges[i].vtEdge
|
||||
CurrentEdge.id = BottomFaces[1].Edges[i].id
|
||||
CurrentEdge.nPreviousEdgeIndex = BottomFaces[1].Edges[i].nPreviousEdgeIndex
|
||||
CurrentEdge.nNextEdgeIndex = BottomFaces[1].Edges[i].nNextEdgeIndex
|
||||
|
||||
if nFirstLongEdgeIndex then
|
||||
if i == nFirstLongEdgeIndex then
|
||||
@@ -454,7 +488,7 @@ end
|
||||
local function GetLongFaces( Proc, MainFaces)
|
||||
local LongFaces = {}
|
||||
|
||||
if Proc.nFct > 5 then
|
||||
if Proc.nFct > 6 then
|
||||
error( 'GetLongFaces : Topology not implemented')
|
||||
elseif Proc.nFct == 1 then
|
||||
return {}
|
||||
@@ -497,8 +531,8 @@ local function GetLongFaces( Proc, MainFaces)
|
||||
for i = 1, #LongFaces do
|
||||
LongFaces[i].sType = 'Long'
|
||||
|
||||
-- calcolo MainEdges possibile solo se 4 lati esatti
|
||||
if #LongFaces[i].Edges ~= 4 then
|
||||
-- calcolo MainEdges possibile solo se 4 lati esatti e caso speciale lato opposto groove tagliato
|
||||
if #LongFaces[i].Edges ~= 4 and not ( #LongFaces[i].Edges == 5 and Proc.Topology.sName == 'Groove-3-Through') then
|
||||
break
|
||||
end
|
||||
|
||||
@@ -507,14 +541,7 @@ local function GetLongFaces( Proc, MainFaces)
|
||||
LongFaces[i].MainEdges.OppositeEdges = {}
|
||||
|
||||
for j = 1, #LongFaces[i].Edges do
|
||||
local nPreviousEdgeIndex = j - 1
|
||||
if j == 1 then
|
||||
nPreviousEdgeIndex = #LongFaces[1].Edges
|
||||
end
|
||||
local nNextEdgeIndex = j + 1
|
||||
if j == #LongFaces[i].Edges then
|
||||
nNextEdgeIndex = 1
|
||||
end
|
||||
local nPreviousEdgeIndex, nNextEdgeIndex = BeamLib.GetAdjacentIndices( j, #LongFaces[i].Edges)
|
||||
|
||||
local CurrentEdge = {}
|
||||
CurrentEdge.idAdjacentFace = LongFaces[i].Edges[j].idAdjacentFace
|
||||
@@ -524,6 +551,12 @@ local function GetLongFaces( Proc, MainFaces)
|
||||
CurrentEdge.dElevation = LongFaces[i].Edges[j].dElevation
|
||||
CurrentEdge.bIsStartOpen = LongFaces[i].Edges[j].bIsStartOpen
|
||||
CurrentEdge.bIsEndOpen = LongFaces[i].Edges[j].bIsEndOpen
|
||||
CurrentEdge.ptStart = LongFaces[i].Edges[j].ptStart
|
||||
CurrentEdge.ptEnd = LongFaces[i].Edges[j].ptEnd
|
||||
CurrentEdge.vtEdge = LongFaces[i].Edges[j].vtEdge
|
||||
CurrentEdge.id = LongFaces[i].Edges[j].id
|
||||
CurrentEdge.nPreviousEdgeIndex = LongFaces[i].Edges[j].nPreviousEdgeIndex
|
||||
CurrentEdge.nNextEdgeIndex = LongFaces[i].Edges[j].nNextEdgeIndex
|
||||
|
||||
if Proc.Topology.sFamily == 'Tunnel' then
|
||||
if CurrentEdge.idAdjacentFace > -1 then
|
||||
@@ -549,6 +582,12 @@ local function GetLongFaces( Proc, MainFaces)
|
||||
end
|
||||
end
|
||||
end
|
||||
-- il primo OppositeEdge deve essere sempre il più lungo, se più di uno
|
||||
if #LongFaces[i].MainEdges.OppositeEdges > 1 then
|
||||
if LongFaces[i].MainEdges.OppositeEdges[1].dLength < LongFaces[i].MainEdges.OppositeEdges[2].dLength - 10 * GEO.EPS_SMALL then
|
||||
LongFaces[i].MainEdges.OppositeEdges[1], LongFaces[i].MainEdges.OppositeEdges[2] = LongFaces[i].MainEdges.OppositeEdges[2], LongFaces[i].MainEdges.OppositeEdges[1]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return LongFaces
|
||||
@@ -558,7 +597,7 @@ end
|
||||
local function GetSideFaces( Proc, MainFaces)
|
||||
local SideFaces = {}
|
||||
|
||||
if Proc.nFct > 5 then
|
||||
if Proc.nFct > 6 then
|
||||
error( 'GetSideFaces : Topology not implemented')
|
||||
elseif Proc.nFct == 1 then
|
||||
return {}
|
||||
@@ -603,14 +642,7 @@ local function GetSideFaces( Proc, MainFaces)
|
||||
SideFaces[i].MainEdges.OppositeEdges = {}
|
||||
|
||||
for j = 1, #SideFaces[i].Edges do
|
||||
local nPreviousEdgeIndex = j - 1
|
||||
if j == 1 then
|
||||
nPreviousEdgeIndex = #SideFaces[1].Edges
|
||||
end
|
||||
local nNextEdgeIndex = j + 1
|
||||
if j == #SideFaces[i].Edges then
|
||||
nNextEdgeIndex = 1
|
||||
end
|
||||
local nPreviousEdgeIndex, nNextEdgeIndex = BeamLib.GetAdjacentIndices( j, #SideFaces[i].Edges)
|
||||
|
||||
local CurrentEdge = {}
|
||||
CurrentEdge.idAdjacentFace = SideFaces[i].Edges[j].idAdjacentFace
|
||||
@@ -620,6 +652,12 @@ local function GetSideFaces( Proc, MainFaces)
|
||||
CurrentEdge.dElevation = SideFaces[i].Edges[j].dElevation
|
||||
CurrentEdge.bIsStartOpen = SideFaces[i].Edges[j].bIsStartOpen
|
||||
CurrentEdge.bIsEndOpen = SideFaces[i].Edges[j].bIsEndOpen
|
||||
CurrentEdge.ptStart = SideFaces[i].Edges[j].ptStart
|
||||
CurrentEdge.ptEnd = SideFaces[i].Edges[j].ptEnd
|
||||
CurrentEdge.vtEdge = SideFaces[i].Edges[j].vtEdge
|
||||
CurrentEdge.id = SideFaces[i].Edges[j].id
|
||||
CurrentEdge.nPreviousEdgeIndex = SideFaces[i].Edges[j].nPreviousEdgeIndex
|
||||
CurrentEdge.nNextEdgeIndex = SideFaces[i].Edges[j].nNextEdgeIndex
|
||||
|
||||
if Proc.Topology.sFamily == 'Tunnel' then
|
||||
if CurrentEdge.idAdjacentFace > -1 then
|
||||
@@ -653,34 +691,33 @@ end
|
||||
-- TODO test iniziale replicato in GetTunnelFaces
|
||||
function FaceData.GetMainFaces( Proc, Part)
|
||||
|
||||
EgtOutLog( '---MainFaces START---')
|
||||
local MainFaces = {}
|
||||
|
||||
-- CASO 1 : Feature tipo LapJoint
|
||||
if Proc.Topology.sFamily == 'Rabbet' or Proc.Topology.sFamily == 'VGroove' or Proc.Topology.sFamily == 'Groove' or
|
||||
if Proc.Topology.sFamily == 'PseudoPocket' or Proc.Topology.sFamily == 'Rabbet' or Proc.Topology.sFamily == 'VGroove' or Proc.Topology.sFamily == 'Groove' or
|
||||
Proc.Topology.sFamily == 'Pocket' or Proc.Topology.sFamily == 'Tunnel' or Proc.Topology.sFamily == 'Bevel' or
|
||||
Proc.Topology.sFamily == 'DoubleBevel' or Proc.Topology.sFamily == 'Cut' or Proc.Topology.sFamily == 'HeadCut' or Proc.Topology.sFamily == 'TailCut' then
|
||||
|
||||
if ( Proc.Topology.bIsThrough and Proc.Topology.bAllRightAngles and Proc.nFct < 5)
|
||||
or ( Proc.nFct == 1) or Proc.Topology.sName == 'Bevel-2-Blind' then
|
||||
if Proc.nParts == 1 and ( ( Proc.Topology.bIsThrough and Proc.Topology.bAllRightAngles and Proc.nFct < 5)
|
||||
or ( Proc.nFct == 1) or Proc.Topology.sName == 'Bevel-2-Blind') then
|
||||
|
||||
MainFaces.TunnelAddedFaces = GetTunnelFaces( Proc, Part)
|
||||
end
|
||||
|
||||
MainFaces.BottomFaces = GetBottomFaces( Proc)
|
||||
MainFaces.LongFaces = GetLongFaces( Proc, MainFaces)
|
||||
MainFaces.SideFaces = GetSideFaces( Proc, MainFaces)
|
||||
|
||||
-- scrivo informazioni delle facce nel log
|
||||
if EgtGetDebugLevel() >= 3 then
|
||||
Logs.WriteMainFacesLog( Proc, MainFaces)
|
||||
if Proc.nParts == 1 then
|
||||
MainFaces.LongFaces = GetLongFaces( Proc, MainFaces)
|
||||
MainFaces.SideFaces = GetSideFaces( Proc, MainFaces)
|
||||
-- caso tipo DoubleBevel con facce separate
|
||||
else
|
||||
MainFaces.LongFaces = {}
|
||||
MainFaces.SideFaces = {}
|
||||
end
|
||||
|
||||
else
|
||||
MainFaces = nil
|
||||
EgtOutLog( '---MainFaces NOT NEEDED---')
|
||||
end
|
||||
|
||||
EgtOutLog( '---MainFaces END---')
|
||||
return MainFaces
|
||||
end
|
||||
|
||||
|
||||
+44
-38
@@ -6,7 +6,7 @@
|
||||
local FeatureLib = {}
|
||||
|
||||
-- Carico i dati globali
|
||||
local BeamData = require( 'BeamData')
|
||||
local BeamData = require( 'BeamDataNew')
|
||||
|
||||
-- carico librerie
|
||||
local BeamLib = require( 'BeamLib')
|
||||
@@ -32,6 +32,10 @@ function FeatureLib.GetProcFromTrimesh( idTrimesh, Part, ProcToCopyFrom)
|
||||
Proc.AffectedFaces = BeamLib.GetAffectedFaces( Proc, Part)
|
||||
Proc.AdjacencyMatrix = FaceData.GetAdjacencyMatrix( Proc)
|
||||
Proc.Faces = FaceData.GetFacesInfo( Proc, Part)
|
||||
Proc.dVolume = FeatureLib.GetFeatureVolume( Proc, Part)
|
||||
if ProcToCopyFrom and Proc.dVolume < 10 * GEO.EPS_SMALL then
|
||||
Proc.dVolume = ProcToCopyFrom.dVolume
|
||||
end
|
||||
-- TODO servono anche altri dati raccolti nel collect??
|
||||
|
||||
return Proc
|
||||
@@ -39,7 +43,7 @@ end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- restituisce vero se la feature con box b3Proc taglia l'intera sezione della barra
|
||||
local function IsFeatureCuttingEntireSection( b3Proc, Part)
|
||||
function FeatureLib.IsFeatureCuttingEntireSection( b3Proc, Part)
|
||||
return ( b3Proc:getDimY() > ( Part.b3Part:getDimY() - 500 * GEO.EPS_SMALL) and b3Proc:getDimZ() > ( Part.b3Part:getDimZ() - 500 * GEO.EPS_SMALL))
|
||||
end
|
||||
|
||||
@@ -54,7 +58,7 @@ end
|
||||
-- restituisce vero se tutti i lati della faccia passata si trovano sul grezzo
|
||||
local function AreAllFaceEdgesOnRaw( Part, Proc, idFace)
|
||||
local bEdgeOnRaw = true
|
||||
local idTempGroup = BeamLib.GetTempGroup()
|
||||
local idTempGroup = Part.idTempGroup
|
||||
local nLoopId, nLoopCnt = EgtExtractSurfTmFacetLoops( Proc.id, idFace, idTempGroup)
|
||||
if nLoopCnt > 1 then
|
||||
error( 'AreAllFaceEdgesOnRaw : too many loops')
|
||||
@@ -194,7 +198,7 @@ function FeatureLib.ClassifyTopology( Proc, Part)
|
||||
|
||||
if not Proc.AffectedFaces then Proc.AffectedFaces = BeamLib.GetAffectedFaces( Proc, Part) end
|
||||
|
||||
local bIsFeatureCuttingEntireSection = IsFeatureCuttingEntireSection( Proc.b3Box, Part)
|
||||
local bIsFeatureCuttingEntireSection = FeatureLib.IsFeatureCuttingEntireSection( Proc.b3Box, Part)
|
||||
local bIsFeatureCuttingEntireLength = IsFeatureCuttingEntireLength( Proc.b3Box, Part)
|
||||
local bIsAnyDimensionLongAsPart = IsAnyDimensionLongAsPart( Proc, Part)
|
||||
local vAdj = Proc.AdjacencyMatrix
|
||||
@@ -222,13 +226,13 @@ function FeatureLib.ClassifyTopology( Proc, Part)
|
||||
elseif Proc.nFct == 2 and bAllAnglesConcave and #vTriangularFaces == 1 then
|
||||
sFamily = 'Bevel'
|
||||
bIsThrough = false
|
||||
elseif Proc.nFct == 2 and bAllAnglesConcave and ( Proc.AffectedFaces.bLeft or Proc.AffectedFaces.bRight) and ( Proc.AffectedFaces.bFront or Proc.AffectedFaces.bBack) then
|
||||
elseif Proc.nFct == 2 and bAllAnglesConcave and Proc.nParts == 1 and ( Proc.AffectedFaces.bLeft or Proc.AffectedFaces.bRight) and ( Proc.AffectedFaces.bFront or Proc.AffectedFaces.bBack) then
|
||||
sFamily = 'Rabbet'
|
||||
bIsThrough = true
|
||||
elseif Proc.nFct == 2 and bAllAnglesConcave then
|
||||
elseif Proc.nFct == 2 and bAllAnglesConcave and Proc.nParts == 1 then
|
||||
sFamily = 'VGroove'
|
||||
bIsThrough = true
|
||||
elseif Proc.nFct == 2 and not bAllAnglesConcave and bIsAnyDimensionLongAsPart then
|
||||
elseif Proc.nFct == 2 and ( not bAllAnglesConcave or Proc.nParts == 2) and bIsAnyDimensionLongAsPart then
|
||||
sFamily = 'DoubleBevel'
|
||||
bIsThrough = true
|
||||
elseif Proc.nFct == 3 and bAllAnglesConcave and #vFacesByAdjNumber[2] == 1 and #vTriangularFaces == 2 then
|
||||
@@ -240,7 +244,9 @@ function FeatureLib.ClassifyTopology( Proc, Part)
|
||||
elseif Proc.nFct == 3 and bAllAnglesConcave and #vFacesByAdjNumber[2] == 3 then
|
||||
sFamily = 'Groove'
|
||||
bIsThrough = false
|
||||
elseif Proc.nFct == 4 and #vFacesByAdjNumber[2] == 4 and #vTriangularFaces == 2 then
|
||||
elseif Proc.nFct == 4
|
||||
and ( ( not bAllAnglesConcave and ( ( #vFacesByAdjNumber[2] == 2 and #vTriangularFaces == 2) or ( #vFacesByAdjNumber[3] == 2)))
|
||||
or ( #vTriangularFaces == 2 and Proc.nParts == 2)) then
|
||||
sFamily = 'DoubleBevel'
|
||||
bIsThrough = false
|
||||
elseif Proc.nFct == 4 and bAllAnglesConcave and #vFacesByAdjNumber[3] == 2 then
|
||||
@@ -249,13 +255,18 @@ function FeatureLib.ClassifyTopology( Proc, Part)
|
||||
elseif Proc.nFct == 4 and bAllAnglesConcave and #vFacesByAdjNumber[2] == 4 and bIsAnyDimensionLongAsPart then
|
||||
sFamily = 'Tunnel'
|
||||
bIsThrough = true
|
||||
elseif Proc.nFct == 4 and bAllAnglesConcave and #vFacesByAdjNumber[3] == 1 then
|
||||
sFamily = 'PseudoPocket'
|
||||
bIsThrough = false
|
||||
elseif Proc.nFct >= 4 and #vFacesByAdjNumber[1] == 2 and bIsAnyDimensionLongAsPart then
|
||||
sFamily = 'Strip'
|
||||
bIsThrough = true
|
||||
elseif Proc.nFct == 5 and bAllAnglesConcave and #vFacesByAdjNumber[4] == 1 then
|
||||
sFamily = 'Pocket'
|
||||
bIsThrough = false
|
||||
elseif Proc.nFct == 6 and #vFacesByAdjNumber[2] == 4 and #vFacesByAdjNumber[3] == 2 and #vTriangularFaces == 4 then
|
||||
elseif Proc.nFct == 6
|
||||
and ( ( #vFacesByAdjNumber[1] == 4 and #vFacesByAdjNumber[3] == 2 and #vTriangularFaces == 4 and not bAllAnglesConcave)
|
||||
or ( #vFacesByAdjNumber[1] == 4 and #vTriangularFaces == 4 and Proc.nParts == 2)) then
|
||||
sFamily = 'DoubleBevel'
|
||||
bIsThrough = false
|
||||
end
|
||||
@@ -323,12 +334,15 @@ function FeatureLib.GetAdditionalInfo( Proc, Part)
|
||||
elseif ID.IsRidgeLap( Proc) then
|
||||
Proc.AdjacencyMatrix = FaceData.GetAdjacencyMatrix( Proc)
|
||||
Proc.Faces = FaceData.GetFacesInfo( Proc, Part)
|
||||
elseif ID.IsMarking( Proc) then
|
||||
elseif ID.IsMarking( Proc) or ID.IsText( Proc) then
|
||||
Proc.FeatureInfo = FeatureLib.GetMarkTextData( Proc)
|
||||
elseif ID.IsHipValleyRafterNotch( Proc) then
|
||||
Proc.AdjacencyMatrix = FaceData.GetAdjacencyMatrix( Proc)
|
||||
Proc.Faces = FaceData.GetFacesInfo( Proc, Part)
|
||||
Proc.FeatureInfo, Proc.MainFaces = FeatureLib.GetRafterNotchData( Proc)
|
||||
elseif ( ID.IsScarfJoint( Proc) or ID.IsScarfSimple( Proc)) then
|
||||
Proc.AdjacencyMatrix = FaceData.GetAdjacencyMatrix( Proc)
|
||||
Proc.Faces = FaceData.GetFacesInfo( Proc, Part)
|
||||
end
|
||||
|
||||
return Proc
|
||||
@@ -495,6 +509,7 @@ function FeatureLib.GetDTMortiseData( Proc)
|
||||
|
||||
-- distanza massima all'imbocco ortogonale all'asse
|
||||
local vtDiff = EgtEP( idAux, GDB_RT.GLOB) - EgtSP( idAux, GDB_RT.GLOB)
|
||||
|
||||
local vtOrtDiff = vtDiff - vtDiff * vtAx * vtAx
|
||||
local dMortiseMaxDist = min( vtOrtDiff:len(), dMortiseWidth)
|
||||
|
||||
@@ -505,6 +520,9 @@ function FeatureLib.GetDTMortiseData( Proc)
|
||||
FeatureExtraInfo.dMortiseDepth = dMortiseDepth
|
||||
FeatureExtraInfo.dMortiseMinRadius = dMortiseMinRadius
|
||||
FeatureExtraInfo.vtMortiseN = vtMortiseN
|
||||
vtDiff:normalize()
|
||||
FeatureExtraInfo.vtMortisePathStart = EgtSV( idAux, GDB_RT.GLOB) * vtDiff
|
||||
FeatureExtraInfo.vtMortisePathEnd = EgtEV( idAux, GDB_RT.GLOB) * vtDiff
|
||||
FeatureExtraInfo.idAddAuxGeom = idAux
|
||||
|
||||
return FeatureExtraInfo
|
||||
@@ -749,6 +767,9 @@ function FeatureLib.CalculateStrategiesCompositeRating( AvailableStrategies, sMa
|
||||
|
||||
AvailableStrategies[n].Result.dCompositeRating = dQuality + dCompletion + dTime -- TODO da verificare se meglio sommare o moltiplicare gli indici
|
||||
else
|
||||
if not AvailableStrategies[n].Result then
|
||||
AvailableStrategies[n].Result = {}
|
||||
end
|
||||
AvailableStrategies[n].Result.dCompositeRating = 0
|
||||
end
|
||||
end
|
||||
@@ -842,7 +863,7 @@ function FeatureLib.GetFeatureSplittingPoints( Proc, Part, OptionalParameters)
|
||||
if Part.dRestLength + Part.b3Part:getDimX() < BeamData.dMinRaw * 1.5 then
|
||||
dSplitXLeft = Part.b3Part:getMax():getX() - ( ( Part.dRestLength + Part.b3Part:getDimX()) / 2)
|
||||
else
|
||||
dSplitXLeft = max( Proc.b3Box:getMin():getX() + ( BeamData.dMinRaw)/2 + 150, Part.b3Part:getMax():getX() - dMaxSegmentLengthOnEdges)
|
||||
dSplitXLeft = max( Proc.b3Box:getMin():getX() + ( BeamData.dMinRaw) / 2 + 150, Part.b3Part:getMax():getX() - dMaxSegmentLengthOnEdges)
|
||||
end
|
||||
end
|
||||
dFeatureCentralLength = abs( dSplitXRight - dSplitXLeft)
|
||||
@@ -901,23 +922,16 @@ end
|
||||
function FeatureLib.GetFeatureVolume( Proc, Part)
|
||||
local dProcVolume = 0
|
||||
|
||||
local idAddGroup = BeamLib.GetAddGroup( Part.id)
|
||||
if not idAddGroup then
|
||||
-- TODO gestire meglio questo errore. Non conviene creare e verificare all'inizio se il gruppo esiste?
|
||||
EgtOutLog( 'Error : missing AddGroup')
|
||||
return 0
|
||||
end
|
||||
local idTempGroup = Part.idTempGroup
|
||||
|
||||
local idProcCopy = EgtCopyGlob( Proc.id, idAddGroup) or GDB_ID.NULL
|
||||
local idProcCopy = EgtCopyGlob( Proc.id, idTempGroup) or GDB_ID.NULL
|
||||
local b3PartCopy = BBox3d( Part.b3Part)
|
||||
b3PartCopy:expand( -100 * GEO.EPS_SMALL)
|
||||
local idPartCopy = EgtSurfTmBBox( idAddGroup, b3PartCopy , false, GDB_RT.GLOB)
|
||||
local idPartCopy = EgtSurfTmBBox( idTempGroup, b3PartCopy , false, GDB_RT.GLOB)
|
||||
|
||||
EgtSurfTmSubtract( idPartCopy, idProcCopy)
|
||||
dProcVolume = EgtSurfVolume( idPartCopy)
|
||||
|
||||
EgtErase( { idProcCopy, idPartCopy})
|
||||
|
||||
return dProcVolume
|
||||
end
|
||||
|
||||
@@ -925,8 +939,9 @@ end
|
||||
-- funzione che verifica se la feature, lavorata in questa fase, compromette lettura misura laser
|
||||
function FeatureLib.CalculateFeatureHindersLaserMeasure( Proc, Part)
|
||||
local bFeatureHindersLaserMeasure = false
|
||||
-- se la feature è aperta frontalmente, posteriormente e di testa, allora potrebbe impattare sulla misura laser, controllo caso per caso
|
||||
if Proc.AffectedFaces.bRight and Proc.AffectedFaces.bFront and Proc.AffectedFaces.bBack then
|
||||
-- se la feature è aperta frontalmente, posteriormente, di testa e più bassa di 40mm, allora potrebbe impattare sulla misura laser, controllo caso per caso
|
||||
if Proc.AffectedFaces.bRight and Proc.AffectedFaces.bFront and Proc.AffectedFaces.bBack and
|
||||
( Proc.b3Box:getMin():getZ() - Part.b3Raw:getMin():getZ()) < 40 then
|
||||
bFeatureHindersLaserMeasure = true
|
||||
end
|
||||
return bFeatureHindersLaserMeasure
|
||||
@@ -940,6 +955,7 @@ function FeatureLib.CalculateFeatureNotClampableLengths( Proc, Part)
|
||||
local dNotClampableLengthTail = 0
|
||||
|
||||
-- se il grezzo non è definito, prendo il box del pezzo
|
||||
-- TODO 1- si sta passando b3part per riferimento, 2- non dovrebbe essre sempre definito?
|
||||
if not Part.b3Raw then
|
||||
Part.b3Raw = Part.b3Part
|
||||
end
|
||||
@@ -961,13 +977,13 @@ function FeatureLib.CalculateFeatureNotClampableLengths( Proc, Part)
|
||||
-- condizioni per limitare pinzaggio testa/coda
|
||||
local bUpdateIng = true
|
||||
-- se dimensione del box della feature maggiore di metà pinzaggio minimo o metà spessore pezzo
|
||||
bUpdateIng = bUpdateIng and Proc.b3Box:getDimZ() > dMinHIng
|
||||
-- bUpdateIng = bUpdateIng and Proc.b3Box:getDimZ() > dMinHIng
|
||||
-- se la feature si trova più in basso del minimo pinzabile in Z o il 35% dello spessore pezzo
|
||||
bUpdateIng = bUpdateIng and Proc.b3Box:getMin():getZ() < Part.b3Raw:getMin():getZ() + dMinZ
|
||||
-- se feature è al di sotto del pinzaggio massimo
|
||||
bUpdateIng = bUpdateIng and Proc.b3Box:getMin():getZ() < dMaxHZ
|
||||
-- se ho le morse verticali, o se la feature è in centro o verso alto, controllo se non prendo abbastanza.
|
||||
if bIsVertClamps or ( Proc.b3Box:getMin():getZ() - Part.b3Raw:getMin():getZ()) > BeamData.MIN_HEIGHT then
|
||||
-- se ho le morse verticali, o se la feature è in centro o verso alto, controllo se non prendo abbastanza
|
||||
if bIsVertClamps or ( Proc.b3Box:getMin():getZ() - Part.b3Raw:getMin():getZ()) > BeamData.MIN_HEIGHT then
|
||||
bUpdateIng = bUpdateIng and dDeltaZClamp < BeamData.VICE_MINH
|
||||
end
|
||||
|
||||
@@ -979,24 +995,14 @@ function FeatureLib.CalculateFeatureNotClampableLengths( Proc, Part)
|
||||
dOffs = min( dOffs, BeamData.VICE_MAXH - BeamData.VICE_MINH)
|
||||
end
|
||||
dNotClampableLengthHead = dOffs
|
||||
elseif Proc.AffectedFaces.bLeft then
|
||||
end
|
||||
if Proc.AffectedFaces.bLeft then
|
||||
local dOffs = Proc.b3Box:getMax():getX() - Part.b3Part:getMin():getX()
|
||||
-- se pinze a 45° e pinza abbastanza materiale, compenso comunque, ma solo inclinazione morse
|
||||
if not bIsVertClamps and dDeltaZClamp > BeamData.VICE_MINH and BeamData.VICE_MAXH then
|
||||
dOffs = min( dOffs, BeamData.VICE_MAXH - BeamData.VICE_MINH)
|
||||
end
|
||||
dNotClampableLengthTail = dOffs
|
||||
-- TODO il controllo sul punto centrale non è corretto, deve essere rivisto.
|
||||
-- Si lascia qui commentato perchè era così anche in quello vecchio, quindi potrebbe essere che in qualche caso potesse funzionare
|
||||
-- elseif Proc.b3Box:getCenter():getX() > Part.b3Part:getCenter():getX() then
|
||||
-- local dOffs = Part.b3Part:getMax():getX() - Proc.b3Box:getMin():getX()
|
||||
-- local dDist = Part.b3Part:getMax():getX() - Proc.b3Box:getMax():getX()
|
||||
-- -- se pinze a 45° e pinza abbastanza materiale, compenso comunque, ma solo inclinazione morse
|
||||
-- if not bIsVertClamps and dDeltaZClamp > BeamData.VICE_MINH and BeamData.VICE_MAXH then
|
||||
-- dOffs = min( dOffs, BeamData.VICE_MAXH - BeamData.VICE_MINH)
|
||||
-- end
|
||||
-- -- dDist serve??
|
||||
-- dNotClampableLengthHead = dOffs
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,247 @@
|
||||
-- LeadInOutLib.lua by Egalware s.r.l. 2025/11/24
|
||||
-- Libreria stima collisioni per travi
|
||||
|
||||
-- Tabella per definizione modulo
|
||||
local LeadInOutLib = {}
|
||||
|
||||
-- Include
|
||||
require( 'EgtBase')
|
||||
local BeamData = require( 'BeamDataNew')
|
||||
local FaceData = require( 'FaceData')
|
||||
local BeamLib = require( 'BeamLib')
|
||||
|
||||
EgtOutLog( ' LeadInOutLib started', 1)
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function GetExtraAddLengthInclinedSides( Face, Edge)
|
||||
|
||||
-- se faccia rettangolare i lati sono tutti a 90deg, inutile fare conti
|
||||
if FaceData.IsFaceRectangle( Face) then
|
||||
return 0, 0
|
||||
end
|
||||
|
||||
local nPreviousEdgeIndex = Edge.id + 1 - 1
|
||||
if nPreviousEdgeIndex < 1 then
|
||||
nPreviousEdgeIndex = #Face.Edges
|
||||
end
|
||||
local nNextEdgeIndex = Edge.id + 1 + 1
|
||||
if nNextEdgeIndex > #Face.Edges then
|
||||
nNextEdgeIndex = 1
|
||||
end
|
||||
|
||||
local vtEdgePrevious = Face.Edges[nPreviousEdgeIndex].vtEdge
|
||||
local vtEdgeNext = Face.Edges[nNextEdgeIndex].vtEdge
|
||||
local dLengthEdgePrevious = Face.Edges[nPreviousEdgeIndex].dLength
|
||||
local dLengthEdgeNext = Face.Edges[nNextEdgeIndex].dLength
|
||||
|
||||
local dExtraPrevious = dLengthEdgePrevious * ( Edge.vtEdge * -vtEdgePrevious)
|
||||
local dExtraNext = dLengthEdgeNext * ( -Edge.vtEdge * vtEdgeNext)
|
||||
|
||||
return dExtraPrevious, dExtraNext
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function GetPerpendicularLeadInOutDirection( Face, Edge)
|
||||
|
||||
-- informazioni lati adiacenti
|
||||
local nCurrentEdgeIndex = Edge.id + 1
|
||||
local nPreviousEdgeIndex = ( nCurrentEdgeIndex == 1 and #Face.Edges) or nCurrentEdgeIndex - 1
|
||||
local nNextEdgeIndex = ( nCurrentEdgeIndex == #Face.Edges and 1) or nCurrentEdgeIndex + 1
|
||||
local EdgeNext = Face.Edges[nNextEdgeIndex]
|
||||
local EdgePrevious = Face.Edges[nPreviousEdgeIndex]
|
||||
|
||||
-- tra le direzioni dei due lati adiacenti, si sceglie la migliore da cui attaccare, ossia quella più vicina alla perpendicolare al lato di lavoro
|
||||
local dCosAngleStart = -EdgePrevious.vtEdge * Edge.vtN
|
||||
local dCosAngleEnd = EdgeNext.vtEdge * Edge.vtN
|
||||
local vtLeadInOut
|
||||
-- se le due direzioni sono entro i 5° scelgo quella a Z assoluta minore, altrimenti quella più vicino alla perpendicolare
|
||||
-- massima differenza scalare per variazione di 5deg: cos(0) - cos(0 + 5) = 1 - cos(5)
|
||||
local dScalarTolerance = 1 - 0.996
|
||||
if abs( dCosAngleStart - dCosAngleEnd) < dScalarTolerance then
|
||||
if abs( EdgePrevious.vtEdge:getZ()) < abs( EdgeNext.vtEdge:getZ()) then
|
||||
vtLeadInOut = Vector3d( -EdgePrevious.vtEdge)
|
||||
else
|
||||
vtLeadInOut = Vector3d( EdgeNext.vtEdge)
|
||||
end
|
||||
else
|
||||
if dCosAngleStart > dCosAngleEnd then
|
||||
vtLeadInOut = Vector3d( -EdgePrevious.vtEdge)
|
||||
else
|
||||
vtLeadInOut = Vector3d( EdgeNext.vtEdge)
|
||||
end
|
||||
end
|
||||
|
||||
return vtLeadInOut
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function CalculateLeadInOutLength( ptToolCenter, vtNFace, b3Box, vtLeadInOut, Tool)
|
||||
|
||||
-- al momento gestita solo lama
|
||||
if not Tool.sFamily == 'SawBlade' then
|
||||
error(' Tool family not implemented')
|
||||
end
|
||||
|
||||
-- Box del pezzo espansi ortogonalmente alle tre direzioni canoniche X, Y e Z
|
||||
local b3BoxX = BBox3d( b3Box) ; b3BoxX:expand( 0, 1000, 1000)
|
||||
local b3BoxY = BBox3d( b3Box) ; b3BoxY:expand( 1000, 0, 1000)
|
||||
local b3BoxZ = BBox3d( b3Box) ; b3BoxZ:expand( 1000, 1000, 0)
|
||||
|
||||
-- si setta utensile lama per il controllo collisione
|
||||
EgtCAvSetSawTool( Tool.dThickness, Tool.dDiameter, Tool.dThickness, 0, 0)
|
||||
|
||||
-- calcolo distanza di cui retrarre con funzioni Tool Collision Avoidance
|
||||
local dLength = min( EgtCAvToolPosBox( ptToolCenter + Tool.dThickness * vtNFace, vtNFace, b3BoxX, vtLeadInOut),
|
||||
EgtCAvToolPosBox( ptToolCenter + Tool.dThickness * vtNFace, vtNFace, b3BoxY, vtLeadInOut),
|
||||
EgtCAvToolPosBox( ptToolCenter + Tool.dThickness * vtNFace, vtNFace, b3BoxZ, vtLeadInOut))
|
||||
|
||||
return dLength
|
||||
end
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function LeadInOutLib.CalculateLeadInOut( sLeadInOutType, Parameters, OptionalParameters)
|
||||
|
||||
-- parametri obbligatori
|
||||
local Face = Parameters.Face
|
||||
local Edge = Parameters.Edge
|
||||
local Part = Parameters.Part
|
||||
local Tool = Parameters.Tool
|
||||
local dDepthToMachine = Parameters.dDepthToMachine
|
||||
|
||||
-- parametri opzionali
|
||||
local sRestLengthSideForPreSimulation = OptionalParameters.sRestLengthSideForPreSimulation or 'Tail'
|
||||
local bCannotSplitRestLength = OptionalParameters.bCannotSplitRestLength or false
|
||||
|
||||
local LeadInOut = {}
|
||||
local bIsStartClosed = not Edge.bIsStartOpen
|
||||
local bIsEndClosed = not Edge.bIsEndOpen
|
||||
|
||||
-- accorciamento per lati chiusi
|
||||
LeadInOut.dToolMarkLength = sqrt( dDepthToMachine * Tool.dDiameter - dDepthToMachine * dDepthToMachine)
|
||||
LeadInOut.dExtraAddLengthStart, LeadInOut.dExtraAddLengthEnd = GetExtraAddLengthInclinedSides( Face, Edge)
|
||||
-- allungamento per faccia singola (aperta in tutte le direzioni)
|
||||
LeadInOut.dAddedLengthOpenFace = BeamData.CUT_EXTRA
|
||||
|
||||
local LeadIn = {}
|
||||
local LeadOut = {}
|
||||
LeadIn.dStartAddLength = 0
|
||||
LeadOut.dEndAddLength = 0
|
||||
LeadIn.nType = MCH_MILL_LI.LINEAR
|
||||
LeadOut.nType = MCH_MILL_LI.LINEAR
|
||||
LeadIn.dPerpDistance = 0
|
||||
LeadOut.dPerpDistance = 0
|
||||
LeadIn.dTangentDistance = 0
|
||||
LeadOut.dTangentDistance = 0
|
||||
LeadIn.dElevation = 0
|
||||
LeadOut.dElevation = 0
|
||||
LeadIn.dCompLength = 0
|
||||
LeadOut.dCompLength = 0
|
||||
|
||||
-- calcolo allungamenti / accorciamenti
|
||||
if bIsStartClosed and bIsEndClosed then
|
||||
LeadIn.dStartAddLength = -LeadInOut.dToolMarkLength - LeadInOut.dExtraAddLengthStart
|
||||
LeadOut.dEndAddLength = -LeadInOut.dToolMarkLength - LeadInOut.dExtraAddLengthEnd
|
||||
elseif bIsStartClosed then
|
||||
LeadIn.dStartAddLength = -LeadInOut.dToolMarkLength - LeadInOut.dExtraAddLengthStart
|
||||
-- eventuale correzione per accorciamento maggiore di larghezza tasca
|
||||
LeadOut.dEndAddLength = max( -LeadIn.dStartAddLength - Edge.dLength + 10 * BeamData.CUT_EXTRA, BeamData.CUT_EXTRA)
|
||||
elseif bIsEndClosed then
|
||||
LeadOut.dEndAddLength = -LeadInOut.dToolMarkLength - LeadInOut.dExtraAddLengthEnd
|
||||
-- eventuale correzione per accorciamento maggiore di larghezza tasca
|
||||
LeadIn.dStartAddLength = max( -LeadOut.dEndAddLength - Edge.dLength + 10 * BeamData.CUT_EXTRA, BeamData.CUT_EXTRA)
|
||||
else
|
||||
LeadIn.dStartAddLength = LeadInOut.dAddedLengthOpenFace
|
||||
LeadOut.dEndAddLength = LeadInOut.dAddedLengthOpenFace
|
||||
end
|
||||
|
||||
-- calcolo punti notevoli della lavorazione
|
||||
-- punti di inizio e fine lavorazione alla profondità di lavoro reale, considerando allungamenti/accorciamenti
|
||||
local ptStartAtDepth = Edge.ptStart - Edge.vtEdge * LeadIn.dStartAddLength + Edge.vtN * ( Edge.dElevation - dDepthToMachine)
|
||||
local ptEndAtDepth = Edge.ptEnd + Edge.vtEdge * LeadOut.dEndAddLength + Edge.vtN * ( Edge.dElevation - dDepthToMachine)
|
||||
-- punti in centro lama
|
||||
local ptStartBladeCenter = ptStartAtDepth + Edge.vtN * Tool.dDiameter / 2
|
||||
local ptEndBladeCenter = ptEndAtDepth + Edge.vtN * Tool.dDiameter / 2
|
||||
|
||||
-- box per calcolo uscita lama
|
||||
-- se è un taglio di testa o coda va aggiunto il sovramateriale
|
||||
local b3BoxPartExpanded = BBox3d( Part.b3Part)
|
||||
if bCannotSplitRestLength then
|
||||
b3BoxPartExpanded = BeamLib.GetPartBoxWithHeadTail( Part, sRestLengthSideForPreSimulation)
|
||||
end
|
||||
-- il box si espande in tutte le direzioni per contemplare la sicurezza CUT_SIC
|
||||
b3BoxPartExpanded:expand( BeamData.CUT_SIC)
|
||||
|
||||
-- calcolo attacco scelto
|
||||
if sLeadInOutType == 'Perpendicular' then
|
||||
|
||||
-- scelta direzione migliore per l'attacco
|
||||
local vtLeadInOut = GetPerpendicularLeadInOutDirection( Face, Edge)
|
||||
|
||||
-- frame solidale al lato di lavoro (X lungo il lato, Y normale al lato)
|
||||
local frEdge = Frame3d( Edge.ptStart, Face.vtN, Edge.vtEdge)
|
||||
|
||||
-- direzione nel frame solidale al lato di lavoro
|
||||
local vtLeadInOuttLoc = Vector3d( vtLeadInOut)
|
||||
vtLeadInOuttLoc:toLoc( frEdge)
|
||||
|
||||
-- calcolo distanza per uscire dal box con questa lama nella direzione vtLeadInOut
|
||||
local dLeadInLength = CalculateLeadInOutLength( ptStartBladeCenter, Face.vtN, b3BoxPartExpanded, vtLeadInOut, Tool)
|
||||
local dLeadOutLength = CalculateLeadInOutLength( ptEndBladeCenter, Face.vtN, b3BoxPartExpanded, vtLeadInOut, Tool)
|
||||
|
||||
-- componenti dell'attacco
|
||||
LeadIn.dPerpDistance = dLeadInLength * vtLeadInOuttLoc:getY()
|
||||
LeadIn.dTangentDistance = dLeadInLength * -vtLeadInOuttLoc:getX()
|
||||
LeadOut.dPerpDistance = dLeadOutLength * vtLeadInOuttLoc:getY()
|
||||
LeadOut.dTangentDistance = dLeadOutLength * vtLeadInOuttLoc:getX()
|
||||
|
||||
-- punti dell'attacco
|
||||
LeadIn.ptPoint = Point3d( ptStartAtDepth + vtLeadInOut * dLeadInLength)
|
||||
LeadOut.ptPoint = Point3d( ptEndAtDepth + vtLeadInOut * dLeadOutLength)
|
||||
|
||||
elseif sLeadInOutType == 'Tangent' then
|
||||
|
||||
-- calcolo distanza per uscire dal box con questa lama nella direzione tangenziale
|
||||
local dLeadInLength = CalculateLeadInOutLength( ptStartBladeCenter, Face.vtN, b3BoxPartExpanded, -Edge.vtEdge, Tool)
|
||||
local dLeadOutLength = CalculateLeadInOutLength( ptEndBladeCenter, Face.vtN, b3BoxPartExpanded, Edge.vtEdge, Tool)
|
||||
|
||||
-- componenti dell'attacco
|
||||
LeadIn.dPerpDistance = 0
|
||||
LeadIn.dTangentDistance = dLeadInLength
|
||||
LeadOut.dPerpDistance = 0
|
||||
LeadOut.dTangentDistance = dLeadOutLength
|
||||
|
||||
-- punti dell'attacco
|
||||
LeadIn.ptPoint = Point3d( ptStartAtDepth - Edge.vtEdge * dLeadInLength)
|
||||
LeadOut.ptPoint = Point3d( ptEndAtDepth + Edge.vtEdge * dLeadOutLength)
|
||||
end
|
||||
|
||||
-- lunghezza totale attacco
|
||||
LeadIn.dTotalLength = sqrt( LeadIn.dPerpDistance ^ 2 + LeadIn.dTangentDistance ^ 2)
|
||||
LeadOut.dTotalLength = sqrt( LeadOut.dPerpDistance ^ 2 + LeadOut.dTangentDistance ^ 2)
|
||||
|
||||
LeadInOut.dTotalLength = LeadIn.dTotalLength + LeadOut.dTotalLength
|
||||
LeadInOut.LeadIn = LeadIn
|
||||
LeadInOut.LeadOut = LeadOut
|
||||
|
||||
return LeadInOut
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function LeadInOutLib.InvertLeadInOut( LeadIn, LeadOut)
|
||||
|
||||
local dOriginalStartAddLength = LeadIn.dStartAddLength
|
||||
local dOriginalEndAddLength = LeadOut.dEndAddLength
|
||||
|
||||
LeadIn, LeadOut = LeadOut, LeadIn
|
||||
|
||||
LeadIn.dStartAddLength = dOriginalEndAddLength
|
||||
LeadOut.dEndAddLength = dOriginalStartAddLength
|
||||
LeadIn.dEndAddLength = nil
|
||||
LeadOut.dStartAddLength = nil
|
||||
|
||||
return LeadIn, LeadOut
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
return LeadInOutLib
|
||||
+11
-9
@@ -5,7 +5,7 @@
|
||||
local Logs = {}
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function Logs.WriteFeaturesLog( ProcessingsOnPart, PartInfo)
|
||||
function Logs.WriteFeaturesLog( ProcessingsOnPart, PartInfo, nReProcessCycles)
|
||||
|
||||
local nCycles = 1
|
||||
local nOffsetIndex = 0
|
||||
@@ -13,15 +13,13 @@ function Logs.WriteFeaturesLog( ProcessingsOnPart, PartInfo)
|
||||
nCycles = 2
|
||||
end
|
||||
|
||||
EgtOutLog( ' === === === === === === === === === === REPROCESS CYCLES ' .. EgtNumToString( nReProcessCycles) .. ' === === === === === === === === === === === ===')
|
||||
EgtOutLog( ' === === === === === === === === === === FEATURES STRATEGIES === === === === === === === === === === === ===')
|
||||
for nCycle = 1, nCycles do
|
||||
local nStartIndex = 1 + nOffsetIndex
|
||||
local nEndIndex = 4 + nOffsetIndex
|
||||
if nCycle == 1 then
|
||||
EgtOutLog( ' === === === === === === === === === === FEATURES STRATEGIES === === === === === === === === === === === ===')
|
||||
else
|
||||
EgtOutLog( ' === === === === === === === === === === === === === === === === === === === === === === === === === === ===')
|
||||
EgtOutLog( ' === === === === === === === === FEATURES STRATEGIES PIECE INVERTED === === === === === === === === === ===')
|
||||
end
|
||||
EgtOutLog( ' === === === === === === === === === === === === === === === === === === === === === === === === === === ===')
|
||||
EgtOutLog( ' === === === === === === === === FEATURES STRATEGIES PIECE INVERTED === === === === === === === === === ===')
|
||||
EgtOutLog( ' Feature ID | BTL POSITION | 90 ROTATION | 180 ROTATION | 270 ROTATION |')
|
||||
EgtOutLog( '----------------------------------------------------------------------------------------------------------')
|
||||
|
||||
@@ -74,7 +72,11 @@ function Logs.WriteFeaturesLog( ProcessingsOnPart, PartInfo)
|
||||
ProcessingsOnPart.Rotation[nRotLog][ProcLog].AvailableStrategies[nCountStrategies].Result.sStatus == 'Not-Applicable' then
|
||||
sStatusStrategy = 'N'
|
||||
sRating = '----'
|
||||
sIndexes = ' (C:---|Q:---|T:---)'
|
||||
if EgtStartsWith( ProcessingsOnPart.Rotation[nRotLog][ProcLog].AvailableStrategies[nCountStrategies].Result.sInfo, 'REJECTED') then
|
||||
sIndexes = ' ( --- REJECTED ---)'
|
||||
else
|
||||
sIndexes = ' (C:---|Q:---|T:---)'
|
||||
end
|
||||
else
|
||||
if ProcessingsOnPart.Rotation[nRotLog][ProcLog].AvailableStrategies[nCountStrategies].Result.sStatus == 'Completed' then
|
||||
sStatusStrategy = 'C'
|
||||
@@ -88,7 +90,7 @@ function Logs.WriteFeaturesLog( ProcessingsOnPart, PartInfo)
|
||||
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, '*', '') .. sRating .. sIndexes .. ' (' ..
|
||||
local sLogLineProc = EgtIf( nIndexBestStrategy == nCountStrategies, '*', '') .. sRating .. sIndexes .. ' (' ..
|
||||
tostring( ProcessingsOnPart.Rotation[nRotLog][ProcLog].AvailableStrategies[nCountStrategies].sStrategyId) .. ')' ..
|
||||
sStatusStrategy .. ' |'
|
||||
while string.len( sLogLineProc) <= 38 do
|
||||
|
||||
+543
-201
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,555 @@
|
||||
-- PreSimulationLib.lua by Egalware s.r.l. 2025/11/24
|
||||
-- Libreria stima collisioni per travi
|
||||
|
||||
-- Tabella per definizione modulo
|
||||
local PreSimulationLib = {}
|
||||
|
||||
-- Include
|
||||
require( 'EgtBase')
|
||||
local BeamLib = require( 'BeamLib')
|
||||
local BeamData = require( 'BeamDataNew')
|
||||
|
||||
EgtOutLog( ' PreSimulationLib started', 1)
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function GetMachineAxes()
|
||||
|
||||
local LinearAxes = {}
|
||||
local RotativeAxes = {}
|
||||
|
||||
-- si recuperano tutti gli assi, lineari e rotativi
|
||||
local AxesNames = EgtGetAllCurrAxesNames()
|
||||
for i = 1, #AxesNames do
|
||||
-- EgtGetAxisType restituisce vero se asse lineare, false se asse rotativo
|
||||
if EgtGetAxisType( AxesNames[i]) then
|
||||
LinearAxes[#LinearAxes + 1] = {}
|
||||
LinearAxes[#LinearAxes].sName = AxesNames[i]
|
||||
else
|
||||
RotativeAxes[#RotativeAxes + 1] = {}
|
||||
RotativeAxes[#RotativeAxes].sName = AxesNames[i]
|
||||
end
|
||||
end
|
||||
|
||||
return LinearAxes, RotativeAxes
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function LogOutstroke( sToolName, ptOnToolTipCenter, vtHead, OptionalParameters)
|
||||
|
||||
-- parametri opzionali
|
||||
OptionalParameters = OptionalParameters or {}
|
||||
local LinearAxesValues = OptionalParameters.LinearAxesValues
|
||||
local RotativeAxesValues = OptionalParameters.RotativeAxesValues
|
||||
|
||||
-- gruppo per geometrie temporanee
|
||||
local idTempGroup = BeamLib.GetTempGroup()
|
||||
|
||||
-- si disegnano punto e vettore
|
||||
local idPoint = EgtPoint( idTempGroup, ptOnToolTipCenter, GDB_RT.GLOB)
|
||||
local idVector = EgtVector( idTempGroup, vtHead, ptOnToolTipCenter, GDB_RT.GLOB)
|
||||
EgtSetColor( idPoint, RED())
|
||||
EgtSetColor( idVector, RED())
|
||||
|
||||
-- nome utensile
|
||||
EgtOutLog( 'Tool ' .. sToolName)
|
||||
|
||||
-- si loggano valori di punto e vettore
|
||||
EgtOutLog( ' Presimulation : OutStroke, Tip Point = ' .. tostring( ptOnToolTipCenter) .. ', id = ' .. idPoint .. ', vtHead = ' .. tostring( vtHead) .. ', id = ' .. idVector)
|
||||
|
||||
-- se disponibili, si loggano anche i valori calcolati degli assi
|
||||
if LinearAxesValues then
|
||||
EgtOutLog( ' ' .. 'Lin1' .. ' = ' .. tostring( LinearAxesValues[1]) .. ', ' .. 'Lin2' .. ' = ' .. tostring( LinearAxesValues[2]) .. ', ' .. 'Lin3' .. ' = ' .. tostring( LinearAxesValues[3]))
|
||||
end
|
||||
if RotativeAxesValues then
|
||||
EgtOutLog( ' ' .. 'Rot1' .. ' = ' .. tostring( RotativeAxesValues[1]) .. ', ' .. 'Rot2' .. ' = ' .. tostring( RotativeAxesValues[2]) .. ', ' .. 'Rot3' .. ' = ' .. tostring( RotativeAxesValues[3]))
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- costruzione trimesh del grezzo restante in testa o in coda
|
||||
local function GetRestlengthSurfTm( Part, sSide)
|
||||
|
||||
-- si costruisce il box in globale
|
||||
local b3RestLength
|
||||
if sSide == 'Head' then
|
||||
local b3PartWithOvermaterial = BeamLib.GetPartBoxWithHeadTail( Part, sSide)
|
||||
local ptStartRestLength = Point3d( Part.b3Part:getMax():getX(), Part.b3Part:getMax():getY(), Part.b3Part:getMax():getZ())
|
||||
local ptEndRestLength = Point3d( b3PartWithOvermaterial:getMax():getX(), Part.b3Part:getMin():getY(), Part.b3Part:getMin():getZ())
|
||||
b3RestLength = BBox3d( ptStartRestLength, ptEndRestLength)
|
||||
elseif sSide == 'Tail' then
|
||||
local b3PartWithOvermaterial = BeamLib.GetPartBoxWithHeadTail( Part, sSide)
|
||||
local dXMin = b3PartWithOvermaterial:getMin():getX()
|
||||
-- si evita sempre di lavorare col motore dietro la coda della barra (potrebbe succedere con barra restante molto corta): in quel caso si deve sempre separare prima
|
||||
dXMin = min( dXMin, Part.b3Part:getMin():getX() - 2000)
|
||||
local ptStartRestLength = Point3d( Part.b3Part:getMin():getX(), Part.b3Part:getMax():getY(), Part.b3Part:getMax():getZ())
|
||||
local ptEndRestLength = Point3d( dXMin, Part.b3Part:getMin():getY(), Part.b3Part:getMin():getZ())
|
||||
b3RestLength = BBox3d( ptStartRestLength, ptEndRestLength)
|
||||
-- caso non testato, non dovrebbe mai finire qui (il default che arriva da fuori è Tail)
|
||||
else
|
||||
return nil
|
||||
end
|
||||
|
||||
-- si crea la trimesh dal box
|
||||
local idRestLengthBoxTm = EgtSurfTmBBox( Part.idTempGroup, b3RestLength , false, GDB_RT.GLOB)
|
||||
|
||||
return idRestLengthBoxTm
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function PreSimulationLib.GetPointOnToolTipCenter( ptPointAtDepth, vtHead, vtNFace, vtToolOffset, Tool)
|
||||
|
||||
return ptPointAtDepth + vtToolOffset * Tool.dDiameter / 2 + vtNFace * EgtIf( AreSameVectorApprox( vtHead, vtNFace), 0, Tool.dThickness)
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- calcolo punto sull'uscita testa a partire dal punto di lavorazione o di attacco sul diametro utensile
|
||||
local function GetToolExitPoint( ptMachining, vtNEdge, vtHead, Tool, bIsDownUp)
|
||||
|
||||
local ptToolExitPoint = Point3d( ptMachining + vtNEdge * Tool.dDiameter / 2) + vtHead * EgtIf( bIsDownUp, ( Tool.dLength - Tool.dThickness), Tool.dLength)
|
||||
|
||||
return ptToolExitPoint
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- calcolo pivot in riferimento globale, dati punto sull'uscita utensile e direzioni
|
||||
local function GetGlobalPivot( ptToolExit, vtC, vtHead, vtMovePivot)
|
||||
|
||||
-- frame solidale all'utensile (lo stesso in cui vtMovePivot è definito)
|
||||
local frTool = Frame3d( ptToolExit, vtHead, vtC)
|
||||
local vtMovePivotGlob = Vector3d( vtMovePivot)
|
||||
vtMovePivotGlob:toGlob( frTool)
|
||||
local ptPivot = ptToolExit + vtMovePivotGlob
|
||||
|
||||
return ptPivot
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- restituisce i punti notevoli della lavorazioni in cui fare il controllo
|
||||
local function GetCollisionPointsToCheck( Edge, dDepthToMachine)
|
||||
|
||||
local PointsToCheck = {}
|
||||
|
||||
-- punti notevoli
|
||||
local ptStart = Edge.ptStart + Edge.vtN * ( Edge.dElevation - dDepthToMachine)
|
||||
local ptEnd = Edge.ptEnd + Edge.vtN * ( Edge.dElevation - dDepthToMachine)
|
||||
local ptMid = Point3d( ( ptStart + ptEnd) / 2)
|
||||
|
||||
-- caso ottimizzato: lato parallelo ad una direzione principale
|
||||
local bIsEdgeParallelToMainDirection =
|
||||
AreSameOrOppositeVectorApprox( Edge.vtEdge, X_AX())
|
||||
or AreSameOrOppositeVectorApprox( Edge.vtEdge, Y_AX())
|
||||
or AreSameOrOppositeVectorApprox( Edge.vtEdge, Z_AX())
|
||||
|
||||
-- aggiunta punti
|
||||
table.insert( PointsToCheck, ptStart)
|
||||
if not bIsEdgeParallelToMainDirection then
|
||||
table.insert( PointsToCheck, ptMid)
|
||||
end
|
||||
table.insert( PointsToCheck, ptEnd)
|
||||
|
||||
return PointsToCheck
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function CheckOutOfStrokePoint( ptOnToolTipCenter, vtHead, nSCC, Tool, vtAux, sBlockedAxis)
|
||||
|
||||
-- impostazione utensile
|
||||
local bOkTool = EgtSetCalcTool( Tool.sName, Tool.sHead, Tool.nExit)
|
||||
if not bOkTool then
|
||||
error( 'CheckOutOfStrokePoint : cannot set calc tool')
|
||||
end
|
||||
|
||||
-- settaggio SCC per discriminare soluzioni multiple
|
||||
EgtSetCalcSolCh( nSCC)
|
||||
|
||||
-- se presente, settaggio asse bloccato
|
||||
if sBlockedAxis and type( sBlockedAxis) == "string" then
|
||||
local BlockedAxis = EgtSplitString( sBlockedAxis, '=')
|
||||
EgtSetRotAxisBlock( BlockedAxis[1], tonumber( BlockedAxis[2]))
|
||||
end
|
||||
|
||||
-- calcolo assi rotativi
|
||||
local bOkAngles, nSolutionsAngles, RotativeAxesValues = EgtGetCalcAnglesEx( vtHead, vtAux)
|
||||
local dRotative1 = RotativeAxesValues[1]
|
||||
local dRotative2 = RotativeAxesValues[2]
|
||||
local dRotative3 = RotativeAxesValues[3]
|
||||
|
||||
if not bOkAngles then
|
||||
error( ' CheckOutOfStrokePoint : error')
|
||||
end
|
||||
|
||||
-- se nessuna soluzione dagli assi rotativi, è in extracorsa
|
||||
if nSolutionsAngles == 0 then
|
||||
|
||||
if EgtGetDebugLevel() >= 3 then
|
||||
LogOutstroke( Tool.sName, ptOnToolTipCenter, vtHead, { RotativeAxesValues = { dRotative1, dRotative2, dRotative3}})
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
-- calcolo assi lineari
|
||||
local bOkPositions, _, dLinear1, dLinear2, dLinear3 = EgtGetCalcPositions( ptOnToolTipCenter, dRotative1, dRotative2, dRotative3)
|
||||
|
||||
if not bOkPositions then
|
||||
|
||||
error( ' CheckOutOfStrokePoint : error')
|
||||
end
|
||||
|
||||
-- verifica finecorsa per assi lineari (assi rotativi già verificati)
|
||||
local bAllAxesInStroke = EgtVerifyOutstroke( dLinear1, dLinear2, dLinear3)
|
||||
|
||||
-- extracorsa
|
||||
if not bAllAxesInStroke then
|
||||
|
||||
if EgtGetDebugLevel() >= 3 then
|
||||
LogOutstroke( Tool.sName, ptOnToolTipCenter, vtHead, { LinearAxesValues = { dLinear1, dLinear2, dLinear3}, RotativeAxesValues = { dRotative1, dRotative2, dRotative3}})
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
-- se si arriva qui, il punto non è in finecorsa
|
||||
return false
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- check extracorsa da punti sul tip dell'utensile
|
||||
function PreSimulationLib.CheckOutOfStrokeFromPoints( PointsOnToolTipCenter, vtHead, nSCC, Tool, vtAux, sBlockedAxis)
|
||||
|
||||
for i = 1, #PointsOnToolTipCenter do
|
||||
|
||||
local bOutOfStroke = CheckOutOfStrokePoint( PointsOnToolTipCenter[i], vtHead, nSCC, Tool, vtAux, sBlockedAxis)
|
||||
|
||||
-- se trovato extracorsa inutile procedere con gli altri punti
|
||||
if bOutOfStroke then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
-- se arrivati qui, nessun extracorsa
|
||||
return false
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- check extracorsa da geometria
|
||||
-- TODO da considerare anche gli attacchi
|
||||
function PreSimulationLib.CheckOutOfStrokeFromGeometry( idGeometry, vtHead, nSCC, Tool, vtAux, sBlockedAxis)
|
||||
|
||||
local b3GeomMaxOffset = EgtGetBBoxGlob( idGeometry, GDB_BB.STANDARD)
|
||||
local ptBoxCenter = b3GeomMaxOffset:getCenter()
|
||||
local dBoxDimX = b3GeomMaxOffset:getDimX()
|
||||
local dBoxDimY = b3GeomMaxOffset:getDimY()
|
||||
local dBoxDimZ = b3GeomMaxOffset:getDimZ()
|
||||
|
||||
-- si controlla il finecorsa nei punti al centro delle 6 facce del box
|
||||
local PointsOnToolTipCenter = {}
|
||||
-- X+
|
||||
table.insert( PointsOnToolTipCenter, Point3d( ptBoxCenter + dBoxDimX / 2 * X_AX()))
|
||||
-- X-
|
||||
table.insert( PointsOnToolTipCenter, Point3d( ptBoxCenter - dBoxDimX / 2 * X_AX()))
|
||||
-- Y+
|
||||
table.insert( PointsOnToolTipCenter, Point3d( ptBoxCenter + dBoxDimY / 2 * Y_AX()))
|
||||
-- Y-
|
||||
table.insert( PointsOnToolTipCenter, Point3d( ptBoxCenter - dBoxDimY / 2 * Y_AX()))
|
||||
-- Z+
|
||||
table.insert( PointsOnToolTipCenter, Point3d( ptBoxCenter + dBoxDimZ / 2 * Z_AX()))
|
||||
-- Z-
|
||||
table.insert( PointsOnToolTipCenter, Point3d( ptBoxCenter - dBoxDimZ / 2 * Z_AX()))
|
||||
|
||||
local bOutOfStroke = PreSimulationLib.CheckOutOfStrokeFromPoints( PointsOnToolTipCenter, vtHead, nSCC, Tool, vtAux, sBlockedAxis)
|
||||
|
||||
return bOutOfStroke
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function MoveMachineAxesToPosition( ptOnToolTipCenter, vtHead, vtAux)
|
||||
|
||||
-- calcolo assi rotativi
|
||||
local bOkAngles, nSolutionsAngles, RotativeAxesValues = EgtGetCalcAnglesEx( vtHead, vtAux)
|
||||
local dRotative1 = RotativeAxesValues[1]
|
||||
local dRotative2 = RotativeAxesValues[2]
|
||||
local dRotative3 = RotativeAxesValues[3]
|
||||
|
||||
if not bOkAngles then
|
||||
error( ' MoveMachineAxesToPosition : error')
|
||||
end
|
||||
|
||||
-- calcolo assi lineari
|
||||
local bOkPositions, _, dLinear1, dLinear2, dLinear3 = EgtGetCalcPositions( ptOnToolTipCenter, dRotative1, dRotative2, dRotative3)
|
||||
|
||||
if not bOkPositions then
|
||||
|
||||
error( ' MoveMachineAxesToPosition : error')
|
||||
end
|
||||
|
||||
local AxesNames = EgtGetAllCurrAxesNames()
|
||||
local dTHome = EgtGetAxisHomePos( AxesNames[1])
|
||||
|
||||
-- spostamento assi in posizione (la T non si sposta perchè si sposta direttamente la testa)
|
||||
EgtSetAxisPos( AxesNames[2], dLinear2)
|
||||
EgtSetAxisPos( AxesNames[3], dLinear3)
|
||||
EgtSetAxisPos( AxesNames[4], dRotative1)
|
||||
EgtSetAxisPos( AxesNames[5], dRotative2)
|
||||
if dRotative3 then
|
||||
EgtSetAxisPos( AxesNames[6], dRotative3)
|
||||
end
|
||||
|
||||
return dLinear1 - dTHome
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function CheckCollisionPoint( sAxis, ptOnToolTipCenter, vtHead, vtAux, Part, bCannotSplitRestLength, sRestLengthSideForPreSimulation, idCheckCollisionTm, idAddedCollisionSurfTm)
|
||||
|
||||
-- spostamento assi macchina in posizione
|
||||
local dDeltaXHeadOffset = MoveMachineAxesToPosition( ptOnToolTipCenter, vtHead, vtAux)
|
||||
|
||||
-- si recuperano gli id delle geometrie dell'asse con cui controllare la collisione
|
||||
local idCollisionGroup = EgtGetFirstNameInGroup( EgtGetAxisId( sAxis), 'COLLISION')
|
||||
local idCollisionGroupOther = EgtGetFirstNameInGroup( EgtGetAxisId( sAxis), 'OTHER_COLLISION') or GDB_ID.NULL
|
||||
local CollisionGroupEntitiesId = EgtGetAllInGroup( idCollisionGroup)
|
||||
local CollisionGroupOtherEntitiesId = EgtGetAllInGroup( idCollisionGroupOther)
|
||||
-- si tengono solo gli elementi trimesh
|
||||
local CollisionSurfTmId = {}
|
||||
for i = 1, #CollisionGroupEntitiesId do
|
||||
if EgtGetType( CollisionGroupEntitiesId[i]) == GDB_TY.SRF_MESH then
|
||||
local idCollisionSurfTmCopy = EgtCopyGlob( CollisionGroupEntitiesId[i], Part.idTempGroup)
|
||||
EgtMove( idCollisionSurfTmCopy, Vector3d( dDeltaXHeadOffset, 0, 0), GDB_RT.GLOB)
|
||||
table.insert( CollisionSurfTmId, idCollisionSurfTmCopy)
|
||||
end
|
||||
end
|
||||
-- se presenti geometrie nel gruppo other si aggiungono anche quelle
|
||||
if CollisionGroupOtherEntitiesId and #CollisionGroupOtherEntitiesId > 0 then
|
||||
for i = 1, #CollisionGroupOtherEntitiesId do
|
||||
if EgtGetType( CollisionGroupOtherEntitiesId[i]) == GDB_TY.SRF_MESH then
|
||||
local idCollisionOtherSurfTmCopy = EgtCopyGlob( CollisionGroupOtherEntitiesId[i], Part.idTempGroup)
|
||||
EgtMove( idCollisionOtherSurfTmCopy, Vector3d( dDeltaXHeadOffset, 0, 0), GDB_RT.GLOB)
|
||||
table.insert( CollisionSurfTmId, idCollisionOtherSurfTmCopy)
|
||||
end
|
||||
end
|
||||
end
|
||||
-- se presente si aggiunge la geometria opzionale (es: flangia lama)
|
||||
if idAddedCollisionSurfTm then
|
||||
table.insert( CollisionSurfTmId, idAddedCollisionSurfTm)
|
||||
end
|
||||
|
||||
-- check collisione con pezzo
|
||||
local bCollisionFoundPiece = false
|
||||
if not idCheckCollisionTm then
|
||||
idCheckCollisionTm = Part.idBoxTm
|
||||
-- se testa o coda attaccate, si considerano nella superficie di collisione
|
||||
if bCannotSplitRestLength then
|
||||
local b3CheckCollision = BeamLib.GetPartBoxWithHeadTail( Part, sRestLengthSideForPreSimulation)
|
||||
idCheckCollisionTm = EgtSurfTmBBox( Part.idTempGroup, b3CheckCollision, false, GDB_RT.GLOB)
|
||||
end
|
||||
end
|
||||
for i = 1, #CollisionSurfTmId do
|
||||
bCollisionFoundPiece = EgtCDeSolidSolid( idCheckCollisionTm, CollisionSurfTmId[i], BeamData.COLL_SIC)
|
||||
if not type( bCollisionFoundPiece) == "boolean" then
|
||||
error( 'Presimulation fail')
|
||||
end
|
||||
if EgtGetDebugLevel() >= 3 and bCollisionFoundPiece then
|
||||
EgtSetColor( CollisionSurfTmId[i], RED())
|
||||
end
|
||||
if bCollisionFoundPiece then
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
-- se trovata collisione con pezzo è inutile procedere con il grezzo
|
||||
if bCollisionFoundPiece then
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
-- check collisione con grezzo restante, se con il pezzo non c'è collisione e non è un taglio di testa o coda
|
||||
local bCollisionFoundRestLength = false
|
||||
if not ( bCollisionFoundPiece or bCannotSplitRestLength) then
|
||||
local idRestLengthSurfFr = GetRestlengthSurfTm( Part, sRestLengthSideForPreSimulation)
|
||||
if idRestLengthSurfFr then
|
||||
for i = 1, #CollisionSurfTmId do
|
||||
bCollisionFoundRestLength = EgtCDeSolidSolid( idRestLengthSurfFr, CollisionSurfTmId[i], BeamData.COLL_SIC)
|
||||
if not type( bCollisionFoundRestLength) == "boolean" then
|
||||
error( 'Presimulation fail')
|
||||
end
|
||||
if EgtGetDebugLevel() >= 3 and bCollisionFoundRestLength then
|
||||
EgtSetColor( CollisionSurfTmId[i], ORANGE())
|
||||
end
|
||||
if bCollisionFoundRestLength then
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return false, bCollisionFoundRestLength
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- controllo collisione con verifica intersezione trimesh e geometrie da macchina
|
||||
local function CheckCollisionWithAxis( sAxis, MachiningParameters, OptionalParameters)
|
||||
|
||||
-- parametri obbligatori
|
||||
local Edge = MachiningParameters.Edge
|
||||
local vtNFace = MachiningParameters.vtNFace
|
||||
local vtHead = MachiningParameters.vtHead
|
||||
local Part = MachiningParameters.Part
|
||||
local Tool = MachiningParameters.Tool
|
||||
local dDepthToMachine = MachiningParameters.dDepthToMachine
|
||||
|
||||
-- parametri opzionali
|
||||
OptionalParameters = OptionalParameters or {}
|
||||
local idCheckCollisionTm = OptionalParameters.idCheckCollisionTm
|
||||
local sRestLengthSideForPreSimulation = OptionalParameters.sRestLengthSideForPreSimulation or 'Tail'
|
||||
local bCannotSplitRestLength = OptionalParameters.bCannotSplitRestLength or false
|
||||
local vtAux = OptionalParameters.vtAux
|
||||
|
||||
-- se normale faccia non parallela a direzione testa c'è qualcosa che non va
|
||||
if not AreSameOrOppositeVectorApprox( vtNFace, vtHead) then
|
||||
error( 'CheckCollisionWithAxis : invalid directions')
|
||||
end
|
||||
|
||||
-- punti notevoli della lavorazione in cui fare il check
|
||||
local PointsToCheck = OptionalParameters.PointsToCheck or GetCollisionPointsToCheck( Edge, dDepthToMachine)
|
||||
|
||||
-- punti sul tip dell'utensile, in centro
|
||||
local PointsOnToolTipCenter = {}
|
||||
for i = 1, #PointsToCheck do
|
||||
PointsOnToolTipCenter[i] = PreSimulationLib.GetPointOnToolTipCenter( PointsToCheck[i], vtHead, vtNFace, Edge.vtN, Tool)
|
||||
end
|
||||
|
||||
local bMoveAfterSplit = false
|
||||
|
||||
-- se almeno in un punto c'è collisione con il pezzo si ritorna collisione
|
||||
-- se non si trova collisione si ritorna se è necessario separare prima di effettuare la lavorazione (ossia non c'è collisione con il pezzo ma c'è con il grezzo restante)
|
||||
for i = 1, #PointsOnToolTipCenter do
|
||||
|
||||
-- se lama con flangia si aggiunge quest'ultima ai solidi di collisione, ipotizzandola grande fino al dMaxDepth + sicurezza
|
||||
local idAddedCollisionSurfTm
|
||||
if Tool.sType == 'SAW_FLAT' then
|
||||
local ptCenterFlange = PointsOnToolTipCenter[i] + vtHead * Tool.dThickness
|
||||
local frHead = Frame3d( ptCenterFlange, vtHead)
|
||||
local dExtraSafety = 2 -- valore empirico che serve nei casi molto inclinati, ci potrebbero essere casi in cui va aumentato
|
||||
local idFlangeCurve = EgtCircle( Part.idTempGroup, ORIG(), dExtraSafety + Tool.dDiameter / 2 - Tool.dMaxDepth, GDB_RT.GLOB)
|
||||
EgtTransform( idFlangeCurve, frHead, GDB_RT.GLOB)
|
||||
|
||||
-- TODO verificare se questo controllo serve
|
||||
if AreOppositeVectorApprox( vtHead, EgtCurveExtrusion( idFlangeCurve)) then
|
||||
EgtInvertCurve( idFlangeCurve)
|
||||
end
|
||||
|
||||
local vtExtrusion = 15 * vtHead
|
||||
idAddedCollisionSurfTm = EgtSurfTmByRegionExtrusion( Part.idTempGroup, idFlangeCurve, vtExtrusion, 0.05, GDB_RT.GLOB)
|
||||
end
|
||||
|
||||
local bCollisionFoundPiece, bCollisionFoundRestLength = CheckCollisionPoint( sAxis, PointsOnToolTipCenter[i], vtHead, vtAux, Part, bCannotSplitRestLength, sRestLengthSideForPreSimulation, idCheckCollisionTm, idAddedCollisionSurfTm)
|
||||
|
||||
-- se trovata collisione con pezzo è inutile controllare gli altri punti
|
||||
if bCollisionFoundPiece then
|
||||
|
||||
return true
|
||||
|
||||
-- se trovata collisione con grezzo si setta che la lavorazione è da fare dopo separazione e si prosegue con gli altri punti
|
||||
elseif bCollisionFoundRestLength then
|
||||
|
||||
bMoveAfterSplit = true
|
||||
end
|
||||
end
|
||||
|
||||
-- se si arriva qui significa che non è stata trovata alcuna collisione con pezzo
|
||||
return false, bMoveAfterSplit
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function PreSimulationLib.CheckCollision( Parameters, OptionalParameters)
|
||||
|
||||
local bCollisionFound
|
||||
local bMoveAfterSplitL3, bMoveAfterSplitR3, bMoveAfterSplitR2, bMoveAfterSplitR1
|
||||
|
||||
-- parametri obbligatori
|
||||
local Edge = Parameters.Edge
|
||||
local vtNFace = Parameters.vtNFace
|
||||
local Tool = Parameters.Tool
|
||||
|
||||
-- parametri opzionali, in parte da far transitare
|
||||
OptionalParameters = OptionalParameters or {}
|
||||
|
||||
local OptionalParametersCheckCollisionWithAxis = {}
|
||||
OptionalParametersCheckCollisionWithAxis.PointsToCheck = OptionalParameters.PointsToCheck or nil
|
||||
OptionalParametersCheckCollisionWithAxis.sRestLengthSideForPreSimulation = OptionalParameters.sRestLengthSideForPreSimulation or 'Tail'
|
||||
OptionalParametersCheckCollisionWithAxis.bCannotSplitRestLength = OptionalParameters.bCannotSplitRestLength or false
|
||||
OptionalParametersCheckCollisionWithAxis.sBlockedAxis = OptionalParameters.sBlockedAxis
|
||||
OptionalParametersCheckCollisionWithAxis.vtAux = OptionalParameters.vtAux
|
||||
OptionalParametersCheckCollisionWithAxis.idCheckCollisionTm = OptionalParameters.idCheckCollisionTm
|
||||
|
||||
local sBlockedAxis = OptionalParameters.sBlockedAxis
|
||||
local bDisableRealElevationCheck = OptionalParameters.bDisableRealElevationCheck or false
|
||||
|
||||
-- se l'elevazione reale (rispetto al pezzo + eventuale materiale in testa/coda) è maggiore del massimo materiale è sempre collisione
|
||||
-- TODO rifare con funzione
|
||||
if not bDisableRealElevationCheck then
|
||||
local Edge = Parameters.Edge
|
||||
local vtNFace = Parameters.vtNFace
|
||||
local dDepthToMachine = Parameters.dDepthToMachine
|
||||
local b3BoxForElevationCheck = BBox3d( Parameters.Part.b3Part)
|
||||
-- se è un taglio di testa o coda va aggiunto il sovramateriale
|
||||
if OptionalParametersCheckCollisionWithAxis.bCannotSplitRestLength then
|
||||
b3BoxForElevationCheck = BeamLib.GetPartBoxWithHeadTail( Parameters.Part, OptionalParametersCheckCollisionWithAxis.sRestLengthSideForPreSimulation)
|
||||
end
|
||||
-- trimesh rettangolare con un lato corrispondente al lato da lavorare e larghezza come spessore utensile
|
||||
local idTrimesh = EgtSurfTmRectangle( Parameters.Part.idTempGroup, Edge.ptStart, Edge.ptEnd, Edge.ptEnd + vtNFace * Parameters.Tool.dThickness, GDB_RT.GLOB)
|
||||
local vtNTrimesh = EgtSurfTmFacetNormVersor( idTrimesh, 0, GDB_ID.ROOT)
|
||||
-- se trimesh con normale opposta a quella del lato, si inverte (non si sa a priori che verso avrà)
|
||||
if not AreSameVectorApprox( Edge.vtN, vtNTrimesh) then
|
||||
EgtInvertSurf( idTrimesh)
|
||||
end
|
||||
local dRealElevation = EgtSurfTmFacetElevationInBBox( idTrimesh, 0, b3BoxForElevationCheck, true, GDB_ID.ROOT)
|
||||
local dRealDepthToMachine = ( dRealElevation - Parameters.Edge.dElevation + dDepthToMachine)
|
||||
if dRealDepthToMachine > Parameters.Tool.dMaxDepth + 10 * GEO.EPS_SMALL then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
-- SCC
|
||||
local nSCC = Tool.SetupInfo.GetSCC( Edge.vtN, Edge.vtEdge, vtNFace)
|
||||
|
||||
-- si settano utensile, SCC e asse bloccato per il controllo collisione
|
||||
local bOkTool = EgtSetCalcTool( Tool.sName, Tool.sHead, Tool.nExit)
|
||||
if not bOkTool then
|
||||
error( 'CheckCollisionWithAxis : cannot set calc tool')
|
||||
end
|
||||
EgtSetCalcSolCh( nSCC)
|
||||
if sBlockedAxis and type( sBlockedAxis) == "string" then
|
||||
local BlockedAxis = EgtSplitString( sBlockedAxis, '=')
|
||||
EgtSetRotAxisBlock( BlockedAxis[1], tonumber( BlockedAxis[2]))
|
||||
end
|
||||
|
||||
-- nomi degli assi con cui controllare la collisione
|
||||
local AxesNames = EgtGetAllCurrAxesNames()
|
||||
local sL3 = AxesNames[3]
|
||||
local sR3 = AxesNames[6]
|
||||
local sR2 = AxesNames[5]
|
||||
local sR1 = AxesNames[4]
|
||||
|
||||
-- ultimo asse lineare prima dei rotativi (solitamente Z) si controlla sempre
|
||||
bCollisionFound, bMoveAfterSplitL3 = CheckCollisionWithAxis( sL3, Parameters, OptionalParametersCheckCollisionWithAxis)
|
||||
|
||||
if sR3 and not bCollisionFound then
|
||||
bCollisionFound, bMoveAfterSplitR3 = CheckCollisionWithAxis( sR3, Parameters, OptionalParametersCheckCollisionWithAxis)
|
||||
end
|
||||
|
||||
if not bCollisionFound then
|
||||
bCollisionFound, bMoveAfterSplitR2 = CheckCollisionWithAxis( sR2, Parameters, OptionalParametersCheckCollisionWithAxis)
|
||||
end
|
||||
|
||||
if not bCollisionFound then
|
||||
bCollisionFound, bMoveAfterSplitR1 = CheckCollisionWithAxis( sR1, Parameters, OptionalParametersCheckCollisionWithAxis)
|
||||
end
|
||||
|
||||
local bMoveAfterSplit = bMoveAfterSplitL3 or bMoveAfterSplitR3 or bMoveAfterSplitR2 or bMoveAfterSplitR1
|
||||
|
||||
return bCollisionFound, bMoveAfterSplit
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
return PreSimulationLib
|
||||
@@ -0,0 +1,122 @@
|
||||
-- BeamLib.lua by Egalware s.r.l. 2025/11/24
|
||||
-- Libreria calcolo tempo automatismo
|
||||
|
||||
|
||||
-- Tabella per definizione modulo
|
||||
local TimeLib = {}
|
||||
|
||||
|
||||
EgtOutLog( ' TimeLib started', 1)
|
||||
|
||||
|
||||
TimeLib.__index = TimeLib
|
||||
|
||||
function TimeLib.new()
|
||||
local TimeLibInstance = setmetatable({}, TimeLib)
|
||||
TimeLibInstance.dStartTime = os.clock()
|
||||
TimeLibInstance.Measurements = {}
|
||||
return TimeLibInstance
|
||||
end
|
||||
|
||||
-- reset entire timer
|
||||
function TimeLib:start()
|
||||
self.dStartTime = os.clock()
|
||||
self.Measurements = {}
|
||||
end
|
||||
|
||||
-- start elapsed measurement for a specific name
|
||||
function TimeLib:startElapsed(sName)
|
||||
local sMeasurementName = sName or "Default"
|
||||
local dNow = os.clock()
|
||||
|
||||
if not self.Measurements[sMeasurementName] then
|
||||
self.Measurements[sMeasurementName] = {
|
||||
dStart = dNow,
|
||||
dLast = 0,
|
||||
dCumulative = 0,
|
||||
dRecent = 0,
|
||||
nCount = 0
|
||||
}
|
||||
else
|
||||
self.Measurements[sMeasurementName].dStart = dNow
|
||||
end
|
||||
end
|
||||
|
||||
-- stop elapsed measurement (increments count and updates cumulative)
|
||||
function TimeLib:stopElapsed(sName)
|
||||
local sMeasurementName = sName or "Default"
|
||||
local dNow = os.clock()
|
||||
local Measurement = self.Measurements[sMeasurementName]
|
||||
|
||||
if Measurement and Measurement.dStart then
|
||||
local dDuration = dNow - Measurement.dStart
|
||||
Measurement.dRecent = dDuration
|
||||
Measurement.dCumulative = Measurement.dCumulative + dDuration
|
||||
Measurement.dLast = dNow
|
||||
Measurement.nCount = Measurement.nCount + 1
|
||||
Measurement.dStart = nil
|
||||
else
|
||||
-- if stop called without start, initialize with zero
|
||||
self.Measurements[sMeasurementName] = {
|
||||
dStart = nil,
|
||||
dLast = dNow,
|
||||
dCumulative = 0,
|
||||
dRecent = 0,
|
||||
nCount = 0
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
-- reset elapsed for a specific measurement
|
||||
function TimeLib:resetElapsed(sName)
|
||||
local sMeasurementName = sName or "Default"
|
||||
self.Measurements[sMeasurementName] = nil
|
||||
end
|
||||
|
||||
-- return elapsed times: total, cumulative, recent, count
|
||||
function TimeLib:getElapsed(sName)
|
||||
local dTotal = os.clock() - self.dStartTime
|
||||
local sMeasurementName = sName or "Default"
|
||||
local Measurement = self.Measurements[sMeasurementName]
|
||||
|
||||
if Measurement then
|
||||
return dTotal, Measurement.dCumulative, Measurement.dRecent, Measurement.nCount
|
||||
else
|
||||
return dTotal, nil, nil, 0
|
||||
end
|
||||
end
|
||||
|
||||
-- log elapsed times for one measurement
|
||||
function TimeLib:logElapsed(sName)
|
||||
local dTotal, dCumulative, dRecent, nCount = self:getElapsed(sName)
|
||||
local sMeasurementName = sName or "Default"
|
||||
|
||||
if dCumulative then
|
||||
EgtOutLog(string.format(
|
||||
"%s(#%d): recent %.3f, cumulative %.3f, total %.3f",
|
||||
sMeasurementName, nCount, dRecent, dCumulative, dTotal))
|
||||
else
|
||||
EgtOutLog(string.format("Total %.3f (no '%s' measurement started)",
|
||||
dTotal, sMeasurementName))
|
||||
end
|
||||
end
|
||||
|
||||
-- log elapsed times for all measurements
|
||||
function TimeLib:logAllElapsed()
|
||||
local dTotal = os.clock() - self.dStartTime
|
||||
if next(self.Measurements) == nil then
|
||||
EgtOutLog(string.format("Total %.3f (no measurements started)", dTotal))
|
||||
return
|
||||
end
|
||||
|
||||
for sMeasurementName, Measurement in pairs(self.Measurements) do
|
||||
local dCumulative = Measurement.dCumulative
|
||||
local dRecent = Measurement.dRecent
|
||||
local nCount = Measurement.nCount
|
||||
EgtOutLog(string.format(
|
||||
"%s(#%d): recent %.3f, cumulative %.3f, total %.3f",
|
||||
sMeasurementName, nCount, dRecent, dCumulative, dTotal))
|
||||
end
|
||||
end
|
||||
|
||||
return TimeLib
|
||||
@@ -0,0 +1,322 @@
|
||||
// Message File EgalTech English 2026/06/23
|
||||
0=ENG
|
||||
// ----- BeamNew -----
|
||||
1000001=Part loading position
|
||||
1000002=Part loading position
|
||||
1000003=Loading position from BTL, no pre-rotation
|
||||
1000004=Loading position from BTL, no pre-rotation
|
||||
1000005=Get Best loading position from 0° and 180°
|
||||
1000006=Get Best loading position from 0° and 180°
|
||||
1000007=Get Best loading position in each piece rotation
|
||||
1000008=Get Best loading position in each piece rotation
|
||||
1000009=Allow piece inversion
|
||||
1000010=Allow piece inversion
|
||||
1000011=Enable material optimization function in nesting (part rotation disabled)
|
||||
1000012=Enable material optimization function in nesting (part rotation disabled)
|
||||
1000013=Part rotating acceptability
|
||||
1000014=Acceptability of rotating the part between machining steps
|
||||
1000015=Rotation not allowed
|
||||
1000016=Rotation not allowed
|
||||
1000017=Rotation allowed only if strictly necessary
|
||||
1000018=Rotation allowed only if strictly necessary
|
||||
1000019=Rotation easily acceptable / no constraint
|
||||
1000020=Rotation easily acceptable / no constraint
|
||||
1000021=Machining Strategy
|
||||
1000022=Machining Strategy
|
||||
1000023=Quality and time equally prioritized
|
||||
1000024=Quality and time equally prioritized
|
||||
1000025=Fastest
|
||||
1000026=Prefer fastest strategies
|
||||
1000027=High quality
|
||||
1000028=Prefer high-quality strategies
|
||||
1000029=Ordering rules
|
||||
1000030=The first complete strategy in list is the one chosen; no intelligent choosing
|
||||
1000031=Max number of reprocessing cycles
|
||||
1000032=Max number of reprocessing cycles
|
||||
1000033=Use entire blade diameter to shorten path
|
||||
1000034=Use entire blade diameter to shorten path
|
||||
1000035=Maximum length for dropped waste
|
||||
1000036=Maximum length for dropped waste
|
||||
1000037=Maximum volume for dropped waste
|
||||
1000038=Maximum volume for dropped waste
|
||||
1000039=Maximum dice dimension
|
||||
1000040=Maximum dice dimension
|
||||
1000041=Overmaterial on tenon length
|
||||
1000042=Overmaterial on tenon length
|
||||
1000043=Overmaterial on tenon width
|
||||
1000044=Overmaterial on tenon width
|
||||
1000045=Maximum number of milling passes
|
||||
1000046=Maximum number of milling passes. If more passes are required, pocketing is performed
|
||||
1000047=Use DoveTail tool to pocket
|
||||
1000048=Use DoveTail tool to pocket
|
||||
1000049=Cutting Strategy
|
||||
1000050=Cutting Strategy
|
||||
1000051=Automatic
|
||||
1000052=Automatic
|
||||
1000053=Blade only
|
||||
1000054=Blade only
|
||||
1000055=Mill only
|
||||
1000056=Mill only
|
||||
1000057=ChainSaw only
|
||||
1000058=ChainSaw only
|
||||
1000059=Available mill to machine the tenon cut surface
|
||||
1000060=Available mill to machine the tenon cut surface
|
||||
1000061=Available mill to machine the dovetail tenon
|
||||
1000062=Available mill to machine the dovetail tenon
|
||||
1000063=Max radius left on corners
|
||||
1000064=Radius-limit left by the tool at each corner of the feature
|
||||
1000065=Use Anti-Splint strategy
|
||||
1000066=The strategy will apply blade cuts on corner to avoid wood splint
|
||||
1000067=Extend after tail
|
||||
1000068=The automatism considers this length as machinable. This means you accept to damage the next piece in the bar
|
||||
1000069=Minimum approach distance on open sides
|
||||
1000070=Minimum approach distance on open sides
|
||||
1000071=Available mill to pocket the feature
|
||||
1000072=Available mill to pocket the feature
|
||||
1000073=Finish with chainsaw if needed
|
||||
1000074=Finish with chainsaw if needed
|
||||
1000075=Extend after tail
|
||||
1000076=The automatism considers this length as machinable. This means you accept to damage the next piece in the bar
|
||||
1000077=Force ripping blade
|
||||
1000078=Force the use of ripping blade, designed for cuts parallel to the grain
|
||||
1000079=Not complete with Blade radius imprint left
|
||||
1000080=If the parameter is active, the automatism considers the feature as - not complete - if the blade radius imprint is left
|
||||
1000081=Use Zig-Zag ChainSaw
|
||||
1000082=Enable the parameter to set the Zig-Zag movement on the ChainSaw machining. Deactivate it to use One-Way movement.
|
||||
1000083=Sort by segment
|
||||
1000084=Sort the machinings according to the piece-segment where the machining has inserted
|
||||
1000085=Damage next piece
|
||||
1000086=This option allows you to decide how to consider the next piece in the bar. The software calculates specifics LeadIn/out to respect the parameter. This parameter may change the machining time
|
||||
1000087=Never damage
|
||||
1000088=Never damage
|
||||
1000089=Damage only if raw
|
||||
1000090=Damage only if raw
|
||||
1000091=Can damage
|
||||
1000092=Can damage
|
||||
1000093=Use Zig-Zag ChainSaw
|
||||
1000094=Enable the parameter to set the Zig-Zag movement on the ChainSaw machining. Deactivate it to use One-Way movement.
|
||||
1000095=Extend after tail
|
||||
1000096=The automatism considers this length as machinable. This means you accept to damage the next piece in the bar
|
||||
1000097=Damage next piece
|
||||
1000098=This option allows you to decide how to consider the next piece in the bar. The software calculates specifics LeadIn/out to respect the parameter. This parameter may change the machining time
|
||||
1000099=Never damage
|
||||
1000100=Never damage
|
||||
1000101=Damage only if raw
|
||||
1000102=Damage only if raw
|
||||
1000103=Can damage
|
||||
1000104=Can damage
|
||||
1000105=Force ripping blade
|
||||
1000106=Force the use of ripping blade, designed for cuts parallel to the grain
|
||||
1000107=Extend after tail
|
||||
1000108=The automatism considers this length as machinable. This means you accept to damage the next piece in the bar
|
||||
1000109=Damage next piece
|
||||
1000110=This option allows you to decide how to consider the next piece in the bar. The software calculates specifics LeadIn/out to respect the parameter. This parameter may change the machining time
|
||||
1000111=Never damage
|
||||
1000112=Never damage
|
||||
1000113=Damage only if raw
|
||||
1000114=Damage only if raw
|
||||
1000115=Can damage
|
||||
1000116=Can damage
|
||||
1000117=Cutting strategy
|
||||
1000118=Cutting strategy
|
||||
1000119=Automatic
|
||||
1000120=Automatic
|
||||
1000121=Drop waste
|
||||
1000122=Drop waste
|
||||
1000123=Keep waste attached
|
||||
1000124=Keep waste attached
|
||||
1000125=Disable dicing
|
||||
1000126=Disable dicing
|
||||
1000127=Prioritize machining speed over quality
|
||||
1000128=Prioritize machining speed over quality
|
||||
1000129=Strip width
|
||||
1000130=In case the waste is still kept attached, this is the wigth dimension of the strip
|
||||
1000131=Clean blade radius with mill
|
||||
1000132=Clean blade radius with mill
|
||||
1000133=Milling offset from side
|
||||
1000134=Milling offset from side
|
||||
1000135=Overmaterial on tenon length
|
||||
1000136=Overmaterial on tenon length
|
||||
1000137=Overmaterial on tenon width
|
||||
1000138=Overmaterial on tenon width
|
||||
1000139=Maximum number of milling passes
|
||||
1000140=Maximum number of milling passes. If more passes are required, pocketing is performed
|
||||
1000141=Cutting Strategy
|
||||
1000142=Cutting Strategy
|
||||
1000143=Automatic
|
||||
1000144=Automatic
|
||||
1000145=Blade only
|
||||
1000146=Blade only
|
||||
1000147=Mill only
|
||||
1000148=Mill only
|
||||
1000149=ChainSaw only
|
||||
1000150=ChainSaw only
|
||||
1000151=Available mill to machine the tenon
|
||||
1000152=Available mill to machine the tenon
|
||||
1000153=Overmaterial on Mortise length
|
||||
1000154=Overmaterial on Mortise length
|
||||
1000155=Overmaterial on Mortise width
|
||||
1000156=Overmaterial on Mortise width
|
||||
1000157=Maximum number of milling passes
|
||||
1000158=Maximum number of milling passes. If more passes are required, pocketing is performed
|
||||
1000159=Use DoveTail tool in case of pocketing
|
||||
1000160=Use DoveTail tool in case of pocketing
|
||||
1000161=Add Anti-Splint
|
||||
1000162=Add Anti-Splint
|
||||
1000163=Cutting Strategy
|
||||
1000164=Cutting Strategy
|
||||
1000165=Automatic
|
||||
1000166=Automatic
|
||||
1000167=Blade only
|
||||
1000168=Blade only
|
||||
1000169=Mill only
|
||||
1000170=Mill only
|
||||
1000171=ChainSaw only
|
||||
1000172=ChainSaw only
|
||||
1000173=Available mill to machine the mortise cut surface
|
||||
1000174=Available mill to machine the mortise cut surface
|
||||
1000175=Available mill to machine the dovetail mortise
|
||||
1000176=Available mill to machine the dovetail mortise
|
||||
1000177=Overmaterial on mortise length
|
||||
1000178=Overmaterial on mortise length
|
||||
1000179=Overmaterial on mortise width
|
||||
1000180=Overmaterial on mortise width
|
||||
1000181=Cutting Strategy
|
||||
1000182=Cutting Strategy
|
||||
1000183=Automatic
|
||||
1000184=Automatic
|
||||
1000185=Blade only
|
||||
1000186=Blade only
|
||||
1000187=Mill only
|
||||
1000188=Mill only
|
||||
1000189=ChainSaw only
|
||||
1000190=ChainSaw only
|
||||
1000191=Available mill to machine the mortise cut surface
|
||||
1000192=Available mill to machine the mortise cut surface
|
||||
1000193=Available mill to machine the mortise
|
||||
1000194=Available mill to machine the mortise
|
||||
1000195=Depth Chamfer
|
||||
1000196=Depth of the V-Mill to execute chamfers on cut-edges
|
||||
1000197=Use Anti-Splint strategy
|
||||
1000198=The strategy will apply blade cuts on corner to avoid wood splint
|
||||
1000199=Available mill to machine the profile
|
||||
1000200=Available mill to machine the profile
|
||||
1000201=Antisplint with blade
|
||||
1000202=Use the blade as antisplint in case the geometry is not through
|
||||
1000203=Extend after tail
|
||||
1000204=The automatism considers this length as machinable. This means you accept to damage the next piece in the bar
|
||||
1000205=Clean radius with mill
|
||||
1000206=Clean radius with mill
|
||||
1000207=Milling offset from side
|
||||
1000208=Milling offset from side
|
||||
1000209=Damage next piece
|
||||
1000210=This option allows you to decide how to consider the next piece in the bar. The software calculates specifics LeadIn/out to respect the parameter. This parameter may change the machining time
|
||||
1000211=Never damage
|
||||
1000212=Never damage
|
||||
1000213=Damage only if raw
|
||||
1000214=Damage only if raw
|
||||
1000215=Can damage
|
||||
1000216=Can damage
|
||||
1000217=Tolerance on Diameter
|
||||
1000218=Tolerance on Diameter
|
||||
1000219=Depth PreHole
|
||||
1000220=Depth PreHole
|
||||
1000221=Drilling Mode
|
||||
1000222=Drilling Mode
|
||||
1000223=Automatic
|
||||
1000224=Automatic
|
||||
1000225=Preferred machining from one side only
|
||||
1000226=Preferred machining from one side only
|
||||
1000227=Force machining from two sides
|
||||
1000228=Force machining from two sides
|
||||
1000229=Available Drillbit list
|
||||
1000230=Available Drillbit list
|
||||
1000231=Extend after tail
|
||||
1000232=The automatism considers this length as machinable. This means you accept to damage the next piece in the bar
|
||||
1000233=Damage next piece
|
||||
1000234=This option allows you to decide how to consider the next piece in the bar. The software calculates specifics LeadIn/out to respect the parameter. This parameter may change the machining time
|
||||
1000235=Never damage
|
||||
1000236=Never damage
|
||||
1000237=Damage only if raw
|
||||
1000238=Damage only if raw
|
||||
1000239=Can damage
|
||||
1000240=Can damage
|
||||
1000241=Ridge Lap strategy
|
||||
1000242=Ridge Lap strategy
|
||||
1000243=Automatic
|
||||
1000244=Automatic
|
||||
1000245=Use blade
|
||||
1000246=Use blade
|
||||
1000247=Use mill
|
||||
1000248=Use mill
|
||||
1000249=Tolerance on Diameter
|
||||
1000250=Tolerance on Diameter
|
||||
1000251=Use mill as a drillbit
|
||||
1000252=Admit to use the mill as a drillbit
|
||||
1000253=Execute contour only
|
||||
1000254=Execute the contour anyway, even the hole is bigger than the tool diameter
|
||||
1000255=Drilling mode
|
||||
1000256=Drilling mode
|
||||
1000257=Automatic
|
||||
1000258=Automatic
|
||||
1000259=Preferred machining from one side only
|
||||
1000260=Preferred machining from one side only
|
||||
1000261=Force machining from two sides
|
||||
1000262=Force machining from two sides
|
||||
1000263=Available mill to machine drills
|
||||
1000264=Available mill to machine drills
|
||||
1000265=Machining Depth
|
||||
1000266=Machining Depth
|
||||
1000267=Available mill to machine mark and text
|
||||
1000268=Available mill to machine mark and text
|
||||
1000269=Marking Strategy
|
||||
1000270=Marking Strategy
|
||||
1000271=Automatic
|
||||
1000272=Automatic
|
||||
1000273=Pen only
|
||||
1000274=Pen only
|
||||
1000275=V-Mill only
|
||||
1000276=V-Mill only
|
||||
1000277=Depth Chamfer
|
||||
1000278=Depth of the V-Mill to execute chamfers on cut-edges
|
||||
1000279=Only Chamfer
|
||||
1000280=Execute the chamfer only, no other machining
|
||||
1000281=Overmaterial
|
||||
1000282=Overmaterial
|
||||
1000283=Max radius left on corners
|
||||
1000284=Radius-limit left by the tool at each corner of the feature
|
||||
1000285=Execute cut to remove material
|
||||
1000286=Execute cut to remove material
|
||||
1000287=Force strip
|
||||
1000288=Enable the parameter to force the software to leave a strip to sustain the piece
|
||||
1000289=Strip width
|
||||
1000290=Width of the strip in case if foreseen from the machining
|
||||
1000291=Cutting Strategy
|
||||
1000292=Cutting Strategy
|
||||
1000293=Automatic
|
||||
1000294=Automatic
|
||||
1000295=No machining
|
||||
1000296=No machining
|
||||
1000297=Blade forced
|
||||
1000298=Blade forced
|
||||
1000299=Mill forced
|
||||
1000300=Mill forced
|
||||
1000301=Available mill to machine the profile
|
||||
1000302=Available mill to machine the profile
|
||||
1000303=Depth Chamfer
|
||||
1000304=Depth of the V-Mill to execute chamfers on cut-edges
|
||||
1000305=Force to use chain saw
|
||||
1000306=Force to use chain saw
|
||||
1000307=Force to add PreCuts
|
||||
1000308=Autocam will apply a machining on the theoretical zero, to avoid collision if the theoretical piece length doesn't correspond to the real length
|
||||
1000309=Finish with mill
|
||||
1000310=Use a mill to finish the surface if split with chain saw
|
||||
1000311=Depth Chamfer
|
||||
1000312=Depth of the V-Mill to execute chamfers on cut-edges
|
||||
1000313=Force to use chain saw
|
||||
1000314=Force to use chain saw
|
||||
1000315=Force to add PreCuts
|
||||
1000316=Autocam will apply a machining on the theoretical zero, to avoid collision if the theoretical piece length doesn't correspond to the real length
|
||||
1000317=Finish with mill
|
||||
1000318=Use a mill to finish the surface if split with chain saw
|
||||
// ----- End -----
|
||||
@@ -0,0 +1,322 @@
|
||||
// File dei messaggi EgalTech Italiano 2026/06/23
|
||||
0=ITA
|
||||
// ----- BeamNew -----
|
||||
1000001=Posizione di caricamento pezzo
|
||||
1000002=Posizione di caricamento pezzo
|
||||
1000003=Posizione di caricamento da BTL, senza pre-rotazione
|
||||
1000004=Posizione di caricamento da BTL, senza pre-rotazione
|
||||
1000005=Ottieni la migliore posizione di caricamento tra 0° e 180°
|
||||
1000006=Ottieni la migliore posizione di caricamento tra 0° e 180°
|
||||
1000007=Ottieni la migliore posizione di caricamento per ogni rotazione del pezzo
|
||||
1000008=Ottieni la migliore posizione di caricamento per ogni rotazione del pezzo
|
||||
1000009=Consenti inversione pezzo
|
||||
1000010=Consenti inversione pezzo
|
||||
1000011=Abilita funzione di ottimizzazione materiale nel nesting (rotazione pezzo disabilitata)
|
||||
1000012=Abilita funzione di ottimizzazione materiale nel nesting (rotazione pezzo disabilitata)
|
||||
1000013=Accettabilità rotazione pezzo
|
||||
1000014=Accettabilità della rotazione del pezzo tra le fasi di lavorazione
|
||||
1000015=Rotazione non consentita
|
||||
1000016=Rotazione non consentita
|
||||
1000017=Rotazione consentita solo se strettamente necessaria
|
||||
1000018=Rotazione consentita solo se strettamente necessaria
|
||||
1000019=Rotazione facilmente accettabile / nessun vincolo
|
||||
1000020=Rotazione facilmente accettabile / nessun vincolo
|
||||
1000021=Strategia di lavorazione
|
||||
1000022=Strategia di lavorazione
|
||||
1000023=Qualità e tempo considerati con la stessa priorità
|
||||
1000024=Qualità e tempo considerati con la stessa priorità
|
||||
1000025=Più veloce
|
||||
1000026=Preferisci le strategie più veloci
|
||||
1000027=Alta qualità
|
||||
1000028=Preferisci le strategie ad alta qualità
|
||||
1000029=Regole di ordinamento
|
||||
1000030=La prima strategia completa in lista è quella scelta; nessuna scelta intelligente
|
||||
1000031=Numero massimo di cicli di rilavorazione
|
||||
1000032=Numero massimo di cicli di rilavorazione
|
||||
1000033=Usa l'intero diametro della lama per accorciare il percorso
|
||||
1000034=Usa l'intero diametro della lama per accorciare il percorso
|
||||
1000035=Massima lunghezza per lo scarto caduto
|
||||
1000036=Massima lunghezza per lo scarto caduto
|
||||
1000037=Massimo volume per lo scarto caduto
|
||||
1000038=Massimo volume per lo scarto caduto
|
||||
1000039=Dimensione massima dei cubetti
|
||||
1000040=Dimensione massima dei cubetti
|
||||
1000041=Sovramateriale sulla lunghezza del tenone
|
||||
1000042=Sovramateriale sulla lunghezza del tenone
|
||||
1000043=Sovramateriale sulla larghezza del tenone
|
||||
1000044=Sovramateriale sulla larghezza del tenone
|
||||
1000045=Numero massimo di passate di fresatura
|
||||
1000046=Numero massimo di passate di fresatura. Se sono necessarie più passate, viene eseguita la svuotatura
|
||||
1000047=Utilizza l'utensile a coda di rondine per svuotare
|
||||
1000048=Utilizza l'utensile a coda di rondine per svuotare
|
||||
1000049=Strategia di taglio
|
||||
1000050=Strategia di taglio
|
||||
1000051=Automatico
|
||||
1000052=Automatico
|
||||
1000053=Solo lama
|
||||
1000054=Solo lama
|
||||
1000055=Solo fresa
|
||||
1000056=Solo fresa
|
||||
1000057=Solo sega a catena
|
||||
1000058=Solo sega a catena
|
||||
1000059=Fresa disponibile per lavorare la superficie di taglio del tenone
|
||||
1000060=Fresa disponibile per lavorare la superficie di taglio del tenone
|
||||
1000061=Fresa disponibile per lavorare il tenone a coda di rondine
|
||||
1000062=Fresa disponibile per lavorare il tenone a coda di rondine
|
||||
1000063=Raggio massimo rimasto sugli spigoli
|
||||
1000064=Limite del raggio lasciato dall'utensile ad ogni spigolo della feature
|
||||
1000065=Utilizza la strategia antischeggia
|
||||
1000066=La strategia applicherà tagli di lama sullo spigolo per evitare scheggiature del legno
|
||||
1000067=Estendi dopo la coda
|
||||
1000068=L'automatismo considera questa lunghezza come lavorabile. Questo significa che si accetta di danneggiare il pezzo successivo nella barra
|
||||
1000069=Distanza minima di approccio sui lati aperti
|
||||
1000070=Distanza minima di approccio sui lati aperti
|
||||
1000071=Fresa disponibile per svuotare la feature
|
||||
1000072=Fresa disponibile per svuotare la feature
|
||||
1000073=Finisci con sega a catena se necessario
|
||||
1000074=Finisci con sega a catena se necessario
|
||||
1000075=Estendi dopo la coda
|
||||
1000076=L'automatismo considera questa lunghezza come lavorabile. Questo significa che si accetta di danneggiare il pezzo successivo nella barra
|
||||
1000077=Forza lama da scasso
|
||||
1000078=Forza l'uso della lama da scasso, progettata per tagli paralleli alla venatura
|
||||
1000079=Non completare se rimane l'impronta del raggio della lama
|
||||
1000080=Se il parametro è attivo, l'automatismo considera la feature come - non completa - se rimane l'impronta del raggio della lama
|
||||
1000081=Utilizza sega a catena in Zig-Zag
|
||||
1000082=Abilita il parametro per impostare il movimento Zig-Zag sulla lavorazione della sega a catena. Disattivarlo per utilizzare il movimento One-Way.
|
||||
1000083=Ordina per segmento
|
||||
1000084=Ordina le lavorazioni in base al segmento del pezzo in cui la lavorazione è inserita
|
||||
1000085=Danneggia il pezzo successivo
|
||||
1000086=Questa opzione consente di decidere come considerare il pezzo successivo nella barra. Il software calcola specifici ingressi/uscite per rispettare il parametro. Questo parametro può variare il tempo di lavorazione
|
||||
1000087=Non danneggiare mai
|
||||
1000088=Non danneggiare mai
|
||||
1000089=Danneggia solo se grezzo
|
||||
1000090=Danneggia solo se grezzo
|
||||
1000091=Può danneggiare
|
||||
1000092=Può danneggiare
|
||||
1000093=Utilizza sega a catena in Zig-Zag
|
||||
1000094=Abilita il parametro per impostare il movimento Zig-Zag sulla lavorazione della sega a catena. Disattivarlo per utilizzare il movimento One-Way.
|
||||
1000095=Estendi dopo la coda
|
||||
1000096=L'automatismo considera questa lunghezza come lavorabile. Questo significa che si accetta di danneggiare il pezzo successivo nella barra
|
||||
1000097=Danneggia il pezzo successivo
|
||||
1000098=Questa opzione consente di decidere come considerare il pezzo successivo nella barra. Il software calcola specifici ingressi/uscite per rispettare il parametro. Questo parametro può variare il tempo di lavorazione
|
||||
1000099=Non danneggiare mai
|
||||
1000100=Non danneggiare mai
|
||||
1000101=Danneggia solo se grezzo
|
||||
1000102=Danneggia solo se grezzo
|
||||
1000103=Può danneggiare
|
||||
1000104=Può danneggiare
|
||||
1000105=Forza lama da scasso
|
||||
1000106=Forza l'uso della lama da scasso, progettata per tagli paralleli alla venatura
|
||||
1000107=Estendi dopo la coda
|
||||
1000108=L'automatismo considera questa lunghezza come lavorabile. Questo significa che si accetta di danneggiare il pezzo successivo nella barra
|
||||
1000109=Danneggia il pezzo successivo
|
||||
1000110=Questa opzione consente di decidere come considerare il pezzo successivo nella barra. Il software calcola specifici ingressi/uscite per rispettare il parametro. Questo parametro può variare il tempo di lavorazione
|
||||
1000111=Non danneggiare mai
|
||||
1000112=Non danneggiare mai
|
||||
1000113=Danneggia solo se grezzo
|
||||
1000114=Danneggia solo se grezzo
|
||||
1000115=Può danneggiare
|
||||
1000116=Può danneggiare
|
||||
1000117=Strategia di taglio
|
||||
1000118=Strategia di taglio
|
||||
1000119=Automatico
|
||||
1000120=Automatico
|
||||
1000121=Scarica lo scarto
|
||||
1000122=Scarica lo scarto
|
||||
1000123=Mantieni lo scarto attaccato
|
||||
1000124=Mantieni lo scarto attaccato
|
||||
1000125=Disabilita la tassellatura
|
||||
1000126=Disabilita la tassellatura
|
||||
1000127=Dai priorità alla velocità di lavorazione rispetto alla qualità
|
||||
1000128=Dai priorità alla velocità di lavorazione rispetto alla qualità
|
||||
1000129=Larghezza del testimone
|
||||
1000130=Nel caso in cui lo scarto venga mantenuto attaccato, questa è la dimensione della larghezza del testimone
|
||||
1000131=Pulisci il raggio della lama con la fresa
|
||||
1000132=Pulisci il raggio della lama con la fresa
|
||||
1000133=Offset di fresatura dal lato
|
||||
1000134=Offset di fresatura dal lato
|
||||
1000135=Sovramateriale sulla lunghezza del tenone
|
||||
1000136=Sovramateriale sulla lunghezza del tenone
|
||||
1000137=Sovramateriale sulla larghezza del tenone
|
||||
1000138=Sovramateriale sulla larghezza del tenone
|
||||
1000139=Numero massimo di passate di fresatura
|
||||
1000140=Numero massimo di passate di fresatura. Se sono necessarie più passate, viene eseguita la svuotatura
|
||||
1000141=Strategia di taglio
|
||||
1000142=Strategia di taglio
|
||||
1000143=Automatico
|
||||
1000144=Automatico
|
||||
1000145=Solo lama
|
||||
1000146=Solo lama
|
||||
1000147=Solo fresa
|
||||
1000148=Solo fresa
|
||||
1000149=Solo sega a catena
|
||||
1000150=Solo sega a catena
|
||||
1000151=Fresa disponibile per lavorare il tenone
|
||||
1000152=Fresa disponibile per lavorare il tenone
|
||||
1000153=Sovramateriale sulla lunghezza della mortasa
|
||||
1000154=Sovramateriale sulla lunghezza della mortasa
|
||||
1000155=Sovramateriale sulla larghezza della mortasa
|
||||
1000156=Sovramateriale sulla larghezza della mortasa
|
||||
1000157=Numero massimo di passate di fresatura
|
||||
1000158=Numero massimo di passate di fresatura. Se sono necessarie più passate, viene eseguita la svuotatura
|
||||
1000159=Utilizza l'utensile a coda di rondine in caso di svuotatura
|
||||
1000160=Utilizza l'utensile a coda di rondine in caso di svuotatura
|
||||
1000161=Aggiungi antischeggia
|
||||
1000162=Aggiungi antischeggia
|
||||
1000163=Strategia di taglio
|
||||
1000164=Strategia di taglio
|
||||
1000165=Automatico
|
||||
1000166=Automatico
|
||||
1000167=Solo lama
|
||||
1000168=Solo lama
|
||||
1000169=Solo fresa
|
||||
1000170=Solo fresa
|
||||
1000171=Solo sega a catena
|
||||
1000172=Solo sega a catena
|
||||
1000173=Fresa disponibile per lavorare la superficie di taglio della mortasa
|
||||
1000174=Fresa disponibile per lavorare la superficie di taglio della mortasa
|
||||
1000175=Fresa disponibile per lavorare la mortasa a coda di rondine
|
||||
1000176=Fresa disponibile per lavorare la mortasa a coda di rondine
|
||||
1000177=Sovramateriale sulla lunghezza della mortasa
|
||||
1000178=Sovramateriale sulla lunghezza della mortasa
|
||||
1000179=Sovramateriale sulla larghezza della mortasa
|
||||
1000180=Sovramateriale sulla larghezza della mortasa
|
||||
1000181=Strategia di taglio
|
||||
1000182=Strategia di taglio
|
||||
1000183=Automatico
|
||||
1000184=Automatico
|
||||
1000185=Solo lama
|
||||
1000186=Solo lama
|
||||
1000187=Solo fresa
|
||||
1000188=Solo fresa
|
||||
1000189=Solo sega a catena
|
||||
1000190=Solo sega a catena
|
||||
1000191=Fresa disponibile per lavorare la superficie di taglio della mortasa
|
||||
1000192=Fresa disponibile per lavorare la superficie di taglio della mortasa
|
||||
1000193=Fresa disponibile per lavorare la mortasa
|
||||
1000194=Fresa disponibile per lavorare la mortasa
|
||||
1000195=Profondità dello smusso
|
||||
1000196=Profondità della fresa a V per eseguire smussi sugli spigoli di taglio
|
||||
1000197=Utilizza la strategia antischeggia
|
||||
1000198=La strategia applicherà tagli di lama sullo spigolo per evitare scheggiature del legno
|
||||
1000199=Fresa disponibile per lavorare il profilo
|
||||
1000200=Fresa disponibile per lavorare il profilo
|
||||
1000201=Antischeggia con lama
|
||||
1000202=Utilizza la lama come antischeggia nel caso in cui la geometria non sia passante
|
||||
1000203=Estendi dopo la coda
|
||||
1000204=L'automatismo considera questa lunghezza come lavorabile. Questo significa che si accetta di danneggiare il pezzo successivo nella barra
|
||||
1000205=Pulisci il raggio con la fresa
|
||||
1000206=Pulisci il raggio con la fresa
|
||||
1000207=Offset di fresatura dal lato
|
||||
1000208=Offset di fresatura dal lato
|
||||
1000209=Danneggia il pezzo successivo
|
||||
1000210=Questa opzione consente di decidere come considerare il pezzo successivo nella barra. Il software calcola specifici ingressi/uscite per rispettare il parametro. Questo parametro può variare il tempo di lavorazione
|
||||
1000211=Non danneggiare mai
|
||||
1000212=Non danneggiare mai
|
||||
1000213=Danneggia solo se grezzo
|
||||
1000214=Danneggia solo se grezzo
|
||||
1000215=Può danneggiare
|
||||
1000216=Può danneggiare
|
||||
1000217=Tolleranza sul diametro
|
||||
1000218=Tolleranza sul diametro
|
||||
1000219=Profondità del preforo
|
||||
1000220=Profondità del preforo
|
||||
1000221=Modalità di foratura
|
||||
1000222=Modalità di foratura
|
||||
1000223=Automatico
|
||||
1000224=Automatico
|
||||
1000225=Lavorazione preferita da un solo lato
|
||||
1000226=Lavorazione preferita da un solo lato
|
||||
1000227=Forza la lavorazione da due lati
|
||||
1000228=Forza la lavorazione da due lati
|
||||
1000229=Lista delle punte disponibili
|
||||
1000230=Lista delle punte disponibili
|
||||
1000231=Estendi dopo la coda
|
||||
1000232=L'automatismo considera questa lunghezza come lavorabile. Questo significa che si accetta di danneggiare il pezzo successivo nella barra
|
||||
1000233=Danneggia il pezzo successivo
|
||||
1000234=Questa opzione consente di decidere come considerare il pezzo successivo nella barra. Il software calcola specifici ingressi/uscite per rispettare il parametro. Questo parametro può variare il tempo di lavorazione
|
||||
1000235=Non danneggiare mai
|
||||
1000236=Non danneggiare mai
|
||||
1000237=Danneggia solo se grezzo
|
||||
1000238=Danneggia solo se grezzo
|
||||
1000239=Può danneggiare
|
||||
1000240=Può danneggiare
|
||||
1000241=Strategia del mezzolegno di colmo
|
||||
1000242=Strategia del mezzolegno di colmo
|
||||
1000243=Automatico
|
||||
1000244=Automatico
|
||||
1000245=Utilizza la lama
|
||||
1000246=Utilizza la lama
|
||||
1000247=Utilizza la fresa
|
||||
1000248=Utilizza la fresa
|
||||
1000249=Tolleranza sul diametro
|
||||
1000250=Tolleranza sul diametro
|
||||
1000251=Utilizza la fresa come una punta
|
||||
1000252=Ammetti l'uso della fresa come una punta da foratura
|
||||
1000253=Esegui solo il contorno
|
||||
1000254=Esegui comunque il contorno, anche se il foro è più grande del diametro dell'utensile
|
||||
1000255=Modalità di foratura
|
||||
1000256=Modalità di foratura
|
||||
1000257=Automatico
|
||||
1000258=Automatico
|
||||
1000259=Lavorazione preferita da un solo lato
|
||||
1000260=Lavorazione preferita da un solo lato
|
||||
1000261=Forza la lavorazione da due lati
|
||||
1000262=Forza la lavorazione da due lati
|
||||
1000263=Fresa disponibile per lavorare i fori
|
||||
1000264=Fresa disponibile per lavorare i fori
|
||||
1000265=Profondità di lavorazione
|
||||
1000266=Profondità di lavorazione
|
||||
1000267=Fresa disponibile per lavorare marcature e testi
|
||||
1000268=Fresa disponibile per lavorare marcature e testi
|
||||
1000269=Strategia di marcatura
|
||||
1000270=Strategia di marcatura
|
||||
1000271=Automatico
|
||||
1000272=Automatico
|
||||
1000273=Solo penna
|
||||
1000274=Solo penna
|
||||
1000275=Solo fresa a V
|
||||
1000276=Solo fresa a V
|
||||
1000277=Profondità dello smusso
|
||||
1000278=Profondità della fresa a V per eseguire smussi sugli spigoli di taglio
|
||||
1000279=Solo smusso
|
||||
1000280=Esegui solo lo smusso, nessuna altra lavorazione
|
||||
1000281=Sovramateriale
|
||||
1000282=Sovramateriale
|
||||
1000283=Raggio massimo rimasto sugli spigoli
|
||||
1000284=Limite del raggio lasciato dall'utensile ad ogni spigolo della feature
|
||||
1000285=Esegui il taglio per rimuovere materiale
|
||||
1000286=Esegui il taglio per rimuovere materiale
|
||||
1000287=Forza il testimone
|
||||
1000288=Abilita il parametro per forzare il software a lasciare un testimone per sostenere il pezzo
|
||||
1000289=Larghezza del testimone
|
||||
1000290=Larghezza del testimone nel caso in cui sia previsto dalla lavorazione
|
||||
1000291=Strategia di taglio
|
||||
1000292=Strategia di taglio
|
||||
1000293=Automatico
|
||||
1000294=Automatico
|
||||
1000295=Nessuna lavorazione
|
||||
1000296=Nessuna lavorazione
|
||||
1000297=Forza lama
|
||||
1000298=Forza lama
|
||||
1000299=Forza fresa
|
||||
1000300=Forza fresa
|
||||
1000301=Fresa disponibile per lavorare il profilo
|
||||
1000302=Fresa disponibile per lavorare il profilo
|
||||
1000303=Profondità dello smusso
|
||||
1000304=Profondità della fresa a V per eseguire smussi sugli spigoli di taglio
|
||||
1000305=Forza l'uso della sega a catena
|
||||
1000306=Forza l'uso della sega a catena
|
||||
1000307=Forza l'aggiunta di pretagli
|
||||
1000308=Autocam applicherà una lavorazione sullo zero teorico per evitare collisioni se la lunghezza teorica del pezzo non corrisponde alla lunghezza reale
|
||||
1000309=Finisci con la fresa
|
||||
1000310=Utilizza una fresa per rifinire la superficie se tagliata con la sega a catena
|
||||
1000311=Profondità dello smusso
|
||||
1000312=Profondità della fresa a V per eseguire smussi sugli spigoli di taglio
|
||||
1000313=Forza l'uso della sega a catena
|
||||
1000314=Forza l'uso della sega a catena
|
||||
1000315=Forza l'aggiunta di pretagli
|
||||
1000316=Autocam applicherà una lavorazione sullo zero teorico per evitare collisioni se la lunghezza teorica del pezzo non corrisponde alla lunghezza reale
|
||||
1000317=Finisci con la fresa
|
||||
1000318=Utilizza una fresa per rifinire la superficie se tagliata con la sega a catena
|
||||
// ----- End -----
|
||||
@@ -0,0 +1,322 @@
|
||||
// Message File EgalTech Dutch 2026/06/23
|
||||
0=NLD
|
||||
// ----- BeamNew -----
|
||||
1000001=Ladevolgorde van het onderdeel
|
||||
1000002=Ladevolgorde van het onderdeel
|
||||
1000003=Laadpositie vanaf BTL, geen voorrotatie
|
||||
1000004=Laadpositie vanaf BTL, geen voorrotatie
|
||||
1000005=Bepaal de beste laadpositie uit 0° en 180°
|
||||
1000006=Bepaal de beste laadpositie uit 0° en 180°
|
||||
1000007=Bepaal de beste laadpositie bij elke rotatie van het onderdeel
|
||||
1000008=Bepaal de beste laadpositie bij elke rotatie van het onderdeel
|
||||
1000009=Omkeren van het onderdeel toestaan
|
||||
1000010=Omkeren van het onderdeel toestaan
|
||||
1000011=Materiaaloptimalisatie in nesting inschakelen (rotatie van onderdeel uitgeschakeld)
|
||||
1000012=Materiaaloptimalisatie in nesting inschakelen (rotatie van onderdeel uitgeschakeld)
|
||||
1000013=Acceptatie van rotatie van het onderdeel
|
||||
1000014=Acceptatie van het roteren van het onderdeel tussen bewerkingsstappen
|
||||
1000015=Rotatie niet toegestaan
|
||||
1000016=Rotatie niet toegestaan
|
||||
1000017=Rotatie alleen toegestaan indien strikt noodzakelijk
|
||||
1000018=Rotatie alleen toegestaan indien strikt noodzakelijk
|
||||
1000019=Rotatie eenvoudig acceptabel / geen beperking
|
||||
1000020=Rotatie eenvoudig acceptabel / geen beperking
|
||||
1000021=Bewerkingsstrategie
|
||||
1000022=Bewerkingsstrategie
|
||||
1000023=Kwaliteit en tijd hebben gelijke prioriteit
|
||||
1000024=Kwaliteit en tijd hebben gelijke prioriteit
|
||||
1000025=Snelste
|
||||
1000026=Voorkeur geven aan de snelste strategieën
|
||||
1000027=Hoge kwaliteit
|
||||
1000028=Voorkeur geven aan hoogwaardige strategieën
|
||||
1000029=Ordeningsregels
|
||||
1000030=De eerste complete strategie in de lijst wordt gekozen; geen intelligente selectie
|
||||
1000031=Max. aantal herbewerkingscycli
|
||||
1000032=Max. aantal herbewerkingscycli
|
||||
1000033=Gebruik de volledige bladdiameter om het pad te verkorten
|
||||
1000034=Gebruik de volledige bladdiameter om het pad te verkorten
|
||||
1000035=Maximale lengte voor vallend afval
|
||||
1000036=Maximale lengte voor vallend afval
|
||||
1000037=Maximaal volume voor vallend afval
|
||||
1000038=Maximaal volume voor vallend afval
|
||||
1000039=Maximale afmeting van de blokjes
|
||||
1000040=Maximale afmeting van de blokjes
|
||||
1000041=Overmaat op de penlengte
|
||||
1000042=Overmaat op de penlengte
|
||||
1000043=Overmaat op de penbreedte
|
||||
1000044=Overmaat op de penbreedte
|
||||
1000045=Maximaal aantal freesgangen
|
||||
1000046=Maximaal aantal freesgangen. Als er meer gangen vereist zijn, wordt er uitkameren/uitfrezen uitgevoerd
|
||||
1000047=Zwaluwstaartgereedschap gebruiken voor uitfrezen
|
||||
1000048=Zwaluwstaartgereedschap gebruiken voor uitfrezen
|
||||
1000049=Snijstrategie
|
||||
1000050=Snijstrategie
|
||||
1000051=Automatisch
|
||||
1000052=Automatisch
|
||||
1000053=Alleen zaagblad
|
||||
1000054=Alleen zaagblad
|
||||
1000055=Alleen frees
|
||||
1000056=Alleen frees
|
||||
1000057=Alleen kettingzaag
|
||||
1000058=Alleen kettingzaag
|
||||
1000059=Beschikbare frees om het snijvlak van de pen te bewerken
|
||||
1000060=Beschikbare frees om het snijvlak van the pen te bewerken
|
||||
1000061=Beschikbare frees om de zwaluwstaartpen te bewerken
|
||||
1000062=Beschikbare frees om de zwaluwstaartpen te bewerken
|
||||
1000063=Maximale hoekradius achtergelaten op hoeken
|
||||
1000064=Radiuslimiet achtergelaten door het gereedschap bij elke binnenhoek van de feature
|
||||
1000065=Anti-splinterstrategie gebruiken
|
||||
1000066=De strategie past zaagsneden toe op de hoek om houtsplinters te voorkomen
|
||||
1000067=Verlengen na de staart
|
||||
1000068=Het automatisme beschouwt deze lengte als bewerkbaar. Dit betekent dat u accepteert dat het volgende onderdeel in de balk beschadigd kan raken
|
||||
1000069=Minimale benaderingsafstand op open zijden
|
||||
1000070=Minimale benaderingsafstand op open zijden
|
||||
1000071=Beschikbare frees voor het uitdiepen/uitfrezen van de feature
|
||||
1000072=Beschikbare frees voor het uitdiepen/uitfrezen van de feature
|
||||
1000073=Afwerken met kettingzaag indien nodig
|
||||
1000074=Afwerken met kettingzaag indien nodig
|
||||
1000075=Verlengen na de staart
|
||||
1000076=Het automatisme beschouwt deze lengte als bewerkbaar. Dit betekent dat u accepteert dat het volgende onderdeel in de balk beschadigd kan raken
|
||||
1000077=Schulpzaagblad forceren
|
||||
1000078=Forceer het gebruik van een schulpzaagblad, ontworpen voor zaagsneden parallel aan de houtnerf
|
||||
1000079=Niet voltooien als de uitloopradius van het zaagblad achterblijft
|
||||
1000080=Als de parameter actief is, beschouwt het automatisme de feature als - niet voltooid - als de uitloopradius van het zaagblad achterblijft
|
||||
1000081=Kettingzaag in zig-zag-modus gebruiken
|
||||
1000082=Schakel deze parameter in om de zig-zag-beweging voor de kettingzaagbewerking in te stellen. Deactiveer deze om de one-way-beweging te gebruiken.
|
||||
1000083=Sorteren per segment
|
||||
1000084=Sorteer de bewerkingen op basis van het onderdeelsegment waarin de bewerking is ingevoegd
|
||||
1000085=Volgend onderdeel beschadigen
|
||||
1000086=Met deze optie kunt u beslissen hoe u het volgende onderdeel in de balk beschouwt. De software berekent specifieke in- en uitlopen om de parameter te respecteren. Deze parameter kan de bewerkingstijd beïnvloeden
|
||||
1000087=Nooit beschadigen
|
||||
1000088=Nooit beschadigen
|
||||
1000089=Alleen beschadigen als het onbewerkt hout betreft
|
||||
1000090=Alleen beschadigen als het onbewerkt hout betreft
|
||||
1000091=Mag beschadigen
|
||||
1000092=Mag beschadigen
|
||||
1000093=Kettingzaag in zig-zag-modus gebruiken
|
||||
1000094=Schakel deze parameter in om de zig-zag-beweging voor de kettingzaagbewerking in te stellen. Deactiveer deze om de one-way-beweging te gebruiken.
|
||||
1000095=Verlengen na de staart
|
||||
1000096=Het automatisme beschouwt deze lengte als bewerkbaar. Dit betekent dat u accepteert dat het volgende onderdeel in de balk beschadigd kan raken
|
||||
1000097=Volgend onderdeel beschadigen
|
||||
1000098=Met deze optie kunt u beslissen hoe u het volgende onderdeel in de balk beschouwt. De software berekent specifieke in- en uitlopen om de parameter te respecteren. Deze parameter kan de bewerkingstijd beïnvloeden
|
||||
1000099=Nooit beschadigen
|
||||
1000100=Nooit beschadigen
|
||||
1000101=Alleen beschadigen als het onbewerkt hout betreft
|
||||
1000102=Alleen beschadigen als het onbewerkt hout betreft
|
||||
1000103=Mag beschadigen
|
||||
1000104=Mag beschadigen
|
||||
1000105=Schulpzaagblad forceren
|
||||
1000106=Forceer het gebruik van een schulpzaagblad, ontworpen voor zaagsneden parallel aan de houtnerf
|
||||
1000107=Verlengen na de staart
|
||||
1000108=Het automatisme beschouwt deze lengte als bewerkbaar. Dit betekent dat u accepteert dat het volgende onderdeel in de balk beschadigd kan raken
|
||||
1000109=Volgend onderdeel beschadigen
|
||||
1000110=Met deze optie kunt u beslissen hoe u het volgende onderdeel in de balk beschouwt. De software berekent specifieke in- en uitlopen om de parameter te respecteren. Deze parameter kan de bewerkingstijd beïnvloeden
|
||||
1000111=Nooit beschadigen
|
||||
1000112=Nooit beschadigen
|
||||
1000113=Alleen beschadigen als het onbewerkt hout betreft
|
||||
1000114=Alleen beschadigen als het onbewerkt hout betreft
|
||||
1000115=Mag beschadigen
|
||||
1000116=Mag beschadigen
|
||||
1000117=Zaagstrategie
|
||||
1000118=Zaagstrategie
|
||||
1000119=Automatisch
|
||||
1000120=Automatisch
|
||||
1000121=Kortafval afvoeren
|
||||
1000122=Kortafval afvoeren
|
||||
1000123=Kortafval verbonden houden
|
||||
1000124=Kortafval verbonden houden
|
||||
1000125=Opdelen in blokjes uitschakelen
|
||||
1000126=Opdelen in blokjes uitschakelen
|
||||
1000127=Prioriteit geven aan bewerkingssnelheid boven kwaliteit
|
||||
1000128=Prioriteit geven aan bewerkingssnelheid boven kwaliteit
|
||||
1000129=Breedte van de verbindingsstrip
|
||||
1000130=In het geval dat het afval vastgehecht blijft, is dit de breedteafmeting van de verbindingsstrip
|
||||
1000131=Uitloopradius van zaagblad reinigen met frees
|
||||
1000132=Uitloopradius van zaagblad reinigen met frees
|
||||
1000133=Freesoffset vanaf de zijde
|
||||
1000134=Freesoffset vanaf de zijde
|
||||
1000135=Overmaat op de penlengte
|
||||
1000136=Overmaat op de penlengte
|
||||
1000137=Overmaat op de penbreedte
|
||||
1000138=Overmaat op de penbreedte
|
||||
1000139=Maximum aantal freesgangen
|
||||
1000140=Maximum aantal freesgangen. Als er meer gangen vereist zijn, wordt er uitfrezen/uitkameren uitgevoerd
|
||||
1000141=Snijstrategie
|
||||
1000142=Snijstrategie
|
||||
1000143=Automatisch
|
||||
1000144=Automatisch
|
||||
1000145=Alleen zaagblad
|
||||
1000146=Alleen zaagblad
|
||||
1000147=Alleen frees
|
||||
1000148=Alleen frees
|
||||
1000149=Alleen kettingzaag
|
||||
1000150=Alleen kettingzaag
|
||||
1000151=Beschikbare frees om de pen te bewerken
|
||||
1000152=Beschikbare frees om de pen te bewerken
|
||||
1000153=Overmaat op de gatlengte
|
||||
1000154=Overmaat op de gatlengte
|
||||
1000155=Overmaat op de gatbreedte
|
||||
1000156=Overmaat op de gatbreedte
|
||||
1000157=Maximum aantal freesgangen
|
||||
1000158=Maximum aantal freesgangen. Als er meer gangen vereist zijn, wordt er uitfrezen/uitkameren uitgevoerd
|
||||
1000159=Zwaluwstaartgereedschap gebruiken bij uitfrezen
|
||||
1000160=Zwaluwstaartgereedschap gebruiken bij uitfrezen
|
||||
1000161=Anti-splintertoevoeging toepassen
|
||||
1000162=Anti-splintertoevoeging toepassen
|
||||
1000163=Snijstrategie
|
||||
1000164=Snijstrategie
|
||||
1000165=Automatisch
|
||||
1000166=Automatisch
|
||||
1000167=Alleen zaagblad
|
||||
1000168=Alleen zaagblad
|
||||
1000169=Alleen frees
|
||||
1000170=Alleen frees
|
||||
1000171=Alleen kettingzaag
|
||||
1000172=Alleen kettingzaag
|
||||
1000173=Beschikbare frees om het snijvlak van het gat te bewerken
|
||||
1000174=Beschikbare frees om het snijvlak van het gat te bewerken
|
||||
1000175=Beschikbare frees om het zwaluwstaartgat te frezen
|
||||
1000176=Beschikbare frees om het zwaluwstaartgat te frezen
|
||||
1000177=Overmaat op de gatlengte
|
||||
1000178=Overmaat op de gatlengte
|
||||
1000179=Overmaat op de gatbreedte
|
||||
1000180=Overmaat op de gatbreedte
|
||||
1000181=Snijstrategie
|
||||
1000182=Snijstrategie
|
||||
1000183=Automatisch
|
||||
1000184=Automatisch
|
||||
1000185=Alleen zaagblad
|
||||
1000186=Alleen zaagblad
|
||||
1000187=Alleen frees
|
||||
1000188=Alleen frees
|
||||
1000189=Alleen kettingzaag
|
||||
1000190=Alleen kettingzaag
|
||||
1000191=Beschikbare frees om het snijvlak van het gat te bewerken
|
||||
1000192=Beschikbare frees om het snijvlak van het gat te bewerken
|
||||
1000193=Beschikbare frees om het gat te frezen
|
||||
1000194=Beschikbare frees om het gat te frezen
|
||||
1000195=Diepte van de afschuining
|
||||
1000196=Diepte van de V-frees om afschuiningen op snijkanten uit te voeren
|
||||
1000197=Anti-splinterstrategie gebruiken
|
||||
1000198=De strategie past zaagsneden toe op de hoek om houtsplinters te voorkomen
|
||||
1000199=Beschikbare frees om het profiel te bewerken
|
||||
1000200=Beschikbare frees om het profiel te bewerken
|
||||
1000201=Anti-splinterfunctie via zaagblad
|
||||
1000202=Gebruik het zaagblad als anti-splintervoorziening indien de geometrie niet doorgaand is
|
||||
1000203=Verlengen na de staart
|
||||
1000204=Het automatisme beschouwt deze lengte als bewerkbaar. Dit betekent dat u accepteert dat het volgende onderdeel in de balk beschadigd kan raken
|
||||
1000205=Uitloopradius reinigen met frees
|
||||
1000206=Uitloopradius reinigen met frees
|
||||
1000207=Freesoffset vanaf de zijde
|
||||
1000208=Freesoffset vanaf de zijde
|
||||
1000209=Volgend onderdeel beschadigen
|
||||
1000210=Met deze optie kunt u beslissen hoe u het volgende onderdeel in de balk beschouwt. De software berekent specifieke in- en uitlopen om de parameter te respecteren. Deze parameter kan de bewerkingstijd beïnvloeden
|
||||
1000211=Nooit beschadigen
|
||||
1000212=Nooit beschadigen
|
||||
1000213=Alleen beschadigen als het onbewerkt hout betreft
|
||||
1000214=Alleen beschadigen als het onbewerkt hout betreft
|
||||
1000215=Mag beschadigen
|
||||
1000216=Mag beschadigen
|
||||
1000217=Tolerantie op diameter
|
||||
1000218=Tolerantie op diameter
|
||||
1000219=Diepte van het voorgat
|
||||
1000220=Diepte van het voorgat
|
||||
1000221=Boormodus
|
||||
1000222=Boormodus
|
||||
1000223=Automatisch
|
||||
1000224=Automatisch
|
||||
1000225=Voorkeursbewerking vanaf slechts één zijde
|
||||
1000226=Voorkeursbewerking vanaf slechts één zijde
|
||||
1000227=Bewerking vanaf beide zijden forceren
|
||||
1000228=Bewerking vanaf beide zijden forceren
|
||||
1000229=Lijst met beschikbare boren
|
||||
1000230=Lijst met beschikbare boren
|
||||
1000231=Verlengen na de staart
|
||||
1000232=Het automatisme beschouwt deze lengte als bewerkbaar. Dit betekent dat u accepteert dat het volgende onderdeel in de balk beschadigd kan raken
|
||||
1000233=Volgend onderdeel beschadigen
|
||||
1000234=Met deze optie kunt u beslissen hoe u het volgende onderdeel in de balk beschouwt. De software berekent specifieke in- en uitlopen om de parameter te respecteren. Deze parameter kan de bewerkingstijd beïnvloeden
|
||||
1000235=Nooit beschadigen
|
||||
1000236=Nooit beschadigen
|
||||
1000237=Alleen beschadigen als het onbewerkt hout betreft
|
||||
1000238=Alleen beschadigen als het onbewerkt hout betreft
|
||||
1000239=Mag beschadigen
|
||||
1000240=Mag beschadigen
|
||||
1000241=Borstverjonging zaag- en freesstrategie
|
||||
1000242=Borstverjonging zaag- en freesstrategie
|
||||
1000243=Automatisch
|
||||
1000244=Automatisch
|
||||
1000245=Zaagblad gebruiken
|
||||
1000246=Zaagblad gebruiken
|
||||
1000247=Frees gebruiken
|
||||
1000248=Frees gebruiken
|
||||
1000249=Tolerantie op diameter
|
||||
1000250=Tolerantie op diameter
|
||||
1000251=Frees gebruiken als boor
|
||||
1000252=Toestaan dat de frees axiaal als boor wordt ingezet
|
||||
1000253=Alleen contour frezen
|
||||
1000254=Contour sowieso frezen, zelfs wanneer het gat groter is dan de gereedschapsdiameter
|
||||
1000255=Boormodus via frezen
|
||||
1000256=Boormodus via frezen
|
||||
1000257=Automatisch
|
||||
1000258=Automatisch
|
||||
1000259=Voorkeursbewerking vanaf slechts één zijde
|
||||
1000260=Voorkeursbewerking vanaf slechts één zijde
|
||||
1000261=Bewerking vanaf beide zijden forceren
|
||||
1000262=Bewerking vanaf beide zijden forceren
|
||||
1000263=Beschikbare frezen om gaten te bewerken
|
||||
1000264=Beschikbare frezen om gaten te bewerken
|
||||
1000265=Bewerkingsdiepte
|
||||
1000266=Bewerkingsdiepte
|
||||
1000267=Beschikbare frees voor markeringen en tekst
|
||||
1000268=Beschikbare frees voor markeringen en tekst
|
||||
1000269=Markeerstrategie
|
||||
1000270=Markeerstrategie
|
||||
1000271=Automatisch
|
||||
1000272=Automatisch
|
||||
1000273=Alleen markeerpen
|
||||
1000274=Alleen markeerpen
|
||||
1000275=Alleen V-frees
|
||||
1000276=Alleen V-frees
|
||||
1000277=Diepte van de afschuining
|
||||
1000278=Diepte van de V-frees om afschuiningen op snijkanten uit te voeren
|
||||
1000279=Alleen afschuining frezen
|
||||
1000280=Alleen de afschuining uitvoeren, geen andere bewerkingen
|
||||
1000281=Overmaat
|
||||
1000282=Overmaat
|
||||
1000283=Maximale hoekradius achtergelaten op hoeken
|
||||
1000284=Radiuslimiet achtergelaten door het gereedschap bij elke binnenhoek van de feature
|
||||
1000285=Zaagsnede uitvoeren om materiaal te verwijderen
|
||||
1000286=Zaagsnede uitvoeren om materiaal te verwijderen
|
||||
1000287=Snoei- / steunstrip forceren
|
||||
1000288=Activeer deze parameter om de software te verplichten een reststrip te laten staan om het onderdeel te ondersteunen
|
||||
1000289=Breedte van de steunstrip
|
||||
1000290=Breedte van de strip in het geval dat deze door de bewerking is voorzien
|
||||
1000291=Kopsnijstrategie
|
||||
1000292=Kopsnijstrategie
|
||||
1000293=Automatisch
|
||||
1000294=Automatisch
|
||||
1000295=Geen bewerking
|
||||
1000296=Geen bewerking
|
||||
1000297=Zaagblad geforceerd
|
||||
1000298=Zaagblad geforceerd
|
||||
1000299=Frees geforceerd
|
||||
1000300=Frees geforceerd
|
||||
1000301=Beschikbare frees om het kops profiel te bewerken
|
||||
1000302=Beschikbare frees om het kops profiel te bewerken
|
||||
1000303=Diepte van de afschuining
|
||||
1000304=Diepte van de V-frees om afschuiningen op snijkanten uit te voeren
|
||||
1000305=Gebruik van kettingzaag forceren
|
||||
1000306=Gebruik van kettingzaag forceren
|
||||
1000307=PreCuts (Voorsneden) forceren
|
||||
1000308=Autocam past een bewerking toe op het theoretische nulpunt om botsingen te voorkomen als de theoretische lengte niet overeenkomt met de werkelijke lengte
|
||||
1000309=Afwerken met frees
|
||||
1000310=Gebruik een frees om het oppervlak na te bewerken als dit met de kettingzaag is gespleten
|
||||
1000311=Diepte van de afschuining
|
||||
1000312=Diepte van de V-frees om afschuiningen op snijkanten uit te voeren
|
||||
1000313=Gebruik van kettingzaag forceren
|
||||
1000314=Gebruik van kettingzaag forceren
|
||||
1000315=PreCuts (Voorsneden) forceren
|
||||
1000316=Autocam past een bewerking toe op het theoretische nulpunt om botsingen te voorkomen als de theoretische lengte niet overeenkomt met de werkelijke lengte
|
||||
1000317=Afwerken met frees
|
||||
1000318=Gebruik een frees om het oppervlak na te bewerken als dit met de kettingzaag is gespleten
|
||||
// ----- End -----
|
||||
+623
-406
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,556 @@
|
||||
-- BeamNestProcess.lua by Egaltech s.r.l. 2023/01/15
|
||||
-- Gestione nesting automatico travi
|
||||
-- 2022/10/05 Piccole modifiche per far funzionare correttamente i compilati.
|
||||
-- 2022/10/06 Corretto bug che moltiplicava i pezzi se erano presenti più grezzi della stessa sezione.
|
||||
-- 2023/01/15 Piccole correzioni.
|
||||
|
||||
-- Intestazioni
|
||||
require( 'EgtBase')
|
||||
_ENV = EgtProtectGlobal()
|
||||
EgtEnableDebug( false)
|
||||
|
||||
-- Per test
|
||||
--NEST = {}
|
||||
--NEST.FILE = 'c:\\TechnoEssetre7\\EgtData\\Prods\\0010\\Bar_10_1.btl'
|
||||
--NEST.MACHINE = 'Essetre-90480019_MW'
|
||||
--NEST.FLAG = 3
|
||||
|
||||
local sLog = ' +++ BeamNestProcess : ' .. NEST.FILE
|
||||
EgtOutLog( sLog)
|
||||
|
||||
-- flag per abilitare statistiche in log
|
||||
local bLogStat = false
|
||||
|
||||
-- Cancello file di log specifico
|
||||
local sLogFile = EgtChangePathExtension( NEST.FILE, '.txt')
|
||||
EgtEraseFile( sLogFile)
|
||||
|
||||
-- Funzioni per scrittura su file di log specifico
|
||||
local function WriteErrToLogFile( nErr, sMsg, nRot, nCutId, nTaskId)
|
||||
local hFile = io.open( sLogFile, 'a')
|
||||
hFile:write( 'ERR=' .. tostring( nErr) .. '\n')
|
||||
hFile:write( sMsg .. '\n')
|
||||
hFile:write( 'ROT=' .. tostring( nRot or 0) .. '\n')
|
||||
hFile:write( 'CUTID=' .. tostring( nCutId or 0) .. '\n')
|
||||
hFile:write( 'TASKID=' .. tostring( nTaskId or 0) .. '\n')
|
||||
hFile:close()
|
||||
end
|
||||
|
||||
local function WriteTimeToLogFile( dTime)
|
||||
local hFile = io.open( sLogFile, 'a')
|
||||
hFile:write( 'TIME=' .. EgtNumToString( dTime) .. '\n')
|
||||
hFile:close()
|
||||
end
|
||||
|
||||
-- Funzione per gestire visualizzazione dopo errore
|
||||
local function PostErrView( nErr, sMsg)
|
||||
if nErr ~= 0 and ( NEST.FLAG == 1 or NEST.FLAG == 2 or NEST.FLAG == 5) then
|
||||
EgtSetView( SCE_VD.ISO_SW, false)
|
||||
EgtZoom( SCE_ZM.ALL)
|
||||
EgtOutBox( sMsg, 'BatchProcess (err=' .. tostring( nErr) .. ')', 'ERRORS')
|
||||
end
|
||||
end
|
||||
|
||||
-- Funzione per gestire visualizzazione dopo warning
|
||||
local function PostWarnView( nWarn, sMsg)
|
||||
if nWarn ~= 0 and ( NEST.FLAG == 1 or NEST.FLAG == 2 or NEST.FLAG == 5) then
|
||||
EgtSetView( SCE_VD.ISO_SW, false)
|
||||
EgtZoom( SCE_ZM.ALL)
|
||||
EgtOutBox( sMsg, 'BatchProcess (wrn=' .. tostring( nWarn) .. ')', 'WARNINGS')
|
||||
end
|
||||
end
|
||||
|
||||
-- Funzione per aggiornare dati ausiliari
|
||||
local function UpdateAuxData( sAuxFile)
|
||||
local bModif = false
|
||||
-- Se definito LOAD90, aggiorno
|
||||
local sLoad90 = EgtGetStringFromIni( 'AuxData', 'LOAD90', '', sAuxFile)
|
||||
if sLoad90 ~= '' then
|
||||
local BtlInfoId = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'BtlInfo') or GDB_ID.NULL
|
||||
EgtSetInfo( BtlInfoId, 'LOAD90', sLoad90)
|
||||
bModif = true
|
||||
end
|
||||
return bModif
|
||||
end
|
||||
|
||||
local function PartsToFill( Parts)
|
||||
local nToFill = 0
|
||||
for i = 1, #Parts do
|
||||
if Parts[i].Cnt > 0 then
|
||||
nToFill = nToFill + Parts[i].Cnt
|
||||
end
|
||||
end
|
||||
return nToFill
|
||||
end
|
||||
|
||||
local function ExecMaximumFilling( Raw, Parts)
|
||||
-- Inizializzo maximum filler
|
||||
EgtMaxFillerStart()
|
||||
-- Inserisco i pezzi
|
||||
for i = 1, #Parts do
|
||||
EgtMaxFillerAddPart( i, Parts[i].Len, Parts[i].DispLen or Parts[i].Len, Parts[i].Cnt or 1)
|
||||
end
|
||||
-- Eseguo l'ottimizzazione
|
||||
EgtMaxFillerCompute( Raw.LenToFill, Raw.StartGap, Raw.MidGap, Raw.EndGap, Raw.SortType)
|
||||
-- Recupero i risultati
|
||||
local nFilledParts, nDiffParts, dTotFillRatio = EgtMaxFillerGetResults()
|
||||
local OneRes = {}
|
||||
for i = 0, nDiffParts - 1 do
|
||||
local nPartId, nCount = EgtMaxFillerGetOneResult( i)
|
||||
table.insert( OneRes, { Id=nPartId, Count=nCount})
|
||||
end
|
||||
--return { FilledParts=nFilledParts, DiffParts=nDiffParts, FillRatio=dTotFillRatio, Time=dTime, Data=OneRes}
|
||||
return { FilledParts=nFilledParts, DiffParts=nDiffParts, FillRatio=dTotFillRatio, Data=OneRes}
|
||||
end
|
||||
|
||||
-- Funzione per trovare nome MachGroup
|
||||
local function NewMachGroupName()
|
||||
local nMachGroupId = EgtGetFirstMachGroup()
|
||||
if not nMachGroupId then return 1 end
|
||||
local nMaxMachGroup = 0
|
||||
while nMachGroupId do
|
||||
sMachGroupName = EgtGetMachGroupName(nMachGroupId)
|
||||
local nMachGroupName = tonumber(sMachGroupName)
|
||||
if nMachGroupName > nMaxMachGroup then
|
||||
nMaxMachGroup = nMachGroupName
|
||||
end
|
||||
nMachGroupId = EgtGetNextMachGroup(nMachGroupId)
|
||||
end
|
||||
return nMaxMachGroup + 1
|
||||
end
|
||||
|
||||
local function TotRawCount(Raws)
|
||||
local nTotRaws = 0
|
||||
for RawIndex = 1, #Raws do
|
||||
nTotRaws = nTotRaws + Raws[RawIndex].Count
|
||||
end
|
||||
return nTotRaws
|
||||
end
|
||||
|
||||
local function TotPartLen(Parts)
|
||||
local nTotPartLen = 0
|
||||
for PartIndex = 1, #Parts do
|
||||
nTotPartLen = nTotPartLen + ( Parts[PartIndex].Len * Parts[PartIndex].Cnt)
|
||||
end
|
||||
return nTotPartLen
|
||||
end
|
||||
|
||||
-- Imposto direttorio libreria specializzata per Travi
|
||||
EgtAddToPackagePath( NEST.BASEDIR .. '\\LuaLibs\\?.lua')
|
||||
|
||||
-- recupero cartella macchine
|
||||
local sIniFilePath = EgtGetIniFile()
|
||||
local MachineDirPath = EgtGetStringFromIni( 'Mach', 'MachinesDir', '', sIniFilePath)
|
||||
-- Verifico che tutte le macchine siano abilitate per la lavorazione delle Travi
|
||||
for MachineIndex = 1, #NEST.MACHINELIST do
|
||||
local sMachDir = MachineDirPath .. '\\' .. NEST.MACHINELIST[MachineIndex]
|
||||
if not EgtExistsFile( sMachDir .. '\\Beam\\BeamData.lua') then
|
||||
NEST.ERR = 12
|
||||
NEST.MSG = 'Error not configured for beam machine : ' .. sMachine
|
||||
WriteErrToLogFile( NEST.ERR, NEST.MSG)
|
||||
PostErrView( NEST.ERR, NEST.MSG)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
---- Imposto la macchina corrente e verifico sia abilitata per la lavorazione delle Travi
|
||||
--EgtSetCurrMachine( NEST.MACHINE)
|
||||
--local sMachDir = EgtGetCurrMachineDir()
|
||||
--if not EgtExistsFile( sMachDir .. '\\Beam\\BeamData.lua') then
|
||||
-- NEST.ERR = 12
|
||||
-- NEST.MSG = 'Error not configured for beam machine : ' .. sMachine
|
||||
-- WriteErrToLogFile( NEST.ERR, NEST.MSG)
|
||||
-- PostErrView( NEST.ERR, NEST.MSG)
|
||||
-- return
|
||||
--end
|
||||
|
||||
---- Elimino direttori altre macchine e imposto direttorio macchina corrente per ricerca librerie
|
||||
--EgtRemoveBaseMachineDirFromPackagePath()
|
||||
--EgtAddToPackagePath( sMachDir .. '\\Beam\\?.lua')
|
||||
|
||||
-- Inizializzo contatori errori e avvisi
|
||||
local nErrCnt = 0
|
||||
local nWarnCnt = 0
|
||||
|
||||
-- Grezzi
|
||||
local Raws = {}
|
||||
for nRawIndex = 1, #RAWLIST do
|
||||
local Raw = RAWLIST[nRawIndex]
|
||||
table.insert( Raws, {LenToFill = Raw.Len, StartGap = NEST.STARTOFFSET, MidGap = NEST.OFFSET, EndGap = 0, SortType = -1, Count = Raw.Qty})
|
||||
end
|
||||
-- cerco il grezzo con la lunghezza maggiore, epurata dello start gap
|
||||
local maxRawLenToFillNoStartGap = 0
|
||||
for RawIndex = 1, #Raws do
|
||||
if Raws[RawIndex].Count > 0 then
|
||||
maxRawLenToFillNoStartGap = max( maxRawLenToFillNoStartGap, Raws[RawIndex].LenToFill - Raws[RawIndex].StartGap)
|
||||
end
|
||||
end
|
||||
|
||||
-- Pezzi
|
||||
local Parts = {}
|
||||
-- ciclo su pezzi per aggiungerli al nesting
|
||||
local dTotLen = 0
|
||||
for nPartId, nCount in pairs( PARTLIST) do
|
||||
-- recupero lunghezza pezzo
|
||||
local Len = EgtGetInfo( nPartId, "L", 'd')
|
||||
local DispLen = EgtIf( Len <= 1000, 2000, 0) --EgtIf( Len <= 2000, max( 2000, 6000 - Len), 0)
|
||||
-- aggiungo il pezzo solo se ci sta nel grezzo più lungo a disposizione
|
||||
if Len < maxRawLenToFillNoStartGap then
|
||||
for nCntIndex = 1 , nCount do
|
||||
table.insert( Parts, {Id = nPartId, Len = Len, DispLen = DispLen, Cnt = 1})
|
||||
dTotLen = dTotLen + Len
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- lunghezza totale pezzi
|
||||
local dTotPartLen = TotPartLen( Parts)
|
||||
-- calcolo media delle barre necessarie
|
||||
local NeededRawsForType = {}
|
||||
for RawIndex = 1, #Raws do
|
||||
NeededRawsForType[RawIndex] = min( ceil( dTotPartLen / Raws[RawIndex].LenToFill), Raws[RawIndex].Count)
|
||||
end
|
||||
local RawQtySum = 0
|
||||
for NeededRawIndex = 1, #NeededRawsForType do
|
||||
RawQtySum = RawQtySum + NeededRawsForType[NeededRawIndex]
|
||||
end
|
||||
local MediumRawQty = ceil( RawQtySum / #NeededRawsForType)
|
||||
if MediumRawQty > 1 then
|
||||
MediumRawQty = MediumRawQty - 1
|
||||
end
|
||||
|
||||
-- lista dei risultati
|
||||
local ResultList = {}
|
||||
local BestResult = nil
|
||||
local BestResultIndex = nil
|
||||
-- riordino lista pezzi per lunghezza
|
||||
table.sort( Parts, function( B1, B2) return B1.Len < B2.Len end)
|
||||
|
||||
local function NestSolutionByIndex( Index)
|
||||
|
||||
-- creo copia lista raw
|
||||
local TempRaws = {}
|
||||
for TempRawIndex = 1, #Raws do
|
||||
table.insert(TempRaws, {LenToFill = Raws[TempRawIndex].LenToFill, StartGap = Raws[TempRawIndex].StartGap, MidGap = Raws[TempRawIndex].MidGap, EndGap = Raws[TempRawIndex].EndGap, SortType = Raws[TempRawIndex].SortType, Count = Raws[TempRawIndex].Count})
|
||||
end
|
||||
|
||||
-- recupero pezzi corti
|
||||
local ShortList = {}
|
||||
local LongList = {}
|
||||
|
||||
for PartIndex = 1, #Parts do
|
||||
if PartIndex <= Index then
|
||||
table.insert( ShortList, Parts[PartIndex])
|
||||
else
|
||||
table.insert( LongList, Parts[PartIndex])
|
||||
end
|
||||
Parts[PartIndex].Cnt = 1
|
||||
end
|
||||
-- numero di pezzi piccoli per barra
|
||||
local ShortCount = Index
|
||||
local ShortForRaw = floor( ShortCount / MediumRawQty)
|
||||
local ExtraShortForRaw = 0
|
||||
if MediumRawQty > 0 then
|
||||
ExtraShortForRaw = fmod( ShortCount, MediumRawQty)
|
||||
end
|
||||
-- creo lista pezzi corti singoli
|
||||
local SingleShortList = {}
|
||||
for ShortIndex = 1, #ShortList do
|
||||
for ShortCount = 1, ShortList[ShortIndex].Cnt do
|
||||
table.insert( SingleShortList, {Id = ShortList[ShortIndex].Id, Len = ShortList[ShortIndex].Len, DispLen = ShortList[ShortIndex].DispLen, Cnt = 1})
|
||||
end
|
||||
end
|
||||
-- li divido per le barre previste
|
||||
local RawsShortList = {}
|
||||
local RawIndex = 0
|
||||
local ShortRawIndex = 0
|
||||
for ShortIndex = 1, #SingleShortList do
|
||||
if ShortRawIndex > 0 then
|
||||
table.insert( RawsShortList[RawIndex], SingleShortList[ShortIndex])
|
||||
ShortRawIndex = ShortRawIndex - 1
|
||||
else
|
||||
table.insert( RawsShortList, {SingleShortList[ShortIndex]})
|
||||
RawIndex = RawIndex + 1
|
||||
ShortRawIndex = ShortForRaw + EgtIf( RawIndex <= ExtraShortForRaw, 1, 0) - 1
|
||||
end
|
||||
end
|
||||
|
||||
-- Ciclo fino ad esaurimento pezzi o barre
|
||||
local dTotPartInRawLen = 0
|
||||
local nRawTot = 0
|
||||
local dRawTotLen = 0
|
||||
local dTime = 0
|
||||
local nCycle = 1
|
||||
local CurrResult = {}
|
||||
while TotRawCount( TempRaws) > 0 and PartsToFill( Parts) > 0 do
|
||||
|
||||
-- creo lista con pezzi lunghi e pezzi corti di questo Cycle
|
||||
local PartsToNest = {}
|
||||
for PartIndex = 1, #LongList do
|
||||
table.insert( PartsToNest, LongList[PartIndex])
|
||||
end
|
||||
for CycleIndex = 1, #RawsShortList do
|
||||
if CycleIndex <= nCycle then
|
||||
for PartIndex = 1, #RawsShortList[CycleIndex] do
|
||||
table.insert( PartsToNest, RawsShortList[CycleIndex][PartIndex])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- se non ci sono pezzi da nestare, esco
|
||||
if PartsToFill( PartsToNest) <= 0 then
|
||||
break
|
||||
end
|
||||
-- Eseguo ottimizzazione per ogni lunghezza di barra
|
||||
local Results = {}
|
||||
for RawIndex = 1, #TempRaws do
|
||||
if TempRaws[RawIndex].Count > 0 then
|
||||
Results[RawIndex] = ExecMaximumFilling( TempRaws[RawIndex], PartsToNest)
|
||||
else
|
||||
Results[RawIndex] = { FillRatio = 0.001, LenToFill = 1000, DiffParts = 0}
|
||||
end
|
||||
end
|
||||
-- verifico quale e' quella con meno scarto
|
||||
local nMinWasteRawIndex = GDB_ID.NULL
|
||||
local dMinWaste = 100000
|
||||
for ResultIndex = 1, #Results do
|
||||
if Results[ResultIndex] then
|
||||
local dWaste = (1 - Results[ResultIndex].FillRatio) * TempRaws[ResultIndex].LenToFill
|
||||
if Results[ResultIndex].DiffParts > 0 and dWaste < dMinWaste then
|
||||
dMinWaste = dWaste
|
||||
nMinWasteRawIndex = ResultIndex
|
||||
end
|
||||
end
|
||||
end
|
||||
-- verifico se ci sono pezzi
|
||||
if nMinWasteRawIndex > 0 and Results[nMinWasteRawIndex] and Results[nMinWasteRawIndex].DiffParts > 0 then
|
||||
-- riporto barra e pezzi nel risultato corrente
|
||||
local CurrBar = { BarLen = TempRaws[nMinWasteRawIndex].LenToFill, Parts = {}}
|
||||
local CurrX = TempRaws[nMinWasteRawIndex].StartGap
|
||||
local nInfoIndex = 1
|
||||
for i = 1, Results[nMinWasteRawIndex].DiffParts do
|
||||
local PartIndex = Results[nMinWasteRawIndex].Data[i].Id
|
||||
local PartId = PartsToNest[PartIndex].Id
|
||||
local dLen = PartsToNest[PartIndex].Len
|
||||
for j = 1, Results[nMinWasteRawIndex].Data[i].Count do
|
||||
-- creo pezzo copia
|
||||
CurrPart = { Index = nInfoIndex, PartId = PartId, PosX = CurrX}
|
||||
table.insert( CurrBar.Parts, CurrPart)
|
||||
CurrX = CurrX + dLen + TempRaws[nMinWasteRawIndex].MidGap
|
||||
nInfoIndex = nInfoIndex + 1
|
||||
end
|
||||
end
|
||||
table.insert( CurrResult, CurrBar)
|
||||
dTotPartInRawLen = dTotPartInRawLen + ( Results[nMinWasteRawIndex].FillRatio * TempRaws[nMinWasteRawIndex].LenToFill)
|
||||
nRawTot = nRawTot + 1
|
||||
dRawTotLen = dRawTotLen + TempRaws[nMinWasteRawIndex].LenToFill
|
||||
-- Aggiorno per prossima iterazione
|
||||
TempRaws[nMinWasteRawIndex].Count = TempRaws[nMinWasteRawIndex].Count - 1
|
||||
for i = 1, Results[nMinWasteRawIndex].DiffParts do
|
||||
local PartId = Results[nMinWasteRawIndex].Data[i].Id
|
||||
PartsToNest[PartId].Cnt = PartsToNest[PartId].Cnt - Results[nMinWasteRawIndex].Data[i].Count
|
||||
end
|
||||
else
|
||||
-- se non sono riuscito ad inserire alcun pezzo esco dal ciclo perche' non ci sono pezzi inseribili
|
||||
break
|
||||
end
|
||||
nCycle = nCycle + 1
|
||||
end
|
||||
-- riporto risultato in lista
|
||||
ResultList[Index] = dTotPartInRawLen
|
||||
if not BestResult or not BestResultIndex or
|
||||
( dTotPartInRawLen > ResultList[BestResultIndex] + 0.02 or ( abs( dTotPartInRawLen - ResultList[BestResultIndex]) < 0.02 and dRawTotLen < BestResult.RawTotLen - 0.02)) then
|
||||
BestResult = CurrResult
|
||||
BestResult.RawTotLen = dRawTotLen
|
||||
BestResultIndex = Index
|
||||
end
|
||||
end
|
||||
|
||||
local CycleCount = 0
|
||||
|
||||
local MinTime = 10 + pow( 3, ceil( log10( #Parts)) - 1)
|
||||
if bLogStat then EgtOutLog('MinTime: ' .. MinTime ) end
|
||||
local MaxTime = 30 + pow( 7, ceil( log10( #Parts)) - 1)
|
||||
if bLogStat then EgtOutLog('MaxTime: ' .. MaxTime ) end
|
||||
local TargetRatio = 0.98
|
||||
local dTargetRatioLen = TargetRatio * dTotLen
|
||||
if bLogStat then EgtOutLog('TargetRatioLen: ' .. dTargetRatioLen ) end
|
||||
local CurrTime = 0
|
||||
|
||||
local function NestSolutionFromSP( StartingPoint, OscillationStep)
|
||||
-- ciclo sulle possibilita' da un punto di origine con uno step fisso
|
||||
local CurrResultIndex = StartingPoint
|
||||
NestSolutionByIndex( StartingPoint)
|
||||
if OscillationStep == 0 then return end
|
||||
local CycleIndex = 1
|
||||
local nOutOfBoundary = 0
|
||||
while nOutOfBoundary ~= 3 do
|
||||
CurrTime = EgtStopCounter() / 1000
|
||||
if bLogStat then EgtOutLog('CurrTime: ' .. CurrTime ) end
|
||||
if bLogStat then EgtOutLog('BestRatio: ' .. dTotLen / BestResult.RawTotLen ) end
|
||||
-- se e' passato il tempo massimo, o e' passato il tempo minimo, ha inserito tutti i pezzi e la percentuale di utilizzo del materiale e' maggiore della soglia
|
||||
if CurrTime > MaxTime or ( CurrTime > MinTime and ResultList[BestResultIndex] > dTotLen - 0.1 and ( dTotLen / BestResult.RawTotLen ) >= TargetRatio) then
|
||||
if bLogStat then EgtOutLog('Brake') end
|
||||
break
|
||||
end
|
||||
local bCurrOutOfBoundary = false
|
||||
if CurrResultIndex < 0 then
|
||||
bCurrOutOfBoundary = true
|
||||
if nOutOfBoundary == 2 then
|
||||
nOutOfBoundary = 3
|
||||
else
|
||||
nOutOfBoundary = 1
|
||||
end
|
||||
end
|
||||
if CurrResultIndex > #Parts then
|
||||
bCurrOutOfBoundary = true
|
||||
if nOutOfBoundary == 1 then
|
||||
nOutOfBoundary = 3
|
||||
else
|
||||
nOutOfBoundary = 2
|
||||
end
|
||||
end
|
||||
if not bCurrOutOfBoundary and not ResultList[CurrResultIndex] then
|
||||
NestSolutionByIndex( CurrResultIndex)
|
||||
if bLogStat then EgtOutLog('CurrResultIndex: ' .. CurrResultIndex ) end
|
||||
if bLogStat then EgtOutLog('Result: ' .. ResultList[CurrResultIndex]) end
|
||||
CycleCount = CycleCount + 1
|
||||
end
|
||||
CurrResultIndex = StartingPoint + EgtIf( CycleIndex % 2 == 0, (CycleIndex / 2) * OscillationStep, -( ( CycleIndex + 1) / 2) * OscillationStep )
|
||||
CycleIndex = CycleIndex + 1
|
||||
end
|
||||
end
|
||||
|
||||
-- lancio calcolo
|
||||
EgtStartCounter()
|
||||
local StartingResult = floor( #Parts * 0.3)
|
||||
if bLogStat then EgtOutLog('StartingResult: ' .. StartingResult ) end
|
||||
--local Step = floor( #Parts / 10) * floor( log10( #Parts))
|
||||
local nDividendo = pow( 10, floor( log10( #Parts)) - 1)
|
||||
nDividendo = EgtIf( nDividendo ~= 1, nDividendo, 10)
|
||||
local Step = floor( #Parts / nDividendo) * floor( log10( #Parts))
|
||||
if bLogStat then EgtOutLog('Step: ' .. Step ) end
|
||||
NestSolutionFromSP( StartingResult, Step)
|
||||
if Step > 1 then
|
||||
NestSolutionFromSP( StartingResult, 1)
|
||||
end
|
||||
|
||||
-- se esiste un MachGorup precedente
|
||||
local nPreviousNestIndex = 0
|
||||
local nLastMachGroupId = EgtGetLastMachGroup()
|
||||
if nLastMachGroupId then
|
||||
nPreviousNestIndex = EgtGetInfo( nLastMachGroupId, "NestIndex", 'i')
|
||||
end
|
||||
for nMachineIndex = 1, #NEST.MACHINELIST do
|
||||
local sMachineName = NEST.MACHINELIST[nMachineIndex]
|
||||
-- imposto macchina corrente
|
||||
EgtSetCurrMachine( sMachineName)
|
||||
-- elimino direttori altre macchine e imposto direttorio macchina corrente per ricerca librerie
|
||||
local sMachDir = EgtGetCurrMachineDir()
|
||||
EgtRemoveBaseMachineDirFromPackagePath()
|
||||
EgtAddToPackagePath( sMachDir .. '\\Beam\\?.lua')
|
||||
-- creo gruppi di lavorazione per risultato
|
||||
for nMachGroupIndex = 1, #BestResult do
|
||||
local CurrMachGroup = BestResult[nMachGroupIndex]
|
||||
-- creo gruppo di lavorazione
|
||||
local MachGroupName = NewMachGroupName()
|
||||
nMachGroup = EgtAddMachGroup( MachGroupName)
|
||||
EgtSetInfo( nMachGroup, "NestIndex", nPreviousNestIndex + nMachGroupIndex)
|
||||
EgtSetInfo( nMachGroup, "BARLEN", CurrMachGroup.BarLen)
|
||||
EgtSetInfo( nMachGroup, "MATERIAL", NEST.MATERIAL)
|
||||
EgtSetInfo( nMachGroup, "AUTONEST", 1)
|
||||
-- scrivo dati per variabili P di comunicazione con la macchina in gruppo di lavorazione
|
||||
EgtSetInfo( nMachGroup, "PRODID", NEST.PRODID)
|
||||
EgtSetInfo( nMachGroup, "PATTID", nMachGroup)
|
||||
-- Disegno i pezzi
|
||||
for i = 1, #CurrMachGroup.Parts do
|
||||
local CurrPart = CurrMachGroup.Parts[ i]
|
||||
-- creo pezzo copia
|
||||
local nPartDuploId = EgtDuploNew( CurrPart.PartId)
|
||||
EgtSetInfo( nMachGroup, "PART" .. CurrPart.Index, nPartDuploId .. "," .. CurrPart.PosX)
|
||||
-- se esiste lista etichette
|
||||
local sTagList = ''
|
||||
if #NEST.MACHINELIST == 1 then
|
||||
sTagList = EgtGetInfo( CurrPart.PartId, 'LuxTagList')
|
||||
else
|
||||
sTagList = EgtGetInfo( CurrPart.PartId, 'LuxTagList' .. nMachineIndex)
|
||||
if not sTagList or #sTagList <= 0 then
|
||||
sTagList = EgtGetInfo( CurrPart.PartId, 'LuxTagList')
|
||||
EgtSetInfo( CurrPart.PartId, 'LuxTagList' .. nMachineIndex, sTagList)
|
||||
end
|
||||
end
|
||||
if sTagList and #sTagList then
|
||||
-- elimino eventuali liste etichette da duplo
|
||||
EgtRemoveInfo( nPartDuploId, 'LuxTagList')
|
||||
for nRemoveTagMachineIndex = 1, nMachineIndex - 1 do
|
||||
EgtRemoveInfo( nPartDuploId, 'LuxTagList' .. nRemoveTagMachineIndex)
|
||||
end
|
||||
-- recupero liste etichette usate e non
|
||||
local TagTypeList = EgtSplitString( sTagList, ';')
|
||||
local UnusedTagList = {}
|
||||
local UsedTagList = {}
|
||||
if #TagTypeList == 1 then
|
||||
UnusedTagList = EgtSplitString( sTagList, ',')
|
||||
else
|
||||
if TagTypeList[1] and #TagTypeList[1] > 0 then
|
||||
UnusedTagList = EgtSplitString( TagTypeList[1], ',')
|
||||
end
|
||||
if TagTypeList[2] and #TagTypeList[2] > 0 then
|
||||
UsedTagList = EgtSplitString( TagTypeList[2], ',')
|
||||
end
|
||||
end
|
||||
local nAssignedTagIndex = #UnusedTagList
|
||||
local sAssignedTag = UnusedTagList[nAssignedTagIndex]
|
||||
-- creo stringa per info etichette aggiornata
|
||||
local sNewTagList = ''
|
||||
for nUnusedTagIndex = 1, nAssignedTagIndex - 1 do
|
||||
sNewTagList = sNewTagList .. UnusedTagList[nUnusedTagIndex] .. EgtIf( nUnusedTagIndex < nAssignedTagIndex - 1, ',', '')
|
||||
end
|
||||
sNewTagList = sNewTagList .. ';' .. UnusedTagList[nAssignedTagIndex] .. EgtIf( #UsedTagList > 0, ',', '')
|
||||
for nUsedTagIndex = 1, #UsedTagList do
|
||||
sNewTagList = sNewTagList .. UsedTagList[nUsedTagIndex] .. EgtIf( nUsedTagIndex < #UsedTagList, ',', '')
|
||||
end
|
||||
-- assegno etichetta a nuovo duplo
|
||||
EgtSetInfo( nPartDuploId, 'LuxTag', sAssignedTag)
|
||||
if #NEST.MACHINELIST == 1 then
|
||||
EgtSetInfo( CurrPart.PartId, 'LuxTagList', sNewTagList)
|
||||
else
|
||||
EgtSetInfo( CurrPart.PartId, 'LuxTagList' .. nMachineIndex, sNewTagList)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
EgtResetCurrMachGroup()
|
||||
end
|
||||
|
||||
-- creo grezzi per ogni gruppo di lavorazione
|
||||
local nRawCnt = 0
|
||||
local nRawTot = ResultList[BestResultIndex]
|
||||
_G.BEAM = {}
|
||||
BEAM.FILE = NEST.FILE
|
||||
--BEAM.MACHINE = NEST.MACHINE
|
||||
BEAM.FLAG = 6 -- CREATE_PANEL
|
||||
BEAM.BASEDIR = NEST.BASEDIR
|
||||
nMachGroup = EgtGetFirstMachGroup()
|
||||
while nMachGroup do
|
||||
local nNextMachGroup = EgtGetNextMachGroup( nMachGroup)
|
||||
EgtSetCurrMachGroup( nMachGroup)
|
||||
if EgtGetInfo( nMachGroup, "AUTONEST",'i') == 1 then
|
||||
EgtRemoveInfo( nMachGroup, "AUTONEST")
|
||||
EgtSetInfo( nMachGroup, "UPDATEUI", 1)
|
||||
local bOk, sErr = pcall( dofile, BEAM.BASEDIR .. "\\BatchProcessNew.lua")
|
||||
if not bOk then
|
||||
EgtOutLog( 'Error in BatchProcessNew.lua call (' .. ( sErr or '') ..')')
|
||||
end
|
||||
nRawCnt = nRawCnt + 1
|
||||
-- aggiorno interfaccia
|
||||
EgtProcessEvents( 200 + ( nRawCnt / nRawTot * 100), 0)
|
||||
end
|
||||
nMachGroup = nNextMachGroup
|
||||
end
|
||||
|
||||
EgtResetCurrMachGroup()
|
||||
|
||||
NEST.ERR = 0
|
||||
|
||||
EgtOutLog( ' +++ BeamNestProcess completed')
|
||||
@@ -0,0 +1,477 @@
|
||||
-- BeamNestProcess.lua by Egaltech s.r.l. 2023/01/15
|
||||
-- Gestione nesting automatico travi
|
||||
-- 2022/10/05 Piccole modifiche per far funzionare correttamente i compilati.
|
||||
-- 2022/10/06 Corretto bug che moltiplicava i pezzi se erano presenti più grezzi della stessa sezione.
|
||||
-- 2023/01/15 Piccole correzioni.
|
||||
|
||||
-- Intestazioni
|
||||
require( 'EgtBase')
|
||||
_ENV = EgtProtectGlobal()
|
||||
EgtEnableDebug( false)
|
||||
|
||||
-- Per test
|
||||
--NEST = {}
|
||||
--NEST.FILE = 'c:\\TechnoEssetre7\\EgtData\\Prods\\0010\\Bar_10_1.btl'
|
||||
--NEST.MACHINE = 'Essetre-90480019_MW'
|
||||
--NEST.FLAG = 3
|
||||
|
||||
local sLog = ' +++ BeamNestProcess : ' .. NEST.FILE .. ', ' .. NEST.MACHINE .. ', ' .. LEN[1]
|
||||
EgtOutLog( sLog)
|
||||
|
||||
-- flag per abilitare statistiche in log
|
||||
local bLogStat = false
|
||||
|
||||
-- Cancello file di log specifico
|
||||
local sLogFile = EgtChangePathExtension( NEST.FILE, '.txt')
|
||||
EgtEraseFile( sLogFile)
|
||||
|
||||
-- Funzioni per scrittura su file di log specifico
|
||||
local function WriteErrToLogFile( nErr, sMsg, nRot, nCutId, nTaskId)
|
||||
local hFile = io.open( sLogFile, 'a')
|
||||
hFile:write( 'ERR=' .. tostring( nErr) .. '\n')
|
||||
hFile:write( sMsg .. '\n')
|
||||
hFile:write( 'ROT=' .. tostring( nRot or 0) .. '\n')
|
||||
hFile:write( 'CUTID=' .. tostring( nCutId or 0) .. '\n')
|
||||
hFile:write( 'TASKID=' .. tostring( nTaskId or 0) .. '\n')
|
||||
hFile:close()
|
||||
end
|
||||
|
||||
local function WriteTimeToLogFile( dTime)
|
||||
local hFile = io.open( sLogFile, 'a')
|
||||
hFile:write( 'TIME=' .. EgtNumToString( dTime) .. '\n')
|
||||
hFile:close()
|
||||
end
|
||||
|
||||
-- Funzione per gestire visualizzazione dopo errore
|
||||
local function PostErrView( nErr, sMsg)
|
||||
if nErr ~= 0 and ( NEST.FLAG == 1 or NEST.FLAG == 2 or NEST.FLAG == 5) then
|
||||
EgtSetView( SCE_VD.ISO_SW, false)
|
||||
EgtZoom( SCE_ZM.ALL)
|
||||
EgtOutBox( sMsg, 'BatchProcess (err=' .. tostring( nErr) .. ')', 'ERRORS')
|
||||
end
|
||||
end
|
||||
|
||||
-- Funzione per gestire visualizzazione dopo warning
|
||||
local function PostWarnView( nWarn, sMsg)
|
||||
if nWarn ~= 0 and ( NEST.FLAG == 1 or NEST.FLAG == 2 or NEST.FLAG == 5) then
|
||||
EgtSetView( SCE_VD.ISO_SW, false)
|
||||
EgtZoom( SCE_ZM.ALL)
|
||||
EgtOutBox( sMsg, 'BatchProcess (wrn=' .. tostring( nWarn) .. ')', 'WARNINGS')
|
||||
end
|
||||
end
|
||||
|
||||
-- Funzione per aggiornare dati ausiliari
|
||||
local function UpdateAuxData( sAuxFile)
|
||||
local bModif = false
|
||||
-- Se definito LOAD90, aggiorno
|
||||
local sLoad90 = EgtGetStringFromIni( 'AuxData', 'LOAD90', '', sAuxFile)
|
||||
if sLoad90 ~= '' then
|
||||
local BtlInfoId = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'BtlInfo') or GDB_ID.NULL
|
||||
EgtSetInfo( BtlInfoId, 'LOAD90', sLoad90)
|
||||
bModif = true
|
||||
end
|
||||
return bModif
|
||||
end
|
||||
|
||||
local function PartsToFill( Parts)
|
||||
local nToFill = 0
|
||||
for i = 1, #Parts do
|
||||
if Parts[i].Cnt > 0 then
|
||||
nToFill = nToFill + Parts[i].Cnt
|
||||
end
|
||||
end
|
||||
return nToFill
|
||||
end
|
||||
|
||||
local function ExecMaximumFilling( Raw, Parts)
|
||||
-- Inizializzo maximum filler
|
||||
EgtMaxFillerStart()
|
||||
-- Inserisco i pezzi
|
||||
for i = 1, #Parts do
|
||||
EgtMaxFillerAddPart( i, Parts[i].Len, Parts[i].DispLen or Parts[i].Len, Parts[i].Cnt or 1)
|
||||
end
|
||||
-- Eseguo l'ottimizzazione
|
||||
EgtMaxFillerCompute( Raw.LenToFill, Raw.StartGap, Raw.MidGap, Raw.EndGap, Raw.SortType)
|
||||
-- Recupero i risultati
|
||||
local nFilledParts, nDiffParts, dTotFillRatio = EgtMaxFillerGetResults()
|
||||
local OneRes = {}
|
||||
for i = 0, nDiffParts - 1 do
|
||||
local nPartId, nCount = EgtMaxFillerGetOneResult( i)
|
||||
table.insert( OneRes, { Id=nPartId, Count=nCount})
|
||||
end
|
||||
--return { FilledParts=nFilledParts, DiffParts=nDiffParts, FillRatio=dTotFillRatio, Time=dTime, Data=OneRes}
|
||||
return { FilledParts=nFilledParts, DiffParts=nDiffParts, FillRatio=dTotFillRatio, Data=OneRes}
|
||||
end
|
||||
|
||||
-- Funzione per trovare nome MachGroup
|
||||
local function NewMachGroupName()
|
||||
local nMachGroupId = EgtGetFirstMachGroup()
|
||||
if not nMachGroupId then return 1 end
|
||||
local nMaxMachGroup = 0
|
||||
while nMachGroupId do
|
||||
sMachGroupName = EgtGetMachGroupName(nMachGroupId)
|
||||
local nMachGroupName = tonumber(sMachGroupName)
|
||||
if nMachGroupName > nMaxMachGroup then
|
||||
nMaxMachGroup = nMachGroupName
|
||||
end
|
||||
nMachGroupId = EgtGetNextMachGroup(nMachGroupId)
|
||||
end
|
||||
return nMaxMachGroup + 1
|
||||
end
|
||||
|
||||
local function TotRawCount(Raws)
|
||||
local nTotRaws = 0
|
||||
for RawIndex = 1, #Raws do
|
||||
nTotRaws = nTotRaws + Raws[RawIndex].Count
|
||||
end
|
||||
return nTotRaws
|
||||
end
|
||||
|
||||
local function TotPartLen(Parts)
|
||||
local nTotPartLen = 0
|
||||
for PartIndex = 1, #Parts do
|
||||
nTotPartLen = nTotPartLen + ( Parts[PartIndex].Len * Parts[PartIndex].Cnt)
|
||||
end
|
||||
return nTotPartLen
|
||||
end
|
||||
|
||||
-- Imposto direttorio libreria specializzata per Travi
|
||||
EgtAddToPackagePath( NEST.BASEDIR .. '\\LuaLibs\\?.lua')
|
||||
|
||||
-- Imposto la macchina corrente e verifico sia abilitata per la lavorazione delle Travi
|
||||
EgtSetCurrMachine( NEST.MACHINE)
|
||||
local sMachDir = EgtGetCurrMachineDir()
|
||||
if not EgtExistsFile( sMachDir .. '\\Beam\\BeamData.lua') then
|
||||
NEST.ERR = 12
|
||||
NEST.MSG = 'Error not configured for beam machine : ' .. sMachine
|
||||
WriteErrToLogFile( NEST.ERR, NEST.MSG)
|
||||
PostErrView( NEST.ERR, NEST.MSG)
|
||||
return
|
||||
end
|
||||
|
||||
-- Elimino direttori altre macchine e imposto direttorio macchina corrente per ricerca librerie
|
||||
EgtRemoveBaseMachineDirFromPackagePath()
|
||||
EgtAddToPackagePath( sMachDir .. '\\Beam\\?.lua')
|
||||
|
||||
-- Inizializzo contatori errori e avvisi
|
||||
local nErrCnt = 0
|
||||
local nWarnCnt = 0
|
||||
|
||||
-- Grezzi
|
||||
local Raws = {}
|
||||
-- creo tabella dei grezzi
|
||||
for nIndex, nLen in pairs( LEN) do
|
||||
Raws[tonumber(nIndex)] = {LenToFill = nLen, StartGap = NEST.STARTOFFSET, MidGap = NEST.OFFSET, EndGap = 0, SortType = -1}
|
||||
end
|
||||
for nIndex, nQty in pairs( QTY) do
|
||||
Raws[tonumber(nIndex)].Count = nQty
|
||||
end
|
||||
-- cerco il grezzo con la lunghezza maggiore, epurata dello start gap
|
||||
local maxRawLenToFillNoStartGap = 0
|
||||
for RawIndex = 1, #Raws do
|
||||
if Raws[RawIndex].Count > 0 then
|
||||
maxRawLenToFillNoStartGap = max( maxRawLenToFillNoStartGap, Raws[RawIndex].LenToFill - Raws[RawIndex].StartGap)
|
||||
end
|
||||
end
|
||||
|
||||
-- Pezzi
|
||||
local Parts = {}
|
||||
-- ciclo su pezzi per aggiungerli al nesting
|
||||
local dTotLen = 0
|
||||
for nPartId, nCount in pairs( PART) do
|
||||
-- recupero lunghezza pezzo
|
||||
local Len = EgtGetInfo( nPartId, "L", 'd')
|
||||
local DispLen = EgtIf( Len <= 1000, 2000, 0) --EgtIf( Len <= 2000, max( 2000, 6000 - Len), 0)
|
||||
-- aggiungo il pezzo solo se ci sta nel grezzo più lungo a disposizione
|
||||
if Len < maxRawLenToFillNoStartGap then
|
||||
for nCntIndex = 1 , nCount do
|
||||
table.insert( Parts, {Id = nPartId, Len = Len, DispLen = DispLen, Cnt = 1})
|
||||
dTotLen = dTotLen + Len
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- lunghezza totale pezzi
|
||||
local dTotPartLen = TotPartLen( Parts)
|
||||
-- calcolo media delle barre necessarie
|
||||
local NeededRawsForType = {}
|
||||
for RawIndex = 1, #Raws do
|
||||
NeededRawsForType[RawIndex] = min( ceil( dTotPartLen / Raws[RawIndex].LenToFill), Raws[RawIndex].Count)
|
||||
end
|
||||
local RawQtySum = 0
|
||||
for NeededRawIndex = 1, #NeededRawsForType do
|
||||
RawQtySum = RawQtySum + NeededRawsForType[NeededRawIndex]
|
||||
end
|
||||
local MediumRawQty = ceil( RawQtySum / #NeededRawsForType)
|
||||
if MediumRawQty > 1 then
|
||||
MediumRawQty = MediumRawQty - 1
|
||||
end
|
||||
|
||||
-- lista dei risultati
|
||||
local ResultList = {}
|
||||
local BestResult = nil
|
||||
local BestResultIndex = nil
|
||||
-- riordino lista pezzi per lunghezza
|
||||
table.sort( Parts, function( B1, B2) return B1.Len < B2.Len end)
|
||||
|
||||
local function NestSolutionByIndex( Index)
|
||||
|
||||
-- creo copia lista raw
|
||||
local TempRaws = {}
|
||||
for TempRawIndex = 1, #Raws do
|
||||
table.insert(TempRaws, {LenToFill = Raws[TempRawIndex].LenToFill, StartGap = Raws[TempRawIndex].StartGap, MidGap = Raws[TempRawIndex].MidGap, EndGap = Raws[TempRawIndex].EndGap, SortType = Raws[TempRawIndex].SortType, Count = Raws[TempRawIndex].Count})
|
||||
end
|
||||
|
||||
-- recupero pezzi corti
|
||||
local ShortList = {}
|
||||
local LongList = {}
|
||||
|
||||
for PartIndex = 1, #Parts do
|
||||
if PartIndex <= Index then
|
||||
table.insert( ShortList, Parts[PartIndex])
|
||||
else
|
||||
table.insert( LongList, Parts[PartIndex])
|
||||
end
|
||||
Parts[PartIndex].Cnt = 1
|
||||
end
|
||||
-- numero di pezzi piccoli per barra
|
||||
local ShortCount = Index
|
||||
local ShortForRaw = floor( ShortCount / MediumRawQty)
|
||||
local ExtraShortForRaw = 0
|
||||
if MediumRawQty > 0 then
|
||||
ExtraShortForRaw = fmod( ShortCount, MediumRawQty)
|
||||
end
|
||||
-- creo lista pezzi corti singoli
|
||||
local SingleShortList = {}
|
||||
for ShortIndex = 1, #ShortList do
|
||||
for ShortCount = 1, ShortList[ShortIndex].Cnt do
|
||||
table.insert( SingleShortList, {Id = ShortList[ShortIndex].Id, Len = ShortList[ShortIndex].Len, DispLen = ShortList[ShortIndex].DispLen, Cnt = 1})
|
||||
end
|
||||
end
|
||||
-- li divido per le barre previste
|
||||
local RawsShortList = {}
|
||||
local RawIndex = 0
|
||||
local ShortRawIndex = 0
|
||||
for ShortIndex = 1, #SingleShortList do
|
||||
if ShortRawIndex > 0 then
|
||||
table.insert( RawsShortList[RawIndex], SingleShortList[ShortIndex])
|
||||
ShortRawIndex = ShortRawIndex - 1
|
||||
else
|
||||
table.insert( RawsShortList, {SingleShortList[ShortIndex]})
|
||||
RawIndex = RawIndex + 1
|
||||
ShortRawIndex = ShortForRaw + EgtIf( RawIndex <= ExtraShortForRaw, 1, 0) - 1
|
||||
end
|
||||
end
|
||||
|
||||
-- Ciclo fino ad esaurimento pezzi o barre
|
||||
local dTotPartInRawLen = 0
|
||||
local nRawTot = 0
|
||||
local dRawTotLen = 0
|
||||
local dTime = 0
|
||||
local nCycle = 1
|
||||
local CurrResult = {}
|
||||
while TotRawCount( TempRaws) > 0 and PartsToFill( Parts) > 0 do
|
||||
|
||||
-- creo lista con pezzi lunghi e pezzi corti di questo Cycle
|
||||
local PartsToNest = {}
|
||||
for PartIndex = 1, #LongList do
|
||||
table.insert( PartsToNest, LongList[PartIndex])
|
||||
end
|
||||
for CycleIndex = 1, #RawsShortList do
|
||||
if CycleIndex <= nCycle then
|
||||
for PartIndex = 1, #RawsShortList[CycleIndex] do
|
||||
table.insert( PartsToNest, RawsShortList[CycleIndex][PartIndex])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- se non ci sono pezzi da nestare, esco
|
||||
if PartsToFill( PartsToNest) <= 0 then
|
||||
break
|
||||
end
|
||||
-- Eseguo ottimizzazione per ogni lunghezza di barra
|
||||
local Results = {}
|
||||
for RawIndex = 1, #TempRaws do
|
||||
if TempRaws[RawIndex].Count > 0 then
|
||||
Results[RawIndex] = ExecMaximumFilling( TempRaws[RawIndex], PartsToNest)
|
||||
else
|
||||
Results[RawIndex] = { FillRatio = 0.001, LenToFill = 1000, DiffParts = 0}
|
||||
end
|
||||
end
|
||||
-- verifico quale e' quella con meno scarto
|
||||
local nMinWasteRawIndex = GDB_ID.NULL
|
||||
local dMinWaste = 100000
|
||||
for ResultIndex = 1, #Results do
|
||||
if Results[ResultIndex] then
|
||||
local dWaste = (1 - Results[ResultIndex].FillRatio) * TempRaws[ResultIndex].LenToFill
|
||||
if Results[ResultIndex].DiffParts > 0 and dWaste < dMinWaste then
|
||||
dMinWaste = dWaste
|
||||
nMinWasteRawIndex = ResultIndex
|
||||
end
|
||||
end
|
||||
end
|
||||
-- verifico se ci sono pezzi
|
||||
if nMinWasteRawIndex > 0 and Results[nMinWasteRawIndex] and Results[nMinWasteRawIndex].DiffParts > 0 then
|
||||
-- riporto barra e pezzi nel risultato corrente
|
||||
local CurrBar = { BarLen = TempRaws[nMinWasteRawIndex].LenToFill, Parts = {}}
|
||||
local CurrX = TempRaws[nMinWasteRawIndex].StartGap
|
||||
local nInfoIndex = 1
|
||||
for i = 1, Results[nMinWasteRawIndex].DiffParts do
|
||||
local PartIndex = Results[nMinWasteRawIndex].Data[i].Id
|
||||
local PartId = PartsToNest[PartIndex].Id
|
||||
local dLen = PartsToNest[PartIndex].Len
|
||||
for j = 1, Results[nMinWasteRawIndex].Data[i].Count do
|
||||
-- creo pezzo copia
|
||||
CurrPart = { Index = nInfoIndex, PartId = PartId, PosX = CurrX}
|
||||
table.insert( CurrBar.Parts, CurrPart)
|
||||
CurrX = CurrX + dLen + TempRaws[nMinWasteRawIndex].MidGap
|
||||
nInfoIndex = nInfoIndex + 1
|
||||
end
|
||||
end
|
||||
table.insert( CurrResult, CurrBar)
|
||||
dTotPartInRawLen = dTotPartInRawLen + ( Results[nMinWasteRawIndex].FillRatio * TempRaws[nMinWasteRawIndex].LenToFill)
|
||||
nRawTot = nRawTot + 1
|
||||
dRawTotLen = dRawTotLen + TempRaws[nMinWasteRawIndex].LenToFill
|
||||
-- Aggiorno per prossima iterazione
|
||||
TempRaws[nMinWasteRawIndex].Count = TempRaws[nMinWasteRawIndex].Count - 1
|
||||
for i = 1, Results[nMinWasteRawIndex].DiffParts do
|
||||
local PartId = Results[nMinWasteRawIndex].Data[i].Id
|
||||
PartsToNest[PartId].Cnt = PartsToNest[PartId].Cnt - Results[nMinWasteRawIndex].Data[i].Count
|
||||
end
|
||||
else
|
||||
-- se non sono riuscito ad inserire alcun pezzo esco dal ciclo perche' non ci sono pezzi inseribili
|
||||
break
|
||||
end
|
||||
nCycle = nCycle + 1
|
||||
end
|
||||
-- riporto risultato in lista
|
||||
ResultList[Index] = dTotPartInRawLen
|
||||
if not BestResult or not BestResultIndex or
|
||||
( dTotPartInRawLen > ResultList[BestResultIndex] + 0.02 or ( abs( dTotPartInRawLen - ResultList[BestResultIndex]) < 0.02 and dRawTotLen < BestResult.RawTotLen - 0.02)) then
|
||||
BestResult = CurrResult
|
||||
BestResult.RawTotLen = dRawTotLen
|
||||
BestResultIndex = Index
|
||||
end
|
||||
end
|
||||
|
||||
local CycleCount = 0
|
||||
|
||||
local MinTime = 10 + pow( 3, ceil( log10( #Parts)) - 1)
|
||||
if bLogStat then EgtOutLog('MinTime: ' .. MinTime ) end
|
||||
local MaxTime = 30 + pow( 7, ceil( log10( #Parts)) - 1)
|
||||
if bLogStat then EgtOutLog('MaxTime: ' .. MaxTime ) end
|
||||
local TargetRatio = 0.98
|
||||
local dTargetRatioLen = TargetRatio * dTotLen
|
||||
if bLogStat then EgtOutLog('TargetRatioLen: ' .. dTargetRatioLen ) end
|
||||
local CurrTime = 0
|
||||
|
||||
local function NestSolutionFromSP( StartingPoint, OscillationStep)
|
||||
-- ciclo sulle possibilita' da un punto di origine con uno step fisso
|
||||
local CurrResultIndex = StartingPoint
|
||||
NestSolutionByIndex( StartingPoint)
|
||||
if OscillationStep == 0 then return end
|
||||
local CycleIndex = 1
|
||||
local nOutOfBoundary = 0
|
||||
while nOutOfBoundary ~= 3 do
|
||||
CurrTime = EgtStopCounter() / 1000
|
||||
if bLogStat then EgtOutLog('CurrTime: ' .. CurrTime ) end
|
||||
if bLogStat then EgtOutLog('BestRatio: ' .. dTotLen / BestResult.RawTotLen ) end
|
||||
-- se e' passato il tempo massimo, o e' passato il tempo minimo, ha inserito tutti i pezzi e la percentuale di utilizzo del materiale e' maggiore della soglia
|
||||
if CurrTime > MaxTime or ( CurrTime > MinTime and ResultList[BestResultIndex] > dTotLen - 0.1 and ( dTotLen / BestResult.RawTotLen ) >= TargetRatio) then
|
||||
if bLogStat then EgtOutLog('Brake') end
|
||||
break
|
||||
end
|
||||
local bCurrOutOfBoundary = false
|
||||
if CurrResultIndex < 0 then
|
||||
bCurrOutOfBoundary = true
|
||||
if nOutOfBoundary == 2 then
|
||||
nOutOfBoundary = 3
|
||||
else
|
||||
nOutOfBoundary = 1
|
||||
end
|
||||
end
|
||||
if CurrResultIndex > #Parts then
|
||||
bCurrOutOfBoundary = true
|
||||
if nOutOfBoundary == 1 then
|
||||
nOutOfBoundary = 3
|
||||
else
|
||||
nOutOfBoundary = 2
|
||||
end
|
||||
end
|
||||
if not bCurrOutOfBoundary and not ResultList[CurrResultIndex] then
|
||||
NestSolutionByIndex( CurrResultIndex)
|
||||
if bLogStat then EgtOutLog('CurrResultIndex: ' .. CurrResultIndex ) end
|
||||
if bLogStat then EgtOutLog('Result: ' .. ResultList[CurrResultIndex]) end
|
||||
CycleCount = CycleCount + 1
|
||||
end
|
||||
CurrResultIndex = StartingPoint + EgtIf( CycleIndex % 2 == 0, (CycleIndex / 2) * OscillationStep, -( ( CycleIndex + 1) / 2) * OscillationStep )
|
||||
CycleIndex = CycleIndex + 1
|
||||
end
|
||||
end
|
||||
|
||||
-- lancio calcolo
|
||||
EgtStartCounter()
|
||||
local StartingResult = floor( #Parts * 0.3)
|
||||
if bLogStat then EgtOutLog('StartingResult: ' .. StartingResult ) end
|
||||
--local Step = floor( #Parts / 10) * floor( log10( #Parts))
|
||||
local nDividendo = pow( 10, floor( log10( #Parts)) - 1)
|
||||
nDividendo = EgtIf( nDividendo ~= 1, nDividendo, 10)
|
||||
local Step = floor( #Parts / nDividendo) * floor( log10( #Parts))
|
||||
if bLogStat then EgtOutLog('Step: ' .. Step ) end
|
||||
NestSolutionFromSP( StartingResult, Step)
|
||||
if Step > 1 then
|
||||
NestSolutionFromSP( StartingResult, 1)
|
||||
end
|
||||
|
||||
-- creo gruppi di lavorazione per risultato
|
||||
for MachGroupIndex = 1, #BestResult do
|
||||
local CurrMachGroup = BestResult[ MachGroupIndex]
|
||||
-- creo gruppo di lavorazione
|
||||
local MachGroupName = NewMachGroupName()
|
||||
nMachGroup = EgtAddMachGroup( MachGroupName)
|
||||
EgtSetInfo( nMachGroup, "BARLEN", CurrMachGroup.BarLen)
|
||||
EgtSetInfo( nMachGroup, "MATERIAL", NEST.MATERIAL)
|
||||
EgtSetInfo( nMachGroup, "AUTONEST", 1)
|
||||
-- scrivo dati per variabili P di comunicazione con la macchina in gruppo di lavorazione
|
||||
EgtSetInfo( nMachGroup, "PRODID", NEST.PRODID)
|
||||
EgtSetInfo( nMachGroup, "PATTID", nMachGroup)
|
||||
-- Disegno i pezzi
|
||||
for i = 1, #CurrMachGroup.Parts do
|
||||
local CurrPart = CurrMachGroup.Parts[ i]
|
||||
-- creo pezzo copia
|
||||
local nPartDuploId = EgtDuploNew( CurrPart.PartId)
|
||||
EgtSetInfo( nMachGroup, "PART" .. CurrPart.Index, nPartDuploId .. "," .. CurrPart.PosX)
|
||||
end
|
||||
end
|
||||
|
||||
-- creo grezzi per ogni gruppo di lavorazione
|
||||
local nRawCnt = 0
|
||||
local nRawTot = ResultList[BestResultIndex]
|
||||
_G.BEAM = {}
|
||||
BEAM.FILE = NEST.FILE
|
||||
BEAM.MACHINE = NEST.MACHINE
|
||||
BEAM.FLAG = 6 -- CREATE_PANEL
|
||||
BEAM.BASEDIR = NEST.BASEDIR
|
||||
nMachGroup = EgtGetFirstMachGroup()
|
||||
while nMachGroup do
|
||||
local nNextMachGroup = EgtGetNextMachGroup( nMachGroup)
|
||||
EgtSetCurrMachGroup( nMachGroup)
|
||||
if EgtGetInfo( nMachGroup, "AUTONEST",'i') == 1 then
|
||||
EgtRemoveInfo( nMachGroup, "AUTONEST")
|
||||
EgtSetInfo( nMachGroup, "UPDATEUI", 1)
|
||||
local bOk, sErr = pcall( dofile, BEAM.BASEDIR .. "\\BatchProcessNew.lua")
|
||||
if not bOk then
|
||||
EgtOutLog( 'Error in BatchProcessNew.lua call (' .. ( sErr or '') ..')')
|
||||
end
|
||||
nRawCnt = nRawCnt + 1
|
||||
-- aggiorno interfaccia
|
||||
EgtProcessEvents( 200 + ( nRawCnt / nRawTot * 100), 0)
|
||||
end
|
||||
nMachGroup = nNextMachGroup
|
||||
end
|
||||
|
||||
EgtResetCurrMachGroup()
|
||||
|
||||
NEST.ERR = 0
|
||||
|
||||
EgtOutLog( ' +++ BeamNestProcess completed')
|
||||
+39
-15
@@ -7,7 +7,7 @@
|
||||
-- Intestazioni
|
||||
require( 'EgtBase')
|
||||
_ENV = EgtProtectGlobal()
|
||||
EgtEnableDebug( true)
|
||||
EgtEnableDebug( false)
|
||||
|
||||
-- Imposto direttorio libreria specializzata per Travi
|
||||
EgtAddToPackagePath( BEAM.BASEDIR .. '\\LuaLibs\\?.lua')
|
||||
@@ -15,16 +15,13 @@ EgtAddToPackagePath( BEAM.BASEDIR .. '\\LuaLibs\\?.lua')
|
||||
EgtAddToPackagePath( BEAM.BASEDIR .. '\\Strategies\\Standard\\?.lua')
|
||||
EgtAddToPackagePath( BEAM.BASEDIR .. '\\StrategyLibs\\?.lua')
|
||||
|
||||
-- TODO forzatura calcolo con prerotazioni. Cancellare dopo che è stata aggiunta la gestione corretta
|
||||
local bCalcBestPieceUnloadPosition = true
|
||||
|
||||
-- Verifico che la macchina corrente sia abilitata per la lavorazione delle Travi
|
||||
local sMachDir = EgtGetCurrMachineDir()
|
||||
if not sMachDir then
|
||||
EgtOutBox( 'Errore nel caricamento della macchina corrente', 'Lavora Travi', 'ERROR')
|
||||
return
|
||||
end
|
||||
if not EgtExistsFile( sMachDir .. '\\Beam\\BeamData.lua') then
|
||||
if not EgtExistsFile( sMachDir .. '\\Beam\\BeamDataNew.lua') then
|
||||
EgtOutBox( 'La macchina corrente non è configurata per lavorare travi', 'Lavora Travi', 'ERROR')
|
||||
return
|
||||
end
|
||||
@@ -46,11 +43,15 @@ _G.package.loaded.FeatureLib = nil
|
||||
_G.package.loaded.Identity = nil
|
||||
_G.package.loaded.Logs = nil
|
||||
_G.package.loaded.MachiningLib = nil
|
||||
_G.package.loaded.PreSimulationLib = nil
|
||||
_G.package.loaded.LeadInOutLib = nil
|
||||
-- strategie di base sempre presenti
|
||||
_G.package.loaded['HEADCUT\\HEADCUT'] = nil
|
||||
_G.package.loaded['TAILCUT\\TAILCUT'] = nil
|
||||
-- libreria macchina
|
||||
_G.package.loaded.BeamData = nil
|
||||
_G.package.loaded.BeamDataNew = nil
|
||||
-- libreria calcolo tempo esecuzione
|
||||
_G.package.loaded.TimeLib = 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.
|
||||
@@ -76,7 +77,7 @@ end
|
||||
PARTS = {} -- tabella contenente tutte le informazioni di ogni pezzo
|
||||
|
||||
-- Carico i dati globali
|
||||
local BeamData = require( 'BeamData')
|
||||
local BeamData = require( 'BeamDataNew')
|
||||
-- carico librerie
|
||||
local BeamExec = require( 'BeamExec')
|
||||
local BeamLib = require( 'BeamLib')
|
||||
@@ -130,6 +131,14 @@ local function MyProcessInputData()
|
||||
else
|
||||
PARTS[i].b3PartOriginal = b3Solid
|
||||
end
|
||||
if BeamData.MAX_LENGTH and BeamData.MAX_LENGTH > 10 and b3Solid:getDimX() > BeamData.MAX_LENGTH then
|
||||
local sOut = 'Lunghezza (' .. EgtNumToString( b3Solid:getDimX(), 2) .. ') ' ..
|
||||
'oltre i limiti della macchina (' .. EgtNumToString( BeamData.MAX_LENGTH, 2) .. ') '
|
||||
EgtOutLog( sOut)
|
||||
EgtOutBox( sOut, 'Lavora Travi', 'WARNING')
|
||||
EgtDraw()
|
||||
return false
|
||||
end
|
||||
end
|
||||
dRawW = PARTS[1].b3PartOriginal:getDimY()
|
||||
dRawH = PARTS[1].b3PartOriginal:getDimZ()
|
||||
@@ -286,7 +295,7 @@ local function MyProcessBeams()
|
||||
end
|
||||
|
||||
-- Sistemo le travi nel grezzo
|
||||
local bOk, sErr = BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, dOvmMid, PARTS, nil, bCalcBestPieceUnloadPosition)
|
||||
local bOk, sErr = BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, dOvmMid, PARTS, nil, false)
|
||||
if not bOk then
|
||||
EgtOutLog( sErr)
|
||||
EgtOutBox( sErr, 'Lavora Travi', 'ERROR')
|
||||
@@ -300,12 +309,10 @@ end
|
||||
-- *** Inserimento delle lavorazioni nelle travi ***
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function MyProcessFeatures()
|
||||
-- creo un gruppo temporaneo dove finiranno tutte le entità che non bisogna salvare, alla fine lo si cancella
|
||||
local idTempGroup = BeamLib.CreateTempGroup()
|
||||
|
||||
BeamExec.GetProcessings( PARTS, bCalcBestPieceUnloadPosition)
|
||||
BeamExec.GetCombinationMatrix( PARTS, bCalcBestPieceUnloadPosition)
|
||||
BeamExec.ProcessMachinings( PARTS)
|
||||
BeamExec.GetProcessings( PARTS, false)
|
||||
BeamExec.GetCombinationMatrix( PARTS, false)
|
||||
BeamExec.ProcessMachinings( PARTS, false)
|
||||
local nErrCnt = 0
|
||||
local nWarnCnt = 0
|
||||
local sOutput = ''
|
||||
@@ -320,7 +327,7 @@ local function MyProcessFeatures()
|
||||
sMsg = string.gsub( sMsg or '', '\r', ' ', 10)
|
||||
-- trovata almeno una strategia e feature lavorata completamente
|
||||
if RESULT[i].sType == 'Feature' and RESULT[i].ChosenStrategy.sStatus == 'Completed' then
|
||||
-- nulla da segnalare
|
||||
sOutput = sOutput .. string.format( '[%d,%d] %s\n', RESULT[i].idCut, RESULT[i].idTask, sMsg or '')
|
||||
|
||||
-- trovata almeno una strategia ma nessuna applicabile oppure non trovata alcuna strategia
|
||||
elseif RESULT[i].sType == 'Feature'
|
||||
@@ -348,6 +355,7 @@ local function MyProcessFeatures()
|
||||
end
|
||||
|
||||
-- cancello gruppo temporaneo
|
||||
local idTempGroup = BeamLib.GetTempGroup()
|
||||
EgtErase( idTempGroup)
|
||||
|
||||
if #sOutput > 0 then EgtOutLog( sOutput) end
|
||||
@@ -365,11 +373,21 @@ end
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- *** Esecuzione ***
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
|
||||
-- calcolo tempo esecuzione
|
||||
TIMER:start()
|
||||
EgtOutLog( ' Execution timer started')
|
||||
|
||||
-- script principale
|
||||
|
||||
if not MyProcessInputData() then return end
|
||||
|
||||
-- recupero parametri generali da progetto
|
||||
BeamExec.GetGeneralParameters()
|
||||
|
||||
-- creo un gruppo temporaneo dove finiranno tutte le entità che non bisogna salvare, alla fine lo si cancella
|
||||
BeamLib.CreateTempGroup()
|
||||
|
||||
if not MyProcessBeams() then return end
|
||||
|
||||
if not GetDataConfig() then return end
|
||||
@@ -377,4 +395,10 @@ if not GetDataConfig() then return end
|
||||
-- Abilito Vmill
|
||||
EgtSetInfo( EgtGetCurrMachGroup(), 'Vm', '1')
|
||||
|
||||
if not MyProcessFeatures() then return end
|
||||
MyProcessFeatures()
|
||||
|
||||
-- log tempi di esecuzione
|
||||
if EgtGetDebugLevel() >= 3 then
|
||||
TIMER:logAllElapsed()
|
||||
end
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
"StrategyList" : [ { "sStrategyId": "STR0002" }, { "sStrategyId": "STR0005" }, { "sStrategyId": "STR0010" } ]
|
||||
},
|
||||
{ "sName": "Bevel-1-Through",
|
||||
"sImage": "ConfigStrategy\\Cut-1-Through.png",
|
||||
"sImage": "ConfigStrategy\\Bevel-1-Through.png",
|
||||
"StrategyList" : [ { "sStrategyId": "STR0002" }, { "sStrategyId": "STR0005" }, { "sStrategyId": "STR0010" } ]
|
||||
}
|
||||
]
|
||||
@@ -227,6 +227,10 @@
|
||||
{ "sName": "Cut-1-Through",
|
||||
"sImage": "ConfigStrategy\\Cut-1-Through.png",
|
||||
"StrategyList" : [ { "sStrategyId": "STR0002" }, { "sStrategyId": "STR0005" } ]
|
||||
},
|
||||
{ "sName": "DoubleBevel-2-Through",
|
||||
"sImage": "ConfigStrategy\\DoubleBevel-2-Through.png",
|
||||
"StrategyList" : [ { "sStrategyId": "STR0002" }, { "sStrategyId": "STR0005" }, { "sStrategyId": "STR0010"} ]
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -388,7 +392,7 @@
|
||||
"TopologyList" : [
|
||||
{ "sName": "Feature",
|
||||
"sImage": "ConfigStrategy\\Chamfer.png",
|
||||
"StrategyList" : [ ]
|
||||
"StrategyList" : [ { "sStrategyId": "STR0002" }, { "sStrategyId": "STR0005" }, { "sStrategyId": "STR0010" } ]
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -684,7 +688,7 @@
|
||||
"TopologyList" : [
|
||||
{ "sName": "Feature",
|
||||
"sImage": "ConfigStrategy\\ScarfJoint.png",
|
||||
"StrategyList" : [ ]
|
||||
"StrategyList" : [ { "sStrategyId": "STR0009" }]
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -837,8 +841,8 @@
|
||||
"nGrp": 0,
|
||||
"TopologyList" : [
|
||||
{ "sName": "Feature",
|
||||
"sImage": "",
|
||||
"StrategyList" : [ ]
|
||||
"sImage": "ConfigStrategy\\ProfileHead.png",
|
||||
"StrategyList" : [ { "sStrategyId": "STR0015" } ]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -1,35 +1,68 @@
|
||||
|
||||
[
|
||||
{
|
||||
"nGroup": "MACHINE",
|
||||
"nGroup": "PIECE LOADING",
|
||||
"sName": "GEN_sPiecesLoadingPosition",
|
||||
"sNameNge": "GEN_PIECES_LOADING",
|
||||
"sValue": "BEST_POSITION",
|
||||
"sValue": "BTL_POSITION",
|
||||
"sDescriptionShort": "Part loading position",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000001,
|
||||
"idDescriptionLongMsg": 1000002,
|
||||
"sType": "combo",
|
||||
"sMinUserLevel": "1",
|
||||
"Choices": [
|
||||
{
|
||||
"sValue": "BTL_POSITION",
|
||||
"sDescriptionShort": "Last piece position as BTL",
|
||||
"sDescriptionShort": "Loading position from BTL, no pre-rotation",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000003,
|
||||
"idDescriptionLongMsg": 1000004,
|
||||
"sMessageId": ""
|
||||
},
|
||||
{
|
||||
"sValue": "BEST_ROTATION",
|
||||
"sDescriptionShort": "Allow piece rotations",
|
||||
"sValue": "STD_PRE_ROTATION",
|
||||
"sDescriptionShort": "Get Best loading position from 0° and 180°",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000005,
|
||||
"idDescriptionLongMsg": 1000006,
|
||||
"sMessageId": ""
|
||||
},
|
||||
{
|
||||
"sValue": "BEST_POSITION",
|
||||
"sDescriptionShort": "Allow piece rotation and inversion",
|
||||
"sValue": "FULL_PRE_ROTATION",
|
||||
"sDescriptionShort": "Get Best loading position in each piece rotation",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000007,
|
||||
"idDescriptionLongMsg": 1000008,
|
||||
"sMessageId": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nGroup": "PIECE LOADING",
|
||||
"sName": "GEN_bAllowPieceInversion",
|
||||
"sNameNge": "ADMIT_INVERSION",
|
||||
"sValue": "false",
|
||||
"sDescriptionShort": "Allow piece inversion",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000009,
|
||||
"idDescriptionLongMsg": 1000010,
|
||||
"sType": "b",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
},
|
||||
{
|
||||
"nGroup": "PIECE LOADING",
|
||||
"sName": "GEN_bGetAlternativesNesting2D",
|
||||
"sNameNge": "GET_ALTERNATIVES_NEST2D",
|
||||
"sValue": "false",
|
||||
"sDescriptionShort": "Enable material optimization function in nesting (part rotation disabled)",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000011,
|
||||
"idDescriptionLongMsg": 1000012,
|
||||
"sType": "b",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
},
|
||||
{
|
||||
"nGroup": "MACHINE",
|
||||
"sName": "GEN_sPieceRotation",
|
||||
@@ -37,6 +70,8 @@
|
||||
"sValue": "IF_NECESSARY",
|
||||
"sDescriptionShort": "Part rotating acceptability",
|
||||
"sDescriptionLong": "Acceptability of rotating the part between machining steps",
|
||||
"idDescriptionShortMsg": 1000013,
|
||||
"idDescriptionLongMsg": 1000014,
|
||||
"sType": "combo",
|
||||
"sMinUserLevel": "1",
|
||||
"Choices": [
|
||||
@@ -44,18 +79,24 @@
|
||||
"sValue": "NOT_ALLOWED",
|
||||
"sDescriptionShort": "Rotation not allowed",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000015,
|
||||
"idDescriptionLongMsg": 1000016,
|
||||
"sMessageId": ""
|
||||
},
|
||||
{
|
||||
"sValue": "IF_NECESSARY",
|
||||
"sDescriptionShort": "Rotation allowed only if strictly necessary",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000017,
|
||||
"idDescriptionLongMsg": 1000018,
|
||||
"sMessageId": ""
|
||||
},
|
||||
{
|
||||
"sValue": "NO_CONSTRAINT",
|
||||
"sDescriptionShort": "Rotation easily acceptable / no constraint",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000019,
|
||||
"idDescriptionLongMsg": 1000020,
|
||||
"sMessageId": ""
|
||||
}
|
||||
]
|
||||
@@ -67,6 +108,8 @@
|
||||
"sValue": "AUTO",
|
||||
"sDescriptionShort": "Machining Strategy",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000021,
|
||||
"idDescriptionLongMsg": 1000022,
|
||||
"sType": "combo",
|
||||
"sMinUserLevel": "1",
|
||||
"Choices": [
|
||||
@@ -74,22 +117,49 @@
|
||||
"sValue": "AUTO",
|
||||
"sDescriptionShort": "Quality and time equally prioritized",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000023,
|
||||
"idDescriptionLongMsg": 1000024,
|
||||
"sMessageId": ""
|
||||
},
|
||||
{
|
||||
"sValue": "FASTEST",
|
||||
"sDescriptionShort": "Fastest",
|
||||
"sDescriptionLong": "Prefer fastest strategies",
|
||||
"idDescriptionShortMsg": 1000025,
|
||||
"idDescriptionLongMsg": 1000026,
|
||||
"sMessageId": ""
|
||||
},
|
||||
{
|
||||
"sValue": "HIGH_QUALITY",
|
||||
"sDescriptionShort": "High quality",
|
||||
"sDescriptionLong": "Prefer high-quality strategies",
|
||||
"idDescriptionShortMsg": 1000027,
|
||||
"idDescriptionLongMsg": 1000028,
|
||||
"sMessageId": ""
|
||||
},
|
||||
{
|
||||
"sValue": "FIRST_IN_LIST",
|
||||
"sDescriptionShort": "Ordering rules",
|
||||
"sDescriptionLong": "The first complete strategy in list is the one chosen; no intelligent choosing",
|
||||
"idDescriptionShortMsg": 1000029,
|
||||
"idDescriptionLongMsg": 1000030,
|
||||
"sMessageId": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nGroup": "MACHINING STRATEGY",
|
||||
"sName": "GEN_nMaxReProcessCycles",
|
||||
"sNameNge": "MAX_REPROCESS_CYCLES",
|
||||
"sValue": "1",
|
||||
"sDescriptionShort": "Max number of reprocessing cycles",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000031,
|
||||
"idDescriptionLongMsg": 1000032,
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "10"
|
||||
},
|
||||
{
|
||||
"nGroup": "MACHINING STRATEGY",
|
||||
"sName": "GEN_bReduceBladePath",
|
||||
@@ -97,6 +167,8 @@
|
||||
"sValue": "true",
|
||||
"sDescriptionShort": "Use entire blade diameter to shorten path",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000033,
|
||||
"idDescriptionLongMsg": 1000034,
|
||||
"sType": "b",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "5"
|
||||
@@ -106,8 +178,10 @@
|
||||
"sName": "GEN_dMaxWasteLength",
|
||||
"sNameNge": "GEN_MAX_WASTE_LENGTH",
|
||||
"sValue": "300",
|
||||
"sDescriptionShort": "Maximum Waste Length for Dice-cut",
|
||||
"sDescriptionShort": "Maximum length for dropped waste",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000035,
|
||||
"idDescriptionLongMsg": 1000036,
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "5"
|
||||
@@ -117,10 +191,25 @@
|
||||
"sName": "GEN_dMaxWasteVolume",
|
||||
"sNameNge": "GEN_MAX_WASTE_VOLUME",
|
||||
"sValue": "6000000",
|
||||
"sDescriptionShort": "Maximum Waste Volume for Dice-cut",
|
||||
"sDescriptionShort": "Maximum volume for dropped waste",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000037,
|
||||
"idDescriptionLongMsg": 1000038,
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "5"
|
||||
},
|
||||
{
|
||||
"nGroup": "MACHINING STRATEGY",
|
||||
"sName": "GEN_dMaxDimDice",
|
||||
"sNameNge": "GEN_MAX_DIM_DICE",
|
||||
"sValue": "150",
|
||||
"sDescriptionShort": "Maximum dice dimension",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000039,
|
||||
"idDescriptionLongMsg": 1000040,
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "5"
|
||||
}
|
||||
]
|
||||
]
|
||||
@@ -8,6 +8,8 @@
|
||||
"sValue": "0",
|
||||
"sDescriptionShort": "Depth Chamfer",
|
||||
"sDescriptionLong": "Depth of the V-Mill to execute chamfers on cut-edges",
|
||||
"idDescriptionShortMsg": 1000301,
|
||||
"idDescriptionLongMsg": 1000302,
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -18,6 +20,8 @@
|
||||
"sValue": "false",
|
||||
"sDescriptionShort": "Force to use chain saw",
|
||||
"sDescriptionLong": "Force to use chain saw",
|
||||
"idDescriptionShortMsg": 1000303,
|
||||
"idDescriptionLongMsg": 1000304,
|
||||
"sType": "b",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -28,6 +32,8 @@
|
||||
"sValue": "false",
|
||||
"sDescriptionShort": "Force to add PreCuts",
|
||||
"sDescriptionLong": "Autocam will apply a machining on the theoretical zero, to avoid collision if the theoretical piece length doesn't correspond to the real length",
|
||||
"idDescriptionShortMsg": 1000305,
|
||||
"idDescriptionLongMsg": 1000306,
|
||||
"sType": "b",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -38,6 +44,8 @@
|
||||
"sValue": "true",
|
||||
"sDescriptionShort": "Finish with mill",
|
||||
"sDescriptionLong": "Use a mill to finish the surface if split with chain saw",
|
||||
"idDescriptionShortMsg": 1000307,
|
||||
"idDescriptionLongMsg": 1000308,
|
||||
"sType": "b",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -58,5 +66,4 @@
|
||||
"sMinUserLevel": "5"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
-- carico librerie
|
||||
local BeamLib = require( 'BeamLib')
|
||||
local BeamData = require( 'BeamData')
|
||||
local BeamData = require( 'BeamDataNew')
|
||||
local FeatureLib = require( 'FeatureLib')
|
||||
local MachiningLib = require( 'MachiningLib')
|
||||
local SPLITCUT = require( 'SPLITCUT')
|
||||
@@ -34,17 +34,28 @@ function HEADCUT.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
Strategy.Result.sInfo = ''
|
||||
local OptionalParameters = { bForceChainSaw = Strategy.Parameters.bForceChainSaw, bReduceBladePath = Strategy.Parameters.bReduceBladePath,
|
||||
dMaxWasteLength = Strategy.Parameters.dMaxWasteLength, dMaxWasteVolume = Strategy.Parameters.dMaxWasteVolume }
|
||||
OptionalParameters.sRestLengthSideForPreSimulation = 'Head'
|
||||
OptionalParameters.bCannotSplitRestLength = true
|
||||
local bAreAllMachiningsAdded = true
|
||||
|
||||
-- si setta che è taglio di coda
|
||||
-- si setta che è taglio di testa
|
||||
Strategy.bIsHeadCut = true
|
||||
-- quando si aggiunge la lavorazione, si cambia il nome della feature
|
||||
if bAddMachining then
|
||||
-- si forza il nome della feature
|
||||
EgtSetName( Proc.id, 'StartCut')
|
||||
end
|
||||
|
||||
-- se abilitato, faccio tagli di PRECUT a zero (come SPLIT)
|
||||
if Strategy.Parameters.bExecutePreCut then
|
||||
Strategy.SplitStrategy, Strategy.Result = SPLITCUT.GetMachining( Proc, Part, OptionalParameters)
|
||||
-- se non faccio tagli PRECUT, imposto tabella Result direttamente. Non serve verificare che riesca a rimuovere il materiale extra
|
||||
if not Strategy.SplitStrategy or #Strategy.SplitStrategy == 0 then
|
||||
Strategy.Result.sInfo = 'PreCut on head not possible'
|
||||
-- if not Strategy.SplitStrategy or #Strategy.SplitStrategy == 0 then
|
||||
-- Strategy.Result.sInfo = 'PreCut on head not possible'
|
||||
-- end
|
||||
if Strategy.Result.sStatus ~= 'Completed' then
|
||||
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( 'Precut Head not possible')
|
||||
return false, Strategy.Result
|
||||
end
|
||||
end
|
||||
|
||||
@@ -54,22 +65,24 @@ function HEADCUT.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
-- TODO di quale utensile si deve impostare la qualità qui?
|
||||
Strategy.Result.dQuality = FeatureLib.GetStrategyQuality( 'SAWBLADE')
|
||||
|
||||
-- se coincide con inizio grezzo, non va fatto
|
||||
if abs( Proc.b3Box:getCenter():getX() - Part.b3Raw:getMax():getX()) < 10 * GEO.EPS_SMALL then
|
||||
return true, Strategy.Result
|
||||
end
|
||||
|
||||
-- se devo applicare le lavorazioni
|
||||
if bAddMachining then
|
||||
-- si forza il nome della feature
|
||||
EgtSetName( Proc.id, 'StartCut')
|
||||
|
||||
-- inserimento smussi su spigoli del taglio
|
||||
if Strategy.Parameters.bMakeChamfer then
|
||||
MakeChamfer()
|
||||
end
|
||||
|
||||
local MachiningsToAdd = {}
|
||||
local bExecutePrecutOnly = Part.dHeadOverMaterial < 20
|
||||
local bExecutePrecutOnly = false
|
||||
-- se abilitato, faccio tagli di PRECUT a zero (come SPLIT)
|
||||
if Strategy.Parameters.bExecutePreCut then
|
||||
|
||||
bExecutePrecutOnly = Part.dHeadOverMaterial < 20
|
||||
|
||||
if Strategy.SplitStrategy and #Strategy.SplitStrategy > 0 then
|
||||
for i = 1, #Strategy.SplitStrategy do
|
||||
local TempList = {}
|
||||
@@ -87,25 +100,35 @@ function HEADCUT.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
end
|
||||
|
||||
if not bExecutePrecutOnly then
|
||||
local OptionalParameters = {}
|
||||
-- si parte dal box della feature e si aggiunge il punto estremo del grezzo
|
||||
-- ATTENZIONE : Proc.b3Box viene modificata dato che il tipo Box è come se fosse una tabella, ma da qui passa solo 1 volta per pezzo quindi non dovrebbero esserci problemi
|
||||
local b3BoxDicing = Proc.b3Box
|
||||
b3BoxDicing:Add( Part.b3Raw:getMax())
|
||||
b3BoxDicing:expand( 1000 * GEO.EPS_SMALL)
|
||||
OptionalParameters.b3BoxDicing = b3BoxDicing
|
||||
|
||||
OptionalParameters.dMaxWasteVolume = Strategy.Parameters.dMaxWasteVolume
|
||||
OptionalParameters.dMaxWasteLength = Strategy.Parameters.dMaxWasteLength
|
||||
OptionalParameters.bReduceBladePath = Strategy.Parameters.bReduceBladePath
|
||||
-- si recuperano gli estremi del box del materiale di testa da togliere
|
||||
local b3PartWithHead = BeamLib.GetPartBoxWithHeadTail( Part, 'Head')
|
||||
local ptStartRestLength = Point3d( Part.b3Part:getMax():getX() - 1, Part.b3Part:getMax():getY(), Part.b3Part:getMax():getZ())
|
||||
local ptEndRestLength = Point3d( b3PartWithHead:getMax():getX(), Part.b3Part:getMin():getY(), Part.b3Part:getMin():getZ())
|
||||
|
||||
Strategy.Machining, _ = BladeToWaste.Make( Proc, Part, OptionalParameters)
|
||||
local OptionalParametersBladeToWaste = {}
|
||||
OptionalParametersBladeToWaste.b3BoxDicing = BBox3d( ptStartRestLength, ptEndRestLength)
|
||||
OptionalParametersBladeToWaste.dMaxWasteVolume = Strategy.Parameters.dMaxWasteVolume
|
||||
OptionalParametersBladeToWaste.dMaxWasteLength = Strategy.Parameters.dMaxWasteLength
|
||||
OptionalParametersBladeToWaste.bReduceBladePath = Strategy.Parameters.bReduceBladePath
|
||||
OptionalParametersBladeToWaste.sRestLengthSideForPreSimulation = 'Head'
|
||||
OptionalParametersBladeToWaste.bCannotSplitRestLength = true
|
||||
|
||||
Strategy.Machining, _ = BladeToWaste.Make( Proc, Part, OptionalParametersBladeToWaste)
|
||||
-- se taglio non riuscito, si riprova con il riduci percorso forzato (collisione possibile in separazione pezzi alti)
|
||||
if ( not Strategy.Machining) or ( #Strategy.Machining == 0) then
|
||||
OptionalParametersBladeToWaste.bReduceBladePath = true
|
||||
Strategy.Machining, _ = BladeToWaste.Make( Proc, Part, OptionalParametersBladeToWaste)
|
||||
end
|
||||
if Strategy.Machining and #Strategy.Machining > 0 then
|
||||
for i = 1, #Strategy.Machining do
|
||||
local TempList = {}
|
||||
TempList = Strategy.Machining[i]
|
||||
table.insert( MachiningsToAdd, TempList)
|
||||
end
|
||||
else
|
||||
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( 'Head machining not possible')
|
||||
return false, Strategy.Result
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
"sValue": "0",
|
||||
"sDescriptionShort": "Overmaterial on tenon length",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000041,
|
||||
"idDescriptionLongMsg": 1000042,
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -18,6 +20,8 @@
|
||||
"sValue": "0",
|
||||
"sDescriptionShort": "Overmaterial on tenon width",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000043,
|
||||
"idDescriptionLongMsg": 1000044,
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -28,6 +32,8 @@
|
||||
"sValue": "3",
|
||||
"sDescriptionShort": "Maximum number of milling passes",
|
||||
"sDescriptionLong": "Maximum number of milling passes. If more passes are required, pocketing is performed",
|
||||
"idDescriptionShortMsg": 1000045,
|
||||
"idDescriptionLongMsg": 1000046,
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -38,6 +44,8 @@
|
||||
"sValue": "true",
|
||||
"sDescriptionShort": "Use DoveTail tool to pocket",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000047,
|
||||
"idDescriptionLongMsg": 1000048,
|
||||
"sType": "b",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -48,6 +56,8 @@
|
||||
"sValue": "AUTO",
|
||||
"sDescriptionShort": "Cutting Strategy",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000049,
|
||||
"idDescriptionLongMsg": 1000050,
|
||||
"sType": "combo",
|
||||
"sMinUserLevel": "1",
|
||||
"Choices": [
|
||||
@@ -55,24 +65,32 @@
|
||||
"sValue": "AUTO",
|
||||
"sDescriptionShort": "Automatic",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000051,
|
||||
"idDescriptionLongMsg": 1000052,
|
||||
"sMessageId": ""
|
||||
},
|
||||
{
|
||||
"sValue": "BLADE_FORCED",
|
||||
"sDescriptionShort": "Blade only",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000053,
|
||||
"idDescriptionLongMsg": 1000054,
|
||||
"sMessageId": ""
|
||||
},
|
||||
{
|
||||
"sValue": "MILL_FORCED",
|
||||
"sDescriptionShort": "Mill only",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000055,
|
||||
"idDescriptionLongMsg": 1000056,
|
||||
"sMessageId": ""
|
||||
},
|
||||
{
|
||||
"sValue": "CHAINSAW_FORCED",
|
||||
"sDescriptionShort": "ChainSaw only",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000057,
|
||||
"idDescriptionLongMsg": 1000058,
|
||||
"sMessageId": ""
|
||||
}
|
||||
]
|
||||
@@ -83,6 +101,8 @@
|
||||
"sValue": "",
|
||||
"sDescriptionShort": "Available mill to machine the tenon cut surface",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000059,
|
||||
"idDescriptionLongMsg": 1000060,
|
||||
"sType": "tool",
|
||||
"sSubType": "MCH_TF.MILL",
|
||||
"sMessageId": " ",
|
||||
@@ -94,6 +114,8 @@
|
||||
"sValue": "",
|
||||
"sDescriptionShort": "Available mill to machine the dovetail tenon",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000061,
|
||||
"idDescriptionLongMsg": 1000062,
|
||||
"sType": "tool",
|
||||
"sSubType": "MCH_TF.MILL",
|
||||
"sMessageId": " ",
|
||||
|
||||
@@ -5,9 +5,10 @@
|
||||
|
||||
-- carico librerie
|
||||
local BeamLib = require( 'BeamLib')
|
||||
local BeamData = require( 'BeamData')
|
||||
local BeamData = require( 'BeamDataNew')
|
||||
local MachiningLib = require( 'MachiningLib')
|
||||
local FeatureLib = require( 'FeatureLib')
|
||||
local PreSimulationLib = require( 'PreSimulationLib')
|
||||
-- strategie di base
|
||||
local BladeToWaste = require('BLADETOWASTE')
|
||||
|
||||
@@ -86,6 +87,7 @@ local function GetTenonStrategy( Proc, Part)
|
||||
ToolSearchParameters.dElevation = EgtSurfTmFacetElevationInBBox( Strategy.idTenonCutPlane, 0, Part.b3Part, true, GDB_ID.ROOT)
|
||||
|
||||
ToolSearchParameters.vtToolDirection = Proc.FeatureInfo.vtTenonN
|
||||
ToolSearchParameters.sMillShape = 'STANDARD'
|
||||
ToolSearchParameters.AvailableToolList = MachiningLib.GetAvailableToolList( Proc, Strategy.Parameters.sPocketingList, 'Pocketing')
|
||||
Machining.Cutting.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
|
||||
|
||||
@@ -183,6 +185,23 @@ local function GetTenonStrategy( Proc, Part)
|
||||
Machining.Milling.AuxiliaryData.Clones[nIndexClones].dRadialOffset = ( i - 1) * dRealSideStep
|
||||
end
|
||||
end
|
||||
|
||||
-- test finecorsa sulla passata più esterna: se extracorsa, la lavorazione non è fattibile
|
||||
-- TODO sostituire con applicazione della lavorazione?
|
||||
-- TODO funzione per allungare il percorso??????
|
||||
local idGeomMaxOffset = EgtCopyGlob( Proc.FeatureInfo.idAddAuxGeom, Part.idTempGroup)
|
||||
EgtOffsetCurve( idGeomMaxOffset, Machining.Milling.AuxiliaryData.Clones[1].dRadialOffset + TOOLS[Machining.Milling.ToolInfo.nToolIndex].dDiameter / 2, Part.idTempGroup)
|
||||
local vtCurveStart = EgtSV( idGeomMaxOffset, GDB_ID.ROOT)
|
||||
local vtCurveEnd = EgtEV( idGeomMaxOffset, GDB_ID.ROOT)
|
||||
local ptCurveStart = EgtSP( idGeomMaxOffset, GDB_ID.ROOT) + -vtCurveStart * Machining.Milling.LeadIn.dTangentDistance + ( Proc.FeatureInfo.vtTenonN ^ -vtCurveStart) * Machining.Milling.LeadIn.dPerpDistance
|
||||
local ptCurveEnd = EgtEP( idGeomMaxOffset, GDB_ID.ROOT) + vtCurveEnd * Machining.Milling.LeadOut.dTangentDistance + ( vtCurveEnd ^ Proc.FeatureInfo.vtTenonN) * Machining.Milling.LeadOut.dPerpDistance
|
||||
EgtAddCurveCompoArcTg( idGeomMaxOffset, ptCurveStart, false, GDB_RT.GLOB)
|
||||
EgtAddCurveCompoArcTg( idGeomMaxOffset, ptCurveEnd, true, GDB_RT.GLOB)
|
||||
local bOutOfStroke = PreSimulationLib.CheckOutOfStrokeFromGeometry( idGeomMaxOffset, Proc.FeatureInfo.vtTenonN, Machining.Milling.nSCC, TOOLS[Machining.Milling.ToolInfo.nToolIndex])
|
||||
if bOutOfStroke then
|
||||
Machining.Milling.bIsApplicable = false
|
||||
end
|
||||
|
||||
-- tempo di svuotatura
|
||||
Result.Milling.dTimeToMachine = MachiningLib.GetTimeToMachineAllStepsWithLeadInOut( Machining.Milling, Part)
|
||||
else
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
"sValue": "15",
|
||||
"sDescriptionShort": "Max radius left on corners",
|
||||
"sDescriptionLong": "Radius-limit left by the tool at each corner of the feature",
|
||||
"idDescriptionShortMsg": 1000063,
|
||||
"idDescriptionLongMsg": 1000064,
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -18,16 +20,32 @@
|
||||
"sValue": "false",
|
||||
"sDescriptionShort": "Use Anti-Splint strategy",
|
||||
"sDescriptionLong": "The strategy will apply blade cuts on corner to avoid wood splint",
|
||||
"idDescriptionShortMsg": 1000065,
|
||||
"idDescriptionLongMsg": 1000066,
|
||||
"sType": "b",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
},
|
||||
{
|
||||
"sName": "dExtendAfterTail",
|
||||
"sNameNge": "EXTEND_AFTER_TAIL",
|
||||
"sValue": "",
|
||||
"sDescriptionShort": "Extend after tail",
|
||||
"sDescriptionLong": "The automatism considers this length as machinable. This means you accept to damage the next piece in the bar",
|
||||
"idDescriptionShortMsg": 1000067,
|
||||
"idDescriptionLongMsg": 1000068,
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
},
|
||||
{
|
||||
"sName": "dOpenMinSafe",
|
||||
"sNameNge": "OPENMINSAFE",
|
||||
"sValue": "40",
|
||||
"sValue": "10",
|
||||
"sDescriptionShort": "Minimum approach distance on open sides",
|
||||
"sDescriptionLong": "Minimum approach distance on open sides",
|
||||
"idDescriptionShortMsg": 1000069,
|
||||
"idDescriptionLongMsg": 1000070,
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -38,6 +56,8 @@
|
||||
"sValue": "",
|
||||
"sDescriptionShort": "Available mill to pocket the feature",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000071,
|
||||
"idDescriptionLongMsg": 1000072,
|
||||
"sType": "tool",
|
||||
"sSubType": "MCH_TF.MILL",
|
||||
"sMessageId": " ",
|
||||
|
||||
@@ -16,9 +16,10 @@
|
||||
|
||||
-- carico librerie
|
||||
local BeamLib = require( 'BeamLib')
|
||||
local BeamData = require( 'BeamData')
|
||||
local BeamData = require( 'BeamDataNew')
|
||||
local MachiningLib = require( 'MachiningLib')
|
||||
local FeatureLib = require( 'FeatureLib')
|
||||
local AntiSplintOnFace = require( 'ANTISPLINTONFACE')
|
||||
|
||||
-- Tabella per definizione modulo
|
||||
local STR0002 = {}
|
||||
@@ -26,7 +27,8 @@ local Strategy = {}
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function IsTopologyOk( Proc)
|
||||
if Proc.Topology.sName == 'Pocket-5-Blind' or
|
||||
if Proc.Topology.sFamily == 'PseudoPocket' or
|
||||
Proc.Topology.sName == 'Pocket-5-Blind' or
|
||||
Proc.Topology.sName == 'RafterNotch-5-Through' or
|
||||
Proc.Topology.sName == 'Tunnel-4-Through' or
|
||||
Proc.Topology.sName == 'Groove-4-Blind' or
|
||||
@@ -101,13 +103,13 @@ end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- TODO va gestita meglio la decisione delle facce da lavorare
|
||||
local function GetBestPocketingStrategy( Proc)
|
||||
local function GetBestPocketingStrategy( Proc, Part)
|
||||
-- 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
|
||||
Machining.sTypeMachining = 'None' -- Bottom-Side1-Side2\ Bottom-Bottom2\ Bottom-Side1\ Bottom-Side2\ Side1-Side2\ Bottom\ Side1 \ Side2 \ None
|
||||
Strategy.Result.dQuality = FeatureLib.GetStrategyQuality( 'STD')
|
||||
|
||||
-- caso speciale Tunnel che non ha faccia bottom
|
||||
@@ -120,7 +122,7 @@ local function GetBestPocketingStrategy( Proc)
|
||||
ToolSearchParameters.sType = 'MILL_STD'
|
||||
ToolSearchParameters.dMaxToolDiameter = min( Strategy.Parameters.dMaxCornerRadius * 2, Proc.FeatureInfo.dFaceLength / 2)
|
||||
-- imposto dati per cercare la fresa migliore
|
||||
elseif Proc.Topology.sName == 'Pocket-5-Blind' then
|
||||
elseif Proc.Topology.sName == 'Pocket-5-Blind' or Proc.Topology.sFamily == 'PseudoPocket' then
|
||||
local dFaceWidth, dFaceLength
|
||||
if Proc.MainFaces.BottomFaces[1].MainEdges then
|
||||
dFaceWidth = Proc.MainFaces.BottomFaces[1].MainEdges.LongEdges[1].dLength
|
||||
@@ -170,16 +172,33 @@ local function GetBestPocketingStrategy( Proc)
|
||||
-- cerco utensile per lavorare faccia Bottom
|
||||
Milling.bIsApplicable = false
|
||||
if Proc.Topology.sName ~= 'Tunnel-4-Through' then
|
||||
-- TODO in caso che la faccia crei un piano asportando tutto il materiale, si potrebbe forzare elevazione a zero e scegliere quindi fresa di diametro maggiore.
|
||||
-- Il discorso non vale se la feature viene spezzata o se non ancora separata, in quanto ci sarebbe comunque del materiale da considerare nell'elevazione.
|
||||
-- In quel caso, un 'Bevel-1-Through' è come se fosse un 'Bevel-2-Blind', quindi l'elevazione deve essere considerata.
|
||||
ToolSearchParameters.dElevation = Proc.MainFaces.BottomFaces[1].dElevation
|
||||
ToolSearchParameters.vtToolDirection = Proc.MainFaces.BottomFaces[1].vtN
|
||||
ToolSearchParameters.AvailableToolList = MachiningLib.GetAvailableToolList( Proc, Strategy.Parameters.sPocketingList, 'Pocketing')
|
||||
Milling.idFaceToMachine = Proc.MainFaces.BottomFaces[1].id
|
||||
Milling.bAddAntiSplint = Strategy.Parameters.bAntiSplint
|
||||
Milling.idProc = Proc.id
|
||||
Milling.vtFaceNormal = Proc.MainFaces.BottomFaces[1].vtN
|
||||
Milling.dElevation = Proc.MainFaces.BottomFaces[1].dElevation
|
||||
Milling.ToolInfo = {}
|
||||
Milling.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
|
||||
if Milling.ToolInfo.nToolIndex then
|
||||
-- se faccia singola e feature lavorata in unica lavorazione si può sempre affondare
|
||||
if Proc.Topology.sName == 'Cut-1-Through'
|
||||
or Proc.Topology.sName == 'Bevel-1-Through' then
|
||||
-- eventuali punti di spezzatura
|
||||
local FeatureSplittingPoints = FeatureLib.GetFeatureSplittingPoints( Proc, Part)
|
||||
local bIsSplitFeature = false
|
||||
if #FeatureSplittingPoints > 0 then
|
||||
bIsSplitFeature = true
|
||||
end
|
||||
if not bIsSplitFeature then
|
||||
Milling.ToolInfo.dResidualDepth = 0
|
||||
end
|
||||
end
|
||||
Milling.bIsApplicable = true
|
||||
local ParametersMRR = {}
|
||||
ParametersMRR.nToolIndex = Milling.ToolInfo.nToolIndex
|
||||
@@ -191,13 +210,14 @@ local function GetBestPocketingStrategy( Proc)
|
||||
-- caso speciale 'Rabbet-2-Through' seconda faccia principale
|
||||
Milling = {}
|
||||
Milling.bIsApplicable = false
|
||||
if Proc.Topology.sName == 'Rabbet-2-Through' or Proc.Topology.sName == 'Bevel-2-Blind' or
|
||||
if Proc.Topology.sName == 'Rabbet-2-Through' or Proc.Topology.sName == 'Bevel-2-Blind' or
|
||||
Proc.Topology.sName == 'DoubleBevel-2-Through' or Proc.Topology.sName == 'VGroove-2-Through' then
|
||||
ToolSearchParameters.dElevation = Proc.MainFaces.BottomFaces[2].dElevation
|
||||
ToolSearchParameters.vtToolDirection = Proc.MainFaces.BottomFaces[2].vtN
|
||||
ToolSearchParameters.AvailableToolList = MachiningLib.GetAvailableToolList( Proc, Strategy.Parameters.sPocketingList, 'Pocketing')
|
||||
Milling.vtFaceNormal = Proc.MainFaces.BottomFaces[2].vtN
|
||||
Milling.idFaceToMachine = Proc.MainFaces.BottomFaces[2].id
|
||||
Milling.bAddAntiSplint = Strategy.Parameters.bAntiSplint
|
||||
Milling.idProc = Proc.id
|
||||
Milling.dElevation = Proc.MainFaces.BottomFaces[2].dElevation
|
||||
Milling.ToolInfo = {}
|
||||
@@ -214,7 +234,7 @@ local function GetBestPocketingStrategy( Proc)
|
||||
-- cerco utensile per lavorare di fianco 1
|
||||
Milling = {}
|
||||
Milling.bIsApplicable = false
|
||||
if Proc.Topology.sName ~= 'DoubleBevel-2-Through'
|
||||
if Proc.Topology.sName ~= 'DoubleBevel-2-Through' and Proc.Topology.sFamily ~= 'PseudoPocket'
|
||||
and Proc.Topology.sName ~= 'Pocket-5-Blind' and Proc.Topology.sName ~= 'RafterNotch-5-Through' then
|
||||
|
||||
if Proc.Topology.sName == 'Groove-4-Blind' then
|
||||
@@ -225,12 +245,21 @@ local function GetBestPocketingStrategy( Proc)
|
||||
Milling.idProc = Proc.id
|
||||
Milling.dElevation = Proc.MainFaces.BottomFaces[2].dElevation
|
||||
elseif Proc.Topology.sName == 'Groove-3-Blind' or Proc.Topology.sName == 'Bevel-3-Blind' then
|
||||
ToolSearchParameters.dElevation = Proc.MainFaces.LongFaces[1].dElevation
|
||||
ToolSearchParameters.vtToolDirection = Proc.MainFaces.LongFaces[1].vtN
|
||||
Milling.vtFaceNormal = Proc.MainFaces.LongFaces[1].vtN
|
||||
Milling.idFaceToMachine = Proc.MainFaces.LongFaces[1].id
|
||||
Milling.idProc = Proc.id
|
||||
Milling.dElevation = Proc.MainFaces.LongFaces[1].dElevation
|
||||
if Proc.MainFaces.LongFaces and Proc.MainFaces.LongFaces[1] then
|
||||
ToolSearchParameters.dElevation = Proc.MainFaces.LongFaces[1].dElevation
|
||||
ToolSearchParameters.vtToolDirection = Proc.MainFaces.LongFaces[1].vtN
|
||||
Milling.vtFaceNormal = Proc.MainFaces.LongFaces[1].vtN
|
||||
Milling.idFaceToMachine = Proc.MainFaces.LongFaces[1].id
|
||||
Milling.idProc = Proc.id
|
||||
Milling.dElevation = Proc.MainFaces.LongFaces[1].dElevation
|
||||
elseif Proc.MainFaces.BottomFaces[2] then
|
||||
ToolSearchParameters.dElevation = Proc.MainFaces.BottomFaces[2].dElevation
|
||||
ToolSearchParameters.vtToolDirection = Proc.MainFaces.BottomFaces[2].vtN
|
||||
Milling.vtFaceNormal = Proc.MainFaces.BottomFaces[2].vtN
|
||||
Milling.idFaceToMachine = Proc.MainFaces.BottomFaces[2].id
|
||||
Milling.idProc = Proc.id
|
||||
Milling.dElevation = Proc.MainFaces.BottomFaces[2].dElevation
|
||||
end
|
||||
elseif Proc.MainFaces.TunnelAddedFaces then -- 'Tunnel-4-Through', 'Groove-3-Through', 'Rabbet-2-Through', 'VGroove-2-Through', 'Bevel-2-Blind'
|
||||
-- se lavoro di fianco, devo comunque rispettare il raggio massimo
|
||||
ToolSearchParameters.dMaxToolDiameter = min( ToolSearchParameters.dMaxToolDiameter, Strategy.Parameters.dMaxCornerRadius * 2)
|
||||
@@ -241,6 +270,8 @@ local function GetBestPocketingStrategy( Proc)
|
||||
Milling.idProc = Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.id
|
||||
Milling.dElevation = ( Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].dElevation * 2) + BeamData.MILL_OVERLAP
|
||||
Milling.bMachAppliedToTunnelFace = true
|
||||
else
|
||||
ToolSearchParameters.vtToolDirection = nil
|
||||
end
|
||||
ToolSearchParameters.AvailableToolList = MachiningLib.GetAvailableToolList( Proc, Strategy.Parameters.sPocketingList, 'Pocketing')
|
||||
Milling.ToolInfo = {}
|
||||
@@ -250,6 +281,19 @@ local function GetBestPocketingStrategy( Proc)
|
||||
local ParametersMRR = {}
|
||||
ParametersMRR.nToolIndex = Milling.ToolInfo.nToolIndex
|
||||
Milling.dMRR = MachiningLib.GetToolMRR( ParametersMRR)
|
||||
-- se la faccia tunnel è troppo piccola non si lavora
|
||||
if Milling.bMachAppliedToTunnelFace then
|
||||
local dLongestEdgeLength = 0
|
||||
for i = 1, #Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].Edges do
|
||||
if Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].Edges[i].dLength > dLongestEdgeLength + 10 * GEO.EPS_SMALL then
|
||||
dLongestEdgeLength = Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].Edges[i].dLength
|
||||
end
|
||||
end
|
||||
if dLongestEdgeLength < TOOLS[Milling.ToolInfo.nToolIndex].dDiameter then
|
||||
Milling.bIsApplicable = false
|
||||
ParametersMRR = {}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
table.insert( Machining, Milling)
|
||||
@@ -259,6 +303,7 @@ local function GetBestPocketingStrategy( Proc)
|
||||
Milling.bIsApplicable = false
|
||||
if Proc.Topology.sName ~= 'DoubleBevel-2-Through'
|
||||
and Proc.Topology.sName ~= 'Pocket-5-Blind'
|
||||
and Proc.Topology.sFamily ~= 'PseudoPocket'
|
||||
and Proc.Topology.sName ~= 'RafterNotch-5-Through'
|
||||
and Proc.Topology.sName ~= 'Groove-4-Blind'
|
||||
and Proc.Topology.sName ~= 'Bevel-3-Blind' then
|
||||
@@ -281,6 +326,8 @@ local function GetBestPocketingStrategy( Proc)
|
||||
Milling.idFaceToMachine = Proc.MainFaces.SideFaces[1].id
|
||||
Milling.idProc = Proc.id
|
||||
Milling.dElevation = Proc.MainFaces.SideFaces[1].dElevation
|
||||
else
|
||||
ToolSearchParameters.vtToolDirection = nil
|
||||
end
|
||||
ToolSearchParameters.AvailableToolList = MachiningLib.GetAvailableToolList( Proc, Strategy.Parameters.sPocketingList, 'Pocketing')
|
||||
Milling.ToolInfo = {}
|
||||
@@ -290,13 +337,60 @@ local function GetBestPocketingStrategy( Proc)
|
||||
local ParametersMRR = {}
|
||||
ParametersMRR.nToolIndex = Milling.ToolInfo.nToolIndex
|
||||
Milling.dMRR = MachiningLib.GetToolMRR( ParametersMRR)
|
||||
-- se la faccia tunnel è troppo piccola non si lavora
|
||||
if Milling.bMachAppliedToTunnelFace then
|
||||
local dLongestEdgeLength = 0
|
||||
for i = 1, #Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].Edges do
|
||||
if Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].Edges[i].dLength > dLongestEdgeLength + 10 * GEO.EPS_SMALL then
|
||||
dLongestEdgeLength = Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].Edges[i].dLength
|
||||
end
|
||||
end
|
||||
if dLongestEdgeLength < TOOLS[Milling.ToolInfo.nToolIndex].dDiameter then
|
||||
Milling.bIsApplicable = false
|
||||
ParametersMRR = {}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
table.insert( Machining, Milling)
|
||||
|
||||
-- ===== SCELTA LAVORAZIONI =====
|
||||
-- TODO per DoubleBevel-2-Through si potrebbe lavorare la faccia tunnel su ogni faccia. Bisogna calcolarla!!
|
||||
-- caso speciale DoubleBevel-2-Through bisogna lavorare entrambe le bottom
|
||||
if Proc.Topology.sName == 'DoubleBevel-2-Through' then
|
||||
-- se entrambe applicabili significa che è completo
|
||||
if Machining[1].bIsApplicable and Machining[2].bIsApplicable then
|
||||
Machining.sTypeMachining = 'Bottom-Bottom2'
|
||||
Strategy.Result.sStatus = 'Completed'
|
||||
Strategy.Result.dCompletionIndex = FeatureLib.GetFeatureCompletionIndex( 100)
|
||||
Strategy.Result.dMRR = Machining[1].dMRR + Machining[2].dMRR / 2
|
||||
Machining[1].ToolInfo.dResidualDepth = 0
|
||||
Machining[2].ToolInfo.dResidualDepth = 0
|
||||
return Machining
|
||||
else
|
||||
local dMachinedPrercentage = 0
|
||||
-- se applicabile solo Bottom
|
||||
if Machining[1].bIsApplicable then
|
||||
Machining.sTypeMachining = 'Bottom'
|
||||
Strategy.Result.sStatus = 'Not-Completed'
|
||||
Machining[1].ToolInfo.dResidualDepth = 0
|
||||
Strategy.Result.dMRR = Machining[1].dMRR
|
||||
dMachinedPrercentage = ( Machining[1].dElevation / ( Machining[1].dElevation + Machining[2].dElevation)) * 100
|
||||
Strategy.Result.dCompletionIndex = FeatureLib.GetFeatureCompletionIndex( dMachinedPrercentage)
|
||||
-- se applicabile solo Bottom2
|
||||
elseif Machining[2].bIsApplicable then
|
||||
Machining.sTypeMachining = 'Bottom2'
|
||||
Strategy.Result.sStatus = 'Not-Completed'
|
||||
Machining[2].ToolInfo.dResidualDepth = 0
|
||||
Strategy.Result.dMRR = Machining[2].dMRR
|
||||
dMachinedPrercentage = ( Machining[2].dElevation / ( Machining[1].dElevation + Machining[2].dElevation)) * 100
|
||||
Strategy.Result.dCompletionIndex = FeatureLib.GetFeatureCompletionIndex( dMachinedPrercentage)
|
||||
end
|
||||
Strategy.Result.sInfo = 'Machining not complete, left ' .. tostring( 100 - ceil( dMachinedPrercentage)) .. '%'
|
||||
end
|
||||
return Machining
|
||||
-- se bottom completa tutto
|
||||
if Machining[1].bIsApplicable and Machining[1].ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then
|
||||
elseif Machining[1].bIsApplicable and Machining[1].ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then
|
||||
Machining.sTypeMachining = 'Bottom'
|
||||
Strategy.Result.sStatus = 'Completed'
|
||||
Strategy.Result.dCompletionIndex = FeatureLib.GetFeatureCompletionIndex( 100)
|
||||
@@ -308,10 +402,10 @@ local function GetBestPocketingStrategy( Proc)
|
||||
if ( Proc.nFct == 2 and Proc.AdjacencyMatrix[1][2] >= -89.9)
|
||||
and Machining[2].bIsApplicable and Machining[2].ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then
|
||||
|
||||
Machining.sTypeMachining = 'Bottom2'
|
||||
Machining.sTypeMachining = 'Bottom-Bottom2'
|
||||
Strategy.Result.sStatus = 'Completed'
|
||||
Strategy.Result.dCompletionIndex = FeatureLib.GetFeatureCompletionIndex( 100)
|
||||
Strategy.Result.dMRR = Machining[2].dMRR
|
||||
Strategy.Result.dMRR = Machining[1].dMRR + Machining[2].dMRR / 2
|
||||
Machining[2].ToolInfo.dResidualDepth = 0
|
||||
else
|
||||
Machining[2].bIsApplicable = false
|
||||
@@ -428,7 +522,12 @@ end
|
||||
local function GetSplitSurfaces( Proc, Part, bAddMachining)
|
||||
local vAddId = {}
|
||||
local vAddIdTunnel = {}
|
||||
local nAddGrpId = BeamLib.GetAddGroup( Part.id)
|
||||
local idAddGroup
|
||||
if bAddMachining then
|
||||
idAddGroup = BeamLib.GetAddGroup( Part.id)
|
||||
else
|
||||
idAddGroup = Part.idTempGroup
|
||||
end
|
||||
local nOriginalTmIdTunnel = GDB_ID.NULL
|
||||
if Proc.MainFaces.TunnelAddedFaces then
|
||||
nOriginalTmIdTunnel = Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.id
|
||||
@@ -438,18 +537,14 @@ local function GetSplitSurfaces( Proc, Part, bAddMachining)
|
||||
local FeatureSplittingPoints = FeatureLib.GetFeatureSplittingPoints( Proc, Part)
|
||||
|
||||
if #FeatureSplittingPoints == 0 then
|
||||
local nAddId = EgtCopyGlob( Proc.id, nAddGrpId) or GDB_ID.NULL
|
||||
local nAddIdTunnel = EgtCopyGlob( nOriginalTmIdTunnel, nAddGrpId) or GDB_ID.NULL
|
||||
if not bAddMachining then
|
||||
EgtSetLevel( nAddId, GDB_LV.TEMP)
|
||||
EgtSetLevel( nAddIdTunnel, GDB_LV.TEMP)
|
||||
end
|
||||
local nAddId = EgtCopyGlob( Proc.id, idAddGroup) or GDB_ID.NULL
|
||||
local nAddIdTunnel = EgtCopyGlob( nOriginalTmIdTunnel, idAddGroup) or GDB_ID.NULL
|
||||
table.insert( vAddId, nAddId)
|
||||
table.insert( vAddIdTunnel, nAddIdTunnel)
|
||||
else
|
||||
for i = 1, #FeatureSplittingPoints do
|
||||
local nAddId = EgtCopyGlob( Proc.id, nAddGrpId) or GDB_ID.NULL
|
||||
local nAddIdTunnel = EgtCopyGlob( nOriginalTmIdTunnel, nAddGrpId) or GDB_ID.NULL
|
||||
local nAddId = EgtCopyGlob( Proc.id, idAddGroup) or GDB_ID.NULL
|
||||
local nAddIdTunnel = EgtCopyGlob( nOriginalTmIdTunnel, idAddGroup) or GDB_ID.NULL
|
||||
if i == 1 then
|
||||
-- prima superficie, va tagliata solo a sinistra
|
||||
local ptSplit = FeatureSplittingPoints[i] + Vector3d( -BeamData.MILL_OVERLAP / 2, 0, 0)
|
||||
@@ -465,23 +560,15 @@ local function GetSplitSurfaces( Proc, Part, bAddMachining)
|
||||
EgtCutSurfTmPlane( nAddId, ptSplit, X_AX(), true, GDB_RT.GLOB)
|
||||
EgtCutSurfTmPlane( nAddIdTunnel, ptSplit, X_AX(), true, GDB_RT.GLOB)
|
||||
end
|
||||
if not bAddMachining then
|
||||
EgtSetLevel( nAddId, GDB_LV.TEMP)
|
||||
EgtSetLevel( nAddIdTunnel, GDB_LV.TEMP)
|
||||
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 nAddId = EgtCopyGlob( Proc.id, idAddGroup) or GDB_ID.NULL
|
||||
local nAddIdTunnel = EgtCopyGlob( nOriginalTmIdTunnel, idAddGroup) or GDB_ID.NULL
|
||||
local ptSplit = FeatureSplittingPoints[#FeatureSplittingPoints] + 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)
|
||||
if not bAddMachining then
|
||||
EgtSetLevel( nAddId, GDB_LV.TEMP)
|
||||
EgtSetLevel( nAddIdTunnel, GDB_LV.TEMP)
|
||||
end
|
||||
table.insert( vAddId, nAddId)
|
||||
table.insert( vAddIdTunnel, nAddIdTunnel)
|
||||
end
|
||||
@@ -501,19 +588,27 @@ function STR0002.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
Strategy.Result = {}
|
||||
Strategy.Result.dTimeToMachine = 0
|
||||
|
||||
-- se la lavorazione ostacola il pinzaggio, non posso farla
|
||||
if not IsTopologyOk( Proc) then
|
||||
local sErr = 'Feature '.. Proc.idFeature .. ' : strategy ' .. StrategyLib.Config.sStrategyId .. ' not implemented'
|
||||
EgtOutLog( sErr)
|
||||
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( sErr)
|
||||
return false, Strategy.Result
|
||||
end
|
||||
-- se la lavorazione ostacola il pinzaggio, non posso farla, serve una lavorazioen che lasci il testimone
|
||||
if MachiningLib.IsFeatureHinderingClamping( Proc, Part) then
|
||||
local sErr = 'Feature '.. Proc.idFeature .. ' : strategy ' .. StrategyLib.Config.sStrategyId .. ' not applicable ( Feature hinders clamping)'
|
||||
EgtOutLog( sErr)
|
||||
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( sErr)
|
||||
return false, Strategy.Result
|
||||
end
|
||||
|
||||
local bAreAllMachiningsAdded = true
|
||||
local dFeatureVolume = FeatureLib.GetFeatureVolume( Proc, Part)
|
||||
local dFeatureVolume = Proc.dVolume
|
||||
local ToolInfo = {}
|
||||
local Pocketing = {}
|
||||
|
||||
Strategy.Machining = GetBestPocketingStrategy( Proc)
|
||||
Strategy.Machining = GetBestPocketingStrategy( Proc, Part)
|
||||
|
||||
if Strategy.Result.sStatus ~= 'Not-Applicable' then
|
||||
local vAddId = {}
|
||||
@@ -535,8 +630,8 @@ function STR0002.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
Pocketing.Steps.dStep = TOOLS[Strategy.Machining[j].ToolInfo.nToolIndex].dStep
|
||||
Pocketing.Steps.dSideStep = TOOLS[Strategy.Machining[j].ToolInfo.nToolIndex].dSideStep
|
||||
Pocketing.nToolIndex = Strategy.Machining[j].ToolInfo.nToolIndex
|
||||
Pocketing.LeadIn.dTangentDistance = TOOLS[Strategy.Machining[j].ToolInfo.nToolIndex].dDiameter/2
|
||||
Pocketing.LeadIn.dElevation = TOOLS[Strategy.Machining[j].ToolInfo.nToolIndex].dDiameter/2
|
||||
Pocketing.LeadIn.dTangentDistance = TOOLS[Strategy.Machining[j].ToolInfo.nToolIndex].dDiameter / 2
|
||||
Pocketing.LeadIn.dElevation = TOOLS[Strategy.Machining[j].ToolInfo.nToolIndex].dDiameter / 2
|
||||
Pocketing.sDepth = -Strategy.Machining[j].ToolInfo.dResidualDepth
|
||||
Pocketing.dResidualDepth = Strategy.Machining[j].ToolInfo.dResidualDepth
|
||||
-- TODO vedere se questo parametro con svuotature nuove si può rimuovere
|
||||
@@ -545,11 +640,35 @@ function STR0002.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
if Strategy.Machining[j].bToolInvert then
|
||||
Pocketing.bToolInvert = true
|
||||
end
|
||||
-- eventuali antischeggia
|
||||
if Strategy.Machining[j].bAddAntiSplint then
|
||||
local OptionalParametersAntiSplint = {
|
||||
bIsSplitFeature = ( #vAddId > 1),
|
||||
dExtendAfterTail = Strategy.Parameters.dExtendAfterTail
|
||||
}
|
||||
local AntiSplints = AntiSplintOnFace.Make( Proc, Part, Proc.Faces[ Strategy.Machining[j].idFaceToMachine + 1], OptionalParametersAntiSplint)
|
||||
local bAreAllAntisplintsApplicable = true
|
||||
for k = 1, #AntiSplints do
|
||||
if AntiSplints[k].bIsApplicable then
|
||||
if bAddMachining then
|
||||
bAreAllMachiningsAdded = MachiningLib.AddMachinings( Proc, AntiSplints[k])
|
||||
end
|
||||
else
|
||||
bAreAllAntisplintsApplicable = false
|
||||
end
|
||||
end
|
||||
if bAreAllAntisplintsApplicable then
|
||||
-- TODO qui si dovrà distinguere tra antischeggia di lama e di fresa; al momento è solo di lama
|
||||
if Strategy.Result.dQuality == FeatureLib.GetStrategyQuality( 'STD') then
|
||||
Strategy.Result.dQuality = FeatureLib.GetStrategyQuality( 'BEST')
|
||||
end
|
||||
end
|
||||
end
|
||||
-- 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}}
|
||||
Pocketing.vtToolDirection = Strategy.Machining[j].vtFaceNormal
|
||||
|
||||
|
||||
-- TODO controllare parametro danneggiamento ammesso per decidere se spostare dopo taglio seprazione
|
||||
-- se è aperta sulla coda, dico che deve essere fatta dopo la separazione
|
||||
if Proc.AffectedFaces.bLeft then
|
||||
@@ -579,10 +698,10 @@ function STR0002.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
end
|
||||
if vtNSplitFace and AreSameVectorApprox( vtNSplitFace * EgtIf( Pocketing.bToolInvert, -1, 1), Strategy.Machining[j].vtFaceNormal) then
|
||||
Pocketing.Geometry = {{ nIdTm, k - 1}}
|
||||
|
||||
|
||||
Pocketing.dTimeToMachine = MachiningLib.GetTimeToMachineAllStepsWithLeadInOut( Pocketing, Part)
|
||||
Strategy.Result.dTimeToMachine = Strategy.Result.dTimeToMachine + Pocketing.dTimeToMachine
|
||||
|
||||
|
||||
if bAddMachining then
|
||||
bAreAllMachiningsAdded = bAreAllMachiningsAdded and MachiningLib.AddMachinings( Proc, Pocketing)
|
||||
end
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
"sValue": "true",
|
||||
"sDescriptionShort": "Finish with chainsaw if needed",
|
||||
"sDescriptionLong": "Finish with chainsaw if needed",
|
||||
"idDescriptionShortMsg": 1000073,
|
||||
"idDescriptionLongMsg": 1000074,
|
||||
"sType": "b",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -17,7 +19,9 @@
|
||||
"sNameNge": "EXTEND_AFTER_TAIL",
|
||||
"sValue": "",
|
||||
"sDescriptionShort": "Extend after tail",
|
||||
"sDescriptionLong": "The automatism considers this lenght as machinable. This means you accept to damage the next piece in the bar",
|
||||
"sDescriptionLong": "The automatism considers this length as machinable. This means you accept to damage the next piece in the bar",
|
||||
"idDescriptionShortMsg": 1000075,
|
||||
"idDescriptionLongMsg": 1000076,
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -28,6 +32,8 @@
|
||||
"sValue": "false",
|
||||
"sDescriptionShort": "Force ripping blade",
|
||||
"sDescriptionLong": "Force the use of ripping blade, designed for cuts parallel to the grain",
|
||||
"idDescriptionShortMsg": 1000077,
|
||||
"idDescriptionLongMsg": 1000078,
|
||||
"sType": "b",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -38,6 +44,8 @@
|
||||
"sValue": "true",
|
||||
"sDescriptionShort": "Not complete with Blade radius imprint left",
|
||||
"sDescriptionLong": "If the parameter is active, the automatism considers the feature as - not complete - if the blade radius imprint is left",
|
||||
"idDescriptionShortMsg": 1000079,
|
||||
"idDescriptionLongMsg": 1000080,
|
||||
"sType": "b",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -48,6 +56,8 @@
|
||||
"sValue": "false",
|
||||
"sDescriptionShort": "Use Zig-Zag ChainSaw",
|
||||
"sDescriptionLong": "Enable the parameter to set the Zig-Zag movement on the ChainSaw machining. Deactivate it to use One-Way movement.",
|
||||
"idDescriptionShortMsg": 1000081,
|
||||
"idDescriptionLongMsg": 1000082,
|
||||
"sType": "b",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -58,6 +68,8 @@
|
||||
"sValue": "true",
|
||||
"sDescriptionShort": "Sort by segment",
|
||||
"sDescriptionLong": "Sort the machinings according to the piece-segment where the machining has inserted",
|
||||
"idDescriptionShortMsg": 1000083,
|
||||
"idDescriptionLongMsg": 1000084,
|
||||
"sType": "b",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -68,6 +80,8 @@
|
||||
"sValue": "NEVER",
|
||||
"sDescriptionShort": "Damage next piece",
|
||||
"sDescriptionLong": "This option allows you to decide how to consider the next piece in the bar. The software calculates specifics LeadIn/out to respect the parameter. This parameter may change the machining time",
|
||||
"idDescriptionShortMsg": 1000085,
|
||||
"idDescriptionLongMsg": 1000086,
|
||||
"sType": "combo",
|
||||
"sMinUserLevel": "1",
|
||||
"Choices": [
|
||||
@@ -75,18 +89,24 @@
|
||||
"sValue": "NEVER",
|
||||
"sDescriptionShort": "Never damage",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000087,
|
||||
"idDescriptionLongMsg": 1000088,
|
||||
"sMessageId": ""
|
||||
},
|
||||
{
|
||||
"sValue": "ONLY_IF_RAWPART",
|
||||
"sDescriptionShort": "Damage only if raw",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000089,
|
||||
"idDescriptionLongMsg": 1000090,
|
||||
"sMessageId": ""
|
||||
},
|
||||
{
|
||||
"sValue": "ALWAYS",
|
||||
"sDescriptionShort": "Can damage",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000091,
|
||||
"idDescriptionLongMsg": 1000092,
|
||||
"sMessageId": ""
|
||||
}
|
||||
]
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
-- carico librerie
|
||||
local BeamLib = require( 'BeamLib')
|
||||
local BeamData = require( 'BeamData')
|
||||
local BeamData = require( 'BeamDataNew')
|
||||
local MachiningLib = require( 'MachiningLib')
|
||||
local FeatureLib = require( 'FeatureLib')
|
||||
-- strategie di base
|
||||
@@ -35,12 +35,19 @@ 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
|
||||
|
||||
-- canale ammesso solo se lati paralleli a 2 a 2
|
||||
elseif Proc.Topology.sName == 'Groove-3-Through'
|
||||
and ( AreOppositeVectorApprox( Proc.MainFaces.BottomFaces[1].MainEdges.LongEdges[1].vtN, Proc.MainFaces.BottomFaces[1].MainEdges.LongEdges[2].vtN)) then
|
||||
|
||||
return true
|
||||
|
||||
else
|
||||
|
||||
return false
|
||||
end
|
||||
end
|
||||
@@ -188,6 +195,17 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
Blade.Result = {}
|
||||
Chainsaw.Result = {}
|
||||
|
||||
|
||||
-- se arriva una feature senza MainFaces o MainEdges necessari la strategia non è applicabile
|
||||
-- TODO riuniure a IsTopologyOk?
|
||||
if not Proc.MainFaces
|
||||
or not Proc.MainFaces.LongFaces[1]
|
||||
or not Proc.MainFaces.LongFaces[1].MainEdges then
|
||||
|
||||
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( 'Topology')
|
||||
return false, Strategy.Result
|
||||
end
|
||||
|
||||
if not IsTopologyOk( Proc) then
|
||||
local sErr = 'Feature '.. Proc.idFeature .. ' : strategy ' .. Strategy.sName .. ' not implemented'
|
||||
EgtOutLog( sErr)
|
||||
@@ -195,13 +213,15 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
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)
|
||||
-- TODO se OnlySaw questo test è da rimuovere ma bisogna considerare anche la lama 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 = FeatureLib.GetStrategyResultNotApplicable( 'Direction')
|
||||
return false, Strategy.Result
|
||||
-- se canale e lati non a 90deg la strategia non è applicabile
|
||||
-- TODO questo è temporaneo finchè non si gestiscono correttamente i lati obliqui per le groove-3-through
|
||||
-- la dPocketHeight è già gestita, ma va allungato il percorso dove c'è l'angolo > 90
|
||||
if Proc.Topology.sName == 'Groove-3-Through' then
|
||||
local BottomFace = Proc.MainFaces.BottomFaces[1]
|
||||
if abs( BottomFace.Edges[1].vtEdge * BottomFace.Edges[2].vtEdge) > 10 * GEO.EPS_SMALL then
|
||||
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( 'Topology')
|
||||
return false, Strategy.Result
|
||||
end
|
||||
end
|
||||
|
||||
local dExtendAfterTail = Strategy.Parameters.dExtendAfterTail or max( Part.dDistanceToNextPiece - BeamData.CUT_EXTRA, 0)
|
||||
@@ -210,7 +230,7 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
end
|
||||
|
||||
-- volume della feature
|
||||
local dFeatureVolume = FeatureLib.GetFeatureVolume( Proc, Part)
|
||||
local dFeatureVolume = Proc.dVolume
|
||||
|
||||
-- eventuali punti di spezzatura
|
||||
local FeatureSplittingPoints = FeatureLib.GetFeatureSplittingPoints( Proc, Part)
|
||||
@@ -223,6 +243,11 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
local dPocketHeight = 0
|
||||
if Proc.Topology.sFamily == 'Tunnel' then
|
||||
dPocketHeight = Proc.MainFaces.SideFaces[1].MainEdges.OppositeEdges[1].dLength
|
||||
elseif Proc.Topology.sName == 'Groove-3-Through' then
|
||||
local BottomFace = Proc.MainFaces.BottomFaces[1]
|
||||
local frFrame = Frame3d( BottomFace.ptCenter, BottomFace.vtN, BottomFace.MainEdges.LongEdges[1].vtEdge)
|
||||
local b3BottomFace = EgtSurfTmGetFacetBBoxRef( Proc.id, BottomFace.id, GDB_BB.STANDARD, frFrame)
|
||||
dPocketHeight = b3BottomFace:getDimY()
|
||||
else
|
||||
dPocketHeight = Proc.MainFaces.BottomFaces[1].MainEdges.SideEdges[1].dLength
|
||||
end
|
||||
@@ -236,6 +261,7 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
local BottomEdge = LongFace.MainEdges.BottomEdge
|
||||
|
||||
-- TODO funzione separata
|
||||
-- TODO è meglio cercare la lama qui e passarla alla FACEBYBLADE, la scelta è più precisa
|
||||
-- lama - calcolo lavorazioni
|
||||
local Cutting = {}
|
||||
-- parametri comuni a tutte le lavorazioni cutting
|
||||
@@ -243,8 +269,7 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
bForceLongcutBlade = Strategy.Parameters.bForceLongcutBlade,
|
||||
dExtendAfterTail = dExtendAfterTail,
|
||||
dPocketHeight = dPocketHeight,
|
||||
bIsSplitFeature = bIsSplitFeature,
|
||||
dMinNzDownUp = 0
|
||||
bIsSplitFeature = bIsSplitFeature
|
||||
}
|
||||
|
||||
-- primo lato del tunnel o lato di fondo
|
||||
@@ -390,7 +415,8 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
end
|
||||
|
||||
-- ancora materiale residuo - se possibile si lavora dal lato
|
||||
if Chainsaw.Result.Bottom[#Chainsaw.Result.Bottom].dResidualDepth > 10 * GEO.EPS_SMALL
|
||||
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
|
||||
|
||||
-- si lavora solamente l'impronta lama sul fondo
|
||||
@@ -673,7 +699,13 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
else
|
||||
Strategy.Result.sStatus = 'Not-Completed'
|
||||
end
|
||||
Strategy.Result.dQuality = FeatureLib.GetStrategyQuality( Result)
|
||||
|
||||
if Proc.Topology.sName == 'Groove-4-Blind' or Proc.Topology.sName == 'Pocket-5-Blind' then
|
||||
Strategy.Result.dQuality = FeatureLib.GetStrategyQuality( 'SEMI')
|
||||
else
|
||||
Strategy.Result.dQuality = FeatureLib.GetStrategyQuality( Result)
|
||||
end
|
||||
|
||||
Strategy.Result.dTimeToMachine = FeatureLib.GetStrategyTimeToMachine( Result)
|
||||
Strategy.Result.dMRR = ( dFeatureVolume / Strategy.Result.dTimeToMachine) / pow( 10, 6)
|
||||
else
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
"sValue": "false",
|
||||
"sDescriptionShort": "Use Zig-Zag ChainSaw",
|
||||
"sDescriptionLong": "Enable the parameter to set the Zig-Zag movement on the ChainSaw machining. Deactivate it to use One-Way movement.",
|
||||
"idDescriptionShortMsg": 1000093,
|
||||
"idDescriptionLongMsg": 1000094,
|
||||
"sType": "b",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -17,7 +19,9 @@
|
||||
"sNameNge": "EXTEND_AFTER_TAIL",
|
||||
"sValue": "",
|
||||
"sDescriptionShort": "Extend after tail",
|
||||
"sDescriptionLong": "The automatism considers this lenght as machinable. This means you accept to damage the next piece in the bar",
|
||||
"sDescriptionLong": "The automatism considers this length as machinable. This means you accept to damage the next piece in the bar",
|
||||
"idDescriptionShortMsg": 1000095,
|
||||
"idDescriptionLongMsg": 1000096,
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -28,6 +32,8 @@
|
||||
"sValue": "NEVER",
|
||||
"sDescriptionShort": "Damage next piece",
|
||||
"sDescriptionLong": "This option allows you to decide how to consider the next piece in the bar. The software calculates specifics LeadIn/out to respect the parameter. This parameter may change the machining time",
|
||||
"idDescriptionShortMsg": 1000097,
|
||||
"idDescriptionLongMsg": 1000098,
|
||||
"sType": "combo",
|
||||
"sMinUserLevel": "1",
|
||||
"Choices": [
|
||||
@@ -35,18 +41,24 @@
|
||||
"sValue": "NEVER",
|
||||
"sDescriptionShort": "Never damage",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000099,
|
||||
"idDescriptionLongMsg": 1000100,
|
||||
"sMessageId": ""
|
||||
},
|
||||
{
|
||||
"sValue": "ONLY_IF_RAWPART",
|
||||
"sDescriptionShort": "Damage only if raw",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000101,
|
||||
"idDescriptionLongMsg": 1000102,
|
||||
"sMessageId": ""
|
||||
},
|
||||
{
|
||||
"sValue": "ALWAYS",
|
||||
"sDescriptionShort": "Can damage",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000103,
|
||||
"idDescriptionLongMsg": 1000104,
|
||||
"sMessageId": ""
|
||||
}
|
||||
]
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
-- carico librerie
|
||||
local BeamLib = require( 'BeamLib')
|
||||
local BeamData = require( 'BeamData')
|
||||
local BeamData = require( 'BeamDataNew')
|
||||
local MachiningLib = require( 'MachiningLib')
|
||||
local FeatureLib = require( 'FeatureLib')
|
||||
-- strategie di base
|
||||
@@ -112,20 +112,10 @@ function STR0004.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
Chainsaw.Result = {}
|
||||
|
||||
if not IsTopologyOk( Proc) then
|
||||
local sErr = 'Feature '.. Proc.idFeature .. ' : strategy ' .. Strategy.sName .. ' not implemented'
|
||||
EgtOutLog( sErr)
|
||||
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( '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 = FeatureLib.GetStrategyResultNotApplicable( 'Direction')
|
||||
return false, Strategy.Result
|
||||
end
|
||||
|
||||
-- calcolo estensione oltre la coda
|
||||
local dExtendAfterTail = Strategy.Parameters.dExtendAfterTail or max( Part.dDistanceToNextPiece - BeamData.CUT_EXTRA, 0)
|
||||
if MachiningLib.CanExtendAfterTail( Strategy.Parameters.sCanDamageNextPiece, Part) then
|
||||
@@ -133,7 +123,7 @@ function STR0004.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
end
|
||||
|
||||
-- volume della feature
|
||||
local dFeatureVolume = FeatureLib.GetFeatureVolume( Proc, Part)
|
||||
local dFeatureVolume = Proc.dVolume
|
||||
|
||||
-- eventuali punti di spezzatura
|
||||
local FeatureSplittingPoints = FeatureLib.GetFeatureSplittingPoints( Proc, Part)
|
||||
@@ -142,10 +132,25 @@ function STR0004.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
bIsSplitFeature = true
|
||||
end
|
||||
|
||||
-- se arriva una feature senza MainFaces o MainEdges necessari la strategia non è applicabile
|
||||
-- TODO riuniure a IsTopologyOk?
|
||||
if not Proc.MainFaces
|
||||
or not Proc.MainFaces.LongFaces[1]
|
||||
or not Proc.MainFaces.LongFaces[1].MainEdges then
|
||||
|
||||
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( 'Topology')
|
||||
return false, Strategy.Result
|
||||
end
|
||||
|
||||
-- altezza tasca
|
||||
local dPocketHeight = 0
|
||||
if Proc.Topology.sFamily == 'Tunnel' then
|
||||
dPocketHeight = Proc.MainFaces.SideFaces[1].MainEdges.OppositeEdges[1].dLength
|
||||
elseif Proc.Topology.sName == 'Groove-3-Through' then
|
||||
local BottomFace = Proc.MainFaces.BottomFaces[1]
|
||||
local frFrame = Frame3d( BottomFace.ptCenter, BottomFace.vtN, BottomFace.MainEdges.LongEdges[1].vtEdge)
|
||||
local b3BottomFace = EgtSurfTmGetFacetBBoxRef( Proc.id, BottomFace.id, GDB_BB.STANDARD, frFrame)
|
||||
dPocketHeight = b3BottomFace:getDimY()
|
||||
else
|
||||
dPocketHeight = Proc.MainFaces.BottomFaces[1].MainEdges.SideEdges[1].dLength
|
||||
end
|
||||
@@ -167,6 +172,7 @@ function STR0004.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
bIsSplitFeature = bIsSplitFeature
|
||||
}
|
||||
|
||||
-- TODO aggiungere verifica finecorsa e nel caso cambio lato
|
||||
if Proc.Topology.sName == 'Groove-4-Blind' or Proc.Topology.sName == 'Pocket-5-Blind' then
|
||||
|
||||
-- si lavora tutto il fondo
|
||||
@@ -179,13 +185,17 @@ function STR0004.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
and #Proc.MainFaces.SideFaces == 1 then
|
||||
|
||||
OptionalParameters.OppositeToolDirectionMode = 'Enabled'
|
||||
local dLengthAlreadyMachined = 0
|
||||
if Chainsaw.Result.Bottom[1].bIsApplicable then
|
||||
dLengthAlreadyMachined = Chainsaw.Result.Bottom[1].dDepthToMachine
|
||||
end
|
||||
|
||||
if BottomEdge.bIsStartOpen then
|
||||
Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, SideEdge1, OptionalParameters)
|
||||
Mortising.dAreaToMachine = Mortising.dDepthToMachine * ( Mortising.dEdgeLength - Chainsaw.Result.Bottom[1].dDepthToMachine)
|
||||
Mortising.dAreaToMachine = Mortising.dDepthToMachine * ( Mortising.dEdgeLength - dLengthAlreadyMachined)
|
||||
elseif BottomEdge.bIsEndOpen then
|
||||
Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, SideEdge2, OptionalParameters)
|
||||
Mortising.dAreaToMachine = Mortising.dDepthToMachine * ( Mortising.dEdgeLength - Chainsaw.Result.Bottom[1].dDepthToMachine)
|
||||
Mortising.dAreaToMachine = Mortising.dDepthToMachine * ( Mortising.dEdgeLength - dLengthAlreadyMachined)
|
||||
end
|
||||
|
||||
Chainsaw.AddResult( Mortising)
|
||||
@@ -242,10 +252,21 @@ function STR0004.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, OppositeEdge1, OptionalParameters)
|
||||
Chainsaw.AddResult( Mortising)
|
||||
|
||||
-- se dal lato OppositeEdge1 non è applicabile (solitamente per finecorsa) si prova dal lato opposto
|
||||
if not Chainsaw.Result.Opposite[1].bIsApplicable then
|
||||
OptionalParameters.dDepthToMachine = OppositeEdge2.dElevation + BeamData.CUT_EXTRA
|
||||
Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, OppositeEdge2, OptionalParameters)
|
||||
Chainsaw.AddResult( Mortising)
|
||||
end
|
||||
|
||||
-- se lavorando solo da un lato rimane materiale residuo, si lavora da entrambi
|
||||
if Chainsaw.Result.Opposite[1].dResidualDepth > 10 * GEO.EPS_SMALL then
|
||||
if Chainsaw.Result.Opposite[1].dResidualDepth > 10 * GEO.EPS_SMALL
|
||||
or ( Chainsaw.Result.Opposite[2] and Chainsaw.Result.Opposite[2].dResidualDepth > 10 * GEO.EPS_SMALL) then
|
||||
|
||||
Chainsaw.Result.Opposite[1].bIsApplicable = false
|
||||
if Chainsaw.Result.Opposite[2] then
|
||||
Chainsaw.Result.Opposite[2].bIsApplicable = false
|
||||
end
|
||||
|
||||
OptionalParameters.dDepthToMachine = OppositeEdge1.dElevation / 2 + BeamData.CUT_EXTRA_MIN
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
"sValue": "false",
|
||||
"sDescriptionShort": "Force ripping blade",
|
||||
"sDescriptionLong": "Force the use of ripping blade, designed for cuts parallel to the grain",
|
||||
"idDescriptionShortMsg": 1000105,
|
||||
"idDescriptionLongMsg": 1000106,
|
||||
"sType": "b",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -17,7 +19,9 @@
|
||||
"sNameNge": "EXTEND_AFTER_TAIL",
|
||||
"sValue": "",
|
||||
"sDescriptionShort": "Extend after tail",
|
||||
"sDescriptionLong": "The automatism considers this lenght as machinable. This means you accept to damage the next piece in the bar",
|
||||
"sDescriptionLong": "The automatism considers this length as machinable. This means you accept to damage the next piece in the bar",
|
||||
"idDescriptionShortMsg": 1000107,
|
||||
"idDescriptionLongMsg": 1000108,
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -28,6 +32,8 @@
|
||||
"sValue": "NEVER",
|
||||
"sDescriptionShort": "Damage next piece",
|
||||
"sDescriptionLong": "This option allows you to decide how to consider the next piece in the bar. The software calculates specifics LeadIn/out to respect the parameter. This parameter may change the machining time",
|
||||
"idDescriptionShortMsg": 1000109,
|
||||
"idDescriptionLongMsg": 1000110,
|
||||
"sType": "combo",
|
||||
"sMinUserLevel": "1",
|
||||
"Choices": [
|
||||
@@ -35,18 +41,24 @@
|
||||
"sValue": "NEVER",
|
||||
"sDescriptionShort": "Never damage",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000111,
|
||||
"idDescriptionLongMsg": 1000112,
|
||||
"sMessageId": ""
|
||||
},
|
||||
{
|
||||
"sValue": "ONLY_IF_RAWPART",
|
||||
"sDescriptionShort": "Damage only if raw",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000113,
|
||||
"idDescriptionLongMsg": 1000114,
|
||||
"sMessageId": ""
|
||||
},
|
||||
{
|
||||
"sValue": "ALWAYS",
|
||||
"sDescriptionShort": "Can damage",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000115,
|
||||
"idDescriptionLongMsg": 1000116,
|
||||
"sMessageId": ""
|
||||
}
|
||||
]
|
||||
@@ -57,6 +69,8 @@
|
||||
"sValue": "AUTO",
|
||||
"sDescriptionShort": "Cutting strategy",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000117,
|
||||
"idDescriptionLongMsg": 1000118,
|
||||
"sType": "combo",
|
||||
"sMinUserLevel": "1",
|
||||
"Choices": [
|
||||
@@ -64,18 +78,24 @@
|
||||
"sValue": "AUTO",
|
||||
"sDescriptionShort": "Automatic",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000119,
|
||||
"idDescriptionLongMsg": 1000120,
|
||||
"sMessageId": ""
|
||||
},
|
||||
{
|
||||
"sValue": "DROP_WASTE",
|
||||
"sDescriptionShort": "Drop waste",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000121,
|
||||
"idDescriptionLongMsg": 1000122,
|
||||
"sMessageId": ""
|
||||
},
|
||||
{
|
||||
"sValue": "KEEP_WASTE_ATTACHED",
|
||||
"sDescriptionShort": "Keep waste attached",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000123,
|
||||
"idDescriptionLongMsg": 1000124,
|
||||
"sMessageId": ""
|
||||
}
|
||||
]
|
||||
@@ -86,6 +106,8 @@
|
||||
"sValue": "false",
|
||||
"sDescriptionShort": "Disable dicing",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000125,
|
||||
"idDescriptionLongMsg": 1000126,
|
||||
"sType": "b",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -96,6 +118,8 @@
|
||||
"sValue": "false",
|
||||
"sDescriptionShort": "Prioritize machining speed over quality",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000127,
|
||||
"idDescriptionLongMsg": 1000128,
|
||||
"sType": "b",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -106,26 +130,8 @@
|
||||
"sValue": "5",
|
||||
"sDescriptionShort": "Strip width",
|
||||
"sDescriptionLong": "In case the waste is still kept attached, this is the wigth dimension of the strip",
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
},
|
||||
{
|
||||
"sName": "dMinZAngleTopBlade",
|
||||
"sNameNge": "MIN_Z_ANGLE_TOP_BLADE",
|
||||
"sValue": "",
|
||||
"sDescriptionShort": "Min Z angle top blade",
|
||||
"sDescriptionLong": "",
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
},
|
||||
{
|
||||
"sName": "dMaxYAngleTopBlade",
|
||||
"sNameNge": "MAX_Y_ANGLE_TOP_BLADE",
|
||||
"sValue": "",
|
||||
"sDescriptionShort": "Max Y angle top blade",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000129,
|
||||
"idDescriptionLongMsg": 1000130,
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -136,6 +142,8 @@
|
||||
"sValue": "true",
|
||||
"sDescriptionShort": "Clean blade radius with mill",
|
||||
"sDescriptionLong": "Clean blade radius with mill",
|
||||
"idDescriptionShortMsg": 1000131,
|
||||
"idDescriptionLongMsg": 1000132,
|
||||
"sType": "b",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -146,6 +154,8 @@
|
||||
"sValue": "1",
|
||||
"sDescriptionShort": "Milling offset from side",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000133,
|
||||
"idDescriptionLongMsg": 1000134,
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -160,6 +170,11 @@
|
||||
"sSource": "GEN_dMaxWasteVolume",
|
||||
"sMinUserLevel": "5"
|
||||
},
|
||||
{
|
||||
"sName": "dMaxDimDice",
|
||||
"sSource": "GEN_dMaxDimDice",
|
||||
"sMinUserLevel": "5"
|
||||
},
|
||||
{
|
||||
"sName": "bReduceBladePath",
|
||||
"sSource": "GEN_bReduceBladePath",
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
-- carico librerie
|
||||
local BeamLib = require( 'BeamLib')
|
||||
local BeamData = require( 'BeamData')
|
||||
local BeamData = require( 'BeamDataNew')
|
||||
local MachiningLib = require( 'MachiningLib')
|
||||
local FeatureLib = require( 'FeatureLib')
|
||||
-- strategie di base
|
||||
@@ -36,7 +36,7 @@ local function IsTwoFacesCommonEdgeTooLong( Proc, Part)
|
||||
end
|
||||
|
||||
-- se due facce, cubetti troppo lunghi in X non si possono fare
|
||||
local ptEdge1, _, ptEdge2 = EgtSurfTmFacetOppositeSide( Proc.id, Proc.Faces[1].id, -Proc.Faces[1].Edges[nCommonEdge].vtN, GDB_ID.ROOT)
|
||||
local ptEdge1, ptEdge2 = Proc.Faces[1].Edges[nCommonEdge].ptStart, Proc.Faces[1].Edges[nCommonEdge].ptEnd
|
||||
local b3BoxEdge = BBox3d( ptEdge1, ptEdge2)
|
||||
local dEdgeLengthOnX = b3BoxEdge:getDimX()
|
||||
if FeatureLib.IsMachiningLong( dEdgeLengthOnX, Part) then
|
||||
@@ -66,7 +66,7 @@ function STR0005.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
local dQualityAddedFace = 0
|
||||
|
||||
-- più di 3 facce non supportate
|
||||
if Proc.nFct > 3 then
|
||||
if Proc.nFct > 3 and ( not Proc.Topology.sFamily == 'DoubleBevel') then
|
||||
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( 'More than 3 faces not supported')
|
||||
end
|
||||
|
||||
@@ -80,9 +80,9 @@ function STR0005.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
local idAddedTmFace
|
||||
local nAddedFace
|
||||
if Proc.nFct == 3 and not Proc.Topology.sName == 'Groove-3-Through' then
|
||||
if Proc.AdjacencyMatrix[1][2] > 10 * GEO.EPS_ANG_SMALL and Proc.AdjacencyMatrix[2][3] < 10 * GEO.EPS_ANG_SMALL then
|
||||
if Proc.AdjacencyMatrix[2][3] < 0 then
|
||||
nAddedFace = 1 - 1
|
||||
elseif Proc.AdjacencyMatrix[2][3] > 10 * GEO.EPS_ANG_SMALL and Proc.AdjacencyMatrix[3][1] < 10 * GEO.EPS_ANG_SMALL then
|
||||
elseif Proc.AdjacencyMatrix[1][3] < 0 then
|
||||
nAddedFace = 2 - 1
|
||||
else
|
||||
nAddedFace = 3 - 1
|
||||
@@ -100,8 +100,9 @@ function STR0005.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
-- considerazioni necessarie a determinare se lavorare con codolo oppure no
|
||||
local bKeepWasteAttached = ( Strategy.Parameters.sCuttingStrategy == 'KEEP_WASTE_ATTACHED')
|
||||
local bDropWaste = ( Strategy.Parameters.sCuttingStrategy == 'DROP_WASTE')
|
||||
local dFeatureMaxNotClampableLengthHead, dFeatureMaxNotClampableLengthTail = FeatureLib.GetFeatureMaxNotClampableLengths( Proc, Part)
|
||||
local bFeatureHindersClamping = FeatureLib.IsMachiningLong( max( dFeatureMaxNotClampableLengthHead, dFeatureMaxNotClampableLengthTail), Part, { dMaxSegmentLength = BeamData.LONGCUT_ENDLEN})
|
||||
|
||||
local bFeatureHindersClamping = MachiningLib.IsFeatureHinderingClamping( Proc, Part)
|
||||
|
||||
local bIsFeatureLong = FeatureLib.IsMachiningLong( Proc.b3Box:getDimX(), Part, { dMaxSegmentLength = BeamData.LONGCUT_ENDLEN})
|
||||
local bIsTwoFacesCommonEdgeTooLong = ( ( Proc.Topology and ( Proc.Topology.sName == 'Rabbet-2-Through' or Proc.Topology.sName == 'Bevel-2-Blind')) and IsTwoFacesCommonEdgeTooLong( Proc, Part))
|
||||
|
||||
@@ -111,13 +112,14 @@ function STR0005.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
or bKeepWasteAttached then
|
||||
|
||||
local BladeKeepWasteResult
|
||||
local OptionalParameters = { dExtendAfterTail = dExtendAfterTail, dStripWidth = Strategy.Parameters.dStripWidth}
|
||||
local OptionalParameters = { dExtendAfterTail = dExtendAfterTail, dStripWidth = Strategy.Parameters.dStripWidth, bForced = bKeepWasteAttached}
|
||||
AuxiliaryData.bIgnoreNotClampableLength = true
|
||||
Blade.Result, BladeKeepWasteResult = BladeKeepWaste.Make( Proc, Part, OptionalParameters)
|
||||
dTimeToMachine = BladeKeepWasteResult.dTimeToMachine
|
||||
dMRRBlade = BladeKeepWasteResult.dMRR
|
||||
dCompletionPercentage = BladeKeepWasteResult.dCompletionPercentage
|
||||
dQuality = BladeKeepWasteResult.dQuality
|
||||
Strategy.Result.sInfo = BladeKeepWasteResult.sInfo or ''
|
||||
end
|
||||
|
||||
-- lavorazione a cubetti / taglio singolo
|
||||
@@ -127,20 +129,9 @@ function STR0005.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
and not bIsTwoFacesCommonEdgeTooLong then
|
||||
|
||||
AuxiliaryData.bIgnoreNotClampableLength = false
|
||||
local dMinZTopBlade
|
||||
local dMaxNyTopBlade
|
||||
local BladeToWasteResult
|
||||
if Strategy.Parameters.dMinZAngleTopBlade then
|
||||
dMinZTopBlade = sin( Strategy.Parameters.dMinZAngleTopBlade)
|
||||
end
|
||||
if Strategy.Parameters.dMaxYAngleTopBlade then
|
||||
dMaxNyTopBlade = sin( Strategy.Parameters.dMaxYAngleTopBlade)
|
||||
end
|
||||
-- TODO rimuovere dMinNzTopBlade e dMaxNyTopBlade opzionali? non sono gestiti ovunque e probabilmente hanno utilizzo limitato
|
||||
local OptionalParameters = { dMaxWasteVolume = Strategy.Parameters.dMaxWasteVolume,
|
||||
dMaxWasteLength = Strategy.Parameters.dMaxWasteLength,
|
||||
dMinNzTopBlade = dMinZTopBlade,
|
||||
dMaxNyTopBlade = dMaxNyTopBlade,
|
||||
bSaveAddedGeometries = bAddMachining,
|
||||
dExtendAfterTail = dExtendAfterTail,
|
||||
bAllowFastCuts = Strategy.Parameters.bAllowFastCuts,
|
||||
@@ -172,19 +163,9 @@ function STR0005.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
-- TODO da completare
|
||||
-- TODO va messa per prima????????
|
||||
if idAddedTmFace then
|
||||
local dMinZTopBlade
|
||||
local dMaxNyTopBlade
|
||||
local BladeToWasteResult
|
||||
if Strategy.Parameters.dMinZAngleTopBlade then
|
||||
dMinZTopBlade = sin( Strategy.Parameters.dMinZAngleTopBlade)
|
||||
end
|
||||
if Strategy.Parameters.dMaxYAngleTopBlade then
|
||||
dMaxNyTopBlade = sin( Strategy.Parameters.dMaxYAngleTopBlade)
|
||||
end
|
||||
local OptionalParameters = { dMaxWasteVolume = Strategy.Parameters.dMaxWasteVolume,
|
||||
dMaxWasteLength = Strategy.Parameters.dMaxWasteLength,
|
||||
dMinNzTopBlade = dMinZTopBlade,
|
||||
dMaxNyTopBlade = dMaxNyTopBlade,
|
||||
bSaveAddedGeometries = bAddMachining,
|
||||
dExtendAfterTail = dExtendAfterTail
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
"sValue": "0",
|
||||
"sDescriptionShort": "Overmaterial on tenon length",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000135,
|
||||
"idDescriptionLongMsg": 1000136,
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -18,6 +20,8 @@
|
||||
"sValue": "0",
|
||||
"sDescriptionShort": "Overmaterial on tenon width",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000137,
|
||||
"idDescriptionLongMsg": 1000138,
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -28,6 +32,8 @@
|
||||
"sValue": "3",
|
||||
"sDescriptionShort": "Maximum number of milling passes",
|
||||
"sDescriptionLong": "Maximum number of milling passes. If more passes are required, pocketing is performed",
|
||||
"idDescriptionShortMsg": 1000139,
|
||||
"idDescriptionLongMsg": 1000140,
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -38,6 +44,8 @@
|
||||
"sValue": "AUTO",
|
||||
"sDescriptionShort": "Cutting Strategy",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000141,
|
||||
"idDescriptionLongMsg": 1000142,
|
||||
"sType": "combo",
|
||||
"sMinUserLevel": "1",
|
||||
"Choices": [
|
||||
@@ -45,24 +53,32 @@
|
||||
"sValue": "AUTO",
|
||||
"sDescriptionShort": "Automatic",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000143,
|
||||
"idDescriptionLongMsg": 1000144,
|
||||
"sMessageId": ""
|
||||
},
|
||||
{
|
||||
"sValue": "BLADE_FORCED",
|
||||
"sDescriptionShort": "Blade only",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000145,
|
||||
"idDescriptionLongMsg": 1000146,
|
||||
"sMessageId": ""
|
||||
},
|
||||
{
|
||||
"sValue": "MILL_FORCED",
|
||||
"sDescriptionShort": "Mill only",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000147,
|
||||
"idDescriptionLongMsg": 1000148,
|
||||
"sMessageId": ""
|
||||
},
|
||||
{
|
||||
"sValue": "CHAINSAW_FORCED",
|
||||
"sDescriptionShort": "ChainSaw only",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000149,
|
||||
"idDescriptionLongMsg": 1000150,
|
||||
"sMessageId": ""
|
||||
}
|
||||
]
|
||||
@@ -73,6 +89,8 @@
|
||||
"sValue": "",
|
||||
"sDescriptionShort": "Available mill to machine the tenon",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000151,
|
||||
"idDescriptionLongMsg": 1000152,
|
||||
"sType": "tool",
|
||||
"sSubType": "MCH_TF.MILL",
|
||||
"sMessageId": " ",
|
||||
|
||||
@@ -5,9 +5,10 @@
|
||||
|
||||
-- carico librerie
|
||||
local BeamLib = require( 'BeamLib')
|
||||
local BeamData = require( 'BeamData')
|
||||
local BeamData = require( 'BeamDataNew')
|
||||
local MachiningLib = require( 'MachiningLib')
|
||||
local FeatureLib = require( 'FeatureLib')
|
||||
local PreSimulationLib = require( 'PreSimulationLib')
|
||||
-- strategie di base
|
||||
local BladeToWaste = require( 'BLADETOWASTE')
|
||||
|
||||
@@ -74,6 +75,7 @@ local function GetTenonStrategy( Proc, Part)
|
||||
local bMachIsOk = true
|
||||
if ( Proc.FeatureInfo.vtTenonN:getZ() < 0 and TOOLS[Machining.Milling.ToolInfo.nToolIndex].SetupInfo.HeadType.bTop) or
|
||||
( Proc.FeatureInfo.vtTenonN:getZ() > 0 and TOOLS[Machining.Milling.ToolInfo.nToolIndex].SetupInfo.HeadType.bBottom) then
|
||||
-- TODO questo test va sostituito con check collisione asse Z (PreCollision)
|
||||
local dTotalLen = TOOLS[Machining.Milling.ToolInfo.nToolIndex].dLength + TOOLS[Machining.Milling.ToolInfo.nToolIndex].SetupInfo.dPivot
|
||||
local dHorizSpace = dTotalLen * sqrt( 1 - ( Proc.FeatureInfo.vtTenonN:getZ() * Proc.FeatureInfo.vtTenonN:getZ()))
|
||||
if dHorizSpace - ( TOOLS[Machining.Milling.ToolInfo.nToolIndex].SetupInfo.dCAxisSideEncumbrance / 2) < Proc.b3Box:getDimX() then
|
||||
@@ -158,6 +160,23 @@ local function GetTenonStrategy( Proc, Part)
|
||||
Machining.Milling.AuxiliaryData.Clones[nIndexClones].dRadialOffset = ( i - 1) * dRealSideStep
|
||||
end
|
||||
end
|
||||
|
||||
-- test finecorsa sulla passata più esterna: se extracorsa, la lavorazione non è fattibile
|
||||
-- TODO sostituire con applicazione della lavorazione?
|
||||
-- TODO funzione per allungare il percorso??????
|
||||
local idGeomMaxOffset = EgtCopyGlob( Proc.FeatureInfo.idAddAuxGeom, Part.idTempGroup)
|
||||
EgtOffsetCurve( idGeomMaxOffset, Machining.Milling.AuxiliaryData.Clones[1].dRadialOffset + TOOLS[Machining.Milling.ToolInfo.nToolIndex].dDiameter / 2, Part.idTempGroup)
|
||||
local vtCurveStart = EgtSV( idGeomMaxOffset, GDB_ID.ROOT)
|
||||
local vtCurveEnd = EgtEV( idGeomMaxOffset, GDB_ID.ROOT)
|
||||
local ptCurveStart = EgtSP( idGeomMaxOffset, GDB_ID.ROOT) + -vtCurveStart * Machining.Milling.LeadIn.dTangentDistance + ( Proc.FeatureInfo.vtTenonN ^ -vtCurveStart) * Machining.Milling.LeadIn.dPerpDistance
|
||||
local ptCurveEnd = EgtEP( idGeomMaxOffset, GDB_ID.ROOT) + vtCurveEnd * Machining.Milling.LeadOut.dTangentDistance + ( vtCurveEnd ^ Proc.FeatureInfo.vtTenonN) * Machining.Milling.LeadOut.dPerpDistance
|
||||
EgtAddCurveCompoArcTg( idGeomMaxOffset, ptCurveStart, false, GDB_RT.GLOB)
|
||||
EgtAddCurveCompoArcTg( idGeomMaxOffset, ptCurveEnd, true, GDB_RT.GLOB)
|
||||
local bOutOfStroke = PreSimulationLib.CheckOutOfStrokeFromGeometry( idGeomMaxOffset, Proc.FeatureInfo.vtTenonN, Machining.Milling.nSCC, TOOLS[Machining.Milling.ToolInfo.nToolIndex])
|
||||
if bOutOfStroke then
|
||||
Machining.Milling.bIsApplicable = false
|
||||
end
|
||||
|
||||
-- tempo di svuotatura
|
||||
Result.Milling.dTimeToMachine = MachiningLib.GetTimeToMachineAllStepsWithLeadInOut( Machining.Milling, Part)
|
||||
end
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
"sValue": "0",
|
||||
"sDescriptionShort": "Overmaterial on Mortise length",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000153,
|
||||
"idDescriptionLongMsg": 1000154,
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -18,6 +20,8 @@
|
||||
"sValue": "0",
|
||||
"sDescriptionShort": "Overmaterial on Mortise width",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000155,
|
||||
"idDescriptionLongMsg": 1000156,
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -28,6 +32,8 @@
|
||||
"sValue": "3",
|
||||
"sDescriptionShort": "Maximum number of milling passes",
|
||||
"sDescriptionLong": "Maximum number of milling passes. If more passes are required, pocketing is performed",
|
||||
"idDescriptionShortMsg": 1000157,
|
||||
"idDescriptionLongMsg": 1000158,
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -38,6 +44,8 @@
|
||||
"sValue": "true",
|
||||
"sDescriptionShort": "Use DoveTail tool in case of pocketing",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000159,
|
||||
"idDescriptionLongMsg": 1000160,
|
||||
"sType": "b",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -48,6 +56,8 @@
|
||||
"sValue": "true",
|
||||
"sDescriptionShort": "Add Anti-Splint",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000161,
|
||||
"idDescriptionLongMsg": 1000162,
|
||||
"sType": "b",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -58,6 +68,8 @@
|
||||
"sValue": "AUTO",
|
||||
"sDescriptionShort": "Cutting Strategy",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000163,
|
||||
"idDescriptionLongMsg": 1000164,
|
||||
"sType": "combo",
|
||||
"sMinUserLevel": "1",
|
||||
"Choices": [
|
||||
@@ -65,24 +77,32 @@
|
||||
"sValue": "AUTO",
|
||||
"sDescriptionShort": "Automatic",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000165,
|
||||
"idDescriptionLongMsg": 1000166,
|
||||
"sMessageId": ""
|
||||
},
|
||||
{
|
||||
"sValue": "BLADE_FORCED",
|
||||
"sDescriptionShort": "Blade only",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000167,
|
||||
"idDescriptionLongMsg": 1000168,
|
||||
"sMessageId": ""
|
||||
},
|
||||
{
|
||||
"sValue": "MILL_FORCED",
|
||||
"sDescriptionShort": "Mill only",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000169,
|
||||
"idDescriptionLongMsg": 1000170,
|
||||
"sMessageId": ""
|
||||
},
|
||||
{
|
||||
"sValue": "CHAINSAW_FORCED",
|
||||
"sDescriptionShort": "ChainSaw only",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000171,
|
||||
"idDescriptionLongMsg": 1000172,
|
||||
"sMessageId": ""
|
||||
}
|
||||
]
|
||||
@@ -93,6 +113,8 @@
|
||||
"sValue": "",
|
||||
"sDescriptionShort": "Available mill to machine the mortise cut surface",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000173,
|
||||
"idDescriptionLongMsg": 1000174,
|
||||
"sType": "tool",
|
||||
"sSubType": "MCH_TF.MILL",
|
||||
"sMessageId": " ",
|
||||
@@ -104,6 +126,8 @@
|
||||
"sValue": "",
|
||||
"sDescriptionShort": "Available mill to machine the dovetail mortise",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000175,
|
||||
"idDescriptionLongMsg": 1000176,
|
||||
"sType": "tool",
|
||||
"sSubType": "MCH_TF.MILL",
|
||||
"sMessageId": " ",
|
||||
|
||||
@@ -5,9 +5,10 @@
|
||||
|
||||
-- carico librerie
|
||||
local BeamLib = require( 'BeamLib')
|
||||
local BeamData = require( 'BeamData')
|
||||
local BeamData = require( 'BeamDataNew')
|
||||
local MachiningLib = require( 'MachiningLib')
|
||||
local FeatureLib = require( 'FeatureLib')
|
||||
local PreSimulationLib = require( 'PreSimulationLib')
|
||||
-- strategie di base
|
||||
local BladeToWaste = require('BLADETOWASTE')
|
||||
|
||||
@@ -15,6 +16,19 @@ local BladeToWaste = require('BLADETOWASTE')
|
||||
local STR0007 = {}
|
||||
local Strategy = {}
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function GetSCC( Machining)
|
||||
local nSCC
|
||||
|
||||
if Machining.vtToolDirection:getX() > 0 then
|
||||
nSCC = MCH_SCC.ADIR_XP
|
||||
else
|
||||
nSCC = MCH_SCC.ADIR_XM
|
||||
end
|
||||
|
||||
return nSCC
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function GetMortiseStrategy( Proc, Part)
|
||||
local Machining = {}
|
||||
@@ -94,11 +108,16 @@ function GetMortiseStrategy( Proc, Part)
|
||||
ToolSearchParameters.AvailableToolList = MachiningLib.GetAvailableToolList( Proc, Strategy.Parameters.sMillingList, 'Milling')
|
||||
Machining.Milling.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
|
||||
if Machining.Milling.ToolInfo.nToolIndex then
|
||||
Machining.Milling.bIsApplicable = true
|
||||
local dToolDiam = TOOLS[Machining.Milling.ToolInfo.nToolIndex].dDiameter
|
||||
|
||||
-- se richiesta passata antischeggia
|
||||
if Strategy.Parameters.bAntiSplint then
|
||||
Machining.AntiSplint = GetMortiseAntiSplint( Proc, Part, Machining.Milling.ToolInfo)
|
||||
end
|
||||
|
||||
Machining.Milling.bIsApplicable = true
|
||||
-- calcolo numero passate necessarie
|
||||
if Proc.FeatureInfo.dMortiseMaxDist > TOOLS[Machining.Milling.ToolInfo.nToolIndex].dDiameter * 1.9 then
|
||||
local dToolDiam = TOOLS[Machining.Milling.ToolInfo.nToolIndex].dDiameter
|
||||
if Proc.FeatureInfo.dMortiseMaxDist > dToolDiam * 1.9 then
|
||||
local sSideStep = TOOLS[Machining.Milling.ToolInfo.nToolIndex].dSideStep
|
||||
Machining.nMillingPathsNeeded = 1 + ceil( ( Proc.FeatureInfo.dMortiseMaxDist - dToolDiam * 1.9) / ( sSideStep * 2))
|
||||
-- suddivido step in base al numero passate da fare
|
||||
@@ -107,6 +126,55 @@ function GetMortiseStrategy( Proc, Part)
|
||||
Machining.nMillingPathsNeeded = 1
|
||||
end
|
||||
|
||||
-- aggiungo geometria
|
||||
Machining.Milling.Geometry = {{ Proc.FeatureInfo.idAddAuxGeom, -1}}
|
||||
Machining.Milling.nToolIndex = Machining.Milling.ToolInfo.nToolIndex
|
||||
Machining.Milling.nType = MCH_MY.MILLING
|
||||
Machining.Milling.vtToolDirection = Proc.FeatureInfo.vtMortiseN
|
||||
Machining.Milling.sDepth = Strategy.Parameters.dOverMatOnLength
|
||||
|
||||
-- LeadIn / LeadOut
|
||||
Machining.Milling.LeadIn = {}
|
||||
Machining.Milling.LeadOut = {}
|
||||
Machining.Milling.LeadIn.nType = MCH_MILL_LI.TANGENT
|
||||
Machining.Milling.LeadOut.nType = MCH_MILL_LI.TANGENT
|
||||
|
||||
local dDeltaAngledEntry = Proc.FeatureInfo.vtMortisePathStart * dToolDiam / 2
|
||||
local dDeltaAngledExit = Proc.FeatureInfo.vtMortisePathEnd * dToolDiam / 2
|
||||
|
||||
Machining.Milling.LeadIn.dTangentDistance = dToolDiam / 2 + dDeltaAngledEntry + BeamData.COLL_SIC
|
||||
Machining.Milling.LeadIn.dPerpDistance = 0
|
||||
Machining.Milling.LeadOut.dTangentDistance = dToolDiam / 2 + dDeltaAngledExit + BeamData.COLL_SIC
|
||||
Machining.Milling.LeadOut.dPerpDistance = 0
|
||||
|
||||
if Proc.AffectedFaces.bLeft and Strategy.bCanMoveAfterSplit then
|
||||
Machining.Milling.sStage = 'AfterTail'
|
||||
end
|
||||
|
||||
-- sistemo il lato e la direzione di lavoro
|
||||
Machining.Milling.bInvert = EgtIf( TOOLS[Machining.Milling.ToolInfo.nToolIndex].bIsCCW, false, true)
|
||||
Machining.Milling.nWorkside = EgtIf( TOOLS[Machining.Milling.ToolInfo.nToolIndex].bIsCCW, MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT)
|
||||
|
||||
Machining.Milling.dMaxElev = Proc.FeatureInfo.dMortiseDepth
|
||||
|
||||
Machining.Milling.nSCC = GetSCC( Machining.Milling)
|
||||
|
||||
-- passate con sovramateriale
|
||||
Machining.Milling.AuxiliaryData = { Clones = {}}
|
||||
for i = Machining.nMillingPathsNeeded, 1, -1 do
|
||||
-- il primo è il passaggio più esterno
|
||||
local nIndexClones = Machining.nMillingPathsNeeded - i + 1
|
||||
-- cambia solo sovrmateriale radiale
|
||||
Machining.Milling.AuxiliaryData.Clones[nIndexClones] = {}
|
||||
-- ultima passata con sovramateriale impostato
|
||||
if i == 1 then
|
||||
Machining.Milling.AuxiliaryData.Clones[nIndexClones].dRadialOffset = Strategy.Parameters.dOverMatOnRadius
|
||||
else
|
||||
-- suddivido step in base al numero passate da fare
|
||||
Machining.Milling.AuxiliaryData.Clones[nIndexClones].dRadialOffset = ( i - 1) * Machining.Milling.dRealSideStep
|
||||
end
|
||||
end
|
||||
|
||||
local ParametersMRR = {}
|
||||
ParametersMRR.nToolIndex = Machining.Milling.ToolInfo.nToolIndex
|
||||
Result.Milling.dMRR = MachiningLib.GetToolMRR( ParametersMRR)
|
||||
@@ -116,6 +184,17 @@ function GetMortiseStrategy( Proc, Part)
|
||||
else
|
||||
Machining.Milling.bIsApplicable = false
|
||||
end
|
||||
|
||||
-- test finecorsa sulla passata più esterna: se extracorsa, la lavorazione non è fattibile
|
||||
local idGeomMaxOffset = EgtCopyGlob( Proc.FeatureInfo.idAddAuxGeom, Part.idTempGroup)
|
||||
-- TODO funzione per allungare il percorso??????
|
||||
EgtAddCurveCompoLineTg( idGeomMaxOffset, Machining.Milling.LeadIn.dTangentDistance, false)
|
||||
EgtAddCurveCompoLineTg( idGeomMaxOffset, Machining.Milling.LeadOut.dTangentDistance, true)
|
||||
EgtOffsetCurve( idGeomMaxOffset, Machining.Milling.AuxiliaryData.Clones[1].dRadialOffset + TOOLS[Machining.Milling.ToolInfo.nToolIndex].dDiameter / 2, Part.idTempGroup)
|
||||
local bOutOfStroke = PreSimulationLib.CheckOutOfStrokeFromGeometry( idGeomMaxOffset, Proc.FeatureInfo.vtMortiseN, Machining.Milling.nSCC, TOOLS[Machining.Milling.ToolInfo.nToolIndex])
|
||||
if bOutOfStroke then
|
||||
Machining.Milling.bIsApplicable = false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -161,9 +240,9 @@ function GetMortiseMachiningResult( Proc, Result)
|
||||
TotalResult.dCompletionIndex = FeatureLib.GetFeatureCompletionIndex( 100)
|
||||
TotalResult.dMRR = ( Result.Milling.dMRR + Result.Cutting.dMRR) / 2
|
||||
local sQuality
|
||||
if not Strategy.Machining.bCuttingWithMill and Strategy.Machining.bAntiSplint then
|
||||
if not Strategy.Machining.bCuttingWithMill and Strategy.Machining.AntiSplint.bIsApplicable then
|
||||
sQuality = 'BEST'
|
||||
elseif Strategy.Machining.bAntiSplint then
|
||||
elseif Strategy.Machining.AntiSplint.bIsApplicable then
|
||||
sQuality = 'FINE'
|
||||
else
|
||||
sQuality = 'STD'
|
||||
@@ -176,7 +255,7 @@ function GetMortiseMachiningResult( Proc, Result)
|
||||
TotalResult.sStatus = Result.Milling.sStatus
|
||||
TotalResult.dCompletionIndex = FeatureLib.GetFeatureCompletionIndex( 100)
|
||||
TotalResult.dMRR = Result.Milling.dMRR
|
||||
local sQuality = EgtIf( Strategy.Parameters.bAntiSplint, 'BEST', 'STD')
|
||||
local sQuality = EgtIf( Strategy.Machining.AntiSplint.bIsApplicable, 'BEST', 'STD')
|
||||
TotalResult.dQuality = FeatureLib.GetStrategyQuality( sQuality)
|
||||
TotalResult.nFeatureRotationIndex = GetFeatureRotationIndex( Proc)
|
||||
TotalResult.sInfo = ''
|
||||
@@ -233,14 +312,15 @@ local function CalcTopPath( nProcId, AuxId, nAddGrpId, dAltMort, dSideAng, b3Sol
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function ApplyMortiseAntiSplint( Proc, Part)
|
||||
function GetMortiseAntiSplint( Proc, Part, ToolInfo)
|
||||
local AntiSplint = { bIsApplicable = false}
|
||||
-- se il percorso non è chiuso, aggiungo percorso e lavorazione antischeggia
|
||||
if not EgtCurveIsClosed( Proc.FeatureInfo.idAddAuxGeom) then
|
||||
-- recupero gruppo per geometria addizionale
|
||||
local nAddGrpId = BeamLib.GetAddGroup( Part.id)
|
||||
-- calcolo il percorso top mortise
|
||||
local dSideAng = TOOLS[Strategy.Machining.Milling.ToolInfo.nToolIndex].dSideAngle
|
||||
local dToolDiam = TOOLS[Strategy.Machining.Milling.ToolInfo.nToolIndex].dDiameter
|
||||
local dSideAng = TOOLS[ToolInfo.nToolIndex].dSideAngle
|
||||
local dToolDiam = TOOLS[ToolInfo.nToolIndex].dDiameter
|
||||
local vtExtr = Proc.FeatureInfo.vtMortiseN
|
||||
local nAuxId1 = CalcTopPath( Proc.id, Proc.FeatureInfo.idAddAuxGeom, nAddGrpId, Proc.FeatureInfo.dMortiseDepth, dSideAng, Part.b3Part)
|
||||
-- se esiste il percorso
|
||||
@@ -275,48 +355,62 @@ function ApplyMortiseAntiSplint( Proc, Part)
|
||||
if not nId1 then
|
||||
local sErr = 'Wrong geometry : Error on DtMortise '
|
||||
EgtOutLog( sErr)
|
||||
return false, sErr
|
||||
return AntiSplint
|
||||
end
|
||||
EgtModifyCurveExtrusion( nId1, vtExtr, GDB_RT.GLOB)
|
||||
|
||||
local Machining = {}
|
||||
Machining.nToolIndex = Strategy.Machining.Milling.ToolInfo.nToolIndex
|
||||
Machining.nType = MCH_MY.MILLING
|
||||
Machining.vtToolDirection = Proc.FeatureInfo.vtMortiseN
|
||||
AntiSplint.nToolIndex = ToolInfo.nToolIndex
|
||||
AntiSplint.nType = MCH_MY.MILLING
|
||||
AntiSplint.vtToolDirection = Proc.FeatureInfo.vtMortiseN
|
||||
|
||||
-- LeadIn / LeadOut
|
||||
Machining.LeadIn = {}
|
||||
Machining.LeadOut = {}
|
||||
Machining.LeadIn.nType = MCH_MILL_LI.TANGENT
|
||||
Machining.LeadOut.nType = MCH_MILL_LI.TANGENT
|
||||
Machining.LeadIn.dTangentDistance = TOOLS[Strategy.Machining.Milling.ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC
|
||||
Machining.LeadIn.dPerpDistance = 0
|
||||
Machining.LeadOut.dTangentDistance = TOOLS[Strategy.Machining.Milling.ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC
|
||||
Machining.LeadOut.dPerpDistance = 0
|
||||
AntiSplint.LeadIn = {}
|
||||
AntiSplint.LeadOut = {}
|
||||
AntiSplint.LeadIn.nType = MCH_MILL_LI.TANGENT
|
||||
AntiSplint.LeadOut.nType = MCH_MILL_LI.TANGENT
|
||||
AntiSplint.LeadIn.dTangentDistance = TOOLS[ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC
|
||||
AntiSplint.LeadIn.dPerpDistance = 0
|
||||
AntiSplint.LeadOut.dTangentDistance = TOOLS[ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC
|
||||
AntiSplint.LeadOut.dPerpDistance = 0
|
||||
|
||||
Machining.dRadialOffset = dToolRadDelta - 1
|
||||
Machining.sDepth = Proc.FeatureInfo.dMortiseDepth - Strategy.Parameters.dOverMatOnLength
|
||||
Machining.Geometry = {{ nId1, -1}}
|
||||
Machining.bInvert = EgtIf( TOOLS[Strategy.Machining.Milling.ToolInfo.nToolIndex].bIsCCW, false, true)
|
||||
Machining.nWorkside = EgtIf( TOOLS[Strategy.Machining.Milling.ToolInfo.nToolIndex].bIsCCW, MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT)
|
||||
Machining.dMaxElev = Proc.FeatureInfo.dMortiseDepth
|
||||
AntiSplint.dRadialOffset = dToolRadDelta - 1
|
||||
AntiSplint.sDepth = Proc.FeatureInfo.dMortiseDepth - Strategy.Parameters.dOverMatOnLength
|
||||
AntiSplint.Geometry = {{ nId1, -1}}
|
||||
AntiSplint.bInvert = EgtIf( TOOLS[ToolInfo.nToolIndex].bIsCCW, false, true)
|
||||
AntiSplint.nWorkside = EgtIf( TOOLS[ToolInfo.nToolIndex].bIsCCW, MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT)
|
||||
AntiSplint.dMaxElev = Proc.FeatureInfo.dMortiseDepth
|
||||
AntiSplint.nSCC = GetSCC( AntiSplint)
|
||||
|
||||
if Proc.AffectedFaces.bLeft and Strategy.bCanMoveAfterSplit then
|
||||
Machining.sStage = 'AfterTail'
|
||||
AntiSplint.sStage = 'AfterTail'
|
||||
end
|
||||
|
||||
-- test finecorsa sulla passata più esterna: se extracorsa, la lavorazione non è fattibile
|
||||
local idGeomOffset = EgtCopyGlob( nId1, Part.idTempGroup)
|
||||
EgtOffsetCurve( idGeomOffset, EgtIf( AntiSplint.bInvert, -TOOLS[ToolInfo.nToolIndex].dDiameter / 2, TOOLS[ToolInfo.nToolIndex].dDiameter / 2), Part.idTempGroup)
|
||||
-- trasformo arco in una curva compo per poi allungarla in direzione tangente
|
||||
-- TODO funzione per allungare il percorso??????
|
||||
idGeomOffset = EgtCurveCompo( Part.idTempGroup, idGeomOffset)
|
||||
EgtAddCurveCompoLineTg( idGeomOffset, AntiSplint.LeadIn.dTangentDistance, false)
|
||||
EgtAddCurveCompoLineTg( idGeomOffset, AntiSplint.LeadOut.dTangentDistance, true)
|
||||
local bOutOfStroke = PreSimulationLib.CheckOutOfStrokeFromGeometry( idGeomOffset, Proc.FeatureInfo.vtMortiseN, AntiSplint.nSCC, TOOLS[ToolInfo.nToolIndex])
|
||||
-- se soddisfa tutti i requisiti, posso applicare
|
||||
if bOutOfStroke then
|
||||
AntiSplint.bIsApplicable = false
|
||||
else
|
||||
AntiSplint.bIsApplicable = true
|
||||
end
|
||||
MachiningLib.AddMachinings( Proc, Machining)
|
||||
|
||||
else
|
||||
local sErr = 'Wrong geometry : Error on DtMortise ' .. tostring( Proc.id)
|
||||
EgtOutLog( sErr)
|
||||
return false, sErr
|
||||
end
|
||||
else
|
||||
local sErr = 'Wrong geometry : Error on DtMortise ' .. tostring( Proc.id)
|
||||
EgtOutLog( sErr)
|
||||
return false, sErr
|
||||
end
|
||||
end
|
||||
return AntiSplint
|
||||
end
|
||||
|
||||
|
||||
@@ -400,65 +494,19 @@ function STR0007.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
end
|
||||
|
||||
-- se richiesta passata antischeggia
|
||||
if Strategy.Parameters.bAntiSplint then
|
||||
ApplyMortiseAntiSplint( Proc, Part)
|
||||
if Strategy.Machining.AntiSplint.bIsApplicable then
|
||||
bAreAllMachiningsAdded = bAreAllMachiningsAdded and MachiningLib.AddMachinings( Proc, Strategy.Machining.AntiSplint)
|
||||
end
|
||||
|
||||
-- passaggio sul profilo
|
||||
if Strategy.Machining.Milling.bIsApplicable then
|
||||
local AuxiliaryData = {}
|
||||
-- se molti passaggi richiesti, si fa svuotatura
|
||||
-- TODO in attesa delle svuotature, si fanno passaggi senza limiti sul numero massimo. Poi togliere il FALSE nella condizione.
|
||||
if false and Strategy.Machining.nMillingPathsNeeded > Strategy.Parameters.nMaxMillingPaths then
|
||||
-- TODO. SERVONO NUOVE SVUOTATURE!!!!
|
||||
else
|
||||
-- aggiungo geometria
|
||||
Strategy.Machining.Milling.Geometry = {{ Proc.FeatureInfo.idAddAuxGeom, -1}}
|
||||
Strategy.Machining.Milling.nToolIndex = Strategy.Machining.Milling.ToolInfo.nToolIndex
|
||||
Strategy.Machining.Milling.nType = MCH_MY.MILLING
|
||||
Strategy.Machining.Milling.vtToolDirection = Proc.FeatureInfo.vtMortiseN
|
||||
Strategy.Machining.Milling.sDepth = Strategy.Parameters.dOverMatOnLength
|
||||
|
||||
-- LeadIn / LeadOut
|
||||
Strategy.Machining.Milling.LeadIn = {}
|
||||
Strategy.Machining.Milling.LeadOut = {}
|
||||
Strategy.Machining.Milling.LeadIn.nType = MCH_MILL_LI.TANGENT
|
||||
Strategy.Machining.Milling.LeadOut.nType = MCH_MILL_LI.TANGENT
|
||||
Strategy.Machining.Milling.LeadIn.dTangentDistance = TOOLS[Strategy.Machining.Milling.ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC
|
||||
Strategy.Machining.Milling.LeadIn.dPerpDistance = 0
|
||||
Strategy.Machining.Milling.LeadOut.dTangentDistance = TOOLS[Strategy.Machining.Milling.ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC
|
||||
Strategy.Machining.Milling.LeadOut.dPerpDistance = 0
|
||||
|
||||
if Proc.AffectedFaces.bLeft and Strategy.bCanMoveAfterSplit then
|
||||
Strategy.Machining.Milling.sStage = 'AfterTail'
|
||||
end
|
||||
|
||||
-- sistemo il lato e la direzione di lavoro
|
||||
Strategy.Machining.Milling.bInvert = EgtIf( TOOLS[Strategy.Machining.Milling.ToolInfo.nToolIndex].bIsCCW, false, true)
|
||||
Strategy.Machining.Milling.nWorkside = EgtIf( TOOLS[Strategy.Machining.Milling.ToolInfo.nToolIndex].bIsCCW, MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT)
|
||||
|
||||
Strategy.Machining.Milling.dMaxElev = Proc.FeatureInfo.dMortiseDepth
|
||||
|
||||
-- TODO calcolare SCC
|
||||
|
||||
-- passate con sovramateriale
|
||||
AuxiliaryData.Clones = {}
|
||||
for i = Strategy.Machining.nMillingPathsNeeded, 1, -1 do
|
||||
-- il primo è il passaggio più esterno
|
||||
local nIndexClones = Strategy.Machining.nMillingPathsNeeded - i + 1
|
||||
-- cambia solo sovrmateriale radiale
|
||||
AuxiliaryData.Clones[nIndexClones] = {}
|
||||
-- ultima passata con sovramateriale impostato
|
||||
if i == 1 then
|
||||
AuxiliaryData.Clones[nIndexClones].dRadialOffset = Strategy.Parameters.dOverMatOnRadius
|
||||
else
|
||||
-- suddivido step in base al numero passate da fare
|
||||
AuxiliaryData.Clones[nIndexClones].dRadialOffset = ( i - 1) * Strategy.Machining.Milling.dRealSideStep
|
||||
end
|
||||
end
|
||||
|
||||
-- aggiunge lavorazione
|
||||
bAreAllMachiningsAdded = MachiningLib.AddMachinings( Proc, Strategy.Machining.Milling, AuxiliaryData)
|
||||
bAreAllMachiningsAdded = bAreAllMachiningsAdded and MachiningLib.AddMachinings( Proc, Strategy.Machining.Milling, Strategy.Machining.Milling.AuxiliaryData)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
"sValue": "0",
|
||||
"sDescriptionShort": "Overmaterial on mortise length",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000177,
|
||||
"idDescriptionLongMsg": 1000178,
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -18,6 +20,8 @@
|
||||
"sValue": "0",
|
||||
"sDescriptionShort": "Overmaterial on mortise width",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000179,
|
||||
"idDescriptionLongMsg": 1000180,
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -28,6 +32,8 @@
|
||||
"sValue": "AUTO",
|
||||
"sDescriptionShort": "Cutting Strategy",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000181,
|
||||
"idDescriptionLongMsg": 1000182,
|
||||
"sType": "combo",
|
||||
"sMinUserLevel": "1",
|
||||
"Choices": [
|
||||
@@ -35,24 +41,32 @@
|
||||
"sValue": "AUTO",
|
||||
"sDescriptionShort": "Automatic",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000183,
|
||||
"idDescriptionLongMsg": 1000184,
|
||||
"sMessageId": ""
|
||||
},
|
||||
{
|
||||
"sValue": "BLADE_FORCED",
|
||||
"sDescriptionShort": "Blade only",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000185,
|
||||
"idDescriptionLongMsg": 1000186,
|
||||
"sMessageId": ""
|
||||
},
|
||||
{
|
||||
"sValue": "MILL_FORCED",
|
||||
"sDescriptionShort": "Mill only",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000187,
|
||||
"idDescriptionLongMsg": 1000188,
|
||||
"sMessageId": ""
|
||||
},
|
||||
{
|
||||
"sValue": "CHAINSAW_FORCED",
|
||||
"sDescriptionShort": "ChainSaw only",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000189,
|
||||
"idDescriptionLongMsg": 1000190,
|
||||
"sMessageId": ""
|
||||
}
|
||||
]
|
||||
@@ -63,6 +77,8 @@
|
||||
"sValue": "",
|
||||
"sDescriptionShort": "Available mill to machine the mortise cut surface",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000191,
|
||||
"idDescriptionLongMsg": 1000192,
|
||||
"sType": "tool",
|
||||
"sSubType": "MCH_TF.MILL",
|
||||
"sMessageId": " ",
|
||||
@@ -74,6 +90,8 @@
|
||||
"sValue": "",
|
||||
"sDescriptionShort": "Available mill to machine the mortise",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000193,
|
||||
"idDescriptionLongMsg": 1000194,
|
||||
"sType": "tool",
|
||||
"sSubType": "MCH_TF.MILL",
|
||||
"sMessageId": " ",
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
-- carico librerie
|
||||
local BeamLib = require( 'BeamLib')
|
||||
local BeamData = require( 'BeamData')
|
||||
local BeamData = require( 'BeamDataNew')
|
||||
local MachiningLib = require( 'MachiningLib')
|
||||
local FeatureLib = require( 'FeatureLib')
|
||||
-- strategie di base
|
||||
@@ -174,13 +174,13 @@ local function GetBestPocketingStrategy( Proc, Part)
|
||||
Strategy.Result.dMRR = MachiningLib.GetToolMRR( Machining.Pocketing[2].ToolInfo)
|
||||
Machining.Pocketing[1].bIsApplicable = false
|
||||
-- solo svuotatura diretta come normale mortasa, incompleta
|
||||
elseif not Machining.Pocketing[2].bIsApplicable then
|
||||
elseif Machining.Pocketing[1].bIsApplicable and not Machining.Pocketing[2].bIsApplicable then
|
||||
Machining.sTypeMachining = 'Side1'
|
||||
Machining.dResidual = Machining.Pocketing[1].ToolInfo.dResidualDepth
|
||||
Machining.Pocketing[1].sDepth = -Machining.dResidual
|
||||
Strategy.Result.dMRR = MachiningLib.GetToolMRR( Machining.Pocketing[1].ToolInfo)
|
||||
-- solo svuotatura diretta come normale mortasa, incompleta
|
||||
elseif not Machining.Pocketing[1].bIsApplicable then
|
||||
elseif Machining.Pocketing[2].bIsApplicable and not Machining.Pocketing[1].bIsApplicable then
|
||||
Machining.sTypeMachining = 'Side2'
|
||||
Machining.dResidual = Machining.Pocketing[2].ToolInfo.dResidualDepth
|
||||
Machining.Pocketing[2].sDepth = Proc.FeatureInfo.dMortiseDepth - Machining.dResidual
|
||||
@@ -311,11 +311,13 @@ function STR0008.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
-- si applicano le lavorazioni di svuotatura
|
||||
for i = 1, #Strategy.Machining.Pocketing do
|
||||
if Strategy.Machining.Pocketing[i].bIsApplicable then
|
||||
Pocketing = {}
|
||||
Pocketing.Steps = {}
|
||||
Pocketing.LeadIn = {}
|
||||
Pocketing.nType = MCH_MY.POCKETING
|
||||
Pocketing.nSubType = MCH_POCK_SUB.SPIRALOUT
|
||||
Pocketing = MachiningLib.InitMachiningParameters( MCH_MY.POCKETING)
|
||||
-- se mortasa aperta su un lato si usa SpiralIn
|
||||
if ( Proc.AffectedFaces.bFront or Proc.AffectedFaces.bBack) and ( Proc.AffectedFaces.bTop or Proc.AffectedFaces.bBottom) then
|
||||
Pocketing.nSubType = MCH_POCK_SUB.SPIRALIN
|
||||
else
|
||||
Pocketing.nSubType = MCH_POCK_SUB.SPIRALOUT
|
||||
end
|
||||
Pocketing.LeadIn.nType = MCH_POCK_LI.ZIGZAG
|
||||
Pocketing.Steps.dStep = TOOLS[Strategy.Machining.Pocketing[i].ToolInfo.nToolIndex].dStep
|
||||
Pocketing.Steps.dSideStep = TOOLS[Strategy.Machining.Pocketing[i].ToolInfo.nToolIndex].dSideStep
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"sStrategyId": "STR0009",
|
||||
"sStrategyName": "Mill Heading",
|
||||
"sStrategyName": "ScarfJoint",
|
||||
"ParameterList" : [
|
||||
{
|
||||
"sName": "dDepthChamfer",
|
||||
@@ -8,46 +8,32 @@
|
||||
"sValue": "0",
|
||||
"sDescriptionShort": "Depth Chamfer",
|
||||
"sDescriptionLong": "Depth of the V-Mill to execute chamfers on cut-edges",
|
||||
"idDescriptionShortMsg": 1000195,
|
||||
"idDescriptionLongMsg": 1000196,
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
},
|
||||
{
|
||||
"sName": "dOverMaterial",
|
||||
"sNameNge": "OVERMAT",
|
||||
"sValue": "0",
|
||||
"sDescriptionShort": "Overmaterial",
|
||||
"sDescriptionLong": "",
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
},
|
||||
{
|
||||
"sName": "bForceStrip",
|
||||
"sNameNge": "FORCE_STRIP",
|
||||
"sName": "bAntiSplint",
|
||||
"sNameNge": "ANTISPLINT",
|
||||
"sValue": "false",
|
||||
"sDescriptionShort": "Force strip",
|
||||
"sDescriptionLong": "Enable the parameter to force the software to leave a strip to sustain the piece",
|
||||
"sDescriptionShort": "Use Anti-Splint strategy",
|
||||
"sDescriptionLong": "The strategy will apply blade cuts on corner to avoid wood splint",
|
||||
"idDescriptionShortMsg": 1000197,
|
||||
"idDescriptionLongMsg": 1000198,
|
||||
"sType": "b",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
},
|
||||
{
|
||||
"sName": "dStripWidth",
|
||||
"sNameNge": "STRIP_WIDTH",
|
||||
"sValue": "0",
|
||||
"sDescriptionShort": "Strip width",
|
||||
"sDescriptionLong": "Width of the strip in case if foreseen from the machining",
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
},
|
||||
{
|
||||
"sName": "sMillingList",
|
||||
"sNameNge": "PROFILE_TOOL_LIST",
|
||||
"sValue": "",
|
||||
"sDescriptionShort": "Available mill to machine the profile",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000199,
|
||||
"idDescriptionLongMsg": 1000200,
|
||||
"sType": "tool",
|
||||
"sSubType": "MCH_TF.MILL",
|
||||
"sMessageId": " ",
|
||||
|
||||
@@ -1,165 +1,190 @@
|
||||
-- Strategia: STR0009
|
||||
-- Descrizione
|
||||
-- Fresatura di contorno
|
||||
-- Feature tipo Arco
|
||||
-- Feature tipo ScarfJoint
|
||||
|
||||
|
||||
-- carico librerie
|
||||
local BeamLib = require( 'BeamLib')
|
||||
local BeamData = require( 'BeamData')
|
||||
local BeamData = require( 'BeamDataNew')
|
||||
local MachiningLib = require( 'MachiningLib')
|
||||
local FeatureLib = require( 'FeatureLib')
|
||||
-- strategie di base
|
||||
local BladeToWaste = require('BLADETOWASTE')
|
||||
local BladeToWaste = require( 'BLADETOWASTE')
|
||||
local FaceByMill = require( 'FACEBYMILL')
|
||||
local FaceByBlade = require( 'FACEBYBLADE')
|
||||
local AntiSplintOnFace = require( 'ANTISPLINTONFACE')
|
||||
|
||||
-- Tabella per definizione modulo
|
||||
local STR0009 = {}
|
||||
local Strategy = {}
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- TODO gestire il caso in cui non si trova l'utensile
|
||||
local function GetArcStrategy( Proc, Part)
|
||||
local Machining = {}
|
||||
local ToolSearchParameters = {}
|
||||
local function GetFacesIdOrder( Proc, Part)
|
||||
local Faces = {}
|
||||
if Proc.nFct == 5 then
|
||||
-- carico gli id delle facce
|
||||
for i = 1, Proc.nFct do
|
||||
Faces[#Faces + 1] = BeamLib.TableCopyDeep( Proc.Faces[i])
|
||||
end
|
||||
elseif Proc.nFct == 4 then
|
||||
local vtN1 = Proc.Faces[1].vtN
|
||||
local vtN2 = Proc.Faces[2].vtN
|
||||
local nIndex = EgtIf( abs( vtN1:getX()) > abs( vtN2:getX()), 1, 2)
|
||||
for i = nIndex, Proc.nFct do
|
||||
Faces[#Faces + 1] = BeamLib.TableCopyDeep( Proc.Faces[i])
|
||||
end
|
||||
-- TODO manca il caso in cui mancano facce 4 e 5
|
||||
else -- Proc.nFct == 3
|
||||
for i = 2, Proc.nFct do
|
||||
Faces[#Faces + 1] = BeamLib.TableCopyDeep( Proc.Faces[i])
|
||||
end
|
||||
end
|
||||
|
||||
-- recupero e verifico l'entità curva
|
||||
local idAux = EgtGetInfo( Proc.id, 'AUXID', 'i')
|
||||
if idAux then idAux = idAux + Proc.id end
|
||||
if not idAux or ( EgtGetType( idAux) & GDB_FY.GEO_CURVE) == 0 then
|
||||
local sErr = 'Error on process ' .. tostring( Proc.id) .. ' missing profile geometry'
|
||||
return Faces
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function GetEdgeToMachine( ClosingFace, idBottomFace)
|
||||
local EdgeToMachine
|
||||
|
||||
for i = 1, #ClosingFace.Edges do
|
||||
if ClosingFace.Edges[i].idAdjacentFace == idBottomFace then
|
||||
EdgeToMachine = ClosingFace.Edges[i]
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
return EdgeToMachine
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function GetScarfJointStrategy( Proc, Part)
|
||||
-- ordino le facce in base al loro numero e al parallelismo delle due facce principali
|
||||
-- faccia 0: superficie tappo (*potrebbe non esserci)
|
||||
-- faccia 1: superficie principale di fondo
|
||||
-- faccia 2: superficie opposta alla faccia 1
|
||||
-- faccia 3: superficie principale superiore
|
||||
-- faccia 4: superficie di testa (*potrebbe non esserci)
|
||||
-- creo una tabella unica contenente tutte le lavorazioni
|
||||
local Result = {}
|
||||
local Cutting = { Machinings = {}, Result = {}}
|
||||
local AntiSplints = {}
|
||||
local Pocketing = {}
|
||||
|
||||
Result.dTimeToMachine = 0
|
||||
local Faces = GetFacesIdOrder( Proc)
|
||||
-- taglio su faccia 4
|
||||
if Faces[4] and Faces[4].vtN then
|
||||
-- recupero gruppo per geometria addizionale
|
||||
local nAddGrpId = BeamLib.GetAddGroup( Part.id)
|
||||
-- TODO la nuova faccia creata sulla 4 può tagliare faccia 1. In caso tagliasse faccia 1, bisogna calcolare i cubetti con 2 facce
|
||||
Strategy.idFeatureCutPlane = EgtSurfTmPlaneInBBox( nAddGrpId, Faces[4].ptCenter, Faces[4].vtN, Part.b3Part, GDB_RT.GLOB)
|
||||
Cutting.Machinings, Cutting.Result = BladeToWaste.Make( Strategy.idFeatureCutPlane, Part)
|
||||
if Cutting.Result.sStatus == 'Completed' then
|
||||
Cutting.Machinings.bIsApplicable = true
|
||||
end
|
||||
end
|
||||
|
||||
-- antischeggia facce 1 e 3
|
||||
local bAreAllAntisplintsApplicable = true
|
||||
if Strategy.Parameters.bAntiSplint then
|
||||
AntiSplints = AntiSplintOnFace.Make( Proc, Part, Faces[2])
|
||||
for k = 1, #AntiSplints do
|
||||
if not AntiSplints[k].bIsApplicable then
|
||||
bAreAllAntisplintsApplicable = false
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- svuotatura faccia 2
|
||||
if Faces[2] then
|
||||
local frPock, dL, dW = EgtSurfTmFacetMinAreaRectangle( Proc.id, Faces[2].id, GDB_ID.ROOT)
|
||||
local ToolSearchParameters = {}
|
||||
ToolSearchParameters.sMillShape = 'STANDARD'
|
||||
ToolSearchParameters.vtToolDirection = Faces[2].vtN
|
||||
ToolSearchParameters.dElevation = abs( ( Faces[2].ptCenter - Faces[4].ptCenter) * Faces[2].vtN)
|
||||
ToolSearchParameters.dMaxToolDiameter = min( dL, dW)
|
||||
ToolSearchParameters.ToolInfo = {}
|
||||
ToolSearchParameters.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
|
||||
if ToolSearchParameters.ToolInfo.nToolIndex then
|
||||
local Machining = MachiningLib.InitMachiningParameters( MCH_MY.POCKETING)
|
||||
Machining.Geometry = {{ Proc.id, Faces[2].id}}
|
||||
Machining.dElevation = ToolSearchParameters.dElevation
|
||||
Machining.dMaxElev = Machining.dElevation
|
||||
Machining.vtToolDirection = ToolSearchParameters.vtToolDirection
|
||||
Machining.nSubType = MCH_POCK_SUB.SPIRALIN
|
||||
Machining.LeadIn.nType = MCH_POCK_LI.ZIGZAG
|
||||
Machining.Steps.dStep = TOOLS[ToolSearchParameters.ToolInfo.nToolIndex].dStep
|
||||
Machining.Steps.dSideStep = TOOLS[ToolSearchParameters.ToolInfo.nToolIndex].dSideStep
|
||||
Machining.nToolIndex = ToolSearchParameters.ToolInfo.nToolIndex
|
||||
Machining.LeadIn.dTangentDistance = TOOLS[ToolSearchParameters.ToolInfo.nToolIndex].dDiameter / 2
|
||||
Machining.LeadIn.dElevation = TOOLS[ToolSearchParameters.ToolInfo.nToolIndex].dDiameter / 2
|
||||
Machining.sDepth = 0
|
||||
Machining.dResidualDepth = ToolSearchParameters.ToolInfo.dResidualDepth
|
||||
-- TODO vedere se questo parametro con svuotature nuove si può rimuovere
|
||||
Machining.dOpenMinSafe = Strategy.Parameters.dOpenMinSafe
|
||||
Machining.dTimeToMachine = MachiningLib.GetTimeToMachineAllStepsWithLeadInOut( Machining, Part)
|
||||
Result.dTimeToMachine = Result.dTimeToMachine + Machining.dTimeToMachine
|
||||
table.insert( Pocketing, Machining)
|
||||
Pocketing.bIsApplicable = true
|
||||
-- se non sono stati fatti i passaggi antischeggia si verifica che le facce siano a 90°, altrimenti serve passaggio con fresa
|
||||
if not Strategy.Parameters.bAntiSplint or not bAreAllAntisplintsApplicable then
|
||||
local dAngleBetweenFaces = Proc.AdjacencyMatrix[1][2] or 0
|
||||
-- si fa passaggio con fresa
|
||||
if dAngleBetweenFaces > -90 then
|
||||
local EdgeToMachine = GetEdgeToMachine( Faces[1], Faces[2].id)
|
||||
local CuttingClosingFace = FaceByBlade.Make( Proc, Part, Faces[1], EdgeToMachine)
|
||||
if CuttingClosingFace.bIsApplicable then
|
||||
table.insert( AntiSplints, CuttingClosingFace)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- se manca taglio principale, feature non eseguibile
|
||||
if not Cutting.Machinings.bIsApplicable then
|
||||
local sErr = 'Feature '.. Proc.idFeature .. ' : strategy ' .. Strategy.sName .. ' not applicable'
|
||||
EgtOutLog( sErr)
|
||||
return false, sErr
|
||||
end
|
||||
Proc.idAddAuxGeom = idAux
|
||||
|
||||
-- recupero i dati della curva e del profilo
|
||||
local dDepth = abs( EgtCurveThickness( idAux))
|
||||
local vtExtr = EgtCurveExtrusion( idAux, GDB_RT.GLOB)
|
||||
local bToolInvert = ( vtExtr:getZ() < -0.1)
|
||||
local bIsHorizontal = abs( vtExtr:getZ()) < 10 * GEO.EPS_SMALL
|
||||
local bIsFeatureDown = Proc.AffectedFaces.bBottom and not Proc.AffectedFaces.bTop
|
||||
local bIsFeatureBack = Proc.AffectedFaces.bBack and not Proc.AffectedFaces.bFront
|
||||
local bForceStrip = Strategy.Parameters.bForceStrip
|
||||
local dDimStrip = EgtIf( Strategy.Parameters.dStripWidth < 100 * GEO.EPS_SMALL, nil, Strategy.Parameters.dStripWidth)
|
||||
|
||||
local bExecStrip = false
|
||||
-- se la lavorazione si trova nella parte inferiore o in battuta dietro, il codolo va sempre lasciato
|
||||
if bIsFeatureDown or bIsFeatureBack or bForceStrip then
|
||||
if bIsFeatureDown or bIsFeatureBack then
|
||||
dDimStrip = dDimStrip or max( BeamData.DIM_STRIP or 5, 5)
|
||||
else
|
||||
dDimStrip = dDimStrip or max( BeamData.DIM_STRIP_SMALL or 5, 1)
|
||||
end
|
||||
bExecStrip = true
|
||||
end
|
||||
if not bExecStrip then
|
||||
dDimStrip = 0
|
||||
end
|
||||
|
||||
-- se lavorazione orizzontale
|
||||
if bIsHorizontal then
|
||||
local bDouble
|
||||
local Milling = MachiningLib.InitMachiningParameters( MCH_MY.MILLING)
|
||||
Milling.bIsApplicable = false
|
||||
ToolSearchParameters = {}
|
||||
ToolSearchParameters.sMillShape = 'STANDARD'
|
||||
ToolSearchParameters.dElevation = EgtIf( bExecStrip, ( dDepth - dDimStrip) / 2, dDepth + BeamData.MILL_OVERLAP)
|
||||
ToolSearchParameters.vtToolDirection = EgtIf( bToolInvert, -vtExtr, vtExtr)
|
||||
ToolSearchParameters.AvailableToolList = MachiningLib.GetAvailableToolList( Proc, Strategy.Parameters.sMillingList, 'Milling')
|
||||
Milling.ToolInfo = {}
|
||||
Milling.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
|
||||
-- se posso lavorare in una passata, ma utensile trovato non completa la lavorazione,
|
||||
-- allora provo a cercare utensile con massimo materiale sufficiente per fare le due passate, magari trova un utensile più prestante
|
||||
if Milling.ToolInfo.dResidualDepth > 10 * GEO.EPS_SMALL and not bExecStrip then
|
||||
bDouble = true
|
||||
ToolSearchParameters.dElevation = ( dDepth + BeamData.MILL_OVERLAP) / 2
|
||||
ToolSearchParameters.vtToolDirection = EgtIf( bToolInvert, -vtExtr, vtExtr)
|
||||
end
|
||||
Milling.bToolInvert = bToolInvert
|
||||
Milling.vtToolDirection = vtExtr
|
||||
|
||||
if bDouble or bExecStrip then
|
||||
if bDouble then
|
||||
Milling.sDepth = ( dDepth + BeamData.MILL_OVERLAP) / 2
|
||||
else
|
||||
Milling.sDepth = ( dDepth - dDimStrip) / 2
|
||||
end
|
||||
table.insert( Machining, Milling)
|
||||
local Milling2 = BeamLib.TableCopyDeep( Milling)
|
||||
table.insert( Machining, Milling2)
|
||||
else
|
||||
Milling.sDepth = dDepth + BeamData.MILL_OVERLAP
|
||||
table.insert( Machining, Milling)
|
||||
end
|
||||
-- se lavorazione verticale
|
||||
Result = FeatureLib.GetStrategyResultNotApplicable( sErr)
|
||||
else
|
||||
-- si cerca utensile 1
|
||||
local Milling = {}
|
||||
Milling.bIsApplicable = false
|
||||
ToolSearchParameters = {}
|
||||
ToolSearchParameters.sMillShape = 'STANDARD'
|
||||
ToolSearchParameters.dElevation = dDepth + BeamData.MILL_OVERLAP
|
||||
ToolSearchParameters.vtToolDirection = EgtIf( bToolInvert, -vtExtr, vtExtr)
|
||||
ToolSearchParameters.AvailableToolList = MachiningLib.GetAvailableToolList( Proc, Strategy.Parameters.sMillingList, 'Milling')
|
||||
Milling.ToolInfo = {}
|
||||
Milling.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
|
||||
-- si cerca utensile 2
|
||||
local Milling2 = {}
|
||||
Milling2.bIsApplicable = false
|
||||
ToolSearchParameters = {}
|
||||
ToolSearchParameters.sMillShape = 'STANDARD'
|
||||
ToolSearchParameters.dElevation = dDepth + BeamData.MILL_OVERLAP
|
||||
ToolSearchParameters.vtToolDirection = EgtIf( bToolInvert, vtExtr, -vtExtr)
|
||||
ToolSearchParameters.AvailableToolList = MachiningLib.GetAvailableToolList( Proc, Strategy.Parameters.sMillingList, 'Milling')
|
||||
Milling2.ToolInfo = {}
|
||||
Milling2.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
|
||||
|
||||
-- se serve codolo
|
||||
if bExecStrip then
|
||||
-- se a disposizione entrambi gli utensili
|
||||
if Milling.ToolInfo.nToolIndex and Milling2.ToolInfo.nToolIndex then
|
||||
table.insert( Machining, Milling)
|
||||
table.insert( Machining, Milling2)
|
||||
-- se disponibile solo primo utensile
|
||||
elseif Milling.ToolInfo.nToolIndex then
|
||||
table.insert( Machining, Milling)
|
||||
-- se disponibile solo secondo utensile
|
||||
elseif Milling2.ToolInfo.nToolIndex then
|
||||
table.insert( Machining, Milling2)
|
||||
-- nessun utensile disponibile
|
||||
local dCompletionPercentage = 100
|
||||
-- completa se svuotatura eseguita e antisplit eseguiti (o non richiesti)
|
||||
if Pocketing.bIsApplicable and ( bAreAllAntisplintsApplicable or not Strategy.Parameters.bAntiSplint) then
|
||||
Result.sStatus = 'Completed'
|
||||
if bAreAllAntisplintsApplicable then
|
||||
Result.dQuality = FeatureLib.GetStrategyQuality( 'FINE')
|
||||
else
|
||||
-- non si fa nulla
|
||||
Result.dQuality = FeatureLib.GetStrategyQuality( 'STD')
|
||||
end
|
||||
-- altrimenti senza codolo
|
||||
-- altrimenti non completa
|
||||
else
|
||||
-- se utensile 1 esegue completamente
|
||||
if Milling.ToolInfo.nToolIndex and Milling.ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then
|
||||
table.insert( Machining, Milling)
|
||||
-- se utensile 2 esegue completamente
|
||||
elseif Milling2.ToolInfo.nToolIndex and Milling2.ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then
|
||||
table.insert( Machining, Milling2)
|
||||
-- se possono lavorare entrambi
|
||||
elseif Milling.ToolInfo.nToolIndex and Milling2.ToolInfo.nToolIndex then
|
||||
table.insert( Machining, Milling)
|
||||
table.insert( Machining, Milling2)
|
||||
-- se utensile 1 non completo
|
||||
elseif Milling.ToolInfo.nToolIndex then
|
||||
table.insert( Machining, Milling)
|
||||
-- se utensile 2 non completo
|
||||
elseif Milling2.ToolInfo.nToolIndex then
|
||||
table.insert( Machining, Milling2)
|
||||
Result.dQuality = FeatureLib.GetStrategyQuality( 'STD')
|
||||
Result.sStatus = 'Not-Completed'
|
||||
-- se fa solo svuotatura
|
||||
if Pocketing.bIsApplicable then
|
||||
dCompletionPercentage = 90
|
||||
Result.sInfo = 'Anti-Split not executed'
|
||||
elseif Strategy.Parameters.bAntiSplint and bAreAllAntisplintsApplicable then
|
||||
dCompletionPercentage = 75
|
||||
Result.sInfo = 'Pocketing not executed'
|
||||
else
|
||||
dCompletionPercentage = 50
|
||||
Result.sInfo = 'Only the cut has been executed'
|
||||
end
|
||||
end
|
||||
|
||||
Result.dCompletionIndex = FeatureLib.GetFeatureCompletionIndex( dCompletionPercentage)
|
||||
end
|
||||
|
||||
-- TODO VOTO DA FARE!!!!
|
||||
Strategy.Result.sStatus = 'Completed'
|
||||
Strategy.Result.dCompletionIndex = 5
|
||||
Strategy.Result.dMRR = MachiningLib.GetToolMRR( Machining[1].ToolInfo or Machining[2].ToolInfo)
|
||||
Strategy.Result.dQuality = FeatureLib.GetStrategyQuality( 'MILL')
|
||||
Strategy.Result.sInfo = ''
|
||||
-- creo una tabella unica contenente tutte le lavorazioni
|
||||
local Machinings = {}
|
||||
EgtJoinTables( Machinings, Cutting.Machinings)
|
||||
EgtJoinTables( Machinings, AntiSplints)
|
||||
EgtJoinTables( Machinings, Pocketing)
|
||||
|
||||
return Machining
|
||||
return Machinings, Result
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
@@ -173,80 +198,33 @@ function STR0009.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
Strategy.Result = {}
|
||||
|
||||
local bAreAllMachiningsAdded = true
|
||||
local Milling = {}
|
||||
|
||||
Strategy.Machinings = GetArcStrategy( Proc, Part)
|
||||
-- controlli preliminari
|
||||
if Proc.nFct < 3 or Proc.nFct > 5 then
|
||||
local sErr = 'Feature '.. Proc.idFeature .. ' : strategy ' .. StrategyLib.Config.sStrategyId .. ' not applicable'
|
||||
EgtOutLog( sErr)
|
||||
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( sErr)
|
||||
return false, Strategy.Result
|
||||
end
|
||||
|
||||
if bAddMachining and Strategy.Result.sStatus ~= 'Not-Applicable' then
|
||||
-- eventuali punti di spezzatura
|
||||
local FeatureSplittingPoints = FeatureLib.GetFeatureSplittingPoints( Proc, Part)
|
||||
Strategy.Machinings, Strategy.Result = GetScarfJointStrategy( Proc, Part)
|
||||
|
||||
for i = 1, #Strategy.Machinings do
|
||||
|
||||
Strategy.Machinings[i].Geometry = {{ Proc.idAddAuxGeom, -1}}
|
||||
Strategy.Machinings[i].nToolIndex = Strategy.Machinings[i].ToolInfo.nToolIndex
|
||||
Strategy.Machinings[i].nType = MCH_MY.MILLING
|
||||
Strategy.Machinings[i].dStartSafetyLength = 0
|
||||
Strategy.Machinings[i].Steps = {}
|
||||
Strategy.Machinings[i].Steps.dStep = TOOLS[Strategy.Machinings[i].ToolInfo.nToolIndex].dStep
|
||||
Strategy.Machinings[i].Steps = MachiningLib.GetMachiningSteps( tonumber( Strategy.Machinings[i].sDepth), TOOLS[Strategy.Machinings[i].nToolIndex].dStep)
|
||||
|
||||
-- LeadIn / LeadOut
|
||||
Strategy.Machinings[i].LeadIn = {}
|
||||
Strategy.Machinings[i].LeadOut = {}
|
||||
Strategy.Machinings[i].LeadIn.nType = MCH_MILL_LI.TANGENT
|
||||
Strategy.Machinings[i].LeadOut.nType = MCH_MILL_LI.TANGENT
|
||||
Strategy.Machinings[i].LeadIn.dTangentDistance = TOOLS[Strategy.Machinings[i].ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC
|
||||
Strategy.Machinings[i].LeadIn.dPerpDistance = 0
|
||||
Strategy.Machinings[i].LeadIn.dStartAddLength = 0
|
||||
Strategy.Machinings[i].LeadOut.dTangentDistance = TOOLS[Strategy.Machinings[i].ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC
|
||||
Strategy.Machinings[i].LeadOut.dPerpDistance = 0
|
||||
Strategy.Machinings[i].LeadOut.dEndAddLength = 0
|
||||
|
||||
local dLengthOnX = Proc.b3Box:getDimX()
|
||||
Strategy.bCanMoveAfterSplit = MachiningLib.CanMoveAfterSplitcut( dLengthOnX, Part)
|
||||
if Proc.AffectedFaces.bLeft and Strategy.bCanMoveAfterSplit then
|
||||
Strategy.Machinings[i].sStage = 'AfterTail'
|
||||
end
|
||||
|
||||
-- preparo attacco/uscita in caso di spezzatura arco
|
||||
Strategy.Machinings[i].LeadInForSplit = BeamLib.TableCopyDeep( Strategy.Machinings[i].LeadIn)
|
||||
Strategy.Machinings[i].LeadOutForSplit = BeamLib.TableCopyDeep( Strategy.Machinings[i].LeadOut)
|
||||
Strategy.Machinings[i].LeadInForSplit.nType = MCH_MILL_LI.LINEAR
|
||||
Strategy.Machinings[i].LeadOutForSplit.nType = MCH_MILL_LI.LINEAR
|
||||
Strategy.Machinings[i].LeadInForSplit.dTangentDistance = 0
|
||||
Strategy.Machinings[i].LeadInForSplit.dPerpDistance = TOOLS[Strategy.Machinings[i].ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC
|
||||
Strategy.Machinings[i].LeadOutForSplit.dTangentDistance = 0
|
||||
Strategy.Machinings[i].LeadOutForSplit.dPerpDistance = TOOLS[Strategy.Machinings[i].ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC
|
||||
|
||||
-- sistemo il lato e la direzione di lavoro
|
||||
if i == 1 then
|
||||
Strategy.Machinings[i].bInvert = EgtIf( TOOLS[Strategy.Machinings[i].ToolInfo.nToolIndex].bIsCCW, false, true)
|
||||
Strategy.Machinings[i].nWorkside = EgtIf( TOOLS[Strategy.Machinings[i].ToolInfo.nToolIndex].bIsCCW, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT)
|
||||
else
|
||||
Strategy.Machinings[i].bToolInvert = true
|
||||
Strategy.Machinings[i].bInvert = EgtIf( TOOLS[Strategy.Machinings[i].ToolInfo.nToolIndex].bIsCCW, true, false)
|
||||
Strategy.Machinings[i].nWorkside = EgtIf( TOOLS[Strategy.Machinings[i].ToolInfo.nToolIndex].bIsCCW, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT)
|
||||
end
|
||||
Strategy.Machinings[i].ptEdge1 = EgtSP( Proc.idAddAuxGeom, GDB_ID.ROOT)
|
||||
Strategy.Machinings[i].ptEdge2 = EgtEP( Proc.idAddAuxGeom, GDB_ID.ROOT)
|
||||
Strategy.Machinings[i].dEdgeLength = EgtCurveLength( Proc.idAddAuxGeom)
|
||||
Strategy.Machinings[i].vtEdgeDirection = EgtSV( Proc.idAddAuxGeom, GDB_ID.ROOT) + EgtMV( Proc.idAddAuxGeom, GDB_ID.ROOT) + EgtEV( Proc.idAddAuxGeom, GDB_ID.ROOT)
|
||||
Strategy.Machinings[i].dLengthOnX = Proc.b3Box:getDimX()
|
||||
|
||||
local MachiningToSplit = {}
|
||||
table.insert( MachiningToSplit, Strategy.Machinings[i])
|
||||
local MachiningResult = MachiningLib.GetSplitMachinings( MachiningToSplit, FeatureSplittingPoints, Part)
|
||||
-- aggiunta lavorazioni
|
||||
if #Strategy.Machinings > 0 then
|
||||
if bAddMachining and Strategy.Result.sStatus ~= 'Not-Applicable' then
|
||||
-- aggiunge lavorazione
|
||||
for j = 1, #MachiningResult do
|
||||
bAreAllMachiningsAdded = MachiningLib.AddMachinings( Proc, MachiningResult[j])
|
||||
for j = 1, #Strategy.Machinings do
|
||||
if Proc.AffectedFaces.bLeft then
|
||||
Strategy.Machinings[j].sStage = 'AfterTail'
|
||||
end
|
||||
bAreAllMachiningsAdded = MachiningLib.AddMachinings( Proc, Strategy.Machinings[j])
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
bAreAllMachiningsAdded = false
|
||||
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable()
|
||||
end
|
||||
|
||||
|
||||
return bAreAllMachiningsAdded, Strategy.Result
|
||||
end
|
||||
|
||||
|
||||
@@ -3,11 +3,13 @@
|
||||
"sStrategyName": "Milling",
|
||||
"ParameterList" : [
|
||||
{
|
||||
"sName": "dAntiSplintWithBlade",
|
||||
"sName": "bAntiSplintWithBlade",
|
||||
"sNameNge": "ANTISPLINT_BLADE",
|
||||
"sValue": "false",
|
||||
"sDescriptionShort": "Antisplint with blade",
|
||||
"sDescriptionLong": "Use the blade as antisplint in case the geometry is not through",
|
||||
"idDescriptionShortMsg": 1000201,
|
||||
"idDescriptionLongMsg": 1000202,
|
||||
"sType": "b",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -17,7 +19,33 @@
|
||||
"sNameNge": "EXTEND_AFTER_TAIL",
|
||||
"sValue": "",
|
||||
"sDescriptionShort": "Extend after tail",
|
||||
"sDescriptionLong": "The automatism considers this lenght as machinable. This means you accept to damage the next piece in the bar",
|
||||
"sDescriptionLong": "The automatism considers this length as machinable. This means you accept to damage the next piece in the bar",
|
||||
"idDescriptionShortMsg": 1000203,
|
||||
"idDescriptionLongMsg": 1000204,
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
},
|
||||
{
|
||||
"sName": "bFinishWithMill",
|
||||
"sNameNge": "ALLOW_FINISH_MILL",
|
||||
"sValue": "true",
|
||||
"sDescriptionShort": "Clean radius with mill",
|
||||
"sDescriptionLong": "Clean radius with mill",
|
||||
"idDescriptionShortMsg": 1000205,
|
||||
"idDescriptionLongMsg": 1000206,
|
||||
"sType": "b",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
},
|
||||
{
|
||||
"sName": "dMillingOffsetFromSide",
|
||||
"sNameNge": "MILLING_OFFSET_SIDE",
|
||||
"sValue": "1",
|
||||
"sDescriptionShort": "Milling offset from side",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000207,
|
||||
"idDescriptionLongMsg": 1000208,
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -28,6 +56,8 @@
|
||||
"sValue": "NEVER",
|
||||
"sDescriptionShort": "Damage next piece",
|
||||
"sDescriptionLong": "This option allows you to decide how to consider the next piece in the bar. The software calculates specifics LeadIn/out to respect the parameter. This parameter may change the machining time",
|
||||
"idDescriptionShortMsg": 1000209,
|
||||
"idDescriptionLongMsg": 1000210,
|
||||
"sType": "combo",
|
||||
"sMinUserLevel": "1",
|
||||
"Choices": [
|
||||
@@ -35,18 +65,24 @@
|
||||
"sValue": "NEVER",
|
||||
"sDescriptionShort": "Never damage",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000211,
|
||||
"idDescriptionLongMsg": 1000212,
|
||||
"sMessageId": ""
|
||||
},
|
||||
{
|
||||
"sValue": "ONLY_IF_RAWPART",
|
||||
"sDescriptionShort": "Damage only if raw",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000213,
|
||||
"idDescriptionLongMsg": 1000214,
|
||||
"sMessageId": ""
|
||||
},
|
||||
{
|
||||
"sValue": "ALWAYS",
|
||||
"sDescriptionShort": "Can damage",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000215,
|
||||
"idDescriptionLongMsg": 1000216,
|
||||
"sMessageId": ""
|
||||
}
|
||||
]
|
||||
|
||||
@@ -5,11 +5,13 @@
|
||||
|
||||
-- carico librerie
|
||||
local BeamLib = require( 'BeamLib')
|
||||
local BeamData = require( 'BeamData')
|
||||
local BeamData = require( 'BeamDataNew')
|
||||
local MachiningLib = require( 'MachiningLib')
|
||||
local FeatureLib = require( 'FeatureLib')
|
||||
-- strategie di base
|
||||
local FaceByMill = require('FACEBYMILL')
|
||||
local FaceByMill = require( 'FACEBYMILL')
|
||||
local FaceByBlade = require( 'FACEBYBLADE')
|
||||
local AntiSplintOnFace = require( 'ANTISPLINTONFACE')
|
||||
|
||||
-- Tabella per definizione modulo
|
||||
local STR0010 = {}
|
||||
@@ -34,7 +36,7 @@ local function GetStrategyCompletionPercentage( Machinings)
|
||||
if nWeightsCount ~= 0 and nWeightsCount ~= i then
|
||||
error( 'GetWeightedCompletionPercentage : inconsistent weights')
|
||||
end
|
||||
local dWeightedCompletionPercentage = Machining.dCompletionPercentage / 100 * dWeight
|
||||
local dWeightedCompletionPercentage = ( Machining.dCompletionPercentage or 0) / 100 * dWeight
|
||||
if Machining.bIsApplicable then
|
||||
dCompletionPercentageNumerator = dCompletionPercentageNumerator + dWeightedCompletionPercentage
|
||||
end
|
||||
@@ -47,34 +49,52 @@ local function GetStrategyCompletionPercentage( Machinings)
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function CompareEdges( EdgeA, EdgeB)
|
||||
-- prima i lati orientati lungo X
|
||||
if abs( EdgeA.vtN:getX()) < abs( EdgeB.vtN:getX()) - 10 * GEO.EPS_SMALL then
|
||||
local function CompareEdgesLongestTop( EdgeA, EdgeB)
|
||||
-- si preferiscono i lati più lunghi
|
||||
if EdgeA.dLength > EdgeB.dLength + 10 * GEO.EPS_SMALL then
|
||||
return true
|
||||
elseif abs( EdgeA.vtN:getX()) > abs( EdgeB.vtN:getX()) + 10 * GEO.EPS_SMALL then
|
||||
elseif EdgeA.dLength < EdgeB.dLength - 10 * GEO.EPS_SMALL then
|
||||
return false
|
||||
-- se stessa X si preferiscono i lati più lunghi (nel caso di 5 lati è quello non spezzato)
|
||||
-- se stessa lunghezza si preferiscono i lati più in basso
|
||||
else
|
||||
if EdgeA.dLength > EdgeB.dLength + 10 * GEO.EPS_SMALL then
|
||||
if EdgeA.vtN:getZ() > EdgeB.vtN:getZ() + 10 * GEO.EPS_SMALL then
|
||||
return true
|
||||
elseif EdgeA.dLength < EdgeB.dLength - 10 * GEO.EPS_SMALL then
|
||||
elseif EdgeA.vtN:getZ() < EdgeB.vtN:getZ() - 10 * GEO.EPS_SMALL then
|
||||
return false
|
||||
-- se stessa lunghezza si preferiscono i lati più in basso
|
||||
-- TODO qui dipenderà dalla lama scelta
|
||||
-- se stessa Z si preferiscono i lati verso il fronte della trave
|
||||
else
|
||||
if EdgeA.vtN:getZ() > EdgeB.vtN:getZ() + 10 * GEO.EPS_SMALL then
|
||||
if EdgeA.vtN:getY() > EdgeB.vtN:getY() + 10 * GEO.EPS_SMALL then
|
||||
return true
|
||||
elseif EdgeA.vtN:getZ() < EdgeB.vtN:getZ() - 10 * GEO.EPS_SMALL then
|
||||
elseif EdgeA.vtN:getY() < EdgeB.vtN:getY() - 10 * GEO.EPS_SMALL then
|
||||
return false
|
||||
-- se stessa Z si preferiscono i lati verso il fronte della trave
|
||||
else
|
||||
if EdgeA.vtN:getY() > EdgeB.vtN:getY() + 10 * GEO.EPS_SMALL then
|
||||
return true
|
||||
elseif EdgeA.vtN:getY() < EdgeB.vtN:getY() - 10 * GEO.EPS_SMALL then
|
||||
return false
|
||||
else
|
||||
return false
|
||||
end
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function CompareEdgesLongestBottom( EdgeA, EdgeB)
|
||||
-- si preferiscono i lati più lunghi
|
||||
if EdgeA.dLength > EdgeB.dLength + 10 * GEO.EPS_SMALL then
|
||||
return true
|
||||
elseif EdgeA.dLength < EdgeB.dLength - 10 * GEO.EPS_SMALL then
|
||||
return false
|
||||
-- se stessa lunghezza si preferiscono i lati più in alto
|
||||
else
|
||||
if EdgeA.vtN:getZ() < EdgeB.vtN:getZ() - 10 * GEO.EPS_SMALL then
|
||||
return true
|
||||
elseif EdgeA.vtN:getZ() > EdgeB.vtN:getZ() + 10 * GEO.EPS_SMALL then
|
||||
return false
|
||||
-- se stessa Z si preferiscono i lati verso il fronte della trave
|
||||
else
|
||||
if EdgeA.vtN:getY() > EdgeB.vtN:getY() + 10 * GEO.EPS_SMALL then
|
||||
return true
|
||||
elseif EdgeA.vtN:getY() < EdgeB.vtN:getY() - 10 * GEO.EPS_SMALL then
|
||||
return false
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -83,7 +103,8 @@ end
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function IsTopologyOk( Proc)
|
||||
if Proc.Topology.sFamily == 'Bevel' or Proc.Topology.sFamily == 'DoubleBevel' or
|
||||
Proc.Topology.sName == 'VGroove-2-Through' or Proc.Topology.sName == 'Rabbet-2-Through' then
|
||||
Proc.Topology.sName == 'VGroove-2-Through' or Proc.Topology.sName == 'Rabbet-2-Through' or
|
||||
Proc.Topology.sName == 'Cut-1-Through' then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
@@ -92,7 +113,7 @@ end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- TODO modificare funzione e verificare pinzaggio con regioni e area outline
|
||||
local function IsPositionOK( Proc, Part)
|
||||
local function IsPositionOk( Proc, Part)
|
||||
local bIsFeatureLong = FeatureLib.IsMachiningLong( Proc.b3Box:getDimX(), Part, { dMaxSegmentLength = BeamData.LONGCUT_ENDLEN})
|
||||
-- se impatta su faccia retro o sotto, controllo fattibilità
|
||||
if Proc.AffectedFaces.bBack then
|
||||
@@ -111,31 +132,24 @@ local function IsPositionOK( Proc, Part)
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- TODO da sistemare
|
||||
local function GetBottomFaceEdge( Proc, nIndexFace)
|
||||
local function GetLongEdgeToMachine( Face, bHeadType)
|
||||
local Edge = {}
|
||||
|
||||
-- si lavora la bottom longitudinalmente
|
||||
if Proc.nFct == 1 or Proc.Topology.sFamily == 'DoubleBevel' then
|
||||
local BottomEdgesSorted = {}
|
||||
for i = 1, #Proc.MainFaces.BottomFaces[nIndexFace].Edges do
|
||||
table.insert( BottomEdgesSorted, Proc.MainFaces.BottomFaces[nIndexFace].Edges[i])
|
||||
end
|
||||
table.sort( BottomEdgesSorted, CompareEdges)
|
||||
Edge = BottomEdgesSorted[1]
|
||||
-- edge in comune tra le due facce
|
||||
elseif Proc.nFct == 2 then
|
||||
if nIndexFace == 1 then
|
||||
Edge = Proc.MainFaces.BottomFaces[nIndexFace].MainEdges.LongEdges[1]
|
||||
elseif nIndexFace == 2 then
|
||||
Edge = Proc.MainFaces.BottomFaces[nIndexFace].MainEdges.BottomEdge
|
||||
end
|
||||
local EdgesSorted = {}
|
||||
for i = 1, #Face.Edges do
|
||||
table.insert( EdgesSorted, Face.Edges[i])
|
||||
end
|
||||
if bHeadType.bBottom then
|
||||
table.sort( EdgesSorted, CompareEdgesLongestBottom)
|
||||
else
|
||||
if nIndexFace == 1 then
|
||||
Edge = Proc.MainFaces.BottomFaces[nIndexFace].MainEdges.LongEdges[1]
|
||||
elseif nIndexFace == 2 then
|
||||
Edge = Proc.MainFaces.BottomFaces[nIndexFace].MainEdges.BottomEdge
|
||||
end
|
||||
table.sort( EdgesSorted, CompareEdgesLongestTop)
|
||||
end
|
||||
|
||||
-- se il lato migliore è accessibile si sceglie questo, altrimenti il lato opposto; se entrambi non accessibili (faccia chiusa da due lati) si mantiene il lato scelto
|
||||
Edge = EdgesSorted[1]
|
||||
local EdgeOpposite = BeamLib.FindEdgeBestOrientedAsDirection( Face.Edges, -Edge.vtN)
|
||||
if ( not EdgeOpposite.bIsOpen) and Edge.bIsOpen then
|
||||
Edge = EdgeOpposite
|
||||
end
|
||||
|
||||
return Edge
|
||||
@@ -147,15 +161,28 @@ local function SortMachiningsBySegment( MachiningA, MachiningB)
|
||||
return false
|
||||
elseif MachiningB.nFeatureSegment > MachiningA.nFeatureSegment then
|
||||
return true
|
||||
-- se segmento uguale, si guarda la priorità
|
||||
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
|
||||
if MachiningA.nInternalSortingPriority > MachiningB.nInternalSortingPriority then
|
||||
return false
|
||||
elseif MachiningB.nInternalSortingPriority > MachiningA.nInternalSortingPriority then
|
||||
return true
|
||||
-- se priorità uguale, si minimizzano i cambi di lato
|
||||
else
|
||||
if MachiningA.sEdgeType == 'Side' and MachiningB.sEdgeType ~= 'Side' then
|
||||
return true
|
||||
elseif MachiningB.sEdgeType == 'Side' and MachiningA.sEdgeType ~= 'Side' then
|
||||
local bIsOddSegment = ( MachiningA.nFeatureSegment % 2 ~= 0)
|
||||
if MachiningA.vtToolDirection:getY() < MachiningB.vtToolDirection:getY() - 10 * GEO.EPS_SMALL then
|
||||
if bIsOddSegment then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
elseif MachiningA.vtToolDirection:getY() > MachiningB.vtToolDirection:getY() + 10 * GEO.EPS_SMALL then
|
||||
if bIsOddSegment then
|
||||
return false
|
||||
else
|
||||
return true
|
||||
end
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
@@ -171,6 +198,7 @@ function STR0010.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
Strategy.Parameters = BeamLib.LoadCustomParametersInStrategy( Proc, Part, CustomParameters, StrategyLib.Config)
|
||||
Strategy.Machinings = {}
|
||||
Strategy.Result = {}
|
||||
local CalculatedMachinings = {}
|
||||
|
||||
-- controllo su topologia
|
||||
if not IsTopologyOk( Proc) then
|
||||
@@ -178,16 +206,24 @@ function STR0010.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
return false, Strategy.Result
|
||||
end
|
||||
|
||||
-- controllo dimensioni
|
||||
if not IsPositionOK( Proc, Part) then
|
||||
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( 'Feature not machinable in this position')
|
||||
-- controllo dimensioni solo se non è forzata
|
||||
if not CustomParameters.bForcedStrategy then
|
||||
if not IsPositionOk( Proc, Part) then
|
||||
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( 'Feature not machinable in this position')
|
||||
return false, Strategy.Result
|
||||
end
|
||||
end
|
||||
|
||||
-- se la lavorazione ostacola il pinzaggio, non posso farla, serve una lavorazioen che lasci il testimone
|
||||
if MachiningLib.IsFeatureHinderingClamping( Proc, Part) then
|
||||
local sErr = 'Feature '.. Proc.idFeature .. ' : strategy ' .. StrategyLib.Config.sStrategyId .. ' not applicable ( Feature hinders clamping)'
|
||||
EgtOutLog( sErr)
|
||||
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( sErr)
|
||||
return false, Strategy.Result
|
||||
end
|
||||
|
||||
-- volume della feature
|
||||
local dFeatureVolume = FeatureLib.GetFeatureVolume( Proc, Part)
|
||||
|
||||
-- TODO taglio su eventuali facce di chiusura
|
||||
local dFeatureVolume = Proc.dVolume
|
||||
|
||||
-- eventuali punti di spezzatura
|
||||
local FeatureSplittingPoints = FeatureLib.GetFeatureSplittingPoints( Proc, Part)
|
||||
@@ -201,45 +237,167 @@ function STR0010.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
dExtendAfterTail = 10000
|
||||
end
|
||||
|
||||
-- lavorazione della BottomFace
|
||||
local bAreAllMachiningsAdded = true
|
||||
local Milling = {}
|
||||
local OptionalParametersFaceByMill = { nStepType = MCH_MILL_ST.ONEWAY, bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail}
|
||||
local EdgeToMachine = GetBottomFaceEdge( Proc, 1)
|
||||
if EdgeToMachine.bIsOpen then
|
||||
OptionalParametersFaceByMill.dDepthToMachine = EdgeToMachine.dElevation + BeamData.CUT_EXTRA
|
||||
end
|
||||
Milling = FaceByMill.Make( Proc, Part, Proc.MainFaces.BottomFaces[1], EdgeToMachine, OptionalParametersFaceByMill)
|
||||
if Milling.bIsApplicable then
|
||||
table.insert( Strategy.Machinings, Milling)
|
||||
|
||||
-- ricerca delle Bottom (la principale deve avere 4 lati esatti)
|
||||
local BottomFace1 = Proc.MainFaces.BottomFaces[1]
|
||||
local BottomFace2 = Proc.MainFaces.BottomFaces[2]
|
||||
if #BottomFace1.Edges ~= 4 then
|
||||
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable()
|
||||
return false, Strategy.Result
|
||||
end
|
||||
|
||||
-- si lavora seconda BottomFace
|
||||
if Proc.Topology.sFamily == 'DoubleBevel' or Proc.Topology.sName == 'Rabbet-2-Through' or Proc.Topology.sName == 'Bevel-2-Blind' then
|
||||
local dAngleBetweenFaces = Proc.AdjacencyMatrix[1][2]
|
||||
-- se convesso o concavo maggiore di angolo retto
|
||||
if dAngleBetweenFaces >= -91 then
|
||||
Milling = {}
|
||||
OptionalParametersFaceByMill = { nStepType = MCH_MILL_ST.ONEWAY, bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail}
|
||||
EdgeToMachine = GetBottomFaceEdge( Proc, 2)
|
||||
if EdgeToMachine.bIsOpen then
|
||||
OptionalParametersFaceByMill.dDepthToMachine = EdgeToMachine.dElevation + BeamData.CUT_EXTRA
|
||||
-- ricerca utensile
|
||||
local ToolSearchParameters = {}
|
||||
ToolSearchParameters.dElevation = BottomFace1.dElevation
|
||||
ToolSearchParameters.vtToolDirection = BottomFace1.vtN
|
||||
ToolSearchParameters.bAllowTopHead = true
|
||||
ToolSearchParameters.bAllowBottomHead = true
|
||||
ToolSearchParameters.sMillShape = 'STANDARD'
|
||||
local ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
|
||||
local nToolIndex = ToolInfo.nToolIndex
|
||||
|
||||
-- se utensile non trovato si esce subito
|
||||
if not TOOLS[nToolIndex] or not TOOLS[nToolIndex].sName then
|
||||
local sMessage = 'Mill not found'
|
||||
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( sMessage)
|
||||
return false, Strategy.Result
|
||||
end
|
||||
|
||||
-- per prima si lavora sempre la Bottom principale
|
||||
local Milling1 = {}
|
||||
local OptionalParametersMilling1 = { nStepType = MCH_MILL_ST.ONEWAY, bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail}
|
||||
local BottomEdgeToMachine1 = GetLongEdgeToMachine( BottomFace1, TOOLS[nToolIndex].SetupInfo.HeadType)
|
||||
if BottomEdgeToMachine1.bIsOpen then
|
||||
OptionalParametersMilling1.dDepthToMachine = BottomEdgeToMachine1.dElevation + BeamData.CUT_EXTRA
|
||||
end
|
||||
Milling1 = FaceByMill.Make( Proc, Part, BottomFace1, BottomEdgeToMachine1, OptionalParametersMilling1)
|
||||
Milling1.nInternalSortingPriority = 2
|
||||
Milling1.dResultWeight = 0.3
|
||||
table.insert( CalculatedMachinings, Milling1)
|
||||
|
||||
-- se necessario si lavora la seconda Bottom (solo se ha 4 lati esatti)
|
||||
local Milling2
|
||||
local BottomEdgeToMachine2
|
||||
if BottomFace2 then
|
||||
local dAngleBetweenFaces = Proc.AdjacencyMatrix[BottomFace1.id + 1][BottomFace2.id + 1]
|
||||
if dAngleBetweenFaces >= -89.5 then
|
||||
Milling2 = {}
|
||||
if #BottomFace2.Edges == 4 then
|
||||
local OptionalParametersMilling2 = { nStepType = MCH_MILL_ST.ONEWAY, bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail}
|
||||
BottomEdgeToMachine2 = GetLongEdgeToMachine( BottomFace2, TOOLS[nToolIndex].SetupInfo.HeadType)
|
||||
if BottomEdgeToMachine2.bIsOpen then
|
||||
OptionalParametersMilling2.dDepthToMachine = BottomEdgeToMachine2.dElevation + BeamData.CUT_EXTRA
|
||||
end
|
||||
Milling2 = FaceByMill.Make( Proc, Part, BottomFace2, BottomEdgeToMachine2, OptionalParametersMilling2)
|
||||
Milling2.nInternalSortingPriority = 2
|
||||
Milling2.dResultWeight = 0.3
|
||||
else
|
||||
Milling2.bIsApplicable = false
|
||||
end
|
||||
Milling = FaceByMill.Make( Proc, Part, Proc.MainFaces.BottomFaces[2], EdgeToMachine, OptionalParametersFaceByMill)
|
||||
if Milling.bIsApplicable then
|
||||
table.insert( Strategy.Machinings, Milling)
|
||||
table.insert( CalculatedMachinings, Milling2)
|
||||
end
|
||||
end
|
||||
|
||||
-- fresatura eventuali facce di chiusura (se non già lavorate)
|
||||
-- TODO funzione
|
||||
if Strategy.Parameters.bFinishWithMill then
|
||||
|
||||
if Milling1 then
|
||||
-- si recuperano i lati chiusi non lavorati
|
||||
local EdgesClosedNotMachined = {}
|
||||
for i = 1, #BottomFace1.Edges do
|
||||
if not( ( BottomFace1.Edges[i].id == BottomEdgeToMachine1.id) or BottomFace1.Edges[i].bIsOpen) then
|
||||
table.insert( EdgesClosedNotMachined, BottomFace1.Edges[i])
|
||||
end
|
||||
end
|
||||
-- su ognuno si fa la fresatura di pulizia
|
||||
for i = 1, #EdgesClosedNotMachined do
|
||||
local dMillingOffsetFromSide = Strategy.Parameters.bAntiSplintWithBlade and Strategy.Parameters.dMillingOffsetFromSide or 0
|
||||
local dDepthToMachine = EdgesClosedNotMachined[i].dElevation - dMillingOffsetFromSide
|
||||
local dToolMarkLength = Milling1.dToolMarkLength or 0
|
||||
local OptionalParameters = {
|
||||
bIsSplitFeature = bIsSplitFeature,
|
||||
dExtendAfterTail = dExtendAfterTail,
|
||||
dRadialStepSpan = dToolMarkLength,
|
||||
dDepthToMachine = dDepthToMachine
|
||||
}
|
||||
local Milling = FaceByMill.Make( Proc, Part, BottomFace1, EdgesClosedNotMachined[i], OptionalParameters)
|
||||
Milling.nInternalSortingPriority = 3
|
||||
Milling.dResultWeight = 0.05
|
||||
table.insert( CalculatedMachinings, Milling)
|
||||
end
|
||||
end
|
||||
|
||||
if Milling2 then
|
||||
-- si recuperano i lati chiusi non lavorati
|
||||
local EdgesClosedNotMachined = {}
|
||||
for i = 1, #BottomFace2.Edges do
|
||||
if not( ( BottomFace2.Edges[i].id == BottomEdgeToMachine2.id) or BottomFace2.Edges[i].bIsOpen) then
|
||||
table.insert( EdgesClosedNotMachined, BottomFace2.Edges[i])
|
||||
end
|
||||
end
|
||||
-- su ognuno si fa la fresatura di pulizia
|
||||
for i = 1, #EdgesClosedNotMachined do
|
||||
local dMillingOffsetFromSide = Strategy.Parameters.bAntiSplintWithBlade and Strategy.Parameters.dMillingOffsetFromSide or 0
|
||||
local dDepthToMachine = EdgesClosedNotMachined[i].dElevation - dMillingOffsetFromSide
|
||||
local dToolMarkLength = Milling2.dToolMarkLength or 0
|
||||
local OptionalParameters = {
|
||||
bIsSplitFeature = bIsSplitFeature,
|
||||
dExtendAfterTail = dExtendAfterTail,
|
||||
dRadialStepSpan = dToolMarkLength,
|
||||
dDepthToMachine = dDepthToMachine
|
||||
}
|
||||
local Milling = FaceByMill.Make( Proc, Part, BottomFace2, EdgesClosedNotMachined[i], OptionalParameters)
|
||||
Milling.nInternalSortingPriority = 3
|
||||
Milling.dResultWeight = 0.05
|
||||
table.insert( CalculatedMachinings, Milling)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- calcolo completamento, serve la lista di lavorazioni che comprende le non applicabili
|
||||
Strategy.Result.dCompletionPercentage = GetStrategyCompletionPercentage( Strategy.Machinings)
|
||||
-- antischeggia sulle facce di chiusura delle facce lavorate
|
||||
local CalculatedMachiningsNoAntisplint = BeamLib.TableCopyDeep( CalculatedMachinings)
|
||||
if Strategy.Parameters.bAntiSplintWithBlade then
|
||||
|
||||
local OptionalParametersAntiSplint = {
|
||||
bIsSplitFeature = bIsSplitFeature,
|
||||
dExtendAfterTail = dExtendAfterTail,
|
||||
nInternalSortingPriority = 1,
|
||||
dResultWeight = 0.15
|
||||
}
|
||||
local AntiSplints1 = AntiSplintOnFace.Make( Proc, Part, BottomFace1, OptionalParametersAntiSplint)
|
||||
for i = 1, #AntiSplints1 do
|
||||
table.insert( CalculatedMachinings, AntiSplints1[i])
|
||||
end
|
||||
if Milling2 then
|
||||
local AntiSplints2 = AntiSplintOnFace.Make( Proc, Part, BottomFace2, OptionalParametersAntiSplint)
|
||||
for i = 1, #AntiSplints2 do
|
||||
table.insert( CalculatedMachinings, AntiSplints2[i])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- calcolo completamento, serve la lista di lavorazioni che comprende le non applicabili, ma non gli antischeggia (quelle alzano la qualità e sono già contemplate)
|
||||
Strategy.Result.dCompletionPercentage = GetStrategyCompletionPercentage( CalculatedMachiningsNoAntisplint)
|
||||
Strategy.Result.dCompletionIndex = FeatureLib.GetFeatureCompletionIndex( Strategy.Result.dCompletionPercentage)
|
||||
|
||||
-- lavorazioni da applicare spostate in lista finale
|
||||
for i = 1, #CalculatedMachinings do
|
||||
if CalculatedMachinings[i].bIsApplicable then
|
||||
table.insert( Strategy.Machinings, CalculatedMachinings[i])
|
||||
end
|
||||
end
|
||||
|
||||
Strategy.Machinings = MachiningLib.GetSplitMachinings( Strategy.Machinings, FeatureSplittingPoints, Part)
|
||||
table.sort( Strategy.Machinings, SortMachiningsBySegment)
|
||||
|
||||
Strategy.Result.dQuality = FeatureLib.GetStrategyQuality( Strategy.Machinings)
|
||||
-- se non ci sono lati chiusi, la qualità è migliore
|
||||
if Proc.Topology.sName == 'Bevel-1-Through' or Proc.Topology.sName == 'DoubleBevel-2-Through' or Proc.Topology.sName == 'Cut-1-Through' then
|
||||
Strategy.Result.dQuality = FeatureLib.GetStrategyQuality( 'FINE')
|
||||
else
|
||||
Strategy.Result.dQuality = FeatureLib.GetStrategyQuality( Strategy.Machinings)
|
||||
end
|
||||
Strategy.Result.dTimeToMachine = FeatureLib.GetStrategyTimeToMachine( Strategy.Machinings)
|
||||
Strategy.Result.dMRR = ( dFeatureVolume / Strategy.Result.dTimeToMachine) / pow( 10, 6)
|
||||
if Strategy.Result.dCompletionPercentage > 100 - 10 * GEO.EPS_SMALL then
|
||||
@@ -253,7 +411,12 @@ function STR0010.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
if bAddMachining and Strategy.Result.sStatus ~= 'Not-Applicable' then
|
||||
-- aggiunge lavorazione
|
||||
for j = 1, #Strategy.Machinings do
|
||||
bAreAllMachiningsAdded = MachiningLib.AddMachinings( Proc, Strategy.Machinings[j])
|
||||
local AuxiliaryData = {}
|
||||
-- se strategia forzata non considero area non pinzabile
|
||||
if CustomParameters.bForcedStrategy then
|
||||
AuxiliaryData.bIgnoreNotClampableLength = true
|
||||
end
|
||||
bAreAllMachiningsAdded = MachiningLib.AddMachinings( Proc, Strategy.Machinings[j], AuxiliaryData)
|
||||
end
|
||||
end
|
||||
else
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
"sValue": "0",
|
||||
"sDescriptionShort": "Tolerance on Diameter",
|
||||
"sDescriptionLong": "Tolerance on Diameter",
|
||||
"idDescriptionShortMsg": 1000217,
|
||||
"idDescriptionLongMsg": 1000218,
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -18,6 +20,8 @@
|
||||
"sValue": "0",
|
||||
"sDescriptionShort": "Depth PreHole",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000219,
|
||||
"idDescriptionLongMsg": 1000220,
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -28,6 +32,8 @@
|
||||
"sValue": "AUTO",
|
||||
"sDescriptionShort": "Drilling Mode",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000221,
|
||||
"idDescriptionLongMsg": 1000222,
|
||||
"sType": "combo",
|
||||
"sMinUserLevel": "1",
|
||||
"Choices": [
|
||||
@@ -35,18 +41,24 @@
|
||||
"sValue": "AUTO",
|
||||
"sDescriptionShort": "Automatic",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000223,
|
||||
"idDescriptionLongMsg": 1000224,
|
||||
"sMessageId": ""
|
||||
},
|
||||
{
|
||||
"sValue": "PREFER_ONE",
|
||||
"sDescriptionShort": "Preferred machining from one side only",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000225,
|
||||
"idDescriptionLongMsg": 1000226,
|
||||
"sMessageId": ""
|
||||
},
|
||||
{
|
||||
"sValue": "FORCE_TWO",
|
||||
"sDescriptionShort": "Force machining from two sides",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000227,
|
||||
"idDescriptionLongMsg": 1000228,
|
||||
"sMessageId": ""
|
||||
}
|
||||
]
|
||||
@@ -57,6 +69,8 @@
|
||||
"sValue": "",
|
||||
"sDescriptionShort": "Available Drillbit list",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000229,
|
||||
"idDescriptionLongMsg": 1000230,
|
||||
"sType": "tool",
|
||||
"sSubType": "MCH_TF.DRILLBIT",
|
||||
"sMessageId": " ",
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
-- carico librerie
|
||||
local BeamLib = require( 'BeamLib')
|
||||
local BeamData = require( 'BeamData')
|
||||
local BeamData = require( 'BeamDataNew')
|
||||
local MachiningLib = require( 'MachiningLib')
|
||||
local FeatureLib = require( 'FeatureLib')
|
||||
-- strategie di base
|
||||
@@ -16,228 +16,186 @@ local Strategy = {}
|
||||
|
||||
-- TODO Da fare completamente gestione foratura doppia con 2 teste
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function GetSCC( vtMachiningDirection)
|
||||
-- TODO implementare SCC come per FacesBySaw
|
||||
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
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function GetDrillingStrategy( Proc, Part)
|
||||
local ToolSearchParameters = {}
|
||||
local Machining = {}
|
||||
local sQuality
|
||||
|
||||
-- se lavorazione orizzontale
|
||||
if Proc.FeatureInfo.bIsDrillHorizontal then
|
||||
local bDouble = false
|
||||
local Drilling = MachiningLib.InitMachiningParameters( MCH_MY.DRILLING)
|
||||
Drilling.bIsApplicable = false
|
||||
-- si cerca utensile 1
|
||||
local Drilling = MachiningLib.InitMachiningParameters( MCH_MY.DRILLING)
|
||||
ToolSearchParameters = {}
|
||||
ToolSearchParameters.dElevation = Proc.FeatureInfo.dDrillLen + BeamData.MILL_OVERLAP
|
||||
ToolSearchParameters.vtToolDirection = Proc.FeatureInfo.vtDrillExtrusion
|
||||
ToolSearchParameters.dToolDiameter = Proc.FeatureInfo.dDrillDiam
|
||||
ToolSearchParameters.dDiameterTolerance = Strategy.Parameters.dDiameterTolerance
|
||||
ToolSearchParameters.AvailableToolList = MachiningLib.GetAvailableToolList( Proc, Strategy.Parameters.sDrillBitList, 'Drilling')
|
||||
ToolSearchParameters.ptCheckOutStroke = { Proc.FeatureInfo.ptDrillCenter + ( EgtMdbGetGeneralParam( MCH_GP.SAFEZ) * ToolSearchParameters.vtToolDirection)}
|
||||
|
||||
Drilling.ToolInfo = {}
|
||||
Drilling.ToolInfo = MachiningLib.FindDrill( Proc, ToolSearchParameters)
|
||||
-- se trovato utensile si settano i parametri comuni
|
||||
if Drilling.ToolInfo.nToolIndex then
|
||||
Drilling.Geometry = {{ Proc.FeatureInfo.idAddAuxGeom, -1}}
|
||||
Drilling.nToolIndex = Drilling.ToolInfo.nToolIndex
|
||||
Drilling.vtToolDirection = Proc.FeatureInfo.vtDrillExtrusion
|
||||
Drilling.dStep = TOOLS[Drilling.nToolIndex].dStep
|
||||
Drilling.nSCC = GetSCC( -Drilling.vtToolDirection)
|
||||
end
|
||||
|
||||
-- TODO se utensile 2 che si torverà è il gemello da usare nelle lavorazioni in doppio, allora gestire di conseguenza l'applicazione delle lavorazioni in doppio
|
||||
-- si cerca utensile 2
|
||||
local Drilling2 = MachiningLib.InitMachiningParameters( MCH_MY.DRILLING)
|
||||
Drilling2.ToolInfo = {}
|
||||
if Proc.FeatureInfo.bIsDrillOpen then
|
||||
ToolSearchParameters = {}
|
||||
ToolSearchParameters.dElevation = Proc.FeatureInfo.dDrillLen + BeamData.MILL_OVERLAP
|
||||
ToolSearchParameters.vtToolDirection = Proc.FeatureInfo.vtDrillExtrusion
|
||||
ToolSearchParameters.dToolDiameter = Proc.FeatureInfo.dDrillDiam
|
||||
ToolSearchParameters.vtToolDirection = -Proc.FeatureInfo.vtDrillExtrusion
|
||||
ToolSearchParameters.dDiameterTolerance = Strategy.Parameters.dDiameterTolerance
|
||||
ToolSearchParameters.AvailableToolList = MachiningLib.GetAvailableToolList( Proc, Strategy.Parameters.sDrillBitList, 'Drilling')
|
||||
Drilling.ToolInfo = {}
|
||||
Drilling.ToolInfo = MachiningLib.FindDrill( Proc, ToolSearchParameters)
|
||||
if Drilling.ToolInfo.nToolIndex then
|
||||
Drilling.nToolIndex = Drilling.ToolInfo.nToolIndex
|
||||
Drilling.Geometry = {{ Proc.FeatureInfo.idAddAuxGeom, -1}}
|
||||
Drilling.dStep = TOOLS[Drilling.ToolInfo.nToolIndex].dStep
|
||||
-- se lavorazione non completa o se si deve forare dai due lati
|
||||
if Proc.FeatureInfo.bIsDrillOpen and
|
||||
( Drilling.ToolInfo.dResidualDepth > 10 * GEO.EPS_SMALL or Strategy.Parameters.sDrillingMode == 'FORCE_TWO' or Strategy.Parameters.sDrillingMode == 'AUTO') then
|
||||
bDouble = true
|
||||
local dHalfDrill = ( Proc.FeatureInfo.dDrillLen + BeamData.MILL_OVERLAP) / 2
|
||||
Drilling.sDepth = min( dHalfDrill, Proc.FeatureInfo.dDrillLen - Drilling.ToolInfo.dResidualDepth)
|
||||
Drilling.vtFaceNormal = Proc.FeatureInfo.vtDrillExtrusion
|
||||
Drilling.bInvert = false
|
||||
Drilling.vtToolDirection = Proc.FeatureInfo.vtDrillExtrusion
|
||||
table.insert( Machining, Drilling)
|
||||
local Drilling2 = BeamLib.TableCopyDeep( Drilling)
|
||||
Drilling2.bInvert = true
|
||||
Drilling2.vtToolDirection = -Proc.FeatureInfo.vtDrillExtrusion
|
||||
table.insert( Machining, Drilling2)
|
||||
else
|
||||
Drilling.sDepth = 'TH'
|
||||
Drilling.vtFaceNormal = Proc.FeatureInfo.vtDrillExtrusion
|
||||
Drilling.bInvert = false
|
||||
Drilling.vtToolDirection = Proc.FeatureInfo.vtDrillExtrusion
|
||||
table.insert( Machining, Drilling)
|
||||
end
|
||||
ToolSearchParameters.ptCheckOutStroke = { Proc.FeatureInfo.ptDrillCenter + ( ( Proc.FeatureInfo.dDrillLen + EgtMdbGetGeneralParam( MCH_GP.SAFEZ)) * ToolSearchParameters.vtToolDirection)}
|
||||
|
||||
-- voto
|
||||
if Drilling.ToolInfo.dResidualDepth < 0 or ( Proc.FeatureInfo.dDrillLen + BeamData.MILL_OVERLAP) / 2 > Drilling.ToolInfo.dResidualDepth then
|
||||
Strategy.Result.sStatus = 'Completed'
|
||||
Strategy.Result.dCompletionIndex = 5
|
||||
Strategy.Result.dMRR = MachiningLib.GetToolMRR( Machining[1].ToolInfo or Machining[2].ToolInfo)
|
||||
if bDouble or not Proc.FeatureInfo.bIsDrillOpen then
|
||||
sQuality = 'FINE'
|
||||
else
|
||||
sQuality = 'ROUGH'
|
||||
end
|
||||
Strategy.Result.dQuality = FeatureLib.GetStrategyQuality( sQuality)
|
||||
Strategy.Result.sInfo = ''
|
||||
else
|
||||
Strategy.Result.sStatus = 'Not-Completed'
|
||||
local dMachinedLen = EgtIf( bDouble, Machining[1].sDepth * 2, Proc.FeatureInfo.dDrillLen)
|
||||
local dMachinedPrercentage = 100 * ( dMachinedLen / Proc.FeatureInfo.dDrillLen)
|
||||
Strategy.Result.dCompletionIndex = FeatureLib.GetFeatureCompletionIndex( dMachinedPrercentage)
|
||||
Strategy.Result.sInfo = 'Drill not complete, left ' .. tostring( 100 - ceil( dMachinedPrercentage)) .. '%'
|
||||
Strategy.Result.dMRR = MachiningLib.GetToolMRR( Machining[1].ToolInfo or Machining[2].ToolInfo)
|
||||
Strategy.Result.dQuality = FeatureLib.GetStrategyQuality( 'FINE') -- se non completo, anche se fosse foro singolo, comunque non esce dall'altra parte, quindi non scheggia
|
||||
end
|
||||
else
|
||||
local sMessage = 'Drillbit not found'
|
||||
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( sMessage)
|
||||
end
|
||||
-- se lavorazione verticale
|
||||
else
|
||||
-- si cerca utensile 1
|
||||
local Drilling = MachiningLib.InitMachiningParameters( MCH_MY.DRILLING)
|
||||
ToolSearchParameters = {}
|
||||
ToolSearchParameters.dElevation = Proc.FeatureInfo.dDrillLen + BeamData.MILL_OVERLAP
|
||||
ToolSearchParameters.vtToolDirection = Proc.FeatureInfo.vtDrillExtrusion
|
||||
ToolSearchParameters.dToolDiameter = Proc.FeatureInfo.dDrillDiam
|
||||
ToolSearchParameters.dDiameterTolerance = Strategy.Parameters.dDiameterTolerance
|
||||
ToolSearchParameters.AvailableToolList = MachiningLib.GetAvailableToolList( Proc, Strategy.Parameters.sDrillBitList, 'Drilling')
|
||||
Drilling.ToolInfo = {}
|
||||
Drilling.ToolInfo = MachiningLib.FindDrill( Proc, ToolSearchParameters)
|
||||
-- si cerca utensile 2
|
||||
local Drilling2 = MachiningLib.InitMachiningParameters( MCH_MY.DRILLING)
|
||||
Drilling2.ToolInfo = {}
|
||||
if Proc.FeatureInfo.bIsDrillOpen then
|
||||
ToolSearchParameters = {}
|
||||
ToolSearchParameters.dElevation = Proc.FeatureInfo.dDrillLen + BeamData.MILL_OVERLAP
|
||||
ToolSearchParameters.vtToolDirection = -Proc.FeatureInfo.vtDrillExtrusion
|
||||
ToolSearchParameters.dDiameterTolerance = Strategy.Parameters.dDiameterTolerance
|
||||
ToolSearchParameters.AvailableToolList = MachiningLib.GetAvailableToolList( Proc, Strategy.Parameters.sDrillBitList, 'Drilling')
|
||||
Drilling2.ToolInfo = MachiningLib.FindDrill( Proc, ToolSearchParameters)
|
||||
end
|
||||
|
||||
-- se possono lavorare entrambi e si deve fare lavorazione doppia e si riesce a completare
|
||||
if Drilling.ToolInfo.nToolIndex and Drilling2.ToolInfo.nToolIndex and
|
||||
( Strategy.Parameters.sDrillingMode == 'FORCE_TWO' or Strategy.Parameters.sDrillingMode == 'AUTO') and
|
||||
Drilling.ToolInfo.dResidualDepth + Drilling2.ToolInfo.dResidualDepth < Proc.FeatureInfo.dDrillLen then
|
||||
|
||||
local dExtraDrill = ( Proc.FeatureInfo.dDrillLen - BeamData.MILL_OVERLAP - ( Drilling.ToolInfo.dResidualDepth + Drilling2.ToolInfo.dResidualDepth)) / 2
|
||||
Drilling.nToolIndex = Drilling.ToolInfo.nToolIndex
|
||||
Drilling.Geometry = {{ Proc.FeatureInfo.idAddAuxGeom, -1}}
|
||||
Drilling.vtToolDirection = Proc.FeatureInfo.vtDrillExtrusion
|
||||
Drilling.sDepth = Proc.FeatureInfo.dDrillLen - Drilling.ToolInfo.dResidualDepth - dExtraDrill
|
||||
table.insert( Machining, Drilling)
|
||||
|
||||
Drilling2.nToolIndex = Drilling2.ToolInfo.nToolIndex
|
||||
Drilling2.ToolInfo = MachiningLib.FindDrill( Proc, ToolSearchParameters)
|
||||
-- se trovato utensile si settano i parametri comuni
|
||||
if Drilling2.ToolInfo.nToolIndex then
|
||||
Drilling2.Geometry = {{ Proc.FeatureInfo.idAddAuxGeom, -1}}
|
||||
Drilling2.nToolIndex = Drilling2.ToolInfo.nToolIndex
|
||||
Drilling2.bInvert = true
|
||||
Drilling2.vtToolDirection = -Proc.FeatureInfo.vtDrillExtrusion
|
||||
Drilling2.sDepth = Proc.FeatureInfo.dDrillLen - Drilling2.ToolInfo.dResidualDepth - dExtraDrill
|
||||
table.insert( Machining, Drilling2)
|
||||
|
||||
-- voto
|
||||
Strategy.Result.sStatus = 'Completed'
|
||||
Strategy.Result.dCompletionIndex = 5
|
||||
Strategy.Result.sInfo = ''
|
||||
Strategy.Result.dMRR = MachiningLib.GetToolMRR( Machining[1].ToolInfo)
|
||||
Strategy.Result.dQuality = FeatureLib.GetStrategyQuality( 'FINE')
|
||||
|
||||
-- se utensile 1 esegue completamente
|
||||
elseif Drilling.ToolInfo.nToolIndex and Drilling.ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL and
|
||||
( Strategy.Parameters.sDrillingMode == 'PREFER_ONE' or ( not Drilling2.ToolInfo.nToolIndex and Strategy.Parameters.sDrillingMode == 'AUTO') or not Proc.FeatureInfo.bIsDrillOpen) then
|
||||
Drilling.sDepth = 'TH'
|
||||
Drilling.nToolIndex = Drilling.ToolInfo.nToolIndex
|
||||
Drilling.Geometry = {{ Proc.FeatureInfo.idAddAuxGeom, -1}}
|
||||
Drilling.vtToolDirection = Proc.FeatureInfo.vtDrillExtrusion
|
||||
table.insert( Machining, Drilling)
|
||||
-- voto
|
||||
Strategy.Result.sStatus = 'Completed'
|
||||
Strategy.Result.dCompletionIndex = 5
|
||||
Strategy.Result.dMRR = MachiningLib.GetToolMRR( Machining[1].ToolInfo)
|
||||
Strategy.Result.dQuality = FeatureLib.GetStrategyQuality( EgtIf( Proc.FeatureInfo.bIsDrillOpen, 'ROUGH', 'FINE'))
|
||||
Strategy.Result.sInfo = ''
|
||||
-- se utensile 2 esegue completamente
|
||||
elseif Drilling2.ToolInfo.nToolIndex and Drilling2.ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL and
|
||||
( Strategy.Parameters.sDrillingMode == 'PREFER_ONE' or ( not Drilling.ToolInfo.nToolIndex and Strategy.Parameters.sDrillingMode == 'AUTO')) then
|
||||
Drilling2.sDepth = 'TH'
|
||||
Drilling2.nToolIndex = Drilling2.ToolInfo.nToolIndex
|
||||
Drilling2.Geometry = {{ Proc.FeatureInfo.idAddAuxGeom, -1}}
|
||||
Drilling2.bInvert = true
|
||||
Drilling2.vtToolDirection = -Proc.FeatureInfo.vtDrillExtrusion
|
||||
table.insert( Machining, Drilling2)
|
||||
-- voto
|
||||
Strategy.Result.sStatus = 'Completed'
|
||||
Strategy.Result.dCompletionIndex = 5
|
||||
Strategy.Result.dMRR = MachiningLib.GetToolMRR( Machining[1].ToolInfo)
|
||||
Strategy.Result.dQuality = FeatureLib.GetStrategyQuality( EgtIf( Proc.FeatureInfo.bIsDrillOpen, 'ROUGH', 'FINE'))
|
||||
Strategy.Result.sInfo = ''
|
||||
-- se possono lavorare entrambi
|
||||
elseif Drilling.ToolInfo.nToolIndex and Drilling2.ToolInfo.nToolIndex then
|
||||
Drilling.nToolIndex = Drilling.ToolInfo.nToolIndex
|
||||
Drilling.Geometry = {{ Proc.FeatureInfo.idAddAuxGeom, -1}}
|
||||
Drilling.vtToolDirection = Proc.FeatureInfo.vtDrillExtrusion
|
||||
Drilling.sDepth = Proc.FeatureInfo.dDrillLen - Drilling.ToolInfo.dResidualDepth
|
||||
table.insert( Machining, Drilling)
|
||||
|
||||
Drilling2.nToolIndex = Drilling2.ToolInfo.nToolIndex
|
||||
Drilling2.Geometry = {{ Proc.FeatureInfo.idAddAuxGeom, -1}}
|
||||
Drilling2.bInvert = true
|
||||
Drilling2.vtToolDirection = -Proc.FeatureInfo.vtDrillExtrusion
|
||||
Drilling2.sDepth = Proc.FeatureInfo.dDrillLen - Drilling2.ToolInfo.dResidualDepth
|
||||
table.insert( Machining, Drilling2)
|
||||
if Drilling.ToolInfo.dResidualDepth + Drilling2.ToolInfo.dResidualDepth < Proc.FeatureInfo.dDrillLen then
|
||||
Strategy.Result.sStatus = 'Not-Completed'
|
||||
local dMachinedLen = Machining[1].sDepth + Machining[2].sDepth
|
||||
local dMachinedPrercentage = 100 * ( dMachinedLen / Proc.FeatureInfo.dDrillLen)
|
||||
Strategy.Result.dCompletionIndex = FeatureLib.GetFeatureCompletionIndex( dMachinedPrercentage)
|
||||
Strategy.Result.sInfo = 'Drill not complete, left ' .. tostring( 100 - ceil( dMachinedPrercentage)) .. '%'
|
||||
else
|
||||
Strategy.Result.sStatus = 'Completed'
|
||||
Strategy.Result.dCompletionIndex = 5
|
||||
Strategy.Result.sInfo = ''
|
||||
end
|
||||
-- voto
|
||||
Strategy.Result.dMRR = MachiningLib.GetToolMRR( Machining[1].ToolInfo)
|
||||
Strategy.Result.dQuality = FeatureLib.GetStrategyQuality( 'FINE')
|
||||
-- se utensile 1 non completo
|
||||
elseif Drilling.ToolInfo.nToolIndex and ( Strategy.Parameters.sDrillingMode ~= 'FORCE_TWO' or Proc.FeatureInfo.bIsDrillOpen) then
|
||||
Drilling.sDepth = Proc.FeatureInfo.dDrillLen - Drilling.ToolInfo.dResidualDepth
|
||||
Drilling.nToolIndex = Drilling.ToolInfo.nToolIndex
|
||||
Drilling.Geometry = {{ Proc.FeatureInfo.idAddAuxGeom, -1}}
|
||||
Drilling.vtToolDirection = Proc.FeatureInfo.vtDrillExtrusion
|
||||
Drilling.sDepth = Proc.FeatureInfo.dDrillLen - Drilling.ToolInfo.dResidualDepth
|
||||
table.insert( Machining, Drilling)
|
||||
-- voto
|
||||
Strategy.Result.sStatus = 'Not-Completed'
|
||||
local dMachinedLen = Machining[1].sDepth
|
||||
local dMachinedPrercentage = 100 * ( dMachinedLen / Proc.FeatureInfo.dDrillLen)
|
||||
Strategy.Result.dCompletionIndex = FeatureLib.GetFeatureCompletionIndex( dMachinedPrercentage)
|
||||
Strategy.Result.sInfo = 'Drill not complete, left ' .. tostring( 100 - ceil( dMachinedPrercentage)) .. '%'
|
||||
Strategy.Result.dMRR = MachiningLib.GetToolMRR( Machining[1].ToolInfo)
|
||||
Strategy.Result.dQuality = FeatureLib.GetStrategyQuality( 'FINE')
|
||||
-- se utensile 2 non completo
|
||||
elseif Drilling2.ToolInfo.nToolIndex and Strategy.Parameters.sDrillingMode ~= 'FORCE_TWO' then
|
||||
Drilling2.sDepth = Proc.FeatureInfo.dDrillLen - Drilling2.ToolInfo.dResidualDepth
|
||||
Drilling2.nToolIndex = Drilling2.ToolInfo.nToolIndex
|
||||
Drilling2.Geometry = {{ Proc.FeatureInfo.idAddAuxGeom, -1}}
|
||||
Drilling2.bInvert = true
|
||||
Drilling2.vtToolDirection = -Proc.FeatureInfo.vtDrillExtrusion
|
||||
Drilling2.sDepth = Proc.FeatureInfo.dDrillLen - Drilling2.ToolInfo.dResidualDepth
|
||||
table.insert( Machining, Drilling2)
|
||||
-- voto
|
||||
Strategy.Result.sStatus = 'Not-Completed'
|
||||
local dMachinedLen = Machining[1].sDepth
|
||||
local dMachinedPrercentage = 100 * ( dMachinedLen / Proc.FeatureInfo.dDrillLen)
|
||||
Strategy.Result.dCompletionIndex = FeatureLib.GetFeatureCompletionIndex( dMachinedPrercentage)
|
||||
Strategy.Result.sInfo = 'Drill not complete, left ' .. tostring( 100 - ceil( dMachinedPrercentage)) .. '%'
|
||||
Strategy.Result.dMRR = MachiningLib.GetToolMRR( Machining[1].ToolInfo)
|
||||
Strategy.Result.dQuality = FeatureLib.GetStrategyQuality( 'FINE')
|
||||
else
|
||||
local sMessage
|
||||
-- se non sono state trovate punte
|
||||
if not Drilling.ToolInfo.nToolIndex and not Drilling2.ToolInfo.nToolIndex then
|
||||
sMessage = 'Drillbit not found'
|
||||
-- se son state trovate delle punte, ma non è stato possibile forare da entrambe le parti
|
||||
elseif Strategy.Parameters.sDrillingMode == 'FORCE_TWO' then
|
||||
sMessage = "Not possible to force machining from both sides. Please change drilling mode to AUTO"
|
||||
end
|
||||
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( sMessage)
|
||||
Drilling2.dStep = TOOLS[Drilling2.nToolIndex].dStep
|
||||
Drilling2.nSCC = GetSCC( -Drilling2.vtToolDirection)
|
||||
end
|
||||
end
|
||||
|
||||
-- se possono lavorare entrambi e si deve fare lavorazione doppia e si riesce a completare
|
||||
if Drilling.ToolInfo.nToolIndex and Drilling2.ToolInfo.nToolIndex and
|
||||
( Strategy.Parameters.sDrillingMode == 'FORCE_TWO' or Strategy.Parameters.sDrillingMode == 'AUTO') and
|
||||
Drilling.ToolInfo.dResidualDepth + Drilling2.ToolInfo.dResidualDepth < Proc.FeatureInfo.dDrillLen then
|
||||
|
||||
local dExtraDrill = ( Proc.FeatureInfo.dDrillLen - BeamData.MILL_OVERLAP - ( Drilling.ToolInfo.dResidualDepth + Drilling2.ToolInfo.dResidualDepth)) / 2
|
||||
Drilling.sDepth = Proc.FeatureInfo.dDrillLen - Drilling.ToolInfo.dResidualDepth - dExtraDrill
|
||||
table.insert( Machining, Drilling)
|
||||
|
||||
Drilling2.sDepth = Proc.FeatureInfo.dDrillLen - Drilling2.ToolInfo.dResidualDepth - dExtraDrill
|
||||
table.insert( Machining, Drilling2)
|
||||
|
||||
-- voto
|
||||
Strategy.Result.sStatus = 'Completed'
|
||||
Strategy.Result.dCompletionIndex = 5
|
||||
Strategy.Result.sInfo = ''
|
||||
Strategy.Result.dQuality = FeatureLib.GetStrategyQuality( 'FINE')
|
||||
|
||||
-- se utensile 1 esegue completamente
|
||||
elseif Drilling.ToolInfo.nToolIndex and Drilling.ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL and
|
||||
( Strategy.Parameters.sDrillingMode == 'PREFER_ONE' or ( not Drilling2.ToolInfo.nToolIndex and Strategy.Parameters.sDrillingMode == 'AUTO') or not Proc.FeatureInfo.bIsDrillOpen) then
|
||||
Drilling.sDepth = Proc.FeatureInfo.dDrillLen
|
||||
table.insert( Machining, Drilling)
|
||||
-- voto
|
||||
Strategy.Result.sStatus = 'Completed'
|
||||
Strategy.Result.dCompletionIndex = 5
|
||||
Strategy.Result.dQuality = FeatureLib.GetStrategyQuality( EgtIf( Proc.FeatureInfo.bIsDrillOpen, 'ROUGH', 'FINE'))
|
||||
Strategy.Result.sInfo = ''
|
||||
-- annullo altra lavorazione
|
||||
Drilling2.ToolInfo.nToolIndex = nil
|
||||
-- se utensile 2 esegue completamente
|
||||
elseif Drilling2.ToolInfo.nToolIndex and Drilling2.ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL and
|
||||
( Strategy.Parameters.sDrillingMode == 'PREFER_ONE' or ( not Drilling.ToolInfo.nToolIndex and Strategy.Parameters.sDrillingMode == 'AUTO')) then
|
||||
Drilling2.sDepth = Proc.FeatureInfo.dDrillLen
|
||||
table.insert( Machining, Drilling2)
|
||||
-- voto
|
||||
Strategy.Result.sStatus = 'Completed'
|
||||
Strategy.Result.dCompletionIndex = 5
|
||||
Strategy.Result.dQuality = FeatureLib.GetStrategyQuality( EgtIf( Proc.FeatureInfo.bIsDrillOpen, 'ROUGH', 'FINE'))
|
||||
Strategy.Result.sInfo = ''
|
||||
-- annullo altra lavorazione
|
||||
Drilling.ToolInfo.nToolIndex = nil
|
||||
-- se possono lavorare entrambi
|
||||
elseif Drilling.ToolInfo.nToolIndex and Drilling2.ToolInfo.nToolIndex then
|
||||
Drilling.sDepth = Proc.FeatureInfo.dDrillLen - Drilling.ToolInfo.dResidualDepth
|
||||
table.insert( Machining, Drilling)
|
||||
|
||||
Drilling2.sDepth = Proc.FeatureInfo.dDrillLen - Drilling2.ToolInfo.dResidualDepth
|
||||
table.insert( Machining, Drilling2)
|
||||
if Drilling.ToolInfo.dResidualDepth + Drilling2.ToolInfo.dResidualDepth < Proc.FeatureInfo.dDrillLen then
|
||||
Strategy.Result.sStatus = 'Not-Completed'
|
||||
local dMachinedLen = Machining[1].sDepth + Machining[2].sDepth
|
||||
local dMachinedPrercentage = 100 * ( dMachinedLen / Proc.FeatureInfo.dDrillLen)
|
||||
Strategy.Result.dCompletionIndex = FeatureLib.GetFeatureCompletionIndex( dMachinedPrercentage)
|
||||
Strategy.Result.sInfo = 'Drill not complete, left ' .. tostring( 100 - ceil( dMachinedPrercentage)) .. '%'
|
||||
else
|
||||
Strategy.Result.sStatus = 'Completed'
|
||||
Strategy.Result.dCompletionIndex = 5
|
||||
Strategy.Result.sInfo = ''
|
||||
end
|
||||
-- voto
|
||||
Strategy.Result.dQuality = FeatureLib.GetStrategyQuality( 'FINE')
|
||||
-- se utensile 1 non completo
|
||||
elseif Drilling.ToolInfo.nToolIndex and ( Strategy.Parameters.sDrillingMode ~= 'FORCE_TWO' or Proc.FeatureInfo.bIsDrillOpen) then
|
||||
Drilling.sDepth = Proc.FeatureInfo.dDrillLen - Drilling.ToolInfo.dResidualDepth
|
||||
table.insert( Machining, Drilling)
|
||||
-- voto
|
||||
Strategy.Result.sStatus = 'Not-Completed'
|
||||
local dMachinedLen = Machining[1].sDepth
|
||||
local dMachinedPrercentage = 100 * ( dMachinedLen / Proc.FeatureInfo.dDrillLen)
|
||||
Strategy.Result.dCompletionIndex = FeatureLib.GetFeatureCompletionIndex( dMachinedPrercentage)
|
||||
Strategy.Result.sInfo = 'Drill not complete, left ' .. tostring( 100 - ceil( dMachinedPrercentage)) .. '%'
|
||||
Strategy.Result.dQuality = FeatureLib.GetStrategyQuality( 'FINE')
|
||||
-- annullo altra lavorazione
|
||||
Drilling2.ToolInfo.nToolIndex = nil
|
||||
-- se utensile 2 non completo
|
||||
elseif Drilling2.ToolInfo.nToolIndex and Strategy.Parameters.sDrillingMode ~= 'FORCE_TWO' then
|
||||
Drilling2.sDepth = Proc.FeatureInfo.dDrillLen - Drilling2.ToolInfo.dResidualDepth
|
||||
table.insert( Machining, Drilling2)
|
||||
-- voto
|
||||
Strategy.Result.sStatus = 'Not-Completed'
|
||||
local dMachinedLen = Machining[1].sDepth
|
||||
local dMachinedPrercentage = 100 * ( dMachinedLen / Proc.FeatureInfo.dDrillLen)
|
||||
Strategy.Result.dCompletionIndex = FeatureLib.GetFeatureCompletionIndex( dMachinedPrercentage)
|
||||
Strategy.Result.sInfo = 'Drill not complete, left ' .. tostring( 100 - ceil( dMachinedPrercentage)) .. '%'
|
||||
Strategy.Result.dQuality = FeatureLib.GetStrategyQuality( 'FINE')
|
||||
-- annullo altra lavorazione
|
||||
Drilling.ToolInfo.nToolIndex = nil
|
||||
else
|
||||
local sMessage
|
||||
-- se non sono state trovate punte
|
||||
if not Drilling.ToolInfo.nToolIndex and not Drilling2.ToolInfo.nToolIndex then
|
||||
sMessage = 'Drillbit not found'
|
||||
-- se son state trovate delle punte, ma non è stato possibile forare da entrambe le parti
|
||||
elseif Strategy.Parameters.sDrillingMode == 'FORCE_TWO' then
|
||||
sMessage = "Not possible to force machining from both sides. Please change drilling mode to AUTO"
|
||||
end
|
||||
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( sMessage)
|
||||
end
|
||||
|
||||
-- calcolo tempo di lavorazione
|
||||
Strategy.Result.dTimeToMachine = 0
|
||||
if Drilling.ToolInfo.nToolIndex then
|
||||
Strategy.Result.dTimeToMachine = MachiningLib.GetTimeToMachineAllStepsWithLeadInOut( Drilling, Part)
|
||||
end
|
||||
if Drilling2.ToolInfo.nToolIndex then
|
||||
Strategy.Result.dTimeToMachine = Strategy.Result.dTimeToMachine + MachiningLib.GetTimeToMachineAllStepsWithLeadInOut( Drilling2, Part)
|
||||
end
|
||||
|
||||
return Machining, Strategy.Result
|
||||
end
|
||||
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
"sNameNge": "EXTEND_AFTER_TAIL",
|
||||
"sValue": "",
|
||||
"sDescriptionShort": "Extend after tail",
|
||||
"sDescriptionLong": "The automatism considers this lenght as machinable. This means you accept to damage the next piece in the bar",
|
||||
"sDescriptionLong": "The automatism considers this length as machinable. This means you accept to damage the next piece in the bar",
|
||||
"idDescriptionShortMsg": 1000231,
|
||||
"idDescriptionLongMsg": 1000232,
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -18,6 +20,8 @@
|
||||
"sValue": "NEVER",
|
||||
"sDescriptionShort": "Damage next piece",
|
||||
"sDescriptionLong": "This option allows you to decide how to consider the next piece in the bar. The software calculates specifics LeadIn/out to respect the parameter. This parameter may change the machining time",
|
||||
"idDescriptionShortMsg": 1000233,
|
||||
"idDescriptionLongMsg": 1000234,
|
||||
"sType": "combo",
|
||||
"sMinUserLevel": "1",
|
||||
"Choices": [
|
||||
@@ -25,18 +29,24 @@
|
||||
"sValue": "NEVER",
|
||||
"sDescriptionShort": "Never damage",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000235,
|
||||
"idDescriptionLongMsg": 1000236,
|
||||
"sMessageId": ""
|
||||
},
|
||||
{
|
||||
"sValue": "ONLY_IF_RAWPART",
|
||||
"sDescriptionShort": "Damage only if raw",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000237,
|
||||
"idDescriptionLongMsg": 1000238,
|
||||
"sMessageId": ""
|
||||
},
|
||||
{
|
||||
"sValue": "ALWAYS",
|
||||
"sDescriptionShort": "Can damage",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000239,
|
||||
"idDescriptionLongMsg": 1000240,
|
||||
"sMessageId": ""
|
||||
}
|
||||
]
|
||||
@@ -47,6 +57,8 @@
|
||||
"sValue": "AUTO",
|
||||
"sDescriptionShort": "Ridge Lap strategy",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000241,
|
||||
"idDescriptionLongMsg": 1000242,
|
||||
"sType": "combo",
|
||||
"sMinUserLevel": "1",
|
||||
"Choices": [
|
||||
@@ -54,42 +66,28 @@
|
||||
"sValue": "AUTO",
|
||||
"sDescriptionShort": "Automatic",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000243,
|
||||
"idDescriptionLongMsg": 1000244,
|
||||
"sMessageId": ""
|
||||
},
|
||||
{
|
||||
"sValue": "BLADE",
|
||||
"sDescriptionShort": "Use blade",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000245,
|
||||
"idDescriptionLongMsg": 1000246,
|
||||
"sMessageId": ""
|
||||
},
|
||||
{
|
||||
"sValue": "MILL",
|
||||
"sDescriptionShort": "Use mill",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000247,
|
||||
"idDescriptionLongMsg": 1000248,
|
||||
"sMessageId": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"sName": "dMinZAngleTopBlade",
|
||||
"sNameNge": "MIN_Z_ANGLE_TOP_BLADE",
|
||||
"sValue": "",
|
||||
"sDescriptionShort": "Min Z angle top blade",
|
||||
"sDescriptionLong": "",
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
},
|
||||
{
|
||||
"sName": "dMaxYAngleTopBlade",
|
||||
"sNameNge": "MAX_Y_ANGLE_TOP_BLADE",
|
||||
"sValue": "",
|
||||
"sDescriptionShort": "Max Y angle top blade",
|
||||
"sDescriptionLong": "",
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
},
|
||||
{
|
||||
"sName": "dMaxWasteLength",
|
||||
"sSource": "GEN_dMaxWasteLength",
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
-- carico librerie
|
||||
local BeamLib = require( 'BeamLib')
|
||||
local BeamData = require( 'BeamData')
|
||||
local BeamData = require( 'BeamDataNew')
|
||||
local MachiningLib = require( 'MachiningLib')
|
||||
local FeatureLib = require( 'FeatureLib')
|
||||
-- strategie di base
|
||||
@@ -59,9 +59,9 @@ function STR0012.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
-- separazione della terza faccia
|
||||
local idAddedTmFace
|
||||
local nAddedFace
|
||||
if Proc.AdjacencyMatrix[1][2] > 10 * GEO.EPS_ANG_SMALL and Proc.AdjacencyMatrix[2][3] < 10 * GEO.EPS_ANG_SMALL then
|
||||
if Proc.AdjacencyMatrix[2][3] < 0 then
|
||||
nAddedFace = 1 - 1
|
||||
elseif Proc.AdjacencyMatrix[2][3] > 10 * GEO.EPS_ANG_SMALL and Proc.AdjacencyMatrix[3][1] < 10 * GEO.EPS_ANG_SMALL then
|
||||
elseif Proc.AdjacencyMatrix[1][3] < 0 then
|
||||
nAddedFace = 2 - 1
|
||||
else
|
||||
nAddedFace = 3 - 1
|
||||
@@ -73,8 +73,14 @@ function STR0012.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
if not( AreSameVectorApprox( Proc.Faces[nAddedFace + 1].vtN, X_AX()) and abs( Proc.Faces[nAddedFace + 1].ptCenter:getX() - Part.b3Part:getMax():getX()) < 10 * GEO.EPS_SMALL)
|
||||
and not( AreSameVectorApprox( Proc.Faces[nAddedFace + 1].vtN, -X_AX()) and abs( Proc.Faces[nAddedFace + 1].ptCenter:getX() - Part.b3Part:getMin():getX()) < 10 * GEO.EPS_SMALL) then
|
||||
|
||||
-- faccia aggiuntiva da lavorare
|
||||
idAddedTmFace = EgtCopySurfTmFacet( Proc.id, nAddedFace, nAddGrpId)
|
||||
-- faccia aggiuntiva da lavorare: si estende fino al box della parte
|
||||
local idAddGroup
|
||||
if bAddMachining then
|
||||
idAddGroup = BeamLib.GetAddGroup( Part.id)
|
||||
else
|
||||
idAddGroup = Part.idTempGroup
|
||||
end
|
||||
idAddedTmFace = EgtSurfTmPlaneInBBox( idAddGroup, Proc.Faces[nAddedFace + 1].ptCenter, Proc.Faces[nAddedFace + 1].vtN, Part.b3Part, GDB_ID.ROOT)
|
||||
end
|
||||
|
||||
-- rimozione della terza faccia dalla Proc
|
||||
@@ -85,17 +91,13 @@ function STR0012.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
NewProc.NotClampableLength = FeatureLib.CalculateFeatureNotClampableLengths( NewProc, Part)
|
||||
NewProc.bHindersLaserMeasure = FeatureLib.CalculateFeatureHindersLaserMeasure( NewProc, Part)
|
||||
|
||||
-- TODO rimuovere??? codolo da implementare o no??
|
||||
-- considerazioni necessarie a determinare se lavorare con codolo oppure no
|
||||
local bKeepWasteAttached = ( Strategy.Parameters.sCuttingStrategy == 'KEEP_WASTE_ATTACHED')
|
||||
local bDropWaste = ( Strategy.Parameters.sCuttingStrategy == 'DROP_WASTE')
|
||||
local dFeatureMaxNotClampableLengthHead, dFeatureMaxNotClampableLengthTail = FeatureLib.GetFeatureMaxNotClampableLengths( NewProc, Part)
|
||||
local bFeatureHindersClamping = FeatureLib.IsMachiningLong( max( dFeatureMaxNotClampableLengthHead, dFeatureMaxNotClampableLengthTail), Part, { dMaxSegmentLength = BeamData.LONGCUT_ENDLEN})
|
||||
local bIsFeatureLong = FeatureLib.IsMachiningLong( NewProc.b3Box:getDimX(), Part, { dMaxSegmentLength = BeamData.LONGCUT_ENDLEN})
|
||||
local bFeatureHindersClamping = MachiningLib.IsFeatureHinderingClamping( Proc, Part)
|
||||
|
||||
-- lavorazione con codolo
|
||||
if ( bIsFeatureLong)
|
||||
or ( bFeatureHindersClamping and not bDropWaste)
|
||||
if ( bFeatureHindersClamping and not bDropWaste)
|
||||
or bKeepWasteAttached then
|
||||
|
||||
local BladeKeepWasteResult
|
||||
@@ -109,19 +111,9 @@ function STR0012.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
|
||||
-- lavorazione a cubetti facce concave
|
||||
else
|
||||
local dMinZTopBlade
|
||||
local dMaxNyTopBlade
|
||||
local BladeToWasteResult
|
||||
if Strategy.Parameters.dMinZAngleTopBlade then
|
||||
dMinZTopBlade = sin( Strategy.Parameters.dMinZAngleTopBlade)
|
||||
end
|
||||
if Strategy.Parameters.dMaxYAngleTopBlade then
|
||||
dMaxNyTopBlade = sin( Strategy.Parameters.dMaxYAngleTopBlade)
|
||||
end
|
||||
local OptionalParameters = { dMaxWasteVolume = Strategy.Parameters.dMaxWasteVolume,
|
||||
dMaxWasteLength = Strategy.Parameters.dMaxWasteLength,
|
||||
dMinNzTopBlade = dMinZTopBlade,
|
||||
dMaxNyTopBlade = dMaxNyTopBlade,
|
||||
bSaveAddedGeometries = bAddMachining,
|
||||
dExtendAfterTail = dExtendAfterTail,
|
||||
bReduceBladePath = Strategy.Parameters.bReduceBladePath
|
||||
@@ -138,19 +130,9 @@ function STR0012.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
-- TODO da completare
|
||||
-- TODO va messa per prima????????
|
||||
if idAddedTmFace then
|
||||
local dMinZTopBlade
|
||||
local dMaxNyTopBlade
|
||||
local BladeToWasteResult
|
||||
if Strategy.Parameters.dMinZAngleTopBlade then
|
||||
dMinZTopBlade = sin( Strategy.Parameters.dMinZAngleTopBlade)
|
||||
end
|
||||
if Strategy.Parameters.dMaxYAngleTopBlade then
|
||||
dMaxNyTopBlade = sin( Strategy.Parameters.dMaxYAngleTopBlade)
|
||||
end
|
||||
local OptionalParameters = { dMaxWasteVolume = Strategy.Parameters.dMaxWasteVolume,
|
||||
dMaxWasteLength = Strategy.Parameters.dMaxWasteLength,
|
||||
dMinNzTopBlade = dMinZTopBlade,
|
||||
dMaxNyTopBlade = dMaxNyTopBlade,
|
||||
bSaveAddedGeometries = bAddMachining,
|
||||
dExtendAfterTail = dExtendAfterTail,
|
||||
bReduceBladePath = Strategy.Parameters.bReduceBladePath
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
"sValue": "0",
|
||||
"sDescriptionShort": "Tolerance on Diameter",
|
||||
"sDescriptionLong": "Tolerance on Diameter",
|
||||
"idDescriptionShortMsg": 1000249,
|
||||
"idDescriptionLongMsg": 1000250,
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -18,6 +20,8 @@
|
||||
"sValue": "0",
|
||||
"sDescriptionShort": "Use mill as a drillbit",
|
||||
"sDescriptionLong": "Admit to use the mill as a drillbit",
|
||||
"idDescriptionShortMsg": 1000251,
|
||||
"idDescriptionLongMsg": 1000252,
|
||||
"sType": "b",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -28,6 +32,8 @@
|
||||
"sValue": "0",
|
||||
"sDescriptionShort": "Execute contour only",
|
||||
"sDescriptionLong": "Execute the contour anyway, even the hole is bigger than the tool diameter",
|
||||
"idDescriptionShortMsg": 1000253,
|
||||
"idDescriptionLongMsg": 1000254,
|
||||
"sType": "b",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -38,6 +44,8 @@
|
||||
"sValue": "AUTO",
|
||||
"sDescriptionShort": "Drilling mode",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000255,
|
||||
"idDescriptionLongMsg": 1000256,
|
||||
"sType": "combo",
|
||||
"sMinUserLevel": "1",
|
||||
"Choices": [
|
||||
@@ -45,18 +53,24 @@
|
||||
"sValue": "AUTO",
|
||||
"sDescriptionShort": "Automatic",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000257,
|
||||
"idDescriptionLongMsg": 1000258,
|
||||
"sMessageId": ""
|
||||
},
|
||||
{
|
||||
"sValue": "PREFER_ONE",
|
||||
"sDescriptionShort": "Preferred machining from one side only",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000259,
|
||||
"idDescriptionLongMsg": 1000260,
|
||||
"sMessageId": ""
|
||||
},
|
||||
{
|
||||
"sValue": "FORCE_TWO",
|
||||
"sDescriptionShort": "Force machining from two sides",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000261,
|
||||
"idDescriptionLongMsg": 1000262,
|
||||
"sMessageId": ""
|
||||
}
|
||||
]
|
||||
@@ -67,6 +81,8 @@
|
||||
"sValue": "",
|
||||
"sDescriptionShort": "Available mill to machine drills",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000263,
|
||||
"idDescriptionLongMsg": 1000264,
|
||||
"sType": "tool",
|
||||
"sSubType": "MCH_TF.MILL",
|
||||
"sMessageId": " ",
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
-- carico librerie
|
||||
local BeamLib = require( 'BeamLib')
|
||||
local BeamData = require( 'BeamData')
|
||||
local BeamData = require( 'BeamDataNew')
|
||||
local MachiningLib = require( 'MachiningLib')
|
||||
local FeatureLib = require( 'FeatureLib')
|
||||
-- strategie di base
|
||||
@@ -14,6 +14,27 @@ local FeatureLib = require( 'FeatureLib')
|
||||
local STR0013 = {}
|
||||
local Strategy = {}
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function GetSCC( vtMachiningDirection)
|
||||
-- TODO implementare SCC come per FacesBySaw
|
||||
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
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function GetDrillingWithMillStrategy( Proc, Part)
|
||||
local ToolSearchParameters = {}
|
||||
@@ -74,7 +95,7 @@ local function GetDrillingWithMillStrategy( Proc, Part)
|
||||
HalfMilling2.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
|
||||
|
||||
-- se entrambi gli utensili lavorano in modo completo fino alla metà del foro, li sostituisco a qeulli trovati in precedenza
|
||||
if HalfMilling.ToolInfo.dResidualDepth < 0 and HalfMilling2.ToolInfo.dResidualDepth < 0 then
|
||||
if HalfMilling.ToolInfo.dResidualDepth and HalfMilling2.ToolInfo.dResidualDepth and HalfMilling.ToolInfo.dResidualDepth < 0 and HalfMilling2.ToolInfo.dResidualDepth < 0 then
|
||||
if Milling.ToolInfo.nToolIndex ~= HalfMilling.ToolInfo.nToolIndex then
|
||||
Milling.ToolInfo.nToolIndex, Milling.ToolInfo.dResidualDepth = HalfMilling.ToolInfo.nToolIndex, HalfMilling.ToolInfo.dResidualDepth
|
||||
end
|
||||
@@ -172,6 +193,7 @@ function STR0013.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
MachiningToAdd = MachiningLib.InitMachiningParameters( MCH_MY.DRILLING)
|
||||
MachiningToAdd = BeamLib.MergeTables( MachiningToAdd, Strategy.Machinings[j])
|
||||
MachiningToAdd.Steps.dStep = TOOLS[nIndexTool].dStep / 3
|
||||
MachiningToAdd.nSCC = GetSCC( -MachiningToAdd.vtToolDirection)
|
||||
-- se diametro foro più grande della fresa, ma non oltre il doppio del diametro, si fa contornatura a spirale
|
||||
elseif Proc.FeatureInfo.dDrillDiam < ( TOOLS[nIndexTool].dDiameter * 0.75) * 2 or Strategy.Parameters.bOnlyContouring then
|
||||
MachiningToAdd = MachiningLib.InitMachiningParameters( MCH_MY.MILLING)
|
||||
@@ -184,6 +206,7 @@ function STR0013.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
MachiningToAdd.LeadOut.dTangentDistance = 0.5
|
||||
MachiningToAdd.LeadOut.dPerpDistance = 0.5
|
||||
MachiningToAdd.LeadOut.dElevation = Proc.FeatureInfo.dDrillLen
|
||||
MachiningToAdd.nSCC = GetSCC( -MachiningToAdd.vtToolDirection)
|
||||
-- se diametro foro più grande del doppio del diametro fresa, si fa svuotatura
|
||||
else
|
||||
MachiningToAdd = MachiningLib.InitMachiningParameters( MCH_MY.POCKETING)
|
||||
@@ -194,10 +217,15 @@ function STR0013.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
MachiningToAdd.LeadIn.nType = MCH_POCK_LI.HELIX
|
||||
MachiningToAdd.LeadIn.dTangentDistance = TOOLS[nIndexTool].dDiameter / 2
|
||||
MachiningToAdd.LeadIn.dElevation = MachiningToAdd.Steps.dStep / 2
|
||||
MachiningToAdd.nSCC = GetSCC( -MachiningToAdd.vtToolDirection)
|
||||
end
|
||||
|
||||
MachiningToAdd.nToolIndex = nIndexTool
|
||||
MachiningToAdd.Geometry = {{ Proc.FeatureInfo.idAddAuxGeom, -1}}
|
||||
|
||||
if Proc.AffectedFaces.bLeft and not Proc.FeatureInfo.bIsDrillOpen then
|
||||
MachiningToAdd.sStage = 'AfterTail'
|
||||
end
|
||||
bAreAllMachiningsAdded = MachiningLib.AddMachinings( Proc, MachiningToAdd)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
"sValue": "1",
|
||||
"sDescriptionShort": "Machining Depth",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000265,
|
||||
"idDescriptionLongMsg": 1000266,
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -18,6 +20,8 @@
|
||||
"sValue": "",
|
||||
"sDescriptionShort": "Available mill to machine mark and text",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000267,
|
||||
"idDescriptionLongMsg": 1000268,
|
||||
"sType": "tool",
|
||||
"sSubType": "MCH_TF.MILL",
|
||||
"sMessageId": " ",
|
||||
@@ -29,6 +33,8 @@
|
||||
"sValue": "AUTO",
|
||||
"sDescriptionShort": "Marking Strategy",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000269,
|
||||
"idDescriptionLongMsg": 1000270,
|
||||
"sType": "combo",
|
||||
"sMinUserLevel": "1",
|
||||
"Choices": [
|
||||
@@ -36,18 +42,24 @@
|
||||
"sValue": "AUTO",
|
||||
"sDescriptionShort": "Automatic",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000271,
|
||||
"idDescriptionLongMsg": 1000272,
|
||||
"sMessageId": ""
|
||||
},
|
||||
{
|
||||
"sValue": "PEN_FORCED",
|
||||
"sDescriptionShort": "Pen only",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000273,
|
||||
"idDescriptionLongMsg": 1000274,
|
||||
"sMessageId": ""
|
||||
},
|
||||
{
|
||||
"sValue": "VMILL_FORCED",
|
||||
"sDescriptionShort": "V-Mill only",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000275,
|
||||
"idDescriptionLongMsg": 1000276,
|
||||
"sMessageId": ""
|
||||
}
|
||||
]
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
-- carico librerie
|
||||
local BeamLib = require( 'BeamLib')
|
||||
local BeamData = require( 'BeamData')
|
||||
local BeamData = require( 'BeamDataNew')
|
||||
local MachiningLib = require( 'MachiningLib')
|
||||
local FeatureLib = require( 'FeatureLib')
|
||||
local ID = require( 'Identity')
|
||||
@@ -24,6 +24,8 @@ local function GetSCC( Machining)
|
||||
|
||||
if TOOLS[Machining.nToolIndex].SetupInfo.bToolOnAggregate then
|
||||
nSCC = MCH_SCC.ADIR_NEAR
|
||||
elseif TOOLS[Machining.nToolIndex].SetupInfo.nBlockedSCC then
|
||||
nSCC = TOOLS[Machining.nToolIndex].SetupInfo.nBlockedSCC
|
||||
elseif Machining.vtToolDirection:getY() <= 0 then
|
||||
nSCC = MCH_SCC.ADIR_YM
|
||||
else
|
||||
@@ -96,7 +98,7 @@ function STR0014.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
Strategy.Machining.nSCC = GetSCC( Strategy.Machining)
|
||||
|
||||
Strategy.Machining.nType = MCH_MY.MILLING
|
||||
Strategy.Machining.sDepth = EgtClamp( Strategy.Parameters.dMachiningDepth, -1, 5)
|
||||
Strategy.Machining.sDepth = EgtClamp( Strategy.Parameters.dMachiningDepth, -1, TOOLS[Strategy.Machining.nToolIndex].dMaxMaterial)
|
||||
Strategy.Machining.nWorkside = MCH_MILL_WS.CENTER
|
||||
|
||||
-- LeadIn / LeadOut
|
||||
@@ -104,12 +106,24 @@ function STR0014.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
Strategy.Machining.LeadOut = {}
|
||||
Strategy.Machining.LeadIn.nType = MCH_MILL_LI.NONE
|
||||
Strategy.Machining.LeadOut.nType = MCH_MILL_LI.NONE
|
||||
|
||||
-- se è una penna, si limita la lavorazione per evitare di partire fuori dal grezzo
|
||||
if ToolSearchParameters.sMillShape == 'PEN' then
|
||||
Strategy.Machining.LeadIn.dStartAddLength = -20
|
||||
Strategy.Machining.LeadOut.dEndAddLength = -20
|
||||
end
|
||||
|
||||
-- TODO gestire meglio
|
||||
-- se utensile montato su aggregato flottante
|
||||
if TOOLS[Strategy.Machining.nToolIndex].bToolOnFloatingTH then
|
||||
Strategy.Machining.dMaxElev = Strategy.Parameters.dMachiningDepth
|
||||
Strategy.Machining.dLongitudinalOffset = -5
|
||||
end
|
||||
-- stessi parametri cambia solo al geometria
|
||||
for i = 1, #Proc.FeatureInfo.AdditionalGeometries do
|
||||
local AuxId = Proc.id + Proc.FeatureInfo.AdditionalGeometries[i]
|
||||
Strategy.AuxiliaryData.Clones[i+1] = {}
|
||||
Strategy.AuxiliaryData.Clones[i+1].Geometry = EgtSetMachiningGeometry( {{ AuxId, -1}})
|
||||
Strategy.AuxiliaryData.Clones[i+1].Geometry = {{ AuxId, -1}}
|
||||
end
|
||||
|
||||
bAreAllMachiningsAdded = MachiningLib.AddMachinings( Proc, Strategy.Machining, Strategy.AuxiliaryData)
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
"sValue": "0",
|
||||
"sDescriptionShort": "Depth Chamfer",
|
||||
"sDescriptionLong": "Depth of the V-Mill to execute chamfers on cut-edges",
|
||||
"idDescriptionShortMsg": 1000277,
|
||||
"idDescriptionLongMsg": 1000278,
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -18,6 +20,8 @@
|
||||
"sValue": "false",
|
||||
"sDescriptionShort": "Only Chamfer",
|
||||
"sDescriptionLong": "Execute the chamfer only, no other machining",
|
||||
"idDescriptionShortMsg": 1000279,
|
||||
"idDescriptionLongMsg": 1000280,
|
||||
"sType": "b",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -28,6 +32,8 @@
|
||||
"sValue": "0",
|
||||
"sDescriptionShort": "Overmaterial",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000281,
|
||||
"idDescriptionLongMsg": 1000282,
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -38,6 +44,8 @@
|
||||
"sValue": "15",
|
||||
"sDescriptionShort": "Max radius left on corners",
|
||||
"sDescriptionLong": "Radius-limit left by the tool at each corner of the feature",
|
||||
"idDescriptionShortMsg": 1000283,
|
||||
"idDescriptionLongMsg": 1000284,
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -48,6 +56,8 @@
|
||||
"sValue": "true",
|
||||
"sDescriptionShort": "Execute cut to remove material",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000285,
|
||||
"idDescriptionLongMsg": 1000286,
|
||||
"sType": "b",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -58,6 +68,8 @@
|
||||
"sValue": "false",
|
||||
"sDescriptionShort": "Force strip",
|
||||
"sDescriptionLong": "Enable the parameter to force the software to leave a strip to sustain the piece",
|
||||
"idDescriptionShortMsg": 1000287,
|
||||
"idDescriptionLongMsg": 1000288,
|
||||
"sType": "b",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -68,6 +80,8 @@
|
||||
"sValue": "0",
|
||||
"sDescriptionShort": "Strip width",
|
||||
"sDescriptionLong": "Width of the strip in case if foreseen from the machining",
|
||||
"idDescriptionShortMsg": 1000289,
|
||||
"idDescriptionLongMsg": 1000290,
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -78,6 +92,8 @@
|
||||
"sValue": "AUTO",
|
||||
"sDescriptionShort": "Cutting Strategy",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000291,
|
||||
"idDescriptionLongMsg": 1000292,
|
||||
"sType": "combo",
|
||||
"sMinUserLevel": "1",
|
||||
"Choices": [
|
||||
@@ -85,24 +101,32 @@
|
||||
"sValue": "AUTO",
|
||||
"sDescriptionShort": "Automatic",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000293,
|
||||
"idDescriptionLongMsg": 1000294,
|
||||
"sMessageId": ""
|
||||
},
|
||||
{
|
||||
"sValue": "NONE",
|
||||
"sDescriptionShort": "No machining",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000295,
|
||||
"idDescriptionLongMsg": 1000296,
|
||||
"sMessageId": ""
|
||||
},
|
||||
{
|
||||
"sValue": "BLADE_FORCED",
|
||||
"sDescriptionShort": "Blade forced",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000297,
|
||||
"idDescriptionLongMsg": 1000298,
|
||||
"sMessageId": ""
|
||||
},
|
||||
{
|
||||
"sValue": "MILL_FORCED",
|
||||
"sDescriptionShort": "Mill forced",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000299,
|
||||
"idDescriptionLongMsg": 1000300,
|
||||
"sMessageId": ""
|
||||
}
|
||||
]
|
||||
@@ -113,6 +137,8 @@
|
||||
"sValue": "",
|
||||
"sDescriptionShort": "Available mill to machine the profile",
|
||||
"sDescriptionLong": "",
|
||||
"idDescriptionShortMsg": 1000301,
|
||||
"idDescriptionLongMsg": 1000302,
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
-- carico librerie
|
||||
local BeamLib = require( 'BeamLib')
|
||||
local BeamData = require( 'BeamData')
|
||||
local BeamData = require( 'BeamDataNew')
|
||||
local MachiningLib = require( 'MachiningLib')
|
||||
local FeatureLib = require( 'FeatureLib')
|
||||
local FaceData = require( 'FaceData')
|
||||
@@ -108,15 +108,17 @@ local function GetRoughStrategy( Proc, Part, bSaveAddedGeometries)
|
||||
local nMidFacet = Proc.nFct // 2 -- faccia a metà circa
|
||||
local vtN = EgtSurfTmFacetNormVersor( Proc.id, nMidFacet, GDB_ID.ROOT)
|
||||
|
||||
local nAddGroupId = BeamLib.GetAddGroup( Part.id)
|
||||
local idAddGroup
|
||||
if bSaveAddedGeometries then
|
||||
idAddGroup = BeamLib.GetAddGroup( Part.id)
|
||||
else
|
||||
idAddGroup = Part.idTempGroup
|
||||
end
|
||||
-- aggiungo piano di sgrossatura e lo lavoro
|
||||
local ptStart, vtNP = GetSawCutData( Proc, Proc.idAddAuxGeom, vtNF, vtN)
|
||||
local AddId = EgtSurfTmPlaneInBBox( nAddGroupId, ptStart, vtNP, Part.b3Part, GDB_RT.GLOB)
|
||||
local AddId = EgtSurfTmPlaneInBBox( idAddGroup, ptStart, vtNP, Part.b3Part, GDB_RT.GLOB)
|
||||
-- se la faccia è stata creata
|
||||
if AddId then
|
||||
if not bSaveAddedGeometries then
|
||||
EgtSetLevel( AddId, GDB_LV.TEMP)
|
||||
end
|
||||
|
||||
-- creo piano di taglio sulla testa del tenone
|
||||
local OptionalParameters = { dMaxWasteVolume = Strategy.Parameters.dMaxWasteVolume,
|
||||
@@ -209,7 +211,7 @@ local function GetEdgeWithCornerStrategy( Proc, Part)
|
||||
-- direzioni di lavorazione
|
||||
local vtCutDir1
|
||||
-- se è diretta verso alto o basso
|
||||
if vtN:getZ() > vtN:getY() then
|
||||
if abs( vtN:getZ()) > abs( vtN:getY()) then
|
||||
if vtN:getZ() > 0 then
|
||||
vtCutDir1 = Z_AX()
|
||||
else
|
||||
@@ -231,81 +233,99 @@ local function GetEdgeWithCornerStrategy( Proc, Part)
|
||||
vtCutDir2 = -X_AX()
|
||||
end
|
||||
|
||||
local nMachiningsToAdd
|
||||
|
||||
-- AUTO = preferisce lama. Se non è possibile prende fresa
|
||||
-- BLADE_FORCED = solo lama, altriemnti non applica nulla (potrebbe essere necessario un ribaltamento)
|
||||
-- MILL_FORCED = solo fresa, altriemnti non applica nulla (potrebbe essere necessario un ribaltamento)
|
||||
if Strategy.Parameters.sConcaveFaceStrategy == 'AUTO' or Strategy.Parameters.sConcaveFaceStrategy == 'BLADE_FORCED' then
|
||||
|
||||
nMachiningsToAdd = 0
|
||||
|
||||
-- TODO c'è una funzione che ritorni l'edge di connessione tra una faccia e un'altra?
|
||||
-- lavorazione faccia 1 spigolo finale
|
||||
if bLastTrim then
|
||||
nMachiningsToAdd = nMachiningsToAdd + 1
|
||||
local EdgeToMachine = GetEdgeToMachine( Proc, nLastFacet+1, vtCutDir1)
|
||||
local Cutting = FaceByBlade.Make( Proc, Part, Proc.Faces[nLastFacet+1], EdgeToMachine)
|
||||
if Proc.AffectedFaces.bLeft and Strategy.bCanMoveAfterSplit then
|
||||
Cutting.sStage = 'AfterTail'
|
||||
end
|
||||
if Cutting then
|
||||
if Cutting.bIsApplicable then
|
||||
table.insert( Machining, Cutting)
|
||||
end
|
||||
end
|
||||
|
||||
-- lavorazione faccia 1 spigolo iniziale
|
||||
if bFirstTrim then
|
||||
nMachiningsToAdd = nMachiningsToAdd + 1
|
||||
local EdgeToMachine = GetEdgeToMachine( Proc, nFirstFacet+2, vtCutDir1)
|
||||
local Cutting = FaceByBlade.Make( Proc, Part, Proc.Faces[nFirstFacet+2], EdgeToMachine)
|
||||
if Proc.AffectedFaces.bLeft and Strategy.bCanMoveAfterSplit then
|
||||
Cutting.sStage = 'AfterTail'
|
||||
end
|
||||
if Cutting then
|
||||
if Cutting.bIsApplicable then
|
||||
table.insert( Machining, Cutting)
|
||||
end
|
||||
end
|
||||
|
||||
-- lavorazione faccia 2 spigolo finale
|
||||
if bLastTrim then
|
||||
nMachiningsToAdd = nMachiningsToAdd + 1
|
||||
EdgeToMachine = GetEdgeToMachine( Proc, nLastFacet, vtCutDir2)
|
||||
Cutting = FaceByBlade.Make( Proc, Part, Proc.Faces[nLastFacet], EdgeToMachine)
|
||||
if Cutting then
|
||||
if Cutting.bIsApplicable then
|
||||
table.insert( Machining, Cutting)
|
||||
end
|
||||
end
|
||||
|
||||
-- lavorazione faccia 2 spigolo iniziale
|
||||
if bFirstTrim then
|
||||
nMachiningsToAdd = nMachiningsToAdd + 1
|
||||
local EdgeToMachine = GetEdgeToMachine( Proc, nFirstFacet+1, vtCutDir2)
|
||||
local Cutting = FaceByBlade.Make( Proc, Part, Proc.Faces[nFirstFacet+1], EdgeToMachine)
|
||||
if Cutting then
|
||||
if Cutting.bIsApplicable then
|
||||
table.insert( Machining, Cutting)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- se non ci sono lavorazioni provo a pulire spigoli con fresa, a patto che non sia stato forzato con lama
|
||||
if #Machining == 0 and Strategy.Parameters.sConcaveFaceStrategy ~= 'BLADE_FORCED' then
|
||||
if ( not nMachiningsToAdd or ( #Machining < nMachiningsToAdd)) and Strategy.Parameters.sConcaveFaceStrategy ~= 'BLADE_FORCED' then
|
||||
|
||||
Machining = {}
|
||||
nMachiningsToAdd = 0
|
||||
|
||||
-- TODO c'è una funzione che ritorni l'edge di connessione tra una faccia e un'altra?
|
||||
-- lavorazione faccia 1 spigolo iniziale
|
||||
if bFirstTrim then
|
||||
nMachiningsToAdd = nMachiningsToAdd + 1
|
||||
local EdgeToMachine = GetEdgeToMachine( Proc, nFirstFacet+2, vtCutDir1)
|
||||
local Milling = FaceByMill.Make( Proc, Part, Proc.Faces[nFirstFacet+2], EdgeToMachine)
|
||||
if Proc.AffectedFaces.bLeft and Strategy.bCanMoveAfterSplit then
|
||||
Milling.sStage = 'AfterTail'
|
||||
end
|
||||
if Milling then
|
||||
if Milling.bIsApplicable then
|
||||
table.insert( Machining, Milling)
|
||||
end
|
||||
end
|
||||
|
||||
-- lavorazione faccia 2 spigolo finale
|
||||
if bLastTrim then
|
||||
nMachiningsToAdd = nMachiningsToAdd + 1
|
||||
EdgeToMachine = GetEdgeToMachine( Proc, nLastFacet, vtCutDir2)
|
||||
local Milling = FaceByMill.Make( Proc, Part, Proc.Faces[nLastFacet], EdgeToMachine)
|
||||
if Proc.AffectedFaces.bLeft and Strategy.bCanMoveAfterSplit then
|
||||
Milling.sStage = 'AfterTail'
|
||||
end
|
||||
if Milling then
|
||||
if Milling.bIsApplicable then
|
||||
table.insert( Machining, Milling)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if nMachiningsToAdd and ( #Machining < nMachiningsToAdd) then
|
||||
Result = { dCompletionPercentage = ( #Machining / nMachiningsToAdd)}
|
||||
end
|
||||
|
||||
return Machining, Result
|
||||
@@ -439,7 +459,7 @@ local function GetArcStrategy( Proc, Part)
|
||||
|
||||
local bExecStrip = false
|
||||
-- se la lavorazione si trova nella parte inferiore o in battuta dietro, il codolo va sempre lasciato
|
||||
if bIsFeatureDown or bIsFeatureBack or bForceStrip then
|
||||
if ID.IsRoundArch( Proc) and ( bIsFeatureDown or bIsFeatureBack or bForceStrip) then
|
||||
if bIsFeatureDown or bIsFeatureBack then
|
||||
dDimStrip = dDimStrip or max( BeamData.DIM_STRIP or 5, 5)
|
||||
else
|
||||
@@ -637,7 +657,7 @@ local function GetFeatureResult( Proc)
|
||||
-- se richieste anche le altre lavorazioni
|
||||
if not Strategy.Parameters.bOnlyChamfer then
|
||||
-- per tutti tranne che per feature RoundArc
|
||||
if not ID.IsRoundArch( Proc) then
|
||||
if not ID.IsRoundArch( Proc) and not ID.IsFreeContour( Proc) then
|
||||
-- se sgrossatura da eseguire
|
||||
if Strategy.Parameters.bExecRough then
|
||||
if not Strategy.RoughCut.Machinings or #Strategy.RoughCut.Machinings == 0 then
|
||||
@@ -684,6 +704,21 @@ local function GetFeatureResult( Proc)
|
||||
return Result
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function GetSCC( Proc, vtToolDirection)
|
||||
local nSCC = MCH_SCC.NONE
|
||||
|
||||
if Proc.AffectedFaces.bRight and not Proc.AffectedFaces.bLeft then
|
||||
nSCC = MCH_SCC.ADIR_XP
|
||||
elseif Proc.AffectedFaces.bLeft and not Proc.AffectedFaces.bRight then
|
||||
nSCC = MCH_SCC.ADIR_XM
|
||||
elseif vtToolDirection and AreSameOrOppositeVectorApprox( vtToolDirection, Z_AX()) then
|
||||
nSCC = MCH_SCC.ADIR_YP
|
||||
end
|
||||
|
||||
return nSCC
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function STR0015.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
-- carico parametri de default e li aggiorno con quelli passati dal chiamante (potrebbero non essere congruenti)
|
||||
@@ -698,7 +733,7 @@ function STR0015.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
|
||||
local bAreAllMachiningsAdded = true
|
||||
|
||||
-- calcolo se la lavorazione del tenone può essere spostata dopo taglio di coda
|
||||
-- verifico se la lavorazione può essere spostata dopo taglio di coda
|
||||
local dLengthOnX = Proc.b3Box:getDimX()
|
||||
Strategy.bCanMoveAfterSplit = MachiningLib.CanMoveAfterSplitcut( dLengthOnX, Part)
|
||||
|
||||
@@ -718,7 +753,7 @@ function STR0015.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
-- se non bisogna fare solo gli smussi, si calcolano le altre lavorazioni
|
||||
if not Strategy.Parameters.bOnlyChamfer then
|
||||
-- per tutti tranne che per feature RoundArc
|
||||
if not ID.IsRoundArch( Proc) then
|
||||
if not ID.IsRoundArch( Proc) and not ID.IsFreeContour( Proc) then
|
||||
-- lavorazione taglio per sgrossare
|
||||
if Strategy.Parameters.bExecRough then
|
||||
Strategy.RoughCut = {}
|
||||
@@ -760,7 +795,7 @@ function STR0015.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
end
|
||||
|
||||
-- per tutti tranne che per feature RoundArc
|
||||
if not ID.IsRoundArch( Proc) then
|
||||
if not ID.IsRoundArch( Proc) and not ID.IsFreeContour( Proc) then
|
||||
-- lavorazione di sgrezzatura di lama
|
||||
if Strategy.Parameters.bExecRough and Strategy.RoughCut.Machinings then
|
||||
-- se cutting da fare come svuotatura
|
||||
@@ -794,56 +829,56 @@ function STR0015.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
if Strategy.Profile.Machinings then
|
||||
for i = 1, #Strategy.Profile.Machinings do
|
||||
|
||||
Strategy.Profile.Machinings[i].Geometry = {{ Proc.idAddAuxGeom, -1}}
|
||||
Strategy.Profile.Machinings[i].nToolIndex = Strategy.Profile.Machinings[i].ToolInfo.nToolIndex
|
||||
Strategy.Profile.Machinings[i].nType = MCH_MY.MILLING
|
||||
Strategy.Profile.Machinings[i].Steps = {}
|
||||
local CurrentMachining = Strategy.Profile.Machinings[i]
|
||||
|
||||
Strategy.Profile.Machinings[i].Steps.dStep = TOOLS[Strategy.Profile.Machinings[i].ToolInfo.nToolIndex].dStep
|
||||
Strategy.Profile.Machinings[i].Steps = MachiningLib.GetMachiningSteps( tonumber( Strategy.Profile.Machinings[i].sDepth), TOOLS[Strategy.Profile.Machinings[i].nToolIndex].dStep)
|
||||
Strategy.Profile.Machinings[i].Steps.nStepType = MCH_MILL_ST.ONEWAY
|
||||
CurrentMachining.Geometry = {{ Proc.idAddAuxGeom, -1}}
|
||||
CurrentMachining.nToolIndex = CurrentMachining.ToolInfo.nToolIndex
|
||||
CurrentMachining.nType = MCH_MY.MILLING
|
||||
CurrentMachining.Steps = MachiningLib.GetMachiningSteps( false, tonumber( CurrentMachining.sDepth), TOOLS[CurrentMachining.nToolIndex].dStep)
|
||||
CurrentMachining.Steps.nStepType = MCH_MILL_ST.ONEWAY
|
||||
CurrentMachining.nSCC = GetSCC( Proc, CurrentMachining.vtToolDirection)
|
||||
|
||||
-- LeadIn / LeadOut
|
||||
Strategy.Profile.Machinings[i].LeadIn.nType = MCH_MILL_LI.TANGENT
|
||||
Strategy.Profile.Machinings[i].LeadOut.nType = MCH_MILL_LI.TANGENT
|
||||
Strategy.Profile.Machinings[i].LeadIn.dTangentDistance = TOOLS[Strategy.Profile.Machinings[i].ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC
|
||||
Strategy.Profile.Machinings[i].LeadIn.dPerpDistance = 0
|
||||
Strategy.Profile.Machinings[i].LeadIn.dStartAddLength = 0
|
||||
Strategy.Profile.Machinings[i].LeadOut.dTangentDistance = TOOLS[Strategy.Profile.Machinings[i].ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC
|
||||
Strategy.Profile.Machinings[i].LeadOut.dPerpDistance = 0
|
||||
Strategy.Profile.Machinings[i].LeadOut.dEndAddLength = 0
|
||||
CurrentMachining.LeadIn.nType = MCH_MILL_LI.TANGENT
|
||||
CurrentMachining.LeadOut.nType = MCH_MILL_LI.TANGENT
|
||||
CurrentMachining.LeadIn.dTangentDistance = TOOLS[CurrentMachining.ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC
|
||||
CurrentMachining.LeadIn.dPerpDistance = 0
|
||||
CurrentMachining.LeadIn.dStartAddLength = 0
|
||||
CurrentMachining.LeadOut.dTangentDistance = TOOLS[CurrentMachining.ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC
|
||||
CurrentMachining.LeadOut.dPerpDistance = 0
|
||||
CurrentMachining.LeadOut.dEndAddLength = 0
|
||||
|
||||
if Proc.AffectedFaces.bLeft and Strategy.bCanMoveAfterSplit then
|
||||
Strategy.Profile.Machinings[i].sStage = 'AfterTail'
|
||||
CurrentMachining.sStage = 'AfterTail'
|
||||
end
|
||||
|
||||
-- preparo attacco/uscita in caso di spezzatura arco
|
||||
Strategy.Profile.Machinings[i].LeadInForSplit = BeamLib.TableCopyDeep( Strategy.Profile.Machinings[i].LeadIn)
|
||||
Strategy.Profile.Machinings[i].LeadOutForSplit = BeamLib.TableCopyDeep( Strategy.Profile.Machinings[i].LeadOut)
|
||||
Strategy.Profile.Machinings[i].LeadInForSplit.nType = MCH_MILL_LI.LINEAR
|
||||
Strategy.Profile.Machinings[i].LeadOutForSplit.nType = MCH_MILL_LI.LINEAR
|
||||
Strategy.Profile.Machinings[i].LeadInForSplit.dTangentDistance = 0
|
||||
Strategy.Profile.Machinings[i].LeadInForSplit.dPerpDistance = TOOLS[Strategy.Profile.Machinings[i].ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC
|
||||
Strategy.Profile.Machinings[i].LeadOutForSplit.dTangentDistance = 0
|
||||
Strategy.Profile.Machinings[i].LeadOutForSplit.dPerpDistance = TOOLS[Strategy.Profile.Machinings[i].ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC
|
||||
CurrentMachining.LeadInForSplit = BeamLib.TableCopyDeep( CurrentMachining.LeadIn)
|
||||
CurrentMachining.LeadOutForSplit = BeamLib.TableCopyDeep( CurrentMachining.LeadOut)
|
||||
CurrentMachining.LeadInForSplit.nType = MCH_MILL_LI.LINEAR
|
||||
CurrentMachining.LeadOutForSplit.nType = MCH_MILL_LI.LINEAR
|
||||
CurrentMachining.LeadInForSplit.dTangentDistance = 0
|
||||
CurrentMachining.LeadInForSplit.dPerpDistance = TOOLS[CurrentMachining.ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC
|
||||
CurrentMachining.LeadOutForSplit.dTangentDistance = 0
|
||||
CurrentMachining.LeadOutForSplit.dPerpDistance = TOOLS[CurrentMachining.ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC
|
||||
|
||||
-- sistemo il lato e la direzione di lavoro
|
||||
if Strategy.Profile.Machinings[i].bOtherDirection then
|
||||
Strategy.Profile.Machinings[i].bToolInvert = true
|
||||
Strategy.Profile.Machinings[i].bInvert = EgtIf( TOOLS[Strategy.Profile.Machinings[i].ToolInfo.nToolIndex].bIsCCW, true, false)
|
||||
Strategy.Profile.Machinings[i].nWorkside = EgtIf( TOOLS[Strategy.Profile.Machinings[i].ToolInfo.nToolIndex].bIsCCW, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT)
|
||||
if CurrentMachining.bOtherDirection then
|
||||
CurrentMachining.bToolInvert = true
|
||||
CurrentMachining.bInvert = EgtIf( TOOLS[CurrentMachining.ToolInfo.nToolIndex].bIsCCW, true, false)
|
||||
CurrentMachining.nWorkside = EgtIf( TOOLS[CurrentMachining.ToolInfo.nToolIndex].bIsCCW, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT)
|
||||
else
|
||||
Strategy.Profile.Machinings[i].bInvert = EgtIf( TOOLS[Strategy.Profile.Machinings[i].ToolInfo.nToolIndex].bIsCCW, false, true)
|
||||
Strategy.Profile.Machinings[i].nWorkside = EgtIf( TOOLS[Strategy.Profile.Machinings[i].ToolInfo.nToolIndex].bIsCCW, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT)
|
||||
CurrentMachining.bInvert = EgtIf( TOOLS[CurrentMachining.ToolInfo.nToolIndex].bIsCCW, false, true)
|
||||
CurrentMachining.nWorkside = EgtIf( TOOLS[CurrentMachining.ToolInfo.nToolIndex].bIsCCW, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT)
|
||||
end
|
||||
Strategy.Profile.Machinings[i].ptEdge1 = EgtSP( Proc.idAddAuxGeom, GDB_ID.ROOT)
|
||||
Strategy.Profile.Machinings[i].ptEdge2 = EgtEP( Proc.idAddAuxGeom, GDB_ID.ROOT)
|
||||
Strategy.Profile.Machinings[i].dEdgeLength = EgtCurveLength( Proc.idAddAuxGeom)
|
||||
Strategy.Profile.Machinings[i].vtEdgeDirection = EgtSV( Proc.idAddAuxGeom, GDB_ID.ROOT) + EgtMV( Proc.idAddAuxGeom, GDB_ID.ROOT) + EgtEV( Proc.idAddAuxGeom, GDB_ID.ROOT)
|
||||
Strategy.Profile.Machinings[i].dLengthOnX = Proc.b3Box:getDimX()
|
||||
CurrentMachining.ptEdge1 = EgtSP( Proc.idAddAuxGeom, GDB_ID.ROOT)
|
||||
CurrentMachining.ptEdge2 = EgtEP( Proc.idAddAuxGeom, GDB_ID.ROOT)
|
||||
CurrentMachining.dEdgeLength = EgtCurveLength( Proc.idAddAuxGeom)
|
||||
CurrentMachining.vtEdgeDirection = EgtSV( Proc.idAddAuxGeom, GDB_ID.ROOT) + EgtMV( Proc.idAddAuxGeom, GDB_ID.ROOT) + EgtEV( Proc.idAddAuxGeom, GDB_ID.ROOT)
|
||||
CurrentMachining.dLengthOnX = Proc.b3Box:getDimX()
|
||||
|
||||
local MachiningToSplit = {}
|
||||
table.insert( MachiningToSplit, Strategy.Profile.Machinings[i])
|
||||
table.insert( MachiningToSplit, CurrentMachining)
|
||||
local MachiningResult = MachiningLib.GetSplitMachinings( MachiningToSplit, FeatureSplittingPoints, Part)
|
||||
-- aggiunge lavorazione
|
||||
for j = 1, #MachiningResult do
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
"sValue": "0",
|
||||
"sDescriptionShort": "Depth Chamfer",
|
||||
"sDescriptionLong": "Depth of the V-Mill to execute chamfers on cut-edges",
|
||||
"idDescriptionShortMsg": 1000309,
|
||||
"idDescriptionLongMsg": 1000310,
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -18,6 +20,8 @@
|
||||
"sValue": "false",
|
||||
"sDescriptionShort": "Force to use chain saw",
|
||||
"sDescriptionLong": "Force to use chain saw",
|
||||
"idDescriptionShortMsg": 1000311,
|
||||
"idDescriptionLongMsg": 1000312,
|
||||
"sType": "b",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -28,6 +32,8 @@
|
||||
"sValue": "true",
|
||||
"sDescriptionShort": "Force to add PreCuts",
|
||||
"sDescriptionLong": "Autocam will apply a machining on the theoretical zero, to avoid collision if the theoretical piece length doesn't correspond to the real length",
|
||||
"idDescriptionShortMsg": 1000313,
|
||||
"idDescriptionLongMsg": 1000314,
|
||||
"sType": "b",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
@@ -38,6 +44,8 @@
|
||||
"sValue": "true",
|
||||
"sDescriptionShort": "Finish with mill",
|
||||
"sDescriptionLong": "Use a mill to finish the surface if split with chain saw",
|
||||
"idDescriptionShortMsg": 1000315,
|
||||
"idDescriptionLongMsg": 1000316,
|
||||
"sType": "b",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
-- carico librerie
|
||||
local BeamLib = require( 'BeamLib')
|
||||
local BeamData = require( 'BeamData')
|
||||
local BeamData = require( 'BeamDataNew')
|
||||
local FeatureLib = require( 'FeatureLib')
|
||||
local MachiningLib = require( 'MachiningLib')
|
||||
local SPLITCUT = require( 'SPLITCUT')
|
||||
@@ -34,11 +34,18 @@ function TAILCUT.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
Strategy.Result.sInfo = ''
|
||||
local OptionalParameters = { bForceChainSaw = Strategy.Parameters.bForceChainSaw, bReduceBladePath = Strategy.Parameters.bReduceBladePath,
|
||||
dMaxWasteLength = Strategy.Parameters.dMaxWasteLength, dMaxWasteVolume = Strategy.Parameters.dMaxWasteVolume }
|
||||
OptionalParameters.sRestLengthSideForPreSimulation = 'Tail'
|
||||
OptionalParameters.bCannotSplitRestLength = true
|
||||
local bAreAllMachiningsAdded = true
|
||||
local bExecutePrecutOnly = false
|
||||
|
||||
-- si setta che è taglio di coda
|
||||
Strategy.bIsTailCut = true
|
||||
-- quando si aggiunge la lavorazione, si cambia il nome della feature
|
||||
if bAddMachining then
|
||||
-- si forza il nome della feature
|
||||
EgtSetName( Proc.id, 'EndCut')
|
||||
end
|
||||
|
||||
-- separazione solo se esiste grezzo successivo con pezzi o scaricabile
|
||||
Strategy.bSplit = not( Part.bIsLastPart) or Part.dRestLength >= BeamData.dMinRaw
|
||||
@@ -49,6 +56,11 @@ function TAILCUT.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
OptionalParameters.bDisableDicing = true
|
||||
Strategy.SplitStrategy, Strategy.Result = SPLITCUT.GetMachining( Proc, Part, OptionalParameters)
|
||||
|
||||
if Strategy.Result.sStatus ~= 'Completed' then
|
||||
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( 'Split not possible')
|
||||
return false, Strategy.Result
|
||||
end
|
||||
|
||||
-- se devo rimuovere tutto il restante
|
||||
else
|
||||
-- se abilitato, faccio tagli di PRECUT a zero (come SPLIT)
|
||||
@@ -58,10 +70,18 @@ function TAILCUT.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
OptionalParameters.dOffset = 0
|
||||
else
|
||||
Strategy.bIsPreCut = true
|
||||
-- TODO questo dOffset è errato, va creata una nuova faccia oppure usare dLongitudinalOffset e farlo transitare per tutti, anche Engagement
|
||||
-- TODO a dRestLength va anche aggiunto lo spessore lama se c'è a fine grezzo?
|
||||
OptionalParameters.dOffset = Part.dRestLength
|
||||
end
|
||||
OptionalParameters.bDisableDicing = true
|
||||
Strategy.SplitStrategy, Strategy.Result = SPLITCUT.GetMachining( Proc, Part, OptionalParameters)
|
||||
|
||||
if Strategy.Result.sStatus ~= 'Completed' then
|
||||
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( 'Precut Tail not possible')
|
||||
return false, Strategy.Result
|
||||
end
|
||||
|
||||
-- se non faccio tagli PRECUT, imposto tabella Result direttamente. Non serve verificare che riesca a rimuovere il materiale extra
|
||||
else
|
||||
Strategy.Result.sStatus = 'Completed'
|
||||
@@ -74,9 +94,6 @@ function TAILCUT.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
|
||||
-- se devo applicare le lavorazioni
|
||||
if bAddMachining then
|
||||
-- si forza il nome della feature
|
||||
EgtSetName( Proc.id, 'EndCut')
|
||||
|
||||
-- inserimento smussi su spigoli del taglio
|
||||
if Strategy.Parameters.bMakeChamfer then
|
||||
MakeChamfer()
|
||||
@@ -122,21 +139,26 @@ function TAILCUT.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
end
|
||||
|
||||
if not bExecutePrecutOnly then
|
||||
OptionalParameters = {}
|
||||
|
||||
-- eventuale grezzo custom per dicing (grezzo attuale + grezzo di coda)
|
||||
local nNextRawId = EgtGetNextRawPart( Part.idRaw)
|
||||
if nNextRawId then
|
||||
local b3BoxDicing = EgtGetRawPartBBox( nNextRawId)
|
||||
b3BoxDicing:Add( Part.b3Raw)
|
||||
OptionalParameters.b3BoxDicing = b3BoxDicing
|
||||
-- si recuperano gli estremi del box del materiale di coda da rimuovere
|
||||
local b3PartWithTail = BeamLib.GetPartBoxWithHeadTail( Part, 'Tail')
|
||||
local ptStartRestLength = Point3d( Part.b3Part:getMin():getX() + 1, Part.b3Part:getMax():getY(), Part.b3Part:getMax():getZ())
|
||||
local ptEndRestLength = Point3d( b3PartWithTail:getMin():getX(), Part.b3Part:getMin():getY(), Part.b3Part:getMin():getZ())
|
||||
|
||||
local OptionalParametersBladeToWaste = {}
|
||||
OptionalParametersBladeToWaste.b3BoxDicing = BBox3d( ptStartRestLength, ptEndRestLength)
|
||||
OptionalParametersBladeToWaste.dMaxWasteVolume = Strategy.Parameters.dMaxWasteVolume
|
||||
OptionalParametersBladeToWaste.dMaxWasteLength = Strategy.Parameters.dMaxWasteLength
|
||||
OptionalParametersBladeToWaste.bReduceBladePath = Strategy.Parameters.bReduceBladePath
|
||||
OptionalParametersBladeToWaste.sRestLengthSideForPreSimulation = 'Tail'
|
||||
OptionalParametersBladeToWaste.bCannotSplitRestLength = true
|
||||
|
||||
Strategy.Machining, _ = BladeToWaste.Make( Proc, Part, OptionalParametersBladeToWaste)
|
||||
-- se taglio non riuscito, si riprova con il riduci percorso forzato (collisione possibile in separazione pezzi alti)
|
||||
if ( not Strategy.Machining) or ( #Strategy.Machining == 0) then
|
||||
OptionalParametersBladeToWaste.bReduceBladePath = true
|
||||
Strategy.Machining, _ = BladeToWaste.Make( Proc, Part, OptionalParametersBladeToWaste)
|
||||
end
|
||||
|
||||
OptionalParameters.dMaxWasteVolume = Strategy.Parameters.dMaxWasteVolume
|
||||
OptionalParameters.dMaxWasteLength = Strategy.Parameters.dMaxWasteLength
|
||||
OptionalParameters.bReduceBladePath = Strategy.Parameters.bReduceBladePath
|
||||
|
||||
Strategy.Machining, _ = BladeToWaste.Make( Proc, Part, OptionalParameters)
|
||||
if Strategy.Machining and #Strategy.Machining > 0 then
|
||||
for i = 1, #Strategy.Machining do
|
||||
local TempList = {}
|
||||
@@ -149,6 +171,9 @@ function TAILCUT.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
end
|
||||
table.insert( MachiningsToAdd, TempList)
|
||||
end
|
||||
else
|
||||
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( 'Tail machining not possible')
|
||||
return false, Strategy.Result
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -7,8 +7,8 @@ STR0004 = Topologia tipo LapJoint. Motosega
|
||||
STR0005 = 1, 2 o 3 facce. Lama con taglio singolo o cubetti. Se richiesto o necessario codolo.
|
||||
STR0006 = Tenone. Lama + fresa
|
||||
STR0007 = Mortasa a coda di rondine e mortasa frontale a coda di rondine
|
||||
STR0008 = Svuotatura tasca
|
||||
STR0009 = !!DEPRECATA!! Sostituita da STR0015. RIUTILIZZABILE!
|
||||
STR0008 = Svuotatura mortasa (raggiata)
|
||||
STR0009 = ScarfJoint
|
||||
STR0010 = Fresatura perpendicolare (tipo cut, longcut)
|
||||
STR0011 = Foratura
|
||||
STR0012 = RidgeLap
|
||||
@@ -79,7 +79,7 @@ STR0015 = Profilo arcuato (Head Cambered Profile)
|
||||
; Feature : French Ridge Lap
|
||||
35,1,Feature,
|
||||
; Feature : Chamfer
|
||||
36,0,Feature,
|
||||
36,0,Feature,STR0002,STR0005,STR0010
|
||||
; Feature : Block Haus Half Lap
|
||||
37,0,Feature,
|
||||
; Feature : Block Haus Front
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
-- Strategia: FACEBYBLADE
|
||||
-- Descrizione
|
||||
-- Strategia di base per la lavorazione delle facce con lama
|
||||
|
||||
-- carico librerie
|
||||
local FaceByBlade = require( 'FACEBYBLADE')
|
||||
|
||||
-- Tabella per definizione modulo
|
||||
local ANTISPLINTONFACE = {}
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function ANTISPLINTONFACE.Make( Proc, Part, Face, OptionalParameters)
|
||||
local Machinings = {}
|
||||
|
||||
-- parametri opzionali
|
||||
if not OptionalParameters then
|
||||
OptionalParameters = {}
|
||||
end
|
||||
local bIsSplitFeature = OptionalParameters.bIsSplitFeature or false
|
||||
local dExtendAfterTail = OptionalParameters.dExtendAfterTail or 10000
|
||||
local nInternalSortingPriority = OptionalParameters.nInternalSortingPriority or 1
|
||||
local dResultWeight = OptionalParameters.dResultWeight or 0.15
|
||||
local bMachineAllClosedEdges = OptionalParameters.bMachineAllClosedEdges or false
|
||||
|
||||
local ClosingFacesAgainstGrain = {}
|
||||
for i = 1, #Face.Edges do
|
||||
local CurrentFace = Proc.Faces[Face.Edges[i].idAdjacentFace + 1]
|
||||
if ( not Face.Edges[i].bIsOpen) and ( Face.Edges[i].bIsStartOpen or Face.Edges[i].bIsEndOpen or bMachineAllClosedEdges) then
|
||||
table.insert( ClosingFacesAgainstGrain, CurrentFace)
|
||||
end
|
||||
end
|
||||
for i = 1, #ClosingFacesAgainstGrain do
|
||||
local EdgeToMachine = {}
|
||||
for j = 1, #ClosingFacesAgainstGrain[i].Edges do
|
||||
if ClosingFacesAgainstGrain[i].Edges[j].idAdjacentFace == Face.id then
|
||||
EdgeToMachine = ClosingFacesAgainstGrain[i].Edges[j]
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
local Cutting = {}
|
||||
local OptionalParametersFaceByBlade = { bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail}
|
||||
Cutting = FaceByBlade.Make( Proc, Part, ClosingFacesAgainstGrain[i], EdgeToMachine, OptionalParametersFaceByBlade)
|
||||
|
||||
Cutting.nInternalSortingPriority = nInternalSortingPriority
|
||||
Cutting.dResultWeight = dResultWeight
|
||||
table.insert( Machinings, Cutting)
|
||||
end
|
||||
|
||||
return Machinings
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
|
||||
return ANTISPLINTONFACE
|
||||
+266
-96
@@ -11,47 +11,66 @@ require( 'EgtBase')
|
||||
local FeatureLib = require( 'FeatureLib')
|
||||
local FaceData = require( 'FaceData')
|
||||
local MachiningLib = require( 'MachiningLib')
|
||||
local BeamLib = require('BeamLib')
|
||||
-- strategie di base
|
||||
local FaceByBlade = require('FACEBYBLADE')
|
||||
local FaceByMill = require('FACEBYMILL')
|
||||
local FaceByMill = require( 'FACEBYMILL')
|
||||
local AntiSplintOnFace = require( 'ANTISPLINTONFACE')
|
||||
|
||||
-- tabelle per definizione modulo
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function CompareEdges( EdgeA, EdgeB)
|
||||
-- prima i lati orientati lungo X
|
||||
if abs( EdgeA.vtN:getX()) < abs( EdgeB.vtN:getX()) - 10 * GEO.EPS_SMALL then
|
||||
local function CompareEdgesLongestTop( EdgeA, EdgeB)
|
||||
-- si preferiscono i lati più lunghi
|
||||
if EdgeA.dLength > EdgeB.dLength + 10 * GEO.EPS_SMALL then
|
||||
return true
|
||||
elseif abs( EdgeA.vtN:getX()) > abs( EdgeB.vtN:getX()) + 10 * GEO.EPS_SMALL then
|
||||
elseif EdgeA.dLength < EdgeB.dLength - 10 * GEO.EPS_SMALL then
|
||||
return false
|
||||
-- se stessa X si preferiscono i lati più lunghi (nel caso di 5 lati è quello non spezzato)
|
||||
-- se stessa lunghezza si preferiscono i lati più in basso
|
||||
else
|
||||
if EdgeA.dLength > EdgeB.dLength + 10 * GEO.EPS_SMALL then
|
||||
if EdgeA.vtN:getZ() > EdgeB.vtN:getZ() + 10 * GEO.EPS_SMALL then
|
||||
return true
|
||||
elseif EdgeA.dLength < EdgeB.dLength - 10 * GEO.EPS_SMALL then
|
||||
elseif EdgeA.vtN:getZ() < EdgeB.vtN:getZ() - 10 * GEO.EPS_SMALL then
|
||||
return false
|
||||
-- se stessa lunghezza si preferiscono i lati più in basso
|
||||
-- TODO qui dipenderà dalla lama scelta
|
||||
-- se stessa Z si preferiscono i lati verso il fronte della trave
|
||||
else
|
||||
if EdgeA.vtN:getZ() > EdgeB.vtN:getZ() + 10 * GEO.EPS_SMALL then
|
||||
if EdgeA.vtN:getY() > EdgeB.vtN:getY() + 10 * GEO.EPS_SMALL then
|
||||
return true
|
||||
elseif EdgeA.vtN:getZ() < EdgeB.vtN:getZ() - 10 * GEO.EPS_SMALL then
|
||||
elseif EdgeA.vtN:getY() < EdgeB.vtN:getY() - 10 * GEO.EPS_SMALL then
|
||||
return false
|
||||
-- se stessa Z si preferiscono i lati verso il fronte della trave
|
||||
else
|
||||
if EdgeA.vtN:getY() > EdgeB.vtN:getY() + 10 * GEO.EPS_SMALL then
|
||||
return true
|
||||
elseif EdgeA.vtN:getY() < EdgeB.vtN:getY() - 10 * GEO.EPS_SMALL then
|
||||
return false
|
||||
else
|
||||
return false
|
||||
end
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function GetLongEdgeToMachine( Face, bHeadType)
|
||||
local Edge = {}
|
||||
|
||||
local EdgesSorted = {}
|
||||
for i = 1, #Face.Edges do
|
||||
table.insert( EdgesSorted, Face.Edges[i])
|
||||
end
|
||||
table.sort( EdgesSorted, CompareEdgesLongestTop)
|
||||
|
||||
-- se il lato migliore è accessibile si sceglie questo, altrimenti il lato opposto; se entrambi non accessibili (faccia chiusa da due lati) la lavorazione non è applicabile
|
||||
Edge = EdgesSorted[1]
|
||||
local EdgeOpposite = BeamLib.FindEdgeBestOrientedAsDirection( Face.Edges, -Edge.vtN)
|
||||
if not EdgeOpposite.bIsOpen then
|
||||
if Edge.bIsOpen then
|
||||
Edge = EdgeOpposite
|
||||
-- entrambi i lati non accessibili: codolo non applicabile
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
return Edge
|
||||
end
|
||||
|
||||
|
||||
local function SortMachiningsBySegment( MachiningA, MachiningB)
|
||||
if MachiningA.nFeatureSegment > MachiningB.nFeatureSegment then
|
||||
return false
|
||||
@@ -104,7 +123,7 @@ local function GetStrategyCompletionPercentage( Machinings)
|
||||
if nWeightsCount ~= 0 and nWeightsCount ~= i then
|
||||
error( 'GetWeightedCompletionPercentage : inconsistent weights')
|
||||
end
|
||||
local dWeightedCompletionPercentage = Machining.dCompletionPercentage / 100 * dWeight
|
||||
local dWeightedCompletionPercentage = ( Machining.dCompletionPercentage or 0) / 100 * dWeight
|
||||
if Machining.bIsApplicable then
|
||||
dCompletionPercentageNumerator = dCompletionPercentageNumerator + dWeightedCompletionPercentage
|
||||
end
|
||||
@@ -117,43 +136,107 @@ local function GetStrategyCompletionPercentage( Machinings)
|
||||
end
|
||||
|
||||
|
||||
local function MakeBottomFace( Proc, Part, BottomFace, EdgeToMachine, Parameters)
|
||||
local Cuttings = {}
|
||||
local Cutting1 = {}
|
||||
local Cutting2 = {}
|
||||
|
||||
-- parametri dal chiamante
|
||||
local bIsSplitFeature = Parameters.bIsSplitFeature
|
||||
local dExtendAfterTail = Parameters.dExtendAfterTail
|
||||
local nToolIndex = Parameters.nToolIndex
|
||||
local dStripWidth = Parameters.dStripWidth
|
||||
local OtherBottomFace = Parameters.OtherBottomFace
|
||||
|
||||
local dDepthToMachine = EdgeToMachine.dElevation / 2 - dStripWidth / 2
|
||||
local OptionalParametersFaceByBlade1 = { dDepthToMachine = dDepthToMachine, bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail, nToolIndex = nToolIndex}
|
||||
local EdgeToMachineOpposite = BeamLib.FindEdgeBestOrientedAsDirection( BottomFace.Edges, -EdgeToMachine.vtN)
|
||||
|
||||
-- primo lato
|
||||
if EdgeToMachineOpposite.bIsOpen then
|
||||
Cutting1 = FaceByBlade.Make( Proc, Part, BottomFace, EdgeToMachine, OptionalParametersFaceByBlade1)
|
||||
end
|
||||
Cutting1.nInternalSortingPriority = 2
|
||||
Cutting1.dResultWeight = 0.3
|
||||
|
||||
-- secondo lato
|
||||
local OptionalParametersFaceByBlade2 = BeamLib.TableCopyDeep( OptionalParametersFaceByBlade1)
|
||||
OptionalParametersFaceByBlade2.OppositeToolDirectionMode = 'Enabled'
|
||||
if EdgeToMachine.bIsOpen then
|
||||
Cutting2 = FaceByBlade.Make( Proc, Part, BottomFace, EdgeToMachine, OptionalParametersFaceByBlade2)
|
||||
end
|
||||
Cutting2.nInternalSortingPriority = 2
|
||||
Cutting2.dResultWeight = 0.3
|
||||
|
||||
-- se uno dei due lati non è riuscito, si estende il più possibile il lato rimasto
|
||||
if not Cutting1.bIsApplicable and Cutting2.bIsApplicable then
|
||||
|
||||
-- se si lavora il lato in comune con l'altra BottomFace significa ci si deve fermare piú indietro
|
||||
if OtherBottomFace and ( EdgeToMachine.idAdjacentFace == OtherBottomFace.id) then
|
||||
dStripWidth = TOOLS[Cutting2.nToolIndex].dThickness + 2 * dStripWidth
|
||||
end
|
||||
dDepthToMachine = min( TOOLS[Cutting2.nToolIndex].dMaxMaterial, EdgeToMachine.dElevation - dStripWidth)
|
||||
OptionalParametersFaceByBlade2.dDepthToMachine = dDepthToMachine
|
||||
|
||||
Cutting2 = FaceByBlade.Make( Proc, Part, BottomFace, EdgeToMachine, OptionalParametersFaceByBlade2)
|
||||
Cutting2.nInternalSortingPriority = 2
|
||||
Cutting2.dResultWeight = 0.3
|
||||
table.insert( Cuttings, Cutting2)
|
||||
|
||||
elseif not Cutting2.bIsApplicable and Cutting1.bIsApplicable then
|
||||
|
||||
-- se si lavora il lato in comune con l'altra BottomFace significa ci si deve fermare piú indietro
|
||||
if OtherBottomFace and ( EdgeToMachine.idAdjacentFace == OtherBottomFace.id) then
|
||||
dStripWidth = TOOLS[Cutting1.nToolIndex].dThickness + 2 * dStripWidth
|
||||
end
|
||||
dDepthToMachine = min( TOOLS[Cutting1.nToolIndex].dMaxMaterial, EdgeToMachine.dElevation - dStripWidth)
|
||||
OptionalParametersFaceByBlade1.dDepthToMachine = dDepthToMachine
|
||||
|
||||
Cutting1 = FaceByBlade.Make( Proc, Part, BottomFace, EdgeToMachine, OptionalParametersFaceByBlade1)
|
||||
Cutting1.nInternalSortingPriority = 2
|
||||
Cutting1.dResultWeight = 0.3
|
||||
table.insert( Cuttings, Cutting1)
|
||||
|
||||
else
|
||||
table.insert( Cuttings, Cutting1)
|
||||
table.insert( Cuttings, Cutting2)
|
||||
end
|
||||
|
||||
return Cuttings
|
||||
end
|
||||
|
||||
|
||||
function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters)
|
||||
-- TODO verificare funzionamento con lama da sotto
|
||||
-- attenzione perchè se l'inclinazione della faccia la fa finire oltre lo spigolo questo riduce il massimo (come calcolare????)
|
||||
-- il FindBlade dovrà restituire di utilizzare sempre la lama sopra se l'angolo lo permette, ma avendo un'altezza massima (da macchina) oltre cui il DownUp non sarà fattibile (evita collisioni tra asse e pezzo)
|
||||
-- TODO scelta utensile è corretto lasciarla a FaceByBlade?
|
||||
-- TODO aggiungere accorciamento se angolo < 90
|
||||
|
||||
local Result = {}
|
||||
local Machinings = {}
|
||||
local CalculatedMachinings = {}
|
||||
local Cutting1 = {}
|
||||
local Cutting2 = {}
|
||||
|
||||
-- controlli preventivi
|
||||
if Proc.nFct > 3 then
|
||||
error( 'BladeKeepWaste : max 3 faces supported')
|
||||
if Proc.nFct > 3 and Proc.Topology.sFamily ~= 'DoubleBevel' then
|
||||
Result = FeatureLib.GetStrategyResultNotApplicable( 'BladeKeepWaste : max 3 faces supported')
|
||||
return Machinings, Result
|
||||
elseif Proc.nFct == 2 then
|
||||
-- per angolo tra le facce >= 90deg (feature convessa) non applicabile
|
||||
if Proc.AdjacencyMatrix[1][2] > 10 * GEO.EPS_SMALL or Proc.AdjacencyMatrix[1][2] < -91 then
|
||||
Result = FeatureLib.GetStrategyResultNotApplicable( 'BladeKeepWaste : angle between faces must be concave and >= 90deg')
|
||||
return Machinings, Result
|
||||
end
|
||||
-- Rabbet lungo X non gestito
|
||||
if Proc.Topology.sName == 'Rabbet-2-Through' and Proc.AffectedFaces.bLeft and Proc.AffectedFaces.bRight then
|
||||
Result = FeatureLib.GetStrategyResultNotApplicable( 'BladeKeepWaste : Rabbet along X not managed')
|
||||
Result = FeatureLib.GetStrategyResultNotApplicable()
|
||||
return Machinings, Result
|
||||
end
|
||||
elseif Proc.nFct == 3 then
|
||||
-- caso speciale RidgeLap - per angolo tra le facce >= 90deg (feature convessa) non applicabile
|
||||
if Proc.AdjacencyMatrix[1][2] > 10 * GEO.EPS_SMALL or Proc.AdjacencyMatrix[1][2] < -91 then
|
||||
Result = FeatureLib.GetStrategyResultNotApplicable( 'BladeKeepWaste : angle between faces must be concave and >= 90deg')
|
||||
Result = FeatureLib.GetStrategyResultNotApplicable()
|
||||
return Machinings, Result
|
||||
end
|
||||
if Proc.AdjacencyMatrix[1][3] > 10 * GEO.EPS_SMALL or Proc.AdjacencyMatrix[1][3] < -91 then
|
||||
Result = FeatureLib.GetStrategyResultNotApplicable( 'BladeKeepWaste : angle between faces must be concave and >= 90deg')
|
||||
Result = FeatureLib.GetStrategyResultNotApplicable()
|
||||
return Machinings, Result
|
||||
end
|
||||
if Proc.AdjacencyMatrix[2][3] > 10 * GEO.EPS_SMALL or Proc.AdjacencyMatrix[2][3] < -91 then
|
||||
Result = FeatureLib.GetStrategyResultNotApplicable( 'BladeKeepWaste : angle between faces must be concave and >= 90deg')
|
||||
Result = FeatureLib.GetStrategyResultNotApplicable()
|
||||
return Machinings, Result
|
||||
end
|
||||
end
|
||||
@@ -164,39 +247,34 @@ function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters)
|
||||
end
|
||||
local nToolIndex = OptionalParameters.nToolIndex
|
||||
local dExtendAfterTail = OptionalParameters.dExtendAfterTail or 10000
|
||||
local bFinishWithMill
|
||||
if OptionalParameters.bFinishWithMill == nil then
|
||||
bFinishWithMill = true
|
||||
else
|
||||
bFinishWithMill = OptionalParameters.bFinishWithMill
|
||||
end
|
||||
local bFinishWithMill = ( OptionalParameters.bFinishWithMill ~= false)
|
||||
local dMillingOffsetFromSide = OptionalParameters.dMillingOffsetFromSide or 1
|
||||
local dStripWidth = OptionalParameters.dStripWidth or 5
|
||||
local bForced = OptionalParameters.bForced or false
|
||||
|
||||
-- volume della feature
|
||||
local dFeatureVolume = FeatureLib.GetFeatureVolume( Proc, Part)
|
||||
local dFeatureVolume = Proc.dVolume
|
||||
|
||||
-- si trovano le facce da lavorare
|
||||
local BottomFace = {}
|
||||
local LongFaces = {}
|
||||
-- si trovano le facce da lavorare (solo 4 lati esatti)
|
||||
local BottomFace1
|
||||
local BottomFace2
|
||||
if Proc.nFct == 1 then
|
||||
BottomFace = Proc.Faces[1]
|
||||
BottomFace1 = Proc.Faces[1]
|
||||
else
|
||||
if not Proc.MainFaces then
|
||||
Proc.MainFaces = FaceData.GetMainFaces( Proc, Part)
|
||||
end
|
||||
BottomFace = Proc.MainFaces.BottomFaces[1]
|
||||
LongFaces = Proc.MainFaces.LongFaces
|
||||
BottomFace1 = Proc.MainFaces.BottomFaces[1]
|
||||
BottomFace2 = Proc.MainFaces.BottomFaces[2]
|
||||
end
|
||||
|
||||
|
||||
-- si trova il lato della faccia di fondo da lavorare
|
||||
local BottomEdgeToMachine = {}
|
||||
local BottomEdgesSorted = {}
|
||||
for i = 1, #BottomFace.Edges do
|
||||
table.insert( BottomEdgesSorted, BottomFace.Edges[i])
|
||||
if #BottomFace1.Edges ~= 4 then
|
||||
Result = FeatureLib.GetStrategyResultNotApplicable()
|
||||
return Machinings, Result
|
||||
end
|
||||
local bConvexAngle
|
||||
if BottomFace2 then
|
||||
bConvexAngle = ( Proc.AdjacencyMatrix[BottomFace1.id + 1][BottomFace2.id + 1]) > 0
|
||||
end
|
||||
table.sort( BottomEdgesSorted, CompareEdges)
|
||||
BottomEdgeToMachine = BottomEdgesSorted[1]
|
||||
|
||||
-- eventuali punti di spezzatura
|
||||
local FeatureSplittingPoints = FeatureLib.GetFeatureSplittingPoints( Proc, Part)
|
||||
@@ -205,44 +283,129 @@ function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters)
|
||||
bIsSplitFeature = true
|
||||
end
|
||||
|
||||
-- calcolo lavorazioni
|
||||
-- taglio eventuali facce di chiusura
|
||||
for i = 1, #LongFaces do
|
||||
local Cutting = {}
|
||||
local OptionalParametersFaceByBlade = { bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = 9999, nToolIndex = nToolIndex}
|
||||
Cutting = FaceByBlade.Make( Proc, Part, LongFaces[i], LongFaces[i].MainEdges.BottomEdge, OptionalParametersFaceByBlade)
|
||||
Cutting.nInternalSortingPriority = 1
|
||||
Cutting.dResultWeight = 0.15
|
||||
table.insert( CalculatedMachinings, Cutting)
|
||||
-- calcolo lavorazioni faccia principale
|
||||
-- ricerca lato da lavorare
|
||||
local BottomEdgeToMachine1 = GetLongEdgeToMachine( BottomFace1, { bTop = true})
|
||||
if not BottomEdgeToMachine1 then
|
||||
Result = FeatureLib.GetStrategyResultNotApplicable()
|
||||
return Machinings, Result
|
||||
end
|
||||
-- calcolo lavorazione
|
||||
local Parameters1 = {
|
||||
bIsSplitFeature = bIsSplitFeature,
|
||||
dExtendAfterTail = dExtendAfterTail,
|
||||
nToolIndex = nToolIndex,
|
||||
dStripWidth = dStripWidth,
|
||||
OtherBottomFace = BottomFace2
|
||||
}
|
||||
local Cuttings1 = MakeBottomFace( Proc, Part, BottomFace1, BottomEdgeToMachine1, Parameters1)
|
||||
-- aggiunta lavorazioni alla lista principale
|
||||
for i = 1, #Cuttings1 do
|
||||
table.insert( CalculatedMachinings, Cuttings1[i])
|
||||
end
|
||||
|
||||
-- taglio con codolo faccia di fondo
|
||||
local dDepthToMachine = BottomEdgeToMachine.dElevation - OptionalParameters.dStripWidth
|
||||
local OptionalParametersFaceByBlade = { dDepthToMachine = dDepthToMachine, bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail, nToolIndex = nToolIndex}
|
||||
-- primo lato
|
||||
Cutting1 = FaceByBlade.Make( Proc, Part, BottomFace, BottomEdgeToMachine, OptionalParametersFaceByBlade)
|
||||
Cutting1.nInternalSortingPriority = 3
|
||||
Cutting1.dResultWeight = 0.3
|
||||
table.insert( CalculatedMachinings, Cutting1)
|
||||
-- secondo lato
|
||||
OptionalParametersFaceByBlade.OppositeToolDirectionMode = 'Enabled'
|
||||
Cutting2 = FaceByBlade.Make( Proc, Part, BottomFace, BottomEdgeToMachine, OptionalParametersFaceByBlade)
|
||||
Cutting2.nInternalSortingPriority = 3
|
||||
Cutting2.dResultWeight = 0.3
|
||||
--table.insert( CalculatedMachinings, Cutting2)
|
||||
|
||||
-- fresatura eventuali facce di chiusura
|
||||
-- calcolo lavorazioni faccia secondaria, solo se lato convesso; se concavo, sarà lavorato come antisplint
|
||||
local Cuttings2
|
||||
local BottomEdgeToMachine2
|
||||
if BottomFace2 then
|
||||
if bConvexAngle then
|
||||
-- ricerca lato da lavorare
|
||||
BottomEdgeToMachine2 = GetLongEdgeToMachine( BottomFace2, { bTop = true})
|
||||
if BottomEdgeToMachine2 then
|
||||
-- calcolo lavorazione
|
||||
local Parameters2 = BeamLib.TableCopyDeep( Parameters1)
|
||||
Parameters2.OtherBottomFace = BottomFace1
|
||||
Cuttings2 = MakeBottomFace( Proc, Part, BottomFace2, BottomEdgeToMachine2, Parameters2)
|
||||
for i = 1, #Cuttings2 do
|
||||
table.insert( CalculatedMachinings, Cuttings2[i])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- antischeggia sulle facce di chiusura delle facce lavorate
|
||||
local OptionalParametersAntiSplint = {
|
||||
bIsSplitFeature = bIsSplitFeature,
|
||||
dExtendAfterTail = dExtendAfterTail,
|
||||
nInternalSortingPriority = 1,
|
||||
dResultWeight = 0.15,
|
||||
bMachineAllClosedEdges = true
|
||||
}
|
||||
local AntiSplints1 = AntiSplintOnFace.Make( Proc, Part, BottomFace1, OptionalParametersAntiSplint)
|
||||
for i = 1, #AntiSplints1 do
|
||||
table.insert( CalculatedMachinings, AntiSplints1[i])
|
||||
end
|
||||
if BottomFace2 and bConvexAngle then
|
||||
OptionalParametersAntiSplint.bMachineAllClosedEdges = false
|
||||
local AntiSplints2 = AntiSplintOnFace.Make( Proc, Part, BottomFace2, OptionalParametersAntiSplint)
|
||||
for i = 1, #AntiSplints2 do
|
||||
table.insert( CalculatedMachinings, AntiSplints2[i])
|
||||
end
|
||||
end
|
||||
|
||||
-- pulitura con fresa dei lati chiusi non lavorati
|
||||
-- TODO funzione
|
||||
if bFinishWithMill then
|
||||
for i = 1, #LongFaces do
|
||||
local dDepthToMachineMill = BottomFace.MainEdges.LongEdges[i].dElevation - dMillingOffsetFromSide
|
||||
local dToolMarkLength = max( Cutting1.dToolMarkLength, Cutting2.dToolMarkLength)
|
||||
local OptionalParametersFaceByMill = { bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail,
|
||||
dRadialStepSpan = dToolMarkLength, dDepthToMachine = dDepthToMachineMill
|
||||
}
|
||||
local Milling = FaceByMill.Make( Proc, Part, BottomFace, BottomFace.MainEdges.LongEdges[i], OptionalParametersFaceByMill)
|
||||
Milling.nInternalSortingPriority = 2
|
||||
Milling.dResultWeight = 0.05
|
||||
table.insert( CalculatedMachinings, Milling)
|
||||
|
||||
if Cuttings1 then
|
||||
-- si recuperano i lati chiusi non lavorati
|
||||
local EdgesClosedNotMachined = {}
|
||||
for i = 1, #BottomFace1.Edges do
|
||||
if not( ( BottomFace1.Edges[i].id == BottomEdgeToMachine1.id) or BottomFace1.Edges[i].bIsOpen) then
|
||||
table.insert( EdgesClosedNotMachined, BottomFace1.Edges[i])
|
||||
end
|
||||
end
|
||||
-- su ognuno si fa la fresatura di pulizia
|
||||
for i = 1, #EdgesClosedNotMachined do
|
||||
local dDepthToMachine = EdgesClosedNotMachined[i].dElevation - dMillingOffsetFromSide
|
||||
local dToolMarkLength = 0
|
||||
-- si prende l'impronta dell'utensile più grande
|
||||
for j = 1, #Cuttings1 do
|
||||
if Cuttings1[j].dToolMarkLength > dToolMarkLength + 10 * GEO.EPS_SMALL then
|
||||
dToolMarkLength = Cuttings1[j].dToolMarkLength
|
||||
end
|
||||
end
|
||||
local OptionalParametersMilling = {
|
||||
bIsSplitFeature = bIsSplitFeature,
|
||||
dExtendAfterTail = dExtendAfterTail,
|
||||
dRadialStepSpan = dToolMarkLength,
|
||||
dDepthToMachine = dDepthToMachine
|
||||
}
|
||||
local Milling = FaceByMill.Make( Proc, Part, BottomFace1, EdgesClosedNotMachined[i], OptionalParametersMilling)
|
||||
Milling.nInternalSortingPriority = 3
|
||||
Milling.dResultWeight = 0.05
|
||||
table.insert( CalculatedMachinings, Milling)
|
||||
end
|
||||
end
|
||||
if Cuttings2 and BottomEdgeToMachine2 then
|
||||
-- si recuperano i lati chiusi non lavorati
|
||||
local EdgesClosedNotMachined = {}
|
||||
for i = 1, #BottomFace2.Edges do
|
||||
if not( ( BottomFace2.Edges[i].id == BottomEdgeToMachine2.id) or BottomFace2.Edges[i].bIsOpen) then
|
||||
table.insert( EdgesClosedNotMachined, BottomFace2.Edges[i])
|
||||
end
|
||||
end
|
||||
-- su ognuno si fa la fresatura di pulizia
|
||||
for i = 1, #EdgesClosedNotMachined do
|
||||
local dDepthToMachine = EdgesClosedNotMachined[i].dElevation - dMillingOffsetFromSide
|
||||
local dToolMarkLength = 0
|
||||
-- si prende l'impronta dell'utensile più grande
|
||||
for j = 1, #Cuttings2 do
|
||||
if Cuttings2[j].dToolMarkLength > dToolMarkLength + 10 * GEO.EPS_SMALL then
|
||||
dToolMarkLength = Cuttings2[j].dToolMarkLength
|
||||
end
|
||||
end
|
||||
local OptionalParametersMilling = {
|
||||
bIsSplitFeature = bIsSplitFeature,
|
||||
dExtendAfterTail = dExtendAfterTail,
|
||||
dRadialStepSpan = dToolMarkLength,
|
||||
dDepthToMachine = dDepthToMachine
|
||||
}
|
||||
local Milling = FaceByMill.Make( Proc, Part, BottomFace2, EdgesClosedNotMachined[i], OptionalParametersMilling)
|
||||
Milling.nInternalSortingPriority = 3
|
||||
Milling.dResultWeight = 0.05
|
||||
table.insert( CalculatedMachinings, Milling)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -253,8 +416,10 @@ function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters)
|
||||
end
|
||||
end
|
||||
|
||||
-- calcolo completamento, serve la lista di lavorazioni che comprende le non applicabili
|
||||
Result.dCompletionPercentage = GetStrategyCompletionPercentage( CalculatedMachinings)
|
||||
-- calcolo completamento (non applicabili devono essere incluse)
|
||||
-- se codolo non forzato si ritorna completa max al 94% (completion index 4)
|
||||
local dCalculatedCompletionPercentage = GetStrategyCompletionPercentage( CalculatedMachinings)
|
||||
Result.dCompletionPercentage = bForced and dCalculatedCompletionPercentage or min( 94, dCalculatedCompletionPercentage)
|
||||
Result.dCompletionIndex = FeatureLib.GetFeatureCompletionIndex( Result.dCompletionPercentage)
|
||||
|
||||
-- aggiunta eventuali lavorazioni splittate
|
||||
@@ -266,12 +431,17 @@ function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters)
|
||||
table.sort( Machinings, SortMachiningsBySegment)
|
||||
|
||||
-- calcolo risultati
|
||||
if Cutting1.bIsApplicable or Cutting2.bIsApplicable then
|
||||
if ( Cuttings1 and ( ( Cuttings1[1] and Cuttings1[1].bIsApplicable) or ( Cuttings1[2] and Cuttings1[2].bIsApplicable)))
|
||||
or ( Cuttings2 and ( ( Cuttings2[1] and Cuttings2[1].bIsApplicable) or ( Cuttings2[2] and Cuttings2[2].bIsApplicable))) then
|
||||
|
||||
Result.dQuality = FeatureLib.GetStrategyQuality( Machinings)
|
||||
Result.dTimeToMachine = FeatureLib.GetStrategyTimeToMachine( Machinings)
|
||||
Result.dMRR = ( dFeatureVolume / Result.dTimeToMachine) / pow( 10, 6)
|
||||
if Result.dCompletionPercentage > 100 - 10 * GEO.EPS_SMALL then
|
||||
Result.sStatus = 'Completed'
|
||||
if bForced then
|
||||
Result.sInfo = 'Waste attached. Remove manually.'
|
||||
end
|
||||
else
|
||||
Result.sStatus = 'Not-Completed'
|
||||
end
|
||||
|
||||
+507
-295
File diff suppressed because it is too large
Load Diff
+305
-206
@@ -4,142 +4,90 @@
|
||||
|
||||
-- carico librerie
|
||||
local BeamLib = require( 'BeamLib')
|
||||
local BeamData = require( 'BeamData')
|
||||
local BeamData = require( 'BeamDataNew')
|
||||
local MachiningLib = require( 'MachiningLib')
|
||||
local FaceData = require( 'FaceData')
|
||||
local LeadInOutLib = require( 'LeadInOutLib')
|
||||
|
||||
-- Tabella per definizione modulo
|
||||
local FACEBYBLADE = {}
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function GetLeadInOutType( Machining)
|
||||
local sLeadInOutType = ''
|
||||
-- i parametri si leggono da LeadInOut (engagement) e si modificano solo se necessario
|
||||
local function GetLeadInOut( Machining, EdgeToMachine, bIsSplitFeature)
|
||||
|
||||
if Machining.bIsStartClosed or Machining.bIsEndClosed
|
||||
or Machining.sCutType == 'Guillotine'
|
||||
or Machining.sCutType == 'Reduced' then
|
||||
|
||||
sLeadInOutType = 'Perpendicular'
|
||||
else
|
||||
-- testa sopra
|
||||
if TOOLS[Machining.nToolIndex].SetupInfo.HeadType.bTop then
|
||||
if abs( Machining.vtToolDirection:getX()) < 0.7 then
|
||||
if Machining.vtToolDirection:getZ() > -0.087
|
||||
or ( abs( Machining.vtToolDirection:getX()) < 0.34202 and abs( Machining.vtToolDirection:getZ()) < 0.7) then
|
||||
sLeadInOutType = 'Perpendicular'
|
||||
else
|
||||
sLeadInOutType = 'Tangent'
|
||||
end
|
||||
elseif abs( Machining.vtEdgeDirection:getZ()) > 0.7 then
|
||||
sLeadInOutType = 'Perpendicular'
|
||||
else
|
||||
-- TODO qui attacco tangenziale speciale tutto da un lato
|
||||
sLeadInOutType = 'Tangent'
|
||||
end
|
||||
-- testa sotto
|
||||
elseif TOOLS[Machining.nToolIndex].SetupInfo.HeadType.bBottom then
|
||||
if abs( Machining.vtToolDirection:getX()) < 0.7 then
|
||||
if Machining.vtToolDirection:getZ() < -GEO.EPS_SMALL
|
||||
or ( abs( Machining.vtToolDirection:getX()) < 0.34202 and abs( Machining.vtToolDirection:getZ()) < 0.7) then
|
||||
sLeadInOutType = 'Perpendicular'
|
||||
else
|
||||
sLeadInOutType = 'Tangent'
|
||||
end
|
||||
elseif abs( Machining.vtEdgeDirection:getZ()) > 0.7 then
|
||||
sLeadInOutType = 'Perpendicular'
|
||||
else
|
||||
-- TODO qui attacco tangenziale speciale tutto da un lato
|
||||
sLeadInOutType = 'Tangent'
|
||||
end
|
||||
-- se testa senza preferenza Top e Bottom si fa sempre attacco tangenziale
|
||||
else
|
||||
sLeadInOutType = 'Tangent'
|
||||
end
|
||||
end
|
||||
local LeadIn
|
||||
local LeadOut
|
||||
|
||||
return sLeadInOutType
|
||||
end
|
||||
|
||||
|
||||
local function CalculateLeadInOut( Machining, EdgeToMachine, bIsSplitFeature)
|
||||
-- TODO implementare le funzioni di Tool Collision Avoidance (vedi wiki e FacesBysaw -> CalcLeadInOutPerpGeom)
|
||||
|
||||
-- accorciamento per lati chiusi (è sempre l'impronta utensile)
|
||||
local dToolMarkLength = sqrt( Machining.dDepthToMachine * TOOLS[Machining.nToolIndex].dDiameter - Machining.dDepthToMachine * Machining.dDepthToMachine)
|
||||
-- allungamento per faccia singola (aperta in tutte le direzioni)
|
||||
local dAddedLengthOpenFace = BeamData.CUT_EXTRA
|
||||
if Machining.sCutType == 'Guillotine' then
|
||||
local dGuillotineLengthToMachine = 1
|
||||
dAddedLengthOpenFace = ( - EdgeToMachine.dLength + dGuillotineLengthToMachine) / 2
|
||||
elseif Machining.sCutType == 'Reduced' then
|
||||
dAddedLengthOpenFace = - FACEBYBLADE.GetPathReductionLength( Machining.nToolIndex, Machining.dMaxRadialOffset)
|
||||
end
|
||||
|
||||
if Machining.bInvert then
|
||||
Machining.bIsStartClosed, Machining.bIsEndClosed = Machining.bIsEndClosed, Machining.bIsStartClosed
|
||||
end
|
||||
|
||||
local LeadIn = {}
|
||||
local LeadOut = {}
|
||||
Machining.sLeadInOutType = ''
|
||||
LeadIn.dStartAddLength = 0
|
||||
LeadOut.dEndAddLength = 0
|
||||
LeadIn.nType = MCH_MILL_LI.LINEAR
|
||||
LeadOut.nType = MCH_MILL_LI.LINEAR
|
||||
LeadIn.dPerpDistance = 0
|
||||
LeadOut.dPerpDistance = 0
|
||||
LeadIn.dTangentDistance = 0
|
||||
LeadOut.dTangentDistance = 0
|
||||
-- in certe condizioni si deve forzare attacco perpendicolare
|
||||
if Machining.bIsStartClosed
|
||||
or Machining.bIsEndClosed
|
||||
or Machining.CloneStepsRadial.nCount > 1
|
||||
or Machining.Steps.nCount > 1
|
||||
or bIsSplitFeature then
|
||||
|
||||
Machining.sLeadInOutType = 'Perpendicular'
|
||||
if AreSameVectorApprox( Machining.vtToolDirection, EdgeToMachine.vtN) then
|
||||
LeadIn.dPerpDistance = EdgeToMachine.dElevation + BeamData.CUT_SIC - Machining.dRadialOffset
|
||||
LeadOut.dPerpDistance = EdgeToMachine.dElevation + BeamData.CUT_SIC - Machining.dRadialOffset
|
||||
|
||||
if Machining.LeadInOut.Perpendicular then
|
||||
|
||||
Machining.sLeadInOutType = 'Perpendicular'
|
||||
|
||||
-- se attacco perpendicolare richiesto ma non disponibile, la lavorazione non è fattibile
|
||||
else
|
||||
LeadIn.dPerpDistance = BeamData.CUT_SIC - Machining.dRadialOffset
|
||||
LeadOut.dPerpDistance = BeamData.CUT_SIC - Machining.dRadialOffset
|
||||
|
||||
return
|
||||
end
|
||||
else
|
||||
Machining.sLeadInOutType = GetLeadInOutType( Machining)
|
||||
if Machining.sLeadInOutType == 'Perpendicular' then
|
||||
LeadIn.dPerpDistance = 1
|
||||
LeadOut.dPerpDistance = 1
|
||||
else
|
||||
-- TODO da rimuovere, già inserito in GetLeadInOutType
|
||||
if abs( Machining.vtEdgeDirection:getZ()) > 0.707 then
|
||||
LeadIn.dPerpDistance = 1
|
||||
LeadOut.dPerpDistance = 1
|
||||
else
|
||||
LeadIn.dTangentDistance = TOOLS[Machining.nToolIndex].dDiameter / 2 + BeamData.CUT_SIC
|
||||
LeadOut.dTangentDistance = TOOLS[Machining.nToolIndex].dDiameter / 2 + BeamData.CUT_SIC
|
||||
end
|
||||
end
|
||||
|
||||
Machining.sLeadInOutType = Machining.LeadInOut.sChosen
|
||||
end
|
||||
LeadIn.dElevation = 0
|
||||
LeadOut.dElevation = 0
|
||||
LeadIn.dCompLength = 0
|
||||
LeadOut.dCompLength = 0
|
||||
if Machining.bIsStartClosed and Machining.bIsEndClosed then
|
||||
LeadIn.dStartAddLength = -dToolMarkLength
|
||||
LeadOut.dEndAddLength = -dToolMarkLength
|
||||
elseif Machining.bIsStartClosed then
|
||||
LeadIn.dStartAddLength = -dToolMarkLength
|
||||
-- eventuale correzione per accorciamento maggiore di larghezza tasca
|
||||
LeadOut.dEndAddLength = max( -LeadIn.dStartAddLength - EdgeToMachine.dLength + 10 * BeamData.CUT_EXTRA, BeamData.CUT_EXTRA)
|
||||
elseif Machining.bIsEndClosed then
|
||||
LeadOut.dEndAddLength = -dToolMarkLength
|
||||
-- eventuale correzione per accorciamento maggiore di larghezza tasca
|
||||
LeadIn.dStartAddLength = max( -LeadOut.dEndAddLength - EdgeToMachine.dLength + 10 * BeamData.CUT_EXTRA, BeamData.CUT_EXTRA)
|
||||
else
|
||||
LeadIn.dStartAddLength = dAddedLengthOpenFace
|
||||
LeadOut.dEndAddLength = dAddedLengthOpenFace
|
||||
|
||||
-- si prendono i valori che arrivano da LeadInOut (engagement)
|
||||
LeadIn = BeamLib.TableCopyDeep( Machining.LeadInOut[Machining.sLeadInOutType].LeadIn)
|
||||
LeadOut = BeamLib.TableCopyDeep( Machining.LeadInOut[Machining.sLeadInOutType].LeadOut)
|
||||
|
||||
-- se senso di percorrenza invertito si invertono anche gli attacchi
|
||||
if Machining.bInvert then
|
||||
Machining.bIsStartClosed, Machining.bIsEndClosed = Machining.bIsEndClosed, Machining.bIsStartClosed
|
||||
LeadIn, LeadOut = LeadInOutLib.InvertLeadInOut( LeadIn, LeadOut)
|
||||
end
|
||||
|
||||
-- in caso di percorso ridotto gli attacchi vanno adeguati
|
||||
if Machining.sEdgeUsage == 'Guillotine' then
|
||||
local dGuillotineLengthToMachine = 1
|
||||
LeadIn.dStartAddLength = ( - EdgeToMachine.dLength + dGuillotineLengthToMachine) / 2
|
||||
LeadOut.dEndAddLength = ( - EdgeToMachine.dLength + dGuillotineLengthToMachine) / 2
|
||||
LeadIn.dPerpDistance = EdgeToMachine.dElevation + BeamData.CUT_SIC - Machining.dRadialOffset
|
||||
LeadIn.dTangentDistance = 0
|
||||
LeadOut.dPerpDistance = EdgeToMachine.dElevation + BeamData.CUT_SIC - Machining.dRadialOffset
|
||||
LeadOut.dTangentDistance = 0
|
||||
LeadIn.dTotalLength = sqrt( LeadIn.dPerpDistance ^ 2 + LeadIn.dTangentDistance ^ 2)
|
||||
LeadOut.dTotalLength = sqrt( LeadOut.dPerpDistance ^ 2 + LeadOut.dTangentDistance ^ 2)
|
||||
elseif Machining.sEdgeUsage == 'Reduced' then
|
||||
LeadIn.dStartAddLength = - FACEBYBLADE.GetPathReductionLength( Machining.nToolIndex, Machining.dMaxRadialOffset)
|
||||
LeadOut.dEndAddLength = - FACEBYBLADE.GetPathReductionLength( Machining.nToolIndex, Machining.dMaxRadialOffset)
|
||||
LeadIn.dPerpDistance = EdgeToMachine.dElevation + BeamData.CUT_SIC - Machining.dRadialOffset
|
||||
LeadIn.dTangentDistance = 0
|
||||
LeadOut.dPerpDistance = EdgeToMachine.dElevation + BeamData.CUT_SIC - Machining.dRadialOffset
|
||||
LeadOut.dTangentDistance = 0
|
||||
LeadIn.dTotalLength = sqrt( LeadIn.dPerpDistance ^ 2 + LeadIn.dTangentDistance ^ 2)
|
||||
LeadOut.dTotalLength = sqrt( LeadOut.dPerpDistance ^ 2 + LeadOut.dTangentDistance ^ 2)
|
||||
end
|
||||
|
||||
-- se accorciamenti maggiori della lunghezza lato, la lavorazione non è fattibile
|
||||
if LeadIn.dStartAddLength + LeadOut.dEndAddLength + EdgeToMachine.dLength < 1 then
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
-- se lavorazione con OppositeToolDirection o ridotta l'attacco va corretto
|
||||
if not AreSameVectorApprox( Machining.vtToolDirection, EdgeToMachine.vtN) then
|
||||
LeadIn.dPerpDistance = BeamData.CUT_SIC - Machining.dRadialOffset
|
||||
LeadOut.dPerpDistance = BeamData.CUT_SIC - Machining.dRadialOffset
|
||||
LeadIn.dTangentDistance = 0
|
||||
LeadOut.dTangentDistance = 0
|
||||
end
|
||||
|
||||
-- stima lunghezza reale attacchi per calcolo lunghezza lavorata
|
||||
-- TODO sistemare per nuovi attacchi
|
||||
local dEstimatedLeadInPerpDistance = 0
|
||||
local dEstimatedLeadInTangentDistance = 0
|
||||
local dEstimatedLeadOutPerpDistance = 0
|
||||
@@ -163,8 +111,8 @@ local function CalculateLeadInOut( Machining, EdgeToMachine, bIsSplitFeature)
|
||||
end
|
||||
|
||||
|
||||
-- TODO implementare SCC in funzione macchina
|
||||
local function GetSCC( vtMachiningDirection, vtEdgeDirection, vtNFace)
|
||||
-- TODO da eliminare, sostituita da funzione macchina
|
||||
function FACEBYBLADE.GetSCC( vtMachiningDirection, vtEdgeDirection, vtNFace)
|
||||
local nSCC = MCH_SCC.NONE
|
||||
|
||||
if abs( vtMachiningDirection:getX()) > abs( vtMachiningDirection:getY()) - GEO.EPS_SMALL then
|
||||
@@ -259,60 +207,86 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
|
||||
dLongitudinalOffset = 0
|
||||
end
|
||||
local dRadialStepSpan = OptionalParameters.dRadialStepSpan
|
||||
local dMinNzDownUp = OptionalParameters.dMinNzDownUp
|
||||
local sUserNotes = OptionalParameters.sUserNotes or ''
|
||||
local bIsDicing = OptionalParameters.bIsDicing or false
|
||||
local idCheckCollisionTm = OptionalParameters.idCheckCollisionTm
|
||||
local sRestLengthSideForPreSimulation = OptionalParameters.sRestLengthSideForPreSimulation or 'Tail'
|
||||
local bCannotSplitRestLength = OptionalParameters.bCannotSplitRestLength or false
|
||||
local bDisableRealElevationCheck = OptionalParameters.bDisableRealElevationCheck or false
|
||||
|
||||
-- lunghezze, direzioni e punti caratteristici della lavorazione e del lato lavorato
|
||||
Cutting.dEdgeLength = EdgeToMachine.dLength
|
||||
if OppositeToolDirectionMode == 'Enabled' then
|
||||
Cutting.vtToolDirection = -EdgeToMachine.vtN
|
||||
else
|
||||
Cutting.vtToolDirection = EdgeToMachine.vtN
|
||||
end
|
||||
Cutting.vtEdgeDirection = EdgeToMachine.vtN ^ FaceToMachine.vtN
|
||||
-- TODO conviene spostare questi calcoli nel FaceData?
|
||||
Cutting.ptEdge1, _, Cutting.ptEdge2 = EgtSurfTmFacetOppositeSide( Proc.id, FaceToMachine.id, -Cutting.vtToolDirection, GDB_ID.ROOT)
|
||||
-- TODO gestire lama da sotto
|
||||
-- se si conosce il limite downUp (utensile forzato o downUp forzato) si decide se invertire (ToolInvert)
|
||||
-- TODO esiste un limite downUp massimo per la lama da sopra??
|
||||
if nToolIndex and not dMinNzDownUp then
|
||||
dMinNzDownUp = TOOLS[nToolIndex].SetupInfo.GetMinNzDownUp( Part.b3Raw, FaceToMachine.vtN, Cutting.vtToolDirection, TOOLS[nToolIndex])
|
||||
end
|
||||
if dMinNzDownUp and FaceToMachine.vtN:getZ() < dMinNzDownUp then
|
||||
Cutting.bToolInvert = true
|
||||
else
|
||||
Cutting.bToolInvert = false
|
||||
end
|
||||
-- TODO questa deve essere ptEnd - ptStart
|
||||
Cutting.vtEdgeDirection = Vector3d( EdgeToMachine.vtEdge)
|
||||
Cutting.vtToolDirection = EdgeToMachine.vtN
|
||||
Cutting.ptEdge1, Cutting.ptEdge2 = EdgeToMachine.ptStart, EdgeToMachine.ptEnd
|
||||
local EdgeToMachineOpposite = BeamLib.FindEdgeBestOrientedAsDirection( FaceToMachine.Edges, -EdgeToMachine.vtN)
|
||||
|
||||
-- ricerca utensile
|
||||
-- l'utensile arriva da fuori: si determina se il taglio è fattibile e il modo di lavorare della lama
|
||||
if nToolIndex then
|
||||
|
||||
Cutting.nToolIndex = nToolIndex
|
||||
local BladeEngagementParameters = {
|
||||
Face = FaceToMachine,
|
||||
Edge = EdgeToMachine,
|
||||
Part = Part,
|
||||
Tool = TOOLS[Cutting.nToolIndex],
|
||||
dDepthToMachine = dDepthToMachine
|
||||
}
|
||||
if OppositeToolDirectionMode == 'Enabled' then
|
||||
BladeEngagementParameters.Edge = EdgeToMachineOpposite
|
||||
end
|
||||
local BladeEngagementOptionalParameters = {
|
||||
bIsDicing = bIsDicing,
|
||||
idCheckCollisionTm = idCheckCollisionTm,
|
||||
sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation,
|
||||
bCannotSplitRestLength = bCannotSplitRestLength,
|
||||
bDisableRealElevationCheck = bDisableRealElevationCheck
|
||||
}
|
||||
local Engagement
|
||||
TIMER:startElapsed( 'GetBladeEngagement')
|
||||
Cutting.bIsApplicable, Engagement = MachiningLib.GetBladeEngagement( BladeEngagementParameters, BladeEngagementOptionalParameters)
|
||||
TIMER:stopElapsed( 'GetBladeEngagement')
|
||||
if Cutting.bIsApplicable then
|
||||
Cutting.sBladeEngagement = Engagement.sBladeEngagement
|
||||
Cutting.bMoveAfterSplit = Engagement.bMoveAfterSplit
|
||||
Cutting.LeadInOut = Engagement.LeadInOut
|
||||
end
|
||||
|
||||
-- utensile da cercare: si prende la lama migliore che può effettuare questo taglio, senza particolari analisi
|
||||
else
|
||||
local ToolSearchParameters = {}
|
||||
ToolSearchParameters.dElevation = dDepthToMachine
|
||||
if Cutting.bToolInvert then
|
||||
ToolSearchParameters.vtN = -FaceToMachine.vtN
|
||||
else
|
||||
ToolSearchParameters.vtN = FaceToMachine.vtN
|
||||
end
|
||||
ToolSearchParameters.bAllowTopHead = true
|
||||
-- TODO bisognerà implementare anche la lama da sotto
|
||||
ToolSearchParameters.bAllowBottomHead = false
|
||||
ToolSearchParameters.bAllowBottomHead = true
|
||||
ToolSearchParameters.bForceLongcutBlade = bForceLongcutBlade
|
||||
ToolSearchParameters.FaceToMachine = FaceToMachine
|
||||
ToolSearchParameters.EdgeToMachine = EdgeToMachine
|
||||
ToolSearchParameters.Part = Part
|
||||
ToolSearchParameters.sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation
|
||||
ToolSearchParameters.bCannotSplitRestLength = bCannotSplitRestLength
|
||||
ToolSearchParameters.bDisableRealElevationCheck = bDisableRealElevationCheck
|
||||
|
||||
local ToolInfo = MachiningLib.FindBlade( Proc, ToolSearchParameters)
|
||||
-- ora che l'utensile è scelto, se non era definito l'angolo di DownUp lo verifico per decidere se invertire
|
||||
if ToolInfo.nToolIndex and not dMinNzDownUp then
|
||||
dMinNzDownUp = TOOLS[ToolInfo.nToolIndex].SetupInfo.GetMinNzDownUp( Part.b3Raw, FaceToMachine.vtN, Cutting.vtToolDirection, TOOLS[ToolInfo.nToolIndex])
|
||||
if FaceToMachine.vtN:getZ() < dMinNzDownUp then
|
||||
Cutting.bToolInvert = true
|
||||
end
|
||||
end
|
||||
Cutting.nToolIndex = ToolInfo.nToolIndex
|
||||
if Cutting.nToolIndex then
|
||||
Cutting.sBladeEngagement = ToolInfo.Engagement.sBladeEngagement
|
||||
Cutting.bMoveAfterSplit = ToolInfo.Engagement.bMoveAfterSplit
|
||||
Cutting.LeadInOut = ToolInfo.Engagement.LeadInOut
|
||||
end
|
||||
|
||||
-- se non trovato utensile, la lavorazione non è applicabile
|
||||
if not Cutting.nToolIndex then
|
||||
Cutting.bIsApplicable = false
|
||||
end
|
||||
end
|
||||
if not TOOLS[Cutting.nToolIndex] or not TOOLS[Cutting.nToolIndex].sName then
|
||||
|
||||
-- orientamento non raggiungibile o lama non trovata: non applicabile
|
||||
if not Cutting.bIsApplicable then
|
||||
Cutting.sMessage = 'Blade not found'
|
||||
Cutting.bIsApplicable = false
|
||||
EgtOutLog( Cutting.sMessage)
|
||||
|
||||
return Cutting, EdgeToMachine.dElevation
|
||||
end
|
||||
|
||||
@@ -322,25 +296,32 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
|
||||
Cutting.sMessage = 'Pocket too narrow for blade thickness'
|
||||
Cutting.bIsApplicable = false
|
||||
EgtOutLog( Cutting.sMessage)
|
||||
|
||||
return Cutting, EdgeToMachine.dElevation
|
||||
end
|
||||
|
||||
-- TODO vedere se la rimozione di questo crea problemi
|
||||
-- se tasca chiusa da entrambi i lati e più stretta della lama la lavorazione non è applicabile
|
||||
if not ( EdgeToMachine.bIsStartOpen or EdgeToMachine.bIsEndOpen) then
|
||||
if TOOLS[Cutting.nToolIndex].dDiameter > EdgeToMachine.dLength + 10 * GEO.EPS_SMALL then
|
||||
Cutting.sMessage = 'Pocket too narrow for blade diameter'
|
||||
Cutting.bIsApplicable = false
|
||||
EgtOutLog( Cutting.sMessage)
|
||||
return Cutting, EdgeToMachine.dElevation
|
||||
end
|
||||
end
|
||||
-- if not ( EdgeToMachine.bIsStartOpen or EdgeToMachine.bIsEndOpen) then
|
||||
-- if TOOLS[Cutting.nToolIndex].dDiameter > EdgeToMachine.dLength + 10 * GEO.EPS_SMALL then
|
||||
-- Cutting.sMessage = 'Pocket too narrow for blade diameter'
|
||||
-- Cutting.bIsApplicable = false
|
||||
-- EgtOutLog( Cutting.sMessage)
|
||||
|
||||
-- return Cutting, EdgeToMachine.dElevation
|
||||
-- end
|
||||
-- end
|
||||
|
||||
-- parametri della lavorazione
|
||||
|
||||
-- profondità (parametro DEPTH)
|
||||
Cutting.sDepth = sDepth
|
||||
Cutting.sDepth = sDepth
|
||||
|
||||
-- inizio e fine aperti o chiusi
|
||||
Cutting.bIsStartClosed = not EdgeToMachine.bIsStartOpen
|
||||
Cutting.bIsEndClosed = not EdgeToMachine.bIsEndOpen
|
||||
-- lato di lavoro e inversione per avere taglio concorde
|
||||
Cutting.bIsStartClosed = not EdgeToMachine.bIsStartOpen
|
||||
Cutting.bIsEndClosed = not EdgeToMachine.bIsEndOpen
|
||||
|
||||
-- si settano lato di lavoro e inversione per avere concordanza
|
||||
if TOOLS[Cutting.nToolIndex].bIsCCW then
|
||||
Cutting.nWorkside = MCH_MILL_WS.RIGHT
|
||||
Cutting.bInvert = true
|
||||
@@ -348,37 +329,96 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
|
||||
Cutting.nWorkside = MCH_MILL_WS.LEFT
|
||||
Cutting.bInvert = false
|
||||
end
|
||||
-- se OppositeToolDirectionMode è Optimized, se possibile e necessario, si attiva per garantire taglio concorde e verso l'alto (massima qualità)
|
||||
if ( OppositeToolDirectionMode == 'Optimized') and ( Proc.nFct == 1) and ( FaceData.IsFaceRhomboid( Proc, FaceToMachine.id)) then
|
||||
OppositeToolDirectionMode = 'Disabled'
|
||||
-- la direzione di percorrenza del lato deve essere verso l'alto; bInvert va considerata perchè inverte la direzione di percorrenza.
|
||||
if ( Cutting.bInvert and Cutting.vtEdgeDirection:getZ() > 100 * GEO.EPS_SMALL)
|
||||
or ( ( not Cutting.bInvert) and Cutting.vtEdgeDirection:getZ() < -100 * GEO.EPS_SMALL) then
|
||||
|
||||
-- si attiva OppositeToolDirection solo se non cambiano le condizioni di taglio downUp
|
||||
local dNewMinNzDownUp = TOOLS[nToolIndex].SetupInfo.GetMinNzDownUp( Part.b3Raw, FaceToMachine.vtN, -Cutting.vtToolDirection, TOOLS[nToolIndex])
|
||||
if ( FaceToMachine.vtN:getZ() < dMinNzDownUp) == ( FaceToMachine.vtN:getZ() < dNewMinNzDownUp) then
|
||||
OppositeToolDirectionMode = 'Enabled'
|
||||
Cutting.vtToolDirection = -EdgeToMachine.vtN
|
||||
Cutting.ptEdge1, _, Cutting.ptEdge2 = EgtSurfTmFacetOppositeSide( Proc.id, FaceToMachine.id, -Cutting.vtToolDirection, GDB_ID.ROOT)
|
||||
Cutting.bInvert = not Cutting.bInvert
|
||||
-- se le condizioni downUp cambiano, si setta per tagliare verso l'alto
|
||||
else
|
||||
if Cutting.nWorkside == MCH_MILL_WS.RIGHT then
|
||||
Cutting.nWorkside = MCH_MILL_WS.LEFT
|
||||
Cutting.bInvert = false
|
||||
else
|
||||
Cutting.nWorkside = MCH_MILL_WS.RIGHT
|
||||
Cutting.bInvert = true
|
||||
end
|
||||
-- ToolInvert
|
||||
if Cutting.sBladeEngagement == 'DownUp' then
|
||||
Cutting.bToolInvert = true
|
||||
Cutting.bInvert = not Cutting.bInvert
|
||||
end
|
||||
|
||||
-- se dicing, lato di lavoro e inversione per avere taglio sempre verso l'alto
|
||||
if bIsDicing
|
||||
and ( Cutting.bInvert and Cutting.vtEdgeDirection:getZ() > 100 * GEO.EPS_SMALL)
|
||||
or ( ( not Cutting.bInvert) and Cutting.vtEdgeDirection:getZ() < -100 * GEO.EPS_SMALL) then
|
||||
|
||||
Cutting.bInvert = not Cutting.bInvert
|
||||
if Cutting.nWorkside == MCH_MILL_WS.LEFT then
|
||||
Cutting.nWorkside = MCH_MILL_WS.RIGHT
|
||||
else
|
||||
Cutting.nWorkside = MCH_MILL_WS.LEFT
|
||||
end
|
||||
end
|
||||
|
||||
-- analisi fattibilità lavorazione dal lato opposto
|
||||
if OppositeToolDirectionMode ~= 'Disabled' then
|
||||
|
||||
-- lavorando dalla direzione opposta si verifica come se si lavorasse il lato opposto
|
||||
local BladeEngagementParameters = {
|
||||
Face = FaceToMachine,
|
||||
Edge = EdgeToMachineOpposite,
|
||||
Part = Part,
|
||||
Tool = TOOLS[Cutting.nToolIndex],
|
||||
dDepthToMachine = dDepthToMachine
|
||||
}
|
||||
local BladeEngagementOptionalParameters = {
|
||||
bIsDicing = bIsDicing,
|
||||
idCheckCollisionTm = idCheckCollisionTm,
|
||||
sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation,
|
||||
bCannotSplitRestLength = bCannotSplitRestLength,
|
||||
bDisableRealElevationCheck = bDisableRealElevationCheck
|
||||
}
|
||||
TIMER:startElapsed( 'GetBladeEngagement')
|
||||
local bIsApplicableOpposite, EngagementOpposite = MachiningLib.GetBladeEngagement( BladeEngagementParameters, BladeEngagementOptionalParameters)
|
||||
TIMER:stopElapsed( 'GetBladeEngagement')
|
||||
|
||||
-- taglio opposto non fattibile
|
||||
if not bIsApplicableOpposite then
|
||||
-- se richiesto, si ritorna non applicabile
|
||||
if OppositeToolDirectionMode == 'Enabled' then
|
||||
|
||||
Cutting.sMessage = 'Orientation not reachable'
|
||||
Cutting.bIsApplicable = false
|
||||
|
||||
return Cutting, EdgeToMachine.dElevation
|
||||
|
||||
-- se opzionale, si disabilita
|
||||
elseif OppositeToolDirectionMode == 'Optimized' then
|
||||
OppositeToolDirectionMode = 'Disabled'
|
||||
end
|
||||
end
|
||||
|
||||
-- se OppositeToolDirectionMode è Optimized, se possibile e necessario, si attiva la lavorazione dal lato opposto per garantire taglio concorde e verso l'alto (massima qualità)
|
||||
if ( OppositeToolDirectionMode == 'Optimized') and ( Proc.nFct == 1) and ( FaceData.IsFaceRectangle( FaceToMachine)) then
|
||||
|
||||
OppositeToolDirectionMode = 'Disabled'
|
||||
|
||||
-- la direzione di percorrenza del lato deve essere verso l'alto; bInvert va considerata perchè inverte la direzione di percorrenza
|
||||
-- il BladeEngagement non deve cambiare, altrimenti è inutile invertire la direzione
|
||||
if ( EngagementOpposite.sBladeEngagement == Cutting.sBladeEngagement)
|
||||
and ( EngagementOpposite.bMoveAfterSplit == Cutting.bMoveAfterSplit)
|
||||
and ( Cutting.bInvert and Cutting.vtEdgeDirection:getZ() > 100 * GEO.EPS_SMALL)
|
||||
or ( ( not Cutting.bInvert) and Cutting.vtEdgeDirection:getZ() < -100 * GEO.EPS_SMALL) then
|
||||
|
||||
OppositeToolDirectionMode = 'Enabled'
|
||||
end
|
||||
end
|
||||
|
||||
if OppositeToolDirectionMode == 'Enabled' then
|
||||
Cutting.vtToolDirection = EdgeToMachineOpposite.vtN
|
||||
Cutting.ptEdge1, Cutting.ptEdge2 = EdgeToMachineOpposite.ptStart, EdgeToMachineOpposite.ptEnd
|
||||
Cutting.bInvert = not Cutting.bInvert
|
||||
-- TODO da migliorare!!!!!!!!!
|
||||
if not EngagementOpposite.LeadInOut.Perpendicular then
|
||||
Cutting.LeadInOut.Perpendicular = nil
|
||||
end
|
||||
if not EngagementOpposite.LeadInOut.Tangent then
|
||||
Cutting.LeadInOut.Tangent = nil
|
||||
end
|
||||
end
|
||||
elseif OppositeToolDirectionMode == 'Enabled' then
|
||||
Cutting.bInvert = not Cutting.bInvert
|
||||
end
|
||||
if Cutting.bToolInvert then
|
||||
Cutting.bInvert = not Cutting.bInvert
|
||||
end
|
||||
|
||||
-- TODO implementare lavorazione in DownUp se non è già DownUp e non si è riusciti a mantenere verso l'alto e concorde (testare solo DownUp))
|
||||
|
||||
-- profondità da lavorare e offset radiale
|
||||
if OptionalParameters.dPocketHeight then
|
||||
if TOOLS[Cutting.nToolIndex].dMaxDepth > dDepthToMachine - 10 * GEO.EPS_SMALL then
|
||||
@@ -402,36 +442,74 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
|
||||
else
|
||||
Cutting.dDepthToMachine = dDepthToMachine
|
||||
Cutting.dResidualDepth = 0
|
||||
Cutting.sCutType = 'Standard'
|
||||
Cutting.sEdgeUsage = 'Standard'
|
||||
if bReduceBladePath
|
||||
and ( Proc.nFct == 1)
|
||||
and FaceData.IsFaceRectangular( Proc, FaceToMachine.id) then
|
||||
and FaceData.IsFaceRectangle( FaceToMachine) then
|
||||
|
||||
local bIsTopBlade = TOOLS[nToolIndex].SetupInfo.HeadType.bTop
|
||||
Cutting.dMaxRadialOffset = TOOLS[nToolIndex].dMaxMaterial - Cutting.dDepthToMachine - BeamData.CUT_SIC
|
||||
Cutting.dRadialOffsetGuillotine = FACEBYBLADE.GetRadialOffsetForGuillotine( nToolIndex, EdgeToMachine.dLength)
|
||||
-- TODO la lama sotto deve poter ridurre. Ghigliottina sì o no?
|
||||
local bIsTopBlade = TOOLS[Cutting.nToolIndex].SetupInfo.HeadType.bTop
|
||||
Cutting.dMaxRadialOffset = TOOLS[Cutting.nToolIndex].dMaxMaterial - Cutting.dDepthToMachine - BeamData.CUT_SIC
|
||||
Cutting.dRadialOffsetGuillotine = FACEBYBLADE.GetRadialOffsetForGuillotine( Cutting.nToolIndex, EdgeToMachine.dLength)
|
||||
if Cutting.dMaxRadialOffset > 10 * GEO.EPS_SMALL then
|
||||
-- taglio a ghigliottina
|
||||
if bIsTopBlade and ( Cutting.dRadialOffsetGuillotine < Cutting.dMaxRadialOffset - 10 * GEO.EPS_SMALL) then
|
||||
|
||||
dDepthToMachine = Cutting.dDepthToMachine + Cutting.dRadialOffsetGuillotine
|
||||
Cutting.sCutType = 'Guillotine'
|
||||
Cutting.sEdgeUsage = 'Guillotine'
|
||||
|
||||
-- taglio ridotto
|
||||
else
|
||||
dDepthToMachine = Cutting.dDepthToMachine + Cutting.dMaxRadialOffset
|
||||
Cutting.sCutType = 'Reduced'
|
||||
Cutting.sEdgeUsage = 'Reduced'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- se cambiata la profondità dDepthToMachine, si ritesta la fattibilità del taglio
|
||||
if Cutting.sEdgeUsage ~= 'Standard' then
|
||||
local EdgeToMachineForEngagement = EdgeToMachine
|
||||
if OppositeToolDirectionMode == 'Enabled' then
|
||||
EdgeToMachineForEngagement = EdgeToMachineOpposite
|
||||
end
|
||||
local BladeEngagementParameters = {
|
||||
Face = FaceToMachine,
|
||||
Edge = EdgeToMachineForEngagement,
|
||||
Part = Part,
|
||||
Tool = TOOLS[Cutting.nToolIndex],
|
||||
dDepthToMachine = dDepthToMachine
|
||||
}
|
||||
local BladeEngagementOptionalParameters = {
|
||||
bIsDicing = bIsDicing,
|
||||
idCheckCollisionTm = idCheckCollisionTm,
|
||||
sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation,
|
||||
bCannotSplitRestLength = bCannotSplitRestLength,
|
||||
bDisableRealElevationCheck = bDisableRealElevationCheck
|
||||
}
|
||||
TIMER:startElapsed( 'GetBladeEngagement')
|
||||
local bIsApplicable, CurrentEngagement = MachiningLib.GetBladeEngagement( BladeEngagementParameters, BladeEngagementOptionalParameters )
|
||||
TIMER:stopElapsed( 'GetBladeEngagement')
|
||||
|
||||
-- se non fattibile o cambiano le condizioni BladeEngagement, non si riduce
|
||||
if not ( bIsApplicable and ( CurrentEngagement.sBladeEngagement == Cutting.sBladeEngagement) and ( CurrentEngagement.bMoveAfterSplit == Cutting.bMoveAfterSplit)) then
|
||||
Cutting.sEdgeUsage = 'Standard'
|
||||
dDepthToMachine = Cutting.dDepthToMachine
|
||||
end
|
||||
end
|
||||
|
||||
-- offset radiale (cambia se taglio opposto)
|
||||
if OppositeToolDirectionMode == 'Enabled' then
|
||||
Cutting.dRadialOffset = -dDepthToMachine
|
||||
else
|
||||
Cutting.dRadialOffset = EdgeToMachine.dElevation - dDepthToMachine
|
||||
end
|
||||
end
|
||||
|
||||
-- completamento
|
||||
Cutting.dCompletionPercentage = ( 1 - Cutting.dResidualDepth / Cutting.dDepthToMachine) * 100
|
||||
|
||||
-- step verticale e offset longitudinale
|
||||
Cutting.Steps = MachiningLib.GetMachiningSteps( dPocketHeight, TOOLS[Cutting.nToolIndex].dThickness)
|
||||
Cutting.Steps = MachiningLib.GetMachiningSteps( true, dPocketHeight, TOOLS[Cutting.nToolIndex].dThickness)
|
||||
Cutting.Steps.nStepType = MCH_MILL_ST.ONEWAY
|
||||
Cutting.dMaxElev = Cutting.Steps.dStep * Cutting.Steps.nCount - 10 * GEO.EPS_SMALL
|
||||
if Cutting.bToolInvert then
|
||||
@@ -443,10 +521,13 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
|
||||
else
|
||||
Cutting.dLongitudinalOffset = dLongitudinalOffset
|
||||
end
|
||||
|
||||
-- distanza di sicurezza
|
||||
Cutting.dStartSafetyLength = BeamData.CUT_SIC
|
||||
|
||||
-- overlap
|
||||
Cutting.dOverlap = 0
|
||||
|
||||
-- EdgeUse e frame lavorazione
|
||||
if OppositeToolDirectionMode == 'Enabled' then
|
||||
Cutting.nFaceuse = BeamLib.GetNearestOrthoOpposite( -Cutting.vtToolDirection)
|
||||
@@ -457,23 +538,37 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
|
||||
--Cutting.vtFaceUse = Cutting.vtToolDirection
|
||||
Cutting.nEdgesFaceUse = EdgeToMachine.id
|
||||
end
|
||||
|
||||
-- SCC
|
||||
Cutting.nSCC = GetSCC( Cutting.vtToolDirection, Cutting.vtEdgeDirection, FaceToMachine.vtN)
|
||||
Cutting.nSCC = TOOLS[Cutting.nToolIndex].SetupInfo.GetSCC( Cutting.vtToolDirection, Cutting.vtEdgeDirection, FaceToMachine.vtN)
|
||||
|
||||
-- asse bloccato
|
||||
Cutting.sBlockedAxis = BeamLib.GetBlockedAxis( Cutting.nToolIndex, 'perpendicular', Part.b3Raw, FaceToMachine.vtN, EgtIf( FaceToMachine.vtN:getX() > 0, X_AX(), -X_AX()))
|
||||
|
||||
-- eventuale step orizzontale
|
||||
Cutting.CloneStepsRadial = {}
|
||||
if not dRadialStepSpan then
|
||||
dRadialStepSpan = Cutting.dDepthToMachine
|
||||
end
|
||||
if dRadialStepSpan > 10 * GEO.EPS_SMALL and TOOLS[Cutting.nToolIndex].dSideStep then
|
||||
Cutting.CloneStepsRadial = MachiningLib.GetMachiningSteps( dRadialStepSpan, TOOLS[Cutting.nToolIndex].dSideStep)
|
||||
Cutting.CloneStepsRadial = MachiningLib.GetMachiningSteps( true, dRadialStepSpan, TOOLS[Cutting.nToolIndex].dSideStep)
|
||||
else
|
||||
Cutting.CloneStepsRadial.nCount = 1
|
||||
Cutting.CloneStepsRadial.dStep = Cutting.dDepthToMachine
|
||||
end
|
||||
|
||||
-- approccio e retrazione
|
||||
Cutting.LeadIn, Cutting.LeadOut = CalculateLeadInOut( Cutting, EdgeToMachine, bIsSplitFeature)
|
||||
Cutting.LeadIn, Cutting.LeadOut = GetLeadInOut( Cutting, EdgeToMachine, bIsSplitFeature)
|
||||
-- se il calcolo attacchi fallisce, la lavorazione non è fattibile
|
||||
if not Cutting.LeadIn or not Cutting.LeadOut then
|
||||
|
||||
Cutting.bIsApplicable = false
|
||||
return Cutting
|
||||
end
|
||||
|
||||
-- solo per debug
|
||||
--Cutting.nOutRaw = 3
|
||||
|
||||
-- lunghezza lavorata
|
||||
-- TODO per il calcolo del dLengthOnX si deve correggere con allungamento / accorciamento percorso
|
||||
Cutting.dLengthToMachine = EdgeToMachine.dLength + Cutting.LeadIn.dStartAddLength + Cutting.LeadOut.dEndAddLength
|
||||
@@ -481,6 +576,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
|
||||
Cutting.dLengthOnX = b3BoxEdge:getDimX()
|
||||
Cutting.dTimeToMachine, Cutting.dLengthToMachineAllStepsWithLeadInOut = MachiningLib.GetTimeToMachineAllStepsWithLeadInOut( Cutting, Part)
|
||||
-- lunghezza impronta lama
|
||||
-- TODO rimpiazzare con LeadInOut.dToolMarkLength
|
||||
if Cutting.bIsStartClosed and Cutting.bIsEndClosed then
|
||||
Cutting.dToolMarkLength = abs( min( Cutting.LeadIn.dStartAddLength, Cutting.LeadOut.dEndAddLength))
|
||||
elseif Cutting.bIsStartClosed then
|
||||
@@ -499,8 +595,9 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
|
||||
|
||||
-- se lavorazione aperta sulla coda, eventuali aggiustamenti
|
||||
-- TODO valutare se fare funzione a parte
|
||||
local bIsTruncatingCutOnTail = Proc.Topology and ( Proc.Topology.sName == 'Cut-1-Through' or Proc.Topology.sName == 'TailCut') and Proc.AffectedFaces.bLeft
|
||||
if bIsTruncatingCutOnTail then
|
||||
Cutting.bMoveAfterSplit = Cutting.bMoveAfterSplit or Cutting.LeadIn.bMoveAfterSplit or Cutting.LeadOut.bMoveAfterSplit
|
||||
local bIsTruncatingCutOnTail = Proc.Topology and ( Proc.Topology.sName == 'Cut-1-Through' or Proc.Topology.sName == 'TailCut') and Proc.AffectedFaces.bLeft
|
||||
if Cutting.bMoveAfterSplit or bIsTruncatingCutOnTail then
|
||||
Cutting.sStage = 'AfterTail'
|
||||
elseif Proc.AffectedFaces.bLeft and ( EdgeToMachine.sType == 'Bottom' or ( Cutting.vtToolDirection:getX() < 0.707)) then
|
||||
local dLengthOnX = Cutting.dLengthOnX
|
||||
@@ -517,12 +614,14 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
|
||||
if not AreSameOrOppositeVectorApprox( EdgeToMachine.vtN, Y_AX()) then
|
||||
if MachiningLib.CanMoveAfterSplitcut( dLengthOnX, Part) then
|
||||
Cutting.sStage = 'AfterTail'
|
||||
Cutting.bMoveAfterSplit = true
|
||||
else
|
||||
Cutting.bIsApplicable = false
|
||||
end
|
||||
elseif dAddLengthLeftSide + dAddLengthToReduce > dExtendAfterTail then
|
||||
if MachiningLib.CanMoveAfterSplitcut( dLengthOnX, Part) then
|
||||
Cutting.sStage = 'AfterTail'
|
||||
Cutting.bMoveAfterSplit = true
|
||||
else
|
||||
if bStartLeft then
|
||||
Cutting.LeadIn.dStartAddLength = - dAddLengthToReduce + dExtendAfterTail
|
||||
|
||||
@@ -4,8 +4,9 @@
|
||||
|
||||
-- carico librerie
|
||||
local BeamLib = require( 'BeamLib')
|
||||
local BeamData = require( 'BeamData')
|
||||
local BeamData = require( 'BeamDataNew')
|
||||
local MachiningLib = require( 'MachiningLib')
|
||||
local PreSimulationLib = require( 'PreSimulationLib')
|
||||
|
||||
-- Tabella per definizione modulo
|
||||
local FACEBYCHAINSAW = {}
|
||||
@@ -42,6 +43,11 @@ local function CalculateLeadInOut( Machining, EdgeToMachine, sSideToMachine, dLe
|
||||
LeadOut.dEndAddLength = BeamData.CUT_EXTRA
|
||||
end
|
||||
|
||||
-- punti dell'attacco
|
||||
local dLengthToAdd = EgtIf( Machining.bToolInvert, -Machining.dStartSafetyLength, EdgeToMachine.dElevation - ( Machining.dMaxElev or 0) + Machining.dStartSafetyLength)
|
||||
LeadIn.ptPoint = EdgeToMachine.ptStart - EdgeToMachine.vtEdge * LeadIn.dStartAddLength + EdgeToMachine.vtN * dLengthToAdd
|
||||
LeadOut.ptPoint = EdgeToMachine.ptEnd + EdgeToMachine.vtEdge * LeadOut.dEndAddLength + EdgeToMachine.vtN * dLengthToAdd
|
||||
|
||||
return LeadIn, LeadOut
|
||||
end
|
||||
|
||||
@@ -75,15 +81,32 @@ function FACEBYCHAINSAW.Make( Proc, Part, FaceToMachine, EdgeToMachine, Optional
|
||||
local sDepth = OptionalParameters.sDepth or 'TH'
|
||||
local dLongitudinalStepSpan = OptionalParameters.dLongitudinalStepSpan
|
||||
|
||||
-- lunghezze e punti caratteristici della lavorazione e del lato lavorato
|
||||
-- lunghezze, direzioni e punti caratteristici della lavorazione e del lato lavorato
|
||||
Mortising.dEdgeLength = EdgeToMachine.dLength
|
||||
if OppositeToolDirectionMode == 'Enabled' then
|
||||
Mortising.vtToolDirection = -EdgeToMachine.vtN
|
||||
else
|
||||
Mortising.vtToolDirection = EdgeToMachine.vtN
|
||||
local dCalculatedMaxElev = FaceToMachine.Edges[EdgeToMachine.nPreviousEdgeIndex].dLength
|
||||
if FaceToMachine.Edges[EdgeToMachine.nNextEdgeIndex].dLength > FaceToMachine.Edges[EdgeToMachine.nPreviousEdgeIndex].dLength + 10 * GEO.EPS_SMALL then
|
||||
dCalculatedMaxElev = FaceToMachine.Edges[EdgeToMachine.nNextEdgeIndex].dLength
|
||||
end
|
||||
Mortising.vtEdgeDirection = EdgeToMachine.vtN ^ FaceToMachine.vtN
|
||||
Mortising.ptEdge1, _, Mortising.ptEdge2 = EgtSurfTmFacetOppositeSide( Proc.id, FaceToMachine.id, -Mortising.vtToolDirection, GDB_ID.ROOT)
|
||||
-- la direzione di lavoro è calcolata in accordo con la direzione calcolata dal Cam5
|
||||
-- fine chiusa
|
||||
if EdgeToMachine.bIsStartOpen and not EdgeToMachine.bIsEndOpen then
|
||||
Mortising.vtToolDirection = FaceToMachine.Edges[EdgeToMachine.nNextEdgeIndex].vtEdge
|
||||
-- inizio chiuso
|
||||
elseif EdgeToMachine.bIsEndOpen and not EdgeToMachine.bIsStartOpen then
|
||||
Mortising.vtToolDirection = -FaceToMachine.Edges[EdgeToMachine.nPreviousEdgeIndex].vtEdge
|
||||
-- entrambi aperti o entrambi chiusi
|
||||
else
|
||||
local vtTemp = ( FaceToMachine.Edges[EdgeToMachine.nNextEdgeIndex].vtEdge - FaceToMachine.Edges[EdgeToMachine.nPreviousEdgeIndex].vtEdge) * 0.5
|
||||
vtTemp:normalize()
|
||||
Mortising.vtToolDirection = vtTemp
|
||||
end
|
||||
if OppositeToolDirectionMode == 'Enabled' then
|
||||
Mortising.vtToolDirection = -Mortising.vtToolDirection
|
||||
else
|
||||
Mortising.vtToolDirection = Mortising.vtToolDirection
|
||||
end
|
||||
Mortising.vtEdgeDirection = Vector3d( EdgeToMachine.vtEdge)
|
||||
Mortising.ptEdge1, Mortising.ptEdge2 = EdgeToMachine.ptStart, EdgeToMachine.ptEnd
|
||||
|
||||
-- ricerca utensile
|
||||
local ToolSearchParameters = {}
|
||||
@@ -164,11 +187,13 @@ function FACEBYCHAINSAW.Make( Proc, Part, FaceToMachine, EdgeToMachine, Optional
|
||||
-- massima elevazione
|
||||
if dCustomMaxElev < Mortising.dDepthToMachine - 10 * GEO.EPS_SMALL then
|
||||
Mortising.dMaxElev = max( dCustomMaxElev, dCustomMaxElev - Mortising.dLongitudinalOffset)
|
||||
else
|
||||
Mortising.dMaxElev = dCalculatedMaxElev
|
||||
end
|
||||
-- offset radiale
|
||||
Mortising.dRadialOffset = 0
|
||||
-- distanza di sicurezza
|
||||
Mortising.dStartSafetyLength = max( EdgeToMachine.dElevation, ( TOOLS[Mortising.nToolIndex].SetupInfo.dZSafeDelta or 60) + EgtMdbGetGeneralParam( MCH_GP.SAFEZ))
|
||||
Mortising.dStartSafetyLength = ( TOOLS[Mortising.nToolIndex].SetupInfo.dZSafeDelta or 0) + EgtMdbGetGeneralParam( MCH_GP.SAFEZ)
|
||||
-- overlap
|
||||
Mortising.dOverlap = 0
|
||||
-- step
|
||||
@@ -189,29 +214,44 @@ function FACEBYCHAINSAW.Make( Proc, Part, FaceToMachine, EdgeToMachine, Optional
|
||||
-- SCC
|
||||
Mortising.SCC = MCH_SCC.NONE
|
||||
-- asse bloccato e angoli suggeriti
|
||||
local vtRes = FaceToMachine.vtN ^ EdgeToMachine.vtN
|
||||
if abs( vtRes:getZ()) < 10 * GEO.EPS_SMALL then
|
||||
Mortising.sBlockedAxis = BeamLib.GetBlockedAxis( Mortising.nToolIndex, 'perpendicular', Part.b3Raw, FaceToMachine.vtN)
|
||||
Mortising.sSuggestedAngles = BeamLib.GetChainSawInitAngs( FaceToMachine.vtN, EdgeToMachine.vtN, 1)
|
||||
elseif EdgeToMachine.vtN:getZ() < 10 * GEO.EPS_SMALL then
|
||||
Mortising.sBlockedAxis = BeamLib.GetBlockedAxis( Mortising.nToolIndex, 'parallel', Part.b3Raw, FaceToMachine.vtN)
|
||||
Mortising.sSuggestedAngles = BeamLib.GetChainSawInitAngs( FaceToMachine.vtN, EdgeToMachine.vtN, 2)
|
||||
end
|
||||
Mortising.sBlockedAxis = BeamLib.GetBlockedAxis( Mortising.nToolIndex, 'perpendicular', Part.b3Raw, FaceToMachine.vtN)
|
||||
Mortising.sInitialAngles = BeamLib.GetChainSawInitAngs( FaceToMachine.vtN, Mortising.vtToolDirection, 1)
|
||||
-- approccio e retrazione
|
||||
Mortising.LeadIn, Mortising.LeadOut = CalculateLeadInOut( Mortising, EdgeToMachine, sSideToMachine, dLengthToMachine)
|
||||
-- check finecorsa nei punti di attacco
|
||||
local PointsOnToolTipCenter = {
|
||||
Mortising.LeadIn.ptPoint,
|
||||
Mortising.LeadOut.ptPoint
|
||||
}
|
||||
local vtAux = FaceToMachine.vtN
|
||||
if Mortising.bToolInvert then
|
||||
vtAux = -FaceToMachine.vtN
|
||||
end
|
||||
local bOutOfStroke = PreSimulationLib.CheckOutOfStrokeFromPoints( PointsOnToolTipCenter, Mortising.vtToolDirection, Mortising.nSCC, TOOLS[Mortising.nToolIndex], vtAux, Mortising.sBlockedAxis)
|
||||
-- se finecorsa si prova a bloccare l'altro asse
|
||||
if bOutOfStroke then
|
||||
Mortising.sBlockedAxis = BeamLib.GetBlockedAxis( Mortising.nToolIndex, 'parallel', Part.b3Raw, FaceToMachine.vtN)
|
||||
Mortising.sInitialAngles = BeamLib.GetChainSawInitAngs( FaceToMachine.vtN, Mortising.vtToolDirection, 2)
|
||||
bOutOfStroke = PreSimulationLib.CheckOutOfStrokeFromPoints( PointsOnToolTipCenter, Mortising.vtToolDirection, Mortising.nSCC, TOOLS[Mortising.nToolIndex], vtAux, Mortising.sBlockedAxis)
|
||||
if bOutOfStroke then
|
||||
Mortising.sMessage = 'Out of stroke'
|
||||
Mortising.bIsApplicable = false
|
||||
return Mortising
|
||||
end
|
||||
end
|
||||
-- eventuale step verticale
|
||||
Mortising.CloneStepsLongitudinal = {}
|
||||
if not dLongitudinalStepSpan then
|
||||
dLongitudinalStepSpan = dPocketHeight
|
||||
end
|
||||
if dLongitudinalStepSpan > 10 * GEO.EPS_SMALL then
|
||||
Mortising.CloneStepsLongitudinal = MachiningLib.GetMachiningSteps( dLongitudinalStepSpan, TOOLS[Mortising.nToolIndex].dThickness)
|
||||
Mortising.CloneStepsLongitudinal = MachiningLib.GetMachiningSteps( true, dLongitudinalStepSpan, TOOLS[Mortising.nToolIndex].dThickness)
|
||||
else
|
||||
Mortising.CloneStepsLongitudinal.nCount = 1
|
||||
Mortising.CloneStepsLongitudinal.dStep = dPocketHeight
|
||||
end
|
||||
-- lunghezza lavorata
|
||||
-- TODO per il calcolo della dLenghtOnX ripetere il calcolo del FACEBYBLADE con proiezione del lato; serve prolungare con la Add Length secondo la vtEdgeDirection
|
||||
-- TODO per il calcolo della dlengthOnX ripetere il calcolo del FACEBYBLADE con proiezione del lato; serve prolungare con la Add Length secondo la vtEdgeDirection
|
||||
-- TODO fare funzione EstimatePathLength o simile
|
||||
Mortising.dLengthToMachine = Mortising.dEdgeLength + Mortising.LeadIn.dStartAddLength + Mortising.LeadOut.dEndAddLength
|
||||
Mortising.dLengthOnX = abs( dLengthToMachine * EdgeToMachine.vtN:getY())
|
||||
|
||||
+25
-12
@@ -4,8 +4,9 @@
|
||||
|
||||
-- carico librerie
|
||||
local BeamLib = require( 'BeamLib')
|
||||
local BeamData = require( 'BeamData')
|
||||
local BeamData = require( 'BeamDataNew')
|
||||
local MachiningLib = require( 'MachiningLib')
|
||||
local PreSimulationLib = require('PreSimulationLib')
|
||||
|
||||
-- Tabella per definizione modulo
|
||||
local FACEBYMILL = {}
|
||||
@@ -119,6 +120,10 @@ local function CalculateLeadInOut( Machining, EdgeToMachine, bIsSplitFeature)
|
||||
LeadIn.dStartAddLength = BeamData.CUT_EXTRA
|
||||
LeadOut.dEndAddLength = BeamData.CUT_EXTRA
|
||||
end
|
||||
-- punti dell'attacco
|
||||
LeadIn.ptPoint = EdgeToMachine.ptStart - EdgeToMachine.vtEdge * ( LeadIn.dStartAddLength + LeadIn.dTangentDistance) + EdgeToMachine.vtN * ( EdgeToMachine.dElevation - Machining.dDepthToMachine + LeadIn.dPerpDistance)
|
||||
LeadOut.ptPoint = EdgeToMachine.ptEnd + EdgeToMachine.vtEdge * ( LeadOut.dEndAddLength + LeadOut.dTangentDistance) + EdgeToMachine.vtN * ( EdgeToMachine.dElevation - Machining.dDepthToMachine + LeadOut.dPerpDistance)
|
||||
|
||||
-- stima lunghezza reale attacchi per calcolo lunghezza lavorata
|
||||
local dEstimatedLeadInPerpDistance = 0
|
||||
local dEstimatedLeadInTangentDistance = 0
|
||||
@@ -203,9 +208,8 @@ function FACEBYMILL.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPara
|
||||
else
|
||||
Milling.vtToolDirection = EdgeToMachine.vtN
|
||||
end
|
||||
Milling.vtEdgeDirection = EdgeToMachine.vtN ^ FaceToMachine.vtN
|
||||
-- TODO conviene spostare questi calcoli nel FaceData?
|
||||
Milling.ptEdge1, _, Milling.ptEdge2 = EgtSurfTmFacetOppositeSide( Proc.id, FaceToMachine.id, -Milling.vtToolDirection, GDB_ID.ROOT)
|
||||
Milling.vtEdgeDirection = Vector3d( EdgeToMachine.vtEdge)
|
||||
Milling.ptEdge1, Milling.ptEdge2 = EdgeToMachine.ptStart, EdgeToMachine.ptEnd
|
||||
|
||||
-- se si conosce il limite downUp (utensile forzato o downUp forzato) si decide se invertire (ToolInvert)
|
||||
if nToolIndex and not dMinNzDownUp then
|
||||
@@ -251,7 +255,7 @@ function FACEBYMILL.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPara
|
||||
Milling.sMessage = 'Mill not found'
|
||||
Milling.bIsApplicable = false
|
||||
EgtOutLog( Milling.sMessage)
|
||||
return Milling, EdgeToMachine.dElevation
|
||||
return Milling
|
||||
end
|
||||
|
||||
-- verifica dimensioni tasca compatibili
|
||||
@@ -260,7 +264,7 @@ function FACEBYMILL.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPara
|
||||
Milling.sMessage = 'Pocket too narrow for blade thickness'
|
||||
Milling.bIsApplicable = false
|
||||
EgtOutLog( Milling.sMessage)
|
||||
return Milling, EdgeToMachine.dElevation
|
||||
return Milling
|
||||
end
|
||||
-- se tasca chiusa da entrambi i lati e più stretta della fresa la lavorazione non è applicabile
|
||||
if not ( EdgeToMachine.bIsStartOpen or EdgeToMachine.bIsEndOpen) then
|
||||
@@ -268,7 +272,7 @@ function FACEBYMILL.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPara
|
||||
Milling.sMessage = 'Pocket too narrow for blade diameter'
|
||||
Milling.bIsApplicable = false
|
||||
EgtOutLog( Milling.sMessage)
|
||||
return Milling, EdgeToMachine.dElevation
|
||||
return Milling
|
||||
end
|
||||
end
|
||||
|
||||
@@ -325,13 +329,11 @@ function FACEBYMILL.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPara
|
||||
Milling.dCompletionPercentage = ( 1 - Milling.dResidualDepth / Milling.dDepthToMachine) * 100
|
||||
-- step verticale e offset longitudinale
|
||||
if OptionalParameters.dPocketHeight then
|
||||
Milling.Steps = MachiningLib.GetMachiningSteps( dPocketHeight, TOOLS[Milling.nToolIndex].dMaxMaterial)
|
||||
Milling.Steps = MachiningLib.GetMachiningSteps( true, dPocketHeight, TOOLS[Milling.nToolIndex].dMaxMaterial)
|
||||
Milling.Steps.nStepType = OptionalParameters.nStepType or MCH_MILL_ST.ONEWAY
|
||||
Milling.dMaxElev = Milling.Steps.dStep * Milling.Steps.nCount - 10 * GEO.EPS_SMALL
|
||||
else
|
||||
Milling.Steps = {}
|
||||
Milling.Steps.dStep = TOOLS[Milling.nToolIndex].dStep
|
||||
Milling.Steps.nCount = ceil( ( FaceToMachine.dElevation - 50 * GEO.EPS_SMALL) / Milling.Steps.dStep)
|
||||
Milling.Steps = MachiningLib.GetMachiningSteps( false, FaceToMachine.dElevation, TOOLS[Milling.nToolIndex].dStep)
|
||||
Milling.Steps.nStepType = OptionalParameters.nStepType or MCH_MILL_ST.ZIGZAG
|
||||
Milling.dMaxElev = FaceToMachine.dElevation
|
||||
end
|
||||
@@ -368,13 +370,24 @@ function FACEBYMILL.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPara
|
||||
dRadialStepSpan = Milling.dDepthToMachine
|
||||
end
|
||||
if dRadialStepSpan > 10 * GEO.EPS_SMALL and TOOLS[Milling.nToolIndex].dSideStep then
|
||||
Milling.CloneStepsRadial = MachiningLib.GetMachiningSteps( dRadialStepSpan, TOOLS[Milling.nToolIndex].dSideStep)
|
||||
Milling.CloneStepsRadial = MachiningLib.GetMachiningSteps( true, dRadialStepSpan, TOOLS[Milling.nToolIndex].dSideStep)
|
||||
else
|
||||
Milling.CloneStepsRadial.nCount = 1
|
||||
Milling.CloneStepsRadial.dStep = 0
|
||||
end
|
||||
-- approccio e retrazione
|
||||
Milling.LeadIn, Milling.LeadOut = CalculateLeadInOut( Milling, EdgeToMachine, bIsSplitFeature)
|
||||
-- check finecorsa nei punti di attacco
|
||||
PointsOnToolTipCenter = {
|
||||
PreSimulationLib.GetPointOnToolTipCenter( Milling.LeadIn.ptPoint, FaceToMachine.vtN, FaceToMachine.vtN, EdgeToMachine.vtN, TOOLS[Milling.nToolIndex]),
|
||||
PreSimulationLib.GetPointOnToolTipCenter( Milling.LeadOut.ptPoint, FaceToMachine.vtN, FaceToMachine.vtN, EdgeToMachine.vtN, TOOLS[Milling.nToolIndex])
|
||||
}
|
||||
local bOutOfStroke = PreSimulationLib.CheckOutOfStrokeFromPoints( PointsOnToolTipCenter, FaceToMachine.vtN, Milling.nSCC, TOOLS[Milling.nToolIndex])
|
||||
if bOutOfStroke then
|
||||
Milling.sMessage = 'Out of stroke'
|
||||
Milling.bIsApplicable = false
|
||||
return Milling
|
||||
end
|
||||
-- lunghezza lavorata
|
||||
-- TODO per il calcolo del dLengthOnX si deve correggere con allungamento / accorciamento percorso
|
||||
Milling.dLengthToMachine = EdgeToMachine.dLength + Milling.LeadIn.dStartAddLength + Milling.LeadOut.dEndAddLength
|
||||
|
||||
@@ -9,6 +9,7 @@ require( 'EgtBase')
|
||||
|
||||
-- Carico i dati globali
|
||||
local FeatureLib = require( 'FeatureLib')
|
||||
local BeamLib = require( 'BeamLib')
|
||||
-- strategie di base
|
||||
local BladeToWaste = require('BLADETOWASTE')
|
||||
|
||||
@@ -31,7 +32,13 @@ function SPLITCUT.GetMachining( Proc, Part, ParametersFromStrategy)
|
||||
else
|
||||
-- Blade
|
||||
Machining, Result = BladeToWaste.Make( Proc, Part, ParametersFromStrategy)
|
||||
if Machining and #Machining > 0 then
|
||||
-- se taglio non riuscito, si riprova con il riduci percorso forzato (collisione possibile in separazione pezzi alti)
|
||||
if ( not Machining) or ( #Machining == 0) then
|
||||
local NewParametersFromStrategy = BeamLib.TableCopyDeep( ParametersFromStrategy)
|
||||
NewParametersFromStrategy.bReduceBladePath = true
|
||||
Machining, Result = BladeToWaste.Make( Proc, Part, NewParametersFromStrategy)
|
||||
end
|
||||
if Machining and ( #Machining > 0) then
|
||||
Machining.sTypeMachining = 'Blade'
|
||||
end
|
||||
-- TODO : casi con motosega da completare
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
==== Beam Update Log ====
|
||||
|
||||
Versione 2.6-- (--/--/2024)
|
||||
- Primo commit creazione nuovo automatismo BEAM con strategie
|
||||
Versione 3.1e1 (29/05/2026)
|
||||
- Primo commit nuovo automatismo a strategie
|
||||
+2
-2
@@ -2,5 +2,5 @@
|
||||
-- Gestione della versione di Beam
|
||||
|
||||
NAME = 'Beam'
|
||||
VERSION = '2.6d1'
|
||||
MIN_EXE = '2.6g1'
|
||||
VERSION = '3.1e1'
|
||||
MIN_EXE = '3.1e1'
|
||||
|
||||
Reference in New Issue
Block a user