Compare commits
40 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b68bbb2c48 | |||
| 6fe6b41e87 | |||
| 78189631c1 | |||
| 1a6433d5f8 | |||
| 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 | |||
| 8efb64810a |
+19
-10
@@ -250,6 +250,7 @@ elseif BEAM.FLAG == 9 then
|
||||
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
|
||||
@@ -548,7 +549,7 @@ if bToProcess then
|
||||
end
|
||||
|
||||
-- Sistemo le travi nel grezzo
|
||||
local bPbOk, sPbErr = BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, nil, PARTS, BEAM.FLAG ~= 6, false)
|
||||
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
|
||||
@@ -637,6 +638,7 @@ if bToProcess then
|
||||
BeamExec.GetStrategiesFromJSONinBD( PARTS[i].sAISetupConfig)
|
||||
PARTS[i].GeneralParameters = BeamLib.GetPieceGeneralParameters( PARTS[i], GENERAL_PARAMETERS_JSON)
|
||||
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
|
||||
@@ -690,12 +692,9 @@ if bToProcess then
|
||||
-- TODO gestire errori e messaggi di ritorno in questo caso
|
||||
if not GetDataConfig() then return end
|
||||
|
||||
BeamExec.GetProcessings( PARTS, false)
|
||||
BeamExec.GetCombinationMatrix( PARTS, false)
|
||||
BeamExec.ProcessMachinings( PARTS)
|
||||
|
||||
-- si cancella gruppo temporaneo contenente entità da cancellare
|
||||
EgtErase( idTempGroup)
|
||||
BeamExec.GetProcessings( PARTS, BEAM.FLAG == 10)
|
||||
BeamExec.GetCombinationMatrix( PARTS, BEAM.FLAG == 10)
|
||||
BeamExec.ProcessMachinings( PARTS, BEAM.FLAG == 10)
|
||||
|
||||
local sOutput = ''
|
||||
|
||||
@@ -722,7 +721,7 @@ if bToProcess then
|
||||
BEAM.ERR = 0
|
||||
BEAM.MSG = '---'
|
||||
end
|
||||
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)
|
||||
@@ -738,7 +737,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)
|
||||
@@ -764,7 +763,7 @@ if bToProcess then
|
||||
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)
|
||||
@@ -772,6 +771,16 @@ 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
|
||||
|
||||
+6
-1
@@ -145,7 +145,12 @@ local function MyProcessFeatures()
|
||||
|
||||
BeamExec.GetProcessings( PARTS, true)
|
||||
BeamExec.GetCombinationMatrix( PARTS, true)
|
||||
BeamExec.ProcessMachinings( PARTS)
|
||||
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 = ''
|
||||
|
||||
+124
-65
@@ -645,6 +645,8 @@ local function CollectFeatures( Part, dRotIndex)
|
||||
Proc.AffectedFaces = BeamLib.GetAffectedFaces( Proc, Part)
|
||||
-- volume feature approssimato
|
||||
Proc.dVolume = FeatureLib.GetFeatureVolume( Proc, Part)
|
||||
-- se trimesh, numero di parti di cui è composta
|
||||
Proc.nParts = EgtSurfTmPartCount( Proc.id) or 1
|
||||
-- calcolo topologia solo se necessario, altrimenti si sfruttano le informazioni della feature BTL
|
||||
local bIsFeatureReadyForProcessing = false
|
||||
if FeatureLib.NeedTopologyFeature( Proc, Part) then
|
||||
@@ -1078,7 +1080,7 @@ local function OrderFeatures( vProc)
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function AddFeatureResultToGlobalList( Proc, OptionalParameters)
|
||||
local function AddFeatureResultToGlobalList( Part, Proc, OptionalParameters)
|
||||
local sStrategyId
|
||||
local sStatus
|
||||
local dCompletionIndex
|
||||
@@ -1097,13 +1099,14 @@ local function AddFeatureResultToGlobalList( Proc, OptionalParameters)
|
||||
if Proc.isVirtualProc then
|
||||
return
|
||||
end
|
||||
local ChosenStrategyTable = PROCESSINGS[Proc.nIndexPartInParts].Rotation[Proc.nIndexRotation][Proc.nIndexMasterProc].ChosenStrategy
|
||||
local nOffsetIndex = EgtIf( Part.bPartInCombiIsInverted, 4, 0)
|
||||
local ChosenStrategyTable = PROCESSINGS[Proc.nIndexPartInParts].Rotation[Proc.nIndexRotation+nOffsetIndex][Proc.nIndexMasterProc].ChosenStrategy
|
||||
if ChosenStrategyTable then
|
||||
sStrategyId = ChosenStrategyTable.sStrategyId
|
||||
sStatus = ChosenStrategyTable.Result.sStatus
|
||||
dCompletionIndex = ChosenStrategyTable.Result.dCompletionIndex
|
||||
dCompositeRating = ChosenStrategyTable.Result.dCompositeRating
|
||||
local idFeature = PROCESSINGS[Proc.nIndexPartInParts].Rotation[Proc.nIndexRotation][Proc.nIndexMasterProc].idFeature
|
||||
local idFeature = PROCESSINGS[Proc.nIndexPartInParts].Rotation[Proc.nIndexRotation+nOffsetIndex][Proc.nIndexMasterProc].idFeature
|
||||
sApplyInfo = 'Skipped. Feature machined: ' .. EgtNumToString( idFeature)
|
||||
end
|
||||
elseif Proc.ChosenStrategy then
|
||||
@@ -1192,15 +1195,16 @@ local function CalculateMachinings( vProc, Part, nInitialRotation)
|
||||
_, _ = StrategyScript.Make( true, Proc, Part, Proc.ChosenStrategy)
|
||||
-- se tutte le strategie disponibili non sono applicabili
|
||||
else
|
||||
local nOffsetIndex = EgtIf( Part.bPartInCombiIsInverted, 4, 0)
|
||||
-- se non esiste una strategia scelta (non dovrebbe mai succedere) cancello da lista generale
|
||||
PROCESSINGS[Proc.nIndexPartInParts].Rotation[Proc.nIndexRotation][Proc.nIndexInVProc].ChosenStrategy = nil
|
||||
PROCESSINGS[Proc.nIndexPartInParts].Rotation[Proc.nIndexRotation+nOffsetIndex][Proc.nIndexInVProc].ChosenStrategy = nil
|
||||
|
||||
-- TODO dare messaggio che la feature non è stata eseguita nonostante la presenza di strategie disponibili
|
||||
|
||||
end
|
||||
end
|
||||
-- scrivo risultato in tabella globale
|
||||
AddFeatureResultToGlobalList( Proc, { nRotation = nCurrRotation})
|
||||
AddFeatureResultToGlobalList( Part, Proc, { nRotation = nCurrRotation})
|
||||
end
|
||||
|
||||
-- ripristino pezzo in posizione originale
|
||||
@@ -1295,7 +1299,7 @@ local function GetBestCombination( ListToCompare, Part)
|
||||
-- scelgo soluzione senza rotazioni
|
||||
if ListToCompare[ListIndex].nRotations == 0 then
|
||||
-- scelgo soluzione con voto più alto
|
||||
if ListToCompare[nIndexBestCombination].dTotalRating < ListToCompare[ListIndex].dTotalRating then
|
||||
if ListToCompare[nIndexBestCombination].dTotalRating + 10 * GEO.EPS_SMALL < ListToCompare[ListIndex].dTotalRating then
|
||||
nIndexBestCombination = ListIndex
|
||||
end
|
||||
end
|
||||
@@ -1313,8 +1317,11 @@ local function GetBestCombination( ListToCompare, Part)
|
||||
else
|
||||
-- se rotazione ha un grande impatto
|
||||
if Part.GeneralParameters.GEN_sPieceRotation == 'IF_NECESSARY' then
|
||||
-- scelgo soluzione con meno feature saltate
|
||||
if ListToCompare[ListIndex].nNotExecute < ListToCompare[nIndexBestCombination].nNotExecute then
|
||||
nIndexBestCombination = ListIndex
|
||||
-- scelgo soluzione con meno rotazioni indipendentemente dal voto
|
||||
if ListToCompare[nIndexBestCombination].nRotations > ListToCompare[ListIndex].nRotations then
|
||||
elseif ListToCompare[nIndexBestCombination].nRotations > ListToCompare[ListIndex].nRotations then
|
||||
nIndexBestCombination = ListIndex
|
||||
-- se stesso numero di rotazioni
|
||||
elseif ListToCompare[nIndexBestCombination].nRotations == ListToCompare[ListIndex].nRotations then
|
||||
@@ -1323,7 +1330,7 @@ local function GetBestCombination( ListToCompare, Part)
|
||||
nIndexBestCombination = ListIndex
|
||||
elseif ListToCompare[ListIndex].nComplete == ListToCompare[nIndexBestCombination].nComplete then
|
||||
-- scelgo soluzione con voto più alto
|
||||
if ListToCompare[nIndexBestCombination].dTotalRating < ListToCompare[ListIndex].dTotalRating then
|
||||
if ListToCompare[nIndexBestCombination].dTotalRating + 10 * GEO.EPS_SMALL < ListToCompare[ListIndex].dTotalRating then
|
||||
nIndexBestCombination = ListIndex
|
||||
end
|
||||
end
|
||||
@@ -1338,10 +1345,10 @@ local function GetBestCombination( ListToCompare, Part)
|
||||
local dOtherTotalRating = ListToCompare[ListIndex].dTotalRating
|
||||
|
||||
-- scelgo soluzione con voto più alto
|
||||
if dBestTotalRating < dOtherTotalRating then
|
||||
if dBestTotalRating + 10 * GEO.EPS_SMALL < dOtherTotalRating then
|
||||
nIndexBestCombination = ListIndex
|
||||
-- se stesso voto
|
||||
elseif dBestTotalRating == dOtherTotalRating then
|
||||
elseif abs( dBestTotalRating - dOtherTotalRating) < 10 * GEO.EPS_SMALL then
|
||||
-- scelgo soluzione con meno rotazioni
|
||||
if ListToCompare[nIndexBestCombination].nRotations > ListToCompare[ListIndex].nRotations then
|
||||
nIndexBestCombination = ListIndex
|
||||
@@ -1607,17 +1614,17 @@ function BeamExec.GetCombinationMatrix( PARTS, bIsFlipRot)
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function BeamExec.ProcessMachinings( PARTS)
|
||||
function BeamExec.ProcessMachinings( PARTS, bIsFlipRot)
|
||||
-- ciclo sui pezzi
|
||||
local nTotErr = 0
|
||||
local Stats = {}
|
||||
local nOrd = 1
|
||||
local nMaxReProcessCycles = EgtClamp( GENERAL_PARAMETERS.PROJECT.GEN_nMaxReProcessCycles, 1, 3)
|
||||
local bTryToReProcess = false
|
||||
|
||||
-- ricerca strategia di lavorazione per ogni pezzo e applicazione lavorazioni
|
||||
for nPart = 1, #PARTS do
|
||||
local nCycles = 1
|
||||
local nMaxReProcessCycles = EgtClamp( PARTS[nPart].GeneralParameters.GEN_nMaxReProcessCycles, 1, 3)
|
||||
|
||||
-- la parte di applicazione lavorazioni può essere lanciata più volte in caso della presenza di errori
|
||||
local bProcess = true
|
||||
@@ -1688,7 +1695,7 @@ function BeamExec.ProcessMachinings( PARTS)
|
||||
MACHININGS.Info.nSplitCutRotation = 1
|
||||
-- anche se non ci sono feature da eseguire, bisogna comunque scrivrere i risultati
|
||||
for nProc = 1, #vProc do
|
||||
AddFeatureResultToGlobalList( vProc[nProc])
|
||||
AddFeatureResultToGlobalList( PARTS[nPart], vProc[nProc])
|
||||
end
|
||||
-- altrimenti si fanno tutti i calcoli
|
||||
else
|
||||
@@ -1704,8 +1711,6 @@ function BeamExec.ProcessMachinings( PARTS)
|
||||
MACHININGS.Info.nSplitCutRotation = 1
|
||||
end
|
||||
end
|
||||
-- salvo sul PART la posizione di partenza che è stata scelta
|
||||
PARTS[nPart].nInitialPosition = MatrixResult.nInitialPosition
|
||||
|
||||
local nOffsetIndex = EgtIf( PARTS[nPart].bPartInCombiIsInverted, 4, 0)
|
||||
-- aggiunge tagli testa e coda in fasi opportune
|
||||
@@ -1713,36 +1718,34 @@ function BeamExec.ProcessMachinings( PARTS)
|
||||
if nRotHeadCut > 4 then
|
||||
nRotHeadCut = nRotHeadCut - 4
|
||||
end
|
||||
nRotHeadCut = nRotHeadCut + nOffsetIndex
|
||||
local nRotSplitCut = MatrixResult.nInitialPosition + MACHININGS.Info.nSplitCutRotation - 1
|
||||
if nRotSplitCut > 4 then
|
||||
nRotSplitCut = nRotSplitCut - 4
|
||||
end
|
||||
nRotSplitCut = nRotSplitCut + nOffsetIndex
|
||||
-- setto nella Proc l'indice rotazione nella quale deve essere lavorata
|
||||
PROCESSINGS[nPart].Rotation[nRotHeadCut][MatrixResult.nIndexHeadCutInVProc].nIndexRotation = nRotHeadCut
|
||||
PROCESSINGS[nPart].Rotation[nRotSplitCut][MatrixResult.nIndexTailCutInVProc].nIndexRotation = nRotSplitCut
|
||||
PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc].nIndexRotation = nRotHeadCut
|
||||
PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc].nIndexRotation = nRotSplitCut
|
||||
|
||||
-- si imposta flag rotazione per taglio di testa
|
||||
if MACHININGS.Info.nHeadCutRotation == 2 then
|
||||
PROCESSINGS[nPart].Rotation[nRotHeadCut][MatrixResult.nIndexHeadCutInVProc].bSide = true
|
||||
PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc].bSide = true
|
||||
elseif MACHININGS.Info.nHeadCutRotation == 3 then
|
||||
PROCESSINGS[nPart].Rotation[nRotHeadCut][MatrixResult.nIndexHeadCutInVProc].bDown = true
|
||||
PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc].bDown = true
|
||||
else
|
||||
PROCESSINGS[nPart].Rotation[nRotHeadCut][MatrixResult.nIndexHeadCutInVProc].bStd = true
|
||||
PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc].bStd = true
|
||||
end
|
||||
-- si imposta flag rotazione per taglio di coda
|
||||
if MACHININGS.Info.nSplitCutRotation == 2 then
|
||||
PROCESSINGS[nPart].Rotation[nRotSplitCut][MatrixResult.nIndexTailCutInVProc].bSide = true
|
||||
PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc].bSide = true
|
||||
elseif MACHININGS.Info.nSplitCutRotation == 3 then
|
||||
PROCESSINGS[nPart].Rotation[nRotSplitCut][MatrixResult.nIndexTailCutInVProc].bDown = true
|
||||
PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc].bDown = true
|
||||
else
|
||||
PROCESSINGS[nPart].Rotation[nRotSplitCut][MatrixResult.nIndexTailCutInVProc].bStd = true
|
||||
PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc].bStd = true
|
||||
end
|
||||
|
||||
local vProcHeadTail = {}
|
||||
table.insert( vProcHeadTail, PROCESSINGS[nPart].Rotation[nRotHeadCut][MatrixResult.nIndexHeadCutInVProc])
|
||||
table.insert( vProcHeadTail, PROCESSINGS[nPart].Rotation[nRotSplitCut][MatrixResult.nIndexTailCutInVProc])
|
||||
table.insert( vProcHeadTail, PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc])
|
||||
table.insert( vProcHeadTail, PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc])
|
||||
|
||||
MACHININGS = CalculateMachinings( vProcHeadTail, PARTS[nPart], MatrixResult.nInitialPosition)
|
||||
|
||||
@@ -1765,6 +1768,44 @@ function BeamExec.ProcessMachinings( PARTS)
|
||||
nRawId = EgtGetNextRawPart( nRawId)
|
||||
end
|
||||
|
||||
|
||||
local nInitialPosition = MatrixResult.nInitialPosition
|
||||
-- PREROTAZIONE PEZZO
|
||||
if MatrixResult.nInitialPosition ~= 1 or PARTS[nPart].bPartInCombiIsInverted then
|
||||
-- si toglie il pezzo dal grezzo per poter fare operazioni
|
||||
EgtRemovePartFromRawPart( PARTS[nPart].id)
|
||||
|
||||
-- salvo situazione precedente su lista BEAM ( scrittura variabili globali per interfaccia)
|
||||
if bIsFlipRot then
|
||||
BEAM.PREROTATE90 = MatrixResult.nInitialPosition - 1
|
||||
BEAM.PREINVERT = EgtIf( PARTS[nPart].bPartInCombiIsInverted, 1, 0)
|
||||
end
|
||||
|
||||
-- se c'è stata inversione, si inverte il pezzo anche in disegna
|
||||
if PARTS[nPart].bPartInCombiIsInverted then
|
||||
local ptInv = PARTS[nPart].b3PartOriginal:getMin() + Vector3d( PARTS[nPart].b3PartOriginal:getDimX() / 2, PARTS[nPart].b3PartOriginal:getDimY() / 2, 0)
|
||||
EgtRotate( PARTS[nPart].id, ptInv, Z_AX(), 180, GDB_RT.GLOB)
|
||||
PARTS[nPart].bIsInverted = true
|
||||
end
|
||||
|
||||
-- se c'è una prerotazione, si inverte il pezzo
|
||||
if MatrixResult.nInitialPosition ~= 1 then
|
||||
local ptRot = PARTS[nPart].b3PartOriginal:getMin() + Vector3d( 0, PARTS[nPart].b3PartOriginal:getDimY() / 2, PARTS[nPart].b3PartOriginal:getDimZ() / 2)
|
||||
local nRotationDeg = 90 * ( MatrixResult.nInitialPosition - 1)
|
||||
EgtRotate( PARTS[nPart].id, ptRot, X_AX(), nRotationDeg, GDB_RT.GLOB)
|
||||
end
|
||||
|
||||
-- si rimette il pezzo nel grezzo
|
||||
EgtAddPartToRawPart( PARTS[nPart].id, {0,0,0}, PARTS[nPart].idRaw)
|
||||
|
||||
-- dico che il pezzo originale è nella posizione iniziale come arriva da BTL ( è stato appena ruotato qui sopra)
|
||||
nInitialPosition = 1
|
||||
end
|
||||
|
||||
-- salvo sul PART la posizione di partenza che è stata scelta
|
||||
PARTS[nPart].nInitialPosition = MatrixResult.nInitialPosition
|
||||
|
||||
|
||||
local bAreAllMachiningApplyOk
|
||||
local sErr
|
||||
local bSplitAlreadyExecuted = false
|
||||
@@ -1778,7 +1819,6 @@ function BeamExec.ProcessMachinings( PARTS)
|
||||
-- creazione effettiva delle lavorazioni
|
||||
MACHININGS.Info = {}
|
||||
local nCurrPosition = 1
|
||||
local nInitialPosition = MatrixResult.nInitialPosition
|
||||
-- se c'è almeno una lavorazione in posizionamento con trave ribaltata
|
||||
if MatrixResult.bSomeFeatureDown then
|
||||
local nRotation = EgtIf( nInitialPosition + 2 > 4, nInitialPosition + 2 - 4, nInitialPosition + 2)
|
||||
@@ -1855,6 +1895,8 @@ function BeamExec.ProcessMachinings( PARTS)
|
||||
if PARTS[nPart].bPartInCombiIsInverted then
|
||||
BeamLib.InvertRawPart( PARTS[nPart], -2)
|
||||
end
|
||||
-- ripristino anche eventuali pre-rotazioni
|
||||
nInitialPosition = nInitialPosition + ( BEAM.PREROTATE90 or 0)
|
||||
-- si ribalta il pezzo in posizione iniziale
|
||||
BeamLib.RotateRawPart( PARTS[nPart], 1 - nInitialPosition)
|
||||
else
|
||||
@@ -1922,6 +1964,11 @@ end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function BeamExec.ProcessAlternatives( PARTS)
|
||||
|
||||
-- inizializzazione variabili globali per interfaccia
|
||||
BEAM.ALTERNATIVESNEST2D = ''
|
||||
BEAM.ALTERNATIVES = ''
|
||||
|
||||
-- ciclo sui pezzi
|
||||
local BestCombination = {}
|
||||
local nPart = 1
|
||||
@@ -1930,7 +1977,7 @@ function BeamExec.ProcessAlternatives( PARTS)
|
||||
local bTryToReProcess = false
|
||||
|
||||
-- se non serve trovare altre soluzioni, si esce subito
|
||||
if not ( PARTS[nPart].GeneralParameters.GEN_bTestAlternative and not PARTS[nPart].bSquareSection) or not PARTS[nPart].GeneralParameters.GEN_bGetAlternativesNesting2D then
|
||||
if not ( PARTS[nPart].GeneralParameters.GEN_sPiecesLoadingPosition == 'FULL_PRE_ROTATION' and not PARTS[nPart].bSquareSection) and not PARTS[nPart].GeneralParameters.GEN_bGetAlternativesNesting2D then
|
||||
return
|
||||
end
|
||||
|
||||
@@ -1956,7 +2003,7 @@ function BeamExec.ProcessAlternatives( PARTS)
|
||||
|
||||
local TotalCombiToTest = {}
|
||||
-- se serve calcolare soluzione alternativa ruotata di 90°
|
||||
if PARTS[nPart].GeneralParameters.GEN_bTestAlternative and not PARTS[nPart].bSquareSection then
|
||||
if PARTS[nPart].GeneralParameters.GEN_sPiecesLoadingPosition == 'FULL_PRE_ROTATION' and not PARTS[nPart].bSquareSection then
|
||||
local CombinationListToCheck = {}
|
||||
for i = 1, #PARTS[nPart].CombinationList do
|
||||
local nUnloadPos = PARTS[nPart].nInitialPosition
|
||||
@@ -1977,33 +2024,33 @@ function BeamExec.ProcessAlternatives( PARTS)
|
||||
if PARTS[nPart].GeneralParameters.GEN_bGetAlternativesNesting2D then
|
||||
-- POSIZIONE 0 (e invertito)
|
||||
local sCombinationToCheck = BeamLib.StringReplaceChar( '0000', PARTS[nPart].nInitialPosition, "1")
|
||||
table.insert( TotalCombiToTest, {{ sBitIndexCombination = sCombinationToCheck}})
|
||||
table.insert( TotalCombiToTest, {{ sBitIndexCombination = sCombinationToCheck}, bIsNesting2D = true})
|
||||
if PARTS[nPart].GeneralParameters.GEN_bAllowPieceInversion then
|
||||
table.insert( TotalCombiToTest, {{ sBitIndexCombination = sCombinationToCheck, bPartInCombiIsInverted = true}})
|
||||
table.insert( TotalCombiToTest, {{ sBitIndexCombination = sCombinationToCheck, bPartInCombiIsInverted = true}, bIsNesting2D = true})
|
||||
end
|
||||
|
||||
-- POSIZIONE 180 (e invertito)
|
||||
if PARTS[nPart].GeneralParameters.GEN_sPiecesLoadingPosition == 'STD_PRE_ROTATION' then
|
||||
local nOtherPosition = EgtIf( PARTS[nPart].nInitialPosition + 2 > 4, PARTS[nPart].nInitialPosition + 2 - 4, PARTS[nPart].nInitialPosition + 2)
|
||||
sCombinationToCheck = BeamLib.StringReplaceChar( '0000', nOtherPosition, "1")
|
||||
table.insert( TotalCombiToTest, {{ sBitIndexCombination = sCombinationToCheck}})
|
||||
table.insert( TotalCombiToTest, {{ sBitIndexCombination = sCombinationToCheck}, bIsNesting2D = true})
|
||||
if PARTS[nPart].GeneralParameters.GEN_bAllowPieceInversion then
|
||||
table.insert( TotalCombiToTest, {{ sBitIndexCombination = sCombinationToCheck, bPartInCombiIsInverted = true}})
|
||||
table.insert( TotalCombiToTest, {{ sBitIndexCombination = sCombinationToCheck, bPartInCombiIsInverted = true}, bIsNesting2D = true})
|
||||
end
|
||||
end
|
||||
-- POSIZIONE 90/270 (e invertito)
|
||||
if PARTS[nPart].GeneralParameters.GEN_sPiecesLoadingPosition == 'FULL_PRE_ROTATION' then
|
||||
local nOtherPosition = EgtIf( PARTS[nPart].nInitialPosition + 1 > 4, PARTS[nPart].nInitialPosition + 1 - 4, PARTS[nPart].nInitialPosition + 1)
|
||||
sCombinationToCheck = BeamLib.StringReplaceChar( '0000', nOtherPosition, "1")
|
||||
table.insert( TotalCombiToTest, {{ sBitIndexCombination = sCombinationToCheck}})
|
||||
table.insert( TotalCombiToTest, {{ sBitIndexCombination = sCombinationToCheck}, bIsNesting2D = true})
|
||||
if PARTS[nPart].GeneralParameters.GEN_bAllowPieceInversion then
|
||||
table.insert( TotalCombiToTest, {{ sBitIndexCombination = sCombinationToCheck, bPartInCombiIsInverted = true}})
|
||||
table.insert( TotalCombiToTest, {{ sBitIndexCombination = sCombinationToCheck, bPartInCombiIsInverted = true}, bIsNesting2D = true})
|
||||
end
|
||||
nOtherPosition = EgtIf( PARTS[nPart].nInitialPosition + 3 > 4, PARTS[nPart].nInitialPosition + 3 - 4, PARTS[nPart].nInitialPosition + 3)
|
||||
sCombinationToCheck = BeamLib.StringReplaceChar( '0000', nOtherPosition, "1")
|
||||
table.insert( TotalCombiToTest, {{ sBitIndexCombination = sCombinationToCheck}})
|
||||
table.insert( TotalCombiToTest, {{ sBitIndexCombination = sCombinationToCheck}, bIsNesting2D = true})
|
||||
if PARTS[nPart].GeneralParameters.GEN_bAllowPieceInversion then
|
||||
table.insert( TotalCombiToTest, {{ sBitIndexCombination = sCombinationToCheck, bPartInCombiIsInverted = true}})
|
||||
table.insert( TotalCombiToTest, {{ sBitIndexCombination = sCombinationToCheck, bPartInCombiIsInverted = true}, bIsNesting2D = true})
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -2030,6 +2077,7 @@ function BeamExec.ProcessAlternatives( PARTS)
|
||||
BestCombination = GetBestCombination( CombinationListFromMatrix, PARTS[nPart])
|
||||
-- se la soluzione alternativa migliore è completa, allora la verifico, altrimenti si tiene la migliore in assoluto
|
||||
if BestCombination.nNotComplete == 0 and BestCombination.nNotExecute == 0 then
|
||||
PARTS[nPart].bPartInCombiIsInverted = BestCombination.bPartInCombiIsInverted
|
||||
|
||||
-- compilazione della vProc finale contenente le feature da lavorare nella giusta rotazione
|
||||
local vProc, MatrixResult = GetProcessingListFromCombination( BestCombination)
|
||||
@@ -2077,48 +2125,46 @@ function BeamExec.ProcessAlternatives( PARTS)
|
||||
if nRotHeadCut > 4 then
|
||||
nRotHeadCut = nRotHeadCut - 4
|
||||
end
|
||||
nRotHeadCut = nRotHeadCut + nOffsetIndex
|
||||
local nRotSplitCut = MatrixResult.nInitialPosition + MACHININGS.Info.nSplitCutRotation - 1
|
||||
if nRotSplitCut > 4 then
|
||||
nRotSplitCut = nRotSplitCut - 4
|
||||
end
|
||||
nRotSplitCut = nRotSplitCut + nOffsetIndex
|
||||
-- setto nella Proc l'indice rotazione nella quale deve essere lavorata
|
||||
PROCESSINGS[nPart].Rotation[nRotHeadCut][MatrixResult.nIndexHeadCutInVProc].nIndexRotation = nRotHeadCut
|
||||
PROCESSINGS[nPart].Rotation[nRotSplitCut][MatrixResult.nIndexTailCutInVProc].nIndexRotation = nRotSplitCut
|
||||
PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc].nIndexRotation = nRotHeadCut
|
||||
PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc].nIndexRotation = nRotSplitCut
|
||||
|
||||
-- si imposta flag rotazione per taglio di testa
|
||||
if MACHININGS.Info.nHeadCutRotation == 2 then
|
||||
PROCESSINGS[nPart].Rotation[nRotHeadCut][MatrixResult.nIndexHeadCutInVProc].bDown = nil
|
||||
PROCESSINGS[nPart].Rotation[nRotHeadCut][MatrixResult.nIndexHeadCutInVProc].bSide = true
|
||||
PROCESSINGS[nPart].Rotation[nRotHeadCut][MatrixResult.nIndexHeadCutInVProc].bStd = nil
|
||||
PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc].bDown = nil
|
||||
PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc].bSide = true
|
||||
PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc].bStd = nil
|
||||
elseif MACHININGS.Info.nHeadCutRotation == 3 then
|
||||
PROCESSINGS[nPart].Rotation[nRotHeadCut][MatrixResult.nIndexHeadCutInVProc].bDown = true
|
||||
PROCESSINGS[nPart].Rotation[nRotHeadCut][MatrixResult.nIndexHeadCutInVProc].bSide = nil
|
||||
PROCESSINGS[nPart].Rotation[nRotHeadCut][MatrixResult.nIndexHeadCutInVProc].bStd = nil
|
||||
PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc].bDown = true
|
||||
PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc].bSide = nil
|
||||
PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc].bStd = nil
|
||||
else
|
||||
PROCESSINGS[nPart].Rotation[nRotHeadCut][MatrixResult.nIndexHeadCutInVProc].bDown = nil
|
||||
PROCESSINGS[nPart].Rotation[nRotHeadCut][MatrixResult.nIndexHeadCutInVProc].bSide = nil
|
||||
PROCESSINGS[nPart].Rotation[nRotHeadCut][MatrixResult.nIndexHeadCutInVProc].bStd = true
|
||||
PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc].bDown = nil
|
||||
PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc].bSide = nil
|
||||
PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc].bStd = true
|
||||
end
|
||||
-- si imposta flag rotazione per taglio di coda
|
||||
if MACHININGS.Info.nSplitCutRotation == 2 then
|
||||
PROCESSINGS[nPart].Rotation[nRotSplitCut][MatrixResult.nIndexTailCutInVProc].bDown = nil
|
||||
PROCESSINGS[nPart].Rotation[nRotSplitCut][MatrixResult.nIndexTailCutInVProc].bSide = true
|
||||
PROCESSINGS[nPart].Rotation[nRotSplitCut][MatrixResult.nIndexTailCutInVProc].bStd = nil
|
||||
PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc].bDown = nil
|
||||
PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc].bSide = true
|
||||
PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc].bStd = nil
|
||||
elseif MACHININGS.Info.nSplitCutRotation == 3 then
|
||||
PROCESSINGS[nPart].Rotation[nRotSplitCut][MatrixResult.nIndexTailCutInVProc].bDown = true
|
||||
PROCESSINGS[nPart].Rotation[nRotSplitCut][MatrixResult.nIndexTailCutInVProc].bSide = nil
|
||||
PROCESSINGS[nPart].Rotation[nRotSplitCut][MatrixResult.nIndexTailCutInVProc].bStd = nil
|
||||
PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc].bDown = true
|
||||
PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc].bSide = nil
|
||||
PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc].bStd = nil
|
||||
else
|
||||
PROCESSINGS[nPart].Rotation[nRotSplitCut][MatrixResult.nIndexTailCutInVProc].bDown = nil
|
||||
PROCESSINGS[nPart].Rotation[nRotSplitCut][MatrixResult.nIndexTailCutInVProc].bSide = nil
|
||||
PROCESSINGS[nPart].Rotation[nRotSplitCut][MatrixResult.nIndexTailCutInVProc].bStd = true
|
||||
PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc].bDown = nil
|
||||
PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc].bSide = nil
|
||||
PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc].bStd = true
|
||||
end
|
||||
|
||||
local vProcHeadTail = {}
|
||||
table.insert( vProcHeadTail, PROCESSINGS[nPart].Rotation[nRotHeadCut][MatrixResult.nIndexHeadCutInVProc])
|
||||
table.insert( vProcHeadTail, PROCESSINGS[nPart].Rotation[nRotSplitCut][MatrixResult.nIndexTailCutInVProc])
|
||||
table.insert( vProcHeadTail, PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc])
|
||||
table.insert( vProcHeadTail, PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc])
|
||||
|
||||
MACHININGS = CalculateMachinings( vProcHeadTail, PARTS[nPart], MatrixResult.nInitialPosition)
|
||||
|
||||
@@ -2248,11 +2294,24 @@ function BeamExec.ProcessAlternatives( PARTS)
|
||||
-- Aggiornamento finale di tutto
|
||||
EgtSetCurrPhase( 1)
|
||||
local bApplOk, _, _ = EgtApplyAllMachinings()
|
||||
-- se non ci sono errori, soluzione alternativa valida
|
||||
-- se non ci sono errori, soluzione alternativa valida: scrittura variabili globali per interfaccia
|
||||
if bApplOk then
|
||||
-- TODO scrivere info su pezzo!
|
||||
local Alternatives = {}
|
||||
local sBitIndexCombinationWithInvert = BestCombination.sBitIndexCombination .. EgtIf( BestCombination.bPartInCombiIsInverted, '_INV', '')
|
||||
if TotalCombiToTest[z].bIsNesting2D then
|
||||
if BEAM.ALTERNATIVESNEST2D and BEAM.ALTERNATIVESNEST2D ~= "" then
|
||||
table.insert( Alternatives, BEAM.ALTERNATIVESNEST2D)
|
||||
end
|
||||
table.insert( Alternatives, sBitIndexCombinationWithInvert)
|
||||
BEAM.ALTERNATIVESNEST2D = table.concat( Alternatives, ', ')
|
||||
else
|
||||
if BEAM.ALTERNATIVES and BEAM.ALTERNATIVES ~= "" then
|
||||
table.insert( Alternatives, BEAM.ALTERNATIVES)
|
||||
end
|
||||
table.insert( Alternatives, sBitIndexCombinationWithInvert)
|
||||
BEAM.ALTERNATIVES = table.concat( Alternatives, ', ')
|
||||
end
|
||||
end
|
||||
|
||||
-- se ultima combinazione, si esce e non si riporta in posizione inizale. Verrà infatti cancellata
|
||||
if z == #TotalCombiToTest then break end
|
||||
|
||||
|
||||
+35
-9
@@ -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
|
||||
@@ -186,7 +188,7 @@ function FaceData.GetFacesInfo( Proc, Part, FacesToGet)
|
||||
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].frFrameHV = Frame3d( Faces[i].ptCenter, Faces[i].vtN)
|
||||
-- elevazione calcolata rispetto al box della parte
|
||||
@@ -383,10 +385,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
|
||||
@@ -476,7 +496,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 {}
|
||||
@@ -584,7 +604,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 {}
|
||||
@@ -690,15 +710,21 @@ function FaceData.GetMainFaces( Proc, Part)
|
||||
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)
|
||||
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
|
||||
|
||||
@@ -226,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
|
||||
@@ -244,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
|
||||
@@ -259,7 +261,9 @@ function FeatureLib.ClassifyTopology( Proc, Part)
|
||||
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
|
||||
|
||||
+55
-45
@@ -1355,13 +1355,19 @@ function MachiningLib.AddOperations( MACHININGS, Part, sRotation)
|
||||
MachStartAxesPos = EgtGetMachiningStartAxes(),
|
||||
MachEndAxesPos = EgtGetMachiningEndAxes()}
|
||||
table.insert( DB_MACH_APPLIED, MachExtraInfo)
|
||||
|
||||
-- se non esistono punto iniziale o finale, si disattiva operazione
|
||||
if not MachExtraInfo.MachStartAxesPos or not MachExtraInfo.MachEndAxesPos then
|
||||
EgtSetOperationMode( nOperationId, false)
|
||||
end
|
||||
|
||||
-- se errore in applicazione
|
||||
if not bIsApplyOk then
|
||||
bAreAllMachiningApplyOk = false
|
||||
nErr, sErr = EgtGetLastMachMgrError()
|
||||
EgtSetOperationMode( nOperationId, false)
|
||||
local CurrProc = PROCESSINGS[MACHININGS[i].Proc.nIndexPartInParts].Rotation[MACHININGS[i].Proc.nIndexRotation][MACHININGS[i].Proc.nIndexInVProc]
|
||||
local nOffsetIndex = EgtIf( Part.bPartInCombiIsInverted, 4, 0)
|
||||
local CurrProc = PROCESSINGS[MACHININGS[i].Proc.nIndexPartInParts].Rotation[MACHININGS[i].Proc.nIndexRotation+nOffsetIndex][MACHININGS[i].Proc.nIndexInVProc]
|
||||
-- si annulla la feature scelta, in modo che un successivo ricalcolo non la tenga in considerazione
|
||||
CurrProc.AvailableStrategies[CurrProc.nIndexBestStrategy].Result.sStatus = 'Not-Applicable'
|
||||
CurrProc.AvailableStrategies[CurrProc.nIndexBestStrategy].Result.sInfo = 'REJECTED (' .. sErr .. ')'
|
||||
@@ -1378,7 +1384,7 @@ function MachiningLib.AddOperations( MACHININGS, Part, sRotation)
|
||||
-- se applicazione andata a buon fine
|
||||
else
|
||||
|
||||
-- se non deve essere igniorato, si salva ingombro lavorazione attuale e fasi successive
|
||||
-- se non deve essere ignorato, si salva ingombro lavorazione attuale e fasi successive
|
||||
if not MACHININGS[i].AuxiliaryData.bIgnoreNotClampableLength then
|
||||
-- salvo ingombro non pinzabile testa/coda
|
||||
local nCurrRotation = MACHININGS[i].Proc.nIndexRotation
|
||||
@@ -1436,18 +1442,20 @@ function MachiningLib.AddOperations( MACHININGS, Part, sRotation)
|
||||
local nPhase = EgtGetCurrPhase()
|
||||
local idDisp = EgtGetPhaseDisposition( nPhase)
|
||||
|
||||
-- posizione iniziale considerando eventuiali prerotazioni
|
||||
local nRealInitialPosition = Part.nInitialPosition - ( BEAM.PREROTATE90 or 0)
|
||||
if sRotation == 'DOWN' then
|
||||
local nRotation = EgtIf( Part.nInitialPosition + 2 > 4, Part.nInitialPosition + 2 - 4, Part.nInitialPosition + 2) - 1
|
||||
local nRotation = EgtIf( nRealInitialPosition + 2 > 4, nRealInitialPosition + 2 - 4, nRealInitialPosition + 2) - 1
|
||||
BeamLib.RotateRawPart( Part, nRotation)
|
||||
EgtSetInfo( idDisp, 'ROT', -2)
|
||||
EgtSetInfo( idDisp, 'TYPE', 'MID2')
|
||||
elseif sRotation == 'SIDE' then
|
||||
local nRotation = EgtIf( Part.nInitialPosition + 1 > 4, Part.nInitialPosition + 1 - 4, Part.nInitialPosition + 1) - 1
|
||||
local nRotation = EgtIf( nRealInitialPosition + 1 > 4, nRealInitialPosition + 1 - 4, nRealInitialPosition + 1) - 1
|
||||
BeamLib.RotateRawPart( Part, nRotation)
|
||||
EgtSetInfo( idDisp, 'ROT', -1)
|
||||
EgtSetInfo( idDisp, 'TYPE', 'MID2')
|
||||
else
|
||||
local nRotation = Part.nInitialPosition - 1
|
||||
local nRotation = nRealInitialPosition - 1
|
||||
BeamLib.RotateRawPart( Part, nRotation)
|
||||
EgtSetInfo( idDisp, 'TYPE', 'END')
|
||||
end
|
||||
@@ -1516,14 +1524,14 @@ function MachiningLib.GetTimeToMachineAllStepsWithLeadInOut( Machining, Part)
|
||||
if Machining.nType == MCH_MY.DRILLING then
|
||||
local function fact(n) return n == 0 and 1 or n * fact(n - 1) end
|
||||
local nSteps = ceil( Machining.sDepth / Machining.dStep)
|
||||
local dLenghtEachStep = Machining.sDepth / nSteps
|
||||
local dLengthEachStep = Machining.sDepth / nSteps
|
||||
-- numero dei movimenti a step, compresi andata e ritorno per scarico truciolo
|
||||
local nTotStepMovement = 2 * fact( nSteps)
|
||||
-- in feed si lavorano solo gli step
|
||||
local dFeedTime = ( ( dLenghtEachStep + Machining.dStartSafetyLength) * nSteps) / dToolFeed
|
||||
-- ritorno per scaricare e approccio al prossimo step seno in feed finale
|
||||
local dEndFeedTime = ( dLenghtEachStep * ( nTotStepMovement - nSteps) + EgtMdbGetGeneralParam( MCH_GP.SAFEZ) * 2) / dToolEndFeed
|
||||
dLengthToMachineAllStepsWithLeadInOut = dLenghtEachStep * nTotStepMovement
|
||||
local dFeedTime = ( ( dLengthEachStep + Machining.dStartSafetyLength) * nSteps) / dToolFeed
|
||||
-- ritorno per scaricare e approccio al prossimo step sono in feed finale
|
||||
local dEndFeedTime = ( dLengthEachStep * ( nTotStepMovement - nSteps) + EgtMdbGetGeneralParam( MCH_GP.SAFEZ) * 2) / dToolEndFeed
|
||||
dLengthToMachineAllStepsWithLeadInOut = dLengthEachStep * nTotStepMovement
|
||||
dTimeToMachineTotal = dFeedTime + dEndFeedTime
|
||||
elseif Machining.nType == MCH_MY.MILLING then
|
||||
-- stima LeadIn e LeadOut; se non settati si impostano a valori di default
|
||||
@@ -1780,44 +1788,46 @@ function MachiningLib.ShortestPathSorting()
|
||||
|
||||
-- se è una lavorazione
|
||||
while DB_MACH_APPLIED[i] and DB_MACH_APPLIED[i].sType ~= 'DISP' do
|
||||
-- se lavorazione non attiva non va considerata
|
||||
local nOperationId = DB_MACH_APPLIED[i].nOperationId
|
||||
if EgtGetOperationMode( nOperationId) then
|
||||
local ptMinX, ptMaxX
|
||||
-- aggiungo lavorazioni
|
||||
local nToolIndex = MACHININGS[DB_MACH_APPLIED[i].nIndexInMachinings].Machining.nToolIndex
|
||||
EgtOptMachAddTool( nToolIndex, 2, 2) -- , [ num dTC_X, num dTC_Y, num dTC_Z, num dTC_A, num dTC_B, num dTC_C])
|
||||
-- viene eseguito prima il gruppo con indice più alto, quindi si inverte indice dato che lo stage è dal più piccolo al più grande
|
||||
local nGroup = 10 - MACHININGS[DB_MACH_APPLIED[i].nIndexInMachinings].Machining.nStage
|
||||
local MachStartAxesPos = DB_MACH_APPLIED[i].MachStartAxesPos
|
||||
local MachEndAxesPos = DB_MACH_APPLIED[i].MachEndAxesPos
|
||||
EgtOptMachAddMachining( i, nToolIndex, nGroup, MachStartAxesPos, MachEndAxesPos)
|
||||
table.insert( MachiningOptList, i)
|
||||
if DB_MACH_APPLIED[i].MachStartAxesPos and DB_MACH_APPLIED[i].MachEndAxesPos then
|
||||
-- se lavorazione non attiva non va considerata
|
||||
local nOperationId = DB_MACH_APPLIED[i].nOperationId
|
||||
if EgtGetOperationMode( nOperationId) then
|
||||
local ptMinX, ptMaxX
|
||||
-- aggiungo lavorazioni
|
||||
local nToolIndex = MACHININGS[DB_MACH_APPLIED[i].nIndexInMachinings].Machining.nToolIndex
|
||||
EgtOptMachAddTool( nToolIndex, 2, 2) -- , [ num dTC_X, num dTC_Y, num dTC_Z, num dTC_A, num dTC_B, num dTC_C])
|
||||
-- viene eseguito prima il gruppo con indice più alto, quindi si inverte indice dato che lo stage è dal più piccolo al più grande
|
||||
local nGroup = 10 - MACHININGS[DB_MACH_APPLIED[i].nIndexInMachinings].Machining.nStage
|
||||
local MachStartAxesPos = DB_MACH_APPLIED[i].MachStartAxesPos
|
||||
local MachEndAxesPos = DB_MACH_APPLIED[i].MachEndAxesPos
|
||||
EgtOptMachAddMachining( i, nToolIndex, nGroup, MachStartAxesPos, MachEndAxesPos)
|
||||
table.insert( MachiningOptList, i)
|
||||
|
||||
-- si salvano i punti minimi e massimi tra tutte le lavorazioni di ogni gruppo
|
||||
if MachStartAxesPos[1] < MachEndAxesPos[1] then
|
||||
ptMinX = MachStartAxesPos
|
||||
ptMaxX = MachEndAxesPos
|
||||
else
|
||||
ptMinX = MachEndAxesPos
|
||||
ptMaxX = MachStartAxesPos
|
||||
end
|
||||
|
||||
-- si aggiungono le info di gruppo
|
||||
local bFound = false
|
||||
for t = 1, #GroupInfo do
|
||||
if GroupInfo[t].nGroup == nGroup then
|
||||
if GroupInfo[t].ptMin[1] > ptMinX[1] then GroupInfo[t].ptMin = ptMinX end
|
||||
if GroupInfo[t].ptMax[1] < ptMaxX[1] then GroupInfo[t].ptMax = ptMaxX end
|
||||
bFound = true
|
||||
-- si salvano i punti minimi e massimi tra tutte le lavorazioni di ogni gruppo
|
||||
if MachStartAxesPos[1] < MachEndAxesPos[1] then
|
||||
ptMinX = MachStartAxesPos
|
||||
ptMaxX = MachEndAxesPos
|
||||
else
|
||||
ptMinX = MachEndAxesPos
|
||||
ptMaxX = MachStartAxesPos
|
||||
end
|
||||
end
|
||||
-- se non ho trovato, si aggiunge in lista
|
||||
if not bFound then
|
||||
table.insert( GroupInfo, { nGroup = nGroup, nStage = MACHININGS[DB_MACH_APPLIED[i].nIndexInMachinings].Machining.nStage, ptMin = ptMinX, ptMax = ptMaxX})
|
||||
end
|
||||
|
||||
nMachInDisp = nMachInDisp + 1
|
||||
-- si aggiungono le info di gruppo
|
||||
local bFound = false
|
||||
for t = 1, #GroupInfo do
|
||||
if GroupInfo[t].nGroup == nGroup then
|
||||
if GroupInfo[t].ptMin[1] > ptMinX[1] then GroupInfo[t].ptMin = ptMinX end
|
||||
if GroupInfo[t].ptMax[1] < ptMaxX[1] then GroupInfo[t].ptMax = ptMaxX end
|
||||
bFound = true
|
||||
end
|
||||
end
|
||||
-- se non ho trovato, si aggiunge in lista
|
||||
if not bFound then
|
||||
table.insert( GroupInfo, { nGroup = nGroup, nStage = MACHININGS[DB_MACH_APPLIED[i].nIndexInMachinings].Machining.nStage, ptMin = ptMinX, ptMax = ptMaxX})
|
||||
end
|
||||
|
||||
nMachInDisp = nMachInDisp + 1
|
||||
end
|
||||
end
|
||||
i = i + 1
|
||||
end
|
||||
|
||||
@@ -34,12 +34,12 @@ local function GetMachineAxes()
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function LogOutstroke( ptOnToolTipCenter, vtHead, OptionalParameters)
|
||||
local function LogOutstroke( sToolName, ptOnToolTipCenter, vtHead, OptionalParameters)
|
||||
|
||||
-- parametri opzionali
|
||||
OptionalParameters = OptionalParameters or {}
|
||||
local LinearAxes = OptionalParameters.LinearAxes
|
||||
local RotativeAxes = OptionalParameters.RotativeAxes
|
||||
local LinearAxesValues = OptionalParameters.LinearAxesValues
|
||||
local RotativeAxesValues = OptionalParameters.RotativeAxesValues
|
||||
|
||||
-- gruppo per geometrie temporanee
|
||||
local idTempGroup = BeamLib.GetTempGroup()
|
||||
@@ -50,15 +50,18 @@ local function LogOutstroke( ptOnToolTipCenter, vtHead, OptionalParameters)
|
||||
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 LinearAxes then
|
||||
EgtOutLog( ' ' .. LinearAxes[1].sName .. ' = ' .. tostring( LinearAxes[1].dValue) .. ', ' .. LinearAxes[2].sName .. ' = ' .. tostring( LinearAxes[2].dValue) .. ', ' .. LinearAxes[3].sName .. ' = ' .. tostring( LinearAxes[3].dValue))
|
||||
if LinearAxesValues then
|
||||
EgtOutLog( ' ' .. 'Lin1' .. ' = ' .. tostring( LinearAxesValues[1]) .. ', ' .. 'Lin2' .. ' = ' .. tostring( LinearAxesValues[2]) .. ', ' .. 'Lin3' .. ' = ' .. tostring( LinearAxesValues[3]))
|
||||
end
|
||||
if RotativeAxes then
|
||||
EgtOutLog( ' ' .. RotativeAxes[1].sName .. ' = ' .. tostring( RotativeAxes[1].dValue) .. ', ' .. RotativeAxes[2].sName .. ' = ' .. tostring( RotativeAxes[2].dValue))
|
||||
if RotativeAxesValues then
|
||||
EgtOutLog( ' ' .. 'Rot1' .. ' = ' .. tostring( RotativeAxesValues[1]) .. ', ' .. 'Rot2' .. ' = ' .. tostring( RotativeAxesValues[2]) .. ', ' .. 'Rot3' .. ' = ' .. tostring( RotativeAxesValues[3]))
|
||||
end
|
||||
|
||||
return
|
||||
@@ -150,27 +153,28 @@ local function GetCollisionPointsToCheck( Edge, dDepthToMachine)
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function CheckOutOfStrokePoint( ptOnToolTipCenter, vtHead, nSCC, Tool)
|
||||
local function CheckOutOfStrokePoint( ptOnToolTipCenter, vtHead, nSCC, Tool, vtAux, sBlockedAxis)
|
||||
|
||||
-- impostazione utensile
|
||||
EgtSetCalcTool( Tool.sName, Tool.sHead, Tool.nExit)
|
||||
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)
|
||||
|
||||
-- assi macchina da calcolare
|
||||
local LinearAxes, RotativeAxes = GetMachineAxes()
|
||||
|
||||
-- se più di 3 assi lineari e 2 assi rotativi, macchina non supportata
|
||||
if #LinearAxes > 3 or #RotativeAxes > 2 then
|
||||
|
||||
error(' CheckOutOfStrokePoint : too many axes')
|
||||
-- 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, dRot1, dRot2 = EgtGetCalcAngles( vtHead)
|
||||
RotativeAxes[1].dValue = dRot1
|
||||
RotativeAxes[2].dValue = dRot2
|
||||
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')
|
||||
@@ -180,40 +184,27 @@ local function CheckOutOfStrokePoint( ptOnToolTipCenter, vtHead, nSCC, Tool)
|
||||
if nSolutionsAngles == 0 then
|
||||
|
||||
if EgtGetDebugLevel() >= 3 then
|
||||
LogOutstroke( ptOnToolTipCenter, vtHead)
|
||||
LogOutstroke( Tool.sName, ptOnToolTipCenter, vtHead, { RotativeAxesValues = { dRotative1, dRotative2, dRotative3}})
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
-- calcolo assi lineari
|
||||
local bOkPositions, _, dLinear1, dLinear2, dLinear3 = EgtGetCalcPositions( ptOnToolTipCenter, RotativeAxes[1].dValue, RotativeAxes[2].dValue)
|
||||
LinearAxes[1].dValue = dLinear1
|
||||
LinearAxes[2].dValue = dLinear2
|
||||
LinearAxes[3].dValue = dLinear3
|
||||
local bOkPositions, _, dLinear1, dLinear2, dLinear3 = EgtGetCalcPositions( ptOnToolTipCenter, dRotative1, dRotative2, dRotative3)
|
||||
|
||||
if not bOkPositions then
|
||||
|
||||
error( ' CheckOutOfStrokePoint : error')
|
||||
end
|
||||
|
||||
-- verifica finecorsa per tutti gli assi
|
||||
-- siccome non si sa a priori il numero di assi lineari e rotativi, si aggiungono tutti a Args in ordine
|
||||
-- Args viene poi esplosa in modo da passare a EgtVerifyOutstroke i valori separati
|
||||
local Args = {}
|
||||
for i = 1, #LinearAxes do
|
||||
Args[#Args+1] = LinearAxes[i].dValue
|
||||
end
|
||||
for i = 1, #RotativeAxes do
|
||||
Args[#Args+1] = RotativeAxes[i].dValue
|
||||
end
|
||||
|
||||
local bAllAxesInStroke = EgtVerifyOutstroke( table.unpack( Args))
|
||||
-- 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( ptOnToolTipCenter, vtHead, { LinearAxes = LinearAxes, RotativeAxes = RotativeAxes})
|
||||
LogOutstroke( Tool.sName, ptOnToolTipCenter, vtHead, { LinearAxesValues = { dLinear1, dLinear2, dLinear3}, RotativeAxesValues = { dRotative1, dRotative2, dRotative3}})
|
||||
end
|
||||
return true
|
||||
end
|
||||
@@ -230,11 +221,11 @@ end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- check extracorsa da punti sul tip dell'utensile
|
||||
function PreSimulationLib.CheckOutOfStrokeFromPoints( PointsOnToolTipCenter, vtHead, nSCC, Tool)
|
||||
function PreSimulationLib.CheckOutOfStrokeFromPoints( PointsOnToolTipCenter, vtHead, nSCC, Tool, vtAux, sBlockedAxis)
|
||||
|
||||
for i = 1, #PointsOnToolTipCenter do
|
||||
|
||||
local bOutOfStroke = CheckOutOfStrokePoint( PointsOnToolTipCenter[i], vtHead, nSCC, Tool)
|
||||
local bOutOfStroke = CheckOutOfStrokePoint( PointsOnToolTipCenter[i], vtHead, nSCC, Tool, vtAux, sBlockedAxis)
|
||||
|
||||
-- se trovato extracorsa inutile procedere con gli altri punti
|
||||
if bOutOfStroke then
|
||||
@@ -249,7 +240,7 @@ end
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- check extracorsa da geometria
|
||||
-- TODO da considerare anche gli attacchi
|
||||
function PreSimulationLib.CheckOutOfStrokeFromGeometry( idGeometry, vtHead, nSCC, Tool)
|
||||
function PreSimulationLib.CheckOutOfStrokeFromGeometry( idGeometry, vtHead, nSCC, Tool, vtAux, sBlockedAxis)
|
||||
|
||||
local b3GeomMaxOffset = EgtGetBBoxGlob( idGeometry, GDB_BB.STANDARD)
|
||||
local ptBoxCenter = b3GeomMaxOffset:getCenter()
|
||||
@@ -272,7 +263,7 @@ function PreSimulationLib.CheckOutOfStrokeFromGeometry( idGeometry, vtHead, nSCC
|
||||
-- Z-
|
||||
table.insert( PointsOnToolTipCenter, Point3d( ptBoxCenter - dBoxDimZ / 2 * Z_AX()))
|
||||
|
||||
local bOutOfStroke = PreSimulationLib.CheckOutOfStrokeFromPoints( PointsOnToolTipCenter, vtHead, nSCC, Tool)
|
||||
local bOutOfStroke = PreSimulationLib.CheckOutOfStrokeFromPoints( PointsOnToolTipCenter, vtHead, nSCC, Tool, vtAux, sBlockedAxis)
|
||||
|
||||
return bOutOfStroke
|
||||
end
|
||||
@@ -385,7 +376,7 @@ local function CheckCollisionWithAxis( sAxis, MachiningParameters, OptionalParam
|
||||
local vtSCC = BeamLib.GetDirectionFromSCC( nSCC)
|
||||
local vtC = vtHead ^ Tool.SetupInfo.vtRotationAxisC
|
||||
vtC:normalize()
|
||||
if vtC:isZero() then
|
||||
if vtC:isSmall() then
|
||||
vtC = vtSCC
|
||||
elseif vtC * vtSCC < GEO.EPS_SMALL then
|
||||
vtC = -vtC
|
||||
|
||||
+1
-1
@@ -304,7 +304,7 @@ local function MyProcessFeatures()
|
||||
|
||||
BeamExec.GetProcessings( PARTS, false)
|
||||
BeamExec.GetCombinationMatrix( PARTS, false)
|
||||
BeamExec.ProcessMachinings( PARTS)
|
||||
BeamExec.ProcessMachinings( PARTS, false)
|
||||
local nErrCnt = 0
|
||||
local nWarnCnt = 0
|
||||
local sOutput = ''
|
||||
|
||||
@@ -41,17 +41,6 @@
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
},
|
||||
{
|
||||
"nGroup": "PIECE LOADING",
|
||||
"sName": "GEN_bTestAlternative",
|
||||
"sNameNge": "TEST_ALTERNATIVE",
|
||||
"sValue": "false",
|
||||
"sDescriptionShort": "Enable the possibility to load the piece 90° turned",
|
||||
"sDescriptionLong": "",
|
||||
"sType": "b",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
},
|
||||
{
|
||||
"nGroup": "PIECE LOADING",
|
||||
"sName": "GEN_bGetAlternativesNesting2D",
|
||||
|
||||
@@ -40,6 +40,11 @@ function HEADCUT.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
|
||||
-- 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
|
||||
@@ -67,9 +72,6 @@ function HEADCUT.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
|
||||
-- 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()
|
||||
|
||||
@@ -22,6 +22,16 @@
|
||||
"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",
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
},
|
||||
{
|
||||
"sName": "dOpenMinSafe",
|
||||
"sNameNge": "OPENMINSAFE",
|
||||
|
||||
@@ -19,6 +19,7 @@ local BeamLib = require( 'BeamLib')
|
||||
local BeamData = require( 'BeamDataNew')
|
||||
local MachiningLib = require( 'MachiningLib')
|
||||
local FeatureLib = require( 'FeatureLib')
|
||||
local AntiSplintOnFace = require( 'ANTISPLINTONFACE')
|
||||
|
||||
-- Tabella per definizione modulo
|
||||
local STR0002 = {}
|
||||
@@ -107,7 +108,7 @@ local function GetBestPocketingStrategy( Proc, Part)
|
||||
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
|
||||
@@ -170,10 +171,14 @@ local function GetBestPocketingStrategy( Proc, Part)
|
||||
-- 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
|
||||
@@ -204,13 +209,14 @@ local function GetBestPocketingStrategy( Proc, Part)
|
||||
-- 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 = {}
|
||||
@@ -238,12 +244,21 @@ local function GetBestPocketingStrategy( Proc, Part)
|
||||
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)
|
||||
@@ -308,8 +323,42 @@ local function GetBestPocketingStrategy( Proc, Part)
|
||||
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)
|
||||
@@ -321,10 +370,10 @@ local function GetBestPocketingStrategy( Proc, Part)
|
||||
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
|
||||
@@ -549,8 +598,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
|
||||
@@ -559,11 +608,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
|
||||
@@ -593,10 +666,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
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
"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",
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
|
||||
@@ -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
|
||||
@@ -195,13 +202,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)
|
||||
@@ -223,10 +232,25 @@ 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
|
||||
|
||||
-- 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
|
||||
|
||||
-- riferimenti locali per leggibilità e performance
|
||||
local LongFace = Proc.MainFaces.LongFaces[1]
|
||||
local OppositeEdge1 = LongFace.MainEdges.OppositeEdges[1]
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
"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",
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
|
||||
@@ -112,8 +112,6 @@ 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
|
||||
@@ -138,10 +136,25 @@ function STR0004.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
|
||||
|
||||
-- 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
|
||||
|
||||
-- riferimenti locali per leggibilità e performance
|
||||
local LongFace = Proc.MainFaces.LongFaces[1]
|
||||
local OppositeEdge1 = LongFace.MainEdges.OppositeEdges[1]
|
||||
@@ -172,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)
|
||||
@@ -235,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
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
"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",
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"sStrategyName": "Milling",
|
||||
"ParameterList" : [
|
||||
{
|
||||
"sName": "dAntiSplintWithBlade",
|
||||
"sName": "bAntiSplintWithBlade",
|
||||
"sNameNge": "ANTISPLINT_BLADE",
|
||||
"sValue": "false",
|
||||
"sDescriptionShort": "Antisplint with blade",
|
||||
@@ -17,7 +17,27 @@
|
||||
"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",
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
},
|
||||
{
|
||||
"sName": "bFinishWithMill",
|
||||
"sNameNge": "ALLOW_FINISH_MILL",
|
||||
"sValue": "true",
|
||||
"sDescriptionShort": "Clean radius with mill",
|
||||
"sDescriptionLong": "Clean radius with mill",
|
||||
"sType": "b",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
},
|
||||
{
|
||||
"sName": "dMillingOffsetFromSide",
|
||||
"sNameNge": "MILLING_OFFSET_SIDE",
|
||||
"sValue": "1",
|
||||
"sDescriptionShort": "Milling offset from side",
|
||||
"sDescriptionLong": "",
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
|
||||
@@ -9,7 +9,9 @@ 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
|
||||
@@ -93,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
|
||||
@@ -112,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
|
||||
@@ -148,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
|
||||
@@ -172,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
|
||||
@@ -181,7 +208,7 @@ function STR0010.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
|
||||
-- controllo dimensioni solo se non è forzata
|
||||
if not CustomParameters.bForcedStrategy then
|
||||
if not IsPositionOK( Proc, Part) then
|
||||
if not IsPositionOk( Proc, Part) then
|
||||
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( 'Feature not machinable in this position')
|
||||
return false, Strategy.Result
|
||||
end
|
||||
@@ -198,8 +225,6 @@ function STR0010.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
-- volume della feature
|
||||
local dFeatureVolume = Proc.dVolume
|
||||
|
||||
-- TODO taglio su eventuali facce di chiusura
|
||||
|
||||
-- eventuali punti di spezzatura
|
||||
local FeatureSplittingPoints = FeatureLib.GetFeatureSplittingPoints( Proc, Part)
|
||||
local bIsSplitFeature = false
|
||||
@@ -212,41 +237,157 @@ 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
|
||||
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)
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"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",
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
|
||||
@@ -41,6 +41,11 @@ function TAILCUT.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
|
||||
-- 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
|
||||
@@ -89,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()
|
||||
|
||||
@@ -7,7 +7,7 @@ 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
|
||||
STR0008 = Svuotatura mortasa (raggiata)
|
||||
STR0009 = !!DEPRECATA!! Sostituita da STR0015. RIUTILIZZABILE!
|
||||
STR0010 = Fresatura perpendicolare (tipo cut, longcut)
|
||||
STR0011 = Foratura
|
||||
|
||||
@@ -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
|
||||
+240
-124
@@ -14,45 +14,63 @@ 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
|
||||
@@ -118,6 +136,76 @@ 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
|
||||
-- TODO scelta utensile è corretto lasciarla a FaceByBlade?
|
||||
@@ -126,12 +214,11 @@ function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters)
|
||||
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 ( not 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
|
||||
@@ -160,12 +247,7 @@ 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
|
||||
@@ -173,28 +255,26 @@ function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters)
|
||||
-- volume della feature
|
||||
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)
|
||||
@@ -203,92 +283,126 @@ function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters)
|
||||
bIsSplitFeature = true
|
||||
end
|
||||
|
||||
-- calcolo lavorazioni
|
||||
-- taglio eventuali facce di chiusura o seconda faccia
|
||||
for i = 1, #LongFaces do
|
||||
local Cutting = {}
|
||||
local OptionalParametersFaceByBlade = { bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail, 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)
|
||||
end
|
||||
|
||||
-- taglio con codolo faccia di fondo; si provano solo i lati a cui si può accedere (lato opposto aperto)
|
||||
-- TODO il check del lato opposto aperto andrà messo nella FaceByBlade
|
||||
-- TODO verificare se il calcolo del completamento (aggiunta lavorazioni applicabili/non) é corretto
|
||||
local dDepthToMachine = BottomEdgeToMachine.dElevation / 2 - dStripWidth / 2
|
||||
local OptionalParametersFaceByBlade1 = { dDepthToMachine = dDepthToMachine, bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail, nToolIndex = nToolIndex}
|
||||
local BottomEdgeToMachineOpposite = BeamLib.FindEdgeBestOrientedAsDirection( BottomFace.Edges, -BottomEdgeToMachine.vtN)
|
||||
-- primo lato
|
||||
if BottomEdgeToMachineOpposite.bIsOpen then
|
||||
Cutting1 = FaceByBlade.Make( Proc, Part, BottomFace, BottomEdgeToMachine, OptionalParametersFaceByBlade1)
|
||||
-- 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
|
||||
Cutting1.nInternalSortingPriority = 3
|
||||
Cutting1.dResultWeight = 0.3
|
||||
|
||||
-- secondo lato
|
||||
local OptionalParametersFaceByBlade2 = BeamLib.TableCopyDeep( OptionalParametersFaceByBlade1)
|
||||
OptionalParametersFaceByBlade2.OppositeToolDirectionMode = 'Enabled'
|
||||
if BottomEdgeToMachine.bIsOpen then
|
||||
Cutting2 = FaceByBlade.Make( Proc, Part, BottomFace, BottomEdgeToMachine, OptionalParametersFaceByBlade2)
|
||||
-- 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
|
||||
Cutting2.nInternalSortingPriority = 3
|
||||
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 la LongFace significa che la LongFace non é di chiusura ma un'altra faccia vera e propria
|
||||
-- ci si deve quindi fermare piú indietro
|
||||
for i = 1, #LongFaces do
|
||||
if BottomEdgeToMachine.idAdjacentFace == LongFaces[i].id then
|
||||
dStripWidth = TOOLS[Cutting2.nToolIndex].dThickness + 2 * dStripWidth
|
||||
break
|
||||
-- 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
|
||||
dDepthToMachine = min( TOOLS[Cutting2.nToolIndex].dMaxMaterial, BottomEdgeToMachine.dElevation - dStripWidth)
|
||||
OptionalParametersFaceByBlade2.dDepthToMachine = dDepthToMachine
|
||||
|
||||
Cutting2 = FaceByBlade.Make( Proc, Part, BottomFace, BottomEdgeToMachine, OptionalParametersFaceByBlade2)
|
||||
Cutting2.nInternalSortingPriority = 3
|
||||
Cutting2.dResultWeight = 0.3
|
||||
table.insert( CalculatedMachinings, Cutting2)
|
||||
|
||||
elseif not Cutting2.bIsApplicable and Cutting1.bIsApplicable then
|
||||
|
||||
-- se si lavora il lato in comune con la LongFace significa che la LongFace non é di chiusura ma un'altra faccia vera e propria
|
||||
-- ci si deve quindi fermare piú indietro
|
||||
for i = 1, #LongFaces do
|
||||
if BottomEdgeToMachine.idAdjacentFace == LongFaces[i].id then
|
||||
dStripWidth = TOOLS[Cutting1.nToolIndex].dThickness + 2 * dStripWidth
|
||||
break
|
||||
end
|
||||
end
|
||||
dDepthToMachine = min( TOOLS[Cutting1.nToolIndex].dMaxMaterial, BottomEdgeToMachine.dElevation - dStripWidth)
|
||||
OptionalParametersFaceByBlade1.dDepthToMachine = dDepthToMachine
|
||||
|
||||
Cutting1 = FaceByBlade.Make( Proc, Part, BottomFace, BottomEdgeToMachine, OptionalParametersFaceByBlade1)
|
||||
Cutting1.nInternalSortingPriority = 3
|
||||
Cutting1.dResultWeight = 0.3
|
||||
table.insert( CalculatedMachinings, Cutting1)
|
||||
|
||||
else
|
||||
table.insert( CalculatedMachinings, Cutting1)
|
||||
table.insert( CalculatedMachinings, Cutting2)
|
||||
end
|
||||
|
||||
-- fresatura eventuali facce di chiusura
|
||||
-- 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
|
||||
if BottomEdgeToMachine.idAdjacentFace ~= LongFaces[i].id then
|
||||
local dDepthToMachineMill = BottomFace.MainEdges.LongEdges[i].dElevation - dMillingOffsetFromSide
|
||||
local dToolMarkLength = max( Cutting1.dToolMarkLength or 0, Cutting2.dToolMarkLength or 0)
|
||||
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
|
||||
|
||||
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
|
||||
@@ -317,7 +431,9 @@ 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)
|
||||
|
||||
@@ -801,13 +801,16 @@ local function CalculateDiceMachinings( vCuts, Parameters)
|
||||
for i = 1, #vCuts do
|
||||
for j = 1, #vCuts[i] do
|
||||
SetDiceFaceInfo( Proc, vCuts[i][j])
|
||||
if ( i % 2) == 1 then
|
||||
local vtO = EgtSurfTmFacetNormVersor( vCuts[i][j], 0, GDB_ID.ROOT)
|
||||
if MachiningLib.IsFaceZOutOfRange( vtO, Tool) then
|
||||
EgtInvertSurf( vCuts[i][j])
|
||||
bAreOrthogonalCutsInverted = true
|
||||
end
|
||||
end
|
||||
-- TODO vedere se questa parte serve ancora; in teoria no perchè il taglio è girato automaticamente nella FaceByBlade
|
||||
-- if ( i % 2) == 1 then
|
||||
-- local vtO = EgtSurfTmFacetNormVersor( vCuts[i][j], 0, GDB_ID.ROOT)
|
||||
-- if MachiningLib.IsFaceZOutOfRange( vtO, Tool) then
|
||||
-- EgtInvertSurf( vCuts[i][j])
|
||||
-- local vtCurrentFaceNormal = EgtSurfTmFacetNormVersor( vCuts[i][j], 0, GDB_ID.ROOT)
|
||||
-- EgtMove( vCuts[i][j], -vtCurrentFaceNormal * Tool.dThickness, GDB_RT.GLOB)
|
||||
-- bAreOrthogonalCutsInverted = true
|
||||
-- end
|
||||
-- end
|
||||
end
|
||||
end
|
||||
-- calcolo lavorazioni
|
||||
@@ -1215,14 +1218,21 @@ function BLADETOWASTE.Make( ProcOrId, Part, OptionalParameters)
|
||||
else
|
||||
-- per ogni faccia si calcola la lavorazione
|
||||
for i = 1, #Proc.Faces do
|
||||
-- ricerca lato in comune da lavorare
|
||||
-- ricerca lato in comune da lavorare; se non trovato è una feature splittata (DoubleBevel) e il lato sarà scelto della GetSingleCutStratetegy
|
||||
local nCommonEdgeIndex
|
||||
for j = 1, #Proc.Faces[i].Edges do
|
||||
if Proc.Faces[i].Edges[j].idAdjacentFace > -1 then
|
||||
nCommonEdgeIndex = j
|
||||
end
|
||||
end
|
||||
local EdgeToMachine = Proc.Faces[i].Edges[nCommonEdgeIndex]
|
||||
local EdgeToMachine
|
||||
if nCommonEdgeIndex then
|
||||
EdgeToMachine = Proc.Faces[i].Edges[nCommonEdgeIndex]
|
||||
end
|
||||
local EdgeToMachineList
|
||||
if EdgeToMachine then
|
||||
EdgeToMachineList = { Top = EdgeToMachine, Bottom = EdgeToMachine}
|
||||
end
|
||||
|
||||
-- scelta lama
|
||||
local nToolIndex = OptionalParameters.nToolIndex
|
||||
@@ -1230,11 +1240,11 @@ function BLADETOWASTE.Make( ProcOrId, Part, OptionalParameters)
|
||||
local OptionalParametersGetSingleCutStrategy = {
|
||||
bReduceBladePath = false,
|
||||
nFaceToMachineIndex = i,
|
||||
EdgeToMachineList = { Top = EdgeToMachine, Bottom = EdgeToMachine},
|
||||
EdgeToMachineList = EdgeToMachineList,
|
||||
sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation,
|
||||
bCannotSplitRestLength = bCannotSplitRestLength
|
||||
}
|
||||
nToolIndex = GetSingleCutStrategy( Proc, Part, OptionalParametersGetSingleCutStrategy)
|
||||
nToolIndex, EdgeToMachine = GetSingleCutStrategy( Proc, Part, OptionalParametersGetSingleCutStrategy)
|
||||
end
|
||||
|
||||
-- se lama non trovata si provano i cubetti
|
||||
|
||||
@@ -72,6 +72,12 @@ local function GetLeadInOut( Machining, EdgeToMachine, bIsSplitFeature)
|
||||
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
|
||||
@@ -285,16 +291,18 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
|
||||
|
||||
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)
|
||||
-- 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
|
||||
-- return Cutting, EdgeToMachine.dElevation
|
||||
-- end
|
||||
-- end
|
||||
|
||||
-- parametri della lavorazione
|
||||
|
||||
@@ -320,7 +328,6 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
|
||||
Cutting.bInvert = not Cutting.bInvert
|
||||
end
|
||||
|
||||
-- TODO al momento commentato per trovare i casi in cui nei riposizionamenti scende sul pezzo; poi valutare se lasciare o togliere
|
||||
-- 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)
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
local BeamLib = require( 'BeamLib')
|
||||
local BeamData = require( 'BeamDataNew')
|
||||
local MachiningLib = require( 'MachiningLib')
|
||||
local PreSimulationLib = require( 'PreSimulationLib')
|
||||
|
||||
-- Tabella per definizione modulo
|
||||
local FACEBYCHAINSAW = {}
|
||||
@@ -42,6 +43,10 @@ local function CalculateLeadInOut( Machining, EdgeToMachine, sSideToMachine, dLe
|
||||
LeadOut.dEndAddLength = BeamData.CUT_EXTRA
|
||||
end
|
||||
|
||||
-- punti dell'attacco
|
||||
LeadIn.ptPoint = EdgeToMachine.ptStart - EdgeToMachine.vtEdge * LeadIn.dStartAddLength + EdgeToMachine.vtN * ( EdgeToMachine.dElevation - Machining.dDepthToMachine)
|
||||
LeadOut.ptPoint = EdgeToMachine.ptEnd + EdgeToMachine.vtEdge * LeadOut.dEndAddLength + EdgeToMachine.vtN * ( EdgeToMachine.dElevation - Machining.dDepthToMachine)
|
||||
|
||||
return LeadIn, LeadOut
|
||||
end
|
||||
|
||||
@@ -196,9 +201,28 @@ function FACEBYCHAINSAW.Make( Proc, Part, FaceToMachine, EdgeToMachine, Optional
|
||||
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)
|
||||
-- TODO al momento si contempla solo sega a catena con asse bloccato
|
||||
else
|
||||
Mortising.bIsApplicable = false
|
||||
return Mortising
|
||||
end
|
||||
-- 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)
|
||||
if bOutOfStroke then
|
||||
Mortising.sMessage = 'Out of stroke'
|
||||
Mortising.bIsApplicable = false
|
||||
return Mortising
|
||||
end
|
||||
-- eventuale step verticale
|
||||
Mortising.CloneStepsLongitudinal = {}
|
||||
if not dLongitudinalStepSpan then
|
||||
@@ -211,7 +235,7 @@ function FACEBYCHAINSAW.Make( Proc, Part, FaceToMachine, EdgeToMachine, Optional
|
||||
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())
|
||||
|
||||
Reference in New Issue
Block a user