d76ecbc9f6
- in BeamExec -> CollectFeatures si salva l'indice della Proc nel vProc - in FeatureLib aggiunta funzione GetFeatureMaxNotClampableLengths - correzioni e migliorie GetFeatureMaxNotClampableLengths
523 lines
22 KiB
Lua
523 lines
22 KiB
Lua
-- FeatureLib.lua by Egalware s.r.l. 2024/04/02
|
|
-- Libreria lettura o calcolo dati e proprietà della feature
|
|
-- 2024/04/02 PRIMA VERSIONE CALCOLO LAVORAZIONI CON STRATEGIE
|
|
|
|
-- Tabella per definizione modulo
|
|
local FeatureLib = {}
|
|
|
|
-- Carico i dati globali
|
|
local BeamData = require( 'BeamData')
|
|
|
|
-- carico librerie
|
|
local BeamLib = require( 'BeamLib')
|
|
local FaceData = require( 'FaceData')
|
|
local ID = require( 'Identity')
|
|
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- recupero topologia della feature
|
|
function FeatureLib.NeedTopologyFeature( Proc)
|
|
-- features tipo taglio
|
|
if ID.IsCut( Proc) then
|
|
return true
|
|
elseif ID.IsHeadCut( Proc) then
|
|
return true
|
|
elseif ID.IsTailCut( Proc) then
|
|
return true
|
|
elseif ID.IsDoubleCut( Proc) then
|
|
return true
|
|
elseif ID.IsSawCut( Proc) then
|
|
return true
|
|
-- features tipo taglio longitudinale
|
|
elseif ID.IsLongitudinalCut( Proc) then
|
|
return true
|
|
elseif ID.IsDoubleLongitudinalCut( Proc) then
|
|
return true
|
|
elseif ID.IsChamfer( Proc) then
|
|
return true
|
|
-- features tipo LapJoint
|
|
elseif ID.IsSlot( Proc) then
|
|
return true
|
|
elseif ID.IsFrontSlot( Proc) then
|
|
return true
|
|
elseif ID.IsRidgeLap( Proc) then
|
|
return true
|
|
elseif ID.IsLapJoint( Proc) then
|
|
return true
|
|
elseif ID.IsNotchRabbet( Proc) then
|
|
return true
|
|
elseif ID.IsNotch( Proc) then
|
|
return true
|
|
elseif ID.IsPocket( Proc) then
|
|
return true
|
|
-- calcolo topologia SOLO se non raggiata
|
|
-- TODO oppure riconoscerla come feature speciale; valutare se controllare il numero di facce è un metodo efficace
|
|
elseif ID.IsMortise( Proc) and Proc.nFct < 6 then
|
|
return true
|
|
-- calcolo topologia SOLO se non raggiata
|
|
-- TODO oppure riconoscerla come feature speciale; valutare se controllare il numero di facce è un metodo efficace
|
|
elseif ID.IsFrontMortise( Proc) and Proc.nFct < 6 then
|
|
return true
|
|
end
|
|
|
|
-- se feature non tra quelle sopra, riconoscimento topologico non necessario
|
|
return false
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- restituisce true se Proc ha tutti gli angoli concavi (bAllConcave) e, nei casi in cui ha senso, se questi sono esattamente 90 deg (bAllRight)
|
|
local function AreAllAnglesConcaveOrRight( vAdj)
|
|
-- se la feature ha una sola faccia, esco subito
|
|
if #vAdj <= 1 then
|
|
return
|
|
end
|
|
|
|
local bAllConcave, bAllRight = true, true
|
|
|
|
local nFct = #( vAdj or {})
|
|
for i = 1, nFct do
|
|
for j = 1, nFct do
|
|
-- se trovo un angolo convesso restituisco falso e esco subito
|
|
if vAdj[i][j] and vAdj[i][j] > 0 then
|
|
bAllConcave = false
|
|
bAllRight = false
|
|
break
|
|
elseif vAdj[i][j] and vAdj[i][j] ~= 0 and vAdj[i][j] + 90 > 500 * GEO.EPS_ANG_SMALL then
|
|
bAllRight = false
|
|
end
|
|
end
|
|
end
|
|
|
|
-- se 1 faccia oppure 2 facce con angolo convesso non ha senso ritornare valori per bAllRight
|
|
if nFct < 2 or ( nFct == 2 and vAdj[1][2] > 0) then
|
|
return bAllConcave
|
|
else
|
|
return bAllConcave, bAllRight
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- restituisce true se almeno una delle dimensioni della feature è maggiore o uguale ad una delle dimensioni principali del pezzo (tolleranza 1 mm)
|
|
local function IsAnyDimensionLongAsPart( Proc, Part)
|
|
local bResult = false
|
|
|
|
if Proc.b3Box:getDimX() > Part.b3Part:getDimX() - 1000 * GEO.EPS_SMALL or
|
|
Proc.b3Box:getDimY() > Part.b3Part:getDimY() - 1000 * GEO.EPS_SMALL or
|
|
Proc.b3Box:getDimZ() > Part.b3Part:getDimZ() - 1000 * GEO.EPS_SMALL then
|
|
bResult = true
|
|
end
|
|
|
|
return bResult
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- restituisce vero se la feature con box b3Proc taglia l'intera sezione della barra, rappresentata dalle sue dimensioni W e H
|
|
local function IsFeatureCuttingEntireSection( b3Proc, Part)
|
|
return ( b3Proc:getDimY() > ( Part.b3Raw:getDimY() - 500 * GEO.EPS_SMALL) and b3Proc:getDimZ() > ( Part.b3Raw:getDimZ() - 500 * GEO.EPS_SMALL))
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- restituisce vero se la feature con box b3Proc taglia l'intera lunghezza della barra, rappresentata dalle sue dimensioni W e L oppure H e L
|
|
local function IsFeatureCuttingEntireLength( b3Proc, Part)
|
|
return ( ( b3Proc:getDimY() > ( Part.b3Raw:getDimY() - 500 * GEO.EPS_SMALL) and b3Proc:getDimX() > ( Part.b3Raw:getDimX() - 500 * GEO.EPS_SMALL)) or
|
|
( b3Proc:getDimZ() > ( Part.b3Raw:getDimZ() - 500 * GEO.EPS_SMALL) and b3Proc:getDimX() > ( Part.b3Raw:getDimX() - 500 * GEO.EPS_SMALL)))
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- restituisce una stringa con il nome esteso della topologia della feature
|
|
-- *famiglia - numero di facce - passante*
|
|
local function GetTopologyName( sFamily, nNumberOfFaces, bIsThrough)
|
|
return sFamily .. '-' .. tostring( nNumberOfFaces) .. '-' .. EgtIf( bIsThrough, 'Through', 'Blind')
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- recupera topologia feature
|
|
function FeatureLib.ClassifyTopology( Proc, Part)
|
|
local FeatureTopology = {}
|
|
|
|
if not Proc.AffectedFaces then Proc.AffectedFaces = BeamLib.GetAffectedFaces( Proc, Part) end
|
|
|
|
local bIsFeatureCuttingEntireSection = IsFeatureCuttingEntireSection( Proc.b3Box, Part)
|
|
local bIsFeatureCuttingEntireLength = IsFeatureCuttingEntireLength( Proc.b3Box, Part)
|
|
local bIsAnyDimensionLongAsPart = IsAnyDimensionLongAsPart( Proc, Part)
|
|
local vAdj = Proc.AdjacencyMatrix
|
|
local bAllAnglesConcave, bAllRightAngles = AreAllAnglesConcaveOrRight( vAdj)
|
|
local vTriangularFaces = FaceData.GetTriangularFaces( Proc)
|
|
local vFacesByAdjNumber = FaceData.GetFacesByAdjacencyNumber( Proc)
|
|
|
|
local sFamily
|
|
local bIsThrough
|
|
if Proc.nFct == 1 and ( bIsFeatureCuttingEntireSection or bIsFeatureCuttingEntireLength) then
|
|
sFamily = 'Cut'
|
|
bIsThrough = true
|
|
elseif Proc.nFct == 1 then
|
|
sFamily = 'Bevel'
|
|
bIsThrough = true
|
|
elseif Proc.nFct == 2 and bAllAnglesConcave and #vTriangularFaces == 1 then
|
|
sFamily = 'Bevel'
|
|
bIsThrough = false
|
|
elseif Proc.nFct == 2 and bAllAnglesConcave and ( Proc.AffectedFaces.bLeft or Proc.AffectedFaces.bRight) and ( Proc.AffectedFaces.bFront or Proc.AffectedFaces.bBack) then
|
|
sFamily = 'Rabbet'
|
|
bIsThrough = true
|
|
elseif Proc.nFct == 2 and bAllAnglesConcave then
|
|
sFamily = 'VGroove'
|
|
bIsThrough = true
|
|
elseif Proc.nFct == 2 and not bAllAnglesConcave and bIsAnyDimensionLongAsPart then
|
|
sFamily = 'DoubleBevel'
|
|
bIsThrough = true
|
|
elseif Proc.nFct == 3 and bAllAnglesConcave and #vFacesByAdjNumber[2] == 1 and #vTriangularFaces == 2 then
|
|
sFamily = 'Bevel'
|
|
bIsThrough = false
|
|
elseif Proc.nFct == 3 and bAllAnglesConcave and #vFacesByAdjNumber[2] == 1 and bIsAnyDimensionLongAsPart then
|
|
sFamily = 'Groove'
|
|
bIsThrough = true
|
|
elseif Proc.nFct == 3 and bAllAnglesConcave and #vFacesByAdjNumber[2] == 3 then
|
|
sFamily = 'Groove'
|
|
bIsThrough = false
|
|
elseif Proc.nFct == 4 and #vFacesByAdjNumber[2] == 4 and #vTriangularFaces == 2 then
|
|
sFamily = 'DoubleBevel'
|
|
bIsThrough = false
|
|
elseif Proc.nFct == 4 and bAllAnglesConcave and #vFacesByAdjNumber[3] == 2 then
|
|
sFamily = 'Groove'
|
|
bIsThrough = false
|
|
elseif Proc.nFct == 4 and bAllAnglesConcave and #vFacesByAdjNumber[2] == 4 and bIsAnyDimensionLongAsPart then
|
|
sFamily = 'Tunnel'
|
|
bIsThrough = true
|
|
elseif Proc.nFct >= 4 and #vFacesByAdjNumber[1] == 2 and bIsAnyDimensionLongAsPart then
|
|
sFamily = 'Strip'
|
|
bIsThrough = true
|
|
elseif Proc.nFct == 5 and bAllAnglesConcave and #vFacesByAdjNumber[4] == 1 then
|
|
sFamily = 'Pocket'
|
|
bIsThrough = false
|
|
elseif Proc.nFct == 6 and #vFacesByAdjNumber[2] == 4 and #vFacesByAdjNumber[3] == 2 and #vTriangularFaces == 4 then
|
|
sFamily = 'DoubleBevel'
|
|
bIsThrough = false
|
|
end
|
|
|
|
if sFamily then
|
|
FeatureTopology.sFamily = sFamily
|
|
FeatureTopology.bIsThrough = bIsThrough
|
|
FeatureTopology.bAllRightAngles = bAllRightAngles
|
|
FeatureTopology.sName = GetTopologyName( sFamily, Proc.nFct, bIsThrough)
|
|
FeatureTopology.AdjacencyMatrix = vAdj
|
|
-- feature che necessita di essere catalogata, ma non si capisce come
|
|
else
|
|
FeatureTopology.sFamily = 'NOT_IMPLEMENTED'
|
|
FeatureTopology.sName = FeatureTopology.sFamily
|
|
end
|
|
|
|
return FeatureTopology
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- Recupero dati foro e adattamento se speciale
|
|
function FeatureLib.GetDrillingData( Proc)
|
|
local AuxId = EgtGetInfo( Proc.id, 'AUXID', 'i')
|
|
|
|
-- verifico se foro da adattare
|
|
if EgtExistsInfo( Proc.id, 'DiamUser') then
|
|
if AuxId then AuxId = AuxId + Proc.id end
|
|
if AuxId and EgtGetType( AuxId) == GDB_TY.CRV_ARC and BeamData.USER_HOLE_DIAM and BeamData.USER_HOLE_DIAM > 1 then
|
|
EgtModifyArcRadius( AuxId, BeamData.USER_HOLE_DIAM / 2)
|
|
end
|
|
end
|
|
|
|
local dDiam = EgtGetInfo( Proc.id, 'P12', 'd') or 0
|
|
local dLen = abs( EgtCurveThickness( Proc.id + AuxId)) or 0
|
|
local nFcs = EgtGetInfo( Proc.id, 'FCS', 'i') or 0
|
|
local nFce = EgtGetInfo( Proc.id, 'FCE', 'i') or 0
|
|
|
|
return dDiam, dLen, nFcs, nFce
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- funzione che restituisce indice di completamento in base alla percentuale di volume lavorato
|
|
function FeatureLib.GetFeatureCompletionIndex( dCompletionPercentage)
|
|
-- indice di completamento
|
|
local nCompletionIndex = 0
|
|
|
|
-- nullo
|
|
if dCompletionPercentage < 5 then
|
|
nCompletionIndex = 0
|
|
-- Low
|
|
elseif dCompletionPercentage < 50 then
|
|
nCompletionIndex = 1
|
|
-- Medium
|
|
elseif dCompletionPercentage < 80 then
|
|
nCompletionIndex = 2
|
|
-- High / Complete
|
|
else
|
|
nCompletionIndex = 5
|
|
end
|
|
|
|
return nCompletionIndex
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- funzione che restituisce qualità della lavorazione in base agli utensili utilizzati
|
|
function FeatureLib.GetFeatureQuality( sTypeTools)
|
|
local nQuality = 5
|
|
local TypeTools = EgtSplitString( sTypeTools)
|
|
|
|
-- indice in base a utensile
|
|
for i=1, #TypeTools do
|
|
if TypeTools[i] == 'Blade' then
|
|
nQuality = min( nQuality, 5)
|
|
elseif TypeTools[i] == 'Mill' then
|
|
nQuality = min( nQuality, 4)
|
|
elseif TypeTools[i] == 'Chainsaw' then
|
|
nQuality = min( nQuality, 2)
|
|
else
|
|
nQuality = min( nQuality, 1)
|
|
end
|
|
end
|
|
-- se si utilizzano più utensili si perde in qualità
|
|
if #TypeTools > 1 then
|
|
nQuality = max( nQuality - 1, 0.5)
|
|
end
|
|
|
|
return nQuality
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- funzione che calcola il 'CompositeRating' di ogni strategia
|
|
function FeatureLib.CalculateCompositeRating( StrategyResult)
|
|
-- se ho tutti i dati che mi servono calcolo il rating della strategia applicato alla feature
|
|
if StrategyResult and StrategyResult.nQuality and StrategyResult.nCompletionIndex and StrategyResult.dMRR then
|
|
StrategyResult.dCompositeRating = ceil( StrategyResult.nQuality * StrategyResult.nCompletionIndex * StrategyResult.dMRR)
|
|
else
|
|
StrategyResult.dCompositeRating = 0
|
|
end
|
|
|
|
return StrategyResult
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
function FeatureLib.IsMachiningLong( dMachiningLengthOnX, Part, OptionalParameters)
|
|
local bIsMachiningLong
|
|
|
|
-- parametri opzionali
|
|
if not OptionalParameters then
|
|
OptionalParameters = {}
|
|
end
|
|
local dMaxSegmentLength = OptionalParameters.dMaxSegmentLength or BeamData.LONGCUT_MAXLEN
|
|
|
|
bIsMachiningLong = ( dMachiningLengthOnX > dMaxSegmentLength + 10 * GEO.EPS_SMALL)
|
|
or ( dMachiningLengthOnX > 0.7 * Part.b3Part:getDimX() + 10 * GEO.EPS_SMALL)
|
|
|
|
return bIsMachiningLong
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
function FeatureLib.GetFeatureSplittingPoints( Proc, Part, OptionalParameters)
|
|
local FeatureSplittingPoints = {}
|
|
local bFeatureStartsOnEdgeLeft = false
|
|
local bFeatureStartsOnEdgeRight = false
|
|
local dSplitXLeft = Proc.b3Box:getMin():getX()
|
|
local dSplitXRight = Proc.b3Box:getMax():getX()
|
|
local dFeatureCentralLength = Proc.b3Box:getDimX()
|
|
|
|
-- parametri opzionali
|
|
if not OptionalParameters then
|
|
OptionalParameters = {}
|
|
end
|
|
local dMaxSegmentLength = OptionalParameters.dMaxSegmentLength or BeamData.LONGCUT_MAXLEN
|
|
local dMaxSegmentLengthOnEdges = OptionalParameters.dMaxSegmentLengthOnEdges or BeamData.LONGCUT_ENDLEN
|
|
local dMinSegmentLength = OptionalParameters.dMinSegmentLength or dMaxSegmentLengthOnEdges / 2
|
|
local dToolOverlapBetweenSegments = OptionalParameters.dToolOverlapBetweenSegments or BeamData.MILL_OVERLAP
|
|
|
|
-- verifica spezzatura necessaria
|
|
if not FeatureLib.IsMachiningLong( Proc.b3Box:getDimX(), Part) then
|
|
return {}
|
|
end
|
|
|
|
-- verifica se necessari spezzoni differenti sugli estremi
|
|
if Proc.b3Box:getMin():getX() < Part.b3Part:getMin():getX() + dMaxSegmentLengthOnEdges - 10 * GEO.EPS_SMALL then
|
|
bFeatureStartsOnEdgeLeft = true
|
|
end
|
|
if Proc.b3Box:getMax():getX() > Part.b3Part:getMax():getX() - dMaxSegmentLengthOnEdges + 10 * GEO.EPS_SMALL then
|
|
bFeatureStartsOnEdgeRight = true
|
|
end
|
|
|
|
-- calcolo punto estremo sinistro
|
|
local ptSplitXLeft
|
|
if bFeatureStartsOnEdgeLeft then
|
|
-- decido punto spezzatura verso la coda
|
|
if Proc.b3Box:getDimX() > dMaxSegmentLengthOnEdges * 2 then
|
|
dSplitXLeft = max( Part.b3Part:getMin():getX() + dMaxSegmentLengthOnEdges, Proc.b3Box:getMin():getX() + dMinSegmentLength)
|
|
else
|
|
-- se pezzo abbastanza piccolo, spezzo in mezzo al 'pezzo + grezzo restante'
|
|
if Part.dRestLength + Part.b3Part:getDimX() < BeamData.dMinRaw * 1.5 then
|
|
dSplitXLeft = Part.b3Part:getMax():getX() - ( ( Part.dRestLength + Part.b3Part:getDimX()) / 2)
|
|
else
|
|
dSplitXLeft = max( Proc.b3Box:getMin():getX() + ( BeamData.dMinRaw)/2 + 150, Part.b3Part:getMax():getX() - dMaxSegmentLengthOnEdges)
|
|
end
|
|
end
|
|
dFeatureCentralLength = abs( dSplitXRight - dSplitXLeft)
|
|
ptSplitXLeft = Point3d( dSplitXLeft, 0, 0)
|
|
end
|
|
|
|
-- calcolo punto estremo destro
|
|
local ptSplitXRight
|
|
if bFeatureStartsOnEdgeRight then
|
|
dSplitXRight = min( ( Proc.b3Box:getMax():getX() - dMinSegmentLength), Part.b3Part:getMax():getX() - dMaxSegmentLengthOnEdges)
|
|
if dSplitXRight - dSplitXLeft < 500 * GEO.EPS_SMALL then
|
|
dSplitXRight = dSplitXLeft - dToolOverlapBetweenSegments
|
|
dFeatureCentralLength = 0
|
|
else
|
|
dFeatureCentralLength = dSplitXRight - dSplitXLeft
|
|
end
|
|
ptSplitXRight = Point3d( dSplitXRight, 0, 0)
|
|
end
|
|
|
|
-- aggiungo eventuale punto estremo destro
|
|
if bFeatureStartsOnEdgeRight then
|
|
table.insert( FeatureSplittingPoints, ptSplitXRight)
|
|
end
|
|
|
|
-- aggiungo punti centrali della feature
|
|
if dFeatureCentralLength > 0 then
|
|
local nSplitParts = max( ceil( dFeatureCentralLength / dMaxSegmentLength + 10 * GEO.EPS_SMALL), 1)
|
|
local dSplitPartsLen = dFeatureCentralLength / nSplitParts
|
|
for i = 1, ( nSplitParts - 1) do
|
|
local ptOn
|
|
local dCurrentPointX = dSplitXRight - i * dSplitPartsLen
|
|
ptOn = Point3d( dCurrentPointX, 0, 0)
|
|
table.insert( FeatureSplittingPoints, ptOn)
|
|
end
|
|
end
|
|
|
|
-- aggiungo eventuale punto estemo sinistro
|
|
if bFeatureStartsOnEdgeLeft then
|
|
table.insert( FeatureSplittingPoints, ptSplitXLeft)
|
|
end
|
|
|
|
return FeatureSplittingPoints
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
function FeatureLib.GetAdditionalInfo( Proc, Part)
|
|
-- se foro calcolo altri dati
|
|
if ID.IsDrilling( Proc) then
|
|
-- assegno diametro e facce di ingresso e uscita (dati tabelle sempre per riferimento)
|
|
Proc.dDiam, Proc.dLen, Proc.nFcs, Proc.nFce = FeatureLib.GetDrillingData( Proc)
|
|
end
|
|
return Proc
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
function FeatureLib.GetFeatureVolume( Proc, Part)
|
|
local dProcVolume = 0
|
|
|
|
local nAddGrpId = BeamLib.GetAddGroup( Proc.idPart)
|
|
if not nAddGrpId then
|
|
-- TODO gestire meglio questo errore. Non conviene creare e verificare all'inizio se il gruppo esiste?
|
|
EgtOutLog( 'Error : missing AddGroup')
|
|
return 0
|
|
end
|
|
|
|
local idProcCopy = EgtCopyGlob( Proc.id, nAddGrpId) or GDB_ID.NULL
|
|
local b3PartCopy = BBox3d( Part.b3Part)
|
|
b3PartCopy:expand( -100 * GEO.EPS_SMALL)
|
|
local idPartCopy = EgtSurfTmBBox( nAddGrpId, b3PartCopy , false, GDB_RT.GLOB)
|
|
|
|
EgtSurfTmSubtract( idPartCopy, idProcCopy)
|
|
dProcVolume = EgtSurfVolume( idPartCopy)
|
|
|
|
EgtErase( { idProcCopy, idPartCopy})
|
|
|
|
return dProcVolume
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- TODO funzione copiata direttamente da automatismo vecchio, da migliorare / completare
|
|
function FeatureLib.CalculateFeatureNotClampableLengths( Proc, Part)
|
|
local NotClampableLength = {}
|
|
|
|
-- verifico siano una o due facce
|
|
if Proc.nFct > 2 then return end
|
|
|
|
-- eventuale segnalazione ingombro di testa o coda
|
|
local dMinHIng = min( 0.5 * BeamData.VICE_MINH, 0.5 * Part.b3Raw:getDimZ())
|
|
local dMinZ = max( BeamData.MIN_HEIGHT, 0.35 * Part.b3Raw:getDimZ())
|
|
-- calcolo punto massimo in Z fino a dove considerare il pinzaggio. Minimo tra pinzaggio massimo e altezza pezzo
|
|
local dMaxHZ = Part.b3Raw:getMin():getZ() + min( BeamData.VICE_MAXH or BeamData.MAX_HEIGHT, Part.b3Raw:getDimZ())
|
|
-- punto massimo in Z considerando anche la Z della feature
|
|
local dMaxHZFeat = min( dMaxHZ, Proc.b3Box:getMax():getZ())
|
|
-- dimensione Z del pinzaggio (differenza massima Z pinzabile e box feature)
|
|
local dDeltaZClamp = ( ( dMaxHZ - Part.b3Raw:getMin():getZ()) - max( 0, dMaxHZFeat - Proc.b3Box:getMin():getZ()))
|
|
-- se pinzaggio minimo è come il massimo (oppure come l'altezza massima del pezzo) significa che è verticale
|
|
local bIsVertClamps = BeamData.VICE_MINH > BeamData.MAX_HEIGHT - 100 * GEO.EPS_SMALL
|
|
|
|
-- condizioni per limitare pinzaggio testa/coda
|
|
local bUpdateIng = true
|
|
-- se dimensione del box della feature maggiore di metà pinzaggio minimo o metà spessore pezzo
|
|
bUpdateIng = bUpdateIng and Proc.b3Box:getDimZ() > dMinHIng
|
|
-- se la feature si trova più in basso del minimo pinzabile in Z o il 35% dello spessore pezzo
|
|
bUpdateIng = bUpdateIng and Proc.b3Box:getMin():getZ() < Part.b3Raw:getMin():getZ() + dMinZ
|
|
-- se feature è al di sotto del pinzaggio massimo
|
|
bUpdateIng = bUpdateIng and Proc.b3Box:getMin():getZ() < dMaxHZ
|
|
-- se ho le morse verticali, o se la feature è in centro o verso alto, controllo se non prendo abbastanza.
|
|
if bIsVertClamps or ( Proc.b3Box:getMin():getZ() - Part.b3Raw:getMin():getZ()) > BeamData.MIN_HEIGHT then
|
|
bUpdateIng = bUpdateIng and dDeltaZClamp < BeamData.VICE_MINH
|
|
end
|
|
|
|
local dNotClampableLengthHead = 0
|
|
local dNotClampableLengthTail = 0
|
|
|
|
if bUpdateIng then
|
|
if Proc.AffectedFaces.bRight then
|
|
local dOffs = Part.b3Part:getMax():getX() - Proc.b3Box:getMin():getX()
|
|
-- se pinze a 45° e pinza abbastanza materiale, compenso comunque, ma solo inclinazione morse
|
|
if not bIsVertClamps and dDeltaZClamp > BeamData.VICE_MINH and BeamData.VICE_MAXH then
|
|
dOffs = min( dOffs, BeamData.VICE_MAXH - BeamData.VICE_MINH)
|
|
end
|
|
dNotClampableLengthHead = dOffs
|
|
elseif Proc.AffectedFaces.bLeft then
|
|
local dOffs = Proc.b3Box:getMax():getX() - Part.b3Part:getMin():getX()
|
|
-- se pinze a 45° e pinza abbastanza materiale, compenso comunque, ma solo inclinazione morse
|
|
if not bIsVertClamps and dDeltaZClamp > BeamData.VICE_MINH and BeamData.VICE_MAXH then
|
|
dOffs = min( dOffs, BeamData.VICE_MAXH - BeamData.VICE_MINH)
|
|
end
|
|
dNotClampableLengthTail = dOffs
|
|
elseif Proc.b3Box:getCenter():getX() > Part.b3Part:getCenter():getX() then
|
|
local dOffs = Part.b3Part:getMax():getX() - Proc.b3Box:getMin():getX()
|
|
local dDist = Part.b3Part:getMax():getX() - Proc.b3Box:getMax():getX()
|
|
-- se pinze a 45° e pinza abbastanza materiale, compenso comunque, ma solo inclinazione morse
|
|
if not bIsVertClamps and dDeltaZClamp > BeamData.VICE_MINH and BeamData.VICE_MAXH then
|
|
dOffs = min( dOffs, BeamData.VICE_MAXH - BeamData.VICE_MINH)
|
|
end
|
|
-- dDist serve??
|
|
dNotClampableLengthHead = dOffs
|
|
end
|
|
end
|
|
|
|
NotClampableLength.dNotClampableLengthHead = dNotClampableLengthHead
|
|
NotClampableLength.dNotClampableLengthTail = dNotClampableLengthTail
|
|
|
|
return NotClampableLength
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
function FeatureLib.GetFeatureMaxNotClampableLengths( Proc, Part)
|
|
local nPartIndex = Part.nIndexInParts
|
|
local nProcIndex = Proc.nIndexInVProc
|
|
local Rotations = PROCESSINGS[nPartIndex].Rotation
|
|
|
|
local dMaxOnHead = 0
|
|
local dMaxOnTail = 0
|
|
for i = 1, #Part.CombinationList do
|
|
for j = 1, 4 do
|
|
-- controllo che la rotazione sia attiva
|
|
if string.sub( Part.CombinationList[i].sBitIndexCombination, j, j) == '1' then
|
|
dMaxOnHead = max( Rotations[j][nProcIndex].NotClampableLength.dNotClampableLengthHead, dMaxOnHead)
|
|
dMaxOnTail = max( Rotations[j][nProcIndex].NotClampableLength.dNotClampableLengthTail, dMaxOnTail)
|
|
end
|
|
end
|
|
end
|
|
|
|
return dMaxOnHead, dMaxOnTail
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
return FeatureLib |