e1c375aa5a
- aggiunto parametro RibsStrandOverlap per impostare una sovrapposizione tra le passate di uno stesso setto - aggiunto numero massimo di layer da realizzare.
4509 lines
187 KiB
Lua
4509 lines
187 KiB
Lua
-- CalcPaths.lua by Egaltech s.r.l. 2022/06/28
|
|
-- Calcolo percorsi di lavoro per Stampa 3d
|
|
|
|
-- Tabella per definizione modulo
|
|
local CalcPaths = {}
|
|
|
|
-- Intestazioni
|
|
require( 'EgtBase')
|
|
|
|
EgtOutLog( ' CalcPaths started', 1)
|
|
|
|
-- Dati
|
|
local AMD = require( 'AddManData')
|
|
|
|
---------------------------------------------------------------------
|
|
local s_nPartId
|
|
local s_dOffsCorr = 20 * GEO.EPS_SMALL
|
|
local s_vErr = {}
|
|
local s_nCurrIdx
|
|
local s_vtSlicing
|
|
local s_dOffsTol = 50 * GEO.EPS_SMALL
|
|
|
|
---------------------------------------------------------------------
|
|
local function GetLayerParamsForPathCalc()
|
|
local LayerParams = {}
|
|
LayerParams.bSpiralVase = EgtGetInfo( s_nPartId, KEY_SPIRAL_VASE, 'b') or false
|
|
LayerParams.nShellsNbr = EgtGetInfo( s_nPartId, KEY_SHELLS_NBR, 'i')
|
|
LayerParams.dStrand = EgtGetInfo( s_nPartId, KEY_STRAND, 'd')
|
|
LayerParams.dInnerStrand = EgtGetInfo( s_nPartId, KEY_INNER_STRAND, 'd') or LayerParams.dStrand
|
|
if LayerParams.dInnerStrand < GEO.EPS_SMALL then LayerParams.dInnerStrand = LayerParams.dStrand end
|
|
LayerParams.dLayHeight = EgtGetInfo( s_nPartId, KEY_SLICE_STEP, 'd')
|
|
LayerParams.dStrandOverlap = EgtGetInfo( s_nPartId, KEY_STRAND_OVERLAP, 'd') or 0
|
|
LayerParams.dOffs = EgtGetInfo( s_nPartId, KEY_OFFSET_SLICE, 'd')
|
|
s_vtSlicing = EgtGetInfo( s_nPartId, KEY_SLICING_DIR, 'v')
|
|
LayerParams.bPrintInvert = ( EgtGetInfo( s_nPartId, KEY_PRINT_DIRECTION, 'i') == PRINT_DIRECTION.CW)
|
|
LayerParams.vPrintOrder = EgtGetInfo( s_nPartId, KEY_PRINT_ORDER, 'vi') or { 1, 2, 3, 4, 5, 6, 7, 8}
|
|
-- parametri costolature
|
|
LayerParams.bRibsInvertOrder = EgtGetInfo( s_nPartId, KEY_RIBS_INVERT_ORDER, 'b') or false
|
|
LayerParams.bInvertRibsMergedShellLink = EgtGetInfo( s_nPartId, KEY_INVERT_RIBS_MERGED_SHELL_LINK, 'b') or false
|
|
-- parametri regioni con diverse passate
|
|
LayerParams.dShellNbrCoasting = EgtGetInfo( s_nPartId, KEY_SHELL_NBR_COASTING, 'd')
|
|
LayerParams.dShellNbrWipe = EgtGetInfo( s_nPartId, KEY_SHELL_NBR_WIPE, 'd')
|
|
LayerParams.dShellNbrWipeDir = EgtGetInfo( s_nPartId, KEY_SHELL_NBR_WIPE_DIR, 'd')
|
|
-- parametri solid fill
|
|
LayerParams.nFloorNbr = EgtGetInfo( s_nPartId, KEY_FLOOR_NBR, 'i') or 0
|
|
LayerParams.nFloorType = EgtGetInfo( s_nPartId, KEY_FLOOR_TYPE, 'i') or FILL_TYPE.OFFSET
|
|
LayerParams.nCeilNbr = EgtGetInfo( s_nPartId, KEY_CEIL_NBR, 'i') or 0
|
|
LayerParams.nCeilType = EgtGetInfo( s_nPartId, KEY_CEIL_TYPE, 'i') or FILL_TYPE.OFFSET
|
|
-- parametri infill
|
|
LayerParams.dInfillStrand = EgtGetInfo( s_nPartId, KEY_INFILL_STRAND, 'd') or LayerParams.dStrand
|
|
if LayerParams.dInfillStrand < GEO.EPS_SMALL then LayerParams.dInfillStrand = LayerParams.dStrand end
|
|
LayerParams.bInfillLink = EgtGetInfo( s_nPartId, KEY_INFILL_LINK, 'b') or false
|
|
LayerParams.dInfillOverlap = EgtGetInfo( s_nPartId, KEY_INFILL_OVERLAP, 'd') or 0
|
|
LayerParams.nInfillType = EgtGetInfo( s_nPartId, KEY_INFILL_TYPE, 'i') or FILL_TYPE.NONE
|
|
|
|
-- eventuale modifica dei parametri per gestire correttamente il caso spiral vase
|
|
if LayerParams.bSpiralVase then
|
|
LayerParams.nFloorNbr = 0
|
|
LayerParams.nCeilNbr = 0
|
|
end
|
|
|
|
return LayerParams
|
|
end
|
|
|
|
--------------------------------------------------------------------------------------------
|
|
local function CopyInfo( nSouId, nDestId, sInfo, sType)
|
|
local info = EgtGetInfo( nSouId, sInfo, sType)
|
|
EgtSetInfo( nDestId, sInfo, info)
|
|
end
|
|
|
|
-------------------------------------------------------------------
|
|
local function SwapInfo( nId1, nId2, sInfo, sType, sDefVal)
|
|
local info1 = EgtGetInfo( nId1, sInfo, sType) or sDefVal
|
|
local info2 = EgtGetInfo( nId2, sInfo, sType) or sDefVal
|
|
EgtSetInfo( nId1, sInfo, info2)
|
|
EgtSetInfo( nId2, sInfo, info1)
|
|
end
|
|
|
|
--------------------------------------------------------------------------------------------
|
|
local function UpdateInvertInfo( nId)
|
|
local bInvert = EgtGetInfo( nId, KEY_INVERTED_CRV, 'b') or false
|
|
EgtSetInfo( nId, KEY_INVERTED_CRV, not bInvert)
|
|
end
|
|
|
|
----------------------------------------------------------------------
|
|
local function ComputeSurfOffset( nSrf, nGrpId, dOffs)
|
|
-- restituisce id della superficie offsettata in caso di successo, nil in caso di errore, GDB_ID.NULL se la superficie offsettata scompare
|
|
|
|
local nOffsSrf = EgtSurfFrOffsetAdv( nSrf, dOffs)
|
|
if not nOffsSrf then
|
|
-- ritento modificando leggermente l'offset
|
|
nOffsSrf = EgtSurfFrOffsetAdv( nSrf, dOffs + 0.05)
|
|
end
|
|
-- sposto nel gruppo desiderato
|
|
EgtRelocateGlob( nOffsSrf or GDB_ID.NULL, nGrpId)
|
|
|
|
return nOffsSrf
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function ComputeTrimSurf( nSrf, nGrpId, dStrand, dOverlap)
|
|
|
|
local nTrimSurf = ComputeSurfOffset( nSrf, nGrpId, - dStrand * ( 0.5 - dOverlap / 100) + 2 * s_dOffsCorr)
|
|
local bNoOverlap = false
|
|
if not nTrimSurf and dOverlap > GEO.EPS_SMALL then
|
|
-- tento senza overlap
|
|
nTrimSurf = ComputeSurfOffset( nSrf, nGrpId, - dStrand * 0.5)
|
|
if not nTrimSurf then
|
|
return
|
|
end
|
|
bNoOverlap = true
|
|
end
|
|
|
|
return nTrimSurf, bNoOverlap
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function GetLayerStartPoint( nLayId)
|
|
|
|
-- recupero quota layer
|
|
local dZ = EgtGetInfo( nLayId, KEY_SLICE_REAL_Z, 'd')
|
|
local dDeltaZ = EgtGetInfo( nLayId, KEY_SLICE_DELTAZ, 'd')
|
|
local frSlicing = Frame3d( ORIG(), s_vtSlicing)
|
|
local ptOn = Point3d( 0, 0, dZ + dDeltaZ)
|
|
ptOn:toGlob( frSlicing)
|
|
|
|
-- gruppo temporaneo dove salvo i risultati
|
|
local nGrpTmp = EgtGroup( nLayId)
|
|
|
|
local vPtStart = {}
|
|
local nMachStartGrp = EgtGetFirstNameInGroup( s_nPartId, LAY_MACH_START)
|
|
local nStartId = EgtGetFirstInGroup( nMachStartGrp)
|
|
while nStartId do
|
|
local nType = EgtGetType( nStartId)
|
|
-- se punto
|
|
if nType == GDB_TY.GEO_POINT then
|
|
table.insert( vPtStart, EgtSP( nStartId))
|
|
else
|
|
-- se curva interseco con il piano
|
|
local nId, nCnt = EgtPlaneCurveInters( ptOn, s_vtSlicing, nStartId, nGrpTmp, GDB_RT.GLOB)
|
|
if nId then
|
|
for i = nId, nId + nCnt - 1 do
|
|
table.insert( vPtStart, EgtSP( i))
|
|
end
|
|
end
|
|
end
|
|
nStartId = EgtGetNext( nStartId)
|
|
end
|
|
|
|
EgtErase( nGrpTmp)
|
|
return vPtStart
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function ModifyStartPoint( nCrvId, vPtStart)
|
|
|
|
-- cerco lo start point più vicino tra quelli possibili
|
|
if vPtStart and #vPtStart > 0 then
|
|
local nMinIdx = -1
|
|
if #vPtStart == 1 then
|
|
nMinIdx = 1
|
|
else
|
|
local dMinDist = GEO.INFINITO
|
|
for i = 1, #vPtStart do
|
|
local dDist = EgtPointCurveDist( vPtStart[i], nCrvId)
|
|
if dDist < dMinDist - 10 * GEO.EPS_SMALL then
|
|
dMinDist = dDist
|
|
nMinIdx = i
|
|
end
|
|
end
|
|
end
|
|
EgtChangeClosedCurveStartPoint( nCrvId, vPtStart[nMinIdx])
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function GetPathsFromSurf( nSrfId, sName, nType, nGrpId, vPtStart)
|
|
|
|
local vIds = {}
|
|
local nChunks = EgtSurfFrChunkCount( nSrfId)
|
|
for nC = 0, nChunks - 1 do
|
|
-- estraggo i contorni
|
|
local nCrvId, nCrvCnt = EgtExtractSurfFrChunkLoops( nSrfId, nC, nGrpId)
|
|
for nInd = 0, nCrvCnt - 1 do
|
|
EgtSetName( nCrvId + nInd, sName)
|
|
EgtSetInfo( nCrvId + nInd, KEY_TYPE, nType)
|
|
EgtModifyCurveExtrusion( nCrvId + nInd, s_vtSlicing, GDB_ID.ROOT)
|
|
|
|
-- se è loop interno lo inverto per averlo orientato in senso antiorario
|
|
if nInd > 0 then
|
|
EgtInvertCurve( nCrvId + nInd)
|
|
EgtSetInfo( nCrvId + nInd, KEY_INTERNAL_SRF_LOOP, true)
|
|
end
|
|
|
|
-- verifico soddisfi i requisiti (lunghezza e area)
|
|
local dLen = EgtCurveLength( nCrvId + nInd)
|
|
local _ , _ , dArea = EgtCurveArea( nCrvId + nInd)
|
|
if dLen < MIN_LEN or dArea < MIN_AREA then
|
|
EgtErase( nCrvId + nInd)
|
|
else
|
|
table.insert( vIds, nCrvId + nInd)
|
|
ModifyStartPoint( nCrvId + nInd, vPtStart)
|
|
end
|
|
end
|
|
end
|
|
|
|
return vIds or {}
|
|
end
|
|
|
|
----------------------------------------------------------------------
|
|
local function VerifyPath( nCrvId, dStrand, nGrp)
|
|
|
|
local _, _, dArea = EgtCurveArea( nCrvId)
|
|
|
|
-- verifico se esiste l'offset ( permetto una piccola sovrapposizione)
|
|
-- TODO migliorare il controllo per verificare se sovrapposizione
|
|
local dAllowedOverlap = 1
|
|
local nRes, nCnt = EgtOffsetCurveAdv( nCrvId, - dStrand / 2 + dAllowedOverlap, GDB_OT.FILLET, s_dOffsTol)
|
|
-- se errore ritento con valore leggermente modificato
|
|
if not nRes then
|
|
nRes, nCnt = EgtOffsetCurveAdv( nCrvId, - dStrand / 2 + 0.05, GDB_OT.FILLET, s_dOffsTol)
|
|
if not nRes then return false end
|
|
end
|
|
for j = nRes, nRes + nCnt - 1 do
|
|
EgtErase( j)
|
|
end
|
|
|
|
if nRes == GDB_ID.NULL or not dArea or dArea < GEO.EPS_SMALL then
|
|
-- verifico se fattibile con una sola passata
|
|
-- TODO da sistemare con medial axis per curva generica
|
|
local bSingleStrand = false
|
|
if EgtCurveIsClosed( nCrvId) then
|
|
local nGrpTmp = EgtGroup( nGrp, Frame3d( ORIG(), s_vtSlicing), GDB_RT.GLOB)
|
|
EgtRelocateGlob( nCrvId, nGrpTmp)
|
|
local frLoc, dDimX, dDimY = EgtCurveMinAreaRectangleXY( nCrvId)
|
|
if dDimY < 0.5 then
|
|
-- TODO curva generica
|
|
local dZ = EgtSP( nCrvId):getZ()
|
|
-- creo la curva che corrisponde alla sigola passata
|
|
local ptS = frLoc:getOrigin() - dDimX / 2 * frLoc:getVersX() + dZ * Z_AX()
|
|
local ptE = frLoc:getOrigin() + dDimX / 2 * frLoc:getVersX() + dZ * Z_AX()
|
|
if dist( ptS, ptE) > 5 then
|
|
local nId = EgtCurveCompoFromPoints( nGrpTmp, { ptS, ptE})
|
|
local sName = EgtGetName( nCrvId)
|
|
if sName then EgtSetName( nId, sName) end
|
|
local nType = EgtGetInfo( nCrvId, KEY_TYPE, 'i')
|
|
if nType then EgtSetInfo( nId, KEY_TYPE, nType) end
|
|
EgtErase( nCrvId)
|
|
EgtChangeId( nId, nCrvId)
|
|
bSingleStrand = true
|
|
end
|
|
end
|
|
EgtRelocateGlob( nCrvId, nGrp, GDB_IN.LAST_SON)
|
|
EgtErase( nGrpTmp)
|
|
end
|
|
-- se non è fattibile con unica passata lo cancello
|
|
if not bSingleStrand then
|
|
-- verifico se devo eliminarlo dalle info della curva precedente
|
|
local nPrev = EgtGetInfo( nCrvId, KEY_PREV_CRV, 'i')
|
|
if nPrev then
|
|
local vNext = EgtGetInfo( nPrev, KEY_NEXT_CRVS, 'vi')
|
|
if vNext then
|
|
for k = 1, #vNext do
|
|
if vNext[k] == nCrvId then
|
|
table.remove( vNext, k)
|
|
break
|
|
end
|
|
end
|
|
EgtSetInfo( nPrev, KEY_NEXT_CRVS, vNext)
|
|
end
|
|
end
|
|
-- cancello
|
|
EgtErase( nCrvId)
|
|
return false
|
|
end
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function AdjustTrimSurfExtraAngleChunks( nTrimSurf, dOffs, dStrand)
|
|
|
|
if EgtSurfFrChunkCount( nTrimSurf) == 0 then
|
|
return
|
|
end
|
|
|
|
-- calcolo la superficie occupata dalle shell se non ci fossero shell particolari ( extra shells o ribs-merged shells)
|
|
local nLaySurf = EgtGetFirstNameInGroup( EgtGetParent( nTrimSurf), LAYER_SRF)
|
|
dOffs = dOffs + dStrand * 0.5 + 50 * GEO.EPS_SMALL
|
|
local nBaseSurf = ComputeSurfOffset( nLaySurf, EgtGetParent( nTrimSurf), - dOffs)
|
|
if not nBaseSurf then
|
|
EgtOutLog( 'Warning : AdjustTrimSurfExtraAngleChunks base surf computation failed. TrimSurf may be inaccurate (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
return
|
|
elseif nBaseSurf == GDB_ID.NULL then
|
|
EgtOutLog( 'Warning : AdjustTrimSurfExtraAngleChunks base surf does not exist. TrimSurf may be inaccurate (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
return
|
|
end
|
|
local nChunks = EgtSurfFrChunkCount( nBaseSurf)
|
|
|
|
-- individuo i chunk della TrimSurf da conservare
|
|
local vValidChunks = {}
|
|
local nFirstId, nCnt = EgtExplodeSurf( nTrimSurf)
|
|
for nId = nFirstId, nFirstId + nCnt - 1 do
|
|
-- verifico se è esterno a tutti i chunks di nBaseSurf ( quindi è porzione non riempita tra le shell da eliminare)
|
|
local bIsOut = true
|
|
for i = 0, nChunks - 1 do
|
|
local nRes = EgtSurfFrChunkSimpleClassify( nId, 0, nBaseSurf, i)
|
|
if nRes ~= GDB_RC.OUT then
|
|
bIsOut = false
|
|
break
|
|
end
|
|
end
|
|
|
|
if bIsOut then
|
|
EgtErase( nId)
|
|
else
|
|
-- se compreso nella superficie base va conservato
|
|
table.insert( vValidChunks, nId)
|
|
end
|
|
end
|
|
|
|
-- unisco tutti i chunk validi in un'unica superficie
|
|
for i = 2, #vValidChunks do
|
|
EgtSurfFrAdd( vValidChunks[1], vValidChunks[i])
|
|
EgtErase( vValidChunks[i])
|
|
end
|
|
|
|
EgtErase( nBaseSurf)
|
|
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
------------------------- INFILL -----------------------------------
|
|
--------------------------------------------------------------------
|
|
local function CalcInfillPaths( nLayId, nInfillGrp, LayerParams)
|
|
|
|
if not nInfillGrp then return end
|
|
|
|
-- recupero le curve di infill
|
|
local vIds = EgtGetAllInGroup( nInfillGrp)
|
|
if not vIds or #vIds == 0 then return end
|
|
|
|
-- scorro i gruppi di curve
|
|
local vCrvGrps = EgtGetNameInGroup( nLayId, CONTOUR_GRP .. '*')
|
|
for i = 1, #vCrvGrps do
|
|
|
|
-- creo il gruppo per infill
|
|
local nInfillPathGrp = EgtGroup( vCrvGrps[i])
|
|
EgtSetName( nInfillPathGrp, INFILL_GRP)
|
|
EgtSetStatus( nInfillPathGrp, GDB_ST.OFF)
|
|
EgtSetInfo( nInfillPathGrp, KEY_FILL_TYPE, LayerParams.nInfillType)
|
|
|
|
-- recupero la superficie occupata dalle shell
|
|
local nSrfBase = EgtGetFirstNameInGroup( vCrvGrps[i], TOT_SHELL_TRIM_SURF)
|
|
if not nSrfBase then
|
|
-- se non esiste non c'è spazio per infill
|
|
EgtOutLog( 'Warning : Infill not possibile (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
else
|
|
-- calcolo la superficie per trim
|
|
local nTrimSrf, bNoOverlap = ComputeTrimSurf( nSrfBase, nInfillPathGrp, LayerParams.dInfillStrand, LayerParams.dInfillOverlap)
|
|
if not nTrimSrf then
|
|
-- errore
|
|
EgtOutLog( 'Error : creation of Infill region failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : creation of Infill region failed')
|
|
elseif nTrimSrf == GDB_ID.NULL then
|
|
EgtOutLog( 'Warning : Infill not possibile (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
else
|
|
if bNoOverlap then
|
|
EgtOutLog( 'Warning : Infill without correct overlap (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
end
|
|
|
|
for i = 1, #vIds do
|
|
local nNewId = EgtCopyGlob( vIds[i], nInfillPathGrp)
|
|
-- eventuale inversione della curva per link
|
|
if LayerParams.bInfillLink and i % 2 == 0 then
|
|
EgtInvertCurve( nNewId)
|
|
UpdateInvertInfo( nNewId)
|
|
end
|
|
|
|
-- faccio trim con la superficie
|
|
local nRes, nCnt = EgtTrimCurveWithRegion( nNewId, nTrimSrf, true, true)
|
|
for nId = nRes, nRes + nCnt - 1 do
|
|
-- verifico se lunghezza minima
|
|
local dLen = EgtCurveLength( nId)
|
|
if dLen < MIN_INFILL_LEN then
|
|
EgtErase( nId)
|
|
else
|
|
EgtSetName( nId, INFILL_CRV)
|
|
EgtSetInfo( nId, KEY_TYPE, TYPE.INFILL)
|
|
EgtSetInfo( nId, KEY_ASSOCIATED_SURF, nTrimSrf)
|
|
EgtModifyCurveExtrusion( nId, s_vtSlicing, GDB_RT.GLOB)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- avendo riempito la regione con gli infill, la TotShellTrimSurf non deve esistere
|
|
EgtErase( nSrfBase)
|
|
end
|
|
end
|
|
|
|
-- se gruppo vuoto lo cancello
|
|
if not EgtGetFirstNameInGroup( nInfillPathGrp, INFILL_CRV .. '*') then
|
|
EgtErase( nInfillPathGrp)
|
|
end
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
------------------------ SOLID FILL --------------------------------
|
|
--------------------------------------------------------------------
|
|
local function AssignChildrenCurves( vParentIds, vChildrenIds, vOrdered)
|
|
|
|
if not vParentIds or not vChildrenIds then return end
|
|
|
|
if #vParentIds == 1 then
|
|
vOrdered[vParentIds[1]] = vChildrenIds
|
|
else
|
|
-- recupero i centroidi di tutte le curve padre
|
|
local vPtCParent = {}
|
|
for i = 1, #vParentIds do
|
|
table.insert( vPtCParent, EgtGP( vParentIds[i]))
|
|
end
|
|
|
|
-- associo ad ogni elemento di vParentIds gli elementi di vChildrenIds che ha generato
|
|
for i = 1, #vChildrenIds do
|
|
-- individuo la curva di vParentIds con il centroiode più vicino
|
|
local ptC = EgtGP( vChildrenIds[i])
|
|
local dDistMin = GEO.INFINITO
|
|
local nParentId = -1
|
|
for j = 1, #vPtCParent do
|
|
local dCurrDist = dist( ptC, vPtCParent[j])
|
|
if dCurrDist < dDistMin - GEO.EPS_SMALL then
|
|
dDistMin = dCurrDist
|
|
nParentId = vParentIds[j]
|
|
end
|
|
end
|
|
|
|
-- la aggiungo tra i figli della curva di vParentIds trovata
|
|
if not vOrdered[nParentId] then
|
|
vOrdered[nParentId] = {vChildrenIds[i]}
|
|
else
|
|
table.insert( vOrdered[nParentId], vChildrenIds[i])
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------------
|
|
local function ReorderPath( vOldIds, vNewIds)
|
|
|
|
if not vNewIds or #vNewIds == 0 then return end
|
|
if not vOldIds or #vOldIds == 0 then return end
|
|
|
|
-- suddivido in base alla tipologia di loop ( esterno o interno)
|
|
local tOldIds = {{}, {}}
|
|
for i = 1, #vOldIds do
|
|
local bIntLoop = EgtGetInfo( vOldIds[i], KEY_INTERNAL_SRF_LOOP, 'b') or false
|
|
local nTabInd = EgtIf( bIntLoop, 2, 1)
|
|
table.insert( tOldIds[nTabInd], vOldIds[i])
|
|
end
|
|
|
|
local tNewIds = {{}, {}}
|
|
for i = 1, #vNewIds do
|
|
local bIntLoop = EgtGetInfo( vNewIds[i], KEY_INTERNAL_SRF_LOOP, 'b') or false
|
|
local nTabInd = EgtIf( bIntLoop, 2, 1)
|
|
table.insert( tNewIds[nTabInd], vNewIds[i])
|
|
end
|
|
|
|
-- assegno ad ogni curva di vOldIds le curve di vNewIds che ha generato
|
|
local vOrdered = {}
|
|
AssignChildrenCurves( tOldIds[1], tNewIds[1], vOrdered) -- loop esterni
|
|
AssignChildrenCurves( tOldIds[2], tNewIds[2], vOrdered) -- loop interni
|
|
|
|
-- assegno le info e riordino
|
|
local vNewOrder = {}
|
|
local nGrp = EgtGetParent( vNewIds[1])
|
|
for i = 1, #vOldIds do
|
|
local vChildrenIds = vOrdered[vOldIds[i]] or {}
|
|
EgtSetInfo( vOldIds[i], KEY_NEXT_CRVS, vChildrenIds)
|
|
for j = 1, #vChildrenIds do
|
|
EgtRelocateGlob( vChildrenIds[j], nGrp, GDB_IN.LAST_SON)
|
|
table.insert( vNewOrder, vChildrenIds[j])
|
|
EgtSetInfo( vChildrenIds[j], KEY_PREV_CRV, vOldIds[i])
|
|
end
|
|
end
|
|
|
|
return vNewOrder
|
|
end
|
|
|
|
---------------------------------------------------------------------------
|
|
local function ComputeOffsetShells( nSrf, dStrand, sName, nType, nGrp, vPtStart, vOldIds, nMaxShells)
|
|
|
|
if nSrf == GDB_ID.NULL then return true end
|
|
if not nMaxShells then nMaxShells = GEO.INFINITO end
|
|
if nMaxShells == 0 then return true end
|
|
|
|
-- nSrf è già la prima superficie da cui estrarre i bordi, quindi il primo offset non va fatto
|
|
local dOffs = 0
|
|
local nSrfOffs = EgtCopyGlob( nSrf, nGrp)
|
|
|
|
for i = 1, nMaxShells do
|
|
-- estraggo i contorni
|
|
local vNewIds = GetPathsFromSurf( nSrfOffs, sName, nType, nGrp, vPtStart)
|
|
if vNewIds then
|
|
-- riordino
|
|
local vNewOrder = ReorderPath( vOldIds, vNewIds) or vNewIds
|
|
vOldIds = vNewOrder
|
|
else
|
|
return false
|
|
end
|
|
|
|
EgtErase( nSrfOffs)
|
|
|
|
-- se sei già all'ultima shell richiesta non è necessario calcolare offset successivo
|
|
if i == nMaxShells then
|
|
return true
|
|
end
|
|
|
|
-- offset successivo
|
|
dOffs = dOffs - dStrand
|
|
nSrfOffs = ComputeSurfOffset( nSrf, nGrp, dOffs)
|
|
if not nSrfOffs then
|
|
-- errore nel calcolo della superficie
|
|
return false
|
|
elseif nSrfOffs == GDB_ID.NULL then
|
|
-- spazio esaurito, termino la funzione
|
|
return true
|
|
end
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
------------------------------------------------------------------
|
|
local function FindOptimalZigZagDirection( nSrfId, nBorderSurf, dStrand, nGrp, frLoc)
|
|
|
|
-- come direzione ottimale scelgo quella del lato più vicino al bordo oppure quella del
|
|
-- lato più lungo nel caso in cui i lati fossero tutti sufficientemente lontani ( distanza > dStrand) dal bordo
|
|
|
|
local nGrpTmp = EgtGroup( nGrp, frLoc, GDB_RT.GLOB) -- gruppo temporaneo per i conti
|
|
local dTol = 1 + GEO.EPS_SMALL
|
|
|
|
-- recupero tutti i lati della superficie da riempire
|
|
local vCrvIds = GetPathsFromSurf( nSrfId, 'Tmp', 0, nGrpTmp)
|
|
local nId, nCnt = EgtExplodeCurveCompo( vCrvIds[1])
|
|
local vAllIds = {}
|
|
for i = nId, nId + nCnt - 1 do
|
|
table.insert( vAllIds, i)
|
|
end
|
|
local vCheckIds = {}
|
|
|
|
-- se ho superficie che contiene nSrfId ( caso AuxSolid) cerco il lato di lunghezza massima tra quelli a distanza minima dal bordo
|
|
if nBorderSurf then
|
|
-- recupero i contorni della curva di bordo
|
|
local vBorderIds = GetPathsFromSurf( nBorderSurf, 'TmpBorder', 0, nGrpTmp)
|
|
|
|
local dMinDist = GEO.INFINITO
|
|
for i = nId, nId + nCnt - 1 do
|
|
|
|
-- trovo la distanza minima dalle curve di bordo
|
|
local dDist
|
|
if #vBorderIds == 1 then
|
|
dDist = EgtPointCurveDist( EgtMP( i), vBorderIds[1])
|
|
else
|
|
dDist = GEO.INFINITO
|
|
for j = 1, #vBorderIds do
|
|
local dCurrDist = EgtPointCurveDist( EgtMP( i), vBorderIds[j])
|
|
if dCurrDist < dDist then
|
|
dDist = dCurrDist
|
|
end
|
|
end
|
|
end
|
|
|
|
-- se tratto sufficientemente vicino al bordo verifico se a distanza minima ( entro tolleranza dTol)
|
|
if dDist < dStrand + GEO.EPS_SMALL then
|
|
if abs( dDist - dMinDist) < dTol then
|
|
table.insert( vCheckIds, i)
|
|
elseif dDist < dMinDist - dTol then
|
|
dMinDist = dDist
|
|
vCheckIds = {i}
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- se non ho id specifici da controllare considero tutti i lati
|
|
if #vCheckIds == 0 then
|
|
vCheckIds = vAllIds
|
|
end
|
|
|
|
-- cerco il lato più lungo tra quelli selezionati
|
|
local vtDir
|
|
if #vCheckIds == 1 then
|
|
vtDir = EgtSV( vCheckIds[1])
|
|
else
|
|
local dLen = - GEO.INFINITO
|
|
for k = 1, #vCheckIds do
|
|
local dCurrLen = EgtCurveLength( vCheckIds[k])
|
|
if dCurrLen > dLen + GEO.EPS_SMALL then
|
|
dLen = dCurrLen
|
|
vtDir = EgtSV( vCheckIds[k])
|
|
end
|
|
end
|
|
end
|
|
|
|
EgtErase( nGrpTmp)
|
|
return vtDir
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function ComputeZigZagSolidFill( nSrf, dStrand, sName, nType, nGrp, nBorderSurf)
|
|
|
|
if nSrf == GDB_ID.NULL then return end
|
|
|
|
local nCopySrf = EgtCopyGlob( nSrf, nGrp)
|
|
local frLoc = Frame3d( ORIG(), s_vtSlicing)
|
|
|
|
-- analizzo tutti i chunk della superficie da riempire
|
|
local nFirst, nSrfCnt = EgtExplodeSurf( nCopySrf)
|
|
local vIds = {}
|
|
for nSrfId = nFirst, nFirst + nSrfCnt - 1 do
|
|
|
|
-- trovo la direzione ottimale per la svuotatura in frLoc
|
|
local vtDir = FindOptimalZigZagDirection( nSrfId, nBorderSurf, dStrand, nGrp, frLoc)
|
|
local _, _, dAng = SphericalFromVector( vtDir)
|
|
vtDir:toGlob( frLoc)
|
|
|
|
local nInd, nCnt = EgtGetSurfFrZigZagInfill( nSrfId, nGrp, dStrand, dAng, false, false)
|
|
if nInd then
|
|
for j = nInd, nInd + nCnt - 1 do
|
|
EgtSetName( j, sName)
|
|
EgtSetInfo( j, KEY_TYPE, nType)
|
|
EgtSetInfo( j, KEY_ZIG_ZAG_DIR, vtDir)
|
|
EgtSetInfo( j, KEY_ZIG_ZAG_INFILL, true)
|
|
EgtModifyCurveExtrusion( j, s_vtSlicing, GDB_RT.GLOB)
|
|
table.insert( vIds, j)
|
|
end
|
|
end
|
|
EgtErase( nSrfId)
|
|
end
|
|
end
|
|
|
|
------------------------------------------------------------------
|
|
local function CalcSolidFillPath( nLayId, LayerParams, vPtStart, nFillType)
|
|
|
|
-- scorro i gruppi di curve
|
|
local vCrvGrps = EgtGetNameInGroup( nLayId, CONTOUR_GRP .. '*')
|
|
for i = 1, #vCrvGrps do
|
|
|
|
-- creo il gruppo per infill
|
|
local nInfillPathGrp = EgtGroup( vCrvGrps[i])
|
|
EgtSetName( nInfillPathGrp, INFILL_GRP)
|
|
EgtSetStatus( nInfillPathGrp, GDB_ST.OFF)
|
|
EgtSetInfo( nInfillPathGrp, KEY_FILL_TYPE, nFillType)
|
|
|
|
-- recupero la superficie occupata dalle shell
|
|
local nSrfBase = EgtGetFirstNameInGroup( vCrvGrps[i], TOT_SHELL_TRIM_SURF)
|
|
if not nSrfBase then
|
|
-- se non esiste non c'è spazio per solid fill
|
|
EgtOutLog( 'Warning : SolidFill not possibile (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
else
|
|
-- calcolo la superficie da riempire
|
|
local nSrfToFill, bNoOverlap = ComputeTrimSurf( nSrfBase, nInfillPathGrp, LayerParams.dInfillStrand, LayerParams.dInfillOverlap)
|
|
if not nSrfToFill then
|
|
-- errore
|
|
EgtOutLog( 'Error : creation of SolidFill region failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : creation of SolidFill region failed')
|
|
elseif nSrfToFill == GDB_ID.NULL then
|
|
EgtOutLog( 'Warning : SolidFill not possibile (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
else
|
|
if bNoOverlap then
|
|
EgtOutLog( 'Warning : SolidFill without correct overlap (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
end
|
|
|
|
-- distanza tra passate tenendo conto dell'overlap indicato
|
|
local dDist = ( 1 - LayerParams.dStrandOverlap / 100) * LayerParams.dInfillStrand
|
|
-- inserisco il riempimento
|
|
if nFillType == FILL_TYPE.OFFSET then
|
|
-- recupero le shell precedenti dal PathGrp
|
|
local nPathGrp = EgtGetFirstNameInGroup( vCrvGrps[i], PATH_GRP)
|
|
local nLast = EgtGetLastNameInGroup( nPathGrp, SHELL_CRV .. '*') or EgtGetLastNameInGroup( nPathGrp, EXTRA_SHELL_CRV .. '*')
|
|
local vOldIds = EgtGetNameInGroup( nPathGrp, EgtGetName( nLast))
|
|
if not ComputeOffsetShells( nSrfToFill, dDist, INFILL_CRV, TYPE.INFILL, nInfillPathGrp, vPtStart, vOldIds) then
|
|
EgtOutLog( 'Error : creation of SolidFill failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : creation of SolidFill failed')
|
|
end
|
|
elseif nFillType == FILL_TYPE.ZIGZAG then
|
|
ComputeZigZagSolidFill( nSrfToFill, dDist, INFILL_CRV, TYPE.INFILL, nInfillPathGrp)
|
|
end
|
|
|
|
-- avendo riempito la regione, la TotShellTrimSurf non deve esistere
|
|
EgtErase( nSrfBase)
|
|
end
|
|
end
|
|
|
|
-- se gruppo vuoto lo cancello
|
|
if not EgtGetFirstInGroup( nInfillPathGrp) then
|
|
EgtErase( nInfillPathGrp)
|
|
end
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
--------------------------- RIBS -----------------------------------
|
|
--------------------------------------------------------------------
|
|
local function VerifyRibsHoles( vIds)
|
|
|
|
local sPrevName = EgtGetName( vIds[1])
|
|
local i = 2
|
|
while i <= #vIds do
|
|
|
|
local bAdd = false
|
|
local sCurrName = EgtGetName( vIds[i])
|
|
-- se derivano dallo stesso setto verifico se possono essere uniti
|
|
if sCurrName == sPrevName then
|
|
local dStrand = EgtGetInfo( vIds[i], KEY_RIBS_STRAND, 'd')
|
|
local ptS1 = EgtSP( vIds[i-1])
|
|
local ptE1 = EgtEP( vIds[i-1])
|
|
local ptS2 = EgtSP( vIds[i])
|
|
local ptE2 = EgtEP( vIds[i])
|
|
|
|
local bAdd1 = dist( ptS1, ptE2) < dStrand + 10 * GEO.EPS_SMALL or dist( ptS1, ptS2) < dStrand + 10 * GEO.EPS_SMALL
|
|
local bAdd2 = dist( ptE1, ptS2) < dStrand + 10 * GEO.EPS_SMALL or dist( ptE1, ptE2) < dStrand + 10 * GEO.EPS_SMALL
|
|
local bInvert = dist( ptE1, ptE2) < dStrand + 10 * GEO.EPS_SMALL or dist( ptS1, ptS2) < dStrand + 10 * GEO.EPS_SMALL
|
|
|
|
if bInvert then
|
|
EgtInvertCurve( vIds[i])
|
|
end
|
|
|
|
if bAdd1 and bAdd2 then
|
|
-- se da unire in setto chiuso
|
|
bAdd = true
|
|
EgtAddCurveCompoLine( vIds[i-1], EgtEP( vIds[i]), false)
|
|
EgtAddCurveCompoLine( vIds[i-1], EgtSP( vIds[i]))
|
|
EgtAddCurveCompoCurve( vIds[i-1], vIds[i])
|
|
table.remove( vIds, i) -- rimuovo il setto dalla tabella
|
|
|
|
elseif bAdd2 then
|
|
bAdd = true
|
|
-- unisco il secondo tratto al primo
|
|
EgtAddCurveCompoLine( vIds[i-1], EgtSP( vIds[i]))
|
|
EgtAddCurveCompoCurve( vIds[i-1], vIds[i])
|
|
table.remove( vIds, i) -- rimuovo il setto dalla tabella
|
|
|
|
elseif bAdd1 then
|
|
bAdd = true
|
|
-- unisco il primo tratto al secondo
|
|
EgtAddCurveCompoLine( vIds[i], EgtSP( vIds[i-1]))
|
|
EgtAddCurveCompoCurve( vIds[i], vIds[i-1])
|
|
table.remove( vIds, i-1) -- rimuovo il setto dalla tabella
|
|
end
|
|
end
|
|
|
|
-- aggiorno per iterazione successiva
|
|
sPrevName = sCurrName
|
|
if not bAdd then
|
|
i = i + 1
|
|
end
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function FindRibsUserLinkDirection( nCrv1, nCrv2)
|
|
|
|
-- stabilisco l'orientamento del link
|
|
local bCCW = false
|
|
|
|
-- costruisco la superficie "definita" dal setto di partenza con i primi due setti che lo definiscono
|
|
local nGrpTmp = EgtGroup( EgtGetParent( nCrv1))
|
|
local nSrfLoop = EgtCurveCompoFromPoints( nGrpTmp, {EgtEP( nCrv1), EgtSP( nCrv2)})
|
|
if not nSrfLoop then return false end
|
|
EgtAddCurveCompoLine( nSrfLoop, EgtSP( nCrv2) + 100 * EgtSV( nCrv2))
|
|
EgtAddCurveCompoLine( nSrfLoop, EgtEP( nCrv1) - 100 * EgtEV( nCrv1))
|
|
EgtCloseCurveCompo( nSrfLoop)
|
|
|
|
local nSurf = EgtSurfFlatRegion( nGrpTmp, {nSrfLoop})
|
|
if not nSurf then
|
|
EgtErase( nGrpTmp)
|
|
return
|
|
end
|
|
-- verifico direzione della normale
|
|
local vtN = EgtSurfFrNormVersor( nSurf, GDB_ID.ROOT)
|
|
if AreSameVectorApprox( vtN, s_vtSlicing) then
|
|
bCCW = true
|
|
end
|
|
|
|
EgtErase( nGrpTmp)
|
|
return bCCW
|
|
|
|
end
|
|
|
|
-----------------------------------------------------------------------
|
|
local function FindAssociatedUserLinkParts( nStartRib, vRibs, vUsed, nGrpTmp, nType, nSrfTest)
|
|
|
|
local tabUserLink = {}
|
|
|
|
for i = 1, #vRibs do
|
|
local nTypeCurr = EgtGetInfo( vRibs[i], KEY_RIBS_TYPE, 'i')
|
|
-- verifico che il setto non sia già stato utilizzato in un altro UserLink e sia di tipologia compatibile
|
|
if not vUsed[vRibs[i]] and nTypeCurr == nType then
|
|
|
|
-- recupero setto di partenza non trimmato
|
|
local nStartId = EgtGetInfo( vRibs[i], KEY_START_RIB, 'i')
|
|
|
|
-- verifico se interseca nStartRib con un estremo
|
|
local dParS = EgtCurveParamAtPoint( nStartRib, EgtSP( nStartId), 100 * GEO.EPS_SMALL)
|
|
local dParE = EgtCurveParamAtPoint( nStartRib, EgtEP( nStartId), 100 * GEO.EPS_SMALL)
|
|
if dParS and dParE then
|
|
-- se entrambi gli estremi non ha senso aggiungerlo a UserLink
|
|
elseif dParS or dParE then
|
|
-- se solo un estremo verifico se si unisce a UserLink in tratto sensato
|
|
local dPar = dParS or dParE
|
|
local ptTest = EgtPoint( nGrpTmp, EgtUP( nStartRib, dPar))
|
|
local bExtJoint = EgtSurfFrTestExternal( nSrfTest, ptTest)
|
|
if ( nType == RIB_TYPE.EXTERNAL and not bExtJoint) or ( nType ~= RIB_TYPE.EXTERNAL and bExtJoint) then
|
|
|
|
-- lo aggiungo alla tabella di UserLink
|
|
local tRib = { nId = vRibs[i], bStart = EgtIf( dParS, true, false), bOn = false, dPar = dPar}
|
|
table.insert( tabUserLink, tRib)
|
|
-- indico che il setto è stato utilizzato
|
|
vUsed[vRibs[i]] = 1
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
return tabUserLink
|
|
end
|
|
|
|
-----------------------------------------------------------------------
|
|
local function AssignUserLinkInfo( tabUserLink, bCCW, bLoopRib, bSameSide, sName)
|
|
|
|
-- ordino per paramentro crescente
|
|
table.sort( tabUserLink, function(a,b) return a.dPar < b.dPar end)
|
|
|
|
-- aggiorno le info dei tratti di UserLink per tenere conto delle aggiunte
|
|
local bUseOppositeCondition = EgtIf( bSameSide, false, true)
|
|
for i = 1, #tabUserLink do
|
|
local nId = tabUserLink[i].nId
|
|
|
|
EgtSetName( nId, sName)
|
|
EgtSetInfo( nId, KEY_RIBS_USER_LINK, 1)
|
|
EgtSetInfo( nId, KEY_RIBS_USER_LINK_CCW, bCCW)
|
|
EgtSetInfo( nId, KEY_LOOP_RIB, bLoopRib)
|
|
EgtSetInfo( nId, KEY_RIBS_USER_LINK_SAME_SIDE, bSameSide)
|
|
EgtSetInfo( nId, KEY_RIBS_USER_LINK_TOT, #tabUserLink)
|
|
|
|
-- riposiziono
|
|
if i > 1 then
|
|
EgtRelocateGlob( nId, tabUserLink[i-1].nId, GDB_IN.AFTER)
|
|
end
|
|
|
|
-- ordine
|
|
local nPrevOrd = EgtGetInfo( nId, KEY_RIBS_USER_LINK_ORDER, 'i')
|
|
local nCurrOrd = i - 1
|
|
EgtSetInfo( nId, KEY_RIBS_USER_LINK_ORDER, nCurrOrd)
|
|
|
|
-- orientamento
|
|
if tabUserLink[i].bOn then
|
|
-- se il tratto apparteneva già a UserLink va invertito se order passa da pari a dispari o viceversa
|
|
local bInvert = ( nPrevOrd and nPrevOrd % 2 ~= nCurrOrd % 2) or ( not nPrevOrd and i ~= 1 and i % 2 ~= 0)
|
|
if bInvert then
|
|
EgtInvertCurve( nId)
|
|
UpdateInvertInfo( nId)
|
|
end
|
|
if not bSameSide then bUseOppositeCondition = not bUseOppositeCondition end
|
|
else
|
|
-- se tratto aggiunto dipende con quale estremo interseca il setto
|
|
local bCondition = ( nCurrOrd % 2 == 0 and tabUserLink[i].bStart) or ( nCurrOrd % 2 ~= 0 and not tabUserLink[i].bStart)
|
|
if bUseOppositeCondition ~= bCondition then
|
|
EgtInvertCurve( nId)
|
|
UpdateInvertInfo( nId)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
------------------------------------------------------------------------
|
|
local function AdjustUserLinkRibs( tUserLink, vRibs, nSrfInt, nSrfExt, nGrp)
|
|
|
|
local nGrpTmp = EgtGroup( nGrp) -- gruppo temporaneo per conti
|
|
local vUsed = {} -- setti di vRibs utilizzati per UserLink
|
|
|
|
-- verifico se posso aggiungere tratti extra agli UserLink già individuati
|
|
for nStartRib, vAssociatedRibs in pairs( tUserLink) do
|
|
|
|
-- verifico se ho tratti singoli da aggiungere a UserLink definito da nStartRib
|
|
local nType = EgtGetInfo( nStartRib, KEY_RIBS_TYPE, 'i')
|
|
local nSrfTest = EgtIf( nType == RIB_TYPE.EXTERNAL, nSrfExt, nSrfInt)
|
|
local tabUserLink = FindAssociatedUserLinkParts( nStartRib, vRibs, vUsed, nGrpTmp, nType, nSrfTest)
|
|
|
|
-- se ho tratti da aggiungere
|
|
if #tabUserLink > 0 then
|
|
|
|
-- recupero i tratti già individuati su UserLink
|
|
for i = 1, #vAssociatedRibs do
|
|
local dPar = EgtCurveParamAtPoint( nStartRib, EgtSP( vAssociatedRibs[i]), 100 * GEO.EPS_SMALL)
|
|
local tRib = { nId = vAssociatedRibs[i], bStart = true, bOn = true, dPar = dPar}
|
|
table.insert( tabUserLink, tRib)
|
|
end
|
|
|
|
-- recupero alcune info utili relative a UserLink
|
|
local bCCW = EgtGetInfo( vAssociatedRibs[1], KEY_RIBS_USER_LINK_CCW, 'b') or false
|
|
local bLoopRib = EgtGetInfo( vAssociatedRibs[1], KEY_LOOP_RIB, 'b') or false
|
|
local bSameSide = EgtGetInfo( vAssociatedRibs[1], KEY_RIBS_USER_LINK_SAME_SIDE, 'b') or false
|
|
local sName = EgtGetName( vAssociatedRibs[1])
|
|
|
|
-- assegno le proprietà
|
|
AssignUserLinkInfo( tabUserLink, bCCW, bLoopRib, bSameSide, sName)
|
|
end
|
|
end
|
|
|
|
-- verifico se tra i setti singoli rimasti posso trovare nuovi UserLink
|
|
for i = 1, #vRibs do
|
|
if not vUsed[vRibs[i]] then
|
|
-- indico il corrente come utilizzato per non ricontrollarlo in FindAssociatedUserLinkParts
|
|
vUsed[vRibs[i]] = 1
|
|
|
|
-- verifico se trovo setti associati ( e quindi definisce UserLink)
|
|
local nStartRib = EgtGetInfo( vRibs[i], KEY_START_RIB, 'i')
|
|
local nType = EgtGetInfo( vRibs[i], KEY_RIBS_TYPE, 'i')
|
|
local nSrfTest = EgtIf( nType == RIB_TYPE.EXTERNAL, nSrfExt, nSrfInt)
|
|
local tabUserLink = FindAssociatedUserLinkParts( nStartRib, vRibs, vUsed, nGrpTmp, nType, nSrfTest)
|
|
|
|
if #tabUserLink > 0 then
|
|
-- se definisce UserLink aggiungo setto di partenza alla tabella
|
|
local dPar = EgtCurveParamAtPoint( nStartRib, EgtSP( vRibs[i]), 100 * GEO.EPS_SMALL)
|
|
local tRib = { nId = vRibs[i], bStart = true, bOn = true, dPar = dPar}
|
|
table.insert( tabUserLink, tRib)
|
|
|
|
-- assegno le info
|
|
local bCCW = false -- non posso conoscere a priori il verso del collegamento
|
|
local bLoopRib = false
|
|
local bSameSide = true
|
|
local sName = EgtGetName( vRibs[i])
|
|
AssignUserLinkInfo( tabUserLink, bCCW, bLoopRib, bSameSide, sName)
|
|
|
|
-- correggo orientamento del link
|
|
bCCW = FindRibsUserLinkDirection( tabUserLink[1].nId, tabUserLink[2].nId)
|
|
for i = 1, #tabUserLink do
|
|
local nId = tabUserLink[i].nId
|
|
EgtSetInfo( nId, KEY_RIBS_USER_LINK_CCW, bCCW)
|
|
end
|
|
|
|
else
|
|
-- se non è UserLink lo rimuovo dalla tabella dei tratti utilizzati per controllarlo nelle iterazioni successive
|
|
vUsed[vRibs[i]] = nil
|
|
end
|
|
end
|
|
end
|
|
|
|
EgtErase( nGrpTmp)
|
|
end
|
|
|
|
-------------------------------------------------------------------
|
|
local function FindAssociatedHoledRib( vRibs, nCrv)
|
|
-- trovo setto di vRibs che poggia su nCrv
|
|
if not nCrv then return end
|
|
if not vRibs or #vRibs == 0 then return end
|
|
|
|
for i = 1, #vRibs do
|
|
-- verifico se ha un estremo sulla curva
|
|
local ptS = EgtSP( vRibs[i], GDB_ID.ROOT)
|
|
local dParS = EgtCurveParamAtPoint( nCrv, ptS, 100 * GEO.EPS_SMALL, GDB_RT.GLOB)
|
|
if dParS then
|
|
return i, true
|
|
else
|
|
local ptE = EgtEP( vRibs[i], GDB_ID.ROOT)
|
|
local dParE = EgtCurveParamAtPoint( nCrv, ptE, 100 * GEO.EPS_SMALL, GDB_RT.GLOB)
|
|
if dParE then
|
|
return i, false
|
|
end
|
|
end
|
|
end
|
|
return
|
|
end
|
|
|
|
-------------------------------------------------------------------
|
|
local function FindHoleCurve( pt, vLoopIds)
|
|
-- trovo indice della curva di vLoopIds a cui appartiene pt ( in globale)
|
|
if not vLoopIds or #vLoopIds == 0 then return end
|
|
for i = 1, #vLoopIds do
|
|
local dPar = EgtCurveParamAtPoint( vLoopIds[i], pt, 100 * GEO.EPS_SMALL, GDB_RT.GLOB)
|
|
if dPar then
|
|
return i
|
|
end
|
|
end
|
|
return
|
|
end
|
|
|
|
-------------------------------------------------------------------
|
|
local function ReorderHoledRibs( vRibs, tHoles, bInvertOrder)
|
|
|
|
local vUserLink = {} -- vettore con gli id dei tratti di UserLink
|
|
local tUserLink = {} -- chiave = setto, valore = true/false se userlink oppure no
|
|
for i = 1, #vRibs do
|
|
local bUserLink = EgtGetInfo( vRibs[i], KEY_RIBS_USER_LINK, 'b') or false
|
|
tUserLink[vRibs[i]] = bUserLink
|
|
if bUserLink then
|
|
table.insert( vUserLink, vRibs[i])
|
|
end
|
|
end
|
|
|
|
local nRelocatePosFirst = EgtIf( bInvertOrder, GDB_IN.AFTER, GDB_IN.BEFORE)
|
|
local nRelocatePos = EgtIf( bInvertOrder, GDB_IN.BEFORE, GDB_IN.AFTER)
|
|
|
|
local nIdx = 1
|
|
while nIdx <= #vUserLink do
|
|
|
|
local nTot = EgtGetInfo( vUserLink[nIdx], KEY_RIBS_USER_LINK_TOT, 'i')
|
|
local nFirst = vUserLink[nIdx]
|
|
local nLast = vUserLink[nIdx + nTot - 1]
|
|
if bInvertOrder then
|
|
-- i tratti di UserLink saranno ordinati in senso opposto
|
|
nFirst, nLast = nLast, nFirst
|
|
end
|
|
|
|
-- primo tratto di UserLink
|
|
local vAssRibs = tHoles[nFirst] or {}
|
|
for j = #vAssRibs, 1, -1 do
|
|
if not tUserLink[vAssRibs[j]] then
|
|
EgtRelocateGlob( vAssRibs[j], nFirst, nRelocatePosFirst)
|
|
end
|
|
end
|
|
|
|
-- altri tratti di UserLink
|
|
for k = 1, nTot - 1 do
|
|
local nCurrIdx = EgtIf( bInvertOrder, nIdx + nTot - 1 - k, nIdx + k)
|
|
local vAssRibs = tHoles[vUserLink[nCurrIdx]] or {}
|
|
for j = #vAssRibs, 1, -1 do
|
|
if not tUserLink[vAssRibs[j]] then
|
|
EgtRelocateGlob( vAssRibs[j], nLast, nRelocatePos)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- passo al gruppo di UserLink successivo
|
|
nIdx = nIdx + nTot
|
|
end
|
|
|
|
end
|
|
|
|
-------------------------------------------------------------------
|
|
local function AdjustHoledRibs( nTrimmedRibsGrp, nSrfInt, nSrfExt)
|
|
|
|
local vRibs = EgtGetAllInGroup( nTrimmedRibsGrp)
|
|
if not vRibs then return end
|
|
|
|
-- recupero i loop della superficie del setto
|
|
local nLoopGrp = EgtGetFirstNameInGroup( s_nPartId, RIBS_LOOP_GRP)
|
|
-- estraggo eventuali loop interni dalle superfici di trim
|
|
local vLoopInt = {}
|
|
local vLoopExt = {}
|
|
local vSurfs = { nSrfInt, nSrfExt}
|
|
for i = 1, 2 do
|
|
if vSurfs[i] then
|
|
local nChunk = EgtSurfFrChunkCount( vSurfs[i])
|
|
for nC = 0, nChunk - 1 do
|
|
local nRes, nCnt = EgtExtractSurfFrChunkLoops( vSurfs[i], nC, nTrimmedRibsGrp)
|
|
if nCnt > 1 then
|
|
EgtTableAdd( EgtIf( i == 1, vLoopInt, vLoopExt), nRes + 1, nCnt - 1)
|
|
end
|
|
EgtErase( nRes)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- individuo catena di setti che è stata interrotta dagli holes partendo dai setti con user link
|
|
local bHoles = false
|
|
local tHoles = {}
|
|
while #vRibs > 0 do
|
|
-- cerco il primo setto di tipo UserLink
|
|
local nRefRib
|
|
for i = 1, #vRibs do
|
|
local bUserLink = EgtGetInfo( vRibs[i], KEY_RIBS_USER_LINK, 'b') or false
|
|
if bUserLink then
|
|
nRefRib = vRibs[i]
|
|
table.remove( vRibs, i)
|
|
break
|
|
end
|
|
end
|
|
if not nRefRib then break end
|
|
local sName = EgtGetName( nRefRib)
|
|
|
|
-- recupero eventuali loop interessati dal setto
|
|
local nOrigSrfId = EgtGetInfo( nRefRib, KEY_ORIGINAL_SURF, 'i')
|
|
local nType = EgtGetInfo( nRefRib, KEY_RIBS_TYPE, 'i')
|
|
local vLoopIds = EgtGetNameInGroup( nLoopGrp, SURF_LOOP .. tostring( nOrigSrfId))
|
|
if nType == RIB_TYPE.INTERNAL then
|
|
EgtJoinTables( vLoopIds, vLoopInt)
|
|
elseif nType == RIB_TYPE.EXTERNAL then
|
|
EgtJoinTables( vLoopIds, vLoopExt)
|
|
end
|
|
|
|
-- verifico se è limitato da un hole
|
|
local ptS = EgtSP( nRefRib, GDB_ID.ROOT)
|
|
local ptE = EgtEP( nRefRib, GDB_ID.ROOT)
|
|
local nIdx = FindHoleCurve( ptS, vLoopIds)
|
|
local bStartOrig = true
|
|
if not nIdx then
|
|
nIdx = FindHoleCurve( ptE, vLoopIds)
|
|
bStartOrig = false
|
|
end
|
|
if nIdx then
|
|
tHoles[nRefRib] = {}
|
|
-- trovo tutti i setti associati
|
|
local nAssIdx, bStart = FindAssociatedHoledRib( vRibs, vLoopIds[nIdx])
|
|
while nAssIdx do
|
|
bHoles = true
|
|
local nCurrRib = vRibs[nAssIdx]
|
|
local ptRef = EgtIf( bStart, EgtEP( nCurrRib, GDB_ID.ROOT), EgtSP( nCurrRib, GDB_ID.ROOT))
|
|
|
|
local bUserLink = EgtGetInfo( nCurrRib, KEY_RIBS_USER_LINK, 'b') or false
|
|
if not bUserLink then
|
|
-- se non è coinvolto in altro user link assegno lo stesso orientamento e lo stesso nome
|
|
if bStartOrig == bStart then
|
|
EgtInvertCurve( nCurrRib)
|
|
UpdateInvertInfo( nCurrRib)
|
|
end
|
|
EgtSetName( nCurrRib, sName)
|
|
end
|
|
|
|
table.insert( tHoles[nRefRib], nCurrRib)
|
|
table.remove( vRibs, nAssIdx)
|
|
|
|
-- verifico se con l'altro estermo poggia su hole e trovo setto associato
|
|
local nIdx = FindHoleCurve( ptRef, vLoopIds)
|
|
nAssIdx, bStart = FindAssociatedHoledRib( vRibs, vLoopIds[nIdx])
|
|
end
|
|
end
|
|
end
|
|
|
|
-- se no holes esco
|
|
if not bHoles then return end
|
|
|
|
-- riordino
|
|
vRibs = EgtGetAllInGroup( nTrimmedRibsGrp)
|
|
local bInvertOrder = EgtGetInfo( vRibs[1], KEY_RIBS_INVERT_STRAND_ORDER, 'b') or false
|
|
ReorderHoledRibs( vRibs, tHoles, bInvertOrder)
|
|
|
|
-- gestione per eventuale InvertDirection
|
|
local bInvertDir = EgtGetInfo( vRibs[1], KEY_RIBS_INVERT_DIR, 'b') or false
|
|
if bInvertDir then
|
|
|
|
for nRib1, vAssRibs in pairs( tHoles) do
|
|
local nRib2 = vAssRibs[#vAssRibs]
|
|
if nRib2 then
|
|
|
|
-- se entrambi coinvolti in UserLink scambio le direzioni
|
|
local bUserLink1 = EgtGetInfo( nRib1, KEY_RIBS_USER_LINK, 'b') or false
|
|
local bUserLink2 = EgtGetInfo( nRib2, KEY_RIBS_USER_LINK, 'b') or false
|
|
if bUserLink1 and bUserLink2 then
|
|
local bInvert1 = EgtGetInfo( nRib1, KEY_INVERTED_CRV, 'b') or false
|
|
local bInvert2 = EgtGetInfo( nRib2, KEY_INVERTED_CRV, 'b') or false
|
|
if bInvert1 ~= bInvert2 then
|
|
EgtInvertCurve( nRib1)
|
|
UpdateInvertInfo( nRib1)
|
|
EgtInvertCurve( nRib2)
|
|
UpdateInvertInfo( nRib2)
|
|
end
|
|
end
|
|
|
|
-- scambio le info
|
|
SwapInfo( nRib1, nRib2, KEY_RIBS_USER_LINK, 'b', false)
|
|
SwapInfo( nRib1, nRib2, KEY_RIBS_USER_LINK_ORDER, 'i', 0)
|
|
SwapInfo( nRib1, nRib2, KEY_RIBS_USER_LINK_TOT, 'i', 0)
|
|
SwapInfo( nRib1, nRib2, KEY_RIBS_USER_LINK_CCW, 'b', false)
|
|
|
|
-- scambio la posizione
|
|
local nCopy = EgtCopyGlob( nRib2, nRib2, GDB_IN.AFTER)
|
|
EgtRelocateGlob( nRib2, nRib1, GDB_IN.AFTER)
|
|
EgtRelocateGlob( nRib1, nCopy, GDB_IN.AFTER)
|
|
EgtErase( nCopy)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- elimino loop dello slice utilizzati
|
|
for i = 1, #vLoopInt do
|
|
EgtErase( vLoopInt[i])
|
|
end
|
|
for i = 1, #vLoopExt do
|
|
EgtErase( vLoopExt[i])
|
|
end
|
|
|
|
end
|
|
|
|
-------------------------------------------------------------------
|
|
local function TrimRibs( vRibs, nRibsGrp, nSrfTrimInt, nSrfTrimExt)
|
|
|
|
-- trim dei setti
|
|
local nTrimmedRibsGrp = EgtGroup( nRibsGrp)
|
|
local tUserLink = {} -- tratti appartenenti a UserLink
|
|
local vSingleRibs = {} -- tratti singoli
|
|
for i = 1, #vRibs do
|
|
-- trim dei setti
|
|
local nType = EgtGetInfo( vRibs[i], KEY_RIBS_TYPE, 'i')
|
|
local nCopyRib = EgtCopyGlob( vRibs[i], nTrimmedRibsGrp)
|
|
|
|
local nCrv, nCnt
|
|
-- setto interno
|
|
if nType == RIB_TYPE.INTERNAL or nType == RIB_TYPE.SUPPORT then
|
|
if nSrfTrimInt == GDB_ID.NULL then
|
|
-- se la superficie non esiste, il setto deve essere cancellato perchè non c'è spazio
|
|
nCrv = nCopyRib
|
|
nCnt = 0
|
|
elseif nSrfTrimInt then
|
|
nCrv, nCnt = EgtTrimCurveWithRegion( nCopyRib, nSrfTrimInt, true, true)
|
|
end
|
|
-- setto esterno
|
|
elseif nType == RIB_TYPE.EXTERNAL then
|
|
if nSrfTrimExt ~= GDB_ID.NULL then
|
|
nCrv, nCnt = EgtTrimCurveWithRegion( nCopyRib, nSrfTrimExt, false, true)
|
|
end
|
|
end
|
|
|
|
-- se nCrv non definito ( per errore nel trim o perchè il setto va conservato) riprendo il setto originario
|
|
if not nCrv then
|
|
nCrv = nCopyRib
|
|
nCnt = 1
|
|
end
|
|
|
|
if nCnt == 0 then
|
|
-- il setto va eliminato
|
|
EgtErase( nCrv)
|
|
elseif nCnt == 1 then
|
|
-- tratto singolo
|
|
EgtSetInfo( nCrv, KEY_START_RIB, vRibs[i])
|
|
table.insert( vSingleRibs, nCrv)
|
|
EgtSetInfo( vRibs[i], KEY_ASSOCIATED_CRVS, {nCrv})
|
|
else
|
|
-- UserLink
|
|
tUserLink[vRibs[i]] = {}
|
|
local bCCW = FindRibsUserLinkDirection( nCrv, nCrv + 1)
|
|
-- sistemo le info
|
|
for j = 0, nCnt - 1 do
|
|
EgtSetInfo( nCrv + j, KEY_START_RIB, vRibs[i])
|
|
EgtSetInfo( nCrv + j, KEY_RIBS_USER_LINK, 1)
|
|
EgtSetInfo( nCrv + j, KEY_RIBS_USER_LINK_ORDER, j)
|
|
EgtSetInfo( nCrv + j, KEY_RIBS_USER_LINK_TOT, nCnt)
|
|
EgtSetInfo( nCrv + j, KEY_RIBS_USER_LINK_CCW, bCCW)
|
|
-- se setto di partenza è chiuso è LoopRib
|
|
if EgtCurveIsClosed( vRibs[i]) then EgtSetInfo( nCrv + j, KEY_LOOP_RIB, 1) end
|
|
-- se ho solo due tratti allora il link è realizzato da un solo lato
|
|
if nCnt == 2 then EgtSetInfo( nCrv + j, KEY_RIBS_USER_LINK_SAME_SIDE, 1) end
|
|
table.insert( tUserLink[vRibs[i]], nCrv + j)
|
|
end
|
|
EgtSetInfo( vRibs[i], KEY_ASSOCIATED_CRVS, tUserLink[vRibs[i]])
|
|
end
|
|
end
|
|
|
|
-- verifico e sistemo UserLink
|
|
AdjustUserLinkRibs( tUserLink, vSingleRibs, nSrfTrimInt, nSrfTrimExt, nRibsGrp)
|
|
|
|
-- verifico se necessari aggiustamenti per holes
|
|
AdjustHoledRibs( nTrimmedRibsGrp, nSrfTrimInt, nSrfTrimExt)
|
|
|
|
return nTrimmedRibsGrp
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function ComputeRibsOrientedOffset( nRibsGrp)
|
|
|
|
local nOffsGrp = EgtGroup( EgtGetParent( nRibsGrp))
|
|
|
|
local nCurrRib = EgtGetFirstNameInGroup( nRibsGrp, RIBS_CRV .. '*')
|
|
while nCurrRib do
|
|
|
|
-- recupero tutti i tratti appartenenti a quel setto (hanno lo stesso nome)
|
|
local sName = EgtGetName( nCurrRib)
|
|
local vIds = EgtGetNameInGroup( nRibsGrp, sName)
|
|
|
|
-- recupero i parametri del setto
|
|
local bInvert = EgtGetInfo( nCurrRib, KEY_RIBS_INVERT_DIR, 'b') or false
|
|
local bInvertOrder = EgtGetInfo( nCurrRib, KEY_RIBS_INVERT_STRAND_ORDER, 'b') or false
|
|
local nShellsNbr = EgtGetInfo( nCurrRib, KEY_RIBS_SHELLS_NBR, 'i')
|
|
|
|
-- offset di ogni tratto del setto
|
|
local vOffs = {}
|
|
local bPlusToMinus = false
|
|
for i = 1, #vIds do
|
|
|
|
local bUserLinked = EgtGetInfo( vIds[i], KEY_RIBS_USER_LINK, 'b') or false
|
|
local bCCW = EgtGetInfo( vIds[i], KEY_RIBS_USER_LINK_CCW, 'b') or false
|
|
local nLinkOrder = EgtGetInfo( vIds[i], KEY_RIBS_USER_LINK_ORDER, 'i') or 0
|
|
local dStrand = EgtGetInfo( vIds[i], KEY_RIBS_STRAND, 'd')
|
|
local dStrandOverlap = EgtGetInfo( vIds[i], KEY_RIBS_STRAND_OVERLAP, 'd') or 0
|
|
local dOffs = ( nShellsNbr - 1) * ( 1 - dStrandOverlap / 100) * dStrand / 2
|
|
|
|
-- ordine di realizzazione degli offset
|
|
if not bUserLinked then
|
|
bPlusToMinus = false
|
|
else
|
|
if nLinkOrder == 0 then
|
|
-- determinato dal verso del collegamento
|
|
bPlusToMinus = EgtIf( bCCW, true, false)
|
|
else
|
|
bPlusToMinus = not bPlusToMinus
|
|
end
|
|
end
|
|
|
|
local vOffsRib = {}
|
|
for k = 0, nShellsNbr - 1 do
|
|
local dOffsCurr = dOffs - k * ( 1 - dStrandOverlap / 100) * dStrand
|
|
local nNewId
|
|
if abs( dOffsCurr) < GEO.EPS_SMALL then
|
|
nNewId = EgtCopyGlob( vIds[i], nOffsGrp)
|
|
else
|
|
nNewId = EgtOffsetCurveAdv( vIds[i], EgtIf( bPlusToMinus, dOffsCurr, - dOffsCurr), GDB_OT.FILLET, s_dOffsTol)
|
|
end
|
|
|
|
if nNewId then
|
|
EgtSetName( nNewId, sName)
|
|
EgtSetInfo( nNewId, KEY_TYPE, TYPE.RIB)
|
|
EgtSetInfo( nNewId, KEY_ORIGINAL_RIB, vIds[i])
|
|
EgtRelocateGlob( nNewId, nOffsGrp)
|
|
table.insert( vOffs, nNewId)
|
|
table.insert( vOffsRib, nNewId)
|
|
end
|
|
end
|
|
|
|
EgtSetInfo( vIds[i], KEY_ASSOCIATED_CRVS, vOffsRib)
|
|
end
|
|
|
|
-- ordinamento
|
|
if bInvertOrder then
|
|
for i = 1, #vOffs - 1 do
|
|
EgtRelocateGlob( vOffs[i], vOffs[#vOffs], GDB_IN.AFTER)
|
|
end
|
|
-- aggiorno il vettore con gli indici per rispettare nuovo ordinamento
|
|
vOffs = EgtGetNameInGroup( nOffsGrp, sName)
|
|
end
|
|
|
|
-- orientamento
|
|
local bInvertCrv = bInvert
|
|
for j = 1, #vOffs, nShellsNbr do
|
|
|
|
-- stabilisco orientamento del primo tratto del gruppo
|
|
local bUserLinked = EgtGetInfo( vOffs[j], KEY_RIBS_USER_LINK, 'b') or false
|
|
local nLinkOrder = EgtGetInfo( vOffs[j], KEY_RIBS_USER_LINK_ORDER, 'i') or 0
|
|
local nLinkTot = EgtGetInfo( vOffs[j], KEY_RIBS_USER_LINK_TOT, 'i') or 0
|
|
if not bUserLinked then
|
|
bInvertCrv = bInvert
|
|
else
|
|
if ( not bInvertOrder and nLinkOrder == 0) or ( bInvertOrder and nLinkOrder == nLinkTot - 1) then
|
|
bInvertCrv = bInvert
|
|
if ( nShellsNbr % 2 == 0 and ( not bInvertOrder or nLinkTot % 2 ~= 0)) or ( nShellsNbr % 2 ~= 0 and bInvertOrder) then
|
|
bInvertCrv = not bInvert
|
|
end
|
|
else
|
|
if nShellsNbr % 2 == 0 then
|
|
bInvertCrv = not bInvertCrv
|
|
end
|
|
end
|
|
end
|
|
|
|
-- inversione
|
|
for k = 0, nShellsNbr - 1 do
|
|
if ( bInvertCrv and k % 2 == 0) or ( not bInvertCrv and k % 2 ~= 0) then
|
|
EgtInvertCurve( vOffs[j + k])
|
|
UpdateInvertInfo( vOffs[j + k])
|
|
end
|
|
end
|
|
end
|
|
|
|
-- passo al setto successivo
|
|
nCurrRib = EgtGetNextName( vIds[#vIds], RIBS_CRV .. '*')
|
|
end
|
|
|
|
return nOffsGrp
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function FindRibWithSameTrimSurf( tOffs, dOffs, nType)
|
|
|
|
for nId, dCurrOffs in pairs( tOffs) do
|
|
local nCurrType = EgtGetInfo( nId, KEY_RIBS_TYPE, 'i')
|
|
if nCurrType == nType and abs( dOffs - dCurrOffs) < GEO.EPS_SMALL then
|
|
return nId
|
|
end
|
|
end
|
|
return
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function ComputeTrimSurfWithOverlapsForRibs( vIds, nGrp, nSrfInt, nSrfExt, nLoopGrp)
|
|
-- ad ogni setto ottenuto dallo slicing associo la superficie con cui fare trim : nSurfId se setto da trimmare, nil se setto da cancellare, GDB_ID.NULL se setto da non trimmare
|
|
|
|
local tOffs = {}
|
|
local tSurfOffs = {}
|
|
for i = 1, #vIds do
|
|
local dStrand = EgtGetInfo( vIds[i], KEY_RIBS_STRAND, 'd')
|
|
local dOverlap = EgtGetInfo( vIds[i], KEY_RIBS_OVERLAP, 'd')
|
|
local nType = EgtGetInfo( vIds[i], KEY_RIBS_TYPE, 'i')
|
|
local dOffs = dStrand * ( 0.5 - dOverlap / 100)
|
|
|
|
-- verifico se la superficie è già stata calcolata
|
|
local nRefId = FindRibWithSameTrimSurf( tOffs, dOffs, nType)
|
|
if nRefId then
|
|
tSurfOffs[vIds[i]] = tSurfOffs[nRefId]
|
|
else
|
|
|
|
if nType == RIB_TYPE.INTERNAL or nType == RIB_TYPE.SUPPORT then
|
|
if nSrfInt == GDB_ID.NULL then
|
|
-- se la superficie non esiste non c'è spazio per il setto che va cancellato
|
|
EgtOutLog( 'Warning : rib not possibile (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
else
|
|
local nTrimSurf, bNoOverlap = ComputeTrimSurf( nSrfInt, nGrp, dStrand, dOverlap)
|
|
if not nTrimSurf then
|
|
EgtOutLog( 'Error : creation of trim region for internal rib failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : creation of trim region for rib failed')
|
|
elseif nTrimSurf == GDB_ID.NULL then
|
|
EgtOutLog( 'Warning : rib not possibile (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
else
|
|
if bNoOverlap then
|
|
EgtOutLog( 'Warning : internal rib without correct overlap (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
end
|
|
EgtSetName( nTrimSurf, TOT_SHELL_TRIM_SURF)
|
|
tSurfOffs[vIds[i]] = nTrimSurf
|
|
end
|
|
end
|
|
|
|
elseif nType == RIB_TYPE.EXTERNAL then
|
|
if not nSrfExt then
|
|
-- il setto va cancellato
|
|
elseif nSrfExt == GDB_ID.NULL then
|
|
-- se la superficie non esiste il setto va conservato
|
|
tSurfOffs[vIds[i]] = GDB_ID.NULL
|
|
else
|
|
local nTrimSurf, bNoOverlap = ComputeTrimSurf( nSrfExt, nGrp, - dStrand, dOverlap)
|
|
if not nTrimSurf then
|
|
EgtOutLog( 'Error : creation of trim region for external rib failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : creation of trim region for external rib failed')
|
|
else
|
|
if bNoOverlap then
|
|
EgtOutLog( 'Warning : external rib without correct overlap (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
end
|
|
EgtSetName( nTrimSurf, TOT_SHELL_TRIM_SURF)
|
|
tSurfOffs[vIds[i]] = nTrimSurf
|
|
end
|
|
end
|
|
|
|
else
|
|
-- se unbounded non va mai trimmato
|
|
tSurfOffs[vIds[i]] = GDB_ID.NULL
|
|
end
|
|
|
|
tOffs[vIds[i]] = dOffs
|
|
end
|
|
end
|
|
|
|
-- estraggo i contorni
|
|
local vSurfIds = EgtGetNameInGroup( nGrp, TOT_SHELL_TRIM_SURF) or {}
|
|
for i = 1, #vSurfIds do
|
|
local nChunksNbr = EgtSurfFrChunkCount( vSurfIds[i])
|
|
for j = 0, nChunksNbr - 1 do
|
|
local nRes, nCnt = EgtExtractSurfFrChunkLoops( vSurfIds[i], j, nLoopGrp)
|
|
for k = nRes, nRes + nCnt - 1 do
|
|
EgtSetName( k, TRIM_SURF_LOOP)
|
|
end
|
|
end
|
|
end
|
|
|
|
return tSurfOffs
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function VerifyRibsIntersectionValidity( nIntersId, nSrfInt, nSrfExt, nType1, nType2)
|
|
|
|
if nType1 == RIB_TYPE.UNBOUNDED and nType2 == RIB_TYPE.UNBOUNDED then
|
|
-- l'intersezione è sempre valida
|
|
return true
|
|
elseif nType1 == RIB_TYPE.EXTERNAL or nType2 == RIB_TYPE.EXTERNAL then
|
|
if not nSrfExt or nSrfExt == GDB_ID.NULL then
|
|
-- se la surf non esiste l'intersezione è sicuramente esterna
|
|
return true
|
|
else
|
|
-- l'intersezione deve essere esterna
|
|
return EgtSurfFrTestExternal( nSrfExt, nIntersId)
|
|
end
|
|
else
|
|
if nSrfInt == GDB_ID.NULL then
|
|
-- se la superficie non esiste, l'intersezione è sicuramente esterna
|
|
return false
|
|
else
|
|
-- l'intersezione deve essere interna
|
|
return not EgtSurfFrTestExternal( nSrfInt, nIntersId)
|
|
end
|
|
end
|
|
|
|
return false
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function VerifyRibsIntersection( nRib1, nRib2, nType1, nType2, nSrfInt, nSrfExt, nGrp, nOffsGrp)
|
|
-- restituisce se intersezione ( bInters) e se taglio va forzato sulla curva1 ( bForceCrv1Cut)
|
|
|
|
-- setti interni/supporto ed esterni non si possono intersecare per definizione
|
|
if ( ( nType1 == RIB_TYPE.INTERNAL or nType1 == RIB_TYPE.SUPPORT) and nType2 == RIB_TYPE.EXTERNAL) or
|
|
( nType1 == RIB_TYPE.EXTERNAL and ( nType2 == RIB_TYPE.INTERNAL or nType2 == RIB_TYPE.SUPPORT)) then
|
|
return false, false
|
|
end
|
|
-- se hanno lo stesso nome derivano dalla stessa costolatura quindi non ha senso controllare intersezione
|
|
-- ( non vengono gestiti setti che si autointersecano)
|
|
if EgtGetName( nRib1) == EgtGetName( nRib2) then
|
|
return false, false
|
|
end
|
|
|
|
-- porto le curve nel gruppo locale
|
|
local nCrv1 = EgtCopyGlob( nRib1, nGrp)
|
|
local nCrv2 = EgtCopyGlob( nRib2, nGrp)
|
|
|
|
-- verifico se si intersecano nel piano XY definito dal gruppo locale in modo valido
|
|
local bForceCrv1Cut = false
|
|
local nOrigInt, nPntCnt, nCrvCnt = EgtCurveCurveInters( nCrv1, nCrv2, nGrp)
|
|
if nOrigInt then
|
|
local bInters = false
|
|
-- scorro tutti i punti di intersezione trovati
|
|
for nPtId = nOrigInt, nOrigInt + nPntCnt - 1 do
|
|
|
|
-- verifico se forza il taglio sulla curva 1 ( indipendentemente dalla validità)
|
|
if not bForceCrv1Cut then
|
|
local ptInt = EgtSP( nPtId, GDB_ID.ROOT)
|
|
local dPar1 = EgtCurveParamAtPoint( nCrv1, ptInt, GEO.EPS_SMALL, GDB_RT.GLOB)
|
|
local dPar2 = EgtCurveParamAtPoint( nCrv2, ptInt, GEO.EPS_SMALL, GDB_RT.GLOB)
|
|
local _, dParE1 = EgtCurveDomain( nCrv1)
|
|
local _, dParE2 = EgtCurveDomain( nCrv2)
|
|
|
|
local bCrv1OnExtr = ( dPar1 < 10 * GEO.EPS_SMALL or abs( dPar1 - dParE1) < 10 * GEO.EPS_SMALL)
|
|
local bCrv2OnExtr = ( dPar2 < 10 * GEO.EPS_SMALL or abs( dPar2 - dParE2) < 10 * GEO.EPS_SMALL)
|
|
bForceCrv1Cut = bCrv1OnExtr and not bCrv2OnExtr
|
|
end
|
|
|
|
if VerifyRibsIntersectionValidity( nPtId, nSrfInt, nSrfExt, nType1, nType2) then
|
|
bInters = true
|
|
if bForceCrv1Cut then
|
|
return true, true -- intersezione, forza taglio sulla crv1
|
|
end
|
|
end
|
|
end
|
|
|
|
if bInters then
|
|
return true, false -- intersezione, non forza taglio su crv1
|
|
end
|
|
end
|
|
|
|
-- se le curve non si intersecano in modo valido, verifico se lo fanno i loro offset
|
|
local vOffs1 = EgtGetNameInGroup( nOffsGrp, EgtGetName( nCrv1)) or {}
|
|
local vOffs2 = EgtGetNameInGroup( nOffsGrp, EgtGetName( nCrv2)) or {}
|
|
local nOffs1Inters = 0 -- numero di offset di nCrv1 coinvolti nelle intersezioni
|
|
for i = 1, #vOffs1 do
|
|
local nOffs1 = EgtCopyGlob( vOffs1[i], nGrp)
|
|
local bInters = false
|
|
for j = 1, #vOffs2 do
|
|
if bInters then break end -- se già trovato intersezione non ho bisogno di analizzare gli altri offset
|
|
local nOffs2 = EgtCopyGlob( vOffs2[j], nGrp)
|
|
local nId, nPntCnt, nCrvCnt = EgtCurveCurveInters( nOffs1, nOffs2, nGrp)
|
|
if nId then
|
|
for nPtId = nId, nId + nPntCnt - 1 do
|
|
if VerifyRibsIntersectionValidity( nPtId, nSrfInt, nSrfExt, nType1, nType2) then
|
|
-- intersezione valida
|
|
bInters = true
|
|
nOffs1Inters = nOffs1Inters + 1
|
|
break
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if nOffs1Inters > 0 then
|
|
if nOrigInt then
|
|
-- se i setti originiari si intersecavano il forzare il taglio sulla curva1 dipende dalla loro intersezione anche se non valida
|
|
return true, bForceCrv1Cut
|
|
else
|
|
return true, nOffs1Inters == #vOffs1
|
|
end
|
|
end
|
|
|
|
-- se le curve di offset non si intersecano verifico se lo fanno le loro SurfFatCurve
|
|
local dStrand1 = EgtGetInfo( nCrv1, KEY_RIBS_STRAND, 'd')
|
|
local dStrand2 = EgtGetInfo( nCrv2, KEY_RIBS_STRAND, 'd')
|
|
local dOverlap2 = EgtGetInfo( nCrv2, KEY_RIBS_OVERLAP, 'd')
|
|
for i = 1, #vOffs1 do
|
|
for j = 1, #vOffs2 do
|
|
local nSrfOffs = EgtSurfFrFatCurve( nGrp, vOffs1[i], 0.5 * dStrand1 + dStrand2 * ( 0.5 - dOverlap2 / 100), false, false, s_dOffsTol)
|
|
if nSrfOffs then
|
|
local nRes = EgtCurveWithRegionClassify( vOffs2[j], nSrfOffs)
|
|
if nRes ~= GDB_CRC.OUT then
|
|
return true, false
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
return false, false
|
|
end
|
|
|
|
---------------------------------------------------------------------------------
|
|
-- Funzione che sistema le intersezioni fra costolature nel caso generico
|
|
local function AdjustRibsOffsetForIntersection( nCrv1, nCrv2, nOffsGrp, nLoopGrp, nSrfTrim, nType2)
|
|
|
|
-- recupero gli offset della curva secondaria ( nCrv2)
|
|
local vOffs2 = EgtGetNameInGroup( nOffsGrp, EgtGetName( nCrv2)) or {}
|
|
|
|
local nShells = EgtGetInfo( nCrv1, KEY_RIBS_SHELLS_NBR, 'i')
|
|
local dStrand1 = EgtGetInfo( nCrv1, KEY_RIBS_STRAND, 'd')
|
|
local dStrandOverlap1 = EgtGetInfo( nCrv1, KEY_RIBS_STRAND_OVERLAP, 'd') or 0
|
|
local dOverlap = EgtGetInfo( nCrv2, KEY_RIBS_OVERLAP, 'i')
|
|
local dStrand2 = EgtGetInfo( nCrv2, KEY_RIBS_STRAND, 'd')
|
|
|
|
if dOverlap / 100 * dStrand2 > ( nShells - 1) * ( 1 - dStrandOverlap1 / 100) * dStrand1 * 0.5 + dStrand1 * 0.5 - GEO.EPS_SMALL then
|
|
-- non ha senso spezzare la curva, aggiorno solo split order dei suoi offset
|
|
for i = 1, #vOffs2 do
|
|
CopyInfo( nCrv2, vOffs2[i], KEY_SPLIT_ORDER, 'i')
|
|
end
|
|
return
|
|
end
|
|
|
|
-- calcolo la superficie della curva principale ( nCrv1) da usare per trim
|
|
local dOffs = ( nShells - 1) * ( 1 - dStrandOverlap1 / 100) * dStrand1 * 0.5 + dStrand1 * 0.5 + dStrand2 * ( 0.5 - dOverlap / 100)
|
|
local nSrf = EgtSurfFrFatCurve( nOffsGrp, nCrv1, dOffs, false, false, s_dOffsTol)
|
|
if not nSrf then
|
|
EgtOutLog( 'Error : ribs intersection failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : error in computing ribs intersection')
|
|
return
|
|
end
|
|
for i = 1, #vOffs2 do
|
|
local nId, nCnt = EgtTrimCurveWithRegion( vOffs2[i], nSrf, false, true)
|
|
|
|
-- se setto chiuso verifico se primo e ultimo tratto possono essere uniti
|
|
if EgtCurveIsClosed( nCrv2) then
|
|
if nCnt > 1 and AreSamePointApprox( EgtEP( nId + nCnt - 1), EgtSP( nId)) then
|
|
EgtRelocateGlob( nId + nCnt - 1, nId, GDB_IN.AFTER)
|
|
EgtAddCurveCompoCurve( nId + nCnt - 1, nId)
|
|
EgtChangeId( nId + nCnt - 1, nId)
|
|
nCnt = nCnt - 1
|
|
end
|
|
end
|
|
|
|
-- aggiorno ordine di split copiandolo da nCrv2
|
|
for j = nId, nId + nCnt - 1 do
|
|
CopyInfo( nCrv2, j, KEY_SPLIT_ORDER, 'i')
|
|
end
|
|
end
|
|
|
|
-- salvo i loop da usare nel toolpath per ingressi e uscite
|
|
local nSrfRef
|
|
-- recupero la superficie di bordo con lo stesso overlap
|
|
if nSrfTrim and nSrfTrim ~= GDB_ID.NULL then
|
|
nSrfRef = EgtCopyGlob( nSrfTrim, nLoopGrp)
|
|
if nType2 == RIB_TYPE.INTERNAL or nType2 == RIB_TYPE.SUPPORT then
|
|
EgtSurfFrSubtract( nSrfRef, nSrf)
|
|
elseif nType2 == RIB_TYPE.EXTERNAL then
|
|
EgtSurfFrAdd( nSrfRef, nSrf)
|
|
end
|
|
EgtErase( nSrf)
|
|
else
|
|
EgtInvertSurf( nSrf)
|
|
nSrfRef = nSrf
|
|
end
|
|
-- estraggo i loop
|
|
local nChunks = EgtSurfFrChunkCount( nSrfRef)
|
|
for i = 0, nChunks - 1 do
|
|
local nRes, nCnt = EgtExtractSurfFrChunkLoops( nSrfRef, i, nLoopGrp)
|
|
for j = nRes, nRes + nCnt - 1 do
|
|
EgtSetName( j, SURF_LOOP)
|
|
end
|
|
end
|
|
EgtErase( nSrfRef)
|
|
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
-- Funzione che sistema le intersezioni fra costolature nel caso di 2 passate
|
|
local function AdjustRibsOffsetForIntersection2Shells( nCrv1, nCrv2, nOffsGrp)
|
|
|
|
-- costruisco le superfici da usare per trim
|
|
local dStrand1 = EgtGetInfo( nCrv1, KEY_RIBS_STRAND, 'd')
|
|
local dStrandOverlap1 = EgtGetInfo( nCrv1, KEY_RIBS_STRAND_OVERLAP, 'd') or 0
|
|
local nSrf1 = EgtSurfFrFatCurve( nOffsGrp, nCrv1, ( 1 - dStrandOverlap1 / 100) * dStrand1 * 0.5, false, false, s_dOffsTol)
|
|
local dStrand2 = EgtGetInfo( nCrv2, KEY_RIBS_STRAND, 'd')
|
|
local dStrandOverlap2 = EgtGetInfo( nCrv2, KEY_RIBS_STRAND_OVERLAP, 'd') or 0
|
|
local nSrf2 = EgtSurfFrFatCurve( nOffsGrp, nCrv2, ( 1 - dStrandOverlap2 / 100) * dStrand2 * 0.5, false, false, s_dOffsTol)
|
|
|
|
-- trim degli offset di nCrv1
|
|
local vOffs1 = EgtGetNameInGroup( nOffsGrp, EgtGetName( nCrv1)) or {}
|
|
for i = 1, #vOffs1 do
|
|
local nId, nCnt = EgtTrimCurveWithRegion( vOffs1[i], nSrf2, false, true)
|
|
end
|
|
|
|
-- trim degli offset di nCrv2
|
|
local vOffs2 = EgtGetNameInGroup( nOffsGrp, EgtGetName( nCrv2)) or {}
|
|
for i = 1, #vOffs2 do
|
|
local nId, nCnt = EgtTrimCurveWithRegion( vOffs2[i], nSrf1, false, true)
|
|
end
|
|
|
|
EgtErase( nSrf1)
|
|
EgtErase( nSrf2)
|
|
|
|
end
|
|
|
|
------------------------------------------------------------------
|
|
local function UpdateSplitOrder( nCrv, tInters, nOffsGrp)
|
|
|
|
local nOrder = EgtGetInfo( nCrv, KEY_SPLIT_ORDER, 'i') or 0
|
|
local nNewOrder = nOrder + 1
|
|
|
|
-- aggiorno tutte le curve che dipendono da nCrv
|
|
if tInters[nCrv] then
|
|
for i = 1, #tInters[nCrv] do
|
|
local nOldOrder = EgtGetInfo( tInters[nCrv][i], KEY_SPLIT_ORDER, 'i')
|
|
if nOldOrder < nNewOrder then
|
|
EgtSetInfo( tInters[nCrv][i], KEY_SPLIT_ORDER, nNewOrder)
|
|
-- aggiorno i suoi offset
|
|
local vOffs = EgtGetNameInGroup( nOffsGrp, EgtGetName( tInters[nCrv][i]))
|
|
for j = 1, #vOffs do
|
|
EgtSetInfo( vOffs[j], KEY_SPLIT_ORDER, nNewOrder)
|
|
end
|
|
-- aggiorno eventuali dipendenze
|
|
UpdateSplitOrder( tInters[nCrv][i], tInters, nOffsGrp)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
------------------------------------------------------------------
|
|
local function HandleRibsIntersections( nRibsGrp, nOffsGrp, nRibsPathGrp, nSrfInt, nSrfExt, bAllTwoStrands, vTypeSequence, nLoopGrp, tSurfOffs)
|
|
|
|
local bSpecialCase = false
|
|
local vAllRibsIds = EgtGetNameInGroup( nRibsGrp, RIBS_CRV .. '*') -- setti originali
|
|
local vRibsIds = {}
|
|
-- ignoro setti che non hanno passate corrispondenti
|
|
for i = 1, #vAllRibsIds do
|
|
local vOffs = EgtGetNameInGroup( nRibsPathGrp, EgtGetName( vAllRibsIds[i]))
|
|
if vOffs and #vOffs > 0 then table.insert( vRibsIds, vAllRibsIds[i]) end
|
|
end
|
|
|
|
-- creo un gruppo con frame locale per calcolare le intersezioni ( è il piano XY locale dove calcolare intersezioni)
|
|
local frLoc = Frame3d( ORIG(), s_vtSlicing)
|
|
local nGrpTmp = EgtGroup( nRibsGrp, frLoc, GDB_RT.GLOB)
|
|
|
|
local bInters = false
|
|
local tInters = {} -- tabella che tiene traccia delle intersezioni trovate
|
|
for i = 1, #vRibsIds do
|
|
local nType1 = EgtGetInfo( vRibsIds[i], KEY_RIBS_TYPE, 'i')
|
|
|
|
-- verifico se interseca uno dei setti successivi
|
|
for j = i + 1, #vRibsIds do
|
|
local nType2 = EgtGetInfo( vRibsIds[j], KEY_RIBS_TYPE, 'i')
|
|
local bRibInters, bForceCrv1Cut = VerifyRibsIntersection( vRibsIds[i], vRibsIds[j], nType1, nType2, nSrfInt, nSrfExt, nGrpTmp, nOffsGrp)
|
|
|
|
if bRibInters then
|
|
bInters = true
|
|
|
|
local nCrv1 = vRibsIds[i] -- curva principale che non viene tagliata
|
|
local nCrv2 = vRibsIds[j] -- curve secondaria da modificare
|
|
local nSplitOrder1 = EgtGetInfo( nCrv1, KEY_SPLIT_ORDER, 'i') or 0
|
|
local nSplitOrder2 = EgtGetInfo( nCrv2, KEY_SPLIT_ORDER, 'i') or 0
|
|
|
|
if bForceCrv1Cut then
|
|
nCrv1, nCrv2 = nCrv2, nCrv1
|
|
nSplitOrder1, nSplitOrder2 = nSplitOrder2, nSplitOrder1
|
|
else
|
|
-- se stessa tipologia taglio il setto già splittato più volte, altrimenti taglio il setto che viene realizzato successivamente
|
|
if ( nType1 == nType2 and nSplitOrder1 > nSplitOrder2) or
|
|
( nType1 ~= nType2 and vTypeSequence[nType1] > vTypeSequence[nType2]) then
|
|
nCrv1, nCrv2 = nCrv2, nCrv1
|
|
nSplitOrder1, nSplitOrder2 = nSplitOrder2, nSplitOrder1
|
|
end
|
|
end
|
|
|
|
-- aggiorno tabella delle intersezioni
|
|
if tInters[nCrv1] then
|
|
table.insert( tInters[nCrv1], nCrv2)
|
|
else
|
|
tInters[nCrv1] = {nCrv2}
|
|
end
|
|
|
|
-- aggiorno ordine di split
|
|
if nSplitOrder2 < nSplitOrder1 + 1 then
|
|
EgtSetInfo( nCrv2, KEY_SPLIT_ORDER, nSplitOrder1 + 1)
|
|
UpdateSplitOrder( nCrv2, tInters, nRibsPathGrp)
|
|
end
|
|
|
|
if bAllTwoStrands and ( nType1 == nType2) then
|
|
-- nel caso di 2 passate e stessa tipologia gestione speciale per creare unico percorso
|
|
AdjustRibsOffsetForIntersection2Shells( nCrv1, nCrv2, nRibsPathGrp)
|
|
bSpecialCase = true
|
|
else
|
|
AdjustRibsOffsetForIntersection( nCrv1, nCrv2, nRibsPathGrp, nLoopGrp, tSurfOffs[nCrv2], nType2)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
EgtErase( nGrpTmp)
|
|
return bInters, bSpecialCase
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function VerifySplitAssociation( nRib1, nRib2, dStrand)
|
|
|
|
local dDist1 = EgtPointCurveDist( EgtMP( nRib1), nRib2)
|
|
local dDist2 = EgtPointCurveDist( EgtMP( nRib2), nRib1)
|
|
-- verifico siano sufficientemente vicini
|
|
if dDist1 < dStrand + 10 * GEO.EPS_SMALL or dDist2 < dStrand + 10 * GEO.EPS_SMALL then
|
|
|
|
-- verifico nel caso di setti splittati dopo il trim che siano compatibili
|
|
local bUserLink = EgtGetInfo( nRib2, KEY_RIBS_USER_LINK, 'b') or false
|
|
local bSplitAfterTrim1 = EgtGetInfo( nRib1, KEY_SPLIT_AFTER_TRIM, 'b') or false
|
|
local bSplitAfterTrim2 = EgtGetInfo( nRib2, KEY_SPLIT_AFTER_TRIM, 'b') or false
|
|
if bSplitAfterTrim1 ~= bSplitAfterTrim2 then
|
|
if not bSplitAfterTrim2 and bSplitAfterTrim1 then
|
|
local nOrd = EgtGetInfo( nRib2, KEY_SPLIT_AFTER_TRIM_ORDER, 'i')
|
|
if nOrd == 0 then
|
|
return true
|
|
end
|
|
end
|
|
if bSplitAfterTrim1 then
|
|
local nOrd = EgtGetInfo( nRib1, KEY_SPLIT_AFTER_TRIM_ORDER, 'i')
|
|
local nTot = EgtGetInfo( nRib1, KEY_SPLIT_AFTER_TRIM_TOT, 'i')
|
|
if nOrd == nTot - 1 then
|
|
return true
|
|
end
|
|
end
|
|
else
|
|
return true
|
|
end
|
|
end
|
|
|
|
return false
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function FindAssociatedSplitRibs( vRibs, dStrand)
|
|
|
|
local vAssociatedRibs = {}
|
|
|
|
-- vettore di flag per indicare se corrispondente elemento di vRibs è già stato associato ad un gruppo
|
|
local vUsed = {}
|
|
for i = 1, #vRibs do
|
|
vUsed[i] = false
|
|
end
|
|
|
|
local nCurrId = vRibs[1]
|
|
vUsed[1] = true
|
|
while nCurrId do
|
|
-- definisco un nuovo gruppo di setti associati
|
|
local vCurrGrp = { nCurrId}
|
|
local bFound = true
|
|
while bFound do
|
|
-- appena aggiungo un nuovo elemento al gruppo riparto a controllare tutti i setti non ancora associati per vedere quale posso aggiungere
|
|
bFound = false
|
|
for i = 2, #vRibs do
|
|
if bFound then break end
|
|
if not vUsed[i] then
|
|
for j = 1, #vCurrGrp do
|
|
if VerifySplitAssociation( vCurrGrp[j], vRibs[i], dStrand) then
|
|
bFound = true
|
|
table.insert( vCurrGrp, vRibs[i])
|
|
vUsed[i] = true
|
|
break
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
-- quando non ho più setti da aggiungere al gruppo corrente
|
|
-- riordino il gruppo appena individuato
|
|
if #vCurrGrp == 2 then
|
|
-- lascio l'ordinamento 1,2
|
|
EgtRelocateGlob( vCurrGrp[2], vCurrGrp[1], GDB_IN.AFTER)
|
|
|
|
elseif #vCurrGrp > 2 then
|
|
-- calcolo ordinamento ottimale con shorest path
|
|
EgtSpInit()
|
|
for i = 1, #vCurrGrp do
|
|
local ptS = EgtSP( vCurrGrp[i], GDB_ID.ROOT)
|
|
local ptE = EgtEP( vCurrGrp[i], GDB_ID.ROOT)
|
|
EgtSpAddPoint( ptS:getX(), ptS:getY(), ptS:getZ(), 0, 0, ptE:getX(), ptE:getY(), ptE:getZ(), 0, 0)
|
|
end
|
|
local vOrd = EgtSpCalculate( SHP_TY.OPEN)
|
|
EgtSpTerminate()
|
|
local vNewOrd = {}
|
|
for i = 1, #vOrd do
|
|
table.insert( vNewOrd, vCurrGrp[vOrd[i]])
|
|
end
|
|
-- riposiziono il primo elemento ( solo se è cambiato)
|
|
if vOrd[1] ~= 1 then
|
|
EgtRelocateGlob( vNewOrd[1], vCurrGrp[1], GDB_IN.AFTER)
|
|
end
|
|
-- riposiziono gli altri elementi
|
|
for i = 2, #vNewOrd do
|
|
EgtRelocateGlob( vNewOrd[i], vNewOrd[i-1], GDB_IN.AFTER)
|
|
end
|
|
vCurrGrp = vNewOrd
|
|
end
|
|
|
|
-- inserisco nella tabella il gruppo trovato
|
|
table.insert( vAssociatedRibs, vCurrGrp)
|
|
|
|
-- cerco il prossimo setto per un nuovo gruppo
|
|
nCurrId = nil
|
|
for i = 1, #vRibs do
|
|
if not vUsed[i] then
|
|
nCurrId = vRibs[i]
|
|
vUsed[i] = true
|
|
break
|
|
end
|
|
end
|
|
end
|
|
|
|
return vAssociatedRibs
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function ReorderSplitRibs( vIds, bParamInvertOrder)
|
|
|
|
-- individuo i setti che derivano da uno stesso pezzo di costolatura
|
|
local tabRibs = {}
|
|
for i = 1, #vIds do
|
|
local nOrigId = EgtGetInfo( vIds[i], KEY_ORIGINAL_RIB, 'i')
|
|
if tabRibs[nOrigId] then
|
|
table.insert( tabRibs[nOrigId], vIds[i])
|
|
else
|
|
tabRibs[nOrigId] = { vIds[i]}
|
|
end
|
|
end
|
|
|
|
local tUserLinkSameSide = {}
|
|
|
|
for k, tabVal in pairs( tabRibs) do
|
|
|
|
-- verifico se split dopo intersezione con altro setto
|
|
local nSplitOrder = EgtGetInfo( tabVal[1], KEY_SPLIT_ORDER, 'i') or 0
|
|
|
|
-- verifico se split dopo aver fatto il trim con la superficie
|
|
local nStartRib = EgtGetInfo( tabVal[1], KEY_START_RIB, 'i')
|
|
local bSplitAfterTrim = EgtGetInfo( nStartRib, KEY_SPLIT_AFTER_TRIM, 'b') or false
|
|
|
|
if nSplitOrder > 0 or bSplitAfterTrim then
|
|
-- caso di setti splittati
|
|
local nShells = EgtGetInfo( tabVal[1], KEY_RIBS_SHELLS_NBR, 'i')
|
|
local dStrand = EgtGetInfo( tabVal[1], KEY_RIBS_STRAND, 'd')
|
|
if nShells == 1 then
|
|
-- non è necessario il riordino, associo splitId diversi ad ogni tratto per gestire correttamente il link nel CalcToolPath
|
|
for i = 1, #tabVal do
|
|
EgtSetInfo( tabVal[i], KEY_SPLIT_ID, i)
|
|
end
|
|
|
|
else
|
|
-- associo le curve dello split
|
|
local tAssociatedRibs = FindAssociatedSplitRibs( tabVal, dStrand)
|
|
|
|
-- assegno splitid per gestire correttamente il link nel CalcToolPath
|
|
for i = 1, #tAssociatedRibs do
|
|
for j = 1, #tAssociatedRibs[i] do
|
|
EgtSetInfo( tAssociatedRibs[i][j], KEY_SPLIT_ID, i)
|
|
end
|
|
end
|
|
|
|
-- modifiche per preservare i link definiti dall'utente
|
|
local bUserLink = EgtGetInfo( tAssociatedRibs[1][1], KEY_RIBS_USER_LINK, 'b') or false
|
|
if bUserLink and nShells % 2 == 0 then
|
|
|
|
local bSameSide = EgtGetInfo( tAssociatedRibs[1][1], KEY_RIBS_USER_LINK_SAME_SIDE, 'b') or false
|
|
local nLinkOrder = EgtGetInfo( tAssociatedRibs[1][1], KEY_RIBS_USER_LINK_ORDER, 'i') or 0
|
|
local nTotParts = EgtGetInfo( tAssociatedRibs[1][1], KEY_RIBS_USER_LINK_TOT, 'i') or 1
|
|
local bInvertOrder = EgtGetInfo( tAssociatedRibs[1][1], KEY_RIBS_INVERT_STRAND_ORDER, 'b') or false
|
|
|
|
if bSameSide and nTotParts > 2 then
|
|
-- salvo gli id che andaranno collegati nella tabella tUserLinkSameSide
|
|
local sName = EgtGetName( tAssociatedRibs[1][1])
|
|
-- eventuale creazione della voce nella tabella
|
|
if not tUserLinkSameSide[sName] then
|
|
tUserLinkSameSide[sName] = {}
|
|
end
|
|
for i = 1, #tAssociatedRibs[1] do
|
|
table.insert( tUserLinkSameSide[sName], tAssociatedRibs[1][i])
|
|
end
|
|
|
|
else
|
|
-- ordinamento
|
|
if ( bInvertOrder and nLinkOrder % 2 ~= 0 ) or ( not bInvertOrder and nLinkOrder % 2 == 0) then
|
|
local vLastGrp = tAssociatedRibs[#tAssociatedRibs]
|
|
local nPrevId = vLastGrp[#vLastGrp]
|
|
for i = #tAssociatedRibs - 1, 1, -1 do
|
|
for j = 1, #tAssociatedRibs[i] do
|
|
local nCurrId = tAssociatedRibs[i][j]
|
|
EgtRelocateGlob( nCurrId, nPrevId, GDB_IN.AFTER)
|
|
nPrevId = nCurrId
|
|
end
|
|
end
|
|
end
|
|
|
|
-- direzione
|
|
if ( nTotParts % 2 == 0 and nLinkOrder > 0 and nLinkOrder < nTotParts - 1) or
|
|
( nTotParts % 2 ~= 0 and nLinkOrder > 0) then
|
|
local vLastGrp = tAssociatedRibs[#tAssociatedRibs]
|
|
for j = 1, #vLastGrp do
|
|
EgtInvertCurve( vLastGrp[j])
|
|
UpdateInvertInfo( vLastGrp[j])
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
for k, vRibs in pairs( tUserLinkSameSide) do
|
|
table.sort( vRibs)
|
|
for i = 2, #vRibs do
|
|
EgtRelocateGlob( vRibs[i], vRibs[i-1], GDB_IN.AFTER)
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function ShortestPathForRibs( vRibs, nGrp, bInvertOrder)
|
|
|
|
if not vRibs or #vRibs == 0 then return end
|
|
|
|
-- divido per gruppi di setti ( i gruppi sono identificati dallo stesso nome)
|
|
local tabRibs = {}
|
|
local sPrevName = ""
|
|
for i = 1, #vRibs do
|
|
local sName = EgtGetName( vRibs[i])
|
|
if sName == sPrevName then
|
|
table.insert( tabRibs[#tabRibs], vRibs[i])
|
|
else
|
|
table.insert( tabRibs, {vRibs[i]})
|
|
end
|
|
sPrevName = sName
|
|
end
|
|
|
|
-- stabilisco l'ordine di realizzazione dei gruppi di setti
|
|
local vOrd
|
|
if #tabRibs == 1 then
|
|
-- se un solo gruppo ordinamento banale
|
|
vOrd = {1}
|
|
else
|
|
-- se più gruppi ordinamento con shortest path
|
|
EgtSpInit()
|
|
for i = 1, #tabRibs do
|
|
local ptS = EgtSP( tabRibs[i][1], GDB_ID.ROOT)
|
|
local ptE = EgtEP( tabRibs[i][#tabRibs[i]], GDB_ID.ROOT)
|
|
EgtSpAddPoint( ptS:getX(), ptS:getY(), ptS:getZ(), 0, 0, ptE:getX(), ptE:getY(), ptE:getZ(), 0, 0)
|
|
end
|
|
vOrd = EgtSpCalculate( SHP_TY.OPEN)
|
|
EgtSpTerminate()
|
|
end
|
|
|
|
-- creo il vettore con i setti ordinati
|
|
local vIds = {}
|
|
local nStart = EgtIf( bInvertOrder, #vOrd, 1)
|
|
local nEnd = EgtIf( bInvertOrder, 1, #vOrd)
|
|
local nStep = EgtIf( bInvertOrder, -1, 1)
|
|
for i = nStart, nEnd, nStep do
|
|
local vCurrRibs = tabRibs[vOrd[i]]
|
|
for j = 1, #vCurrRibs do
|
|
table.insert( vIds, vCurrRibs[j])
|
|
end
|
|
end
|
|
|
|
EgtRelocateGlob( vIds[1], nGrp, GDB_IN.LAST_SON)
|
|
for i = 2, #vIds do
|
|
EgtRelocateGlob( vIds[i], vIds[i-1], GDB_IN.AFTER)
|
|
end
|
|
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function ReorderRibs( nGrp, bInvertOrder)
|
|
|
|
local vIds = EgtGetNameInGroup( nGrp, RIBS_CRV .. '*')
|
|
if not vIds or #vIds == 0 then return end
|
|
|
|
-- riordino setti splittati
|
|
ReorderSplitRibs( vIds, bInvertOrder)
|
|
|
|
-- aggiorno gli id con il nuovo ordinamento
|
|
vIds = EgtGetNameInGroup( nGrp, RIBS_CRV .. '*')
|
|
|
|
-- raggruppo per tipologia
|
|
local tRibs = {{}, {}, {}, {}}
|
|
for i = 1, #vIds do
|
|
local nType = EgtGetInfo( vIds[i], KEY_RIBS_TYPE, 'i')
|
|
table.insert( tRibs[nType], vIds[i])
|
|
end
|
|
|
|
-- riordino ogni tipologia
|
|
for j = 1, 4 do
|
|
local vIds = tRibs[j]
|
|
|
|
-- raggruppo in base allo split order
|
|
local tSplitOrder = {}
|
|
local nMaxSplitOrder = 0
|
|
for i = 1, #vIds do
|
|
local nSplitOrder = EgtGetInfo( vIds[i], KEY_SPLIT_ORDER, 'i') or 0
|
|
-- eventuale aggiornamento del max split order
|
|
if nSplitOrder > nMaxSplitOrder then nMaxSplitOrder = nSplitOrder end
|
|
-- inserisco nella tabella
|
|
if not tSplitOrder[nSplitOrder] then
|
|
tSplitOrder[nSplitOrder]= {vIds[i]}
|
|
else
|
|
table.insert( tSplitOrder[nSplitOrder], vIds[i])
|
|
end
|
|
end
|
|
|
|
-- riordino ogni ordine di split con shortest path
|
|
for k = 0, nMaxSplitOrder do
|
|
ShortestPathForRibs( tSplitOrder[k], nGrp, bInvertOrder)
|
|
end
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------------------------------
|
|
local function ReassignInfo( nCrv, nCnt, vOrig)
|
|
|
|
for nId = nCrv, nCrv + nCnt - 1 do
|
|
local ptS = EgtSP( nId)
|
|
local ptE = EgtEP( nId)
|
|
|
|
EgtSetInfo( nId, KEY_TYPE, TYPE.RIB)
|
|
if EgtCurveIsClosed( nId) then
|
|
EgtSetInfo( nId, KEY_CLOSED_CRV, 1)
|
|
end
|
|
|
|
local bStart = false
|
|
local bEnd = false
|
|
while not bStart and not bEnd do
|
|
-- scorro le curve originarie per capire da quali deriva
|
|
for i = 1, #vOrig do
|
|
local ptSOrig = EgtSP( vOrig[i])
|
|
local ptEOrig = EgtEP( vOrig[i])
|
|
|
|
-- verifico se corrisponde al suo start
|
|
if AreSamePointApprox( ptS, ptSOrig) or AreSamePointApprox( ptS, ptEOrig) then
|
|
CopyInfo( vOrig[i], nId, KEY_RIBS_STRAND, 'd')
|
|
CopyInfo( vOrig[i], nId, KEY_RIBS_LEAD_IN_INVERT, 'b')
|
|
CopyInfo( vOrig[i], nId, KEY_RIBS_LEAD_IN_LEN, 'd')
|
|
CopyInfo( vOrig[i], nId, KEY_ASSOCIATED_SURF, 'i')
|
|
CopyInfo( vOrig[i], nId, KEY_RIBS_OVERLAP, 'd')
|
|
CopyInfo( vOrig[i], nId, KEY_RIBS_STRAND_OVERLAP, 'd')
|
|
CopyInfo( vOrig[i], nId, KEY_RIBS_TYPE, 'i')
|
|
CopyInfo( vOrig[i], nId, KEY_RIBS_LINK, 'b')
|
|
CopyInfo( vOrig[i], nId, KEY_RIBS_LINK_FILLET, 'd')
|
|
CopyInfo( vOrig[i], nId, KEY_RIBS_LEAD_FILLET, 'd')
|
|
bStart = true
|
|
end
|
|
-- verifico se corrisponde al suo end
|
|
if AreSamePointApprox( ptE, ptSOrig) or AreSamePointApprox( ptE, ptEOrig) then
|
|
CopyInfo( vOrig[i], nId, KEY_RIBS_LEAD_OUT_INVERT, 'b')
|
|
CopyInfo( vOrig[i], nId, KEY_RIBS_LEAD_OUT_LEN, 'd')
|
|
CopyInfo( vOrig[i], nId, KEY_RIBS_LEAD_OUT_COASTING, 'd')
|
|
CopyInfo( vOrig[i], nId, KEY_RIBS_LEAD_OUT_WIPE, 'd')
|
|
CopyInfo( vOrig[i], nId, KEY_RIBS_LEAD_OUT_WIPE_DIR, 'd')
|
|
bEnd = true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- dopo aver salvato le info è inutile conservare le curve originali
|
|
for i = 1, #vOrig do
|
|
EgtErase( vOrig[i])
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------------------------------
|
|
-- Funzione che riordina le costolature nel caso di intersezioni e 2 passate
|
|
local function ReorderRibsInters2Shells( nOffsGrp, bInvertOrder)
|
|
|
|
local vOffs = {}
|
|
local vClosed = {}
|
|
local nId = EgtGetFirstNameInGroup( nOffsGrp, RIBS_CRV .. '*')
|
|
while nId do
|
|
if EgtCurveIsClosed( nId) then
|
|
table.insert( vClosed, nId)
|
|
else
|
|
table.insert( vOffs, nId)
|
|
end
|
|
nId = EgtGetNextName( nId, RIBS_CRV .. '*')
|
|
end
|
|
|
|
local k = 0 -- indice da utilizzare per i nomi
|
|
|
|
-- gestione delle curve chiuse
|
|
if #vClosed > 0 then
|
|
k = k + 1
|
|
local sPrevName = EgtGetName( vClosed[1])
|
|
EgtSetName( vClosed[1], RIBS_CRV .. tostring( k))
|
|
for i = 2, #vClosed do
|
|
local sCurrName = EgtGetName( vClosed[i])
|
|
-- se setto diverso aggiorno il nome
|
|
if sCurrName ~= sPrevName then
|
|
k = k + 1
|
|
end
|
|
EgtSetName( vClosed[i], RIBS_CRV .. tostring( k))
|
|
sPrevName = sCurrName
|
|
end
|
|
end
|
|
|
|
-- gestione delle curve aperte
|
|
-- copio le curve originali ( per recuperarne le info)
|
|
local vCopy = {}
|
|
for i = 1, #vOffs do
|
|
local nNewId = EgtCopy( vOffs[i], nOffsGrp)
|
|
table.insert( vCopy, nNewId)
|
|
end
|
|
local dStrand = EgtGetInfo( vCopy[1], KEY_RIBS_STRAND, 'd')
|
|
|
|
-- concateno le curve
|
|
local nCrv, nCnt = EgtCurveCompoByChain( nOffsGrp, vOffs, ORIG())
|
|
local vIds = {}
|
|
for i = nCrv, nCrv + nCnt - 1 do
|
|
table.insert( vIds, i)
|
|
end
|
|
-- recupero le info dalle curve originali
|
|
ReassignInfo( nCrv, nCnt, vCopy)
|
|
|
|
while #vIds > 0 do
|
|
k = k + 1
|
|
-- prendo la prima tra le curve a disposizione
|
|
local nCurrCrv = vIds[1]
|
|
table.remove( vIds, 1)
|
|
EgtSetName( nCurrCrv, RIBS_CRV .. tostring(k))
|
|
local pt = EgtEP( nCurrCrv)
|
|
local _, dParE = EgtCurveDomain( nCurrCrv)
|
|
local nCnt = 0
|
|
-- scorro alla ricerca di una curva che posso collegare alla corrente
|
|
while nCurrCrv do
|
|
local nCurrType = EgtGetInfo( nCurrCrv, KEY_RIBS_TYPE, 'i')
|
|
local bFound = false
|
|
for j = 1, #vIds do
|
|
local nType = EgtGetInfo( vIds[j], KEY_RIBS_TYPE, 'i')
|
|
|
|
if vIds[j] ~= nCrv and not EgtCurveIsClosed(vIds[j]) and nCurrType == nType then
|
|
|
|
-- verifico se il collegamento è possibile
|
|
local bAdd = false
|
|
local bInvert = false
|
|
local dDist, _, dParMinDist = EgtPointCurveDist( pt, vIds[j])
|
|
if dDist < dStrand + 10 * GEO.EPS_SMALL then
|
|
-- controllo che sia vicino ad uno degli estremi
|
|
local dParS, dParE = EgtCurveDomain( vIds[j])
|
|
if abs( dParMinDist - dParS) < 500 * GEO.EPS_SMALL then
|
|
bAdd = true
|
|
elseif abs( dParMinDist - dParE) < 500 * GEO.EPS_SMALL then
|
|
bAdd = true
|
|
-- è se necessaria inversione di vIds[j]
|
|
bInvert = true
|
|
end
|
|
end
|
|
|
|
if not bAdd then
|
|
-- check sullo start point di vIds[j]
|
|
local dDist, _, dParMinDist = EgtPointCurveDist( EgtSP( vIds[j]), nCurrCrv)
|
|
if dDist < dStrand + 10 * GEO.EPS_SMALL then
|
|
bInvert = false
|
|
-- controllo sia vicino all'end point della curva corrente
|
|
if dParE - dParMinDist < 500 * GEO.EPS_SMALL then
|
|
bAdd = true
|
|
-- altrimenti può essere vicino allo start
|
|
elseif dParMinDist < 500 * GEO.EPS_SMALL and nCnt == 0 then
|
|
bAdd = true
|
|
EgtInvertCurve( nCurrCrv)
|
|
end
|
|
end
|
|
-- se non è aggiunto check con end point di vIds[j]
|
|
if not bAdd then
|
|
local dDist, _, dParMinDist = EgtPointCurveDist( EgtEP( vIds[j]), nCurrCrv)
|
|
if dDist < dStrand + 10 * GEO.EPS_SMALL then
|
|
bInvert = true
|
|
if dParE - dParMinDist < 500 * GEO.EPS_SMALL then
|
|
bAdd = true
|
|
elseif dParMinDist < 500 * GEO.EPS_SMALL and nCnt == 0 then
|
|
bAdd = true
|
|
EgtInvertCurve( nCurrCrv)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if bAdd then
|
|
bFound = true
|
|
nCnt = nCnt + 1
|
|
EgtRelocateGlob( vIds[j], nCurrCrv, GDB_IN.AFTER)
|
|
EgtSetName( vIds[j], RIBS_CRV .. tostring( k))
|
|
-- eventuale inversione della curva
|
|
if bInvert then EgtInvertCurve( vIds[j]) end
|
|
|
|
-- aggiorno per collegamento successivo
|
|
pt = EgtEP( vIds[j])
|
|
_, dParE = EgtCurveDomain( vIds[j])
|
|
nCurrCrv = vIds[j]
|
|
-- elimino la curva dal vettore di curve da considerare
|
|
table.remove( vIds, j)
|
|
break
|
|
end
|
|
end
|
|
end
|
|
-- se non ho più curve da collegare
|
|
if not bFound and nCnt == 0 then
|
|
-- se era la prima curva faccio un tentativo invertendola
|
|
nCnt = 1
|
|
EgtInvertCurve( nCurrCrv)
|
|
pt = EgtEP( nCurrCrv)
|
|
elseif not bFound then
|
|
nCurrCrv = nil
|
|
end
|
|
end
|
|
end
|
|
|
|
-- eventuale inversione ordinamento
|
|
if bInvertOrder then
|
|
local vRibs = EgtGetNameInGroup( nOffsGrp, RIBS_CRV .. '*')
|
|
for j = #vRibs, 1, -1 do
|
|
-- inverto direzione curve per mantenere concatenamento
|
|
EgtInvertCurve( vRibs[j])
|
|
EgtRelocateGlob( vRibs[j], nOffsGrp, GDB_IN.LAST_SON)
|
|
end
|
|
end
|
|
end
|
|
|
|
-------------------------------------------------------------------
|
|
local function CalcRibsPaths( nSliceGrp, nRibsGrp, LayerParams, vPtStart, bIgnoreMergedRibs)
|
|
|
|
-- recupero i setti
|
|
local vAllRibs = EgtGetNameInGroup( nRibsGrp, RIBS_CRV .. '*')
|
|
local vOrigRibs = {}
|
|
if bIgnoreMergedRibs then
|
|
-- escludo i setti che sono stati già uniti nel percorso delle shell
|
|
for i = 1, #vAllRibs do
|
|
local nType = EgtGetInfo( vAllRibs[i], KEY_RIBS_TYPE, 'i')
|
|
local bMergeWithShells = EgtGetInfo( vAllRibs[i], KEY_RIBS_MERGE_WITH_SHELLS, 'b') or false
|
|
if not ( nType == RIB_TYPE.INTERNAL and bMergeWithShells) then
|
|
table.insert( vOrigRibs, vAllRibs[i])
|
|
end
|
|
end
|
|
else
|
|
vOrigRibs = vAllRibs
|
|
end
|
|
if #vOrigRibs == 0 then return end
|
|
|
|
-- stabilisco ordine di realizzazione delle varie tipologie
|
|
local vTypeSequence = {}
|
|
for i = 1, #LayerParams.vPrintOrder do
|
|
if LayerParams.vPrintOrder[i] == PRINT_ELEMENT.RIB_UNBOUNDED then
|
|
vTypeSequence[RIB_TYPE.UNBOUNDED] = i
|
|
elseif LayerParams.vPrintOrder[i] == PRINT_ELEMENT.RIB_INTERNAL then
|
|
vTypeSequence[RIB_TYPE.INTERNAL] = i
|
|
elseif LayerParams.vPrintOrder[i] == PRINT_ELEMENT.RIB_EXTERNAL then
|
|
vTypeSequence[RIB_TYPE.EXTERNAL] = i
|
|
elseif LayerParams.vPrintOrder[i] == PRINT_ELEMENT.RIB_SUPPORT then
|
|
vTypeSequence[RIB_TYPE.SUPPORT] = i
|
|
end
|
|
end
|
|
|
|
-- verifico se tutte le costolature vengono fatte con 2 passate e con lo stesso strand
|
|
local bAllTwoStrands = true
|
|
local dStrandRef = EgtGetInfo( vOrigRibs[1], KEY_RIBS_STRAND, 'd')
|
|
for i = 1, #vOrigRibs do
|
|
local nShells = EgtGetInfo( vOrigRibs[i], KEY_RIBS_SHELLS_NBR, 'i')
|
|
local dStrand = EgtGetInfo( vOrigRibs[i], KEY_RIBS_STRAND, 'd')
|
|
if nShells ~= 2 or abs( dStrand - dStrandRef) > GEO.EPS_SMALL then
|
|
bAllTwoStrands = false
|
|
break
|
|
end
|
|
end
|
|
|
|
-- verifico se posso ignorare eventuali buchi nei setti
|
|
VerifyRibsHoles( vOrigRibs)
|
|
|
|
local nTotSrfInt = GDB_ID.NULL
|
|
local nTotSrfExt = GDB_ID.NULL
|
|
-- scorro i gruppi di curve
|
|
local vCrvGrps = EgtGetNameInGroup( nSliceGrp, CONTOUR_GRP .. '*')
|
|
for i = 1, #vCrvGrps do
|
|
|
|
-- creo o svuoto il gruppo
|
|
local nRibsPathGrp = EgtGetFirstNameInGroup( vCrvGrps[i], RIBS_GRP)
|
|
if not nRibsPathGrp then
|
|
nRibsPathGrp = EgtGroup( vCrvGrps[i])
|
|
EgtSetName( nRibsPathGrp, RIBS_GRP)
|
|
EgtSetStatus( nRibsPathGrp, GDB_ST.OFF)
|
|
else
|
|
EgtEmptyGroup( nRibsPathGrp)
|
|
end
|
|
|
|
-- calcolo le superfici occupate dalle shell nel gruppo di curve corrente e aggiorno le superfici totali
|
|
-- a) superficie più interna
|
|
local nSrfInt = EgtGetFirstNameInGroup( vCrvGrps[i], TOT_SHELL_TRIM_SURF) or GDB_ID.NULL
|
|
if nTotSrfInt == GDB_ID.NULL and nSrfInt ~= GDB_ID.NULL then
|
|
nTotSrfInt = EgtCopyGlob( nSrfInt, nRibsGrp)
|
|
elseif nTotSrfInt ~= GDB_ID.NULL and nSrfInt ~= GDB_ID.NULL then
|
|
if not EgtSurfFrAdd( nTotSrfInt, nSrfInt) then
|
|
EgtOutLog( 'Error : EgtSurfFrAdd for external ribs failed. Errors may occur with user-linked ribs (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
end
|
|
end
|
|
-- b) superficie più esterna
|
|
local nSrfExt = GDB_ID.NULL
|
|
local nSrfLay = EgtGetFirstNameInGroup( vCrvGrps[i], LAYER_SRF)
|
|
if nSrfLay then
|
|
nSrfExt = ComputeSurfOffset( nSrfLay, vCrvGrps[i], LayerParams.dOffs)
|
|
if not nSrfExt then
|
|
EgtOutLog( 'Error : creation of trim region for external ribs failed. Errors may occur also with internal user-linked ribs (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : error in computing trim region for external ribs')
|
|
nTotSrfExt = nil
|
|
else
|
|
if nTotSrfExt == GDB_ID.NULL then
|
|
nTotSrfExt = EgtCopyGlob( nSrfExt, nRibsGrp)
|
|
elseif nTotSrfExt then
|
|
if not EgtSurfFrAdd( nTotSrfExt, nSrfExt) then
|
|
nTotSrfExt = nil
|
|
EgtOutLog( 'Error : creation of trim region for external ribs failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : error in computing trim region for external ribs')
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- trim grossolano dei setti
|
|
local nTrimGrp = TrimRibs( vOrigRibs, nRibsGrp, nSrfExt, EgtIf( i == #vCrvGrps, nTotSrfInt, GDB_ID.NULL))
|
|
|
|
-- calcolo offset orientati
|
|
local nOffsGrp = ComputeRibsOrientedOffset( nTrimGrp)
|
|
|
|
-- preparo il gruppo con i contorni delle superfici di offset ( necessario per CalcToolPath)
|
|
local nLoopGrp = EgtGroup( nRibsPathGrp)
|
|
|
|
-- creo le superfici con cui fare i trim corretti e ne estraggo contorni
|
|
local tSurfOffs = ComputeTrimSurfWithOverlapsForRibs( vOrigRibs, nRibsPathGrp, nSrfInt, EgtIf( i == #vCrvGrps, nTotSrfExt, nil), nLoopGrp)
|
|
|
|
-- copio gli offset delle costolature nel PathGrp
|
|
local vOffsRib = EgtGetAllInGroup( nOffsGrp)
|
|
for i = 1, #vOffsRib do
|
|
EgtCopyGlob( vOffsRib[i], nRibsPathGrp)
|
|
end
|
|
|
|
-- trim dei setti con le regioni offsettate secondo opportuno overlap
|
|
local vRibs = EgtGetNameInGroup( nRibsPathGrp, RIBS_CRV ..'*') or {}
|
|
for i = 1, #vRibs do
|
|
local nCrvId = vRibs[i]
|
|
-- trim con superficie opportuna
|
|
local nType = EgtGetInfo( nCrvId, KEY_RIBS_TYPE, 'i')
|
|
local nStartRib = EgtGetInfo( nCrvId, KEY_START_RIB, 'i')
|
|
if not tSurfOffs[nStartRib] then
|
|
-- la costolatura non è fattibile
|
|
EgtErase( nCrvId)
|
|
else
|
|
local nCrv, nCnt
|
|
if tSurfOffs[nStartRib] == GDB_ID.NULL then
|
|
-- il setto non va trimmato ( caso di rib unbounded o rib esterno senza solido)
|
|
nCrv = nCrvId
|
|
nCnt = 1
|
|
else
|
|
nCrv, nCnt = EgtTrimCurveWithRegion( nCrvId, tSurfOffs[nStartRib], EgtIf( nType == RIB_TYPE.INTERNAL or nType == RIB_TYPE.SUPPORT, true, false), false)
|
|
end
|
|
|
|
for nInd = 0, nCnt - 1 do
|
|
-- verifico vincolo sulla lunghezza
|
|
local dLen = EgtCurveLength( nCrv + nInd)
|
|
if dLen < MIN_RIBS_LEN then
|
|
EgtErase( nCrv + nInd)
|
|
else
|
|
|
|
-- salvo info della superficie di trim associata
|
|
EgtSetInfo( nCrv + nInd, KEY_ASSOCIATED_SURF, tSurfOffs[nStartRib])
|
|
|
|
-- setti chiusi
|
|
if EgtCurveIsClosed( nCrv + nInd) then
|
|
EgtSetInfo( nCrv + nInd, KEY_CLOSED_CRV, 1)
|
|
|
|
-- ripristino orientamento originale
|
|
local bInvertInfo = EgtGetInfo( nCrv + nInd, KEY_RIBS_INVERT_DIR, 'b') or false
|
|
local bInverted = EgtGetInfo( nCrv + nInd, KEY_INVERTED_CRV, 'b') or false
|
|
if bInvertInfo ~= bInverted then
|
|
EgtInvertCurve( nCrv + nInd)
|
|
UpdateInvertInfo( nCrv + nInd)
|
|
end
|
|
|
|
ModifyStartPoint( nCrv + nInd, vPtStart)
|
|
EgtSetInfo( nCrv + nInd, KEY_RIBS_LINK, 0)
|
|
end
|
|
|
|
-- se dopo trim ho avuto split in più tratti, salvo alcune info
|
|
if nCnt > 1 then
|
|
local nStartRib = EgtGetInfo( nCrv + nInd, KEY_START_RIB, 'i')
|
|
EgtSetInfo( nStartRib, KEY_SPLIT_AFTER_TRIM, 1)
|
|
EgtSetInfo( nCrv + nInd, KEY_SPLIT_AFTER_TRIM, 1)
|
|
EgtSetInfo( nCrv + nInd, KEY_SPLIT_AFTER_TRIM_ORDER, nInd)
|
|
EgtSetInfo( nCrv + nInd, KEY_SPLIT_AFTER_TRIM_TOT, nCnt)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- gestisco eventuali intersezioni fra costolature
|
|
local bInters, bSpecialCase = HandleRibsIntersections( nRibsGrp, nOffsGrp, nRibsPathGrp, nSrfInt, EgtIf( i == #vCrvGrps, nTotSrfExt, nil),
|
|
bAllTwoStrands, vTypeSequence, nLoopGrp, tSurfOffs)
|
|
EgtSetInfo( nRibsPathGrp or GDB_ID.NULL, KEY_RIBS_INTERS, bInters)
|
|
EgtSetInfo( nRibsPathGrp or GDB_ID.NULL, KEY_RIBS_SPECIAL_CASE, bSpecialCase)
|
|
|
|
-- riordino le costolature
|
|
if bSpecialCase then
|
|
-- gestione caso speciale di intersezione e 2 passate
|
|
ReorderRibsInters2Shells( nRibsPathGrp, LayerParams.bRibsInvertOrder)
|
|
else
|
|
ReorderRibs( nRibsPathGrp, LayerParams.bRibsInvertOrder)
|
|
end
|
|
|
|
-- sistemo le quote dei loop per CalcToolPath
|
|
local vLoopIds = EgtGetAllInGroup( nLoopGrp) or {}
|
|
for i = 1, #vLoopIds do
|
|
EgtMove( vLoopIds[i], LayerParams.dLayHeight * s_vtSlicing, GDB_RT.GLOB)
|
|
end
|
|
|
|
-- elimino superficie per check
|
|
EgtErase( nSrfExt)
|
|
|
|
if not EgtGetFirstNameInGroup( nRibsPathGrp, RIBS_CRV .. '*') then
|
|
EgtErase( nRibsPathGrp)
|
|
end
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
--------------------- RIBS-MERGED SHELLS ---------------------------
|
|
--------------------------------------------------------------------
|
|
local function CalcFillet( nCrv1, nCrv2, dFillet, nGrpId, nGrpTmp)
|
|
|
|
if dFillet < GEO.EPS_SMALL then return end
|
|
|
|
-- creo il fillet
|
|
local dParRef1 = EgtCurveParamAtLength( nCrv1, EgtCurveLength( nCrv1) - 100 * GEO.EPS_SMALL)
|
|
local dParRef2 = EgtCurveParamAtLength( nCrv2, 100 * GEO.EPS_SMALL)
|
|
local nFillet = EgtCurveFillet( nGrpTmp, nCrv1, EgtUP( nCrv1, dParRef1, nGrpTmp), nCrv2, EgtUP( nCrv2, dParRef2, nGrpTmp), dFillet, true, GDB_RT.LOC)
|
|
if not nFillet then
|
|
-- ritento con valore di fillet leggermente inferiore
|
|
nFillet = EgtCurveFillet( nGrpTmp, nCrv1, EgtUP( nCrv1, dParRef1, nGrpTmp), nCrv2, EgtUP( nCrv2, dParRef2, nGrpTmp), dFillet - 50 * GEO.EPS_SMALL, true, GDB_RT.LOC)
|
|
end
|
|
|
|
-- spezzo a metà il fillet per assegnarlo alle due curve
|
|
if nFillet then
|
|
local nNewFillet = EgtSplitCurve( nFillet, 2)
|
|
|
|
-- aggiungo a nCrv1
|
|
if EgtExistsObj( nCrv1) then
|
|
EgtAddCurveCompoArcTg( nCrv1, EgtEP( nNewFillet, GDB_ID.ROOT), true, GDB_RT.GLOB)
|
|
EgtErase( nNewFillet)
|
|
else
|
|
-- nCrv1 viene sostituita completamente dal fillet
|
|
local nNewCrv = EgtCurveCompo( nGrpId, {nNewFillet})
|
|
EgtChangeId( nNewCrv, nCrv1)
|
|
end
|
|
|
|
-- aggiungo a nCrv2
|
|
if EgtExistsObj( nCrv2) then
|
|
EgtAddCurveCompoArcTg( nCrv2, EgtSP( nNewFillet + 1, GDB_ID.ROOT), false, GDB_RT.GLOB)
|
|
EgtErase( nNewFillet + 1)
|
|
else
|
|
-- nCrv2 viene sostituita completamente dal fillet
|
|
local nNewCrv = EgtCurveCompo( nGrpId, {nNewFillet + 1})
|
|
EgtChangeId( nNewCrv, nCrv2)
|
|
end
|
|
else
|
|
EgtOutLog( 'Warning : ribs-merged shells fillet not possible (layer '..tostring( s_nCurrIdx)..') - CalcPath')
|
|
end
|
|
|
|
EgtRelocateGlob( nFillet or GDB_ID.NULL, nGrpId)
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function AddFillet( nRib1, vLinks, nRib2, nGrpId)
|
|
|
|
local dFillet1 = EgtGetInfo( nRib1, KEY_RIBS_LINK_FILLET, 'd')
|
|
local dFillet2 = EgtGetInfo( nRib2, KEY_RIBS_LINK_FILLET, 'd')
|
|
-- verifico se necessaria correzione per passate dello stesso setto
|
|
local nOrig1 = EgtGetInfo( nRib1, KEY_ORIGINAL_RIB, 'i')
|
|
local nOrig2 = EgtGetInfo( nRib2, KEY_ORIGINAL_RIB, 'i')
|
|
local nSplit1 = EgtGetInfo( nRib1, KEY_SPLIT_ID, 'i') or 0
|
|
local nSplit2 = EgtGetInfo( nRib2, KEY_SPLIT_ID, 'i') or 0
|
|
if nOrig1 == nOrig2 and nSplit1 == nSplit2 then
|
|
local dStrand = EgtGetInfo( nRib1, KEY_RIBS_STRAND, 'd')
|
|
local dStrandOverlap = EgtGetInfo( nRib1, KEY_RIBS_STRAND_OVERLAP, 'd')
|
|
dFillet1 = min( dFillet1, 0.5 * ( 1 - dStrandOverlap / 100) * dStrand)
|
|
dFillet2 = dFillet1
|
|
end
|
|
|
|
-- creo un gruppo con riferimento locale allo slicing per i conti del fillet
|
|
local nGrpTmp = EgtGroup( nGrpId, Frame3d( ORIG(), s_vtSlicing), GDB_RT.GLOB)
|
|
|
|
-- calcolo il primo fillet
|
|
local ptRib1 = EgtEP( nRib1, GDB_ID.ROOT)
|
|
for i = 1, #vLinks do
|
|
if AreSamePointApprox( ptRib1, EgtSP( vLinks[i], GDB_ID.ROOT)) then
|
|
CalcFillet( nRib1, vLinks[i], dFillet1, nGrpId, nGrpTmp)
|
|
break
|
|
end
|
|
end
|
|
-- calcolo il secondo fillet
|
|
local ptRib2 = EgtSP( nRib2, GDB_ID.ROOT)
|
|
for i = 1, #vLinks do
|
|
if AreSamePointApprox( EgtEP( vLinks[i], GDB_ID.ROOT), ptRib2) then
|
|
CalcFillet( vLinks[i], nRib2, dFillet2, nGrpId, nGrpTmp)
|
|
break
|
|
end
|
|
end
|
|
|
|
EgtErase( nGrpTmp)
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function ComputeShortestLinkOnCurve( nCrv, dParS, dParE, nGrp)
|
|
|
|
-- costruisco percorso dParS->dParE
|
|
local nCrv1 = EgtCopyGlob( nCrv, nGrp)
|
|
EgtTrimCurveStartEndAtParam( nCrv1, dParS, dParE)
|
|
-- costruisco percorso dParE->dParS
|
|
local nCrv2 = EgtCopyGlob( nCrv, nGrp)
|
|
EgtTrimCurveStartEndAtParam( nCrv2, dParE, dParS)
|
|
EgtInvertCurve( nCrv2)
|
|
|
|
-- restituisco il tratto più corto
|
|
local dLen1 = EgtCurveLength( nCrv1)
|
|
local dLen2 = EgtCurveLength( nCrv2)
|
|
if dLen1 < dLen2 + GEO.EPS_SMALL then
|
|
EgtErase( nCrv2)
|
|
return nCrv1
|
|
else
|
|
EgtErase( nCrv1)
|
|
return nCrv2
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function TrimCurveExtremity( nCrv, nTrimSrf, bStartOrEnd, nGrp)
|
|
|
|
local nCopyCrv = EgtCopyGlob( nCrv, nGrp)
|
|
local nRes, nCnt = EgtTrimCurveWithRegion( nCopyCrv, nTrimSrf, true, false)
|
|
|
|
if nRes then
|
|
-- recupero estremi di interesse
|
|
local nRefCrv = EgtIf( bStartOrEnd, nRes, nRes + nCnt - 1)
|
|
local ptRefRes = EgtIf( bStartOrEnd, EgtSP( nRefCrv, GDB_ID.ROOT), EgtEP( nRefCrv, GDB_ID.ROOT))
|
|
local ptRefCrv = EgtIf( bStartOrEnd, EgtSP( nCrv, GDB_ID.ROOT), EgtEP( nCrv, GDB_ID.ROOT))
|
|
-- se estremi coincidenti significa che il trim non è necessario
|
|
if not AreSamePointApprox( ptRefRes, ptRefCrv) then
|
|
-- trim della curva
|
|
local dPar = EgtCurveParamAtPoint( nCrv, ptRefRes, 100 * GEO.EPS_SMALL, GDB_RT.GLOB)
|
|
if not dPar then return false end
|
|
if bStartOrEnd then
|
|
EgtTrimCurveStartAtParam( nCrv, dPar)
|
|
else
|
|
EgtTrimCurveEndAtParam( nCrv, dPar)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- cancello tutte le curve ausiliarie create
|
|
EgtErase( nCopyCrv)
|
|
for nId = nRes, nRes + nCnt - 1 do
|
|
EgtErase( nId)
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function PrepareShellsForRibsMerge( vOrigShells, bExtraShell)
|
|
|
|
if #vOrigShells == 0 then
|
|
return vOrigShells
|
|
end
|
|
|
|
local vIds = vOrigShells
|
|
-- se sono extra shells calcolo le curve chiuse da cui si sono generate
|
|
if bExtraShell then
|
|
local nGrp = EgtGetParent( vOrigShells[1])
|
|
local dOffs = EgtGetInfo( vOrigShells[1], KEY_CRV_OFFSET, 'd')
|
|
local nLaySrf = EgtGetFirstNameInGroup( EgtGetParent( nGrp), LAYER_SRF)
|
|
local nSrf = ComputeSurfOffset( nLaySrf, EgtGetParent( vOrigShells[1]), - dOffs)
|
|
if not nSrf or nSrf == GDB_ID.NULL then
|
|
EgtOutLog( 'Error : error in computing complete shell for shell-merged ribs (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : error in ribs-merged shells')
|
|
return
|
|
end
|
|
-- estraggo i loop
|
|
vIds = GetPathsFromSurf( nSrf, '', TYPE.EXTRA_SHELL, EgtGetParent( vOrigShells[1]))
|
|
EgtErase( nSrf)
|
|
end
|
|
|
|
-- associo loop esterni ai loop interni
|
|
local tShells = {}
|
|
if #vIds == 1 then
|
|
tShells = {{vIds[1]}}
|
|
else
|
|
-- individuo i loop esterni e i loop interni
|
|
local vExt = {}
|
|
local vInt = {}
|
|
for i = 1, #vIds do
|
|
local bInternalLoop = EgtGetInfo( vIds[i], KEY_INTERNAL_SRF_LOOP, 'b') or false
|
|
table.insert( EgtIf( bInternalLoop, vInt, vExt), vIds[i])
|
|
end
|
|
|
|
if #vInt == 0 then
|
|
-- se solo loop esterni
|
|
for i = 1, #vExt do
|
|
table.insert( tShells, {vExt[i]})
|
|
end
|
|
elseif #vExt == 1 then
|
|
-- se un solo loop esterno, tutti i loop interni sono riferiti ad esso
|
|
local vCrvs = { vExt[1]}
|
|
for i = 1, #vInt do
|
|
table.insert( vCrvs, vInt[i])
|
|
end
|
|
tShells = { vCrvs}
|
|
else
|
|
-- associo ad ogni loop esterno, gli interni corrispondenti
|
|
local vUsed = {} -- per tenere traccia se il loop è già stato associato ad un esterno
|
|
for i = 1, #vInt do
|
|
vUsed[i] = false
|
|
end
|
|
for i = 1, #vExt do
|
|
local vCrvs = { vExt[i]}
|
|
local nSrfTmp = EgtSurfFlatRegion( EgtGetParent( vOrigShells[1]), vExt[i])
|
|
for j = 1, #vInt do
|
|
if not vUsed[j] then
|
|
local nRes = EgtCurveWithRegionClassify( vInt[j], nSrfTmp)
|
|
if nRes == GDB_CRC.IN then
|
|
table.insert( vCrvs, vInt[j])
|
|
vUsed[j] = true
|
|
end
|
|
end
|
|
end
|
|
table.insert( tShells, vCrvs)
|
|
EgtErase( nSrfTmp)
|
|
end
|
|
end
|
|
end
|
|
|
|
return tShells
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function PrepareAuxSurfsForRibsMerge( nGrp, vShells, dStrand, LayerParams)
|
|
|
|
-- superficie definita dalla shell
|
|
local nSrfShell = EgtSurfFlatRegion( nGrp, vShells)
|
|
if not nSrfShell then
|
|
EgtOutLog( 'Error : error in computing shell region for shell-merged ribs (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : error in computing ribs-merged shells')
|
|
return false
|
|
end
|
|
EgtSetName( nSrfShell, SHELL_SURF)
|
|
|
|
-- superficie per trim grossolano dei setti
|
|
local nCrvGrp = EgtGetParent( EgtGetParent( nGrp))
|
|
local nSrfCoarseTrim = GDB_ID.NULL
|
|
local nSrfLay = EgtGetFirstNameInGroup( nCrvGrp, LAYER_SRF)
|
|
if nSrfLay then
|
|
nSrfCoarseTrim = ComputeSurfOffset( nSrfLay, nGrp, LayerParams.dOffs)
|
|
if not nSrfCoarseTrim then
|
|
EgtOutLog( 'Error : error in computing coarse trim region for shell-merged ribs (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : error in computing ribs-merged shells')
|
|
return false
|
|
end
|
|
EgtSetName( nSrfCoarseTrim, COARSE_TRIM_SURF)
|
|
else
|
|
return false
|
|
end
|
|
|
|
-- superficie per trim corretto dei setti
|
|
local nTotShellTrimSurf = EgtGetFirstNameInGroup( nCrvGrp, TOT_SHELL_TRIM_SURF)
|
|
if not nTotShellTrimSurf then
|
|
EgtOutLog( 'Warning : not enough space for merging ribs with shells (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
return false
|
|
end
|
|
local nTrimSurf = ComputeSurfOffset( nTotShellTrimSurf, nGrp, - ( 0.5 - LayerParams.dStrandOverlap / 100) * dStrand)
|
|
if not nTrimSurf then
|
|
-- errore nel calcolo
|
|
EgtOutLog( 'Error : error in computing trim region for shell-merged ribs (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : error in computing ribs-merged shells')
|
|
return false
|
|
elseif nTrimSurf == GDB_ID.NULL then
|
|
-- non c'è spazio per creare ribs-merged shell, realizzo solo la shell
|
|
EgtOutLog( 'Warning : not enough space for merging ribs with shells (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
return false
|
|
end
|
|
|
|
-- creo il gruppo con i loop delle superfici
|
|
local nLoopGrp = EgtGroup( nGrp)
|
|
EgtSetName( nLoopGrp, LOOP_GRP)
|
|
for i = 1, #vShells do
|
|
local nSrfLoop = EgtCopyGlob( vShells[i], nLoopGrp)
|
|
EgtSetName( nSrfLoop, SURF_LOOP)
|
|
end
|
|
GetPathsFromSurf( nTrimSurf, TRIM_SURF_LOOP, nil, nLoopGrp)
|
|
|
|
return true
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function HandleRibsIntersectionForRibsMergedShells( vOrigRibs, nRibsGrp, nOffsGrp, nLoopGrp, dStrand, dOverlap)
|
|
|
|
local vRibsIds = {}
|
|
-- ignoro setti che non hanno passate corrispondenti
|
|
for i = 1, #vOrigRibs do
|
|
local vOffs = EgtGetNameInGroup( nRibsGrp, EgtGetName( vOrigRibs[i]))
|
|
if vOffs and #vOffs > 0 then table.insert( vRibsIds, vOrigRibs[i]) end
|
|
end
|
|
|
|
-- creo un gruppo con frame locale per calcolare le intersezioni ( è il piano XY locale dove calcolare intersezioni)
|
|
local frLoc = Frame3d( ORIG(), s_vtSlicing)
|
|
local nGrpTmp = EgtGroup( nRibsGrp, frLoc, GDB_RT.GLOB)
|
|
|
|
local nShellSrf = EgtGetFirstNameInGroup( EgtGetParent( nRibsGrp), SHELL_SURF)
|
|
local nTrimSrf = EgtGetFirstNameInGroup( EgtGetParent( nRibsGrp), TOT_SHELL_TRIM_SURF)
|
|
local nShellSrfInters = EgtCopyGlob( nShellSrf, nLoopGrp)
|
|
local nTrimSrfInters = EgtCopyGlob( nTrimSrf, nLoopGrp)
|
|
|
|
local bIntersection = false
|
|
for i = 1, #vRibsIds do
|
|
-- verifico se interseca uno dei setti successivi
|
|
for j = i + 1, #vRibsIds do
|
|
|
|
local bInters, bForceCutOnCrv1 = VerifyRibsIntersection( vRibsIds[i], vRibsIds[j], RIB_TYPE.INTERNAL, RIB_TYPE.INTERNAL, nShellSrf, nil, nGrpTmp, nOffsGrp)
|
|
if bInters then
|
|
bIntersection = true
|
|
local nCrv1 = vRibsIds[i] -- curva principale che non viene tagliata
|
|
local nCrv2 = vRibsIds[j] -- curve secondaria da modificare
|
|
if bForceCutOnCrv1 then
|
|
nCrv1, nCrv2 = nCrv2, nCrv1
|
|
end
|
|
|
|
-- verifico che la curva secondaria abbia una sola passata
|
|
local nShells2 = EgtGetInfo( nCrv2, KEY_RIBS_SHELLS_NBR, 'i')
|
|
if nShells2 > 1 then
|
|
EgtOutLog( 'Error : shell-merged ribs intersect in a non valid way (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : error in ribs-merged shells intersection')
|
|
return false
|
|
end
|
|
|
|
-- calcolo la superficie della curva principale ( nCrv1) da usare per trim
|
|
local nShells = EgtGetInfo( nCrv1, KEY_RIBS_SHELLS_NBR, 'i')
|
|
local dStrandOverlap = EgtGetInfo( nCrv1, KEY_RIBS_STRAND_OVERLAP, 'd')
|
|
local dOffs = (( nShells - 1) * ( 1 - dStrandOverlap / 100) * 0.5 + 1 - dOverlap / 100) * dStrand
|
|
local nSrf = EgtSurfFrFatCurve( nGrpTmp, nCrv1, dOffs, false, false, s_dOffsTol)
|
|
if not nSrf then
|
|
EgtOutLog( 'Error : EgtSurfFrFatCurve for shell-merged ribs intersection failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : error in ribs-merged shells intersection')
|
|
return false
|
|
end
|
|
-- estraggo il loop
|
|
local nLoop, nCnt = EgtExtractSurfFrChunkLoops( nSrf, 0, nGrpTmp)
|
|
|
|
-- taglio il setto secondario ( nCrv2)
|
|
local vOffs2 = EgtGetNameInGroup( nRibsGrp, EgtGetName( nCrv2)) or {}
|
|
for i = 1, #vOffs2 do
|
|
|
|
local nId, nCnt = EgtTrimCurveWithRegion( vOffs2[i], nSrf, false, true)
|
|
if nCnt == 0 then
|
|
-- il setto scompare
|
|
EgtErase( nId)
|
|
elseif nCnt > 1 then
|
|
-- verifico se posso ricollegare i tratti ottenuti per formare un setto unico
|
|
for nCrv = nId, nId + nCnt - 2 do
|
|
local dParS = EgtCurveParamAtPoint( nLoop, EgtEP( nCrv, GDB_ID.ROOT), 100 * GEO.EPS_SMALL, GDB_RT.GLOB)
|
|
local dParE = EgtCurveParamAtPoint( nLoop, EgtSP( nCrv + 1, GDB_ID.ROOT), 100 * GEO.EPS_SMALL, GDB_RT.GLOB)
|
|
local nLinkId = ComputeShortestLinkOnCurve( nLoop, dParS, dParE, nRibsGrp)
|
|
if nLinkId then
|
|
local nRes = EgtCurveWithRegionClassify( nLinkId, nShellSrf)
|
|
if nRes == GDB_CRC.IN then
|
|
-- fillet
|
|
AddFillet( nCrv, {nLinkId}, nCrv + 1, nRibsGrp)
|
|
EgtAddCurveCompoCurve( nCrv + 1, nLinkId, true, false)
|
|
EgtAddCurveCompoCurve( nCrv + 1, nCrv, true, false)
|
|
else
|
|
-- tipo di intersezione non permessa
|
|
EgtOutLog( 'Error : shell-merged ribs intersect in a non valid way (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : error in ribs-merged shells intersection')
|
|
return false
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- aggiorno le superfici da utilizzare per creare collegamenti
|
|
if not EgtSurfFrSubtract( nShellSrfInters, nSrf) or not EgtSurfFrSubtract( nTrimSrfInters, nSrf) then
|
|
EgtOutLog( 'Error : EgtSurfFrSubtract with shell-merged ribs intersection failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : error in ribs-merged shells intersection')
|
|
return false
|
|
end
|
|
EgtErase( nSrf)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- se ho trovato intersezioni estraggo i loop delle superfici ausiliarie
|
|
if bIntersection then
|
|
GetPathsFromSurf( nShellSrfInters, SURF_LOOP, nil, nLoopGrp)
|
|
GetPathsFromSurf( nTrimSrfInters, TRIM_SURF_LOOP, nil, nLoopGrp)
|
|
end
|
|
EgtErase( nShellSrfInters)
|
|
EgtErase( nTrimSrfInters)
|
|
EgtErase( nGrpTmp)
|
|
|
|
return true
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function PrepareRibsForMergeWithShells( vOrigRibs, nGrp, dStrand, dOverlap, bInvertRibsOrder)
|
|
|
|
-- verifico se sono presenti buchi che possono essere chiusi
|
|
VerifyRibsHoles( vOrigRibs)
|
|
|
|
-- trim grossolano dei setti
|
|
local nSrfCoarseTrim = EgtGetFirstNameInGroup( nGrp, COARSE_TRIM_SURF)
|
|
local nTrimGrp = TrimRibs( vOrigRibs, nGrp, nSrfCoarseTrim, GDB_ID.NULL)
|
|
|
|
-- calcolo offset orientati
|
|
local nOffsGrp = ComputeRibsOrientedOffset( nTrimGrp)
|
|
|
|
-- trim con la regione della shell
|
|
local nRibsGrp = EgtGroup( nGrp)
|
|
local nSrfShell = EgtGetFirstNameInGroup( nGrp, SHELL_SURF)
|
|
local nSrfTrim = EgtGetFirstNameInGroup( nGrp, TOT_SHELL_TRIM_SURF)
|
|
local vRibs = EgtGetAllInGroup( nOffsGrp)
|
|
for i = 1, #vRibs do
|
|
-- copio i setti nel gruppo dei conti
|
|
local nCopy = EgtCopyGlob( vRibs[i], nRibsGrp)
|
|
-- trim
|
|
local nRes, nCnt = EgtTrimCurveWithRegion( nCopy, nSrfShell, true, true)
|
|
if nCnt == 0 then
|
|
EgtErase( nRes)
|
|
end
|
|
for nId = nRes, nRes + nCnt - 1 do
|
|
-- verifico se si trova nella regione di trim
|
|
local nClassif = EgtCurveWithRegionClassify( nId, nSrfTrim)
|
|
if nClassif == GDB_CRC.OUT then
|
|
EgtErase( nId)
|
|
end
|
|
end
|
|
end
|
|
local vIds = EgtGetAllInGroup( nRibsGrp) or {}
|
|
if #vIds == 0 then return end
|
|
|
|
-- gestione delle intersezioni
|
|
local nLoopGrp = EgtGetFirstNameInGroup( nGrp, LOOP_GRP)
|
|
if not HandleRibsIntersectionForRibsMergedShells( vOrigRibs, nRibsGrp, nOffsGrp, nLoopGrp, dStrand, dOverlap) then
|
|
return
|
|
end
|
|
|
|
-- ordinamento
|
|
vIds = EgtGetAllInGroup( nRibsGrp)
|
|
ShortestPathForRibs( vIds, nRibsGrp, bInvertRibsOrder)
|
|
|
|
-- elimino elementi superflui per passaggi successivi
|
|
EgtErase( nTrimGrp)
|
|
EgtErase( nOffsGrp)
|
|
EgtErase( nSrfCoarseTrim)
|
|
EgtErase( nSrfShell)
|
|
|
|
return nRibsGrp
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function CreateRibsMergedShellLastLink( vShells, vRibs, nGrp, bInvert)
|
|
|
|
for i = 1, #vShells do
|
|
|
|
local dParS = EgtCurveParamAtPoint( vShells[i], EgtSP( vRibs[1], GDB_ID.ROOT), 100 * GEO.EPS_SMALL, GDB_RT.GLOB)
|
|
local dParE = EgtCurveParamAtPoint( vShells[i], EgtEP( vRibs[#vRibs], GDB_ID.ROOT), 100 * GEO.EPS_SMALL, GDB_RT.GLOB)
|
|
if dParS and dParE then
|
|
|
|
local nLink = EgtCopyGlob( vShells[i], nGrp)
|
|
if bInvert then
|
|
-- conservo tratto dParS->dParE
|
|
EgtTrimCurveStartEndAtParam( nLink, dParS, dParE)
|
|
EgtInvertCurve( nLink)
|
|
else
|
|
-- conservo tratto dParE->dParS
|
|
EgtTrimCurveStartEndAtParam( nLink, dParE, dParS)
|
|
end
|
|
|
|
-- sistemo i setti che hanno tratti nella regione occupata dal last link
|
|
local dStrand = EgtGetInfo( vRibs[1], KEY_RIBS_STRAND, 'd')
|
|
local nLinkSrf = EgtSurfFrFatCurve( nGrp, nLink, dStrand, false, false, s_dOffsTol)
|
|
if not nLinkSrf then
|
|
return nLink
|
|
end
|
|
local nLoopGrp = EgtGetFirstNameInGroup( nGrp, LOOP_GRP)
|
|
local vLoops = EgtGetNameInGroup( nLoopGrp, TRIM_SURF_LOOP)
|
|
local nTrimSurf = EgtGetFirstNameInGroup( nGrp, TOT_SHELL_TRIM_SURF)
|
|
for i = 1, #vRibs do
|
|
-- individuo i tratti del setto esterni alla superficie di trim
|
|
local nCopyCrv = EgtCopyGlob( vRibs[i], nGrp)
|
|
local nCrv, nCnt = EgtTrimCurveWithRegion( nCopyCrv, nTrimSurf, false, false)
|
|
if nCrv then
|
|
for nId = nCrv, nCrv + nCnt - 1 do
|
|
-- ignoro i tratti esterni che corrispondono allo start e all'end della curva
|
|
if not AreSamePointApprox( EgtSP( nId), EgtSP( vRibs[i])) and not AreSamePointApprox( EgtEP( nId), EgtEP( vRibs[i])) then
|
|
-- verifico se giace nella regione occupata dal last link
|
|
local nRes = EgtCurveWithRegionClassify( nId, nLinkSrf)
|
|
if nRes ~= GDB_CRC.OUT then
|
|
local nOtherPart = EgtCopyGlob( vRibs[i], nGrp)
|
|
local ptS = EgtSP( nId, GDB_ID.ROOT)
|
|
local ptE = EgtEP( nId, GDB_ID.ROOT)
|
|
local dPar1 = EgtCurveParamAtPoint( vRibs[i], ptS, 100 * GEO.EPS_SMALL, GDB_RT.GLOB)
|
|
local dPar2 = EgtCurveParamAtPoint( vRibs[i], ptE, 100 * GEO.EPS_SMALL, GDB_RT.GLOB)
|
|
EgtTrimCurveEndAtParam( vRibs[i], dPar1)
|
|
EgtTrimCurveStartAtParam( nOtherPart, dPar2)
|
|
-- creo il collegamento
|
|
local nPartLink
|
|
for i = 1, #vLoops do
|
|
local dParS = EgtCurveParamAtPoint( vLoops[i], ptS, 100 * GEO.EPS_SMALL, GDB_RT.GLOB)
|
|
local dParE = EgtCurveParamAtPoint( vLoops[i], ptE, 100 * GEO.EPS_SMALL, GDB_RT.GLOB)
|
|
if dParS and dParE then
|
|
nPartLink = ComputeShortestLinkOnCurve( vLoops[i], dParS, dParE, nGrp)
|
|
end
|
|
end
|
|
if nPartLink then
|
|
-- fillet
|
|
AddFillet( vRibs[i], {nPartLink}, nOtherPart, nGrp)
|
|
EgtAddCurveCompoCurve( vRibs[i], nPartLink)
|
|
EgtAddCurveCompoCurve( vRibs[i], nOtherPart)
|
|
end
|
|
end
|
|
end
|
|
EgtErase( nId)
|
|
end
|
|
end
|
|
end
|
|
EgtErase( nLinkSrf)
|
|
return nLink
|
|
end
|
|
end
|
|
|
|
-- se non ho trovato curva per il link segnalo errore
|
|
EgtOutLog( 'Error : creation of ribs-merged shells main link failed. Ribs not ending on same shell (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : error in computing ribs-merged shells (ribs link not possible)')
|
|
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function CreateRibsMergedShellLink( nCurr, nNext, nGrp, vLoops, nCheckGrp)
|
|
|
|
for i = 1, #vLoops do
|
|
local dParS = EgtCurveParamAtPoint( vLoops[i], EgtEP( nCurr, GDB_ID.ROOT), 100 * GEO.EPS_SMALL, GDB_RT.GLOB)
|
|
local dParE = EgtCurveParamAtPoint( vLoops[i], EgtSP( nNext, GDB_ID.ROOT), 100 * GEO.EPS_SMALL, GDB_RT.GLOB)
|
|
if dParS and dParE then
|
|
|
|
-- cerco il più corto fra i percorsi dParS->dParE e dParE->dParS
|
|
local nLinkId = ComputeShortestLinkOnCurve( vLoops[i], dParS, dParE, nGrp)
|
|
|
|
-- verifico sia sensato :
|
|
local nCurrCheck = EgtGetInfo( nCurr, KEY_ASSOCIATED_CRVS, 'i')
|
|
local nNextCheck = EgtGetInfo( nNext, KEY_ASSOCIATED_CRVS, 'i')
|
|
local frLoc = Frame3d( ORIG(), s_vtSlicing)
|
|
local nGrpLoc = EgtGroup( nGrp, frLoc, GDB_RT.GLOB)
|
|
|
|
-- a) verifico direzione
|
|
-- verifico se interseca uno dei due setti in un altro punto oltre all'estremo interessato dal collegamento
|
|
local _, nPntCnt1 = EgtCurveCurveInters( nCurrCheck, nLinkId, nGrpLoc)
|
|
local _, nPntCnt2 = EgtCurveCurveInters( nNextCheck, nLinkId, nGrpLoc)
|
|
if nPntCnt1 > 1 or nPntCnt2 > 1 then
|
|
EgtOutLog( 'Error : creation of ribs-merged shells failed for inconsistent ribs directions (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : error in ribs-merged shells (inconsistent ribs direction)')
|
|
EgtErase( nLinkId)
|
|
EgtErase( nGrpLoc)
|
|
return
|
|
end
|
|
|
|
-- b) verifico ordinamento
|
|
-- verifico se interseca uno degli altri setti
|
|
local vCheckIds = EgtGetAllInGroup( nCheckGrp) or {}
|
|
for i = 1, #vCheckIds do
|
|
if vCheckIds[i] ~= nCurrCheck and vCheckIds[i] ~= nNextCheck then
|
|
local _, nPntCnt, nCrvCnt = EgtCurveCurveInters( vCheckIds[i], nLinkId, nGrpLoc)
|
|
if nPntCnt > 0 or nCrvCnt > 0 then
|
|
EgtOutLog( 'Error : creation of ribs-merged shells failed for inconsistent ribs order (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : error in ribs-merged shells (inconsistent ribs order)')
|
|
EgtErase( nLinkId)
|
|
EgtErase( nGrpLoc)
|
|
return
|
|
end
|
|
end
|
|
end
|
|
EgtErase( nGrpLoc)
|
|
|
|
return nLinkId
|
|
end
|
|
end
|
|
|
|
-- se sono passate relative allo stesso setto possono essere collegate con tratto lineare anche se non poggiano sulle curve di bordo
|
|
-- ( caso di setto che non arriva fino al bordo)
|
|
local nOrig1 = EgtGetInfo( nCurr, KEY_ORIGINAL_RIB, 'i')
|
|
local nOrig2 = EgtGetInfo( nNext, KEY_ORIGINAL_RIB, 'i')
|
|
local nSplit1 = EgtGetInfo( nCurr, KEY_SPLIT_ID, 'i') or 0
|
|
local nSplit2 = EgtGetInfo( nNext, KEY_SPLIT_ID, 'i') or 0
|
|
if nOrig1 == nOrig2 and nSplit1 == nSplit2 then
|
|
local nLinkId = EgtCurveCompoFromPoints( nGrp, {EgtEP( nCurr, GDB_ID.ROOT), EgtSP( nNext, GDB_ID.ROOT)}, GDB_RT.GLOB)
|
|
return nLinkId
|
|
end
|
|
|
|
-- se il link non è stato creato errore
|
|
EgtOutLog( 'Error : creation of ribs-merged shells link failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : error in ribs-merged shells (ribs link not possible)')
|
|
return
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function AdjustRibsMergedExtraShellLink( nLinkId, vExtraShells, nGrp)
|
|
|
|
local frLoc = Frame3d( ORIG(), s_vtSlicing)
|
|
local nGrpLoc = EgtGroup( nGrp, frLoc)
|
|
local vLinks = {}
|
|
|
|
-- devo conservare solo le intersezioni fra link ed extra shell
|
|
for i = 1, #vExtraShells do
|
|
local nRes, nPntCnt, nCrvCnt = EgtCurveCurveInters( nLinkId, vExtraShells[i], nGrpLoc)
|
|
if nRes then
|
|
for nId = nRes + nPntCnt, nRes + nPntCnt + nCrvCnt - 1 do
|
|
EgtRelocateGlob( nId, nGrp)
|
|
EgtModifyCurveExtrusion( nId, s_vtSlicing, GDB_ID.ROOT)
|
|
table.insert( vLinks, nId)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- cancello il link originale
|
|
EgtErase( nLinkId)
|
|
EgtErase( nGrpLoc)
|
|
return vLinks
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function CreateRibsMergedShellCurve( nGrp, nRibsGrp, vShells, vOrigShells, dStrand, LayerParams, bExtraShell)
|
|
|
|
local vOrigRibs = EgtGetAllInGroup( nRibsGrp)
|
|
local vRibs = {}
|
|
for i = 1, #vOrigRibs do
|
|
local nCopy = EgtCopyGlob( vOrigRibs[i], nGrp)
|
|
EgtSetInfo( nCopy, KEY_ASSOCIATED_CRVS, vOrigRibs[i])
|
|
table.insert( vRibs, nCopy)
|
|
end
|
|
|
|
local nLoopGrp = EgtGetFirstNameInGroup( nGrp, LOOP_GRP)
|
|
local vLoopsTrim = EgtGetNameInGroup( nLoopGrp, TRIM_SURF_LOOP)
|
|
local vLoopsShell = EgtGetNameInGroup( nLoopGrp, SURF_LOOP)
|
|
local nTrimSurf = EgtGetFirstNameInGroup( nGrp, TOT_SHELL_TRIM_SURF)
|
|
|
|
-- creo ultimo link
|
|
local nLastLink = CreateRibsMergedShellLastLink( vShells, vRibs, nGrp, LayerParams.bInvertRibsMergedShellLink)
|
|
if not nLastLink then return false end
|
|
|
|
-- creo collegamenti interni
|
|
for i = 1, #vRibs - 1 do
|
|
local nCurr = vRibs[i]
|
|
local nNext = vRibs[i+1]
|
|
|
|
-- verifico se posso collegare sulla shell
|
|
local bLinkOnShell = true
|
|
local dPar1 = EgtCurveParamAtPoint( nLastLink, EgtEP( nCurr, GDB_ID.ROOT), 100 * GEO.EPS_SMALL, GDB_RT.GLOB)
|
|
local dPar2 = EgtCurveParamAtPoint( nLastLink, EgtSP( nNext, GDB_ID.ROOT), 100 * GEO.EPS_SMALL, GDB_RT.GLOB)
|
|
if dPar1 or dPar2 then
|
|
-- il collegamento sulla shell non è fattibile, quindi trimmo opportunamente i setti in modo che finiscano sulla curva di trim
|
|
TrimCurveExtremity( nCurr, nTrimSurf, false, nGrp)
|
|
TrimCurveExtremity( nNext, nTrimSurf, true, nGrp)
|
|
bLinkOnShell = false
|
|
end
|
|
|
|
-- creo il link
|
|
local nLinkId = CreateRibsMergedShellLink( nCurr, nNext, nGrp, EgtIf( bLinkOnShell, vLoopsShell, vLoopsTrim), nRibsGrp)
|
|
if not nLinkId then
|
|
return false
|
|
end
|
|
|
|
-- se link fatto sulla shell verifico non si sovrapponga al last link
|
|
-- ( il caso di setti che terminano su intersezione con altro setto non è rilevato dal controllo iniziale)
|
|
if bLinkOnShell then
|
|
local frLoc = Frame3d( ORIG(), s_vtSlicing)
|
|
local nGrpLoc = EgtGroup( nGrp, frLoc, GDB_RT.GLOB)
|
|
local nRes = EgtCurveCurveInters( nLinkId, nLastLink, nGrpLoc)
|
|
-- se sovrapposizione, tento con il link sul trim
|
|
if nRes then
|
|
bLinkOnShell = false
|
|
EgtErase( nLinkId)
|
|
nLinkId = CreateRibsMergedShellLink( nCurr, nNext, nGrp, vLoopsTrim, nRibsGrp)
|
|
if not nLinkId then
|
|
return false
|
|
end
|
|
end
|
|
EgtErase( nGrpLoc)
|
|
end
|
|
|
|
-- verifico se necessari aggiustamenti per extra shell
|
|
local vLinks
|
|
if bExtraShell and bLinkOnShell then
|
|
vLinks = AdjustRibsMergedExtraShellLink( nLinkId, vOrigShells, nGrp)
|
|
end
|
|
|
|
-- fillet
|
|
AddFillet( nCurr, vLinks or {nLinkId}, nNext, nGrp)
|
|
|
|
end
|
|
|
|
-- eventuali aggiustamenti del last link per extra shell
|
|
local vLastLinks
|
|
if bExtraShell then
|
|
vLastLinks = AdjustRibsMergedExtraShellLink( nLastLink, vOrigShells, nGrp)
|
|
end
|
|
|
|
-- fillet sul last link
|
|
AddFillet( vRibs[#vRibs], vLastLinks or {nLastLink}, vRibs[1], nGrp)
|
|
|
|
-- elimino le curve inutili e le superfici
|
|
EgtErase( nRibsGrp)
|
|
EgtErase( nTrimSurf)
|
|
EgtErase( nLoopGrp)
|
|
|
|
return true
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function AssignRibsMergedExtraShellsLeadOutInfo( nCrv, vShells, LayerParams, dStrand)
|
|
|
|
local vCoastLen = { LayerParams.dShellNbrCoasting, LayerParams.dShellNbrCoasting}
|
|
local vWipeLen = { LayerParams.dShellNbrWipe, LayerParams.dShellNbrWipe}
|
|
local vWipeDir = { LayerParams.dShellNbrWipeDir, LayerParams.dShellNbrWipeDir}
|
|
|
|
local bFoundS = false
|
|
local bFoundE = false
|
|
local ptS = EgtSP( nCrv, GDB_ID.ROOT)
|
|
local ptE = EgtEP( nCrv, GDB_ID.ROOT)
|
|
|
|
for i = 1, #vShells do
|
|
-- recupero le info della shell attuale
|
|
local vShellCoastLen = EgtGetInfo( vShells[i], KEY_EXTRA_SHELL_COASTING, 'vd')
|
|
local vShellWipeLen = EgtGetInfo( vShells[i], KEY_EXTRA_SHELL_WIPE, 'vd')
|
|
local vShellWipeDir = EgtGetInfo( vShells[i], KEY_EXTRA_SHELL_WIPE_DIR, 'vd')
|
|
|
|
-- verifico se posso usarle per settare info per lo start point
|
|
if not bFoundS then
|
|
if AreSamePointEpsilon( ptS, EgtSP( vShells[i], GDB_ID.ROOT), dStrand) then
|
|
bFoundS = true
|
|
vCoastLen[1] = vShellCoastLen[1]
|
|
vWipeLen[1] = vShellWipeLen[1]
|
|
vWipeDir[1] = vShellWipeDir[1]
|
|
elseif AreSamePointEpsilon( ptS, EgtEP( vShells[i], GDB_ID.ROOT), dStrand) then
|
|
bFoundS = true
|
|
vCoastLen[1] = vShellCoastLen[2]
|
|
vWipeLen[1] = vShellWipeLen[2]
|
|
vWipeDir[1] = vShellWipeDir[2]
|
|
end
|
|
end
|
|
|
|
-- verifico se posso usarle per settare info per l'end point
|
|
if not bFoundE then
|
|
if AreSamePointEpsilon( ptE, EgtSP( vShells[i], GDB_ID.ROOT), dStrand) then
|
|
bFoundE = true
|
|
vCoastLen[2] = vShellCoastLen[1]
|
|
vWipeLen[2] = vShellWipeLen[1]
|
|
vWipeDir[2] = vShellWipeDir[1]
|
|
elseif AreSamePointEpsilon( ptE, EgtEP( vShells[i], GDB_ID.ROOT), dStrand) then
|
|
bFoundE = true
|
|
vCoastLen[2] = vShellCoastLen[2]
|
|
vWipeLen[2] = vShellWipeLen[2]
|
|
vWipeDir[2] = vShellWipeDir[2]
|
|
end
|
|
end
|
|
|
|
-- se ho trovato sia start sia end termino la ricerca
|
|
if bFoundS and bFoundE then
|
|
break
|
|
end
|
|
end
|
|
|
|
-- setto le info alla nuova shell
|
|
EgtSetInfo( nCrv, KEY_EXTRA_SHELL_COASTING, vCoastLen)
|
|
EgtSetInfo( nCrv, KEY_EXTRA_SHELL_WIPE, vWipeLen)
|
|
EgtSetInfo( nCrv, KEY_EXTRA_SHELL_WIPE_DIR, vWipeDir)
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function UpdateTrimSurfWithRibsMergedShell( nPathGrp, sName, LayerParams)
|
|
|
|
local nCrvGrp = EgtGetParent( nPathGrp)
|
|
local nOldTrimSurf = EgtGetFirstNameInGroup( nCrvGrp, TOT_SHELL_TRIM_SURF)
|
|
|
|
-- calcolo la nuova superficie di trim a partire dalla regione occupata dall'ultima shell completa che conservo
|
|
local nFirstShell = EgtGetFirstNameInGroup( nPathGrp, sName)
|
|
local nPrevShell = EgtGetPrev( nFirstShell)
|
|
local dOffs
|
|
if nPrevShell then
|
|
dOffs = EgtGetInfo( nPrevShell, KEY_CRV_OFFSET, 'd')
|
|
local nType = EgtGetInfo( nPrevShell, KEY_TYPE, 'i')
|
|
local dPrevStrand = EgtIf( nType == TYPE.OUTER_SHELL, LayerParams.dStrand, LayerParams.dInnerStrand)
|
|
dOffs = dOffs + 0.5 * dPrevStrand
|
|
else
|
|
dOffs = - LayerParams.dOffs
|
|
end
|
|
|
|
local nLaySurf = EgtGetFirstNameInGroup( nCrvGrp, LAYER_SRF)
|
|
local nNewTrimSurf = ComputeSurfOffset( nLaySurf, nCrvGrp, - dOffs)
|
|
if not nNewTrimSurf then
|
|
EgtOutLog( 'Error : ComputeSurfOffset with ribs-merged shell for TotTrimSurfRegion failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : error in computing region for internal elements')
|
|
return false
|
|
end
|
|
EgtSetName( nNewTrimSurf, TOT_SHELL_TRIM_SURF)
|
|
|
|
-- aggiorno con le nuove shell appena modificate
|
|
local vNewShells = EgtGetNameInGroup( nPathGrp, sName) or {}
|
|
local bOk = true
|
|
local dStrand
|
|
for i = 1, #vNewShells do
|
|
-- calcolo la regione occupata dalla nuova shell
|
|
local nType = EgtGetInfo( vNewShells[i], KEY_TYPE, 'i')
|
|
dStrand = EgtIf( nType == TYPE.OUTER_SHELL or nType == TYPE.EXTRA_OUTER_SHELL, LayerParams.dStrand, LayerParams.dInnerStrand)
|
|
local nSrfShell = EgtSurfFrFatCurve( nCrvGrp, vNewShells[i], dStrand * 0.5 + s_dOffsCorr, false, false, s_dOffsTol)
|
|
if nSrfShell then
|
|
if not EgtSurfFrSubtract( nNewTrimSurf, nSrfShell) then
|
|
EgtOutLog( 'Error : EgtSurfFrSubtract with ribs-merged shell for TotTrimSurfRegion failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
bOk = false
|
|
end
|
|
EgtErase( nSrfShell)
|
|
else
|
|
EgtOutLog( 'Error : EgtSurfFrFatCurve with ribs-merged shell for TotTrimSurfRegion failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
bOk = false
|
|
end
|
|
end
|
|
if not bOk then
|
|
table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : error in computing region for internal elements')
|
|
end
|
|
|
|
-- aggiorno la trim surf eliminando piccole zone non riempite tra le shell
|
|
local dCurrOffs = EgtGetInfo( vNewShells[#vNewShells], KEY_CRV_OFFSET, 'd')
|
|
AdjustTrimSurfExtraAngleChunks( nNewTrimSurf, dCurrOffs, dStrand)
|
|
|
|
-- elimino la vecchia superficie di trim
|
|
EgtErase( nOldTrimSurf)
|
|
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function CalcRibsMergedShells( nSlicedRibsGrp, nPathGrp, LayerParams, vPtStart)
|
|
|
|
if not nSlicedRibsGrp then return true end
|
|
|
|
-- recupero i setti interni/supporto da collegare alla shell
|
|
local vAllRibs = EgtGetAllInGroup( nSlicedRibsGrp)
|
|
local vOrigRibs = {}
|
|
for i = 1, #vAllRibs do
|
|
local nType = EgtGetInfo( vAllRibs[i], KEY_RIBS_TYPE, 'i')
|
|
local bMergeWithShell = EgtGetInfo( vAllRibs[i], KEY_RIBS_MERGE_WITH_SHELLS, 'b') or false
|
|
if ( nType == RIB_TYPE.INTERNAL or nType == RIB_TYPE.SUPPORT) and bMergeWithShell then
|
|
table.insert( vOrigRibs, vAllRibs[i])
|
|
end
|
|
end
|
|
if #vOrigRibs == 0 then return true end
|
|
|
|
-- recupero le shell da unire ai setti
|
|
local nLast = EgtGetLastInGroup( nPathGrp) or GDB_ID.NULL
|
|
local nShellType = EgtGetInfo( nLast, KEY_TYPE, 'i')
|
|
local bExtraShell = ( nShellType == TYPE.EXTRA_OUTER_SHELL or nShellType == TYPE.EXTRA_SHELL)
|
|
local sLastName = EgtGetName( nLast)
|
|
local vOrigShells = EgtGetNameInGroup( nPathGrp, sLastName) or {}
|
|
local tShells = PrepareShellsForRibsMerge( vOrigShells, bExtraShell)
|
|
if not tShells then return false end
|
|
if #tShells == 0 then return false end
|
|
|
|
-- sistemo gli strand dei setti per adattarli alla shell
|
|
local dStrand = EgtIf( nShellType == TYPE.OUTER_SHELL or nShellType == TYPE.EXTRA_OUTER_SHELL, LayerParams.dStrand, LayerParams.dInnerStrand)
|
|
for i = 1, #vOrigRibs do
|
|
EgtSetInfo( vOrigRibs[i], KEY_RIBS_STRAND, dStrand)
|
|
end
|
|
local dShellOffs = EgtGetInfo( vOrigShells[1], KEY_CRV_OFFSET, 'd')
|
|
|
|
-- per ogni gruppo di shell preparo il nuovo percorso
|
|
local bOk = true
|
|
for i = 1, #tShells do
|
|
|
|
-- gruppo per conti
|
|
local nGrp = EgtGroup( nPathGrp)
|
|
local bShellOk = false
|
|
|
|
-- preparo le superfici ausiliarie per la creazione delle shell
|
|
if PrepareAuxSurfsForRibsMerge( nGrp, tShells[i], dStrand, LayerParams) then
|
|
|
|
-- preparazione dei setti
|
|
local nRibsGrp = PrepareRibsForMergeWithShells( vOrigRibs, nGrp, dStrand, LayerParams.dStrandOverlap, LayerParams.bRibsInvertOrder)
|
|
if nRibsGrp then
|
|
-- combino i setti con le shell per creare il nuovo percorso
|
|
if CreateRibsMergedShellCurve( nGrp, nRibsGrp, tShells[i], vOrigShells, dStrand, LayerParams, bExtraShell) then
|
|
-- creo le nuove curve di shell
|
|
local nCrv, nCnt = EgtCurveCompoByChain( nGrp, EgtGetAllInGroup( nGrp), ORIG())
|
|
if nCrv and nCnt > 0 then
|
|
for nId = nCrv, nCrv + nCnt - 1 do
|
|
EgtRelocateGlob( nId, nPathGrp)
|
|
-- assegno info
|
|
EgtSetName( nId, sLastName)
|
|
EgtSetInfo( nId, KEY_TYPE, nShellType)
|
|
EgtSetInfo( nId, KEY_CRV_OFFSET, dShellOffs)
|
|
|
|
ModifyStartPoint( nId, vPtStart)
|
|
EgtModifyCurveExtrusion( nId, s_vtSlicing, GDB_RT.GLOB)
|
|
-- ripristino orientamento originale
|
|
if EgtCurveIsClosed( nId) then
|
|
local vtCrv = EgtCurveArea( nId)
|
|
if AreOppositeVectorApprox( vtCrv, s_vtSlicing) then
|
|
EgtInvertCurve( nId)
|
|
end
|
|
end
|
|
|
|
-- riassegno le info di lead out se extra shell
|
|
if bExtraShell then
|
|
AssignRibsMergedExtraShellsLeadOutInfo( nId, vOrigShells, LayerParams, dStrand)
|
|
end
|
|
end
|
|
|
|
-- cancello le shell e le shell originarie associati
|
|
for j = 1, #vOrigShells do
|
|
local ptRef = EgtMP( vOrigShells[j], GDB_ID.ROOT)
|
|
if ptRef then
|
|
for k = 1, #tShells[i] do
|
|
if EgtCurveParamAtPoint( tShells[i][k], ptRef, 100 * GEO.EPS_SMALL, GDB_RT.GLOB) then
|
|
EgtErase( vOrigShells[j])
|
|
vOrigShells[j] = GDB_ID.NULL
|
|
break
|
|
end
|
|
end
|
|
end
|
|
end
|
|
for j = 1, #tShells[i] do
|
|
EgtErase( tShells[i][j])
|
|
end
|
|
|
|
bShellOk = true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
if not bShellOk then bOk = false end
|
|
EgtErase( nGrp)
|
|
end
|
|
|
|
-- riordino rispetto alle shell precedenti
|
|
if not bExtraShell then
|
|
local nFirstShell = EgtGetFirstNameInGroup( nPathGrp, sLastName)
|
|
local nPrevShell = EgtGetPrev( nFirstShell)
|
|
if nPrevShell then
|
|
local vOldIds = EgtGetNameInGroup( nPathGrp, EgtGetName( nPrevShell))
|
|
local vNewIds = EgtGetNameInGroup( nPathGrp, sLastName)
|
|
ReorderPath( vOldIds, vNewIds)
|
|
end
|
|
end
|
|
|
|
-- aggiorno la superficie di trim con le nuove shell
|
|
UpdateTrimSurfWithRibsMergedShell( nPathGrp, EgtIf( bExtraShell, EXTRA_SHELL_CRV .. '*', sLastName), LayerParams)
|
|
|
|
-- se ho fallito in qualche merge i setti saranno considerati anche per la realizzazione standard
|
|
return bOk
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
----------------- REGIONI CON DIVERSE PASSATE ----------------------
|
|
--------------------------------------------------------------------
|
|
local function CreateShellNbrSurfaces( nGrp, nShellsNbr)
|
|
|
|
if not nGrp then return end
|
|
|
|
local tDiffCrvs = {}
|
|
local nMaxShellNbrDiff = 0
|
|
local nCrvId = EgtGetFirstNameInGroup( nGrp, SHELL_NBR_CRV .. '*')
|
|
while nCrvId do
|
|
if EgtCurveIsClosed( nCrvId) then
|
|
-- verifico se area significativa
|
|
local _, _, dArea = EgtCurveArea( nCrvId)
|
|
if dArea and dArea > GEO.EPS_SMALL then
|
|
-- recupero info sul gap
|
|
local nShellNbrDiff = EgtGetInfo( nCrvId, KEY_SHELL_NBR_DIFF, 'i')
|
|
-- aggiorno eventuale massimo
|
|
if nMaxShellNbrDiff < nShellNbrDiff then nMaxShellNbrDiff = nShellNbrDiff end
|
|
-- salvo gli id delle curve
|
|
if not tDiffCrvs[nShellNbrDiff] then
|
|
tDiffCrvs[nShellNbrDiff] = { nCrvId}
|
|
else
|
|
table.insert( tDiffCrvs[nShellNbrDiff], nCrvId)
|
|
end
|
|
else
|
|
EgtOutLog( 'Warning : ReducedShellNumber is too small (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
end
|
|
else
|
|
EgtOutLog( 'Error : ReducedShellNumber is not closed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : ReducedShellNumber is not closed')
|
|
end
|
|
|
|
nCrvId = EgtGetNextName( nCrvId, SHELL_NBR_CRV .. '*')
|
|
end
|
|
|
|
-- eventuale correzione del numero massimo in base al numero di passate
|
|
nMaxShellNbrDiff = min( nMaxShellNbrDiff, nShellsNbr)
|
|
|
|
-- costruisco per ogni valore la superficie complessiva
|
|
local nSrfGrp = EgtGroup( nGrp)
|
|
for nDiff = 1, nMaxShellNbrDiff do
|
|
-- recupero gli id delle curve coinvolte
|
|
local vCrvIds = {}
|
|
for nG, vIds in pairs( tDiffCrvs) do
|
|
if nG >= nDiff then
|
|
for k = 1, #vIds do
|
|
table.insert( vCrvIds, vIds[k])
|
|
end
|
|
end
|
|
end
|
|
-- costruisco la surf
|
|
local nSrfId
|
|
for i = 1, #vCrvIds do
|
|
local nSrfTmp = EgtSurfFlatRegion( nSrfGrp, vCrvIds[i])
|
|
local bOk = false
|
|
if nSrfTmp then
|
|
if not nSrfId then
|
|
-- se è la prima curva è quella che definisce la superficie
|
|
nSrfId = nSrfTmp
|
|
bOk = true
|
|
else
|
|
bOk = EgtSurfFrAdd( nSrfId, nSrfTmp)
|
|
EgtErase( nSrfTmp)
|
|
end
|
|
end
|
|
if not bOk then
|
|
EgtOutLog( 'Error : ReducedShellNumber is not considered (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : ReducedShellNumber is not considered')
|
|
end
|
|
end
|
|
if nSrfId then
|
|
EgtSetName( nSrfId, SHELL_NBR_SURF .. EgtNumToString( nDiff))
|
|
-- salvo come info gli id delle curve che la definiscono
|
|
EgtSetInfo( nSrfId, KEY_ASSOCIATED_CRVS, vCrvIds)
|
|
end
|
|
end
|
|
|
|
return nSrfGrp
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function ComputeMaxShellNbrDiff( nSrf, nShellNbrSurfGrp)
|
|
|
|
local nMaxShellNbrDiff = 0
|
|
if nShellNbrSurfGrp then
|
|
local nId = 1
|
|
local nShellNbrSrf = EgtGetFirstNameInGroup( nShellNbrSurfGrp, SHELL_NBR_SURF .. tostring( nId))
|
|
while nShellNbrSrf do
|
|
-- se interessa la regione considerata aggiorno il nMaxShellNbrDiff
|
|
if not EgtSurfFrTestExternal( nSrf, nShellNbrSrf) then
|
|
nMaxShellNbrDiff = nId
|
|
end
|
|
|
|
-- passo al successivo
|
|
nId = nId + 1
|
|
nShellNbrSrf = EgtGetFirstNameInGroup( nShellNbrSurfGrp, SHELL_NBR_SURF .. tostring( nId))
|
|
end
|
|
end
|
|
|
|
return nMaxShellNbrDiff
|
|
end
|
|
|
|
----------------------------------------------------------------
|
|
local function FindExtraShellRetractionParams( ptP, vIds, LayerParams)
|
|
|
|
local dCoasting, dWipe, dWipeDir
|
|
-- cerco la curva sulla quale si ferma
|
|
for i = 1, #vIds do
|
|
local dPar = EgtCurveParamAtPoint( vIds[i], ptP, 10 * GEO.EPS_SMALL)
|
|
if dPar then
|
|
dCoasting = EgtGetInfo( vIds[i], KEY_SHELL_NBR_COASTING, 'd')
|
|
dWipe = EgtGetInfo( vIds[i], KEY_SHELL_NBR_WIPE, 'd')
|
|
dWipeDir = EgtGetInfo( vIds[i], KEY_SHELL_NBR_WIPE_DIR, 'd')
|
|
break
|
|
end
|
|
end
|
|
|
|
if not dCoasting then
|
|
-- se non ho trovato una curva considero i parametri generali
|
|
return LayerParams.dShellNbrCoasting, LayerParams.dShellNbrWipe, LayerParams.dShellNbrWipeDir
|
|
else
|
|
return dCoasting, dWipe, dWipeDir
|
|
end
|
|
end
|
|
|
|
-----------------------------------------------------------------
|
|
local function TrimOuterCurveForExtraShellCalc( nOuterCrv, nSrfDiff, nGrpId, vPtStart, LayerParams)
|
|
|
|
local nCopy = EgtCopyGlob( nOuterCrv, nGrpId)
|
|
ModifyStartPoint( nCopy, vPtStart)
|
|
-- recupero tutte le curve delle ShellNumber coinvolte
|
|
local vShellNbrCrvs = EgtGetInfo( nSrfDiff, KEY_ASSOCIATED_CRVS, 'vi')
|
|
|
|
-- trim della curva
|
|
local nCrv, nCnt = EgtTrimCurveWithRegion( nCopy, nSrfDiff, false, false)
|
|
if nCrv and nCnt ~= 0 then
|
|
|
|
-- verifico se prima e ultima curva possono essere unite
|
|
if nCnt > 1 and AreSamePointApprox( EgtEP( nCrv + nCnt - 1), EgtSP( nCrv)) then
|
|
EgtRelocateGlob( nCrv + nCnt - 1, nCrv, GDB_IN.AFTER)
|
|
EgtAddCurveCompoCurve( nCrv + nCnt - 1, nCrv)
|
|
EgtChangeId( nCrv + nCnt - 1, nCrv)
|
|
nCnt = nCnt - 1
|
|
end
|
|
|
|
for nId = nCrv, nCrv + nCnt - 1 do
|
|
-- assegno estrusione
|
|
EgtModifyCurveExtrusion( nCrv, s_vtSlicing, GDB_RT.GLOB)
|
|
-- assegno le info per leadout
|
|
local ptS = EgtSP( nId)
|
|
local dCoastingS, dWipeS, dWipeDirS = FindExtraShellRetractionParams( ptS, vShellNbrCrvs, LayerParams)
|
|
local ptE = EgtEP( nId)
|
|
local dCoastingE, dWipeE, dWipeDirE = FindExtraShellRetractionParams( ptE, vShellNbrCrvs, LayerParams)
|
|
EgtSetInfo( nId, KEY_EXTRA_SHELL_COASTING, {dCoastingS, dCoastingE})
|
|
EgtSetInfo( nId, KEY_EXTRA_SHELL_WIPE, {dWipeS, dWipeE})
|
|
EgtSetInfo( nId, KEY_EXTRA_SHELL_WIPE_DIR, {dWipeDirS, dWipeDirE})
|
|
end
|
|
return nCrv, nCnt
|
|
else
|
|
return nOuterCrv, 0
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function UpdateTrimSurfWithExtraShell( nSrf, nCrv, dStrand, nGrpId)
|
|
|
|
local nSrfExtraShell = EgtSurfFrFatCurve( nGrpId, nCrv, dStrand * 0.5 + s_dOffsCorr, true, false, s_dOffsTol)
|
|
if nSrfExtraShell then
|
|
if not EgtSurfFrSubtract( nSrf, nSrfExtraShell) then
|
|
EgtOutLog( 'Error : EgtSurfFrSubtract with ExtraShell for TotTrimSurfRegion failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : error in computing region for internal elements')
|
|
end
|
|
EgtErase( nSrfExtraShell)
|
|
else
|
|
EgtOutLog( 'Error : creation of ExtraShell region for TotTrimSurfRegion failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : error in computing region for internal elements')
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function UpdateExtraShellRetractionParamsAfterMerge( nCrv1, nCrv2, nCase)
|
|
|
|
-- recupero le info delle due curve da combinare
|
|
local vCoast1 = EgtGetInfo( nCrv1, KEY_EXTRA_SHELL_COASTING, 'vi')
|
|
local vCoast2 = EgtGetInfo( nCrv2, KEY_EXTRA_SHELL_COASTING, 'vi')
|
|
local vWipe1 = EgtGetInfo( nCrv1, KEY_EXTRA_SHELL_WIPE, 'vi')
|
|
local vWipe2 = EgtGetInfo( nCrv2, KEY_EXTRA_SHELL_WIPE, 'vi')
|
|
local vWipeDir1 = EgtGetInfo( nCrv1, KEY_EXTRA_SHELL_WIPE_DIR, 'vi')
|
|
local vWipeDir2 = EgtGetInfo( nCrv2, KEY_EXTRA_SHELL_WIPE_DIR, 'vi')
|
|
|
|
local vCoast, vWipe, vWipeDir
|
|
|
|
if nCase == 1 then
|
|
-- ep di nCrv1 e sp di nCrv2
|
|
vCoast = { vCoast1[1], vCoast2[2]}
|
|
vWipe = { vWipe1[1], vWipe2[2]}
|
|
vWipeDir = { vWipeDir1[1], vWipeDir2[2]}
|
|
elseif nCase == 2 then
|
|
-- sp di nCrv1 ed ep di nCrv2
|
|
vCoast = { vCoast2[1], vCoast1[2]}
|
|
vWipe = { vWipe2[1], vWipe1[2]}
|
|
vWipeDir = { vWipeDir2[1], vWipeDir1[2]}
|
|
elseif nCase == 3 then
|
|
-- ep di nCrv1 e ep di nCrv2
|
|
vCoast = { vCoast1[1], vCoast2[1]}
|
|
vWipe = { vWipe1[1], vWipe2[1]}
|
|
vWipeDir = { vWipeDir1[1], vWipeDir2[1]}
|
|
elseif nCase == 4 then
|
|
-- sp di nCrv1 e sp di nCrv2
|
|
vCoast = { vCoast2[2], vCoast1[2]}
|
|
vWipe = { vWipe2[2], vWipe1[2]}
|
|
vWipeDir = { vWipeDir2[2], vWipeDir1[2]}
|
|
end
|
|
|
|
EgtErase( nCrv2)
|
|
EgtSetInfo( nCrv1, KEY_EXTRA_SHELL_COASTING, vCoast)
|
|
EgtSetInfo( nCrv1, KEY_EXTRA_SHELL_WIPE, vWipe)
|
|
EgtSetInfo( nCrv1, KEY_EXTRA_SHELL_WIPE_DIR, vWipeDir)
|
|
|
|
end
|
|
---------------------------------------------------------------------
|
|
local function ReorderExtraShells( nPathGrp, vPtStart, LayerParams)
|
|
|
|
local dAlpha = 1.2
|
|
|
|
-- verifico se posso unire due tratti consecutivi della stessa shell aggiornando opportunamente le info per il lead out
|
|
local nFirst = EgtGetFirstNameInGroup( nPathGrp, EXTRA_SHELL_CRV .. '*')
|
|
if not nFirst then return end
|
|
|
|
while nFirst do
|
|
-- recupero tratti appartenenti alla stessa shell
|
|
local sName = EgtGetName( nFirst)
|
|
local vShells = EgtGetNameInGroup( nPathGrp, sName)
|
|
-- inserisco la prima shell anche in fondo alla tabella per garantire anche il confronto fra l'ultima e la prima
|
|
table.insert( vShells, vShells[1])
|
|
local nType = EgtGetInfo( nFirst, KEY_TYPE, 'i')
|
|
local dStrand = EgtIf( nType == TYPE.EXTRA_OUTER_SHELL, LayerParams.dStrand, LayerParams.dInnerStrand)
|
|
local nCurr = vShells[1]
|
|
for i = 2, #vShells do
|
|
if nCurr == vShells[i] then
|
|
-- nell'ultimo confronto ( ultima e prima extra shell) potresti confrontare una curva con se stessa
|
|
break
|
|
end
|
|
|
|
if dist( EgtSP( nCurr), EgtSP( vShells[i])) < dAlpha * dStrand + GEO.EPS_SMALL then
|
|
-- start- start
|
|
EgtAddCurveCompoLine( nCurr, EgtSP( vShells[i]), false)
|
|
EgtInvertCurve( vShells[i])
|
|
EgtAddCurveCompoCurve( nCurr, vShells[i], false, false)
|
|
UpdateExtraShellRetractionParamsAfterMerge( nCurr, vShells[i], 4)
|
|
|
|
elseif dist( EgtSP( nCurr), EgtEP( vShells[i])) < dAlpha * dStrand + GEO.EPS_SMALL then
|
|
-- start - end
|
|
EgtAddCurveCompoLine( nCurr, EgtEP( vShells[i]), false)
|
|
EgtAddCurveCompoCurve( nCurr, vShells[i], false, false)
|
|
UpdateExtraShellRetractionParamsAfterMerge( nCurr, vShells[i], 2)
|
|
|
|
elseif dist( EgtEP( nCurr), EgtSP( vShells[i])) < dAlpha * dStrand + GEO.EPS_SMALL then
|
|
-- end - start
|
|
EgtAddCurveCompoLine( nCurr, EgtSP( vShells[i]))
|
|
EgtAddCurveCompoCurve( nCurr, vShells[i], false)
|
|
UpdateExtraShellRetractionParamsAfterMerge( nCurr, vShells[i], 1)
|
|
|
|
elseif dist( EgtEP( nCurr), EgtEP( vShells[i])) < dAlpha * dStrand + GEO.EPS_SMALL then
|
|
-- end - end
|
|
EgtAddCurveCompoLine( nCurr, EgtEP( vShells[i]))
|
|
EgtInvertCurve( vShells[i])
|
|
EgtAddCurveCompoCurve( nCurr, vShells[i], false)
|
|
UpdateExtraShellRetractionParamsAfterMerge( nCurr, vShells[i], 3)
|
|
|
|
else
|
|
nCurr = vShells[i]
|
|
end
|
|
end
|
|
|
|
-- verifico se le curve si possono chiudere
|
|
vShells = EgtGetNameInGroup( nPathGrp, sName)
|
|
for i = 1, #vShells do
|
|
if not EgtCurveIsClosed( vShells[i]) then
|
|
if dist( EgtSP( vShells[i]), EgtEP( vShells[i])) < dAlpha * dStrand + GEO.EPS_SMALL then
|
|
EgtCloseCurveCompo( vShells[i])
|
|
-- ripristino orientamento originale
|
|
local vtCrv = EgtCurveArea( vShells[i])
|
|
if AreOppositeVectorApprox( vtCrv, s_vtSlicing) then
|
|
EgtInvertCurve( vShells[i])
|
|
UpdateInvertInfo( vShells[i])
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- passo al gruppo di extra shell successivo
|
|
nFirst = EgtGetNextName( vShells[#vShells], EXTRA_SHELL_CRV .. '*')
|
|
end
|
|
|
|
local vIds = EgtGetNameInGroup( nPathGrp, EXTRA_SHELL_CRV .. '*')
|
|
if not vIds or #vIds == 0 then return end
|
|
|
|
-- eventuale inversione di tutte le curve
|
|
if LayerParams.bPrintInvert then
|
|
for i = 1, #vIds do
|
|
EgtInvertCurve( vIds[i])
|
|
UpdateInvertInfo( vIds[i])
|
|
end
|
|
end
|
|
|
|
-- cerco di creare percorsi
|
|
local k = 1 -- indice da utilizzare per i nomi
|
|
local vUsed = {} -- flag per indicare se corrispondente elemento di vIds è già stato considerato
|
|
for i = 1, #vIds do
|
|
vUsed[i] = false
|
|
end
|
|
|
|
local nCurr = vIds[1]
|
|
vUsed[1] = true
|
|
EgtSetName( nCurr, EXTRA_SHELL_CRV .. tostring(k))
|
|
while nCurr do
|
|
local bEndChain = false
|
|
local nCnt = 0
|
|
local vLinkedShells = { nCurr}
|
|
local dCurrStrand
|
|
local bSameStrand = true
|
|
|
|
if EgtCurveIsClosed( nCurr) then
|
|
ModifyStartPoint( nCurr, vPtStart)
|
|
-- se è chiusa costituisce già una catena
|
|
bEndChain = true
|
|
end
|
|
|
|
local ptSCurr = EgtSP( nCurr)
|
|
local ptECurr = EgtEP( nCurr)
|
|
|
|
while not bEndChain do
|
|
|
|
local nCurrType = EgtGetInfo( nCurr, KEY_TYPE, 'i')
|
|
dCurrStrand = EgtIf( nCurrType == TYPE.EXTRA_OUTER_SHELL, LayerParams.dStrand, LayerParams.dInnerStrand)
|
|
|
|
local bFound = false
|
|
for j = 1, #vIds do
|
|
if not vUsed[j] and not EgtCurveIsClosed( vIds[j]) then
|
|
local ptS = EgtSP( vIds[j])
|
|
local ptE = EgtEP( vIds[j])
|
|
local nTypeJ = EgtGetInfo( vIds[j], KEY_TYPE, 'i')
|
|
local dStrandJ = EgtIf( nTypeJ == TYPE.EXTRA_OUTER_SHELL, LayerParams.dStrand, LayerParams.dInnerStrand)
|
|
local dVal = dAlpha * max( dCurrStrand, dStrandJ)
|
|
|
|
local bLink = false
|
|
local bAddFirst = false
|
|
if dist( ptECurr, ptE) < dVal then
|
|
-- congiungo end-end
|
|
EgtInvertCurve( vIds[j])
|
|
UpdateInvertInfo( vIds[j])
|
|
ptECurr = ptS
|
|
bLink = true
|
|
elseif dist( ptECurr, ptS) < dVal then
|
|
-- congiungo end-start
|
|
bLink = true
|
|
ptECurr = ptE
|
|
elseif dist( ptSCurr, ptE) < dVal then
|
|
-- congiungo start-end
|
|
-- il tratto va posizionato in testa
|
|
bLink = true
|
|
bAddFirst = true
|
|
ptSCurr = ptS
|
|
elseif dist( ptSCurr, ptS) < dVal then
|
|
-- congiungo start-start
|
|
bLink = true
|
|
local vNewLinkedShells = {}
|
|
for k = 1, #vLinkedShells do
|
|
EgtInvertCurve( vLinkedShells[k])
|
|
UpdateInvertInfo( vLinkedShells[k])
|
|
EgtRelocateGlob( vLinkedShells[k], vLinkedShells[#vLinkedShells], GDB_IN.AFTER)
|
|
table.insert( vNewLinkedShells, 1, vLinkedShells[k])
|
|
end
|
|
vLinkedShells = vNewLinkedShells
|
|
ptSCurr = EgtSP( vLinkedShells[1])
|
|
ptECurr = ptE
|
|
end
|
|
|
|
if bLink then
|
|
EgtRelocateGlob( vIds[j], EgtIf( bAddFirst, vLinkedShells[1], vLinkedShells[#vLinkedShells]), EgtIf( bAddFirst, GDB_IN.BEFORE, GDB_IN.AFTER))
|
|
EgtSetName( vIds[j], EXTRA_SHELL_CRV .. tostring( k))
|
|
table.insert( vLinkedShells, EgtIf( bAddFirst, 1, #vLinkedShells + 1), vIds[j])
|
|
if abs( dStrandJ - dCurrStrand) > GEO.EPS_SMALL then
|
|
bSameStrand = false
|
|
end
|
|
vUsed[j] = true
|
|
|
|
-- aggiorno per collegamento successivo
|
|
if not bAddFirst then
|
|
bFound = true
|
|
nCurr = vIds[j]
|
|
break
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- se non ho trovato setti da collegare la catena è finita, altrimenti posso cercare successivo
|
|
bEndChain = not bFound
|
|
end
|
|
|
|
-- verifico se posso unire tutti i tratti appena trovati in curva chiusa
|
|
if #vLinkedShells > 1 and bSameStrand and EgtGetInfo( vLinkedShells[1], KEY_TYPE, 'i') == TYPE.EXTRA_OUTER_SHELL and
|
|
dist( EgtSP( vLinkedShells[1]), EgtEP( vLinkedShells[#vLinkedShells])) < dAlpha * dCurrStrand + GEO.EPS_SMALL then
|
|
-- unisco le curve
|
|
for i = 2, #vLinkedShells do
|
|
EgtAddCurveCompoLine( vLinkedShells[1], EgtSP( vLinkedShells[i]))
|
|
EgtAddCurveCompoCurve( vLinkedShells[1], vLinkedShells[i])
|
|
end
|
|
EgtCloseCurveCompo( vLinkedShells[1])
|
|
|
|
ModifyStartPoint( vLinkedShells[1], vPtStart)
|
|
EgtSetInfo( vLinkedShells[1], KEY_CLOSED_CRV, true)
|
|
-- ripristino orientamento desiderato
|
|
local vtCrv = EgtCurveArea( vLinkedShells[1])
|
|
if ( not LayerParams.bPrintInvert and AreOppositeVectorApprox( vtCrv, s_vtSlicing)) or ( LayerParams.bPrintInvert and AreSameVectorApprox( vtCrv, s_vtSlicing)) then
|
|
EgtInvertCurve( vLinkedShells[1])
|
|
UpdateInvertInfo( vLinkedShells[1])
|
|
end
|
|
end
|
|
|
|
-- cerco il prossimo da cui partire
|
|
nCurr = nil
|
|
for i = 1, #vIds do
|
|
if not vUsed[i] then
|
|
nCurr = vIds[i]
|
|
vUsed[i] = true
|
|
k = k + 1
|
|
EgtSetName( nCurr, EXTRA_SHELL_CRV .. tostring(k))
|
|
break
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function CalcExtraShellsPath( nMaxShellNbrDiff, nShellNbrGrp, nCrvGrpId, dOffs, LayerParams, vPtStart, nRibsGrp)
|
|
|
|
local nGrpId = EgtGetFirstNameInGroup( nCrvGrpId, PATH_GRP)
|
|
local nGrpTmp = EgtGroup( nGrpId) -- gruppo temporaneo per conti
|
|
|
|
-- recupero la superficie occupata dalle shell
|
|
local nTotShellTrim = EgtGetFirstNameInGroup( nCrvGrpId, TOT_SHELL_TRIM_SURF)
|
|
if not nTotShellTrim then
|
|
EgtOutLog( 'Warning : ExtraInnerShells not possible (layer '..tostring( s_nCurrIdx)..') - CalcPaths')
|
|
return
|
|
end
|
|
|
|
local dCurrStrand = 0
|
|
for nInd = nMaxShellNbrDiff, 1, -1 do
|
|
|
|
if nInd == LayerParams.nShellsNbr then
|
|
-- devo realizzare la shell esterna
|
|
dOffs = dOffs + 0.5 * LayerParams.dStrand
|
|
elseif nInd == LayerParams.nShellsNbr - 1 then
|
|
-- devo realizzare la prima shell interna
|
|
dOffs = dOffs + 0.5 * LayerParams.dStrand + LayerParams.dInnerStrand * ( 0.5 - LayerParams.dStrandOverlap / 100)
|
|
else
|
|
-- devo realizzare shell interne
|
|
dOffs = dOffs + LayerParams.dInnerStrand * ( 1 - LayerParams.dStrandOverlap / 100)
|
|
end
|
|
dCurrStrand = EgtIf( nInd == LayerParams.nShellsNbr, LayerParams.dStrand, LayerParams.dInnerStrand)
|
|
|
|
local nSrfDiff = EgtGetFirstNameInGroup( nShellNbrGrp, SHELL_NBR_SURF .. tostring( nInd))
|
|
local bOk = true
|
|
local nOuterCrv = EgtGetFirstNameInGroup( nCrvGrpId, OUTER_CRV)
|
|
while nOuterCrv do
|
|
if not bOk then break end
|
|
|
|
-- trim della outer curve con la superficie
|
|
local nTrimCrv, nTrimCnt = TrimOuterCurveForExtraShellCalc( nOuterCrv, nSrfDiff, nGrpTmp, vPtStart, LayerParams)
|
|
for nCrvT = nTrimCrv, nTrimCrv + nTrimCnt - 1 do
|
|
if not bOk then break end
|
|
|
|
-- calcolo offset della curva ( è il percorso della shell)
|
|
local nOffs, nOffsCnt = EgtOffsetCurveAdv( nCrvT, - dOffs, GDB_OT.FILLET, s_dOffsTol)
|
|
for nCrvOffs = nOffs, nOffs + nOffsCnt - 1 do
|
|
|
|
-- calcolo la regione con cui fare trim ( con correzione extra per evitare tratti on)
|
|
local nTrimSurf, bNoOverlap = ComputeTrimSurf( nTotShellTrim, nGrpTmp, dCurrStrand - 10 * s_dOffsCorr, LayerParams.dStrandOverlap)
|
|
if not nTrimSurf then
|
|
-- errore nel calcolo della superficie di trim
|
|
EgtOutLog( 'Error : creation of ExtraShell failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : error in computing extra shell')
|
|
bOk = false
|
|
break
|
|
elseif nTrimSurf == GDB_ID.NULL then
|
|
-- non c'è più spazio per realizzare le extra shell
|
|
EgtOutLog( 'Warning : ExtraInnerShells not possible (layer '..tostring( s_nCurrIdx)..') - CalcPaths')
|
|
bOk = false
|
|
break
|
|
else
|
|
if bNoOverlap then
|
|
EgtOutLog( 'Warning : ExtraShell without correct overlap (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
end
|
|
|
|
local nCrv, nCnt = EgtTrimCurveWithRegion( nCrvOffs, nTrimSurf, true, true)
|
|
if nCrv and nCnt ~= 0 then
|
|
-- verifico se posso unire primo e ultimo tratto
|
|
if nCrv and nCnt > 1 and AreSamePointApprox( EgtEP( nCrv + nCnt - 1), EgtSP( nCrv)) then
|
|
EgtRelocateGlob( nCrv + nCnt - 1, nCrv, GDB_IN.AFTER)
|
|
EgtAddCurveCompoCurve( nCrv + nCnt - 1, nCrv)
|
|
EgtChangeId( nCrv + nCnt - 1, nCrv)
|
|
nCnt = nCnt - 1
|
|
end
|
|
|
|
for nId = nCrv, nCrv + nCnt - 1 do
|
|
local dLen = EgtCurveLength( nId)
|
|
local bValid = true
|
|
if EgtCurveIsClosed( nId) then
|
|
bValid = VerifyPath( nId, LayerParams.dStrand, nGrpId)
|
|
end
|
|
-- verifico se soddisfa vincolo sulla lunghezza
|
|
if dLen > MIN_LEN and bValid then
|
|
-- sposto nel path
|
|
EgtRelocateGlob( nId, nGrpId)
|
|
EgtSetStatus( nId, GDB_ST.ON)
|
|
EgtModifyCurveExtrusion( nId, s_vtSlicing, GDB_RT.GLOB)
|
|
EgtSetName( nId, EXTRA_SHELL_CRV .. tostring( nMaxShellNbrDiff - nInd + 1))
|
|
EgtSetInfo( nId, KEY_CRV_OFFSET, dOffs)
|
|
if nInd == LayerParams.nShellsNbr then
|
|
EgtSetInfo( nId, KEY_TYPE, TYPE.EXTRA_OUTER_SHELL)
|
|
else
|
|
EgtSetInfo( nId, KEY_TYPE, TYPE.EXTRA_SHELL)
|
|
end
|
|
|
|
-- verifico se può essere chiusa
|
|
if not EgtCurveIsClosed( nId) then
|
|
if dLen > dCurrStrand and dist( EgtSP( nId), EgtEP( nId)) < dCurrStrand + GEO.EPS_SMALL then
|
|
EgtCloseCurveCompo( nId)
|
|
end
|
|
end
|
|
|
|
-- aggiorno la superficie occupata dalle shell con quella appena calcolata
|
|
UpdateTrimSurfWithExtraShell( nTotShellTrim, nId, dCurrStrand, nGrpId)
|
|
else
|
|
EgtErase( nId)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
nOuterCrv = EgtGetNextName( nOuterCrv, OUTER_CRV)
|
|
end
|
|
end
|
|
|
|
-- ultimi aggiustamenti alla superfice di trim
|
|
AdjustTrimSurfExtraAngleChunks( nTotShellTrim, dOffs, dCurrStrand, nGrpTmp)
|
|
EgtErase( nGrpTmp)
|
|
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
------------------ AUX SOLIDS -------------------------------------
|
|
--------------------------------------------------------------------
|
|
local function UpdateTrimSurfWithAuxSolidsOffset( nSrfSolid, nSrfBase, dStrand, nCrvGrp)
|
|
|
|
-- offset della superfice del solido
|
|
local nSrfOffs = ComputeSurfOffset( nSrfSolid, nCrvGrp, dStrand * 0.5)
|
|
if not nSrfOffs then
|
|
EgtOutLog( 'Error : creation of AuxSolid region for TotTrimSurfRegion failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : error in computing region for internal elements')
|
|
else
|
|
if not EgtSurfFrSubtract( nSrfBase, nSrfOffs) then
|
|
EgtOutLog( 'Error : EgtSurfFrSubtract with AuxSolid for TotTrimSurfRegion failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : error in computing region for internal elements')
|
|
end
|
|
EgtErase( nSrfOffs)
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function UpdateTrimSurfWithAuxSolidsZigZag( nAuxSolidsGrp, sName, nSrfBase, dStrand, nSrf)
|
|
|
|
local nGrpTmp = EgtGroup( nAuxSolidsGrp) -- gruppo temporaneo per conti
|
|
|
|
-- recupero le curve associate
|
|
local vCrvs = EgtGetNameInGroup( nAuxSolidsGrp, sName)
|
|
for i = 1, #vCrvs do
|
|
|
|
local vtDir = EgtSV( vCrvs[i])
|
|
-- costruisco percorso associato
|
|
local nSrfFatCrv = EgtSurfFrFatCurve( nGrpTmp, vCrvs[i], dStrand * 0.5 + 10 * GEO.EPS_SMALL, false, false, s_dOffsTol)
|
|
local nOffsP = EgtExtractSurfFrChunkLoops( nSrfFatCrv, 0, nGrpTmp)
|
|
local nFirst, nCnt = EgtExplodeCurveCompo( nOffsP, nGrpTmp)
|
|
|
|
-- cerco tratti lineari orientati ortogonalmente alla direzione di svuotatura
|
|
local nRes = EgtCurveCompo( nGrpTmp, {nFirst})
|
|
local nInd = nFirst + 1
|
|
while nInd < nFirst + nCnt do
|
|
local vtCurrDir = EgtSV( nInd)
|
|
local nType = EgtGetType( nInd)
|
|
-- se è linea ortogonale alla direzione della svuotatura la approssimo
|
|
if nType == GDB_TY.CRV_LINE and abs( vtDir * vtCurrDir) < 0.1 then
|
|
-- cerco ultima curva con lo stesso orientamento
|
|
local nLastValidId = nInd
|
|
local nInd2 = nInd + 1
|
|
while nInd2 < nFirst + nCnt do
|
|
local nType2 = EgtGetType( nInd2)
|
|
if nType2 == GDB_TY.CRV_LINE and not AreSameOrOppositeVectorApprox( EgtSV( nInd2), vtDir) then
|
|
if AreSameVectorApprox( EgtSV( nInd2), vtCurrDir) then
|
|
nLastValidId = nInd2
|
|
else
|
|
break
|
|
end
|
|
end
|
|
nInd2 = nInd2 + 1
|
|
end
|
|
|
|
-- aggiungo l'approssimazione lineare
|
|
EgtAddCurveCompoLine( nRes, EgtEP( nLastValidId))
|
|
-- setto l'indice per ripartire correttamente dopo l'approssimazione
|
|
nInd = nLastValidId
|
|
|
|
else
|
|
-- se arco o linea inclinata, aggiungo direttamente al percorso
|
|
EgtAddCurveCompoCurve( nRes, nInd)
|
|
end
|
|
|
|
nInd = nInd + 1
|
|
end
|
|
|
|
-- utilizzo la curva per creare superficie
|
|
local nSrfZigZag = EgtSurfFlatRegion( nGrpTmp, {nRes})
|
|
if not nSrfZigZag then
|
|
-- uso la superficie occupata dall'aux solid, anche se potrebbe non corrispondere perfettamente con quella effettiva del percorso a zigzag
|
|
EgtOutLog( 'Warning : approximation of the region filled by AuxSolid (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
nSrfZigZag = nSrf
|
|
end
|
|
-- aggiorno la TotShellSurfForTrim
|
|
if not EgtSurfFrSubtract( nSrfBase, nSrfZigZag) then
|
|
EgtOutLog( 'Error : EgtSurfFrSubtract with AuxSolid for TotTrimSurfRegion failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : error in computing region for internal elements')
|
|
end
|
|
end
|
|
EgtErase( nGrpTmp)
|
|
|
|
end
|
|
|
|
-------------------------------------------------------------------
|
|
local function AddExtraZigZag( nSrf, sName, dStrand, nGrp, nSrfTrim)
|
|
|
|
local vIds = EgtGetNameInGroup( nGrp, sName)
|
|
if not vIds or #vIds == 0 then return end
|
|
local vtDir = EgtSV( vIds[1], GDB_ID.ROOT)
|
|
local vtYLoc = s_vtSlicing ^ vtDir
|
|
|
|
local nOuterLoop, nCnt = EgtExtractSurfFrChunkLoops( nSrf, 0, nGrp)
|
|
|
|
for i = 1, #vIds do
|
|
local _, dParE = EgtCurveDomain( vIds[i])
|
|
local ptS = EgtUP( vIds[i], dParE - 1, GDB_ID.ROOT) + dStrand * vtYLoc
|
|
local ptE = EgtEP( vIds[i], GDB_ID.ROOT) + dStrand * vtYLoc
|
|
local nExtraCrv = EgtLine( nGrp, ptS, ptE, GDB_RT.GLOB)
|
|
-- verifico se la linea aggiuntiva serve
|
|
local dDist = EgtPointCurveDist( EgtMP( nExtraCrv), nOuterLoop)
|
|
if dDist < 0.5 * dStrand - 100 * GEO.EPS_SMALL then
|
|
-- verifico se si trova nella regione ammissibile
|
|
if EgtCurveWithRegionClassify( nExtraCrv, nSrfTrim) == GDB_CRC.IN then
|
|
EgtInvertCurve( nExtraCrv)
|
|
EgtAddCurveCompoLine( vIds[i], ptE, GDB_RT.GLOB)
|
|
EgtAddCurveCompoCurve( vIds[i], nExtraCrv)
|
|
end
|
|
end
|
|
EgtErase( nExtraCrv)
|
|
end
|
|
|
|
for nId = nOuterLoop, nOuterLoop + nCnt - 1 do
|
|
EgtErase( nId)
|
|
end
|
|
|
|
end
|
|
|
|
-------------------------------------------------------------------
|
|
local function ComputeAuxSolidsGenericInfill( nSrf, dStrand, sName, nPathGrp, vPtStart, nOrigSurf, dOverlap, nAuxSolidsGrp, bLink)
|
|
|
|
if nSrf == GDB_ID.NULL then return end
|
|
|
|
-- recupero gli infill associati
|
|
local sNameInfill = AUX_SOLIDS_INFILL_CRV .. tostring( nOrigSurf)
|
|
local vInfillIds = EgtGetNameInGroup( nAuxSolidsGrp, sNameInfill .. '*') or {}
|
|
|
|
-- eseguo trim con la superficie
|
|
for i = 1, #vInfillIds do
|
|
local nCrv = EgtCopyGlob( vInfillIds[i], nPathGrp)
|
|
-- eventuale inversione della curva per link
|
|
if bLink and i % 2 == 0 then
|
|
EgtInvertCurve( nCrv)
|
|
UpdateInvertInfo( nCrv)
|
|
end
|
|
|
|
local nRes, nCnt = EgtTrimCurveWithRegion( nCrv, nSrf, true, true)
|
|
for nId = nRes, nRes + nCnt - 1 do
|
|
-- verifico se lunghezza minima
|
|
local dLen = EgtCurveLength( nId)
|
|
if dLen < MIN_INFILL_LEN then
|
|
EgtErase( nId)
|
|
else
|
|
EgtSetName( nId, sName)
|
|
EgtSetInfo( nId, KEY_TYPE, TYPE.INFILL)
|
|
EgtSetInfo( nId, KEY_ASSOCIATED_SURF, nSrf)
|
|
EgtModifyCurveExtrusion( nId, s_vtSlicing, GDB_RT.GLOB)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function CalcAuxSolidsPaths( nSliceGrp, nSolidGrp, LayerParams, vPtStart)
|
|
|
|
-- recupero i solidi ausiliari dividendoli per nome
|
|
local vSolidIds = {}
|
|
local nFirst = EgtGetFirstNameInGroup( nSolidGrp, AUX_SOLIDS_CRV .. '*')
|
|
while nFirst do
|
|
local sName = EgtGetName( nFirst)
|
|
local vIds = EgtGetNameInGroup( nSolidGrp, sName)
|
|
table.insert( vSolidIds, vIds)
|
|
nFirst = EgtGetNextName( vIds[#vIds], AUX_SOLIDS_CRV .. '*')
|
|
end
|
|
|
|
-- scorro i gruppi di curve
|
|
local nCrvGrp = EgtGetFirstNameInGroup( nSliceGrp, CONTOUR_GRP .. '*')
|
|
while nCrvGrp do
|
|
|
|
-- creo o svuoto il gruppo per i solidi ausiliari
|
|
local nSolidPathGrp = EgtGetFirstNameInGroup( nCrvGrp, AUX_SOLIDS_GRP)
|
|
if not nSolidPathGrp then
|
|
nSolidPathGrp = EgtGroup( nCrvGrp)
|
|
EgtSetName( nSolidPathGrp, AUX_SOLIDS_GRP)
|
|
EgtSetStatus( nSolidPathGrp, GDB_ST.OFF)
|
|
else
|
|
EgtEmptyGroup( nSolidPathGrp)
|
|
end
|
|
|
|
-- creo le superfici con cui fare i trim
|
|
local nSrfBase = EgtGetFirstNameInGroup( nCrvGrp, TOT_SHELL_TRIM_SURF)
|
|
if not nSrfBase then
|
|
EgtOutLog( 'Warning : AuxSolids not possible (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
else
|
|
|
|
for i = 1, #vSolidIds do
|
|
-- creo la flat region corrispondente al solido ausiliario
|
|
local sName = EgtGetName( vSolidIds[i][1])
|
|
local dStrand = EgtGetInfo( vSolidIds[i][1], KEY_AUX_SOLIDS_STRAND, 'd')
|
|
local dOverlap = EgtGetInfo( vSolidIds[i][1], KEY_AUX_SOLIDS_OVERLAP, 'd')
|
|
local nOrigSurf = EgtGetInfo( vSolidIds[i][1], KEY_ORIGINAL_SURF, 'i')
|
|
local nInfillType = EgtGetInfo( vSolidIds[i][1], KEY_AUX_SOLIDS_INFILL, 'i')
|
|
local bInfillLink = EgtGetInfo( vSolidIds[i][1], KEY_AUX_SOLIDS_INFILL_LINK, 'b')
|
|
local nShells = EgtGetInfo( vSolidIds[i][1], KEY_AUX_SOLIDS_SHELLS_NBR, 'i')
|
|
if nInfillType == FILL_TYPE.OFFSET then
|
|
-- realizzo le shells insieme al riempimento
|
|
nShells = 0
|
|
end
|
|
|
|
local nSrfId = EgtSurfFlatRegion( nSolidPathGrp, vSolidIds[i])
|
|
if nSrfId then
|
|
EgtSetName( nSrfId, AUX_SOLIDS_SRF)
|
|
-- calcolo superficie con cui fare trim
|
|
local nTrimSurf, bNoOverlap = ComputeTrimSurf( nSrfBase, nSolidPathGrp, dStrand, dOverlap)
|
|
if not nTrimSurf then
|
|
EgtOutLog( 'Error : creation of AuxSolid region failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : creation of AuxSolid region failed')
|
|
elseif nTrimSurf == GDB_ID.NULL then
|
|
EgtOutLog( 'Warning : AuxSolids not possible (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
else
|
|
if bNoOverlap then
|
|
EgtOutLog( 'Warning : AuxSolids without correct overlap (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
end
|
|
|
|
-- trim con la superficie di offset
|
|
EgtSurfFrIntersect( nSrfId, nTrimSurf)
|
|
|
|
local nFirst, nCnt = EgtExplodeSurf( nSrfId)
|
|
for j = 0, nCnt - 1 do
|
|
local sNewName = sName .. EgtIf( j == 0, '', '_' .. tostring( j))
|
|
|
|
-- calcolo shells
|
|
if not ComputeOffsetShells( nFirst + j, dStrand, sNewName, TYPE.AUX_SOLID, nSolidPathGrp, vPtStart, nil, nShells) then
|
|
EgtOutLog( 'Error : creation of AuxSolid shells failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : creation of AuxSolid shells failed')
|
|
end
|
|
|
|
-- calcolo la superficie per il riempimento
|
|
local nSrfFill
|
|
if nShells > 0 then
|
|
local dOffs = ( nShells - dOverlap / 100) * dStrand
|
|
nSrfFill = ComputeSurfOffset( nFirst + j, nSolidPathGrp, - dOffs)
|
|
if not nSrfFill then
|
|
EgtOutLog( 'Error : creation of AuxSolid infill region failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : creation of AuxSolid infill region failed')
|
|
elseif nSrfFill == GDB_ID.NULL then
|
|
EgtOutLog( 'Warning : AuxSolids infill not possible (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
end
|
|
else
|
|
-- la superficie per il riempimento è la surf del solido
|
|
nSrfFill = nFirst + j
|
|
end
|
|
|
|
-- riempimento
|
|
if nInfillType == FILL_TYPE.OFFSET then
|
|
-- recupero le shells
|
|
if not ComputeOffsetShells( nSrfFill, dStrand, sNewName, TYPE.AUX_SOLID, nSolidPathGrp, vPtStart) then
|
|
EgtOutLog( 'Error : creation of AuxSolid offset infill failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : creation of AuxSolid offset infill failed')
|
|
end
|
|
elseif nInfillType == FILL_TYPE.ZIGZAG then
|
|
ComputeZigZagSolidFill( nSrfFill, dStrand, sNewName, TYPE.AUX_SOLID, nSolidPathGrp, EgtIf( nShells == 0, nTrimSurf, nil))
|
|
if nShells == 0 then
|
|
-- aggiungo eventuale passata extra
|
|
AddExtraZigZag( nSrfFill, sNewName, dStrand, nSolidPathGrp, nTrimSurf)
|
|
end
|
|
elseif nInfillType ~= FILL_TYPE.NONE then
|
|
ComputeAuxSolidsGenericInfill( nSrfFill, dStrand, sNewName, nSolidPathGrp, vPtStart, nOrigSurf, dOverlap, nSolidGrp, bInfillLink)
|
|
end
|
|
|
|
-- aggiorno la superficie di trim con il solido ausiliario
|
|
if nShells == 0 and nInfillType == FILL_TYPE.ZIGZAG then
|
|
-- gestione speciale perchè non è detto che le passate corrispondano esattamente al solido
|
|
UpdateTrimSurfWithAuxSolidsZigZag( nSolidPathGrp, sNewName, nSrfBase, dStrand, nFirst + j)
|
|
else
|
|
UpdateTrimSurfWithAuxSolidsOffset( nFirst + j, nSrfBase, dStrand, nSolidPathGrp)
|
|
end
|
|
|
|
end
|
|
end
|
|
else
|
|
EgtOutLog( 'Error : creation of AuxSolid region failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : creation of AuxSolid region failed')
|
|
end
|
|
end
|
|
end
|
|
|
|
-- verifico se il gruppo contine qualcosa
|
|
if not EgtGetFirstNameInGroup( nSolidPathGrp, AUX_SOLIDS_CRV .. '*') then
|
|
EgtErase( nSolidPathGrp)
|
|
end
|
|
|
|
-- passo al gruppo di contorni successivo
|
|
nCrvGrp = EgtGetNextName( nCrvGrp, CONTOUR_GRP .. '*')
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function CalcPaths.Exec( nPartId)
|
|
|
|
EgtStartCounter()
|
|
|
|
s_nPartId = nPartId
|
|
|
|
local vLayIds = EgtGetNameInGroup( s_nPartId, SLICE_LAYER.."*")
|
|
if not vLayIds or #vLayIds == 0 then
|
|
EgtOutBox( 'Error no slice', 'PathCalc')
|
|
return true
|
|
end
|
|
|
|
-- recupero i parametri per calcolo dei path
|
|
local LayerParams = GetLayerParamsForPathCalc()
|
|
local nFirstSolidLay = EgtGetInfo( s_nPartId, KEY_FIRST_SOLID_LAY, 'i') or -1
|
|
local nLastSolidLay = EgtGetInfo( s_nPartId, KEY_LAST_SOLID_LAY, 'i') or -1
|
|
|
|
-- scorro tutti i suoi layer
|
|
for nIdx = 1, #vLayIds do
|
|
|
|
s_nCurrIdx = nIdx
|
|
|
|
local nRibsGrp = EgtGetFirstNameInGroup( vLayIds[nIdx], RIBS_GRP)
|
|
local bIgnoreMergedRibs = true
|
|
local nAuxSolidsGrp = EgtGetFirstNameInGroup( vLayIds[nIdx], AUX_SOLIDS_GRP)
|
|
local nInfillGrp = EgtGetFirstNameInGroup( vLayIds[nIdx], INFILL_GRP)
|
|
|
|
-- regioni con diverso numero di passate
|
|
local nShellNbrGrp = EgtGetFirstNameInGroup( vLayIds[nIdx], SHELL_NBR_GRP)
|
|
local nShellNbrSurfGrp = CreateShellNbrSurfaces( nShellNbrGrp, LayerParams.nShellsNbr)
|
|
|
|
-- recupero gli start point per il layer
|
|
local vPtStart = GetLayerStartPoint( vLayIds[nIdx])
|
|
|
|
-- scorro tutti i gruppi di contorni
|
|
local nCrvGrpId = EgtGetFirstNameInGroup( vLayIds[nIdx], CONTOUR_GRP.."*") or GDB_ID.NULL
|
|
while nCrvGrpId ~= GDB_ID.NULL do
|
|
|
|
-- verifico se il path è già stato calcolato
|
|
local nGrpId = EgtGetFirstNameInGroup( nCrvGrpId, PATH_GRP) or GDB_ID.NULL
|
|
if nGrpId == GDB_ID.NULL then
|
|
nGrpId = EgtGroup( nCrvGrpId)
|
|
EgtSetName( nGrpId, PATH_GRP)
|
|
else
|
|
EgtEmptyGroup( nGrpId)
|
|
EgtSetStatus( nGrpId, GDB_ST.ON)
|
|
end
|
|
|
|
-- recupero la superficie ottenuta dallo slicing
|
|
local nSrf = EgtGetFirstNameInGroup( nCrvGrpId, LAYER_SRF)
|
|
if nSrf then
|
|
|
|
local nMaxShellNbrDiff = ComputeMaxShellNbrDiff( nSrf, nShellNbrSurfGrp)
|
|
nMaxShellNbrDiff = min( nMaxShellNbrDiff, LayerParams.nShellsNbr)
|
|
|
|
-- parete esterna
|
|
local vOldIds
|
|
local bPrevExists = true
|
|
local dLastStrand = 0
|
|
local dOffs = - LayerParams.dOffs
|
|
if nMaxShellNbrDiff < LayerParams.nShellsNbr then
|
|
dOffs = dOffs + 0.5 * LayerParams.dStrand
|
|
dLastStrand = LayerParams.dStrand
|
|
local nSrfId = ComputeSurfOffset( nSrf, nCrvGrpId, - dOffs)
|
|
if not nSrfId then
|
|
EgtOutLog( 'Error : ExtOffset failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : creation of OuterShell failed')
|
|
elseif nSrfId == GDB_ID.NULL then
|
|
EgtOutLog( 'Warning : ExtOffset not possible (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
else
|
|
-- se offset riuscito, estraggo i contorni (pareti esterne)
|
|
vOldIds = GetPathsFromSurf( nSrfId, SHELL_CRV ..'0', TYPE.OUTER_SHELL, nGrpId, vPtStart)
|
|
for i = 1, #vOldIds do
|
|
EgtSetInfo( vOldIds[i], KEY_CRV_OFFSET, dOffs)
|
|
end
|
|
end
|
|
bPrevExists = ( nSrfId ~= GDB_ID.NULL)
|
|
EgtErase( nSrfId)
|
|
end
|
|
|
|
-- pareti interne complete
|
|
for nInd = 1, LayerParams.nShellsNbr - 1 - nMaxShellNbrDiff do
|
|
dLastStrand = LayerParams.dInnerStrand
|
|
-- offset della superficie originale
|
|
if nInd == 1 then
|
|
dOffs = dOffs + 0.5 * LayerParams.dStrand + LayerParams.dInnerStrand * ( 0.5 - LayerParams.dStrandOverlap / 100)
|
|
else
|
|
dOffs = dOffs + LayerParams.dInnerStrand * ( 1 - LayerParams.dStrandOverlap / 100)
|
|
end
|
|
local nSrfId = ComputeSurfOffset( nSrf, nCrvGrpId, - dOffs)
|
|
if not nSrfId then
|
|
EgtOutLog( 'Error : IntOffset failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : creation of InnerShell failed')
|
|
elseif nSrfId == GDB_ID.NULL then
|
|
EgtOutLog( 'Warning : IntOffset ' .. EgtNumToString( nInd) .. ' not possible (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
else
|
|
-- se offset riuscito, estraggo i contorni ( pareti interne)
|
|
local vNewIds = GetPathsFromSurf( nSrfId, SHELL_CRV..tostring( nInd), TYPE.INNER_SHELL, nGrpId, vPtStart)
|
|
ReorderPath( vOldIds, vNewIds)
|
|
for i = 1, #vNewIds do
|
|
EgtSetInfo( vNewIds[i], KEY_CRV_OFFSET, dOffs)
|
|
end
|
|
vOldIds = vNewIds
|
|
|
|
-- se questo offset esiste ma il precedente no, allora il precedente è un errore da segnalare
|
|
if not bPrevExists then
|
|
local sElement = EgtIf( nInd > 1, 'IntOffset ' .. EgtNumToString( nInd - 1), 'ExtOffset')
|
|
EgtOutLog( 'Error :' .. sElement .. ' failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : creation of ' .. EgtIf( nInd > 1, 'InnerShell', 'OuterShell') .. ' failed')
|
|
end
|
|
end
|
|
|
|
bPrevExists = ( nSrfId ~= GDB_ID.NULL)
|
|
EgtErase( nSrfId)
|
|
end
|
|
|
|
-- preparo superficie occupata dalle shell da usare per trim
|
|
local dSurfTrimOffs = dOffs + 0.5 * dLastStrand
|
|
local nSrfTrim = ComputeSurfOffset( nSrf, nCrvGrpId, - dSurfTrimOffs)
|
|
if not nSrfTrim then
|
|
EgtOutLog( 'Error : offset for TotTrimSurfRegion failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : error in computing region for internal elements')
|
|
elseif nSrfTrim ~= GDB_ID.NULL then
|
|
EgtSetName( nSrfTrim, TOT_SHELL_TRIM_SURF)
|
|
EgtSetStatus( nSrfTrim, GDB_ST.OFF)
|
|
|
|
-- se questo offset esiste ma il precedente no, allora il precedente è un errore da segnalare
|
|
if not bPrevExists then
|
|
EgtOutLog( 'Error : IntOffset' .. EgtNumToString( LayerParams.nShellsNbr - 1 - nMaxShellNbrDiff) .. ' failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths')
|
|
table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : creation of InnerShell failed')
|
|
end
|
|
end
|
|
|
|
-- pareti coinvolte dal diverso numero di passate
|
|
if nMaxShellNbrDiff > 0 then
|
|
CalcExtraShellsPath( nMaxShellNbrDiff, nShellNbrSurfGrp, nCrvGrpId, dOffs, LayerParams, vPtStart, nRibsGrp)
|
|
end
|
|
|
|
-- ribs-merged shells
|
|
bIgnoreMergedRibs = CalcRibsMergedShells( nRibsGrp, nGrpId, LayerParams, vPtStart)
|
|
|
|
-- riordino extra shells
|
|
ReorderExtraShells( nGrpId, vPtStart, LayerParams)
|
|
end
|
|
|
|
-- passo al gruppo di contorni successivo
|
|
nCrvGrpId = EgtGetNextName( nCrvGrpId, CONTOUR_GRP.."*") or GDB_ID.NULL
|
|
end
|
|
|
|
-- gestione solidi ausiliari ( se no floor o ceil)
|
|
if nAuxSolidsGrp and ( nFirstSolidLay + LayerParams.nFloorNbr <= nIdx and nIdx <= nLastSolidLay - LayerParams.nCeilNbr or LayerParams.nShellsNbr == 0) then
|
|
CalcAuxSolidsPaths( vLayIds[nIdx], nAuxSolidsGrp, LayerParams, vPtStart)
|
|
end
|
|
|
|
-- gestione riempimenti
|
|
if LayerParams.nShellsNbr > 0 then
|
|
-- infill
|
|
if nFirstSolidLay + LayerParams.nFloorNbr <= nIdx and nIdx <= nLastSolidLay - LayerParams.nCeilNbr then
|
|
CalcInfillPaths( vLayIds[nIdx], nInfillGrp, LayerParams)
|
|
-- floor
|
|
elseif nFirstSolidLay <= nIdx and nIdx < nFirstSolidLay + LayerParams.nFloorNbr then
|
|
CalcSolidFillPath( vLayIds[nIdx], LayerParams, vPtStart, LayerParams.nFloorType)
|
|
-- ceil
|
|
elseif nLastSolidLay - LayerParams.nCeilNbr < nIdx and nIdx <= nLastSolidLay then
|
|
CalcSolidFillPath( vLayIds[nIdx], LayerParams, vPtStart, LayerParams.nCeilType)
|
|
end
|
|
end
|
|
|
|
-- gestione costolature
|
|
if nRibsGrp then
|
|
CalcRibsPaths( vLayIds[nIdx], nRibsGrp, LayerParams, vPtStart, bIgnoreMergedRibs)
|
|
end
|
|
|
|
if EgtProcessEvents( EgtIf( PRINT, 200, 0) + nIdx / #vLayIds * 100, 0) == 1 then
|
|
EgtDraw()
|
|
return false
|
|
end
|
|
end
|
|
|
|
-- report tempo di calcolo in log
|
|
EgtOutLog( string.format( ' CalcPathTime = %.2f ms', EgtStopCounter()))
|
|
|
|
if #s_vErr > 0 then
|
|
EgtOutBox( 'CalcPath Error on :\n' .. table.concat( s_vErr, '\n'), 'Calculating Paths')
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
return CalcPaths |