bef986e453
- modifiche per TURN.
653 lines
30 KiB
Lua
653 lines
30 KiB
Lua
-- FacesBySaw.lua by Egaltech s.r.l. 2022/09/24
|
|
-- Gestione taglio con lama di feature con una o due facce
|
|
-- 2021/01/06 Cambiato limite per attacco Tg con lama e CalcLeadInOutGeom rinominata in CalcLeadInOutPerpGeom.
|
|
-- 2021/02/03 In taglio lama si accettano anche due lati con deviazione minore di 20deg.
|
|
-- 2021/02/09 In taglio lama con PF si preferisce testa in Y- quindi SCC di conseguenza.
|
|
-- 2021/02/26 In taglio lama consento attacco anche da sotto (grazie a migliorie in MachKernel).
|
|
-- 2021/03/22 Attacchi e uscite di tagli longitudinali da sotto con lama solo ortogonali.
|
|
-- 2021/04/27 Migliorati controlli per attacchi e uscite Tg con lama.
|
|
-- 2021/07/08 Modifiche in MakeOneFaceBySaw per gestione taglio con due segmenti.
|
|
-- 2021/08/03 In MakeOneFaceBySaw mgliorata gestione tagli con normale verso il basso e da sopra.
|
|
-- 2021/08/31 DS Aggiunta gestione nessun limite direzione da sotto per testa da sotto.
|
|
-- 2021/11/26 DS Spostate qui MakeOneFaceBySaw (ora MakeOne), CalcLeadInOutPerpGeom e CalcLeadInOutTangGeom.
|
|
-- 2022/04/12 DS Aggiunta gestione speciale cubetti con fresa da sotto.
|
|
-- 2022/06/29 DS In MakeTwo modificato controllo facce dirette verso il basso.
|
|
-- 2022/09/08 In MakeOne aggiunto argomento bForceInvert per poter forzare l'inversione del percorso.
|
|
|
|
-- Tabella per definizione modulo
|
|
local FacesBySaw = {}
|
|
|
|
-- Include
|
|
require( 'EgtBase')
|
|
local BL = require( 'BeamLib')
|
|
local DC = require( 'DiceCut')
|
|
|
|
EgtOutLog( ' FacesBySaw started', 1)
|
|
|
|
-- Dati
|
|
local BD = require( 'BeamData')
|
|
local ML = require( 'MachiningLib')
|
|
|
|
---------------------------------------------------------------------
|
|
function FacesBySaw.MakeOne( nSurfId, nFacet, sCutting, dSawDiam, Par5, dVzLimDwnUp, dCutExtra, dCutSic, dCutOffset, dAccStart, dAccEnd, sNotes, b3Raw, bForceInvert)
|
|
-- dati della faccia
|
|
local ptC, vtN = EgtSurfTmFacetCenter( nSurfId, nFacet, GDB_ID.ROOT)
|
|
-- risolvo parametro ambiguo
|
|
local nOrthoOpposite
|
|
local vtOrthO
|
|
if isVector3d( Par5) then
|
|
nOrthoOpposite = BL.GetNearestOrthoOpposite( Par5, vtN)
|
|
vtOrthO = Vector3d( Par5)
|
|
else
|
|
nOrthoOpposite = Par5
|
|
vtOrthO = BL.GetVersRef( Par5)
|
|
end
|
|
-- verifico se testa da sotto
|
|
local bDownHead = ( dVzLimDwnUp and dVzLimDwnUp < - 1.5)
|
|
-- linea o bilinea di lavorazione (qui uso nOrthoOpposite per ripetere esattamente il calcolo del Mach)
|
|
local ptP1, ptPm, ptP2, vtV1, vtV2, dLen, dWidth = EgtSurfTmFacetOppositeSide( nSurfId, nFacet, BL.GetVersRef( nOrthoOpposite), GDB_ID.ROOT)
|
|
if not dLen or dLen < 1.1 or not dWidth or dWidth < 1.1 then
|
|
local sWarn = 'Face ' .. string.format( '%d,%d', nSurfId, nFacet) .. ' skipped : too small'
|
|
EgtOutLog( sWarn, 1)
|
|
return true, ''
|
|
end
|
|
vtV1 = - vtV1
|
|
local bInvert = bForceInvert
|
|
if bInvert == nil then
|
|
bInvert = ( ptP2:getZ() < ptP1:getZ() - 100 * GEO.EPS_SMALL)
|
|
end
|
|
if bInvert then
|
|
ptP1, ptP2 = ptP2, ptP1
|
|
vtV1, vtV2 = vtV2, vtV1
|
|
end
|
|
local vtTg = ptP2 - ptP1 ; vtTg:normalize()
|
|
local dAllStart = 0
|
|
local dAllEnd = 0
|
|
-- se bilinea, scarto la parte più allineata con la direzione ortogonale (se deviazione angolare oltre 20 deg o lunghezza minore di dSawDiam/2 * cos( 20/2)) ma maggiore di un minimo
|
|
if ( ( ptPm - ptP1) - ( ptPm - ptP1) * vtTg * vtTg):len() > 100 * GEO.EPS_SMALL then
|
|
local vtTg1 = ptPm - ptP1 ; vtTg1:normalize()
|
|
local vtTg2 = ptP2 - ptPm ; vtTg2:normalize()
|
|
local dDist1 = dist( ptP1, ptPm)
|
|
local dDist2 = dist( ptP2, ptPm)
|
|
local dCosMax = 0.951 -- cos( 18°)
|
|
local dLenMin = 30
|
|
local dLenMax = max( 0.5 * dSawDiam * 0.17365 + 1, 2 * dLenMin)
|
|
--if vtTg1 * vtTg2 < dCosMax or ( dDist1 < dLenMax and dDist1 > dLenMin) or ( dDist2 < dLenMax and dDist2 > dLenMin) then
|
|
if vtTg1 * vtTg2 < dCosMax then
|
|
local dOrtho1 = abs( vtTg1 * vtOrthO)
|
|
local dOrtho2 = abs( vtTg2 * vtOrthO)
|
|
if dOrtho1 < dOrtho2 or ( abs( dOrtho1 - dOrtho2) < 0.1 and dDist1 > 4 * dDist2) then
|
|
if dDist1 > dLenMin or dDist1 > 0.5 * dDist2 then
|
|
ptP2 = Point3d( ptPm)
|
|
dAllEnd = - dDist2 - 10 * GEO.EPS_SMALL
|
|
end
|
|
else
|
|
if dDist2 > dLenMin or dDist2 > 0.5 * dDist1 then
|
|
ptP1 = Point3d( ptPm)
|
|
dAllStart = - dDist1 - 10 * GEO.EPS_SMALL
|
|
end
|
|
end
|
|
vtTg = ptP2 - ptP1 ; vtTg:normalize()
|
|
end
|
|
end
|
|
-- verifico se lavorazione con lama sotto e testa sopra
|
|
if not dVzLimDwnUp then dVzLimDwnUp = BL.GetNzLimDownUp( b3Raw, vtN, vtOrthO) end
|
|
local bDownUp = ( vtN:getZ() < dVzLimDwnUp)
|
|
local nFaceUse = nOrthoOpposite
|
|
if bDownUp then nFaceUse = BL.GetOrtupOpposite( nOrthoOpposite) end
|
|
local bWsRight = ( bInvert ~= bDownUp)
|
|
local nWorkSide = EgtIf( bWsRight, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT)
|
|
-- Versore di riferimento
|
|
local vtRef = Vector3d( vtTg)
|
|
vtRef:rotate( vtN, EgtIf( bInvert, -90, 90))
|
|
-- Versore esterno
|
|
local vtOut = vtRef - vtRef * vtTg * vtTg ; vtOut:normalize()
|
|
-- Versore ausiliario (direzione braccio)
|
|
local vtAux = Vector3d( vtN:getX(), vtN:getY(), 0) ; vtAux:normalize()
|
|
vtAux:rotate( Z_AX(), EgtIf( bWsRight, 90, -90))
|
|
if vtAux:isSmall() then
|
|
vtAux = Vector3d( vtOut:getX(), vtOut:getY(), 0) ; vtAux:normalize()
|
|
else
|
|
if abs( vtAux * vtOut) < GEO.EPS_SMALL then
|
|
if abs( vtTg:getZ()) > 0.5 then
|
|
if vtAux * vtRef < 0 then
|
|
vtAux = - vtAux
|
|
end
|
|
elseif vtAux * vtTg > 0 then
|
|
vtAux = - vtAux
|
|
end
|
|
elseif vtAux * vtOut < 0 then
|
|
vtAux = - vtAux
|
|
end
|
|
end
|
|
-- parametri di attacco/uscita
|
|
local b3Box = BBox3d( b3Raw)
|
|
b3Box:expand( dCutSic)
|
|
local ptP1act = ptP1 + vtN * dCutOffset
|
|
local ptP2act = ptP2 + vtN * dCutOffset
|
|
-- attacco perpendicolare
|
|
local dLiTang, dLiPerp, dLoTang, dLoPerp, vtLio = FacesBySaw.CalcLeadInOutPerpGeom( ptP1act, ptP2act, vtV1, vtV2, vtN, dSawDiam/2, vtRef, dCutExtra, b3Box)
|
|
local dLenLi = sqrt( dLiTang * dLiTang + dLiPerp * dLiPerp)
|
|
local dLenLo = sqrt( dLoTang * dLoTang + dLoPerp * dLoPerp)
|
|
-- attacco tangente
|
|
local dLi2Tang, dLi2Perp, dLo2Tang, dLo2Perp = FacesBySaw.CalcLeadInOutTangGeom( ptP1act, ptP2act, vtN, dSawDiam/2, vtRef, dCutExtra, b3Box)
|
|
local dLenLi2 = abs( dLi2Tang)
|
|
local dLenLo2 = abs( dLo2Tang)
|
|
-- scelgo l'attacco più conveniente (se non taglio praticamente longitudinale)
|
|
local bTurnTang
|
|
local Ktp = 1.1
|
|
if BD.KIOTP then Ktp = BD.KIOTP end
|
|
if ( not bDownUp or abs( vtTg:getY()) > 0.5) and
|
|
( not bDownHead or abs( vtTg:getZ()) < 0.51) and
|
|
abs( vtTg:getX()) < 0.9848 and
|
|
( ( abs( vtTg:getZ()) < 0.17 and ( vtV1:getZ() < -0.5 or vtV2:getZ() < -0.5) and not bDownHead) or
|
|
( abs( vtTg:getZ()) < 0.51 and b3Box:getDimZ() > 300 and BD.C_SIMM and BD.MAX_HEIGHT > 450) or
|
|
( Ktp * dLenLi2 < dLenLi and Ktp * dLenLo2 < dLenLo) or Ktp * ( dLenLi2 + dLenLo2) < ( dLenLi + dLenLo)) then
|
|
dLiTang, dLiPerp, dLoTang, dLoPerp = dLi2Tang, dLi2Perp, dLo2Tang, dLo2Perp
|
|
if BD.TURN then
|
|
bTurnTang = true
|
|
dLoTang = -( dLiTang + dAllStart - dAccStart + dAllEnd - dAccEnd + dLen)
|
|
dLoPerp = BD.COLL_SIC
|
|
end
|
|
end
|
|
-- posizione braccio
|
|
EgtOutLog( 'vtN=' .. tostring( vtN) .. ' vtRef=' .. tostring( vtRef) .. ' vtOut=' .. tostring( vtOut) .. ' vtAux=' .. tostring( vtAux), 3)
|
|
local nSCC = MCH_SCC.NONE
|
|
if not BD.TURN then
|
|
if abs( vtAux:getX()) > abs( vtAux:getY()) - GEO.EPS_SMALL then
|
|
nSCC = EgtIf( ( vtAux:getX() > -GEO.EPS_SMALL), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)
|
|
else
|
|
nSCC = EgtIf( ( vtAux:getY() > -GEO.EPS_SMALL), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM)
|
|
end
|
|
else
|
|
if bTurnTang then
|
|
local vtTest = EgtIf( bInvert, vtTg, -vtTg)
|
|
if abs( vtTest:getY()) > abs( vtTest:getZ()) then
|
|
nSCC = EgtIf( vtTest:getY() > 0, MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM)
|
|
else
|
|
nSCC = EgtIf( vtTest:getZ() > 0, MCH_SCC.ADIR_ZP, MCH_SCC.ADIR_ZM)
|
|
end
|
|
else
|
|
local vtTest = vtOut -- vtLio
|
|
if abs( vtN:getY()) < 0.174 and abs( vtN:getZ()) < 0.174 then
|
|
if abs( vtTest:getY()) > abs( vtTest:getZ()) then
|
|
nSCC = EgtIf( vtTest:getY() > 0, MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM)
|
|
else
|
|
nSCC = EgtIf( vtTest:getZ() > 0, MCH_SCC.ADIR_ZP, MCH_SCC.ADIR_ZM)
|
|
end
|
|
elseif abs( vtN:getZ()) < 0.174 then
|
|
nSCC = EgtIf( vtTest:getZ() > -0.017, MCH_SCC.ADIR_ZP, MCH_SCC.ADIR_ZM)
|
|
else
|
|
nSCC = EgtIf( vtTest:getY() > 0, MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM)
|
|
end
|
|
end
|
|
end
|
|
-- inserisco la lavorazione di taglio
|
|
local sName = 'Cut_' .. ( EgtGetName( nSurfId) or tostring( nSurfId)) .. '_' .. tostring( nFacet + 1)
|
|
local nMchFId = EgtAddMachining( sName, sCutting)
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sCutting
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
sName = EgtGetOperationName( nMchFId)
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ nSurfId, nFacet}})
|
|
-- imposto uso faccia
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse)
|
|
-- imposto posizione braccio porta testa
|
|
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
|
|
-- imposto inversione e lato correzione
|
|
EgtSetMachiningParam( MCH_MP.INVERT, bInvert)
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, nWorkSide)
|
|
-- affondamento aggiuntivo
|
|
EgtSetMachiningParam( MCH_MP.OFFSR, -dCutExtra)
|
|
-- offset longitudinale
|
|
EgtSetMachiningParam( MCH_MP.OFFSL, EgtIf( bDownUp, -dCutOffset, dCutOffset))
|
|
-- imposto attacco/uscita
|
|
EgtSetMachiningParam( MCH_MP.LITANG, dLiTang)
|
|
EgtSetMachiningParam( MCH_MP.LIPERP, dLiPerp)
|
|
if bTurnTang then EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LO.PERP_TG) end
|
|
EgtSetMachiningParam( MCH_MP.LOTANG, dLoTang)
|
|
EgtSetMachiningParam( MCH_MP.LOPERP, dLoPerp)
|
|
-- imposto allungamenti iniziale e finale
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dAllStart - dAccStart)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dAllEnd - dAccEnd)
|
|
-- eventuali note
|
|
if sNotes and #sNotes > 0 then EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) end
|
|
-- eseguo
|
|
if not ML.ApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
return true, sName, nMchFId
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function FacesBySaw.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, sCutType, bUpdateIng, bDownHead)
|
|
-- bUpdateIng : parametro opzionale con default true
|
|
if bUpdateIng == nil then bUpdateIng = true end
|
|
-- recupero l'ingombro del grezzo di appartenenza
|
|
local b3Raw = EgtGetRawPartBBox( nRawId)
|
|
-- ingombro del pezzo
|
|
local Ls = EgtGetFirstNameInGroup( nPartId, 'Box')
|
|
local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD)
|
|
if not b3Solid then
|
|
local sErr = 'Error : part box not found'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- verifico il numero di facce
|
|
if Proc.Fct < 2 then
|
|
local sErr = 'Error : TwoFacesBySaw facet number not supported'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- dati delle facce
|
|
local ptC = {}
|
|
local vtN = {}
|
|
ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT)
|
|
ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT)
|
|
-- recupero dati su giunzione tra facce
|
|
local bTouch, ptT1, ptT2, dAngT = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT)
|
|
if not bTouch then
|
|
local sErr = 'Error : TwoFacesBySaw faces not touching'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
local ptM = ( ptT1 + ptT2) / 2
|
|
local vtTg = ptT2 - ptT1 ;
|
|
local bConvex = ( dAngT > 0)
|
|
-- verifico non siano orientate troppo verso il basso e molto sbandate (oltre 10 deg)
|
|
local bFaceOk = {}
|
|
bFaceOk[1] = ( vtN[1]:getZ() >= BD.NZ_MINB or abs( vtN[1]:getY()) < 0.174)
|
|
bFaceOk[2] = ( vtN[2]:getZ() >= BD.NZ_MINB or abs( vtN[2]:getY()) < 0.174)
|
|
if not bDownHead and not bFaceOk[1] and not bFaceOk[2] then
|
|
local sErr = 'Error : TwoFacesBySaw from bottom impossible'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- calcolo direzione di lavoro
|
|
local vtRef = {}
|
|
vtRef[1] = vtN[1] ^ vtTg
|
|
if vtRef[1] * vtN[2] < 0 then vtRef[1] = - vtRef[1] end
|
|
vtRef[1]:normalize()
|
|
if abs( vtRef[1]:getZ()) < 0.577 and abs( abs( vtRef[1]:getX()) - abs( vtRef[1]:getY())) < 0.1 then
|
|
vtRef[1] = ptC[1] - ptM
|
|
vtRef[1]:normalize()
|
|
end
|
|
vtRef[2] = vtN[2] ^ vtTg
|
|
if vtRef[2] * vtN[1] < 0 then vtRef[2] = - vtRef[2] end
|
|
vtRef[2]:normalize()
|
|
if abs( vtRef[2]:getZ()) < 0.577 and abs( abs( vtRef[2]:getX()) - abs( vtRef[2]:getY())) < 0.1 then
|
|
vtRef[2] = ptC[2] - ptM
|
|
vtRef[2]:normalize()
|
|
end
|
|
-- determino quale faccia è più grande
|
|
local dSqDim1 = ( ptC[1] - ptM):sqlen()
|
|
local dSqDim2 = ( ptC[2] - ptM):sqlen()
|
|
local nBigInd = EgtIf( dSqDim1 > dSqDim2 - 1., 1, 2)
|
|
local nSmaInd = 3 - nBigInd
|
|
local nUpInd = EgtIf( vtN[1]:getZ() > vtN[2]:getZ() - GEO.EPS_SMALL, 1, 2)
|
|
local nOtInd = 3 - nUpInd
|
|
-- metto in relazione la scelta facce con il confronto del versore Z con la scelta in base alla grandezza faccia
|
|
-- se la faccia più grande è messa secondaria e il suo versore Z non è troppo negativo
|
|
if nOtInd == nBigInd and vtN[nBigInd]:getZ() > -0.5 and vtN[nSmaInd]:getZ() < 0.966 then
|
|
nUpInd = nBigInd
|
|
nOtInd = nSmaInd
|
|
end
|
|
-- recupero la lavorazione
|
|
local sCutting = ML.FindCutting( sCutType, nil, bDownHead)
|
|
if not sCutting then
|
|
local sErr = 'Error : cutting not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- recupero i dati dell'utensile
|
|
local dSawDiam = 400
|
|
local dSawThick = 5
|
|
local dMaxDepth = 0
|
|
if EgtMdbSetCurrMachining( sCutting) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
|
|
dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam
|
|
dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick
|
|
dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth
|
|
end
|
|
end
|
|
-- calcolo extra taglio
|
|
local dCutExtra = 0
|
|
if dAngT < -91 and dAngT > -179 then
|
|
dCutExtra = - dSawThick / tan( 180 + dAngT)
|
|
end
|
|
-- sistemo direzione limite da sotto (con testa da sotto limite Vz Down Up messo a -2 per non farlo mai intervenire)
|
|
local dNzLimDwnUp
|
|
if bDownHead then
|
|
dNzLimDwnUp = - 2
|
|
end
|
|
-- recupero gruppo per geometria addizionale
|
|
local nAddGrpId = BL.GetAddGroup( nPartId)
|
|
if not nAddGrpId then
|
|
local sErr = 'Error : missing AddGroup'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- verifico se necessari tagli supplementari
|
|
local vCuts = DC.GetDice( nAddGrpId, b3Solid, ptC[nUpInd], vtN[nUpInd], false, ptC[nOtInd], vtN[nOtInd])
|
|
--DC.PrintOrderCut( vCuts)
|
|
if #vCuts > 0 then
|
|
-- sistemo posizione nel DB, nome e info
|
|
for i = 1, #vCuts do
|
|
for j = 1, #vCuts[i] do
|
|
EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id))
|
|
EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId)
|
|
end
|
|
end
|
|
-- con testa da sopra
|
|
if not bDownHead or BD.TURN then
|
|
-- eseguo
|
|
for i = 1, #vCuts do
|
|
-- assegno il modo di tagliare
|
|
local vtOrthO = EgtIf( ( i % 2) == 1, vtRef[nOtInd], vtRef[nUpInd])
|
|
-- lavoro la faccia
|
|
for j = 1, #vCuts[i] do
|
|
-- se FAST, pezzo alto e ultimo taglio verticale -> allungo uscita per consentire eventuale rotazione B sul posto
|
|
local dAccEnd = 0
|
|
if not BD.C_SIMM and BD.MAX_HEIGHT_ROT_B_ABOVE and b3Raw:getDimZ() > BD.MAX_HEIGHT_ROT_B_ABOVE and vtOrthO:getZ() > 0.866 and j == #vCuts[i] then
|
|
dAccEnd = - ( dSawDiam / 2 + BD.CUT_SIC)
|
|
end
|
|
local bOk, sErr = FacesBySaw.MakeOne( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthO, dNzLimDwnUp, dCutExtra, BD.CUT_SIC, 0, 0, dAccEnd, nil, b3Raw)
|
|
if not bOk then
|
|
return bOk, sErr
|
|
end
|
|
end
|
|
end
|
|
-- altrimenti con testa da sotto
|
|
else
|
|
-- eseguo (facendo di seguito i due tagli di ogni singolo cubetto)
|
|
for i = 1, #vCuts, 2 do
|
|
-- determino il modo di tagliare dei perpendicolari
|
|
local vtOrthoO_1 = Vector3d( vtN[nUpInd])
|
|
-- determino il modo di tagliare dei paralleli
|
|
local vtOrthoO_2
|
|
local bNoPerpCuts_2 = false
|
|
local vtO
|
|
if #vCuts[i] > 0 then
|
|
vtO = EgtSurfTmFacetNormVersor( vCuts[i][1], 0, GDB_ID.ROOT)
|
|
elseif vCuts[i+2] and #vCuts[i+2] > 0 then
|
|
-- lunghezza faccia nell'eventuale direzione ortogonale
|
|
local asseX = EgtSurfTmFacetNormVersor( vCuts[i+2][1], 0, GDB_ID.ROOT)
|
|
local asseY = asseX ^ vtN[nUpInd]
|
|
local Frame = Frame3d( ptC, ptC + asseX, ptC + asseY)
|
|
local b3Fac = EgtGetBBoxRef( vCuts[i+1][1], GDB_BB.STANDARD, Frame)
|
|
-- se lunghezza inferiore al limite, accetto la direzione
|
|
if b3Fac:getDimX() < dMaxDepth - BD.CUT_EXTRA then
|
|
vtO = asseX
|
|
else
|
|
bNoPerpCuts_2 = true
|
|
end
|
|
else
|
|
bNoPerpCuts_2 = true
|
|
end
|
|
if vtO then
|
|
vtOrthoO_2 = Vector3d( vtO)
|
|
else
|
|
if bHorizCut then
|
|
vtOrthoO_2 = -Z_AX()
|
|
elseif vtN:getY() > -0.02 then
|
|
if not Proc.Head then
|
|
vtOrthoO_2 = -Y_AX()
|
|
else
|
|
vtOrthoO_2 = Y_AX()
|
|
end
|
|
else
|
|
vtOrthoO_2 = -Y_AX()
|
|
end
|
|
end
|
|
-- lavoro le coppie di facce del singolo cubetto
|
|
for j = 1, max( #vCuts[i], #vCuts[i+1]) do
|
|
-- extra taglio per perpendicolari
|
|
local dExtraCut_1 = -0.1
|
|
-- extra taglio per paralleli
|
|
local dExtraCut_2 = -0.1
|
|
-- se non ci sono tagli ortogonali devo affondare
|
|
if bNoPerpCuts_2 then
|
|
dExtraCut_2 = BD.CUT_EXTRA
|
|
end
|
|
-- taglio perpendicolare (limite Vz Down Up messo a -2 per non farlo mai intervenire)
|
|
if vCuts[i][j] then
|
|
local bOk, sErr = FacesBySaw.MakeOne( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthoO_1, -2, dExtraCut_1, BD.CUT_SIC, 0, 0, 0, nil, b3Raw)
|
|
if not bOk then
|
|
return bOk, sErr
|
|
end
|
|
end
|
|
-- taglio parallelo (limite Vz Down Up messo a -2 per non farlo mai intervenire)
|
|
if vCuts[i+1][j] then
|
|
local bOk, sErr = FacesBySaw.MakeOne( vCuts[i+1][j], 0, sCutting, dSawDiam, vtOrthoO_2, -2, dExtraCut_2, BD.CUT_SIC, 0, 0, 0, nil, b3Raw)
|
|
if not bOk then
|
|
return bOk, sErr
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
else
|
|
-- se prima faccia lavorata è da sotto scambio le facce
|
|
if vtN[nOtInd]:getZ() < -0.5 then
|
|
nUpInd, nOtInd = nOtInd, nUpInd
|
|
end
|
|
-- lavoro la prima faccia
|
|
local bOk, sErr = FacesBySaw.MakeOne( Proc.Id, nOtInd-1, sCutting, dSawDiam, vtRef[nOtInd], dNzLimDwnUp, dCutExtra, BD.CUT_SIC, 0, 0, 0, nil, b3Raw)
|
|
if not bOk then return bOk, sErr end
|
|
-- lavoro seconda faccia
|
|
bOk, sErr = FacesBySaw.MakeOne( Proc.Id, nUpInd-1, sCutting, dSawDiam, vtRef[nUpInd], dNzLimDwnUp, dCutExtra, BD.CUT_SIC, 0, 0, 0, nil, b3Raw)
|
|
if not bOk then
|
|
return bOk, sErr
|
|
end
|
|
end
|
|
-- eventuale segnalazione ingombro di testa o coda
|
|
local dMinHIng = min( 0.5 * BD.VICE_MINH, 0.5 * b3Raw:getDimZ())
|
|
if bUpdateIng and Proc.Box:getDimZ() > dMinHIng and Proc.Box:getMin():getZ() < b3Raw:getMin():getZ() + dMinHIng and
|
|
not ( abs( vtN[nBigInd]:getX()) < 0.05 and vtN[nBigInd]:getY() < 0 and Proc.Box:getDimX() > 500) then
|
|
if Proc.Head then
|
|
local dOffs = b3Solid:getMax():getX() - Proc.Box:getMin():getX()
|
|
BL.UpdateHCING( nRawId, dOffs)
|
|
elseif Proc.Tail then
|
|
local dOffs = Proc.Box:getMax():getX() - b3Solid:getMin():getX()
|
|
BL.UpdateTCING( nRawId, dOffs)
|
|
elseif Proc.Box:getCenter():getX() > b3Solid:getCenter():getX() then
|
|
local dOffs = b3Solid:getMax():getX() - Proc.Box:getMin():getX()
|
|
local dDist = b3Solid:getMax():getX() - Proc.Box:getMax():getX()
|
|
-- se concavo aumento la distanza (rimane una punta...)
|
|
if dAngT < 0 then dDist = dDist + 10 end
|
|
BL.UpdateHCING( nRawId, dOffs, dDist)
|
|
end
|
|
end
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function FacesBySaw.CalcLeadInOutPerpGeom( ptP1, ptP2, vtV1, vtV2, vtN, dRad, vtRef, dCutExtra, b3Box)
|
|
-- Mi assicuro che i vettori ingresso/uscita giacciano nel piano
|
|
vtV1 = vtV1 - vtV1 * vtN * vtN ; vtV1:normalize()
|
|
vtV2 = vtV2 - vtV2 * vtN * vtN ; vtV2:normalize()
|
|
-- Versore tangente al taglio
|
|
local vtTg = ptP2 - ptP1 ;
|
|
vtTg = vtTg - vtTg * vtN * vtN ; vtTg:normalize()
|
|
-- Sistema di riferimento intrinseco al taglio
|
|
local vtX = vtTg ^ vtN
|
|
local frFace = Frame3d( ptP1, vtX, vtTg, vtN)
|
|
EgtOutLog( 'Vref=' .. tostring( vtRef) .. ' V1=' .. tostring( vtV1) .. ' V2=' .. tostring( vtV2), 3)
|
|
-- Versore di attacco e uscita
|
|
local dCos1 = vtV1 * vtRef
|
|
local dCos2 = vtV2 * vtRef
|
|
local vtLio
|
|
if abs( dCos1 - dCos2) < 0.001 then
|
|
if abs( vtV1:getZ()) < abs( vtV2:getZ()) then
|
|
vtLio = vtV1
|
|
else
|
|
vtLio = vtV2
|
|
end
|
|
elseif dCos1 > dCos2 then
|
|
vtLio = vtV1
|
|
else
|
|
vtLio = vtV2
|
|
end
|
|
local bRight = ( vtX * vtLio > 0)
|
|
-- Versore di attacco e uscita nel riferimento intrinseco al taglio
|
|
local vtLioL = Vector3d( vtLio) ; vtLioL:toLoc( frFace)
|
|
-- Spostamento punti per effetto dell'extra o della deficienza di taglio
|
|
ptP1 = ptP1 + vtX * ( EgtIf( bRight, - dCutExtra, dCutExtra))
|
|
ptP2 = ptP2 + vtX * ( EgtIf( bRight, - dCutExtra, dCutExtra))
|
|
-- Non va considerata l'uscita dalla faccia sotto, pertanto va abbassata
|
|
-- 2021/02/26 Abilito anche uscita sotto
|
|
local b3MyBox = BBox3d( b3Box) ; --b3MyBox:Add( b3MyBox:getMin() - 1000 * Z_AX())
|
|
-- Attacco
|
|
local dLiTang = 10000
|
|
local dLiPerp = 10000
|
|
local bLiOk, _, vLiPar = EgtLineBoxInters( ptP1, vtLio, b3MyBox)
|
|
if bLiOk and #vLiPar > 0 then
|
|
-- con la prima faccia di uscita
|
|
local dLen = vLiPar[#vLiPar]
|
|
local ptInt = ptP1 + vtLio * dLen
|
|
local vtFN = BL.GetBoxFaceNorm( b3MyBox, ptInt, vtLio)
|
|
EgtOutLog( 'LiFaceNorm=' .. tostring( vtFN), 3)
|
|
local dAddLen = dRad * ( sqrt( 1 - ( vtN * vtFN) * ( vtN * vtFN)) - abs( vtX * vtFN)) / ( vtLio * vtFN)
|
|
local dLiLen = dLen + dAddLen
|
|
EgtOutLog( 'LeadIn Dist=' .. EgtNumToString( dLiLen), 3)
|
|
dLiTang = - dLiLen * vtLioL:getY()
|
|
dLiPerp = EgtIf( bRight, dLiLen, - dLiLen) * vtLioL:getX()
|
|
-- verifico se miglioro calcolando con faccia successiva
|
|
local b3Mod = BBox3d( b3MyBox) ; b3Mod:Add( ptInt + 1000 * vtFN)
|
|
local bLiOk2, _, vLiPar2 = EgtLineBoxInters( ptP1, vtLio, b3Mod)
|
|
if bLiOk2 and #vLiPar2 > 0 then
|
|
local dLen2 = vLiPar2[#vLiPar2]
|
|
local vtFN2 = BL.GetBoxFaceNorm( b3Mod, ptP1 + vtLio * dLen2, vtLio)
|
|
EgtOutLog( 'LiFaceNorm2=' .. tostring( vtFN2), 3)
|
|
local dAddLen2 = dRad * ( sqrt( 1 - ( vtN * vtFN2) * ( vtN * vtFN2)) - abs( vtX * vtFN2)) / ( vtLio * vtFN2)
|
|
local dLiLen2 = dLen2 + dAddLen2
|
|
EgtOutLog( 'LeadIn Dist2=' .. EgtNumToString( dLiLen2), 3)
|
|
local dLiTang2 = - dLiLen2 * vtLioL:getY()
|
|
local dLiPerp2 = EgtIf( bRight, dLiLen2, - dLiLen2) * vtLioL:getX()
|
|
if dLiLen2 < dLiLen then
|
|
dLiTang = dLiTang2
|
|
dLiPerp = dLiPerp2
|
|
end
|
|
end
|
|
end
|
|
-- Lunghezza di uscita
|
|
local dLoTang = 10000
|
|
local dLoPerp = 10000
|
|
local bLoOk, _, vLoPar = EgtLineBoxInters( ptP2, vtLio, b3MyBox)
|
|
if bLoOk and #vLoPar > 0 then
|
|
-- con la prima faccia di uscita
|
|
local dLen = vLoPar[#vLoPar]
|
|
local ptInt = ptP2 + vtLio * dLen
|
|
local vtFN = BL.GetBoxFaceNorm( b3MyBox, ptInt, vtLio)
|
|
EgtOutLog( 'LoFaceNorm=' .. tostring( vtFN), 3)
|
|
local dAddLen = dRad * ( sqrt( 1 - ( vtN * vtFN) * ( vtN * vtFN)) - abs( vtX * vtFN)) / ( vtLio * vtFN)
|
|
local dLoLen = dLen + dAddLen
|
|
EgtOutLog( 'LeadOut Dist=' .. EgtNumToString( dLoLen), 3)
|
|
dLoTang = dLoLen * vtLioL:getY()
|
|
dLoPerp = EgtIf( bRight, dLoLen, - dLoLen) * vtLioL:getX()
|
|
-- verifico se miglioro calcolando con faccia successiva
|
|
local b3Mod = BBox3d( b3MyBox) ; b3Mod:Add( ptInt + 1000 * vtFN)
|
|
local bLoOk2, _, vLoPar2 = EgtLineBoxInters( ptP2, vtLio, b3Mod)
|
|
if bLoOk2 and #vLoPar2 > 0 then
|
|
local dLen2 = vLoPar2[#vLoPar2]
|
|
local vtFN2 = BL.GetBoxFaceNorm( b3Mod, ptP2 + vtLio * dLen2, vtLio)
|
|
EgtOutLog( 'LoFaceNorm2=' .. tostring( vtFN2), 3)
|
|
local dAddLen2 = dRad * ( sqrt( 1 - ( vtN * vtFN2) * ( vtN * vtFN2)) - abs( vtX * vtFN2)) / ( vtLio * vtFN2)
|
|
local dLoLen2 = dLen2 + dAddLen2
|
|
EgtOutLog( 'LeadOut Dist2=' .. EgtNumToString( dLoLen2), 3)
|
|
local dLoTang2 = dLoLen2 * vtLioL:getY()
|
|
local dLoPerp2 = EgtIf( bRight, dLoLen2, - dLoLen2) * vtLioL:getX()
|
|
if dLoLen2 < dLoLen then
|
|
dLoTang = dLoTang2
|
|
dLoPerp = dLoPerp2
|
|
end
|
|
end
|
|
end
|
|
return dLiTang, dLiPerp, dLoTang, dLoPerp, vtLio
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function FacesBySaw.CalcLeadInOutTangGeom( ptP1, ptP2, vtN, dRad, vtRef, dCutExtra, b3Box)
|
|
-- Versore tangente al taglio
|
|
local vtTg = ptP2 - ptP1 ;
|
|
vtTg = vtTg - vtTg * vtN * vtN ; vtTg:normalize()
|
|
-- Sistema di riferimento intrinseco al taglio
|
|
local vtX = vtTg ^ vtN
|
|
local frFace = Frame3d( ptP1, vtX, vtTg, vtN)
|
|
if ( vtX * vtRef < 0) then
|
|
vtX = - vtX
|
|
end
|
|
EgtOutLog( 'Vref=' .. tostring( vtRef) .. ' V1=' .. tostring( vtV1) .. ' V2=' .. tostring( vtV2), 3)
|
|
-- Spostamento punti per effetto dell'extra o della deficienza di taglio
|
|
ptP1 = ptP1 - vtX * dCutExtra
|
|
ptP2 = ptP2 - vtX * dCutExtra
|
|
-- Non va considerata l'uscita dalla faccia sotto, pertanto va abbassata
|
|
-- 2021/02/26 Abilito anche uscita sotto
|
|
local b3MyBox = BBox3d( b3Box) ; --b3MyBox:Add( b3MyBox:getMin() - 1000 * Z_AX())
|
|
-- Attacco
|
|
local dLiTang = 10000
|
|
local dLiPerp = 0
|
|
local bLiOk, _, vLiPar = EgtLineBoxInters( ptP1, vtTg, b3MyBox)
|
|
if bLiOk and #vLiPar > 0 then
|
|
local dLen = vLiPar[1]
|
|
local ptInt = ptP1 + vtTg * dLen
|
|
local vtFN = BL.GetBoxFaceNorm( b3MyBox, ptInt, -vtTg)
|
|
EgtOutLog( 'LiFaceNorm=' .. tostring( vtFN), 3)
|
|
local dAddLen = dRad * ( sqrt( 1 - ( vtN * vtFN) * ( vtN * vtFN)) - ( vtX * vtFN)) / ( vtTg * vtFN)
|
|
local dLiLen = dLen + dAddLen
|
|
EgtOutLog( 'LeadIn Dist=' .. EgtNumToString( dLiLen), 3)
|
|
dLiTang = - dLiLen
|
|
-- verifico se miglioro calcolando con faccia successiva
|
|
local b3Mod = BBox3d( b3MyBox) ; b3Mod:Add( ptInt + 1000 * vtFN)
|
|
local bLiOk2, _, vLiPar2 = EgtLineBoxInters( ptP1, vtTg, b3Mod)
|
|
if bLiOk2 and #vLiPar2 > 0 then
|
|
local dLen2 = vLiPar2[1]
|
|
local vtFN2 = BL.GetBoxFaceNorm( b3Mod, ptP1 + vtTg * dLen2, -vtTg)
|
|
EgtOutLog( 'LiFaceNorm2=' .. tostring( vtFN2), 3)
|
|
local dAddLen2 = dRad * ( sqrt( 1 - ( vtN * vtFN2) * ( vtN * vtFN2)) - ( vtX * vtFN2)) / ( vtTg * vtFN2)
|
|
local dLiLen2 = dLen2 + dAddLen2
|
|
EgtOutLog( 'LeadIn Dist2=' .. EgtNumToString( dLiLen2), 3)
|
|
if -dLiLen2 < -dLiLen then
|
|
dLiTang = - dLiLen2
|
|
end
|
|
end
|
|
end
|
|
-- Lunghezza di uscita
|
|
local dLoTang = 10000
|
|
local dLoPerp = 0
|
|
local bLoOk, _, vLoPar = EgtLineBoxInters( ptP2, vtTg, b3MyBox)
|
|
if bLoOk and #vLoPar > 0 then
|
|
local dLen = vLoPar[#vLoPar]
|
|
local ptInt = ptP2 + vtTg * dLen
|
|
local vtFN = BL.GetBoxFaceNorm( b3MyBox, ptInt, vtTg)
|
|
EgtOutLog( 'LoFaceNorm=' .. tostring( vtFN), 3)
|
|
local dAddLen = dRad * ( sqrt( 1 - ( vtN * vtFN) * ( vtN * vtFN)) - ( vtX * vtFN)) / ( vtTg * vtFN)
|
|
local dLoLen = dLen + dAddLen
|
|
EgtOutLog( 'LeadOut Dist=' .. EgtNumToString( dLoLen), 3)
|
|
dLoTang = dLoLen
|
|
-- verifico se miglioro calcolando con faccia successiva
|
|
local b3Mod = BBox3d( b3MyBox) ; b3Mod:Add( ptInt + 1000 * vtFN)
|
|
local bLoOk2, _, vLoPar2 = EgtLineBoxInters( ptP2, vtTg, b3Mod)
|
|
if bLoOk2 and #vLoPar2 > 0 then
|
|
local dLen2 = vLoPar2[#vLoPar2]
|
|
local vtFN2 = BL.GetBoxFaceNorm( b3Mod, ptP2 + vtTg * dLen2, vtTg)
|
|
EgtOutLog( 'LoFaceNorm2=' .. tostring( vtFN2), 3)
|
|
local dAddLen2 = dRad * ( sqrt( 1 - ( vtN * vtFN2) * ( vtN * vtFN2)) - ( vtX * vtFN2)) / ( vtTg * vtFN2)
|
|
local dLoLen2 = dLen2 + dAddLen2
|
|
EgtOutLog( 'LeadOut Dist2=' .. EgtNumToString( dLoLen2), 3)
|
|
if dLoLen2 < dLoLen then
|
|
dLoTang = dLoLen2
|
|
end
|
|
end
|
|
end
|
|
return dLiTang, dLiPerp, dLoTang, dLoPerp
|
|
end
|
|
|
|
return FacesBySaw
|