diff --git a/LuaLibs/BeamLib.lua b/LuaLibs/BeamLib.lua index 9238635..34baa4c 100644 --- a/LuaLibs/BeamLib.lua +++ b/LuaLibs/BeamLib.lua @@ -65,6 +65,64 @@ function BeamLib.AddPartEndFace( PartId, b3Solid) return true end +------------------------------------------------------------------------------------------------------------- +function BeamLib.GetPartBoxWithHeadTail( Part, sSide) + local _sSide = sSide or '' + + -- si può usare il box del grezzo che contiene sempre il sovramateriale di testa + if _sSide == 'Head' then + + local b3WithHead = BBox3d( Part.b3Raw) + return b3WithHead + + -- se è l'ultimo pezzo della barra si aggiunge il box dell'eventuale grezzo successivo + -- se non lo è, si estende il box del pezzo fino alla fine della barra + elseif _sSide == 'Tail' then + + local b3WithTail = BBox3d( Part.b3Part) + if Part.bIsLastPart then + local nNextRawId = EgtGetNextRawPart( Part.idRaw) + if nNextRawId then + local b3Tail = EgtGetRawPartBBox( nNextRawId) + b3WithTail:Add( b3Tail) + end + else + -- per il punto di inizio barra si parte dal box del grezzo perchè contiene già il sovramateriale spessore lama/catena in coda (la restLength non lo comprende) + local ptXMin = Point3d( Part.b3Raw:getMin():getX() - Part.dRestLength, Part.b3Part:getMin():getY(), Part.b3Part:getMin():getZ()) + b3WithTail:Add( ptXMin) + end + + return b3WithTail + + -- per aggiungere entrambi si procede come per la coda ma partendo dal box del grezzo, che già contiene la testa + elseif sSide == 'HeadTail' then + + local b3WithHeadTail = BBox3d( Part.b3Raw) + if Part.bIsLastPart then + local nNextRawId = EgtGetNextRawPart( Part.idRaw) + if nNextRawId then + local b3Tail = EgtGetRawPartBBox( nNextRawId) + b3WithHeadTail:Add( b3Tail) + end + else + -- per il punto di inizio barra si parte dal box del grezzo perchè contiene già il sovramateriale spessore lama/catena in coda (la restLength non lo comprende) + local ptXMin = Point3d( Part.b3Raw:getMin():getX() - Part.dRestLength, Part.b3Part:getMin():getY(), Part.b3Part:getMin():getZ()) + b3WithHeadTail:Add( ptXMin) + end + + return b3WithHeadTail + + -- sSide non definito, si restituisce il box del pezzo con l'aggiunta dello spessore lama/catena in coda + else + local b3WithSplit = BBox3d( Part.b3Part) + -- per il punto di inizio barra si parte dal box del grezzo perchè contiene già il sovramateriale spessore lama/catena in coda (la restLength non lo comprende) + local ptXMin = Point3d( Part.b3Raw:getMin():getX(), Part.b3Part:getMin():getY(), Part.b3Part:getMin():getZ()) + b3WithSplit:Add( ptXMin) + + return b3WithSplit + end +end + ------------------------------------------------------------------------------------------------------------- function BeamLib.GetPartSplittingPoints( Part) local PartSplittingPoints = {} diff --git a/LuaLibs/FeatureLib.lua b/LuaLibs/FeatureLib.lua index aa70c25..13debb8 100644 --- a/LuaLibs/FeatureLib.lua +++ b/LuaLibs/FeatureLib.lua @@ -941,6 +941,7 @@ function FeatureLib.CalculateFeatureNotClampableLengths( Proc, Part) local dNotClampableLengthTail = 0 -- se il grezzo non è definito, prendo il box del pezzo + -- TODO 1- si sta passando b3part per riferimento, 2- non dovrebbe essre sempre definito? if not Part.b3Raw then Part.b3Raw = Part.b3Part end diff --git a/LuaLibs/LeadInOutLib.lua b/LuaLibs/LeadInOutLib.lua index 93cf9f7..bc62cf2 100644 --- a/LuaLibs/LeadInOutLib.lua +++ b/LuaLibs/LeadInOutLib.lua @@ -8,6 +8,7 @@ local LeadInOutLib = {} require( 'EgtBase') local BeamData = require( 'BeamDataNew') local FaceData = require( 'FaceData') +local BeamLib = require( 'BeamLib') EgtOutLog( ' LeadInOutLib started', 1) @@ -99,7 +100,7 @@ end ------------------------------------------------------------------------------------------------------------- -function LeadInOutLib.CalculateLeadInOut( sLeadInOutType, Parameters) +function LeadInOutLib.CalculateLeadInOut( sLeadInOutType, Parameters, OptionalParameters) -- parametri obbligatori local Face = Parameters.Face @@ -108,6 +109,10 @@ function LeadInOutLib.CalculateLeadInOut( sLeadInOutType, Parameters) local Tool = Parameters.Tool local dDepthToMachine = Parameters.dDepthToMachine + -- parametri opzionali + local sRestLengthSideForPreSimulation = OptionalParameters.sRestLengthSideForPreSimulation or 'Tail' + local bCannotSplitRestLength = OptionalParameters.bCannotSplitRestLength or false + local LeadInOut = {} local bIsStartClosed = not Edge.bIsStartOpen local bIsEndClosed = not Edge.bIsEndOpen @@ -159,8 +164,13 @@ function LeadInOutLib.CalculateLeadInOut( sLeadInOutType, Parameters) local ptEndBladeCenter = ptEndAtDepth + Edge.vtN * Tool.dDiameter / 2 -- box per calcolo uscita lama + -- se è un taglio di testa o coda va aggiunto il sovramateriale + local b3BoxPartExpanded = BBox3d( Part.b3Part) + if bCannotSplitRestLength then + b3BoxPartExpanded = BeamLib.GetPartBoxWithHeadTail( Part, sRestLengthSideForPreSimulation) + end -- il box si espande in tutte le direzioni per contemplare la sicurezza CUT_SIC - local b3BoxPartExpanded = BBox3d( Part.b3Part) ; b3BoxPartExpanded:expand( BeamData.CUT_SIC) + b3BoxPartExpanded:expand( BeamData.CUT_SIC) -- calcolo attacco scelto if sLeadInOutType == 'Perpendicular' then diff --git a/LuaLibs/MachiningLib.lua b/LuaLibs/MachiningLib.lua index 0ea68d4..11c0429 100644 --- a/LuaLibs/MachiningLib.lua +++ b/LuaLibs/MachiningLib.lua @@ -284,7 +284,7 @@ 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) +function MachiningLib.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 @@ -319,7 +319,7 @@ local function TestEngagement( sBladeEngagement, Parameters, OptionalParameters) end -- se l'angolo non può essere raggiunto dall'utensile la lavorazione non è fattibile - if IsFaceZOutOfRange( vtHead, Tool) then + if MachiningLib.IsFaceZOutOfRange( vtHead, Tool) then return false end @@ -354,9 +354,14 @@ local function TestEngagement( sBladeEngagement, Parameters, OptionalParameters) -- calcolo e check attacchi local LeadInOut = {} + local LeadInOutOptionalParameters = { + sRestLengthSideForPreSimulation = OptionalParameters.sRestLengthSideForPreSimulation, + bCannotSplitRestLength = OptionalParameters.bCannotSplitRestLength, + bMoveAfterSplit = bMoveAfterSplit + } -- attacco perpendicolare - local PerpendicularLeadInOut = LeadInOutLib.CalculateLeadInOut( 'Perpendicular', Parameters) + local PerpendicularLeadInOut = LeadInOutLib.CalculateLeadInOut( 'Perpendicular', Parameters, LeadInOutOptionalParameters) -- check extracorsa nei punti di attacco PointsOnToolTipCenter = { @@ -380,7 +385,7 @@ local function TestEngagement( sBladeEngagement, Parameters, OptionalParameters) end -- attacco tangenziale - local TangentLeadInOut = LeadInOutLib.CalculateLeadInOut( 'Tangent', Parameters) + local TangentLeadInOut = LeadInOutLib.CalculateLeadInOut( 'Tangent', Parameters, LeadInOutOptionalParameters) -- check extracorsa nei punti di attacco PointsOnToolTipCenter = { PreSimulationLib.GetPointOnToolTipCenter( TangentLeadInOut.LeadIn.ptPoint, vtHead, Face.vtN, Edge.vtN, Tool), @@ -571,7 +576,6 @@ end ------------------------------------------------------------------------------------------------------------- -- funzione per cercare utensile tipo LAMA con certe caratteristiche -- 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 = {} @@ -598,6 +602,8 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters) local EdgeToMachine = ToolSearchParameters.EdgeToMachine local Part = ToolSearchParameters.Part local bIsDicing = ToolSearchParameters.bIsDicing or false + local sRestLengthSideForPreSimulation = ToolSearchParameters.sRestLengthSideForPreSimulation or 'Tail' + local bCannotSplitRestLength = ToolSearchParameters.bCannotSplitRestLength or false local nBestToolIndex local dBestToolResidualDepth = 0 @@ -629,7 +635,9 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters) dDepthToMachine = min( dElevation, TOOLS[i].dMaxDepth) } local BladeEngagementOptionalParameters = { - bIsDicing = bIsDicing + bIsDicing = bIsDicing, + sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation, + bCannotSplitRestLength = bCannotSplitRestLength } TIMER:startElapsed( 'GetBladeEngagement') bIsBladeOk, CurrentEngagement = MachiningLib.GetBladeEngagement( BladeEngagementParameters, BladeEngagementOptionalParameters) @@ -641,7 +649,7 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters) -- se si ha solo la faccia si può verificare se questa è orientata correttamente elseif FaceToMachine then - if IsFaceZOutOfRange( FaceToMachine.vtN, TOOLS[i]) then + if MachiningLib.IsFaceZOutOfRange( FaceToMachine.vtN, TOOLS[i]) then bIsToolCompatible = false end end diff --git a/LuaLibs/PreSimulationLib.lua b/LuaLibs/PreSimulationLib.lua index 1eb8671..b67a9b3 100644 --- a/LuaLibs/PreSimulationLib.lua +++ b/LuaLibs/PreSimulationLib.lua @@ -65,13 +65,29 @@ local function LogOutstroke( ptOnToolTipCenter, vtHead, OptionalParameters) end ------------------------------------------------------------------------------------------------------------- --- costruzione trimesh del grezzo restante (con leggera sovrapposizione) -local function GetRestlengthSurfTm( Part) - +-- costruzione trimesh del grezzo restante in testa o in coda +local function GetRestlengthSurfTm( Part, sSide) + -- 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) + local b3RestLength + if sSide == 'Head' then + local b3PartWithOvermaterial = BeamLib.GetPartBoxWithHeadTail( Part, sSide) + local ptStartRestLength = Point3d( Part.b3Part:getMax():getX(), Part.b3Part:getMax():getY(), Part.b3Part:getMax():getZ()) + local ptEndRestLength = Point3d( b3PartWithOvermaterial:getMax():getX(), Part.b3Part:getMin():getY(), Part.b3Part:getMin():getZ()) + b3RestLength = BBox3d( ptStartRestLength, ptEndRestLength) + elseif sSide == 'Tail' then + local b3PartWithOvermaterial = BeamLib.GetPartBoxWithHeadTail( Part, sSide) + local dXMin = b3PartWithOvermaterial:getMin():getX() + -- si evita sempre di lavorare col motore dietro la coda della barra (potrebbe succedere con barra restante molto corta): in quel caso si deve sempre separare prima + dXMin = min( dXMin, Part.b3Part:getMin():getX() - 2000) + local ptStartRestLength = Point3d( Part.b3Part:getMin():getX(), Part.b3Part:getMax():getY(), Part.b3Part:getMax():getZ()) + local ptEndRestLength = Point3d( dXMin, Part.b3Part:getMin():getY(), Part.b3Part:getMin():getZ()) + b3RestLength = BBox3d( ptStartRestLength, ptEndRestLength) + -- caso non testato, non dovrebbe mai finire qui (il default che arriva da fuori è Tail) + else + return nil + end + -- si crea la trimesh dal box local idRestLengthBoxTm = EgtSurfTmBBox( Part.idTempGroup, b3RestLength , false, GDB_RT.GLOB) @@ -124,14 +140,11 @@ local function GetCollisionPointsToCheck( Edge, dDepthToMachine) or AreSameOrOppositeVectorApprox( Edge.vtEdge, Z_AX()) -- aggiunta punti - -- inizio e fine solo se lato obliquo + table.insert( PointsToCheck, ptStart) if not bIsEdgeParallelToMainDirection then - table.insert( PointsToCheck, ptStart) - end - table.insert( PointsToCheck, ptMid) - if not bIsEdgeParallelToMainDirection then - table.insert( PointsToCheck, ptEnd) + table.insert( PointsToCheck, ptMid) end + table.insert( PointsToCheck, ptEnd) return PointsToCheck end @@ -266,7 +279,7 @@ function PreSimulationLib.CheckOutOfStrokeFromGeometry( idGeometry, vtHead, nSCC end ------------------------------------------------------------------------------------------------------------- -local function CheckCollisionPoint( ptToolExitToCheck, vtC, vtHead, PreCollisionData, Part, bCheckOnlyRestlength) +local function CheckCollisionPoint( ptToolExitToCheck, vtC, vtHead, PreCollisionData, Part, bCannotSplitRestLength, sRestLengthSideForPreSimulation, bCheckOnlyRestlength) local ptPivot = GetGlobalPivot( ptToolExitToCheck, vtC, vtHead, PreCollisionData.vtMovePivot) @@ -297,9 +310,15 @@ local function CheckCollisionPoint( ptToolExitToCheck, vtC, vtHead, PreCollision -- check collisione con pezzo local bCollisionFoundPiece = false if not bCheckOnlyRestlength then - bCollisionFoundPiece = EgtTestSurfaceSurface( Part.idBoxTm, idCollisionSurfTm, BeamData.COLL_SIC) + local idCheckCollisionTm = Part.idBoxTm + -- se testa o coda attaccate, si considerano nella superficie di collisione + if bCannotSplitRestLength then + local b3CheckCollision = BeamLib.GetPartBoxWithHeadTail( Part, sRestLengthSideForPreSimulation) + idCheckCollisionTm = EgtSurfTmBBox( Part.idTempGroup, b3CheckCollision, false, GDB_RT.GLOB) + end + bCollisionFoundPiece = EgtCDeSolidSolid( idCheckCollisionTm, idCollisionSurfTm, BeamData.COLL_SIC) if not type( bCollisionFoundPiece) == "boolean" then - error( 'EgtTestSurfaceSurface fail') + error( 'Presimulation fail') end if EgtGetDebugLevel() >= 3 and bCollisionFoundPiece then EgtSetColor( idCollisionSurfTm, RED()) @@ -311,16 +330,18 @@ local function CheckCollisionPoint( ptToolExitToCheck, vtC, vtHead, PreCollision end end - -- check collisione con grezzo restante, se con il pezzo non c'è collisione + -- check collisione con grezzo restante, se con il pezzo non c'è collisione e non è un taglio di testa o coda local bCollisionFoundRestLength = false - if not bCollisionFoundPiece then - local idRestLengthSurfFr = GetRestlengthSurfTm( Part) - bCollisionFoundRestLength = EgtTestSurfaceSurface( idRestLengthSurfFr, idCollisionSurfTm, BeamData.COLL_SIC) - if not type( bCollisionFoundRestLength) == "boolean" then - error( 'EgtTestSurfaceSurface fail') - end - if EgtGetDebugLevel() >= 3 and bCollisionFoundRestLength then - EgtSetColor( idCollisionSurfTm, ORANGE()) + if not ( bCollisionFoundPiece or bCannotSplitRestLength) then + local idRestLengthSurfFr = GetRestlengthSurfTm( Part, sRestLengthSideForPreSimulation) + if idRestLengthSurfFr then + bCollisionFoundRestLength = EgtCDeSolidSolid( idRestLengthSurfFr, idCollisionSurfTm, BeamData.COLL_SIC) + if not type( bCollisionFoundRestLength) == "boolean" then + error( 'Presimulation fail') + end + if EgtGetDebugLevel() >= 3 and bCollisionFoundRestLength then + EgtSetColor( idCollisionSurfTm, ORANGE()) + end end end @@ -342,21 +363,14 @@ local function CheckCollisionWithAxis( sAxis, MachiningParameters, OptionalParam -- parametri opzionali OptionalParameters = OptionalParameters or {} local bCheckOnlyRestlength = OptionalParameters.bCheckOnlyRestlength or false + local sRestLengthSideForPreSimulation = OptionalParameters.sRestLengthSideForPreSimulation or 'Tail' + local bCannotSplitRestLength = OptionalParameters.bCannotSplitRestLength or false -- se normale faccia non parallela a direzione testa c'è qualcosa che non va if not AreSameOrOppositeVectorApprox( vtNFace, vtHead) then error( 'CheckCollisionWithAxis : invalid directions') end - - -- TODO modificare e rimettere (Hmax pezzo) - -- 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 - + -- punti notevoli della lavorazione in cui fare il check local PointsToCheck = OptionalParameters.PointsToCheck or GetCollisionPointsToCheck( Edge, dDepthToMachine) @@ -387,7 +401,7 @@ local function CheckCollisionWithAxis( sAxis, MachiningParameters, OptionalParam -- se non si trova collisione si ritorna se è necessario separare prima di effettuare la lavorazione (ossia non c'è collisione con il pezzo ma c'è con il grezzo restante) for i = 1, #ToolExitPoints do - local bCollisionFoundPiece, bCollisionFoundRestLength = CheckCollisionPoint( ToolExitPoints[i], vtC, vtHead, PreCollisionData, Part, bCheckOnlyRestlength) + local bCollisionFoundPiece, bCollisionFoundRestLength = CheckCollisionPoint( ToolExitPoints[i], vtC, vtHead, PreCollisionData, Part, bCannotSplitRestLength, sRestLengthSideForPreSimulation, bCheckOnlyRestlength) -- se trovata collisione con pezzo è inutile controllare gli altri punti if bCollisionFoundPiece then @@ -417,6 +431,8 @@ function PreSimulationLib.CheckCollision( sBladeEngagement, Parameters, Optional local OptionalParametersCheckCollisionWithAxis = {} OptionalParametersCheckCollisionWithAxis.bCheckOnlyRestlength = false OptionalParametersCheckCollisionWithAxis.PointsToCheck = OptionalParameters.PointsToCheck or nil + OptionalParametersCheckCollisionWithAxis.sRestLengthSideForPreSimulation = OptionalParameters.sRestLengthSideForPreSimulation or 'Tail' + OptionalParametersCheckCollisionWithAxis.bCannotSplitRestLength = OptionalParameters.bCannotSplitRestLength or false local bIsDicing = OptionalParameters.bIsDicing or false local bCheckOnlyRestlengthForAxisABC = false @@ -424,12 +440,17 @@ function PreSimulationLib.CheckCollision( sBladeEngagement, Parameters, Optional -- se cubetti in modalità standard (no DownUp) gli assi AB e C si controllano solo con grezzo (ci sarebbe collisione con il materiale già rimosso controllando AB e C con pezzo) if bIsDicing and ( sBladeEngagement == 'Standard') then bCheckOnlyRestlengthForAxisABC = true - -- se l'elevazione reale (rispetto al pezzo) è maggiore del massimo materiale è sempre collisione - -- TODO funzione + -- se l'elevazione reale (rispetto al pezzo + eventuale materiale in testa/coda) è maggiore del massimo materiale è sempre collisione + -- TODO rifare con funzione else local Edge = Parameters.Edge local vtNFace = Parameters.vtNFace local dDepthToMachine = Parameters.dDepthToMachine + local b3BoxForElevationCheck = BBox3d( Parameters.Part.b3Part) + -- se è un taglio di testa o coda va aggiunto il sovramateriale + if OptionalParametersCheckCollisionWithAxis.bCannotSplitRestLength then + b3BoxForElevationCheck = BeamLib.GetPartBoxWithHeadTail( Parameters.Part, OptionalParametersCheckCollisionWithAxis.sRestLengthSideForPreSimulation) + end -- trimesh rettangolare con un lato corrispondente al lato da lavorare e larghezza come spessore utensile local idTrimesh = EgtSurfTmRectangle( Parameters.Part.idTempGroup, Edge.ptStart, Edge.ptEnd, Edge.ptEnd + vtNFace * Parameters.Tool.dThickness, GDB_RT.GLOB) local vtNTrimesh = EgtSurfTmFacetNormVersor( idTrimesh, 0, GDB_ID.ROOT) @@ -437,7 +458,7 @@ function PreSimulationLib.CheckCollision( sBladeEngagement, Parameters, Optional if not AreSameVectorApprox( Edge.vtN, vtNTrimesh) then EgtInvertSurf( idTrimesh) end - local dRealElevation = EgtSurfTmFacetElevationInBBox( idTrimesh, 0, Parameters.Part.b3Part, true, GDB_ID.ROOT) + local dRealElevation = EgtSurfTmFacetElevationInBBox( idTrimesh, 0, b3BoxForElevationCheck, true, GDB_ID.ROOT) local dRealDepthToMachine = ( dRealElevation - Parameters.Edge.dElevation + dDepthToMachine) if dRealDepthToMachine > Parameters.Tool.dMaxDepth + 10 * GEO.EPS_SMALL then return true diff --git a/Strategies/Standard/HEADCUT/HEADCUT.lua b/Strategies/Standard/HEADCUT/HEADCUT.lua index c1bdd59..c5fea98 100644 --- a/Strategies/Standard/HEADCUT/HEADCUT.lua +++ b/Strategies/Standard/HEADCUT/HEADCUT.lua @@ -34,6 +34,8 @@ function HEADCUT.Make( bAddMachining, Proc, Part, CustomParameters) Strategy.Result.sInfo = '' local OptionalParameters = { bForceChainSaw = Strategy.Parameters.bForceChainSaw, bReduceBladePath = Strategy.Parameters.bReduceBladePath, dMaxWasteLength = Strategy.Parameters.dMaxWasteLength, dMaxWasteVolume = Strategy.Parameters.dMaxWasteVolume } + OptionalParameters.sRestLengthSideForPreSimulation = 'Head' + OptionalParameters.bCannotSplitRestLength = true local bAreAllMachiningsAdded = true -- si setta che è taglio di testa @@ -43,8 +45,12 @@ function HEADCUT.Make( bAddMachining, Proc, Part, CustomParameters) if Strategy.Parameters.bExecutePreCut then Strategy.SplitStrategy, Strategy.Result = SPLITCUT.GetMachining( Proc, Part, OptionalParameters) -- se non faccio tagli PRECUT, imposto tabella Result direttamente. Non serve verificare che riesca a rimuovere il materiale extra - if not Strategy.SplitStrategy or #Strategy.SplitStrategy == 0 then - Strategy.Result.sInfo = 'PreCut on head not possible' + -- if not Strategy.SplitStrategy or #Strategy.SplitStrategy == 0 then + -- Strategy.Result.sInfo = 'PreCut on head not possible' + -- end + if Strategy.Result.sStatus ~= 'Completed' then + Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( 'Precut Head not possible') + return false, Strategy.Result end end @@ -92,24 +98,35 @@ function HEADCUT.Make( bAddMachining, Proc, Part, CustomParameters) end if not bExecutePrecutOnly then - local OptionalParameters = {} - -- si parte dal box della feature e si aggiunge il punto estremo del grezzo - local b3BoxDicing = BBox3d( Proc.b3Box) - b3BoxDicing:Add( Part.b3Raw:getMax()) - b3BoxDicing:expand( 1000 * GEO.EPS_SMALL) - OptionalParameters.b3BoxDicing = b3BoxDicing - OptionalParameters.dMaxWasteVolume = Strategy.Parameters.dMaxWasteVolume - OptionalParameters.dMaxWasteLength = Strategy.Parameters.dMaxWasteLength - OptionalParameters.bReduceBladePath = Strategy.Parameters.bReduceBladePath + -- si recuperano gli estremi del box del materiale di testa da togliere + local b3PartWithHead = BeamLib.GetPartBoxWithHeadTail( Part, 'Head') + local ptStartRestLength = Point3d( Part.b3Part:getMax():getX() - 1, Part.b3Part:getMax():getY(), Part.b3Part:getMax():getZ()) + local ptEndRestLength = Point3d( b3PartWithHead:getMax():getX(), Part.b3Part:getMin():getY(), Part.b3Part:getMin():getZ()) - Strategy.Machining, _ = BladeToWaste.Make( Proc, Part, OptionalParameters) + local OptionalParametersBladeToWaste = {} + OptionalParametersBladeToWaste.b3BoxDicing = BBox3d( ptStartRestLength, ptEndRestLength) + OptionalParametersBladeToWaste.dMaxWasteVolume = Strategy.Parameters.dMaxWasteVolume + OptionalParametersBladeToWaste.dMaxWasteLength = Strategy.Parameters.dMaxWasteLength + OptionalParametersBladeToWaste.bReduceBladePath = Strategy.Parameters.bReduceBladePath + OptionalParametersBladeToWaste.sRestLengthSideForPreSimulation = 'Head' + OptionalParametersBladeToWaste.bCannotSplitRestLength = true + + Strategy.Machining, _ = BladeToWaste.Make( Proc, Part, OptionalParametersBladeToWaste) + -- se taglio non riuscito, si riprova con il riduci percorso forzato (collisione possibile in separazione pezzi alti) + if ( not Strategy.Machining) or ( #Strategy.Machining == 0) then + OptionalParametersBladeToWaste.bReduceBladePath = true + Strategy.Machining, _ = BladeToWaste.Make( Proc, Part, OptionalParametersBladeToWaste) + end if Strategy.Machining and #Strategy.Machining > 0 then for i = 1, #Strategy.Machining do local TempList = {} TempList = Strategy.Machining[i] table.insert( MachiningsToAdd, TempList) end + else + Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( 'Head machining not possible') + return false, Strategy.Result end end diff --git a/Strategies/Standard/STR0012/STR0012.lua b/Strategies/Standard/STR0012/STR0012.lua index 9b5bcbc..949a492 100644 --- a/Strategies/Standard/STR0012/STR0012.lua +++ b/Strategies/Standard/STR0012/STR0012.lua @@ -73,8 +73,14 @@ function STR0012.Make( bAddMachining, Proc, Part, CustomParameters) if not( AreSameVectorApprox( Proc.Faces[nAddedFace + 1].vtN, X_AX()) and abs( Proc.Faces[nAddedFace + 1].ptCenter:getX() - Part.b3Part:getMax():getX()) < 10 * GEO.EPS_SMALL) and not( AreSameVectorApprox( Proc.Faces[nAddedFace + 1].vtN, -X_AX()) and abs( Proc.Faces[nAddedFace + 1].ptCenter:getX() - Part.b3Part:getMin():getX()) < 10 * GEO.EPS_SMALL) then - -- faccia aggiuntiva da lavorare - idAddedTmFace = EgtCopySurfTmFacet( Proc.id, nAddedFace, nAddGrpId) + -- faccia aggiuntiva da lavorare: si estende fino al box della parte + local idAddGroup + if bAddMachining then + idAddGroup = BeamLib.GetAddGroup( Part.id) + else + idAddGroup = Part.idTempGroup + end + idAddedTmFace = EgtSurfTmPlaneInBBox( idAddGroup, Proc.Faces[nAddedFace + 1].ptCenter, Proc.Faces[nAddedFace + 1].vtN, Part.b3Part, GDB_ID.ROOT) end -- rimozione della terza faccia dalla Proc diff --git a/Strategies/Standard/TAILCUT/TAILCUT.lua b/Strategies/Standard/TAILCUT/TAILCUT.lua index f2d5f56..19767bd 100644 --- a/Strategies/Standard/TAILCUT/TAILCUT.lua +++ b/Strategies/Standard/TAILCUT/TAILCUT.lua @@ -34,6 +34,8 @@ function TAILCUT.Make( bAddMachining, Proc, Part, CustomParameters) Strategy.Result.sInfo = '' local OptionalParameters = { bForceChainSaw = Strategy.Parameters.bForceChainSaw, bReduceBladePath = Strategy.Parameters.bReduceBladePath, dMaxWasteLength = Strategy.Parameters.dMaxWasteLength, dMaxWasteVolume = Strategy.Parameters.dMaxWasteVolume } + OptionalParameters.sRestLengthSideForPreSimulation = 'Tail' + OptionalParameters.bCannotSplitRestLength = true local bAreAllMachiningsAdded = true local bExecutePrecutOnly = false @@ -49,6 +51,11 @@ function TAILCUT.Make( bAddMachining, Proc, Part, CustomParameters) OptionalParameters.bDisableDicing = true Strategy.SplitStrategy, Strategy.Result = SPLITCUT.GetMachining( Proc, Part, OptionalParameters) + if Strategy.Result.sStatus ~= 'Completed' then + Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( 'Split not possible') + return false, Strategy.Result + end + -- se devo rimuovere tutto il restante else -- se abilitato, faccio tagli di PRECUT a zero (come SPLIT) @@ -58,10 +65,18 @@ function TAILCUT.Make( bAddMachining, Proc, Part, CustomParameters) OptionalParameters.dOffset = 0 else Strategy.bIsPreCut = true + -- TODO questo dOffset è errato, va creata una nuova faccia oppure usare dLongitudinalOffset e farlo transitare per tutti, anche Engagement + -- TODO a dRestLength va anche aggiunto lo spessore lama se c'è a fine grezzo? OptionalParameters.dOffset = Part.dRestLength end OptionalParameters.bDisableDicing = true Strategy.SplitStrategy, Strategy.Result = SPLITCUT.GetMachining( Proc, Part, OptionalParameters) + + if Strategy.Result.sStatus ~= 'Completed' then + Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( 'Precut Tail not possible') + return false, Strategy.Result + end + -- se non faccio tagli PRECUT, imposto tabella Result direttamente. Non serve verificare che riesca a rimuovere il materiale extra else Strategy.Result.sStatus = 'Completed' @@ -122,21 +137,26 @@ function TAILCUT.Make( bAddMachining, Proc, Part, CustomParameters) end if not bExecutePrecutOnly then - OptionalParameters = {} - -- eventuale grezzo custom per dicing (grezzo attuale + grezzo di coda) - local nNextRawId = EgtGetNextRawPart( Part.idRaw) - if nNextRawId then - local b3BoxDicing = EgtGetRawPartBBox( nNextRawId) - b3BoxDicing:Add( Part.b3Raw) - OptionalParameters.b3BoxDicing = b3BoxDicing + -- si recuperano gli estremi del box del materiale di coda da rimuovere + local b3PartWithTail = BeamLib.GetPartBoxWithHeadTail( Part, 'Tail') + local ptStartRestLength = Point3d( Part.b3Part:getMin():getX() + 1, Part.b3Part:getMax():getY(), Part.b3Part:getMax():getZ()) + local ptEndRestLength = Point3d( b3PartWithTail:getMin():getX(), Part.b3Part:getMin():getY(), Part.b3Part:getMin():getZ()) + + local OptionalParametersBladeToWaste = {} + OptionalParametersBladeToWaste.b3BoxDicing = BBox3d( ptStartRestLength, ptEndRestLength) + OptionalParametersBladeToWaste.dMaxWasteVolume = Strategy.Parameters.dMaxWasteVolume + OptionalParametersBladeToWaste.dMaxWasteLength = Strategy.Parameters.dMaxWasteLength + OptionalParametersBladeToWaste.bReduceBladePath = Strategy.Parameters.bReduceBladePath + OptionalParametersBladeToWaste.sRestLengthSideForPreSimulation = 'Tail' + OptionalParametersBladeToWaste.bCannotSplitRestLength = true + + Strategy.Machining, _ = BladeToWaste.Make( Proc, Part, OptionalParametersBladeToWaste) + -- se taglio non riuscito, si riprova con il riduci percorso forzato (collisione possibile in separazione pezzi alti) + if ( not Strategy.Machining) or ( #Strategy.Machining == 0) then + OptionalParametersBladeToWaste.bReduceBladePath = true + Strategy.Machining, _ = BladeToWaste.Make( Proc, Part, OptionalParametersBladeToWaste) end - - OptionalParameters.dMaxWasteVolume = Strategy.Parameters.dMaxWasteVolume - OptionalParameters.dMaxWasteLength = Strategy.Parameters.dMaxWasteLength - OptionalParameters.bReduceBladePath = Strategy.Parameters.bReduceBladePath - - Strategy.Machining, _ = BladeToWaste.Make( Proc, Part, OptionalParameters) if Strategy.Machining and #Strategy.Machining > 0 then for i = 1, #Strategy.Machining do local TempList = {} @@ -149,6 +169,9 @@ function TAILCUT.Make( bAddMachining, Proc, Part, CustomParameters) end table.insert( MachiningsToAdd, TempList) end + else + Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( 'Tail machining not possible') + return false, Strategy.Result end end end diff --git a/StrategyLibs/BLADETOWASTE.lua b/StrategyLibs/BLADETOWASTE.lua index aeae7b0..d2fce68 100644 --- a/StrategyLibs/BLADETOWASTE.lua +++ b/StrategyLibs/BLADETOWASTE.lua @@ -260,6 +260,9 @@ local function GetBestBlade( Proc, Part, Face, OptionalParameters) local dShortPartLength = OptionalParameters.dShortPartLength or BeamData.LEN_SHORT_PART local EdgeToMachineTop = OptionalParameters.EdgeToMachineTop local EdgeToMachineBottom = OptionalParameters.EdgeToMachineBottom + local bIsDicing = OptionalParameters.bIsDicing + local sRestLengthSideForPreSimulation = OptionalParameters.sRestLengthSideForPreSimulation + local bCannotSplitRestLength = OptionalParameters.bCannotSplitRestLength -- TODO qui sarebbe meglio avere dExtra come OptionalParameter??? local dElevationTop = EdgeToMachineTop and EdgeToMachineTop.dElevation + BeamData.CUT_EXTRA or nil local dElevationBottom = EdgeToMachineBottom and EdgeToMachineBottom.dElevation + BeamData.CUT_EXTRA or nil @@ -285,7 +288,10 @@ local function GetBestBlade( Proc, Part, Face, OptionalParameters) dElevation = dElevationTop, FaceToMachine = Face, EdgeToMachine = EdgeToMachineTop, - Part = Part + Part = Part, + bIsDicing = bIsDicing, + sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation, + bCannotSplitRestLength = bCannotSplitRestLength }) if ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then nToolIndexTop = ToolInfo.nToolIndex @@ -297,7 +303,10 @@ local function GetBestBlade( Proc, Part, Face, OptionalParameters) dElevation = dElevationBottom, FaceToMachine = Face, EdgeToMachine = EdgeToMachineBottom, - Part = Part + Part = Part, + bIsDicing = bIsDicing, + sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation, + bCannotSplitRestLength = bCannotSplitRestLength }) if ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then nToolIndexBottom = ToolInfo.nToolIndex @@ -362,6 +371,9 @@ local function GetSingleCutStrategy( Proc, Part, OptionalParameters) local bReduceBladePath = OptionalParameters.bReduceBladePath or false local bAllowFastCuts = OptionalParameters.bAllowFastCuts or false local FaceToMachine = Proc.Faces[OptionalParameters.nFaceToMachineIndex or 1] + local bIsDicing = OptionalParameters.bIsDicing or false + local sRestLengthSideForPreSimulation = OptionalParameters.sRestLengthSideForPreSimulation or 'Tail' + local bCannotSplitRestLength = OptionalParameters.bCannotSplitRestLength or false -- lati da lavorare in base al tipo di lama -- se non arrivano dall'esterno si cercano i migliori disponibili, dapprima ignorando il flag bAllowFastCuts local EdgeToMachineList = OptionalParameters.EdgeToMachineList @@ -377,7 +389,10 @@ local function GetSingleCutStrategy( Proc, Part, OptionalParameters) local OptionalParametersGetBestBlade = { EdgeToMachineTop = EdgeToMachineList.Top, EdgeToMachineBottom = EdgeToMachineList.Bottom, - nToolIndex = nToolIndex + nToolIndex = nToolIndex, + bIsDicing = bIsDicing, + sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation, + bCannotSplitRestLength = bCannotSplitRestLength } -- se nToolIndex è presente, GetBestBlade sceglierà solo il lato, altrimenti sceglierà lama e lato nToolIndex, sChosenBladeType = GetBestBlade( Proc, Part, FaceToMachine, OptionalParametersGetBestBlade) @@ -426,7 +441,10 @@ local function GetSingleCutStrategy( Proc, Part, OptionalParameters) dElevation = EdgeToMachineList.TopGuillotine.dElevation, FaceToMachine = FaceToMachine, EdgeToMachine = EdgeToMachineList.TopGuillotine, - Part = Part + Part = Part, + bIsDicing = bIsDicing, + sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation, + bCannotSplitRestLength = bCannotSplitRestLength }) nToolIndexGuillotine = ToolInfo.nToolIndex @@ -457,6 +475,9 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters) OptionalParameters = OptionalParameters or {} local nToolIndex = OptionalParameters.nToolIndex local FaceToMachine = Proc.Faces[OptionalParameters.nFaceToMachineIndex or 1] + local bIsDicing = OptionalParameters.bIsDicing or false + local sRestLengthSideForPreSimulation = OptionalParameters.sRestLengthSideForPreSimulation or 'Tail' + local bCannotSplitRestLength = OptionalParameters.bCannotSplitRestLength or false local CuttingParametersList local EdgeToMachine @@ -477,7 +498,10 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters) dElevation = dDepthToMachineTop, FaceToMachine = FaceToMachine, EdgeToMachine = EdgeToMachine, - Part = Part + Part = Part, + bIsDicing = bIsDicing, + sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation, + bCannotSplitRestLength = bCannotSplitRestLength }) -- ricerca lama testa sotto -- lavorando dalla direzione opposta si verifica come se si lavorasse il lato opposto @@ -487,7 +511,10 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters) dElevation = dDepthToMachineBottom, FaceToMachine = FaceToMachine, EdgeToMachine = BeamLib.FindEdgeBestOrientedAsDirection( FaceToMachine.Edges, -EdgeToMachine.vtN), - Part = Part + Part = Part, + bIsDicing = bIsDicing, + sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation, + bCannotSplitRestLength = bCannotSplitRestLength }) local bIsTopLimited = ToolInfoTopBlade.dResidualDepth > 10 * GEO.EPS_SMALL @@ -506,7 +533,10 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters) dElevation = dDepthToMachineBottom, FaceToMachine = FaceToMachine, EdgeToMachine = BeamLib.FindEdgeBestOrientedAsDirection( FaceToMachine.Edges, -EdgeToMachine.vtN), - Part = Part + Part = Part, + bIsDicing = bIsDicing, + sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation, + bCannotSplitRestLength = bCannotSplitRestLength }) bIsBottomLimited = ToolInfoBottomBlade.dResidualDepth > 10 * GEO.EPS_SMALL @@ -522,7 +552,10 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters) dElevation = dDepthToMachineTop, FaceToMachine = FaceToMachine, EdgeToMachine = EdgeToMachine, - Part = Part + Part = Part, + bIsDicing = bIsDicing, + sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation, + bCannotSplitRestLength = bCannotSplitRestLength }) bIsTopLimited = ToolInfoTopBlade.dResidualDepth > 10 * GEO.EPS_SMALL end @@ -555,7 +588,10 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters) dElevation = dDepthToMachine, FaceToMachine = FaceToMachine, EdgeToMachine = EdgeToMachine, - Part = Part + Part = Part, + bIsDicing = bIsDicing, + sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation, + bCannotSplitRestLength = bCannotSplitRestLength }) -- se lama ci arriva si assegnano utensili e profondità da ritornare @@ -570,8 +606,13 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters) Tool = TOOLS[ToolInfo.nToolIndex], dDepthToMachine = dDepthToMachine } + local BladeEngagementOptionalParameters = { + bIsDicing = bIsDicing, + sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation, + bCannotSplitRestLength = bCannotSplitRestLength + } TIMER:startElapsed( 'GetBladeEngagement') - local bIsApplicableOpposite = MachiningLib.GetBladeEngagement( BladeEngagementParameters) + local bIsApplicableOpposite = MachiningLib.GetBladeEngagement( BladeEngagementParameters, BladeEngagementOptionalParameters) TIMER:stopElapsed( 'GetBladeEngagement') if not bIsApplicableOpposite then return CuttingParametersList, EdgeToMachine @@ -627,6 +668,8 @@ local function CutWholeWaste( Proc, Part, OptionalParameters) local nToolIndex = OptionalParameters.nToolIndex local dExtendAfterTail = OptionalParameters.dExtendAfterTail or 10000 local bReduceBladePath = OptionalParameters.bReduceBladePath or false + local sRestLengthSideForPreSimulation = OptionalParameters.sRestLengthSideForPreSimulation or 'Tail' + local bCannotSplitRestLength = OptionalParameters.bCannotSplitRestLength or false -- si cerca di tagliare tutto da un lato nToolIndex, EdgeToMachine, sChosenBladeType = GetSingleCutStrategy( Proc, Part, OptionalParameters) @@ -637,7 +680,9 @@ local function CutWholeWaste( Proc, Part, OptionalParameters) dDepthToMachine = EdgeToMachine.dElevation + BeamData.CUT_EXTRA, nToolIndex = nToolIndex, dExtendAfterTail = dExtendAfterTail, - bReduceBladePath = bReduceBladePath + bReduceBladePath = bReduceBladePath, + sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation, + bCannotSplitRestLength = bCannotSplitRestLength } if sChosenBladeType ~= 'TopGuillotine' then OptionalParametersFaceByBlade.OppositeToolDirectionMode = 'Optimized' @@ -657,13 +702,17 @@ local function CutWholeWaste( Proc, Part, OptionalParameters) nToolIndex = CuttingParametersList[1].nToolIndex, dExtendAfterTail = dExtendAfterTail, bReduceBladePath = bReduceBladePath, - OppositeToolDirectionMode = 'Enabled' + OppositeToolDirectionMode = 'Enabled', + sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation, + bCannotSplitRestLength = bCannotSplitRestLength } local OptionalParametersFaceByBladeDouble = { dDepthToMachine = CuttingParametersList[2].dDepthToMachine, nToolIndex = CuttingParametersList[2].nToolIndex, dExtendAfterTail = dExtendAfterTail, - bReduceBladePath = bReduceBladePath + bReduceBladePath = bReduceBladePath, + sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation, + bCannotSplitRestLength = bCannotSplitRestLength } -- se necessario, si inverte l'ordine delle lavorazioni per avere il secondo taglio verso l'alto if not CuttingParametersList.bIsOppositeCutFirst then @@ -686,7 +735,9 @@ local function CutWholeWaste( Proc, Part, OptionalParameters) dDepthToMachine = EdgeToMachine.dElevation + BeamData.CUT_EXTRA, nToolIndex = nToolIndex, dExtendAfterTail = dExtendAfterTail, - bReduceBladePath = bReduceBladePath + bReduceBladePath = bReduceBladePath, + sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation, + bCannotSplitRestLength = bCannotSplitRestLength } if sChosenBladeType ~= 'TopGuillotine' then OptionalParametersFaceByBlade.OppositeToolDirectionMode = 'Optimized' @@ -742,6 +793,8 @@ local function CalculateDiceMachinings( vCuts, Parameters) local sChosenBladeType = Parameters.sChosenBladeType local dExtendAfterTail = Parameters.dExtendAfterTail local bReduceBladePath = Parameters.bReduceBladePath + local sRestLengthSideForPreSimulation = Parameters.sRestLengthSideForPreSimulation + local bCannotSplitRestLength = Parameters.bCannotSplitRestLength -- eventuale inversione tagli ortogonali e aggiunta informazioni alla geometria local bAreOrthogonalCutsInverted = false @@ -750,8 +803,7 @@ local function CalculateDiceMachinings( vCuts, Parameters) SetDiceFaceInfo( Proc, vCuts[i][j]) if ( i % 2) == 1 then local vtO = EgtSurfTmFacetNormVersor( vCuts[i][j], 0, GDB_ID.ROOT) - if ( MainFace.vtN:getY() > 0.766 and vtO:getY() < -0.05) or - ( MainFace.vtN:getY() < -0.766 and vtO:getY() > 0.05) then + if MachiningLib.IsFaceZOutOfRange( vtO, Tool) then EgtInvertSurf( vCuts[i][j]) bAreOrthogonalCutsInverted = true end @@ -796,6 +848,7 @@ local function CalculateDiceMachinings( vCuts, Parameters) end -- calcolo lavorazione della singola faccia -- per tagli paralleli e faccia aperta si prova a tagliare come se fosse una faccia singola, accorpando i tagli + -- TODO bIsDicing è da mettere a true? local bCanMergeParallelCuts = ( ( i % 2) == 0) and ( Proc.nFct == 1) local bIsDicingOk = true if bCanMergeParallelCuts then @@ -806,7 +859,10 @@ local function CalculateDiceMachinings( vCuts, Parameters) local OptionalParametersCutWholeWaste = { nToolIndex = Tool.nIndex, dExtendAfterTail = dExtendAfterTail, - bReduceBladePath = bReduceBladePath + bReduceBladePath = bReduceBladePath, + bIsDicing = false, + sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation, + bCannotSplitRestLength = bCannotSplitRestLength } local CutWholeWasteMachinings, CutWholeWasteResult = CutWholeWaste( ProcTrimesh, Part, OptionalParametersCutWholeWaste) @@ -853,7 +909,9 @@ local function CalculateDiceMachinings( vCuts, Parameters) nToolIndex = Tool.nIndex, dRadialStepSpan = 0, dExtendAfterTail = dExtendAfterTail, - bIsDicing = true + bIsDicing = true, + sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation, + bCannotSplitRestLength = bCannotSplitRestLength } Cutting = FaceByBlade.Make( ProcTrimesh, Part, FaceToMachine, EdgeToMachine, OptionalParametersFaceByBlade) Cutting.ptCenter = Point3d( ProcTrimesh.Faces[1].ptCenter:getX(), 0, 0) @@ -887,11 +945,10 @@ local function CutWithDicing( Proc, Part, OptionalParameters) local nToolIndex = OptionalParameters.nToolIndex local dExtendAfterTail = OptionalParameters.dExtendAfterTail or 10000 local b3BoxDicing = OptionalParameters.b3BoxDicing - local bSaveAddedGeometries = OptionalParameters.bSaveAddedGeometries + local bSaveAddedGeometries = ( OptionalParameters.bSaveAddedGeometries ~= false) local bReduceBladePath = OptionalParameters.bReduceBladePath or false - if bSaveAddedGeometries == nil then - bSaveAddedGeometries = true - end + local sRestLengthSideForPreSimulation = OptionalParameters.sRestLengthSideForPreSimulation or 'Tail' + local bCannotSplitRestLength = OptionalParameters.bCannotSplitRestLength or false -- scelta faccia da lavorare -- se due facce, la faccia principale Face1 è la più grande @@ -917,7 +974,7 @@ local function CutWithDicing( Proc, Part, OptionalParameters) return {}, Result end - -- calcolo dimensione cubetto e eventuale cubetto ridotto (tagli orizzontali con affondamento verticale) + -- calcolo dimensione cubetto local dDiceDimension = min( TOOLS[nToolIndex].dMaxMaterial, Part.GeneralParameters.GEN_dMaxDimDice) dDiceDimension = dDiceDimension - BeamData.CUT_EXTRA @@ -946,11 +1003,30 @@ local function CutWithDicing( Proc, Part, OptionalParameters) Tool = TOOLS[nToolIndex], sChosenBladeType = sChosenBladeType, dExtendAfterTail = dExtendAfterTail, - bReduceBladePath = bReduceBladePath + bReduceBladePath = bReduceBladePath, + sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation, + bCannotSplitRestLength = bCannotSplitRestLength } bIsDicingOk, Machinings, bMoveAfterSplit = CalculateDiceMachinings( vCuts, Parameters) + -- se i cubetti falliscono si riprova con la dimensione ridotta (ad esempio quando tocca l'asse Z nei cubetti in coda) + if not bIsDicingOk and BeamData.SAFE_DIM_DICE then + dDiceDimension = BeamData.SAFE_DIM_DICE - BeamData.CUT_EXTRA + OptionalParametersDiceCut.dOffsetParallel = dDiceDimension + OptionalParametersDiceCut.dOffsetOrthogonal = dDiceDimension + vCuts = DiceCut.GetDice( Part, Face1, Face2, OptionalParametersDiceCut) + + -- se nessun cubetto trovato, si richiama ricorsivamente la BladeToWaste forzando di non fare i cubetti + if #vCuts == 0 then + OptionalParameters.bDisableDicing = true + Machinings, Result = BLADETOWASTE.Make( Proc, Part, OptionalParameters) + return Machinings, Result + end + + bIsDicingOk, Machinings, bMoveAfterSplit = CalculateDiceMachinings( vCuts, Parameters) + end + if not bIsDicingOk then Result = FeatureLib.GetStrategyResultNotApplicable() return {}, Result @@ -1051,10 +1127,9 @@ function BLADETOWASTE.Make( ProcOrId, Part, OptionalParameters) local dMaxWasteVolume = OptionalParameters.dMaxWasteVolume or 0 local dMaxWasteLength = OptionalParameters.dMaxWasteLength or 0 local bDisableDicing = OptionalParameters.bDisableDicing or false - local bSaveAddedGeometries = OptionalParameters.bSaveAddedGeometries - if bSaveAddedGeometries == nil then - bSaveAddedGeometries = true - end + local bSaveAddedGeometries = ( OptionalParameters.bSaveAddedGeometries ~= false) + local sRestLengthSideForPreSimulation = OptionalParameters.sRestLengthSideForPreSimulation or 'Tail' + local bCannotSplitRestLength = OptionalParameters.bCannotSplitRestLength or false -- dimensioni feature if OptionalParameters.b3BoxDicing then @@ -1155,7 +1230,9 @@ function BLADETOWASTE.Make( ProcOrId, Part, OptionalParameters) local OptionalParametersGetSingleCutStrategy = { bReduceBladePath = false, nFaceToMachineIndex = i, - EdgeToMachineList = { Top = EdgeToMachine, Bottom = EdgeToMachine} + EdgeToMachineList = { Top = EdgeToMachine, Bottom = EdgeToMachine}, + sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation, + bCannotSplitRestLength = bCannotSplitRestLength } nToolIndex = GetSingleCutStrategy( Proc, Part, OptionalParametersGetSingleCutStrategy) end @@ -1177,7 +1254,9 @@ function BLADETOWASTE.Make( ProcOrId, Part, OptionalParameters) dDepthToMachine = EdgeToMachine.dElevation - dPathShortening, nToolIndex = nToolIndex, dExtendAfterTail = OptionalParameters.dExtendAfterTail, - bReduceBladePath = false + bReduceBladePath = false, + sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation, + bCannotSplitRestLength = bCannotSplitRestLength } local Cutting = FaceByBlade.Make( Proc, Part, Proc.Faces[i], EdgeToMachine, OptionalParametersFaceByBlade) diff --git a/StrategyLibs/FACEBYBLADE.lua b/StrategyLibs/FACEBYBLADE.lua index 58b5f6d..c66ec14 100644 --- a/StrategyLibs/FACEBYBLADE.lua +++ b/StrategyLibs/FACEBYBLADE.lua @@ -203,6 +203,8 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar local dRadialStepSpan = OptionalParameters.dRadialStepSpan local sUserNotes = OptionalParameters.sUserNotes or '' local bIsDicing = OptionalParameters.bIsDicing or false + local sRestLengthSideForPreSimulation = OptionalParameters.sRestLengthSideForPreSimulation or 'Tail' + local bCannotSplitRestLength = OptionalParameters.bCannotSplitRestLength or false -- lunghezze, direzioni e punti caratteristici della lavorazione e del lato lavorato Cutting.dEdgeLength = EdgeToMachine.dLength @@ -224,7 +226,9 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar dDepthToMachine = dDepthToMachine } local BladeEngagementOptionalParameters = { - bIsDicing = bIsDicing + bIsDicing = bIsDicing, + sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation, + bCannotSplitRestLength = bCannotSplitRestLength } local Engagement TIMER:startElapsed( 'GetBladeEngagement') @@ -246,6 +250,8 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar ToolSearchParameters.FaceToMachine = FaceToMachine ToolSearchParameters.EdgeToMachine = EdgeToMachine ToolSearchParameters.Part = Part + ToolSearchParameters.sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation + ToolSearchParameters.bCannotSplitRestLength = bCannotSplitRestLength local ToolInfo = MachiningLib.FindBlade( Proc, ToolSearchParameters) Cutting.nToolIndex = ToolInfo.nToolIndex @@ -340,7 +346,9 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar dDepthToMachine = dDepthToMachine } local BladeEngagementOptionalParameters = { - bIsDicing = bIsDicing + bIsDicing = bIsDicing, + sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation, + bCannotSplitRestLength = bCannotSplitRestLength } TIMER:startElapsed( 'GetBladeEngagement') local bIsApplicableOpposite, EngagementOpposite = MachiningLib.GetBladeEngagement( BladeEngagementParameters, BladeEngagementOptionalParameters) @@ -455,7 +463,9 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar dDepthToMachine = dDepthToMachine } local BladeEngagementOptionalParameters = { - bIsDicing = bIsDicing + bIsDicing = bIsDicing, + sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation, + bCannotSplitRestLength = bCannotSplitRestLength } TIMER:startElapsed( 'GetBladeEngagement') local bIsApplicable, CurrentEngagement = MachiningLib.GetBladeEngagement( BladeEngagementParameters, BladeEngagementOptionalParameters ) @@ -538,7 +548,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar end -- solo per debug - --Cutting.nOutRaw = 3 + Cutting.nOutRaw = 3 -- lunghezza lavorata -- TODO per il calcolo del dLengthOnX si deve correggere con allungamento / accorciamento percorso diff --git a/StrategyLibs/SPLITCUT.lua b/StrategyLibs/SPLITCUT.lua index 5d8409e..861acb1 100644 --- a/StrategyLibs/SPLITCUT.lua +++ b/StrategyLibs/SPLITCUT.lua @@ -9,6 +9,7 @@ require( 'EgtBase') -- Carico i dati globali local FeatureLib = require( 'FeatureLib') +local BeamLib = require( 'BeamLib') -- strategie di base local BladeToWaste = require('BLADETOWASTE') @@ -31,7 +32,13 @@ function SPLITCUT.GetMachining( Proc, Part, ParametersFromStrategy) else -- Blade Machining, Result = BladeToWaste.Make( Proc, Part, ParametersFromStrategy) - if Machining and #Machining > 0 then + -- se taglio non riuscito, si riprova con il riduci percorso forzato (collisione possibile in separazione pezzi alti) + if ( not Machining) or ( #Machining == 0) then + local NewParametersFromStrategy = BeamLib.TableCopyDeep( ParametersFromStrategy) + NewParametersFromStrategy.bReduceBladePath = true + Machining, Result = BladeToWaste.Make( Proc, Part, NewParametersFromStrategy) + end + if Machining and ( #Machining > 0) then Machining.sTypeMachining = 'Blade' end -- TODO : casi con motosega da completare