Prima versione funzionante mortasa passante

This commit is contained in:
andrea.villa
2025-03-28 15:25:30 +01:00
parent 68a6c7d897
commit 1c1d0f7b96
3 changed files with 232 additions and 53 deletions
+64
View File
@@ -117,6 +117,70 @@ function BeamLib.AddPhaseWithRawParts( nRawId, OriXR, PosXR, dDeltaSucc)
end
end
---------------------------------------------------------------------
function BeamLib.SetOpenSide( nPathInt, b3Solid)
-- fondo tra loro le curve compatibili
EgtMergeCurvesInCurveCompo( nPathInt)
-- vettore indici lati aperti
local vOpen = {}
-- ciclo sulle curve elementari della composita
local _, nNumEnt = EgtCurveDomain( nPathInt)
for i = 0, nNumEnt - 1 do
-- se segmento di retta
if EgtCurveCompoRadius( nPathInt, i) == -1 then
-- verifico se giace in uno dei piani limite del pezzo quindi se è un lato aperto
local ptIni = EgtUP( nPathInt, i, GDB_RT.GLOB)
local ptFin = EgtUP( nPathInt, i + 1, GDB_RT.GLOB)
if ( abs( ptIni:getX() - b3Solid:getMax():getX()) < 100 * GEO.EPS_SMALL and abs( ptFin:getX() - b3Solid:getMax():getX()) < 100 * GEO.EPS_SMALL) or
( abs( ptIni:getX() - b3Solid:getMin():getX()) < 100 * GEO.EPS_SMALL and abs( ptFin:getX() - b3Solid:getMin():getX()) < 100 * GEO.EPS_SMALL) or
( abs( ptIni:getY() - b3Solid:getMax():getY()) < 100 * GEO.EPS_SMALL and abs( ptFin:getY() - b3Solid:getMax():getY()) < 100 * GEO.EPS_SMALL) or
( abs( ptIni:getY() - b3Solid:getMin():getY()) < 100 * GEO.EPS_SMALL and abs( ptFin:getY() - b3Solid:getMin():getY()) < 100 * GEO.EPS_SMALL) or
( abs( ptIni:getZ() - b3Solid:getMax():getZ()) < 100 * GEO.EPS_SMALL and abs( ptFin:getZ() - b3Solid:getMax():getZ()) < 100 * GEO.EPS_SMALL) or
( abs( ptIni:getZ() - b3Solid:getMin():getZ()) < 100 * GEO.EPS_SMALL and abs( ptFin:getZ() - b3Solid:getMin():getZ()) < 100 * GEO.EPS_SMALL) then
-- aggiorno il vettore dei lati aperti
table.insert( vOpen, i)
end
end
end
-- assegno gli indici dei lati aperti
EgtSetInfo( nPathInt, 'OPEN', vOpen)
return true
end
-------------------------------------------------------------------------------------------------------------
function BeamLib.ConvertToClosedCurve( Proc, AuxId)
local bCurveModified = false
if not EgtCurveIsClosed( AuxId) then
local NewId, nCount = EgtExtractSurfTmFacetLoops( Proc.id, 0, EgtGetParent( Proc.id))
if NewId then
-- elimino eventuali loop interni (non dovrebbero comunque esserci)
for i = 1, nCount - 1 do
EgtErase( NewId + i)
end
local vtExtr = EgtCurveExtrusion( AuxId, GDB_ID.ROOT)
-- sostituisco il loop esterno alla curva originale
EgtModifyCurveExtrusion( NewId, vtExtr, GDB_ID.ROOT)
EgtRelocate( NewId, AuxId, GDB_IN.AFTER)
EgtErase( AuxId)
EgtChangeId( NewId, AuxId)
bCurveModified = true
-- sistemo i lati aperti
local vFacAdj = EgtSurfTmFacetAdjacencies( Proc.id, 0)[1]
if vFacAdj then
local vOpen = {}
for i = 1, #vFacAdj do
if vFacAdj[i] < 0 then
table.insert( vOpen, i - 1)
end
end
EgtSetInfo( AuxId, 'OPEN', vOpen)
end
end
end
return true, bCurveModified
end
-------------------------------------------------------------------------------------------------------------
--- funzione che ruota il pezzo, da lanciare per creare la disposizione corretta
function BeamLib.RotatePart( Part, nNumberOfRotations)
+41 -6
View File
@@ -264,7 +264,7 @@ function FeatureLib.GetAdditionalInfo( Proc, Part)
Proc.FeatureInfo = FeatureLib.GetDTMortiseData( Proc)
-- se mortasa a coda di rondine o mortasa frontale a coda di rondine
elseif ID.IsMortise( Proc) or ID.IsFrontMortise( Proc) then
Proc.FeatureInfo = FeatureLib.GetMortiseData( Proc)
Proc.FeatureInfo = FeatureLib.GetMortiseData( Proc, Part)
end
return Proc
@@ -396,7 +396,7 @@ end
-------------------------------------------------------------------------------------------------------------
-- Recupero dati mortasa
function FeatureLib.GetMortiseData( Proc)
function FeatureLib.GetMortiseData( Proc, Part)
local FeatureExtraInfo = {}
local idAux = EgtGetInfo( Proc.id, 'AUXID', 'i')
@@ -405,13 +405,42 @@ function FeatureLib.GetMortiseData( Proc)
-- recupero i dati della faccia di fondo
local frMortise, dMortiseLength, dMortiseWidth = EgtSurfTmFacetMinAreaRectangle( Proc.id, 0, GDB_ID.ROOT)
local ptC = frMortise:getOrigin()
local vtN = frMortise:getVersZ()
-- se curva di contorno aperta la rendo chiusa
local _, bCurveModified = BeamLib.ConvertToClosedCurve( Proc, idAux)
-- Confronto le direzioni dei 2 versori : se diverse la faccia 0 non è il fondo => mortasa passante
local bMortiseThrough = not AreSameVectorApprox( vtMortiseN, frMortise:getVersZ())
-- in caso sia passante si ricalcola tutto sul contorno della tasca
if bMortiseThrough then
-- creo superficie chiusa sul contorno
local nFlat = EgtSurfTmByFlatContour( EgtGetParent( idAux), idAux, 0.05)
if nFlat then
frMortise, dMortiseLength, dMortiseWidth = EgtSurfTmFacetMinAreaRectangle( nFlat, 0, GDB_ID.ROOT)
-- verifico se copiare la geometria lungo l'asse Z
local b3Aux = EgtGetBBoxRef( idAux, GDB_BB.STANDARD, frMortise)
local bxMax = b3Aux:getMax()
local b3Mor = EgtGetBBoxRef( Proc.id, GDB_BB.STANDARD, frMortise)
local bxMin = b3Mor:getMin()
local dMove = bxMin:getZ() - bxMax:getZ()
-- se il percorso ausiliario è esterno al grezzo, lo riavvicino
if abs( dMove) > GEO.EPS_SMALL then
idAux = EgtCopyGlob( idAux, BeamLib.GetAddGroup( Part.id))
local vtMove = Vector3d( 0, 0, dMove)
vtMove:toGlob( frMortise)
EgtMove( idAux, vtMove, GDB_RT.GLOB)
EgtMove( nFlat, vtMove, GDB_RT.GLOB)
frMortise, dMortiseLength, dMortiseWidth = EgtSurfTmFacetMinAreaRectangle( nFlat, 0, GDB_ID.ROOT)
end
-- cancello la superficie piana utilizzata per ricalcolare dati
EgtErase( nFlat)
end
end
-- determino altezza della mortasa
local b3Mortise = EgtGetBBoxRef( Proc.id, GDB_BB.STANDARD, frMortise)
local dMortiseDepth = b3Mortise:getDimZ()
-- Confronto le direzioni dei 2 versori : se diverse la faccia 0 non è il fondo => mortasa passante
local bMortiseThrough = not AreSameVectorApprox( vtMortiseN, vtN)
-- recupero il raggio minimo della mortasa
local dMortiseMinRadius = 1000
@@ -423,8 +452,14 @@ function FeatureLib.GetMortiseData( Proc)
end
end
-- se la mortasa passante il contorno è sulla faccia della trave e il riconoscimento lati aperti non è corretto
if not bCurveModified and not bMortiseThrough then
BeamLib.SetOpenSide( idAux, Part.b3Part)
end
FeatureExtraInfo.bIsFrontMortise = Proc.nPrc == 51
FeatureExtraInfo.bIsMortiseThrough = bMortiseThrough
FeatureExtraInfo.bIsMortiseOpen = bCurveModified
FeatureExtraInfo.dMortiseLength = dMortiseLength
FeatureExtraInfo.dMortiseWidth = dMortiseWidth
FeatureExtraInfo.dMortiseDepth = dMortiseDepth
+127 -47
View File
@@ -75,74 +75,146 @@ local function GetBestPocketingStrategy( Proc, Part)
end
-- === ricerca utensile per svuotare taglio iniziale, se taglio non possibile ===
if Machining.bCuttingWithMill and ( not( Proc.AffectedFaces.bLeft) or Strategy.bCanMoveAfterSplit) then
ToolSearchParameters = {}
ToolSearchParameters.dElevation = 0
ToolSearchParameters.vtToolDirection = Proc.FeatureInfo.vtMortiseN
ToolSearchParameters.sMillShape = 'STANDARD'
Machining.Cutting.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
if Machining.Cutting.ToolInfo.nToolIndex then
Machining.Cutting.bIsApplicable = true
local ParametersMRR = {}
ParametersMRR.nToolIndex = Machining.Cutting.ToolInfo.nToolIndex
Result.Cutting.dMRR = MachiningLib.GetToolMRR( ParametersMRR)
Result.Cutting.sStatus = 'Completed'
if Machining.bCuttingWithMill then
-- se può essere fatto di fresa
if not( Proc.AffectedFaces.bLeft) or Strategy.bCanMoveAfterSplit then
ToolSearchParameters = {}
ToolSearchParameters.dElevation = 0
ToolSearchParameters.vtToolDirection = Proc.FeatureInfo.vtMortiseN
ToolSearchParameters.sMillShape = 'STANDARD'
Machining.Cutting.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
if Machining.Cutting.ToolInfo.nToolIndex then
Machining.Cutting.bIsApplicable = true
local ParametersMRR = {}
ParametersMRR.nToolIndex = Machining.Cutting.ToolInfo.nToolIndex
Result.Cutting.dMRR = MachiningLib.GetToolMRR( ParametersMRR)
Result.Cutting.sStatus = 'Completed'
end
-- alterimenti esco subito
else
Strategy.Result.sStatus = 'Not-Applicable'
Strategy.Result.nCompletionIndex = 0
Strategy.Result.dMRR = 0
Strategy.Result.nQuality = 0
Strategy.Result.sInfo = 'Mill not found'
return Machining
end
end
end
-- ===== RICERCA UTENSILE =====
-- cerco utensile per lavorare faccia Bottom
Machining.Pocketing.bIsApplicable = false
if Proc.Topology.sName == 'Pocket-Round' or Proc.Topology.sName == 'Pocket-Round-Front' then
local Milling = {}
local Milling = {}
Milling.bIsApplicable = false
ToolSearchParameters = {}
ToolSearchParameters.sMillShape = 'STANDARD'
ToolSearchParameters.dMaxToolDiameter = Proc.FeatureInfo.dMortiseMinRadius * 2
ToolSearchParameters.dElevation = Proc.FeatureInfo.dMortiseDepth + EgtIf( Proc.Topology.sName == 'Pocket-Round-Through', BeamData.CUT_EXTRA, 0)
ToolSearchParameters.vtToolDirection = Proc.FeatureInfo.vtMortiseN
Milling.ToolInfo = {}
-- si cerca prima utensile per lavorare in accordo con normale mortasa
Milling.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
Milling.idFaceToMachine = 0 -- ATTENZIONE: Per convenzione, la faccia di fondo della mortasa ha sempre indice 0
Milling.idProc = Proc.id
Milling.vtFaceNormal = Proc.FeatureInfo.vtMortiseN
Milling.dElevation = Proc.FeatureInfo.dMortiseDepth
if Milling.ToolInfo.nToolIndex then
Milling.bIsApplicable = true
end
table.insert( Machining.Pocketing, Milling)
-- si cerca utensile che lavora dal lato opposto
Milling = {}
Milling.bIsApplicable = false
if Proc.Topology.sName == 'Pocket-Round-Through' then
ToolSearchParameters = {}
ToolSearchParameters.sMillShape = 'STANDARD'
ToolSearchParameters.dMaxToolDiameter = Proc.FeatureInfo.dMortiseMinRadius * 2
ToolSearchParameters.dElevation = Proc.FeatureInfo.dMortiseDepth
ToolSearchParameters.vtToolDirection = Proc.FeatureInfo.vtMortiseN
ToolSearchParameters.dElevation = Proc.FeatureInfo.dMortiseDepth + BeamData.CUT_EXTRA
ToolSearchParameters.vtToolDirection = -Proc.FeatureInfo.vtMortiseN
Milling.ToolInfo = {}
-- si cerca prima utensile per lavorare in accordo con normale mortasa
Milling.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
Milling.idFaceToMachine = 0 -- ATTENZIONE: Per convenzione, la faccia di fondo della mortasa ha sempre indice 0
Milling.idProc = Proc.id
Milling.vtFaceNormal = Proc.FeatureInfo.vtMortiseN
Milling.vtFaceNormal = -Proc.FeatureInfo.vtMortiseN
Milling.bToolInvert = true
Milling.dElevation = Proc.FeatureInfo.dMortiseDepth
Milling.ToolInfo = {}
Milling.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
if Milling.ToolInfo.nToolIndex then
-- se utensile scelto è su aggregato, ricalcolo la qualità
if TOOLS[Milling.ToolInfo.nToolIndex].SetupInfo.bToolOnAggregate then
Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'MillOnAggregate')
end
Milling.bIsApplicable = true
local ParametersMRR = {}
ParametersMRR.nToolIndex = Milling.ToolInfo.nToolIndex
Strategy.Result.dMRR = MachiningLib.GetToolMRR( ParametersMRR)
Machining.sTypeMachining = 'Bottom'
if Milling.ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then
Strategy.Result.sStatus = 'Completed'
Strategy.Result.dCompletionPercentage = 100
else
Strategy.Result.sStatus = 'Not-Completed'
Strategy.Result.sInfo = 'Mortise not complete, left ' .. ceil( Milling.ToolInfo.dResidualDepth) .. 'mm'
Strategy.Result.dCompletionPercentage = ( Milling.ToolInfo.dResidualDepth * 100) / Proc.FeatureInfo.dMortiseDepth
end
Strategy.Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( Strategy.Result.dCompletionPercentage)
table.insert( Machining.Pocketing, Milling)
end
-- si lavora faccia di mezzo
elseif 'Pocket-Round-Through' then
-- TODO aggiungere faccia di mezzo tipo tunnel e decidere da che parte lavorare
end
table.insert( Machining.Pocketing, Milling)
-- se non ho trovato neanche una lavorazione, oppure se taglio fatto di fresa e non può essere fatto dopo separazione
if Machining.sTypeMachining == 'None' or
( Machining.bCuttingWithMill and ( Proc.AffectedFaces.bLeft and not Strategy.bCanMoveAfterSplit)) then
-- tipo di lavorazione
-- solo svuotatura diretta come normale mortasa, completa
if Machining.Pocketing[1].bIsApplicable and Machining.Pocketing[1].ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then
if Proc.Topology.sName == 'Pocket-Round-Through' then
Machining.sTypeMachining = 'Side1'
Machining.Pocketing[1].sDepth = BeamData.CUT_EXTRA
else
Machining.sTypeMachining = 'Bottom'
Machining.Pocketing[1].sDepth = -Strategy.Parameters.dOverMatOnLength
end
Strategy.Result.dMRR = MachiningLib.GetToolMRR( Machining.Pocketing[1].ToolInfo)
Machining.dResidual = 0
Machining.Pocketing[2].bIsApplicable = false
-- solo svuotatura diretta opposta alla normale mortasa, completa
elseif Machining.Pocketing[2].bIsApplicable and Machining.Pocketing[2].ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then
Machining.sTypeMachining = 'Side2'
Machining.dResidual = 0
Machining.Pocketing[2].sDepth = Proc.FeatureInfo.dMortiseDepth + BeamData.CUT_EXTRA
Strategy.Result.dMRR = MachiningLib.GetToolMRR( Machining.Pocketing[2].ToolInfo)
Machining.Pocketing[1].bIsApplicable = false
-- solo svuotatura diretta come normale mortasa, incompleta
elseif not Machining.Pocketing[2].bIsApplicable then
Machining.sTypeMachining = 'Side1'
Machining.dResidual = Machining.Pocketing[1].ToolInfo.dResidualDepth
Machining.Pocketing[1].sDepth = -Machining.dResidual
Strategy.Result.dMRR = MachiningLib.GetToolMRR( Machining.Pocketing[1].ToolInfo)
-- solo svuotatura diretta come normale mortasa, incompleta
elseif not Machining.Pocketing[1].bIsApplicable then
Machining.sTypeMachining = 'Side2'
Machining.dResidual = Machining.Pocketing[2].ToolInfo.dResidualDepth
Machining.Pocketing[2].sDepth = Proc.FeatureInfo.dMortiseDepth - Machining.dResidual
Strategy.Result.dMRR = MachiningLib.GetToolMRR( Machining.Pocketing[2].ToolInfo)
-- lavorazione da entrambi i lati
elseif Machining.Pocketing[1].bIsApplicable and Machining.Pocketing[2].bIsApplicable then
Machining.sTypeMachining = 'Side1-Side2'
local dResidualMach = Machining.Pocketing[1].ToolInfo.dResidualDepth + Machining.Pocketing[2].ToolInfo.dResidualDepth - Proc.FeatureInfo.dMortiseDepth
Machining.dResidual = max( 0, dResidualMach)
-- se lavorazione non copmpleta, si entra il massimio possibile
if dResidualMach > 0 then
Machining.Pocketing[1].sDepth = -Machining.Pocketing[1].ToolInfo.dResidualDepth
Machining.Pocketing[2].sDepth = Proc.FeatureInfo.dMortiseDepth - Machining.Pocketing[2].ToolInfo.dResidualDepth
else
Machining.Pocketing[1].sDepth = -Machining.Pocketing[1].ToolInfo.dResidualDepth + dResidualMach/2 + BeamData.CUT_EXTRA_MIN
Machining.Pocketing[2].sDepth = Proc.FeatureInfo.dMortiseDepth - ( Machining.Pocketing[2].ToolInfo.dResidualDepth - dResidualMach/2 - BeamData.CUT_EXTRA_MIN)
end
Strategy.Result.dMRR = min( MachiningLib.GetToolMRR( Machining.Pocketing[1].ToolInfo), MachiningLib.GetToolMRR( Machining.Pocketing[2].ToolInfo))
-- altrimenti non applicabile
else
-- TODO per feature frontale, ha senso voler applicare solo il taglio e non la lavorazione della mortasatura? Adesso non fa nulla
Strategy.Result.sStatus = 'Not-Applicable'
Strategy.Result.nCompletionIndex = 0
Strategy.Result.dMRR = 0
Strategy.Result.nQuality = 0
Strategy.Result.sInfo = 'Mill not found'
return Machining
end
-- se completo
if Machining.dResidual < 10 * GEO.EPS_SMALL then
Strategy.Result.sStatus = 'Completed'
Strategy.Result.dCompletionPercentage = 100
else
Strategy.Result.sStatus = 'Not-Completed'
Strategy.Result.sInfo = 'Mortise not complete, left ' .. ceil( Machining.dResidual) .. 'mm'
Strategy.Result.dCompletionPercentage = ( 1 - Machining.dResidual / Proc.FeatureInfo.dMortiseDepth) * 100
end
Strategy.Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( Strategy.Result.dCompletionPercentage)
return Machining
end
@@ -248,11 +320,19 @@ function STR0008.Make( bAddMachining, Proc, Part, CustomParameters)
Pocketing.nToolIndex = Strategy.Machining.Pocketing[i].ToolInfo.nToolIndex
Pocketing.LeadIn.dTangentDistance = TOOLS[Strategy.Machining.Pocketing[i].ToolInfo.nToolIndex].dDiameter/2
Pocketing.LeadIn.dElevation = TOOLS[Strategy.Machining.Pocketing[i].ToolInfo.nToolIndex].dDiameter/2
Pocketing.sDepth = min( -Strategy.Parameters.dOverMatOnLength, -Strategy.Machining.Pocketing[i].ToolInfo.dResidualDepth)
Pocketing.dMaxElev = Proc.FeatureInfo.dMortiseDepth
Pocketing.sDepth = Strategy.Machining.Pocketing[i].sDepth
Pocketing.dRadialOffset = Strategy.Parameters.dOverMatOnRadius
Pocketing.bToolInvert = Strategy.Machining.Pocketing[i].bToolInvert
Pocketing.Geometry = {{ Strategy.Machining.Pocketing[i].idProc, Strategy.Machining.Pocketing[i].idFaceToMachine}}
if Proc.FeatureInfo.bIsFrontMortise then
Pocketing.dMaxElev = Proc.FeatureInfo.dMortiseDepth
end
-- se feature passante, si applica la lavorazione alla curva
if Proc.Topology.sName == 'Pocket-Round-Through' then
Pocketing.Geometry = {{ Proc.FeatureInfo.idAddAuxGeom, -1}}
else
Pocketing.Geometry = {{ Strategy.Machining.Pocketing[i].idProc, Strategy.Machining.Pocketing[i].idFaceToMachine}}
end
Pocketing.vtToolDirection = Strategy.Machining.Pocketing[i].vtFaceNormal
-- se è aperta sulla coda, dico che deve essere fatta dopo la separazione