-- Strategia: STR0015 -- Descrizione -- Fresatura di contorno -- Feature tipo Profilo arcuato, Convesso, Concavo, Arco -- carico librerie local BeamLib = require( 'BeamLib') local BeamData = require( 'BeamDataNew') local MachiningLib = require( 'MachiningLib') local FeatureLib = require( 'FeatureLib') local FaceData = require( 'FaceData') local ID = require( 'Identity') -- strategie di base local BladeToWaste = require('BLADETOWASTE') local FaceByBlade = require('FACEBYBLADE') local FaceByMill = require('FACEBYMILL') -- Tabella per definizione modulo local STR0015 = {} local Strategy = {} ------------------------------------------------------------------------------------------------------------- local function GetEdgeToMachine( Proc, idFace, vtEdge) local Edge local dBestEdgeAngle = 999 for i = 1, #Proc.Faces[idFace].Edges do local dAngle = abs( GetAngle( Proc.Faces[idFace].Edges[i].vtN, vtEdge) or 999) if dAngle < dBestEdgeAngle then dBestEdgeAngle = dAngle Edge = Proc.Faces[idFace].Edges[i] end end return Edge end -- TODO funzione recuperata da beam vecchio, verificare se possibile migliorare --------------------------------------------------------------------- local function GetSawCutData( Proc, AuxId, vtNF, vtN) local ptStart, vtNP if ID.IsHeadConcaveProfile( Proc) or ID.IsHeadConvexProfile( Proc) or ID.IsHeadProfile( Proc) or ID.IsFrontProfile( Proc) then vtNP = Vector3d( vtN) -- comincio con la normale a 45deg for i = 1, 3 do if vtNP[i] > GEO.EPS_SMALL then vtNP[i] = 1 elseif vtNP[i] < -GEO.EPS_SMALL then vtNP[i] = -1 end end vtNP:normalize() -- assegno un punto di passaggio ptStart = EgtMP( AuxId, GDB_ID.ROOT) local frOCS = Frame3d( ptStart, vtNP) ; local b3Box = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frOCS) ptStart = ptStart + vtNP * ( b3Box:getMax():getZ() + 10.0) elseif ID.IsHeadCamberedProfile( Proc) then vtNP = Vector3d( vtNF) -- comincio con la normale a 45deg for i = 1, 3 do if vtNP[i] > GEO.EPS_SMALL then vtNP[i] = 1 elseif vtNP[i] < -GEO.EPS_SMALL then vtNP[i] = -1 end end vtNP:normalize() -- assegno un punto di passaggio ptStart = EgtSP( AuxId, GDB_ID.ROOT) + vtNP * 5.0 -- determino asse di rotazione local vtRot = - Y_AX() if vtNF:getX() < 0 then vtRot = - vtRot end if vtNF:getZ() < -0.1 then vtRot = - vtRot elseif vtNF:getY() < -0.1 then vtRot:rotate( X_AX(), 90) elseif vtNF:getY() > 0.1 then vtRot:rotate( X_AX(), -90) end -- miglioro l'inclinazione (ripartendo da faccia perpendicolare asse trave) vtNP[2] = 0 vtNP[3] = 0 local dRot = 45 for i = 1, 4 do local vtNP2 = Vector3d( vtNP) vtNP2:rotate( vtRot, dRot) local frRef = Frame3d( ptStart, vtNP2) local b3Box = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frRef) if b3Box:getMax():getZ() < -3 then vtNP = Vector3d( vtNP2) end dRot = dRot / 2 end end -- restituisco i dati del piano return ptStart, vtNP end ------------------------------------------------------------------------------------------------------------- local function GetRoughStrategy( Proc, Part, bSaveAddedGeometries) local Machining = {} local Result = {} -- ====== Taglio di sgrossatura generale su tutto il profilo ====== local vtNF = EgtSurfTmFacetNormVersor( Proc.id, Proc.nFct-1, GDB_ID.ROOT) local nMidFacet = Proc.nFct // 2 -- faccia a metà circa local vtN = EgtSurfTmFacetNormVersor( Proc.id, nMidFacet, GDB_ID.ROOT) local idAddGroup if bSaveAddedGeometries then idAddGroup = BeamLib.GetAddGroup( Part.id) else idAddGroup = Part.idTempGroup end -- aggiungo piano di sgrossatura e lo lavoro local ptStart, vtNP = GetSawCutData( Proc, Proc.idAddAuxGeom, vtNF, vtN) local AddId = EgtSurfTmPlaneInBBox( idAddGroup, ptStart, vtNP, Part.b3Part, GDB_RT.GLOB) -- se la faccia è stata creata if AddId then -- creo piano di taglio sulla testa del tenone local OptionalParameters = { dMaxWasteVolume = Strategy.Parameters.dMaxWasteVolume, dMaxWasteLength = Strategy.Parameters.dMaxWasteLength, bReduceBladePath = Strategy.Parameters.bReduceBladePath } Machining, Result = BladeToWaste.Make( AddId, Part, OptionalParameters) -- se non ci sono lavorazioni, provo con fresa if not Machining or #Machining == 0 then Machining.bCuttingWithMill = true -- === ricerca utensile per svuotare taglio iniziale, se taglio non possibile === if not( Proc.AffectedFaces.bLeft) or Strategy.bCanMoveAfterSplit then ToolSearchParameters = {} -- TODO SISTEMARE!!! qui la svuotatura non deve limitare l'elevazione se aperta da tutti i lati. In futuro si deve passare 0 come elevazione ToolSearchParameters.dElevation = EgtSurfTmFacetElevationInBBox( AddId, 0, Part.b3Part, true, GDB_ID.ROOT) ToolSearchParameters.vtToolDirection = vtNP ToolSearchParameters.AvailableToolList = MachiningLib.GetAvailableToolList( Proc, Strategy.Parameters.sPocketingList, 'Pocketing') Machining.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters) -- TODO anche il test sul ResidualDepth va tolto if Machining.ToolInfo.nToolIndex and ( Machining.ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL) then Machining.bIsApplicable = true local ParametersMRR = {} ParametersMRR.nToolIndex = Machining.ToolInfo.nToolIndex Result.dMRR = MachiningLib.GetToolMRR( ParametersMRR) Result.sStatus = 'Completed' Machining.Steps = {} Machining.LeadIn = {} Machining.nType = MCH_MY.POCKETING Machining.nSubType = MCH_POCK_SUB.SPIRALIN Machining.LeadIn.nType = MCH_POCK_LI.ZIGZAG Machining.Steps.dStep = TOOLS[Machining.ToolInfo.nToolIndex].dStep Machining.Steps.dSideStep = TOOLS[Machining.ToolInfo.nToolIndex].dSideStep Machining.nToolIndex = Machining.ToolInfo.nToolIndex Machining.LeadIn.dTangentDistance = TOOLS[Machining.ToolInfo.nToolIndex].dDiameter/2 Machining.LeadIn.dElevation = TOOLS[Machining.ToolInfo.nToolIndex].dDiameter/2 Machining.sDepth = 0 Machining.Geometry = {{ AddId, 0}} Machining.vtToolDirection = vtNF if Proc.AffectedFaces.bLeft and Strategy.bCanMoveAfterSplit then Machining.sStage = 'AfterTail' end -- tempo di svuotatura Result.dTimeToMachine = MachiningLib.GetTimeToMachineAllStepsWithLeadInOut( Machining, Part) end end end end return Machining, Result end ------------------------------------------------------------------------------------------------------------- local function GetEdgeWithCornerStrategy( Proc, Part) local Machining = {} local Result = { dCompletionPercentage = 100} local nFirstFacet = 0 -- faccia iniziale local nLastFacet = Proc.nFct - 1 -- faccia finale -- verifico se necessari ripassi agli estremi negli angoli local _, _, _, dFirstAng = EgtSurfTmFacetsContact( Proc.id, nFirstFacet, nFirstFacet + 1, GDB_ID.ROOT) local bFirstTrim = ( dFirstAng and dFirstAng < -30) local _, _, _, dLastAng = EgtSurfTmFacetsContact( Proc.id, nLastFacet, nLastFacet - 1, GDB_ID.ROOT) local bLastTrim = ( dLastAng and dLastAng < -30) local nMidFacet = ( nLastFacet + 1) // 2 -- faccia a metà circa local vtN = EgtSurfTmFacetNormVersor( Proc.id, nMidFacet, GDB_ID.ROOT) -- se non ci sono angoli da pulire si esce subito if Strategy.Parameters.sConcaveFaceStrategy == 'NONE' or ( not bFirstTrim and not bLastTrim) then return nil, nil end local FacesToGet = {} if bFirstTrim then table.insert( FacesToGet, nFirstFacet) table.insert( FacesToGet, nFirstFacet+1) end if bLastTrim then table.insert( FacesToGet, nLastFacet - 1) table.insert( FacesToGet, nLastFacet) end -- ricavo info facce da lavorare Proc.Faces = FaceData.GetFacesInfo( Proc, Part, FacesToGet) -- direzioni di lavorazione local vtCutDir1 -- se è diretta verso alto o basso if abs( vtN:getZ()) > abs( vtN:getY()) then if vtN:getZ() > 0 then vtCutDir1 = Z_AX() else vtCutDir1 = -Z_AX() end -- altrimenti è di fianco else if vtN:getY() > 0 then vtCutDir1 = Y_AX() else vtCutDir1 = -Y_AX() end end local vtCutDir2 if vtN:getX() > 0 then vtCutDir2 = X_AX() else vtCutDir2 = -X_AX() end local nMachiningsToAdd -- AUTO = preferisce lama. Se non è possibile prende fresa -- BLADE_FORCED = solo lama, altriemnti non applica nulla (potrebbe essere necessario un ribaltamento) -- MILL_FORCED = solo fresa, altriemnti non applica nulla (potrebbe essere necessario un ribaltamento) if Strategy.Parameters.sConcaveFaceStrategy == 'AUTO' or Strategy.Parameters.sConcaveFaceStrategy == 'BLADE_FORCED' then nMachiningsToAdd = 0 -- TODO c'è una funzione che ritorni l'edge di connessione tra una faccia e un'altra? -- lavorazione faccia 1 spigolo finale if bLastTrim then nMachiningsToAdd = nMachiningsToAdd + 1 local EdgeToMachine = GetEdgeToMachine( Proc, nLastFacet+1, vtCutDir1) local Cutting = FaceByBlade.Make( Proc, Part, Proc.Faces[nLastFacet+1], EdgeToMachine) if Proc.AffectedFaces.bLeft and Strategy.bCanMoveAfterSplit then Cutting.sStage = 'AfterTail' end if Cutting.bIsApplicable then table.insert( Machining, Cutting) end end -- lavorazione faccia 1 spigolo iniziale if bFirstTrim then nMachiningsToAdd = nMachiningsToAdd + 1 local EdgeToMachine = GetEdgeToMachine( Proc, nFirstFacet+2, vtCutDir1) local Cutting = FaceByBlade.Make( Proc, Part, Proc.Faces[nFirstFacet+2], EdgeToMachine) if Proc.AffectedFaces.bLeft and Strategy.bCanMoveAfterSplit then Cutting.sStage = 'AfterTail' end if Cutting.bIsApplicable then table.insert( Machining, Cutting) end end -- lavorazione faccia 2 spigolo finale if bLastTrim then nMachiningsToAdd = nMachiningsToAdd + 1 EdgeToMachine = GetEdgeToMachine( Proc, nLastFacet, vtCutDir2) Cutting = FaceByBlade.Make( Proc, Part, Proc.Faces[nLastFacet], EdgeToMachine) if Cutting.bIsApplicable then table.insert( Machining, Cutting) end end -- lavorazione faccia 2 spigolo iniziale if bFirstTrim then nMachiningsToAdd = nMachiningsToAdd + 1 local EdgeToMachine = GetEdgeToMachine( Proc, nFirstFacet+1, vtCutDir2) local Cutting = FaceByBlade.Make( Proc, Part, Proc.Faces[nFirstFacet+1], EdgeToMachine) if Cutting.bIsApplicable then table.insert( Machining, Cutting) end end end -- se non ci sono lavorazioni provo a pulire spigoli con fresa, a patto che non sia stato forzato con lama if ( not nMachiningsToAdd or ( #Machining < nMachiningsToAdd)) and Strategy.Parameters.sConcaveFaceStrategy ~= 'BLADE_FORCED' then Machining = {} nMachiningsToAdd = 0 -- TODO c'è una funzione che ritorni l'edge di connessione tra una faccia e un'altra? -- lavorazione faccia 1 spigolo iniziale if bFirstTrim then nMachiningsToAdd = nMachiningsToAdd + 1 local EdgeToMachine = GetEdgeToMachine( Proc, nFirstFacet+2, vtCutDir1) local Milling = FaceByMill.Make( Proc, Part, Proc.Faces[nFirstFacet+2], EdgeToMachine) if Proc.AffectedFaces.bLeft and Strategy.bCanMoveAfterSplit then Milling.sStage = 'AfterTail' end if Milling.bIsApplicable then table.insert( Machining, Milling) end end -- lavorazione faccia 2 spigolo finale if bLastTrim then nMachiningsToAdd = nMachiningsToAdd + 1 EdgeToMachine = GetEdgeToMachine( Proc, nLastFacet, vtCutDir2) local Milling = FaceByMill.Make( Proc, Part, Proc.Faces[nLastFacet], EdgeToMachine) if Proc.AffectedFaces.bLeft and Strategy.bCanMoveAfterSplit then Milling.sStage = 'AfterTail' end if Milling.bIsApplicable then table.insert( Machining, Milling) end end end if nMachiningsToAdd and ( #Machining < nMachiningsToAdd) then Result = { dCompletionPercentage = ( #Machining / nMachiningsToAdd)} end return Machining, Result end ------------------------------------------------------------------------------------------------------------- local function GetChamferStrategy( Proc, Part) local Machining = {} local Result = {} local ToolSearchParameters = {} local dExtraDepth = 2 local vtExtr = EgtCurveExtrusion( Proc.idAddAuxGeom, GDB_RT.GLOB) local bIsHorizontal = abs( vtExtr:getZ()) < 10 * GEO.EPS_SMALL local bToolInvert = ( vtExtr:getZ() < -0.1) if Strategy.Parameters.dDepthChamfer > 100 * GEO.EPS_SMALL then -- controllo conformità affondamento smussi Strategy.Parameters.dDepthChamfer = EgtClamp( Strategy.Parameters.dDepthChamfer, 0.1, 5) -- si prapara tabella con parametri di base comuni a tutte le lavorazioni local BasicMach = MachiningLib.InitMachiningParameters( MCH_MY.MILLING) BasicMach.Geometry = {{ Proc.idAddAuxGeom, -1}} BasicMach.nType = MCH_MY.MILLING BasicMach.sDepth = Strategy.Parameters.dDepthChamfer + dExtraDepth -- LeadIn / LeadOut BasicMach.LeadIn.nType = MCH_MILL_LI.NONE BasicMach.LeadOut.nType = MCH_MILL_LI.NONE BasicMach.LeadIn.dStartAddLength = 5 BasicMach.LeadOut.dEndAddLength = 5 if Proc.AffectedFaces.bLeft and Strategy.bCanMoveAfterSplit then BasicMach.sStage = 'AfterTail' end BasicMach.ptEdge1 = EgtSP( Proc.idAddAuxGeom, GDB_ID.ROOT) BasicMach.ptEdge2 = EgtEP( Proc.idAddAuxGeom, GDB_ID.ROOT) BasicMach.dEdgeLength = EgtCurveLength( Proc.idAddAuxGeom) BasicMach.vtEdgeDirection = EgtSV( Proc.idAddAuxGeom, GDB_ID.ROOT) + EgtMV( Proc.idAddAuxGeom, GDB_ID.ROOT) + EgtEV( Proc.idAddAuxGeom, GDB_ID.ROOT) BasicMach.dLengthOnX = Proc.b3Box:getDimX() -- parametri di ricerca utensile comuni a tutte le lavorazioni ToolSearchParameters.sMillShape = 'VMILL' ToolSearchParameters.dElevation = Strategy.Parameters.dDepthChamfer ToolSearchParameters.AvailableToolList = MachiningLib.GetAvailableToolList( Proc, Strategy.Parameters.sMillingList, 'MillingSmooth') -- se lavorazione orizzontale if bIsHorizontal then local Milling = {} ToolSearchParameters.vtToolDirection = EgtIf( bToolInvert, -vtExtr, vtExtr) Milling.ToolInfo = {} Milling.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters) -- se trovato utensile adatto if Milling.ToolInfo.nToolIndex then Milling.vtToolDirection = ToolSearchParameters.vtToolDirection Milling.nToolIndex = Milling.ToolInfo.nToolIndex Milling.dRadialOffset = dExtraDepth * cos( TOOLS[Milling.nToolIndex].dSideAngle) Milling.bInvert = EgtIf( TOOLS[Milling.nToolIndex].bIsCCW, false, true) Milling.nWorkside = EgtIf( TOOLS[Milling.nToolIndex].bIsCCW, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT) Milling = BeamLib.MergeTables( BasicMach, Milling) table.insert( Machining, Milling) local Milling2 = BeamLib.TableCopyDeep( Milling) Milling2.bToolInvert = true Milling2.bInvert = EgtIf( TOOLS[Milling2.nToolIndex].bIsCCW, true, false) Milling2.nWorkside = EgtIf( TOOLS[Milling2.nToolIndex].bIsCCW, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT) table.insert( Machining, Milling2) end -- se lavorazione verticale else -- si cerca utensile 1 local Milling = {} ToolSearchParameters.vtToolDirection = EgtIf( bToolInvert, -vtExtr, vtExtr) Milling.ToolInfo = {} Milling.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters) Milling.vtToolDirection = ToolSearchParameters.vtToolDirection -- si cerca utensile 2 local Milling2 = {} ToolSearchParameters.vtToolDirection = EgtIf( bToolInvert, vtExtr, -vtExtr) Milling2.ToolInfo = {} Milling2.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters) Milling2.vtToolDirection = ToolSearchParameters.vtToolDirection Milling2.bToolInvert = true -- se trovato utensile 1 adatto if Milling.ToolInfo.nToolIndex then Milling.nToolIndex = Milling.ToolInfo.nToolIndex Milling.dRadialOffset = dExtraDepth * cos( TOOLS[Milling.nToolIndex].dSideAngle) Milling.bInvert = EgtIf( TOOLS[Milling.nToolIndex].bIsCCW, false, true) Milling.nWorkside = EgtIf( TOOLS[Milling.nToolIndex].bIsCCW, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT) Milling = BeamLib.MergeTables( BasicMach, Milling) table.insert( Machining, Milling) end -- se trovato utensile 2 adatto if Milling2.ToolInfo.nToolIndex then Milling2.nToolIndex = Milling2.ToolInfo.nToolIndex Milling2.dRadialOffset = dExtraDepth * cos( TOOLS[Milling2.nToolIndex].dSideAngle) Milling2.bToolInvert = true Milling2.bInvert = EgtIf( TOOLS[Milling2.nToolIndex].bIsCCW, true, false) Milling2.nWorkside = EgtIf( TOOLS[Milling2.nToolIndex].bIsCCW, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT) Milling2 = BeamLib.MergeTables( BasicMach, Milling2) table.insert( Machining, Milling2) end end end return Machining, Result end ------------------------------------------------------------------------------------------------------------- local function GetArcStrategy( Proc, Part) local Machining = {} local Result = { dCompletionPercentage = 100} local ToolSearchParameters = {} -- recupero i dati della curva e del profilo local dDepth = abs( EgtCurveThickness( Proc.idAddAuxGeom)) local vtExtr = EgtCurveExtrusion( Proc.idAddAuxGeom, GDB_RT.GLOB) local bToolInvert = ( vtExtr:getZ() < -0.1) local bIsHorizontal = abs( vtExtr:getZ()) < 10 * GEO.EPS_SMALL local bIsFeatureDown = Proc.AffectedFaces.bBottom and not Proc.AffectedFaces.bTop local bIsFeatureBack = Proc.AffectedFaces.bBack and not Proc.AffectedFaces.bFront local bForceStrip = Strategy.Parameters.bForceStrip local dDimStrip = EgtIf( Strategy.Parameters.dStripWidth < 100 * GEO.EPS_SMALL, nil, Strategy.Parameters.dStripWidth) local sMaxDepth = dDepth * 2 local bExecStrip = false -- se la lavorazione si trova nella parte inferiore o in battuta dietro, il codolo va sempre lasciato if ID.IsRoundArch( Proc) and ( bIsFeatureDown or bIsFeatureBack or bForceStrip) then if bIsFeatureDown or bIsFeatureBack then dDimStrip = dDimStrip or max( BeamData.DIM_STRIP or 5, 5) else dDimStrip = dDimStrip or max( BeamData.DIM_STRIP_SMALL or 5, 1) end bExecStrip = true end if not bExecStrip then dDimStrip = 0 end -- la passata di finitura c'è sempre local nPassages = 1 -- si verifica se fare passaggio di sgrossatura con fresa if not bExecStrip and Strategy.Parameters.dOverMaterial > 100 * GEO.EPS_SMALL then nPassages = 2 end -- ciclo su numero passate (2 in caso di sgrossatura + finitura) for nCycle = nPassages, 1, -1 do local nMaxDiamMill = EgtIf( nCycle == 1, Strategy.Parameters.dMaxCornerRadius * 2, nil) local sTypeTool = EgtIf( nCycle == 1 and nPassages == 2, 'MillingFinish', 'Milling') -- se lavorazione orizzontale if bIsHorizontal then local bDouble local Milling = MachiningLib.InitMachiningParameters( MCH_MY.MILLING) ToolSearchParameters = {} ToolSearchParameters.sMillShape = 'STANDARD' ToolSearchParameters.dElevation = EgtIf( bExecStrip, ( dDepth - dDimStrip) / 2, dDepth + BeamData.MILL_OVERLAP) ToolSearchParameters.vtToolDirection = EgtIf( bToolInvert, -vtExtr, vtExtr) ToolSearchParameters.AvailableToolList = MachiningLib.GetAvailableToolList( Proc, Strategy.Parameters.sMillingList, sTypeTool) ToolSearchParameters.dMaxToolDiameter = nMaxDiamMill Milling.ToolInfo = {} Milling.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters) -- se posso lavorare in una passata, ma utensile trovato non completa la lavorazione, -- allora provo a cercare utensile con massimo materiale sufficiente per fare le due passate, magari trova un utensile più prestante if Milling.ToolInfo.nToolIndex then if Milling.ToolInfo.dResidualDepth > 10 * GEO.EPS_SMALL and not bExecStrip then bDouble = true ToolSearchParameters.dElevation = ( dDepth + BeamData.MILL_OVERLAP) / 2 Milling.ToolInfo = {} Milling.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters) end Milling.vtToolDirection = ToolSearchParameters.vtToolDirection if nCycle == 2 then Milling.dRadialOffset = Strategy.Parameters.dOverMaterial end -- se non completo if Milling.ToolInfo.dResidualDepth > 10 * GEO.EPS_SMALL then sMaxDepth = ToolSearchParameters.dElevation - Milling.ToolInfo.dResidualDepth -- si salva percentuala lavorata Result.dCompletionPercentage = 100 - ceil( ( Milling.ToolInfo.dResidualDepth / ToolSearchParameters.dElevation) * 100) end if bDouble or bExecStrip then if bDouble then Milling.sDepth = min( sMaxDepth, ( dDepth + BeamData.MILL_OVERLAP) / 2) else Milling.sDepth = min( sMaxDepth, ( dDepth - dDimStrip) / 2) end table.insert( Machining, Milling) local Milling2 = BeamLib.TableCopyDeep( Milling) Milling2.bOtherDirection = true table.insert( Machining, Milling2) else Milling.sDepth = min( sMaxDepth, dDepth + BeamData.MILL_OVERLAP) table.insert( Machining, Milling) end end -- se lavorazione verticale else ToolSearchParameters = {} ToolSearchParameters.sMillShape = 'STANDARD' ToolSearchParameters.dElevation = dDepth + BeamData.MILL_OVERLAP ToolSearchParameters.AvailableToolList = MachiningLib.GetAvailableToolList( Proc, Strategy.Parameters.sMillingList, sTypeTool) ToolSearchParameters.dMaxToolDiameter = nMaxDiamMill -- si cerca utensile 1 local Milling = MachiningLib.InitMachiningParameters( MCH_MY.MILLING) ToolSearchParameters.vtToolDirection = EgtIf( bToolInvert, -vtExtr, vtExtr) Milling.ToolInfo = {} Milling.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters) if nCycle == 2 then Milling.dRadialOffset = Strategy.Parameters.dOverMaterial end Milling.vtToolDirection = ToolSearchParameters.vtToolDirection Milling.bOtherDirection = bToolInvert -- si cerca utensile 2 local Milling2 = MachiningLib.InitMachiningParameters( MCH_MY.MILLING) ToolSearchParameters.vtToolDirection = EgtIf( bToolInvert, vtExtr, -vtExtr) Milling2.ToolInfo = {} Milling2.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters) if nCycle == 2 then Milling2.dRadialOffset = Strategy.Parameters.dOverMaterial end Milling2.vtToolDirection = ToolSearchParameters.vtToolDirection Milling2.bOtherDirection = bToolInvert -- se serve codolo if bExecStrip then local sDepthMachined = 0 -- se a disposizione entrambi gli utensili if Milling.ToolInfo.nToolIndex and Milling2.ToolInfo.nToolIndex then local dExtraDepth = ( dDepth - dDimStrip - ( Milling.ToolInfo.dResidualDepth + Milling2.ToolInfo.dResidualDepth)) / 2 Milling.sDepth = dDepth - Milling.ToolInfo.dResidualDepth - dExtraDepth Milling2.sDepth = dDepth - Milling2.ToolInfo.dResidualDepth - dExtraDepth sDepthMachined = Milling.sDepth + Milling2.sDepth table.insert( Machining, Milling) table.insert( Machining, Milling2) -- se disponibile solo primo utensile elseif Milling.ToolInfo.nToolIndex then sMaxDepth = ToolSearchParameters.dElevation - Milling.ToolInfo.dResidualDepth Milling.sDepth = min( sMaxDepth, dDepth - dDimStrip) table.insert( Machining, Milling) sDepthMachined = Milling.sDepth -- se disponibile solo secondo utensile elseif Milling2.ToolInfo.nToolIndex then sMaxDepth = ToolSearchParameters.dElevation - Milling2.ToolInfo.dResidualDepth Milling2.sDepth = min( sMaxDepth, dDepth - dDimStrip) table.insert( Machining, Milling2) sDepthMachined = Milling2.sDepth -- nessun utensile disponibile else -- non si fa nulla end Result.dCompletionPercentage = min( ( sDepthMachined * 100) / ( dDepth - dDimStrip), 100) -- altrimenti senza codolo else local sDepthMachined = 0 local dExtraDepth = ( dDepth - BeamData.MILL_OVERLAP - ( Milling.ToolInfo.dResidualDepth + Milling2.ToolInfo.dResidualDepth)) / 2 -- se utensile 1 esegue completamente (con almeno 1mm extra) if Milling.ToolInfo.nToolIndex and Milling.ToolInfo.dResidualDepth < 1000 * GEO.EPS_SMALL then sMaxDepth = ToolSearchParameters.dElevation - Milling.ToolInfo.dResidualDepth Milling.sDepth = min( sMaxDepth, dDepth + BeamData.MILL_OVERLAP) table.insert( Machining, Milling) sDepthMachined = Milling.sDepth -- se utensile 2 esegue completamente (con almeno 1mm extra) elseif Milling2.ToolInfo.nToolIndex and Milling2.ToolInfo.dResidualDepth < 1000 * GEO.EPS_SMALL then sMaxDepth = ToolSearchParameters.dElevation - Milling2.ToolInfo.dResidualDepth Milling2.sDepth = min( sMaxDepth, dDepth + BeamData.MILL_OVERLAP) table.insert( Machining, Milling2) sDepthMachined = Milling2.sDepth -- se possono lavorare entrambi elseif Milling.ToolInfo.nToolIndex and Milling2.ToolInfo.nToolIndex then Milling.sDepth = dDepth - Milling.ToolInfo.dResidualDepth - dExtraDepth Milling2.sDepth = dDepth - Milling2.ToolInfo.dResidualDepth - dExtraDepth table.insert( Machining, Milling) table.insert( Machining, Milling2) sDepthMachined = Milling.sDepth + Milling2.sDepth -- se utensile 1 non completo elseif Milling.ToolInfo.nToolIndex then Milling.sDepth = ToolSearchParameters.dElevation - Milling.ToolInfo.dResidualDepth table.insert( Machining, Milling) sDepthMachined = Milling.sDepth -- se utensile 2 non completo elseif Milling2.ToolInfo.nToolIndex then Milling2.sDepth = ToolSearchParameters.dElevation - Milling2.ToolInfo.dResidualDepth table.insert( Machining, Milling2) sDepthMachined = Milling2.sDepth end Result.dCompletionPercentage = min( ( sDepthMachined * 100) / ( dDepth - dDimStrip), 100) end end end Machining.bIsApplicable = #Machining > 0 return Machining, Result end ------------------------------------------------------------------------------------------------------------- local function GetFeatureResult( Proc) local Result = { sStatus = 'Completed', dCompletionPercentage = 100, sInfo = ''} local dPercentageChamfer = 10 local dPercentageEdgeCorner = 10 local dPercentageProfile = 80 -- se non ci sono lavorazioni di smusso if not Strategy.Chamfer.Machinings or #Strategy.Chamfer.Machinings < 2 then -- se esclusivo, non applicabile if Strategy.Parameters.bOnlyChamfer then Result = FeatureLib.GetStrategyResultNotApplicable( 'Not possible to machine chamfer only, tool not found!') Result.dCompletionPercentage = 0 -- se non esclusivo, non completo elseif Strategy.Parameters.dDepthChamfer > 100 * GEO.EPS_SMALL then Result.dCompletionPercentage = Result.dCompletionPercentage - dPercentageChamfer -- gli smussi incidono per il 10% dPercentageChamfer = 0 Result.sInfo = '- Chamfer not executed, tool not found!\n' end end -- se richieste anche le altre lavorazioni if not Strategy.Parameters.bOnlyChamfer then -- per tutti tranne che per feature RoundArc if not ID.IsRoundArch( Proc) and not ID.IsFreeContour( Proc) then -- se sgrossatura da eseguire if Strategy.Parameters.bExecRough then if not Strategy.RoughCut.Machinings or #Strategy.RoughCut.Machinings == 0 then Result.dCompletionPercentage = Result.dCompletionPercentage -- non incide sulla percentuale lavorata, solo messaggio che manca Result.sInfo = Result.sInfo .. '- Roughing not executed\n' end end -- se lavorazioni corner if Strategy.EdgeWithCorner.Machinings and #Strategy.EdgeWithCorner.Machinings == 0 then Result.dCompletionPercentage = Result.dCompletionPercentage - dPercentageEdgeCorner -- la pulizia dei corner incide per il 10% dPercentageEdgeCorner = 0 Result.sInfo = Result.sInfo .. '- Corner not executed, material left\n' end end -- lavorazione del profilo if not Strategy.Profile.Machinings or #Strategy.Profile.Machinings == 0 then Result.sInfo = Result.sInfo .. '- Profile not executed, tool not found!\n' else local dTotalPercentage = dPercentageProfile + dPercentageEdgeCorner + dPercentageChamfer Result.dCompletionPercentage = Result.dCompletionPercentage - ( ( ( 100 - Strategy.Profile.Result.dCompletionPercentage) * dTotalPercentage) / 100) end end -- si setta lo stato in base alla percentuale di completamento if Result.dCompletionPercentage == 100 then Result.sStatus = "Completed" elseif Result.dCompletionPercentage == 0 then Result.sStatus = "Not-Applicable" else Result.sStatus = "Not-Completed" local dPercentageLeft = ceil( 100 - Result.dCompletionPercentage) Result.sInfo = Result.sInfo .. '- Not Complete : left ' .. tostring( dPercentageLeft) .. '%\n' end Result.dCompletionIndex = FeatureLib.GetFeatureCompletionIndex( Result.dCompletionPercentage) Result.dMRR = 1 -- se tutte le lavorazioni sono state eseguite, è la massima qualità che si possa ottenere, altrimenti qualità più bassa if Result.sInfo == '' then Result.dQuality = FeatureLib.GetStrategyQuality( 'BEST') else Result.dQuality = FeatureLib.GetStrategyQuality( 'MILL') end return Result end ------------------------------------------------------------------------------------------------------------- function STR0015.Make( bAddMachining, Proc, Part, CustomParameters) -- carico parametri de default e li aggiorno con quelli passati dal chiamante (potrebbero non essere congruenti) local StrategyLib = {} StrategyLib.Config = STRATEGIES_CONFIG[CustomParameters.sStrategyId] Strategy.sName = StrategyLib.Config.sStrategyId Strategy.Parameters = BeamLib.LoadCustomParametersInStrategy( Proc, Part, CustomParameters, StrategyLib.Config) Strategy.Chamfer = {} Strategy.Chamfer.Machinings = {} Strategy.Chamfer.Result = {} Strategy.Result = {} local bAreAllMachiningsAdded = true -- verifico se la lavorazione può essere spostata dopo taglio di coda local dLengthOnX = Proc.b3Box:getDimX() Strategy.bCanMoveAfterSplit = MachiningLib.CanMoveAfterSplitcut( dLengthOnX, Part) -- recupero e verifico l'entità curva local idAux = EgtGetInfo( Proc.id, 'AUXID', 'i') if idAux then idAux = idAux + Proc.id end if not idAux or ( EgtGetType( idAux) & GDB_FY.GEO_CURVE) == 0 then local sErr = 'Error on process ' .. tostring( Proc.id) .. ' missing profile geometry' EgtOutLog( sErr) return false, sErr end Proc.idAddAuxGeom = idAux -- lavorazione smussi Strategy.Chamfer.Machinings, Strategy.Chamfer.Result = GetChamferStrategy( Proc, Part) -- se non bisogna fare solo gli smussi, si calcolano le altre lavorazioni if not Strategy.Parameters.bOnlyChamfer then -- per tutti tranne che per feature RoundArc if not ID.IsRoundArch( Proc) and not ID.IsFreeContour( Proc) then -- lavorazione taglio per sgrossare if Strategy.Parameters.bExecRough then Strategy.RoughCut = {} Strategy.RoughCut.Machinings = {} Strategy.RoughCut.Result = {} Strategy.RoughCut.Machinings, Strategy.RoughCut.Result = GetRoughStrategy( Proc, Part, bAddMachining) end -- lavorazione degli estremi con angoli interni Strategy.EdgeWithCorner = {} Strategy.EdgeWithCorner.Machinings = {} Strategy.EdgeWithCorner.Result = {} Strategy.EdgeWithCorner.Machinings, Strategy.EdgeWithCorner.Result = GetEdgeWithCornerStrategy( Proc, Part) end -- lavorazione profilo (a meno che non si facciano solo smussi) Strategy.Profile = {} Strategy.Profile.Machinings = {} Strategy.Profile.Result = {} Strategy.Profile.Machinings, Strategy.Profile.Result = GetArcStrategy( Proc, Part) end Strategy.Result = GetFeatureResult( Proc) if bAddMachining and Strategy.Result.sStatus ~= 'Not-Applicable' then -- eventuali punti di spezzatura local FeatureSplittingPoints = FeatureLib.GetFeatureSplittingPoints( Proc, Part) -- lavorazione degli smussi if Strategy.Chamfer.Machinings then for i = 1, #Strategy.Chamfer.Machinings do local MachiningToSplit = {} table.insert( MachiningToSplit, Strategy.Chamfer.Machinings[i]) local MachiningResult = MachiningLib.GetSplitMachinings( MachiningToSplit, FeatureSplittingPoints, Part) -- aggiunge lavorazione for j = 1, #MachiningResult do bAreAllMachiningsAdded = MachiningLib.AddMachinings( Proc, MachiningResult[j]) end end end -- per tutti tranne che per feature RoundArc if not ID.IsRoundArch( Proc) and not ID.IsFreeContour( Proc) then -- lavorazione di sgrezzatura di lama if Strategy.Parameters.bExecRough and Strategy.RoughCut.Machinings then -- se cutting da fare come svuotatura if Strategy.RoughCut.Machinings.bCuttingWithMill then bAreAllMachiningsAdded = MachiningLib.AddMachinings( Proc, Strategy.RoughCut.Machinings) -- taglio di lama else for i = 1, #Strategy.RoughCut.Machinings do if Proc.AffectedFaces.bLeft and Strategy.bCanMoveAfterSplit then Strategy.RoughCut.Machinings[i].sStage = 'AfterTail' end local bIsMachiningAdded = MachiningLib.AddMachinings( Proc, Strategy.RoughCut.Machinings[i]) if not bIsMachiningAdded then bAreAllMachiningsAdded = false end end end end -- lavorazione degli angoli interni if Strategy.EdgeWithCorner.Machinings then for i = 1, #Strategy.EdgeWithCorner.Machinings do local bIsMachiningAdded = MachiningLib.AddMachinings( Proc, Strategy.EdgeWithCorner.Machinings[i]) if not bIsMachiningAdded then bAreAllMachiningsAdded = false end end end end -- lavorazione del profilo if Strategy.Profile.Machinings then for i = 1, #Strategy.Profile.Machinings do Strategy.Profile.Machinings[i].Geometry = {{ Proc.idAddAuxGeom, -1}} Strategy.Profile.Machinings[i].nToolIndex = Strategy.Profile.Machinings[i].ToolInfo.nToolIndex Strategy.Profile.Machinings[i].nType = MCH_MY.MILLING Strategy.Profile.Machinings[i].Steps = MachiningLib.GetMachiningSteps( false, tonumber( Strategy.Profile.Machinings[i].sDepth), TOOLS[Strategy.Profile.Machinings[i].nToolIndex].dStep) Strategy.Profile.Machinings[i].Steps.nStepType = MCH_MILL_ST.ONEWAY -- LeadIn / LeadOut Strategy.Profile.Machinings[i].LeadIn.nType = MCH_MILL_LI.TANGENT Strategy.Profile.Machinings[i].LeadOut.nType = MCH_MILL_LI.TANGENT Strategy.Profile.Machinings[i].LeadIn.dTangentDistance = TOOLS[Strategy.Profile.Machinings[i].ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC Strategy.Profile.Machinings[i].LeadIn.dPerpDistance = 0 Strategy.Profile.Machinings[i].LeadIn.dStartAddLength = 0 Strategy.Profile.Machinings[i].LeadOut.dTangentDistance = TOOLS[Strategy.Profile.Machinings[i].ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC Strategy.Profile.Machinings[i].LeadOut.dPerpDistance = 0 Strategy.Profile.Machinings[i].LeadOut.dEndAddLength = 0 if Proc.AffectedFaces.bLeft and Strategy.bCanMoveAfterSplit then Strategy.Profile.Machinings[i].sStage = 'AfterTail' end -- preparo attacco/uscita in caso di spezzatura arco Strategy.Profile.Machinings[i].LeadInForSplit = BeamLib.TableCopyDeep( Strategy.Profile.Machinings[i].LeadIn) Strategy.Profile.Machinings[i].LeadOutForSplit = BeamLib.TableCopyDeep( Strategy.Profile.Machinings[i].LeadOut) Strategy.Profile.Machinings[i].LeadInForSplit.nType = MCH_MILL_LI.LINEAR Strategy.Profile.Machinings[i].LeadOutForSplit.nType = MCH_MILL_LI.LINEAR Strategy.Profile.Machinings[i].LeadInForSplit.dTangentDistance = 0 Strategy.Profile.Machinings[i].LeadInForSplit.dPerpDistance = TOOLS[Strategy.Profile.Machinings[i].ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC Strategy.Profile.Machinings[i].LeadOutForSplit.dTangentDistance = 0 Strategy.Profile.Machinings[i].LeadOutForSplit.dPerpDistance = TOOLS[Strategy.Profile.Machinings[i].ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC -- sistemo il lato e la direzione di lavoro if Strategy.Profile.Machinings[i].bOtherDirection then Strategy.Profile.Machinings[i].bToolInvert = true Strategy.Profile.Machinings[i].bInvert = EgtIf( TOOLS[Strategy.Profile.Machinings[i].ToolInfo.nToolIndex].bIsCCW, true, false) Strategy.Profile.Machinings[i].nWorkside = EgtIf( TOOLS[Strategy.Profile.Machinings[i].ToolInfo.nToolIndex].bIsCCW, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT) else Strategy.Profile.Machinings[i].bInvert = EgtIf( TOOLS[Strategy.Profile.Machinings[i].ToolInfo.nToolIndex].bIsCCW, false, true) Strategy.Profile.Machinings[i].nWorkside = EgtIf( TOOLS[Strategy.Profile.Machinings[i].ToolInfo.nToolIndex].bIsCCW, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT) end Strategy.Profile.Machinings[i].ptEdge1 = EgtSP( Proc.idAddAuxGeom, GDB_ID.ROOT) Strategy.Profile.Machinings[i].ptEdge2 = EgtEP( Proc.idAddAuxGeom, GDB_ID.ROOT) Strategy.Profile.Machinings[i].dEdgeLength = EgtCurveLength( Proc.idAddAuxGeom) Strategy.Profile.Machinings[i].vtEdgeDirection = EgtSV( Proc.idAddAuxGeom, GDB_ID.ROOT) + EgtMV( Proc.idAddAuxGeom, GDB_ID.ROOT) + EgtEV( Proc.idAddAuxGeom, GDB_ID.ROOT) Strategy.Profile.Machinings[i].dLengthOnX = Proc.b3Box:getDimX() local MachiningToSplit = {} table.insert( MachiningToSplit, Strategy.Profile.Machinings[i]) local MachiningResult = MachiningLib.GetSplitMachinings( MachiningToSplit, FeatureSplittingPoints, Part) -- aggiunge lavorazione for j = 1, #MachiningResult do bAreAllMachiningsAdded = MachiningLib.AddMachinings( Proc, MachiningResult[j]) end end end else bAreAllMachiningsAdded = false end return bAreAllMachiningsAdded, Strategy.Result end ------------------------------------------------------------------------------------------------------------- return STR0015