Merge branch 'STR0005_BladeToWaste' into develop

This commit is contained in:
luca.mazzoleni
2025-02-25 18:30:45 +01:00
10 changed files with 245 additions and 188 deletions
+3 -36
View File
@@ -1332,49 +1332,16 @@ function BeamExec.ProcessMachinings( PARTS)
end
EgtOutLog( ' *** AddMachinings ***', 1)
-- ordino le features
-- ordinamento di base delle feature
vProc = OrderFeatures( vProc)
-- esegue le strategie migliori che ha precedentemente scelto e salva le lavorazioni nella lista globale
MACHININGS = CalculateMachinings( vProc, PARTS[nPart])
-- ordinamento lavorazioni
MACHININGS = MachiningLib.PrepareMachiningsForSorting( PARTS[nPart])
--TODO - rimuovere o mettere in Log, serve solo per test
-- TEST
local MachiningPropertiesBeforeSorting = {}
for i =1, #MACHININGS do
MachiningPropertiesBeforeSorting[i] = {}
MachiningPropertiesBeforeSorting[i] = {
ptCenter = MACHININGS[i].Machining.ptCenter,
nStage = MACHININGS[i].Machining.nStage,
nPartSegment = MACHININGS[i].Machining.nPartSegment,
sToolFamily = TOOLS[ MACHININGS[i].Machining.nToolIndex].sFamily,
dToolPerformanceIndex = TOOLS[ MACHININGS[i].Machining.nToolIndex].dPerformanceIndex,
sToolName = TOOLS[ MACHININGS[i].Machining.nToolIndex].sName,
vtToolDirection = MACHININGS[i].Machining.vtToolDirection
}
end
-- fine TEST
-- TODO completare ordinamento. Mancano le dipendenze.
MACHININGS = BeamLib.StableSort( MACHININGS, MachiningLib.CompareMachinings)
--TODO - rimuovere o mettere in Log, serve solo per test
-- TEST
local MachiningPropertiesAfterSorting = {}
for i =1, #MACHININGS do
MachiningPropertiesAfterSorting[i] = {}
MachiningPropertiesAfterSorting[i] = {
ptCenter = MACHININGS[i].Machining.ptCenter,
nStage = MACHININGS[i].Machining.nStage,
nPartSegment = MACHININGS[i].Machining.nPartSegment,
sToolFamily = TOOLS[ MACHININGS[i].Machining.nToolIndex].sFamily,
dToolPerformanceIndex = TOOLS[ MACHININGS[i].Machining.nToolIndex].dPerformanceIndex,
sToolName = TOOLS[ MACHININGS[i].Machining.nToolIndex].sName,
vtToolDirection = MACHININGS[i].Machining.vtToolDirection
}
end
-- fine TEST
-- aggiungo la fase, se non è la prima
if nOrd == 1 then
+64 -69
View File
@@ -17,7 +17,7 @@ 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
-- b3BoxDicing: 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
@@ -30,7 +30,7 @@ local BeamData = require( 'BeamData')
-- 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 function GetParallelPlanes( nAddGrpId, b3BoxDicing, ptC, vtN, nCopyPlane, dOffset, nStep, Color, dTolerance, bNoTolOnFirstCut, ptCCut, vtNCut, ptCCut1, vtNCut1 )
local ptMyCCut
local AreaMin = 5*5
if ptCCut and vtNCut then
@@ -46,7 +46,7 @@ local function GetParallelPlanes( nAddGrpId, b3BoxToDicing, ptC, vtN, nCopyPlane
local TabellaTmSurfParallel = {}
local i = nCopyPlane
while i < nStep do
local SurfId = EgtSurfTmPlaneInBBox( nAddGrpId, ptC + ( i * dOffset) * vtN, vtN, b3BoxToDicing, GDB_RT.GLOB)
local SurfId = EgtSurfTmPlaneInBBox( nAddGrpId, ptC + ( i * dOffset) * vtN, vtN, b3BoxDicing, 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
@@ -134,7 +134,7 @@ end
-- 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 function GetOrtoCutCenter( FacetId, ptC, vtN, vtO, dOffsetEff, dNzLimDownUp)
local FrameLocal = Frame3d( EgtSurfTmFacetCenter( FacetId, 0, GDB_ID.ROOT))
EgtSetGridFrame(FrameLocal)
local IdAuxLocal = EgtGroup(EgtGetParent( FacetId), FrameLocal)
@@ -155,7 +155,7 @@ local function GetOrtoCutCenter( FacetId, ptC, vtN, vtO, dOffsetEff, dNzLimDwnUp
-- 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
( dLen < dOffsetEff + 1.0 or dWidth < dOffsetEff + 1.0) and vtN:getZ() > dNzLimDownUp then
return nil, nil, nil
end
@@ -257,10 +257,10 @@ end
----------------------------------------------------------------------------------------------------------------------------------------------------
-- VerifyFirstOrthoCut :
-- CutTable: tabella dei tagli
-- OffsetP: offset della distanza dal punto centrale
-- b3BoxToDicing: il grezzo della barra
-- dOffsetParallel: offset della distanza dal punto centrale
-- b3BoxDicing: 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)
local function VerifyFirstOrthoCut( CutTable, dOffsetParallel, b3BoxDicing, dNzLimDownUp)
if not CutTable[1] or not CutTable[2] then return end
@@ -275,7 +275,7 @@ local function VerifyFirstOrthoCut( CutTable, OffsetP, b3BoxToDicing, dNzLimDwnU
-- 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)
local dMaxElev = EgtSurfTmFacetElevationInBBox( CutOId, 0, b3BoxDicing, true, GDB_ID.ROOT)
-- calcolo lunghezza prima semi-faccia
local asseX1 = vtO
local asseY1 = vtN1 ^ asseX1
@@ -293,7 +293,7 @@ local function VerifyFirstOrthoCut( CutTable, OffsetP, b3BoxToDicing, dNzLimDwnU
-- 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
if dLongSize <= dOffsetParallel + 1.0 and vtN1:getZ() > dNzLimDownUp then
local nAddGrpId = EgtGetParent( Cut1Id)
local SurfId = EgtSurfTmBySewing( nAddGrpId, { Cut1Id, Cut2Id})
EgtSetColor( SurfId, Color3d( FUCHSIA(), 60))
@@ -308,9 +308,9 @@ end
----------------------------------------------------------------------------------------------------------------------------------------------------
-- ricavo i vertici del box
local function CalcolaPuntiEstremiBox( b3BoxToDicing)
local ptMin = b3BoxToDicing:getMin()
local ptMax = b3BoxToDicing:getMax()
local function CalcolaPuntiEstremiBox( b3BoxDicing)
local ptMin = b3BoxDicing:getMin()
local ptMax = b3BoxDicing: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})
@@ -337,7 +337,7 @@ 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)
local function DistanzaMassima( nAddGrpId, ptC1, vtN1, ptC2, vtN2, b3BoxDicing, 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
@@ -353,7 +353,7 @@ local function DistanzaMassima( nAddGrpId, ptC1, vtN1, ptC2, vtN2, b3BoxToDicing
-- eventuale altra faccia
if ptC2 and vtN2 then
local IdAux = EgtGroup( nAddGrpId)
local IdSurf2 = EgtSurfTmPlaneInBBox( IdAux, ptC2, vtN2, b3BoxToDicing, GDB_RT.GLOB)
local IdSurf2 = EgtSurfTmPlaneInBBox( IdAux, ptC2, vtN2, b3BoxDicing, GDB_RT.GLOB)
EgtCutSurfTmPlane( IdSurf2, ptC1, -vtN1, false, GDB_RT.GLOB)
if IdSurf2 then
local BB2 = EgtGetBBoxRef( IdSurf2, GDB_BB.STANDARD, Frame1)
@@ -392,25 +392,20 @@ end
-- 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
-- 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.b3Part
-- copio dati passati su variabili locali
local ptCMainFace, vtNMainFace, ptCSubordinateFace, vtNSubordinateFace, bGetOrtoPlanes
-- faccia primaria
local ptCMainFace
local vtNMainFace
if Face1.ptCenter and Face1.vtNormal then
ptCMainFace = Face1.ptCenter
vtNMainFace = Face1.vtNormal
end
-- se esiste faccia secondaria non esiste, forzo calcolo piani ortogonali
-- faccia secondaria; se non esiste, si forza il calcolo dei piani ortogonali
local ptCSubordinateFace
local vtNSubordinateFace
local bGetOrtoPlanes
if Face2.ptCenter and Face2.vtNormal then
ptCSubordinateFace = Face2.ptCenter
vtNSubordinateFace = Face2.vtNormal
@@ -418,48 +413,52 @@ function DiceCut.GetDice( Part, Face1, Face2, OptionalParameters)
else
bGetOrtoPlanes = true
end
-- ricavo dimensione massima cubetti
if OptionalParameters.dCustMaxDimDice and OptionalParameters.dCustMaxDimDice < BeamData.MAX_DIM_DICE then
dMaxDimDice = abs( OptionalParameters.dCustMaxDimDice)
end
-- parametri opzionali e default
-- box per dicing
local b3BoxDicing = OptionalParameters.b3BoxDicing or Part.b3Part
-- distanza tra piani paralleli
local dOffsetParallel = OptionalParameters.dOffsetParallel or BeamData.MAX_DIM_DICE
-- distanza tra piani ortogonali
local dOffsetOrthogonal = OptionalParameters.dOffsetOrthogonal or BeamData.MAX_DIM_DICE
-- numero massimo piani paralleli
local nStepParallel = OptionalParameters.nStepParallel or 100
-- numero massimo piani perpendicolari
local nStepOrthogonal = OptionalParameters.nStepOrthogonal or 100
-- distanza tra piani paralleli e piani di taglio (era sempre 0, serve???)
local dTolerance = OptionalParameters.dTolerance or 0
-- inclinazione limite per taglio da sotto
local dNzLimDownUp = OptionalParameters.dNzLimDownUp or BeamLib.GetNzLimDownUp( b3BoxDicing)
--Ricavo le altezze dei BoundingBox contenente feature e estremi del grezzo
local TBoxPoint = CalcolaPuntiEstremiBox( b3BoxToDicing)
local TBoxPoint = CalcolaPuntiEstremiBox( b3BoxDicing)
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 dElevP = DistanzaMassima( nAddGrpId, ptCMainFace, vtNMainFace, ptCSubordinateFace, vtNSubordinateFace, b3BoxDicing, 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
dElevO = DistanzaMassima( nAddGrpId, ptCSubordinateFace, vtNSubordinateFace, ptCMainFace, vtNMainFace, b3BoxDicing, TBoxPoint)
end
-- aggiungo piccolo extra agli offset
OffsetP = OffsetP + 10 * GEO.EPS_SMALL
OffsetO = OffsetO + 10 * GEO.EPS_SMALL
dOffsetParallel = dOffsetParallel + 10 * GEO.EPS_SMALL
dOffsetOrthogonal = dOffsetOrthogonal + 10 * GEO.EPS_SMALL
-- se piani non ortogonali, diminuisco la distanza di offset opportunamente
local originalOffsetP = OffsetP
local dOffsetParallelOriginal = dOffsetParallel
if not bGetOrtoPlanes then
local dCoeff = ( vtNMainFace ^ vtNSubordinateFace):len()
OffsetP = OffsetP * dCoeff
OffsetO = OffsetO * dCoeff
dOffsetParallel = dOffsetParallel * dCoeff
dOffsetOrthogonal = dOffsetOrthogonal * dCoeff
end
local n = ceil( dElevP / OffsetP)
OffsetP = dElevP / n
local n = ceil( dElevP / dOffsetParallel)
dOffsetParallel = dElevP / n
if dElevO then
local m = ceil( dElevO / OffsetO)
OffsetO = dElevO / m
local m = ceil( dElevO / dOffsetOrthogonal)
dOffsetOrthogonal = dElevO / m
end
-- elenco di tutte le superfici generate dai tagli
@@ -468,7 +467,7 @@ function DiceCut.GetDice( Part, Face1, Face2, OptionalParameters)
-- 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)
local TabFromIn = GetParallelPlanes( nAddGrpId, b3BoxDicing, ptCMainFace, vtNMainFace, 0, dOffsetParallel, nStepParallel, Color3d( FUCHSIA(), 60), dTolerance, true, ptCSubordinateFace, vtNSubordinateFace)
for i = #TabFromIn, 1, -1 do
table.insert( TabellaTmSurfP, TabFromIn[i])
end
@@ -477,7 +476,7 @@ function DiceCut.GetDice( Part, Face1, Face2, OptionalParameters)
-- 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)
local TabFromIn = GetParallelPlanes( nAddGrpId, b3BoxDicing, ptCSubordinateFace, vtNSubordinateFace, 0, dOffsetOrthogonal, nStepOrthogonal, Color3d( GREEN(), 60), dTolerance, false, ptCMainFace, vtNMainFace)
for i = #TabFromIn, 1, -1 do
table.insert( TabellaTmSurfOrto, TabFromIn[i])
end
@@ -500,10 +499,10 @@ function DiceCut.GetDice( Part, Face1, Face2, OptionalParameters)
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
if vtNInner:getZ() > -0.0175 or vtNInner:getZ() < dNzLimDownUp 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
if ( abs( vtO:getY()) > 4 * abs( vtO:getX()) or b3BoxDicing:getDimZ() > 620) and vtNInner:getZ() > dNzLimDownUp 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
@@ -521,24 +520,20 @@ function DiceCut.GetDice( Part, Face1, Face2, OptionalParameters)
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)
local OffsetRel, CopyPlane, dCenOffs, ptCStart = GetOrtoCutCenter( TabellaTmSurfP[PlnInd], ptCInner, vtNInner, vtO, dOffsetOrthogonal, dNzLimDownUp)
if OffsetRel and CopyPlane and dCenOffs then
ptCInner = ptCInner + dCenOffs * vtO
local TabRight = GetParallelPlanes( nAddGrpId, b3BoxToDicing, ptCStart, vtO, CopyPlane, -OffsetRel, StepO, Color3d( GREEN(), 60),
local TabRight = GetParallelPlanes( nAddGrpId, b3BoxDicing, ptCStart, vtO, CopyPlane, -OffsetRel, nStepOrthogonal, 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),
local TabLeft = GetParallelPlanes( nAddGrpId, b3BoxDicing, ptCStart, vtO, CopyPlane, OffsetRel, nStepOrthogonal, Color3d( GREEN(), 60),
dTolerance, false, ptCInner, vtNInner, ptCOuter, vtNOuter)
-- carico la tabella con gli indici riordinati
local TempOrtoTab = {}
@@ -578,7 +573,7 @@ function DiceCut.GetDice( Part, Face1, Face2, OptionalParameters)
-- 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)
VerifyFirstOrthoCut( UltimateTable, dOffsetParallelOriginal, b3BoxDicing, dNzLimDownUp)
-- 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])
@@ -636,8 +631,8 @@ local function DiceCutTest()
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 )
-- local b3BoxDicing = EgtGetBBoxGlob( nRawPart, GDB_BB.STANDARD )
local b3BoxDicing = EgtGetBBoxGlob( nBox, GDB_BB.STANDARD )
-- seleziono il Part e il Layer di destinazione
EgtSetCurrPartLayer( nRawPart, nAddGrpId)
@@ -656,9 +651,9 @@ local function DiceCutTest()
local CutTable = {}
if nFacet == 1 then
CutTable = DiceCut.GetDice( nAddGrpId, b3BoxToDicing, ptC1, vtN1, true)
CutTable = DiceCut.GetDice( nAddGrpId, b3BoxDicing, ptC1, vtN1, true)
elseif nFacet == 2 then
CutTable = DiceCut.GetDice( nAddGrpId, b3BoxToDicing, ptC1, vtN1, false, TabPlanesFeatures[2].ptC, TabPlanesFeatures[2].vtN)
CutTable = DiceCut.GetDice( nAddGrpId, b3BoxDicing, ptC1, vtN1, false, TabPlanesFeatures[2].ptC, TabPlanesFeatures[2].vtN)
end
if EgtGetDebugLevel() >= 3 then
+33 -9
View File
@@ -216,9 +216,9 @@ function MachiningLib.FindMill( Proc, ToolSearchParameters)
-- controlli standard
elseif TOOLS[i].dDiameter > ToolSearchParameters.dMaxToolDiameter then
bIsToolCompatible = false
elseif TOOLS[i].SetupInfo.bIsTopHead and ToolSearchParameters.vtToolDirection:getZ() < TOOLS[i].SetupInfo.dMaxNegativeAngle then
elseif TOOLS[i].SetupInfo.HeadType.bTop and ToolSearchParameters.vtToolDirection:getZ() < TOOLS[i].SetupInfo.dMaxNegativeAngle then
bIsToolCompatible = false
elseif TOOLS[i].SetupInfo.bIsBottomHead and ToolSearchParameters.vtToolDirection:getZ() > TOOLS[i].SetupInfo.dMaxPositiveAngle then
elseif TOOLS[i].SetupInfo.HeadType.bBottom and ToolSearchParameters.vtToolDirection:getZ() > TOOLS[i].SetupInfo.dMaxPositiveAngle then
bIsToolCompatible = false
elseif ToolSearchParameters.sMillShape == 'STANDARD' and ( TOOLS[i].dSideAngle ~= 0 or TOOLS[i].bIsPen) then
bIsToolCompatible = false
@@ -297,6 +297,7 @@ end
-- funzione per cercare utensile tipo LAMA con certe caratteristiche
-- TODO da completare
-- TODO il FindBlade dovrà restituire di utilizzare sempre la lama sopra se l'angolo lo permette, ma avendo un'altezza massima (da macchina) oltre cui il DownUp non sarà fattibile (evita collisioni tra asse e pezzo)
-- TODO bisogna leggere vtToolDirection in arrivo e confrontarlo con il SetupInfo
function MachiningLib.FindBlade( Proc, ToolSearchParameters)
local ToolInfo = {}
@@ -319,33 +320,55 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters)
ToolSearchParameters.bForceLongcutBlade = ToolSearchParameters.bForceLongcutBlade or false
local nBestToolIndex
local dBestToolResidualDepth = 0
for i = 1, #TOOLS do
local bIsToolCompatible = false
if TOOLS[i].sFamily == 'SAWBLADE' then
if ToolSearchParameters.bAllowTopHead and not ToolSearchParameters.bAllowBottomHead then
bIsToolCompatible = TOOLS[i].SetupInfo.bIsTopHead
bIsToolCompatible = TOOLS[i].SetupInfo.HeadType.bTop
elseif ToolSearchParameters.bAllowBottomHead and not ToolSearchParameters.bAllowTopHead then
bIsToolCompatible = TOOLS[i].SetupInfo.bIsBottomHead
bIsToolCompatible = TOOLS[i].SetupInfo.HeadType.bBottom
else
bIsToolCompatible = true
end
end
if bIsToolCompatible then
if not nBestToolIndex then
-- TODO gestire accorciamento massimo materiale per inclinazione
local dCurrentResidualDepth = ToolSearchParameters.dElevation - TOOLS[i].dMaxDepth
if not nBestToolIndex or ( dBestToolResidualDepth > 0 and dCurrentResidualDepth <= 10 * GEO.EPS_SMALL) then
nBestToolIndex = i
dBestToolResidualDepth = dCurrentResidualDepth
else
-- prediligo utensile per tagli lunghi, se richiesto
if ToolSearchParameters.bForceLongcutBlade and not TOOLS[nBestToolIndex].bIsUsedForLongCut and TOOLS[i].bIsUsedForLongCut then
nBestToolIndex = i
dBestToolResidualDepth = dCurrentResidualDepth
else
-- entrambi completi
if dBestToolResidualDepth <= 10 * GEO.EPS_SMALL and dCurrentResidualDepth <= 10 * GEO.EPS_SMALL then
-- si sceglie quello con le performance migliori
if TOOLS[i].dPerformanceIndex > TOOLS[nBestToolIndex].dPerformanceIndex + 10 * GEO.EPS_SMALL then
nBestToolIndex = i
dBestToolResidualDepth = dCurrentResidualDepth
end
-- entrambi incompleti
elseif dBestToolResidualDepth > 10 * GEO.EPS_SMALL and dCurrentResidualDepth > 10 * GEO.EPS_SMALL then
-- si sceglie quello che lavora di più
if dCurrentResidualDepth > dBestToolResidualDepth then
nBestToolIndex = i
dBestToolResidualDepth = dCurrentResidualDepth
end
end
end
end
end
end
ToolInfo.nToolIndex = nBestToolIndex
ToolInfo.dResidualDepth = dBestToolResidualDepth
return ToolInfo
end
@@ -386,9 +409,9 @@ function MachiningLib.FindChainSaw( Proc, ToolSearchParameters)
if TOOLS[i].sFamily == 'MORTISE' then
if ToolSearchParameters.bAllowTopHead and not ToolSearchParameters.bAllowBottomHead then
bIsToolCompatible = TOOLS[i].SetupInfo.bIsTopHead
bIsToolCompatible = TOOLS[i].SetupInfo.HeadType.bTop
elseif ToolSearchParameters.bAllowBottomHead and not ToolSearchParameters.bAllowTopHead then
bIsToolCompatible = TOOLS[i].SetupInfo.bIsBottomHead
bIsToolCompatible = TOOLS[i].SetupInfo.HeadType.bBottom
else
bIsToolCompatible = true
end
@@ -542,7 +565,8 @@ function MachiningLib.AddOperations( vProc, Part, sRotation)
{ sName = 'dStartZmax', sMchParam = 'StartZmax'},
{ sName = 'nOutRaw', sMchParam = 'OutRaw'},
{ sName = 'nOpenOutRaw', sMchParam = 'OpenOutRaw'},
{ sName = 'nPlunge', sMchParam = 'Plunge'}
{ sName = 'nPlunge', sMchParam = 'Plunge'},
{ sName = 'vtFaceUse', sMchParam = 'VtFaceUse'}
}
-- parametri da scrivere nelle note di sistema
+1 -24
View File
@@ -34,32 +34,9 @@ local function LoadStrategyParameters( CustomParameters)
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
LeadIn.dPerpDistance = BeamData.CUT_SIC + EdgeToMachine.dElevation
LeadOut.dPerpDistance = BeamData.CUT_SIC + EdgeToMachine.dElevation
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
-- TODO funzionalità da aggiungere
end
-------------------------------------------------------------------------------------------------------------
+1 -1
View File
@@ -294,7 +294,7 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters)
-- lama - calcolo lavorazioni
local Cutting = {}
local OptionalParameters = { bForceLongcutBlade = Strategy.Parameters.bForceLongcutBlade, dExtendAfterTail = dExtendAfterTail, dPocketHeight = dPocketHeight, bIsSplitFeature = bIsSplitFeature}
local OptionalParameters = { bForceLongcutBlade = Strategy.Parameters.bForceLongcutBlade, dExtendAfterTail = dExtendAfterTail, dPocketHeight = dPocketHeight, bIsSplitFeature = bIsSplitFeature, bAllowToolInvert = true}
if Proc.Topology.sFamily == 'Tunnel' then
OptionalParameters.bOppositeToolDirection = true
Cutting = FaceByBlade.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[1], OptionalParameters)
+15 -9
View File
@@ -114,6 +114,8 @@ function STR0005.Make( bAddMachining, Proc, Part, CustomParameters)
Strategy.Result = {}
Strategy.Result.sInfo = ''
Blade.Result = {}
local dMRRBlade = 0
local dCompletionPercentage = 0
-- estensione oltre la coda
local dExtendAfterTail = Strategy.Parameters.dExtendAfterTail or max( Part.dDistanceToNextPiece - BeamData.CUT_EXTRA, 0)
@@ -121,12 +123,12 @@ function STR0005.Make( bAddMachining, Proc, Part, CustomParameters)
dExtendAfterTail = 10000
end
-- considerazioni necessarie a determinare se lavorare con codolo oppure no
local dFeatureMaxNotClampableLengthHead, dFeatureMaxNotClampableLengthTail = FeatureLib.GetFeatureMaxNotClampableLengths( Proc, Part)
local bLeaveWasteAttached = Strategy.Parameters.sCuttingStrategy == 'LEAVE_WASTE_ATTACHED'
local bFeatureHindersClamping = FeatureLib.IsMachiningLong( max( dFeatureMaxNotClampableLengthHead, dFeatureMaxNotClampableLengthTail), Part, { dMaxSegmentLength = BeamData.LONGCUT_ENDLEN})
local Cutting = {}
local dMRRBlade = 0
-- lavorazione con codolo
if bFeatureHindersClamping or bLeaveWasteAttached then
-- TODO valutare se estrapolare in funzione a sè stante in StrategyLibs
-- TODO verificare funzionamento con lama da sotto
@@ -152,6 +154,7 @@ function STR0005.Make( bAddMachining, Proc, Part, CustomParameters)
bIsSplitFeature = true
end
-- calcolo lavorazioni
-- primo lato
local OptionalParameters = { dDepthToMachine = dDepthToMachine, bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail}
Cutting1 = FaceByBlade.Make( Proc, Part, Proc.Faces[1], EdgesSorted[1], OptionalParameters)
@@ -173,9 +176,10 @@ function STR0005.Make( bAddMachining, Proc, Part, CustomParameters)
Blade.Result.Sorted = MachiningLib.GetSplitMachinings( Blade.Result.Sorted, FeatureSplittingPoints, Part)
end
-- ordinamento
table.sort( Blade.Result.Sorted, SortMachiningsBySegment)
-- parametri per il calcolo della velocità di asportazione
-- calcolo parametri per la stima della velocità di asportazione
MRRParameters1 = {
dStep = TOOLS[Cutting1.nToolIndex].dThickness,
dSideStep = min( TOOLS[Cutting1.nToolIndex].dSideStep, dDepthToMachine),
@@ -190,12 +194,14 @@ function STR0005.Make( bAddMachining, Proc, Part, CustomParameters)
local dMRRBlade2 = MachiningLib.GetToolMRR( MRRParameters2)
dMRRBlade = ( dMRRBlade1 + dMRRBlade2) / 2
Cutting = Cutting2
-- se la lavorazione con codolo fallisce o non è possibile si proseguirà a quella con cubetti
dCompletionPercentage = Cutting2.dCompletionPercentage
end
-- lavorazione a cubetti / taglio singolo
if #Blade.Result == 0 and not bLeaveWasteAttached then
-- BladeToWaste
local bDropWholeWaste = Strategy.Parameters.sCuttingStrategy == 'DROP_WHOLE_WASTE'
local OptionalParameters = { bDropWholeWaste = bDropWholeWaste, dMaxWasteVolume = Strategy.Parameters.dMaxWasteVolume, dMaxWasteLength = Strategy.Parameters.dMaxWasteLength}
Blade.Result.Sorted, dCompletionPercentage = BladeToWaste.Make( Proc, Part, OptionalParameters)
end
-- aggiunta lavorazioni
@@ -214,14 +220,14 @@ function STR0005.Make( bAddMachining, Proc, Part, CustomParameters)
Strategy.Result.sInfo = Strategy.Result.sInfo .. '\n' .. Blade.Result.Sorted[i].sMessage
end
end
-- TODO calcolo migliore area lavorata; se ho il codolo ha senso l'incompleta? se incompleta con codolo faccio i cubetti??
-- TODO migliorare calcolo area lavorata; se ho il codolo ha senso l'incompleta? se incompleta con codolo faccio i cubetti??
if nIsApplicableCount > 0 then
if Cutting.dCompletionPercentage > 100 - 10 * GEO.EPS_SMALL then
if dCompletionPercentage > 100 - 10 * GEO.EPS_SMALL then
Strategy.Result.sStatus = 'Completed'
else
Strategy.Result.sStatus = 'Not-Completed'
-- TODO al momento si assume che la percentuale di completamento dell'ultima lavorazione sia quella rilevante
dFinalCompletionPercentage = Cutting.dCompletionPercentage
dFinalCompletionPercentage = dCompletionPercentage
end
else
Strategy.Result.sStatus = 'Not-Applicable'
+110 -3
View File
@@ -9,18 +9,125 @@ require( 'EgtBase')
-- Carico i dati globali
local BeamData = require( 'BeamData')
local BeamLib = require( 'BeamLib')
local FeatureLib = require( 'FeatureLib')
local MachiningLib = require( 'MachiningLib')
local DiceCut = require( 'DiceCut')
-- strategie di base
local FaceByBlade = require('FACEBYBLADE')
EgtOutLog( ' BLADETOWASTE started', 1)
-------------------------------------------------------------------------------------------------------------
function BLADETOWASTE.Make( Proc, Part, OptionalParameters)
local Result = {}
local dCompletionPercentage = 0
-- controlli preventivi
if Proc.nFct > 2 then
error( 'BladeToWaste : max 2 faces supported')
elseif Proc.nFct == 2 then
if Proc.AdjacencyMatrix[1][2] > 10 * GEO.EPS_SMALL or Proc.AdjacencyMatrix[1][2] < -91 then
error( 'BladeToWaste : angle between faces must be concave and >= 90deg')
end
end
-- parametri opzionali e default
local nToolIndex = OptionalParameters.nToolIndex
local bDropWholeWaste = OptionalParameters.bDropWholeWaste or false
local dMaxWasteVolume = OptionalParameters.dMaxWasteVolume or 0
local dMaxWasteLength = OptionalParameters.dMaxWasteLength or 0
-- dimensioni feature
local dFeatureVolume = FeatureLib.GetFeatureVolume( Proc, Part)
local dFeatureMaxDimension = max( Proc.b3Box:getDimX(), Proc.b3Box:getDimY())
local bIsFeatureSmall = dFeatureVolume < dMaxWasteVolume + 10 * GEO.EPS_SMALL
and dFeatureMaxDimension < dMaxWasteLength + 10 * GEO.EPS_SMALL
-- si taglia tutto lo scarto in una sola lavorazione
if Proc.nFct == 1 and ( bIsFeatureSmall or bDropWholeWaste) then
local Cutting = {}
local EdgeToMachine = {}
local dDepthToMachine = 0
local ToolInfo = {}
-- ricerca utensile
if not nToolIndex then
local ToolSearchParameters = {}
for i = 1, #Proc.Faces[1].Edges do
if ( i == 1) or Proc.Faces[1].Edges[i].dElevation < EdgeToMachine.dElevation - 10 * GEO.EPS_SMALL then
EdgeToMachine = Proc.Faces[1].Edges[i]
end
end
dDepthToMachine = EdgeToMachine.dElevation + BeamData.CUT_EXTRA
ToolSearchParameters.dElevation = dDepthToMachine
ToolSearchParameters.vtToolDirection = EdgeToMachine.vtN
ToolSearchParameters.bAllowTopHead = true
-- TODO bisognerà implementare anche la lama da sotto
ToolSearchParameters.bAllowBottomHead = false
ToolSearchParameters.bForceLongcutBlade = false
ToolInfo = MachiningLib.FindBlade( Proc, ToolSearchParameters)
nToolIndex = ToolInfo.nToolIndex
end
if ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then
local OptionalParametersFaceByBlade = { dDepthToMachine = dDepthToMachine, nToolIndex = nToolIndex}
Cutting = FaceByBlade.Make( Proc, Part, Proc.Faces[1], EdgeToMachine, OptionalParametersFaceByBlade)
end
if Cutting.bIsApplicable or bDropWholeWaste then
table.insert( Result, Cutting)
dCompletionPercentage = Cutting.dCompletionPercentage or dCompletionPercentage
end
return Result, dCompletionPercentage
end
-- lavorazione con cubetti
-- se due facce, la faccia principale è la più grande
local Face1 = Proc.Faces[1]
local Face2 = {}
if Proc.nFct == 2 then
Face2 = Proc.Faces[2]
end
-- direzione migliore di lavoro, per la ricerca utensile
local _, dCutH, dCutV = BeamLib.GetFaceHvRefDim( Proc.Id, 0, Part.b3Raw)
-- ricerca utensile
local ToolSearchParameters = {}
ToolSearchParameters.vtToolDirection = EdgeToMachine.vtN
ToolSearchParameters.bAllowTopHead = true
-- TODO bisognerà implementare anche la lama da sotto
ToolSearchParameters.bAllowBottomHead = false
ToolSearchParameters.bForceLongcutBlade = false
ToolInfo = MachiningLib.FindBlade( Proc, ToolSearchParameters)
nToolIndex = ToolInfo.nToolIndex
local vCuts = DiceCut.GetDice( Part, Face1, Face2, OptionalParameters)
-- if dFeatureVolume < StrategyParameters.dMaxWasteVolume + 10 * GEO.EPS_SMALL
-- and dFeatureMaxDimension < StrategyParameters.dMaxWasteLength + 10 * GEO.EPS_SMALL then
-- end
-- restituire tabella contenente lavorazioni, già con cloni se necessari
return Result, dCompletionPercentage
end
-------------------------------------------------------------------------------------------------------------
return BLADETOWASTE
+17 -13
View File
@@ -65,18 +65,18 @@ end
local function GetSCC( vtMachiningDirection)
-- TODO implementare SCC come per FacesBySaw
local nSCC = MCH_SCC.NONE
if AreSameVectorApprox( vtMachiningDirection, Z_AX()) then
nSCC = MCH_SCC.ADIR_ZP
elseif AreOppositeVectorApprox( vtMachiningDirection, Z_AX()) then
if vtMachiningDirection:getZ() < -0.9 then
nSCC = MCH_SCC.ADIR_ZM
elseif AreSameVectorApprox( vtMachiningDirection, Y_AX()) then
nSCC = MCH_SCC.ADIR_YP
elseif AreOppositeVectorApprox( vtMachiningDirection, Y_AX()) then
elseif vtMachiningDirection:getZ() > 0.9 then
nSCC = MCH_SCC.ADIR_ZP
elseif vtMachiningDirection:getY() < -0.707 then
nSCC = MCH_SCC.ADIR_YM
elseif AreSameVectorApprox( vtMachiningDirection, X_AX()) then
nSCC = MCH_SCC.ADIR_XP
elseif AreOppositeVectorApprox( vtMachiningDirection, X_AX()) then
elseif vtMachiningDirection:getY() > 0.707 then
nSCC = MCH_SCC.ADIR_YP
elseif vtMachiningDirection:getX() < -0.707 then
nSCC = MCH_SCC.ADIR_XM
elseif vtMachiningDirection:getX() > 0.707 then
nSCC = MCH_SCC.ADIR_XP
end
return nSCC
@@ -102,7 +102,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
local bForceLongcutBlade = OptionalParameters.bForceLongcutBlade or false
local dExtendAfterTail = OptionalParameters.dExtendAfterTail or 10000
local dPocketHeight = OptionalParameters.dPocketHeight or 0
local dDepthToMachine = min( OptionalParameters.dDepthToMachine or EdgeToMachine.dElevation, EdgeToMachine.dElevation)
local dDepthToMachine = OptionalParameters.dDepthToMachine or EdgeToMachine.dElevation
local bIsSplitFeature = OptionalParameters.bIsSplitFeature or false
local bOppositeToolDirection = OptionalParameters.bOppositeToolDirection or false
local sDepth = OptionalParameters.sDepth or 0
@@ -111,6 +111,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
if OptionalParameters.dPocketHeight then
dLongitudinalOffset = 0
end
local bAllowToolInvert = OptionalParameters.bAllowToolInvert or false
local sUserNotes = OptionalParameters.sUserNotes or ''
-- lunghezze e punti caratteristici della lavorazione e del lato lavorato
@@ -186,7 +187,8 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
Cutting.bInvert = not Cutting.bInvert
end
-- TODO gestire lama da sotto e lama downUp
if FaceToMachine.vtN:getZ() < - 10 * GEO.EPS_SMALL then
-- TODO qui il check della vtN dovrebbe essere sulla dMaxNegativeAngle in SetupInfo dell'utensile?
if bAllowToolInvert and FaceToMachine.vtN:getZ() < - 10 * GEO.EPS_SMALL then
Cutting.bToolInvert = true
Cutting.bInvert = not Cutting.bInvert
else
@@ -204,7 +206,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
end
else
Cutting.dDepthToMachine = TOOLS[Cutting.nToolIndex].dMaxDepth - 1
Cutting.dResidualDepth = EdgeToMachine.dElevation - Cutting.dDepthToMachine
Cutting.dResidualDepth = dDepthToMachine - Cutting.dDepthToMachine
if bOppositeToolDirection then
Cutting.dRadialOffset = -Cutting.dDepthToMachine
else
@@ -226,11 +228,13 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
Cutting.dStartSafetyLength = 10
-- overlap
Cutting.dOverlap = 0
-- faceuse
-- faceuse e frame lavorazione
if bOppositeToolDirection then
Cutting.nFaceuse = BeamLib.GetNearestOrthoOpposite( -Cutting.vtToolDirection)
Cutting.vtFaceUse = -Cutting.vtToolDirection
else
Cutting.nFaceuse = BeamLib.GetNearestOrthoOpposite( Cutting.vtToolDirection)
Cutting.vtFaceUse = Cutting.vtToolDirection
end
-- SCC
Cutting.nSCC = GetSCC( Cutting.vtToolDirection)
+1 -1
View File
@@ -140,7 +140,7 @@ function FACEBYCHAINSAW.Make( Proc, Part, FaceToMachine, EdgeToMachine, Optional
-- parametri della lavorazione
-- TODO gestire ToolInvert per rispettare direzione migliore di lavorazione
-- profondità (parametro DEPTH) non usata
Mortising.sDepth = 'TH'
Mortising.sDepth = sDepth
-- inizio e fine aperti o chiusi
Mortising.bIsStartClosed = not EdgeToMachine.bIsStartOpen
Mortising.bIsEndClosed = not EdgeToMachine.bIsEndOpen
-23
View File
@@ -192,29 +192,6 @@ function SPLITCUT.GetEdgeToMachine( Proc, vtEdge)
return Edge
end
-------------------------------------------------------------------------------------------------------------
function SPLITCUT.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
LeadIn.dPerpDistance = BeamData.CUT_SIC + EdgeToMachine.dElevation
LeadOut.dPerpDistance = BeamData.CUT_SIC + EdgeToMachine.dElevation
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 SPLITCUT.Execute( Proc, Part, Strategy)
local Machinings = {}