-- BeamLib.lua by Egaltech s.r.l. 2019/07/25 -- Libreria globale per Travi -- Tabella per definizione modulo local BeamLib = {} -- Include require( 'EgtBase') EgtOutLog( ' BeamLib started', 1) ------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------- function BeamLib.GetAddGroup( PartId) -- recupero il nome del gruppo di lavoro corrente local sMchGrp = EgtGetMachGroupName( EgtGetCurrMachGroup() or GDB_ID.NULL) if not sMchGrp then return nil, nil end -- cerco il gruppo aggiuntivo omonimo nel pezzo e se esiste lo restituisco local AddGrpId = EgtGetFirstNameInGroup( PartId or GDB_ID.NULL, sMchGrp) -- restituisco Id e Nome return AddGrpId, sMchGrp end ------------------------------------------------------------------------------------------------------------- function BeamLib.CreateOrEmptyAddGroup( PartId) -- recupero i dati del gruppo aggiuntivo local AddGrpId, sMchGrp = BeamLib.GetAddGroup( PartId) if not sMchGrp then return false end -- se esiste lo svuoto if AddGrpId then return EgtEmptyGroup( AddGrpId) end -- altrimenti lo creo AddGrpId = EgtGroup( PartId or GDB_ID.NULL) if not AddGrpId then return false end -- assegno nome, flag di layer per gruppo di lavoro e colore EgtSetName( AddGrpId, sMchGrp) EgtSetInfo( AddGrpId, GDB_SI.MGRPONLY, EgtGetCurrMachGroup()) EgtSetColor( AddGrpId, Color3d( 80, 160, 160, 50)) return true end ------------------------------------------------------------------------------------------------------------- function BeamLib.AddPartStartFace( PartId, b3Solid) -- recupero gruppo per geometria aggiuntiva local AddGrpId = BeamLib.GetAddGroup( PartId) if not AddGrpId then local sErr = 'Error on process StartFace impossible to find AddGroup' EgtOutLog( sErr) return false, sErr end -- aggiungo nuovo taglio iniziale local nStmId = EgtSurfTmPlaneInBBox( AddGrpId, b3Solid:getMax(), X_AX(), b3Solid, GDB_RT.GLOB) if not nStmId then local sErr = 'Error on process StartFace impossible to create Face' EgtOutLog( sErr) return false, sErr end -- applico gli opportuni attributi di feature EgtSetName( nStmId, 'StartCut') EgtSetInfo( nStmId, 'GRP', 1) EgtSetInfo( nStmId, 'PRC', 340) return true end ------------------------------------------------------------------------------------------------------------- function BeamLib.AddPartEndFace( PartId, b3Solid) -- recupero gruppo per geometria aggiuntiva local AddGrpId = BeamLib.GetAddGroup( PartId) if not AddGrpId then local sErr = 'Error on process EndFace impossible to find AddGroup' EgtOutLog( sErr) return false, sErr end -- aggiungo nuovo taglio finale local nStmId = EgtSurfTmPlaneInBBox( AddGrpId, b3Solid:getMin(), -X_AX(), b3Solid, GDB_RT.GLOB) if not nStmId then local sErr = 'Error on process EndFace impossible to create Face' EgtOutLog( sErr) return false, sErr end -- applico gli opportuni attributi di feature EgtSetName( nStmId, 'EndCut') EgtSetInfo( nStmId, 'GRP', 2) EgtSetInfo( nStmId, 'PRC', 350) return true end ------------------------------------------------------------------------------------------------------------- function BeamLib.AddPhaseWithRawParts( nFirstRawId, OriTR, dDeltaSucc) EgtAddPhase() local nRawId = nFirstRawId local dRawMove = 0 while nRawId do EgtKeepRawPart( nRawId) EgtMoveToCornerRawPart( nRawId, OriTR, MCH_CR.TR) EgtMoveRawPart( nRawId, Vector3d( - dRawMove, 0, 0)) if dRawMove == 0 then dRawMove = dRawMove + dDeltaSucc end dRawMove = dRawMove + EgtGetRawPartBBox( nRawId):getDimX() nRawId = EgtGetNextRawPart( nRawId) end end ------------------------------------------------------------------------------------------------------------- function BeamLib.PutStartOnTop( nCrvId) -- verifico che la curva sia chiusa if not EgtCurveIsClosed( nCrvId) then return false end -- cerco l'estremo più alto e lo imposto come inizio local dUmax = 0 local dZmax = - GEO.INFINITO local dUi, dUf = EgtCurveDomain( nCrvId) for dU = dUi, dUf, 0.5 do local ptP = EgtUP( nCrvId, dU, GDB_ID.ROOT) if ptP and ptP:getZ() > dZmax + GEO.EPS_SMALL then dZmax = ptP:getZ() dUmax = dU end end if abs( dUmax - dUi) > GEO.EPS_ZERO then EgtChangeClosedCurveStart( nCrvId, dUmax) end return true end ------------------------------------------------------------------------------------------------------------- function BeamLib.PutStartNearestToEdge( nCrvId, b3Raw) -- verifico che la curva sia chiusa if not EgtCurveIsClosed( nCrvId) then return false end -- recupero il versore normale al piano di lavoro o estrusione local vtN = EgtCurveExtrusion( nCrvId, GDB_ID.ROOT) -- coefficienti per riportare la distanza nel piano di lavoro local dCoeffX = 1 / ( sqrt( 1 - vtN:getX() * vtN:getX())) local dCoeffY = 1 / ( sqrt( 1 - vtN:getY() * vtN:getY())) local dCoeffZ = 1 / ( sqrt( 1 - vtN:getZ() * vtN:getZ())) -- cerco l'estremo più vicino al box e lo imposto come inizio (escluso Zmin) local dUopt = 0 local dDopt = GEO.INFINITO local dUi, dUf = EgtCurveDomain( nCrvId) for dU = dUi, dUf, 0.5 do local ptP = EgtUP( nCrvId, dU, GDB_ID.ROOT) if ptP then local vtMin = ptP - b3Raw:getMin() local vtMax = ptP - b3Raw:getMax() local dD = abs( vtMin:getX()) * dCoeffX dD = min( abs( vtMax:getX()) * dCoeffX, dD) dD = min( abs( vtMin:getY()) * dCoeffY, dD) dD = min( abs( vtMax:getY()) * dCoeffY, dD) dD = min( abs( vtMax:getZ()) * dCoeffZ, dD) if dD < dDopt + GEO.EPS_SMALL then dDopt = dD dUopt = dU end end end if abs( dUopt - dUi) > GEO.EPS_ZERO then EgtChangeClosedCurveStart( nCrvId, dUopt) end return true end ------------------------------------------------------------------------------------------------------------- function BeamLib.GetPointDirDepth( nRawId, ptP, vtDir) -- recupero il solido del grezzo local nSolId = EgtGetFirstNameInGroup( nRawId, 'RawSolid') if not nSolId then return end -- interseco con la retta local bOk, vType, vPar = EgtLineSurfTmInters( ptP, vtDir, nSolId, GDB_RT.GLOB) if not bOk then return end if not vPar or #vPar == 0 then return -2 end local dLenIn, dLenOut for i = 1, #vPar do if vPar[i] < 0 then if vType[i] == GDB_SLT.IN or vType[i] == GDB_SLT.TG_INI then dLenIn = -1 end if vType[i] == GDB_SLT.OUT or vType[i] == GDB_SLT.TG_FIN then dLenIn = -2 end else if vType[i] == GDB_SLT.IN or vType[i] == GDB_SLT.TG_INI then dLenIn = vPar[i] end if vType[i] == GDB_SLT.OUT or vType[i] == GDB_SLT.TG_FIN or vType[i] == GDB_SLT.TOUCH then dLenOut = vPar[i] end end end return dLenIn, dLenOut end --------------------------------------------------------------------- function BeamLib.GetNearestParalOpposite( vtRef) -- devo confrontare la componente orizzontale con quella verticale local dHorSq = vtRef:getX() * vtRef:getX() + vtRef:getY() * vtRef:getY() local dVertSq =vtRef:getZ() * vtRef:getZ() -- se prevalente la componente orizzontale if dHorSq >= dVertSq then if abs( vtRef:getX()) > abs( vtRef:getY()) then if vtRef:getX() > 0 then return MCH_MILL_FU.PARAL_LEFT else return MCH_MILL_FU.PARAL_RIGHT end elseif abs( vtRef:getY()) > abs( vtRef:getZ()) then if vtRef:getY() > 0 then return MCH_MILL_FU.PARAL_FRONT else return MCH_MILL_FU.PARAL_BACK end end -- altrimenti prevale la verticale else if vtRef:getZ() > 0 then return MCH_MILL_FU.PARAL_DOWN else return MCH_MILL_FU.PARAL_TOP end end return nil end --------------------------------------------------------------------- function BeamLib.GetNearestOrthoOpposite( vtRef) -- devo confrontare la componente orizzontale con quella verticale local dHorSq = vtRef:getX() * vtRef:getX() + vtRef:getY() * vtRef:getY() local dVertSq =vtRef:getZ() * vtRef:getZ() -- se prevalente la componente orizzontale if dHorSq >= dVertSq then if abs( vtRef:getX()) >= abs( vtRef:getY()) then if vtRef:getX() > 0 then return MCH_MILL_FU.ORTHO_LEFT else return MCH_MILL_FU.ORTHO_RIGHT end else if vtRef:getY() > 0 then return MCH_MILL_FU.ORTHO_FRONT else return MCH_MILL_FU.ORTHO_BACK end end -- altrimenti prevale la verticale else if vtRef:getZ() > 0 then return MCH_MILL_FU.ORTHO_DOWN else return MCH_MILL_FU.ORTHO_TOP end end return nil end --------------------------------------------------------------------- function BeamLib.GetOrtupOpposite( nOrthoOpposite) if nOrthoOpposite == MCH_MILL_FU.ORTHO_LEFT then return MCH_MILL_FU.ORTUP_LEFT elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_RIGHT then return MCH_MILL_FU.ORTUP_RIGHT elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_FRONT then return MCH_MILL_FU.ORTUP_FRONT elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_BACK then return MCH_MILL_FU.ORTUP_BACK elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_DOWN then return MCH_MILL_FU.ORTUP_DOWN elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_TOP then return MCH_MILL_FU.ORTUP_TOP end return nil end --------------------------------------------------------------------- function BeamLib.GetVersRef( nOrthoOpposite) if nOrthoOpposite == MCH_MILL_FU.ORTHO_LEFT then return X_AX() elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_RIGHT then return -X_AX() elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_FRONT then return Y_AX() elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_BACK then return -Y_AX() elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_DOWN then return Z_AX() elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_TOP then return -Z_AX() end return nil end --------------------------------------------------------------------- function BeamLib.GetBoxFaceNorm( b3Box, ptP, vtV) local vtNx = V_NULL() if abs( ptP:getX() - b3Box:getMin():getX()) < 10 * GEO.EPS_SMALL then vtNx = -X_AX() elseif abs( ptP:getX() - b3Box:getMax():getX()) < 10 * GEO.EPS_SMALL then vtNx = X_AX() end local vtNy = V_NULL() if abs( ptP:getY() - b3Box:getMin():getY()) < 10 * GEO.EPS_SMALL then vtNy = -Y_AX() elseif abs( ptP:getY() - b3Box:getMax():getY()) < 10 * GEO.EPS_SMALL then vtNy = Y_AX() end local vtNz = V_NULL() if abs( ptP:getZ() - b3Box:getMin():getZ()) < 10 * GEO.EPS_SMALL then vtNz = -Z_AX() elseif abs( ptP:getZ() - b3Box:getMax():getZ()) < 10 * GEO.EPS_SMALL then vtNz = Z_AX() end local dNxDotV = vtNx * vtV local dNyDotV = vtNy * vtV local dNzDotV = vtNz * vtV if dNxDotV > dNyDotV and dNxDotV > dNzDotV then return vtNx elseif dNyDotV > dNzDotV and dNyDotV > dNxDotV then return vtNy else return vtNz end end --------------------------------------------------------------------- function BeamLib.GetFaceWithMostAdj( nSurfId) -- recupero il numero di facce local nFacCnt = EgtSurfTmFacetCount( nSurfId) -- recupero le normali delle facce local vvtN = {} for i = 1, nFacCnt do local _, vtN = EgtSurfTmFacetCenter( nSurfId, i - 1, GDB_ID.ROOT) vvtN[i] = vtN ; end -- adiacenze e sottosquadra delle facce local vAdj = {} local vUcut = {} for i = 1, nFacCnt do -- recupero le adiacenze del loop esterno local vFacAdj = EgtSurfTmFacetAdjacencies( nSurfId, i - 1)[1] -- le conto local nCount = 0 for j = 1, #vFacAdj do if vFacAdj[j] >= 0 then nCount = nCount + 1 end end vAdj[i] = nCount -- ne determino eventuale sottosquadra (- 3deg) local bUcut = false for j = 1, #vFacAdj do if vFacAdj[j] >= 0 then local vtN = vvtN[i] local vtN2 = vvtN[vFacAdj[j]+1] if vtN * vtN2 < -0.05 then bUcut = true end end end vUcut[i] = bUcut end -- se 4 facce tutte con adiacenza 2, allora è un tunnel if nFacCnt == 4 then if vAdj[1] == 2 and vAdj[2] == 2 and vAdj[3] == 2 and vAdj[4] == 2 then return -1, GEO.INFINITO end end -- recupero le facce non in sottosquadra e con il maggior numero di adiacenze local nFacInd = {} local nMaxAdj = 0 local nSupAdj = 0 for i = 1, nFacCnt do if not vUcut[i] then if vAdj[i] > nMaxAdj then nFacInd = {} nFacInd[1] = i - 1 nMaxAdj = vAdj[i] elseif vAdj[i] == nMaxAdj and nMaxAdj > 0 then table.insert( nFacInd, i - 1) end end if vAdj[i] > nSupAdj then nSupAdj = vAdj[i] end end -- verifico non ci sia una faccia in sottosquadra con adiacenza superiore if nSupAdj > nMaxAdj then return -2, GEO.INFINITO end -- premio la faccia con minore elevazione local nFacOpt, nFacOpt2 local dMinElev, dMinElev2 = GEO.INFINITO, GEO.INFINITO for i = 1, #nFacInd do local ptC, vtN = EgtSurfTmFacetCenter( nSurfId, nFacInd[i], GDB_ID.ROOT) local frOCS = Frame3d( ptC, vtN) ; local b3Box = EgtGetBBoxRef( nSurfId, GDB_BB.STANDARD, frOCS) if b3Box:getDimZ() < dMinElev then if dMinElev < dMinElev2 then nFacOpt2 = nFacOpt dMinElev2 = dMinElev end nFacOpt = nFacInd[i] dMinElev = b3Box:getDimZ() elseif b3Box:getDimZ() < dMinElev2 then nFacOpt2 = nFacInd[i] dMinElev2 = b3Box:getDimZ() end end return nFacOpt, dMinElev, nFacOpt2, dMinElev2 end --------------------------------------------------------------------- function BeamLib.GetFaceBox( nSurfId, nFacet) -- estraggo la faccia temporaneamente local FacId = EgtCopySurfTmFacet( nSurfId, nFacet, EgtGetParent( nSurfId)) if not FacId then return end -- determino l'ingombro in globale local b3Glob = EgtGetBBoxGlob( FacId, GDB_BB.STANDARD) -- cancello la faccia temporanea EgtErase( FacId) -- restituisco il bounding box return b3Glob end --------------------------------------------------------------------- function BeamLib.GetFaceHvRefDim( nSurfId, nFacet) -- recupero centro e normale della faccia local ptC, vtN = EgtSurfTmFacetCenter( nSurfId, nFacet, GDB_ID.ROOT) if not ptC or not vtN then return end -- riferimento tipo OCS della faccia (X orizz, Y max pendenza, Z normale) local frHV = Frame3d( ptC, vtN) if frHV:getVersY():getZ() < 0 then frHV:rotate( ptC, vtN, 180) end -- estraggo la faccia temporaneamente local FacId = EgtCopySurfTmFacet( nSurfId, nFacet, EgtGetParent( nSurfId)) -- determino l'ingombro in questo riferimento local b3HV = EgtGetBBoxRef( FacId, GDB_BB.STANDARD, frHV) -- cancello la faccia temporanea EgtErase( FacId) -- restituisco i valori calcolati return frHV, b3HV:getDimX(), b3HV:getDimY() end --------------------------------------------------------------------- function BeamLib.CalcLeadInOutGeom( 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) -- Versori di attacco e uscita local dCos1 = vtV1 * vtRef local dCos2 = vtV2 * vtRef local vtLi, vtLo if dCos1 > dCos2 then vtLi = vtV1 vtLo = vtV1 else vtLi = vtV2 vtLo = vtV2 end local bRight = ( vtX * vtLi > 0) -- Versori di attacco e uscita nel riferimento intrinseco al taglio local vtLiL = Vector3d( vtLi) ; vtLiL:toLoc( frFace) local vtLoL = Vector3d( vtLo) ; vtLoL:toLoc( frFace) -- Spostamento punti per effetto dell'extra di taglio if dCutExtra > GEO.EPS_SMALL then ptP1 = ptP1 + vtX * ( EgtIf( bRight, - dCutExtra, dCutExtra)) ptP2 = ptP2 + vtX * ( EgtIf( bRight, - dCutExtra, dCutExtra)) end -- Attacco local dLiTang = 10000 local dLiPerp = 10000 local bLiOk, _, vLiPar = EgtLineBoxInters( ptP1, vtLi, b3Box) if bLiOk and #vLiPar > 0 then -- con la prima faccia di uscita local dLen = vLiPar[#vLiPar] local ptInt = ptP1 + vtLi * dLen local vtFN = BeamLib.GetBoxFaceNorm( b3Box, ptInt, vtLi) EgtOutLog( 'LiFaceNorm=' .. tostring( vtFN), 3) local dAddLen = dRad * ( sqrt( 1 - ( vtN * vtFN) * ( vtN * vtFN)) - abs( vtX * vtFN)) / ( vtLi * vtFN) local dLiLen = dLen + dAddLen EgtOutLog( 'LeadIn Dist=' .. EgtNumToString( dLiLen), 3) dLiTang = - dLiLen * vtLiL:getY() dLiPerp = EgtIf( bRight, dLiLen, - dLiLen) * vtLiL:getX() -- verifico se miglioro calcolando con faccia successiva local b3Mod = BBox3d( b3Box) ; b3Mod:Add( ptInt + 1000 * vtFN) local bLiOk2, _, vLiPar2 = EgtLineBoxInters( ptP1, vtLi, b3Mod) if bLiOk2 and #vLiPar2 > 0 then local dLen2 = vLiPar2[#vLiPar2] local vtFN2 = BeamLib.GetBoxFaceNorm( b3Mod, ptP1 + vtLi * dLen2, vtLi) EgtOutLog( 'LiFaceNorm2=' .. tostring( vtFN2), 3) local dAddLen2 = dRad * ( sqrt( 1 - ( vtN * vtFN2) * ( vtN * vtFN2)) - abs( vtX * vtFN2)) / ( vtLi * vtFN2) local dLiLen2 = dLen2 + dAddLen2 EgtOutLog( 'LeadIn Dist2=' .. EgtNumToString( dLiLen2), 3) local dLiTang2 = - dLiLen2 * vtLiL:getY() local dLiPerp2 = EgtIf( bRight, dLiLen2, - dLiLen2) * vtLiL: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, vtLo, b3Box) if bLoOk and #vLoPar > 0 then -- con la prima faccia di uscita local dLen = vLoPar[#vLoPar] local ptInt = ptP2 + vtLo * dLen local vtFN = BeamLib.GetBoxFaceNorm( b3Box, ptInt, vtLo) EgtOutLog( 'LoFaceNorm=' .. tostring( vtFN), 3) local dAddLen = dRad * ( sqrt( 1 - ( vtN * vtFN) * ( vtN * vtFN)) - abs( vtX * vtFN)) / ( vtLo * vtFN) local dLoLen = dLen + dAddLen EgtOutLog( 'LeadOut Dist=' .. EgtNumToString( dLoLen), 3) dLoTang = dLoLen * vtLoL:getY() dLoPerp = EgtIf( bRight, dLoLen, - dLoLen) * vtLoL:getX() -- verifico se miglioro calcolando con faccia successiva local b3Mod = BBox3d( b3Box) ; b3Mod:Add( ptInt + 1000 * vtFN) local bLoOk2, _, vLoPar2 = EgtLineBoxInters( ptP2, vtLo, b3Mod) if bLoOk2 and #vLoPar2 > 0 then local dLen2 = vLoPar2[#vLoPar2] local vtFN2 = BeamLib.GetBoxFaceNorm( b3Mod, ptP2 + vtLo * dLen2, vtLo) EgtOutLog( 'LoFaceNorm2=' .. tostring( vtFN2), 3) local dAddLen2 = dRad * ( sqrt( 1 - ( vtN * vtFN2) * ( vtN * vtFN2)) - abs( vtX * vtFN2)) / ( vtLo * vtFN2) local dLoLen2 = dLen2 + dAddLen2 EgtOutLog( 'LeadOut Dist2=' .. EgtNumToString( dLoLen2), 3) local dLoTang2 = dLoLen2 * vtLoL:getY() local dLoPerp2 = EgtIf( bRight, dLoLen2, - dLoLen2) * vtLoL:getX() if dLoLen2 < dLoLen then dLoTang = dLoTang2 dLoPerp = dLoPerp2 end end end return dLiTang, dLiPerp, dLoTang, dLoPerp end --------------------------------------------------------------------- function BeamLib.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 di taglio if dCutExtra > GEO.EPS_SMALL then ptP1 = ptP1 - vtX * dCutExtra ptP2 = ptP2 - vtX * dCutExtra end -- Attacco local dLiTang = 10000 local dLiPerp = 0 local bLiOk, _, vLiPar = EgtLineBoxInters( ptP1, vtTg, b3Box) if bLiOk and #vLiPar > 0 then local dLen = vLiPar[1] local ptInt = ptP1 + vtTg * dLen local vtFN = BeamLib.GetBoxFaceNorm( b3Box, 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( b3Box) ; b3Mod:Add( ptInt + 1000 * vtFN) local bLiOk2, _, vLiPar2 = EgtLineBoxInters( ptP1, vtTg, b3Mod) if bLiOk2 and #vLiPar2 > 0 then local dLen2 = vLiPar2[1] local vtFN2 = BeamLib.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, b3Box) if bLoOk and #vLoPar > 0 then local dLen = vLoPar[#vLoPar] local ptInt = ptP2 + vtTg * dLen local vtFN = BeamLib.GetBoxFaceNorm( b3Box, 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( b3Box) ; b3Mod:Add( ptInt + 1000 * vtFN) local bLoOk2, _, vLoPar2 = EgtLineBoxInters( ptP2, vtTg, b3Mod) if bLoOk2 and #vLoPar2 > 0 then local dLen2 = vLoPar2[#vLoPar2] local vtFN2 = BeamLib.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 --------------------------------------------------------------------- function BeamLib.MakeOneFaceBySaw( nSurfId, nFacet, sCutting, dSawDiam, nOrthoOpposite, dVzLimDwnUp, dCutExtra, dCutSic, dCutOffset, dAccStart, sNotes, b3Raw) -- dati della faccia local ptC, vtN = EgtSurfTmFacetCenter( nSurfId, nFacet, GDB_ID.ROOT) -- linea o bilinea di lavorazione local ptP1, ptPm, ptP2, vtV1, vtV2, dLen, dWidth = EgtSurfTmFacetOppositeSide( nSurfId, nFacet, BeamLib.GetVersRef( nOrthoOpposite), GDB_ID.ROOT) if dLen < 1.1 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 = ( ptP2:getZ() < ptP1:getZ() - 100 * GEO.EPS_SMALL) 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 corta if ( ( ptPm - ptP1) - ( ptPm - ptP1) * vtTg * vtTg):len() > 100 * GEO.EPS_SMALL then local dDist1 = dist( ptP1, ptPm) local dDist2 = dist( ptP2, ptPm) if dDist1 >= dDist2 then ptP2 = Point3d( ptPm) dAllEnd = - dDist2 - 10 * GEO.EPS_SMALL else ptP1 = Point3d( ptPm) dAllStart = - dDist1 - 10 * GEO.EPS_SMALL end vtTg = ptP2 - ptP1 ; vtTg:normalize() end -- verifico se lavorazione con lama sotto e testa sopra if not dVzLimDwnUp then dVzLimDwnUp = -0.5 end local bDownUp = ( vtN:getZ() < dVzLimDwnUp) local nFaceUse = nOrthoOpposite if bDownUp then nFaceUse = BeamLib.GetOrtupOpposite( nOrthoOpposite) end local bWsRight = ( bInvert ~= bDownUp) local nWorkSide = EgtIf( bWsRight, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT) -- Versore di riferimento local vtRef = BeamLib.GetVersRef( nOrthoOpposite) vtRef = vtRef - vtRef * vtN * vtN ; vtRef:normalize() -- 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 dLiTang, dLiPerp, dLoTang, dLoPerp if ( vtV1:getZ() > -0.1 or vtV2:getZ() > -0.1) and ( abs( vtV1:getY()) > 0.707 or abs( vtV2:getY()) > 0.707 or vtN:getZ() < 0.95) then dLiTang, dLiPerp, dLoTang, dLoPerp = BeamLib.CalcLeadInOutGeom( ptP1, ptP2, vtV1, vtV2, vtN, dSawDiam/2, vtRef, dCutExtra, b3Box) else dLiTang, dLiPerp, dLoTang, dLoPerp = BeamLib.CalcLeadInOutTangGeom( ptP1, ptP2, vtN, dSawDiam/2, vtRef, dCutExtra, b3Box) end -- posizione braccio EgtOutLog( 'vtN=' .. tostring( vtN) .. ' vtRef=' .. tostring( vtRef) .. ' vtOut=' .. tostring( vtOut) .. ' vtAux=' .. tostring( vtAux), 3) local nSCC = MCH_SCC.NONE if abs( vtAux:getX()) > abs( vtAux:getY()) then nSCC = EgtIf( ( vtAux:getX() > 0), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM) else nSCC = EgtIf( ( vtAux:getY() > 0), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM) 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) 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) -- eventuali note if sNotes and #sNotes > 0 then EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) end -- eseguo if not EgtApplyMachining( true, false) then local _, sErr = EgtGetLastMachMgrError() EgtSetOperationMode( nMchFId, false) return false, sErr end return true, sName end ------------------------------------------------------------------------------------------------------------- function BeamLib.UpdateHCING( nRawId, dHCI) local dOldHCI = EgtGetInfo( nRawId, 'HCING', 'd') if not dOldHCI or dHCI > dOldHCI then EgtSetInfo( nRawId, 'HCING', dHCI) end end ------------------------------------------------------------------------------------------------------------- function BeamLib.UpdateTCING( nRawId, dTCI) local dOldTCI = EgtGetInfo( nRawId, 'TCING', 'd') if not dOldTCI or dTCI > dOldTCI then EgtSetInfo( nRawId, 'TCING', dTCI) end end ------------------------------------------------------------------------------------------------------------- return BeamLib