diff --git a/LuaLibs/BeamExec.lua b/LuaLibs/BeamExec.lua index 97a81ad..3f7d310 100644 --- a/LuaLibs/BeamExec.lua +++ b/LuaLibs/BeamExec.lua @@ -198,6 +198,7 @@ function BeamExec.GetToolsFromDB() -- se tutti i dati necessari sono disponibili, inserisco utensile nella lista globale degli utensili disponibili if IsToolOk( Tool) then + Tool.nIndex = #TOOLS table.insert( TOOLS, Tool) -- altrimenti scrivo nel log che l'utensile non è conforme else diff --git a/StrategyLibs/BLADETOWASTE.lua b/StrategyLibs/BLADETOWASTE.lua index f9f740e..8157107 100644 --- a/StrategyLibs/BLADETOWASTE.lua +++ b/StrategyLibs/BLADETOWASTE.lua @@ -730,8 +730,152 @@ local function CutWholeWaste( Proc, Part, OptionalParameters) end -local function CutWithDicing( Proc, Part, OptionalParameters) +local function CalculateDiceMachinings( vCuts, Parameters) local Machinings = {} + local bMoveAfterSplit = false + + local Proc = Parameters.Proc + local Part = Parameters.Part + local MainFace = Parameters.MainFace + local Tool = Parameters.Tool + local sChosenBladeType = Parameters.sChosenBladeType + local dExtendAfterTail = Parameters.dExtendAfterTail + local bReduceBladePath = Parameters.bReduceBladePath + + -- eventuale inversione tagli ortogonali e aggiunta informazioni alla geometria + local bAreOrthogonalCutsInverted = false + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + SetDiceFaceInfo( Proc, vCuts[i][j]) + if ( i % 2) == 1 then + local vtO = EgtSurfTmFacetNormVersor( vCuts[i][j], 0, GDB_ID.ROOT) + if ( MainFace.vtN:getY() > 0.766 and vtO:getY() < -0.05) or + ( MainFace.vtN:getY() < -0.766 and vtO:getY() > 0.05) then + EgtInvertSurf( vCuts[i][j]) + bAreOrthogonalCutsInverted = true + end + end + end + end + -- calcolo lavorazioni + for i = 1, #vCuts do + -- determinazione direzione di taglio + local vtToolDirection + local bNoPerpCuts = false + if i % 2 == 1 then + vtToolDirection = Vector3d( MainFace.vtN) + else + local vtO + if #vCuts[i-1] > 0 then + vtO = EgtSurfTmFacetNormVersor( vCuts[i-1][1], 0, GDB_ID.ROOT) + elseif vCuts[i+1] and #vCuts[i+1] > 0 then + -- lunghezza faccia nell'eventuale direzione ortogonale + local asseX = EgtSurfTmFacetNormVersor( vCuts[i+1][1], 0, GDB_ID.ROOT) + local asseY = asseX ^ MainFace.vtN + local Frame = Frame3d( MainFace.ptCenter, MainFace.ptCenter + asseX, MainFace.ptCenter + asseY) + local b3Fac = EgtGetBBoxRef( vCuts[i][1], GDB_BB.STANDARD, Frame) + -- se lunghezza inferiore al limite, accetto la direzione + if b3Fac:getDimX() < Tool.dMaxDepth - BeamData.CUT_EXTRA then + vtO = asseX + else + bNoPerpCuts = true + end + else + bNoPerpCuts = true + end + if vtO then + vtToolDirection = Vector3d( vtO) * EgtIf( bAreOrthogonalCutsInverted, -1, 1) + else + -- scelta lato da lavorare per stabilire la vtToolDirection + local EdgeToMachine = {} + local _, Edges = FaceData.GetEdgesInfo( vCuts[i][1], 0) + EdgeToMachine = GetEdgeToMachine( Edges, sChosenBladeType) + vtToolDirection = EdgeToMachine.vtN + end + 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 + local bCanMergeParallelCuts = ( ( i % 2) == 0) and ( Proc.nFct == 1) + local bIsDicingOk = true + if bCanMergeParallelCuts then + local nAddGrpId = BeamLib.GetAddGroup( Part.id) + local nSurfToCut = EgtSurfTmBySewing( nAddGrpId, vCuts[i], false) + local ProcTrimesh = FeatureLib.GetProcFromTrimesh( nSurfToCut, Part) + + local OptionalParametersCutWholeWaste = { + nToolIndex = Tool.nIndex, + dExtendAfterTail = dExtendAfterTail, + bReduceBladePath = bReduceBladePath + } + local CutWholeWasteMachinings, CutWholeWasteResult = CutWholeWaste( ProcTrimesh, Part, OptionalParametersCutWholeWaste) + + if CutWholeWasteResult.sStatus == 'Completed' then + for k = 1, #CutWholeWasteMachinings do + table.insert( Machinings, CutWholeWasteMachinings[k]) + if CutWholeWasteMachinings[k].sStage == 'AfterTail' then + bMoveAfterSplit = true + end + end + else + EgtErase( nSurfToCut) + bIsDicingOk = false + end + end + -- caso standard (tagli perpendicolari o paralleli non accorpabili) + if ( not bCanMergeParallelCuts) or ( not bIsDicingOk) then + for j = 1, #vCuts[i] do + -- 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 = Tool.dThickness + -- se ultimo taglio, devo affondare + elseif j == #vCuts[i] then + dExtraCut = BeamData.CUT_EXTRA + end + end + 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 = Tool.nIndex, + dRadialStepSpan = 0, + dExtendAfterTail = dExtendAfterTail, + bIsDicing = 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) + -- se un cubetto fallisce è inutile proseguire + else + Result = FeatureLib.GetStrategyResultNotApplicable( 'Dicing failed') + return false + end + if Cutting.sStage == 'AfterTail' then + bMoveAfterSplit = true + end + end + end + end + + return true, Machinings, bMoveAfterSplit +end + + +local function CutWithDicing( Proc, Part, OptionalParameters) local Result = {} -- parametri opzionali e default @@ -768,7 +912,7 @@ local function CutWithDicing( Proc, Part, OptionalParameters) if not nToolIndex then Result = FeatureLib.GetStrategyResultNotApplicable( 'Blade not found') - return Machinings, Result + return {}, Result end -- calcolo dimensione cubetto e eventuale cubetto ridotto (tagli orizzontali con affondamento verticale) @@ -791,138 +935,25 @@ local function CutWithDicing( Proc, Part, OptionalParameters) if #vCuts == 0 then OptionalParameters.bDisableDicing = true Machinings, Result = BLADETOWASTE.Make( Proc, Part, OptionalParameters) - return Machinings, Result + return {}, Result end -- lavorazione cubetti - local bIsDicingOk = true - local bMoveAfterSplit = false - -- eventuale inversione tagli ortogonali e aggiunta informazioni alla geometria - local bAreOrthogonalCutsInverted = false - for i = 1, #vCuts do - for j = 1, #vCuts[i] do - SetDiceFaceInfo( Proc, vCuts[i][j]) - if ( i % 2) == 1 then - local vtO = EgtSurfTmFacetNormVersor( vCuts[i][j], 0, GDB_ID.ROOT) - if ( Face1.vtN:getY() > 0.766 and vtO:getY() < -0.05) or - ( Face1.vtN:getY() < -0.766 and vtO:getY() > 0.05) then - EgtInvertSurf( vCuts[i][j]) - bAreOrthogonalCutsInverted = true - end - end - end - end - -- calcolo lavorazioni - for i = 1, #vCuts do - -- determinazione direzione di taglio - local vtToolDirection - local bNoPerpCuts = false - if i % 2 == 1 then - vtToolDirection = Vector3d( Face1.vtN) - else - local vtO - if #vCuts[i-1] > 0 then - vtO = EgtSurfTmFacetNormVersor( vCuts[i-1][1], 0, GDB_ID.ROOT) - elseif vCuts[i+1] and #vCuts[i+1] > 0 then - -- lunghezza faccia nell'eventuale direzione ortogonale - local asseX = EgtSurfTmFacetNormVersor( vCuts[i+1][1], 0, GDB_ID.ROOT) - local asseY = asseX ^ Face1.vtN - local Frame = Frame3d( Face1.ptCenter, Face1.ptCenter + asseX, Face1.ptCenter + asseY) - local b3Fac = EgtGetBBoxRef( vCuts[i][1], GDB_BB.STANDARD, Frame) - -- se lunghezza inferiore al limite, accetto la direzione - if b3Fac:getDimX() < TOOLS[nToolIndex].dMaxDepth - BeamData.CUT_EXTRA then - vtO = asseX - else - bNoPerpCuts = true - end - else - bNoPerpCuts = true - end - if vtO then - vtToolDirection = Vector3d( vtO) * EgtIf( bAreOrthogonalCutsInverted, -1, 1) - else - -- scelta lato da lavorare per stabilire la vtToolDirection - local EdgeToMachine = {} - local _, Edges = FaceData.GetEdgesInfo( vCuts[i][1], 0) - EdgeToMachine = GetEdgeToMachine( Edges, sChosenBladeType) - vtToolDirection = EdgeToMachine.vtN - end - 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 - local bCanMergeParallelCuts = ( ( i % 2) == 0) and ( Proc.nFct == 1) - if bCanMergeParallelCuts then - local nAddGrpId = BeamLib.GetAddGroup( Part.id) - local nSurfToCut = EgtSurfTmBySewing( nAddGrpId, vCuts[i], false) - local ProcTrimesh = FeatureLib.GetProcFromTrimesh( nSurfToCut, Part) + local Parameters = { + Proc = Proc, + Part = Part, + MainFace = Face1, + Tool = TOOLS[nToolIndex], + sChosenBladeType = sChosenBladeType, + dExtendAfterTail = dExtendAfterTail, + bReduceBladePath = bReduceBladePath + } + + local bIsDicingOk, Machinings, bMoveAfterSplit = CalculateDiceMachinings( vCuts, Parameters) - local OptionalParametersCutWholeWaste = { - nToolIndex = nToolIndex, - dExtendAfterTail = dExtendAfterTail, - bReduceBladePath = bReduceBladePath - } - local CutWholeWasteMachinings, CutWholeWasteResult = CutWholeWaste( ProcTrimesh, Part, OptionalParametersCutWholeWaste) - - if CutWholeWasteResult.sStatus == 'Completed' then - for k = 1, #CutWholeWasteMachinings do - table.insert( Machinings, CutWholeWasteMachinings[k]) - if CutWholeWasteMachinings[k].sStage == 'AfterTail' then - bMoveAfterSplit = true - end - end - else - EgtErase( nSurfToCut) - bIsDicingOk = false - end - end - -- caso standard (tagli perpendicolari o paralleli non accorpabili) - if ( not bCanMergeParallelCuts) or ( not bIsDicingOk) then - for j = 1, #vCuts[i] do - -- 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 - end - end - 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, - bIsDicing = 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 - Result = FeatureLib.GetStrategyResultNotApplicable( 'Dicing failed') - return Machinings, Result - end - if Cutting.sStage == 'AfterTail' then - bMoveAfterSplit = true - end - end - end + if not bIsDicingOk then + Result = FeatureLib.GetStrategyResultNotApplicable() + return {}, Result end -- se presente anche solo una lavorazione AfterTail si spostano tutte @@ -933,16 +964,12 @@ local function CutWithDicing( Proc, Part, OptionalParameters) end -- risultati del calcolo - if bIsDicingOk then - Result.sStatus = 'Completed' - Result.dCompletionPercentage = 100 - Result.dQuality = FeatureLib.GetStrategyQuality( TOOLS[nToolIndex].sFamily) - Result.dTimeToMachineOriginal = FeatureLib.GetStrategyTimeToMachine( Machinings) - Result.dTimeToMachine = Result.dTimeToMachineOriginal * 2 - Result.dMRR = ( FeatureInfo.dFeatureVolume / Result.dTimeToMachine) / pow( 10, 6) - else - Result = FeatureLib.GetStrategyResultNotApplicable() - end + Result.sStatus = 'Completed' + Result.dCompletionPercentage = 100 + Result.dQuality = FeatureLib.GetStrategyQuality( TOOLS[nToolIndex].sFamily) + Result.dTimeToMachineOriginal = FeatureLib.GetStrategyTimeToMachine( Machinings) + Result.dTimeToMachine = Result.dTimeToMachineOriginal * 2 + Result.dMRR = ( FeatureInfo.dFeatureVolume / Result.dTimeToMachine) / pow( 10, 6) return Machinings, Result end