Compare commits

..

7 Commits

Author SHA1 Message Date
luca.mazzoleni 992a115f93 Merge branch 'develop' into feature/NewStrategyLib 2024-12-10 16:14:55 +01:00
luca.mazzoleni 50753dda52 Merge branch 'STR0003_Splitting' into develop 2024-12-06 16:30:29 +01:00
andrea.villa cff250ca37 - TAILCUT utilizza nuova libreria
- Prima versione funzionante tagli PRECUT
2024-12-05 08:09:50 +01:00
andrea.villa 7309ebb6a3 - Creazione (vuota) nuova libreria StrategyLib
- SPLITCUT non è più una strategia ma sarà una funzionalità della nuova libreria
- Nuova strategia TAILCUT, corrispettivo del HEADCUT sulla testa
- Alla feature 340 si applica la strategia TAILCUT
2024-12-04 10:52:59 +01:00
andrea.villa c649870518 Piccola modifica Splitcut 2024-12-04 10:18:40 +01:00
andrea.villa 3d8ec03c47 Merge branch 'feature/DiceCut' into develop 2024-12-04 10:17:24 +01:00
andrea.villa 42329d7688 Aggiunta libreria DiceCut. Funzione GetDice uniformata a nuovo standard, funzioni interne non modificate. 2024-12-04 10:17:09 +01:00
12 changed files with 1226 additions and 440 deletions
+4 -4
View File
@@ -44,8 +44,8 @@ local function GetStrategies_Egalware( Proc)
Strategies = { { sStrategyId = 'HEADCUT'}} Strategies = { { sStrategyId = 'HEADCUT'}}
--------------------------------------------------------------------- ---------------------------------------------------------------------
-- Feature : Cut -- Feature : Cut
elseif ID.IsSplitCut( Proc) then elseif ID.IsTailCut( Proc) then
Strategies = { { sStrategyId = 'SPLITCUT'}} Strategies = { { sStrategyId = 'TAILCUT'}}
--------------------------------------------------------------------- ---------------------------------------------------------------------
-- Feature : Cut -- Feature : Cut
elseif ID.IsCut( Proc) then elseif ID.IsCut( Proc) then
@@ -302,8 +302,8 @@ local function GetStrategies_Essetre( Proc)
Strategies = { { sStrategyId = 'HEADCUT'}} Strategies = { { sStrategyId = 'HEADCUT'}}
--------------------------------------------------------------------- ---------------------------------------------------------------------
-- Feature : Cut -- Feature : Cut
elseif ID.IsSplitCut( Proc) then elseif ID.IsTailCut( Proc) then
Strategies = { { sStrategyId = 'SPLITCUT'}} Strategies = { { sStrategyId = 'TAILCUT'}}
--------------------------------------------------------------------- ---------------------------------------------------------------------
-- Feature : Cut -- Feature : Cut
elseif ID.IsCut( Proc) then elseif ID.IsCut( Proc) then
+60
View File
@@ -319,6 +319,66 @@ function BeamLib.Is3EdgesApprox( Proc, idFace, nAddGrpId)
return bResult return bResult
end end
-------------------------------------------------------------------------------------------------------------
function BeamLib.GetNzLimDownUp( b3Raw, vtN, vtOrtho)
if BeamData.GetNzLimDownUp then
return BeamData.GetNzLimDownUp( b3Raw, vtN, vtOrtho)
elseif BeamData.C_SIMM then
return -0.484
elseif BeamData.TURN then
return -2
else
if vtOrtho and vtOrtho:getZ() > 0.35 then
-- N_HorAng < 15° or N_HorAng > 55°
if vtN and ( abs( vtN:getY()) < 0.259 or abs( vtN:getY()) > 0.819) then
return -0.708
-- N_HorAng > 50°
elseif vtN and abs( vtN:getY()) > 0.766 then
return -0.383
else
return EgtIf( b3Raw:getDimZ() < BeamData.MIN_DIM_HBEAM, -0.609, -0.383)
end
else
-- N_HorAng > 60°
if vtN and ( abs( vtN:getY()) > 0.866) then
return -0.708
else
if b3Raw:getDimZ() < 120 then
return -0.708
elseif b3Raw:getDimZ() < 200 then
-- N_HorAng < 15° or N_HorAng > 55°
if vtN and ( abs( vtN:getY()) < 0.259 or abs( vtN:getY()) > 0.819) then
return -0.5
else
return -0.383
end
elseif b3Raw:getDimZ() < 300 then
-- N_HorAng < 10°
if vtN and ( abs( vtN:getY()) < 0.174) then
return -0.5
else
return -0.259
end
elseif b3Raw:getDimZ() < BeamData.MIN_DIM_HBEAM then
-- N_HorAng < 10°
if vtN and ( abs( vtN:getY()) < 0.174) then
return -0.342
else
return -0.259
end
else
-- N_HorAng < 10°
if vtN and ( abs( vtN:getY()) < 0.174) then
return -0.383
else
return -0.174
end
end
end
end
end
end
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
-- sovrascrivo i parametri personalizzati salvati su Proc a quelli di default dalla strategia -- sovrascrivo i parametri personalizzati salvati su Proc a quelli di default dalla strategia
-- N.B. : I parametri personalizzati non più presenti tra i default della strategia, verranno ignorati. Quelli extra avranno valore di default -- N.B. : I parametri personalizzati non più presenti tra i default della strategia, verranno ignorati. Quelli extra avranno valore di default
+676
View File
@@ -0,0 +1,676 @@
-- DiceCut.lua by Egaltech s.r.l. 2024/01/23
-- Gestione dei piano paralleli nei tagli lunghi: equidistanziamento dei piani paralleli
-- Tabella per definizione modulo
local DiceCut = {}
-- Include
require( 'EgtBase')
local BeamLib = require( 'BeamLib')
EgtOutLog( ' DiceCut started', 1)
-- Dati
local BeamData = require( 'BeamData')
----------------------------------------------------------------------------------------------------------------------------------------------------
-- creo i piani paralleli
-- GetParallelPlanes: restituisce un vettore con gli indici delle superfici
-- nAddGrpId: il layer
-- b3BoxToDicing: il grezzo della barra
-- ptC: il punto centrale del piano della feature
-- vtN: il versore normale del piano della feature
-- nCopyPlane: 0 => genera una copia del piano passato, 1=> non genera una copia del piano passato
-- dOffset: offset dei piani paralleli
-- nStep: numero massimo di step
-- Color: colre del fascio di piani
-- dTolerance*: distanza tra i piani paralleli e i piani di taglio (se non esistono altre superfici può essere omesso)
-- bNoTolOnFirstCut*: elimina la tolleranza per il primo piano del fascio (se non esistono altre superfici può essere omesso)
-- ptCCut*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso)
-- vtNCut*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso)
-- ptCCut1*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso)
-- vtNCut1*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso)
local function GetParallelPlanes( nAddGrpId, b3BoxToDicing, ptC, vtN, nCopyPlane, dOffset, nStep, Color, dTolerance, bNoTolOnFirstCut, ptCCut, vtNCut, ptCCut1, vtNCut1 )
local ptMyCCut
local AreaMin = 5*5
if ptCCut and vtNCut then
if dTolerance then
ptMyCCut = Point3d( ptCCut + dTolerance * vtNCut)
end
ptMyCCut = Point3d( ptCCut)
end
local ptMyCCut1
if ptCCut1 and vtNCut1 then
ptMyCCut1 = Point3d( ptCCut1 + 0 * vtNCut1)
end
local TabellaTmSurfParallel = {}
local i = nCopyPlane
while i < nStep do
local SurfId = EgtSurfTmPlaneInBBox( nAddGrpId, ptC + ( i * dOffset) * vtN, vtN, b3BoxToDicing, GDB_RT.GLOB)
local nFacet = EgtSurfTmFacetCount( SurfId or GDB_ID.NULL)
if nFacet == 0 then
-- se sono al primo taglio do una possibilità in più di girare
if i > nCopyPlane then
break
end
end
if nFacet > 0 and vtNCut and ptMyCCut and EgtSurfArea(SurfId) > AreaMin then
if i == nCopyPlane and bNoTolOnFirstCut then
EgtCutSurfTmPlane( SurfId, ptCCut, -vtNCut, false, GDB_RT.GLOB)
else
EgtCutSurfTmPlane( SurfId, ptMyCCut, -vtNCut, false, GDB_RT.GLOB)
end
nFacet = EgtSurfTmFacetCount( SurfId)
end
if nFacet > 0 and vtNCut1 and ptMyCCut1 and EgtSurfArea(SurfId) > AreaMin then
if i == nCopyPlane and bNoTolOnFirstCut then
EgtCutSurfTmPlane( SurfId, ptCCut1, -vtNCut1, false, GDB_RT.GLOB)
else
EgtCutSurfTmPlane( SurfId, ptMyCCut1, -vtNCut1, false, GDB_RT.GLOB)
end
nFacet = EgtSurfTmFacetCount( SurfId)
end
if nFacet > 0 and EgtSurfArea(SurfId) > AreaMin then
table.insert( TabellaTmSurfParallel, SurfId)
EgtSetColor( SurfId, Color)
else
EgtErase( SurfId)
end
if dOffset == 0 then
break
end
i = i + 1
end
return TabellaTmSurfParallel
end
----------------------------------------------------------------------------------------------------------------------------------------------------
-- GetOrderedCutTable:
-- nAddGrpId: il layer
-- TabParallelPlanes: tabella delle superfici dei piani paralleli
-- TabOrtoPlanes: tabella delle superfici dei piani ortogonali
-- stampo l'ordine dei piani di taglio (prima tagli ortogonali piu' esterni poi taglio parallelo collettivo)
local function GetOrderedCutTable( nAddGrpId, TabParallelPlanes, TabOrtoPlanes)
local StepParallel = #TabParallelPlanes
local StepOrto = #TabOrtoPlanes
local TabellaOrderParallelCut1 = {}
for IndexTmP=1, StepParallel do
TabellaOrderParallelCut1[IndexTmP] = {}
for IndexOrto=1, StepOrto do
local ptOrtoN, vtNOrtoN = EgtSurfTmFacetCenter( TabOrtoPlanes[IndexOrto ], 0, GDB_ID.ROOT)
local Copy1Id = EgtCopySurfTmFacet( TabParallelPlanes[IndexTmP], 0, nAddGrpId)
local Copy2Id = EgtCopySurfTmFacet( TabParallelPlanes[IndexTmP], 0, nAddGrpId)
if Copy1Id and ptOrtoN then
EgtCutSurfTmPlane( Copy1Id, ptOrtoN, -vtNOrtoN, false, GDB_RT.GLOB)
EgtCutSurfTmPlane( Copy2Id, ptOrtoN, vtNOrtoN, false, GDB_RT.GLOB)
local nFacet1 = EgtSurfTmFacetCount( Copy1Id)
local nFacet2 = EgtSurfTmFacetCount( Copy2Id)
if nFacet1 < 1 then
EgtErase( Copy1Id)
EgtErase( Copy2Id)
EgtCutSurfTmPlane( TabParallelPlanes[IndexTmP], ptOrtoN, vtNOrtoN, false, GDB_RT.GLOB)
elseif nFacet2 < 1 then
EgtErase( Copy1Id)
EgtErase( Copy2Id)
break
else
table.insert( TabellaOrderParallelCut1[IndexTmP], Copy1Id)
EgtErase( Copy2Id)
EgtCutSurfTmPlane( TabParallelPlanes[IndexTmP], ptOrtoN, vtNOrtoN, false, GDB_RT.GLOB)
end
end
end
table.insert(TabellaOrderParallelCut1[IndexTmP], TabParallelPlanes[IndexTmP])
end
return TabellaOrderParallelCut1
end
----------------------------------------------------------------------------------------------------------------------------------------------------
-- GetOrtoCutCenter:
-- idFacet: l'id della faccia
-- ptC: il punto centrale della faccia
-- vtN: il versore normale della faccia
-- vtO: il versore dei piani ortogonali
-- dOffsetEff: offset della distanza dal punto centrale
-- Verifica se l'asse X del box costruito sopra la superficie è più grande di un certo offset
local function GetOrtoCutCenter( FacetId, ptC, vtN, vtO, dOffsetEff, dNzLimDwnUp)
local FrameLocal = Frame3d( EgtSurfTmFacetCenter( FacetId, 0, GDB_ID.ROOT))
EgtSetGridFrame(FrameLocal)
local IdAuxLocal = EgtGroup(EgtGetParent( FacetId), FrameLocal)
EgtSetName( IdAuxLocal, "AuxLocal")
local BoxLocal = EgtGetBBoxRef( FacetId, GDB_BB.STANDARD, FrameLocal)
local ptS = EgtGP( EgtSurfTmBBox( IdAuxLocal, BoxLocal, GDB_RT.GRID), GDB_ID.ROOT)
EgtErase( IdAuxLocal)
EgtSetGridFrame(Frame3d())
-- riferimento intrinseco
local asseX = Vector3d( vtO)
local asseY = vtN ^ asseX
local Frame = Frame3d( ptC, ptC + asseX, ptC + asseY)
-- ingombro della faccia secondo questo riferimento
local Box = EgtGetBBoxRef( FacetId, GDB_BB.STANDARD, Frame)
local dLen = Box:getDimX()
local dWidth = Box:getDimY()
-- se faccia non troppo lunga, con un lato piccolo e non diretta troppo verso il basso, non servono dice
local dMaxLen = BeamData.MAX_LEN_DICE or 600
if dLen < dMaxLen and dWidth < dMaxLen and
( dLen < dOffsetEff + 1.0 or dWidth < dOffsetEff + 1.0) and vtN:getZ() > dNzLimDwnUp then
return nil, nil, nil
end
local N = ceil( dLen / dOffsetEff)
local dOffsetRel = ( dLen / N) + 10 * GEO.EPS_SMALL
local dCopyPlane
local dCenOffs = ( Box:getMax():getX() + Box:getMin():getX()) / 2
if dLen <= dOffsetRel then
dCopyPlane = 1
elseif dLen <= 2 * dOffsetRel then
dOffsetRel = dOffsetEff
dCopyPlane = 0
else
if N % 2 == 0 then
dCopyPlane = 0
elseif N % 2 == 1 then
dCopyPlane = 0.5
end
end
return dOffsetRel, dCopyPlane, dCenOffs, ptS
end
----------------------------------------------------------------------------------------------------------------------------------------------------
-- TableMesh:
-- TableOrto: tabella delle superfici dei piani ortogonali
-- TableParallel: tabella delle superfici dei piani paralleli
-- Forma una tabella unica delle superfici di taglio inserendo strati di tagli ortogonali alternati da strati di taglio parallelo
local function TableMesh( TableOrto, TableParallel)
local TableUnited = {}
for i=1, #TableOrto do
table.insert( TableUnited, TableOrto[i])
table.insert( TableUnited, TableParallel[i])
end
return TableUnited
end
----------------------------------------------------------------------------------------------------------------------------------------------------
-- FindValue:
-- tab: tabella da scansionare
-- val: valore da cercare
-- Verifica se tab contiene val, a supporto della funzione SortOrtoCutsByNormalMethod
local function FindValue( tab, val)
for index, value in ipairs( tab) do
if value == val then
return true
end
end
return false
end
----------------------------------------------------------------------------------------------------------------------------------------------------
-- SortOrtoCutsByNormalMethod:
-- TabParallelPlanes: tabella delle superfici dei piani paralleli
-- TabOrtoPlanes: tabella delle superfici dei piani ortogonali
-- stampo l'ordine dei piani di taglio sfruttando il prodotto dei versori normali (prima tagli ortogonali piu' esterni poi taglio parallelo collettivo)
local function SortOrtoCutsByNormalMethod( TabParallelPlanes, TabOrtoPlanes)
-- tabella dei tagli ordinati
local TabOrderOrtoCut = {}
-- tabella ausiliaria dei dati inseriti nell'ordine
local TabAux = {}
-- ciclo di ordinamento
local StepParallel = #TabParallelPlanes
local StepOrto = #TabOrtoPlanes
for IndexTmP=1, StepParallel do
TabOrderOrtoCut[IndexTmP] = {}
local ptParalN, vtNParalN = EgtSurfTmFacetCenter( TabParallelPlanes[IndexTmP][1], 0, GDB_ID.ROOT)
for IndexOrto=1, StepOrto do
for i=1, #TabOrtoPlanes[IndexOrto] do
-- identificativo del taglio
local OrtoPlaneId = TabOrtoPlanes[IndexOrto][i]
-- controlla che l'elemento da valutare non sia gia' stato inserito nella tabella
if not FindValue( TabAux, OrtoPlaneId) then
local ptOrtoN, vtNOrtoN = EgtSurfTmFacetCenter( OrtoPlaneId, 0, GDB_ID.ROOT)
local scalarProduct = ( ptOrtoN - ptParalN) * vtNParalN
if scalarProduct > 0 then
table.insert( TabOrderOrtoCut[IndexTmP], OrtoPlaneId)
table.insert( TabAux, OrtoPlaneId)
end
end
end
end
end
-- cancello dal DB geometrico i tagli non inseriti
for IndexOrto=1, StepOrto do
for i=1, #TabOrtoPlanes[IndexOrto] do
-- identificativo del taglio
local OrtoPlaneId = TabOrtoPlanes[IndexOrto][i]
-- ricerco il taglio tra gli inseriti
if not FindValue( TabAux, OrtoPlaneId) then
EgtErase( OrtoPlaneId)
end
end
end
return TabOrderOrtoCut
end
----------------------------------------------------------------------------------------------------------------------------------------------------
-- VerifyFirstOrthoCut :
-- CutTable: tabella dei tagli
-- OffsetP: offset della distanza dal punto centrale
-- b3BoxToDicing: il grezzo della barra
-- Verifica se l'asse X del box costruito sopra le 2 facce è più piccolo di un certo offset e quindi la faccia O è superflua
local function VerifyFirstOrthoCut( CutTable, OffsetP, b3BoxToDicing, dNzLimDwnUp)
if not CutTable[1] or not CutTable[2] then return end
local CutOId = CutTable[1][1]
local Cut1Id = CutTable[2][1]
local Cut2Id = CutTable[2][2]
if CutOId and Cut1Id and Cut2Id then
-- centri e normali delle due semifacce
local ptC1, vtN1 = EgtSurfTmFacetCenter( Cut1Id, 0, GDB_ID.ROOT)
local ptC2, vtN2 = EgtSurfTmFacetCenter( Cut2Id, 0, GDB_ID.ROOT)
-- normale alla faccia ortogonale
local _, vtO = EgtSurfTmFacetCenter( CutOId, 0, GDB_ID.ROOT)
vtO = vtO - vtO * vtN1 * vtN1 ; vtO:normalize()
local dMaxElev = EgtSurfTmFacetElevationInBBox( CutOId, 0, b3BoxToDicing, true, GDB_ID.ROOT)
-- calcolo lunghezza prima semi-faccia
local asseX1 = vtO
local asseY1 = vtN1 ^ asseX1
local Frame1 = Frame3d( ptC1, ptC1+asseX1, ptC1+asseY1)
local Box1 = EgtGetBBoxRef( Cut1Id, GDB_BB.STANDARD, Frame1)
local x1 = Box1:getDimX()
-- prendo il massimo tra la lugnhezza della faccia parallela e l'elevazione della corrispondente ortogonale
x1 = max( x1, dMaxElev)
-- calcolo lunghezza seconda semi-faccia
local asseX2 = vtO
local asseY2 = vtN2 ^ asseX2
local Frame2 = Frame3d( ptC2, ptC2+asseX2, ptC2+asseY2)
local Box2 = EgtGetBBoxRef( Cut2Id, GDB_BB.STANDARD, Frame2)
local x2 = Box2:getDimX()
-- lunghezza totale faccia
local dLongSize = x1 + x2
-- se faccia piccola e non orientata verso il basso, elimino ortogonale e unisco le due parti
if dLongSize <= OffsetP + 1.0 and vtN1:getZ() > dNzLimDwnUp then
local nAddGrpId = EgtGetParent( Cut1Id)
local SurfId = EgtSurfTmBySewing( nAddGrpId, { Cut1Id, Cut2Id})
EgtSetColor( SurfId, Color3d( FUCHSIA(), 60))
EgtErase( CutOId)
table.remove( CutTable[1], 1)
table.remove( CutTable[2], 1)
table.remove( CutTable[2], 1)
table.insert( CutTable[2], 1, SurfId)
end
end
end
----------------------------------------------------------------------------------------------------------------------------------------------------
-- ricavo i vertici del box
local function CalcolaPuntiEstremiBox( b3BoxToDicing)
local ptMin = b3BoxToDicing:getMin()
local ptMax = b3BoxToDicing:getMax()
local TBoxPoint = {}
table.insert( TBoxPoint, { P = Point3d( ptMin:getX(), ptMin:getY(), ptMin:getZ()), On = true})
table.insert( TBoxPoint, { P = Point3d( ptMax:getX(), ptMin:getY(), ptMin:getZ()), On = true})
table.insert( TBoxPoint, { P = Point3d( ptMin:getX(), ptMax:getY(), ptMin:getZ()), On = true})
table.insert( TBoxPoint, { P = Point3d( ptMax:getX(), ptMax:getY(), ptMin:getZ()), On = true})
table.insert( TBoxPoint, { P = Point3d( ptMin:getX(), ptMin:getY(), ptMax:getZ()), On = true})
table.insert( TBoxPoint, { P = Point3d( ptMax:getX(), ptMin:getY(), ptMax:getZ()), On = true})
table.insert( TBoxPoint, { P = Point3d( ptMin:getX(), ptMax:getY(), ptMax:getZ()), On = true})
table.insert( TBoxPoint, { P = Point3d( ptMax:getX(), ptMax:getY(), ptMax:getZ()), On = true})
return TBoxPoint
end
----------------------------------------------------------------------------------------------------------------------------------------------------
-- restituisce i punti che devono essere presi in considerazione per la costruzione del BoundingBox
local function VerificaEstremiGrezzo( ptC, vtN, TPoint)
for i = 1, #TPoint do
if ( TPoint[i].P - ptC) * vtN < 0 then
TPoint[i].On = false
end
end
return TPoint
end
----------------------------------------------------------------------------------------------------------------------------------------------------
-- ricavo l'altezza del BoundingBox assegnati gli estremi del grezzo e la feature
-- le funzioni commentate permettono di vedere la creazione di BoundingBox
local function DistanzaMassima( nAddGrpId, ptC1, vtN1, ptC2, vtN2, b3BoxToDicing, TPoint)
-- calcolo il riferimento nel piano 1
local Frame1 = Frame3d( ptC1, vtN1)
-- determino l'ingombro in questo riferimento della parte di trave compresa nel o nei piani
local BB1 = BBox3d()
-- punti di vertice della trave compresi
for i = 1, #TPoint do
if TPoint[i].On then
local ptP = Point3d( TPoint[i].P)
ptP:toLoc( Frame1)
BB1:Add( ptP)
end
end
-- eventuale altra faccia
if ptC2 and vtN2 then
local IdAux = EgtGroup( nAddGrpId)
local IdSurf2 = EgtSurfTmPlaneInBBox( IdAux, ptC2, vtN2, b3BoxToDicing, GDB_RT.GLOB)
EgtCutSurfTmPlane( IdSurf2, ptC1, -vtN1, false, GDB_RT.GLOB)
if IdSurf2 then
local BB2 = EgtGetBBoxRef( IdSurf2, GDB_BB.STANDARD, Frame1)
BB1:Add( BB2)
end
EgtErase( IdAux)
end
if not BB1:isEmpty() then
return ( BB1:getMax():getZ() + 0.1)
end
return 0
end
----------------------------------------------------------------------------------------------------------------------------------------------------
-- DiceCut.GetDice :
-- nParent: il layer
-- BBoxRawPart: il grezzo della barra
-- ptCPlanes: il punto centrale del piano della feature
-- vtNPlanes: il versore normale del piano della feature
-- bGetOrtoPlanes*: se voglio calcolare i piani ortogonali al piano passato (se non esistono altre superfici può essere omesso)
-- ptCBond*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso)
-- vtNBond*: il versore normale della superfice limitante (se non esistono altre superfici può essere omesso)
-- dOrthoMaxDim : massima profondità taglio se faccia singola perpendicolare facce laterali trave
-- dCustMaxDimDice: dimensione massima customizzata, sostituisce il parametro BeamData.MAX_DIM_DICE (se negativa qualunque, se positiva deve stare nel MAX)
-- bDownHead : taglio con testa da sotto
----------------------------------------------------------------------------------------------------------------------------------------------------
-- function DiceCut.GetDice( nParent, BBoxRawPart, ptCPlanes, vtNPlanes, bGetOrtoPlanes, ptCBond, vtNBond, dOrthoMaxDim, dCustMaxDimDice, bDownHead)
---------------------------------------------------------------------------------------------------------------
-- DiceCut.GetDice :
-- Part : pezzo
-- MainFace : lista. Contiene tutti i dati della faccia principale. Obblogatori i campi '.ptCenter' e '.vtNormal'
-- SubordinateFace : lista. Contiene tutti i dati della faccia secondaria. Se non esiste, la lista è vuota. Se esiste, obblogatori i campi '.ptCenter' e '.vtNormal'
-- OptionaParameters : eventuali parametri opzionali
---------------------------------------------------------------------------------------------------------------
function DiceCut.GetDice( Part, Face1, Face2, OptionalParameters)
local dMaxDimDice = BeamData.MAX_DIM_DICE
local dTolerance = 0 -- distanza di sicurezza per i tagli ortogonali
local OffsetP = dMaxDimDice -- distanza tra i piani paralleli
local StepP = 100 -- numero massimo di piani paralleli da generare
local OffsetO = dMaxDimDice -- distanza tra i piani ortogonali
local StepO = 100 -- numero massimo di piani ortogonali da generare
-- recupero gruppo per geometria addizionale
local nAddGrpId = BeamLib.GetAddGroup( Part.id)
-- se il box non è passato tra i parametri opzionali, faccio i calcoli sul SOLID del Part
local b3BoxToDicing = OptionalParameters.b3BoxToDicing or Part.b3Solid
-- copio dati passati su variabili locali
local ptCMainFace, vtNMainFace, ptCSubordinateFace, vtNSubordinateFace, bGetOrtoPlanes
if Face1.ptCenter and Face1.vtNormal then
ptCMainFace = Face1.ptCenter
vtNMainFace = Face1.vtNormal
end
-- se esiste faccia secondaria non esiste, forzo calcolo piani ortogonali
if Face2.ptCenter and Face2.vtNormal then
ptCSubordinateFace = Face2.ptCenter
vtNSubordinateFace = Face2.vtNormal
bGetOrtoPlanes = false
else
bGetOrtoPlanes = true
end
-- ricavo dimensione massima cubetti
if OptionalParameters.dCustMaxDimDice and OptionalParameters.dCustMaxDimDice < BeamData.MAX_DIM_DICE then
dMaxDimDice = abs( OptionalParameters.dCustMaxDimDice)
end
--Ricavo le altezze dei BoundingBox contenente feature e estremi del grezzo
local TBoxPoint = CalcolaPuntiEstremiBox( b3BoxToDicing)
TBoxPoint = VerificaEstremiGrezzo( ptCMainFace, vtNMainFace, TBoxPoint)
if ptCSubordinateFace and vtNSubordinateFace then
TBoxPoint = VerificaEstremiGrezzo( ptCSubordinateFace, vtNSubordinateFace, TBoxPoint)
end
local dElevP = DistanzaMassima( nAddGrpId, ptCMainFace, vtNMainFace, ptCSubordinateFace, vtNSubordinateFace, b3BoxToDicing, TBoxPoint)
local dElevO
if ptCSubordinateFace and vtNSubordinateFace and not AreOppositeVectorApprox( vtNSubordinateFace, vtNMainFace) then
dElevO = DistanzaMassima( nAddGrpId, ptCSubordinateFace, vtNSubordinateFace, ptCMainFace, vtNMainFace, b3BoxToDicing, TBoxPoint)
end
-- inclinazione limite per taglio da sotto
local dNzLimDwnUp = BeamLib.GetNzLimDownUp( b3BoxToDicing)
-- se non c'è testa da sotto e normali senza componenti in Y con faccia quasi verticale e trave non alta, uso per offset i limiti dei tagli di testa e coda
if not BeamData.DOWN_HEAD and abs( vtNMainFace:getY()) < 0.1 and vtNMainFace:getZ() < 0.7071 and ( not vtNSubordinateFace or abs( vtNSubordinateFace:getY()) < 0.1) and b3BoxToDicing:getDimZ() < BeamData.MIN_DIM_HBEAM then
OffsetO = OptionalParameters.dOrthoMaxDim or BeamData.MAX_DIM_HTCUT
end
-- aggiungo piccolo extra agli offset
OffsetP = OffsetP + 10 * GEO.EPS_SMALL
OffsetO = OffsetO + 10 * GEO.EPS_SMALL
-- se piani non ortogonali, diminuisco la distanza di offset opportunamente
local originalOffsetP = OffsetP
if not bGetOrtoPlanes then
local dCoeff = ( vtNMainFace ^ vtNSubordinateFace):len()
OffsetP = OffsetP * dCoeff
OffsetO = OffsetO * dCoeff
end
local n = ceil( dElevP / OffsetP)
OffsetP = dElevP / n
if dElevO then
local m = ceil( dElevO / OffsetO)
OffsetO = dElevO / m
end
-- elenco di tutte le superfici generate dai tagli
local TabFUCHSIA = {}
local TabGREEN = {}
-- PIANI PARALLELI alla faccia di taglio
local TabellaTmSurfP = {}
local TabFromIn = GetParallelPlanes( nAddGrpId, b3BoxToDicing, ptCMainFace, vtNMainFace, 0, OffsetP, StepP, Color3d( FUCHSIA(), 60), dTolerance, true, ptCSubordinateFace, vtNSubordinateFace)
for i = #TabFromIn, 1, -1 do
table.insert( TabellaTmSurfP, TabFromIn[i])
end
-- PIANI ORTOGONALI alla faccia di taglio
-- orientamento definito da seconda faccia
if not bGetOrtoPlanes then
local TabellaTmSurfOrto = {}
local TabFromIn = GetParallelPlanes( nAddGrpId, b3BoxToDicing, ptCSubordinateFace, vtNSubordinateFace, 0, OffsetO, StepO, Color3d( GREEN(), 60), dTolerance, false, ptCMainFace, vtNMainFace)
for i = #TabFromIn, 1, -1 do
table.insert( TabellaTmSurfOrto, TabFromIn[i])
end
local TabellaOrderParallelCut = GetOrderedCutTable( nAddGrpId, TabellaTmSurfP, TabellaTmSurfOrto) -- Ottiene la tabella dei tagli paralleli ordinati
local TabellaOrderOrtoCut = GetOrderedCutTable( nAddGrpId, TabellaTmSurfOrto, TabellaTmSurfP) -- Ottiene la tabella dei tagli ortogonali da riordinare per strato
TabGREEN = SortOrtoCutsByNormalMethod( TabellaOrderParallelCut, TabellaOrderOrtoCut) -- I tagli ortogonali vengono ordinati per strato
TabFUCHSIA = TabellaOrderParallelCut -- I tagli paralleli sono già ordinati
-- orientamento da definire
else
for PlnInd = 1, #TabellaTmSurfP do
-- piano interno
local ptCInner, vtNInner = EgtSurfTmFacetCenter( TabellaTmSurfP[PlnInd], 0, GDB_ID.ROOT)
-- eventuale piano esterno
local ptCOuter, vtNOuter = nil, nil
if PlnInd > 1 then
ptCOuter, vtNOuter = EgtSurfTmFacetCenter( TabellaTmSurfP[PlnInd-1], 0, GDB_ID.ROOT)
vtNOuter = -vtNOuter
end
-- calcolo la direzione dei piani ortogonali
local vtO = VectorFromUprightOrtho( vtNInner)
if vtNInner:getZ() > -0.0175 or vtNInner:getZ() < dNzLimDwnUp or abs( vtNInner:getY()) > 0.8 then
vtO:rotate( vtNInner, 90)
-- se diretto troppo ortogonalmente all'asse trave e taglio non da sotto, lo ruoto ulteriormente
if ( abs( vtO:getY()) > 4 * abs( vtO:getX()) or b3BoxToDicing:getDimZ() > 620) and vtNInner:getZ() > dNzLimDwnUp then
vtO:rotate( vtNInner, 90)
-- se faccia principale verso il basso (almeno -3deg), lo inverto per iniziare da sopra
if vtNInner:getZ() < -0.05 then
vtO = -vtO
end
else
if vtNInner:getX() > -0.017 then
if vtO:getX() < -0.001 then vtO = -vtO end
else
if vtO:getX() > 0.001 then vtO = -vtO end
end
end
end
-- se quasi verticale (fino a 20 gradi di distanza) su faccia inclinata in Y, ruoto di 90 gradi
if vtO:getZ() > 0.939 and abs( vtNInner:getY()) > 0.5 then
vtO:rotate( vtNInner, 90)
end
-- se taglio con testa da sotto
if OptionalParameters.bHeadFromBottom and vtO:getZ() > 0.05 then
vtO = -vtO
end
-- calcolo le dimensioni dell'offset e dove posizionare la prima faccia:
-- CopyPlane: 0 => crea la prima faccia direttamente sul punto passato
-- CopyPlane: 1 => crea la prima faccia e tutte le altre con l'offset passato
-- CopyPlane: 0.5 => crea la prima faccia a metà offset e tutte le altre con l'offest intero
local OffsetRel, CopyPlane, dCenOffs, ptCStart = GetOrtoCutCenter( TabellaTmSurfP[PlnInd], ptCInner, vtNInner, vtO, OffsetO, dNzLimDwnUp)
if OffsetRel and CopyPlane and dCenOffs then
ptCInner = ptCInner + dCenOffs * vtO
local TabRight = GetParallelPlanes( nAddGrpId, b3BoxToDicing, ptCStart, vtO, CopyPlane, -OffsetRel, StepO, Color3d( GREEN(), 60),
dTolerance, false, ptCInner, vtNInner, ptCOuter, vtNOuter)
if CopyPlane == 0 then
CopyPlane = 1
end
local TabLeft = GetParallelPlanes( nAddGrpId, b3BoxToDicing, ptCStart, vtO, CopyPlane, OffsetRel, StepO, Color3d( GREEN(), 60),
dTolerance, false, ptCInner, vtNInner, ptCOuter, vtNOuter)
-- carico la tabella con gli indici riordinati
local TempOrtoTab = {}
for i = #TabLeft, 1, -1 do
table.insert( TempOrtoTab, TabLeft[i])
end
for i = 1, #TabRight do
table.insert( TempOrtoTab, TabRight[i])
end
-- creo una tabella per ogni piano per generare i tagli sulla Inner
local TempParTab = GetOrderedCutTable( nAddGrpId, {TabellaTmSurfP[PlnInd]}, TempOrtoTab)
for i = 1, #TempParTab do
table.insert( TabFUCHSIA, TempParTab[i])
end
table.insert( TabGREEN, TempOrtoTab)
else
table.insert( TabFUCHSIA, {TabellaTmSurfP[PlnInd]})
table.insert( TabGREEN, {})
end
end
end
-- Se sono state costruite non più di una faccia parallela e una faccia perpendicolare, allora non servono e tengo le originali
if #TabGREEN == 1 and #TabGREEN[1] <= 1 and #TabFUCHSIA == 1 and #TabFUCHSIA[1] <= 1 then
if #TabGREEN[1] == 1 then
EgtErase( TabGREEN[1][1])
end
TabGREEN = {}
if #TabFUCHSIA[1] == 1 then
EgtErase( TabFUCHSIA[1][1])
end
TabFUCHSIA = {}
end
-- Si uniscono le tabelle dei tagli ortogonali e paralleli in una sola tabella
local UltimateTable = TableMesh( TabGREEN, TabFUCHSIA)
-- Se esiste la superficie limitante (nFacet == 2) verifica se il taglio più esterno è superfluo e quindi viene eliminato
if not bGetOrtoPlanes then
VerifyFirstOrthoCut( UltimateTable, originalOffsetP, b3BoxToDicing, dNzLimDwnUp)
-- se rimangono due sole facce, devono coincidere con le originali e quindi sono superflue
if #UltimateTable == 2 and #UltimateTable[1] == 1 and #UltimateTable[2] == 1 then
EgtErase( UltimateTable[1][1])
EgtErase( UltimateTable[2][1])
UltimateTable = {}
end
end
return UltimateTable
end
----------------------------------------------------------------------------------------------------------------------------------------------------
-- PrintOrderCut:
-- TabellaOrderCut: tabella delle superfici di taglio
-- stampo l'ordine dei piani di taglio ricevendo una tabella con gli strati parallelo/ortogonali già ordinati
function DiceCut.PrintOrderCut( TabellaOrderCut)
local Step = #TabellaOrderCut
if Step > 0 then
EgtOutLog( " L'ordine delle superfici da tagliare è il seguente:")
else
EgtOutLog( ' Non sono necessarie superfici aggiuntive di taglio.')
end
for i = 1, Step do
if i % 2 == 1 then
EgtOutLog( ' *** Strato di taglio ' .. EgtNumToString( ( i + 1) / 2, 0))
if #TabellaOrderCut[i] > 0 then
EgtOutLog( ' Tagli ortogonali: ')
else
EgtOutLog( ' Tagli ortogonali assenti')
end
else
if #TabellaOrderCut[i] > 0 then
EgtOutLog( ' Tagli paralleli: ')
else
EgtOutLog( ' Tagli paralleli assenti')
end
end
for j=1, #TabellaOrderCut[i] do
EgtOutLog( ' Indice faccia ' .. (TabellaOrderCut[i][j] or 0))
end
end
end
----------------------------------------------------------------------------------------------------------------------------------------------------
local function DiceCutTest()
-- salvo l'indice del layer Trimesh selezionato
local SelectedIndex = EgtGetFirstSelectedObj()
-- verifico che sia selezionato un elemento
if not SelectedIndex then return end
-- salvo l'indice del layer Processing
local nAddGrpId = EgtGetParent( SelectedIndex)
-- salvo l'indice del layer Part
local nRawPart = EgtGetParent( nAddGrpId)
local nBox = EgtGetFirstNameInGroup( nRawPart, 'Box')
-- carico il bounding box della trave
-- local b3BoxToDicing = EgtGetBBoxGlob( nRawPart, GDB_BB.STANDARD )
local b3BoxToDicing = EgtGetBBoxGlob( nBox, GDB_BB.STANDARD )
-- seleziono il Part e il Layer di destinazione
EgtSetCurrPartLayer( nRawPart, nAddGrpId)
-- conto il numero di facce da processare
local nFacet = EgtSurfTmFacetCount( SelectedIndex)
EgtOutLog( ' Numero facce ' .. nFacet, 1)
-- salvo
local TabPlanesFeatures = {}
for i = 1, nFacet do
local ptC, vtN = EgtSurfTmFacetCenter( SelectedIndex, i - 1, GDB_ID.ROOT)
table.insert( TabPlanesFeatures, { ptC = ptC, vtN = vtN})
end
local ptC1 = Point3d( TabPlanesFeatures[1].ptC)
local vtN1 = Vector3d( TabPlanesFeatures[1].vtN)
local CutTable = {}
if nFacet == 1 then
CutTable = DiceCut.GetDice( nAddGrpId, b3BoxToDicing, ptC1, vtN1, true)
elseif nFacet == 2 then
CutTable = DiceCut.GetDice( nAddGrpId, b3BoxToDicing, ptC1, vtN1, false, TabPlanesFeatures[2].ptC, TabPlanesFeatures[2].vtN)
end
if EgtGetDebugLevel() >= 3 then
DiceCut.PrintOrderCut( CutTable)
end
EgtDeselectAll()
EgtDraw()
end
----------------------------------------------------------------------------------------------------------------------------------------------------
--DiceCutTest()
return DiceCut
+1 -1
View File
@@ -22,7 +22,7 @@ function FeatureLib.NeedTopologyFeature( Proc)
return true return true
elseif ID.IsHeadCut( Proc) then elseif ID.IsHeadCut( Proc) then
return true return true
elseif ID.IsSplitCut( Proc) then elseif ID.IsTailCut( Proc) then
return true return true
elseif ID.IsDoubleCut( Proc) then elseif ID.IsDoubleCut( Proc) then
return true return true
+2 -2
View File
@@ -13,8 +13,8 @@ function Identity.IsHeadCut( Proc)
return ( Proc.nGrp == 1 and Proc.nPrc == 340) return ( Proc.nGrp == 1 and Proc.nPrc == 340)
end end
--------------------------------------------------------------------- ---------------------------------------------------------------------
-- Feature : Split Cut -- Feature : Tail Cut
function Identity.IsSplitCut( Proc) function Identity.IsTailCut( Proc)
return ( Proc.nGrp == 2 and Proc.nPrc == 350) return ( Proc.nGrp == 2 and Proc.nPrc == 350)
end end
+368
View File
@@ -0,0 +1,368 @@
-- StrategyLib.lua by Egalware s.r.l. 2024/04/02
-- Libreria di supporto a strategie con funzioni comune a strategie diverse.
-- Tabella per definizione modulo
local StrategyLib = {}
-- Include
require( 'EgtBase')
-- Carico i dati globali
local BeamData = require( 'BeamData')
local FeatureLib = require( 'FeatureLib')
local MachiningLib = require( 'MachiningLib')
-- strategie di base
local FaceByBlade = require('FACEBYBLADE')
EgtOutLog( ' StrategyLib started', 1)
-----------------------------------------------------------------------------------
---------------------- FUNZIONI DI SPLIT ------------------------------------------
-----------------------------------------------------------------------------------
StrategyLib.SplitStrategy = {}
function StrategyLib.SplitStrategy.Get( Proc, Part, OptionalParameters)
local Machining = {}
local Result = {}
-- sTypeMachining = BladeSideSingle\ BladeSideDouble\ BladeHorizontalSingle\ BladeHorizontalDouble\ ChainSawHorizontal\ ChainSawSideSingle\ ChainSawSideDouble\ ChainSawPlusBlade\ Mill\ None
Machining.sTypeMachining = 'None'
local Splitting = {}
-- imposto parametri di ricerca utensile in base a topologia
local ToolSearchParameters = {}
ToolSearchParameters.vtToolDirection = Proc.Faces[1].vtN
-- ===== RICERCA UTENSILE =====
-- cerco lama sopra
Splitting.bIsApplicable = false
ToolSearchParameters.bAllowTopHead = true
ToolSearchParameters.bAllowBottomHead = false
Splitting.ToolInfo = {}
Splitting.ToolInfo = MachiningLib.FindBlade( Proc, ToolSearchParameters)
if Splitting.ToolInfo.nToolIndex then
Splitting.bIsApplicable = true
local ParametersMRR = {}
ParametersMRR.nToolIndex = Splitting.ToolInfo.nToolIndex
Splitting.dMRR = MachiningLib.GetToolMRR( ParametersMRR)
end
table.insert( Machining, Splitting)
-- cerco lama sotto
Splitting = {}
Splitting.bIsApplicable = false
ToolSearchParameters.bAllowTopHead = false
ToolSearchParameters.bAllowBottomHead = true
Splitting.ToolInfo = {}
Splitting.ToolInfo = MachiningLib.FindBlade( Proc, ToolSearchParameters)
if Splitting.ToolInfo.nToolIndex then
Splitting.bIsApplicable = true
local ParametersMRR = {}
ParametersMRR.nToolIndex = Splitting.ToolInfo.nToolIndex
Splitting.dMRR = MachiningLib.GetToolMRR( ParametersMRR)
end
table.insert( Machining, Splitting)
-- cerco motosega
Splitting = {}
Splitting.bIsApplicable = false
table.insert( Machining, Splitting)
-- cerco fresa
Splitting = {}
Splitting.bIsApplicable = false
table.insert( Machining, Splitting)
-- ===== SCELTA LAVORAZIONI =====
-- forzature da parametri
if OptionalParameters.bForceChainSaw then
Machining[1].bIsApplicable = false
Machining[2].bIsApplicable = false
end
-- setto valori di default. Impossibile che taglio di separazione sia incompleto
Result.sStatus = 'Completed'
Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( 100)
Result.dMRR = 1
-- correzioni sul massimo materiale lama, considerando ingombri vari
local dMaxMatBladeSideSingle
local dMaxMatBladeSideDouble
local dMaxMatBladeHorizontalSingle
local dMaxMatBladeHorizontalDouble
if Machining[1].bIsApplicable then
local dMaxMat = TOOLS[Machining[1].ToolInfo.nToolIndex].dMaxMaterial
local dRadius = TOOLS[Machining[1].ToolInfo.nToolIndex].dDiameter / 2
local sHead = TOOLS[Machining[1].ToolInfo.nToolIndex].sHead
-- se taglio di fianco disponibile, si controlla il massimo materiale reale. Per pezzi alti, bisogna controllare anche l'ingombro asse Z nelle 4 direzioni.
if Part.dHeight < BeamData.MIN_DIM_HBEAM then
dMaxMat = min( dMaxMat, BeamData.MAX_DIM_HTCUT)
dMaxMatBladeSideSingle = dMaxMat
dMaxMatBladeSideDouble = dMaxMat * 2
else
if BeamData.GetMaxMatReductionBladeCut then
dMaxMatBladeSideSingle = min( max( dRadius - BeamData.GetMaxMatReductionBladeCut( sHead, Y_AX()), dRadius - BeamData.GetMaxMatReductionBladeCut( sHead, -Y_AX())),
TOOLS[Machining[1].ToolInfo.nToolIndex].dMaxMaterial)
dMaxMatBladeSideDouble = dRadius - BeamData.GetMaxMatReductionBladeCut( sHead, Y_AX()) + dRadius - BeamData.GetMaxMatReductionBladeCut( sHead, -Y_AX())
else
dMaxMatBladeSideSingle = abs( BeamData.MAX_DIM_HTCUT_HBEAM)
dMaxMatBladeSideDouble = abs( BeamData.MAX_DIM_HTCUT_HBEAM) * 2
end
end
-- se taglio orizzontale
if BeamData.GetMaxMatReductionBladeCut then
dMaxMatBladeHorizontalSingle = min( TOOLS[Machining[1].ToolInfo.nToolIndex].dMaxMaterial, dRadius - BeamData.GetMaxMatReductionBladeCut( TOOLS[Machining[1].ToolInfo.nToolIndex].sHead, -Z_AX()))
else
dMaxMatBladeHorizontalSingle = TOOLS[Machining[1].ToolInfo.nToolIndex].dMaxMaterial
end
end
if Machining[2].bIsApplicable then
if BeamData.GetMaxMatReductionBladeCut then
local dRadius = TOOLS[Machining[2].ToolInfo.nToolIndex].dDiameter / 2
dMaxMatBladeHorizontalDouble = min( TOOLS[Machining[2].ToolInfo.nToolIndex].dMaxMaterial, dRadius - BeamData.GetMaxMatReductionBladeCut( TOOLS[Machining[2].ToolInfo.nToolIndex].sHead, Z_AX()))
else
dMaxMatBladeHorizontalDouble = TOOLS[Machining[2].ToolInfo.nToolIndex].dMaxMaterial
end
end
-- TODO considerare di tagliare con il massimo materiale possibile per non salire troppo in Z (macchine tipo PF), oppure non scendere troppo (tipo Kairos)
-- BladeSideSingle (taglio di lama singolo di fianco)
if Machining[1].bIsApplicable and ( dMaxMatBladeSideSingle - BeamData.CUT_EXTRA) > Part.dWidth + 10 * GEO.EPS_SMALL then
Result.nQuality = FeatureLib.GetFeatureQuality( 'Blade')
Machining.sTypeMachining = 'BladeSideSingle'
Machining[2].bIsApplicable = false
Machining[3].bIsApplicable = false
Machining[4].bIsApplicable = false
return Machining, Result
-- TODO considerare di tagliare con il massimo materiale possibile per non salire troppo in Z (macchine tipo PF), oppure non scendere troppo (tipo Kairos)
-- BladeSideDouble (taglio di lama doppio di fianco)
elseif Machining[1].bIsApplicable and ( dMaxMatBladeSideDouble - BeamData.CUT_EXTRA) > Part.dWidth + 10 * GEO.EPS_SMALL then
Result.nQuality = FeatureLib.GetFeatureQuality( 'Blade')
Result.dMRR = Result.dMRR/2
Machining.sTypeMachining = 'BladeSideDouble'
Machining[2].bIsApplicable = false
Machining[3].bIsApplicable = false
Machining[4].bIsApplicable = false
return Machining, Result
-- BladeHorizontalSingle (taglio di lama singolo orizzontale)
elseif Machining[1].bIsApplicable and ( dMaxMatBladeHorizontalSingle - BeamData.CUT_EXTRA) > Part.dHeight + 10 * GEO.EPS_SMALL then
Result.nQuality = FeatureLib.GetFeatureQuality( 'Blade')
Machining.sTypeMachining = 'BladeHorizontalSingle'
Machining[2].bIsApplicable = false
Machining[3].bIsApplicable = false
Machining[4].bIsApplicable = false
return Machining, Result
-- BladeHorizontalDouble (taglio di lama doppio orizzontale)
elseif Machining[1].bIsApplicable and Machining[2].bIsApplicable and
( dMaxMatBladeHorizontalSingle + dMaxMatBladeHorizontalDouble - BeamData.CUT_EXTRA) > Part.dHeight + 10 * GEO.EPS_SMALL then
Result.nQuality = FeatureLib.GetFeatureQuality( 'Blade')
Result.dMRR = Result.dMRR/2
Machining.sTypeMachining = 'BladeHorizontalDouble'
Machining[1].ToolInfo.dMaxMatBladeFromTop = dMaxMatBladeHorizontalSingle
Machining[2].ToolInfo.dMaxMatBladeFromDown = dMaxMatBladeHorizontalDouble
Machining[3].bIsApplicable = false
Machining[4].bIsApplicable = false
return Machining, Result
-- TODO : casi con motosega da completare
-- ChainSawHorizontal (motosega)
-- ChainSawSideSingle (motosega)
-- ChainSawSideDouble (motosega)
-- ChainSawPlusBlade (motosega più lama orizzontale)
-- Mill (svuotatura)
end
-- se non ho trovato neanche una lavorazione completa, non posso separare
if Machining.sTypeMachining == 'None' then
Result.sStatus = 'Not-Applicable'
Result.nCompletionIndex = 0
Result.dMRR = 0
Result.nQuality = 0
Result.sInfo = 'Split not possible'
end
return Machining, Result
end
-------------------------------------------------------------------------------------------------------------
function StrategyLib.SplitStrategy.GetEdgeToMachine( Proc, vtEdge)
local Edge
for i = 1, #Proc.Faces[1].Edges do
if AreSameVectorApprox( Proc.Faces[1].Edges[i].Norm, vtEdge) then
Edge = Proc.Faces[1].Edges[i]
end
end
return Edge
end
-------------------------------------------------------------------------------------------------------------
function StrategyLib.SplitStrategy.CalculateLeadInOut( EdgeToMachine)
local LeadIn = {}
local LeadOut = {}
LeadIn.dStartAddLength = 0
LeadOut.dEndAddLength = 0
LeadIn.nType = MCH_MILL_LI.LINEAR
LeadOut.nType = MCH_MILL_LI.LINEAR
LeadIn.dTangentDistance = 0
LeadOut.dTangentDistance = 0
-- elevazione sempre in negativo
if EdgeToMachine.Elev < 10 * GEO.EPS_SMALL then
LeadIn.dPerpDistance = BeamData.CUT_SIC - EdgeToMachine.Elev
LeadOut.dPerpDistance = BeamData.CUT_SIC - EdgeToMachine.Elev
else
LeadIn.dPerpDistance = BeamData.CUT_SIC
LeadOut.dPerpDistance = BeamData.CUT_SIC
end
LeadIn.dElevation = 0
LeadOut.dElevation = 0
LeadIn.dCompLength = 0
LeadOut.dCompLength = 0
LeadIn.dStartAddLength = BeamData.CUT_EXTRA
LeadOut.dEndAddLength = BeamData.CUT_EXTRA
return LeadIn, LeadOut
end
-----------------------------------------------------------------------------------
function StrategyLib.SplitStrategy.Execute( Proc, Part, Strategy)
local Machinings = {}
-- applico le lavorazioni
--------------------------------------------------------------------------------
if Strategy.SplitStrategy.sTypeMachining == 'BladeSideSingle' then
local Machining = {}
Machining.Splitting = {}
Machining.AuxiliaryData = {}
local OptionalParameters = {}
OptionalParameters.nToolIndex = Strategy.SplitStrategy[1].ToolInfo.nToolIndex
OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_BACK
OptionalParameters.sDepth = 0
OptionalParameters.dLongitudinalOffset = Strategy.dOffset or 0
OptionalParameters.sUserNotes = EgtIf( Strategy.bSplit, 'Split;', 'Cut;')
Machining.AuxiliaryData.bAddNewPhase = true
local EdgeToMachine = StrategyLib.SplitStrategy.GetEdgeToMachine( Proc, -Y_AX())
-- approccio e retrazione
OptionalParameters.LeadIn, OptionalParameters.LeadOut = StrategyLib.SplitStrategy.CalculateLeadInOut( EdgeToMachine)
Machining.Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters)
table.insert( Machinings, Machining)
----------------------------------------------------------------------------------
elseif Strategy.SplitStrategy.sTypeMachining == 'BladeSideDouble' then
local Machining = {}
Machining.Splitting = {}
Machining.AuxiliaryData = {}
local OptionalParameters = {}
OptionalParameters.nToolIndex = Strategy.SplitStrategy[1].ToolInfo.nToolIndex
-- Taglio lato frontale
OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_BACK
OptionalParameters.sDepth = 0
OptionalParameters.dLongitudinalOffset = Strategy.dOffset or 0
OptionalParameters.dRadialOffset = ( Part.dWidth - BeamData.CUT_EXTRA) / 2
OptionalParameters.sUserNotes = EgtIf( Strategy.bSplit, 'Presplit;', 'Precut;')
local EdgeToMachine = StrategyLib.SplitStrategy.GetEdgeToMachine( Proc, -Y_AX())
-- approccio e retrazione
OptionalParameters.LeadIn, OptionalParameters.LeadOut = StrategyLib.SplitStrategy.CalculateLeadInOut( EdgeToMachine)
Machining.Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters)
table.insert( Machinings, Machining)
-- Taglio lato dietro
Machining = {}
Machining.Splitting = {}
Machining.AuxiliaryData = {}
OptionalParameters = {}
OptionalParameters.nToolIndex = Strategy.SplitStrategy[1].ToolInfo.nToolIndex
OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_FRONT
OptionalParameters.sDepth = 0
OptionalParameters.dLongitudinalOffset = Strategy.dOffset or 0
OptionalParameters.dRadialOffset = ( Part.dWidth - BeamData.CUT_EXTRA) / 2
OptionalParameters.sUserNotes = EgtIf( Strategy.bSplit, 'Split;', 'Cut;')
Machining.AuxiliaryData.bAddNewPhase = true
EdgeToMachine = StrategyLib.SplitStrategy.GetEdgeToMachine( Proc, Y_AX())
-- approccio e retrazione
OptionalParameters.LeadIn, OptionalParameters.LeadOut = StrategyLib.SplitStrategy.CalculateLeadInOut( EdgeToMachine)
Machining.Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters)
table.insert( Machinings, Machining)
----------------------------------------------------------------------------------
elseif Strategy.SplitStrategy.sTypeMachining == 'BladeHorizontalSingle' then
local Machining = {}
Machining.Splitting = {}
Machining.AuxiliaryData = {}
local OptionalParameters = {}
OptionalParameters.nToolIndex = Strategy.SplitStrategy[1].ToolInfo.nToolIndex
OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_DOWN
OptionalParameters.sDepth = 0
OptionalParameters.dLongitudinalOffset = Strategy.dOffset or 0
OptionalParameters.dRadialOffset = -BeamData.CUT_EXTRA
OptionalParameters.sUserNotes = EgtIf( Strategy.bSplit, 'Split;', 'Cut;')
Machining.AuxiliaryData.bAddNewPhase = true
local EdgeToMachine = StrategyLib.SplitStrategy.GetEdgeToMachine( Proc, Z_AX())
-- approccio e retrazione
OptionalParameters.LeadIn, OptionalParameters.LeadOut = StrategyLib.SplitStrategy.CalculateLeadInOut( EdgeToMachine)
Machining.Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters)
table.insert( Machinings, Machining)
----------------------------------------------------------------------------------
elseif Strategy.SplitStrategy.sTypeMachining == 'BladeHorizontalDouble' then
local Machining = {}
Machining.Splitting = {}
Machining.AuxiliaryData = {}
local OptionalParameters = {}
OptionalParameters.nToolIndex = Strategy.SplitStrategy[1].ToolInfo.nToolIndex
-- Taglio lato frontale
OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_DOWN
OptionalParameters.sDepth = 0
OptionalParameters.dLongitudinalOffset = Strategy.dOffset or 0
local dExtraMaxMat = ( Strategy.SplitStrategy[1].ToolInfo.dMaxMatBladeFromTop + Strategy.SplitStrategy[2].ToolInfo.dMaxMatBladeFromDown - Part.dHeight - BeamData.CUT_EXTRA) / 2
OptionalParameters.dRadialOffset = Part.dHeight - Strategy.SplitStrategy[1].ToolInfo.dMaxMatBladeFromTop + dExtraMaxMat
OptionalParameters.sUserNotes = EgtIf( Strategy.bSplit, 'Presplit;', 'Precut;')
local EdgeToMachine = StrategyLib.SplitStrategy.GetEdgeToMachine( Proc, Z_AX())
-- approccio e retrazione
OptionalParameters.LeadIn, OptionalParameters.LeadOut = StrategyLib.SplitStrategy.CalculateLeadInOut( EdgeToMachine)
Machining.Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters)
table.insert( Machinings, Machining)
-- Taglio lato dietro
Machining = {}
Machining.Splitting = {}
Machining.AuxiliaryData = {}
OptionalParameters = {}
OptionalParameters.nToolIndex = Strategy.SplitStrategy[2].ToolInfo.nToolIndex
OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_TOP
OptionalParameters.sDepth = 0
OptionalParameters.dLongitudinalOffset = Strategy.dOffset or 0
OptionalParameters.dRadialOffset = Part.dHeight - Strategy.SplitStrategy[2].ToolInfo.dMaxMatBladeFromDown + dExtraMaxMat
OptionalParameters.sUserNotes = EgtIf( Strategy.bSplit, 'Split;', 'Cut;')
Machining.AuxiliaryData.bAddNewPhase = true
EdgeToMachine = StrategyLib.SplitStrategy.GetEdgeToMachine( Proc, -Z_AX())
-- approccio e retrazione
OptionalParameters.LeadIn, OptionalParameters.LeadOut = StrategyLib.SplitStrategy.CalculateLeadInOut( EdgeToMachine)
Machining.Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters)
table.insert( Machinings, Machining)
----------------------------------------------------------------------------------
elseif Strategy.SplitStrategy.sTypeMachining == 'ChainSawHorizontal' then
; -- TODO
----------------------------------------------------------------------------------
elseif Strategy.SplitStrategy.sTypeMachining == 'ChainSawSideSingle' then
; -- TODO
----------------------------------------------------------------------------------
elseif Strategy.SplitStrategy.sTypeMachining == 'ChainSawSideDouble' then
; -- TODO
----------------------------------------------------------------------------------
elseif Strategy.SplitStrategy.sTypeMachining == 'ChainSawPlusBlade' then
; -- TODO
----------------------------------------------------------------------------------
end
return Machinings
end
-------------------------------------------------------------------------------------------------------------
return StrategyLib
+4 -2
View File
@@ -42,12 +42,14 @@ _G.package.loaded.BasicCustomerStrategies = nil
_G.package.loaded.FeatureLib = nil _G.package.loaded.FeatureLib = nil
_G.package.loaded.FaceData = nil _G.package.loaded.FaceData = nil
_G.package.loaded.MachiningLib = nil _G.package.loaded.MachiningLib = nil
_G.package.loaded.DiceCut = nil
_G.package.loaded.StrategyLib = nil
_G.package.loaded.Logs = nil _G.package.loaded.Logs = nil
-- strategie di base sempre presenti -- strategie di base sempre presenti
_G.package.loaded['SPLITCUT\\SPLITCUT'] = nil
_G.package.loaded['SPLITCUT\\SPLITCUTConfig'] = nil
_G.package.loaded['HEADCUT\\HEADCUT'] = nil _G.package.loaded['HEADCUT\\HEADCUT'] = nil
_G.package.loaded['HEADCUT\\HEADCUTConfig'] = nil _G.package.loaded['HEADCUT\\HEADCUTConfig'] = nil
_G.package.loaded['TAILCUT\\TAILCUT'] = nil
_G.package.loaded['TAILCUT\\TAILCUTConfig'] = nil
-- TODO controllare se c'è un modo migliore per resettare librerie delle strategie caricate precedentemente -- TODO controllare se c'è un modo migliore per resettare librerie delle strategie caricate precedentemente
-- Per ottimizzare potremmo anche ciclare solo fino al numero di strategie raggiunto per il momento. -- Per ottimizzare potremmo anche ciclare solo fino al numero di strategie raggiunto per il momento.
+1
View File
@@ -70,6 +70,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
local vtMachiningDirection = EdgeToMachine.Norm local vtMachiningDirection = EdgeToMachine.Norm
local vtN = Proc.Faces[FaceToMachine+1].vtN local vtN = Proc.Faces[FaceToMachine+1].vtN
Cutting.sDepth = OptionalParameters.sDepth or 0 Cutting.sDepth = OptionalParameters.sDepth or 0
Cutting.dLongitudinalOffset = OptionalParameters.dLongitudinalOffset or 0
Cutting.dRadialOffset = OptionalParameters.dRadialOffset or 0 Cutting.dRadialOffset = OptionalParameters.dRadialOffset or 0
Cutting.nType = MCH_MY.MILLING Cutting.nType = MCH_MY.MILLING
-425
View File
@@ -1,425 +0,0 @@
-- Strategia: SPLITCUT
-- Descrizione
-- Taglio di separazione
-- Feature: SplitCut
-- carico librerie
local BeamLib = require( 'BeamLib')
local BeamData = require( 'BeamData')
local MachiningLib = require( 'MachiningLib')
local FeatureLib = require( 'FeatureLib')
-- strategie di base
local FaceByBlade = require('FACEBYBLADE')
-- Tabella per definizione modulo
local SPLITCUT = {}
local Strategy = {}
-------------------------------------------------------------------------------------------------------------
local function LoadStrategyParameters( CustomParameters)
local StrategyLib = {}
StrategyLib.Config = require( 'SPLITCUT\\SPLITCUTConfig')
Strategy.sName = StrategyLib.Config.sStrategyId
CustomParameters = BeamLib.GetUpdateCustomParameters( CustomParameters, StrategyLib.Config.Parameters)
Strategy.Parameters = BeamLib.LoadCustomParametersInStrategy( CustomParameters)
Strategy.Result = {}
Strategy.Machining = {}
Strategy.Result.sInfo = ''
return Strategy
end
-------------------------------------------------------------------------------------------------------------
local function CalculateLeadInOut( Machining, EdgeToMachine)
local LeadIn = {}
local LeadOut = {}
LeadIn.dStartAddLength = 0
LeadOut.dEndAddLength = 0
LeadIn.nType = MCH_MILL_LI.LINEAR
LeadOut.nType = MCH_MILL_LI.LINEAR
LeadIn.dTangentDistance = 0
LeadOut.dTangentDistance = 0
-- elevazione sempre in negativo
if EdgeToMachine.Elev < 10 * GEO.EPS_SMALL then
LeadIn.dPerpDistance = BeamData.CUT_SIC - EdgeToMachine.Elev
LeadOut.dPerpDistance = BeamData.CUT_SIC - EdgeToMachine.Elev
else
LeadIn.dPerpDistance = BeamData.CUT_SIC
LeadOut.dPerpDistance = BeamData.CUT_SIC
end
LeadIn.dElevation = 0
LeadOut.dElevation = 0
LeadIn.dCompLength = 0
LeadOut.dCompLength = 0
LeadIn.dStartAddLength = BeamData.CUT_EXTRA
LeadOut.dEndAddLength = BeamData.CUT_EXTRA
return LeadIn, LeadOut
end
-------------------------------------------------------------------------------------------------------------
local function MakeChamfer()
-- TODO funzionalità da aggiungere
end
-------------------------------------------------------------------------------------------------------------
local function GetEdgeToMachine( Proc, vtEdge)
local Edge
for i = 1, #Proc.Faces[1].Edges do
if AreSameVectorApprox( Proc.Faces[1].Edges[i].Norm, vtEdge) then
Edge = Proc.Faces[1].Edges[i]
end
end
return Edge
end
-------------------------------------------------------------------------------------------------------------
local function GetSplitStrategy( Proc, Part)
-- se non sono stati caricati i parametri, si ricaricano
if not Strategy.Parameters then
Strategy = LoadStrategyParameters()
end
-- separazione solo se esiste grezzo successivo con pezzi o scaricabile
local nNextRawId = EgtGetNextRawPart( Part.idRaw)
Strategy.bSplit = ( nNextRawId and ( EgtGetPartInRawPartCount( nNextRawId) > 0 or EgtGetRawPartBBox( nNextRawId):getDimX() >= BeamData.dMinRaw))
-- imposto paraemtri di ricerca utensile in base a topologia
local Machining = {}
-- sTypeMachining = BladeSideSingle\ BladeSideDouble\ BladeHorizontalSingle\ BladeHorizontalDouble\ ChainSawHorizontal\ ChainSawSideSingle\ ChainSawSideDouble\ ChainSawPlusBlade\ Mill\ None
Machining.sTypeMachining = 'None'
local Splitting = {}
local ToolSearchParameters = {}
ToolSearchParameters.vtToolDirection = Proc.Faces[1].vtN
-- ===== RICERCA UTENSILE =====
-- cerco lama sopra
Splitting.bIsApplicable = false
ToolSearchParameters.bAllowTopHead = true
ToolSearchParameters.bAllowBottomHead = false
Splitting.ToolInfo = {}
Splitting.ToolInfo = MachiningLib.FindBlade( Proc, ToolSearchParameters)
if Splitting.ToolInfo.nToolIndex then
Splitting.bIsApplicable = true
local ParametersMRR = {}
ParametersMRR.nToolIndex = Splitting.ToolInfo.nToolIndex
Splitting.dMRR = MachiningLib.GetToolMRR( ParametersMRR)
end
table.insert( Machining, Splitting)
-- cerco lama sotto
Splitting = {}
Splitting.bIsApplicable = false
ToolSearchParameters.bAllowTopHead = false
ToolSearchParameters.bAllowBottomHead = true
Splitting.ToolInfo = {}
Splitting.ToolInfo = MachiningLib.FindBlade( Proc, ToolSearchParameters)
if Splitting.ToolInfo.nToolIndex then
Splitting.bIsApplicable = true
local ParametersMRR = {}
ParametersMRR.nToolIndex = Splitting.ToolInfo.nToolIndex
Splitting.dMRR = MachiningLib.GetToolMRR( ParametersMRR)
end
table.insert( Machining, Splitting)
-- cerco motosega
Splitting = {}
Splitting.bIsApplicable = false
table.insert( Machining, Splitting)
-- cerco fresa
Splitting = {}
Splitting.bIsApplicable = false
table.insert( Machining, Splitting)
-- ===== SCELTA LAVORAZIONI =====
-- forzature da parametri
if Strategy.Parameters.bForceChainSaw then
Machining[1].bIsApplicable = false
Machining[2].bIsApplicable = false
end
-- setto valori di default. Impossibile che taglio di separazione sia incompleto
Strategy.Result.sStatus = 'Completed'
Strategy.Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( 100)
Strategy.Result.dMRR = 1
-- correzioni sul massimo materiale lama, considerando ingombri vari
local dMaxMatBladeSideSingle
local dMaxMatBladeSideDouble
local dMaxMatBladeHorizontalSingle
local dMaxMatBladeHorizontalDouble
if Machining[1].bIsApplicable then
local dMaxMat = TOOLS[Machining[1].ToolInfo.nToolIndex].dMaxMaterial
local dRadius = TOOLS[Machining[1].ToolInfo.nToolIndex].dDiameter / 2
local sHead = TOOLS[Machining[1].ToolInfo.nToolIndex].sHead
-- se taglio di fianco disponibile, si controlla il massimo materiale reale. Per pezzi alti, bisogna controllare anche l'ingombro asse Z nelle 4 direzioni.
if Part.dHeight < BeamData.MIN_DIM_HBEAM then
dMaxMat = min( dMaxMat, BeamData.MAX_DIM_HTCUT)
dMaxMatBladeSideSingle = dMaxMat
dMaxMatBladeSideDouble = dMaxMat * 2
else
if BeamData.GetMaxMatReductionBladeCut then
dMaxMatBladeSideSingle = min( max( dRadius - BeamData.GetMaxMatReductionBladeCut( sHead, Y_AX()), dRadius - BeamData.GetMaxMatReductionBladeCut( sHead, -Y_AX())),
TOOLS[Machining[1].ToolInfo.nToolIndex].dMaxMaterial)
dMaxMatBladeSideDouble = dRadius - BeamData.GetMaxMatReductionBladeCut( sHead, Y_AX()) + dRadius - BeamData.GetMaxMatReductionBladeCut( sHead, -Y_AX())
else
dMaxMatBladeSideSingle = abs( BeamData.MAX_DIM_HTCUT_HBEAM)
dMaxMatBladeSideDouble = abs( BeamData.MAX_DIM_HTCUT_HBEAM) * 2
end
end
-- se taglio orizzontale
if BeamData.GetMaxMatReductionBladeCut then
dMaxMatBladeHorizontalSingle = min( TOOLS[Machining[1].ToolInfo.nToolIndex].dMaxMaterial, dRadius - BeamData.GetMaxMatReductionBladeCut( TOOLS[Machining[1].ToolInfo.nToolIndex].sHead, -Z_AX()))
else
dMaxMatBladeHorizontalSingle = TOOLS[Machining[1].ToolInfo.nToolIndex].dMaxMaterial
end
end
if Machining[2].bIsApplicable then
if BeamData.GetMaxMatReductionBladeCut then
local dRadius = TOOLS[Machining[2].ToolInfo.nToolIndex].dDiameter / 2
dMaxMatBladeHorizontalDouble = min( TOOLS[Machining[2].ToolInfo.nToolIndex].dMaxMaterial, dRadius - BeamData.GetMaxMatReductionBladeCut( TOOLS[Machining[2].ToolInfo.nToolIndex].sHead, Z_AX()))
else
dMaxMatBladeHorizontalDouble = TOOLS[Machining[2].ToolInfo.nToolIndex].dMaxMaterial
end
end
-- TODO considerare di tagliare con il massimo materiale possibile per non salire troppo in Z (macchine tipo PF), oppure non scendere troppo (tipo Kairos)
-- BladeSideSingle (taglio di lama singolo di fianco)
if Machining[1].bIsApplicable and ( dMaxMatBladeSideSingle - BeamData.CUT_EXTRA) > Part.dWidth + 10 * GEO.EPS_SMALL then
Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'Blade')
Machining.sTypeMachining = 'BladeSideSingle'
Machining[2].bIsApplicable = false
Machining[3].bIsApplicable = false
Machining[4].bIsApplicable = false
return Machining
-- TODO considerare di tagliare con il massimo materiale possibile per non salire troppo in Z (macchine tipo PF), oppure non scendere troppo (tipo Kairos)
-- BladeSideDouble (taglio di lama doppio di fianco)
elseif Machining[1].bIsApplicable and ( dMaxMatBladeSideDouble - BeamData.CUT_EXTRA) > Part.dWidth + 10 * GEO.EPS_SMALL then
Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'Blade')
Strategy.Result.dMRR = Strategy.Result.dMRR/2
Machining.sTypeMachining = 'BladeSideDouble'
Machining[2].bIsApplicable = false
Machining[3].bIsApplicable = false
Machining[4].bIsApplicable = false
return Machining
-- BladeHorizontalSingle (taglio di lama singolo orizzontale)
elseif Machining[1].bIsApplicable and ( dMaxMatBladeHorizontalSingle - BeamData.CUT_EXTRA) > Part.dHeight + 10 * GEO.EPS_SMALL then
Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'Blade')
Machining.sTypeMachining = 'BladeHorizontalSingle'
Machining[2].bIsApplicable = false
Machining[3].bIsApplicable = false
Machining[4].bIsApplicable = false
return Machining
-- BladeHorizontalDouble (taglio di lama doppio orizzontale)
elseif Machining[1].bIsApplicable and Machining[2].bIsApplicable and
( dMaxMatBladeHorizontalSingle + dMaxMatBladeHorizontalDouble - BeamData.CUT_EXTRA) > Part.dHeight + 10 * GEO.EPS_SMALL then
Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'Blade')
Strategy.Result.dMRR = Strategy.Result.dMRR/2
Machining.sTypeMachining = 'BladeHorizontalDouble'
Machining[1].ToolInfo.dMaxMatBladeFromTop = dMaxMatBladeHorizontalSingle
Machining[2].ToolInfo.dMaxMatBladeFromDown = dMaxMatBladeHorizontalDouble
Machining[3].bIsApplicable = false
Machining[4].bIsApplicable = false
return Machining
-- TODO : casi con motosega da completare
-- ChainSawHorizontal (motosega)
-- ChainSawSideSingle (motosega)
-- ChainSawSideDouble (motosega)
-- ChainSawPlusBlade (motosega più lama orizzontale)
-- Mill (svuotatura)
end
-- se non ho trovato neanche una lavorazione completa, non posso separare
if Machining.sTypeMachining == 'None' then
Strategy.Result.sStatus = 'Not-Applicable'
Strategy.Result.nCompletionIndex = 0
Strategy.Result.dMRR = 0
Strategy.Result.nQuality = 0
Strategy.Result.sInfo = 'Split not possible'
end
return Machining
end
-------------------------------------------------------------------------------------------------------------
function SPLITCUT.Make( bAddMachining, Proc, Part, CustomParameters)
Strategy = LoadStrategyParameters( CustomParameters)
local bAreAllMachiningsAdded = true
local Splitting = {}
local AuxiliaryData = {}
Strategy.sSplitStrategy = GetSplitStrategy( Proc, Part)
if bAddMachining then
-- inserimento smussi su spigoli del taglio
if Strategy.Parameters.bMakeChamfer then
MakeChamfer()
end
local OptionalParameters = {}
-- applico le lavorazioni
----------------------------------------------------------------------------------
if Strategy.sSplitStrategy.sTypeMachining == 'BladeSideSingle' then
OptionalParameters = {}
OptionalParameters.nToolIndex = Strategy.sSplitStrategy[1].ToolInfo.nToolIndex
OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_BACK
OptionalParameters.sDepth = 0
-- TODO gestire lavorazione a cubetti
if Strategy.bSplit then
OptionalParameters.sUserNotes = 'Split;'
else
OptionalParameters.sUserNotes = 'Cut;'
end
AuxiliaryData.bAddNewPhase = true
local EdgeToMachine = GetEdgeToMachine( Proc, -Y_AX())
-- approccio e retrazione
OptionalParameters.LeadIn, OptionalParameters.LeadOut = CalculateLeadInOut( Splitting, EdgeToMachine)
Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters)
MachiningLib.AddNewMachining( Proc, Splitting, AuxiliaryData)
----------------------------------------------------------------------------------
elseif Strategy.sSplitStrategy.sTypeMachining == 'BladeSideDouble' then
OptionalParameters = {}
OptionalParameters.nToolIndex = Strategy.sSplitStrategy[1].ToolInfo.nToolIndex
-- Taglio lato frontale
OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_BACK
OptionalParameters.sDepth = 0
OptionalParameters.dRadialOffset = ( Part.dWidth - BeamData.CUT_EXTRA) / 2
-- TODO gestire lavorazione a cubetti
if Strategy.bSplit then
OptionalParameters.sUserNotes = 'PreSplit;'
else
OptionalParameters.sUserNotes = 'PreCut;'
end
local EdgeToMachine = GetEdgeToMachine( Proc, -Y_AX())
-- approccio e retrazione
OptionalParameters.LeadIn, OptionalParameters.LeadOut = CalculateLeadInOut( Splitting, EdgeToMachine)
Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters)
MachiningLib.AddNewMachining( Proc, Splitting, AuxiliaryData)
-- Taglio lato dietro
OptionalParameters = {}
Splitting = {}
AuxiliaryData = {}
OptionalParameters.nToolIndex = Strategy.sSplitStrategy[1].ToolInfo.nToolIndex
OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_FRONT
OptionalParameters.sDepth = 0
OptionalParameters.dRadialOffset = ( Part.dWidth - BeamData.CUT_EXTRA) / 2
-- TODO gestire lavorazione a cubetti
if Strategy.bSplit then
OptionalParameters.sUserNotes = 'Split;'
else
OptionalParameters.sUserNotes = 'Cut;'
end
AuxiliaryData.bAddNewPhase = true
EdgeToMachine = GetEdgeToMachine( Proc, Y_AX())
-- approccio e retrazione
OptionalParameters.LeadIn, OptionalParameters.LeadOut = CalculateLeadInOut( Splitting, EdgeToMachine)
Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters)
MachiningLib.AddNewMachining( Proc, Splitting, AuxiliaryData)
----------------------------------------------------------------------------------
elseif Strategy.sSplitStrategy.sTypeMachining == 'BladeHorizontalSingle' then
OptionalParameters = {}
OptionalParameters.nToolIndex = Strategy.sSplitStrategy[1].ToolInfo.nToolIndex
OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_DOWN
OptionalParameters.sDepth = 0
OptionalParameters.dRadialOffset = -BeamData.CUT_EXTRA
-- TODO gestire lavorazione a cubetti
if Strategy.bSplit then
OptionalParameters.sUserNotes = 'Split;'
else
OptionalParameters.sUserNotes = 'Cut;'
end
AuxiliaryData.bAddNewPhase = true
local EdgeToMachine = GetEdgeToMachine( Proc, Z_AX())
-- approccio e retrazione
OptionalParameters.LeadIn, OptionalParameters.LeadOut = CalculateLeadInOut( Splitting, EdgeToMachine)
Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters)
MachiningLib.AddNewMachining( Proc, Splitting, AuxiliaryData)
----------------------------------------------------------------------------------
elseif Strategy.sSplitStrategy.sTypeMachining == 'BladeHorizontalDouble' then
OptionalParameters = {}
OptionalParameters.nToolIndex = Strategy.sSplitStrategy[1].ToolInfo.nToolIndex
-- Taglio lato frontale
OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_DOWN
OptionalParameters.sDepth = 0
local dExtraMaxMat = ( Strategy.sSplitStrategy[1].ToolInfo.dMaxMatBladeFromTop + Strategy.sSplitStrategy[2].ToolInfo.dMaxMatBladeFromDown - Part.dHeight - BeamData.CUT_EXTRA) / 2
OptionalParameters.dRadialOffset = Part.dHeight - Strategy.sSplitStrategy[1].ToolInfo.dMaxMatBladeFromTop + dExtraMaxMat
-- TODO gestire lavorazione a cubetti
if Strategy.bSplit then
OptionalParameters.sUserNotes = 'PreSplit;'
else
OptionalParameters.sUserNotes = 'PreCut;'
end
local EdgeToMachine = GetEdgeToMachine( Proc, Z_AX())
-- approccio e retrazione
OptionalParameters.LeadIn, OptionalParameters.LeadOut = CalculateLeadInOut( Splitting, EdgeToMachine)
Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters)
MachiningLib.AddNewMachining( Proc, Splitting, AuxiliaryData)
-- Taglio lato dietro
OptionalParameters = {}
Splitting = {}
AuxiliaryData = {}
OptionalParameters.nToolIndex = Strategy.sSplitStrategy[2].ToolInfo.nToolIndex
OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_TOP
OptionalParameters.sDepth = 0
OptionalParameters.dRadialOffset = Part.dHeight - Strategy.sSplitStrategy[2].ToolInfo.dMaxMatBladeFromDown + dExtraMaxMat
-- TODO gestire lavorazione a cubetti
if Strategy.bSplit then
OptionalParameters.sUserNotes = 'Split;'
else
OptionalParameters.sUserNotes = 'Cut;'
end
AuxiliaryData.bAddNewPhase = true
EdgeToMachine = GetEdgeToMachine( Proc, -Z_AX())
-- approccio e retrazione
OptionalParameters.LeadIn, OptionalParameters.LeadOut = CalculateLeadInOut( Splitting, EdgeToMachine)
Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters)
MachiningLib.AddNewMachining( Proc, Splitting, AuxiliaryData)
----------------------------------------------------------------------------------
elseif Strategy.sSplitStrategy.sTypeMachining == 'ChainSawHorizontal' then
; -- TODO
----------------------------------------------------------------------------------
elseif Strategy.sSplitStrategy.sTypeMachining == 'ChainSawSideSingle' then
; -- TODO
----------------------------------------------------------------------------------
elseif Strategy.sSplitStrategy.sTypeMachining == 'ChainSawSideDouble' then
; -- TODO
----------------------------------------------------------------------------------
elseif Strategy.sSplitStrategy.sTypeMachining == 'ChainSawPlusBlade' then
; -- TODO
----------------------------------------------------------------------------------
elseif Strategy.sSplitStrategy.sTypeMachining == 'Mill' then
; -- TODO
----------------------------------------------------------------------------------
end
return bAreAllMachiningsAdded, Strategy.Result
else
return nil, Strategy.Result
end
end
-------------------------------------------------------------------------------------------------------------
return SPLITCUT
+103
View File
@@ -0,0 +1,103 @@
-- Strategia: TAILCUT
-- Descrizione
-- Taglio di separazione
-- Feature: TailCut
-- carico librerie
local BeamLib = require( 'BeamLib')
local BeamData = require( 'BeamData')
local MachiningLib = require( 'MachiningLib')
local StrategyLib = require( 'StrategyLib')
local DiceCut = require( 'DiceCut')
-- Tabella per definizione modulo
local TAILCUT = {}
local Strategy = {}
-------------------------------------------------------------------------------------------------------------
local function MakeChamfer()
-- TODO funzionalità da aggiungere
end
-------------------------------------------------------------------------------------------------------------
function TAILCUT.Make( bAddMachining, Proc, Part, CustomParameters)
local StrategyDefaultParam = {}
StrategyDefaultParam.Config = require( 'TAILCUT\\TAILCUTConfig')
Strategy.sName = StrategyDefaultParam.Config.sStrategyId
CustomParameters = BeamLib.GetUpdateCustomParameters( CustomParameters, StrategyDefaultParam.Config.Parameters)
Strategy.Parameters = BeamLib.LoadCustomParametersInStrategy( CustomParameters)
Strategy.SplitStrategy = {}
Strategy.Result = {}
Strategy.Machining = {}
Strategy.Result.sInfo = ''
local bAreAllMachiningsAdded = true
-- separazione solo se esiste grezzo successivo con pezzi o scaricabile
Strategy.bSplit = not( Part.bIsLastPart) or Part.dRestLength >= BeamData.dMinRaw
-- se devo fare split perchè c'è un grezzo da scaricare o un altro pezzo
if Strategy.bSplit then
Strategy.SplitStrategy, Strategy.Result = StrategyLib.SplitStrategy.Get( Proc, Part, Strategy.Parameters)
-- se devo rimuovere tutto il restante
else
-- se abilitato, faccio tagli di PRECUT a zero (come SPLIT)
if Strategy.Parameters.bExecutePreCut then
Strategy.SplitStrategy, Strategy.Result = StrategyLib.SplitStrategy.Get( Proc, Part, Strategy.Parameters)
-- se non faccio tagli PRECUT, imposto tabella Result direttamente. Non serve verificare che riesca a rimuovere il materiale extra
else
Strategy.Result.sStatus = 'Completed'
Strategy.Result.nCompletionIndex = 5
Strategy.Result.dMRR = 1
Strategy.Result.nQuality = 5
Strategy.Result.sInfo = 'Split not possible'
end
end
-- se devo applicare le lavorazioni
if bAddMachining then
-- inserimento smussi su spigoli del taglio
if Strategy.Parameters.bMakeChamfer then
MakeChamfer()
end
local MachiningsToAdd = {}
-- se devo fare split perchè c'è un grezzo da scaricare o un altro pezzo
if Strategy.bSplit then
Strategy.dOffset = 0
MachiningsToAdd = StrategyLib.SplitStrategy.Execute( Proc, Part, Strategy)
-- se devo rimuovere tutto il restante
else
-- se abilitato, faccio tagli di PRECUT a zero (come SPLIT)
if Strategy.Parameters.bExecutePreCut then
Strategy.dOffset = Part.dRestLength
MachiningsToAdd = StrategyLib.SplitStrategy.Execute( Proc, Part, Strategy)
end
-- rimuovo tutto il restante
-- table.insert( MachiningsToAdd, StrategyLib.BladeToWasteOneFace( Proc, Part))
local Faces = {}
local Face1 = {}
local Face2 = {}
local OptionalParameters = {}
Face1.ptCenter = Proc.Faces[1].ptCenter
Face1.vtNormal = Proc.Faces[1].vtN
OptionalParameters.b3BoxToDicing = Part.b3Raw
Faces = DiceCut.GetDice( Part, Face1, Face2, OptionalParameters)
end
-- aggiungo lavorazioni trovate alla lista generale
for i = 1, #MachiningsToAdd do
MachiningLib.AddNewMachining( Proc, MachiningsToAdd[i].Splitting, MachiningsToAdd[i].AuxiliaryData)
end
return bAreAllMachiningsAdded, Strategy.Result
else
return nil, Strategy.Result
end
end
-------------------------------------------------------------------------------------------------------------
return TAILCUT
@@ -1,12 +1,13 @@
-- Parametri configurabili da cliente per strategia: SPLITCUT -- Parametri configurabili da cliente per strategia: TAILCUT
local SPLITCUTData = { local TAILCUTData = {
sStrategyId = 'SPLITCUT', sStrategyId = 'TAILCUT',
Parameters = { Parameters = {
{ sName = 'bMakeChamfer', sValue = 'false', sDescriptionShort = 'Execute Chamfer', sDescriptionLong = 'Use the V-Mill to execute chamfers on cut-edges', sType = 'b', sMessageId = '', sMinUserLevel = '1'}, { sName = 'bMakeChamfer', sValue = 'false', sDescriptionShort = 'Execute Chamfer', sDescriptionLong = 'Use the V-Mill to execute chamfers on cut-edges', sType = 'b', sMessageId = '', sMinUserLevel = '1'},
{ sName = 'bForceChainSaw', sValue = 'false', sDescriptionShort = 'Force to use chain saw', sDescriptionLong = 'Force to use chain saw', sType = 'b', sMessageId = '', sMinUserLevel = '1'}, { sName = 'bForceChainSaw', sValue = 'false', sDescriptionShort = 'Force to use chain saw', sDescriptionLong = 'Force to use chain saw', sType = 'b', sMessageId = '', sMinUserLevel = '1'},
{ sName = 'bExecutePreCut', sValue = 'true', sDescriptionShort = 'Force to add PreCuts', sDescriptionLong = "Autocam will apply a machining on the theoric zero, to avoid collision if the theoric piece length doesn't correspond to the real length", sType = 'b', sMessageId = '', sMinUserLevel = '1'},
{ sName = 'bFinishWithMill', sValue = 'true', sDescriptionShort = 'Finish with mill', sDescriptionLong = 'Use a mill to finish the surface if split with chain saw', sType = 'b', sMessageId = '', sMinUserLevel = '1'} { sName = 'bFinishWithMill', sValue = 'true', sDescriptionShort = 'Finish with mill', sDescriptionLong = 'Use a mill to finish the surface if split with chain saw', sType = 'b', sMessageId = '', sMinUserLevel = '1'}
} }
} }
return SPLITCUTData return TAILCUTData
+2 -2
View File
@@ -139,8 +139,8 @@ STR0003 = Topologia tipo LapJoint. Lama + motosega
252,0,Feature, 252,0,Feature,
; Feature : HEADCUT ; Feature : HEADCUT
340,0,Feature,HEADCUT 340,0,Feature,HEADCUT
; Feature : SPLITCUT ; Feature : TAILCUT
350,0,Feature,SPLITCUT 350,0,Feature,TAILCUT
; Feature : Variant ; Feature : Variant
900,0,Feature, 900,0,Feature,
; Feature Decor ; Feature Decor