Merge branch 'CuttingImprovements' into develop

This commit is contained in:
luca.mazzoleni
2025-11-11 14:51:12 +01:00
18 changed files with 672 additions and 401 deletions
+11 -4
View File
@@ -235,7 +235,8 @@ elseif BEAM.FLAG == 9 then
local Part = {}
Part.id = EgtGetParent( EgtGetParent( BEAM.FEATUREID))
Part.b3Part = EgtGetBBoxGlob( EgtGetFirstNameInGroup( Part.id, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
Part.idBoxTm = EgtGetFirstInGroup( EgtGetFirstNameInGroup( Part.id, 'Box') or GDB_ID.NULL)
Part.b3Part = EgtGetBBoxGlob( Part.idBoxTm, GDB_BB.STANDARD)
local Proc = FeatureLib.GetProcFromTrimesh( BEAM.FEATUREID, Part)
Proc.nGrp = EgtGetInfo( Proc.id, 'GRP', 'i')
@@ -573,7 +574,8 @@ if bToProcess then
PARTS[i].dRawWidth = PARTS[i].b3Raw:getDimY()
PARTS[i].dRawHeight = PARTS[i].b3Raw:getDimZ()
-- dimensione pezzo finito
PARTS[i].b3Part = EgtGetBBoxGlob( EgtGetFirstNameInGroup( PARTS[i].id, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
PARTS[i].idBoxTm = EgtGetFirstInGroup( EgtGetFirstNameInGroup( PARTS[i].id, 'Box') or GDB_ID.NULL)
PARTS[i].b3Part = EgtGetBBoxGlob( PARTS[i].idBoxTm, GDB_BB.STANDARD)
PARTS[i].dLength = PARTS[i].b3Part:getDimX()
PARTS[i].dWidth = PARTS[i].b3Part:getDimY()
PARTS[i].dHeight = PARTS[i].b3Part:getDimZ()
@@ -670,8 +672,13 @@ if bToProcess then
sMsg = string.gsub( sMsg or '', '\r', ' ', 10)
-- trovata almeno una strategia e feature lavorata completamente
if RESULT[i].sType == 'Feature' and RESULT[i].ChosenStrategy.sStatus == 'Completed' then
BEAM.ERR = 0
BEAM.MSG = '---'
if #EgtTrim( sMsg) > 0 then
BEAM.ERR = -19
BEAM.MSG = sMsg
else
BEAM.ERR = 0
BEAM.MSG = '---'
end
BEAM.ROT = -( RESULT[i].nRotation or 1) + 1
BEAM.CUTID = RESULT[i].idCut
BEAM.TASKID = RESULT[i].idTask
+16 -25
View File
@@ -477,7 +477,8 @@ function BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, dOvmMid, PARTS, b
PARTS[i].dWidth = PARTS[i].b3Raw:getDimY()
PARTS[i].dHeight = PARTS[i].b3Raw:getDimZ()
PARTS[i].bSquareSection = abs( PARTS[i].dWidth - PARTS[i].dHeight) < 100 * GEO.EPS_SMALL
PARTS[i].b3Part = EgtGetBBoxGlob( EgtGetFirstNameInGroup( PARTS[i].id, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
PARTS[i].idBoxTm = EgtGetFirstInGroup( EgtGetFirstNameInGroup( PARTS[i].id, 'Box') or GDB_ID.NULL)
PARTS[i].b3Part = EgtGetBBoxGlob( PARTS[i].idBoxTm, GDB_BB.STANDARD)
PARTS[i].nIndexInParts = i
PARTS[i].SplittingPoints = BeamLib.GetPartSplittingPoints( PARTS[i])
PARTS[i].NotClampableLength = { STD = { dHead = 0, dTail = 0}, SIDE = { dHead = 0, dTail = 0}, DOWN = { dHead = 0, dTail = 0}}
@@ -715,6 +716,7 @@ local function AreDrillingsMirrored( Proc, ProcMirror, Part)
if AreOppositeVectorApprox( vtExtr, vtExtrMirror) then
-- fori lungo Y
-- per macchine tipo PF il foro principale è sul lato back, per macchine tipo PF1250 è sul lato front
-- TODO eliminare i riferimenti a DOWN_HEAD e TWO_EQUAL_HEADS e sostituirli con check iniziale sulla disponibilità di teste?
if ( BeamData.TWO_EQUAL_HEADS and AreSameVectorApprox( vtExtr, Y_AX())) or
( BeamData.DOWN_HEAD and AreOppositeVectorApprox( vtExtr, Y_AX())) then
nDouble = 2
@@ -791,6 +793,7 @@ local function GetFeatureInfoAndDependency( vProcSingleRot, Part)
Proc.bPassedByHole = true
end
-- verifiche per specchiature
-- TODO eliminare i riferimenti a DOWN_HEAD e TWO_EQUAL_HEADS e sostituirli con check iniziale sulla disponibilità di teste?
if BeamData.DOWN_HEAD or BeamData.TWO_EQUAL_HEADS then
-- forature
if BeamData.DOUBLE_HEAD_DRILLING and ID.IsDrill( Proc) and ID.IsDrill( ProcB) and not Proc.Mirror then
@@ -1145,7 +1148,7 @@ local function CalculateMachinings( vProc, Part, nInitialRotation)
end
-- aggiorno info pezzo
Part.b3Raw = EgtGetRawPartBBox( Part.idRaw)
Part.b3Part = EgtGetBBoxGlob( EgtGetFirstNameInGroup( Part.id, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
Part.b3Part = EgtGetBBoxGlob( Part.idBoxTm, GDB_BB.STANDARD)
-- si applicano le strategie
if Proc.ChosenStrategy then
-- carico file script strategia (non serve verificare presenza del file perchè già fatto durante scelta strategia)
@@ -1171,7 +1174,7 @@ local function CalculateMachinings( vProc, Part, nInitialRotation)
BeamLib.RotateRawPart( Part, 1 - nCurrRotation)
-- aggiorno info pezzo
Part.b3Raw = EgtGetRawPartBBox( Part.idRaw)
Part.b3Part = EgtGetBBoxGlob( EgtGetFirstNameInGroup( Part.id, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
Part.b3Part = EgtGetBBoxGlob( Part.idBoxTm, GDB_BB.STANDARD)
end
return MACHININGS, bAreAllApplyOk
end
@@ -1204,7 +1207,8 @@ function BeamExec.GetProcessings( PARTS, bCalcBestPieceUnloadPosition)
if not PARTS[nPart].id and PARTS[nPart].b3Raw:getDimX() < BeamData.dMinRaw then break end
local vProcRot = {}
local nCycles = EgtIf( bCalcBestPieceUnloadPosition, 2, 1) -- se è prerotazione, oltre al ciclo normale, si devono verificare anche invertiti
-- se è prerotazione, oltre al ciclo normale, si devono verificare anche invertiti
local nCycles = EgtIf( bCalcBestPieceUnloadPosition and PARTS[nPart].GeneralParameters.GEN_sPiecesLoadingPosition ~= 'BTL_POSITION', 2, 1)
-- per ogni inversione
for nInvertIndex = 1, nCycles do
-- per ogni rotazione
@@ -1227,14 +1231,14 @@ function BeamExec.GetProcessings( PARTS, bCalcBestPieceUnloadPosition)
BeamLib.RotateRawPart( PARTS[nPart], 1)
-- aggiorno info pezzo
PARTS[nPart].b3Raw = EgtGetRawPartBBox( PARTS[nPart].idRaw)
PARTS[nPart].b3Part = EgtGetBBoxGlob( EgtGetFirstNameInGroup( PARTS[nPart].id, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
PARTS[nPart].b3Part = EgtGetBBoxGlob( PARTS[nPart].idBoxTm, GDB_BB.STANDARD)
end
if bCalcBestPieceUnloadPosition then
if bCalcBestPieceUnloadPosition and PARTS[nPart].GeneralParameters.GEN_sPiecesLoadingPosition ~= 'BTL_POSITION' then
-- inversione pezzo testa-coda
BeamLib.InvertRawPart( PARTS[nPart], 2)
-- aggiorno info pezzo
PARTS[nPart].b3Raw = EgtGetRawPartBBox( PARTS[nPart].idRaw)
PARTS[nPart].b3Part = EgtGetBBoxGlob( EgtGetFirstNameInGroup( PARTS[nPart].id, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
PARTS[nPart].b3Part = EgtGetBBoxGlob( PARTS[nPart].idBoxTm, GDB_BB.STANDARD)
end
end
local Part = {}
@@ -1528,7 +1532,7 @@ end
function BeamExec.GetCombinationMatrix( PARTS, bCalcBestPieceUnloadPosition)
-- ricerca strategia di lavorazione per ogni pezzo e applicazione lavorazioni
for nPart = 1, #PARTS do
local nCycles = EgtIf( bCalcBestPieceUnloadPosition, 2, 1)
local nCycles = EgtIf( bCalcBestPieceUnloadPosition and PARTS[nPart].GeneralParameters.GEN_sPiecesLoadingPosition ~= 'BTL_POSITION', 2, 1)
-- per ogni inversione
for nInvertIndex = 1, nCycles do
-- calcolo della migliore strategia per ogni rotazione del pezzo
@@ -1543,14 +1547,14 @@ function BeamExec.GetCombinationMatrix( PARTS, bCalcBestPieceUnloadPosition)
BeamLib.RotateRawPart( PARTS[nPart], 1)
-- aggiorno info pezzo
PARTS[nPart].b3Raw = EgtGetRawPartBBox( PARTS[nPart].idRaw)
PARTS[nPart].b3Part = EgtGetBBoxGlob( EgtGetFirstNameInGroup( PARTS[nPart].id, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
PARTS[nPart].b3Part = EgtGetBBoxGlob( PARTS[nPart].idBoxTm, GDB_BB.STANDARD)
end
if bCalcBestPieceUnloadPosition then
if bCalcBestPieceUnloadPosition and PARTS[nPart].GeneralParameters.GEN_sPiecesLoadingPosition ~= 'BTL_POSITION' then
-- inversione del pezzo testa-coda
BeamLib.InvertRawPart( PARTS[nPart], 2)
-- aggiorno info pezzo
PARTS[nPart].b3Raw = EgtGetRawPartBBox( PARTS[nPart].idRaw)
PARTS[nPart].b3Part = EgtGetBBoxGlob( EgtGetFirstNameInGroup( PARTS[nPart].id, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
PARTS[nPart].b3Part = EgtGetBBoxGlob( PARTS[nPart].idBoxTm, GDB_BB.STANDARD)
end
end
end
@@ -1702,21 +1706,8 @@ function BeamExec.ProcessMachinings( PARTS)
bAllStrategiesApplied = false
MACHININGS, bAllStrategiesApplied = CalculateMachinings( vProcHeadTail, PARTS[nPart], MatrixResult.nInitialPosition)
-- cancellazione entità create ma non usate
-- TODO funzione?
local idAddGroup = BeamLib.GetAddGroup( PARTS[nPart].id)
local idCurrentEntity = EgtGetFirstInGroup( idAddGroup or GDB_ID.NULL)
while idCurrentEntity do
if EgtGetLevel( idCurrentEntity) == GDB_LV.TEMP then
local idEntityToDelete = idCurrentEntity
idCurrentEntity = EgtGetNext( idCurrentEntity)
EgtErase( idEntityToDelete)
else
idCurrentEntity = EgtGetNext( idCurrentEntity)
end
end
-- ordinamento lavorazioni
-- TODO sostituire con sorting Egt
-- TODO completare ordinamento. Mancano le dipendenze.
-- TODO la FinalizeSorting andrebbe rimossa e usato un sorting che non viola le dipendenze
MACHININGS = MachiningLib.PrepareMachiningsForSorting( PARTS[nPart])
+35 -31
View File
@@ -16,7 +16,7 @@ local BeamData = require( 'BeamData')
----------------------------------------------------------------------------------------------------------------------------------------------------
-- creo i piani paralleli
-- GetParallelPlanes: restituisce un vettore con gli indici delle superfici
-- nAddGrpId: il layer
-- idAddGroup: il layer
-- b3BoxDicing: il grezzo della barra
-- ptC: il punto centrale del piano della feature
-- vtN: il versore normale del piano della feature
@@ -30,7 +30,7 @@ local BeamData = require( 'BeamData')
-- vtNCut*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso)
-- ptCCut1*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso)
-- vtNCut1*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso)
local function GetParallelPlanes( nAddGrpId, b3BoxDicing, ptC, vtN, nCopyPlane, dOffset, nStep, Color, dTolerance, bNoTolOnFirstCut, ptCCut, vtNCut, ptCCut1, vtNCut1 )
local function GetParallelPlanes( idAddGroup, b3BoxDicing, ptC, vtN, nCopyPlane, dOffset, nStep, Color, dTolerance, bNoTolOnFirstCut, ptCCut, vtNCut, ptCCut1, vtNCut1 )
local ptMyCCut
local AreaMin = 5*5
if ptCCut and vtNCut then
@@ -46,7 +46,7 @@ local function GetParallelPlanes( nAddGrpId, b3BoxDicing, ptC, vtN, nCopyPlane,
local TabellaTmSurfParallel = {}
local i = nCopyPlane
while i < nStep do
local SurfId = EgtSurfTmPlaneInBBox( nAddGrpId, ptC + ( i * dOffset) * vtN, vtN, b3BoxDicing, GDB_RT.GLOB)
local SurfId = EgtSurfTmPlaneInBBox( idAddGroup, ptC + ( i * dOffset) * vtN, vtN, b3BoxDicing, GDB_RT.GLOB)
local nFacet = EgtSurfTmFacetCount( SurfId or GDB_ID.NULL)
if nFacet == 0 then
-- se sono al primo taglio do una possibilità in più di girare
@@ -86,11 +86,11 @@ end
----------------------------------------------------------------------------------------------------------------------------------------------------
-- GetOrderedCutTable:
-- nAddGrpId: il layer
-- idAddGroup: il layer
-- TabParallelPlanes: tabella delle superfici dei piani paralleli
-- TabOrtoPlanes: tabella delle superfici dei piani ortogonali
-- stampo l'ordine dei piani di taglio (prima tagli ortogonali piu' esterni poi taglio parallelo collettivo)
local function GetOrderedCutTable( nAddGrpId, TabParallelPlanes, TabOrtoPlanes)
local function GetOrderedCutTable( idAddGroup, TabParallelPlanes, TabOrtoPlanes)
local StepParallel = #TabParallelPlanes
local StepOrto = #TabOrtoPlanes
local TabellaOrderParallelCut1 = {}
@@ -99,8 +99,8 @@ local function GetOrderedCutTable( nAddGrpId, TabParallelPlanes, TabOrtoPlanes)
TabellaOrderParallelCut1[IndexTmP] = {}
for IndexOrto=1, StepOrto do
local ptOrtoN, vtNOrtoN = EgtSurfTmFacetCenter( TabOrtoPlanes[IndexOrto ], 0, GDB_ID.ROOT)
local Copy1Id = EgtCopySurfTmFacet( TabParallelPlanes[IndexTmP], 0, nAddGrpId)
local Copy2Id = EgtCopySurfTmFacet( TabParallelPlanes[IndexTmP], 0, nAddGrpId)
local Copy1Id = EgtCopySurfTmFacet( TabParallelPlanes[IndexTmP], 0, idAddGroup)
local Copy2Id = EgtCopySurfTmFacet( TabParallelPlanes[IndexTmP], 0, idAddGroup)
if Copy1Id and ptOrtoN then
EgtCutSurfTmPlane( Copy1Id, ptOrtoN, -vtNOrtoN, false, GDB_RT.GLOB)
EgtCutSurfTmPlane( Copy2Id, ptOrtoN, vtNOrtoN, false, GDB_RT.GLOB)
@@ -134,7 +134,7 @@ end
-- vtO: il versore dei piani ortogonali
-- dOffsetEff: offset della distanza dal punto centrale
-- Verifica se l'asse X del box costruito sopra la superficie è più grande di un certo offset
local function GetOrtoCutCenter( FacetId, ptC, vtN, vtO, dOffsetEff, dMinNzDownUp)
local function GetOrtoCutCenter( FacetId, ptC, vtN, vtO, dOffsetEff)
local FrameLocal = Frame3d( EgtSurfTmFacetCenter( FacetId, 0, GDB_ID.ROOT))
EgtSetGridFrame(FrameLocal)
local IdAuxLocal = EgtGroup(EgtGetParent( FacetId), FrameLocal)
@@ -156,7 +156,7 @@ local function GetOrtoCutCenter( FacetId, ptC, vtN, vtO, dOffsetEff, dMinNzDownU
-- TODO si può eliminare questo test dato che vengono verificate già volume e dimensione del cubetto??
local dMaxLen = BeamData.MAX_LEN_DICE or 600
if dLen < dMaxLen and dWidth < dMaxLen and
( dLen < dOffsetEff + 1.0 or dWidth < dOffsetEff + 1.0) and vtN:getZ() > dMinNzDownUp then
( dLen < dOffsetEff + 1.0 or dWidth < dOffsetEff + 1.0) then
return nil, nil, nil
end
@@ -261,7 +261,7 @@ end
-- dOffsetParallel: offset della distanza dal punto centrale
-- b3BoxDicing: il grezzo della barra
-- Verifica se l'asse X del box costruito sopra le 2 facce è più piccolo di un certo offset e quindi la faccia O è superflua
local function VerifyFirstOrthoCut( CutTable, dOffsetParallel, b3BoxDicing, dMinNzDownUp)
local function VerifyFirstOrthoCut( CutTable, dOffsetParallel, b3BoxDicing)
if not CutTable[1] or not CutTable[2] then return end
@@ -294,9 +294,9 @@ local function VerifyFirstOrthoCut( CutTable, dOffsetParallel, b3BoxDicing, dMin
-- lunghezza totale faccia
local dLongSize = x1 + x2
-- se faccia piccola e non orientata verso il basso, elimino ortogonale e unisco le due parti
if dLongSize <= dOffsetParallel + 1.0 and vtN1:getZ() > dMinNzDownUp then
local nAddGrpId = EgtGetParent( Cut1Id)
local SurfId = EgtSurfTmBySewing( nAddGrpId, { Cut1Id, Cut2Id})
if dLongSize <= dOffsetParallel + 1.0 then
local idAddGroup = EgtGetParent( Cut1Id)
local SurfId = EgtSurfTmBySewing( idAddGroup, { Cut1Id, Cut2Id})
--EgtSetColor( SurfId, Color3d( FUCHSIA(), 60))
EgtErase( CutOId)
table.remove( CutTable[1], 1)
@@ -338,7 +338,7 @@ end
----------------------------------------------------------------------------------------------------------------------------------------------------
-- ricavo l'altezza del BoundingBox assegnati gli estremi del grezzo e la feature
-- le funzioni commentate permettono di vedere la creazione di BoundingBox
local function DistanzaMassima( nAddGrpId, ptC1, vtN1, ptC2, vtN2, b3BoxDicing, TPoint)
local function DistanzaMassima( idAddGroup, ptC1, vtN1, ptC2, vtN2, b3BoxDicing, TPoint)
-- calcolo il riferimento nel piano 1
local Frame1 = Frame3d( ptC1, vtN1)
-- determino l'ingombro in questo riferimento della parte di trave compresa nel o nei piani
@@ -353,7 +353,7 @@ local function DistanzaMassima( nAddGrpId, ptC1, vtN1, ptC2, vtN2, b3BoxDicing,
end
-- eventuale altra faccia
if ptC2 and vtN2 then
local IdAux = EgtGroup( nAddGrpId)
local IdAux = EgtGroup( idAddGroup)
local IdSurf2 = EgtSurfTmPlaneInBBox( IdAux, ptC2, vtN2, b3BoxDicing, GDB_RT.GLOB)
EgtCutSurfTmPlane( IdSurf2, ptC1, -vtN1, false, GDB_RT.GLOB)
if IdSurf2 then
@@ -394,7 +394,12 @@ end
---------------------------------------------------------------------------------------------------------------
function DiceCut.GetDice( Part, Face1, Face2, OptionalParameters)
-- gruppo per geometria addizionale
local nAddGrpId = BeamLib.GetAddGroup( Part.id)
local idAddGroup
if OptionalParameters.bSaveAddedGeometries then
idAddGroup = BeamLib.GetAddGroup( Part.id)
else
idAddGroup = BeamLib.GetTempGroup()
end
-- faccia primaria
local ptCMainFace
@@ -430,8 +435,6 @@ function DiceCut.GetDice( Part, Face1, Face2, OptionalParameters)
local nStepOrthogonal = OptionalParameters.nStepOrthogonal or 100
-- distanza tra piani paralleli e piani di taglio (era sempre 0, serve???)
local dTolerance = OptionalParameters.dTolerance or 0
-- inclinazione limite per taglio da sotto
local dMinNzDownUp = OptionalParameters.dMinNzDownUp or -2
--Ricavo le altezze dei BoundingBox contenente feature e estremi del grezzo
local TBoxPoint = CalcolaPuntiEstremiBox( b3BoxDicing)
@@ -439,14 +442,15 @@ function DiceCut.GetDice( Part, Face1, Face2, OptionalParameters)
if ptCSubordinateFace and vtNSubordinateFace then
TBoxPoint = VerificaEstremiGrezzo( ptCSubordinateFace, vtNSubordinateFace, TBoxPoint)
end
local dElevP = DistanzaMassima( nAddGrpId, ptCMainFace, vtNMainFace, ptCSubordinateFace, vtNSubordinateFace, b3BoxDicing, TBoxPoint)
local dElevP = DistanzaMassima( idAddGroup, ptCMainFace, vtNMainFace, ptCSubordinateFace, vtNSubordinateFace, b3BoxDicing, TBoxPoint)
local dElevO
if ptCSubordinateFace and vtNSubordinateFace and not AreOppositeVectorApprox( vtNSubordinateFace, vtNMainFace) then
dElevO = DistanzaMassima( nAddGrpId, ptCSubordinateFace, vtNSubordinateFace, ptCMainFace, vtNMainFace, b3BoxDicing, TBoxPoint)
dElevO = DistanzaMassima( idAddGroup, ptCSubordinateFace, vtNSubordinateFace, ptCMainFace, vtNMainFace, b3BoxDicing, TBoxPoint)
end
-- TODO parte sotto da aggiungere???? se sì va passata anche la dimensione cubetto ridotta dOffsetOrthogonalReduced
-- se non c'è testa da sotto e normali senza componenti in Y con faccia quasi verticale e trave non alta, uso per offset i limiti dei tagli di testa e coda
-- TODO eliminare i riferimenti a DOWN_HEAD e TWO_EQUAL_HEADS e sostituirli con check iniziale sulla disponibilità di teste?
-- if not BD.TURN and not BD.DOWN_HEAD and abs( vtNPlanes:getY()) < 0.1 and vtNPlanes:getZ() < 0.7071 and ( not vtNBond or abs( vtNBond:getY()) < 0.1) and BBoxRawPart:getDimZ() < BD.MIN_DIM_HBEAM then
-- dOffsetOrthogonal = dOffsetOrthogonalReduced
-- end
@@ -476,7 +480,7 @@ function DiceCut.GetDice( Part, Face1, Face2, OptionalParameters)
-- PIANI PARALLELI alla faccia di taglio
local TabellaTmSurfP = {}
local TabFromIn = GetParallelPlanes( nAddGrpId, b3BoxDicing, ptCMainFace, vtNMainFace, 0, dOffsetParallel, nStepParallel, Color3d( FUCHSIA(), 60), dTolerance, true, ptCSubordinateFace, vtNSubordinateFace)
local TabFromIn = GetParallelPlanes( idAddGroup, b3BoxDicing, ptCMainFace, vtNMainFace, 0, dOffsetParallel, nStepParallel, Color3d( FUCHSIA(), 60), dTolerance, true, ptCSubordinateFace, vtNSubordinateFace)
for i = #TabFromIn, 1, -1 do
table.insert( TabellaTmSurfP, TabFromIn[i])
end
@@ -485,12 +489,12 @@ function DiceCut.GetDice( Part, Face1, Face2, OptionalParameters)
-- orientamento definito da seconda faccia
if not bGetOrtoPlanes then
local TabellaTmSurfOrto = {}
local TabFromIn = GetParallelPlanes( nAddGrpId, b3BoxDicing, ptCSubordinateFace, vtNSubordinateFace, 0, dOffsetOrthogonal, nStepOrthogonal, Color3d( GREEN(), 60), dTolerance, false, ptCMainFace, vtNMainFace)
local TabFromIn = GetParallelPlanes( idAddGroup, b3BoxDicing, ptCSubordinateFace, vtNSubordinateFace, 0, dOffsetOrthogonal, nStepOrthogonal, Color3d( GREEN(), 60), dTolerance, false, ptCMainFace, vtNMainFace)
for i = #TabFromIn, 1, -1 do
table.insert( TabellaTmSurfOrto, TabFromIn[i])
end
local TabellaOrderParallelCut = GetOrderedCutTable( nAddGrpId, TabellaTmSurfP, TabellaTmSurfOrto) -- Ottiene la tabella dei tagli paralleli ordinati
local TabellaOrderOrtoCut = GetOrderedCutTable( nAddGrpId, TabellaTmSurfOrto, TabellaTmSurfP) -- Ottiene la tabella dei tagli ortogonali da riordinare per strato
local TabellaOrderParallelCut = GetOrderedCutTable( idAddGroup, TabellaTmSurfP, TabellaTmSurfOrto) -- Ottiene la tabella dei tagli paralleli ordinati
local TabellaOrderOrtoCut = GetOrderedCutTable( idAddGroup, TabellaTmSurfOrto, TabellaTmSurfP) -- Ottiene la tabella dei tagli ortogonali da riordinare per strato
TabGREEN = SortOrtoCutsByNormalMethod( TabellaOrderParallelCut, TabellaOrderOrtoCut) -- I tagli ortogonali vengono ordinati per strato
TabFUCHSIA = TabellaOrderParallelCut -- I tagli paralleli sono già ordinati
@@ -508,10 +512,10 @@ function DiceCut.GetDice( Part, Face1, Face2, OptionalParameters)
end
-- calcolo la direzione dei piani ortogonali
local vtO = VectorFromUprightOrtho( vtNInner)
if vtNInner:getZ() > -0.0175 or vtNInner:getZ() < dMinNzDownUp or abs( vtNInner:getY()) > 0.8 then
if vtNInner:getZ() > -0.0175 or abs( vtNInner:getY()) > 0.8 then
vtO:rotate( vtNInner, 90)
-- se diretto troppo ortogonalmente all'asse trave e taglio non da sotto, lo ruoto ulteriormente
if ( abs( vtO:getY()) > 4 * abs( vtO:getX()) or b3BoxDicing:getDimZ() > 620) and vtNInner:getZ() > dMinNzDownUp then
if ( abs( vtO:getY()) > 4 * abs( vtO:getX()) or b3BoxDicing:getDimZ() > 620) then
vtO:rotate( vtNInner, 90)
-- se faccia principale verso il basso (almeno -3deg), lo inverto per iniziare da sopra
if vtNInner:getZ() < -0.05 then
@@ -533,16 +537,16 @@ function DiceCut.GetDice( Part, Face1, Face2, OptionalParameters)
-- CopyPlane: 0 => crea la prima faccia direttamente sul punto passato
-- CopyPlane: 1 => crea la prima faccia e tutte le altre con l'offset passato
-- CopyPlane: 0.5 => crea la prima faccia a metà offset e tutte le altre con l'offest intero
local OffsetRel, CopyPlane, dCenOffs, ptCStart = GetOrtoCutCenter( TabellaTmSurfP[PlnInd], ptCInner, vtNInner, vtO, dOffsetOrthogonal, dMinNzDownUp)
local OffsetRel, CopyPlane, dCenOffs, ptCStart = GetOrtoCutCenter( TabellaTmSurfP[PlnInd], ptCInner, vtNInner, vtO, dOffsetOrthogonal)
if OffsetRel and CopyPlane and dCenOffs then
ptCInner = ptCInner + dCenOffs * vtO
local TabRight = GetParallelPlanes( nAddGrpId, b3BoxDicing, ptCStart, vtO, CopyPlane, -OffsetRel, nStepOrthogonal, Color3d( GREEN(), 60),
local TabRight = GetParallelPlanes( idAddGroup, b3BoxDicing, ptCStart, vtO, CopyPlane, -OffsetRel, nStepOrthogonal, Color3d( GREEN(), 60),
dTolerance, false, ptCInner, vtNInner, ptCOuter, vtNOuter)
if CopyPlane == 0 then
CopyPlane = 1
end
local TabLeft = GetParallelPlanes( nAddGrpId, b3BoxDicing, ptCStart, vtO, CopyPlane, OffsetRel, nStepOrthogonal, Color3d( GREEN(), 60),
local TabLeft = GetParallelPlanes( idAddGroup, b3BoxDicing, ptCStart, vtO, CopyPlane, OffsetRel, nStepOrthogonal, Color3d( GREEN(), 60),
dTolerance, false, ptCInner, vtNInner, ptCOuter, vtNOuter)
-- carico la tabella con gli indici riordinati
local TempOrtoTab = {}
@@ -553,7 +557,7 @@ function DiceCut.GetDice( Part, Face1, Face2, OptionalParameters)
table.insert( TempOrtoTab, TabRight[i])
end
-- creo una tabella per ogni piano per generare i tagli sulla Inner
local TempParTab = GetOrderedCutTable( nAddGrpId, {TabellaTmSurfP[PlnInd]}, TempOrtoTab)
local TempParTab = GetOrderedCutTable( idAddGroup, {TabellaTmSurfP[PlnInd]}, TempOrtoTab)
for i = 1, #TempParTab do
table.insert( TabFUCHSIA, TempParTab[i])
end
@@ -582,7 +586,7 @@ function DiceCut.GetDice( Part, Face1, Face2, OptionalParameters)
-- Se esiste la superficie limitante (nFacet == 2) verifica se il taglio più esterno è superfluo e quindi viene eliminato
if not bGetOrtoPlanes then
VerifyFirstOrthoCut( UltimateTable, dOffsetParallelOriginal, b3BoxDicing, dMinNzDownUp)
VerifyFirstOrthoCut( UltimateTable, dOffsetParallelOriginal, b3BoxDicing)
-- se rimangono due sole facce, devono coincidere con le originali e quindi sono superflue
if #UltimateTable == 2 and #UltimateTable[1] == 1 and #UltimateTable[2] == 1 then
EgtErase( UltimateTable[1][1])
+24 -25
View File
@@ -136,6 +136,8 @@ function FaceData.GetEdgesInfo( ProcOrId, idFace )
end
CurrentEdge.bIsStartOpen = EdgesEgt[nPreviousEdgeIndex].Open
CurrentEdge.bIsEndOpen = EdgesEgt[nNextEdgeIndex].Open
CurrentEdge.ptStart = Point3d( EdgesEgt[i].Start)
CurrentEdge.ptEnd = Point3d( EdgesEgt[nNextEdgeIndex].Start)
CurrentEdge.sType = 'Standard'
CurrentEdge.id = i - 1
@@ -175,10 +177,11 @@ function FaceData.GetFacesInfo( Proc, Part, FacesToGet)
for i = 1, Proc.nFct do
Faces[i] = {}
Faces[i].id = i - 1
Faces[i].idTrimesh = Proc.id
Faces[i].ptCenter, Faces[i].vtN = EgtSurfTmFacetCenter( Proc.id, i - 1, GDB_ID.ROOT)
if Proc.nFct < 6 or FaceIsToGet( i) then
-- frame OCS faccia
Faces[i].vtFrameHV = Frame3d( Faces[i].ptCenter, Faces[i].vtN)
Faces[i].frFrameHV = Frame3d( Faces[i].ptCenter, Faces[i].vtN)
-- elevazione calcolata rispetto al box della parte
Faces[i].dElevation = EgtSurfTmFacetElevationInBBox( Proc.id, i - 1, Part.b3Part, true, GDB_ID.ROOT)
-- TODO qui sarebbe meglio l'area vera e non quella del rettangolo minimo
@@ -215,46 +218,40 @@ function FaceData.GetFacesInfo( Proc, Part, FacesToGet)
end
-------------------------------------------------------------------------------------------------------------
function FaceData.IsFaceRectangular( Proc, idFace)
local nAddGrpId = BeamLib.GetAddGroup( Proc.idPart)
local nContourId, nContourCnt = EgtExtractSurfTmFacetLoops( Proc.id, idFace, nAddGrpId)
function FaceData.IsFaceRectangle( Face)
-- recupero gruppo per geometrie temporanee
local idTempGroup = BeamLib.GetTempGroup()
local nContourId, nContourCnt = EgtExtractSurfTmFacetLoops( Face.idTrimesh, Face.id, idTempGroup)
if nContourCnt > 1 then
error( 'IsFaceRectangular : too many loops')
error( 'IsFaceRectangle : too many loops')
end
local bIsRectangular = EgtCurveIsARectangle( nContourId)
-- elimino curve create
for i = 1, nContourCnt do
EgtErase( nContourId + i - 1)
end
return bIsRectangular
end
-------------------------------------------------------------------------------------------------------------
function FaceData.IsFaceRhomboid( Proc, idFace)
local nAddGrpId = BeamLib.GetAddGroup( Proc.idPart)
local nContourId, nContourCnt = EgtExtractSurfTmFacetLoops( Proc.id, idFace, nAddGrpId)
function FaceData.IsFaceParallelogram( Face)
-- recupero gruppo per geometrie temporanee
local idTempGroup = BeamLib.GetTempGroup()
local nContourId, nContourCnt = EgtExtractSurfTmFacetLoops( Face.idTrimesh, Face.id, idTempGroup)
if nContourCnt > 1 then
error( 'IsFaceRectangular : too many loops')
error( 'IsFaceParallelogram : too many loops')
end
local bIsTrapezoid = EgtCurveIsATrapezoid( nContourId)
local bIsRhomboid = false
-- un parallelogramma è un trapezoide con i lati paralleli a due a due
if bIsTrapezoid
and AreOppositeVectorApprox( Proc.Faces[idFace + 1].Edges[1].vtN, Proc.Faces[idFace + 1].Edges[3].vtN)
and AreOppositeVectorApprox( Proc.Faces[idFace + 1].Edges[2].vtN, Proc.Faces[idFace + 1].Edges[4].vtN) then
and AreOppositeVectorApprox( Face.Edges[1].vtN, Face.Edges[3].vtN)
and AreOppositeVectorApprox( Face.Edges[2].vtN, Face.Edges[4].vtN) then
bIsRhomboid = true
end
-- elimino curve create
for i = 1, nContourCnt do
EgtErase( nContourId + i - 1)
end
return bIsRhomboid
end
@@ -429,6 +426,8 @@ local function GetBottomFaces( Proc)
CurrentEdge.dElevation = BottomFaces[1].Edges[i].dElevation
CurrentEdge.bIsStartOpen = BottomFaces[1].Edges[i].bIsStartOpen
CurrentEdge.bIsEndOpen = BottomFaces[1].Edges[i].bIsEndOpen
CurrentEdge.ptStart = BottomFaces[1].Edges[i].ptStart
CurrentEdge.ptEnd = BottomFaces[1].Edges[i].ptEnd
if nFirstLongEdgeIndex then
if i == nFirstLongEdgeIndex then
@@ -524,6 +523,8 @@ local function GetLongFaces( Proc, MainFaces)
CurrentEdge.dElevation = LongFaces[i].Edges[j].dElevation
CurrentEdge.bIsStartOpen = LongFaces[i].Edges[j].bIsStartOpen
CurrentEdge.bIsEndOpen = LongFaces[i].Edges[j].bIsEndOpen
CurrentEdge.ptStart = LongFaces[i].Edges[j].ptStart
CurrentEdge.ptEnd = LongFaces[i].Edges[j].ptEnd
if Proc.Topology.sFamily == 'Tunnel' then
if CurrentEdge.idAdjacentFace > -1 then
@@ -620,6 +621,8 @@ local function GetSideFaces( Proc, MainFaces)
CurrentEdge.dElevation = SideFaces[i].Edges[j].dElevation
CurrentEdge.bIsStartOpen = SideFaces[i].Edges[j].bIsStartOpen
CurrentEdge.bIsEndOpen = SideFaces[i].Edges[j].bIsEndOpen
CurrentEdge.ptStart = SideFaces[i].Edges[j].ptStart
CurrentEdge.ptEnd = SideFaces[i].Edges[j].ptEnd
if Proc.Topology.sFamily == 'Tunnel' then
if CurrentEdge.idAdjacentFace > -1 then
@@ -671,10 +674,6 @@ function FaceData.GetMainFaces( Proc, Part)
MainFaces.LongFaces = GetLongFaces( Proc, MainFaces)
MainFaces.SideFaces = GetSideFaces( Proc, MainFaces)
-- scrivo informazioni delle facce nel log
if EgtGetDebugLevel() >= 3 then
Logs.WriteMainFacesLog( Proc, MainFaces)
end
else
MainFaces = nil
EgtOutLog( '---MainFaces NOT NEEDED---')
+1 -1
View File
@@ -323,7 +323,7 @@ function FeatureLib.GetAdditionalInfo( Proc, Part)
elseif ID.IsRidgeLap( Proc) then
Proc.AdjacencyMatrix = FaceData.GetAdjacencyMatrix( Proc)
Proc.Faces = FaceData.GetFacesInfo( Proc, Part)
elseif ID.IsMarking( Proc) then
elseif ID.IsMarking( Proc) or ID.IsText( Proc) then
Proc.FeatureInfo = FeatureLib.GetMarkTextData( Proc)
elseif ID.IsHipValleyRafterNotch( Proc) then
Proc.AdjacencyMatrix = FaceData.GetAdjacencyMatrix( Proc)
+208 -24
View File
@@ -267,6 +267,162 @@ local function IsToolInAvailableToolList( AvailableToolList, sTool)
return bToolFound
end
-------------------------------------------------------------------------------------------------------------
-- in base a tipo testa e angolo soglia, verifica se la faccia è troppo inclinata per la lavorazione scelta (per DownUp passare vtNFace opposta)
local function IsFaceZOutOfRange ( vtNFace, Tool)
-- lama sopra: angolo negativo troppo basso
if Tool.SetupInfo.HeadType.bTop and vtNFace:getZ() < Tool.SetupInfo.GetMinNz( vtNFace, Tool) - GEO.EPS_ZERO then
return true
end
-- lama sotto: angolo positivo troppo elevato
if Tool.SetupInfo.HeadType.bBottom and vtNFace:getZ() > Tool.SetupInfo.GetMaxNz( vtNFace, Tool) + GEO.EPS_ZERO then
return true
end
return false
end
-------------------------------------------------------------------------------------------------------------
-- nel piano perpendicolare alla direzione di taglio, se c'è intersezione tra motore e trave c'è collisione
local function Check2DBladeCollision( Edge, vtNFace, vtHead, Part, Tool, dDepthToMachine)
-- se direzione utensile parallela ad uno degli assi principali non serve alcuna verifica
if AreSameOrOppositeVectorApprox( Edge.vtN, X_AX())
or AreSameOrOppositeVectorApprox( Edge.vtN, Y_AX())
or AreSameOrOppositeVectorApprox( Edge.vtN, Z_AX()) then
return false
end
local idTempGroup = BeamLib.GetTempGroup()
-- riferimento perpendicolare al taglio, X nel verso della normale al lato e Y verso il motore
local ptMachining = Point3d( ( Edge.ptStart + Edge.ptEnd) / 2) + Edge.vtN * ( Edge.dElevation - dDepthToMachine)
local vtEdge = Edge.ptEnd - Edge.ptStart
vtEdge:normalize()
-- costruzione flat region del pezzo nel piano perpendicolare al taglio
-- si estrae prima la silhouette nel piano
local idFirstCurve, nCurveCount = EgtGetSurfTmSilhouette( Part.idBoxTm, vtEdge, 10 * GEO.EPS_SMALL, idTempGroup, GDB_RT.GLOB)
-- se più curve c'è qualcosa che non va: errore
if nCurveCount > 1 then
error( 'Check2DBladeCollision : error in part box')
end
-- creazione flat region dalla silhouette
local idPartSurfFr = EgtSurfFlatRegion( idTempGroup, idFirstCurve)
-- costruzione flat region del grezzo restante nel piano perpendicolare al taglio
-- si costruisce il box in globale
local ptRestLengthMax = Point3d( Part.b3Part:getMin() + X_AX() * 500 * GEO.EPS_SMALL)
local ptRestLengthMin = Point3d( Part.b3Part:getMin():getX() - 2000, Part.b3Part:getMax():getY(), Part.b3Part:getMax():getZ())
local b3RestLength = BBox3d( ptRestLengthMin, ptRestLengthMax)
-- si crea la trimesh dal box
local idRestLengthBoxTm = EgtSurfTmBBox( idTempGroup, b3RestLength , false, GDB_RT.GLOB)
-- si estrae la silhouette nel piano
idFirstCurve, nCurveCount = EgtGetSurfTmSilhouette( idRestLengthBoxTm, vtEdge, 10 * GEO.EPS_SMALL, idTempGroup, GDB_RT.GLOB)
-- se più curve c'è qualcosa che non va: errore
if nCurveCount > 1 then
error( 'Check2DBladeCollision : error in part box')
end
-- creazione flat region dalla silhouette
local idRestLengthSurfFr = EgtSurfFlatRegion( idTempGroup, idFirstCurve)
-- costruzione flat region approssimata del motore nel piano perpendicolare al taglio
-- punto di congiunzione tra motore e lama
local ptMaxElev = ptMachining + Edge.vtN * Tool.dMaxMaterial
-- se taglio standard (no DownUp) il punto va spostato dello spessore lama
if AreSameVectorApprox( vtNFace, vtHead) then
ptMaxElev = ptMaxElev + vtNFace * Tool.dThickness
end
-- TODO qui sostituire con il valore reale letto dal SetupInfo
-- per Fast si dovrà aggiungere la lunghezza del massimo utensile utilizzabile con lama
local dHeadDepth = 480
local dHeadWidth = 480
local ptOpposite = ptMaxElev + Edge.vtN * dHeadWidth
local ptCross = ptOpposite + vtHead * dHeadDepth
local idHeadRectangle = EgtRectangle3P( idTempGroup, ptMaxElev, ptCross, ptOpposite, GDB_RT.GLOB)
-- flat region dal rettangolo
local idHeadSurfFr = EgtSurfFlatRegion( idTempGroup, idHeadRectangle)
-- intersezione tra pezzo e motore (se fallisce si inverte la flat region del motore, probabile normale opposta)
local bIntersectSuccess = EgtSurfFrIntersect( idPartSurfFr, idHeadSurfFr)
if not bIntersectSuccess then
EgtInvertSurf( idHeadSurfFr)
bIntersectSuccess = EgtSurfFrIntersect( idPartSurfFr, idHeadSurfFr)
end
if not bIntersectSuccess then
error( 'Check2DBladeCollision : intersect fail')
end
local bCollisionFoundPiece = EgtExistsObj( idPartSurfFr)
-- intersezione tra grezzo restante e motore, se con il pezzo non c'è collisione
local bCollisionFoundRestLength
if not bCollisionFoundPiece then
bIntersectSuccess = EgtSurfFrIntersect( idRestLengthSurfFr, idHeadSurfFr)
if not bIntersectSuccess then
EgtInvertSurf( idHeadSurfFr)
bIntersectSuccess = EgtSurfFrIntersect( idRestLengthSurfFr, idHeadSurfFr)
end
if not bIntersectSuccess then
error( 'Check2DBladeCollision : intersect fail')
end
bCollisionFoundRestLength = EgtExistsObj( idRestLengthSurfFr)
end
return bCollisionFoundPiece, bCollisionFoundRestLength
end
-------------------------------------------------------------------------------------------------------------
-- ritorna se la faccia e il lato sono lavorabili e, se sì, il modo di lavorare (standard/DownUp)
-- TODO si dovrà decidere come tagliare anche in base a lavorazione di coda (spostare dopo separazione?) o pezzo corto (il motore non deve ingombrare con il pinzaggio)
-- valutare se restituire, se disponibili, entrambe le soluzioni e demandare la decisione alla FaceByBlade
function MachiningLib.GetBladeEngagement( Face, Edge, Part, Tool, dDepthToMachine, bCollisionCheckForDownUpOnly)
local sBladeEngagement = 'Standard'
-- la normale della faccia permette di lavorare in modo standard, ma potrebbero esserci altre condizioni che fanno fallire il taglio
if not IsFaceZOutOfRange( Face.vtN, Tool) then
-- TODO verifica collisione carro Z, collisione traversa PF, collisione 'C' Fast... La riduzione percorso cambia questo test?
local bCollisionFound, bMoveAfterSplit = Check2DBladeCollision( Edge, Face.vtN, Face.vtN, Part, Tool, dDepthToMachine)
if bCollisionCheckForDownUpOnly or not bCollisionFound then
return true, sBladeEngagement, bMoveAfterSplit
end
end
-- faccia non lavorabile in modo standard: si verifica se il DownUp è fattibile
-- la normale della faccia non permette il DownUp: non lavorabile in DownUp (se taglio DownUp la faccia è lavorata al contrario, vtN opposta)
if IsFaceZOutOfRange( -Face.vtN, Tool) then
return false
end
-- rischio collisione carro Z: non lavorabile in Downup
-- TODO questo test è da spostare sulla macchina, non è universale
local bIsToolBelowWorkpiece = Edge.vtN:getZ() < - 0.5
local bIsToolAboveWorkpiece = Edge.vtN:getZ() > 0.5
if Tool.SetupInfo.HeadType.bTop and bIsToolBelowWorkpiece
or ( Tool.SetupInfo.HeadType.bBottom and bIsToolAboveWorkpiece) then
return false
end
-- orientamento faccia / utensile compatibili con DownUp: lavorabile
local bCollisionFound, bMoveAfterSplit = Check2DBladeCollision( Edge, Face.vtN, -Face.vtN, Part, Tool, dDepthToMachine)
if not bCollisionFound then
sBladeEngagement = 'DownUp'
return true, sBladeEngagement, bMoveAfterSplit
end
return false
end
-------------------------------------------------------------------------------------------------------------
-- funzione per cercare utensile tipo FRESA con certe caratteristiche
-- TODO qui vtToolDirection è in realtà vtN
@@ -383,14 +539,14 @@ end
-------------------------------------------------------------------------------------------------------------
-- funzione per cercare utensile tipo LAMA con certe caratteristiche
-- TODO da completare
-- TODO da rivedere/completare
-- TODO il FindBlade dovrà restituire di utilizzare sempre la lama sopra se l'angolo lo permette, ma avendo un'altezza massima (da macchina) oltre cui il DownUp non sarà fattibile (evita collisioni tra asse e pezzo)
function MachiningLib.FindBlade( Proc, ToolSearchParameters)
local ToolInfo = {}
-- parametri obbligatori
if type( ToolSearchParameters.vtN) ~= 'table' then
error( 'FindBlade : missing tool direction')
if type( ToolSearchParameters.FaceToMachine) ~= 'table' then
error( 'FindBlade : missing face info')
end
if type( ToolSearchParameters.bAllowTopHead) ~= 'boolean' then
error( 'FindBlade : missing top head info')
@@ -401,32 +557,52 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters)
if not ToolSearchParameters.bAllowTopHead and not ToolSearchParameters.bAllowBottomHead then
error( 'FindBlade : wrong head info')
end
local FaceToMachine = ToolSearchParameters.FaceToMachine
local bAllowTopHead = ToolSearchParameters.bAllowTopHead
local bAllowBottomHead = ToolSearchParameters.bAllowBottomHead
-- parametri opzionali
ToolSearchParameters.dElevation = ToolSearchParameters.dElevation or 0
ToolSearchParameters.bForceLongcutBlade = ToolSearchParameters.bForceLongcutBlade or false
local dElevation = ToolSearchParameters.dElevation or 0
local bForceLongcutBlade = ToolSearchParameters.bForceLongcutBlade or false
local EdgeToMachine = ToolSearchParameters.EdgeToMachine
local Part = ToolSearchParameters.Part
local bCollisionCheckForDownUpOnly = ToolSearchParameters.bCollisionCheckForDownUpOnly or false
local nBestToolIndex
local dBestToolResidualDepth = 0
local sCurrentBladeEngagement
local sBestBladeEngagement
local bCurrentMoveAfterSplit
local bBestMoveAfterSplit
for i = 1, #TOOLS do
local bIsToolCompatible = false
if TOOLS[i].sFamily == 'SAWBLADE' then
if ToolSearchParameters.bAllowTopHead and not ToolSearchParameters.bAllowBottomHead then
if bAllowTopHead and not bAllowBottomHead then
bIsToolCompatible = TOOLS[i].SetupInfo.HeadType.bTop
elseif ToolSearchParameters.bAllowBottomHead and not ToolSearchParameters.bAllowTopHead then
elseif bAllowBottomHead and not bAllowTopHead then
bIsToolCompatible = TOOLS[i].SetupInfo.HeadType.bBottom
else
bIsToolCompatible = true
end
end
-- check angolo limite lama
if TOOLS[i].SetupInfo.HeadType.bTop and ToolSearchParameters.vtN:getZ() < TOOLS[i].SetupInfo.GetMinNz( ToolSearchParameters.vtN, TOOLS[i]) - GEO.EPS_ZERO then
bIsToolCompatible = false
end
if TOOLS[i].SetupInfo.HeadType.bBottom and ToolSearchParameters.vtN:getZ() > TOOLS[i].SetupInfo.GetMaxNz( ToolSearchParameters.vtN, TOOLS[i]) + GEO.EPS_ZERO then
bIsToolCompatible = false
-- se dati sufficienti, si determina se con questo utensile il taglio è fattibile e il modo di lavorare della lama
if bIsToolCompatible then
if FaceToMachine and EdgeToMachine and Part and dElevation then
local bIsBladeOk = false
bIsBladeOk, sCurrentBladeEngagement, bCurrentMoveAfterSplit = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, Part, TOOLS[i], dElevation, bCollisionCheckForDownUpOnly)
-- orientamento non raggiungibile
if not bIsBladeOk then
bIsToolCompatible = false
end
-- se si ha solo la faccia si può verificare se questa è orientata correttamente
elseif FaceToMachine then
if IsFaceZOutOfRange( FaceToMachine.vtN, TOOLS[i]) then
bIsToolCompatible = false
end
end
end
-- se c'è una lista di utensili disponibili, si verifica che l'utensile attuale sia tra quelli
@@ -436,15 +612,19 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters)
if bIsToolCompatible then
-- TODO gestire accorciamento massimo materiale per inclinazione
local dCurrentResidualDepth = ToolSearchParameters.dElevation - TOOLS[i].dMaxDepth
local dCurrentResidualDepth = dElevation - TOOLS[i].dMaxDepth
if not nBestToolIndex or ( dBestToolResidualDepth > 0 and dCurrentResidualDepth <= 10 * GEO.EPS_SMALL) then
nBestToolIndex = i
dBestToolResidualDepth = dCurrentResidualDepth
sBestBladeEngagement = sCurrentBladeEngagement
bBestMoveAfterSplit = bCurrentMoveAfterSplit
else
-- prediligo utensile per tagli lunghi, se richiesto
if ToolSearchParameters.bForceLongcutBlade and not TOOLS[nBestToolIndex].bIsUsedForLongCut and TOOLS[i].bIsUsedForLongCut then
-- prediligo utensile per tagli lungo vena, se richiesto
if bForceLongcutBlade and not TOOLS[nBestToolIndex].bIsUsedForLongCut and TOOLS[i].bIsUsedForLongCut then
nBestToolIndex = i
dBestToolResidualDepth = dCurrentResidualDepth
sBestBladeEngagement = sCurrentBladeEngagement
bBestMoveAfterSplit = bCurrentMoveAfterSplit
else
-- entrambi completi
if dBestToolResidualDepth <= 10 * GEO.EPS_SMALL and dCurrentResidualDepth <= 10 * GEO.EPS_SMALL then
@@ -455,11 +635,15 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters)
GetIndexToolInAvailableToolList( ToolSearchParameters.AvailableToolList, TOOLS[nBestToolIndex].sName) then
nBestToolIndex = i
dBestToolResidualDepth = dCurrentResidualDepth
sBestBladeEngagement = sCurrentBladeEngagement
bBestMoveAfterSplit = bCurrentMoveAfterSplit
end
-- si sceglie quello con le performance migliori
elseif TOOLS[i].dPerformanceIndex > TOOLS[nBestToolIndex].dPerformanceIndex + 10 * GEO.EPS_SMALL then
nBestToolIndex = i
dBestToolResidualDepth = dCurrentResidualDepth
sBestBladeEngagement = sCurrentBladeEngagement
bBestMoveAfterSplit = bCurrentMoveAfterSplit
end
-- entrambi incompleti
elseif dBestToolResidualDepth > 10 * GEO.EPS_SMALL and dCurrentResidualDepth > 10 * GEO.EPS_SMALL then
@@ -467,6 +651,8 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters)
if dCurrentResidualDepth > dBestToolResidualDepth then
nBestToolIndex = i
dBestToolResidualDepth = dCurrentResidualDepth
sBestBladeEngagement = sCurrentBladeEngagement
bBestMoveAfterSplit = bCurrentMoveAfterSplit
end
end
end
@@ -476,6 +662,8 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters)
ToolInfo.nToolIndex = nBestToolIndex
ToolInfo.dResidualDepth = dBestToolResidualDepth
ToolInfo.sBladeEngagement = sBestBladeEngagement
ToolInfo.bMoveAfterSplit = bBestMoveAfterSplit
return ToolInfo
end
@@ -1284,9 +1472,9 @@ function MachiningLib.GetTimeToMachineAllStepsWithLeadInOut( Machining, Part)
local ProcTm = FeatureLib.GetProcFromTrimesh( Machining.Geometry[1][1], Part)
local dDepthToMachine = min( ProcTm.Faces[Machining.Geometry[1][2] + 1].dElevation, ( Machining.dMaxElev or ProcTm.Faces[Machining.Geometry[1][2] + 1].dElevation)) - ( max( 0, Machining.dResidualDepth or 0))
local nSteps = max( ceil( ( dDepthToMachine - 50 * GEO.EPS_SMALL) / TOOLS[Machining.nToolIndex].dStep), 1)
local nAddGroupId = BeamLib.GetAddGroup( Part.id)
local idTempGroup = BeamLib.GetTempGroup()
-- TODO in futuro creare flatregion (se ci fossero isole il calcolo del percorso non sarebbe corretto)
local idFaceContour = EgtExtractSurfTmFacetLoops( ProcTm.id, Machining.Geometry[1][2], nAddGroupId)
local idFaceContour = EgtExtractSurfTmFacetLoops( ProcTm.id, Machining.Geometry[1][2], idTempGroup)
-- si settano i lati aperti della curva derivata dalla superficie
for i = 1, #ProcTm.Faces[Machining.Geometry[1][2] + 1].Edges do
if ProcTm.Faces[Machining.Geometry[1][2] + 1].Edges[i].bIsOpen then
@@ -1294,7 +1482,7 @@ function MachiningLib.GetTimeToMachineAllStepsWithLeadInOut( Machining, Part)
end
end
-- dal momento che la funzione EgtPocketing non considera il grezzo, nei casi ottimizzati si deve correggere l'offset
local idTestCurve = EgtCopyGlob( idFaceContour, nAddGroupId )
local idTestCurve = EgtCopyGlob( idFaceContour, idTempGroup )
local bIsOptimizedPocketing = ( TOOLS[Machining.nToolIndex].dDiameter > TOOLS[Machining.nToolIndex].dSideStep - 10 * GEO.EPS_SMALL)
and EgtOffsetCurve( idTestCurve, -TOOLS[Machining.nToolIndex].dDiameter / 2 - 10 * GEO.EPS_SMALL)
if not bIsOptimizedPocketing then
@@ -1310,7 +1498,7 @@ function MachiningLib.GetTimeToMachineAllStepsWithLeadInOut( Machining, Part)
end
end
-- calcolo percorso di svuotatura replicando il calcolo che fa la svuotatura
local idPocketingPath = EgtPocketing( idFaceContour, TOOLS[Machining.nToolIndex].dDiameter / 2, TOOLS[Machining.nToolIndex].dSideStep, 0, Machining.nSubType, true, nAddGroupId)
local idPocketingPath = EgtPocketing( idFaceContour, TOOLS[Machining.nToolIndex].dDiameter / 2, TOOLS[Machining.nToolIndex].dSideStep, 0, Machining.nSubType, true, idTempGroup)
local dPocketingPathLength = EgtCurveLength( idPocketingPath)
-- calcolo lunghezze e tempi totali
if dPocketingPathLength then
@@ -1322,10 +1510,6 @@ function MachiningLib.GetTimeToMachineAllStepsWithLeadInOut( Machining, Part)
dLengthToMachineAllStepsWithLeadInOut = 99999 * nSteps
dTimeToMachineTotal = dLengthToMachineAllStepsWithLeadInOut / dToolFeed
end
-- le geometrie create si settano da cancellare
EgtSetLevel( idFaceContour, GDB_LV.TEMP)
EgtSetLevel( idPocketingPath, GDB_LV.TEMP)
EgtSetLevel( idTestCurve, GDB_LV.TEMP)
else
error( 'GetTimeToMachineAllStepsWithLeadInOut : unknown machining type')
end
+1 -1
View File
@@ -320,7 +320,7 @@ local function MyProcessFeatures()
sMsg = string.gsub( sMsg or '', '\r', ' ', 10)
-- trovata almeno una strategia e feature lavorata completamente
if RESULT[i].sType == 'Feature' and RESULT[i].ChosenStrategy.sStatus == 'Completed' then
-- nulla da segnalare
sOutput = sOutput .. string.format( '[%d,%d] %s\n', RESULT[i].idCut, RESULT[i].idTask, sMsg or '')
-- trovata almeno una strategia ma nessuna applicabile oppure non trovata alcuna strategia
elseif RESULT[i].sType == 'Feature'
+1 -2
View File
@@ -89,8 +89,7 @@ function HEADCUT.Make( bAddMachining, Proc, Part, CustomParameters)
if not bExecutePrecutOnly then
local OptionalParameters = {}
-- si parte dal box della feature e si aggiunge il punto estremo del grezzo
-- ATTENZIONE : Proc.b3Box viene modificata dato che il tipo Box è come se fosse una tabella, ma da qui passa solo 1 volta per pezzo quindi non dovrebbero esserci problemi
local b3BoxDicing = Proc.b3Box
local b3BoxDicing = BBox3d( Proc.b3Box)
b3BoxDicing:Add( Part.b3Raw:getMax())
b3BoxDicing:expand( 1000 * GEO.EPS_SMALL)
OptionalParameters.b3BoxDicing = b3BoxDicing
+12 -19
View File
@@ -428,7 +428,12 @@ end
local function GetSplitSurfaces( Proc, Part, bAddMachining)
local vAddId = {}
local vAddIdTunnel = {}
local nAddGrpId = BeamLib.GetAddGroup( Part.id)
local idAddGroup
if bAddMachining then
idAddGroup = BeamLib.GetAddGroup( Part.id)
else
idAddGroup = BeamLib.GetTempGroup()
end
local nOriginalTmIdTunnel = GDB_ID.NULL
if Proc.MainFaces.TunnelAddedFaces then
nOriginalTmIdTunnel = Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.id
@@ -438,18 +443,14 @@ local function GetSplitSurfaces( Proc, Part, bAddMachining)
local FeatureSplittingPoints = FeatureLib.GetFeatureSplittingPoints( Proc, Part)
if #FeatureSplittingPoints == 0 then
local nAddId = EgtCopyGlob( Proc.id, nAddGrpId) or GDB_ID.NULL
local nAddIdTunnel = EgtCopyGlob( nOriginalTmIdTunnel, nAddGrpId) or GDB_ID.NULL
if not bAddMachining then
EgtSetLevel( nAddId, GDB_LV.TEMP)
EgtSetLevel( nAddIdTunnel, GDB_LV.TEMP)
end
local nAddId = EgtCopyGlob( Proc.id, idAddGroup) or GDB_ID.NULL
local nAddIdTunnel = EgtCopyGlob( nOriginalTmIdTunnel, idAddGroup) or GDB_ID.NULL
table.insert( vAddId, nAddId)
table.insert( vAddIdTunnel, nAddIdTunnel)
else
for i = 1, #FeatureSplittingPoints do
local nAddId = EgtCopyGlob( Proc.id, nAddGrpId) or GDB_ID.NULL
local nAddIdTunnel = EgtCopyGlob( nOriginalTmIdTunnel, nAddGrpId) or GDB_ID.NULL
local nAddId = EgtCopyGlob( Proc.id, idAddGroup) or GDB_ID.NULL
local nAddIdTunnel = EgtCopyGlob( nOriginalTmIdTunnel, idAddGroup) or GDB_ID.NULL
if i == 1 then
-- prima superficie, va tagliata solo a sinistra
local ptSplit = FeatureSplittingPoints[i] + Vector3d( -BeamData.MILL_OVERLAP / 2, 0, 0)
@@ -465,23 +466,15 @@ local function GetSplitSurfaces( Proc, Part, bAddMachining)
EgtCutSurfTmPlane( nAddId, ptSplit, X_AX(), true, GDB_RT.GLOB)
EgtCutSurfTmPlane( nAddIdTunnel, ptSplit, X_AX(), true, GDB_RT.GLOB)
end
if not bAddMachining then
EgtSetLevel( nAddId, GDB_LV.TEMP)
EgtSetLevel( nAddIdTunnel, GDB_LV.TEMP)
end
table.insert( vAddId, nAddId)
table.insert( vAddIdTunnel, nAddIdTunnel)
end
-- taglio ultima superficie, va tagliata solo a destra
local nAddId = EgtCopyGlob( Proc.id, nAddGrpId) or GDB_ID.NULL
local nAddIdTunnel = EgtCopyGlob( nOriginalTmIdTunnel, nAddGrpId) or GDB_ID.NULL
local nAddId = EgtCopyGlob( Proc.id, idAddGroup) or GDB_ID.NULL
local nAddIdTunnel = EgtCopyGlob( nOriginalTmIdTunnel, idAddGroup) or GDB_ID.NULL
local ptSplit = FeatureSplittingPoints[#FeatureSplittingPoints] + Vector3d( BeamData.MILL_OVERLAP / 2, 0, 0)
EgtCutSurfTmPlane( nAddId, ptSplit, X_AX(), true, GDB_RT.GLOB)
EgtCutSurfTmPlane( nAddIdTunnel, ptSplit, X_AX(), true, GDB_RT.GLOB)
if not bAddMachining then
EgtSetLevel( nAddId, GDB_LV.TEMP)
EgtSetLevel( nAddIdTunnel, GDB_LV.TEMP)
end
table.insert( vAddId, nAddId)
table.insert( vAddIdTunnel, nAddIdTunnel)
end
+2 -2
View File
@@ -236,6 +236,7 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters)
local BottomEdge = LongFace.MainEdges.BottomEdge
-- TODO funzione separata
-- TODO è meglio cercare la lama qui e passarla alla FACEBYBLADE, la scelta è più precisa
-- lama - calcolo lavorazioni
local Cutting = {}
-- parametri comuni a tutte le lavorazioni cutting
@@ -243,8 +244,7 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters)
bForceLongcutBlade = Strategy.Parameters.bForceLongcutBlade,
dExtendAfterTail = dExtendAfterTail,
dPocketHeight = dPocketHeight,
bIsSplitFeature = bIsSplitFeature,
dMinNzDownUp = 0
bIsSplitFeature = bIsSplitFeature
}
-- primo lato del tunnel o lato di fondo
+3 -2
View File
@@ -36,7 +36,7 @@ local function IsTwoFacesCommonEdgeTooLong( Proc, Part)
end
-- se due facce, cubetti troppo lunghi in X non si possono fare
local ptEdge1, _, ptEdge2 = EgtSurfTmFacetOppositeSide( Proc.id, Proc.Faces[1].id, -Proc.Faces[1].Edges[nCommonEdge].vtN, GDB_ID.ROOT)
local ptEdge1, ptEdge2 = Proc.Faces[1].Edges[nCommonEdge].ptStart, Proc.Faces[1].Edges[nCommonEdge].ptEnd
local b3BoxEdge = BBox3d( ptEdge1, ptEdge2)
local dEdgeLengthOnX = b3BoxEdge:getDimX()
if FeatureLib.IsMachiningLong( dEdgeLengthOnX, Part) then
@@ -111,13 +111,14 @@ function STR0005.Make( bAddMachining, Proc, Part, CustomParameters)
or bKeepWasteAttached then
local BladeKeepWasteResult
local OptionalParameters = { dExtendAfterTail = dExtendAfterTail, dStripWidth = Strategy.Parameters.dStripWidth}
local OptionalParameters = { dExtendAfterTail = dExtendAfterTail, dStripWidth = Strategy.Parameters.dStripWidth, bForced = bKeepWasteAttached}
AuxiliaryData.bIgnoreNotClampableLength = true
Blade.Result, BladeKeepWasteResult = BladeKeepWaste.Make( Proc, Part, OptionalParameters)
dTimeToMachine = BladeKeepWasteResult.dTimeToMachine
dMRRBlade = BladeKeepWasteResult.dMRR
dCompletionPercentage = BladeKeepWasteResult.dCompletionPercentage
dQuality = BladeKeepWasteResult.dQuality
Strategy.Result.sInfo = BladeKeepWasteResult.sInfo or ''
end
-- lavorazione a cubetti / taglio singolo
+7 -5
View File
@@ -108,15 +108,17 @@ local function GetRoughStrategy( Proc, Part, bSaveAddedGeometries)
local nMidFacet = Proc.nFct // 2 -- faccia a metà circa
local vtN = EgtSurfTmFacetNormVersor( Proc.id, nMidFacet, GDB_ID.ROOT)
local nAddGroupId = BeamLib.GetAddGroup( Part.id)
local idAddGroup
if bSaveAddedGeometries then
idAddGroup = BeamLib.GetAddGroup( Part.id)
else
idAddGroup = BeamLib.GetTempGroup()
end
-- aggiungo piano di sgrossatura e lo lavoro
local ptStart, vtNP = GetSawCutData( Proc, Proc.idAddAuxGeom, vtNF, vtN)
local AddId = EgtSurfTmPlaneInBBox( nAddGroupId, ptStart, vtNP, Part.b3Part, GDB_RT.GLOB)
local AddId = EgtSurfTmPlaneInBBox( idAddGroup, ptStart, vtNP, Part.b3Part, GDB_RT.GLOB)
-- se la faccia è stata creata
if AddId then
if not bSaveAddedGeometries then
EgtSetLevel( AddId, GDB_LV.TEMP)
end
-- creo piano di taglio sulla testa del tenone
local OptionalParameters = { dMaxWasteVolume = Strategy.Parameters.dMaxWasteVolume,
+39 -10
View File
@@ -11,6 +11,7 @@ require( 'EgtBase')
local FeatureLib = require( 'FeatureLib')
local FaceData = require( 'FaceData')
local MachiningLib = require( 'MachiningLib')
local BeamLib = require('BeamLib')
-- strategie di base
local FaceByBlade = require('FACEBYBLADE')
local FaceByMill = require('FACEBYMILL')
@@ -119,8 +120,8 @@ end
function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters)
-- TODO verificare funzionamento con lama da sotto
-- TODO scelta utensile è corretto lasciarla a FaceByBlade?
-- attenzione perchè se l'inclinazione della faccia la fa finire oltre lo spigolo questo riduce il massimo (come calcolare????)
-- il FindBlade dovrà restituire di utilizzare sempre la lama sopra se l'angolo lo permette, ma avendo un'altezza massima (da macchina) oltre cui il DownUp non sarà fattibile (evita collisioni tra asse e pezzo)
local Result = {}
local Machinings = {}
@@ -171,6 +172,8 @@ function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters)
bFinishWithMill = OptionalParameters.bFinishWithMill
end
local dMillingOffsetFromSide = OptionalParameters.dMillingOffsetFromSide or 1
local dStripWidth = OptionalParameters.dStripWidth or 5
local bForced = OptionalParameters.bForced or false
-- volume della feature
local dFeatureVolume = FeatureLib.GetFeatureVolume( Proc, Part)
@@ -217,19 +220,41 @@ function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters)
end
-- taglio con codolo faccia di fondo
local dDepthToMachine = BottomEdgeToMachine.dElevation / 2 - OptionalParameters.dStripWidth / 2
local OptionalParametersFaceByBlade = { dDepthToMachine = dDepthToMachine, bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail, nToolIndex = nToolIndex}
local dDepthToMachine = BottomEdgeToMachine.dElevation / 2 - dStripWidth / 2
local OptionalParametersFaceByBlade1 = { dDepthToMachine = dDepthToMachine, bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail, nToolIndex = nToolIndex}
-- primo lato
Cutting1 = FaceByBlade.Make( Proc, Part, BottomFace, BottomEdgeToMachine, OptionalParametersFaceByBlade)
Cutting1 = FaceByBlade.Make( Proc, Part, BottomFace, BottomEdgeToMachine, OptionalParametersFaceByBlade1)
Cutting1.nInternalSortingPriority = 3
Cutting1.dResultWeight = 0.3
table.insert( CalculatedMachinings, Cutting1)
-- secondo lato
OptionalParametersFaceByBlade.OppositeToolDirectionMode = 'Enabled'
Cutting2 = FaceByBlade.Make( Proc, Part, BottomFace, BottomEdgeToMachine, OptionalParametersFaceByBlade)
local OptionalParametersFaceByBlade2 = BeamLib.TableCopyDeep( OptionalParametersFaceByBlade1)
OptionalParametersFaceByBlade2.OppositeToolDirectionMode = 'Enabled'
Cutting2 = FaceByBlade.Make( Proc, Part, BottomFace, BottomEdgeToMachine, OptionalParametersFaceByBlade2)
Cutting2.nInternalSortingPriority = 3
Cutting2.dResultWeight = 0.3
table.insert( CalculatedMachinings, Cutting2)
-- se uno dei due lati non è riuscito, si estende il più possibile il lato rimasto
if not Cutting1.bIsApplicable and Cutting2.bIsApplicable then
dDepthToMachine = min( TOOLS[Cutting2.nToolIndex].dMaxMaterial, BottomEdgeToMachine.dElevation - dStripWidth)
OptionalParametersFaceByBlade2.dDepthToMachine = dDepthToMachine
Cutting2 = FaceByBlade.Make( Proc, Part, BottomFace, BottomEdgeToMachine, OptionalParametersFaceByBlade2)
table.insert( CalculatedMachinings, Cutting2)
elseif not Cutting2.bIsApplicable and Cutting1.bIsApplicable then
dDepthToMachine = min( TOOLS[Cutting1.nToolIndex].dMaxMaterial, BottomEdgeToMachine.dElevation - dStripWidth)
OptionalParametersFaceByBlade1.dDepthToMachine = dDepthToMachine
Cutting1 = FaceByBlade.Make( Proc, Part, BottomFace, BottomEdgeToMachine, OptionalParametersFaceByBlade1)
table.insert( CalculatedMachinings, Cutting1)
else
table.insert( CalculatedMachinings, Cutting1)
table.insert( CalculatedMachinings, Cutting2)
end
-- fresatura eventuali facce di chiusura
if bFinishWithMill then
@@ -253,8 +278,9 @@ function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters)
end
end
-- calcolo completamento, serve la lista di lavorazioni che comprende le non applicabili
Result.dCompletionPercentage = GetStrategyCompletionPercentage( CalculatedMachinings)
-- calcolo completamento (non applicabili devono essere incluse)
-- se codolo non forzato si ritorna completa solo al 94% (completion index 4)
Result.dCompletionPercentage = bForced and GetStrategyCompletionPercentage( CalculatedMachinings) or 94
Result.dCompletionIndex = FeatureLib.GetFeatureCompletionIndex( Result.dCompletionPercentage)
-- aggiunta eventuali lavorazioni splittate
@@ -272,6 +298,9 @@ function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters)
Result.dMRR = ( dFeatureVolume / Result.dTimeToMachine) / pow( 10, 6)
if Result.dCompletionPercentage > 100 - 10 * GEO.EPS_SMALL then
Result.sStatus = 'Completed'
if bForced then
Result.sInfo = 'Waste attached. Remove manually.'
end
else
Result.sStatus = 'Not-Completed'
end
+185 -171
View File
@@ -204,9 +204,14 @@ local function CompareEdgesNoPreference( EdgeA, EdgeB)
end
local function GetEdgeToMachine( Edges, vtNFace, sBladeType, bAllowFastCuts)
local function GetEdgeToMachine( Edges, sBladeType, OptionalParameters)
local EdgeToMachine = {}
-- parametri opzionali
OptionalParameters = OptionalParameters or {}
local bAllowFastCuts = OptionalParameters.bAllowFastCuts or false
local nIndex = OptionalParameters.nIndex or 1
local EdgesSorted = {}
for i = 1, #Edges do
table.insert( EdgesSorted, Edges[i])
@@ -218,31 +223,23 @@ local function GetEdgeToMachine( Edges, vtNFace, sBladeType, bAllowFastCuts)
else
table.sort( EdgesSorted, CompareEdgesTopHead)
end
EdgeToMachine = EdgesSorted[1]
EdgeToMachine = EdgesSorted[nIndex]
elseif sBladeType == 'Bottom' then
table.sort( EdgesSorted, CompareEdgesBottomHead)
EdgeToMachine = EdgesSorted[1]
elseif sBladeType == 'TopDownUp' then
local vtEdgeDirection
if vtNFace:getY() > -0.02 then
vtEdgeDirection = -Y_AX()
else
vtEdgeDirection = Y_AX()
end
EdgeToMachine = BeamLib.FindEdgeBestOrientedAsDirection( Edges, vtEdgeDirection)
EdgeToMachine = EdgesSorted[nIndex]
elseif sBladeType == 'TopGuillotine' then
table.sort( EdgesSorted, CompareEdgesTopHeadGuillotine)
EdgeToMachine = EdgesSorted[1]
EdgeToMachine = EdgesSorted[nIndex]
elseif sBladeType == 'HorizontalBottom' then
table.sort( EdgesSorted, CompareEdgesHorizontalBottom)
EdgeToMachine = EdgesSorted[1]
EdgeToMachine = EdgesSorted[nIndex]
elseif sBladeType == 'Vertical' then
table.sort( EdgesSorted, CompareEdgesVertical)
EdgeToMachine = EdgesSorted[1]
EdgeToMachine = EdgesSorted[nIndex]
-- TODO non testato; non si dovrebbe mai entrare in questo caso
else
table.sort( EdgesSorted, CompareEdgesNoPreference)
EdgeToMachine = EdgesSorted[1]
EdgeToMachine = EdgesSorted[nIndex]
end
return EdgeToMachine
@@ -262,9 +259,10 @@ local function GetBestBlade( Proc, Part, Face, OptionalParameters)
local dMinNzTopBladeIfEqual = OptionalParameters.dMinNzTopBlade or sin(-5)
local dMaxNyTopBlade = OptionalParameters.dMaxNyTopBlade or sin(1)
local dShortPartLength = OptionalParameters.dShortPartLength or BeamData.LEN_SHORT_PART
local dElevationTop = OptionalParameters.dElevationTop
local dElevationBottom = OptionalParameters.dElevationBottom
local dElevationTopDownUp = OptionalParameters.dElevationTopDownUp or 0
local EdgeToMachineTop = OptionalParameters.EdgeToMachineTop
local EdgeToMachineBottom = OptionalParameters.EdgeToMachineBottom
local dElevationTop = EdgeToMachineTop and EdgeToMachineTop.dElevation + BeamData.CUT_EXTRA or nil
local dElevationBottom = EdgeToMachineBottom and EdgeToMachineBottom.dElevation + BeamData.CUT_EXTRA or nil
-- se ho già l'utensile, devo solo discriminare se è lama sopra o sotto e verificare se ci arriva
if OptionalParameters.nToolIndex then
@@ -282,20 +280,24 @@ local function GetBestBlade( Proc, Part, Face, OptionalParameters)
local ToolInfo
-- ricerca lama testa sopra
ToolInfo = MachiningLib.FindBlade( Proc, {
vtN = Face.vtN,
bAllowTopHead = true,
bAllowBottomHead = false,
dElevation = dElevationTop
dElevation = dElevationTop,
FaceToMachine = Face,
EdgeToMachine = EdgeToMachineTop,
Part = Part
})
if ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then
nToolIndexTop = ToolInfo.nToolIndex
end
-- ricerca lama testa sotto
ToolInfo = MachiningLib.FindBlade( Proc, {
vtN = Face.vtN,
bAllowTopHead = false,
bAllowBottomHead = true,
dElevation = dElevationBottom
dElevation = dElevationBottom,
FaceToMachine = Face,
EdgeToMachine = EdgeToMachineBottom,
Part = Part
})
if ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then
nToolIndexBottom = ToolInfo.nToolIndex
@@ -337,19 +339,8 @@ local function GetBestBlade( Proc, Part, Face, OptionalParameters)
-- assegnazione tipo lama
if nChosenToolIndex == nToolIndexBottom then
sChosenBladeType = 'Bottom'
-- se lama sopra va verificato se va usata in DownUp
elseif nChosenToolIndex == nToolIndexTop then
local dMinNzDownUp = TOOLS[nToolIndexTop].SetupInfo.GetMinNzDownUp( Part.b3Raw, Face.vtN, nil, TOOLS[nToolIndexTop])
local dCurrentResidualDepth = dElevationTopDownUp - TOOLS[nToolIndexTop].dMaxDepth
if Face.vtN:getZ() < dMinNzDownUp then
if ( dCurrentResidualDepth > 10 * GEO.EPS_SMALL) then
-- TODO serve messaggio per motivare il non applicabile??
nChosenToolIndex = nil
end
sChosenBladeType = 'TopDownUp'
else
sChosenBladeType = 'Top'
end
sChosenBladeType = 'Top'
end
-- se non trovata alcuna lama ritorna nil
@@ -357,13 +348,8 @@ local function GetBestBlade( Proc, Part, Face, OptionalParameters)
end
local function SetDiceFaceInfo( Proc, idDiceFace, bSaveAddedGeometries)
EgtSetName( idDiceFace, 'Face' .. tostring( Proc.idFeature) .. '_Dice')
-- TODO la scrittura del TaskId probabilmente non serve (è fatta nell'AddOperations)
EgtSetInfo( idDiceFace, 'TASKID', Proc.idTask)
if not bSaveAddedGeometries then
EgtSetLevel( idDiceFace, GDB_LV.TEMP)
end
local function SetDiceFaceInfo( Proc, idDiceFace)
EgtSetName( idDiceFace, 'Face' .. tostring( Proc.idFeature or 'Add') .. '_Dice')
end
@@ -376,52 +362,71 @@ local function GetSingleCutStrategy( Proc, Part, OptionalParameters)
local bAllowFastCuts = OptionalParameters.bAllowFastCuts or false
local FaceToMachine = Proc.Faces[OptionalParameters.nFaceToMachineIndex or 1]
-- lati da lavorare in base al tipo di lama
-- se non arrivano dall'esterno si cercano i migliori disponibili
-- se non arrivano dall'esterno si cercano i migliori disponibili, dapprima ignorando il flag bAllowFastCuts
local EdgeToMachineList = OptionalParameters.EdgeToMachineList
or {
Top = GetEdgeToMachine( FaceToMachine.Edges, FaceToMachine.vtN, 'Top', bAllowFastCuts),
Bottom = GetEdgeToMachine( FaceToMachine.Edges, FaceToMachine.vtN, 'Bottom', bAllowFastCuts),
TopDownUp = GetEdgeToMachine( FaceToMachine.Edges, FaceToMachine.vtN, 'TopDownUp', bAllowFastCuts),
TopGuillotine = GetEdgeToMachine( FaceToMachine.Edges, FaceToMachine.vtN, 'TopGuillotine', bAllowFastCuts)
Top = GetEdgeToMachine( FaceToMachine.Edges, 'Top'),
Bottom = GetEdgeToMachine( FaceToMachine.Edges, 'Bottom'),
TopGuillotine = GetEdgeToMachine( FaceToMachine.Edges, 'TopGuillotine')
}
local sChosenBladeType
-- se nToolIndex è presente, GetBestBlade sceglierà solo il lato, altrimenti sceglierà lama e lato
local OptionalParametersGetBestBlade = {
dElevationTop = EdgeToMachineList.Top.dElevation + BeamData.CUT_EXTRA,
dElevationBottom = EdgeToMachineList.Bottom.dElevation + BeamData.CUT_EXTRA,
dElevationTopDownUp = EdgeToMachineList.TopDownUp.dElevation + BeamData.CUT_EXTRA,
EdgeToMachineTop = EdgeToMachineList.Top,
EdgeToMachineBottom = EdgeToMachineList.Bottom,
nToolIndex = nToolIndex
}
-- se nToolIndex è presente, GetBestBlade sceglierà solo il lato, altrimenti sceglierà lama e lato
nToolIndex, sChosenBladeType = GetBestBlade( Proc, Part, FaceToMachine, OptionalParametersGetBestBlade)
-- se non è stato trovato un utensile e utensile e lati non arrivavano dall'esterno, si prova a cambiare lato (si prende il secondo della lista), sempre ignorando bAllowFastCuts
if not nToolIndex and not OptionalParameters.nToolIndex and not OptionalParameters.EdgeToMachineList then
EdgeToMachineList.Top = GetEdgeToMachine( FaceToMachine.Edges, 'Top', { nIndex = 2})
EdgeToMachineList.Bottom = GetEdgeToMachine( FaceToMachine.Edges, 'Bottom', { nIndex = 2})
OptionalParametersGetBestBlade.EdgeToMachineTop = EdgeToMachineList.Top
OptionalParametersGetBestBlade.EdgeToMachineBottom = EdgeToMachineList.Bottom
nToolIndex, sChosenBladeType = GetBestBlade( Proc, Part, FaceToMachine, OptionalParametersGetBestBlade)
end
-- se ancora non è stato trovato un utensile e utensile e lati non arrivavano dall'esterno, se permesso, si prova a scegliere il primo lato a minor elevazione (bAllowFastCuts)
if bAllowFastCuts and not nToolIndex and not OptionalParameters.nToolIndex and not OptionalParameters.EdgeToMachineList then
EdgeToMachineList.Top = GetEdgeToMachine( FaceToMachine.Edges, 'Top', { bAllowFastCuts = true})
EdgeToMachineList.Bottom = GetEdgeToMachine( FaceToMachine.Edges, 'Bottom', { bAllowFastCuts = true})
OptionalParametersGetBestBlade.EdgeToMachineTop = EdgeToMachineList.Top
OptionalParametersGetBestBlade.EdgeToMachineBottom = EdgeToMachineList.Bottom
nToolIndex, sChosenBladeType = GetBestBlade( Proc, Part, FaceToMachine, OptionalParametersGetBestBlade)
sChosenBladeType = sChosenBladeType .. 'Fast'
end
-- se ancora non è stato trovato un utensile e utensile e lati non arrivavano dall'esterno, se permesso, si prova a scegliere il secondo lato a minor elevazione (bAllowFastCuts)
if bAllowFastCuts and not nToolIndex and not OptionalParameters.nToolIndex and not OptionalParameters.EdgeToMachineList then
EdgeToMachineList.Top = GetEdgeToMachine( FaceToMachine.Edges, 'Top', { bAllowFastCuts = true, nIndex = 2})
EdgeToMachineList.Bottom = GetEdgeToMachine( FaceToMachine.Edges, 'Bottom', { bAllowFastCuts = true, nIndex = 2})
OptionalParametersGetBestBlade.EdgeToMachineTop = EdgeToMachineList.Top
OptionalParametersGetBestBlade.EdgeToMachineBottom = EdgeToMachineList.Bottom
nToolIndex, sChosenBladeType = GetBestBlade( Proc, Part, FaceToMachine, OptionalParametersGetBestBlade)
sChosenBladeType = sChosenBladeType .. 'Fast'
end
-- se possibile, upgrade del taglio tipo 'Top' a taglio a ghigliottina. Si tenta anche se il taglio singolo non è riuscito.
if ( sChosenBladeType == 'Top' or not nToolIndex) and bReduceBladePath and FaceData.IsFaceRectangular( Proc, FaceToMachine.id) then
if ( sChosenBladeType == 'Top' or not nToolIndex) and bReduceBladePath and FaceData.IsFaceRectangle( FaceToMachine) then
local nToolIndexGuillotine
-- ricerca lama migliore testa sopra
local ToolInfo = MachiningLib.FindBlade( Proc, {
vtN = FaceToMachine.vtN,
bAllowTopHead = true,
bAllowBottomHead = false
bAllowBottomHead = false,
FaceToMachine = FaceToMachine,
EdgeToMachine = EdgeToMachineList.TopGuillotine,
Part = Part
})
nToolIndexGuillotine = ToolInfo.nToolIndex
-- se non trovato utensile, si prova in DownUp
if not nToolIndexGuillotine then
ToolInfo = MachiningLib.FindBlade( Proc, {
vtN = -FaceToMachine.vtN,
bAllowTopHead = true,
bAllowBottomHead = false})
if ToolInfo.nToolIndex then
local dMinNzDownUp = TOOLS[ToolInfo.nToolIndex].SetupInfo.GetMinNzDownUp( Part.b3Raw, FaceToMachine.vtN, EdgeToMachineList.TopGuillotine.vtN, TOOLS[ToolInfo.nToolIndex])
if FaceToMachine.vtN:getZ() < dMinNzDownUp then
nToolIndexGuillotine = ToolInfo.nToolIndex
end
end
end
-- test fattibilità taglio a ghigliottina
if nToolIndexGuillotine then
local dRadialOffset = FaceByBlade.GetRadialOffsetForGuillotine( nToolIndexGuillotine, EdgeToMachineList.TopGuillotine.dLength)
@@ -437,7 +442,7 @@ local function GetSingleCutStrategy( Proc, Part, OptionalParameters)
end
local function GetDualSideCutStrategy( Proc, OptionalParameters)
local function GetDualSideCutStrategy( Proc, Part, OptionalParameters)
-- parametri opzionali
OptionalParameters = OptionalParameters or {}
@@ -449,7 +454,7 @@ local function GetDualSideCutStrategy( Proc, OptionalParameters)
-- se possibile, si prova il doppio taglio orizzontale con mix testa sopra/sotto (questa modalità si esclude se l'utensile arriva dall'esterno)
-- TODO valutare se farlo anche doppio orizzontale solo con testa sopra, se la lama ha la corsa per andare sotto!
EdgeToMachine = GetEdgeToMachine( FaceToMachine.Edges, FaceToMachine.vtN, 'HorizontalBottom')
EdgeToMachine = GetEdgeToMachine( FaceToMachine.Edges, 'HorizontalBottom')
if not nToolIndex and AreSameOrOppositeVectorApprox( EdgeToMachine.vtN, Z_AX()) then
-- inizialmente si prova a lavorare in mezzeria
@@ -458,17 +463,22 @@ local function GetDualSideCutStrategy( Proc, OptionalParameters)
-- ricerca lama testa sopra
local ToolInfoTopBlade = MachiningLib.FindBlade( Proc, {
vtN = FaceToMachine.vtN,
bAllowTopHead = true,
bAllowBottomHead = false,
dElevation = dDepthToMachineTop
dElevation = dDepthToMachineTop,
FaceToMachine = FaceToMachine,
EdgeToMachine = EdgeToMachine,
Part = Part
})
-- ricerca lama testa sotto
-- lavorando dalla direzione opposta si verifica come se si lavorasse il lato opposto
local ToolInfoBottomBlade = MachiningLib.FindBlade( Proc, {
vtN = FaceToMachine.vtN,
bAllowTopHead = false,
bAllowBottomHead = true,
dElevation = dDepthToMachineBottom
dElevation = dDepthToMachineBottom,
FaceToMachine = FaceToMachine,
EdgeToMachine = BeamLib.FindEdgeBestOrientedAsDirection( FaceToMachine.Edges, -EdgeToMachine.vtN),
Part = Part
})
local bIsTopLimited = ToolInfoTopBlade.dResidualDepth > 10 * GEO.EPS_SMALL
@@ -480,11 +490,14 @@ local function GetDualSideCutStrategy( Proc, OptionalParameters)
dDepthToMachineTop = TOOLS[ToolInfoTopBlade.nToolIndex].dMaxMaterial
dDepthToMachineBottom = EdgeToMachine.dElevation - dDepthToMachineTop + BeamData.CUT_EXTRA_MIN
-- ricerca lama sotto con la nuova depth
-- lavorando dalla direzione opposta si verifica come se si lavorasse il lato opposto
ToolInfoBottomBlade = MachiningLib.FindBlade( Proc, {
vtN = FaceToMachine.vtN,
bAllowTopHead = false,
bAllowBottomHead = true,
dElevation = dDepthToMachineBottom
dElevation = dDepthToMachineBottom,
FaceToMachine = FaceToMachine,
EdgeToMachine = BeamLib.FindEdgeBestOrientedAsDirection( FaceToMachine.Edges, -EdgeToMachine.vtN),
Part = Part
})
bIsBottomLimited = ToolInfoBottomBlade.dResidualDepth > 10 * GEO.EPS_SMALL
@@ -495,10 +508,12 @@ local function GetDualSideCutStrategy( Proc, OptionalParameters)
dDepthToMachineTop = EdgeToMachine.dElevation - dDepthToMachineBottom + BeamData.CUT_EXTRA_MIN
-- ricerca lama sopra con la nuova depth
ToolInfoTopBlade = MachiningLib.FindBlade( Proc, {
vtN = FaceToMachine.vtN,
bAllowTopHead = true,
bAllowBottomHead = false,
dElevation = dDepthToMachineTop
dElevation = dDepthToMachineTop,
FaceToMachine = FaceToMachine,
EdgeToMachine = EdgeToMachine,
Part = Part
})
bIsTopLimited = ToolInfoTopBlade.dResidualDepth > 10 * GEO.EPS_SMALL
end
@@ -521,19 +536,29 @@ local function GetDualSideCutStrategy( Proc, OptionalParameters)
end
-- arrivati qui si prova il taglio doppio verticale (taglio doppio orizzontale non si può fare oppure non ci arriva)
EdgeToMachine = GetEdgeToMachine( FaceToMachine.Edges, FaceToMachine.vtN, 'Vertical')
EdgeToMachine = GetEdgeToMachine( FaceToMachine.Edges, 'Vertical')
local dDepthToMachine = EdgeToMachine.dElevation / 2 + BeamData.CUT_EXTRA_MIN
-- ricerca lama testa sopra
local ToolInfo = MachiningLib.FindBlade( Proc, {
vtN = FaceToMachine.vtN,
bAllowTopHead = true,
bAllowBottomHead = false,
dElevation = dDepthToMachine
dElevation = dDepthToMachine,
FaceToMachine = FaceToMachine,
EdgeToMachine = EdgeToMachine,
Part = Part
})
-- se lama ci arriva si assegnano utensili e profondità da ritornare
if ToolInfo.nToolIndex and ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then
-- lavorando dalla direzione opposta si verifica come se si lavorasse il lato opposto
local EdgeToMachineOpposite = BeamLib.FindEdgeBestOrientedAsDirection( FaceToMachine.Edges, -EdgeToMachine.vtN)
local bIsApplicableOpposite = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachineOpposite, Part, TOOLS[ToolInfo.nToolIndex], dDepthToMachine)
if not bIsApplicableOpposite then
return CuttingParametersList, EdgeToMachine
end
-- si deve decidere se fare per primo il taglio opposto oppure no
local bIsOppositeCutFirst = false
local vtTemp = EdgeToMachine.vtN ^ FaceToMachine.vtN
@@ -596,18 +621,18 @@ local function CutWholeWaste( Proc, Part, OptionalParameters)
dExtendAfterTail = dExtendAfterTail,
bReduceBladePath = bReduceBladePath
}
if sChosenBladeType == 'Top' or sChosenBladeType == 'Bottom' then
if sChosenBladeType ~= 'TopGuillotine' then
OptionalParametersFaceByBlade.OppositeToolDirectionMode = 'Optimized'
end
Cutting = FaceByBlade.Make( Proc, Part, Proc.Faces[1], EdgeToMachine, OptionalParametersFaceByBlade)
-- se taglio da un lato non ce la fa, si prova da due lati
-- TODO valutare se estendere ai non parallelogrammi
elseif FaceData.IsFaceRhomboid( Proc, Proc.Faces[1].id) then
-- TODO valutare se deve funzionare solo per i rettangoli
elseif FaceData.IsFaceParallelogram( Proc.Faces[1]) then
local CuttingParametersList
CuttingParametersList, EdgeToMachine = GetDualSideCutStrategy( Proc, OptionalParameters)
CuttingParametersList, EdgeToMachine = GetDualSideCutStrategy( Proc, Part, OptionalParameters)
if CuttingParametersList then
local OptionalParametersFaceByBlade = {
@@ -633,6 +658,27 @@ local function CutWholeWaste( Proc, Part, OptionalParameters)
end
end
-- se nessun taglio è riuscito si riprova il taglio singolo permettendo i lati a minor elevazione, abbassando la qualità
if not ( Cutting and Cutting.bIsApplicable) or ( CuttingDouble and not CuttingDouble.bIsApplicable) then
OptionalParameters.bAllowFastCuts = true
nToolIndex, EdgeToMachine, sChosenBladeType = GetSingleCutStrategy( Proc, Part, OptionalParameters)
if nToolIndex then
local OptionalParametersFaceByBlade = {
dDepthToMachine = EdgeToMachine.dElevation + BeamData.CUT_EXTRA,
nToolIndex = nToolIndex,
dExtendAfterTail = dExtendAfterTail,
bReduceBladePath = bReduceBladePath
}
if sChosenBladeType ~= 'TopGuillotine' then
OptionalParametersFaceByBlade.OppositeToolDirectionMode = 'Optimized'
end
Cutting = FaceByBlade.Make( Proc, Part, Proc.Faces[1], EdgeToMachine, OptionalParametersFaceByBlade)
end
end
if Cutting and Cutting.bIsApplicable then
table.insert( Machinings, Cutting)
dCompletionPercentage = Cutting.dCompletionPercentage or dCompletionPercentage
@@ -654,6 +700,10 @@ local function CutWholeWaste( Proc, Part, OptionalParameters)
Result.dCompletionPercentage = dCompletionPercentage
Result.dCompletionIndex = FeatureLib.GetFeatureCompletionIndex( dCompletionPercentage)
Result.dQuality = FeatureLib.GetStrategyQuality( Machinings)
-- per tagli con lati brutti o ghigliottina si abbassa la qualità
if ( sChosenBladeType ~= 'Top') and ( sChosenBladeType ~= 'Bottom') then
Result.dQuality = FeatureLib.GetStrategyQuality( 'STD')
end
Result.dTimeToMachine = FeatureLib.GetStrategyTimeToMachine( Machinings)
Result.dMRR = ( FeatureInfo.dFeatureVolume / Result.dTimeToMachine) / pow( 10, 6)
else
@@ -704,9 +754,6 @@ local function CutWithDicing( Proc, Part, OptionalParameters)
return Machinings, Result
end
-- limite per taglio DownUp
local dMinNzDownUp = TOOLS[nToolIndex].SetupInfo.GetMinNzDownUp( Part.b3Raw, Face1.vtN, nil, TOOLS[nToolIndex])
-- calcolo dimensione cubetto e eventuale cubetto ridotto (tagli orizzontali con affondamento verticale)
local dDiceDimension = min( TOOLS[nToolIndex].dMaxMaterial, BeamData.MAX_DIM_DICE)
local dDiceDimensionReduced = dDiceDimension
@@ -719,8 +766,8 @@ local function CutWithDicing( Proc, Part, OptionalParameters)
OptionalParametersDiceCut.dOffsetParallel = dDiceDimension
OptionalParametersDiceCut.dOffsetOrthogonal = dDiceDimension
OptionalParametersDiceCut.dOffsetOrthogonalReduced = dDiceDimensionReduced
OptionalParametersDiceCut.dMinNzDownUp = dMinNzDownUp
OptionalParametersDiceCut.b3BoxDicing = b3BoxDicing
OptionalParametersDiceCut.bSaveAddedGeometries = bSaveAddedGeometries
local vCuts = DiceCut.GetDice( Part, Face1, Face2, OptionalParametersDiceCut)
-- se nessun cubetto trovato, si richiama ricorsivamente la BladeToWaste forzando di non fare i cubetti
@@ -737,7 +784,7 @@ local function CutWithDicing( Proc, Part, OptionalParameters)
local bAreOrthogonalCutsInverted = false
for i = 1, #vCuts do
for j = 1, #vCuts[i] do
SetDiceFaceInfo( Proc, vCuts[i][j], bSaveAddedGeometries)
SetDiceFaceInfo( Proc, vCuts[i][j])
if ( i % 2) == 1 then
local vtO = EgtSurfTmFacetNormVersor( vCuts[i][j], 0, GDB_ID.ROOT)
if ( Face1.vtN:getY() > 0.766 and vtO:getY() < -0.05) or
@@ -780,8 +827,7 @@ local function CutWithDicing( Proc, Part, OptionalParameters)
-- scelta lato da lavorare per stabilire la vtToolDirection
local EdgeToMachine = {}
local _, Edges = FaceData.GetEdgesInfo( vCuts[i][1], 0)
local vtNCurrentFace = EgtSurfTmFacetNormVersor( vCuts[i][1], 0, GDB_ID.ROOT)
EdgeToMachine = GetEdgeToMachine( Edges, vtNCurrentFace, sChosenBladeType)
EdgeToMachine = GetEdgeToMachine( Edges, sChosenBladeType)
vtToolDirection = EdgeToMachine.vtN
end
end
@@ -815,80 +861,47 @@ local function CutWithDicing( Proc, Part, OptionalParameters)
-- caso standard (tagli perpendicolari o paralleli non accorpabili)
if ( not bCanMergeParallelCuts) or ( not bIsDicingOk) then
for j = 1, #vCuts[i] do
local Cutting = {}
local vtNCurrentFace = EgtSurfTmFacetNormVersor( vCuts[i][j], 0, GDB_ID.ROOT)
local FaceToMachine = { id = 0, vtN = vtNCurrentFace}
-- se taglio DownUp e strato pari composto da 1 o 2 elementi (tutti gli altri casi vengono saltati)
if ( vtNCurrentFace:getZ() < dMinNzDownUp) and ( ( i % 2) == 0) and ( #vCuts[i] <= 2) then
-- il primo elemento prende la direzione prevista, il secondo quella opposta
local vtToolDirectionNew = Vector3d( vtToolDirection)
if j ~= 1 then
vtToolDirectionNew = -vtToolDirection
end
-- lavorazione
local ProcTrimesh = FeatureLib.GetProcFromTrimesh( vCuts[i][j], Part)
local _, Edges = FaceData.GetEdgesInfo( vCuts[i][j], 0)
local EdgeToMachine = BeamLib.FindEdgeBestOrientedAsDirection( Edges, vtToolDirectionNew)
local dDepthToMachine = EdgeToMachine.dElevation + BeamData.CUT_EXTRA
local OptionalParametersFaceByBlade = {
dDepthToMachine = dDepthToMachine,
nToolIndex = nToolIndex,
dRadialStepSpan = 0,
dExtendAfterTail = dExtendAfterTail
}
Cutting = FaceByBlade.Make( ProcTrimesh, Part, FaceToMachine, EdgeToMachine, OptionalParametersFaceByBlade)
Cutting.ptCenter = Point3d( ProcTrimesh.Faces[1].ptCenter:getX(), 0, 0)
if Cutting.bIsApplicable then
table.insert( Machinings, Cutting)
else
bIsDicingOk = false
end
if Cutting.sStage == 'AfterTail' then
bMoveAfterSplit = true
end
-- caso generale
else
-- in generale sta sollevato di pochissimo
local dExtraCut = -0.1
-- se tagli paralleli
if ( i % 2) == 0 then
-- se non ci sono tagli ortogonali devo affondare
if bNoPerpCuts then
-- in generale sta sollevato di pochissimo
local dExtraCut = -0.1
-- se tagli paralleli
if ( i % 2) == 0 then
-- se non ci sono tagli ortogonali devo affondare
if bNoPerpCuts then
dExtraCut = BeamData.CUT_EXTRA
-- se è faccia singola si affonda
elseif Proc.nFct < 2 then
-- se tagli ortogonali invertiti, devo approfondire dello spessore lama
if bAreOrthogonalCutsInverted then
dExtraCut = TOOLS[nToolIndex].dThickness
-- se ultimo taglio, devo affondare
elseif j == #vCuts[i] then
dExtraCut = BeamData.CUT_EXTRA
-- se è faccia singola si affonda
elseif Proc.nFct < 2 then
-- se tagli ortogonali invertiti, devo approfondire dello spessore lama
if bAreOrthogonalCutsInverted then
dExtraCut = TOOLS[nToolIndex].dThickness
-- se ultimo taglio, devo affondare
elseif j == #vCuts[i] then
dExtraCut = BeamData.CUT_EXTRA
end
end
end
local ProcTrimesh = FeatureLib.GetProcFromTrimesh( vCuts[i][j], Part)
local _, Edges = FaceData.GetEdgesInfo( vCuts[i][j], 0)
local EdgeToMachine = BeamLib.FindEdgeBestOrientedAsDirection( Edges, vtToolDirection)
local dDepthToMachine = EdgeToMachine.dElevation + dExtraCut
local OptionalParametersFaceByBlade = {
dDepthToMachine = dDepthToMachine,
nToolIndex = nToolIndex,
dRadialStepSpan = 0,
dExtendAfterTail = dExtendAfterTail
}
Cutting = FaceByBlade.Make( ProcTrimesh, Part, FaceToMachine, EdgeToMachine, OptionalParametersFaceByBlade)
Cutting.ptCenter = Point3d( ProcTrimesh.Faces[1].ptCenter:getX(), 0, 0)
end
local Cutting = {}
local ProcTrimesh = FeatureLib.GetProcFromTrimesh( vCuts[i][j], Part)
local FaceToMachine = ProcTrimesh.Faces[1]
local EdgeToMachine = BeamLib.FindEdgeBestOrientedAsDirection( FaceToMachine.Edges, vtToolDirection)
local dDepthToMachine = EdgeToMachine.dElevation + dExtraCut
local OptionalParametersFaceByBlade = {
dDepthToMachine = dDepthToMachine,
nToolIndex = nToolIndex,
dRadialStepSpan = 0,
dExtendAfterTail = dExtendAfterTail,
bCollisionCheckForDownUpOnly = true
}
Cutting = FaceByBlade.Make( ProcTrimesh, Part, FaceToMachine, EdgeToMachine, OptionalParametersFaceByBlade)
Cutting.ptCenter = Point3d( ProcTrimesh.Faces[1].ptCenter:getX(), 0, 0)
if Cutting.bIsApplicable then
table.insert( Machinings, Cutting)
bIsDicingOk = true
else
bIsDicingOk = false
end
if Cutting.sStage == 'AfterTail' then
bMoveAfterSplit = true
end
if Cutting.bIsApplicable then
table.insert( Machinings, Cutting)
bIsDicingOk = true
else
bIsDicingOk = false
end
if Cutting.sStage == 'AfterTail' then
bMoveAfterSplit = true
end
end
end
@@ -978,7 +991,7 @@ function BLADETOWASTE.Make( ProcOrId, Part, OptionalParameters)
end
end
-- se due facce, cubetti troppo lunghi in X non si possono fare
local ptEdge1, _, ptEdge2 = EgtSurfTmFacetOppositeSide( Proc.id, Proc.Faces[1].id, -Proc.Faces[1].Edges[nCommonEdge].vtN, GDB_ID.ROOT)
local ptEdge1, ptEdge2 = Proc.Faces[1].Edges[nCommonEdge].ptStart, Proc.Faces[1].Edges[nCommonEdge].ptEnd
local b3BoxEdge = BBox3d( ptEdge1, ptEdge2)
local dEdgeLengthOnX = b3BoxEdge:getDimX()
if FeatureLib.IsMachiningLong( dEdgeLengthOnX, Part) then
@@ -1021,13 +1034,14 @@ function BLADETOWASTE.Make( ProcOrId, Part, OptionalParameters)
-- TODO qui sostituire con check topologia DoubleBevel
if dAngleBetweenFaces > 10 * GEO.EPS_SMALL then
-- si creano superfici singole per le facce, estese fino al box della parte
local nAddGrpId = BeamLib.GetAddGroup( Part.id)
local idFace1 = EgtSurfTmPlaneInBBox( nAddGrpId, Proc.Faces[1].ptCenter, Proc.Faces[1].vtN, Part.b3Part, GDB_ID.ROOT)
local idFace2 = EgtSurfTmPlaneInBBox( nAddGrpId, Proc.Faces[2].ptCenter, Proc.Faces[2].vtN, Part.b3Part, GDB_ID.ROOT)
if not bSaveAddedGeometries then
EgtSetLevel( idFace1, GDB_LV.TEMP)
EgtSetLevel( idFace2, GDB_LV.TEMP)
local idAddGroup
if bSaveAddedGeometries then
idAddGroup = BeamLib.GetAddGroup( Part.id)
else
idAddGroup = BeamLib.GetTempGroup()
end
local idFace1 = EgtSurfTmPlaneInBBox( idAddGroup, Proc.Faces[1].ptCenter, Proc.Faces[1].vtN, Part.b3Part, GDB_ID.ROOT)
local idFace2 = EgtSurfTmPlaneInBBox( idAddGroup, Proc.Faces[2].ptCenter, Proc.Faces[2].vtN, Part.b3Part, GDB_ID.ROOT)
-- lavorazione facce
local Machinings1, Result1 = MakeOneFace( idFace1, Part, OptionalParameters)
@@ -1074,10 +1088,10 @@ function BLADETOWASTE.Make( ProcOrId, Part, OptionalParameters)
end
-- feature concava >= 90deg: lavorata con cubetti, se attivi
elseif ( not bDisableDicing) and ( dAngleBetweenFaces >= -91) then
elseif not ( bDisableDicing or FeatureInfo.bIsFeatureSmall) and ( dAngleBetweenFaces >= -91) then
Machinings, Result = CutWithDicing( Proc, Part, OptionalParameters)
-- qui arrivano feature concave < 90deg, oppure >= 90deg con cubetti disabilitati: lavorata come 2 facce singole con accorciamento
-- qui arrivano feature concave < 90deg, oppure >= 90deg con cubetti disabilitati: lavorata come 2 facce singole con eventuale accorciamento
else
-- per ogni faccia si calcola la lavorazione
for i = 1, #Proc.Faces do
@@ -1096,7 +1110,7 @@ function BLADETOWASTE.Make( ProcOrId, Part, OptionalParameters)
local OptionalParametersGetSingleCutStrategy = {
bReduceBladePath = false,
nFaceToMachineIndex = i,
EdgeToMachineList = { Top = EdgeToMachine, Bottom = EdgeToMachine, TopDownUp = EdgeToMachine}
EdgeToMachineList = { Top = EdgeToMachine, Bottom = EdgeToMachine}
}
nToolIndex = GetSingleCutStrategy( Proc, Part, OptionalParametersGetSingleCutStrategy)
end
+123 -74
View File
@@ -16,8 +16,8 @@ local function GetLeadInOutType( Machining)
local sLeadInOutType = ''
if Machining.bIsStartClosed or Machining.bIsEndClosed
or Machining.sCutType == 'Guillotine'
or Machining.sCutType == 'Reduced' then
or Machining.sEdgeUsage == 'Guillotine'
or Machining.sEdgeUsage == 'Reduced' then
sLeadInOutType = 'Perpendicular'
else
@@ -68,10 +68,10 @@ local function CalculateLeadInOut( Machining, EdgeToMachine, bIsSplitFeature)
local dToolMarkLength = sqrt( Machining.dDepthToMachine * TOOLS[Machining.nToolIndex].dDiameter - Machining.dDepthToMachine * Machining.dDepthToMachine)
-- allungamento per faccia singola (aperta in tutte le direzioni)
local dAddedLengthOpenFace = BeamData.CUT_EXTRA
if Machining.sCutType == 'Guillotine' then
if Machining.sEdgeUsage == 'Guillotine' then
local dGuillotineLengthToMachine = 1
dAddedLengthOpenFace = ( - EdgeToMachine.dLength + dGuillotineLengthToMachine) / 2
elseif Machining.sCutType == 'Reduced' then
elseif Machining.sEdgeUsage == 'Reduced' then
dAddedLengthOpenFace = - FACEBYBLADE.GetPathReductionLength( Machining.nToolIndex, Machining.dMaxRadialOffset)
end
@@ -259,60 +259,50 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
dLongitudinalOffset = 0
end
local dRadialStepSpan = OptionalParameters.dRadialStepSpan
local dMinNzDownUp = OptionalParameters.dMinNzDownUp
local sUserNotes = OptionalParameters.sUserNotes or ''
local bCollisionCheckForDownUpOnly = OptionalParameters.bCollisionCheckForDownUpOnly or false
-- lunghezze, direzioni e punti caratteristici della lavorazione e del lato lavorato
Cutting.dEdgeLength = EdgeToMachine.dLength
if OppositeToolDirectionMode == 'Enabled' then
Cutting.vtToolDirection = -EdgeToMachine.vtN
else
Cutting.vtToolDirection = EdgeToMachine.vtN
end
Cutting.vtEdgeDirection = EdgeToMachine.vtN ^ FaceToMachine.vtN
-- TODO conviene spostare questi calcoli nel FaceData?
Cutting.ptEdge1, _, Cutting.ptEdge2 = EgtSurfTmFacetOppositeSide( Proc.id, FaceToMachine.id, -Cutting.vtToolDirection, GDB_ID.ROOT)
-- TODO gestire lama da sotto
-- se si conosce il limite downUp (utensile forzato o downUp forzato) si decide se invertire (ToolInvert)
-- TODO esiste un limite downUp massimo per la lama da sopra??
if nToolIndex and not dMinNzDownUp then
dMinNzDownUp = TOOLS[nToolIndex].SetupInfo.GetMinNzDownUp( Part.b3Raw, FaceToMachine.vtN, Cutting.vtToolDirection, TOOLS[nToolIndex])
end
if dMinNzDownUp and FaceToMachine.vtN:getZ() < dMinNzDownUp then
Cutting.bToolInvert = true
else
Cutting.bToolInvert = false
end
Cutting.vtToolDirection = EdgeToMachine.vtN
Cutting.ptEdge1, Cutting.ptEdge2 = EdgeToMachine.ptStart, EdgeToMachine.ptEnd
local EdgeToMachineOpposite = BeamLib.FindEdgeBestOrientedAsDirection( FaceToMachine.Edges, -EdgeToMachine.vtN)
-- ricerca utensile
-- l'utensile arriva da fuori: si determina se il taglio è fattibile e il modo di lavorare della lama
if nToolIndex then
Cutting.nToolIndex = nToolIndex
Cutting.bIsApplicable, Cutting.sBladeEngagement, Cutting.bMoveAfterSplit = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, Part, TOOLS[Cutting.nToolIndex], dDepthToMachine, bCollisionCheckForDownUpOnly)
-- utensile da cercare: si prende la lama migliore che può effettuare questo taglio, senza particolari analisi
else
local ToolSearchParameters = {}
ToolSearchParameters.dElevation = dDepthToMachine
if Cutting.bToolInvert then
ToolSearchParameters.vtN = -FaceToMachine.vtN
else
ToolSearchParameters.vtN = FaceToMachine.vtN
end
ToolSearchParameters.bAllowTopHead = true
-- TODO bisognerà implementare anche la lama da sotto
ToolSearchParameters.bAllowBottomHead = false
ToolSearchParameters.bAllowBottomHead = true
ToolSearchParameters.bForceLongcutBlade = bForceLongcutBlade
ToolSearchParameters.FaceToMachine = FaceToMachine
ToolSearchParameters.EdgeToMachine = EdgeToMachine
ToolSearchParameters.Part = Part
local ToolInfo = MachiningLib.FindBlade( Proc, ToolSearchParameters)
-- ora che l'utensile è scelto, se non era definito l'angolo di DownUp lo verifico per decidere se invertire
if ToolInfo.nToolIndex and not dMinNzDownUp then
dMinNzDownUp = TOOLS[ToolInfo.nToolIndex].SetupInfo.GetMinNzDownUp( Part.b3Raw, FaceToMachine.vtN, Cutting.vtToolDirection, TOOLS[ToolInfo.nToolIndex])
if FaceToMachine.vtN:getZ() < dMinNzDownUp then
Cutting.bToolInvert = true
end
end
Cutting.nToolIndex = ToolInfo.nToolIndex
Cutting.sBladeEngagement = ToolInfo.sBladeEngagement
Cutting.bMoveAfterSplit = ToolInfo.bMoveAfterSplit
-- se non trovato utensile, la lavorazione non è applicabile
if not Cutting.nToolIndex then
Cutting.bIsApplicable = false
end
end
if not TOOLS[Cutting.nToolIndex] or not TOOLS[Cutting.nToolIndex].sName then
-- orientamento non raggiungibile o lama non trovata: non applicabile
if not Cutting.bIsApplicable then
Cutting.sMessage = 'Blade not found'
Cutting.bIsApplicable = false
EgtOutLog( Cutting.sMessage)
return Cutting, EdgeToMachine.dElevation
end
@@ -322,6 +312,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
Cutting.sMessage = 'Pocket too narrow for blade thickness'
Cutting.bIsApplicable = false
EgtOutLog( Cutting.sMessage)
return Cutting, EdgeToMachine.dElevation
end
-- se tasca chiusa da entrambi i lati e più stretta della lama la lavorazione non è applicabile
@@ -330,16 +321,20 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
Cutting.sMessage = 'Pocket too narrow for blade diameter'
Cutting.bIsApplicable = false
EgtOutLog( Cutting.sMessage)
return Cutting, EdgeToMachine.dElevation
end
end
-- parametri della lavorazione
-- profondità (parametro DEPTH)
Cutting.sDepth = sDepth
-- inizio e fine aperti o chiusi
Cutting.bIsStartClosed = not EdgeToMachine.bIsStartOpen
Cutting.bIsEndClosed = not EdgeToMachine.bIsEndOpen
-- lato di lavoro e inversione per avere taglio concorde
if TOOLS[Cutting.nToolIndex].bIsCCW then
Cutting.nWorkside = MCH_MILL_WS.RIGHT
@@ -348,37 +343,59 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
Cutting.nWorkside = MCH_MILL_WS.LEFT
Cutting.bInvert = false
end
-- se OppositeToolDirectionMode è Optimized, se possibile e necessario, si attiva per garantire taglio concorde e verso l'alto (massima qualità)
if ( OppositeToolDirectionMode == 'Optimized') and ( Proc.nFct == 1) and ( FaceData.IsFaceRhomboid( Proc, FaceToMachine.id)) then
OppositeToolDirectionMode = 'Disabled'
-- la direzione di percorrenza del lato deve essere verso l'alto; bInvert va considerata perchè inverte la direzione di percorrenza.
if ( Cutting.bInvert and Cutting.vtEdgeDirection:getZ() > 100 * GEO.EPS_SMALL)
or ( ( not Cutting.bInvert) and Cutting.vtEdgeDirection:getZ() < -100 * GEO.EPS_SMALL) then
-- si attiva OppositeToolDirection solo se non cambiano le condizioni di taglio downUp
local dNewMinNzDownUp = TOOLS[nToolIndex].SetupInfo.GetMinNzDownUp( Part.b3Raw, FaceToMachine.vtN, -Cutting.vtToolDirection, TOOLS[nToolIndex])
if ( FaceToMachine.vtN:getZ() < dMinNzDownUp) == ( FaceToMachine.vtN:getZ() < dNewMinNzDownUp) then
OppositeToolDirectionMode = 'Enabled'
Cutting.vtToolDirection = -EdgeToMachine.vtN
Cutting.ptEdge1, _, Cutting.ptEdge2 = EgtSurfTmFacetOppositeSide( Proc.id, FaceToMachine.id, -Cutting.vtToolDirection, GDB_ID.ROOT)
Cutting.bInvert = not Cutting.bInvert
-- se le condizioni downUp cambiano, si setta per tagliare verso l'alto
else
if Cutting.nWorkside == MCH_MILL_WS.RIGHT then
Cutting.nWorkside = MCH_MILL_WS.LEFT
Cutting.bInvert = false
else
Cutting.nWorkside = MCH_MILL_WS.RIGHT
Cutting.bInvert = true
end
-- ToolInvert
if Cutting.sBladeEngagement == 'DownUp' then
Cutting.bToolInvert = true
Cutting.bInvert = not Cutting.bInvert
end
-- analisi fattibilità lavorazione dal lato opposto
if OppositeToolDirectionMode ~= 'Disabled' then
-- lavorando dalla direzione opposta si verifica come se si lavorasse il lato opposto
local bIsApplicableOpposite, sBladeEngagementOpposite, bMoveAfterSplit = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachineOpposite, Part, TOOLS[Cutting.nToolIndex], dDepthToMachine, bCollisionCheckForDownUpOnly)
-- taglio opposto non fattibile
if not bIsApplicableOpposite then
-- se richiesto, si ritorna non applicabile
if OppositeToolDirectionMode == 'Enabled' then
Cutting.sMessage = 'Orientation not reachable'
Cutting.bIsApplicable = false
EgtOutLog( Cutting.sMessage)
return Cutting, EdgeToMachine.dElevation
-- se opzionale, si disabilita
elseif OppositeToolDirectionMode == 'Optimized' then
OppositeToolDirectionMode = 'Disabled'
end
end
elseif OppositeToolDirectionMode == 'Enabled' then
Cutting.bInvert = not Cutting.bInvert
end
if Cutting.bToolInvert then
Cutting.bInvert = not Cutting.bInvert
-- se OppositeToolDirectionMode è Optimized, se possibile e necessario, si attiva la lavorazione dal lato opposto per garantire taglio concorde e verso l'alto (massima qualità)
if ( OppositeToolDirectionMode == 'Optimized') and ( Proc.nFct == 1) and ( FaceData.IsFaceParallelogram( FaceToMachine)) then
OppositeToolDirectionMode = 'Disabled'
-- la direzione di percorrenza del lato deve essere verso l'alto; bInvert va considerata perchè inverte la direzione di percorrenza
-- il BladeEngagement non deve cambiare, altrimenti è inutile invertire la direzione
if ( sBladeEngagementOpposite == Cutting.sBladeEngagement)
and ( bMoveAfterSplit == Cutting.bMoveAfterSplit)
and ( Cutting.bInvert and Cutting.vtEdgeDirection:getZ() > 100 * GEO.EPS_SMALL)
or ( ( not Cutting.bInvert) and Cutting.vtEdgeDirection:getZ() < -100 * GEO.EPS_SMALL) then
OppositeToolDirectionMode = 'Enabled'
end
end
if OppositeToolDirectionMode == 'Enabled' then
Cutting.vtToolDirection = EdgeToMachineOpposite.vtN
Cutting.ptEdge1, Cutting.ptEdge2 = EdgeToMachineOpposite.ptStart, EdgeToMachineOpposite.ptEnd
Cutting.bInvert = not Cutting.bInvert
end
end
-- profondità da lavorare e offset radiale
if OptionalParameters.dPocketHeight then
if TOOLS[Cutting.nToolIndex].dMaxDepth > dDepthToMachine - 10 * GEO.EPS_SMALL then
@@ -402,34 +419,56 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
else
Cutting.dDepthToMachine = dDepthToMachine
Cutting.dResidualDepth = 0
Cutting.sCutType = 'Standard'
Cutting.sEdgeUsage = 'Standard'
if bReduceBladePath
and ( Proc.nFct == 1)
and FaceData.IsFaceRectangular( Proc, FaceToMachine.id) then
and FaceData.IsFaceRectangle( FaceToMachine) then
local bIsTopBlade = TOOLS[nToolIndex].SetupInfo.HeadType.bTop
Cutting.dMaxRadialOffset = TOOLS[nToolIndex].dMaxMaterial - Cutting.dDepthToMachine - BeamData.CUT_SIC
Cutting.dRadialOffsetGuillotine = FACEBYBLADE.GetRadialOffsetForGuillotine( nToolIndex, EdgeToMachine.dLength)
-- TODO la lama sotto deve poter ridurre. Ghigliottina sì o no?
local bIsTopBlade = TOOLS[Cutting.nToolIndex].SetupInfo.HeadType.bTop
Cutting.dMaxRadialOffset = TOOLS[Cutting.nToolIndex].dMaxMaterial - Cutting.dDepthToMachine - BeamData.CUT_SIC
Cutting.dRadialOffsetGuillotine = FACEBYBLADE.GetRadialOffsetForGuillotine( Cutting.nToolIndex, EdgeToMachine.dLength)
if Cutting.dMaxRadialOffset > 10 * GEO.EPS_SMALL then
-- taglio a ghigliottina
if bIsTopBlade and ( Cutting.dRadialOffsetGuillotine < Cutting.dMaxRadialOffset - 10 * GEO.EPS_SMALL) then
dDepthToMachine = Cutting.dDepthToMachine + Cutting.dRadialOffsetGuillotine
Cutting.sCutType = 'Guillotine'
Cutting.sEdgeUsage = 'Guillotine'
-- taglio ridotto
else
dDepthToMachine = Cutting.dDepthToMachine + Cutting.dMaxRadialOffset
Cutting.sCutType = 'Reduced'
Cutting.sEdgeUsage = 'Reduced'
end
end
end
-- se cambiata la profondità dDepthToMachine, si ritesta la fattibilità del taglio
if Cutting.sEdgeUsage ~= 'Standard' then
local EdgeToMachineForEngagement = EdgeToMachine
if OppositeToolDirectionMode == 'Enabled' then
EdgeToMachineForEngagement = EdgeToMachineOpposite
end
local bIsApplicable, sBladeEngagement, bMoveAfterSplit = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachineForEngagement, Part, TOOLS[Cutting.nToolIndex], dDepthToMachine)
-- se non fattibile o cambiano le condizioni BladeEngagement, non si riduce
if not ( bIsApplicable and ( sBladeEngagement == Cutting.sBladeEngagement) and ( bMoveAfterSplit == Cutting.bMoveAfterSplit)) then
Cutting.sEdgeUsage = 'Standard'
dDepthToMachine = Cutting.dDepthToMachine
end
end
-- offset radiale (cambia se taglio opposto)
if OppositeToolDirectionMode == 'Enabled' then
Cutting.dRadialOffset = -dDepthToMachine
else
Cutting.dRadialOffset = EdgeToMachine.dElevation - dDepthToMachine
end
end
-- completamento
Cutting.dCompletionPercentage = ( 1 - Cutting.dResidualDepth / Cutting.dDepthToMachine) * 100
-- step verticale e offset longitudinale
Cutting.Steps = MachiningLib.GetMachiningSteps( dPocketHeight, TOOLS[Cutting.nToolIndex].dThickness)
Cutting.Steps.nStepType = MCH_MILL_ST.ONEWAY
@@ -443,10 +482,13 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
else
Cutting.dLongitudinalOffset = dLongitudinalOffset
end
-- distanza di sicurezza
Cutting.dStartSafetyLength = BeamData.CUT_SIC
-- overlap
Cutting.dOverlap = 0
-- EdgeUse e frame lavorazione
if OppositeToolDirectionMode == 'Enabled' then
Cutting.nFaceuse = BeamLib.GetNearestOrthoOpposite( -Cutting.vtToolDirection)
@@ -457,10 +499,13 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
--Cutting.vtFaceUse = Cutting.vtToolDirection
Cutting.nEdgesFaceUse = EdgeToMachine.id
end
-- SCC
Cutting.nSCC = GetSCC( Cutting.vtToolDirection, Cutting.vtEdgeDirection, FaceToMachine.vtN)
-- asse bloccato
Cutting.sBlockedAxis = BeamLib.GetBlockedAxis( Cutting.nToolIndex, 'perpendicular', Part.b3Raw, FaceToMachine.vtN, EgtIf( FaceToMachine.vtN:getX() > 0, X_AX(), -X_AX()))
-- eventuale step orizzontale
Cutting.CloneStepsRadial = {}
if not dRadialStepSpan then
@@ -472,8 +517,10 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
Cutting.CloneStepsRadial.nCount = 1
Cutting.CloneStepsRadial.dStep = Cutting.dDepthToMachine
end
-- approccio e retrazione
Cutting.LeadIn, Cutting.LeadOut = CalculateLeadInOut( Cutting, EdgeToMachine, bIsSplitFeature)
-- lunghezza lavorata
-- TODO per il calcolo del dLengthOnX si deve correggere con allungamento / accorciamento percorso
Cutting.dLengthToMachine = EdgeToMachine.dLength + Cutting.LeadIn.dStartAddLength + Cutting.LeadOut.dEndAddLength
@@ -500,7 +547,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
-- se lavorazione aperta sulla coda, eventuali aggiustamenti
-- TODO valutare se fare funzione a parte
local bIsTruncatingCutOnTail = Proc.Topology and ( Proc.Topology.sName == 'Cut-1-Through' or Proc.Topology.sName == 'TailCut') and Proc.AffectedFaces.bLeft
if bIsTruncatingCutOnTail then
if Cutting.bMoveAfterSplit or bIsTruncatingCutOnTail then
Cutting.sStage = 'AfterTail'
elseif Proc.AffectedFaces.bLeft and ( EdgeToMachine.sType == 'Bottom' or ( Cutting.vtToolDirection:getX() < 0.707)) then
local dLengthOnX = Cutting.dLengthOnX
@@ -517,12 +564,14 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
if not AreSameOrOppositeVectorApprox( EdgeToMachine.vtN, Y_AX()) then
if MachiningLib.CanMoveAfterSplitcut( dLengthOnX, Part) then
Cutting.sStage = 'AfterTail'
Cutting.bMoveAfterSplit = true
else
Cutting.bIsApplicable = false
end
elseif dAddLengthLeftSide + dAddLengthToReduce > dExtendAfterTail then
if MachiningLib.CanMoveAfterSplitcut( dLengthOnX, Part) then
Cutting.sStage = 'AfterTail'
Cutting.bMoveAfterSplit = true
else
if bStartLeft then
Cutting.LeadIn.dStartAddLength = - dAddLengthToReduce + dExtendAfterTail
+1 -1
View File
@@ -83,7 +83,7 @@ function FACEBYCHAINSAW.Make( Proc, Part, FaceToMachine, EdgeToMachine, Optional
Mortising.vtToolDirection = EdgeToMachine.vtN
end
Mortising.vtEdgeDirection = EdgeToMachine.vtN ^ FaceToMachine.vtN
Mortising.ptEdge1, _, Mortising.ptEdge2 = EgtSurfTmFacetOppositeSide( Proc.id, FaceToMachine.id, -Mortising.vtToolDirection, GDB_ID.ROOT)
Mortising.ptEdge1, Mortising.ptEdge2 = EdgeToMachine.ptStart, EdgeToMachine.ptEnd
-- ricerca utensile
local ToolSearchParameters = {}
+1 -2
View File
@@ -204,8 +204,7 @@ function FACEBYMILL.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPara
Milling.vtToolDirection = EdgeToMachine.vtN
end
Milling.vtEdgeDirection = EdgeToMachine.vtN ^ FaceToMachine.vtN
-- TODO conviene spostare questi calcoli nel FaceData?
Milling.ptEdge1, _, Milling.ptEdge2 = EgtSurfTmFacetOppositeSide( Proc.id, FaceToMachine.id, -Milling.vtToolDirection, GDB_ID.ROOT)
Milling.ptEdge1, Milling.ptEdge2 = EdgeToMachine.ptStart, EdgeToMachine.ptEnd
-- se si conosce il limite downUp (utensile forzato o downUp forzato) si decide se invertire (ToolInvert)
if nToolIndex and not dMinNzDownUp then
+2 -2
View File
@@ -2,5 +2,5 @@
-- Gestione della versione di Beam
NAME = 'Beam'
VERSION = '2.6d1'
MIN_EXE = '2.6g1'
VERSION = '2.8a1'
MIN_EXE = '2.7j2'