Compare commits

..

60 Commits

Author SHA1 Message Date
luca.mazzoleni da7d2a7159 - in WallExec aggiunte al sorting le lavorazioni PreSideMill che vengono sempre fatte prima delle SideMill
- LapJoint -> MakeSideGrooveByMill, se rabbet doppio uno verso l'alto e uno verso il basso, aggiunto step extra iniziale per ripulire la lamina che potrebbe rimanere nella rabbet che guarda in alto.
2023-11-13 18:18:48 +01:00
luca.mazzoleni d1ca35e29d correzione minore in WallExec -> SetMirroredFeatures 2023-11-10 15:11:28 +01:00
luca.mazzoleni e92ba3e740 - In WallExec doppio disattivato se side e la lavorazione mirror è troppo distante dal grezzo. 2023-11-10 11:48:06 +01:00
luca.mazzoleni a84fb0608f - varie modifiche, principalmente a MachiningLib e LapJoint, che migliorano il funzionamento delle tasche, anche in doppio. 2023-11-09 18:17:17 +01:00
luca.mazzoleni f9bb10bf6e - in LapJoint -> FindPocketing le lavorazioni con attacco speciale (rampa molto lunga e step basso) ignorano il flag per escludere le frese che non lavorano di testa. 2023-10-31 18:47:38 +01:00
luca.mazzoleni fea5cfd8ed - In LapJoint -> VerifyPocket, se topologia pocket, forzata ricerca fresa che possa lavorare di testa. 2023-10-31 17:25:20 +01:00
luca.mazzoleni 31172238d8 - In LpJoint -> IsToolDoubleOk permessa una lunghezza inferiore di 5.5mm dell'utensile secondario rispetto al principale 2023-10-31 16:41:10 +01:00
luca.mazzoleni f29816c693 - In LapJoint -> VerifyPocket, per tasche in doppio forzata ricerca fresa che possa lavorare di testa.
- In MachiningLib -> FindPocketing aggiunto parametro per poter escludere le frese che non lavorano di testa.
- In WallExec -> SetMirroredFeatures permesso il doppio per groove con specchiata non sul fianco se settate per essere lavorate come pocket.
2023-10-30 18:22:04 +01:00
luca.mazzoleni 164e0474fa Merge branch 'develop' into feature/MirroredMachinings 2023-10-23 14:57:55 +02:00
luca.mazzoleni 732e6c0390 Merge tag '2.5j3' into develop
Finish Release: 2.5j3
2023-10-23 13:18:21 +02:00
luca.mazzoleni 5340c6a92c - update del compile per includere topology 2023-10-19 18:10:45 +02:00
luca.mazzoleni 9edd6aec23 - nella ricerca lavorazione da usare controllo di utensile attivo sostituito con controllo utensile presente nel setup corrente 2023-10-19 09:54:01 +02:00
luca.mazzoleni 7c67b24b37 Merge branch 'develop' into feature/MirroredMachinings 2023-10-19 09:33:14 +02:00
luca.mazzoleni 64ca535056 Merge branch 'develop' into feature/MirroredMachinings 2023-10-16 10:07:19 +02:00
luca.mazzoleni 3b998e5fba Merge remote-tracking branch 'origin/master' into feature/MirroredMachinings 2023-10-02 14:41:09 +02:00
luca.mazzoleni 47ec893959 - piccole correzioni bug 2023-09-28 16:36:43 +02:00
luca.mazzoleni 79e97c9e1f - migliorata WallLib -> Is3EdgesApprox 2023-09-28 09:26:38 +02:00
luca.mazzoleni 18ae1a71cc Merge branch 'develop' into feature/MirroredMachinings 2023-09-28 09:23:46 +02:00
luca.mazzoleni 007288b9c9 Merge branch 'develop' into feature/MirroredMachinings 2023-09-27 12:00:37 +02:00
luca.mazzoleni efc9a89bf5 Merge branch 'develop' into feature/MirroredMachinings 2023-09-21 17:04:54 +02:00
luca.mazzoleni eca052bd67 Merge branch 'develop' into feature/MirroredMachinings 2023-09-21 16:10:49 +02:00
luca.mazzoleni 8b999fad88 Merge branch 'develop' into feature/MirroredMachinings 2023-09-20 10:33:27 +02:00
luca.mazzoleni 11b6a8716e Merge branch 'develop' into feature/MirroredMachinings 2023-09-19 18:35:17 +02:00
luca.mazzoleni 4bcf2c8068 Merge branch 'develop' into feature/MirroredMachinings 2023-09-19 10:25:52 +02:00
luca.mazzoleni 93f9df0d5f Merge branch 'develop' into feature/MirroredMachinings 2023-09-13 08:54:17 +02:00
luca.mazzoleni 9f014c70f7 - lievi correzioni 2023-09-11 09:56:22 +02:00
luca.mazzoleni b2fdd27130 in WallExec -> SetMirroredOperations ora si controlla che la lavorazione non sia vuota prima di aggiungerla alla lista delle plausibili per doppio 2023-09-07 17:03:12 +02:00
luca.mazzoleni 6a2a87b91f - la Topology tunnel chiuso diventa pocket
- piccole correzioni alla raccolta features in doppio in WallExec
- correzione in LApJoint per evitare di lavorare groove completamente affondate nel grezzo
2023-09-07 12:23:27 +02:00
luca.mazzoleni 61e5ce6359 - aggiunta costante if WD.DOUBLE_HEAD_MILLCORNER per attivazione puliture in doppio 2023-09-05 16:14:05 +02:00
luca.mazzoleni fa276949a2 - in WallExec completata ricerca e esecuzione di fresature in doppio da percorso specchiato
- in WMachiningLib resa globale la funzione IsToolDoubleOk
- piccole correzioni
2023-09-04 17:56:07 +02:00
luca.mazzoleni d24a86bcdd - aggiunta ricerca e esecuzione di fresature in doppio da percorso specchiato
- piccole correzioni
2023-08-30 18:21:10 +02:00
luca.mazzoleni 5524fbf0cb - spostate funzioni per verifica lavorazione adatta a doppio in MachiningLib
- aggiunte (commentate per ora) prime righe per riconoscimento percorsi fresature da specchiare
2023-08-30 12:09:08 +02:00
luca.mazzoleni afb33aa7c6 - in WallLib -> GetProcessDistanceToNearestParts piccole correzioni al calcolo del solido della parte
- in LapJoint -> MakeByPocketing migliorata la scelta utensile e la forzatura tasca chiusa nel caso di parti vicine
2023-08-29 13:12:34 +02:00
luca.mazzoleni 924313a0ea - alcune correzioni 2023-08-24 18:40:00 +02:00
luca.mazzoleni 9d812ab33a - in LapJoint -> MakeByPocketing, se doppio, escludo ottimizzazioni e forzo attacco interno perchè la tasca specchiata potrebbe essere nel mezzo del pannello 2023-08-24 17:08:39 +02:00
luca.mazzoleni 3c7c22ae7c - in WallLib aggiunta la funzione GetProcessDistanceToRawPart
- alcune correzioni in WallExec
2023-08-24 16:05:42 +02:00
luca.mazzoleni b9c9cc5167 - in WallExec -> Collect viene ora calcolata e scritta in Proc la distanza dalle parti vicine, nelle direzioni Y+/Y-/X+/X-, tramite la funzione GetProcessDistanceToNearestParts da WallLib
- in WallExec -> SetMirroredFeatures semplificato il calcolo di IsFeatureOnEdge
- in LapJoint -> IsMachiningDamagingOtherParts eliminata la verifica di overlap nelle singole direzioni (ora già calcolata nel Collect)
2023-08-24 09:53:18 +02:00
luca.mazzoleni 756d58b3e4 - piccole correzioni a WallExec
- in LapJoint -> MakeByPocketing aggiunta forzatura tasche chiuse se la lavorazione potrebbe danneggiare  i pezzi limitrofi
2023-08-23 12:24:45 +02:00
luca.mazzoleni 4a5c213de6 - refactoring di SetMirroredMachinings
- da definire cosa specchiare se feature non sul bordo
2023-08-11 18:51:02 +02:00
luca.mazzoleni d0cecd6a0d - in WallLib -> affectedFaces modificata tolleranza
- in WallExec introduzione costanti distinte per tolleranze ricerca tasche e fori in doppio
- altre piccole migliorie
2023-08-10 16:54:02 +02:00
luca.mazzoleni 3326f8ef4e - corretto id geometria per disattivazione fori
- massima distanza dal bordo pannello portata a 200 mm
- migliorie stilistiche
2023-08-09 18:25:32 +02:00
luca.mazzoleni 5e6dfe320f - aggiunta gestione in doppio di forature e groove passanti (rivolte verso Z+)
- lieve correzione a check utensile doppio
- aggiunto interasse minimo per lavorazioni in doppio
2023-08-09 17:16:47 +02:00
luca.mazzoleni a4c3b74434 Merge branch 'develop' into feature/MirroredMachinings 2023-08-08 08:56:19 +02:00
luca.mazzoleni 46a299b83d Merge branch 'develop' into feature/MirroredMachinings 2023-08-07 17:13:10 +02:00
luca.mazzoleni e6bd4e7e94 piccola correzione a WallExec 2023-08-07 10:53:35 +02:00
luca.mazzoleni 5ff950015e - a WallExec aggiunta rimozione operazioni se legate a lavorazioni specchiate
- modifiche varie per forzare sideGroove in caso la lavorazione principale sia una tasca cieca che guarda in alto
- modificata MakeMoreFaces per contemplare lavorazioni in doppio
2023-08-04 18:57:04 +02:00
luca.mazzoleni 57ed0d934f Merge branch 'develop' into feature/MirroredMachinings 2023-08-03 16:33:02 +02:00
luca.mazzoleni 5b5ce504b1 - qualche piccola modifica a WallExec
- in LapJoint (MakeTwoFaces e altri make, manca MakeMoreFaces) implementata parzialmente gestione doppio
- in MachiningLib aggiunta la possibilità di forzare una testa per milling e pocketing
2023-07-14 19:02:13 +02:00
luca.mazzoleni f2027d03a3 feature/MirroredMachinings:
- implementato riconoscimento tasche sul fianco (e relativa specchiata) da fare in doppio; funzionanti, da testare
- piccoli ritocchi a AffectedFaces e Topology
2023-07-12 18:35:36 +02:00
luca.mazzoleni 5ee62cfee2 commenti funzioni e piccoli fix 2023-07-10 09:51:08 +02:00
luca.mazzoleni 3ca0ab1692 - altri piccoli miglioramenti legati al riconoscimento topologia 2023-07-07 18:07:11 +02:00
luca.mazzoleni 51e1425921 Merge branch 'develop' into feature/MirroredMachinings 2023-07-06 15:32:50 +02:00
luca.mazzoleni b0abe6d088 - alcune correzioni a Topology
- aggiunto riconoscimento topologie fino a 5 lati (da testare)
2023-07-06 15:32:40 +02:00
luca.mazzoleni be49385bb0 - riconoscimento bevel e rabbet funzionanti; da testare 2023-07-05 18:38:17 +02:00
luca.mazzoleni 4e079f6708 completamento parziale della funzione per recuperare le facce parallele alla parte 2023-07-04 11:22:03 +02:00
luca.mazzoleni 6550ddd456 altre aggiunte a WFeatureTopology 2023-06-30 09:54:33 +02:00
luca.mazzoleni 68ad658bc5 Merge branch 'develop' into feature/MirroredMachinings 2023-06-28 12:59:28 +02:00
luca.mazzoleni 5bb7fdd634 - aggiunta libreria WFeatureTopology per il riconoscimento topologico delle feature (da completare)
- spostate alcune funzioni da FreeContour a WallLib
2023-06-28 11:32:48 +02:00
luca.mazzoleni 30c449bfad Merge branch 'develop' into feature/MirroredMachinings 2023-06-20 09:43:00 +02:00
luca.mazzoleni 1236d196ba - TestElleShape 3 e 4 spostati in WallLib
- a DoubleCut aggiunto riconoscimento della sola L011
- in WallLib aggiunta funzione GetProcessAffectedFaces che restituisce le facce del grezzo interessate dalla feature
- in WallExec aggiunte alle Proc informazioni sulle facce della feature
- alcune modifiche iniziali per Mirror
2023-06-20 09:35:25 +02:00
12 changed files with 1459 additions and 214 deletions
+2
View File
@@ -20,3 +20,5 @@
/bin/LuaLibs/*.lua
/bin/Images/*.png
.vscode/settings.json
bin/LuaLibs/.placeholder
bin/Images/.placeholder
+1 -1
View File
@@ -11,7 +11,7 @@ REM Compilazione 32 e 64 bit
\EgtProg\Dll32\luac54 -o bin\LuaLibs\WProcessDoubleCut.lua LuaLibs\WProcessDoubleCut.lua
\EgtProg\Dll32\luac54 -o bin\LuaLibs\WProcessDrill.lua LuaLibs\WProcessDrill.lua
\EgtProg\Dll32\luac54 -o bin\LuaLibs\WProcessDtMortise.lua LuaLibs\WProcessDtMortise.lua
REM \EgtProg\Dll32\luac54 -o bin\LuaLibs\WFeatureTopology.lua LuaLibs\WFeatureTopology.lua
\EgtProg\Dll32\luac54 -o bin\LuaLibs\WFeatureTopology.lua LuaLibs\WFeatureTopology.lua
\EgtProg\Dll32\luac54 -o bin\LuaLibs\WProcessFreeContour.lua LuaLibs\WProcessFreeContour.lua
\EgtProg\Dll32\luac54 -o bin\LuaLibs\WProcessLapJoint.lua LuaLibs\WProcessLapJoint.lua
\EgtProg\Dll32\luac54 -o bin\LuaLibs\WProcessMark.lua LuaLibs\WProcessMark.lua
+234
View File
@@ -0,0 +1,234 @@
-- WFeatureTopology.lua by Egaltech s.r.l. 2023/06/23
-- Libreria per classificazione topologica feature pareti
-- Tabella per definizione modulo
local WFeatureTopology = {}
-- Include
require( 'EgtBase')
-- Carico le librerie
local WL = require( 'WallLib')
EgtOutLog( ' WFeatureTopology started', 1)
---------------------------------------------------------------------
-- restituisce la matrice delle adiacenze di Proc dove i e j sono le facce e a(ij) è l'angolo tra di esse; 0 se nessuna adiacenza
local function GetAdjacencyMatrix( Proc)
local vAdj = {}
for i = 1, Proc.Fct do
vAdj[i] = {}
for j = 1, Proc.Fct do
if i == j then
vAdj[i][j] = 0
else
_, _, _, vAdj[i][j] = EgtSurfTmFacetsContact( Proc.Id, i - 1, j - 1, GDB_ID.ROOT)
if not vAdj[i][j] then vAdj[i][j] = 0 end
end
j = j + 1
end
i = i + 1
end
return vAdj
end
---------------------------------------------------------------------
-- restituisce gli id delle facce di Proc che hanno il numero di adiacenze nAdj
function WFeatureTopology.GetFacesWithGivenAdjacencyNumber( Proc, nAdj)
local vAdj = GetAdjacencyMatrix( Proc)
local vFacesWithGivenAdj = {}
for i = 1, Proc.Fct do
local nAdjCount = 0
for j = 1, Proc.Fct do
if vAdj[i][j] and vAdj[i][j] ~= 0 then
nAdjCount = nAdjCount + 1
end
end
if nAdjCount == nAdj then
table.insert( vFacesWithGivenAdj, i - 1)
end
end
return vFacesWithGivenAdj
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( Proc)
local vAdj = GetAdjacencyMatrix( Proc)
local bAllConcave, bAllRight = true, true
for i = 1, Proc.Fct do
for j = 1, Proc.Fct 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 Proc.Fct < 2 or ( Proc.Fct == 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)
local bResult = false
local nBoxSolidId = EgtGetFirstNameInGroup( Proc.PartId or GDB_ID.NULL, 'Box')
local b3Solid = EgtGetBBoxGlob( nBoxSolidId, GDB_BB.STANDARD)
if Proc.Box:getDimX() > b3Solid:getDimX() - 1000 * GEO.EPS_SMALL or
Proc.Box:getDimY() > b3Solid:getDimY() - 1000 * GEO.EPS_SMALL or
Proc.Box:getDimZ() > b3Solid:getDimZ() - 1000 * GEO.EPS_SMALL then
bResult = true
end
return bResult
end
---------------------------------------------------------------------
-- retituisce un vettore con gli indici (0 based) delle facce triangolari (o quasi) di Proc
local function GetTriangularFaces( Proc)
local vTriangularFaces = {}
for i = 1, Proc.Fct do
if WL.Is3EdgesApprox( Proc, i - 1) then
table.insert( vTriangularFaces, i - 1)
end
end
return vTriangularFaces
end
---------------------------------------------------------------------
-- restituisce un vettore contenente gli indici delle facce di Proc parallele ad una delle direzioni principali; il check varia in base alla famiglia topologica
local function GetFacesParallelToPart( Proc, sFamily)
local vFacesParallelToPart = {}
for i = 0, Proc.Fct - 1 do
local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i, GDB_ID.ROOT)
if sFamily == 'Bevel' or sFamily == 'DoubleBevel' then
local vTriangularFaces = GetTriangularFaces( Proc)
local bIsTriangularFace = false
-- verifico se la faccia è triangolare
for j = 1, #vTriangularFaces do
if i == vTriangularFaces[j] then
bIsTriangularFace = true
end
end
-- se faccia triangolare deve avere la normale parallela ad una direzione principale
if bIsTriangularFace then
if AreSameOrOppositeVectorApprox( vtN, X_AX()) or AreSameOrOppositeVectorApprox( vtN, Y_AX()) or AreSameOrOppositeVectorApprox( vtN, Z_AX()) then
table.insert( vFacesParallelToPart, i)
end
-- altrimenti deve avere una componente della normale nulla
else
if abs( vtN:getX()) < 10 * GEO.EPS_SMALL or abs( vtN:getY()) < 10 * GEO.EPS_SMALL or abs( vtN:getZ()) < 10 * GEO.EPS_SMALL then
table.insert( vFacesParallelToPart, i)
end
end
else
-- la normale deve essere parallela ad una direzione principale
if AreSameOrOppositeVectorApprox( vtN, X_AX()) or AreSameOrOppositeVectorApprox( vtN, Y_AX()) or AreSameOrOppositeVectorApprox( vtN, Z_AX()) then
table.insert( vFacesParallelToPart, i)
end
end
end
return vFacesParallelToPart
end
---------------------------------------------------------------------
-- restituisce una stringa con il nome esteso della topologia della feature
-- *famiglia-passante-angoli tutti concavi a 90deg-facce tutte parallele alle dimensioni principali-numero di facce*
local function GetTopologyLongName( sFamily, bIsThrough, bAllRightAngles, bIsParallel, nNumberOfFaces)
-- feature passante o cieca
local sThrough = '_'
if bIsThrough ~= nil then sThrough = EgtIf( bIsThrough, 'Through', 'Blind') end
-- tutti gli angoli della feature sono retti oppure no
local sAllRightAngles = '_'
if bAllRightAngles ~= nil then sAllRightAngles = EgtIf( bAllRightAngles, 'RightAngles', 'NotRightAngles') end
-- tutte le dimensioni della feature sono parallele agli assi principali del pezzo oppure no
local sParallel = '_'
if bIsParallel ~= nil then sParallel = EgtIf( bIsParallel, 'Parallel', 'NotParallel') end
local sLongName = sFamily .. '-' .. sThrough .. '-' .. sAllRightAngles .. '-' .. sParallel .. '-' .. nNumberOfFaces
return sLongName
end
---------------------------------------------------------------------
-- riconosce se Proc è una delle topologie standard e, in caso positivo, ne scrive le caratteristiche in campi specifici della Proc stessa restituendo true
function WFeatureTopology.Classify( Proc)
local bRecognized = false
local sFamily
local bIsThrough
local bAllRightAngles
local bIsParallel
local sLongName = ''
-- SE NON HA TUTTE LE FACCE PIANE RITORNARE NIL!!
local bAllAnglesConcave
bAllAnglesConcave, bAllRightAngles = AreAllAnglesConcaveOrRight( Proc)
local vTriangularFaces = GetTriangularFaces( Proc)
local bIsAnyDimensionLongAsPart = IsAnyDimensionLongAsPart( Proc)
local vFacesWithTwoAdj = WFeatureTopology.GetFacesWithGivenAdjacencyNumber( Proc, 2)
local vFacesWithThreeAdj = WFeatureTopology.GetFacesWithGivenAdjacencyNumber( Proc, 3)
local vFacesWithFourAdj = WFeatureTopology.GetFacesWithGivenAdjacencyNumber( Proc, 4)
if Proc.IsOutline then
sFamily = 'OUTLINE'
elseif Proc.Prc == 40 then
sFamily = 'DRILLING'
elseif Proc.Fct == 1 and bIsAnyDimensionLongAsPart then
sFamily = 'Bevel'
bIsThrough = true
elseif Proc.Fct == 2 and bAllAnglesConcave and #vTriangularFaces == 1 then
sFamily = 'Bevel'
bIsThrough = false
elseif Proc.Fct == 2 and bAllAnglesConcave then
sFamily = 'Rabbet'
bIsThrough = true
elseif Proc.Fct == 2 and not bAllAnglesConcave and bIsAnyDimensionLongAsPart then
sFamily = 'DoubleBevel'
bIsThrough = true
elseif Proc.Fct == 3 and bAllAnglesConcave and #vFacesWithTwoAdj == 1 and #vTriangularFaces == 2 then
sFamily = 'Bevel'
bIsThrough = false
elseif Proc.Fct == 3 and bAllAnglesConcave and #vFacesWithTwoAdj == 1 and bIsAnyDimensionLongAsPart then
sFamily = 'Groove'
bIsThrough = true
elseif Proc.Fct == 3 and bAllAnglesConcave and #vFacesWithTwoAdj == 3 then
sFamily = 'Groove'
bIsThrough = false
elseif Proc.Fct == 4 and bAllAnglesConcave and #vFacesWithThreeAdj == 2 then
sFamily = 'Groove'
bIsThrough = false
elseif Proc.Fct == 4 and bAllAnglesConcave and #vFacesWithTwoAdj == 4 and bIsAnyDimensionLongAsPart then
sFamily = 'Tunnel'
bIsThrough = true
elseif Proc.Fct == 5 and bAllAnglesConcave and #vFacesWithFourAdj == 1 then
sFamily = 'Pocket'
bIsThrough = false
end
local vFacesParallelToPart = GetFacesParallelToPart( Proc, sFamily)
bIsParallel = ( #vFacesParallelToPart == Proc.Fct)
if sFamily == 'OUTLINE' or sFamily == 'DRILLING' then
Proc.Topology = sFamily
Proc.TopologyLongName = sFamily
bRecognized = true
elseif sFamily then
sLongName = GetTopologyLongName( sFamily, bIsThrough, bAllRightAngles, bIsParallel, Proc.Fct)
Proc.Topology, Proc.IsThrough, Proc.AllRightAngles, Proc.IsParallel, Proc.TopologyLongName = sFamily, bIsThrough, bAllRightAngles, bIsParallel, sLongName
bRecognized = true
else
Proc.Topology = 'OTHER'
Proc.TopologyLongName = 'OTHER'
end
return bRecognized
end
-------------------------------------------------------------------------------------------------------------
return WFeatureTopology
+83 -7
View File
@@ -3,8 +3,13 @@
-- 2023/03/09 Piccola correzione alla SideDepth in FindMilling
-- In FindMilling aggiunta gestione spessore e massimo materiale nel caso di lam
-- 2023/05/25 Aggiunta funzione AddMachining che incapsula EgtAddMachining trascrivendo le priorità btl dalle feature alle lavorazioni.
-- 2023/06/07 Alla funzione AddMachining aggiunta la scrittura dell'info ISOUTLINE alle lavorazioni.
-- 2023/06/07 Alla funzione AddMachining aggiunta la scrittura di alcune info alle lavorazioni.
-- 2023/07/13 In FindMilling, FindPocketing aggiunta la possibilità di limitare la ricerca lavorazioni alla sola testa specificata.
-- 2023/10/18 In SetCurrMachiningAndTool sostituito controllo di utensile attivo con controllo utensile nel setup corrente.
-- 2023/10/30 In FindPocketing aggiunto parametro per poter escludere le frese che non lavorano di testa.
-- 2023/10/31 In IsToolDoubleOk permessa una lunghezza lievemente inferiore dell'utensile secondario rispetto al principale.
-- 2023/10/31 In FindPocketing le lavorazioni con attacco speciale (rampa molto lunga e step basso) ignorano il flag per escludere le frese che non lavorano di testa.
-- 2023/11/06 In FindPocketing aggiunto parametro dDistanceToNearestPart per ridurre il massimo diametro in caso di altro pezzo troppo vicino.
-- Tabella per definizione modulo
local WMachiningLib = {}
@@ -56,7 +61,7 @@ function WMachiningLib.FindCutting( sType, dDepth, nTool_ID)
end
---------------------------------------------------------------------
function WMachiningLib.FindMilling( sType, dDepth, sTuuid, nTool_ID, dMaxDiam, dMaxMat, bTipFeed, dMinSideElev)
function WMachiningLib.FindMilling( sType, dDepth, sTuuid, nTool_ID, dMaxDiam, dMaxMat, bTipFeed, dMinSideElev, sHead)
for i = 1, #Millings do
local Milling = Millings[i]
if Milling.On and Milling.Type == sType and SetCurrMachiningAndTool( Milling.Name) then
@@ -70,6 +75,7 @@ function WMachiningLib.FindMilling( sType, dDepth, sTuuid, nTool_ID, dMaxDiam, d
local dTTipFeed = EgtTdbGetCurrToolParam( MCH_TP.TIPFEED)
local dTMaxDepthOnSide = EgtIf( bIsBlade, EgtTdbGetCurrToolParam( MCH_TP.MAXMAT), min( EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'SIDEDEPTH', 'd') or 999, 0.5 * ( dTDiam - dTDiamTh)))
local nMyTool_ID = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'Tool_ID', 'i')
local sMyHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD)
if nMchType == MCH_MY.MILLING and
( not sTuuid or sTuuid == sMyTuuid) and
( not dDepth or dTMaxDepth > dDepth - GEO.EPS_SMALL) and
@@ -77,7 +83,8 @@ function WMachiningLib.FindMilling( sType, dDepth, sTuuid, nTool_ID, dMaxDiam, d
( not dMaxMat or dTMaxMat < dMaxMat + GEO.EPS_SMALL) and
( not bTipFeed or dTTipFeed > 1) and
( not dMinSideElev or dTMaxDepthOnSide > dMinSideElev - GEO.EPS_SMALL) and
( not nTool_ID or nTool_ID == 0 or nTool_ID == nMyTool_ID) then
( not nTool_ID or nTool_ID == 0 or nTool_ID == nMyTool_ID) and
( not sHead or sHead == sMyHead) then
return Milling.Name, dTMaxDepth, dTMaxMat, dTDiam
end
end
@@ -100,18 +107,32 @@ function WMachiningLib.FindNailing( nType)
end
---------------------------------------------------------------------
function WMachiningLib.FindPocketing( sType, dMaxDiam, dDepth, nTool_ID)
function WMachiningLib.FindPocketing( sType, dMaxDiam, dDepth, nTool_ID, sHead, bExcludeNoTipFeed, dDistanceToNearestPart)
if not dMaxDiam then dMaxDiam = 999 end
for i = 1, #Pocketings do
local Pocketing = Pocketings[i]
if Pocketing.On and Pocketing.Type == sType and SetCurrMachiningAndTool( Pocketing.Name) then
local nMchType = EgtMdbGetCurrMachiningParam( MCH_MP.TYPE)
local dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM)
local dTMaxDepth = EgtIf( WD.MILL_MAX_DEPTH_AS_MAT, EgtTdbGetCurrToolParam( MCH_TP.MAXMAT), EgtTdbGetCurrToolMaxDepth())
local nMyTool_ID = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'Tool_ID', 'i')
local nMyTool_ID = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'Tool_ID', 'i')
local sMyHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD)
local bHasTipFeed = ( EgtTdbGetCurrToolParam( MCH_TP.TIPFEED) ~= 0)
-- attacco con rampa molto lunga e step basso, utilizzabile anche con frese che non lavorano di testa
local bIsSpecialLeadIn = ( EgtMdbGetCurrMachiningParam( MCH_MP.LEADINTYPE) == MCH_POCK_LI.ZIGZAG or MCH_POCK_LI.HELIX) and
( ( EgtMdbGetCurrMachiningParam( MCH_MP.LITANG) or 0) > dTDiam - 1 - 10 * GEO.EPS_SMALL) and
( ( EgtMdbGetCurrMachiningParam( MCH_MP.LIELEV) or 999) <= 2)
local bIsSpiralOut = EgtMdbGetCurrMachiningParam( MCH_MP.SUBTYPE) == MCH_POCK_SUB.SPIRALOUT
-- se ho un altro pezzo troppo vicino riduco il diametro massimo utensile
if dDistanceToNearestPart then
dMaxDiam = min( dMaxDiam, EgtIf( bIsSpiralOut, dDistanceToNearestPart * 2 + 5, dDistanceToNearestPart + 5))
end
if nMchType == MCH_MY.POCKETING and
( not dMaxDiam or dTDiam < dMaxDiam + GEO.EPS_SMALL) and
( not dDepth or dTMaxDepth > dDepth - GEO.EPS_SMALL) and
( not nTool_ID or nTool_ID == 0 or nTool_ID == nMyTool_ID) then
( not nTool_ID or nTool_ID == 0 or nTool_ID == nMyTool_ID) and
( not sHead or sHead == sMyHead) and
( not bExcludeNoTipFeed or bHasTipFeed or bIsSpecialLeadIn) then
return Pocketing.Name, dTDiam, dTMaxDepth
end
end
@@ -183,8 +204,8 @@ function WMachiningLib.FindSurfacing( sType)
end
end
-- incapsulo EgtAddMachining e trascrivo alcune informazioni utili nelle note dell'operazione
---------------------------------------------------------------------
-- incapsulo EgtAddMachining e trascrivo alcune informazioni utili nelle note dell'operazione
function WMachiningLib.AddMachining( Proc, sName, sMachining)
local nMchId, sFinalName = EgtAddMachining( sName, sMachining)
if type( Proc) == 'table' then
@@ -195,5 +216,60 @@ function WMachiningLib.AddMachining( Proc, sName, sMachining)
return nMchId, sFinalName
end
---------------------------------------------------------------------
-- verifica se utensile sToolMasterName e gemello sToolDoubleName sono compatibili con la specchiatura
function WMachiningLib.IsToolDoubleOk( sToolMasterName, sToolDoubleName)
local bIsToolDoubleOk = false
-- dimensioni utensile master
EgtTdbSetCurrTool( sToolMasterName)
local bIsBlade = ( EgtTdbGetCurrToolParam( MCH_TP.TYPE) & MCH_TF.SAWBLADE ~= 0) or false
local dTMaxMat = EgtIf( bIsBlade, EgtTdbGetCurrToolParam( MCH_TP.THICK), EgtTdbGetCurrToolParam( MCH_TP.MAXMAT))
local dTMaxDepth = EgtIf( WD.MILL_MAX_DEPTH_AS_MAT, dTMaxMat, EgtTdbGetCurrToolMaxDepth())
local dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM)
local dTDiamTh = EgtTdbGetCurrToolThDiam() or 0
local bHasTipFeed = EgtTdbGetCurrToolParam( MCH_TP.TIPFEED) ~= 0
local dTMaxDepthOnSide = EgtIf( bIsBlade, EgtTdbGetCurrToolParam( MCH_TP.MAXMAT), min( EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'SIDEDEPTH', 'd') or 999, 0.5 * ( dTDiam - dTDiamTh)))
local bIsPrimaryHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) == 'H1'
-- dimensioni utensile double
EgtTdbSetCurrTool( sToolDoubleName)
local bIsBladeDouble = ( EgtTdbGetCurrToolParam( MCH_TP.TYPE) & MCH_TF.SAWBLADE ~= 0) or false
local dTMaxMatDouble = EgtIf( bIsBladeDouble, EgtTdbGetCurrToolParam( MCH_TP.THICK), EgtTdbGetCurrToolParam( MCH_TP.MAXMAT))
local dTMaxDepthDouble = EgtIf( WD.MILL_MAX_DEPTH_AS_MAT, dTMaxMatDouble, EgtTdbGetCurrToolMaxDepth())
local dTDiamDouble = EgtTdbGetCurrToolParam( MCH_TP.DIAM)
local dTDiamThDouble = EgtTdbGetCurrToolThDiam() or 0
local bHasTipFeedDouble = EgtTdbGetCurrToolParam( MCH_TP.TIPFEED) ~= 0
local dTMaxDepthOnSideDouble = EgtIf( bIsBladeDouble, EgtTdbGetCurrToolParam( MCH_TP.MAXMAT), min( EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'SIDEDEPTH', 'd') or 999, 0.5 * ( dTDiamDouble - dTDiamThDouble)))
-- controllo che siano uguali ( permetto una leggera differenza di lunghezza)
local dMaxLengthDifference = 6.5
bIsToolDoubleOk = bIsPrimaryHead and
( bIsBlade == bIsBladeDouble) and
( dTMaxMatDouble > dTMaxMat - 100 * GEO.EPS_SMALL) and
( dTMaxDepthDouble > dTMaxDepth - dMaxLengthDifference) and
( abs( dTDiam - dTDiamDouble) < 100 * GEO.EPS_SMALL) and
( abs( dTDiamTh - dTDiamThDouble) < 100 * GEO.EPS_SMALL) and
( bHasTipFeed == bHasTipFeedDouble) and
( abs( dTMaxDepthOnSide - dTMaxDepthOnSideDouble) < GEO.EPS_SMALL) and
EgtFindToolInCurrSetup( sToolDoubleName)
return bIsToolDoubleOk
end
---------------------------------------------------------------------
-- verifica se la lavorazione sMachining è adatta alla specchiatura
function WMachiningLib.IsMachiningOkForDouble( sMachining)
local bDoubleOk = false
if sMachining and EgtMdbSetCurrMachining( sMachining) then
-- recupero l'utensile della lavorazione
local sToolMasterName = EgtMdbGetCurrMachiningParam( MCH_MP.TOOL)
if EgtTdbSetCurrTool( sToolMasterName or '') then
-- cerco eventuale utensile in doppio
local sToolDoubleName = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'DOUBLE', 's')
if sToolDoubleName and EgtTdbSetCurrTool( sToolDoubleName) then
bDoubleOk = WMachiningLib.IsToolDoubleOk( sToolMasterName, sToolDoubleName)
end
end
end
return bDoubleOk
end
-------------------------------------------------------------------------------------------------------------
return WMachiningLib
+6
View File
@@ -24,6 +24,12 @@ function WPDC.Identify( Proc)
( Proc.Grp == 0 and Proc.Prc == 12))
end
---------------------------------------------------------------------
-- Riconoscimento della sola feature L011
function WPDC.IdentifyStrict( Proc)
return ( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 11
end
---------------------------------------------------------------------
-- Classificazione della feature
function WPDC.Classify( Proc, b3Raw)
+57 -6
View File
@@ -55,7 +55,7 @@ end
---------------------------------------------------------------------
-- Classificazione della feature
function WPD.Classify( Proc, b3Raw)
function WPD.Classify( Proc, b3Raw)
-- recupero e verifico l'entità foro
local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') or 0
@@ -156,6 +156,41 @@ function WPD.RotateClassify( Proc)
end
end
---------------------------------------------------------------------
local function IsToolDoubleOk( sToolMasterName, sToolDoubleName)
local bIsToolDoubleOk = false
-- dimensioni utensile master
EgtTdbSetCurrTool( sToolMasterName)
local dTMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT)
local dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM)
-- dimensioni utensile double
EgtTdbSetCurrTool( sToolDoubleName)
local dTMaxMatDouble = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT)
local dTDiamDouble = EgtTdbGetCurrToolParam( MCH_TP.DIAM)
-- controllo che siano uguali
bIsToolDoubleOk = ( dTMaxMatDouble > dTMaxMat - 100 * GEO.EPS_SMALL) and
( abs( dTDiam - dTDiamDouble) < 100 * GEO.EPS_SMALL) and
EgtFindToolInCurrSetup( sToolDoubleName)
return bIsToolDoubleOk
end
---------------------------------------------------------------------
local function IsMachiningOkForDouble( sMachining)
local bDoubleOk = false
if sMachining and EgtMdbSetCurrMachining( sMachining) then
-- recupero l'utensile della lavorazione
local sToolMasterName = EgtMdbGetCurrMachiningParam( MCH_MP.TOOL)
if EgtTdbSetCurrTool( sToolMasterName or '') then
-- cerco eventuale utensile in doppio
local sToolDoubleName = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'DOUBLE', 's')
if sToolDoubleName and EgtTdbSetCurrTool( sToolDoubleName) then
bDoubleOk = IsToolDoubleOk( sToolMasterName, sToolDoubleName)
end
end
end
return bDoubleOk
end
---------------------------------------------------------------------
local function IsHorizLongDrill( Proc)
-- recupero e verifico l'entità foro
@@ -263,10 +298,21 @@ function WPD.Make( Proc, nRawId, b3Raw)
end
end
end
local bUseDLenToFindDrilling = true
local sDrilling, nType = WM.FindDrilling( dDiam, dLen, sHead)
if not sDrilling then
bUseDLenToFindDrilling = false
sDrilling, nType = WM.FindDrilling( dDiam, nil, sHead)
end
-- se Proc è settata per essere specchiata cerco la lavorazione adatta e verifico possa essere effettivamente specchiata
if Proc.Double and Proc.Double == 2 then
local sDrillingBackup = sDrilling
sDrilling = WM.FindDrilling( dDiam, EgtIf( bUseDLenToFindDrilling, dLen, nil), 'H1')
if not IsMachiningOkForDouble( sDrilling) then
Proc.Double = 0
sDrilling = sDrillingBackup
end
end
if sHead and not sDrilling then
sDrilling, nType = WM.FindDrilling( dDiam, dLen)
if not sDrilling then
@@ -447,21 +493,26 @@ function WPD.Make( Proc, nRawId, b3Raw)
end
end
EgtSetMachiningParam( MCH_MP.DEPTH, dDepth)
-- Note utente
local sUserNotes = ''
-- leggo eventuali note esistenti della lavorazione
local sUserNotes = EgtGetMachiningParam( MCH_MP.USERNOTES)
-- se foratura o svuotatura, dichiarazione nessuna generazione sfridi per Vmill
if nType == 'Drill' or nType == 'Pocket' then
sUserNotes = 'VMRS=0;'
sUserNotes = EgtSetValInNotes( sUserNotes, 'VMRS', 0)
end
-- se foratura
if nType == 'Drill' then
-- aggiungo alle note massima elevazione (coincide con affondamento)
sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( dDepth, 1) .. ';'
sUserNotes = EgtSetValInNotes( sUserNotes, 'MaxElev', EgtNumToString( dDepth, 1))
-- se foro passante, aggiungo questa qualifica alle note
if bOpen then
sUserNotes = sUserNotes .. 'Open=1;'
sUserNotes = EgtSetValInNotes( sUserNotes, 'Open', 1)
end
end
-- se lavorazione in doppio aggiungo le rispettive note
if Proc.Double and Proc.Double == 2 then
sUserNotes = EgtSetValInNotes( sUserNotes, 'DOUBLE', Proc.Double)
sUserNotes = EgtSetValInNotes( sUserNotes, 'MirrorAx', Proc.MirrorAx)
end
EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes)
-- eseguo
if not EgtApplyMachining( true, false) then
+15 -90
View File
@@ -20,6 +20,7 @@
-- 2023/04/17 Lavorazione CleanCorner sempre forzata con lato di lavoro in centro.
-- 2023/05/25 Funzioni EgtAddMachining sostituite da WM.AddMachining in modo da trascrivere le priorità da btl alle lavorazioni.
-- 2023/06/06 Aggiunta gestione lavorazione per lamatura speciale affondata con Tool_ID specifico.
-- 2023/06/26 Funzione Is3EdgesApprox spostata in WallLib.
-- 2023/07/26 In MakeByCut migliorata la scelta della fresa secondaria nel caso non sia disponibile una fresa di lunghezza sufficiente.
-- 2023/09/12 Modifiche a GetTunnelDimension (asse deve essere com Z globale) e MakeLocalSurf per gestire finestre con lati inclinati.
-- 2023/09/21 In MakeByMill modificato SCC per correggere caso con lama su testa fresa.
@@ -155,64 +156,6 @@ function WPF.FlipClassify( Proc, b3Raw)
return nFlip0, nFlip1
end
---------------------------------------------------------------------
local function TestElleShape3( nIdGeom, nNumFacet)
-- valida solo nel caso di tre facce
if nNumFacet ~= 3 then return false end
-- determino se L con una faccia terminale o U con tre facce
local bIsL = true
for i = 1, 3 do
local vFacAdj = EgtSurfTmFacetAdjacencies( nIdGeom, i - 1)[1]
-- le conto
local nCount = 0
for j = 1, #vFacAdj do
if vFacAdj[j] >= 0 then
nCount = nCount + 1
end
end
if nCount == 1 then
bIsL = false
break
end
end
return bIsL
end
---------------------------------------------------------------------
local function TestElleShape4( nIdGeom, nNumFacet)
-- valida solo nel caso di quattro facce
if nNumFacet ~= 4 then return false end
-- determino se L con due facce terminali o O
local nFac3Adj = 0
local dMinArea3 = GEO.INFINITO * GEO.INFINITO
local dMaxArea2 = 0
for i = 1, 4 do
local vFacAdj = EgtSurfTmFacetAdjacencies( nIdGeom, i - 1)[1]
-- le conto
local nCount = 0
for j = 1, #vFacAdj do
if vFacAdj[j] >= 0 then
nCount = nCount + 1
end
end
local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( nIdGeom, i - 1, GDB_ID.ROOT)
local dArea = dH * dV
if nCount == 2 then
dMaxArea2 = max( dMaxArea2, dArea)
elseif nCount == 3 then
dMinArea3 = min( dMinArea3, dArea)
nFac3Adj = nFac3Adj + 1
end
end
if nFac3Adj ~= 2 then return false end
-- verifico se L profonda oppure lunga
if dMinArea3 < dMaxArea2 then
return 1
else
return 2
end
end
---------------------------------------------------------------------
local function VerifyCornerType( Proc)
-- Verifico il tipo di lavorazione su angolo :
@@ -1212,35 +1155,6 @@ local function GetMaxDepth( vtNz, dMillDiam, dDiamTh, dMaxDepth, dFreeLen)
end
end
---------------------------------------------------------------------
-- Funzione per determinare se la faccia ha lati molto corti (trascurabili) ed è quindi approssimabile ad una 3 facce
local function Is3EdgesApprox( Proc, nFacet, nAddGrpId)
nAddGrpId = nAddGrpId or WL.GetAddGroup( Proc.PartId)
-- recupero il contorno della faccia
local nContourId, nContourCnt = EgtExtractSurfTmFacetLoops( Proc.Id, nFacet, nAddGrpId)
if not nContourId then return false end
EgtMergeCurvesInCurveCompo( nContourId)
-- recupero il numero di lati del contorno
local _, nEntityCount = EgtCurveDomain( nContourId)
if not nEntityCount then return false end
-- se sono già tre, ho finito
if nEntityCount == 3 then return true end
-- rimuovo i lati molto corti dal conteggio totale
local nEdges = nEntityCount
for i = 1, nEntityCount do
local dLength = EgtCurveCompoLength( nContourId, i - 1)
if dLength < 15 then nEdges = nEdges - 1 end
end
-- verifico il numero significativo di lati
local bResult = ( nEdges == 3)
-- cancello tutti i contorni appena creati
EgtErase( EgtTableFill( nContourId, nContourCnt))
if bResult then
EgtOutLog( 'FreeContour : Face with ' .. tostring( nEntityCount) .. ' edges skipped (approx 3 edges)')
end
return bResult
end
---------------------------------------------------------------------
local function AddMillings( sMilling, vFace, Proc, nRawId, b3Raw, nConeCut, nAddGrpId)
-- flag per fresature non passanti
@@ -1263,7 +1177,7 @@ local function AddMillings( sMilling, vFace, Proc, nRawId, b3Raw, nConeCut, nAdd
end
-- verifico se le facce hanno alcuni lati molto corti e possono quindi essere approssimate a 3 lati
for currentFace = 1, #vFace do
if Is3EdgesApprox( Proc, vFace[currentFace].Fac, nAddGrpId) then
if WL.Is3EdgesApprox( Proc, vFace[currentFace].Fac, nAddGrpId) then
vFace[currentFace].Is3EdgesApprox = true
end
end
@@ -1369,6 +1283,8 @@ local function AddMillings( sMilling, vFace, Proc, nRawId, b3Raw, nConeCut, nAdd
nSCC = EgtIf( abs( vFace[i].Norm:getX()) > abs( vFace[i].Norm:getY()), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_YP)
end
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
-- scrivo nell'operazione il vettore normale alla superfice che servirà per il doppio
EgtSetInfo( nMchId or GDB_ID.NULL, 'NORM_SUM', vFace[i].Norm)
-- eseguo
if not EgtApplyMachining( true, false) then
local _, sErr = EgtGetLastMachMgrError()
@@ -1566,6 +1482,13 @@ local function AddMillings( sMilling, vFace, Proc, nRawId, b3Raw, nConeCut, nAdd
-- posizione braccio porta testa
EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_XP)
end
--scrivo nell'operazione il vettore somma delle normali alle superfici che servirà per il doppio
local vtNSum = Vector3d( 0, 0, 0)
for iGeom = 1, #vGeom do
local nFace = vGeom[iGeom][2]
vtNSum = vtNSum + Proc.Face[ nFace + 1].VtN
end
EgtSetInfo( nMchId or GDB_ID.NULL, 'NORM_SUM', vtNSum)
-- eseguo
if not EgtApplyMachining( true, false) then
local _, sErr = EgtGetLastMachMgrError()
@@ -1628,6 +1551,8 @@ local function AddMillings( sMilling, vFace, Proc, nRawId, b3Raw, nConeCut, nAdd
nSCC = EgtIf( abs( vFace[i].Norm:getX()) > abs( vFace[i].Norm:getY()), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_YP)
end
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
-- scrivo nell'operazione il vettore normale alla superfice che servirà per il doppio
EgtSetInfo( nMchId or GDB_ID.NULL, 'NORM_SUM', vFace[i].Norm)
-- eseguo
if not EgtApplyMachining( true, false) then
local _, sErr = EgtGetLastMachMgrError()
@@ -2478,9 +2403,9 @@ local function MakeByPocket( Proc, nRawId, b3Raw)
local nAddGrpId = WL.GetAddGroup( Proc.PartId)
local nNewProc, nNumFacet = RemoveBottomFaceAndReorder( Proc, nAddGrpId, nFacet)
-- se ho forma a L
local bIsL = ( nNumFacet == 2 or TestElleShape3( nNewProc, nNumFacet) or TestElleShape4( nNewProc, nNumFacet) == 2)
local bIsL = ( nNumFacet == 2 or WL.TestElleShape3( nNewProc, nNumFacet) or WL.TestElleShape4( nNewProc, nNumFacet) == 2)
-- verifico se U
local bIsU = ( nNumFacet == 3 and not TestElleShape3( nNewProc, nNumFacet))
local bIsU = ( nNumFacet == 3 and not WL.TestElleShape3( nNewProc, nNumFacet))
local dMiddleFacetLength = 0
if bIsU then
local _, dH2, dV2 = EgtSurfTmFacetMinAreaRectangle( nNewProc, 1, GDB_ID.ROOT)
+363 -106
View File
@@ -30,6 +30,13 @@
-- 2023/09/21 Modifica controllo lavorabilità con tre facce tipo tunnel ma non ortogonali tra loro.
-- 2023/09/21 In MakeByMill modificato SCC per correggere caso con lama su testa fresa.
-- 2023/10/02 Aggiunta segnalazione lavorazione tipo Side non trovata.
-- 2023/10/30 In VerifyPocket, per tasche in doppio forzata ricerca fresa che possa lavorare di testa.
-- 2023/10/31 In VerifyPocket, se topologia pocket, forzata ricerca fresa che possa lavorare di testa.
-- 2023/11/06 In VerifyPocket controllo massimo diametro in base a distanza pezzo più vicino demandato a FindPocketing.
-- 2023/11/07 In MakeByPocketing, se tasca che guarda davanti, aggiunta possibilità di attaccare fuori dal grezzo fino ad uno spessore di 75 mm.
-- In MakeByPocketing calcolo del massimo diametro utensile spostato in VerifyPocketing.
-- In MakeByPocketing il doppio viene ora disattivato se una tasca deve essere forzata chiusa e l'altra no.
-- 2023/11/13 In MakeSideGrooveByMill, se rabbet doppio uno verso l'alto e uno verso il basso, aggiunto step extra iniziale per ripulire la lamina che potrebbe rimanere nella rabbet che guarda in alto.
-- Tabella per definizione modulo
local WPL = {}
@@ -358,64 +365,6 @@ function WPL.FlipClassify( Proc)
return nFlip0, nFlip1
end
---------------------------------------------------------------------
local function TestElleShape3( nIdGeom, nNumFacet)
-- valida solo nel caso di tre facce
if nNumFacet ~= 3 then return false end
-- determino se L con una faccia terminale o U con tre facce
local bIsL = true
for i = 1, 3 do
local vFacAdj = EgtSurfTmFacetAdjacencies( nIdGeom, i - 1)[1]
-- le conto
local nCount = 0
for j = 1, #vFacAdj do
if vFacAdj[j] >= 0 then
nCount = nCount + 1
end
end
if nCount == 1 then
bIsL = false
break
end
end
return bIsL
end
---------------------------------------------------------------------
local function TestElleShape4( nIdGeom, nNumFacet)
-- valida solo nel caso di quattro facce
if nNumFacet ~= 4 then return false end
-- determino se L con due facce terminali o O
local nFac3Adj = 0
local dMinArea3 = GEO.INFINITO * GEO.INFINITO
local dMaxArea2 = 0
for i = 1, 4 do
local vFacAdj = EgtSurfTmFacetAdjacencies( nIdGeom, i - 1)[1]
-- le conto
local nCount = 0
for j = 1, #vFacAdj do
if vFacAdj[j] >= 0 then
nCount = nCount + 1
end
end
local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( nIdGeom, i - 1, GDB_ID.ROOT)
local dArea = dH * dV
if nCount == 2 then
dMaxArea2 = max( dMaxArea2, dArea)
elseif nCount == 3 then
dMinArea3 = min( dMinArea3, dArea)
nFac3Adj = nFac3Adj + 1
end
end
if nFac3Adj ~= 2 then return false end
-- verifico se L profonda oppure lunga
if dMinArea3 < dMaxArea2 then
return 1
else
return 2
end
end
---------------------------------------------------------------------
local function GetOtherRegions( nPartId)
local vOthers = {}
@@ -1336,6 +1285,54 @@ local function MakeByChainSaw( Proc, nFacet, nRawId, b3Raw, dElev, dH, dV)
return true
end
---------------------------------------------------------------------
-- restituisce true se la lavorazione potrebbe danneggiare le parti limitrofe
local function IsMachiningDamagingOtherParts( Proc, dMillDiameter, nRawId)
local bIsMachiningDamagingOtherParts = false
-- box da estendere in tutte le direzioni, compreso angolo cieco
local b3ProcExtended = EgtGetBBoxGlob( Proc.Id, GDB_BB.STANDARD)
-- punto minimo e massimo assoluti del box
local ptMin = b3ProcExtended:getMin()
local ptMax = b3ProcExtended:getMax()
-- estensione aggiunta ai box
local dBoxExtensionLength = dMillDiameter / 2 + 5
-- check box verso X-
if Proc.AffectedFaces.Left then
local vtMove = Vector3d( -dBoxExtensionLength, 0, 0)
ptMin:move( vtMove)
end
-- check box verso X+
if Proc.AffectedFaces.Right then
local vtMove = Vector3d( dBoxExtensionLength, 0, 0)
ptMax:move( vtMove)
end
-- check box verso Y-
if Proc.AffectedFaces.Front then
local vtMove = Vector3d( 0, -dBoxExtensionLength, 0)
ptMin:move( vtMove)
end
-- check box verso Y+
if Proc.AffectedFaces.Back then
local vtMove = Vector3d( 0, dBoxExtensionLength, 0)
ptMax:move( vtMove)
end
-- estendo il box in direzione X e Y e verifico se interseca altre parti
b3ProcExtended:Add( ptMin)
b3ProcExtended:Add( ptMax)
local nPartId = EgtGetFirstPartInRawPart( nRawId)
while nPartId do
local nBoxSolidId = EgtGetFirstNameInGroup( nPartId, 'Box')
local b3Solid = EgtGetBBoxGlob( nBoxSolidId or GDB_ID.NULL, GDB_BB.STANDARD)
b3Solid:expand( - 10 * GEO.EPS_SMALL)
if ( nPartId ~= Proc.PartId) and OverlapsXY( b3ProcExtended, b3Solid) then
bIsMachiningDamagingOtherParts = true
end
nPartId = EgtGetNextPartInRawPart( nPartId)
end
return bIsMachiningDamagingOtherParts
end
---------------------------------------------------------------------
local function MakeByMill( Proc, nFacet, nOthFac, nRawId, b3Raw, dSideDist)
-- dati della faccia e dell'altra
@@ -1346,6 +1343,14 @@ local function MakeByMill( Proc, nFacet, nOthFac, nRawId, b3Raw, dSideDist)
local _, vtRef = EgtSurfTmFacetCenter( Proc.Id, nOthFac, GDB_ID.ROOT)
-- recupero la lavorazione
local sMilling = WM.FindMilling( 'Side')
if Proc.Double and Proc.Double == 2 then
local sMillingBackup = sMilling
sMilling = WM.FindMilling( 'Side', nil, nil, nil, nil, nil, nil, nil, 'H1')
if not WM.IsMachiningOkForDouble( sMilling) then
Proc.Double = 0
sMilling = sMillingBackup
end
end
if not sMilling then
local sErr = 'Error : Side not found in library'
EgtOutLog( sErr)
@@ -1413,6 +1418,16 @@ local function MakeByMill( Proc, nFacet, nOthFac, nRawId, b3Raw, dSideDist)
-- imposto modo di lavorare la faccia
local nFaceUse = WL.GetNearestOrthoOpposite( vtRef, vtN)
EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse)
-- leggo eventuali note esistenti della lavorazione
local sUserNotes = EgtGetMachiningParam( MCH_MP.USERNOTES)
-- se lavorazione in doppio aggiungo le rispettive note
if Proc.Double and Proc.Double == 2 then
sUserNotes = EgtSetValInNotes( sUserNotes, 'DOUBLE', Proc.Double)
sUserNotes = EgtSetValInNotes( sUserNotes, 'MirrorAx', Proc.MirrorAx)
sUserNotes = EgtSetValInNotes( sUserNotes, 'DeltaZ', Proc.MirrorDeltaZ)
end
-- scrivo le note della lavorazione
EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes)
-- eseguo
if not EgtApplyMachining( true, false) then
local _, sErr = EgtGetLastMachMgrError()
@@ -1423,7 +1438,7 @@ local function MakeByMill( Proc, nFacet, nOthFac, nRawId, b3Raw, dSideDist)
end
---------------------------------------------------------------------
local function MakeSideGrooveByMill( Proc, nFacet, nRawId, b3Raw, sCustomMach, dMaxDepthOnSide, bEnablePreMill, bMachFromDn, dAng, bAsEnablePreMill, nSinglePass, bExcludeFinishing)
local function MakeSideGrooveByMill( Proc, nFacet, nRawId, b3Raw, sCustomMach, dMaxDepthOnSide, bEnablePreMill, bMachFromDn, dAng, bAsEnablePreMill, nSinglePass, bExcludeFinishing, bDoubleCustomMach)
local sWarn
-- dati della faccia principale (la più verticale)
local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacet, GDB_ID.ROOT)
@@ -1444,9 +1459,20 @@ local function MakeSideGrooveByMill( Proc, nFacet, nRawId, b3Raw, sCustomMach, d
-- se ho lavorazione custom
if sCustomMach then
sMilling = sCustomMach
-- se avevo stabilito che la customMach non era adatta al double, setto per non specchiare
if not bDoubleCustomMach then Proc.Double = 0 end
-- altrimenti la cerco
else
sMilling = WM.FindMilling( 'SideGroove', nil, nil, nil, nil, min( dH, dV))
-- se Proc è settata per essere specchiata cerco la lavorazione adatta e verifico possa essere effettivamente specchiata
if Proc.Double and Proc.Double == 2 then
local sMillOnSideBackup = sMilling
sMilling = WM.FindMilling( 'SideGroove', nil, nil, nil, nil, min( dH, dV), nil, nil, 'H1')
if not WM.IsMachiningOkForDouble( sMilling) then
Proc.Double = 0
sMilling = sMillOnSideBackup
end
end
end
if not sMilling then
local sErr = 'Error : SideGroove not found in library'
@@ -1497,10 +1523,14 @@ local function MakeSideGrooveByMill( Proc, nFacet, nRawId, b3Raw, sCustomMach, d
end
end
-- se profondità ribasso è maggiore della capacità di sottosquadro dell'utensile
if ( not bEnablePreMill and bMachFromDn) and ( dElev > 0.5 * ( dMillDiam - dMillDiamTh) - 10 * GEO.EPS_SMALL) then
local sErr = 'Error : Side Elevation (' .. dElev .. ') bigger than max tool side depth (' .. ( 0.5 * ( dMillDiam - dMillDiamTh)) ..')'
EgtOutLog( sErr)
return false, sErr
if ( dElev > 0.5 * ( dMillDiam - dMillDiamTh) - 10 * GEO.EPS_SMALL) then
if ( not bEnablePreMill and ( bMachFromDn or Proc.Fct > 2)) then
local sErr = 'Error : Side Elevation (' .. dElev .. ') bigger than max tool side depth (' .. ( 0.5 * ( dMillDiam - dMillDiamTh)) ..')'
EgtOutLog( sErr)
return false, sErr
elseif Proc.Double then
Proc.Double = 0
end
end
local dMillExtra = dMillTotLen - dMillLen
if Proc.Box:getMin():getZ() - dMillExtra < b3Raw:getMin():getZ() - 10 * GEO.EPS_SMALL then
@@ -1871,6 +1901,78 @@ local function MakeSideGrooveByMill( Proc, nFacet, nRawId, b3Raw, sCustomMach, d
bUpwardMilling = true
end
-- step extra in caso di doppio con mix rabbet dal basso e dall'alto, per eliminare la lamina che potrebbe rimanere
if Proc.Double and Proc.Double == 2 and Proc.Topology == 'Rabbet' and
not ( Proc.AffectedFaces.Bottom and Proc.Mirror.AffectedFaces.Bottom) and not ( Proc.AffectedFaces.Top and Proc.AffectedFaces.Bottom) then
-- determino a quale delle due feature applicare la lavorazione
local bProcVsMirrorToCopy = true
local nFacetToMachine = nFacet
if Proc.AffectedFaces.Bottom then
bProcVsMirrorToCopy = false
for i = 1, Proc.Mirror.Fct do
local vtNMirror = Proc.Mirror.Face[i].VtN
if AreOppositeVectorApprox( vtN, vtNMirror) then
nFacetToMachine = Proc.Mirror.Face[i].Id
break
end
end
end
local nAddGrpId = WL.GetAddGroup( EgtIf( bProcVsMirrorToCopy, Proc.PartId, Proc.Mirror.PartId))
local nNewProc = EgtCopyGlob( EgtIf( bProcVsMirrorToCopy, Proc.Id, Proc.Mirror.Id), nAddGrpId) or GDB_ID.NULL
local NewProc = { Id = nNewProc, PartId = EgtIf( bProcVsMirrorToCopy, Proc.PartId, Proc.Mirror.PartId)}
-- lavorazione
local sName = 'PreSideMill_' .. EgtGetName( NewProc.Id) or tostring( NewProc.Id)
local nMchFId = WM.AddMachining( NewProc, sName, sMilling)
if not nMchFId then
local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling
EgtOutLog( sErr)
return false, sErr
end
EgtSetInfo( nMchFId, 'Part', NewProc.PartId)
-- aggiungo geometria
EgtSetMachiningGeometry( {{ NewProc.Id, nFacetToMachine}})
-- imposto posizione braccio porta testa
local nSCC = MCH_SCC.ADIR_NEAR
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
-- imposto modo di lavorare la faccia
local nFaceUse = WL.GetNearestParalOpposite( Z_AX())
EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse)
-- imposto elevazione e step
local dDepth = 5
EgtSetMachiningParam( MCH_MP.DEPTH, dDepth)
EgtSetMachiningParam( MCH_MP.STEP, dElev)
-- setto il lato di lavoro standard
EgtSetMachiningParam( MCH_MP.INVERT, true)
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT)
-- setto allungamenti iniziali e finali
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dExtraLongIni)
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dExtraLongEnd)
-- Confronto il raggio fresa con l'elevazione dalla normale per vedere se devo modificare l'uscita
if dElev > ( 0.5 * dMillDiam) then
-- setto allungamenti perpendicolari
EgtSetMachiningParam( MCH_MP.LIPERP, 0)
EgtSetMachiningParam( MCH_MP.LOPERP, 0)
end
-- se richiesto, setto la nota per spostare la lavorazione alla fine
if not WD.SIDEMILL_BEFORE then
EgtSetInfo( nMchFId, 'MOVE_AFTER', 1)
end
-- eseguo
if not EgtApplyMachining( true, false) then
-- provo a invertire posizione braccio porta testa
nSCC = MCH_SCC.ADIR_FAR
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
if not EgtApplyMachining( true, false) then
local _, sErr = EgtGetLastMachMgrError()
EgtSetOperationMode( nMchFId, false)
return false, sErr
end
end
-- se faccio lo step extra e ho rimosso la lamina, in doppio lavorerò dal basso verso l'alto
bUpwardMilling = true
end
-- lavorazione
local dStepOri
if not bExcludeSideMill then
local nSideStep = 1
@@ -1921,6 +2023,12 @@ local function MakeSideGrooveByMill( Proc, nFacet, nRawId, b3Raw, sCustomMach, d
local sUserNotes = EgtGetMachiningParam( MCH_MP.USERNOTES)
-- aggiungo alle note massima elevazione
sUserNotes = EgtSetValInNotes( sUserNotes, 'MaxElev', EgtNumToString( dMaxElev, 3))
-- se lavorazione in doppio aggiungo le rispettive note
if Proc.Double and Proc.Double == 2 then
sUserNotes = EgtSetValInNotes( sUserNotes, 'DOUBLE', Proc.Double)
sUserNotes = EgtSetValInNotes( sUserNotes, 'MirrorAx', Proc.MirrorAx)
sUserNotes = EgtSetValInNotes( sUserNotes, 'DeltaZ', Proc.MirrorDeltaZ)
end
-- scrivo le note della lavorazione
EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes)
-- setto il lato di lavoro standard
@@ -2154,61 +2262,140 @@ local function MakeSideGrooveByMill( Proc, nFacet, nRawId, b3Raw, sCustomMach, d
end
---------------------------------------------------------------------
local function MakeByPocketing( Proc, nFacet, nRawId, b3Raw, bCheckQPar)
-- dati della faccia
local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacet, GDB_ID.ROOT)
local dElev = WL.GetFaceElevation( Proc.Id, nFacet, nRawId)
-- trova la migliore lavorazione tasca in base a diametro utensile, elevazione, doppio e eventuale interferenza di parti vicine
-- se necessario forza la tasca a chiusa
local function VerifyPocket( Proc, nFacet, dElev, nRawId)
local bForceClosedPocket = false
local b3Raw = EgtGetRawPartBBox( nRawId)
-- verifico se la feature è sul bordo (non ci sono altri pezzi davanti alla tasca). Se è sul bordo, l'utensile potrà attaccare da fuori.
local bIsFeatureOnEdge = ( Proc.Topology == 'Groove' and Proc.Fct == 4 and Proc.DistanceToNearestParts.Front > b3Raw:getDimY())
-- trovo il massimo diametro utensile ammissibile per la tasca
local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacet, GDB_ID.ROOT)
local dDiam = min( dH, dV)
-- gruppo ausiliario
local nAddGrpId = WL.GetAddGroup( Proc.PartId)
local nNewProc, nNumFacet = RemoveBottomFaceAndReorder( Proc, nAddGrpId, nFacet)
-- se una sola faccia
local dStartDiameter = min( dH, dV)
local dMaxDiameter = dStartDiameter
-- se una sola faccia posso usare un utensile più grande della faccia
if Proc.Fct == 1 then
dDiam = 2 * dDiam
dMaxDiameter = 2 * dMaxDiameter
end
-- se forma ad L
local bIsL = ( Proc.Fct == 2 or TestElleShape3( Proc.Id, Proc.Fct) or TestElleShape4( Proc.Id, Proc.Fct) == 2)
-- se forma ad L posso usare un utensile più grande della faccia
local bIsL = ( Proc.Fct == 2 or WL.TestElleShape3( Proc.Id, Proc.Fct) or WL.TestElleShape4( Proc.Id, Proc.Fct) == 2)
if bIsL then
dDiam = 2 * dDiam
dMaxDiameter = 2 * dMaxDiameter
end
-- se forma ad U
local bIsU = ( Proc.Fct == 3 and not TestElleShape3( Proc.Id, Proc.Fct))
-- se forma ad U riduco il diametro se necessario
local bIsU = ( Proc.Fct == 3 and not WL.TestElleShape3( Proc.Id, Proc.Fct))
if bIsU then
local _, dH2, dV2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacet, GDB_ID.ROOT)
-- prendo la linea di base
local dMiddleFacetLength = 0
if abs( dElev - dH2) < 1 and abs( dElev - dV2) > 1 then
dMiddleFacetLength = dV2
elseif abs( dElev - dV2) < 1 and abs( dElev - dH2) > 1 then
dMiddleFacetLength = dH2
if abs( dElev - dH) < 1 and abs( dElev - dV) > 1 then
dMiddleFacetLength = dV
elseif abs( dElev - dV) < 1 and abs( dElev - dH) > 1 then
dMiddleFacetLength = dH
end
if dMiddleFacetLength > dDiam then
dDiam = min( 2 * dDiam, dMiddleFacetLength)
if dMiddleFacetLength > dMaxDiameter then
dMaxDiameter = min( 2 * dMaxDiameter, dMiddleFacetLength)
end
end
-- in presenza di angoli interni, limito secondo impostazione globale il diametro massimo utensile
if Proc.Fct == 3 and bIsL then
dDiam = min( dDiam, WD.MAXDIAM_POCK_CORNER or 1000)
dMaxDiameter = min( dMaxDiameter, WD.MAXDIAM_POCK_CORNER or 1000)
elseif Proc.Fct >= 4 then
dDiam = min( dDiam, WD.MAXDIAM_POCK_CORNER or 1000)
dMaxDiameter = min( dMaxDiameter, WD.MAXDIAM_POCK_CORNER or 1000)
end
-- verifico la distanza minima dalle parti vicine e nel caso il FindPocketing limiterà il diametro massimo dell'utensile
local dDistanceToNearestPart = GEO.INFINITO
if Proc.AffectedFaces.Front then
dDistanceToNearestPart = Proc.DistanceToNearestParts.Front
end
if Proc.AffectedFaces.Back then
dDistanceToNearestPart = min( dDistanceToNearestPart, Proc.DistanceToNearestParts.Back)
end
if Proc.AffectedFaces.Left then
dDistanceToNearestPart = min( dDistanceToNearestPart, Proc.DistanceToNearestParts.Left)
end
if Proc.AffectedFaces.Right then
dDistanceToNearestPart = min( dDistanceToNearestPart, Proc.DistanceToNearestParts.Right)
end
-- se la distanza è inferiore ad un valore minimo forzo la tasca chiusa per evitare che la ricerca utensile fallisca
local dMinToolDiameter = 25
if dDistanceToNearestPart < dMinToolDiameter / 2 - 10 * GEO.EPS_SMALL then
bForceClosedPocket = true
dDistanceToNearestPart = dMaxDiameter
end
local bExcludeNoTipFeed = ( Proc.Topology == 'Pocket')
-- recupero la lavorazione
local sPocketing = WM.FindPocketing( 'Pocket', dDiam, dElev)
local bUseDElevToFindPocketing = true
local sPocketing = WM.FindPocketing( 'Pocket', dMaxDiameter, dElev, nil, nil, bExcludeNoTipFeed, dDistanceToNearestPart)
-- se tasca troppo profonda cerco senza elevazione e limiterò la profondità
if not sPocketing then
sPocketing = WM.FindPocketing( 'Pocket', dDiam)
if not sPocketing then
local sErr = 'Error : pocketing not found in library'
EgtOutLog( sErr)
return false, sErr
end
bUseDElevToFindPocketing = false
sPocketing = WM.FindPocketing( 'Pocket', dMaxDiameter, nil, nil, nil, bExcludeNoTipFeed, dDistanceToNearestPart)
end
-- recupero i dati dell'utensile
local dMillDiam = 20
local dMaxDepth = 0
local dThDiam = 100
local sTuuid
if EgtMdbSetCurrMachining( sPocketing) then
-- se lavorazione trovata verifico eventuale doppio, raccolgo i dati utensile e verifico collisioni dell'utensile con altre parti
if sPocketing then
-- se doppio cerco una lavorazione adatta
if Proc.Double and Proc.Double == 2 then
local sPocketingBackup = sPocketing
sPocketing = WM.FindPocketing( 'Pocket', dMaxDiameter, EgtIf( bUseDElevToFindPocketing, dElev, nil), nil, 'H1', true, dDistanceToNearestPart)
if not WM.IsMachiningOkForDouble( sPocketing) then
Proc.Double = 0
sPocketing = sPocketingBackup
end
end
-- recupero diametro utensile
if EgtMdbSetCurrMachining( sPocketing) then
sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam
end
end
-- verifico se la lavorazione (o il suo eventuale mirror) potrebbe danneggiare le parti limitrofe e devo quindi forzare una tasca chiusa
local bIsMachiningDamagingOtherParts = IsMachiningDamagingOtherParts( Proc, dMillDiam, nRawId)
if bIsMachiningDamagingOtherParts then
bForceClosedPocket = true
end
-- disattivo il doppio se devo forzare una tasca chiusa ma l'altra no
if Proc.Double and Proc.Double > 0 then
local bIsMirrorMachiningDamagingOtherParts = IsMachiningDamagingOtherParts( Proc.Mirror, dMillDiam, nRawId)
if bIsMachiningDamagingOtherParts ~= bIsMirrorMachiningDamagingOtherParts then
Proc.Double = 0
end
end
-- altrimenti diametro utensile troppo piccolo: devo forzare tasca chiusa
else
bForceClosedPocket = true
end
-- se tasca chiusa cerco lavorazione con diametro massimo pari a dimensione tasca e riverifico per eventuale doppio
if bForceClosedPocket then
dMaxDiameter = dStartDiameter
bUseDElevToFindPocketing = true
sPocketing = WM.FindPocketing( 'Pocket', dMaxDiameter, dElev, nil, nil, bExcludeNoTipFeed, dDistanceToNearestPart)
if not sPocketing then
bUseDElevToFindPocketing = false
sPocketing = WM.FindPocketing( 'Pocket', dMaxDiameter, nil, nil, nil, bExcludeNoTipFeed, dDistanceToNearestPart)
end
-- se doppio cerco una lavorazione adatta
if Proc.Double and Proc.Double == 2 then
local sPocketingBackup = sPocketing
sPocketing = WM.FindPocketing( 'Pocket', dMaxDiameter, EgtIf( bUseDElevToFindPocketing, dElev, nil), nil, 'H1', true, dDistanceToNearestPart)
if not WM.IsMachiningOkForDouble( sPocketing) then
Proc.Double = 0
sPocketing = sPocketingBackup
end
end
end
-- recupero dati utensile
if sPocketing and EgtMdbSetCurrMachining( sPocketing) then
sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam
@@ -2216,6 +2403,25 @@ local function MakeByPocketing( Proc, nFacet, nRawId, b3Raw, bCheckQPar)
dThDiam = EgtTdbGetCurrToolThDiam() or dThDiam
end
end
return sPocketing, bForceClosedPocket, bIsFeatureOnEdge, sTuuid, dMillDiam, dMaxDepth, dThDiam
end
---------------------------------------------------------------------
local function MakeByPocketing( Proc, nFacet, nRawId, b3Raw, bCheckQPar)
-- dati della faccia
local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacet, GDB_ID.ROOT)
local dElev = WL.GetFaceElevation( Proc.Id, nFacet, nRawId)
-- gruppo ausiliario
local nAddGrpId = WL.GetAddGroup( Proc.PartId)
local nNewProc = RemoveBottomFaceAndReorder( Proc, nAddGrpId, nFacet)
-- cerco lavorazione adatta e recupero i dati utensile
local sPocketing, bForceClosedPocket, bIsFeatureOnEdge, sTuuid, dMillDiam, dMaxDepth, dThDiam = VerifyPocket( Proc, nFacet, dElev, nRawId)
if not sPocketing then
local sErr = 'Error : pocketing not found in library'
EgtOutLog( sErr)
return false, sErr
end
-- inserisco la lavorazione di svuotatura
local sName = 'Pock_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
local nMchFId = WM.AddMachining( Proc, sName, sPocketing)
@@ -2251,6 +2457,20 @@ local function MakeByPocketing( Proc, nFacet, nRawId, b3Raw, bCheckQPar)
local sUserNotes = EgtGetMachiningParam( MCH_MP.USERNOTES)
-- imposto elevazione
sUserNotes = EgtSetValInNotes( sUserNotes, 'MaxElev', EgtNumToString( min( dElev, dMaxDepth), 1))
-- se lavorazione in doppio aggiungo le rispettive note
if Proc.Double and Proc.Double == 2 then
sUserNotes = EgtSetValInNotes( sUserNotes, 'DOUBLE', Proc.Double)
sUserNotes = EgtSetValInNotes( sUserNotes, 'MirrorAx', Proc.MirrorAx)
sUserNotes = EgtSetValInNotes( sUserNotes, 'DeltaZ', Proc.MirrorDeltaZ)
-- escludo ottimizzazioni e forzo attacco interno perchè la tasca specchiata potrebbe essere nel mezzo del pannello
sUserNotes = EgtSetValInNotes( sUserNotes, 'MaxOptSize', 0.1)
EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALOUT)
end
-- setto eventuale nota per forzare tasca chiusa
if bForceClosedPocket then sUserNotes = EgtSetValInNotes( sUserNotes, 'Open', 0) end
-- setto eventuale nota per forzare attacco esterno, fino ad un certo spessore del grezzo
local dMaxRawThicknessToStartOut = 75
if bIsFeatureOnEdge and ( not Proc.Double or Proc.Double == 0) then sUserNotes = EgtSetValInNotes( sUserNotes, 'OpenMinSafe', dMaxRawThicknessToStartOut) end
-- scrivo le note della lavorazione
EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes)
-- eseguo
@@ -2259,7 +2479,9 @@ local function MakeByPocketing( Proc, nFacet, nRawId, b3Raw, bCheckQPar)
EgtSetOperationMode( nMchFId, false)
return false, sErr
end
-- verifica parametro Q per pulitura spigoli
local bIsU = ( Proc.Fct == 3 and not WL.TestElleShape3( Proc.Id, Proc.Fct))
if bCheckQPar and not ( bIsU and AreSameOrOppositeVectorApprox( vtN, Z_AX())) then
-- lettura parametri (probabile/i parametro/i Q)
local nConeCut = EvaluateQParam( Proc)
@@ -2267,7 +2489,7 @@ local function MakeByPocketing( Proc, nFacet, nRawId, b3Raw, bCheckQPar)
local vFace, dMaxWidth = GetFacesData( nNewProc, false, false, dMillDiam, dMaxDepth, (dMillDiam/2), nAddGrpId, Proc.PartId)
-- se abilitata la lavorazione corner con stop macchina
if nConeCut == 1 then
local bMcok, sMcErr = AddMillCorner( nConeCut, vFace, Proc, nRawId, b3Raw,
local bMcok, sMcErr = AddMillCorner( nConeCut, vFace, Proc, nRawId, b3Raw,
dMillDiam, nAddGrpId, dMaxWidth, nNewProc, dDepth)
if not bMcok then return bMcok, sMcErr end
elseif nConeCut == 2 then
@@ -2383,7 +2605,18 @@ local function MakeTwoFaces( Proc, nRawId, b3Raw)
dMinSideElev = dDimY[2]
end
end
local sMillOnSide, dTMaxDepth, dMaxMat, dDiam = WM.FindMilling( 'SideMill', nil, nil, nil, nil, dMaxThick, nil, dMinSideElev)
local sMillOnSide = WM.FindMilling( 'SideMill', nil, nil, nil, nil, dMaxThick, nil, dMinSideElev)
-- se Proc è settata per essere specchiata cerco la lavorazione adatta e verifico possa essere effettivamente specchiata
local bDoubleMillOnSide = false
if Proc.Double and Proc.Double == 2 then
local sMillOnSideBackup = sMillOnSide
sMillOnSide = WM.FindMilling( 'SideMill', nil, nil, nil, nil, dMaxThick, nil, dMinSideElev, 'H1')
if WM.IsMachiningOkForDouble( sMillOnSide) then
bDoubleMillOnSide = true
else
sMillOnSide = sMillOnSideBackup
end
end
local bEnableMillOnSide
if sMillOnSide and nUseMillOnSide >= 1 then
dMaxZVers = 0.866
@@ -2444,7 +2677,7 @@ local function MakeTwoFaces( Proc, nRawId, b3Raw)
end
-- se posso eseguire la lavorazione per distanza inferiore utensile o lavorazione preceduta da sgossatura gola
if bInsertMach then
return MakeSideGrooveByMill( Proc, nFacet, nRawId, b3Raw, EgtIf( bEnableMillOnSide and dMaxDepthOnSide, sMillOnSide, nil), dMaxDepthOnSide, bMakeFirstGroove, bMachFromDn, dAng)
return MakeSideGrooveByMill( Proc, nFacet, nRawId, b3Raw, EgtIf( bEnableMillOnSide and dMaxDepthOnSide, sMillOnSide, nil), dMaxDepthOnSide, bMakeFirstGroove, bMachFromDn, dAng, nil, nil, nil, bDoubleMillOnSide)
else
local sErr = 'Error feature not machinable (dimensions)'
EgtOutLog( sErr)
@@ -2512,10 +2745,10 @@ local function MakeTwoFaces( Proc, nRawId, b3Raw)
local bMachFromDn = false
local bInsertMach
if dSideDist and dSideDist < dMaxDist then
-- se abilitata SideMill
if bEnableMillOnSide and dMaxDepthOnSide > 0 then
-- se abilitata SideMill oppure se la specchiata guarda in basso e quindi l'attacco deve essere a filo
if ( bEnableMillOnSide and dMaxDepthOnSide > 0) or ( Proc.Double == 2 and Proc.MirrorDeltaZ and abs( Proc.MirrorDeltaZ) > GEO.EPS_SMALL) then
bLikeAsMakeFirstGroove = false
return MakeSideGrooveByMill( Proc, nFacetVert, nRawId, b3Raw, EgtIf( bEnableMillOnSide and dMaxDepthOnSide, sMillOnSide, nil), dMaxDepthOnSide, bMakeFirstGroove, bMachFromDn, dAng, bLikeAsMakeFirstGroove)
return MakeSideGrooveByMill( Proc, nFacetVert, nRawId, b3Raw, EgtIf( bEnableMillOnSide and dMaxDepthOnSide, sMillOnSide, nil), dMaxDepthOnSide, bMakeFirstGroove, bMachFromDn, dAng, bLikeAsMakeFirstGroove, nil, nil, bDoubleMillOnSide)
else
local bOk, sErr = MakeByMill( Proc, nFacet, 1 - nFacet, nRawId, b3Raw, dSideDist)
-- se angolo ottuso riprendo il lato quasi verticale
@@ -2526,7 +2759,7 @@ local function MakeTwoFaces( Proc, nRawId, b3Raw)
end
elseif bEnableMillOnSide and dMaxDepthOnSide > 0 then
bLikeAsMakeFirstGroove = true
local bOk, sErr = MakeSideGrooveByMill( Proc, nFacetVert, nRawId, b3Raw, EgtIf( bEnableMillOnSide and dMaxDepthOnSide, sMillOnSide, nil), dMaxDepthOnSide, bMakeFirstGroove, bMachFromDn, dAng, bLikeAsMakeFirstGroove)
local bOk, sErr = MakeSideGrooveByMill( Proc, nFacetVert, nRawId, b3Raw, EgtIf( bEnableMillOnSide and dMaxDepthOnSide, sMillOnSide, nil), dMaxDepthOnSide, bMakeFirstGroove, bMachFromDn, dAng, bLikeAsMakeFirstGroove, nil, nil, bDoubleMillOnSide)
if bOk then return true end
end
-- se non inclinate o capacità di taglio non sufficiente o non molto grandi (80mm), provo con contornatura o svuotatura
@@ -2629,6 +2862,17 @@ local function MakeMoreFaces( Proc, nRawId, b3Raw)
local dSideElev = WL.GetFaceElevation( Proc.Id, nFacInd)
-- se abilitata lavorazione ribasso con fresa di fianco e parametro Q03 abilitato
local sMillOnSide, dTMaxDepth, dMaxMat, dDiam = WM.FindMilling( 'SideMill', nil, nil, nil, nil, min( dH, dV), nil, dSideElev)
-- se Proc è settata per essere specchiata cerco la lavorazione adatta e verifico possa essere effettivamente specchiata
local bDoubleMillOnSide = false
if Proc.Double and Proc.Double == 2 then
local sMillOnSideBackup = sMillOnSide
sMillOnSide = WM.FindMilling( 'SideMill', nil, nil, nil, nil, min( dH, dV), nil, dSideElev, 'H1')
if WM.IsMachiningOkForDouble( sMillOnSide) then
bDoubleMillOnSide = true
else
sMillOnSide = sMillOnSideBackup
end
end
local _, nUseMillOnSide = EvaluateQParam( Proc)
-- se ho abilitata lavorazione di fresa di fianco
if Proc.Fct >= 3 and sMillOnSide and nUseMillOnSide >= 1 and not bIsSmallSlot then
@@ -2669,14 +2913,27 @@ local function MakeMoreFaces( Proc, nRawId, b3Raw)
nSinglePass = 2
bMakeFirstGroove = false
end
return MakeSideGrooveByMill( Proc, nFacInd, nRawId, b3Raw, EgtIf( dMaxDepthOnSide, sMillOnSide, nil), dMaxDepthOnSide, bMakeFirstGroove, nil, nil, bLikeAsMakeFirstGroove, nSinglePass)
return MakeSideGrooveByMill( Proc, nFacInd, nRawId, b3Raw, EgtIf( dMaxDepthOnSide, sMillOnSide, nil), dMaxDepthOnSide, bMakeFirstGroove, nil, nil, bLikeAsMakeFirstGroove, nSinglePass, nil, bDoubleMillOnSide)
end
else
-- fresatura (se definita); se disponibile, cerco di usare un utensile che non lavori al limite della capacità di sottosquadro
local sMilling = WM.FindMilling( 'SideGroove', nil, nil, nil, nil, min( dH, dV), nil, 1.2 * dSideElev)
local dSideElevMultiplier = 1.2
local sMilling = WM.FindMilling( 'SideGroove', nil, nil, nil, nil, min( dH, dV), nil, dSideElevMultiplier * dSideElev)
-- se non ho trovato un utensile un po' più grande del sottosquadro richiesto, passo alla ricerca standard
if not sMilling then
sMilling = WM.FindMilling( 'SideGroove', nil, nil, nil, nil, min( dH, dV), nil, dSideElev)
dSideElevMultiplier = 1
end
-- se Proc è settata per essere specchiata cerco la lavorazione adatta e verifico possa essere effettivamente specchiata
bDoubleMillOnSide = false
if Proc.Double and Proc.Double == 2 then
local sMillOnSideBackup = sMillOnSide
sMillOnSide = WM.FindMilling( 'SideGroove', nil, nil, nil, nil, min( dH, dV), nil, dSideElevMultiplier * dSideElev, 'H1')
if WM.IsMachiningOkForDouble( sMillOnSide) then
bDoubleMillOnSide = true
else
sMillOnSide = sMillOnSideBackup
end
end
-- recupero i dati dell'utensile
local dMaxMat = 1000
@@ -2701,7 +2958,7 @@ local function MakeMoreFaces( Proc, nRawId, b3Raw)
end
end
if sMilling and dElev < dMaxDepthOnSide then
return MakeSideGrooveByMill( Proc, nFacInd, nRawId, b3Raw, sMilling)
return MakeSideGrooveByMill( Proc, nFacInd, nRawId, b3Raw, sMilling, nil, nil, nil, nil, nil, nil, nil, bDoubleMillOnSide)
-- altrimenti sega a catena
else
return MakeByChainSaw( Proc, nFacInd, nRawId, b3Raw, dElev, dH, dV)
+490 -4
View File
@@ -5,6 +5,8 @@
-- 2023/06/27 Aggiunte origini TN e BN.
-- 2023/07/04 Se c'è funzione di macchina WD.GetOrigCorner si lascia scegliere posizione default a questa impostando 0 se non c'è 'REFPOS'.
-- 2023/10/16 Aggiunta gestione Aree vietate (LockOut) per chiodature.
-- 2023/11/10 In SetMirroredFeatures doppio disattivato se side e la lavorazione mirror è troppo distante dal grezzo.
-- 2023/11/13 Aggiunte le lavorazioni PreSideMill che vengono sempre fatte prima delle SideMill.
-- Tabella per definizione modulo
local WallExec = {}
@@ -25,6 +27,7 @@ if WALL and WALL.NESTINGCORNERBL then WD.NESTING_CORNER = 'BL' end
-- Carico le librerie
_G.package.loaded.WMachiningLib = nil
_G.package.loaded.WallLib = nil
_G.package.loaded.WFeatureTopology = nil
_G.package.loaded.WProcessCut = nil
_G.package.loaded.WProcessDoubleCut = nil
_G.package.loaded.WProcessSawCut = nil
@@ -38,6 +41,7 @@ _G.package.loaded.WProcessFreeContour = nil
_G.package.loaded.WProcessVariant = nil
local WM = require( 'WMachiningLib')
local WL = require( 'WallLib')
local Topology = require( 'WFeatureTopology')
local Cut = require( 'WProcessCut')
local DoubleCut = require( 'WProcessDoubleCut')
local SawCut = require( 'WProcessSawCut')
@@ -191,6 +195,19 @@ function WallExec.CollectFeatures( PartId, b3Raw)
Proc.TaskId = nTaskId
Proc.Box = EgtGetBBoxGlob( ProcId, GDB_BB.STANDARD)
Proc.IsOutline = ( Proc.Prc == 251 or Proc.Prc == 252)
if b3Raw then
-- recupero l'elenco delle facce della parte interessate dalla feature
Proc.AffectedFaces = WL.GetProcessAffectedFaces( Proc)
-- recupero le distanze tra la feature e le altre parti più vicine
Proc.DistanceToNearestParts = WL.GetProcessDistanceToNearestParts( Proc)
-- recupero le distanze tra la feature e il grezzo
Proc.DistanceToRawPart = WL.GetProcessDistanceToRawPart( Proc, b3Raw)
-- recupero informazioni sulle facce della feature
Proc.Face = {}
for i = 1, Proc.Fct do
Proc.Face[i] = { Id = i - 1, VtN = EgtSurfTmFacetNormVersor( Proc.Id, i - 1, GDB_ID.ROOT ), Elevation = WL.GetFaceElevation( Proc.Id, i - 1, PartId)}
end
end
if Proc.Box and not Proc.Box:isEmpty() then
table.insert( vProc, Proc)
-- se foro
@@ -291,14 +308,27 @@ local function ClassifyFeatures( vProc, b3Raw)
end
end
-------------------------------------------------------------------------------------------------------------
local function ClassifyTopology( vProc)
local nRecognized = 0
for i = 1, #vProc do
local Proc = vProc[i]
if Topology.Classify( Proc) then
nRecognized = nRecognized + 1
end
end
return nRecognized
end
-------------------------------------------------------------------------------------------------------------
local function PrintFeatures( vProc)
EgtOutLog( ' *** Feature List ***')
for i = 1, #vProc do
local Proc = vProc[i]
local sOut = string.format( 'Part=%3d Proc=%3d Grp=%1d Prc=%3d TC=%2d/%d Flg=%2d Lo=%d Fcse=%1d,%1d Diam=%.2f Fct=%2d Dbl=%2d Dlt=%.1f Box=%s',
local sOut = string.format( 'Part=%3d Proc=%3d Grp=%1d Prc=%3d TC=%2d/%d Flg=%2d Lo=%d Fcse=%1d,%1d Diam=%.2f Fct=%2d Dbl=%2d Dlt=%.1f Box=%s TopoName=%s',
Proc.PartId, Proc.Id, Proc.Grp, Proc.Prc, Proc.TaskId, Proc.CutId,
Proc.Flg, EgtIf( Proc.LockOut, 1, 0), Proc.Fcs, Proc.Fce, Proc.Diam, Proc.Fct, Proc.Double or 0, Proc.Delta or 0, tostring( Proc.Box))
Proc.Flg, EgtIf( Proc.LockOut, 1, 0), Proc.Fcs, Proc.Fce, Proc.Diam, Proc.Fct, Proc.Double or 0, Proc.Delta or 0, tostring( Proc.Box), Proc.TopologyLongName or '')
EgtOutLog( sOut)
end
end
@@ -579,6 +609,8 @@ local function SortMachinings( nPhase, PrevMch, nPartId, nPriority)
PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_MY.SURFFINISHING, nil, nil, 'MOVE_AFTER', false, nil, nil, nil, nPriority)
-- Fresature per gole
PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.MILLING, { 'Gorge_'}, true, 'MOVE_AFTER', false, nil, nil, nil, nPriority)
-- Fresature da fare prima delle SideMill
PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.MILLING, { 'PreSideMill_'}, true, 'MOVE_AFTER', false, false, true, true, nPriority)
-- Fresature che sono rifiniture di spigoli
PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.MILLING, { 'SideMill_'}, true, 'MOVE_AFTER', false, false, true, true, nPriority)
-- Fresature che sono puliture di spigoli
@@ -589,6 +621,8 @@ local function SortMachinings( nPhase, PrevMch, nPartId, nPriority)
PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.SAWING, nil, nil, nil, nil, nil, nil, nil, nPriority)
-- Qui rimozione sfridi (se ci sono lavorazioni successive)
if not nPriority then
-- Fresature da fare prima delle SideMill
PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.MILLING, { 'PreSideMill_'}, true, 'MOVE_AFTER', true, false, true, true)
-- Fresature dei lapjoint che necessitano di gorge
PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.MILLING, { 'SideMill_'}, true, 'MOVE_AFTER', true, false, true, true)
-- Tagli con sega a catena che vanno fatti dopo i tagli con lama
@@ -626,6 +660,406 @@ function InsertScrapRemoval( nPhase)
EgtSetCurrMachining( nActiveMachiningId or GDB_ID.NULL)
end
-------------------------------------------------------------------------------------------------------------
-- funzione per l'ordinamento delle features in doppio da accoppiare
-- ordinate prima in base alla X e poi alla Y
local function SortFeaturesForMirror( Proc1, Proc2)
-- tolleranza di ricerca
local TOL = EgtIf( Proc1.TopologyLongName == 'DRILLING', WD.DOUBLE_HEAD_DRILLING_TOLERANCE or 0.1 , WD.DOUBLE_HEAD_POCKET_TOLERANCE or 0.5)
-- recupero i centri dei box lungo X e Y
local Proc1X = Proc1.Box:getCenter():getX()
local Proc1Y = Proc1.Box:getCenter():getY()
local Proc2X = Proc2.Box:getCenter():getX()
local Proc2Y = Proc2.Box:getCenter():getY()
-- confronto per ordinamento
if Proc1X < Proc2X - TOL then
return true
elseif abs( Proc1X - Proc2X) < TOL then
if Proc1Y < Proc2Y - TOL then
return true
end
end
end
-------------------------------------------------------------------------------------------------------------
-- funzione per l'ordinamento delle operazioni in doppio da accoppiare
-- ordinate prima in base alla X e poi alla Y
local function SortOperationsForMirror( nOper1, nOper2)
-- tolleranza di ricerca
local TOL = 0.1
-- recupero il box della prima operazione
local nClId1 = EgtGetFirstNameInGroup( nOper1, 'CL')
local ptMin1 = EgtGetInfo( nClId1, 'MMIN', 'p')
local ptMax1 = EgtGetInfo( nClId1, 'MMAX', 'p')
local b3Oper1 = BBox3d( ptMin1, ptMax1)
-- recupero il box delle seconda operazione
local nClId2 = EgtGetFirstNameInGroup( nOper2, 'CL')
local ptMin2 = EgtGetInfo( nClId2, 'MMIN', 'p')
local ptMax2 = EgtGetInfo( nClId2, 'MMAX', 'p')
local b3Oper2 = BBox3d( ptMin2, ptMax2)
-- recupero i centri dei box lungo X e Y
local dOper1X = b3Oper1:getCenter():getX()
local dOper1Y = b3Oper1:getCenter():getY()
local dOper2X = b3Oper2:getCenter():getX()
local dOper2Y = b3Oper2:getCenter():getY()
-- confronto per ordinamento
if dOper1X < dOper2X - TOL then
return true
elseif abs( dOper1X - dOper2X) < TOL then
if dOper1Y < dOper2Y - TOL then
return true
end
end
end
-------------------------------------------------------------------------------------------------------------
-- Controlla in vProc la presenza di feature da lavorare in doppio e, se trovate, ne setta i parametri
local function SetMirroredFeatures( vProc, b3Raw)
-- interasse minimo
local dMinimumDistanceMirroredFeatures = 780
-- inizializzazione array tasche e forature
local vPockets = {}
local vDrillings = {}
-- raccolgo le feature compatibili con doppio
for i = 1, #vProc do
local Proc = vProc[i]
if Proc.Flg ~= 0 then
-- raccolgo le tasche compatibili
if WD.DOUBLE_HEAD_POCKET and
(
( Proc.TopologyLongName == 'Rabbet-Through-RightAngles-Parallel-2' and Proc.AffectedFaces.Left and Proc.AffectedFaces.Right) or
( Proc.TopologyLongName == 'Groove-Through-RightAngles-Parallel-3' and ( not Proc.AffectedFaces.Bottom and Proc.AffectedFaces.Left and Proc.AffectedFaces.Right)) or
( Proc.TopologyLongName == 'Groove-Blind-RightAngles-Parallel-3') or
( Proc.TopologyLongName == 'Groove-Blind-RightAngles-Parallel-4') or
( Proc.TopologyLongName == 'Pocket-Blind-RightAngles-Parallel-5' and not Proc.AffectedFaces.Bottom)
) then
table.insert( vPockets, Proc)
-- raccolgo i fori verticali e aperti verso Z+
elseif WD.DOUBLE_HEAD_DRILLING and Proc.TopologyLongName == 'DRILLING' then
-- recupero e verifico la geometria del foro
local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') or 0
if AuxId then AuxId = AuxId + Proc.Id end
if not AuxId or EgtGetType( AuxId) ~= GDB_TY.CRV_ARC then
return false
end
local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB)
if Proc.AffectedFaces.Top and AreSameOrOppositeVectorApprox( vtExtr, Z_AX()) then
table.insert( vDrillings, Proc)
end
end
end
end
-- ordinamento delle feature raccolte secondo X e poi Y crescente
table.sort( vPockets, SortFeaturesForMirror)
table.sort( vDrillings, SortFeaturesForMirror)
-- accoppio le tasche
local nCurrentPocket = 1
while nCurrentPocket <= #vPockets do
local Proc = vPockets[nCurrentPocket]
if Proc.Flg ~= 0 then
local b3Proc = EgtGetBBoxGlob( Proc.Id, GDB_BB.STANDARD)
-- cerco evenutale specchiata
local nCurrentMirrorPocket = nCurrentPocket + 1
while nCurrentMirrorPocket <= #vPockets do
local ProcMirror = vPockets[nCurrentMirrorPocket]
local b3ProcMirror = EgtGetBBoxGlob( ProcMirror.Id, GDB_BB.STANDARD)
-- feature non disattivata e diversa da nCurrentPocket
local bIsMirrorIdOk = ( Proc.Id ~= ProcMirror.Id and ProcMirror.Flg ~= 0)
-- feature mirror della stessa classe topologica
local bIsMirrorTopologyOk = ( Proc.TopologyLongName == ProcMirror.TopologyLongName)
-- determino se di fianco o in mezzo al singolo pannello
local bLapVsTop = Proc.AffectedFaces.Front and
(
Proc.TopologyLongName == 'Rabbet-Through-RightAngles-Parallel-2' or
Proc.TopologyLongName == 'Groove-Through-RightAngles-Parallel-3' or
Proc.TopologyLongName == 'Groove-Blind-RightAngles-Parallel-3' or
Proc.TopologyLongName == 'Groove-Blind-RightAngles-Parallel-4' or
Proc.TopologyLongName == 'Pocket-Blind-RightAngles-Parallel-5'
)
-- se di fianco, determino se è l'ultima parte prima della fine del grezzo
local bIsFeatureOnEdge, bIsMirrorFeatureOnEdge = false, false
if bLapVsTop then
bIsFeatureOnEdge = Proc.DistanceToNearestParts.Front > b3Raw:getDimY()
bIsMirrorFeatureOnEdge = ProcMirror.DistanceToNearestParts.Back > b3Raw:getDimY()
end
-- se di fianco, si sceglie se le feature sono compatibili con il doppio e nel caso che tipo di lavorazione fare
-- -1: no doppio, 0: nessuna preferenza, 1: pocket, 2: side (scambio faccia principale)
local nDoubleType = 0
local bAllowSideOnMirror = ( ProcMirror.DistanceToRawPart.Back - Proc.DistanceToRawPart.Front < 1 + 10 * GEO.EPS_SMALL) or ( not WD.SIDEMILL_BEFORE and ( not Proc.AffectedFaces.Top or not ProcMirror.AffectedFaces.Top))
if bLapVsTop and ( Proc.AffectedFaces.Top or Proc.AffectedFaces.Bottom) then
-- side
if bIsFeatureOnEdge and bIsMirrorFeatureOnEdge then
if not ( Proc.AffectedFaces.Top and ProcMirror.AffectedFaces.Top) then
nDoubleType = 2
end
-- no doppio
elseif Proc.AffectedFaces.Bottom or ProcMirror.AffectedFaces.Bottom then
nDoubleType = -1
-- tasca
else
nDoubleType = 1
end
end
-- corrispondenza nella posizione delle feature. Se di fianco il lato master è sempre quello verso l'operatore, se sopra nessun vincolo
local bIsMirrorSideOk = ( bLapVsTop and ProcMirror.AffectedFaces.Back and bIsFeatureOnEdge and bIsMirrorFeatureOnEdge and bAllowSideOnMirror) or
Proc.TopologyLongName == 'Groove-Through-RightAngles-Parallel-3' and Proc.AffectedFaces.Top and ProcMirror.AffectedFaces.Top or
Proc.TopologyLongName == 'Groove-Blind-RightAngles-Parallel-4' and Proc.AffectedFaces.Top and Proc.AffectedFaces.Left and ProcMirror.AffectedFaces.Top and ProcMirror.AffectedFaces.Left or
Proc.TopologyLongName == 'Groove-Blind-RightAngles-Parallel-4' and Proc.AffectedFaces.Top and Proc.AffectedFaces.Right and ProcMirror.AffectedFaces.Top and ProcMirror.AffectedFaces.Right or
Proc.TopologyLongName == 'Pocket-Blind-RightAngles-Parallel-5' and Proc.AffectedFaces.Top and ProcMirror.AffectedFaces.Top
-- box delle stesse dimensioni
local bIsMirrorFeatureSameDimension = abs( b3Proc:getDimX() - b3ProcMirror:getDimX()) < ( WD.DOUBLE_HEAD_POCKET_TOLERANCE or 0.5) and
abs( b3Proc:getDimY() - b3ProcMirror:getDimY()) < ( WD.DOUBLE_HEAD_POCKET_TOLERANCE or 0.5) and
abs( b3Proc:getDimZ() - b3ProcMirror:getDimZ()) < ( WD.DOUBLE_HEAD_POCKET_TOLERANCE or 0.5)
-- box allineati in X
local bIsMirrorBoxXAligned = abs( Proc.Box:getCenter():getX() - ProcMirror.Box:getCenter():getX()) < ( WD.DOUBLE_HEAD_POCKET_TOLERANCE or 0.5)
-- box che non si intersecano
local bIsNotMirrorBoxOverlapping = not OverlapsXY( b3Proc, b3ProcMirror)
-- distanza minima tra le feature
local dYMinDistance = max( b3Proc:getMin():getY(), b3ProcMirror:getMin():getY()) - min( b3Proc:getMax():getY(), b3ProcMirror:getMax():getY())
local bIsMirrorFeatureDistanceOk = dYMinDistance > dMinimumDistanceMirroredFeatures + 10 * GEO.EPS_SMALL
-- se tutte vere le condizioni, calcolo i parametri da passare alle lavorazioni
if nDoubleType > -1 and bIsMirrorIdOk and bIsMirrorTopologyOk and bIsMirrorSideOk and bIsMirrorFeatureSameDimension and bIsMirrorBoxXAligned and bIsNotMirrorBoxOverlapping and bIsMirrorFeatureDistanceOk then
local dYMirrorAx
local b3Tab = EgtGetTableArea()
local ptOnMirrorAx = ( Proc.Box:getCenter() + ProcMirror.Box:getCenter()) / 2
dYMirrorAx = ptOnMirrorAx:getY() - b3Tab:getMin():getY()
local dDeltaZ = ProcMirror.Box:getMax():getZ() - Proc.Box:getMax():getZ()
-- forzo side o pocket, se necessario
if nDoubleType == 1 then
EgtSetInfo( Proc.Id, 'PCKT', 1)
EgtSetInfo( ProcMirror.Id, 'PCKT', 1)
elseif nDoubleType == 2 then
Proc.Stype = 2
ProcMirror.Stype = 2
end
-- scrivo i parametri nella lavorazione
-- 2: specchiatura in Y
Proc.Double = 2
Proc.Mirror = ProcMirror
-- posizione Y dell'asse di specchiatura
Proc.MirrorAx = dYMirrorAx
-- Offset Z tra le feature
Proc.MirrorDeltaZ = dDeltaZ
-- rimuovo dalla lista le pocket già assegnate
local ProcMirrorOldId = ProcMirror.Id
table.remove( vPockets, nCurrentPocket)
-- avendo rimosso un elemento dall'array, potrebbe essere cambiato l'elemento nCurrentMirrorPocket
if nCurrentMirrorPocket > #vPockets or ( vPockets[nCurrentMirrorPocket].Id ~= ProcMirrorOldId) then nCurrentMirrorPocket = nCurrentMirrorPocket - 1 end
table.remove( vPockets, nCurrentMirrorPocket)
nCurrentPocket = 0
break
end
nCurrentMirrorPocket = nCurrentMirrorPocket + 1
end
end
nCurrentPocket = nCurrentPocket + 1
end
-- accoppio le forature
local nCurrentDrilling = 1
while nCurrentDrilling <= #vDrillings do
local Proc = vDrillings[nCurrentDrilling]
if Proc.Flg ~= 0 then
local b3Proc = EgtGetBBoxGlob( Proc.Id, GDB_BB.STANDARD)
-- cerco evenutale specchiata
local nCurrentMirrorDrilling = nCurrentDrilling + 1
while nCurrentMirrorDrilling <= #vDrillings do
local ProcMirror = vDrillings[nCurrentMirrorDrilling]
local b3ProcMirror = EgtGetBBoxGlob( ProcMirror.Id, GDB_BB.STANDARD)
-- feature non disattivata e diversa da nCurrentDrilling
local bIsMirrorIdOk = ( Proc.Id ~= ProcMirror.Id and ProcMirror.Flg ~= 0)
-- box delle stesse dimensioni
local bIsMirrorFeatureSameDimension = abs( b3Proc:getDimX() - b3ProcMirror:getDimX()) < ( WD.DOUBLE_HEAD_DRILLING_TOLERANCE or 0.1) and
abs( b3Proc:getDimY() - b3ProcMirror:getDimY()) < ( WD.DOUBLE_HEAD_DRILLING_TOLERANCE or 0.1) and
abs( b3Proc:getDimZ() - b3ProcMirror:getDimZ()) < ( WD.DOUBLE_HEAD_DRILLING_TOLERANCE or 0.1)
-- box allineati in X
local bIsMirrorBoxXAligned = abs( Proc.Box:getCenter():getX() - ProcMirror.Box:getCenter():getX()) < ( WD.DOUBLE_HEAD_DRILLING_TOLERANCE or 0.1)
-- box che non si intersecano
local bIsNotMirrorBoxOverlapping = not OverlapsXY( b3Proc, b3ProcMirror)
-- distanza minima tra le feature
local dYMinDistance = max( b3Proc:getMin():getY(), b3ProcMirror:getMin():getY()) - min( b3Proc:getMax():getY(), b3ProcMirror:getMax():getY())
local bIsMirrorFeatureDistanceOk = dYMinDistance > dMinimumDistanceMirroredFeatures + 10 * GEO.EPS_SMALL
-- se tutte vere le condizioni, calcolo i parametri da passare alle lavorazioni
if bIsMirrorIdOk and bIsMirrorFeatureSameDimension and bIsMirrorBoxXAligned and bIsNotMirrorBoxOverlapping and bIsMirrorFeatureDistanceOk then
local dYMirrorAx
local b3Tab = EgtGetTableArea()
local ptOnMirrorAx = ( Proc.Box:getCenter() + ProcMirror.Box:getCenter()) / 2
dYMirrorAx = ptOnMirrorAx:getY() - b3Tab:getMin():getY()
-- scrivo i parametri nella lavorazione
-- 2: specchiatura in Y
Proc.Double = 2
Proc.Mirror = ProcMirror
-- posizione Y dell'asse di specchiatura
Proc.MirrorAx = dYMirrorAx
-- rimuovo dalla lista le forature già assegnate
local ProcMirrorOldId = ProcMirror.Id
table.remove( vDrillings, nCurrentDrilling)
-- avendo rimosso un elemento dall'array, potrebbe essere cambiato l'elemento nCurrentMirrorDrilling
if nCurrentMirrorDrilling > #vDrillings or ( vDrillings[nCurrentMirrorDrilling].Id ~= ProcMirrorOldId) then nCurrentMirrorDrilling = nCurrentMirrorDrilling - 1 end
table.remove( vDrillings, nCurrentMirrorDrilling)
nCurrentDrilling = 0
break
end
nCurrentMirrorDrilling = nCurrentMirrorDrilling + 1
end
end
nCurrentDrilling = nCurrentDrilling + 1
end
end
-------------------------------------------------------------------------------------------------------------
-- verifico e imposto le fresature da specchiare
local function SetMirroredOperations()
-- interasse minimo
local dMinimumDistanceMirroredOperations = 780
-- inzializzazione array
local vMillings = {}
-- raccolgo le fresature non già fatte in doppio
if WD.DOUBLE_HEAD_MILLCORNER then
local nOperId = EgtGetNextOperation( EgtGetPhaseDisposition( 1))
while nOperId do
EgtSetCurrMachining( nOperId)
local sUserNotes = EgtGetMachiningParam( MCH_MP.USERNOTES)
local bIsDouble = ( EgtGetValInNotes( sUserNotes, 'DOUBLE', 'i') or 0) > 0
if EgtGetOperationMode( nOperId) and not EgtIsMachiningEmpty( nOperId) and not bIsDouble and EgtGetOperationType( nOperId) == MCH_OY.MILLING then
table.insert( vMillings, nOperId)
end
nOperId = EgtGetNextOperation( nOperId)
end
end
-- ordinamento delle operazioni raccolte secondo X e poi Y crescente
table.sort( vMillings, SortOperationsForMirror)
-- accoppio le fresature
local nCurrentMilling = 1
while nCurrentMilling <= #vMillings do
local nOperIdMaster = vMillings[nCurrentMilling]
EgtSetCurrMachining( nOperIdMaster)
local sMachining = EgtGetMachiningParam( MCH_MP.NAME, 's')
local nClId = EgtGetFirstNameInGroup( nOperIdMaster, 'CL')
local nPathId = EgtGetFirstInGroup( nClId or GDB_ID.NULL)
-- vettore direzione utensile e somma normali facce per lavorazione master
local vtTool = EgtGetInfo( nPathId, 'EXTR', 'v')
local vtNormSum = EgtGetInfo( nOperIdMaster, 'NORM_SUM', 'v')
local ptMin = EgtGetInfo( nClId, 'MMIN', 'p')
local ptMax = EgtGetInfo( nClId, 'MMAX', 'p')
-- box percorso lavorazione master
local b3Operation = BBox3d( ptMin, ptMax)
-- lavorazione master adatta alla specchiatura
local bIsMachiningOk = WM.IsMachiningOkForDouble( sMachining)
if bIsMachiningOk then
-- recupero la distanza tra centro di rotazione e punta dell'utensile per aumentare o ridurre l'interasse minimo
local dTipToPivot, dTipToPivotDouble = 999, 999
local dToolMasterTotLength, dToolMasterTotLengthDouble = 999, 999
local sToolMasterName = ''
if EgtMdbSetCurrMachining( sMachining) then
-- recupero l'utensile della lavorazione e il suo doppio
sToolMasterName = EgtMdbGetCurrMachiningParam( MCH_MP.TOOL)
if EgtTdbSetCurrTool( sToolMasterName or '') then
dToolMasterTotLength = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) or dToolMasterTotLength
local sToolDoubleName = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'DOUBLE', 's')
if sToolDoubleName and EgtTdbSetCurrTool( sToolDoubleName) then
dToolMasterTotLengthDouble = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) or dToolMasterTotLengthDouble
end
end
end
if WD.HEAD_PIVOT_MAIN and WD.HEAD_PIVOT_SECONDARY then
dTipToPivot = dToolMasterTotLength + WD.HEAD_PIVOT_MAIN
dTipToPivotDouble = dToolMasterTotLengthDouble + WD.HEAD_PIVOT_SECONDARY
else
local sOut = 'Error : HEAD_PIVOT_MAIN or HEAD_PIVOT_SECONDARY missing in WallData'
return false, sOut
end
-- cerco eventuale specchiata
local nCurrentMirrorMilling = nCurrentMilling + 1
while nCurrentMirrorMilling <= #vMillings do
local nOperIdMirror = vMillings[nCurrentMirrorMilling]
EgtSetCurrMachining( nOperIdMirror)
local nClIdMirror = EgtGetFirstNameInGroup( nOperIdMirror, 'CL')
local nPathIdMirror = EgtGetFirstInGroup( nClIdMirror or GDB_ID.NULL)
-- vettore direzione utensile e somma normali facce per lavorazione mirror
local vtToolMirror = EgtGetInfo( nPathIdMirror, 'EXTR', 'v')
local vtNormSumMirror = EgtGetInfo( nOperIdMirror, 'NORM_SUM', 'v')
local ptMinMirror = EgtGetInfo( nClIdMirror, 'MMIN', 'p')
local ptMaxMirror = EgtGetInfo( nClIdMirror, 'MMAX', 'p')
-- box percorso lavorazione mirror
local b3OperationMirror = BBox3d( ptMinMirror, ptMaxMirror)
-- utensile originale lavorazione specchiata
local sOriginalMirrorToolName = EgtGetMachiningParam( MCH_MP.TOOL)
local bIsOriginalMirrorToolSameSize = WM.IsToolDoubleOk( sToolMasterName, sOriginalMirrorToolName)
-- lavorazione mirror adatta alla specchiatura
local bIsMirrorMachiningOk = nOperIdMaster ~= nOperIdMirror
-- lavorazione master più a sinistra
local bIsMirrorSideOk = ( b3OperationMirror:getCenter():getY() - b3Operation:getCenter():getY()) > ( WD.DOUBLE_HEAD_POCKET_TOLERANCE or 0.5)
-- box delle stesse dimensioni
local bIsMirrorOperationSameDimension = abs( b3Operation:getDimX() - b3OperationMirror:getDimX()) < ( WD.DOUBLE_HEAD_POCKET_TOLERANCE or 0.5) and
abs( b3Operation:getDimY() - b3OperationMirror:getDimY()) < ( WD.DOUBLE_HEAD_POCKET_TOLERANCE or 0.5) and
abs( b3Operation:getDimZ() - b3OperationMirror:getDimZ()) < ( WD.DOUBLE_HEAD_POCKET_TOLERANCE or 0.5)
-- box allineati in X
local bIsMirrorBoxXAligned = abs( b3Operation:getCenter():getX() - b3OperationMirror:getCenter():getX()) < ( WD.DOUBLE_HEAD_POCKET_TOLERANCE or 0.5) and
abs( b3Operation:getCenter():getX() - b3OperationMirror:getCenter():getX()) < ( WD.DOUBLE_HEAD_POCKET_TOLERANCE or 0.5)
-- box che non si intersecano
local bIsNotMirrorBoxOverlapping = not OverlapsXY( b3Operation, b3OperationMirror)
-- distanza minima tra le feature
local dTipToPivotProjectionOnY = dTipToPivot * vtTool:getY()
local dTipToPivotProjectionOnYDouble = dTipToPivotDouble * vtToolMirror:getY()
local dYMinDistance = max( b3Operation:getMin():getY(), b3OperationMirror:getMin():getY()) - min( b3Operation:getMax():getY(), b3OperationMirror:getMax():getY())
local bIsMirrorOperationDistanceOk = dYMinDistance > dMinimumDistanceMirroredOperations + dTipToPivotProjectionOnY - dTipToPivotProjectionOnYDouble + 10 * GEO.EPS_SMALL
-- vettori utensile e somma normali facce specchiati
local vtToolMirrored = Vector3d( vtTool)
vtToolMirrored:mirror( Y_AX())
local bIsMirrorVectorOk = false
if AreSameVectorApprox( vtToolMirrored, vtToolMirror) then
if AreSameVectorApprox(vtTool, vtToolMirror) then
if vtNormSum and vtNormSumMirror then
local vtNormSumMirrored = Vector3d( vtNormSum)
vtNormSumMirrored:mirror( Y_AX())
bIsMirrorVectorOk = AreSameVectorApprox( vtNormSumMirrored, vtNormSumMirror)
end
else
bIsMirrorVectorOk = true
end
end
-- se condizioni corrette, scrivo le note e cancello la specchiata
if bIsOriginalMirrorToolSameSize and bIsMirrorMachiningOk and bIsMirrorSideOk and bIsMirrorOperationSameDimension and bIsMirrorBoxXAligned and bIsNotMirrorBoxOverlapping and bIsMirrorOperationDistanceOk and bIsMirrorVectorOk then
-- calcolo asse di specchiatura
local dYMirrorAx
local b3Tab = EgtGetTableArea()
local ptOnMirrorAx = ( b3Operation:getCenter() + b3OperationMirror:getCenter()) / 2
dYMirrorAx = ptOnMirrorAx:getY() - b3Tab:getMin():getY()
EgtSetCurrMachining( nOperIdMaster)
-- leggo note esistenti
local sUserNotes = EgtGetMachiningParam( MCH_MP.USERNOTES)
-- aggiungo note per doppio
sUserNotes = EgtSetValInNotes( sUserNotes, 'DOUBLE', 2)
sUserNotes = EgtSetValInNotes( sUserNotes, 'MirrorAx', dYMirrorAx)
-- scrivo le note della lavorazione
EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes)
-- cancello l'operazione specchiata
EgtRemoveOperation( nOperIdMirror)
-- rimuovo dalla lista le fresature già assegnate
local nCurrentMirrorMillingOldId = nCurrentMirrorMilling
table.remove( vMillings, nCurrentMilling)
-- avendo rimosso un elemento dall'array, potrebbe essere cambiato l'elemento nCurrentMirrorPocket
if nCurrentMirrorMilling > #vMillings or ( vMillings[nCurrentMirrorMilling] ~= nCurrentMirrorMillingOldId) then nCurrentMirrorMilling = nCurrentMirrorMilling - 1 end
table.remove( vMillings, nCurrentMirrorMilling)
nCurrentMilling = 0
break
end
nCurrentMirrorMilling = nCurrentMirrorMilling + 1
end
end
nCurrentMilling = nCurrentMilling + 1
end
end
-------------------------------------------------------------------------------------------------------------
function WallExec.ProcessFeatures()
-- errori e stato
@@ -650,6 +1084,8 @@ function WallExec.ProcessFeatures()
local vPartProc = WallExec.CollectFeatures( vPart[i].Id, b3Raw)
vProc = EgtJoinTables( vProc, vPartProc)
end
-- classifico topologicamente le feature
ClassifyTopology( vProc)
-- classifico le feature
ClassifyFeatures( vProc, b3Raw)
-- recupero l'elenco delle aree vietate alle chiodature
@@ -659,6 +1095,9 @@ function WallExec.ProcessFeatures()
if #vNLO == 0 and WD.FindFeaturesInDouble then
WD.FindFeaturesInDouble( vProc, b3Raw)
end
SetMirroredFeatures( vProc, b3Raw)
-- debug
if EgtGetDebugLevel() >= 1 then
PrintFeatures( vProc)
@@ -678,12 +1117,59 @@ function WallExec.ProcessFeatures()
else
table.insert( Stats, {Err=0, Msg='', Rot=0, CutId=Proc.CutId, TaskId=Proc.TaskId})
end
elseif not Proc.Double and not Proc.LockOut then
elseif not Proc.Double and not Proc.LockOut then
local sMsg = 'Feature not machinable by orientation'
table.insert( Stats, {Err=1, Msg=sMsg, Rot=0, CutId=Proc.CutId, TaskId=Proc.TaskId})
end
end
EgtOutLog( ' *** End AddMachinings ***', 1)
-- setto quali sono le lavorazioni da disattivare perchè specchiate di lavorazioni in doppio
local vProcToDisable = {}
for i = 1, #vProc do
local Proc = vProc[i]
if Proc.Double and Proc.Double > 0 then
for j = 1, #vProc do
local ProcMirror = vProc[j]
if Proc.Mirror.Id == ProcMirror.Id then
-- per i fori l'operazione si basa sulla geometria ausiliaria
if Proc.TopologyLongName == 'DRILLING' then
local AuxId = EgtGetInfo( ProcMirror.Id, 'AUXID', 'i') or 0
if AuxId then AuxId = AuxId + ProcMirror.Id end
table.insert( vProcToDisable, AuxId)
-- per tutte le altre lavorazioni si usa la geometria della feature
else
table.insert( vProcToDisable, ProcMirror.Id)
end
end
end
end
end
-- cancello le operazioni legate a lavorazioni specchiate
local nOperId = EgtGetNextOperation( EgtGetPhaseDisposition( 1))
while nOperId do
EgtSetCurrMachining( nOperId)
local nOperationProcIds = EgtGetMachiningGeometry()
local nCurrentOperId = nOperId
if #nOperationProcIds > 0 then
local nOperationProcId = nOperationProcIds[1][1]
for i = 1, #vProcToDisable do
local ProcId = vProcToDisable[i]
if nOperationProcId == ProcId then
nOperId = EgtGetNextOperation( nOperId)
EgtRemoveOperation( nCurrentOperId)
break
end
end
end
if nCurrentOperId == nOperId then
nOperId = EgtGetNextOperation( nOperId)
end
end
SetMirroredOperations()
-- se macchina pareti
if not WD.BEAM_MACHINE then
-- riordino le lavorazioni tra tutti i pezzi
@@ -695,7 +1181,7 @@ function WallExec.ProcessFeatures()
local nGetPriorityFromBtl = WD.BTL_PRIORITY or 0
if nGetPriorityFromBtl > 0 then
local vPriority = {}
local nOperId = EgtGetNextOperation( PrevMch)
nOperId = EgtGetNextOperation( PrevMch)
local nCurrentPriorityId = 1
while nOperId do
local nPriority = EgtGetInfo( nOperId or GDB_ID.NULL, 'PRIORITY', 'i')
+208
View File
@@ -1,5 +1,6 @@
-- WallLib.lua by Egaltech s.r.l. 2023/10/16
-- Libreria globale per Pareti
-- 2023/06/26 Spostata qui Is3EdgesApprox da FreeContour. Ora cerca autonomamente il gruppo se non viene passato.
-- Tabella per definizione modulo
local WallLib = {}
@@ -316,6 +317,213 @@ function WallLib.GetNearestOrthoOpposite( vtRef, vtNorm)
return nil
end
---------------------------------------------------------------------
function WallLib.TestElleShape3( nIdGeom, nNumFacet)
-- valida solo nel caso di tre facce
if nNumFacet ~= 3 then return false end
-- determino se L con una faccia terminale o U con tre facce
local bIsL = true
for i = 1, 3 do
local vFacAdj = EgtSurfTmFacetAdjacencies( nIdGeom, i - 1)[1]
-- le conto
local nCount = 0
for j = 1, #vFacAdj do
if vFacAdj[j] >= 0 then
nCount = nCount + 1
end
end
if nCount == 1 then
bIsL = false
break
end
end
return bIsL
end
---------------------------------------------------------------------
function WallLib.TestElleShape4( nIdGeom, nNumFacet)
-- valida solo nel caso di quattro facce
if nNumFacet ~= 4 then return false end
-- determino se L con due facce terminali o O
local nFac3Adj = 0
local dMinArea3 = GEO.INFINITO * GEO.INFINITO
local dMaxArea2 = 0
for i = 1, 4 do
local vFacAdj = EgtSurfTmFacetAdjacencies( nIdGeom, i - 1)[1]
-- le conto
local nCount = 0
for j = 1, #vFacAdj do
if vFacAdj[j] >= 0 then
nCount = nCount + 1
end
end
local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( nIdGeom, i - 1, GDB_ID.ROOT)
local dArea = dH * dV
if nCount == 2 then
dMaxArea2 = max( dMaxArea2, dArea)
elseif nCount == 3 then
dMinArea3 = min( dMinArea3, dArea)
nFac3Adj = nFac3Adj + 1
end
end
if nFac3Adj ~= 2 then return false end
-- verifico se L profonda oppure lunga
if dMinArea3 < dMaxArea2 then
return 1
else
return 2
end
end
---------------------------------------------------------------------
-- Funzione per determinare se la faccia ha lati molto corti (trascurabili) ed è quindi approssimabile ad una 3 facce
function WallLib.Is3EdgesApprox( Proc, nFacet, nAddGrpId)
nAddGrpId = nAddGrpId or WallLib.GetAddGroup( Proc.PartId)
-- recupero il contorno della faccia
local nContourId, nContourCnt = EgtExtractSurfTmFacetLoops( Proc.Id, nFacet, nAddGrpId)
if not nContourId then return false end
EgtMergeCurvesInCurveCompo( nContourId)
-- recupero il numero di lati del contorno
local _, nEntityCount = EgtCurveDomain( nContourId)
if not nEntityCount then return false end
-- se sono già tre, ho finito
if nEntityCount == 3 then return true end
-- rimuovo i lati molto corti dal conteggio totale
local nEdges = nEntityCount
for i = 1, nEntityCount do
local dLength = EgtCurveCompoLength( nContourId, i - 1)
if dLength < 15 then nEdges = nEdges - 1 end
end
-- verifico il numero significativo di lati
local bResult = ( nEdges == 3)
-- cancello tutti i contorni appena creati
EgtErase( EgtTableFill( nContourId, nContourCnt))
if bResult then
EgtOutLog( 'FreeContour : Face with ' .. tostring( nEntityCount) .. ' edges skipped (approx 3 edges)')
end
return bResult
end
-------------------------------------------------------------------------------------------------------------
-- restituisce le facce della parte interessate dalla feature Proc
function WallLib.GetProcessAffectedFaces( Proc)
local nBoxSolidId = EgtGetFirstNameInGroup( Proc.PartId or GDB_ID.NULL, 'Box')
local b3Part = EgtGetBBoxGlob( nBoxSolidId, GDB_BB.STANDARD)
local vtFacesAffected = { Top = false, Bottom = false, Front = false, Back = false, Left = false, Right = false}
if Proc.Box and not Proc.Box:isEmpty() then
if Proc.Box:getMax():getZ() > b3Part:getMax():getZ() - 500 * GEO.EPS_SMALL then
vtFacesAffected.Top = true
end
if Proc.Box:getMin():getZ() < b3Part:getMin():getZ() + 500 * GEO.EPS_SMALL then
vtFacesAffected.Bottom = true
end
if Proc.Box:getMin():getY() < b3Part:getMin():getY() + 500 * GEO.EPS_SMALL then
vtFacesAffected.Front = true
end
if Proc.Box:getMax():getY() > b3Part:getMax():getY() - 500 * GEO.EPS_SMALL then
vtFacesAffected.Back = true
end
if Proc.Box:getMin():getX() < b3Part:getMin():getX() + 500 * GEO.EPS_SMALL then
vtFacesAffected.Left = true
end
if Proc.Box:getMax():getX() > b3Part:getMax():getX() - 500 * GEO.EPS_SMALL then
vtFacesAffected.Right = true
end
end
return vtFacesAffected
end
-------------------------------------------------------------------------------------------------------------
-- restituisce le distanze XY tra la feature Proc e le altre parti più vicine, secondo le direzioni Y-/Y+/X-/X+
function WallLib.GetProcessDistanceToNearestParts( Proc)
local b3Proc = Proc.Box
local ptMinProc = b3Proc:getMin()
local ptMaxProc = b3Proc:getMax()
local vtDistances = { Front = 0, Back = 0, Left = 0, Right = 0}
if Proc.AffectedFaces.Front then
vtDistances.Front = GEO.INFINITO
end
if Proc.AffectedFaces.Back then
vtDistances.Back = GEO.INFINITO
end
if Proc.AffectedFaces.Left then
vtDistances.Left = GEO.INFINITO
end
if Proc.AffectedFaces.Right then
vtDistances.Right = GEO.INFINITO
end
local nRawId = EgtGetFirstRawPart()
local nPartId = EgtGetFirstPartInRawPart( nRawId)
while nPartId do
if Proc.PartId ~= nPartId then
local nBoxSolidId = EgtGetFirstNameInGroup( nPartId, 'Box')
local b3Solid = EgtGetBBoxGlob( nBoxSolidId or GDB_ID.NULL, GDB_BB.STANDARD)
b3Solid:expand( - 10 * GEO.EPS_SMALL)
local ptMinPart = b3Solid:getMin()
local ptMaxPart = b3Solid:getMax()
if Proc.AffectedFaces.Front then
if OverlapsXY( b3Proc, b3Solid) then
vtDistances.Front = 0
elseif OverlapsX( b3Proc, b3Solid) then
if ptMaxPart:getY() < ptMinProc:getY() + 100 * GEO.EPS_SMALL then
vtDistances.Front = min( vtDistances.Front, max( 0, ptMinProc:getY() - ptMaxPart:getY()))
end
end
end
if Proc.AffectedFaces.Back then
if OverlapsXY( b3Proc, b3Solid) then
vtDistances.Back = 0
elseif OverlapsX( b3Proc, b3Solid) then
if ptMaxProc:getY() < ptMinPart:getY() + 100 * GEO.EPS_SMALL then
vtDistances.Back = min( vtDistances.Back, max( 0, ptMinPart:getY() - ptMaxProc:getY()))
end
end
end
if Proc.AffectedFaces.Left then
if OverlapsXY( b3Proc, b3Solid) then
vtDistances.Left = 0
elseif OverlapsY( b3Proc, b3Solid) then
if ptMaxPart:getX() < ptMinProc:getX() + 100 * GEO.EPS_SMALL then
vtDistances.Left = min( vtDistances.Left, max( 0, ptMinProc:getX() - ptMaxPart:getX()))
end
end
end
if Proc.AffectedFaces.Right then
if OverlapsXY( b3Proc, b3Solid) then
vtDistances.Right = 0
elseif OverlapsY( b3Proc, b3Solid) then
if ptMaxProc:getX() < ptMinPart:getX() + 100 * GEO.EPS_SMALL then
vtDistances.Right = min( vtDistances.Right, max( 0, ptMinPart:getX() - ptMaxProc:getX()))
end
end
end
end
nPartId = EgtGetNextPartInRawPart( nPartId)
end
return vtDistances
end
-------------------------------------------------------------------------------------------------------------
-- restituisce le distanze XY tra la feature Proc e il termine del grezzo, secondo le direzioni Y-/Y+/X-/X+
function WallLib.GetProcessDistanceToRawPart( Proc, b3Raw)
local b3Proc = Proc.Box
local ptMinProc = b3Proc:getMin()
local ptMaxProc = b3Proc:getMax()
local ptMinRaw = b3Raw:getMin()
local ptMaxRaw = b3Raw:getMax()
local vtDistances = { Front = GEO.INFINITO, Back = GEO.INFINITO, Left = GEO.INFINITO, Right = GEO.INFINITO}
if EnclosesXY( b3Raw, b3Proc) then
vtDistances.Front = max( 0, ptMinProc:getY() - ptMinRaw:getY())
vtDistances.Back = max( 0, ptMaxRaw:getY() - ptMaxProc:getY())
vtDistances.Left = max( 0, ptMinProc:getX() - ptMinRaw:getX())
vtDistances.Right = max( 0, ptMaxRaw:getX() - ptMaxProc:getX())
end
return vtDistances
end
-------------------------------------------------------------------------------------------------------------
function WallLib.GetNailLockOutAreas( vProc)
local vNLO = {}
View File
View File