65e0b550c6
- cambio profilo su split - sistemata identificazione dei cambi profilo dopo gli spostamenti degli outlines degli split per misura luce - preview con pezzi dello stesso colore.
9448 lines
412 KiB
Lua
9448 lines
412 KiB
Lua
--
|
|
-- EEEEEEEEEE GGGGGG TTTTTTTTTTTTTT
|
|
-- EEEEEEEEEE GGGGGGGGGG TTTTTTTTTTTTTT
|
|
-- EEEE GGGG GGGG TTTT
|
|
-- EEEE GGGG TTTT
|
|
-- EEEEEEE GGGG GGGGGGG TTTT
|
|
-- EEEEEEE GGGG GGGGGGG TTTT
|
|
-- EEEE GGGG GGGG TTTT
|
|
-- EEEE GGGG GGGG TTTT
|
|
-- EEEEEEEEEE GGGGGGGGGG TTTT
|
|
-- EEEEEEEEEE GGGGGG TTTT
|
|
--
|
|
-- by Egalware s.r.l.
|
|
-- Window project software by Egalware s.r.l. 2023/05/02
|
|
|
|
-- Tabella per definizione modulo
|
|
local WinCalculate = {}
|
|
|
|
-- Include
|
|
local JSON = require( 'JSON')
|
|
local XML = require( 'xml2lua')
|
|
local XMLHandler = require( 'xml2lua_tree')
|
|
|
|
local s_nRedisConnectionId = 0 -- 0 connessione non definita, > 0 connessione definita
|
|
local s_dDowelTol = 1
|
|
local s_dSimplSolidApprox = 0.2 -- approssimazione lineare nel caso di solidi semplificati
|
|
local s_nSashNbr = 0 -- contatore delle ante per assegnare nomi
|
|
local s_dAngledCos = 0.995 -- coseno limite oltre il quale viene forzata giunzione angled
|
|
|
|
---------------------------------------------------------------------
|
|
|
|
local s_bCalcSolid = false
|
|
function WinCalculate.GetCalcSolid()
|
|
return s_bCalcSolid
|
|
end
|
|
function WinCalculate.SetCalcSolid( bValue)
|
|
s_bCalcSolid = bValue
|
|
end
|
|
|
|
local s_bSimplSolid = false
|
|
function WinCalculate.SetSimplifiedSolid( bValue)
|
|
s_bSimplSolid = bValue
|
|
end
|
|
|
|
local s_bCalcPreview = false
|
|
function WinCalculate.SetCalcPreview( bValue)
|
|
s_bCalcPreview = bValue
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che copia la info di chiave sInfo da nSou a nDest
|
|
local function CopyInfo( nDest, nSou, sInfo, Default)
|
|
local sVal = EgtGetInfo( nSou, sInfo) or Default
|
|
EgtSetInfo( nDest, sInfo, sVal)
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function AddInfo( nId, sInfo, sVal)
|
|
local vInfo = EgtGetInfo( nId, sInfo, 'vs') or {}
|
|
table.insert( vInfo, sVal)
|
|
EgtSetInfo( nId, sInfo, vInfo)
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che restituisce o crea il layer ausiliario per soldi di ferramenta e accessori
|
|
local function GetAuxLayer()
|
|
local nAuxLayerId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_AUX)
|
|
if not nAuxLayerId then
|
|
nAuxLayerId = EgtGroup( GDB_ID.ROOT)
|
|
EgtSetName( nAuxLayerId, WIN_AUX)
|
|
EgtSetLevel( nAuxLayerId, GDB_LV.SYSTEM)
|
|
end
|
|
return nAuxLayerId
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che trova il punto di intersezione fra due curve considerandole estese
|
|
local function FindIntersectionPoint( nCrv1, nCrv2, ptRef)
|
|
|
|
local ptInt = EgtIP( nCrv1, nCrv2, ptRef)
|
|
|
|
-- se il punto di intersezione non esiste ritento estendendo le curve
|
|
if not ptInt then
|
|
local nGrp = EgtGroup( EgtGetParent( nCrv1))
|
|
local dExtraLen = 10000
|
|
local nCrvA, nCrvB
|
|
|
|
local nType1 = EgtGetType( nCrv1)
|
|
local nType2 = EgtGetType( nCrv2)
|
|
|
|
-- se compo viene gestita estensione solo sulla sua prima/ultima curva
|
|
if nType1 == GDB_TY.CRV_COMPO then
|
|
local _, dE = EgtCurveDomain( nCrv1)
|
|
nCrv1 = EgtCopyCompoSubCurve( nCrv1, dE - 1, nGrp)
|
|
nType1 = EgtGetType( nCrv1)
|
|
end
|
|
if nType2 == GDB_TY.CRV_COMPO then
|
|
nCrv2 = EgtCopyCompoSubCurve( nCrv2, 0, nGrp)
|
|
nType2 = EgtGetType( nCrv2)
|
|
end
|
|
|
|
if nType1 == GDB_TY.CRV_LINE and nType2 == GDB_TY.CRV_LINE then
|
|
-- caso linea-linea : estendo le due linee
|
|
nCrvA = EgtCopyGlob( nCrv1, nGrp)
|
|
nCrvB = EgtCopyGlob( nCrv2, nGrp)
|
|
EgtExtendCurveStartByLen( nCrvA, dExtraLen)
|
|
EgtExtendCurveEndByLen( nCrvA, dExtraLen)
|
|
EgtExtendCurveStartByLen( nCrvB, dExtraLen)
|
|
EgtExtendCurveEndByLen( nCrvB, dExtraLen)
|
|
|
|
elseif nType1 == GDB_TY.CRV_ARC and nType2 == GDB_TY.CRV_ARC then
|
|
-- caso arco-arco : cerco intersezione tra le due circonferenze
|
|
nCrvA = EgtCircle( nGrp, EgtCP( nCrv1), EgtArcRadius( nCrv1))
|
|
nCrvB = EgtCircle( nGrp, EgtCP( nCrv2), EgtArcRadius( nCrv2))
|
|
|
|
elseif ( nType1 == GDB_TY.CRV_ARC and nType2 == GDB_TY.CRV_LINE) or
|
|
( nType1 == GDB_TY.CRV_LINE and nType2 == GDB_TY.CRV_ARC) then
|
|
-- caso arco-linea : cerco intersezione fra la linea e la circonferenza
|
|
local nArc = EgtIf( EgtGetType( nCrv1) == GDB_TY.CRV_ARC, nCrv1, nCrv2)
|
|
local nLine = EgtIf( nArc == nCrv1, nCrv2, nCrv1)
|
|
nCrvA = EgtCircle( nGrp, EgtCP( nArc), EgtArcRadius( nArc))
|
|
nCrvB = EgtCopyGlob( nLine, nGrp)
|
|
EgtExtendCurveStartByLen( nCrvB, dExtraLen)
|
|
EgtExtendCurveEndByLen( nCrvB, dExtraLen)
|
|
end
|
|
|
|
ptInt = EgtIP( nCrvA, nCrvB, ptRef)
|
|
EgtErase( nGrp)
|
|
end
|
|
|
|
return ptInt
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che controlla se vi è overlap tra nOrigId e una porzione della sua estensione ( nCrvId)
|
|
local function CheckExtensionOverlap( nCrvId, nOrigId)
|
|
|
|
local dParS = EgtCurveParamAtPoint( nOrigId, EgtSP( nCrvId))
|
|
local dParE = EgtCurveParamAtPoint( nOrigId, EgtEP( nCrvId))
|
|
if not dParS and not dParE then
|
|
-- se il nuovo tratto non poggia sull'originale, verifico se è l'originale a poggiare sul nuovo
|
|
local dPar1 = EgtCurveParamAtPoint( nCrvId, EgtSP( nOrigId))
|
|
local dPar2 = EgtCurveParamAtPoint( nCrvId, EgtEP( nOrigId))
|
|
if dPar1 or dPar2 then
|
|
return true
|
|
end
|
|
elseif dParS and not AreSamePointApprox( EgtSP( nCrvId), EgtEP( nOrigId)) then
|
|
return true
|
|
elseif dParE and not AreSamePointApprox( EgtEP( nCrvId), EgtSP( nOrigId)) then
|
|
return true
|
|
end
|
|
return false
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che crea una copia estesa della curva con estensione di lunghezza "illimitata"
|
|
local function CreateCurveExtension( nCrvId, nGrpId)
|
|
|
|
-- recupero tipo di estensione
|
|
local bTangStart = EgtGetInfo( nCrvId, WIN_TANG_START, 'b') or false
|
|
local bTangEnd = EgtGetInfo( nCrvId, WIN_TANG_END, 'b') or false
|
|
local dExtraLen = 10000
|
|
local nExtId
|
|
|
|
if EgtGetType( nCrvId) == GDB_TY.CRV_LINE then
|
|
-- estensione immediata
|
|
nExtId = EgtCopyGlob( nCrvId, nGrpId)
|
|
EgtExtendCurveStartByLen( nExtId, dExtraLen)
|
|
EgtExtendCurveEndByLen( nExtId, dExtraLen)
|
|
|
|
elseif EgtGetType( nCrvId) == GDB_TY.CRV_ARC then
|
|
-- il risultato sarà una circonferenza ( se start ed end non vanno estesi in tangenza) oppure una composita ( se uno degli estremi va esteso in tangenza)
|
|
|
|
if not bTangStart and not bTangEnd then
|
|
-- se estensione standard su entrambi gli estremi trasformo arco in circonferenza
|
|
nExtId = EgtCopyGlob( nCrvId, nGrpId)
|
|
local dAngOld = EgtArcAngCenter( nCrvId)
|
|
EgtModifyArcAngCenter( nExtId, EgtIf( dAngOld > 0, 360, -360))
|
|
|
|
elseif bTangStart and bTangEnd then
|
|
nExtId = EgtCurveCompo( nGrpId, nCrvId, false)
|
|
EgtAddCurveCompoLineTg( nExtId, dExtraLen, true)
|
|
EgtAddCurveCompoLineTg( nExtId, dExtraLen, false)
|
|
|
|
elseif bTangStart and not bTangEnd then
|
|
local nExtArcId = EgtCopyGlob( nCrvId, nGrpId)
|
|
local dAngOld = EgtArcAngCenter( nCrvId)
|
|
EgtModifyArcAngCenter( nExtArcId, EgtIf( dAngOld > 0, 340, -340))
|
|
nExtId = EgtCurveCompo( nGrpId, nExtArcId)
|
|
EgtAddCurveCompoLineTg( nExtId, dExtraLen, false)
|
|
|
|
elseif not bTangStart and bTangEnd then
|
|
local nExtArcId = EgtCopyGlob( nCrvId,nGrpId)
|
|
EgtInvertCurve( nExtArcId)
|
|
local dAngOld = EgtArcAngCenter( nExtArcId)
|
|
EgtModifyArcAngCenter( nExtArcId, EgtIf( dAngOld > 0, 340, -340))
|
|
EgtInvertCurve( nExtArcId)
|
|
nExtId = EgtCurveCompo( nGrpId, nExtArcId)
|
|
EgtAddCurveCompoLineTg( nExtId, dExtraLen)
|
|
end
|
|
|
|
elseif EgtGetType( nCrvId) == GDB_TY.CRV_COMPO then
|
|
-- se composita formata da una sola sottocurva la gestisco come curva semplice
|
|
local _, dEnd = EgtCurveDomain( nCrvId)
|
|
if abs( dEnd - 1) < GEO.EPS_SMALL then
|
|
local nSimpleCrv = EgtCopyCompoSubCurve( nCrvId, 0, nGrpId)
|
|
EgtSetInfo( nSimpleCrv, WIN_TANG_START, bTangStart)
|
|
EgtSetInfo( nSimpleCrv, WIN_TANG_END, bTangEnd)
|
|
nExtId = CreateCurveExtension( nSimpleCrv, nGrpId)
|
|
EgtErase( nSimpleCrv)
|
|
|
|
else
|
|
nExtId = EgtCopyGlob( nCrvId, nGrpId)
|
|
-- start
|
|
if EgtCurveCompoRadius( nExtId, 0) > 0 then
|
|
if bTangStart then
|
|
EgtAddCurveCompoLineTg( nExtId, dExtraLen, false)
|
|
else
|
|
local ptC = EgtCurveCompoCenter( nExtId, 0)
|
|
local dAngOld = EgtCurveCompoAngCenter( nExtId, 0)
|
|
EgtRemoveCurveCompoCurve( nExtId, false)
|
|
local nNewArc = EgtArcCPA( nGrpId, ptC, EgtSP( nExtId), EgtIf( dAngOld > 0, -340, 340), 0)
|
|
EgtInvertCurve( nNewArc)
|
|
EgtAddCurveCompoCurve( nExtId, nNewArc, true, false)
|
|
end
|
|
else
|
|
EgtExtendCurveStartByLen( nExtId, dExtraLen)
|
|
end
|
|
-- end
|
|
local _, dEnd = EgtCurveDomain( nExtId)
|
|
if EgtCurveCompoRadius( nExtId, dEnd - 1) > 0 then
|
|
if bTangEnd then
|
|
EgtAddCurveCompoLineTg( nExtId, dExtraLen)
|
|
else
|
|
local ptC = EgtCurveCompoCenter( nExtId, dEnd - 1)
|
|
local dAngOld = EgtCurveCompoAngCenter( nExtId, dEnd - 1)
|
|
EgtRemoveCurveCompoCurve( nExtId, true)
|
|
local nNewArc = EgtArcCPA( nGrpId, ptC, EgtEP( nExtId), EgtIf( dAngOld > 0, 340, -340), 0)
|
|
EgtAddCurveCompoCurve( nExtId, nNewArc)
|
|
end
|
|
else
|
|
EgtExtendCurveEndByLen( nExtId, dExtraLen)
|
|
end
|
|
end
|
|
end
|
|
|
|
return nExtId
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che data una lista di curve ordinate e orientate che creano una curva chiusa, ne individua la regione definita
|
|
local function CalcIntersectionRegion( vCrvs, nGrp)
|
|
|
|
local nSurfId
|
|
|
|
-- gruppo temporaneo per i conti
|
|
local nGrpTmp = EgtGroup( nGrp)
|
|
EgtSetStatus( nGrpTmp, GDB_ST.OFF)
|
|
|
|
-- costruisco le regioni definite dai semipiani delle linee che compongono il contorno e calcolo le estensioni per gli archi e le composite ( che vanno gestite come gli archi)
|
|
local dExtraLen = 10000
|
|
local vSemiPlanes = {}
|
|
local tArcs = {}
|
|
for i = 1, #vCrvs do
|
|
if EgtGetType( vCrvs[i]) == GDB_TY.CRV_LINE then
|
|
local vtDir = EgtSV( vCrvs[i])
|
|
local vtOrtho = Vector3d( vtDir)
|
|
vtOrtho:rotate( Z_AX(), 90)
|
|
local nSemiPlaneId = EgtSurfFrRectangle( nGrpTmp, ORIG(), Point3d( EgtCurveLength( vCrvs[i]) + 2 * dExtraLen, dExtraLen, 0))
|
|
local frRect = Frame3d( EgtSP( vCrvs[i]) - vtDir * dExtraLen, vtDir, vtOrtho, Z_AX())
|
|
EgtTransform( nSemiPlaneId, frRect)
|
|
table.insert( vSemiPlanes, nSemiPlaneId)
|
|
|
|
elseif EgtGetType( vCrvs[i]) == GDB_TY.CRV_ARC then
|
|
local nCrvId = CreateCurveExtension( vCrvs[i], nGrpTmp)
|
|
table.insert( tArcs, { nCrvId = nCrvId, nOrigId = vCrvs[i], dRad = EgtArcRadius( vCrvs[i])})
|
|
|
|
else
|
|
-- se composita deve contenere un arco, recupero il suo raggio
|
|
local _, dEnd = EgtCurveDomain( vCrvs[i])
|
|
local dRad = 0
|
|
for j = 0, dEnd - 1 do
|
|
dRad = EgtCurveCompoRadius( vCrvs[i], j)
|
|
if dRad > 0 then break end
|
|
end
|
|
|
|
local nCrvId = CreateCurveExtension( vCrvs[i], nGrpTmp)
|
|
table.insert( tArcs, { nCrvId = nCrvId, nOrigId = vCrvs[i], dRad = dRad})
|
|
end
|
|
end
|
|
|
|
-- calcolo la regione definita dai semipiani
|
|
for i = 2, #vSemiPlanes do
|
|
EgtSurfFrIntersect( vSemiPlanes[1], vSemiPlanes[i])
|
|
EgtErase( vSemiPlanes[i])
|
|
end
|
|
nSurfId = vSemiPlanes[1]
|
|
|
|
-- se presenti archi, calcolo il loro contributo alla regione
|
|
if #tArcs > 0 then
|
|
|
|
local nCrvBorder = EgtExtractSurfFrChunkLoops( nSurfId, 0, nGrpTmp)
|
|
|
|
-- riordino per raggio decrescente ( per gestire prima quelle più grandi che potrebbero contenere le altre)
|
|
table.sort( tArcs, function ( a, b) return a.dRad > b.dRad end)
|
|
|
|
for i = 1, #tArcs do
|
|
-- limito la curva estesa alla regione
|
|
local nSurfTrim = EgtSurfFlatRegion( nGrpTmp, nCrvBorder)
|
|
local nCrv, nCnt = EgtTrimCurveWithRegion( tArcs[i].nCrvId, nSurfTrim, true, false)
|
|
-- se errore lo ignoro
|
|
if not nCrv then
|
|
nCnt = 0
|
|
end
|
|
|
|
if nCnt > 0 then
|
|
-- unisco tratto iniziale e finale se consecutivi
|
|
if nCnt > 1 and AreSamePointApprox( EgtSP( nCrv), EgtEP( nCrv + nCnt - 1)) then
|
|
if EgtGetType( nCrv) == GDB_TY.CRV_ARC then
|
|
EgtModifyCurveStartPoint( nCrv, EgtSP( nCrv + nCnt - 1))
|
|
EgtErase( nCrv + nCnt - 1)
|
|
else
|
|
EgtAddCurveCompoCurve( nCrv, nCrv + nCnt - 1, true, false)
|
|
end
|
|
nCnt = nCnt - 1
|
|
end
|
|
|
|
-- spezzo in corrispondenza di eventuali punti tangenti alla regione
|
|
local vArcs = EgtTableFill( nCrv, nCnt)
|
|
for j = nCrv, nCrv + nCnt - 1 do
|
|
local nInters, nPntCnt, nCrvCnt = EgtCurveCurveInters( j, nCrvBorder, nGrpTmp)
|
|
if nInters then
|
|
if nCnt == 1 then
|
|
EgtChangeClosedCurveStartPoint( j, EgtSP( nInters))
|
|
end
|
|
local nCurrCrv = j
|
|
for nPntId = nInters, nInters + nPntCnt - 1 do
|
|
local dPar = EgtCurveParamAtPoint( nCurrCrv, EgtSP( nPntId))
|
|
local nNewCrv = EgtSplitCurveAtParam( nCurrCrv, dPar)
|
|
if nNewCrv then
|
|
table.insert( vArcs, nNewCrv)
|
|
nCurrCrv = nNewCrv
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- modifico il bordo corrente considerando solo i tratti che poggiano sulle curve originali
|
|
for j = 1, #vArcs do
|
|
if CheckExtensionOverlap( vArcs[j], tArcs[i].nOrigId) then
|
|
local dParS = EgtCurveParamAtPoint( nCrvBorder, EgtSP( vArcs[j]), 100 * GEO.EPS_SMALL)
|
|
local dParE = EgtCurveParamAtPoint( nCrvBorder, EgtEP( vArcs[j]), 100 * GEO.EPS_SMALL)
|
|
EgtTrimCurveStartEndAtParam( nCrvBorder, dParE, dParS)
|
|
EgtAddCurveCompoCurve( nCrvBorder, vArcs[j])
|
|
break
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- ricostruisco la superficie
|
|
nSurfId = EgtSurfFlatRegion( nGrpTmp, nCrvBorder)
|
|
end
|
|
|
|
EgtRelocateGlob( nSurfId, nGrp)
|
|
EgtErase( nGrpTmp)
|
|
return nSurfId
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che data una lista di curve ordinate e orientate le estende o le taglia per creare una curva chiusa
|
|
local function TrimOrderedCurves( vCrvs, bDelete, nSurfId)
|
|
|
|
local nGrpTmp = EgtGroup( GDB_ID.ROOT)
|
|
EgtSetStatus( nGrpTmp, GDB_ST.OFF)
|
|
|
|
-- se non calcolata, costruisco la regione definita dalle curve
|
|
if not nSurfId then
|
|
nSurfId = CalcIntersectionRegion( vCrvs, nGrpTmp)
|
|
end
|
|
|
|
-- copia estesa delle curve per verificare gli overlaps
|
|
local vExtCrvs = {}
|
|
for i = 1, #vCrvs do
|
|
vExtCrvs[i] = CreateCurveExtension( vCrvs[i], nGrpTmp)
|
|
end
|
|
|
|
-- recupero le curve di bordo della regione
|
|
local nBorderId = EgtExtractSurfFrChunkLoops( nSurfId, 0, nGrpTmp)
|
|
local nCrvBorder, nCnt = EgtExplodeCurveCompo( nBorderId)
|
|
|
|
-- associo ad ogni curva originale le curve di bordo corrispondenti
|
|
-- per gestire correttamente associazione devo partire da una curva di vCrvs e un tratto di nCrvBorder in corrispondenza biunivoca
|
|
-- ( possono esserci curve di vCrvs senza corrispondente o con più corrispondenti tra le curve di bordo)
|
|
local nFirstIdxCrv = 1
|
|
local nFirstIdxBorder = 1
|
|
for i = 1, #vCrvs do
|
|
local vCrvBorderRef = {}
|
|
for nId = nCrvBorder, nCrvBorder + nCnt - 1 do
|
|
local dDist = EgtPointCurveDist( EgtMP( nId), vExtCrvs[i])
|
|
if dDist < GEO.EPS_SMALL then
|
|
table.insert( vCrvBorderRef, nId)
|
|
end
|
|
end
|
|
if #vCrvBorderRef == 1 then
|
|
-- preparo indici in modo che siano 0-based
|
|
nFirstIdxCrv = i - 1
|
|
nFirstIdxBorder = vCrvBorderRef[1] - nCrvBorder
|
|
break
|
|
end
|
|
end
|
|
|
|
-- creo tabella di corrispondenze vCrvs -> CrvBorder
|
|
local tabAss = {}
|
|
local nC = nFirstIdxCrv
|
|
local nB = nFirstIdxBorder
|
|
repeat
|
|
-- cerco la curva originale associata partendo dall'ultima trovata
|
|
local dDist = EgtPointCurveDist( EgtMP( nCrvBorder + nB), vExtCrvs[nC+1])
|
|
local nSafeCnt = 0
|
|
while dDist > 2 * GEO.EPS_SMALL and nSafeCnt < #vExtCrvs do
|
|
nSafeCnt = nSafeCnt + 1
|
|
nC = ( nC + 1) % #vCrvs
|
|
dDist = EgtPointCurveDist( EgtMP( nCrvBorder + nB), vExtCrvs[nC+1])
|
|
end
|
|
-- se non ho trovato curva associata errore
|
|
if nSafeCnt == #vExtCrvs then
|
|
return
|
|
end
|
|
-- se la curva originale trovata è già associata ad una curva di bordo, verifico se posso associare alla curva di bordo corrente la curva originale consecutiva
|
|
-- ( per gestire estensioni che si sovrappongono a curve originali)
|
|
if tabAss[vCrvs[nC + 1]] then
|
|
local nNext = ( nC + 1) % #vCrvs
|
|
dDist = EgtPointCurveDist( EgtMP( nCrvBorder + nB), vExtCrvs[nNext+1])
|
|
while dDist < GEO.EPS_SMALL do
|
|
nC = nNext
|
|
nNext = ( nNext + 1) % #vCrvs
|
|
dDist = EgtPointCurveDist( EgtMP( nCrvBorder + nB), vExtCrvs[nNext+1])
|
|
end
|
|
end
|
|
|
|
-- aggiungo associazione
|
|
local nOrigCrv = vCrvs[nC + 1]
|
|
if tabAss[nOrigCrv] then
|
|
table.insert( tabAss[nOrigCrv], nCrvBorder + nB)
|
|
else
|
|
tabAss[nOrigCrv] = { nCrvBorder + nB}
|
|
end
|
|
|
|
-- passo alla curva di bordo successiva
|
|
nB = ( nB + 1) % nCnt
|
|
|
|
until nB == nFirstIdxBorder
|
|
|
|
-- sostituisco le curve originali con quelle di bordo appena calcolate
|
|
local vResultCurves = {}
|
|
local vExtraCurves = {}
|
|
for i = 1, #vCrvs do
|
|
|
|
if not tabAss[vCrvs[i]] then
|
|
-- se non ha curve di bordo associate è curva extra da gestire in modo speciale
|
|
if bDelete then
|
|
EgtErase( vCrvs[i])
|
|
else
|
|
-- se non va eliminata la restituisco come curva extra
|
|
EgtSetStatus( vCrvs[i], GDB_ST.OFF)
|
|
table.insert( vExtraCurves, vCrvs[i])
|
|
end
|
|
|
|
else
|
|
local nCrvId
|
|
if #tabAss[vCrvs[i]] > 1 then
|
|
-- se ha associata più di una curva di bordo creo la compo corrispondente
|
|
nCrvId = EgtCurveCompo( nGrpTmp, tabAss[vCrvs[i]])
|
|
else
|
|
nCrvId = tabAss[vCrvs[i]][1]
|
|
end
|
|
|
|
-- assegno il nome
|
|
local sName = EgtGetName( vCrvs[i])
|
|
if sName then
|
|
EgtSetName( nCrvId, sName)
|
|
end
|
|
-- copio le info
|
|
local vInfo = EgtGetAllInfo( vCrvs[i])
|
|
for j = 1, #vInfo do
|
|
local sInfo = EgtSplitString( vInfo[j], '=')
|
|
EgtSetInfo( nCrvId, sInfo[1], sInfo[2])
|
|
end
|
|
-- riposiziono
|
|
EgtRelocateGlob( nCrvId, vCrvs[i], GDB_IN.AFTER)
|
|
-- modifico l'id assegnando quello della curva originale che sostituisce
|
|
EgtErase( vCrvs[i])
|
|
EgtChangeId( nCrvId, vCrvs[i])
|
|
|
|
table.insert( vResultCurves, vCrvs[i])
|
|
end
|
|
end
|
|
|
|
EgtErase( nGrpTmp)
|
|
return vResultCurves, vExtraCurves
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che crea il bisettore parabolico tra linea e arco
|
|
local function CalcParabolicBisector( nCrv1, nCrv2, dDim, nGrp, bArcExternal, bLineExternal)
|
|
|
|
-- modifico le curve affinchè abbiano estremo in comune
|
|
local ptInt = FindIntersectionPoint( nCrv1, nCrv2, EgtSP( nCrv2))
|
|
EgtModifyCurveStartPoint( nCrv2, ptInt)
|
|
EgtModifyCurveEndPoint( nCrv1, ptInt)
|
|
|
|
-- calcolo coefficienti dell'equazione del bisettore ( equazione presa da Vroni)
|
|
local nArc, nLine, nSign
|
|
if EgtGetType( nCrv1) == GDB_TY.CRV_ARC then
|
|
nArc = nCrv1
|
|
nLine = nCrv2
|
|
nSign = -1
|
|
else
|
|
nArc = nCrv2
|
|
nLine = nCrv1
|
|
nSign = 1
|
|
end
|
|
local ptC = EgtCP( nArc)
|
|
local dRad = EgtArcRadius( nArc)
|
|
-- equazione della retta
|
|
local dCoeffA = - EgtSV( nLine):getY()
|
|
local dCoeffB = EgtSV( nLine):getX()
|
|
local dCoeffC = - dCoeffA * ptInt:getX() - dCoeffB * ptInt:getY()
|
|
|
|
local dDist = dCoeffA * ptC:getX() + dCoeffB * ptC:getY() + dCoeffC
|
|
local dA = ptC:getX() - dCoeffA * dDist
|
|
local dB = ptC:getY() - dCoeffB * dDist
|
|
local dZ = ptC:getZ()
|
|
|
|
local k1 = EgtIf( bArcExternal, 1, -1) -- 1 esterno alla circonferenza / -1 interno alla circonferenza
|
|
local k2 = EgtIf( bLineExternal, 1, -1) -- 1 a destra della linea / -1 a sinistra della linea
|
|
|
|
-- campiono il bisettore ( è parametrizzato sul valore di offset t)
|
|
local vPoints = {}
|
|
local nTot = 50
|
|
for i = 1, nTot do
|
|
local t = dDim / ( nTot - 1) * ( i - 1)
|
|
local dDiscriminant = dRad * dRad + 2 * t * ( k1 * dRad - k2 * dDist) - dDist * dDist
|
|
local dX, dY
|
|
if dDiscriminant < GEO.EPS_ZERO then
|
|
dX = dA - k2 * dCoeffA * t
|
|
dY = dB - k2 * dCoeffB * t
|
|
else
|
|
dX = dA - k2 * dCoeffA * t + nSign * dCoeffB * sqrt( dDiscriminant)
|
|
dY = dB - k2 * dCoeffB * t - nSign * dCoeffA * sqrt( dDiscriminant)
|
|
end
|
|
vPoints[i] = Point3d( dX, dY, dZ)
|
|
end
|
|
|
|
local nCompo = EgtCurveCompoFromPoints( nGrp, vPoints)
|
|
return nCompo
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function CreateTestBoxFromOutline( nOutlineId, nProfileId, b3Profile)
|
|
|
|
local frBox
|
|
local b3Box
|
|
|
|
local dDimStd = b3Profile:getDimX()
|
|
local dDimReal = EgtGetInfo( nOutlineId, WIN_PART_DIM, 'd')
|
|
|
|
if EgtGetType( nOutlineId) == GDB_TY.CRV_LINE then
|
|
-- oriento il box come la curva
|
|
frBox = Frame3d( EgtSP( nOutlineId), Z_AX(), EgtSV( nOutlineId))
|
|
b3Box = EgtGetBBoxRef( nOutlineId, GDB_BB.STANDARD, frBox)
|
|
|
|
-- ingrandisco il box con punti opportuni per tenere conto delle dimensioni del pezzo
|
|
local vtDir = VectorFromRotated( EgtSV( nOutlineId), Z_AX(), 90)
|
|
local ptMin = EgtSP( nOutlineId) + vtDir * abs( b3Profile:getMin():getX() * dDimReal / dDimStd)
|
|
local ptMax = EgtSP( nOutlineId) - vtDir * abs( b3Profile:getMax():getX() * dDimReal / dDimStd)
|
|
ptMin:toLoc( frBox)
|
|
ptMax:toLoc( frBox)
|
|
b3Box:Add( ptMin)
|
|
b3Box:Add( ptMax)
|
|
|
|
else
|
|
-- calcolo il rettangolo di area minima che racchiude il pezzo
|
|
local nOffsMax = EgtOffsetCurveAdv( nOutlineId, b3Profile:getMax():getX() * dDimReal / dDimStd)
|
|
local nOffsMin = EgtOffsetCurveAdv( nOutlineId, b3Profile:getMin():getX() * dDimReal / dDimStd)
|
|
EgtInvertCurve( nOffsMin)
|
|
local nCompo = EgtCurveCompo( EgtGetParent( nOutlineId), nOffsMax)
|
|
EgtAddCurveCompoLine( nCompo, EgtSP( nOffsMin))
|
|
EgtAddCurveCompoCurve( nCompo, nOffsMin)
|
|
EgtCloseCurveCompo( nCompo)
|
|
frBox = EgtCurveMinAreaRectangleXY( nCompo)
|
|
b3Box = EgtGetBBoxRef( nCompo, GDB_BB.STANDARD, frBox)
|
|
EgtErase( nCompo)
|
|
end
|
|
|
|
return b3Box, frBox
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che data una curva di outline restituisce l'id del suo profilo teorico ( ovvero quello del file dei profili)
|
|
local function GetOutlineTheoricProfileId( nOutlineId, bForceBottomRail, nBottomRail)
|
|
|
|
-- recupero se è pezzo di telaio o anta
|
|
local nParentId = EgtGetParent( EgtGetParent( nOutlineId))
|
|
local nAreaType = EgtGetInfo( nParentId or GDB_ID.NULL, WIN_AREATYPE, 'i') or WIN_AREATYPES.NULL
|
|
while nParentId and ( nAreaType == WIN_AREATYPES.SPLIT or nAreaType == WIN_AREATYPES.NULL) do
|
|
nParentId = EgtGetParent( nParentId)
|
|
nAreaType = EgtGetInfo( nParentId or GDB_ID.NULL, WIN_AREATYPE, 'i') or WIN_AREATYPES.NULL
|
|
end
|
|
|
|
-- recupero il gruppo contenente il profilo
|
|
local nProfilesGrpId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_PROFILE)
|
|
local nLayerId
|
|
if nAreaType == WIN_AREATYPES.FRAME then
|
|
nLayerId = EgtGetFirstNameInGroup( nProfilesGrpId, WIN_FRAME)
|
|
elseif nAreaType == WIN_AREATYPES.SASH then
|
|
nLayerId = EgtGetFirstNameInGroup( nProfilesGrpId, WIN_SASH)
|
|
elseif nAreaType == WIN_AREATYPES.FILL then
|
|
nLayerId = EgtGetFirstNameInGroup( nProfilesGrpId, WIN_FILL)
|
|
end
|
|
|
|
-- recupero il nome del profilo
|
|
local sProfileName = EgtGetInfo( nOutlineId, WIN_PROFILETYPE)
|
|
|
|
-- controlli per bottomrail
|
|
if EgtGetName( nOutlineId) == WIN_BOTTOM then
|
|
local nBottomRailTot = EgtGetInfo( nOutlineId, WIN_BOTTOMRAIL, 'i') or 0
|
|
if nBottomRailTot > 0 then
|
|
if bForceBottomRail then
|
|
sProfileName = WIN_FILL_RAIL
|
|
elseif nBottomRail then
|
|
if nBottomRail == nBottomRailTot then
|
|
sProfileName = WIN_FILL_RAIL
|
|
else
|
|
sProfileName = WIN_RAIL
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- restituisco il profilo
|
|
return EgtGetFirstNameInGroup( nLayerId, sProfileName)
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che data una curva di outline restituisce l'id del suo profilo reale ( preso dal pezzo)
|
|
local function GetOutlineProfileId( nOutlineId, bForceBottomRail, nBottomRail)
|
|
|
|
-- recupero il pezzo associato all'outline
|
|
local nPartId
|
|
|
|
if EgtGetName( nOutlineId) == WIN_BOTTOM then
|
|
-- controlli per bottomrail
|
|
local nBottomRailTot = EgtGetInfo( nOutlineId, WIN_BOTTOMRAIL, 'i') or 0
|
|
if nBottomRailTot > 0 then
|
|
local vBottomRailParts = EgtGetInfo( nOutlineId, WIN_REF_BOTTOMRAIL_PART, 'vi')
|
|
if bForceBottomRail then
|
|
-- devo recuperare l'ultimo bottomrail
|
|
nPartId = vBottomRailParts[#vBottomRailParts]
|
|
elseif nBottomRail then
|
|
-- devo recuperare il bottomrail indicato
|
|
nPartId = vBottomRailParts[nBottomRail]
|
|
end
|
|
end
|
|
|
|
-- controllo per soglia : non avendo un pezzo associato, devo restituire il profilo teorico
|
|
local bThreshold = EgtGetInfo( nOutlineId, WIN_THRESHOLD, 'b')
|
|
if bThreshold then
|
|
local nProfileGrpId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_PROFILE)
|
|
local nFrameProfileGrpId = EgtGetFirstNameInGroup( nProfileGrpId, WIN_FRAME)
|
|
local sThreshold = EgtGetInfo( nOutlineId, WIN_PROFILETYPE)
|
|
return EgtGetFirstNameInGroup( nFrameProfileGrpId, sThreshold)
|
|
end
|
|
end
|
|
|
|
if not nPartId then
|
|
nPartId = EgtGetInfo( nOutlineId, WIN_REF_PART, 'i')
|
|
end
|
|
|
|
-- recupero il profilo
|
|
local nProfileGrpId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE)
|
|
local nMainProfileId = EgtGetFirstNameInGroup( nProfileGrpId, WIN_PRF_MAIN)
|
|
return nMainProfileId
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che restituisce l'outline non virtuale associato alla curva ( potrebbe anche essere la curva stessa)
|
|
local function GetNonVirtualOutline( nOutlineId)
|
|
|
|
local nSouOutlineId = nOutlineId
|
|
local nAreaType = EgtGetInfo( EgtGetParent( EgtGetParent( nSouOutlineId)), WIN_AREATYPE, 'i')
|
|
while nAreaType ~= WIN_AREATYPES.FRAME and nAreaType ~= WIN_AREATYPES.SASH and EgtGetName( abs( nSouOutlineId)) ~= WIN_SPLIT do
|
|
nSouOutlineId = EgtGetInfo( abs( nSouOutlineId), WIN_SOU_OUTLINE, 'i')
|
|
local nAreaId = EgtGetParent( EgtGetParent( abs( nSouOutlineId)))
|
|
nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i')
|
|
end
|
|
return nSouOutlineId
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che recupera il pezzo associato ad un outline
|
|
local function FindAssociatedPart( nOutlineId, bUseBottomRail)
|
|
|
|
-- ricavo la curva non virtuale associata ( ovvero la curva da cui deriva che ha un pezzo associato)
|
|
local nCrvId = abs( GetNonVirtualOutline( nOutlineId))
|
|
local nPartId = EgtGetInfo( nCrvId, WIN_REF_PART, 'i')
|
|
|
|
-- se serve bottomrail verifico se presente
|
|
if bUseBottomRail then
|
|
local vBottomRailParts = EgtGetInfo( nCrvId, WIN_REF_BOTTOMRAIL_PART, 'vi')
|
|
if vBottomRailParts then
|
|
nPartId = vBottomRailParts[#vBottomRailParts]
|
|
end
|
|
end
|
|
|
|
return nPartId
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che calcola il box di un profilo ( guardando la sua curva Ref) rispetto al suo frame
|
|
local function GetProfileLocalBox( nProfileId)
|
|
-- recupero il frame del profilo
|
|
local nFrameId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME)
|
|
local frFrame = EgtFR( nFrameId, GDB_ID.ROOT)
|
|
-- recupero il Ref del profilo e ne calcolo il box
|
|
local nRefId = EgtGetFirstNameInGroup( nProfileId, WIN_REF)
|
|
local b3Box = EgtGetBBoxRef( nRefId, GDB_BB.STANDARD, frFrame)
|
|
return b3Box
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che restituisce il tipo di controprofilo dell'outline adiacente
|
|
local function GetProfileCtrIn( nPrevOutlineId, nOutlineId, nPrevProfileId, bStart)
|
|
|
|
local sCtrIn = WIN_CTRIN
|
|
local nPrfChange = EgtGetInfo( abs( nPrevOutlineId), WIN_PRF_CHANGE, 'i') or 0
|
|
local nSide = EgtIf( nPrevOutlineId < 0, 1, 2)
|
|
|
|
-- 1) se è inglesina interna
|
|
if EgtGetName( nOutlineId) == WIN_SPLIT and EgtGetInfo( nOutlineId, WIN_MUNTINFILL_SIDE, 'i') == WIN_MUNTINFILL_SIDES.IN then
|
|
-- deve finire contro il fermavetro ( dal lato corretto nel caso di split) oppure contro il bordo interno se finisce contro altra inglesina
|
|
if EgtGetName( abs( nPrevOutlineId)) == WIN_SPLIT then
|
|
if EgtGetInfo( abs( nPrevOutlineId), WIN_SPLITTYPE, 'i') ~= WIN_SPLITTYPES.MUNTIN_FILL then
|
|
sCtrIn = WIN_CTRIN .. WIN_STRIP
|
|
end
|
|
else
|
|
sCtrIn = WIN_CTRIN .. WIN_STRIP
|
|
end
|
|
|
|
-- 2) se finisce contro cambio profilo devo capire se va tagliato il controprofilo sash o fill
|
|
elseif nPrfChange & nSide > 0 then
|
|
local nPrfChangeCurr = EgtGetInfo( nOutlineId, WIN_PRF_CHANGE, 'i') or WIN_PRF_CHANGE_TYPES.NULL
|
|
if ( bStart and nPrfChangeCurr & WIN_PRF_CHANGE_TYPES.START > 0) or ( not bStart and nPrfChangeCurr & WIN_PRF_CHANGE_TYPES.END > 0) then
|
|
-- se il cambio profilo è stato determinato dall'outline allora devo tagliarlo con la parte sash
|
|
sCtrIn = WIN_SASH .. WIN_CTRIN
|
|
else
|
|
-- per capire contro quale parte finisce posso guardare i figli dell'outline. Se l'outline non ha cambio profilo posso considerare un figlio qualsiasi,
|
|
-- altrimenti devo considerare un figlio sull'estremo in analisi per essere sicuri di individuare la tipologia corretta
|
|
local nType
|
|
if nPrfChangeCurr == WIN_PRF_CHANGE_TYPES.NULL then
|
|
local vChildren = EgtGetInfo( nOutlineId, WIN_CHILD_OUTLINE, 'vi')
|
|
if not vChildren then
|
|
-- l'unico caso senza figli è inglesina, quindi sicuramente finisce contro la parte fill
|
|
nType = WIN_AREATYPES.FILL
|
|
else
|
|
local nAreaId = EgtGetParent( EgtGetParent( abs( vChildren[1])))
|
|
nType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i')
|
|
end
|
|
else
|
|
if EgtGetName( nOutlineId) == WIN_SPLIT then
|
|
-- il figlio sull'estremo è salvato in una info
|
|
local sKey = EgtIf( bStart, WIN_MIXED_START_CHILDREN, WIN_MIXED_END_CHILDREN) .. '1'
|
|
local nChildrenType = EgtGetInfo( nOutlineId, sKey, 'i')
|
|
nType = EgtIf( nChildrenType == WIN_CHILDREN_TYPES.SASH, WIN_AREATYPES.SASH, WIN_AREATYPES.FILL)
|
|
else
|
|
-- per trovare il figlio nell'estremo corretto controllo quale figlio ha l'area in comune con un figlio di PrevOutline
|
|
local vChildren = EgtGetInfo( nOutlineId, WIN_CHILD_OUTLINE, 'vi')
|
|
local vChildrenPrev = EgtGetInfo( abs( nPrevOutlineId), WIN_CHILD_OUTLINE, 'vi')
|
|
for i = 1, #vChildren do
|
|
if nType then
|
|
break
|
|
end
|
|
local nRefArea = EgtGetParent( EgtGetParent( abs( vChildren[i])))
|
|
for j = 1, #vChildrenPrev do
|
|
local nArea = EgtGetParent( EgtGetParent( abs( vChildrenPrev[j])))
|
|
if nArea == nRefArea then
|
|
nType = EgtGetInfo( nArea, WIN_AREATYPE, 'i')
|
|
break
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if nType == WIN_AREATYPES.SASH then
|
|
sCtrIn = WIN_SASH .. WIN_CTRIN
|
|
else
|
|
sCtrIn = WIN_FILL .. WIN_CTRIN
|
|
end
|
|
end
|
|
end
|
|
|
|
-- se finisce contro split recupero il controprofilo dal lato corretto ( destro (1) o sinistro (2))
|
|
if EgtGetName( abs( nPrevOutlineId)) == WIN_SPLIT then
|
|
sCtrIn = sCtrIn .. tostring( nSide)
|
|
end
|
|
|
|
return sCtrIn
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che costruisce una superficie estrudendo il nSectionId lungo l'outline
|
|
local function CreateProfileSurfById( nOutlineId, nProfileId, nSectionId, dExtraLen, nLayerId)
|
|
|
|
-- creo guida con estensione in tangenza
|
|
local nGuideId = EgtCopy( nOutlineId, nLayerId)
|
|
if EgtGetType( nGuideId) == GDB_TY.CRV_LINE then
|
|
EgtExtendCurveStartByLen( nGuideId, dExtraLen)
|
|
EgtExtendCurveEndByLen( nGuideId, dExtraLen)
|
|
else
|
|
nGuideId = EgtCurveCompo( nLayerId, nGuideId)
|
|
EgtAddCurveCompoLineTg( nGuideId, dExtraLen)
|
|
EgtAddCurveCompoLineTg( nGuideId, dExtraLen, false)
|
|
end
|
|
-- correzione nel caso di bottomrail
|
|
local sProfileType = EgtGetInfo( nProfileId, WIN_PROFILETYPE)
|
|
if sProfileType == WIN_RAIL or sProfileType == WIN_FILL_RAIL then
|
|
local dOffs = EgtGetInfo( nProfileId, WIN_RAILOFFS, 'd')
|
|
EgtOffsetCurve( nGuideId, - dOffs)
|
|
end
|
|
|
|
-- recupero il profilo da estrudere
|
|
local nSectionRefId = EgtCopyGlob( nSectionId, nLayerId)
|
|
|
|
-- posiziono la sezione di estrusione sulla guida :
|
|
-- recupero frame del profilo
|
|
local nProfileFrameId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME)
|
|
local frProfile = EgtFR( nProfileFrameId, GDB_ID.ROOT)
|
|
frProfile:invert()
|
|
-- calcolo il frame di destinazione sulla guida
|
|
local frDest = Frame3d( EgtSP( nGuideId), - EgtSV( nGuideId), GDB_RT.GLOB)
|
|
-- posiziono con i riferimenti
|
|
EgtTransform( nSectionRefId, frProfile, GDB_RT.GLOB)
|
|
EgtTransform( nSectionRefId, frDest, GDB_RT.GLOB)
|
|
|
|
-- creo la superfice di estrusione
|
|
local nStmId = EgtSurfTmSwept( nLayerId, nSectionRefId, nGuideId, false, WIN_SURF_APPROX)
|
|
EgtErase( nGuideId)
|
|
EgtErase( nSectionRefId)
|
|
|
|
return nStmId
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- come CreateProfileSurfById ma riceve il nome della sezione da estrudere
|
|
local function CreateProfileSurf( nOutlineId, nProfileId, sSectionName, dExtraLen, nLayerId)
|
|
-- recupero l'id della sezione da estrudere
|
|
local nSectionId = EgtGetFirstNameInGroup( nProfileId, sSectionName)
|
|
if not nSectionId then return end
|
|
return CreateProfileSurfById( nOutlineId, nProfileId, nSectionId, dExtraLen, nLayerId)
|
|
end
|
|
|
|
|
|
|
|
----------------------------------------------------------------------------------
|
|
------------------------------ CALCOLO DEI PROFILI ------------------------------
|
|
----------------------------------------------------------------------------------
|
|
-- funzione che verifica la tipologia dei figli di una curva analizzando i base outlines
|
|
local function GetBaseChildrenType( nCrvId)
|
|
|
|
local vStack = EgtGetInfo( nCrvId, WIN_CHILD, 'vi') or {}
|
|
local i = 1
|
|
local vFillChildren = {}
|
|
local vSashChildren = {}
|
|
while vStack[i] do
|
|
-- verifico se la sua area è di tipo sash o fill
|
|
local nAreaId = EgtGetParent( EgtGetParent( abs( vStack[i])))
|
|
local nType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i')
|
|
if nType == WIN_AREATYPES.FILL then
|
|
table.insert( vFillChildren, vStack[i])
|
|
elseif nType == WIN_AREATYPES.SASH then
|
|
table.insert( vSashChildren, vStack[i])
|
|
else
|
|
-- aggiungo i suoi figli tra gli elementi da analizzare
|
|
local vChildren = EgtGetInfo( abs( vStack[i]), WIN_CHILD, 'vi') or {}
|
|
EgtJoinTables( vStack, vChildren)
|
|
end
|
|
-- aggiorno il contatore
|
|
i = i + 1
|
|
end
|
|
|
|
local nChildrenType
|
|
if #vFillChildren > 0 and #vSashChildren > 0 then
|
|
nChildrenType = WIN_CHILDREN_TYPES.MIXED -- cambio profilo
|
|
elseif #vFillChildren > 0 then
|
|
nChildrenType = WIN_CHILDREN_TYPES.FILL
|
|
elseif #vSashChildren > 0 then
|
|
nChildrenType = WIN_CHILDREN_TYPES.SASH
|
|
else
|
|
nChildrenType = WIN_CHILDREN_TYPES.NULL
|
|
end
|
|
|
|
EgtSetInfo( nCrvId, WIN_CHILDREN_TYPE, nChildrenType)
|
|
EgtSetInfo( nCrvId, WIN_SASH_CHILDREN, vSashChildren)
|
|
EgtSetInfo( nCrvId, WIN_FILL_CHILDREN, vFillChildren)
|
|
|
|
return nChildrenType
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che identifica il tipo di split ( mullion, mixed, ...)
|
|
local function GetSplitType( nSplitId, nAreaId)
|
|
|
|
local nSplitType = EgtGetInfo( nAreaId, WIN_SPLITTYPE, 'i')
|
|
-- la tipologia è salvata nell'area solo se si tratta di un french split, negli altri casi va calcolata
|
|
if not nSplitType then
|
|
-- controllo se è dentro telaio, anta o vetro
|
|
local nParentAreaId = nAreaId
|
|
local nParentAreaType = EgtGetInfo( nParentAreaId, WIN_AREATYPE, 'i') or WIN_AREATYPES.NULL
|
|
while nParentAreaId and ( nParentAreaType == WIN_AREATYPES.NULL or nParentAreaType == WIN_AREATYPES.SPLIT) do
|
|
nParentAreaId = EgtGetParent( nParentAreaId)
|
|
nParentAreaType = EgtGetInfo( nParentAreaId or GDB_ID.NULL, WIN_AREATYPE, 'i') or WIN_AREATYPES.NULL
|
|
end
|
|
|
|
-- se dentro anta
|
|
if nParentAreaType == WIN_AREATYPES.SASH then
|
|
nSplitType = WIN_SPLITTYPES.MUNTIN_SASH
|
|
-- se dentro vetro è inglesina incollata
|
|
elseif nParentAreaType == WIN_AREATYPES.FILL then
|
|
nSplitType = WIN_SPLITTYPES.MUNTIN_FILL
|
|
-- se dentro telaio verifico la tipologia dei figli
|
|
elseif nParentAreaType == WIN_AREATYPES.FRAME then
|
|
local nChildrenType = GetBaseChildrenType( nSplitId)
|
|
if nChildrenType == WIN_CHILDREN_TYPES.MIXED then
|
|
nSplitType = WIN_SPLITTYPES.MIXED
|
|
elseif nChildrenType == WIN_CHILDREN_TYPES.FILL then
|
|
nSplitType = WIN_SPLITTYPES.MUNTIN_FRAME
|
|
else -- sash o non definiti
|
|
nSplitType = WIN_SPLITTYPES.MULLION
|
|
end
|
|
end
|
|
|
|
if not nSplitType then
|
|
nSplitType = WIN_SPLITTYPES.NULL
|
|
end
|
|
end
|
|
-- salvo la tipologia come info sulla curva
|
|
EgtSetInfo( nSplitId, WIN_SPLITTYPE, nSplitType)
|
|
return nSplitType
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function FindAdjacentSashType( nSplitId, nCurrType)
|
|
-- i figli della curva nSouId sono base outlines e non posso sapere a quali outlines corrispondono quindi per capire se sto guardando il figlio
|
|
-- corretto controllo se il tipo di anta è lo stesso del corrente oppure no
|
|
local vSplitChildren = EgtGetInfo( nSplitId, WIN_CHILD, 'vi')
|
|
local nAdjSashType = EgtGetInfo( EgtGetParent( EgtGetParent( abs( vSplitChildren[1]))), WIN_SASHTYPE, 'i')
|
|
if nAdjSashType == nCurrType then
|
|
-- se il tipo è lo stesso allora devo guardare l'altro figlio dello split
|
|
nAdjSashType = EgtGetInfo( EgtGetParent( EgtGetParent( abs( vSplitChildren[2]))), WIN_SASHTYPE, 'i')
|
|
end
|
|
return nAdjSashType
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che calcola i profili delle ante sulle curve di outline ( non di base outline)
|
|
local function CalcSashProfiles( vOutlines, nAreaId)
|
|
|
|
local nSashType = EgtGetInfo( nAreaId, WIN_SASHTYPE, 'i') or WIN_SASHTYPES.NULL
|
|
local nBottomRail = EgtGetInfo( nAreaId, WIN_BOTTOMRAIL, 'i') or 0
|
|
|
|
-- imposto profili sash
|
|
for i = 1, #vOutlines do
|
|
local nOutlineId = vOutlines[i]
|
|
local sName = EgtGetName( nOutlineId)
|
|
|
|
-- se non è definita tipologia
|
|
if nSashType == WIN_SASHTYPES.NULL then
|
|
if sName == WIN_BOTTOM then
|
|
if nBottomRail == 0 then
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_FRAME_BOTTOM)
|
|
else
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_RAIL_BOTTOM)
|
|
end
|
|
else
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_FRAME_TOP)
|
|
end
|
|
|
|
else
|
|
-- verifico se deriva da una curva di split french ( e quindi deve avere profilo speciale e.g. battente/ricevente)
|
|
local nSouId = abs( EgtGetInfo( nOutlineId, WIN_SOU_OUTLINE, 'i'))
|
|
local nSplitType = EgtGetInfo( nSouId, WIN_SPLITTYPE, 'i')
|
|
if nSplitType == WIN_SPLITTYPES.FRENCH then
|
|
|
|
EgtSetInfo( nOutlineId, WIN_CRV_ON_FRENCH_SPLIT, true)
|
|
|
|
-- a) battente/ricevente
|
|
if nSashType == WIN_SASHTYPES.ACTIVE then
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SASH_ACTIVE)
|
|
elseif nSashType == WIN_SASHTYPES.INACTIVE then
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SASH_INACTIVE)
|
|
elseif nSashType == WIN_SASHTYPES.ACTIVE_OUT or nSashType == WIN_SASHTYPES.INACTIVE_OUT then
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_FRENCH_OUT)
|
|
elseif nSashType == WIN_SASHTYPES.ACTIVE_IN then
|
|
-- scelgo il profilo in base al tipo dell'anta adiacente
|
|
local nAdjSashType = FindAdjacentSashType( nSouId, WIN_SASHTYPES.ACTIVE_IN)
|
|
if nAdjSashType == WIN_SASHTYPES.ACTIVE_OUT then
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_FRENCH_IN)
|
|
else -- adiacente è inactive
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SASH_ACTIVE)
|
|
end
|
|
elseif nSashType == WIN_SASHTYPES.INACTIVE_IN then
|
|
-- scelgo il profilo in base al tipo dell'anta adiacente
|
|
local nAdjSashType = FindAdjacentSashType( nSouId, WIN_SASHTYPES.INACTIVE_IN)
|
|
if nAdjSashType == WIN_SASHTYPES.INACTIVE_OUT then
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_FRENCH_IN)
|
|
else -- adiacente è active
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SASH_INACTIVE)
|
|
end
|
|
|
|
-- b) alzante scorrevole
|
|
elseif nSashType == WIN_SASHTYPES.SLIDE_MOVABLE then
|
|
local nAdjSashType = FindAdjacentSashType( nSouId, WIN_SASHTYPES.SLIDE_MOVABLE)
|
|
if nAdjSashType == WIN_SASHTYPES.SLIDE_MOVABLE then
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_ACTIVE_IN)
|
|
else
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_ACTIVE)
|
|
end
|
|
elseif nSashType == WIN_SASHTYPES.SLIDE_FIXED then
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_INACTIVE)
|
|
elseif nSashType == WIN_SASHTYPES.SLIDE_MOVABLE_BACK then
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_INACTIVE)
|
|
end
|
|
|
|
else
|
|
-- b) alzante scorrevole
|
|
if nSashType == WIN_SASHTYPES.SLIDE_MOVABLE then
|
|
if sName == WIN_BOTTOM then
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_MOVABLE_BOTTOM)
|
|
elseif sName == WIN_TOP then
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_MOVABLE_TOP)
|
|
else
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_MOVABLE_SIDE)
|
|
end
|
|
elseif nSashType == WIN_SASHTYPES.SLIDE_FIXED then
|
|
if sName == WIN_BOTTOM then
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_FIXED_BOTTOM)
|
|
elseif sName == WIN_TOP then
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_FIXED_TOP)
|
|
else
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_FIXED_SIDE)
|
|
end
|
|
elseif nSashType == WIN_SASHTYPES.SLIDE_MOVABLE_BACK then
|
|
if sName == WIN_BOTTOM then
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_MOVABLEBACK_BOTTOM)
|
|
elseif sName == WIN_TOP then
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_MOVABLEBACK_TOP)
|
|
else
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_MOVABLEBACK_SIDE)
|
|
end
|
|
|
|
-- a) standard
|
|
else
|
|
if sName == WIN_BOTTOM then
|
|
-- verifico se bottomrail
|
|
if nBottomRail == 0 then
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_FRAME_BOTTOM)
|
|
else
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_RAIL_BOTTOM)
|
|
end
|
|
else
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_FRAME_TOP)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che cicla ricorsivamente su aree e sottoaree per impostare i tipi di profilo
|
|
local function CalculateAreaProfileType( nAreaId)
|
|
|
|
local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i')
|
|
|
|
-- FRAME
|
|
if nAreaType == WIN_AREATYPES.FRAME then
|
|
-- gestione soglia
|
|
local sThreshold = EgtGetInfo( nAreaId, WIN_THRESHOLD_PROFILE) or WIN_BOTTOM
|
|
local bThreshold = ( sThreshold == WIN_THRESHOLD)
|
|
|
|
-- assegno il profilo alle curve di outline
|
|
local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_AREAOUTLINE)
|
|
local nOutlineId = EgtGetFirstInGroup( nOutlineLayerId)
|
|
while nOutlineId do
|
|
local sName = EgtGetName( nOutlineId)
|
|
|
|
-- verifico se soglia
|
|
if sName == WIN_BOTTOM then
|
|
EgtSetInfo( nOutlineId, WIN_THRESHOLD, bThreshold)
|
|
end
|
|
|
|
-- recupero il tipo dei figli
|
|
local nChildrenType = GetBaseChildrenType( nOutlineId)
|
|
|
|
-- a) se riempimento o non definiti
|
|
if nChildrenType == WIN_CHILDREN_TYPES.FILL or nChildrenType == WIN_CHILDREN_TYPES.NULL then
|
|
if sName == WIN_BOTTOM then
|
|
-- verifico presenza bottomrail
|
|
local nBottomRail = EgtGetInfo( nAreaId, WIN_BOTTOMRAIL, 'i') or 0
|
|
if nBottomRail == 0 then
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_FIXED .. '_' .. sThreshold)
|
|
else
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_RAIL .. '_' .. sThreshold)
|
|
end
|
|
else
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_FIXED_TOP)
|
|
end
|
|
|
|
-- b) se anta
|
|
elseif nChildrenType == WIN_CHILDREN_TYPES.SASH then
|
|
-- verifico tipologia di anta contro cui poggia
|
|
local vSashChildren = EgtGetInfo( nOutlineId, WIN_SASH_CHILDREN, 'vi')
|
|
local nSashArea = EgtGetParent( EgtGetParent( vSashChildren[1]))
|
|
local nSashType = EgtGetInfo( nSashArea, WIN_SASHTYPE, 'i') or WIN_SASHTYPES.NULL
|
|
|
|
-- b1) alzante scorrevole
|
|
if nSashType == WIN_SASHTYPES.SLIDE_MOVABLE or nSashType == WIN_SASHTYPES.SLIDE_FIXED or nSashType == WIN_SASHTYPES.SLIDE_MOVABLE_BACK then
|
|
EgtSetInfo( nAreaId, WIN_SLIDE_WINDOW, true)
|
|
if sName == WIN_BOTTOM then
|
|
EgtRemoveInfo( nAreaId, WIN_BOTTOMRAIL)
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE .. '_' .. sThreshold)
|
|
-- se le ante contro cui poggia sono tutte mobili devo aggiornare il profilo
|
|
if nSashType == WIN_SASHTYPES.SLIDE_MOVABLE_BACK then
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_MOVABLEBACK .. '_' .. sThreshold)
|
|
elseif nSashType == WIN_SASHTYPES.SLIDE_MOVABLE then
|
|
for i = 2, #vSashChildren do
|
|
local nSashArea = EgtGetParent( EgtGetParent( vSashChildren[i]))
|
|
local nSashType = EgtGetInfo( nSashArea, WIN_SASHTYPE, 'i') or WIN_SASHTYPES.NULL
|
|
if nSashType == WIN_SASHTYPES.SLIDE_MOVABLE_BACK then
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_MOVABLEBACK .. '_' .. sThreshold)
|
|
break
|
|
elseif nSashType == WIN_SASHTYPES.SLIDE_FIXED then
|
|
break
|
|
end
|
|
end
|
|
end
|
|
elseif sName == WIN_TOP then
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_TOP)
|
|
else
|
|
if nSashType == WIN_SASHTYPES.SLIDE_MOVABLE then
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_MOVABLE)
|
|
else
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_FIXED)
|
|
end
|
|
end
|
|
-- b2) standard
|
|
else
|
|
if sName == WIN_BOTTOM then
|
|
EgtRemoveInfo( nAreaId, WIN_BOTTOMRAIL)
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SASH .. '_' .. sThreshold)
|
|
else
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SASH_TOP)
|
|
end
|
|
end
|
|
|
|
-- c) se cambio profilo
|
|
elseif nChildrenType == WIN_CHILDREN_TYPES.MIXED then
|
|
EgtSetInfo( nAreaId, WIN_MIXED_WINDOW, true)
|
|
if sName == WIN_BOTTOM then
|
|
EgtRemoveInfo( nAreaId, WIN_BOTTOMRAIL)
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_MIXED_BOTTOM)
|
|
else
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_MIXED_TOP)
|
|
end
|
|
end
|
|
|
|
nOutlineId = EgtGetNext( nOutlineId)
|
|
end
|
|
|
|
|
|
-- SPLIT
|
|
elseif nAreaType == WIN_AREATYPES.SPLIT then
|
|
local nSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_BASESPLIT)
|
|
local vSplitIds = EgtGetAllInGroup( nSplitLayerId)
|
|
for i = 1, #vSplitIds do
|
|
-- ricavo il tipo di split
|
|
local nSplitType = GetSplitType( vSplitIds[i], nAreaId)
|
|
|
|
if nSplitType == WIN_SPLITTYPES.MULLION then
|
|
-- verifico direzione per assengare il profilo
|
|
local vtMedia = ( ( EgtEV( vSplitIds[i]) - EgtSV( vSplitIds[i])) / 2)
|
|
if not vtMedia:normalize() then
|
|
vtMedia = EgtSV( vSplitIds[i])
|
|
end
|
|
if abs( vtMedia:getX()) > abs( vtMedia:getY()) then
|
|
EgtSetInfo( vSplitIds[i], WIN_PROFILETYPE, WIN_SASH_HORIZONTAL)
|
|
else
|
|
EgtSetInfo( vSplitIds[i], WIN_PROFILETYPE, WIN_SASH_VERTICAL)
|
|
end
|
|
|
|
elseif nSplitType == WIN_SPLITTYPES.MUNTIN_SASH then
|
|
EgtSetInfo( vSplitIds[i], WIN_PROFILETYPE, WIN_SASH_SPLIT)
|
|
|
|
elseif nSplitType == WIN_SPLITTYPES.MUNTIN_FRAME then
|
|
EgtSetInfo( vSplitIds[i], WIN_PROFILETYPE, WIN_FRAME_SPLIT)
|
|
|
|
elseif nSplitType == WIN_SPLITTYPES.MUNTIN_FILL then
|
|
-- se solo interne o entrambe assegno il profilo in ( l'out verrà aggiunto successivamente durante il calcolo del suo outline), se solo out assegno direttamente
|
|
-- il profilo corretto
|
|
local sProfile = WIN_FILL_SPLIT_IN
|
|
local nType = EgtGetInfo( nAreaId, WIN_MUNTINFILL_SIDE, 'i')
|
|
if nType == WIN_MUNTINFILL_SIDES.OUT then
|
|
sProfile = WIN_FILL_SPLIT_OUT
|
|
end
|
|
local bSlide = EgtGetInfo( EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_AREA .. '*'), WIN_SLIDE_WINDOW, 'b') or false
|
|
if bSlide then
|
|
sProfile = WIN_SLIDE .. '_' .. sProfile
|
|
end
|
|
EgtSetInfo( vSplitIds[i], WIN_PROFILETYPE, sProfile)
|
|
|
|
elseif nSplitType == WIN_SPLITTYPES.MIXED then
|
|
EgtSetInfo( vSplitIds[i], WIN_PROFILETYPE, WIN_MIXED_SPLIT)
|
|
end
|
|
-- se split di tipo french non ha profilo assegnato perchè non ha un pezzo associato
|
|
end
|
|
|
|
|
|
-- NULL
|
|
elseif nAreaType == WIN_AREATYPES.NULL then
|
|
-- le aree null sono aree virtuali quindi non hanno pezzi ( e dunque profili) associati
|
|
|
|
-- SASH
|
|
elseif nAreaType == WIN_AREATYPES.SASH then
|
|
-- i profili verranno calcolati direttamente sulle curve di outline perchè non è detto che corrispondano alle curve di base outline
|
|
end
|
|
|
|
-- calcolo i profili per le eventuali sottoaree
|
|
local nChildAreaId = EgtGetFirstNameInGroup( nAreaId, WIN_AREA .. '*')
|
|
while nChildAreaId do
|
|
CalculateAreaProfileType( nChildAreaId)
|
|
nChildAreaId = EgtGetNextName( nChildAreaId, WIN_AREA .. '*')
|
|
end
|
|
end
|
|
|
|
|
|
|
|
----------------------------------------------------------------------------------
|
|
----------------------------- PROFILI PEZZO -------------------------------------
|
|
----------------------------------------------------------------------------------
|
|
-- funzione che calcola l'offset da applicare alla curva di outline bottom per ottenere la curva di outline del bottomrail richiesto
|
|
local function CalcRailOffset( nOutlineId, nProfileId, nBottomRail)
|
|
|
|
-- recupero la dimensioni dei pezzi bottom e bottomrails
|
|
local dDimBottom = EgtGetInfo( nOutlineId, WIN_PART_DIM, 'd')
|
|
local vDimBottomRails = EgtGetInfo( nOutlineId, WIN_BOTTOMRAIL .. WIN_PART_DIM, 'vd')
|
|
local dOverlap = EgtGetInfo( nProfileId, WIN_OVERLAP, 'd')
|
|
|
|
local dRailOffs = dDimBottom
|
|
for i = 1, nBottomRail - 1 do
|
|
dRailOffs = dRailOffs + vDimBottomRails[i]
|
|
end
|
|
dRailOffs = dRailOffs - nBottomRail * dOverlap
|
|
|
|
return dRailOffs
|
|
end
|
|
|
|
----------------------------------------------------------------------------------
|
|
-- funzione che nel caso di profilo mixed split conserva solamente le curve veramente necessarie per le tipologie di figli
|
|
local function CreateMixedSplitProfile( nOutlineId, nProfileId)
|
|
-- sistemo i profili dx (1) e sx (2) : se da un lato è presente una sola tipologia di figli allora :
|
|
-- a) elimino le curve legate all'altra tipologia e la curva common legata al cambio profilo
|
|
-- b) rinomino le curve della tipologia presente
|
|
-- In questo modo si può gestire quel lato come in uno split non mixed. Se invece da un lato sono presenti entrambe le tipologie di figli allora non servono modifiche
|
|
|
|
local vSashProfiles = { WIN_SASH .. WIN_IN, WIN_SASH .. WIN_CTRIN, WIN_OFST .. WIN_SASH .. WIN_CTRIN}
|
|
local vFillProfiles = { WIN_FILL .. WIN_IN, WIN_FILL .. WIN_CTRIN, WIN_OFST .. WIN_FILL .. WIN_CTRIN, WIN_STRIP, WIN_CTRIN .. WIN_STRIP, WIN_OFST .. WIN_CTRIN .. WIN_STRIP}
|
|
local nNewNames = { WIN_IN, WIN_CTRIN, WIN_OFST .. WIN_CTRIN, WIN_STRIP, WIN_CTRIN .. WIN_STRIP, WIN_OFST .. WIN_CTRIN .. WIN_STRIP}
|
|
|
|
local nPrfChange = EgtGetInfo( nOutlineId, WIN_PRF_CHANGE, 'i')
|
|
for i = 1, 2 do
|
|
-- verifico se lato con cambio profilo
|
|
if nPrfChange & i == 0 then
|
|
-- recupero la tipologia di figli da quel lato
|
|
local nChildrenType = EgtGetInfo( nOutlineId, WIN_MIXED_START_CHILDREN .. tostring( i), 'i')
|
|
local vToBeRenamed = {}
|
|
local vToBeErased = {}
|
|
if nChildrenType == WIN_CHILDREN_TYPES.SASH then
|
|
vToBeRenamed = vSashProfiles
|
|
vToBeErased = vFillProfiles
|
|
elseif nChildrenType == WIN_CHILDREN_TYPES.FILL then
|
|
vToBeRenamed = vFillProfiles
|
|
vToBeErased = vSashProfiles
|
|
end
|
|
|
|
-- a) cancello
|
|
if #vToBeErased > 0 then
|
|
for j = 1, #vToBeErased do
|
|
local nId = EgtGetFirstNameInGroup( nProfileId, vToBeErased[j] .. tostring( i)) or GDB_ID.NULL
|
|
local nSimplId = EgtGetFirstNameInGroup( nProfileId, WIN_SIMPLIFIED .. vToBeErased[j] .. tostring( i)) or GDB_ID.NULL
|
|
EgtErase( { nId, nSimplId})
|
|
end
|
|
local nId = EgtGetFirstNameInGroup( nProfileId, WIN_MIXED_COMMON .. WIN_IN .. tostring( i)) or GDB_ID.NULL
|
|
local nSimplId = EgtGetFirstNameInGroup( nProfileId, WIN_SIMPLIFIED .. WIN_MIXED_COMMON .. WIN_IN .. tostring( i)) or GDB_ID.NULL
|
|
EgtErase( { nId, nSimplId})
|
|
end
|
|
|
|
-- b) rinomino
|
|
for j = 1, #vToBeRenamed do
|
|
local nId = EgtGetFirstNameInGroup( nProfileId, vToBeRenamed[j] .. tostring( i)) or GDB_ID.NULL
|
|
EgtSetName( nId, nNewNames[j] .. tostring( i))
|
|
local nSimplId = EgtGetFirstNameInGroup( nProfileId, WIN_SIMPLIFIED .. vToBeRenamed[j] .. tostring( i)) or GDB_ID.NULL
|
|
EgtSetName( nSimplId, WIN_SIMPLIFIED .. nNewNames[j] .. tostring( i))
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che crea il profilo della dimensione corretta
|
|
local function AdjustProfileDimension( nOutlineId, nProfileId, dDimOld, dDim)
|
|
|
|
local bSplit = ( EgtGetName( nOutlineId) == WIN_SPLIT)
|
|
local bPrfChange = ( EgtGetInfo( nOutlineId, WIN_PRF_CHANGE, 'i') == WIN_PRF_CHANGE_TYPES.IN)
|
|
local bMixedSplit = ( bSplit and EgtGetInfo( nOutlineId, WIN_SPLITTYPE, 'i') == WIN_SPLITTYPES.MIXED)
|
|
|
|
local dDeltaDim = dDim - dDimOld
|
|
local nFrameId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME)
|
|
local frSection = EgtFR( nFrameId, GDB_RT.GLOB)
|
|
local vtMove = - frSection:getVersX()
|
|
|
|
-- traslo le curve "interne"
|
|
local vCurves = { WIN_IN, WIN_CTRIN, WIN_OFST .. WIN_CTRIN, WIN_STRIP, WIN_CTRIN .. WIN_STRIP, WIN_OFST .. WIN_CTRIN .. WIN_STRIP}
|
|
if bPrfChange then
|
|
vCurves = { WIN_SASH .. WIN_IN, WIN_FILL .. WIN_IN, WIN_SASH .. WIN_CTRIN, WIN_FILL .. WIN_CTRIN, WIN_OFST .. WIN_SASH .. WIN_CTRIN, WIN_OFST .. WIN_FILL .. WIN_CTRIN,
|
|
WIN_MIXED_COMMON .. WIN_IN, WIN_STRIP, WIN_CTRIN .. WIN_STRIP, WIN_OFST .. WIN_CTRIN .. WIN_STRIP}
|
|
end
|
|
if bSplit then
|
|
for i = 1, #vCurves do
|
|
vCurves[i] = vCurves[i] .. '2'
|
|
end
|
|
end
|
|
|
|
for i = 1, #vCurves do
|
|
local nCrvId = EgtGetFirstNameInGroup( nProfileId, vCurves[i]) or GDB_ID.NULL
|
|
EgtMove( nCrvId, dDeltaDim * vtMove, GDB_RT.GLOB)
|
|
local nSimplifiedCrvId = EgtGetFirstNameInGroup( nProfileId, WIN_SIMPLIFIED .. vCurves[i]) or GDB_ID.NULL
|
|
EgtMove( nSimplifiedCrvId, dDeltaDim * vtMove, GDB_RT.GLOB)
|
|
end
|
|
|
|
-- traslo i dowels
|
|
local vDowels = EgtGetNameInGroup( nProfileId, WIN_DOWEL .. '*')
|
|
EgtMove( vDowels, 0.5 * dDeltaDim * vtMove)
|
|
|
|
-- ricostruisco la sezione ( i=1) e la sezione semplificata ( i=2) tranne nel caso di split mixed ( perchè la sezione non è definita)
|
|
if not bMixedSplit then
|
|
for i = 1, 2 do
|
|
-- prefisso al nome delle curve per sezione standard o semplificata
|
|
local sSimplPrefix = EgtIf( i == 1, '', WIN_SIMPLIFIED)
|
|
-- prefisso al nome delle curve per gestire parte sash o fill ( cambio profilo)
|
|
local vsPartPrefix = EgtIf( bPrfChange, { WIN_SASH, WIN_FILL}, {''})
|
|
-- nome dei semiprofili da combinare per creare la sezione
|
|
local vsProfiles = EgtIf( bSplit, { WIN_IN .. '1', WIN_IN .. '2'}, { WIN_IN, WIN_OUT})
|
|
|
|
for j = 1, #vsPartPrefix do
|
|
local nSectionId = EgtGetFirstNameInGroup( nProfileId, sSimplPrefix .. vsPartPrefix[j] .. WIN_SECTION)
|
|
EgtErase( nSectionId)
|
|
local vSemiProfileNames = { sSimplPrefix .. vsPartPrefix[j] .. vsProfiles[1], sSimplPrefix .. vsProfiles[2]}
|
|
local vSemiProfiles = { EgtGetFirstNameInGroup( nProfileId, vSemiProfileNames[1]), EgtGetFirstNameInGroup( nProfileId, vSemiProfileNames[2])}
|
|
nSectionId = EgtCurveCompo( nProfileId, vSemiProfiles[1], false)
|
|
EgtAddCurveCompoLine( nSectionId, EgtSP( vSemiProfiles[2]))
|
|
EgtAddCurveCompoCurve( nSectionId, vSemiProfiles[2], false)
|
|
EgtCloseCurveCompo( nSectionId)
|
|
EgtSetName( nSectionId, sSimplPrefix .. vsPartPrefix[j] .. WIN_SECTION)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- ricostruisco il box
|
|
local nRef = EgtGetFirstNameInGroup( nProfileId, WIN_REF)
|
|
local b3Profile = EgtGetBBoxRef( nRef, GDB_BB.STANDARD, frSection)
|
|
EgtErase( nRef)
|
|
nRef = EgtRectangle2P( nProfileId, b3Profile:getMin() - X_AX() * dDeltaDim, b3Profile:getMax())
|
|
EgtTransform( nRef, EgtFR( nFrameId))
|
|
EgtSetName( nRef, WIN_REF)
|
|
|
|
if EgtGetName( nOutlineId) == WIN_SPLIT then
|
|
-- sposto il frame per lasciarlo posizionato come prima rispetto al box ( sono state spostate solo le curve interne)
|
|
local dMove = b3Profile:getMax():getX() / dDimOld * dDim - b3Profile:getMax():getX()
|
|
EgtMove( nFrameId, dMove * vtMove)
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function CreatePartProfile( nPartId, nOutlineId, dDim, nBottomRail)
|
|
|
|
-- gruppo per i profili
|
|
local nProfileLayerId = EgtGroup( nPartId)
|
|
EgtSetName( nProfileLayerId, WIN_PROFILE)
|
|
EgtSetStatus( nProfileLayerId, GDB_ST.OFF)
|
|
|
|
-- recupero il profilo teorico
|
|
local nOrigProfileId = GetOutlineTheoricProfileId( nOutlineId, false, nBottomRail)
|
|
|
|
-- creo copia
|
|
local nProfileId = EgtCopy( nOrigProfileId, nProfileLayerId)
|
|
local sProfileType = EgtGetName( nProfileId)
|
|
EgtSetInfo( nProfileId, WIN_PROFILETYPE, sProfileType)
|
|
EgtSetName( nProfileId, WIN_PRF_MAIN)
|
|
|
|
-- se bottomrail salvo info per scostamento dall'outline
|
|
if nBottomRail then
|
|
local dRailOffs = CalcRailOffset( nOutlineId, nProfileId, nBottomRail)
|
|
EgtSetInfo( nProfileId, WIN_RAILOFFS, dRailOffs)
|
|
end
|
|
|
|
-- se split mixed aggiusto le curve del profilo in base alla reale tipologia di figli
|
|
if sProfileType == WIN_MIXED_SPLIT then
|
|
CreateMixedSplitProfile( nOutlineId, nProfileId)
|
|
end
|
|
|
|
-- verifico se vanno modificate le dimensioni del profilo
|
|
local dDimStd = EgtGetInfo( nProfileId, WIN_DIM_STD, 'd')
|
|
if abs( dDimStd - dDim) > GEO.EPS_SMALL then
|
|
AdjustProfileDimension( nOutlineId, nProfileId, dDimStd, dDim)
|
|
end
|
|
|
|
-- recupero le info di pinzaggio dal profilo di estrusione
|
|
CopyInfo( nPartId, nProfileId, WIN_PRC_OFFY_1, 0)
|
|
CopyInfo( nPartId, nProfileId, WIN_PRC_OFFZ_1, 0)
|
|
CopyInfo( nPartId, nProfileId, WIN_PRC_OFFY_2, 0)
|
|
CopyInfo( nPartId, nProfileId, WIN_PRC_OFFZ_2, 0)
|
|
CopyInfo( nPartId, nProfileId, WIN_PRC_CLAMPV_1, 0)
|
|
CopyInfo( nPartId, nProfileId, WIN_PRC_CLAMPV_2, 0)
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che recupera i profili start ed end di un pezzo
|
|
local function CalcStartEndProfiles( nPartId, nOutlineId, vPrevOutlineId, vNextOutlineId)
|
|
|
|
-- recupero il gruppo per i profili
|
|
local nProfileLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE)
|
|
|
|
-- recupero profili start/end e ne creo copia
|
|
for i = 1, #vPrevOutlineId do
|
|
-- se il tipo corrente è split il pezzo va tagliato con eventuale bottomrail, altrimenti con il bottom
|
|
local nOrigStartProfileId = GetOutlineProfileId( abs( vPrevOutlineId[i]), EgtGetName( nOutlineId) == WIN_SPLIT)
|
|
local nStartProfileId = EgtCopy( nOrigStartProfileId, nProfileLayerId)
|
|
EgtSetName( nStartProfileId, WIN_PRF_START)
|
|
end
|
|
|
|
for i = 1, #vNextOutlineId do
|
|
local nOrigEndProfileId = GetOutlineProfileId( abs( vNextOutlineId[i]), EgtGetName( nOutlineId) == WIN_SPLIT)
|
|
local nEndProfileId = EgtCopy( nOrigEndProfileId, nProfileLayerId)
|
|
EgtSetName( nEndProfileId, WIN_PRF_END)
|
|
end
|
|
|
|
return nProfileLayerId
|
|
end
|
|
|
|
|
|
|
|
----------------------------------------------------------------------------------
|
|
------------------------------ CALCOLO OUTLINE ---------------------------------
|
|
----------------------------------------------------------------------------------
|
|
|
|
------------------------------ NULL ------------------------------
|
|
---------------------------------------------------------------------
|
|
local function GetBorderRegions( nSplitId, nCompo, nAreaId)
|
|
|
|
-- taglio il bordo in due in corrispondenza dello split
|
|
local nCrv1 = EgtCopyGlob( nCompo, nAreaId)
|
|
local nCrv2 = EgtCopyGlob( nCompo, nAreaId)
|
|
local dPar1 = EgtCurveParamAtPoint( nCompo, EgtSP( nSplitId), 100 * GEO.EPS_SMALL)
|
|
local dPar2 = EgtCurveParamAtPoint( nCompo, EgtEP( nSplitId), 100 * GEO.EPS_SMALL)
|
|
EgtTrimCurveStartEndAtParam( nCrv1, dPar2, dPar1)
|
|
EgtTrimCurveStartEndAtParam( nCrv2, dPar1, dPar2)
|
|
|
|
-- aggiungo la curva di split al bordo per chiuderlo orientandola opportunamente
|
|
local nSplitId1 = EgtCopyGlob( nSplitId, nAreaId)
|
|
EgtAddCurveCompoCurve( nCrv1, nSplitId1)
|
|
local _, dParE1 = EgtCurveDomain( nCrv1)
|
|
EgtCurveCompoSetTempProp( nCrv1, dParE1 - 1, nSplitId)
|
|
|
|
local nSplitId2 = EgtCopyGlob( nSplitId, nAreaId)
|
|
EgtInvertCurve( nSplitId2)
|
|
EgtAddCurveCompoCurve( nCrv2, nSplitId2)
|
|
local _, dParE2 = EgtCurveDomain( nCrv2)
|
|
EgtCurveCompoSetTempProp( nCrv2, dParE2 - 1, - nSplitId)
|
|
|
|
return nCrv1, nCrv2
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function AssignSplitName( nCrvId)
|
|
-- sceglie il nome della curva di split in base al suo orientamento
|
|
-- TODO forme non lineari o con orientamento diverso dagli assi principali
|
|
local vtS = EgtSV( nCrvId)
|
|
if AreSameVectorApprox( vtS, X_AX()) then
|
|
EgtSetName( nCrvId, WIN_BOTTOM)
|
|
elseif AreOppositeVectorApprox( vtS, X_AX()) then
|
|
EgtSetName( nCrvId, WIN_TOP)
|
|
elseif AreSameVectorApprox( vtS, Y_AX()) then
|
|
EgtSetName( nCrvId, WIN_RIGHT)
|
|
elseif AreOppositeVectorApprox( vtS, Y_AX()) then
|
|
EgtSetName( nCrvId, WIN_LEFT)
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function CalculateNullOutline( nCompoOutline, vSplitIds, vChildAreas)
|
|
|
|
local nGrpTmp = EgtGroup( GDB_ID.ROOT)
|
|
|
|
-- calcolo i bordi delle sottoregioni null tagliando il bordo complessivo dell'area di split con gli split
|
|
local vBorders = {}
|
|
local nCompoRef = nCompoOutline
|
|
for i = 1, #vSplitIds do
|
|
-- calcolo i bordi delle due regioni definite dallo split
|
|
local nCrv1, nCrv2 = GetBorderRegions( vSplitIds[i], nCompoRef, nGrpTmp)
|
|
table.insert( vBorders, nCrv1)
|
|
-- il secondo bordo è quello da suddividere con lo split successivo ( se esiste)
|
|
nCompoRef = nCrv2
|
|
if i == #vSplitIds then
|
|
table.insert( vBorders, nCrv2)
|
|
end
|
|
end
|
|
|
|
-- creo gli outline delle sottoaree a partire dai bordi calcolati
|
|
for i = 1, #vChildAreas do
|
|
|
|
if vBorders[i] then
|
|
local nOutlineLayerId = EgtGroup( vChildAreas[i])
|
|
EgtSetName( nOutlineLayerId, WIN_OUTLINE)
|
|
EgtSetStatus( nOutlineLayerId, GDB_ST.OFF)
|
|
EgtRelocateGlob( vBorders[i], nOutlineLayerId)
|
|
|
|
-- dalla curva di bordo ricavo le sottocurve che compongono l'outline
|
|
local vSouCrvs = EgtCurveCompoGetTempProp( vBorders[i])
|
|
local nFirst, nCnt = EgtExplodeCurveCompo( vBorders[i])
|
|
|
|
-- assegno nome e info a tutte le curve a partire dalla curva da cui derviano ( salvata nella temp prop della curva)
|
|
for j = 0, nCnt - 1 do
|
|
local nCrvId = nFirst + j
|
|
EgtSetInfo( nCrvId, WIN_SOU_OUTLINE, vSouCrvs[j+1])
|
|
|
|
if vSouCrvs[j+1] < 0 then
|
|
AddInfo( abs( vSouCrvs[j+1]), WIN_CHILD_VIRTUAL_OUTLINE, -nCrvId)
|
|
else
|
|
AddInfo( vSouCrvs[j+1], WIN_CHILD_VIRTUAL_OUTLINE, nCrvId)
|
|
end
|
|
|
|
-- assengo il nome : se deriva da split lo scelgo in base all'orientamento, se deriva da outline lo copio
|
|
if EgtGetName( abs( vSouCrvs[j+1])) == WIN_SPLIT then
|
|
AssignSplitName( nCrvId)
|
|
else
|
|
EgtSetName( nCrvId, EgtGetName( abs( vSouCrvs[j+1])))
|
|
end
|
|
end
|
|
|
|
-- riordino le curve per avere la bottom come prima
|
|
for j = 0, nCnt - 1 do
|
|
if EgtGetName( nFirst + j) ~= WIN_BOTTOM then
|
|
EgtRelocate( nFirst + j, nOutlineLayerId)
|
|
else
|
|
break
|
|
end
|
|
end
|
|
else
|
|
-- se non c'è bordo l'area non è valida e va eliminata
|
|
EgtErase( vChildAreas[i])
|
|
end
|
|
end
|
|
EgtErase( nGrpTmp)
|
|
end
|
|
|
|
|
|
------------------------------ SPLIT ------------------------------
|
|
---------------------------------------------------------------------
|
|
-- funzione che adatta la curva di split al bordo
|
|
local function TrimSplitWithOutline( nSplitId, nOutlineCompo, vOutlineIds)
|
|
-- estendo agli estremi ( TO DO : gestire caso di split non lineare)
|
|
EgtExtendCurveStartByLen( nSplitId, 1000)
|
|
EgtExtendCurveEndByLen( nSplitId, 1000)
|
|
|
|
local ptS = EgtIP( nSplitId, nOutlineCompo, EgtSP( nSplitId))
|
|
local ptE = EgtIP( nSplitId, nOutlineCompo, EgtEP( nSplitId))
|
|
-- se non trovo punti di intersezione lo split è fuori dall'outline e quindi va eliminato
|
|
if not ptS and not ptE then
|
|
return false
|
|
end
|
|
|
|
local dParS = EgtCurveParamAtPoint( nSplitId, ptS)
|
|
local dParE = EgtCurveParamAtPoint( nSplitId, ptE)
|
|
EgtTrimCurveStartEndAtParam( nSplitId, dParS, dParE)
|
|
|
|
-- recupero le curve con cui avviene l'intersezione e le salvo come info
|
|
local dParCrvS = EgtCurveParamAtPoint( nOutlineCompo, ptS)
|
|
local nCrv = vOutlineIds[ floor( dParCrvS) + 1]
|
|
EgtSetInfo( nSplitId, WIN_SPLIT_STARTINTERS, nCrv)
|
|
local dParCrvE = EgtCurveParamAtPoint( nOutlineCompo, ptE)
|
|
nCrv = vOutlineIds[ floor( dParCrvE) + 1]
|
|
EgtSetInfo( nSplitId, WIN_SPLIT_ENDINTERS, nCrv)
|
|
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function CalcSplitDimensions( nAreaId, dDim)
|
|
|
|
local vMeasureTypes = EgtGetInfo( nAreaId, WIN_MEASURE_TYPE, 'vi')
|
|
local vMeasureValues = EgtGetInfo( nAreaId, WIN_MEASURE_VALUE, 'vd')
|
|
local vDimensions = {}
|
|
-- calcolo le dimensioni di tutti gli split assoluti e percentuali e calcolo i valori di riferimento per eventuali split proporzionali
|
|
local nPropTot = 0
|
|
local dPropDim = dDim
|
|
local bProportional = false
|
|
for i = 1, #vMeasureTypes do
|
|
if vMeasureTypes[i] == WIN_MEASURE.ABSOLUTE then
|
|
vDimensions[i] = vMeasureValues[i]
|
|
dPropDim = dPropDim - vDimensions[i]
|
|
elseif vMeasureTypes[i] == WIN_MEASURE.PERCENTAGE then
|
|
vDimensions[i] = dDim * vMeasureValues[i] / 100
|
|
dPropDim = dPropDim - vDimensions[i]
|
|
elseif vMeasureTypes[i] == WIN_MEASURE.PROPORTIONAL then
|
|
nPropTot = nPropTot + vMeasureValues[i]
|
|
bProportional = true
|
|
end
|
|
end
|
|
|
|
-- calcolo le dimensioni degli split proporzionali
|
|
if bProportional then
|
|
if dPropDim < GEO.EPS_SMALL then
|
|
return {}
|
|
end
|
|
for i = 1, #vMeasureTypes do
|
|
if vMeasureTypes[i] == WIN_MEASURE.PROPORTIONAL then
|
|
vDimensions[i] = dPropDim * vMeasureValues[i] / nPropTot
|
|
end
|
|
end
|
|
end
|
|
|
|
return vDimensions
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function GetSplitAreaBorderCurves( nSplitDir, nOutlineLayerId)
|
|
|
|
local vCrvs = {}
|
|
-- se split verticale servono le curve di sinistra e di destra, che sono rispettivamente quella prima e quella dopo il bottom
|
|
-- non ricerco la left/right per casi dove non sono definite ( e.g. triangolo)
|
|
if nSplitDir == WIN_SPLITORIENTATION.VERTICAL then
|
|
vCrvs[1] = EgtGetLastInGroup( nOutlineLayerId)
|
|
vCrvs[2] = EgtGetNext( EgtGetFirstNameInGroup( nOutlineLayerId, WIN_BOTTOM))
|
|
|
|
-- se split orizzontale servono le curve inferiore e superiore
|
|
elseif nSplitDir == WIN_SPLITORIENTATION.HORIZONTAL then
|
|
vCrvs[1] = EgtGetFirstNameInGroup( nOutlineLayerId, WIN_BOTTOM)
|
|
vCrvs[2] = EgtGetFirstNameInGroup( nOutlineLayerId, WIN_TOP)
|
|
end
|
|
|
|
return vCrvs
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function CalcStandardSplitContributions( nSplitDir, nOutlineLayerId, vSplitIds)
|
|
-- nel caso di split standard la dimensione è sempre luce
|
|
|
|
local tPartsDim = {}
|
|
|
|
-- 1) contributo dei pezzi che delimitano la regione degli split
|
|
local vDim = {}
|
|
local vCrvs = GetSplitAreaBorderCurves( nSplitDir, nOutlineLayerId)
|
|
for i = 1, 2 do
|
|
-- recupero il pezzo contro cui poggia
|
|
local nSouId = GetNonVirtualOutline( vCrvs[i])
|
|
-- recupero il profilo ( eventualmente di bottomrail)
|
|
local nProfileId = GetOutlineTheoricProfileId( abs( nSouId), true)
|
|
local dRealDim = EgtGetInfo( abs( nSouId), WIN_PART_DIM, 'd')
|
|
-- se bottomrail calcolo scostamento
|
|
local dRailOffs = 0
|
|
if EgtGetName( nProfileId) == WIN_FILL_RAIL then
|
|
local nBottomRail = EgtGetInfo( abs( nSouId), WIN_BOTTOMRAIL, 'i')
|
|
dRailOffs = CalcRailOffset( abs( nSouId), nProfileId, nBottomRail)
|
|
local vBottomRailDims = EgtGetInfo( abs( nSouId), WIN_BOTTOMRAIL .. WIN_PART_DIM, 'vd')
|
|
dRealDim = vBottomRailDims[#vBottomRailDims]
|
|
end
|
|
local b3Profile = GetProfileLocalBox( nProfileId)
|
|
-- calcolo il contributo
|
|
if nSouId < 0 then
|
|
vDim[i] = b3Profile:getMax():getX()
|
|
else
|
|
vDim[i] = abs( b3Profile:getMin():getX())
|
|
end
|
|
vDim[i] = vDim[i] * dRealDim / b3Profile:getDimX() + dRailOffs
|
|
end
|
|
|
|
tPartsDim[1] = { 0, vDim[1]}
|
|
|
|
-- 2) contributo degli split
|
|
for i = 1, #vSplitIds do
|
|
local nProfileId = GetOutlineTheoricProfileId( vSplitIds[i])
|
|
local b3Profile = GetProfileLocalBox( nProfileId)
|
|
local dRealDim = EgtGetInfo( vSplitIds[i], WIN_PART_DIM, 'd')
|
|
local vCurrSplitDim = {}
|
|
vCurrSplitDim[1] = abs( b3Profile:getMin():getX()) * dRealDim / b3Profile:getDimX()
|
|
vCurrSplitDim[2] = b3Profile:getMax():getX() * dRealDim / b3Profile:getDimX()
|
|
table.insert( tPartsDim, vCurrSplitDim)
|
|
end
|
|
|
|
table.insert( tPartsDim, { vDim[2], 0})
|
|
|
|
return tPartsDim
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function CalcFrenchSplitContributions( nOutlineLayerId, nBaseOutlineLayerId, vSplitIds, bDaylight)
|
|
-- nel caso di french split ( gruppo di ante) la dimensione può essere di tipo luce o esterno anta
|
|
|
|
local tPartsDim = {}
|
|
local nProfileGrp = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_PROFILE)
|
|
local nSashProfileGrp = EgtGetFirstNameInGroup( nProfileGrp, WIN_SASH)
|
|
|
|
-- 1) contributo dei pezzi che delimitano la regione degli split
|
|
local vDim = {}
|
|
local vCrvs = GetSplitAreaBorderCurves( WIN_SPLITORIENTATION.VERTICAL, nOutlineLayerId)
|
|
local vBaseCrvs = GetSplitAreaBorderCurves( WIN_SPLITORIENTATION.VERTICAL, nBaseOutlineLayerId)
|
|
for i = 1, 2 do
|
|
|
|
-- a) contributo del telaio
|
|
local nSouId = GetNonVirtualOutline( vCrvs[i])
|
|
local nProfileId = GetOutlineTheoricProfileId( abs( nSouId))
|
|
local b3Profile = GetProfileLocalBox( nProfileId)
|
|
if nSouId < 0 then
|
|
vDim[i] = abs( b3Profile:getMax():getX())
|
|
else
|
|
vDim[i] = abs( b3Profile:getMin():getX())
|
|
end
|
|
local dRealDim = EgtGetInfo( abs( nSouId), WIN_PART_DIM, 'd')
|
|
local dSashOverlap = EgtGetInfo( nProfileId, WIN_SASH_TOP_OVERLAP, 'd')
|
|
vDim[i] = vDim[i] * dRealDim / b3Profile:getDimX() - dSashOverlap
|
|
|
|
-- b) se luce devo considerare anche il contributo dell'anta
|
|
if bDaylight then
|
|
-- anta non è ancora calcolata quindi devo calcolare la sua dimensione ricavandola dal base outline
|
|
local nSashBaseOutline = EgtGetInfo( vBaseCrvs[i], WIN_CHILD, 'i')
|
|
local vDimensions = EgtGetInfo( EgtGetParent( EgtGetParent( nSashBaseOutline)), WIN_PART_DIM, 'vd')
|
|
local dDim
|
|
if not vDimensions then
|
|
local nFrameId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_AREA .. '*')
|
|
local bSlide = EgtGetInfo( nFrameId, WIN_SLIDE_WINDOW, 'b')
|
|
local sProfileName = WIN_FRAME_TOP
|
|
if bSlide then
|
|
sProfileName = WIN_SLIDE_MOVABLE_SIDE -- la dimensione standard dovrebbe essere la stessa indipendentemente dalla tipologia di anta slide
|
|
end
|
|
local nProfileId = EgtGetFirstNameInGroup( nSashProfileGrp, sProfileName)
|
|
dDim = EgtGetInfo( nProfileId, WIN_DIM_STD, 'd')
|
|
else
|
|
local nIdx = EgtIf( i == 1, #vDimensions, 2)
|
|
dDim = vDimensions[nIdx]
|
|
end
|
|
vDim[i] = vDim[i] + dDim
|
|
end
|
|
end
|
|
|
|
tPartsDim[1] = { 0, vDim[1]}
|
|
|
|
-- 2) contributo degli split
|
|
for i = 1, #vSplitIds do
|
|
|
|
local vCurrSplitDim = { 0, 0}
|
|
-- ricavo dai base outlines le ante che poggeranno sullo split
|
|
local vSashChildren = EgtGetInfo( vSplitIds[i], WIN_CHILD, 'vi')
|
|
local vSashTypes = {}
|
|
vSashTypes[1] = EgtGetInfo( EgtGetParent( EgtGetParent( abs( vSashChildren[1]))), WIN_SASHTYPE, 'i')
|
|
vSashTypes[2] = EgtGetInfo( EgtGetParent( EgtGetParent( abs( vSashChildren[2]))), WIN_SASHTYPE, 'i')
|
|
for j = 1, 2 do
|
|
-- recupero il profilo teorico
|
|
local sSashProfile
|
|
local nOther = EgtIf( j == 1, 2, 1)
|
|
if vSashTypes[j] == WIN_SASHTYPES.ACTIVE then
|
|
sSashProfile = WIN_SASH_ACTIVE
|
|
elseif vSashTypes[j] == WIN_SASHTYPES.INACTIVE then
|
|
sSashProfile = WIN_SASH_INACTIVE
|
|
elseif vSashTypes[j] == WIN_SASHTYPES.ACTIVE_OUT or vSashTypes[j] == WIN_SASHTYPES.INACTIVE_OUT then
|
|
sSashProfile = WIN_FRENCH_OUT
|
|
elseif vSashTypes[j] == WIN_SASHTYPES.ACTIVE_IN then
|
|
if vSashTypes[nOther] == WIN_SASHTYPES.ACTIVE_OUT then
|
|
sSashProfile = WIN_FRENCH_IN
|
|
else
|
|
sSashProfile = WIN_SASH_ACTIVE
|
|
end
|
|
elseif vSashTypes[j] == WIN_SASHTYPES.INACTIVE_IN then
|
|
if vSashTypes[nOther] == WIN_SASHTYPES.INACTIVE_OUT then
|
|
sSashProfile = WIN_FRENCH_IN
|
|
else -- adiacente è active
|
|
sSashProfile = WIN_SASH_INACTIVE
|
|
end
|
|
|
|
elseif vSashTypes[j] == WIN_SASHTYPES.SLIDE_MOVABLE then
|
|
if vSashTypes[nOther] == WIN_SASHTYPES.SLIDE_MOVABLE then
|
|
sSashProfile = WIN_SLIDE_ACTIVE_IN
|
|
else
|
|
sSashProfile = WIN_SLIDE_ACTIVE
|
|
end
|
|
elseif vSashTypes[j] == WIN_SASHTYPES.SLIDE_FIXED then
|
|
sSashProfile = WIN_SLIDE_INACTIVE
|
|
elseif vSashTypes[j] == WIN_SASHTYPES.SLIDE_MOVABLE_BACK then
|
|
sSashProfile = WIN_SLIDE_INACTIVE
|
|
end
|
|
|
|
local nProfileId = EgtGetFirstNameInGroup( nSashProfileGrp, sSashProfile)
|
|
local b3Profile = GetProfileLocalBox( nProfileId)
|
|
if bDaylight then
|
|
local dDim
|
|
local vDimensions = EgtGetInfo( EgtGetParent( EgtGetParent( abs( vSashChildren[j]))), WIN_PART_DIM, 'vd')
|
|
if not vDimensions then
|
|
dDim = EgtGetInfo( nProfileId, WIN_DIM_STD, 'd')
|
|
else
|
|
-- il primo figlio è quello di sx, il secondo figlio è quello di dx
|
|
local nIdx = EgtIf( j == 1, 2, #vDimensions)
|
|
dDim = vDimensions[nIdx]
|
|
end
|
|
vCurrSplitDim[j] = dDim - b3Profile:getMax():getX()
|
|
else
|
|
vCurrSplitDim[j] = - b3Profile:getMax():getX()
|
|
end
|
|
end
|
|
|
|
table.insert( tPartsDim, vCurrSplitDim)
|
|
end
|
|
|
|
table.insert( tPartsDim, { vDim[2], 0})
|
|
|
|
return tPartsDim
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che calcola gli offset da applicare ai base splits per posizionarli correttamente
|
|
local function CalcSplitPositionOffsets( nAreaId, nAreaInfoId, vSplitIds, nSplitType)
|
|
|
|
local nSplitDir = EgtGetInfo( nAreaInfoId, WIN_SPLIT_DIR, 'i')
|
|
local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE)
|
|
local nBaseOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_AREAOUTLINE)
|
|
|
|
-- calcolo i contributi dei vari pezzi presenti
|
|
local tPartsDim
|
|
if nSplitType == WIN_SPLITTYPES.FRENCH then
|
|
local bDaylight = EgtGetInfo( nAreaInfoId, WIN_DAYLIGHT_MEASURE, 'b') or false
|
|
tPartsDim = CalcFrenchSplitContributions( nOutlineLayerId, nBaseOutlineLayerId, vSplitIds, bDaylight)
|
|
else
|
|
tPartsDim = CalcStandardSplitContributions( nSplitDir, nOutlineLayerId, vSplitIds)
|
|
end
|
|
|
|
-- ricavo la vera dimensione disponibile
|
|
local b3Box = EgtGetBBoxGlob( nOutlineLayerId, GDB_BB.STANDARD)
|
|
local dRealDim = EgtIf( nSplitDir == WIN_SPLITORIENTATION.VERTICAL, b3Box:getDimX(), b3Box:getDimY())
|
|
for i = 1, #tPartsDim do
|
|
dRealDim = dRealDim - tPartsDim[i][1] - tPartsDim[i][2]
|
|
end
|
|
|
|
-- calcolo le dimensioni assolute di tutte le sottoaree
|
|
local vSplitDimensions = CalcSplitDimensions( nAreaInfoId, dRealDim)
|
|
|
|
-- le posizioni salvate negli split sono calcolate rispetto al box del base outline, le posizioni appena calcolate sono rispetto al box dell'outline
|
|
-- quindi calcolo la correzione da applicare
|
|
local b3BoxBase = EgtGetBBoxGlob( nBaseOutlineLayerId, GDB_BB.STANDARD)
|
|
local dCorrection = EgtIf( nSplitDir == WIN_SPLITORIENTATION.VERTICAL, ( b3Box:getMin():getX() - b3BoxBase:getMin():getX()), ( b3Box:getMin():getY() - b3BoxBase:getMin():getY()))
|
|
tPartsDim[1][2] = tPartsDim[1][2] + dCorrection
|
|
|
|
-- calcolo gli offset
|
|
local vOffs = {}
|
|
local dPrevPos = 0
|
|
for i = 1, #vSplitIds do
|
|
local dNewPos = dPrevPos + tPartsDim[i][2] + vSplitDimensions[i] + tPartsDim[i+1][1]
|
|
local dOldPos = EgtGetInfo( vSplitIds[i], WIN_SPLIT_POSITION, 'd')
|
|
vOffs[i] = dNewPos - dOldPos
|
|
dPrevPos = dNewPos
|
|
end
|
|
|
|
return vOffs
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function CalculateSplitOutline( nAreaId, vSplitIds)
|
|
|
|
-- recupero l'outline e creo composita del bordo
|
|
local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE)
|
|
local vOutlineIds = EgtGetAllInGroup( nOutlineLayerId)
|
|
local nOutlineCompo = EgtCurveCompo( nAreaId, vOutlineIds, false)
|
|
for i = 1, #vOutlineIds do
|
|
EgtCurveCompoSetTempProp( nOutlineCompo, i - 1, vOutlineIds[i])
|
|
end
|
|
|
|
local nSplitType = EgtGetInfo( vSplitIds[1], WIN_SPLITTYPE, 'i')
|
|
|
|
-- assegno le dimensioni
|
|
if nSplitType ~= WIN_SPLITTYPES.FRENCH then
|
|
local vSplitDim = EgtGetInfo( nAreaId, WIN_PART_DIM, 'vd') or {}
|
|
for i = 1, #vSplitIds do
|
|
if not vSplitDim[i] then
|
|
-- se dimensione non è impostata recupero quella standard del profilo
|
|
local nProfileId = GetOutlineTheoricProfileId( vSplitIds[i])
|
|
vSplitDim[i] = EgtGetInfo( nProfileId, WIN_DIM_STD, 'd')
|
|
end
|
|
EgtSetInfo( vSplitIds[i], WIN_PART_DIM, vSplitDim[i])
|
|
end
|
|
end
|
|
|
|
-- posiziono correttamente gli split e li taglio con l'outline
|
|
local vOffs = CalcSplitPositionOffsets( nAreaId, nAreaId, vSplitIds, nSplitType)
|
|
for i = 1, #vSplitIds do
|
|
EgtOffsetCurve( vSplitIds[i], vOffs[i])
|
|
TrimSplitWithOutline( vSplitIds[i], nOutlineCompo, vOutlineIds)
|
|
end
|
|
|
|
-- creo l'outline delle aree figlie di tipo null
|
|
if nSplitType ~= WIN_SPLITTYPES.FRENCH then
|
|
local vChildAreas = EgtGetNameInGroup( nAreaId, WIN_AREA .. '*')
|
|
CalculateNullOutline( nOutlineCompo, vSplitIds, vChildAreas)
|
|
end
|
|
|
|
EgtErase( nOutlineCompo)
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function CalculateGridSplitOutline( nAreaId, vSplitIds)
|
|
|
|
local vAreas = EgtGetNameInGroup( nAreaId, WIN_AREA .. '*')
|
|
local vVirtualAreas = EgtGetNameInGroup( nAreaId, WIN_VIRTUAL_AREA)
|
|
|
|
-- raggruppo gli split e le aree per ordine
|
|
local tabGrid = {}
|
|
for i = 1, #vSplitIds do
|
|
local nOrder = EgtGetInfo( vSplitIds[i], WIN_GRIDSPLIT_ORDER, 'i')
|
|
if tabGrid[nOrder] then
|
|
table.insert( tabGrid[nOrder], vSplitIds[i])
|
|
else
|
|
tabGrid[nOrder] = { vSplitIds[i]}
|
|
end
|
|
end
|
|
|
|
local tabAreas = {}
|
|
for i = 1, #vAreas do
|
|
local nOrder = EgtGetInfo( vAreas[i], WIN_GRIDSPLIT_ORDER, 'i')
|
|
if tabAreas[nOrder] then
|
|
table.insert( tabAreas[nOrder], vAreas[i])
|
|
else
|
|
tabAreas[nOrder] = { vAreas[i]}
|
|
end
|
|
end
|
|
|
|
-- assegno le dimensioni
|
|
local vDimMain = EgtGetInfo( nAreaId, WIN_PART_DIM, 'vd') or {}
|
|
local vDimOther = EgtGetInfo( vVirtualAreas[1], WIN_PART_DIM, 'vd') or {}
|
|
for i = 0, #tabGrid do
|
|
for j = 1, #tabGrid[i] do
|
|
local dDim = EgtIf( i == 0, vDimMain[j], vDimOther[j])
|
|
if not dDim then
|
|
-- se dimensione non è impostata recupero quella standard del profilo
|
|
local nProfileId = GetOutlineTheoricProfileId( tabGrid[i][j])
|
|
dDim = EgtGetInfo( nProfileId, WIN_DIM_STD, 'd')
|
|
end
|
|
EgtSetInfo( tabGrid[i][j], WIN_PART_DIM, dDim)
|
|
end
|
|
end
|
|
|
|
-- calcolo gli offset
|
|
local vOffsMain = CalcSplitPositionOffsets( nAreaId, nAreaId, tabGrid[0])
|
|
local vOffsSecondary = CalcSplitPositionOffsets( nAreaId, vVirtualAreas[1], tabGrid[1])
|
|
|
|
for i = 0, #tabGrid do
|
|
-- recupero l'area di riferimento che racchiude gli split ( i.e. l'area dello split per split principali, area virtuale i-esima per split secondari) e ne costruisco il bordo
|
|
local nRefAreaId = EgtIf( i == 0, nAreaId, vVirtualAreas[i])
|
|
local nOutlineLayerId = EgtGetFirstNameInGroup( nRefAreaId, WIN_OUTLINE)
|
|
local vOutlineIds = EgtGetAllInGroup( nOutlineLayerId)
|
|
local nOutlineCompo = EgtCurveCompo( nAreaId, vOutlineIds, false)
|
|
for i = 1, #vOutlineIds do
|
|
EgtCurveCompoSetTempProp( nOutlineCompo, i - 1, vOutlineIds[i])
|
|
end
|
|
|
|
-- posiziono correttamente e taglio con outline
|
|
local vOffs = EgtIf( i == 0, vOffsMain, vOffsSecondary)
|
|
for j = 1, #tabGrid[i] do
|
|
EgtOffsetCurve( tabGrid[i][j], vOffs[j])
|
|
if not TrimSplitWithOutline( tabGrid[i][j], nOutlineCompo, vOutlineIds) then
|
|
-- se split fuoriesce dalla sottoarea lo elimino
|
|
EgtErase( tabGrid[i][j])
|
|
tabGrid[i][j] = nil
|
|
end
|
|
end
|
|
|
|
-- creo gli outline delle aree figlie ( i.e. aree virtuali per split principale, sottoaree di ordine i-esimo per split secondari di ordine i-esimo)
|
|
CalculateNullOutline( nOutlineCompo, tabGrid[i], EgtIf( i == 0, vVirtualAreas, tabAreas[i]))
|
|
|
|
EgtErase( nOutlineCompo)
|
|
end
|
|
end
|
|
|
|
|
|
------------------------------ SASH -------------------------------
|
|
---------------------------------------------------------------------
|
|
-- funzione che disegna l'apertura dell'anta
|
|
local function DrawOpening( nAreaId)
|
|
|
|
local nOpeningType = EgtGetInfo( nAreaId, WIN_OPENING_TYPE, 'i')
|
|
if nOpeningType == WIN_OPENING_TYPES.NULL then
|
|
return
|
|
end
|
|
|
|
-- creo gruppo per aperture
|
|
local nOpeningLayId = EgtGroup( nAreaId)
|
|
EgtSetName( nOpeningLayId, WIN_SASH_OPENING)
|
|
|
|
-- verifico se anta ricevente per impostare tratteggio
|
|
local nFactor = 7
|
|
local nPattern = 0xAAAA
|
|
local nType = EgtGetInfo( nAreaId, WIN_SASHTYPE, 'i')
|
|
local bStippled = ( nType == WIN_SASHTYPES.INACTIVE or nType == WIN_SASHTYPES.INACTIVE_IN or nType == WIN_SASHTYPES.INACTIVE_OUT)
|
|
|
|
-- calcolo la curva di riferimento per il disegno dell'apertura
|
|
local nOutlineLayId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE)
|
|
local vOutlines = EgtGetAllInGroup( nOutlineLayId)
|
|
-- TODO gestire caso di triangolo
|
|
if #vOutlines == 3 then
|
|
return
|
|
end
|
|
local vCrvs = {}
|
|
for i = 1, #vOutlines do
|
|
local nCrv = EgtCopyGlob( vOutlines[i], nOpeningLayId)
|
|
table.insert( vCrvs, nCrv)
|
|
local nProfileId = GetOutlineTheoricProfileId( vOutlines[i], true)
|
|
local dRealDim = EgtGetInfo( vOutlines[i], WIN_PART_DIM, 'd')
|
|
local dRailOffs = 0
|
|
if EgtGetName( nProfileId) == WIN_FILL_RAIL then
|
|
local nBottomRail = EgtGetInfo( vOutlines[i], WIN_BOTTOMRAIL, 'i')
|
|
dRailOffs = CalcRailOffset( vOutlines[i], nProfileId, nBottomRail)
|
|
local vBottomRailDims = EgtGetInfo( vOutlines[i], WIN_BOTTOMRAIL .. WIN_PART_DIM, 'vd')
|
|
dRealDim = vBottomRailDims[#vBottomRailDims]
|
|
end
|
|
local b3Profile = GetProfileLocalBox( nProfileId)
|
|
local dOffs = b3Profile:getMin():getX() * dRealDim / b3Profile:getDimX() - dRailOffs
|
|
EgtOffsetCurve( nCrv, dOffs)
|
|
end
|
|
vCrvs = TrimOrderedCurves( vCrvs, true)
|
|
local nGuideId = EgtCurveCompo( nOpeningLayId, vCrvs)
|
|
local _, dParE = EgtCurveDomain( nGuideId)
|
|
|
|
-- ribalta
|
|
if nOpeningType == WIN_OPENING_TYPES.TILTONLY_TOP or nOpeningType == WIN_OPENING_TYPES.TILTTURN_LEFT or nOpeningType == WIN_OPENING_TYPES.TILTTURN_RIGHT then
|
|
-- ricavo il punto sul top
|
|
local ptMid = EgtUP( nGuideId, 2.5)
|
|
if not EgtCurveIsARectangle( nGuideId) then
|
|
-- per maggiore simmetria ricavo il punto sul top in corrispondenza del punto medio del bottom
|
|
local ptTest = EgtUP( nGuideId, 0.5)
|
|
local nLineTest = EgtLinePVL( nOpeningLayId, ptTest + Y_AX(), Y_AX(), 10000)
|
|
ptMid = EgtIP( nGuideId, nLineTest, ORIG())
|
|
EgtErase( nLineTest)
|
|
end
|
|
EgtCurveCompoFromPoints( nOpeningLayId, { EgtSP( nGuideId), ptMid, EgtUP( nGuideId, 1)})
|
|
elseif nOpeningType == WIN_OPENING_TYPES.TILTONLY_BOTTOM then
|
|
-- ricavo il punto sul bottom
|
|
local ptMid = EgtUP( nGuideId, 0.5)
|
|
EgtCurveCompoFromPoints( nOpeningLayId, { EgtUP( nGuideId, 2), ptMid, EgtUP( nGuideId, dParE - 1)})
|
|
end
|
|
|
|
-- altre tipologie
|
|
if nOpeningType == WIN_OPENING_TYPES.TILTTURN_LEFT or nOpeningType == WIN_OPENING_TYPES.TURNONLY_LEFT then
|
|
-- battente sx
|
|
local dLenRight = EgtCurveCompoLength( nGuideId, 1)
|
|
local dLenLeft = EgtCurveCompoLength( nGuideId, dParE - 1)
|
|
local dParMid = 1.5
|
|
-- se lato sinistro è il più corto, prendo sul destro il corrispondente del suo punto medio
|
|
if dLenLeft < dLenRight - GEO.EPS_SMALL then
|
|
dParMid = EgtCurveParamAtLength( nGuideId, EgtCurveCompoLength( nGuideId, 0) + dLenLeft * 0.5)
|
|
end
|
|
local nCrv = EgtCurveCompoFromPoints( nOpeningLayId, { EgtSP( nGuideId), EgtUP( nGuideId, dParMid), EgtUP( nGuideId, dParE - 1)})
|
|
-- tratteggio
|
|
if bStippled then
|
|
EgtSetStipple( nCrv, nFactor, nPattern)
|
|
end
|
|
|
|
elseif nOpeningType == WIN_OPENING_TYPES.TILTTURN_RIGHT or nOpeningType == WIN_OPENING_TYPES.TURNONLY_RIGHT then
|
|
-- battente dx
|
|
local dLenRight = EgtCurveCompoLength( nGuideId, 1)
|
|
local dLenLeft = EgtCurveCompoLength( nGuideId, dParE - 1)
|
|
local dParMid = dParE - 0.5
|
|
-- se lato destro è il più corto, prendo sul sinistro il corrispondente del suo punto medio
|
|
if dLenRight < dLenLeft - GEO.EPS_SMALL then
|
|
dParMid = EgtCurveParamAtLength( nGuideId, EgtCurveLength( nGuideId) - dLenRight * 0.5)
|
|
end
|
|
local nCrv = EgtCurveCompoFromPoints( nOpeningLayId, { EgtUP( nGuideId, 1), EgtUP( nGuideId, dParMid), EgtUP( nGuideId, 2)})
|
|
-- tratteggio
|
|
if bStippled then
|
|
EgtSetStipple( nCrv, nFactor, nPattern)
|
|
end
|
|
|
|
elseif nOpeningType == WIN_OPENING_TYPES.COPLANARSLIDE_LEFT or nOpeningType == WIN_OPENING_TYPES.COPLANARSLIDE_RIGHT or
|
|
nOpeningType == WIN_OPENING_TYPES.LIFTSLIDE_LEFT or nOpeningType == WIN_OPENING_TYPES.LIFTSLIDE_RIGHT then
|
|
-- scorrevole e alzante scorrevole ( solo forma rettangolare)
|
|
local bRight = ( nOpeningType == WIN_OPENING_TYPES.COPLANARSLIDE_RIGHT or nOpeningType == WIN_OPENING_TYPES.LIFTSLIDE_RIGHT)
|
|
local dLen0 = EgtCurveCompoLength( nGuideId, 0)
|
|
local dLen1 = EgtCurveCompoLength( nGuideId, 1)
|
|
local dCoeff = 0.15
|
|
local ptS = EgtUP( nGuideId, 1.5) - dCoeff * dLen0 * X_AX()
|
|
local ptE = EgtUP( nGuideId, dParE - 0.5) + dCoeff * dLen0 * X_AX()
|
|
if bRight then
|
|
ptS, ptE = ptE, ptS
|
|
end
|
|
local nCompo = EgtCurveCompoFromPoints( nOpeningLayId, { ptS, ptE})
|
|
if nOpeningType == WIN_OPENING_TYPES.COPLANARSLIDE_LEFT or nOpeningType == WIN_OPENING_TYPES.COPLANARSLIDE_RIGHT then
|
|
EgtAddCurveCompoLine( nCompo, ptS - dCoeff * dLen1 * Y_AX(), false)
|
|
end
|
|
local dAng = EgtIf( bRight, 135, 45)
|
|
EgtLinePDL( nOpeningLayId, ptE, dAng, dCoeff * dLen0)
|
|
EgtLinePDL( nOpeningLayId, ptE, - dAng, dCoeff * dLen0)
|
|
|
|
elseif nOpeningType == WIN_OPENING_TYPES.FIXED then
|
|
-- nessun disegno
|
|
|
|
elseif nOpeningType == WIN_OPENING_TYPES.PIVOT then
|
|
-- bilico rettangolare
|
|
local nCompo = EgtCurveCompoFromPoints( nOpeningLayId, { EgtUP( nGuideId, 0.5), EgtUP( nGuideId, 1.5), EgtUP( nGuideId, 2.5), EgtUP( nGuideId, 3.5)})
|
|
EgtCloseCurveCompo( nCompo)
|
|
-- TODO oblò
|
|
end
|
|
|
|
EgtErase( nGuideId)
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che identifica la forma dell'anta/gruppo di ante
|
|
local function IdentifySashShape( nAreaId, nOutlineLayerId)
|
|
|
|
local vOutlines = EgtGetAllInGroup( nOutlineLayerId)
|
|
local nCompoId = EgtCurveCompo( nOutlineLayerId, vOutlines, false)
|
|
|
|
-- verifico se trapezio
|
|
local bTrap, ptOrig, vtB1, vtE1, vtB2 = EgtCurveIsATrapezoid( nCompoId)
|
|
if bTrap then
|
|
-- verifico se rettangolo controllando se lati sono paralleli
|
|
local vtE2 = vtB1 + vtE1 - vtB2
|
|
if AreSameOrOppositeVectorApprox( vtE1, vtE2) then
|
|
EgtSetInfo( nAreaId, WIN_SASH_SHAPE, WIN_SASH_SHAPES.RECT)
|
|
else
|
|
EgtSetInfo( nAreaId, WIN_SASH_SHAPE, WIN_SASH_SHAPES.TRAP)
|
|
end
|
|
|
|
else
|
|
-- verifico se cerchio
|
|
local bCircle = EgtCurveIsACircle( nCompoId)
|
|
if bCircle then
|
|
EgtSetInfo( nAreaId, WIN_SASH_SHAPE, WIN_SASH_SHAPES.CIRCLE)
|
|
|
|
-- verifico se forma con arco
|
|
elseif #vOutlines == 4 and EgtGetType( vOutlines[3]) == GDB_TY.CRV_ARC then
|
|
local dAngCenter = EgtArcAngCenter( vOutlines[3])
|
|
if abs( dAngCenter - 180) < GEO.EPS_SMALL then
|
|
EgtSetInfo( nAreaId, WIN_SASH_SHAPE, WIN_SASH_SHAPES.ROUND_ARC)
|
|
else
|
|
if abs( EgtCurveLength( vOutlines[2]) - EgtCurveLength( vOutlines[4])) < GEO.EPS_SMALL then
|
|
EgtSetInfo( nAreaId, WIN_SASH_SHAPE, WIN_SASH_SHAPES.SEGMENTAL_ARC)
|
|
else
|
|
-- verifico se metà di arco a tutto sesto o ribassato
|
|
if AreSameVectorApprox( EgtEV( vOutlines[2]), EgtSV( vOutlines[3])) or AreSameVectorApprox( EgtEV( vOutlines[3]), EgtSV( vOutlines[4])) then
|
|
EgtSetInfo( nAreaId, WIN_SASH_SHAPE, WIN_SASH_SHAPES.SEMI_ROUND_ARC)
|
|
else
|
|
EgtSetInfo( nAreaId, WIN_SASH_SHAPE, WIN_SASH_SHAPES.SEMI_SEGMENTAL_ARC)
|
|
end
|
|
end
|
|
end
|
|
else
|
|
EgtSetInfo( nAreaId, WIN_SASH_SHAPE, WIN_SASH_SHAPES.GENERIC)
|
|
end
|
|
end
|
|
|
|
EgtErase( nCompoId)
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function CalculateSashOutline( nAreaId, nAreaLayerId, nOutlineLayerId)
|
|
|
|
-- calcolo l'outline corrispondente al telaio
|
|
local nFrameArea = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_AREA .. '*')
|
|
local nFrameOutlineLayer = EgtGetFirstNameInGroup( nFrameArea, WIN_OUTLINE)
|
|
local vFrameOutlines = EgtGetAllInGroup( nFrameOutlineLayer)
|
|
local vFrameOffs = {}
|
|
-- calcolo gli offset da applicare ad ogni curva
|
|
for i = 1, #vFrameOutlines do
|
|
-- recupero il suo profilo per calcolare l'offset
|
|
local nProfileId = GetOutlineTheoricProfileId( vFrameOutlines[i])
|
|
local sKey = EgtIf( EgtGetName( vFrameOutlines[i]) == WIN_BOTTOM, WIN_SASH_BOTTOM_OVERLAP, WIN_SASH_TOP_OVERLAP)
|
|
local dOverlap = EgtGetInfo( nProfileId, sKey, 'd')
|
|
if dOverlap then
|
|
local b3Profile = GetProfileLocalBox( nProfileId)
|
|
local dRealDim = EgtGetInfo( vFrameOutlines[i], WIN_PART_DIM, 'd')
|
|
vFrameOffs[i] = b3Profile:getMin():getX() * dRealDim / b3Profile:getDimX() + dOverlap
|
|
end
|
|
end
|
|
-- costruisco l'outline
|
|
for i = 1, #vFrameOutlines do
|
|
local nOutlineId = EgtCopyGlob( vFrameOutlines[i], nOutlineLayerId)
|
|
EgtSetInfo( nOutlineId, WIN_SOU_OUTLINE, vFrameOutlines[i])
|
|
-- rimuovo info che non voglio trasferire sull'anta
|
|
EgtRemoveInfo( nOutlineId, WIN_PRF_CHANGE)
|
|
EgtRemoveInfo( nOutlineId, WIN_THRESHOLD)
|
|
EgtRemoveInfo( nOutlineId, WIN_PART_DIM)
|
|
-- applico l'offset
|
|
if vFrameOffs[i] then
|
|
EgtOffsetCurve( nOutlineId, vFrameOffs[i])
|
|
else
|
|
-- se non ha offset definito è un pezzo che verrà tagliato da uno split ma, affinchè la forma del telaio sia coerente, se è in tangenza con uno dei suoi vicini
|
|
-- devo applicare lo stesso offset
|
|
local nPrevIdx = EgtIf( i == 1, #vFrameOutlines, i-1)
|
|
local nNextIdx = EgtIf( i == #vFrameOutlines, 1, i+1)
|
|
if AreSameVectorApprox( EgtSV( vFrameOutlines[i]), EgtEV( vFrameOutlines[nPrevIdx])) then
|
|
while not vFrameOffs[nPrevIdx] do
|
|
nPrevIdx = EgtIf( nPrevIdx == 1, #vFrameOutlines, nPrevIdx-1)
|
|
end
|
|
EgtOffsetCurve( nOutlineId, vFrameOffs[nPrevIdx])
|
|
vFrameOffs[i] = vFrameOffs[nPrevIdx]
|
|
elseif AreSameVectorApprox( EgtEV( vFrameOutlines[i]), EgtSV( vFrameOutlines[nNextIdx])) then
|
|
while not vFrameOffs[nNextIdx] do
|
|
nNextIdx = EgtIf( nNextIdx == #vFrameOutlines, 1, nNextIdx+1)
|
|
end
|
|
EgtOffsetCurve( nOutlineId, vFrameOffs[nNextIdx])
|
|
vFrameOffs[i] = vFrameOffs[nNextIdx]
|
|
end
|
|
end
|
|
end
|
|
-- accorcio gli offset
|
|
local vCrvs = TrimOrderedCurves( EgtGetAllInGroup( nOutlineLayerId), true)
|
|
|
|
|
|
-- 2) taglio con eventuali split
|
|
local vSplitIds = {}
|
|
local tabSplitCrvName = {} -- associa allo split il nome della curva di outline che da esso deriva
|
|
local nParentId = EgtGetParent( nAreaId)
|
|
while nParentId ~= nFrameArea do
|
|
local nParentType = EgtGetInfo( nParentId, WIN_AREATYPE, 'i')
|
|
if nParentType == WIN_AREATYPES.NULL then
|
|
local nNullOutlineLay = EgtGetFirstNameInGroup( nParentId, WIN_OUTLINE)
|
|
local vNullOutlines = EgtGetAllInGroup( nNullOutlineLay)
|
|
for i = 1, #vNullOutlines do
|
|
local nSou = EgtGetInfo( vNullOutlines[i], WIN_SOU_OUTLINE, 'i')
|
|
if EgtGetName( EgtGetParent( EgtGetParent( abs( nSou)))) == WIN_VIRTUAL_AREA then
|
|
nSou = EgtGetInfo( abs( nSou), WIN_SOU_OUTLINE, 'i')
|
|
end
|
|
if EgtGetName( abs( nSou)) == WIN_SPLIT then
|
|
table.insert( vSplitIds, nSou)
|
|
tabSplitCrvName[abs( nSou)] = EgtGetName( vNullOutlines[i])
|
|
end
|
|
end
|
|
elseif nParentType == WIN_AREATYPES.SPLIT and EgtGetInfo( nParentId, WIN_SPLITTYPE, 'i') == WIN_SPLITTYPES.FRENCH then
|
|
-- recupero l'indice dell'anta french dal suo nome
|
|
local sAreaName = EgtGetName( nAreaId)
|
|
local sAreaIdx = string.sub( sAreaName, string.len( WIN_AREA) + 1, string.len( WIN_AREA) + 1)
|
|
local nAreaIdx = tonumber( sAreaIdx)
|
|
local nSplitLayerId = EgtGetFirstNameInGroup( nParentId, WIN_SPLIT)
|
|
local vFrenchSplits = EgtGetAllInGroup( nSplitLayerId)
|
|
-- in base al numero di anta french recupero i french split che la definiscono con il corretto orientamento
|
|
if nAreaIdx > 1 then
|
|
table.insert( vSplitIds, - vFrenchSplits[nAreaIdx - 1])
|
|
end
|
|
if nAreaIdx < #vFrenchSplits + 1 then
|
|
table.insert( vSplitIds, vFrenchSplits[nAreaIdx])
|
|
end
|
|
end
|
|
nParentId = EgtGetParent( nParentId)
|
|
end
|
|
|
|
if #vSplitIds == 0 then
|
|
-- salvo associazioni sou/child sugli outlines
|
|
for i = 1, #vCrvs do
|
|
local nSouOutlineId = EgtGetInfo( vCrvs[i], WIN_SOU_OUTLINE, 'i')
|
|
AddInfo( nSouOutlineId, WIN_CHILD_OUTLINE, vCrvs[i])
|
|
end
|
|
else
|
|
|
|
-- li ordino per id crescente in modo da effettuare i tagli nell'ordine corretto
|
|
table.sort( vSplitIds, function ( a, b) return abs( a) < abs( b) end)
|
|
|
|
-- creo bordo complessivo dell'outline, salvando le info di SouOutline come temp prop della curva per non perderle
|
|
local vSouOutlines = {}
|
|
for i = 1, #vCrvs do
|
|
vSouOutlines[i] = EgtGetInfo( vCrvs[i], WIN_SOU_OUTLINE, 'i')
|
|
end
|
|
local nCompo = EgtCurveCompo( nOutlineLayerId, vCrvs)
|
|
for i = 0, #vCrvs - 1 do
|
|
EgtCurveCompoSetTempProp( nCompo, i, vSouOutlines[i+1])
|
|
end
|
|
|
|
-- taglio con split
|
|
for i = 1, #vSplitIds do
|
|
|
|
-- a) creo la curva di outline corrispondente allo split
|
|
local nOutlineId = EgtCopy( abs( vSplitIds[i]), nOutlineLayerId)
|
|
-- rimuovo info che non voglio trasferire
|
|
EgtRemoveInfo( nOutlineId, WIN_PRF_CHANGE)
|
|
-- verifico orientamento
|
|
if vSplitIds[i] < 0 then
|
|
EgtInvertCurve( nOutlineId)
|
|
end
|
|
-- calcolo gli offset
|
|
local nProfileId = GetOutlineTheoricProfileId( abs( vSplitIds[i]))
|
|
if nProfileId then
|
|
local b3Profile = GetProfileLocalBox( nProfileId)
|
|
local sKey = EgtIf( tabSplitCrvName[abs( vSplitIds[i])] == WIN_BOTTOM, WIN_SASH_BOTTOM_OVERLAP, WIN_SASH_TOP_OVERLAP)
|
|
local dOverlap = EgtGetInfo( nProfileId, sKey, 'd')
|
|
local dRealDim = EgtGetInfo( abs( vSplitIds[i]), WIN_PART_DIM, 'd')
|
|
local dFillPerpOffset = abs( b3Profile:getMin():getX()) * dRealDim / b3Profile:getDimX() - dOverlap
|
|
EgtOffsetCurve( nOutlineId, - dFillPerpOffset)
|
|
else
|
|
-- è french split quindi non ha offset
|
|
end
|
|
|
|
-- b) aggiorno la curva complessiva di outline con la curva appena calcolata
|
|
EgtExtendCurveStartByLen( nOutlineId, 1000)
|
|
EgtExtendCurveEndByLen( nOutlineId, 1000)
|
|
local ptS = EgtIP( nOutlineId, nCompo, EgtSP( nOutlineId))
|
|
local ptE = EgtIP( nOutlineId, nCompo, EgtEP( nOutlineId))
|
|
local dBorderParS = EgtCurveParamAtPoint( nCompo, ptS)
|
|
local dBorderParE = EgtCurveParamAtPoint( nCompo, ptE)
|
|
EgtTrimCurveStartEndAtParam( nCompo, dBorderParE, dBorderParS)
|
|
local dSplitParS = EgtCurveParamAtPoint( nOutlineId, ptS)
|
|
local dSplitParE = EgtCurveParamAtPoint( nOutlineId, ptE)
|
|
EgtTrimCurveStartEndAtParam( nOutlineId, dSplitParS, dSplitParE)
|
|
EgtAddCurveCompoCurve( nCompo, nOutlineId)
|
|
local _, dParEnd = EgtCurveDomain( nCompo)
|
|
EgtCurveCompoSetTempProp( nCompo, dParEnd - 1, vSplitIds[i])
|
|
end
|
|
|
|
-- spezzo la curva di outline nelle sue sottocurve e riassegno le info
|
|
local vTempProps = EgtCurveCompoGetTempProp( nCompo)
|
|
local nCrv, nCnt = EgtExplodeCurveCompo( nCompo)
|
|
for i = 0, nCnt - 1 do
|
|
local nOutlineId = nCrv + i
|
|
-- assegno le info sou/child
|
|
EgtSetInfo( nOutlineId, WIN_SOU_OUTLINE, vTempProps[i+1])
|
|
if vTempProps[i+1] > 0 then
|
|
AddInfo( vTempProps[i+1], WIN_CHILD_OUTLINE, nOutlineId)
|
|
else
|
|
AddInfo( abs( vTempProps[i+1]), WIN_CHILD_OUTLINE, - nOutlineId)
|
|
end
|
|
-- sistemo il nome
|
|
if EgtGetName( abs( vTempProps[i+1])) == WIN_SPLIT then
|
|
-- se deriva da split il nome è salvato nella tabella, se non lo fosse si tratta di un french split e lo calcolo al momento
|
|
local sName = tabSplitCrvName[abs( vTempProps[i+1])]
|
|
if sName then
|
|
EgtSetName( nOutlineId, sName)
|
|
else
|
|
AssignSplitName( nOutlineId)
|
|
end
|
|
else
|
|
EgtSetName( nOutlineId, EgtGetName( abs( vTempProps[i+1])))
|
|
end
|
|
end
|
|
|
|
-- riordino in modo da avere il bottom come prima curva
|
|
for i = 0, nCnt - 1 do
|
|
if EgtGetName( nCrv + i) ~= WIN_BOTTOM then
|
|
EgtRelocateGlob( nCrv + i, nOutlineLayerId, GDB_IN.LAST_SON)
|
|
else
|
|
break
|
|
end
|
|
end
|
|
end
|
|
|
|
-- calcolo i profili
|
|
local vOutlineCrvs = EgtGetAllInGroup( nOutlineLayerId)
|
|
CalcSashProfiles( vOutlineCrvs, nAreaId)
|
|
|
|
-- spostamento in z : recupero la quota da un profilo dell'anta
|
|
local nProfileLayerId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_PROFILE)
|
|
local nSashProfileLayerId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_SASH)
|
|
local sSashProfile = EgtGetInfo( vOutlineCrvs[1], WIN_PROFILETYPE)
|
|
local nSashProfileId = EgtGetFirstNameInGroup( nSashProfileLayerId, sSashProfile)
|
|
local dSashZOffset = EgtGetInfo( nSashProfileId, WIN_DELTA, 'd')
|
|
EgtMove( vOutlineCrvs, Z_AX() * dSashZOffset)
|
|
|
|
return vOutlineCrvs
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function VerifySashOutlines( vOutlines, nAreaId)
|
|
|
|
-- controlla se i pezzi di un'anta sono validi e se necessitano di gestione speciale nel calcolo dei prev e dei next. Vi sono due tipologie di pezzi che richiedono gestione speciale :
|
|
-- a) extra : il pezzo non serve, il suo contributo si limita al trim dei suoi pezzi vicini con il suo bordo out
|
|
-- b) special : il pezzo è necessario ma non sufficiente per il trim dei suoi pezzi vicini, che vanno tagliati non solo con il pezzo stesso ma anche tra di loro
|
|
-- per distinguere i pezzi extra da special controllo se i semiprofili interni dei pezzi vicini si incontrano in un punto sensato per cui il pezzo risulta superfluo oppure no
|
|
|
|
local nGrpTmp1 = EgtGroup( nAreaId)
|
|
local nGrpTmp2 = EgtGroup( nAreaId)
|
|
|
|
-- recupero i bordi interni ed esterni dei semiprofili in
|
|
local vInSemiProfile = {}
|
|
local vOutSemiProfile = {}
|
|
for i = 1, #vOutlines do
|
|
|
|
-- recupero il semiprofilo in
|
|
local nProfileId = GetOutlineTheoricProfileId( vOutlines[i])
|
|
local nSectionFrId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME)
|
|
local frSectionFrame = EgtFR( nSectionFrId, GDB_ID.ROOT)
|
|
local nInId = EgtGetFirstNameInGroup( nProfileId, WIN_IN)
|
|
local b3In = EgtGetBBoxRef( nInId, GDB_BB.STANDARD, frSectionFrame)
|
|
local dDimStd = EgtGetInfo( nProfileId, WIN_DIM_STD, 'd')
|
|
local dRealDim = EgtGetInfo( vOutlines[i], WIN_PART_DIM, 'd')
|
|
|
|
vInSemiProfile[i] = EgtCopyGlob( vOutlines[i], nGrpTmp1)
|
|
EgtSetInfo( vInSemiProfile[i], 'SouIdx', i)
|
|
-- se non è possibile calcolare l'interno ( e.g. arco con raggio inferiore alla sua dimensione) il pezzo è sicuramente extra ma considero comunque le sue curve nel fare i conti
|
|
-- per non sfalsare gli indici
|
|
if not EgtOffsetCurve( vInSemiProfile[i], b3In:getMin():getX() * dRealDim / dDimStd) then
|
|
EgtSetInfo( vOutlines[i], WIN_EXTRA_CRV, true)
|
|
end
|
|
|
|
vOutSemiProfile[i] = EgtCopyGlob( vOutlines[i], nGrpTmp2)
|
|
EgtOffsetCurve( vOutSemiProfile[i], b3In:getMax():getX() * dRealDim / dDimStd)
|
|
EgtSetInfo( vOutSemiProfile[i], 'SouIdx', i)
|
|
end
|
|
|
|
local _, vExtraIn = TrimOrderedCurves( vInSemiProfile, false)
|
|
-- se nessun bordo più interno scompare allora tutti i pezzi sono standard
|
|
if #vExtraIn == 0 then
|
|
EgtErase( nGrpTmp1)
|
|
EgtErase( nGrpTmp2)
|
|
return
|
|
end
|
|
|
|
local _, vExtraOut = TrimOrderedCurves( vOutSemiProfile, false)
|
|
-- se il bordo esterno del suo profilo in scompare i suoi vicini si incontrano in modo sensato quindi il pezzo è sicuramente superfluo
|
|
for i = 1, #vExtraOut do
|
|
local nIdx = EgtGetInfo( vExtraOut[i], 'SouIdx', 'i')
|
|
EgtSetInfo( vOutlines[nIdx], WIN_EXTRA_CRV, true)
|
|
end
|
|
|
|
-- analizzo i tratti con gestione speciale consecutivi insieme
|
|
local nOldId
|
|
local vExtraInGrps = {}
|
|
for i = 1, #vExtraIn do
|
|
local nIdx = EgtGetInfo( vExtraIn[i], 'SouIdx', 'i')
|
|
if not EgtGetInfo( vOutlines[nIdx], WIN_EXTRA_CRV, 'b') then
|
|
if not nOldId or EgtGetNext( nOldId) ~= vExtraIn[i] then
|
|
table.insert( vExtraInGrps, { vExtraIn[i]})
|
|
else
|
|
table.insert( vExtraInGrps[#vExtraInGrps], vExtraIn[i])
|
|
end
|
|
nOldId = vExtraIn[i]
|
|
end
|
|
end
|
|
|
|
for i = 1, #vExtraInGrps do
|
|
|
|
-- calcolo il punto di incontro dei semiprofili interni dei due pezzi vicini validi
|
|
local nIdx1 = EgtGetInfo( vExtraInGrps[i][1], 'SouIdx', 'i')
|
|
local nPrevIdx = EgtIf( nIdx1 == 1, #vOutlines, nIdx1-1)
|
|
while EgtGetInfo( vOutlines[nPrevIdx], WIN_EXTRA_CRV, 'b') do
|
|
nPrevIdx = EgtIf( nPrevIdx == 1, #vOutlines, nPrevIdx-1)
|
|
end
|
|
local nIdx2 = EgtGetInfo( vExtraInGrps[i][#vExtraInGrps[i]], 'SouIdx', 'i')
|
|
local nNextIdx = EgtIf( nIdx2 == #vOutlines, 1, nIdx2+1)
|
|
while EgtGetInfo( vOutlines[nNextIdx], WIN_EXTRA_CRV, 'b') do
|
|
nNextIdx = EgtIf( nNextIdx == #vOutlines, 1, nNextIdx+1)
|
|
end
|
|
local nPrevOut = vOutSemiProfile[nPrevIdx]
|
|
local nNextOut = vOutSemiProfile[nNextIdx]
|
|
local ptInters = FindIntersectionPoint( nPrevOut, nNextOut, EgtEP( nPrevOut))
|
|
|
|
-- ricavo le curva che delimita la regione valida per l'intersezione dei semiprofili dei pezzi vicini
|
|
local vCurrOutlines = {}
|
|
for j = 1, #vExtraInGrps[i] do
|
|
local nIdx = EgtGetInfo( vExtraInGrps[i][j], 'SouIdx', 'i')
|
|
vCurrOutlines[j] = vOutlines[nIdx]
|
|
end
|
|
local nCompoOutline = EgtCurveCompo( nGrpTmp1, vCurrOutlines, false)
|
|
local nProfileId = GetOutlineTheoricProfileId( vCurrOutlines[1])
|
|
local dDimStd = EgtGetInfo( nProfileId, WIN_DIM_STD, 'd')
|
|
local dRealDim = EgtGetInfo( vCurrOutlines[1], WIN_PART_DIM, 'd')
|
|
local nSectionFrId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME)
|
|
local frSectionFrame = EgtFR( nSectionFrId, GDB_ID.ROOT)
|
|
local nCPId = EgtGetFirstNameInGroup( nProfileId, WIN_OUT)
|
|
local b3CP = EgtGetBBoxRef( nCPId, GDB_BB.STANDARD, frSectionFrame)
|
|
local nRefCrv = EgtOffsetCurveAdv( nCompoOutline, b3CP:getMin():getX() * dRealDim / dDimStd)
|
|
local _, _, nSide = EgtPointCurveDistSide( ptInters, nRefCrv, Z_AX())
|
|
|
|
for j = 1, #vCurrOutlines do
|
|
-- se il punto di intersezione cade nella regione valida il pezzo è extra altrimenti è special
|
|
if nSide == -1 then
|
|
EgtSetInfo( vCurrOutlines[j], WIN_EXTRA_CRV, true)
|
|
else
|
|
EgtSetInfo( vCurrOutlines[j], WIN_SPECIAL_CRV, true)
|
|
end
|
|
end
|
|
end
|
|
|
|
EgtErase( nGrpTmp1)
|
|
EgtErase( nGrpTmp2)
|
|
end
|
|
|
|
|
|
------------------------------ FILL -------------------------------
|
|
---------------------------------------------------------------------
|
|
local function CalculateFillOutline( nAreaId, nOutlineLayerId)
|
|
|
|
-- recupero area parent di tipo telaio/anta che la contiene
|
|
local nParentArea = EgtGetParent( nAreaId)
|
|
local nAreaType = EgtGetInfo( nParentArea, WIN_AREATYPE, 'i')
|
|
while nAreaType ~= WIN_AREATYPES.FRAME and nAreaType ~= WIN_AREATYPES.SASH do
|
|
nParentArea = EgtGetParent( nParentArea)
|
|
nAreaType = EgtGetInfo( nParentArea, WIN_AREATYPE, 'i')
|
|
end
|
|
|
|
-- 1) calcolo l'area complessiva di fill definita dal suo parent
|
|
local nParentOutlineLayer = EgtGetFirstNameInGroup( nParentArea, WIN_OUTLINE)
|
|
local dDeltaZ = 0
|
|
local vParentOutlines = EgtGetAllInGroup( nParentOutlineLayer)
|
|
local vParentOffs = {}
|
|
-- calcolo gli offset
|
|
for i = 1, #vParentOutlines do
|
|
-- recupero il suo profilo per calcolare l'offset perpendicolare
|
|
local nParentProfileId = GetOutlineTheoricProfileId( vParentOutlines[i], true)
|
|
local dOverlap = EgtGetInfo( nParentProfileId, WIN_FILLOVERLAP, 'd')
|
|
if dOverlap then
|
|
local dRealDim = EgtGetInfo( vParentOutlines[i], WIN_PART_DIM, 'd')
|
|
-- verifico se contributo per bottomrail
|
|
local dRailOffs = 0
|
|
if EgtGetName( nParentProfileId) == WIN_FILL_RAIL then
|
|
local nBottomRail = EgtGetInfo( vParentOutlines[i], WIN_BOTTOMRAIL, 'i')
|
|
dRailOffs = CalcRailOffset( vParentOutlines[i], nParentProfileId, nBottomRail)
|
|
local vBottomRailDims = EgtGetInfo( vParentOutlines[i], WIN_BOTTOMRAIL .. WIN_PART_DIM, 'vd')
|
|
dRealDim = vBottomRailDims[#vBottomRailDims]
|
|
end
|
|
local b3FrameProfile = GetProfileLocalBox( nParentProfileId)
|
|
local dDimRef = b3FrameProfile:getMin():getX() * dRealDim / b3FrameProfile:getDimX()
|
|
vParentOffs[i] = abs( dDimRef) - dOverlap + dRailOffs
|
|
-- movimento in z
|
|
if dDeltaZ < GEO.EPS_SMALL then
|
|
dDeltaZ = EgtGetInfo( nParentProfileId, WIN_FILLDELTA, 'd')
|
|
end
|
|
end
|
|
end
|
|
-- creo le curve di outlines
|
|
for i = 1, #vParentOutlines do
|
|
-- copio la curva di outline del parent
|
|
local nOutlineId = EgtCopy( vParentOutlines[i], nOutlineLayerId)
|
|
EgtSetInfo( nOutlineId, WIN_SOU_OUTLINE, vParentOutlines[i])
|
|
-- applico offset
|
|
if vParentOffs[i] then
|
|
EgtOffsetCurve( nOutlineId, - vParentOffs[i])
|
|
else
|
|
-- se non ha offset definito è un pezzo che verrà tagliato da uno split ma, affinchè la forma del telaio sia coerente, devo applicare lo stesso offset a curve
|
|
-- che sono in tangenza
|
|
local nPrevIdx = EgtIf( i == 1, #vParentOutlines, i-1)
|
|
local nNextIdx = EgtIf( i == #vParentOutlines, 1, i+1)
|
|
if AreSameVectorApprox( EgtSV( vParentOutlines[i]), EgtEV( vParentOutlines[nPrevIdx])) then
|
|
while not vParentOffs[nPrevIdx] do
|
|
nPrevIdx = EgtIf( nPrevIdx == 1, #vParentOutlines, nPrevIdx-1)
|
|
end
|
|
EgtOffsetCurve( nOutlineId, - vParentOffs[nPrevIdx])
|
|
vParentOffs[i] = vParentOffs[nPrevIdx]
|
|
elseif AreSameVectorApprox( EgtEV( vParentOutlines[i]), EgtSV( vParentOutlines[nNextIdx])) then
|
|
while not vParentOffs[nNextIdx] do
|
|
nNextIdx = EgtIf( nNextIdx == #vParentOutlines, 1, nNextIdx+1)
|
|
end
|
|
EgtOffsetCurve( nOutlineId, - vParentOffs[nNextIdx])
|
|
vParentOffs[i] = vParentOffs[nNextIdx]
|
|
end
|
|
end
|
|
end
|
|
-- accorcio gli offset
|
|
local vCrvs = TrimOrderedCurves( EgtGetAllInGroup( nOutlineLayerId), true)
|
|
-- applico spostamento verticale
|
|
EgtMove( vCrvs, Z_AX() * dDeltaZ)
|
|
|
|
|
|
-- 2) taglio con split
|
|
local nParentType = EgtGetInfo( EgtGetParent( nAreaId), WIN_AREATYPE, 'i')
|
|
if nParentType ~= WIN_AREATYPES.NULL then
|
|
-- salvo associazioni sou/child
|
|
for i = 1, #vCrvs do
|
|
local nSouOutlineId = EgtGetInfo( vCrvs[i], WIN_SOU_OUTLINE, 'i')
|
|
AddInfo( nSouOutlineId, WIN_CHILD_OUTLINE, vCrvs[i])
|
|
end
|
|
return
|
|
end
|
|
|
|
-- creo bordo complessivo dell'outline, salvando le info come temp prop della curva per non perderle
|
|
local vSouOutlines = {}
|
|
for i = 1, #vCrvs do
|
|
vSouOutlines[i] = EgtGetInfo( vCrvs[i], WIN_SOU_OUTLINE, 'i')
|
|
end
|
|
local nCompo = EgtCurveCompo( nOutlineLayerId, vCrvs)
|
|
for i = 0, #vCrvs - 1 do
|
|
EgtCurveCompoSetTempProp( nCompo, i, vSouOutlines[i+1])
|
|
end
|
|
|
|
-- recupero gli split che definiscono l'area fill cercando gli split in tutte le aree parent di tipo null
|
|
local vSplitIds = {}
|
|
local nParentId = EgtGetParent( nAreaId)
|
|
while nParentId ~= nParentArea do
|
|
local nParentType = EgtGetInfo( nParentId, WIN_AREATYPE, 'i')
|
|
if nParentType == WIN_AREATYPES.NULL then
|
|
local nNullOutlineLay = EgtGetFirstNameInGroup( nParentId, WIN_OUTLINE)
|
|
local vNullOutlines = EgtGetAllInGroup( nNullOutlineLay)
|
|
for i = 1, #vNullOutlines do
|
|
local nSou = EgtGetInfo( vNullOutlines[i], WIN_SOU_OUTLINE, 'i')
|
|
if EgtGetName( EgtGetParent( EgtGetParent( abs( nSou)))) == WIN_VIRTUAL_AREA then
|
|
nSou = EgtGetInfo( abs( nSou), WIN_SOU_OUTLINE, 'i')
|
|
end
|
|
if EgtGetName( abs( nSou)) == WIN_SPLIT then
|
|
table.insert( vSplitIds, nSou)
|
|
end
|
|
end
|
|
end
|
|
nParentId = EgtGetParent( nParentId)
|
|
end
|
|
|
|
-- li ordino per id crescente in modo da effettuare i tagli nell'ordine corretto
|
|
table.sort( vSplitIds, function ( a, b) return abs( a) < abs( b) end)
|
|
|
|
for i = 1, #vSplitIds do
|
|
|
|
-- creo la curva di outline corrispondente allo split
|
|
local nOutlineId = EgtCopy( abs( vSplitIds[i]), nOutlineLayerId)
|
|
if vSplitIds[i] < 0 then
|
|
EgtInvertCurve( nOutlineId)
|
|
end
|
|
-- calcolo gli offset
|
|
local nProfileId = GetOutlineTheoricProfileId( abs( vSplitIds[i]), true)
|
|
local b3Profile = GetProfileLocalBox( nProfileId)
|
|
local dOverlap = EgtGetInfo( nProfileId, WIN_FILLOVERLAP, 'd')
|
|
local dDimRef = EgtIf( vSplitIds[i] < 0, b3Profile:getMax():getX(), b3Profile:getMin():getX())
|
|
local dRealDim = EgtGetInfo( abs( vSplitIds[i]), WIN_PART_DIM, 'd')
|
|
local dOffs = abs( dDimRef) * dRealDim / b3Profile:getDimX() - dOverlap
|
|
EgtOffsetCurve( nOutlineId, - dOffs)
|
|
-- movimento in z
|
|
local dFillZOffset = EgtGetInfo( nProfileId, WIN_FILLDELTA, 'd')
|
|
EgtMove( nOutlineId, Z_AX() * dFillZOffset)
|
|
|
|
-- aggiorno la curva complessiva di outline con la curva appena calcolata
|
|
local ptS = EgtIP( nOutlineId, nCompo, EgtSP( nOutlineId))
|
|
local ptE = EgtIP( nOutlineId, nCompo, EgtEP( nOutlineId))
|
|
local dBorderParS = EgtCurveParamAtPoint( nCompo, ptS)
|
|
local dBorderParE = EgtCurveParamAtPoint( nCompo, ptE)
|
|
EgtTrimCurveStartEndAtParam( nCompo, dBorderParE, dBorderParS)
|
|
local dSplitParS = EgtCurveParamAtPoint( nOutlineId, ptS)
|
|
local dSplitParE = EgtCurveParamAtPoint( nOutlineId, ptE)
|
|
EgtTrimCurveStartEndAtParam( nOutlineId, dSplitParS, dSplitParE)
|
|
EgtAddCurveCompoCurve( nCompo, nOutlineId)
|
|
local _, dParEnd = EgtCurveDomain( nCompo)
|
|
EgtCurveCompoSetTempProp( nCompo, dParEnd - 1, vSplitIds[i])
|
|
end
|
|
|
|
-- spezzo la curva di outline nelle sue sottocurve e riassegno le info
|
|
local vTempProps = EgtCurveCompoGetTempProp( nCompo)
|
|
local nCrv, nCnt = EgtExplodeCurveCompo( nCompo)
|
|
for i = 0, nCnt - 1 do
|
|
EgtSetInfo( nCrv + i, WIN_SOU_OUTLINE, vTempProps[i+1])
|
|
if vTempProps[i+1] > 0 then
|
|
AddInfo( vTempProps[i+1], WIN_CHILD_OUTLINE, nCrv + i)
|
|
else
|
|
AddInfo( abs( vTempProps[i+1]), WIN_CHILD_OUTLINE, - ( nCrv + i))
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
-------------------- AGGIORNAMENTO TIPOLOGIE ----------------------
|
|
---------------------------------------------------------------------
|
|
-- funzione ricorsiva che aggiorna le tipologie di split guardando le curve di outlines ( e non quelle di base outlines come fatto in CalcProfileType)
|
|
local function UpdateSplitTypes( nAreaId)
|
|
|
|
local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i')
|
|
|
|
if nAreaType == WIN_AREATYPES.SASH or nAreaType == WIN_AREATYPES.FILL then
|
|
return
|
|
|
|
elseif nAreaType == WIN_AREATYPES.SPLIT then
|
|
if EgtGetInfo( nAreaId, WIN_SPLITTYPE, 'i') ~= WIN_SPLITTYPES.FRENCH then
|
|
local nSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_SPLIT)
|
|
local vSplits = EgtGetAllInGroup( nSplitLayerId)
|
|
for i = 1, #vSplits do
|
|
|
|
-- identifico la tipologia di figli dal lato destro (1) e sinistro (2)
|
|
local tabChildren = {{}, {}}
|
|
local vSashNbr = { 0, 0}
|
|
local vFillNbr = { 0, 0}
|
|
local vBaseChildren = EgtGetInfo( vSplits[i], WIN_CHILD_VIRTUAL_OUTLINE, 'vi')
|
|
-- ordino i figli letti dalle info in modo tale che quello di destra ( che ha segno negativo) sia il primo e quello di sinistra ( che ha segno positivo) sia il secondo
|
|
if vBaseChildren[1] > vBaseChildren[2] then
|
|
vBaseChildren[1], vBaseChildren[2] = vBaseChildren[2], vBaseChildren[1]
|
|
end
|
|
|
|
for k = 1, 2 do
|
|
local vCurrChildren = { vBaseChildren[k]}
|
|
local j = 1
|
|
while vCurrChildren[j] do
|
|
local vNewChildren = EgtGetInfo( abs( vCurrChildren[j]), WIN_CHILD_VIRTUAL_OUTLINE, 'vi')
|
|
if vNewChildren then
|
|
EgtJoinTables( vCurrChildren, vNewChildren)
|
|
else
|
|
-- se non ha ulteriori figli allora è l'area null finale che deve essere studiata
|
|
local nNullAreaId = EgtGetParent( EgtGetParent( abs( vCurrChildren[j])))
|
|
local nAreaId = EgtGetFirstNameInGroup( nNullAreaId, WIN_AREA .. '*')
|
|
local nAreaType
|
|
if nAreaId then
|
|
nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i')
|
|
if nAreaType == WIN_AREATYPES.SASH then
|
|
vSashNbr[k] = vSashNbr[k] + 1
|
|
elseif nAreaType == WIN_AREATYPES.FILL then
|
|
vFillNbr[k] = vFillNbr[k] + 1
|
|
end
|
|
end
|
|
table.insert( tabChildren[k], { nId = abs( vCurrChildren[j]), nType = nAreaType})
|
|
end
|
|
j = j + 1
|
|
end
|
|
end
|
|
|
|
-- ricavo la nuova tipologia di split ed eventualmente aggiorno il profilo se fosse diverso da quello calcolato dai base outlines
|
|
local nOldType = EgtGetInfo( vSplits[i], WIN_SPLITTYPE, 'i')
|
|
|
|
-- se figli sono solo ante è montante
|
|
if vFillNbr[1] == 0 and vFillNbr[2] == 0 then
|
|
if nOldType ~= WIN_SPLITTYPES.MULLION then
|
|
EgtSetInfo( vSplits[i], WIN_SPLITTYPE, WIN_SPLITTYPES.MULLION)
|
|
if AreSameOrOppositeVectorApprox( EgtSV( vSplits[i]), X_AX()) then
|
|
EgtSetInfo( vSplits[i], WIN_PROFILETYPE, WIN_SASH_HORIZONTAL)
|
|
else
|
|
EgtSetInfo( vSplits[i], WIN_PROFILETYPE, WIN_SASH_VERTICAL)
|
|
end
|
|
end
|
|
|
|
-- se figli sono solo vetri fissi è muntin interno al telaio
|
|
elseif vSashNbr[1] == 0 and vSashNbr[2] == 0 then
|
|
if nOldType ~= WIN_SPLITTYPES.MUNTIN_FRAME then
|
|
EgtSetInfo( vSplits[i], WIN_SPLITTYPE, WIN_SPLITTYPES.MUNTIN_FRAME)
|
|
EgtSetInfo( vSplits[i], WIN_PROFILETYPE, WIN_FRAME_SPLIT)
|
|
end
|
|
|
|
-- se figli di entrambe le tipologie è mixed e verifico quali sono le parti dello split coinvolte dal cambio profilo
|
|
else
|
|
local nPrfChange = 0
|
|
-- ricavo le tipologie di figli su start ed end a destra
|
|
local nStart1, nEnd1
|
|
if vSashNbr[1] > 0 and vFillNbr[1] == 0 then
|
|
nStart1 = WIN_CHILDREN_TYPES.SASH
|
|
nEnd1 = WIN_CHILDREN_TYPES.SASH
|
|
elseif vSashNbr[1] == 0 and vFillNbr[1] > 0 then
|
|
nStart1 = WIN_CHILDREN_TYPES.FILL
|
|
nEnd1 = WIN_CHILDREN_TYPES.FILL
|
|
else
|
|
nPrfChange = nPrfChange + WIN_PRF_CHANGE_TYPES.OUT -- ha cambio profilo sul lato esterno
|
|
for j = 1, #tabChildren[1] do
|
|
if AreSamePointApprox( EgtSP( vSplits[i]), EgtEP( tabChildren[1][j].nId)) then
|
|
nStart1 = EgtIf( tabChildren[1][j].nType == WIN_AREATYPES.SASH, WIN_CHILDREN_TYPES.SASH, WIN_CHILDREN_TYPES.FILL)
|
|
end
|
|
if AreSamePointApprox( EgtEP( vSplits[i]), EgtSP( tabChildren[1][j].nId)) then
|
|
nEnd1 = EgtIf( tabChildren[1][j].nType == WIN_AREATYPES.SASH, WIN_CHILDREN_TYPES.SASH, WIN_CHILDREN_TYPES.FILL)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- ricavo le tipologie di figli su start ed end a sinistra
|
|
local nStart2, nEnd2
|
|
if vSashNbr[2] > 0 and vFillNbr[2] == 0 then
|
|
nStart2 = WIN_CHILDREN_TYPES.SASH
|
|
nEnd2 = WIN_CHILDREN_TYPES.SASH
|
|
elseif vSashNbr[2] == 0 and vFillNbr[2] > 0 then
|
|
nStart2 = WIN_CHILDREN_TYPES.FILL
|
|
nEnd2 = WIN_CHILDREN_TYPES.FILL
|
|
else
|
|
nPrfChange = nPrfChange + WIN_PRF_CHANGE_TYPES.IN -- ha cambio profilo su lato interno
|
|
for j = 1, #tabChildren[2] do
|
|
if AreSamePointApprox( EgtSP( vSplits[i]), EgtSP( tabChildren[2][j].nId)) then
|
|
nStart2 = EgtIf( tabChildren[2][j].nType == WIN_AREATYPES.SASH, WIN_CHILDREN_TYPES.SASH, WIN_CHILDREN_TYPES.FILL)
|
|
end
|
|
if AreSamePointApprox( EgtEP( vSplits[i]), EgtEP( tabChildren[2][j].nId)) then
|
|
nEnd2 = EgtIf( tabChildren[2][j].nType == WIN_AREATYPES.SASH, WIN_CHILDREN_TYPES.SASH, WIN_CHILDREN_TYPES.FILL)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- se le tipologie di figli sugli estremi sono diverse tra destra e sinistra allora l'estremo è coinvolto dal cambio profilo
|
|
if nStart1 ~= nStart2 then
|
|
nPrfChange = nPrfChange + WIN_PRF_CHANGE_TYPES.START
|
|
end
|
|
if nEnd1 ~= nEnd2 then
|
|
nPrfChange = nPrfChange + WIN_PRF_CHANGE_TYPES.END
|
|
end
|
|
|
|
EgtSetInfo( vSplits[i], WIN_SPLITTYPE, WIN_SPLITTYPES.MIXED)
|
|
EgtSetInfo( vSplits[i], WIN_PRF_CHANGE, nPrfChange)
|
|
EgtSetInfo( vSplits[i], WIN_MIXED_START_CHILDREN .. '1', nStart1)
|
|
EgtSetInfo( vSplits[i], WIN_MIXED_START_CHILDREN .. '2', nStart2)
|
|
EgtSetInfo( vSplits[i], WIN_MIXED_END_CHILDREN .. '1', nEnd1)
|
|
EgtSetInfo( vSplits[i], WIN_MIXED_END_CHILDREN .. '2', nEnd2)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- analizzo le sottoaree
|
|
local vChildren = EgtGetNameInGroup( nAreaId, WIN_AREA .. '*')
|
|
for i = 1, #vChildren do
|
|
UpdateSplitTypes( vChildren[i])
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function VerifyOutlinesInterferenceWithMixedSplit( nAreaId, vOutlines)
|
|
|
|
local vInterference = {}
|
|
local vToBeTested = {}
|
|
for i = 1, #vOutlines do
|
|
vInterference[i] = false
|
|
vToBeTested[i] = false
|
|
end
|
|
|
|
local nGrpTmp = EgtGroup( nAreaId)
|
|
EgtSetStatus( nGrpTmp, GDB_ST.OFF)
|
|
|
|
-- ricavo i profili mixed teorici
|
|
local nProfileGrp = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_PROFILE)
|
|
local nFrameProfileGrp = EgtGetFirstNameInGroup( nProfileGrp, WIN_FRAME)
|
|
local nBottomProfileId = EgtGetFirstNameInGroup( nFrameProfileGrp, WIN_MIXED_BOTTOM)
|
|
local b3Bottom = GetProfileLocalBox( nBottomProfileId)
|
|
local nTopProfileId = EgtGetFirstNameInGroup( nFrameProfileGrp, WIN_MIXED_TOP)
|
|
local b3Top = GetProfileLocalBox( nTopProfileId)
|
|
local nSplitProfileId = EgtGetFirstNameInGroup( nFrameProfileGrp, WIN_MIXED_SPLIT)
|
|
local b3Split = GetProfileLocalBox( nSplitProfileId)
|
|
|
|
-- calcolo i box delle curve di outlines
|
|
local tabBox = {}
|
|
for i = 1, #vOutlines do
|
|
local nProfileId = EgtIf( i == 1, nBottomProfileId, nTopProfileId)
|
|
local b3Profile = EgtIf( i == 1, b3Bottom, b3Top)
|
|
local b3Box, frRef = CreateTestBoxFromOutline( vOutlines[i], nProfileId, b3Profile)
|
|
tabBox[i] = { frRef = frRef, b3Box = b3Box}
|
|
end
|
|
|
|
|
|
-- recupero tutti gli split con cambio profilo sugli estremi che arrivano sul telaio
|
|
local tabSplits = {}
|
|
local vChildAreas = EgtGetNameInGroup( nAreaId, WIN_AREA .. '*')
|
|
local i = 1
|
|
while vChildAreas[i] do
|
|
local nAreaType = EgtGetInfo( vChildAreas[i], WIN_AREATYPE, 'i')
|
|
if nAreaType == WIN_AREATYPES.SASH or nAreaType == WIN_AREATYPES.FILL then
|
|
-- la ricerca a cascata si interrompe
|
|
else
|
|
if nAreaType == WIN_AREATYPES.SPLIT then
|
|
local nSplitLayerId = EgtGetFirstNameInGroup( vChildAreas[i], WIN_SPLIT)
|
|
local vSplits = EgtGetAllInGroup( nSplitLayerId)
|
|
for j = 1, #vSplits do
|
|
|
|
local nPrfChange = EgtGetInfo( vSplits[j], WIN_PRF_CHANGE, 'i') or WIN_PRF_CHANGE_TYPES.NULL
|
|
if nPrfChange & WIN_PRF_CHANGE_TYPES.START > 0 then
|
|
local nBaseStart = EgtGetInfo( vSplits[j], WIN_SPLIT_STARTINTERS, 'i')
|
|
local nStart = GetNonVirtualOutline( nBaseStart)
|
|
if EgtGetName( abs( nStart)) ~= WIN_SPLIT then
|
|
-- controllo con quanti outlines fa interferenza controllando l'overlap dei box
|
|
local nRefCrv = EgtCopyGlob( vSplits[j], nGrpTmp)
|
|
EgtTrimCurveEndAtLen( nRefCrv, 0.5 * EgtCurveLength( nRefCrv))
|
|
local b3Box, frRef = CreateTestBoxFromOutline( nRefCrv, nSplitProfileId, b3Split)
|
|
|
|
local vTest = {} -- indici degli outlines con cui fa interferenza
|
|
for k = 1, #tabBox do
|
|
if Overlaps( tabBox[k].b3Box, tabBox[k].frRef, b3Box, frRef) then
|
|
table.insert( vTest, k)
|
|
end
|
|
end
|
|
|
|
if #vTest == 1 then
|
|
-- se fa intereferenza con una sola curva non servono ulteriori controlli, l'interferenza è confermata
|
|
vInterference[vTest[1]] = true
|
|
AddInfo( vOutlines[vTest[1]], WIN_CHILD_PRFCHANGE_SPLIT, vSplits[j])
|
|
EgtSetInfo( vSplits[j], WIN_PREV_OUTLINES, vOutlines[vTest[1]])
|
|
EgtSetInfo( vSplits[j], WIN_STARTJOINT, WIN_PART_JNT.SHORT)
|
|
elseif #vTest > 1 then
|
|
-- se fa interferenza con più curve allora dovrò controllare quali sono le vere interferenze controllando i profili
|
|
table.insert( tabSplits, { nId = vSplits[j], bStart = true, vTest = vTest})
|
|
for k = 1, #vTest do
|
|
vToBeTested[vTest[k]] = true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if nPrfChange & WIN_PRF_CHANGE_TYPES.END > 0 then
|
|
local nBaseEnd = EgtGetInfo( vSplits[j], WIN_SPLIT_ENDINTERS, 'i')
|
|
local nEnd = GetNonVirtualOutline( nBaseEnd)
|
|
if EgtGetName( abs( nEnd)) ~= WIN_SPLIT then
|
|
local nRefCrv = EgtCopyGlob( vSplits[j], nGrpTmp)
|
|
EgtTrimCurveStartAtLen( nRefCrv, 0.5 * EgtCurveLength( nRefCrv))
|
|
local b3Box, frRef = CreateTestBoxFromOutline( nRefCrv, nSplitProfileId, b3Split)
|
|
|
|
local vTest = {}
|
|
for k = 1, #tabBox do
|
|
if Overlaps( tabBox[k].b3Box, tabBox[k].frRef, b3Box, frRef) then
|
|
table.insert( vTest, k)
|
|
end
|
|
end
|
|
|
|
if #vTest == 1 then
|
|
vInterference[vTest[1]] = true
|
|
AddInfo( vOutlines[vTest[1]], WIN_CHILD_PRFCHANGE_SPLIT, vSplits[j])
|
|
EgtSetInfo( vSplits[j], WIN_NEXT_OUTLINES, vOutlines[vTest[1]])
|
|
EgtSetInfo( vSplits[j], WIN_ENDJOINT, WIN_PART_JNT.SHORT)
|
|
elseif #vTest > 1 then
|
|
table.insert( tabSplits, { nId = vSplits[j], bStart = false, vTest = vTest})
|
|
for k = 1, #vTest do
|
|
vToBeTested[vTest[k]] = true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
-- analizzo le sottaree
|
|
local vCurrChildAreas = EgtGetNameInGroup( vChildAreas[i], WIN_AREA .. '*')
|
|
EgtJoinTables( vChildAreas, vCurrChildAreas)
|
|
end
|
|
i = i + 1
|
|
end
|
|
|
|
-- per ogni curva di outline che deve essere testata costruisco la superficie in con il controprofilo sash ( perchè è quella che verrà usata per tagliare lo split)
|
|
local vTestSurfs = {}
|
|
for i = 1, #vOutlines do
|
|
if vToBeTested[i] then
|
|
local nProfileId = EgtIf( i == 1, nBottomProfileId, nTopProfileId)
|
|
local nGuideId = EgtCopyGlob( vOutlines[i], nGrpTmp)
|
|
local dDimStd = EgtGetInfo( nProfileId, WIN_DIM_STD, 'd')
|
|
local dDimReal = EgtGetInfo( vOutlines[i], WIN_PART_DIM, 'd')
|
|
if abs( dDimReal - dDimStd) > GEO.EPS_SMALL then
|
|
local dOffs = dDimReal / dDimStd
|
|
EgtOffsetCurve( nGuideId, - dOffs)
|
|
end
|
|
vTestSurfs[i] = CreateProfileSurf( nGuideId, nProfileId, WIN_SASH .. WIN_CTRIN, 100, nGrpTmp)
|
|
end
|
|
end
|
|
|
|
-- taglio le superfici con bisettrice ( perchè se entrambi i pezzi hanno cambio profilo la giunzione viene forzata a angled)
|
|
for i = 1, #vOutlines do
|
|
local nPrevIdx = EgtIf( i == 1, #vOutlines, i - 1)
|
|
if vTestSurfs[i] or vTestSurfs[nPrevIdx] then
|
|
if EgtGetType( vOutlines[i]) == GDB_TY.CRV_LINE and EgtGetType( vOutlines[nPrevIdx]) == GDB_TY.CRV_LINE then
|
|
local vtDir = 0.5 * ( EgtSV( vOutlines[i]) - EgtEV( vOutlines[nPrevIdx]))
|
|
if vtDir:isZero() then
|
|
vtDir = - EgtSV( vOutlines[i])
|
|
else
|
|
vtDir:rotate( Z_AX(), 90)
|
|
end
|
|
if vTestSurfs[i] then
|
|
EgtCutSurfTmPlane( vTestSurfs[i], EgtSP( vOutlines[i]), vtDir, false)
|
|
end
|
|
if vTestSurfs[nPrevIdx] then
|
|
EgtCutSurfTmPlane( vTestSurfs[nPrevIdx], EgtSP( vOutlines[i]), - vtDir, false)
|
|
end
|
|
else
|
|
-- calcolo bisettore
|
|
local nBisector = CalcParabolicBisector( vOutlines[nPrevIdx], vOutlines[i], 100, nGrpTmp, false, false)
|
|
local nBisectorSurf = EgtSurfTmByRegionExtrusion( nGrpTmp, nBisector, - 100 * Z_AX())
|
|
if vTestSurfs[i] then
|
|
EgtSurfTmCut( vTestSurfs[i], nBisectorSurf, true, false)
|
|
end
|
|
if vTestSurfs[nPrevIdx] then
|
|
EgtSurfTmCut( vTestSurfs[nPrevIdx], nBisectorSurf, false, false)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- verifico le intereferernze
|
|
for i = 1, #tabSplits do
|
|
|
|
-- costruisco il profilo dello split sull'estremo considerato in base alla tipologia di figli
|
|
local nChildrenType1 = EgtGetInfo( tabSplits[i].nId, EgtIf( tabSplits[i].bStart, WIN_MIXED_START_CHILDREN, WIN_MIXED_END_CHILDREN) .. '1', 'i')
|
|
local sSemiProfileName1 = EgtIf( nChildrenType1 == WIN_CHILDREN_TYPES.SASH, WIN_SASH, WIN_FILL) .. WIN_IN .. '1'
|
|
local nSemiProfile1 = EgtGetFirstNameInGroup( nSplitProfileId, sSemiProfileName1)
|
|
|
|
local nChildrenType2 = EgtGetInfo( tabSplits[i].nId, EgtIf( tabSplits[i].bStart, WIN_MIXED_START_CHILDREN, WIN_MIXED_END_CHILDREN) .. '2', 'i')
|
|
local sSemiProfileName2 = EgtIf( nChildrenType2 == WIN_CHILDREN_TYPES.SASH, WIN_SASH, WIN_FILL) .. WIN_IN .. '2'
|
|
local nSemiProfile2 = EgtGetFirstNameInGroup( nSplitProfileId, sSemiProfileName2)
|
|
|
|
local dDimStd = EgtGetInfo( nSplitProfileId, WIN_DIM_STD, 'd')
|
|
local dDimReal = EgtGetInfo( tabSplits[i].nId, WIN_PART_DIM, 'd')
|
|
if abs( dDimReal - dDimStd) > GEO.EPS_SMALL then
|
|
local nSectionFrame = EgtGetFirstNameInGroup( nSplitProfileId, WIN_SECTIONFRAME)
|
|
local frProfile = EgtFR( nSectionFrame, GDB_ID.ROOT)
|
|
EgtMove( nSemiProfile1, b3Split:getMax():getX() * dDimReal / dDimStd * frProfile:getVersX(), GDB_RT.GLOB)
|
|
EgtMove( nSemiProfile1, b3Split:getMin():getX() * dDimReal / dDimStd * frProfile:getVersX(), GDB_RT.GLOB)
|
|
end
|
|
local nSection = EgtCurveCompo( nGrpTmp, nSemiProfile1, false)
|
|
EgtAddCurveCompoLine( nSection, EgtSP( nSemiProfile2, GDB_ID.ROOT), GDB_RT.GLOB)
|
|
EgtAddCurveCompoCurve( nSection, nSemiProfile2, false)
|
|
EgtCloseCurveCompo( nSection)
|
|
|
|
-- costruisco il solido di split
|
|
local nSplitSolid = CreateProfileSurfById( tabSplits[i].nId, nSplitProfileId, nSection, 400, nGrpTmp)
|
|
EgtCutSurfTmPlane( nSplitSolid, EgtMP( tabSplits[i].nId), EgtIf( tabSplits[i].bStart, 1, -1) * EgtSV( tabSplits[i].nId))
|
|
|
|
-- testo con quali superfici degli outlines fa interferenza
|
|
for j = 1, #( tabSplits[i].vTest) do
|
|
local nIdx = tabSplits[i].vTest[j]
|
|
local nId, _, nCrvCnt = EgtSurfTmSurfTmInters( nSplitSolid, vTestSurfs[nIdx], nGrpTmp)
|
|
if nId and nCrvCnt > 0 then
|
|
vInterference[nIdx] = true
|
|
AddInfo( vOutlines[nIdx], WIN_CHILD_PRFCHANGE_SPLIT, tabSplits[i].nId)
|
|
AddInfo( tabSplits[i].nId, EgtIf( tabSplits[i].bStart, WIN_PREV_OUTLINES, WIN_NEXT_OUTLINES), vOutlines[nIdx])
|
|
AddInfo( tabSplits[i].nId, EgtIf( tabSplits[i].bStart, WIN_STARTJOINT, WIN_ENDJOINT), WIN_PART_JNT.SHORT)
|
|
end
|
|
end
|
|
end
|
|
|
|
EgtErase( nGrpTmp)
|
|
return vInterference
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che aggiorna i profili del telaio guardando le curve di outlines ( e non quelle di base outlines come fatto in CalcProfileType)
|
|
local function UpdateFrameTypes( nAreaId)
|
|
|
|
local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE)
|
|
local vOutlines = EgtGetAllInGroup( nOutlineLayerId)
|
|
|
|
-- per ogni outline verifico se fa interferenza con uno split con cambio profilo sull'estremo
|
|
local vInterference = VerifyOutlinesInterferenceWithMixedSplit( nAreaId, vOutlines)
|
|
|
|
for i = 1, #vOutlines do
|
|
local nOldType = EgtGetInfo( vOutlines[i], WIN_CHILDREN_TYPE, 'i')
|
|
|
|
if vInterference[i] then
|
|
-- se fa interferenza con uno split con cambio profilo sull'estremo deve avere un profilo mixed
|
|
EgtSetInfo( vOutlines[i], WIN_PRF_CHANGE, WIN_PRF_CHANGE_TYPES.IN)
|
|
-- verifico se devo aggiornare il profilo
|
|
if nOldType ~= WIN_CHILDREN_TYPES.MIXED then
|
|
if EgtGetName( vOutlines[i]) == WIN_BOTTOM then
|
|
EgtSetInfo( vOutlines[i], WIN_PROFILETYPE, WIN_MIXED_BOTTOM)
|
|
else
|
|
EgtSetInfo( vOutlines[i], WIN_PROFILETYPE, WIN_MIXED_TOP)
|
|
end
|
|
end
|
|
|
|
else
|
|
-- se non fa interferenza con cambio profilo devo controllare la tipologia dei figli.
|
|
-- Se non era stato classificato come mixed allora basta trovare la tipologia di un figlio qualunque, se invece era mixed allora ha entrambe le tipologie di figli,
|
|
-- devo considerare quella della curva più lunga ( euristicamente se non è più mixed vuol dire che il cambio profilo avviene vicino al suo estremo quindi
|
|
-- uno dei due figli è molto più corto dell'altro)
|
|
local dFillLen = 0
|
|
local dSashLen = 0
|
|
local vChildren = EgtGetInfo( vOutlines[i], WIN_CHILD_VIRTUAL_OUTLINE, 'vi')
|
|
local j = 1
|
|
while vChildren[j] do
|
|
-- verifico se ho cascata di children
|
|
local vNewChildren = EgtGetInfo( abs( vChildren[j]), WIN_CHILD_VIRTUAL_OUTLINE, 'vi')
|
|
if vNewChildren then
|
|
EgtJoinTables( vChildren, vNewChildren)
|
|
else
|
|
-- recupero la tipologia di figli dell'area null
|
|
local nNullAreaId = EgtGetParent( EgtGetParent( abs( vChildren[j])))
|
|
local nAreaId = EgtGetFirstNameInGroup( nNullAreaId, WIN_AREA .. '*')
|
|
if nAreaId then
|
|
local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i')
|
|
if nAreaType == WIN_AREATYPES.SASH then
|
|
dSashLen = dSashLen + EgtCurveLength( abs( vChildren[j]))
|
|
else
|
|
dFillLen = dFillLen + EgtCurveLength( abs( vChildren[j]))
|
|
end
|
|
end
|
|
end
|
|
j = j + 1
|
|
end
|
|
local nChildrenType = EgtIf( dSashLen > dFillLen, WIN_CHILDREN_TYPES.SASH, WIN_CHILDREN_TYPES.FILL)
|
|
|
|
-- verifico se devo aggiornare il profilo
|
|
if nChildrenType ~= nOldType then
|
|
if nChildrenType == WIN_CHILDREN_TYPES.FILL then
|
|
if EgtGetName( vOutlines[i]) == WIN_BOTTOM then
|
|
-- verifico presenza bottomrail
|
|
local nBottomRail = EgtGetInfo( vOutlines[i], WIN_BOTTOMRAIL, 'i') or 0
|
|
local sThreshold = EgtGetInfo( EgtetParent( EgtGetParent( vOutlines[i])), WIN_THRESHOLD_PROFILE) or WIN_BOTTOM
|
|
if nBottomRail == 0 then
|
|
EgtSetInfo( vOutlines[i], WIN_PROFILETYPE, WIN_FIXED .. '_' .. sThreshold)
|
|
else
|
|
EgtSetInfo( vOutlines[i], WIN_PROFILETYPE, WIN_RAIL .. '_' .. sThreshold)
|
|
end
|
|
else
|
|
EgtSetInfo( vOutlines[i], WIN_PROFILETYPE, WIN_FIXED_TOP)
|
|
end
|
|
|
|
else -- sash
|
|
if EgtGetName( vOutlines[i]) == WIN_BOTTOM then
|
|
local sThreshold = EgtGetInfo( nAreaId, WIN_THRESHOLD_PROFILE) or WIN_BOTTOM
|
|
EgtSetInfo( vOutlines[i], WIN_PROFILETYPE, WIN_SASH .. '_' .. sThreshold)
|
|
else
|
|
EgtSetInfo( vOutlines[i], WIN_PROFILETYPE, WIN_SASH_TOP)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
---------------------------------------------------------------------
|
|
--------------------------------------------------------------------
|
|
local function CalcOutlineDimensions( vOutlines, nAreaId)
|
|
|
|
local vPartsDim = EgtGetInfo( nAreaId, WIN_PART_DIM, 'vd') or {}
|
|
local nBottomRail = EgtGetInfo( nAreaId, WIN_BOTTOMRAIL, 'i') or 0
|
|
for i = 1, #vOutlines do
|
|
|
|
if not vPartsDim[i] or EgtGetInfo( vOutlines[i], WIN_THRESHOLD, 'b') then
|
|
-- se dimensione non è impostata oppure soglia recupero quella standard del profilo
|
|
local nProfileId = GetOutlineTheoricProfileId( vOutlines[i], false)
|
|
vPartsDim[i] = EgtGetInfo( nProfileId, WIN_DIM_STD, 'd')
|
|
end
|
|
EgtSetInfo( vOutlines[i], WIN_PART_DIM, vPartsDim[i])
|
|
|
|
-- dimensioni dei bottomrails
|
|
if nBottomRail and EgtGetName( vOutlines[i]) == WIN_BOTTOM then
|
|
EgtSetInfo( vOutlines[i], WIN_BOTTOMRAIL, nBottomRail)
|
|
local vBottomRailDim = EgtGetInfo( nAreaId, WIN_BOTTOMRAIL .. WIN_PART_DIM, 'vd') or {}
|
|
if #vBottomRailDim ~= nBottomRail then
|
|
for j = 1, nBottomRail do
|
|
if not vBottomRailDim[j] then
|
|
local nProfileId = GetOutlineTheoricProfileId( vOutlines[i], false, j)
|
|
vBottomRailDim[j] = EgtGetInfo( nProfileId, WIN_DIM_STD, 'd')
|
|
end
|
|
end
|
|
end
|
|
EgtSetInfo( vOutlines[i], WIN_BOTTOMRAIL .. WIN_PART_DIM, vBottomRailDim)
|
|
end
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che calcola l'outline dal base outline e i pezzi associati
|
|
local function CalculateOutlineFromAreaOutline( nAreaId)
|
|
|
|
local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i')
|
|
|
|
-- se area null il suo outline è già stato calcolato dalla sua area split parent
|
|
if nAreaType == WIN_AREATYPES.NULL then
|
|
return
|
|
end
|
|
|
|
-- creo gruppo per outline
|
|
local nOutlineLayerId = EgtGroup( nAreaId)
|
|
EgtSetName( nOutlineLayerId, WIN_OUTLINE)
|
|
EgtSetStatus( nOutlineLayerId, GDB_ST.OFF)
|
|
|
|
-- FRAME
|
|
if nAreaType == WIN_AREATYPES.FRAME then
|
|
-- l'outline è la copia del base outline
|
|
local nBaseOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_AREAOUTLINE)
|
|
local vBaseOutlineIds = EgtGetAllInGroup( nBaseOutlineLayerId)
|
|
local nBottomRail = EgtGetInfo( nAreaId, WIN_BOTTOMRAIL, 'i') or 0
|
|
local vOutlines = {}
|
|
for i = 1, #vBaseOutlineIds do
|
|
vOutlines[i] = EgtCopyGlob( vBaseOutlineIds[i], nOutlineLayerId)
|
|
if i == 1 and nBottomRail > 0 then
|
|
EgtSetInfo( vOutlines[i], WIN_BOTTOMRAIL, nBottomRail)
|
|
end
|
|
end
|
|
CalcOutlineDimensions( vOutlines, nAreaId)
|
|
|
|
|
|
-- SPLIT
|
|
elseif nAreaType == WIN_AREATYPES.SPLIT then
|
|
|
|
-- l'outline è copia del parent outline
|
|
local nParentId = EgtGetParent( nAreaId)
|
|
if EgtGetInfo( nParentId, WIN_AREATYPE, 'i') == WIN_AREATYPES.FILL then
|
|
-- se inglesina il parent è un vetro. Il pezzo però non va tagliato con il vetro ma con l'elemento che contiene il vetro, quindi considero come outline quello del parent del vetro
|
|
nParentId = EgtGetParent( nParentId)
|
|
end
|
|
local nParentOutlineId = EgtGetFirstNameInGroup( nParentId, WIN_OUTLINE)
|
|
local vParentOutlines = EgtGetAllInGroup( nParentOutlineId)
|
|
for i = 1, #vParentOutlines do
|
|
local nOutlineId = EgtCopyGlob( vParentOutlines[i], nOutlineLayerId)
|
|
EgtSetInfo( nOutlineId, WIN_SOU_OUTLINE, vParentOutlines[i])
|
|
AddInfo( vParentOutlines[i], WIN_CHILD_VIRTUAL_OUTLINE, nOutlineId)
|
|
end
|
|
|
|
-- copio il layer di base split
|
|
local nBaseSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_BASESPLIT)
|
|
local nSplitLayerId = EgtCopy( nBaseSplitLayerId, nAreaId)
|
|
EgtSetName( nSplitLayerId, WIN_SPLIT)
|
|
EgtSetStatus( nSplitLayerId, GDB_ST.OFF)
|
|
local vBaseSplitIds = EgtGetAllInGroup( nBaseSplitLayerId)
|
|
local vSplitIds = EgtGetAllInGroup( nSplitLayerId)
|
|
|
|
-- aggiusto la quota degli split per allinearli all'outline
|
|
local dZMove = ( EgtSP( vParentOutlines[1]) - EgtSP( vSplitIds[1])) * Z_AX()
|
|
EgtMove( vSplitIds, dZMove * Z_AX())
|
|
|
|
-- aggiusto gli outlines e calcolo l'outline delle sottoaree null generate
|
|
local bGrid = EgtGetInfo( nAreaId, WIN_GRID_SPLIT, 'b') or false
|
|
if bGrid then
|
|
CalculateGridSplitOutline( nAreaId, vSplitIds)
|
|
else
|
|
CalculateSplitOutline( nAreaId, vSplitIds)
|
|
end
|
|
|
|
local nSplitType = EgtGetInfo( vSplitIds[1], WIN_SPLITTYPE, 'i')
|
|
|
|
if nSplitType == WIN_SPLITTYPES.FRENCH then
|
|
IdentifySashShape( nAreaId, nOutlineLayerId)
|
|
end
|
|
|
|
-- se inglesina su entrambi i lati creo copia degli outline per le inglesine esterne
|
|
if nSplitType == WIN_SPLITTYPES.MUNTIN_FILL then
|
|
local nMuntinType = EgtGetInfo( nAreaId, WIN_MUNTINFILL_SIDE, 'i')
|
|
if nMuntinType == WIN_MUNTINFILL_SIDES.BOTH then
|
|
local bSlide = EgtGetInfo( EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_AREA .. '*'), WIN_SLIDE_WINDOW, 'b') or false
|
|
for i = 1, #vSplitIds do
|
|
local nId = EgtCopyGlob( vSplitIds[i], nSplitLayerId)
|
|
EgtSetInfo( vSplitIds[i], WIN_REF_MUNTIN, nId)
|
|
EgtSetInfo( vSplitIds[i], WIN_MUNTINFILL_SIDE, WIN_MUNTINFILL_SIDES.IN)
|
|
EgtSetInfo( nId, WIN_PROFILETYPE, EgtIf( bSlide, WIN_SLIDE .. '_', '') .. WIN_FILL_SPLIT_OUT)
|
|
EgtSetInfo( nId, WIN_MUNTINFILL_SIDE, WIN_MUNTINFILL_SIDES.OUT)
|
|
end
|
|
else
|
|
for i = 1, #vSplitIds do
|
|
EgtSetInfo( vSplitIds[i], WIN_MUNTINFILL_SIDE, nMuntinType)
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
-- SASH
|
|
elseif nAreaType == WIN_AREATYPES.SASH then
|
|
local nBaseOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_AREAOUTLINE)
|
|
local vOutlines = CalculateSashOutline( nAreaId, nBaseOutlineLayerId, nOutlineLayerId)
|
|
CalcOutlineDimensions( vOutlines, nAreaId)
|
|
-- ne verifico validità
|
|
VerifySashOutlines( vOutlines, nAreaId)
|
|
-- identifico la forma
|
|
IdentifySashShape( nAreaId, nOutlineLayerId)
|
|
-- disegno apertura
|
|
DrawOpening( nAreaId)
|
|
|
|
|
|
-- FILL
|
|
elseif nAreaType == WIN_AREATYPES.FILL then
|
|
CalculateFillOutline( nAreaId, nOutlineLayerId)
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function CalculateFrameAreasOutlines( nAreaId)
|
|
|
|
local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i')
|
|
|
|
-- se area di telaio o split calcolo l'outline
|
|
if nAreaType == WIN_AREATYPES.FRAME or nAreaType == WIN_AREATYPES.SPLIT then
|
|
CalculateOutlineFromAreaOutline( nAreaId)
|
|
|
|
-- se area anta o fill devo interrompere la ricerca
|
|
elseif nAreaType == WIN_AREATYPES.SASH or nAreaType == WIN_AREATYPES.FILL then
|
|
return
|
|
end
|
|
|
|
local vChildrenAreas = EgtGetNameInGroup( nAreaId, WIN_AREA .. '*')
|
|
for i = 1, #vChildrenAreas do
|
|
CalculateFrameAreasOutlines( vChildrenAreas[i])
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function CalculateResidualAreaOutlines( nAreaId)
|
|
|
|
local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i')
|
|
|
|
if nAreaType == WIN_AREATYPES.SASH or nAreaType == WIN_AREATYPES.FILL then
|
|
CalculateOutlineFromAreaOutline( nAreaId)
|
|
|
|
elseif nAreaType == WIN_AREATYPES.SPLIT then
|
|
-- devo calcolarla solo se non è già stato fatto ( quindi non è uno split che dipende dal telaio)
|
|
local nOutlineLayer = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE)
|
|
if not nOutlineLayer then
|
|
CalculateOutlineFromAreaOutline( nAreaId)
|
|
end
|
|
end
|
|
|
|
local vChildAreas = EgtGetNameInGroup( nAreaId, WIN_AREA .. '*')
|
|
for i = 1, #vChildAreas do
|
|
CalculateResidualAreaOutlines( vChildAreas[i])
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function CalculateAreaOutline( nAreaId)
|
|
|
|
-- calcolo l'outline del telaio e di tutti gli split ad esso riferiti
|
|
CalculateFrameAreasOutlines( nAreaId)
|
|
|
|
-- se cambio profilo lo spostamento degli split per le misure luce/esterno anta potrebbe aver modificato la tipologia dei figli delle curve del telaio e di altri split,
|
|
-- quindi la aggiorno in base agli outlines appena calcolati ( e non più rispetto ai base outlines)
|
|
local bChangeProfile = EgtGetInfo( nAreaId, WIN_MIXED_WINDOW, 'b')
|
|
if bChangeProfile then
|
|
UpdateSplitTypes( nAreaId)
|
|
UpdateFrameTypes( nAreaId)
|
|
end
|
|
|
|
-- calcolo gli outlines delle ante, dei vetri e degli split in essi contenuti
|
|
CalculateResidualAreaOutlines( nAreaId)
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che cicla ricorsivamente su aree e sottoaree per assegnare i profili all'area
|
|
local function SetAreaProfiles( nAreaId)
|
|
|
|
local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i')
|
|
if nAreaType == WIN_AREATYPES.FRAME or nAreaType == WIN_AREATYPES.SASH then
|
|
-- recupero i profili dalle curve di outline
|
|
local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE)
|
|
local vOutlines = EgtGetAllInGroup( nOutlineLayerId)
|
|
local sAreaName = EgtIf( nAreaType == WIN_AREATYPES.FRAME, WIN_FRAME, WIN_SASH)
|
|
local vProfiles = {}
|
|
for i = 1, #vOutlines do
|
|
vProfiles[i] = sAreaName .. '_' .. EgtGetInfo( vOutlines[i], WIN_PROFILETYPE)
|
|
end
|
|
EgtSetInfo( nAreaId, WIN_AREA_PROFILES, vProfiles)
|
|
|
|
elseif nAreaType == WIN_AREATYPES.SPLIT then
|
|
local nSplitType = EgtGetInfo( nAreaId, WIN_SPLITTYPE, 'i')
|
|
if nSplitType ~= WIN_SPLITTYPES.FRENCH then
|
|
-- recupero area parent per capire se dentro telaio, anta o vetro
|
|
local nParentAreaId = EgtGetParent( nAreaId)
|
|
local nParentAreaType = EgtGetInfo( nParentAreaId, WIN_AREATYPE, 'i')
|
|
while nParentAreaType == WIN_AREATYPES.SPLIT or nParentAreaType == WIN_AREATYPES.NULL do
|
|
nParentAreaId = EgtGetParent( nParentAreaId)
|
|
nParentAreaType = EgtGetInfo( nParentAreaId, WIN_AREATYPE, 'i')
|
|
end
|
|
local sAreaName
|
|
if nParentAreaType == WIN_AREATYPES.FRAME then
|
|
sAreaName = WIN_FRAME
|
|
elseif nParentAreaType == WIN_AREATYPES.SASH then
|
|
sAreaName = WIN_SASH
|
|
else
|
|
sAreaName = WIN_FILL
|
|
end
|
|
|
|
local nSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_SPLIT)
|
|
local vSplitIds = EgtGetAllInGroup( nSplitLayerId)
|
|
local bGridSplit = EgtGetInfo( nAreaId, WIN_GRID_SPLIT, 'b') or false
|
|
if bGridSplit then
|
|
-- recupero i profili distinguendoli per ordine di split
|
|
local tabProfiles = {}
|
|
for i = 1, #vSplitIds do
|
|
if not EgtExistsInfo( vSplitIds[i], WIN_REF_MUNTIN) then
|
|
local nOrder = EgtGetInfo( vSplitIds[i], WIN_GRIDSPLIT_ORDER, 'i')
|
|
local sProfile = sAreaName .. '_' .. EgtGetInfo( vSplitIds[i], WIN_PROFILETYPE)
|
|
if tabProfiles[nOrder+1] then
|
|
table.insert( tabProfiles[nOrder+1], sProfile)
|
|
else
|
|
tabProfiles[nOrder+1] = { sProfile}
|
|
end
|
|
end
|
|
end
|
|
-- salvo in info separate
|
|
for i = 1, #tabProfiles do
|
|
EgtSetInfo( nAreaId, WIN_AREA_PROFILES .. tostring( i-1), tabProfiles[i])
|
|
end
|
|
else
|
|
-- recupero tutti i profili degli split
|
|
-- se ha info WIN_REF_MUNTIN significa che split è inglesina sia interna che esterna, non ha senso considerarla due volte anche se sono due outlines distinti perchè
|
|
-- lo split che la definisce è uno solo
|
|
local vProfiles = {}
|
|
for i = 1, #vSplitIds do
|
|
if not EgtExistsInfo( vSplitIds[i], WIN_REF_MUNTIN) then
|
|
table.insert( vProfiles, sAreaName .. '_' .. EgtGetInfo( vSplitIds[i], WIN_PROFILETYPE))
|
|
end
|
|
end
|
|
EgtSetInfo( nAreaId, WIN_AREA_PROFILES, vProfiles)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- analizzo le sottoaree
|
|
local nChildAreaId = EgtGetFirstNameInGroup( nAreaId, WIN_AREA .. '*')
|
|
while nChildAreaId do
|
|
SetAreaProfiles( nChildAreaId)
|
|
nChildAreaId = EgtGetNextName( nChildAreaId, WIN_AREA .. '*')
|
|
end
|
|
end
|
|
|
|
|
|
|
|
----------------------------------------------------------------------------------
|
|
------------------------------ CALCOLO JOINTS ----------------------------------
|
|
----------------------------------------------------------------------------------
|
|
-- funzione che dato il tipo di giunzione e di pezzo ( orizzontale o verticale) restituisce se è corto, lungo o angolato
|
|
local function CalcPartJoint( nJointType, bHorizontal)
|
|
|
|
if nJointType == WIN_JNT.ANGLED then
|
|
return WIN_PART_JNT.ANGLED
|
|
elseif nJointType == WIN_JNT.FULL_H then
|
|
if bHorizontal then
|
|
return WIN_PART_JNT.FULL
|
|
else
|
|
return WIN_PART_JNT.SHORT
|
|
end
|
|
elseif nJointType == WIN_JNT.FULL_V then
|
|
if bHorizontal then
|
|
return WIN_PART_JNT.SHORT
|
|
else
|
|
return WIN_PART_JNT.FULL
|
|
end
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function CalcOutlineStartJoint( nOutlineId, nPrevOutlineId, vJoints)
|
|
|
|
local nStartJoint
|
|
|
|
if EgtGetName( nOutlineId) == WIN_BOTTOM then
|
|
nStartJoint = CalcPartJoint( vJoints[1], true)
|
|
elseif EgtGetName( nOutlineId) == WIN_RIGHT then
|
|
nStartJoint = CalcPartJoint( vJoints[2], false)
|
|
elseif EgtGetName( nOutlineId) == WIN_TOP then
|
|
nStartJoint = CalcPartJoint( vJoints[3], true)
|
|
-- correzione per caso a triangolo : se l'outline vicino è di tipo bottom, il corrente deve essere trattato come un pezzo verticale
|
|
if EgtGetName( nPrevOutlineId) == WIN_BOTTOM then
|
|
nStartJoint = CalcPartJoint( vJoints[2], false)
|
|
end
|
|
elseif EgtGetName( nOutlineId) == WIN_LEFT then
|
|
nStartJoint = CalcPartJoint( vJoints[4] or vJoints[3], false) -- ( vJoints[3] per gestire caso a triangolo)
|
|
end
|
|
|
|
-- eventuali correzioni :
|
|
-- a) forzatura a bisettrice se elementi in tangenza ( entro 6°) o dello stesso tipo
|
|
if nStartJoint ~= WIN_PART_JNT.ANGLED then
|
|
if EgtEV( nPrevOutlineId) * EgtSV( nOutlineId) > s_dAngledCos or EgtGetName( nOutlineId) == EgtGetName( nPrevOutlineId) then
|
|
nStartJoint = WIN_PART_JNT.ANGLED
|
|
end
|
|
end
|
|
|
|
-- b) forzatura a short se incontro con soglia
|
|
if EgtGetInfo( nPrevOutlineId, WIN_THRESHOLD, 'b') then
|
|
nStartJoint = WIN_PART_JNT.SHORT
|
|
end
|
|
|
|
-- c) forzatura ad angled se cambio profilo sul punto di incontro
|
|
local nProfileChange = EgtGetInfo( nOutlineId, WIN_PRF_CHANGE, 'i')
|
|
local nProfileChangeP = EgtGetInfo( nPrevOutlineId, WIN_PRF_CHANGE, 'i')
|
|
if nProfileChange == WIN_PRF_CHANGE_TYPES.IN and nProfileChangeP == WIN_PRF_CHANGE_TYPES.IN then
|
|
-- per vedere se il cambio profilo è sul punto di incontro verifico se hanno uno split con cambio profilo sull'estremo in comune
|
|
local vSplits1 = EgtGetInfo( nOutlineId, WIN_CHILD_PRFCHANGE_SPLIT, 'vi')
|
|
local vSplits2 = EgtGetInfo( nPrevOutlineId, WIN_CHILD_PRFCHANGE_SPLIT, 'vi')
|
|
for i = 1, #vSplits1 do
|
|
for j = 1, #vSplits2 do
|
|
if vSplits1[i] == vSplits2[j] then
|
|
return WIN_PART_JNT.ANGLED
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
return nStartJoint
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function CalcOutlineEndJoint( nOutlineId, nNextOutlineId, vJoints)
|
|
|
|
local nEndJoint
|
|
|
|
if EgtGetName( nOutlineId) == WIN_BOTTOM then
|
|
nEndJoint = CalcPartJoint( vJoints[2], true)
|
|
elseif EgtGetName( nOutlineId) == WIN_RIGHT then
|
|
nEndJoint = CalcPartJoint( vJoints[3], false)
|
|
elseif EgtGetName( nOutlineId) == WIN_TOP then
|
|
nEndJoint = CalcPartJoint( vJoints[4] or vJoints[3], true) -- ( vJoints[3] per gestire caso a triangolo)
|
|
-- correzione per caso a triangolo : se l'outline vicino è di tipo bottom, il corrente deve essere trattato come un pezzo verticale
|
|
if EgtGetName( nNextOutlineId) == WIN_BOTTOM then
|
|
nEndJoint = CalcPartJoint( vJoints[1], false)
|
|
end
|
|
elseif EgtGetName( nOutlineId) == WIN_LEFT then
|
|
nEndJoint = CalcPartJoint( vJoints[1], false)
|
|
end
|
|
|
|
-- eventuali correzioni :
|
|
-- a) forzatura a bisettrice se elementi in tangenza ( entro 6°) o dello stesso tipo
|
|
if nEndJoint ~= WIN_PART_JNT.ANGLED then
|
|
if EgtEV( nOutlineId) * EgtSV( nNextOutlineId) > s_dAngledCos or EgtGetName( nOutlineId) == EgtGetName( nNextOutlineId) then
|
|
nEndJoint = WIN_PART_JNT.ANGLED
|
|
end
|
|
end
|
|
|
|
-- b) forzatura a short se incontro con soglia
|
|
if EgtGetInfo( nNextOutlineId, WIN_THRESHOLD, 'b') then
|
|
nEndJoint = WIN_PART_JNT.SHORT
|
|
end
|
|
|
|
-- c) forzatura ad angled se cambio profilo sul punto di incontro
|
|
local nProfileChange = EgtGetInfo( nOutlineId, WIN_PRF_CHANGE, 'i')
|
|
local nProfileChangeN = EgtGetInfo( nNextOutlineId, WIN_PRF_CHANGE, 'i')
|
|
if nProfileChange == WIN_PRF_CHANGE_TYPES.IN and nProfileChangeN == WIN_PRF_CHANGE_TYPES.IN then
|
|
-- per vedere se il cambio profilo è sul punto di incontro verifico se hanno uno split con cambio profilo sull'estremo in comune
|
|
local vSplits1 = EgtGetInfo( nOutlineId, WIN_CHILD_PRFCHANGE_SPLIT, 'vi')
|
|
local vSplits2 = EgtGetInfo( nNextOutlineId, WIN_CHILD_PRFCHANGE_SPLIT, 'vi')
|
|
for i = 1, #vSplits1 do
|
|
for j = 1, #vSplits2 do
|
|
if vSplits1[i] == vSplits2[j] then
|
|
return WIN_PART_JNT.ANGLED
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
return nEndJoint
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function GetOutlineJoints( vOutlineIds, nAreaId)
|
|
|
|
local vJoints = EgtGetInfo( nAreaId, WIN_JOINTS, 'vi')
|
|
for i = 1, #vOutlineIds do
|
|
local nPrevIdx = EgtIf( i == 1, #vOutlineIds, i - 1)
|
|
local nNextIdx = EgtIf( i == #vOutlineIds, 1, i + 1)
|
|
local nStartJoint = CalcOutlineStartJoint( vOutlineIds[i], vOutlineIds[nPrevIdx], vJoints)
|
|
local nEndJoint = CalcOutlineEndJoint( vOutlineIds[i], vOutlineIds[nNextIdx], vJoints)
|
|
EgtSetInfo( vOutlineIds[i], WIN_STARTJOINT, nStartJoint)
|
|
EgtSetInfo( vOutlineIds[i], WIN_ENDJOINT, nEndJoint)
|
|
end
|
|
end
|
|
|
|
|
|
|
|
----------------------------------------------------------------------------------
|
|
------------------------------ CREAZIONE PEZZI ---------------------------------
|
|
----------------------------------------------------------------------------------
|
|
-- funzione che stabilisce il nome del pezzo
|
|
local function CalcPartName( nAreaId, nAreaType)
|
|
|
|
local sName = ''
|
|
if nAreaType == WIN_AREATYPES.FRAME then
|
|
sName = WIN_FRAME
|
|
EgtSetInfo( nAreaId, WIN_AREA_NAME, sName)
|
|
elseif nAreaType == WIN_AREATYPES.SASH then
|
|
s_nSashNbr = s_nSashNbr + 1
|
|
sName = WIN_SASH .. '_'.. tostring( s_nSashNbr)
|
|
EgtSetInfo( nAreaId, WIN_AREA_NAME, sName)
|
|
else
|
|
-- per split o riempimento devo ricavare il nome del parent che lo contiene
|
|
local nParentId = EgtGetParent( nAreaId)
|
|
local nParentType = EgtGetInfo( nParentId, WIN_AREATYPE, 'i')
|
|
while nParentType == WIN_AREATYPES.SPLIT or nParentType == WIN_AREATYPES.NULL do
|
|
nParentId = EgtGetParent( nParentId)
|
|
nParentType = EgtGetInfo( nParentId, WIN_AREATYPE, 'i')
|
|
end
|
|
sName = EgtGetInfo( nParentId, WIN_AREA_NAME)
|
|
|
|
if nAreaType == WIN_AREATYPES.FILL then
|
|
sName = sName .. '_' .. WIN_FILL
|
|
EgtSetInfo( nAreaId, WIN_AREA_NAME, sName)
|
|
end
|
|
end
|
|
|
|
return sName
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function CreateOutlinePart( nOutlineId, sName, dDim, nBottomRail)
|
|
|
|
-- se soglia ignoro
|
|
local bThreshold = EgtGetInfo( nOutlineId or GDB_ID.NULL, WIN_THRESHOLD, 'b') or false
|
|
if bThreshold then
|
|
return
|
|
end
|
|
|
|
-- creo pezzo
|
|
local nPartId = EgtGroup( GDB_ID.ROOT)
|
|
|
|
-- creo riferimenti tra pezzo e outline
|
|
EgtSetInfo( nPartId, WIN_REF_OUTLINE, nOutlineId)
|
|
if nBottomRail then
|
|
-- aggiorno i riferimenti del bottomrail
|
|
AddInfo( nOutlineId, WIN_REF_BOTTOMRAIL_PART, nPartId)
|
|
EgtSetInfo( nPartId, WIN_PART_TYPE, WIN_PART_TYPES.BOTTOMRAIL)
|
|
EgtSetInfo( nPartId, WIN_BOTTOMRAIL, nBottomRail)
|
|
else
|
|
EgtSetInfo( nOutlineId, WIN_REF_PART, nPartId)
|
|
EgtSetInfo( nPartId, WIN_PART_TYPE, WIN_PART_TYPES.STD)
|
|
end
|
|
|
|
-- imposto nome
|
|
local sOutlineName = EgtIf( nBottomRail, WIN_BOTTOMRAIL .. '_' .. tostring( nBottomRail), EgtGetName( nOutlineId))
|
|
local sPartName = sName .. '_' .. sOutlineName
|
|
EgtSetName( nPartId, sPartName)
|
|
|
|
-- imposto colore
|
|
if sOutlineName == WIN_BOTTOM or sOutlineName == WIN_TOP or nBottomRail then
|
|
EgtSetColor( nPartId, Color3d( 204, 102, 0))
|
|
elseif sOutlineName == WIN_RIGHT or sOutlineName == WIN_LEFT then
|
|
EgtSetColor( nPartId, Color3d( 251, 128, 4))
|
|
else
|
|
EgtSetColor( nPartId, Color3d( 255, 159, 57))
|
|
end
|
|
|
|
-- creo il profilo associato al pezzo con la dimensione opportuna
|
|
CreatePartProfile( nPartId, nOutlineId, dDim, nBottomRail)
|
|
|
|
return nPartId
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function CreatePartsFromOutlines( vOutlines, nAreaId, sName)
|
|
|
|
-- calcolo le giunzioni
|
|
GetOutlineJoints( vOutlines, nAreaId)
|
|
|
|
-- creo i pezzi per ogni curva
|
|
for i = 1, #vOutlines do
|
|
local dDim = EgtGetInfo( vOutlines[i], WIN_PART_DIM, 'd')
|
|
CreateOutlinePart( vOutlines[i], sName, dDim)
|
|
|
|
if EgtGetName( vOutlines[i]) == WIN_BOTTOM then
|
|
local nBottomRail = EgtGetInfo( vOutlines[i], WIN_BOTTOMRAIL, 'i') or 0
|
|
if nBottomRail > 0 then
|
|
local vBottomRailDim = EgtGetInfo( vOutlines[i], WIN_BOTTOMRAIL .. WIN_PART_DIM, 'vd')
|
|
for j = 1, nBottomRail do
|
|
CreateOutlinePart( vOutlines[i], sName, vBottomRailDim[j], j)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function CreateFillPartFromArea( nAreaId, sName)
|
|
|
|
local nPartId = EgtGroup( GDB_ID.ROOT)
|
|
-- inserisco riferimento alla sua area
|
|
EgtSetInfo( nPartId, WIN_AREA, nAreaId)
|
|
|
|
-- imposto nome del pezzo
|
|
EgtSetName( nPartId, sName)
|
|
EgtSetInfo( nPartId, WIN_PART_TYPE, WIN_PART_TYPES.FILL)
|
|
|
|
-- imposto colore e tipologia
|
|
local nFillType = EgtGetInfo( nAreaId, WIN_FILLTYPE, 'i')
|
|
if nFillType == WIN_FILLTYPES.GLASS then
|
|
EgtSetColor( nPartId, Color3d( 71, 161, 255))
|
|
EgtSetAlpha( nPartId, 30)
|
|
EgtSetInfo( nPartId, WIN_FILLTYPE, WIN_GLASS)
|
|
elseif nFillType == WIN_FILLTYPES.WOOD then
|
|
EgtSetColor( nPartId, Color3d( 194, 148, 103))
|
|
EgtSetInfo( nPartId, WIN_FILLTYPE, WIN_WOOD)
|
|
end
|
|
|
|
return nPartId
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che crea ricorsivamente i pezzi con i relativi profili
|
|
local function CreateAreaParts( nAreaId)
|
|
|
|
local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i')
|
|
local sName = CalcPartName( nAreaId, nAreaType)
|
|
|
|
-- FRAME
|
|
if nAreaType == WIN_AREATYPES.FRAME then
|
|
local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE)
|
|
local vOutlines = EgtGetAllInGroup( nOutlineLayerId)
|
|
CreatePartsFromOutlines( vOutlines, nAreaId, sName)
|
|
|
|
-- SPLIT
|
|
elseif nAreaType == WIN_AREATYPES.SPLIT then
|
|
if EgtGetInfo( nAreaId, WIN_SPLITTYPE, 'i') ~= WIN_SPLITTYPES.FRENCH then
|
|
local nSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_SPLIT)
|
|
local vSplits = EgtGetAllInGroup( nSplitLayerId)
|
|
for i = 1, #vSplits do
|
|
local dDim = EgtGetInfo( vSplits[i], WIN_PART_DIM, 'd')
|
|
CreateOutlinePart( vSplits[i], sName, dDim)
|
|
end
|
|
end
|
|
|
|
-- SASH
|
|
elseif nAreaType == WIN_AREATYPES.SASH then
|
|
local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE)
|
|
local vOutlines = EgtGetAllInGroup( nOutlineLayerId)
|
|
CreatePartsFromOutlines( vOutlines, nAreaId, sName)
|
|
|
|
-- FILL
|
|
elseif nAreaType == WIN_AREATYPES.FILL then
|
|
CreateFillPartFromArea( nAreaId, sName)
|
|
end
|
|
|
|
-- analizzo le sottoaree
|
|
local vAreas = EgtGetNameInGroup( nAreaId, WIN_AREA .. '*')
|
|
for i = 1, #vAreas do
|
|
CreateAreaParts( vAreas[i])
|
|
end
|
|
end
|
|
|
|
|
|
|
|
----------------------------------------------------------------------------------
|
|
------------------------ PREV & NEXT OUTLINES ----------------------------------
|
|
----------------------------------------------------------------------------------
|
|
local function TestSplitTrimOutlines( nOutlineId, nSplitType, nTrimOutline, tabOutlines, nMainProfile, b3Profile, nGrpTmp, bPrevOrNext)
|
|
|
|
local vTrimOutlines = {}
|
|
|
|
-- 1) recupero le curve da testare :
|
|
-- a) curva individuata dall'intersezione dello split con l'outline
|
|
local vTestOutlines = { tabOutlines[nTrimOutline]}
|
|
|
|
-- b) curve vicine a quella individuata dall'intersezione che interferiscono con lo split ( guardando interferenza grossolana dei box dei pezzi)
|
|
-- creo il box della curva di split
|
|
local nOutlineCopyId = EgtCopyGlob( nOutlineId, nGrpTmp)
|
|
if bPrevOrNext then
|
|
EgtTrimCurveEndAtParam( nOutlineCopyId, 0.5)
|
|
else
|
|
EgtTrimCurveStartAtParam( nOutlineCopyId, 0.5)
|
|
end
|
|
local b3Split, frSplit = CreateTestBoxFromOutline( nOutlineCopyId, nMainProfile, b3Profile)
|
|
|
|
-- curve precedenti
|
|
local nTestCurve = EgtGetPrev( nTrimOutline) or EgtGetLastInGroup( EgtGetParent( nTrimOutline))
|
|
local bInters = true
|
|
while bInters and nTestCurve ~= nTrimOutline do
|
|
-- verifico interferenza tra i box
|
|
if Overlaps( tabOutlines[nTestCurve].b3Box, tabOutlines[nTestCurve].frRef, b3Split, frSplit) then
|
|
table.insert( vTestOutlines, 1, tabOutlines[nTestCurve])
|
|
nTestCurve = EgtGetPrev( nTestCurve) or EgtGetLastInGroup( EgtGetParent( nTestCurve))
|
|
else
|
|
bInters = false
|
|
end
|
|
end
|
|
|
|
-- curve successive ( solo se non ho già considerato tutto il loop, potrebbe capitare a causa di archi il cui box non è ottimizzato con un frame)
|
|
if nTestCurve ~= nTrimOutline then
|
|
nTestCurve = EgtGetNext( nTrimOutline) or EgtGetFirstInGroup( EgtGetParent( nTrimOutline))
|
|
bInters = true
|
|
while bInters and nTestCurve ~= nTrimOutline do
|
|
-- verifico interferenza tra i box
|
|
if Overlaps( tabOutlines[nTestCurve].b3Box, tabOutlines[nTestCurve].frRef, b3Split, frSplit) then
|
|
table.insert( vTestOutlines, tabOutlines[nTestCurve])
|
|
nTestCurve = EgtGetNext( nTestCurve) or EgtGetFirstInGroup( EgtGetParent( nTestCurve))
|
|
else
|
|
bInters = false
|
|
end
|
|
end
|
|
end
|
|
|
|
if #vTestOutlines == 1 then
|
|
return { vTestOutlines[1].nId}
|
|
end
|
|
|
|
-- 2) testo le curve controllando intersezione tra le superfici dei pezzi
|
|
-- creo il solido principale
|
|
local dExtraLen = b3Profile:getDimX()
|
|
local nMainSurf
|
|
if nSplitType == WIN_SPLITTYPES.MIXED then
|
|
-- nel caso di profilo split mixed non è definita una sezione quindi devo costruirla recuperando i semiprofili in in base alla tipologia di figli sull'estremo
|
|
local nSemiProfile1 = EgtGetFirstNameInGroup( nMainProfile, WIN_IN .. '1')
|
|
if not nSemiProfile1 then
|
|
local nChildrenType1 = EgtGetInfo( nOutlineId, EgtIf( bPrevOrNext, WIN_MIXED_START_CHILDREN, WIN_MIXED_END_CHILDREN) .. '1', 'i')
|
|
local sSemiProfileName = EgtIf( nChildrenType1 == WIN_CHILDREN_TYPES.SASH, WIN_SASH, WIN_FILL) .. WIN_IN .. '1'
|
|
nSemiProfile1 = EgtGetFirstNameInGroup( nMainProfile, sSemiProfileName)
|
|
end
|
|
local nSemiProfile2 = EgtGetFirstNameInGroup( nMainProfile, WIN_IN .. '2')
|
|
if not nSemiProfile2 then
|
|
local nChildrenType2 = EgtGetInfo( nOutlineId, EgtIf( bPrevOrNext, WIN_MIXED_START_CHILDREN, WIN_MIXED_END_CHILDREN) .. '2', 'i')
|
|
local sSemiProfileName = EgtIf( nChildrenType2 == WIN_CHILDREN_TYPES.SASH, WIN_SASH, WIN_FILL) .. WIN_IN .. '2'
|
|
nSemiProfile2 = EgtGetFirstNameInGroup( nMainProfile, sSemiProfileName)
|
|
end
|
|
|
|
local nSection = EgtCurveCompo( nGrpTmp, nSemiProfile1, false)
|
|
EgtAddCurveCompoLine( nSection, EgtSP( nSemiProfile2, GDB_ID.ROOT), GDB_RT.GLOB)
|
|
EgtAddCurveCompoCurve( nSection, nSemiProfile2, false)
|
|
EgtCloseCurveCompo( nSection)
|
|
|
|
nMainSurf = CreateProfileSurfById( nOutlineId, nMainProfile, nSection, 4 * dExtraLen, nGrpTmp)
|
|
|
|
else
|
|
nMainSurf = CreateProfileSurf( nOutlineId, nMainProfile, WIN_SECTION, 4 * dExtraLen, nGrpTmp)
|
|
end
|
|
EgtCutSurfTmPlane( nMainSurf, EgtMP( nOutlineId), EgtIf( bPrevOrNext, 1, -1) * EgtSV( nOutlineId))
|
|
|
|
-- recupero profili delle curve di test per i conti
|
|
local vProfiles = {}
|
|
local vsCtrIn = {}
|
|
for i = 1, #vTestOutlines do
|
|
vProfiles[i] = vTestOutlines[i].nProfile
|
|
vsCtrIn[i] = GetProfileCtrIn( vTestOutlines[i].nId, nOutlineId, vProfiles[i], bPrevOrNext)
|
|
end
|
|
|
|
-- testo le curve
|
|
for i = 1, #vTestOutlines do
|
|
-- creo la superficie di test limitandola con le sue vicine
|
|
local nTestSurf = CreateProfileSurf( abs( vTestOutlines[i].nId), vProfiles[i], vsCtrIn[i], 4 * dExtraLen, nGrpTmp)
|
|
|
|
if i > 1 then
|
|
if AreSameVectorApprox( EgtEV( abs( vTestOutlines[i-1].nId)), EgtSV( abs( vTestOutlines[i].nId))) then
|
|
EgtCutSurfTmPlane( nTestSurf, EgtEP( abs( vTestOutlines[i-1].nId)), - EgtEV( abs( vTestOutlines[i-1].nId)), false)
|
|
else
|
|
local nTrimSurf = CreateProfileSurf( abs( vTestOutlines[i-1].nId), vProfiles[i-1], WIN_OFST .. vsCtrIn[i-1], 4 * dExtraLen, nGrpTmp)
|
|
EgtSurfTmCut( nTestSurf, nTrimSurf, true, false)
|
|
end
|
|
end
|
|
if i < #vTestOutlines then
|
|
if AreSameVectorApprox( EgtEV( abs( vTestOutlines[i].nId)), EgtSV( abs( vTestOutlines[i+1].nId))) then
|
|
EgtCutSurfTmPlane( nTestSurf, EgtEP( abs( vTestOutlines[i].nId)), EgtEV( abs( vTestOutlines[i].nId)), false)
|
|
else
|
|
local nTrimSurf = CreateProfileSurf( abs( vTestOutlines[i+1].nId), vProfiles[i+1], WIN_OFST .. vsCtrIn[i+1], 4 * dExtraLen, nGrpTmp)
|
|
EgtSurfTmCut( nTestSurf, nTrimSurf, true, false)
|
|
end
|
|
end
|
|
|
|
-- calcolo intersezione con il solido : se c'è intersezione è una vera curva di trim, altrimenti non va considerata
|
|
local nId, _, nCrvCnt = EgtSurfTmSurfTmInters( nMainSurf, nTestSurf, nGrpTmp)
|
|
if nId and nCrvCnt > 0 then
|
|
table.insert( vTrimOutlines, vTestOutlines[i].nId)
|
|
end
|
|
end
|
|
|
|
return vTrimOutlines
|
|
end
|
|
|
|
-------------------------------------------------------------------
|
|
-- funzione che recupera gli outline precedenti e successivi degli split
|
|
local function GetSplitsPrevNextOutline( vSplitIds, vOutlineIds)
|
|
|
|
local nGrpTmp = EgtGroup( GDB_ID.ROOT)
|
|
|
|
-- ad ogni outline dell'area di split associo l'outline non virtuale corrispondente ( per rendere più solidi i conti successivi)
|
|
local tabOutlines = {}
|
|
for i = 1, #vOutlineIds do
|
|
local nId = GetNonVirtualOutline( vOutlineIds[i])
|
|
-- calcolo il suo box
|
|
local nProfileId = GetOutlineProfileId( abs( nId))
|
|
local b3Profile = GetProfileLocalBox( nProfileId)
|
|
local b3Box, frRef = CreateTestBoxFromOutline( abs( nId), nProfileId, b3Profile)
|
|
tabOutlines[vOutlineIds[i]] = { nId = nId, frRef = frRef, b3Box = b3Box, nProfile = nProfileId}
|
|
end
|
|
|
|
-- per ogni split controllo la validità delle curve prev/next trovate dall'intersezione degli outlines e la validità di eventuali curve vicine verificando l'interferenza tra i profili
|
|
for i = 1, #vSplitIds do
|
|
|
|
local nMainProfile = GetOutlineProfileId( vSplitIds[i])
|
|
local b3Profile = GetProfileLocalBox( nMainProfile)
|
|
local nSplitType = EgtGetInfo( vSplitIds[i], WIN_SPLITTYPE, 'i')
|
|
|
|
-- prev
|
|
if not EgtExistsInfo( vSplitIds[i], WIN_PREV_OUTLINES) then
|
|
local nPrevOutlineId = EgtGetInfo( vSplitIds[i], WIN_SPLIT_STARTINTERS, 'i')
|
|
local vPrevOutlineIds = TestSplitTrimOutlines( vSplitIds[i], nSplitType, nPrevOutlineId, tabOutlines, nMainProfile, b3Profile, nGrpTmp, true)
|
|
EgtSetInfo( vSplitIds[i], WIN_PREV_OUTLINES, vPrevOutlineIds)
|
|
-- setto tutte le giunzioni a short
|
|
local vStartJoints = {}
|
|
for j = 1, #vPrevOutlineIds do
|
|
vStartJoints[j] = WIN_PART_JNT.SHORT
|
|
end
|
|
EgtSetInfo( vSplitIds[i], WIN_STARTJOINT, vStartJoints)
|
|
end
|
|
|
|
-- next
|
|
if not EgtExistsInfo( vSplitIds[i], WIN_NEXT_OUTLINES) then
|
|
local nNextOutlineId = EgtGetInfo( vSplitIds[i], WIN_SPLIT_ENDINTERS, 'i')
|
|
local vNextOutlineIds = TestSplitTrimOutlines( vSplitIds[i], nSplitType, nNextOutlineId, tabOutlines, nMainProfile, b3Profile, nGrpTmp, false)
|
|
EgtSetInfo( vSplitIds[i], WIN_NEXT_OUTLINES, vNextOutlineIds)
|
|
local vEndJoints = {}
|
|
for j = 1, #vNextOutlineIds do
|
|
vEndJoints[j] = WIN_PART_JNT.SHORT
|
|
end
|
|
EgtSetInfo( vSplitIds[i], WIN_ENDJOINT, vEndJoints)
|
|
end
|
|
end
|
|
|
|
EgtErase( nGrpTmp)
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function GetSashPrevNextOutlines( nAreaId)
|
|
|
|
local vJoints = EgtGetInfo( nAreaId, WIN_JOINTS, 'vi')
|
|
local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE)
|
|
local vOutlineIds = EgtGetAllInGroup( nOutlineLayerId)
|
|
|
|
for i = 1, #vOutlineIds do
|
|
|
|
if EgtGetInfo( vOutlineIds[i], WIN_EXTRA_CRV, 'b') then
|
|
-- non ha bisogno di prev/next perchè il pezzo viene ignorato
|
|
else
|
|
|
|
-- a) prev
|
|
local nPrevId = EgtGetPrev( vOutlineIds[i]) or EgtGetLastInGroup( nOutlineLayerId)
|
|
local bExtra = EgtGetInfo( nPrevId, WIN_EXTRA_CRV, 'b') or false
|
|
local bSpecial = EgtGetInfo( nPrevId, WIN_SPECIAL_CRV, 'b') or false
|
|
if not bExtra and not bSpecial then
|
|
-- se il precedente è un pezzo standard il prev è solamente lui e il joint calcolato è già corretto
|
|
EgtSetInfo( vOutlineIds[i], WIN_PREV_OUTLINES, nPrevId)
|
|
else
|
|
-- recupero tutti i precedenti fino a quando non trovo un elemento standard
|
|
local vPrevIds = {}
|
|
while bExtra or bSpecial do
|
|
table.insert( vPrevIds, 1, nPrevId)
|
|
nPrevId = EgtGetPrev( nPrevId) or EgtGetLastInGroup( nOutlineLayerId)
|
|
bExtra = EgtGetInfo( nPrevId, WIN_EXTRA_CRV, 'b') or false
|
|
bSpecial = EgtGetInfo( nPrevId, WIN_SPECIAL_CRV, 'b') or false
|
|
end
|
|
table.insert( vPrevIds, 1, nPrevId)
|
|
|
|
-- calcolo i joints
|
|
local vStartJoints = {}
|
|
local nOldId = vOutlineIds[i]
|
|
local nOldTgId = vOutlineIds[i]
|
|
local bTangChain = true -- indica se l'outline e i primi vicini formano una catena di curve in tangenza
|
|
local nJoint -- il primo joint non è quello salvato nelle info della curva ma è da calcolare con la prima curva non extra
|
|
for j = #vPrevIds, 1, -1 do
|
|
if EgtGetInfo( vPrevIds[j], WIN_EXTRA_CRV, 'b') then
|
|
-- con i pezzi extra la giunzione è sempre full perchè il pezzo corrente va trimmato con il loro bordo esterno
|
|
vStartJoints[j] = WIN_PART_JNT.FULL
|
|
else
|
|
if not nJoint then
|
|
nJoint = CalcOutlineStartJoint( nOldId, vPrevIds[j], vJoints)
|
|
end
|
|
if AreSameVectorApprox( EgtEV( vPrevIds[j]), EgtSV( nOldTgId)) then
|
|
-- curve in tangenza devono avere la stessa giunzione
|
|
vStartJoints[j] = nJoint
|
|
else
|
|
-- se arrivo dalla catena di primi vicini tangenti devo ricalcolare il joint altrimenti va forzato ad angled
|
|
if bTangChain then
|
|
nJoint = CalcOutlineStartJoint( nOldId, vPrevIds[j], vJoints)
|
|
else
|
|
nJoint = WIN_PART_JNT.ANGLED
|
|
end
|
|
bTangChain = false
|
|
vStartJoints[j] = nJoint
|
|
end
|
|
nOldId = vPrevIds[j]
|
|
end
|
|
-- gli extra vanno ignorati nel calcolo delle giunzioni ma vanno considerati per il calcolo delle tangenze
|
|
nOldTgId = vPrevIds[j]
|
|
end
|
|
|
|
EgtSetInfo( vOutlineIds[i], WIN_PREV_OUTLINES, vPrevIds)
|
|
EgtSetInfo( vOutlineIds[i], WIN_STARTJOINT, vStartJoints)
|
|
end
|
|
|
|
|
|
-- b) next
|
|
local nNextId = EgtGetNext( vOutlineIds[i]) or EgtGetFirstInGroup( nOutlineLayerId)
|
|
bExtra = EgtGetInfo( nNextId, WIN_EXTRA_CRV, 'b') or false
|
|
bSpecial = EgtGetInfo( nNextId, WIN_SPECIAL_CRV, 'b') or false
|
|
if not bExtra and not bSpecial then
|
|
-- caso standard
|
|
EgtSetInfo( vOutlineIds[i], WIN_NEXT_OUTLINES, nNextId)
|
|
else
|
|
|
|
local vNextIds = {}
|
|
while bExtra or bSpecial do
|
|
table.insert( vNextIds, nNextId)
|
|
nNextId = EgtGetNext( nNextId) or EgtGetFirstInGroup( nOutlineLayerId)
|
|
bExtra = EgtGetInfo( nNextId, WIN_EXTRA_CRV, 'b') or false
|
|
bSpecial = EgtGetInfo( nNextId, WIN_SPECIAL_CRV, 'b')
|
|
end
|
|
table.insert( vNextIds, nNextId)
|
|
|
|
-- calcolo i joints
|
|
local vEndJoints = {}
|
|
local nOldId = vOutlineIds[i]
|
|
local nOldTgId = vOutlineIds[i]
|
|
local bTangChain = true
|
|
local nJoint
|
|
for j = 1, #vNextIds do
|
|
-- se extra la giunzione deve essere full
|
|
if EgtGetInfo( vNextIds[j], WIN_EXTRA_CRV, 'b') then
|
|
vEndJoints[j] = WIN_PART_JNT.FULL
|
|
else
|
|
if not nJoint then
|
|
nJoint = CalcOutlineEndJoint( nOldId, vNextIds[j], vJoints)
|
|
end
|
|
if AreSameVectorApprox( EgtEV( nOldTgId), EgtSV( vNextIds[j])) then
|
|
vEndJoints[j] = nJoint
|
|
else
|
|
if bTangChain then
|
|
nJoint = CalcOutlineEndJoint( nOldId, vNextIds[j], vJoints)
|
|
else
|
|
nJoint = WIN_PART_JNT.ANGLED
|
|
end
|
|
bTangChain = false
|
|
vEndJoints[j] = nJoint
|
|
end
|
|
nOldId = vNextIds[j]
|
|
end
|
|
nOldTgId = vNextIds[j]
|
|
end
|
|
|
|
EgtSetInfo( vOutlineIds[i], WIN_NEXT_OUTLINES, vNextIds)
|
|
EgtSetInfo( vOutlineIds[i], WIN_ENDJOINT, vEndJoints)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function GetAreaPrevNextOutlines( nAreaId)
|
|
|
|
local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i')
|
|
|
|
-- FRAME
|
|
if nAreaType == WIN_AREATYPES.FRAME then
|
|
local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE)
|
|
local vOutlines = EgtGetAllInGroup( nOutlineLayerId)
|
|
for i = 2, #vOutlines - 1 do
|
|
EgtSetInfo( vOutlines[i], WIN_PREV_OUTLINES, vOutlines[i-1])
|
|
EgtSetInfo( vOutlines[i], WIN_NEXT_OUTLINES, vOutlines[i+1])
|
|
end
|
|
-- gestione particolare per primo e ultimo
|
|
EgtSetInfo( vOutlines[1], WIN_PREV_OUTLINES, vOutlines[#vOutlines])
|
|
EgtSetInfo( vOutlines[1], WIN_NEXT_OUTLINES, vOutlines[2])
|
|
EgtSetInfo( vOutlines[#vOutlines], WIN_PREV_OUTLINES, vOutlines[#vOutlines - 1])
|
|
EgtSetInfo( vOutlines[#vOutlines], WIN_NEXT_OUTLINES, vOutlines[1])
|
|
|
|
|
|
-- SPLIT
|
|
elseif nAreaType == WIN_AREATYPES.SPLIT then
|
|
if EgtGetInfo( nAreaId, WIN_SPLITTYPE, 'i') ~= WIN_SPLITTYPES.FRENCH then
|
|
local nSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_SPLIT)
|
|
local vSplits = EgtGetAllInGroup( nSplitLayerId)
|
|
|
|
-- se inglesine da entrambi i lati calcolo prev/next solo per quelle interne, quelle esterne verranno sistemate in base a quelle interne di cui sono copia
|
|
local bFillMuntin = false
|
|
if EgtGetInfo( vSplits[1], WIN_SPLITTYPE, 'i') == WIN_SPLITTYPES.MUNTIN_FILL and EgtGetInfo( nAreaId, WIN_MUNTINFILL_SIDE, 'i') == WIN_MUNTINFILL_SIDES.BOTH then
|
|
bFillMuntin = true
|
|
local vInSplits = {}
|
|
for i = 1, #vSplits do
|
|
local nSide = EgtGetInfo( vSplits[i], WIN_MUNTINFILL_SIDE, 'i')
|
|
if nSide == WIN_MUNTINFILL_SIDES.OUT then
|
|
break
|
|
end
|
|
vInSplits[i] = vSplits[i]
|
|
end
|
|
vSplits = vInSplits
|
|
end
|
|
|
|
-- se split a griglia
|
|
local bGrid = EgtGetInfo( nAreaId, WIN_GRID_SPLIT, 'b') or false
|
|
if bGrid then
|
|
local vVirtualAreas = EgtGetNameInGroup( nAreaId, WIN_VIRTUAL_AREA)
|
|
-- raggruppo gli split per ordine
|
|
local tabGrid = {}
|
|
for i = 1, #vSplits do
|
|
local nOrder = EgtGetInfo( vSplits[i], WIN_GRIDSPLIT_ORDER, 'i')
|
|
if tabGrid[nOrder] then
|
|
table.insert( tabGrid[nOrder], vSplits[i])
|
|
else
|
|
tabGrid[nOrder] = { vSplits[i]}
|
|
end
|
|
end
|
|
|
|
for i = 0, #tabGrid do
|
|
local nRefAreaId = EgtIf( i == 0, nAreaId, vVirtualAreas[i])
|
|
local nOutlineLayerId = EgtGetFirstNameInGroup( nRefAreaId, WIN_OUTLINE)
|
|
local vOutlineIds = EgtGetAllInGroup( nOutlineLayerId)
|
|
GetSplitsPrevNextOutline( tabGrid[i], vOutlineIds)
|
|
end
|
|
|
|
else
|
|
local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE)
|
|
GetSplitsPrevNextOutline( vSplits, EgtGetAllInGroup( nOutlineLayerId))
|
|
end
|
|
|
|
-- aggiorno eventuali inglesine out
|
|
if bFillMuntin then
|
|
for i = 1, #vSplits do
|
|
local nOutSplit = EgtGetInfo( vSplits[i], WIN_REF_MUNTIN, 'i')
|
|
-- verifico se devo aggiornare i prev/next ( caso di inglesina contro inglesina)
|
|
local vPrevOutlines = EgtGetInfo( vSplits[i], WIN_PREV_OUTLINES, 'vi')
|
|
for j = 1, #vPrevOutlines do
|
|
local nRef = EgtGetInfo( abs( vPrevOutlines[j]), WIN_REF_MUNTIN, 'i')
|
|
if nRef then
|
|
vPrevOutlines[j] = EgtIf( vPrevOutlines[j] > 0, nRef, - nRef)
|
|
end
|
|
end
|
|
local vNextOutlines = EgtGetInfo( vSplits[i], WIN_NEXT_OUTLINES, 'vi')
|
|
for j = 1, #vNextOutlines do
|
|
local nRef = EgtGetInfo( abs( vNextOutlines[j]), WIN_REF_MUNTIN, 'i')
|
|
if nRef then
|
|
vNextOutlines[j] = EgtIf( vNextOutlines[j] > 0, nRef, - nRef)
|
|
end
|
|
end
|
|
EgtSetInfo( nOutSplit, WIN_PREV_OUTLINES, vPrevOutlines)
|
|
EgtSetInfo( nOutSplit, WIN_NEXT_OUTLINES, vNextOutlines)
|
|
CopyInfo( nOutSplit, vSplits[i], WIN_STARTJOINT)
|
|
CopyInfo( nOutSplit, vSplits[i], WIN_ENDJOINT)
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
-- SASH
|
|
elseif nAreaType == WIN_AREATYPES.SASH then
|
|
GetSashPrevNextOutlines( nAreaId)
|
|
end
|
|
|
|
-- analizzo le sottaree
|
|
local vAreas = EgtGetNameInGroup( nAreaId, WIN_AREA .. '*')
|
|
for i = 1, #vAreas do
|
|
GetAreaPrevNextOutlines( vAreas[i])
|
|
end
|
|
end
|
|
|
|
|
|
|
|
----------------------------------------------------------------------------------
|
|
-------------------------------- GEO -------------------------------------------
|
|
----------------------------------------------------------------------------------
|
|
-- funzione simile a CalcIntersectionRegion ma con considerazioni speciali per le curve del geo ( e.g. gestione bisettori, curve doppie)
|
|
local function CalcGeoRegion( vCrvs, nGrp)
|
|
|
|
local nSurfId
|
|
local dExtraLen = 10000
|
|
|
|
-- gruppo temporaneo per i conti
|
|
local nGrpTmp = EgtGroup( nGrp)
|
|
EgtSetStatus( nGrpTmp, GDB_ST.OFF)
|
|
|
|
-- a) costruisco i semipiani e identifico le curve con gestione speciale
|
|
local vSemiPlanes = {}
|
|
local tArcs = {}
|
|
local vBisectors = {}
|
|
for i = 1, #vCrvs do
|
|
|
|
-- se linea costruisco il semipiano corrispondente
|
|
if EgtGetType( vCrvs[i]) == GDB_TY.CRV_LINE then
|
|
local vtDir = EgtSV( vCrvs[i])
|
|
local vtOrtho = Vector3d( vtDir)
|
|
vtOrtho:rotate( Z_AX(), 90)
|
|
local nSemiPlaneId = EgtSurfFrRectangle( nGrpTmp, ORIG(), Point3d( EgtCurveLength( vCrvs[i]) + 2 * dExtraLen, dExtraLen, 0))
|
|
local frRect = Frame3d( EgtSP( vCrvs[i]) - vtDir * dExtraLen, vtDir, vtOrtho, Z_AX())
|
|
EgtTransform( nSemiPlaneId, frRect)
|
|
table.insert( vSemiPlanes, nSemiPlaneId)
|
|
|
|
-- se arco calcolo estensione verificando se la curva è doppia
|
|
elseif EgtGetType( vCrvs[i]) == GDB_TY.CRV_ARC then
|
|
local nCrvId = CreateCurveExtension( vCrvs[i], nGrpTmp)
|
|
local bFound = false
|
|
local nRefOutline = EgtGetInfo( vCrvs[i], WIN_REF_OUTLINE, 'i')
|
|
if nRefOutline then
|
|
for j = 1, #tArcs do
|
|
if tArcs[j].nRefOutline == nRefOutline then
|
|
-- taglio le due estensioni e le unisco nel loro punto centrale
|
|
local ptM = EgtMP( nRefOutline)
|
|
local _, _, dPar1 = EgtPointCurveDist( ptM, tArcs[j].nCrvId)
|
|
local _, _, dPar2 = EgtPointCurveDist( ptM, nCrvId)
|
|
EgtTrimCurveStartAtParam( nCrvId, dPar2)
|
|
EgtTrimCurveEndAtParam( tArcs[j].nCrvId, dPar1)
|
|
local nNewExt = EgtCurveCompo( nGrpTmp, nCrvId)
|
|
EgtAddCurveCompoLine( nNewExt, EgtSP( tArcs[j].nCrvId))
|
|
EgtAddCurveCompoCurve( nNewExt, tArcs[j].nCrvId)
|
|
|
|
tArcs[j].nCrvId = nNewExt
|
|
table.insert( tArcs[j].vOrigId, vCrvs[i])
|
|
bFound = true
|
|
break
|
|
end
|
|
end
|
|
end
|
|
if not bFound then
|
|
table.insert( tArcs, { nCrvId = nCrvId, vOrigId = { vCrvs[i]}, nRefOutline = nRefOutline, dRad = EgtArcRadius( vCrvs[i])})
|
|
end
|
|
|
|
-- se composita è bisettore con gestione speciale
|
|
else
|
|
local nCrvId = EgtCopyGlob( vCrvs[i], nGrpTmp)
|
|
table.insert( vBisectors, nCrvId)
|
|
end
|
|
end
|
|
|
|
-- b) calcolo la regione definita dai semipiani
|
|
for i = 2, #vSemiPlanes do
|
|
EgtSurfFrIntersect( vSemiPlanes[1], vSemiPlanes[i])
|
|
EgtErase( vSemiPlanes[i])
|
|
end
|
|
if EgtSurfFrChunkCount( vSemiPlanes[1]) == 0 then
|
|
return
|
|
end
|
|
nSurfId = vSemiPlanes[1]
|
|
|
|
-- c) se presenti archi, calcolo il loro contributo alla regione
|
|
if #tArcs > 0 then
|
|
|
|
local nCrvBorder = EgtExtractSurfFrChunkLoops( nSurfId, 0, nGrpTmp)
|
|
|
|
-- riordino per raggio decrescente ( per gestire prima quelle più grandi che potrebbero contenere le altre)
|
|
table.sort( tArcs, function ( a, b) return a.dRad > b.dRad end)
|
|
|
|
for i = 1, #tArcs do
|
|
-- limito la curva estesa alla regione
|
|
local nSurfTrim = EgtSurfFlatRegion( nGrpTmp, nCrvBorder)
|
|
local nCrv, nCnt = EgtTrimCurveWithRegion( tArcs[i].nCrvId, nSurfTrim, true, false)
|
|
|
|
-- se errore lo ignoro
|
|
if not nCrv then
|
|
nCnt = 0
|
|
end
|
|
|
|
if nCnt > 0 then
|
|
-- unisco tratto iniziale e finale se consecutivi
|
|
if nCnt > 1 and AreSamePointApprox( EgtSP( nCrv), EgtEP( nCrv + nCnt - 1)) then
|
|
if EgtGetType( nCrv) == GDB_TY.CRV_ARC then
|
|
EgtModifyCurveStartPoint( nCrv, EgtSP( nCrv + nCnt - 1))
|
|
EgtErase( nCrv + nCnt - 1)
|
|
else
|
|
EgtAddCurveCompoCurve( nCrv, nCrv + nCnt - 1, true, false)
|
|
end
|
|
nCnt = nCnt - 1
|
|
end
|
|
|
|
-- spezzo in corrispondenza di eventuali punti tangenti alla regione
|
|
local vArcs = EgtTableFill( nCrv, nCnt)
|
|
for j = nCrv, nCrv + nCnt - 1 do
|
|
local nInters, nPntCnt, nCrvCnt = EgtCurveCurveInters( j, nCrvBorder, nGrpTmp)
|
|
if nInters then
|
|
if nCnt == 1 then
|
|
EgtChangeClosedCurveStartPoint( j, EgtSP( nInters))
|
|
end
|
|
local nCurrCrv = j
|
|
for nPntId = nInters, nInters + nPntCnt - 1 do
|
|
local dPar = EgtCurveParamAtPoint( nCurrCrv, EgtSP( nPntId))
|
|
local nNewCrv = EgtSplitCurveAtParam( nCurrCrv, dPar)
|
|
if nNewCrv then
|
|
table.insert( vArcs, nNewCrv)
|
|
nCurrCrv = nNewCrv
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- modifico il bordo corrente considerando solo i tratti che poggiano sulle curve orginali
|
|
for j = 1, #vArcs do
|
|
for k = 1, #tArcs[i].vOrigId do
|
|
if CheckExtensionOverlap( vArcs[j], tArcs[i].vOrigId[k]) then
|
|
local dParS = EgtCurveParamAtPoint( nCrvBorder, EgtSP( vArcs[j]), 100 * GEO.EPS_SMALL)
|
|
local dParE = EgtCurveParamAtPoint( nCrvBorder, EgtEP( vArcs[j]), 100 * GEO.EPS_SMALL)
|
|
EgtTrimCurveStartEndAtParam( nCrvBorder, dParE, dParS)
|
|
EgtAddCurveCompoCurve( nCrvBorder, vArcs[j])
|
|
break
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- ricostruisco la superficie
|
|
nSurfId = EgtSurfFlatRegion( nGrpTmp, nCrvBorder)
|
|
end
|
|
|
|
-- d) gestione di eventuali bisettori
|
|
if #vBisectors > 0 then
|
|
local nCrvBorder = EgtExtractSurfFrChunkLoops( nSurfId, 0, nGrpTmp)
|
|
for i = 1, #vBisectors do
|
|
local nCrv, nCnt = EgtTrimCurveWithRegion( vBisectors[i], nSurfId, true, false)
|
|
if nCrv and nCnt == 1 then
|
|
local dParS = EgtCurveParamAtPoint( nCrvBorder, EgtSP( nCrv), 100 * GEO.EPS_SMALL)
|
|
local dParE = EgtCurveParamAtPoint( nCrvBorder, EgtEP( nCrv), 100 * GEO.EPS_SMALL)
|
|
EgtTrimCurveStartEndAtParam( nCrvBorder, dParE, dParS)
|
|
EgtAddCurveCompoCurve( nCrvBorder, nCrv)
|
|
end
|
|
|
|
end
|
|
nSurfId = EgtSurfFlatRegion( nGrpTmp, nCrvBorder)
|
|
end
|
|
|
|
EgtRelocateGlob( nSurfId, nGrp)
|
|
EgtErase( nGrpTmp)
|
|
return nSurfId
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function GetDeltaProfile( nProfileId, sCtrIn, nOutlineId)
|
|
|
|
local dCPDelta = 0
|
|
local nSectionFrId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME)
|
|
local frSectionFrame = EgtFR( nSectionFrId, GDB_ID.ROOT)
|
|
local nCPId = EgtGetFirstNameInGroup( nProfileId, sCtrIn)
|
|
local b3CP = EgtGetBBoxRef( nCPId, GDB_BB.STANDARD, frSectionFrame)
|
|
if nOutlineId < 0 then
|
|
-- se a destra della curva sto considerando i semiprofili 1
|
|
dCPDelta = abs( b3CP:getMin():getX())
|
|
else
|
|
dCPDelta = abs( b3CP:getMax():getX())
|
|
end
|
|
-- se bottomrail considero anche scostamento dall'outline
|
|
local sProfileType = EgtGetInfo( nProfileId, WIN_PROFILETYPE)
|
|
if sProfileType == WIN_FILL_RAIL then
|
|
local dDelta = EgtGetInfo( nProfileId, WIN_RAILOFFS, 'd')
|
|
dCPDelta = dCPDelta + dDelta
|
|
end
|
|
return dCPDelta
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function CheckSemiprofileIntersection( nGeoId, nPrevGeoId, nNextGeoId)
|
|
|
|
local nOutlineId = EgtGetInfo( nGeoId, WIN_REF_OUTLINE, 'i')
|
|
|
|
-- recupero la curva più interna del semiprofilo
|
|
local nSemiProfileId = EgtGetInfo( nGeoId, WIN_SEMI_PROFILE, 'i')
|
|
local nProfileId = EgtGetParent( nSemiProfileId)
|
|
local nFrameId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME)
|
|
local frFrame = EgtFR( nFrameId, GDB_ID.ROOT)
|
|
local b3Box = EgtGetBBoxRef( nSemiProfileId, GDB_BB.STANDARD, frFrame)
|
|
local nInnerCrv = EgtCopyGlob( nOutlineId, EgtGetParent( nGeoId))
|
|
EgtOffsetCurve( nInnerCrv, b3Box:getMin():getX())
|
|
|
|
-- verifico se con estensione standard ( ovvero seguendo la circonferenza associata) arriva alle curve vicine del geo
|
|
local ptInt1 = FindIntersectionPoint( nInnerCrv, nPrevGeoId, ORIG())
|
|
local bTangStart = ( not ptInt1)
|
|
local ptInt2 = FindIntersectionPoint( nInnerCrv, nNextGeoId, ORIG())
|
|
local bTangEnd = ( not ptInt2)
|
|
|
|
EgtErase( nInnerCrv)
|
|
return bTangStart, bTangEnd
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che stabilisce il tipo di estensione ( standard seguendo la circonferenza o lineare in tangenza) per curve del geo ad arco in base a condizioni euristiche per evitare giunzioni
|
|
-- problematiche
|
|
local function ComputeArcExtensions( nOutId, nInId, vLeftIds, vRightIds, vStartJoints, vEndJoints)
|
|
|
|
-- controllo euristico : verifico se la parte più interna del semiprofilo associato alla curva del geo ( ovvero considero tra i due archi che limitano il semiprofilo quello
|
|
-- con raggio minore perchè dovrebbe essere il più problematico) arriva alla curva di geo vicina con estensione standard oppure no
|
|
-- se curve in tangenza forza estensione in tangenza
|
|
|
|
-- se il pezzo corrente è arco devo verificare estensione per in e out
|
|
if EgtGetType( nOutId) == GDB_TY.CRV_ARC then
|
|
|
|
local bTangStart, bTangEnd = CheckSemiprofileIntersection( nOutId, vLeftIds[#vLeftIds], vRightIds[1])
|
|
-- verifico se necessaria estensione in tangenza per giunzione angled o per la curva in
|
|
if not bTangStart then
|
|
bTangStart = ( vStartJoints[#vStartJoints] == WIN_PART_JNT.ANGLED or not FindIntersectionPoint( nInId, vLeftIds[1], ORIG()))
|
|
end
|
|
EgtSetInfo( nOutId, WIN_TANG_START, bTangStart)
|
|
EgtSetInfo( nInId, WIN_TANG_END, bTangStart)
|
|
|
|
if not bTangEnd then
|
|
bTangEnd = ( vEndJoints[1] == WIN_PART_JNT.ANGLED or not FindIntersectionPoint( nInId, vRightIds[#vRightIds], ORIG()))
|
|
end
|
|
EgtSetInfo( nOutId, WIN_TANG_END, bTangEnd)
|
|
EgtSetInfo( nInId, WIN_TANG_START, bTangEnd)
|
|
end
|
|
|
|
-- verifico estensione left
|
|
for i = 1, #vLeftIds do
|
|
if EgtGetType( vLeftIds[i]) == GDB_TY.CRV_ARC then
|
|
local bTangS, bTangE = CheckSemiprofileIntersection( vLeftIds[i], nInId, nOutId)
|
|
|
|
-- se outline in tangenza con i vicini forzo estensione in tangenza
|
|
if not bTangS then
|
|
local nOutlineId = EgtGetInfo( vLeftIds[i], WIN_REF_OUTLINE, 'i')
|
|
local nPrevOutlineId = EgtGetPrev( nOutlineId) or EgtGetLastInGroup( EgtGetParent( nOutlineId))
|
|
if AreSameVectorApprox( EgtEV( nPrevOutlineId), EgtSV( nOutlineId)) then
|
|
bTangS = true
|
|
end
|
|
end
|
|
if not bTangE then
|
|
local nOutlineId = EgtGetInfo( vLeftIds[i], WIN_REF_OUTLINE, 'i')
|
|
local nNextOutlineId = EgtGetNext( nOutlineId) or EgtGetFirstInGroup( EgtGetParent( nOutlineId))
|
|
if AreSameVectorApprox( EgtEV( nOutlineId), EgtSV( nNextOutlineId)) then
|
|
bTangE = true
|
|
end
|
|
end
|
|
|
|
EgtSetInfo( vLeftIds[i], WIN_TANG_START, bTangS)
|
|
EgtSetInfo( vLeftIds[i], WIN_TANG_END, bTangE)
|
|
end
|
|
end
|
|
|
|
-- verifico estensione right
|
|
for i = 1, #vRightIds do
|
|
if EgtGetType( vRightIds[i]) == GDB_TY.CRV_ARC then
|
|
local bTangS, bTangE = CheckSemiprofileIntersection( vRightIds[i], nOutId, nInId)
|
|
|
|
if not bTangS then
|
|
local nOutlineId = EgtGetInfo( vRightIds[i], WIN_REF_OUTLINE, 'i')
|
|
local nPrevOutlineId = EgtGetPrev( nOutlineId) or EgtGetLastInGroup( EgtGetParent( nOutlineId))
|
|
if AreSameVectorApprox( EgtEV( nPrevOutlineId), EgtSV( nOutlineId)) then
|
|
bTangS = true
|
|
end
|
|
end
|
|
if not bTangE then
|
|
local nOutlineId = EgtGetInfo( vRightIds[i], WIN_REF_OUTLINE, 'i')
|
|
local nNextOutlineId = EgtGetNext( nOutlineId) or EgtGetFirstInGroup( EgtGetParent( nOutlineId))
|
|
if AreSameVectorApprox( EgtEV( nOutlineId), EgtSV( nNextOutlineId)) then
|
|
bTangE = true
|
|
end
|
|
end
|
|
|
|
EgtSetInfo( vRightIds[i], WIN_TANG_START, bTangS)
|
|
EgtSetInfo( vRightIds[i], WIN_TANG_END, bTangE)
|
|
end
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che crea le curve del geo
|
|
local function CreateGeoCurves( nOutlineId, vPrevOutlineId, vNextOutlineId, vStartJoints, vEndJoints, nGeoLayerId, nProfileLayerId)
|
|
|
|
local nCurrProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN)
|
|
-- calcolo spostamento della curva iniziale dovuto a posizione riferimento
|
|
local b3CurrProfileFrame = GetProfileLocalBox( nCurrProfileId)
|
|
local dCurrOffset = b3CurrProfileFrame:getMax():getX()
|
|
local sProfileType = EgtGetInfo( nCurrProfileId, WIN_PROFILETYPE)
|
|
if sProfileType == WIN_FILL_RAIL or sProfileType == WIN_RAIL then
|
|
-- scostamento extra legato al bottomrail
|
|
local dDelta = EgtGetInfo( nCurrProfileId, WIN_RAILOFFS, 'd')
|
|
dCurrOffset = dCurrOffset - dDelta
|
|
end
|
|
|
|
-- creo copie degli outline e le offsetto opportunamente
|
|
-- curva out
|
|
local nOutId = EgtCopy( nOutlineId, nGeoLayerId)
|
|
EgtOffsetCurve( nOutId, dCurrOffset)
|
|
EgtSetName( nOutId, WIN_GEO_OUT)
|
|
local nSemiProfileOut = EgtGetFirstNameInGroup( nCurrProfileId, WIN_OUT)
|
|
if not nSemiProfileOut then
|
|
nSemiProfileOut = EgtGetFirstNameInGroup( nCurrProfileId, WIN_IN .. '1') or EgtGetFirstNameInGroup( nCurrProfileId, WIN_MIXED_COMMON .. WIN_IN .. '1')
|
|
end
|
|
EgtSetInfo( nOutId, WIN_SEMI_PROFILE, nSemiProfileOut)
|
|
EgtSetInfo( nOutId, WIN_REF_OUTLINE, nOutlineId)
|
|
EgtSetInfo( nOutId, WIN_GEO_OFFS, dCurrOffset)
|
|
|
|
-- curva in
|
|
local nInId = EgtCopy( nOutlineId, nGeoLayerId)
|
|
EgtOffsetCurve( nInId, dCurrOffset - b3CurrProfileFrame:getDimX())
|
|
EgtInvertCurve( nInId)
|
|
EgtSetName( nInId, WIN_GEO_IN)
|
|
local nSemiProfileIn = EgtGetFirstNameInGroup( nCurrProfileId, WIN_IN)
|
|
if not nSemiProfileIn then
|
|
nSemiProfileIn = EgtGetFirstNameInGroup( nCurrProfileId, WIN_IN .. '2') or EgtGetFirstNameInGroup( nCurrProfileId, WIN_MIXED_COMMON .. WIN_IN .. '2') or
|
|
EgtGetFirstNameInGroup( nCurrProfileId, WIN_MIXED_COMMON .. WIN_IN)
|
|
end
|
|
EgtSetInfo( nInId, WIN_SEMI_PROFILE, nSemiProfileIn)
|
|
EgtSetInfo( nInId, WIN_REF_OUTLINE, - nOutlineId)
|
|
EgtSetInfo( nInId, WIN_GEO_OFFS, - dCurrOffset + b3CurrProfileFrame:getDimX())
|
|
|
|
-- curve left
|
|
local vPrevProfileId = EgtGetNameInGroup( nProfileLayerId, WIN_PRF_START)
|
|
for i = 1, #vPrevOutlineId do
|
|
|
|
if vStartJoints[i] == WIN_PART_JNT.ANGLED then
|
|
|
|
-- recupero bordo out dell'altro pezzo ( non è detto coincida con l'outline)
|
|
local b3Profile = GetProfileLocalBox( vPrevProfileId[i])
|
|
local nOtherOut = EgtCopyGlob( vPrevOutlineId[i], nGeoLayerId)
|
|
EgtOffsetCurve( nOtherOut, b3Profile:getMax():getX())
|
|
|
|
-- a) calcolo bisettore: se pezzi lineari o in tangenza è segmento, altrimenti è tratto di parabola
|
|
local nBisector
|
|
if ( EgtGetType( nOutlineId) == GDB_TY.CRV_LINE and EgtGetType( vPrevOutlineId[i]) == GDB_TY.CRV_LINE) or
|
|
EgtEV( vPrevOutlineId[i]) * EgtSV( nOutlineId) > s_dAngledCos or
|
|
EgtGetName( nOutlineId) == EgtGetName( vPrevOutlineId[i]) then
|
|
|
|
local nOtherIn = EgtCopyGlob( vPrevOutlineId[i], nGeoLayerId)
|
|
EgtOffsetCurve( nOtherIn, b3Profile:getMin():getX())
|
|
local ptInt1 = FindIntersectionPoint( nOutId, nOtherOut, EgtSP( nOutId))
|
|
local ptInt2 = FindIntersectionPoint( nInId, nOtherIn, EgtSP( nInId))
|
|
EgtErase( nOtherIn)
|
|
nBisector = EgtLine( nGeoLayerId, ptInt2, ptInt1)
|
|
else
|
|
nBisector = CalcParabolicBisector( nOtherOut, nOutId, b3Profile:getDimX(), nGeoLayerId)
|
|
EgtInvertCurve( nBisector)
|
|
end
|
|
EgtSetName( nBisector, WIN_GEO_LEFT)
|
|
EgtSetInfo( nBisector, WIN_REF_OUTLINE, vPrevOutlineId[i])
|
|
EgtRelocateGlob( nBisector, nGeoLayerId, GDB_IN.LAST_SON)
|
|
|
|
-- b) se profili diversi per taglio corretto dei profili serve considerare anche il bordo out del pezzo adiacente
|
|
local sCurrProfile = EgtGetInfo( nCurrProfileId, WIN_PROFILETYPE)
|
|
local sPrevProfile = EgtGetInfo( vPrevProfileId[i], WIN_PROFILETYPE)
|
|
if sCurrProfile ~= sPrevProfile and not AreSameVectorApprox( EgtSV( nOutlineId), EgtEV( vPrevOutlineId[i])) then
|
|
EgtSetName( nOtherOut, WIN_GEO_LEFT)
|
|
EgtRelocateGlob( nOtherOut, nGeoLayerId, GDB_IN.LAST_SON)
|
|
local nSemiProfileId = EgtGetFirstNameInGroup( vPrevProfileId[i], WIN_OUT)
|
|
EgtSetInfo( nOtherOut, WIN_SEMI_PROFILE, nSemiProfileId)
|
|
EgtSetInfo( nOtherOut, WIN_REF_OUTLINE, vPrevOutlineId[i])
|
|
EgtSetInfo( nOtherOut, WIN_GEO_OFFS, b3Profile:getMax():getX())
|
|
else
|
|
-- considero la curva out come curva ausiliaria per il calcolo del geo
|
|
EgtSetName( nOtherOut, WIN_AUX)
|
|
EgtSetInfo( nOtherOut, WIN_TANG_START, true)
|
|
EgtSetInfo( nOtherOut, WIN_TANG_END, true)
|
|
end
|
|
|
|
else
|
|
local nPrevCurveId = EgtCopy( abs( vPrevOutlineId[i]), nGeoLayerId)
|
|
if vPrevOutlineId[i] < 0 then
|
|
EgtInvertCurve( nPrevCurveId)
|
|
end
|
|
local dOffs, nPrevSemiProfile
|
|
if vStartJoints[i] == WIN_PART_JNT.SHORT then
|
|
-- la curva del geo corrisponde al bordo del controprofilo in del pezzo vicino
|
|
local sCtrIn = GetProfileCtrIn( vPrevOutlineId[i], nOutlineId, vPrevProfileId[i], true)
|
|
local dCPDelta = GetDeltaProfile( vPrevProfileId[i], sCtrIn, vPrevOutlineId[i])
|
|
dOffs = - dCPDelta
|
|
nPrevSemiProfile = EgtGetFirstNameInGroup( vPrevProfileId[i], sCtrIn)
|
|
else
|
|
-- la curva del geo corrisponde all'out del pezzo vicino
|
|
local b3Profile = GetProfileLocalBox( vPrevProfileId[i])
|
|
dOffs = b3Profile:getMax():getX()
|
|
nPrevSemiProfile = EgtGetFirstNameInGroup( vPrevProfileId[i], WIN_OUT)
|
|
end
|
|
EgtOffsetCurve( nPrevCurveId, dOffs)
|
|
EgtSetInfo( nPrevCurveId, WIN_GEO_OFFS, dOffs)
|
|
EgtSetInfo( nPrevCurveId, WIN_SEMI_PROFILE, nPrevSemiProfile)
|
|
EgtSetInfo( nPrevCurveId, WIN_REF_OUTLINE, vPrevOutlineId[i])
|
|
EgtSetName( nPrevCurveId, WIN_GEO_LEFT)
|
|
EgtRelocateGlob( nPrevCurveId, nGeoLayerId, GDB_IN.LAST_SON)
|
|
end
|
|
end
|
|
|
|
-- curve right
|
|
local vNextProfileId = EgtGetNameInGroup( nProfileLayerId, WIN_PRF_END)
|
|
for i = 1, #vNextOutlineId do
|
|
|
|
if vEndJoints[i] == WIN_PART_JNT.ANGLED then
|
|
|
|
local b3Profile = GetProfileLocalBox( vNextProfileId[i])
|
|
local nOtherOut = EgtCopyGlob( vNextOutlineId[i], nGeoLayerId)
|
|
EgtOffsetCurve( nOtherOut, b3Profile:getMax():getX())
|
|
|
|
-- calcolo bisettore
|
|
local nBisector
|
|
if ( EgtGetType( nOutlineId) == GDB_TY.CRV_LINE and EgtGetType( vNextOutlineId[i]) == GDB_TY.CRV_LINE) or
|
|
EgtEV( nOutlineId) * EgtSV( vNextOutlineId[i]) > s_dAngledCos or
|
|
EgtGetName( nOutlineId) == EgtGetName( vNextOutlineId[i]) then
|
|
|
|
local nOtherIn = EgtCopyGlob( vNextOutlineId[i], nGeoLayerId)
|
|
EgtOffsetCurve( nOtherIn, b3Profile:getMin():getX())
|
|
local ptInt1 = FindIntersectionPoint( nOutId, nOtherOut, EgtEP( nOutId))
|
|
local ptInt2 = FindIntersectionPoint( nInId, nOtherIn, EgtEP( nInId))
|
|
EgtErase( nOtherIn)
|
|
nBisector = EgtLine( nGeoLayerId, ptInt1, ptInt2)
|
|
else
|
|
nBisector = CalcParabolicBisector( nOutId, nOtherOut, b3Profile:getDimX(), nGeoLayerId)
|
|
end
|
|
EgtSetName( nBisector, WIN_GEO_RIGHT)
|
|
EgtSetInfo( nBisector, WIN_REF_OUTLINE, vNextOutlineId[i])
|
|
EgtRelocateGlob( nBisector, nInId, GDB_IN.BEFORE)
|
|
|
|
-- gestione per profili diversi
|
|
local sCurrProfile = EgtGetInfo( nCurrProfileId, WIN_PROFILETYPE)
|
|
local sNextProfile = EgtGetInfo( vNextProfileId[i], WIN_PROFILETYPE)
|
|
if sCurrProfile ~= sNextProfile and not AreSameVectorApprox( EgtEV( nOutlineId), EgtSV( vNextOutlineId[i])) then
|
|
EgtSetName( nOtherOut, WIN_GEO_RIGHT)
|
|
local nSemiProfileId = EgtGetFirstNameInGroup( vNextProfileId[i], WIN_OUT)
|
|
EgtSetInfo( nOtherOut, WIN_SEMI_PROFILE, nSemiProfileId)
|
|
EgtSetInfo( nOtherOut, WIN_REF_OUTLINE, vNextOutlineId[i])
|
|
EgtSetInfo( nOtherOut, WIN_GEO_OFFS, b3Profile:getMax():getX())
|
|
EgtRelocateGlob( nOtherOut, nInId, GDB_IN.BEFORE)
|
|
else
|
|
EgtSetName( nOtherOut, WIN_AUX)
|
|
EgtSetInfo( nOtherOut, WIN_TANG_START, true)
|
|
EgtSetInfo( nOtherOut, WIN_TANG_END, true)
|
|
end
|
|
|
|
else
|
|
local nNextCurveId = EgtCopy( abs( vNextOutlineId[i]), nGeoLayerId)
|
|
if vNextOutlineId[i] < 0 then
|
|
EgtInvertCurve( nNextCurveId)
|
|
end
|
|
local dOffs, nNextSemiProfile
|
|
if vEndJoints[i] == WIN_PART_JNT.SHORT then
|
|
local sCtrIn = GetProfileCtrIn( vNextOutlineId[i], nOutlineId, vNextProfileId[i], false)
|
|
local dCPDelta = GetDeltaProfile( vNextProfileId[i], sCtrIn, vNextOutlineId[i])
|
|
dOffs = - dCPDelta
|
|
nNextSemiProfile = EgtGetFirstNameInGroup( vNextProfileId[i], sCtrIn)
|
|
else
|
|
local b3Profile = GetProfileLocalBox( vNextProfileId[i])
|
|
dOffs = b3Profile:getMax():getX()
|
|
nNextSemiProfile = EgtGetFirstNameInGroup( vNextProfileId[i], WIN_OUT)
|
|
end
|
|
EgtOffsetCurve( nNextCurveId, dOffs)
|
|
EgtSetInfo( nNextCurveId, WIN_GEO_OFFS, dOffs)
|
|
EgtSetInfo( nNextCurveId, WIN_SEMI_PROFILE, nNextSemiProfile)
|
|
EgtSetInfo( nNextCurveId, WIN_REF_OUTLINE, vNextOutlineId[i])
|
|
EgtSetName( nNextCurveId, WIN_GEO_RIGHT)
|
|
EgtRelocateGlob( nNextCurveId, nInId, GDB_IN.BEFORE)
|
|
end
|
|
end
|
|
|
|
-- verifico se necessaria estensione in tangenza per pezzi ad arco
|
|
local vLeftIds = EgtGetNameInGroup( nGeoLayerId, WIN_LEFT)
|
|
local vRightIds = EgtGetNameInGroup( nGeoLayerId, WIN_RIGHT)
|
|
ComputeArcExtensions( nOutId, nInId, vLeftIds, vRightIds, vStartJoints, vEndJoints)
|
|
|
|
-- costruisco la superficie
|
|
local vIds = EgtGetAllInGroup( nGeoLayerId)
|
|
local nAreaId = CalcGeoRegion( vIds, nGeoLayerId)
|
|
if not nAreaId then
|
|
return false
|
|
end
|
|
EgtSetName( nAreaId, WIN_GEO_SURF)
|
|
EgtSetStatus( nAreaId, GDB_ST.OFF)
|
|
|
|
-- elimino curve aux
|
|
local vCrvs = {}
|
|
for i = 1, #vIds do
|
|
if EgtGetName( vIds[i]) == WIN_AUX then
|
|
EgtErase( vIds[i])
|
|
else
|
|
table.insert( vCrvs, vIds[i])
|
|
end
|
|
end
|
|
local _, vExtraCrvs = TrimOrderedCurves( vCrvs, false, nAreaId)
|
|
for i = 1, #vExtraCrvs do
|
|
EgtSetInfo( vExtraCrvs[i], WIN_GEO_EXTRA, true)
|
|
end
|
|
|
|
-- assegno spessore
|
|
local dGeoH = b3CurrProfileFrame:getDimY()
|
|
EgtModifyCurveThickness( vIds, - dGeoH)
|
|
|
|
-- salvo spessore serramento nel gruppo
|
|
local dGeoWidth = b3CurrProfileFrame:getDimX()
|
|
EgtSetInfo( nGeoLayerId, WIN_GEOWIDTH, dGeoWidth)
|
|
EgtSetInfo( nGeoLayerId, WIN_GEOHEIGHT, dGeoH)
|
|
|
|
-- calcolo lunghezza se pezzo lineare ( se arco verrà gestito nel calcolo dei tronchetti)
|
|
if EgtGetType( nOutlineId) == GDB_TY.CRV_LINE then
|
|
local vtS = EgtSV( nOutlineId)
|
|
local frRef = Frame3d( ORIG(), vtS, Z_AX() ^ vtS, Z_AX())
|
|
local b3Ref = EgtGetBBoxRef( nAreaId, GDB_BB.STANDARD, frRef)
|
|
EgtSetInfo( nGeoLayerId, WIN_GEOLEN, b3Ref:getDimX())
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che calcola l'ingombro dei pezzi del telaio
|
|
local function CalcGeo( nPartId, nOutlineId)
|
|
|
|
-- creo layer per ingombro
|
|
local nGeoLayerId = EgtGroup( nPartId)
|
|
EgtSetName( nGeoLayerId, WIN_GEO)
|
|
|
|
-- recupero il tipo di giunzioni
|
|
local vStartJoints
|
|
local vEndJoints
|
|
local nBottomRail = EgtGetInfo( nPartId, WIN_BOTTOMRAIL, 'i')
|
|
if nBottomRail then
|
|
-- se bottomrail deve essere short ( l'info sulla curva di riferisce al pezzo bottom)
|
|
vStartJoints = { WIN_PART_JNT.SHORT}
|
|
vEndJoints = { WIN_PART_JNT.SHORT}
|
|
else
|
|
vStartJoints = EgtGetInfo( nOutlineId, WIN_STARTJOINT, 'vi')
|
|
vEndJoints = EgtGetInfo( nOutlineId, WIN_ENDJOINT, 'vi')
|
|
end
|
|
|
|
-- aggiungo al gruppo profili quelli di trim
|
|
local vPrevOutlineId = EgtGetInfo( nOutlineId, WIN_PREV_OUTLINES, 'vi')
|
|
local vNextOutlineId = EgtGetInfo( nOutlineId, WIN_NEXT_OUTLINES, 'vi')
|
|
local nProfileLayerId = CalcStartEndProfiles( nPartId, nOutlineId, vPrevOutlineId, vNextOutlineId)
|
|
|
|
-- creo lati dell'outline
|
|
local bOk = CreateGeoCurves( nOutlineId, vPrevOutlineId, vNextOutlineId, vStartJoints, vEndJoints, nGeoLayerId, nProfileLayerId)
|
|
|
|
-- TODO verificare la validità del pezzo ( si è creata geo region, la curva out non è extra, ...)
|
|
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che calcola l'ingombro del fill
|
|
local function CalcFillGeo( nPartId, nOutlineLayerId)
|
|
|
|
-- creo layer per ingombro
|
|
local nGeoLayerId = EgtGroup( nPartId)
|
|
EgtSetName( nGeoLayerId, WIN_GEO)
|
|
-- copio lati da Outline
|
|
local vOutlineIds = EgtGetAllInGroup( nOutlineLayerId)
|
|
for i = 1, #vOutlineIds do
|
|
local nCrv = EgtCopy( vOutlineIds[i], nGeoLayerId)
|
|
EgtSetInfo( nCrv, WIN_REF_OUTLINE, vOutlineIds[i])
|
|
end
|
|
|
|
-- recupero e salvo spessore vetro
|
|
local nProfileLayerId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_PROFILE)
|
|
local nSashProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_SASH)
|
|
local dGlassThickness = EgtGetInfo( nSashProfileId, WIN_GLASSTHICKNESS, 'd')
|
|
EgtSetInfo( nGeoLayerId, WIN_GLASSTHICKNESS, dGlassThickness)
|
|
|
|
-- verifico forma e salvataggio info associate
|
|
local nCompo = EgtCurveCompo( nGeoLayerId, EgtGetAllInGroup( nGeoLayerId), false)
|
|
local bRect, ptTest, vtEdge1, vtEdge2 = EgtCurveIsARectangle( nCompo)
|
|
EgtSetInfo( nGeoLayerId, WIN_GLASS_RECT, bRect)
|
|
if bRect then
|
|
EgtSetInfo( nGeoLayerId, WIN_GEOWIDTH, vtEdge1:len())
|
|
EgtSetInfo( nGeoLayerId, WIN_GEOHEIGHT, vtEdge2:len())
|
|
else
|
|
-- se non è rettangolare salvo le dimensioni del suo box orientato in modo ottimale
|
|
local _, dDim1, dDim2 = EgtCurveMinAreaRectangleXY( nCompo)
|
|
EgtSetInfo( nGeoLayerId, WIN_GEOWIDTH, dDim1)
|
|
EgtSetInfo( nGeoLayerId, WIN_GEOHEIGHT, dDim2)
|
|
end
|
|
EgtErase( nCompo)
|
|
|
|
return nGeoLayerId
|
|
end
|
|
|
|
|
|
|
|
----------------------------------------------------------------------------------
|
|
----------------------- CURVE AUX PER CAMBIO PROFILO -----------------------------
|
|
----------------------------------------------------------------------------------
|
|
local function CalcMixedMillings( vOutlines, nOutlineProfileId, nSplitId, nSplitProfileId, bStart, bSashFill, bFillOnRight, nGrp)
|
|
|
|
-- TO DO : da capire bene come gestire il caso di cambio profilo che coinvolge più pezzi
|
|
-- TO DO : da capire quali info serve riportare nel profilo
|
|
|
|
local nGrpTmp = EgtGroup( nGrp)
|
|
|
|
local dDim1 = 61
|
|
local dDim2 = 45
|
|
local dRad = EgtGetInfo( nSplitProfileId, WIN_RAD_REF .. '1', 'd')
|
|
local ptRef = EgtIf( bStart, EgtSP( nSplitId), EgtEP( nSplitId))
|
|
|
|
-- calcolo le curve di riferimento per lo split
|
|
local b3SplitProfile = GetProfileLocalBox( nSplitProfileId)
|
|
local dSplitFixedOverl = EgtGetInfo( nSplitProfileId, WIN_FIXED_REF, 'd')
|
|
local dSplitSashOverl1 = EgtGetInfo( nSplitProfileId, WIN_SASH_REF .. '1', 'd')
|
|
local dSplitSashOverl2 = EgtGetInfo( nSplitProfileId, WIN_SASH_REF .. '2', 'd')
|
|
local nCrvSF, nCrvSS1, nCrvSS2
|
|
if bFillOnRight then
|
|
nCrvSF = EgtOffsetCurveAdv( nSplitId, b3SplitProfile:getMax():getX() - dSplitFixedOverl)
|
|
nCrvSS1 = EgtOffsetCurveAdv( nSplitId, b3SplitProfile:getMin():getX() + dSplitSashOverl1)
|
|
nCrvSS2 = EgtOffsetCurveAdv( nSplitId, b3SplitProfile:getMin():getX() + dSplitSashOverl2)
|
|
else
|
|
nCrvSF = EgtOffsetCurveAdv( nSplitId, b3SplitProfile:getMin():getX() + dSplitFixedOverl)
|
|
nCrvSS1 = EgtOffsetCurveAdv( nSplitId, b3SplitProfile:getMax():getX() - dSplitSashOverl1)
|
|
nCrvSS2 = EgtOffsetCurveAdv( nSplitId, b3SplitProfile:getMax():getX() - dSplitSashOverl2)
|
|
end
|
|
EgtRelocateGlob( nCrvSF, nGrpTmp)
|
|
EgtRelocateGlob( nCrvSS1, nGrpTmp)
|
|
EgtRelocateGlob( nCrvSS2, nGrpTmp)
|
|
|
|
-- calcolo le curve di riferimento prev
|
|
local vCompoOutlines = {}
|
|
for i = 1, #vOutlines do
|
|
vCompoOutlines[i] = EgtCopyGlob( abs( vOutlines[i]), nGrpTmp)
|
|
if vOutlines[i] < 0 then
|
|
EgtInvertCurve( vCompoOutlines[i])
|
|
end
|
|
end
|
|
local nOutlineCompo = EgtCurveCompo( nGrpTmp, vCompoOutlines)
|
|
|
|
local b3FrameProfile = GetProfileLocalBox( nOutlineProfileId)
|
|
local dFrameFixedOverl = EgtGetInfo( nOutlineProfileId, WIN_FIXED_REF, 'd')
|
|
local nCrvFF = EgtOffsetCurveAdv( nOutlineCompo, b3FrameProfile:getMin():getX() + dFrameFixedOverl)
|
|
local dFrameSashOverl1 = EgtGetInfo( nOutlineProfileId, WIN_SASH_REF .. '1', 'd')
|
|
local nCrvFS1 = EgtOffsetCurveAdv( nOutlineCompo, b3FrameProfile:getMin():getX() + dFrameSashOverl1)
|
|
local dFrameSashOverl2 = EgtGetInfo( nOutlineProfileId, WIN_SASH_REF .. '2', 'd')
|
|
local nCrvFS2 = EgtOffsetCurveAdv( nOutlineCompo, b3FrameProfile:getMin():getX() + dFrameSashOverl2)
|
|
local dFrameExtra = EgtGetInfo( nOutlineProfileId, WIN_EXTRA_DIST, 'd')
|
|
local nCrvFIn = EgtOffsetCurveAdv( nOutlineCompo, b3FrameProfile:getMin():getX() + dFrameSashOverl2 + dFrameExtra)
|
|
|
|
local dDepth = EgtGetInfo( nOutlineProfileId, WIN_SASH_DEPTH .. '2', 'd')
|
|
|
|
-- calcolo il bisettore a partire dall'incontro delle parti fixed del telaio e dello split
|
|
local nBisector
|
|
local pt1 = EgtIP( nCrvSF, nCrvFF, ptRef)
|
|
local dParRef = EgtCurveParamAtPoint( nCrvFF, pt1)
|
|
local nCrvRef = floor( dParRef)
|
|
|
|
if EgtCurveCompoRadius( nCrvFF, nCrvRef) == -1 then
|
|
-- se l'incontro tra la parte fixed del telaio e dello split avviene su un tratto lineare il bisettore è linea
|
|
local vtDir = ( EgtUV( nCrvFF, dParRef, -1) + EgtSV( nSplitId))
|
|
if not bFillOnRight then
|
|
vtDir = ( EgtUV( nCrvFF, dParRef, -1) - EgtSV( nSplitId))
|
|
end
|
|
nBisector = EgtLinePVL( nGrpTmp, pt1, vtDir, 1000)
|
|
EgtExtendCurveStartByLen( nBisector, 1000)
|
|
|
|
else
|
|
-- se l'incontro tra la parte fixed del telaio e dello split avviene su un tratto ad arco il bisettore è porzione di parabola
|
|
local nArc = EgtCopyCompoSubCurve( nCrvFF, nCrvRef, nGrpTmp)
|
|
local b3Profile = GetProfileLocalBox( nSplitProfileId)
|
|
local dDim = b3Profile:getDimX()
|
|
|
|
if bStart and bFillOnRight then
|
|
nBisector = CalcParabolicBisector( nArc, nCrvSF, dDim, nGrpTmp, true, false)
|
|
EgtInvertCurve( nBisector)
|
|
elseif bStart and not bFillOnRight then
|
|
nBisector = CalcParabolicBisector( nArc, nCrvSF, dDim, nGrpTmp, true, true)
|
|
elseif not bStart and not bFillOnRight then
|
|
nBisector = CalcParabolicBisector( nCrvSF, nArc, dDim, nGrpTmp, true, true)
|
|
EgtInvertCurve( nBisector)
|
|
elseif not bStart and bFillOnRight then
|
|
nBisector = CalcParabolicBisector( nCrvSF, nArc, dDim, nGrpTmp, true, false)
|
|
end
|
|
|
|
EgtErase( nArc)
|
|
end
|
|
|
|
-- posizione finale del tool di profilatura che determina il limite delle fresature
|
|
local nBisectTool = EgtCopyGlob( nBisector, nGrpTmp)
|
|
EgtOffsetCurve( nBisectTool, - dDim1 * 0.5)
|
|
EgtExtendCurveStartByLen( nBisectTool, 10)
|
|
EgtExtendCurveEndByLen( nBisectTool, 10)
|
|
local nCrvSash = EgtOffsetCurveAdv( nOutlineCompo, b3FrameProfile:getMin():getX() + dFrameSashOverl1 - dDim1 * 0.5)
|
|
local ptEnd = EgtIP( nCrvSash, nBisectTool, ptRef)
|
|
local nCircle = EgtCircle( nGrpTmp, ptEnd, dDim1 * 0.5)
|
|
local nCircle2 = EgtCircle( nGrpTmp, ptEnd, dDim2 * 0.5)
|
|
|
|
|
|
-- 1) Fresatura #1
|
|
local pt2 = EgtIP( nBisector, nCrvFS1, ptRef)
|
|
local dPar1 = EgtCurveParamAtPoint( nBisector, pt1)
|
|
local dPar2 = EgtCurveParamAtPoint( nBisector, pt2)
|
|
local nMill1 = EgtCopyParamRange( nBisector, min( dPar2, dPar1), max( dPar1, dPar2), nGrpTmp)
|
|
local dPar3 = EgtCurveParamAtPoint( nCrvFS1, pt2)
|
|
local _, _, dPar4 = EgtPointCurveDist( ptEnd, nCrvFS1)
|
|
local nMill2 = EgtCopyParamRange( nCrvFS1, min( dPar4, dPar3), max( dPar3, dPar4), nGrpTmp)
|
|
|
|
local nMilling
|
|
if bSashFill then
|
|
nMilling = EgtCurveCompo( nGrpTmp, { nMill2, nMill1})
|
|
else
|
|
nMilling = EgtCurveCompo( nGrpTmp, { nMill1, nMill2})
|
|
end
|
|
-- offset e contro-offset per creare fillet
|
|
local nMillingOffs = EgtOffsetCurveAdv( nMilling, - dRad)
|
|
nMilling = EgtOffsetCurveAdv( nMillingOffs, dRad)
|
|
|
|
EgtRelocateGlob( nMilling, nGrp)
|
|
EgtSetColor( nMilling, EgtStdColor( 'BLUE'))
|
|
EgtSetName( nMilling, WIN_MIXED_MILLING .. '1')
|
|
EgtSetInfo( nMilling, WIN_MIXED_SPLIT_REF, nSplitId)
|
|
EgtModifyCurveExtrusion( nMilling, Z_AX())
|
|
EgtModifyCurveThickness( nMilling, - dDepth)
|
|
|
|
EgtSetInfo( nMilling, WIN_FILL_ON_SPLIT_RIGHT, bFillOnRight)
|
|
|
|
|
|
-- 2) Fresatura #2
|
|
-- calcolo i punti di riferimento
|
|
local pt3 = EgtIP( nBisector, nCrvFIn, ptRef)
|
|
local pt4 = EgtIP( nCrvFIn, nCrvSS1, ptRef)
|
|
local pt5 = EgtIP( nCrvSS1, nCrvFS2, ptRef)
|
|
-- calcolo le curve
|
|
local dParA = EgtCurveParamAtPoint( nBisector, EgtIf( bSashFill, EgtEP( nMilling), EgtSP( nMilling)))
|
|
local dParB = EgtCurveParamAtPoint( nBisector, pt3)
|
|
local nMill3 = EgtCopyParamRange( nBisector, min( dParA, dParB), max( dParA, dParB), nGrpTmp)
|
|
local dParC = EgtCurveParamAtPoint( nCrvFIn, pt3)
|
|
local dParD = EgtCurveParamAtPoint( nCrvFIn, pt4)
|
|
local nMill4 = EgtCopyParamRange( nCrvFIn, min( dParC, dParD), max( dParC, dParD), nGrpTmp)
|
|
local dParE = EgtCurveParamAtPoint( nCrvSS1, pt4)
|
|
local dParF = EgtCurveParamAtPoint( nCrvSS1, pt5)
|
|
local nMill5 = EgtCopyParamRange( nCrvSS1, min( dParE, dParF), max( dParE, dParF), nGrpTmp)
|
|
if bFillOnRight then
|
|
EgtInvertCurve( nMill5)
|
|
end
|
|
local dParG = EgtCurveParamAtPoint( nCrvFS2, pt5)
|
|
local nMill6
|
|
if bSashFill then
|
|
nMill6 = EgtCopyParamRange( nCrvFS2, 0, dParG, nGrpTmp)
|
|
else
|
|
local _, dE = EgtCurveDomain( nCrvFS2)
|
|
nMill6 = EgtCopyParamRange( nCrvFS2, dParG, dE, nGrpTmp)
|
|
end
|
|
|
|
local nMilling2
|
|
if bSashFill then
|
|
nMilling2 = EgtCurveCompo( nGrp, { nMill6, nMill5, nMill4, nMill3})
|
|
else
|
|
nMilling2 = EgtCurveCompo( nGrp, { nMill3, nMill4, nMill5, nMill6})
|
|
end
|
|
EgtSetColor( nMilling2, EgtStdColor( 'BLUE'))
|
|
EgtSetName( nMilling2, WIN_MIXED_MILLING .. '2')
|
|
EgtModifyCurveExtrusion( nMilling2, Z_AX())
|
|
EgtModifyCurveThickness( nMilling2, - dDepth)
|
|
|
|
-- taglio sul punto finale della lavorazione di profilatura
|
|
local pt6 = EgtIP( nMilling2, nCircle2, ptRef)
|
|
if not pt6 then
|
|
_, pt6 = EgtPointCurveDist( EgtIf( bSashFill, EgtSP( nMilling), EgtEP( nMilling)), nMilling2)
|
|
end
|
|
local dParH = EgtCurveParamAtPoint( nMilling2, pt6)
|
|
if bSashFill then
|
|
EgtTrimCurveStartAtParam( nMilling2, dParH)
|
|
else
|
|
EgtTrimCurveEndAtParam( nMilling2, dParH)
|
|
end
|
|
|
|
EgtErase( nGrpTmp)
|
|
return nMilling, nMilling2
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che calcola le curve legate al cambio profilo
|
|
local function CalcMixedCurves( nPartId, nSplitId)
|
|
|
|
local nGrp = EgtGroup( nPartId)
|
|
EgtSetName( nGrp, WIN_MIXED_CURVES)
|
|
EgtSetStatus( nGrp, GDB_ST.OFF)
|
|
|
|
local nProfileGrpId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE)
|
|
local nSplitProfileId = EgtGetFirstNameInGroup( nProfileGrpId, WIN_PRF_MAIN)
|
|
local nPrfChange = EgtGetInfo( nSplitId, WIN_PRF_CHANGE, 'i')
|
|
|
|
-- start
|
|
-- se cambio profilo sull'estremo start allora serve fresatura per cambio profilo
|
|
if nPrfChange & WIN_PRF_CHANGE_TYPES.START > 0 then
|
|
local vPrevOutlines = EgtGetInfo( nSplitId, WIN_PREV_OUTLINES, 'vi')
|
|
local nPrevProfileId = GetOutlineProfileId( abs( vPrevOutlines[1]))
|
|
-- verifico se lungo la direzione del prev outline l'ordine è sash/fill ( true) o fill/sash ( false)
|
|
local nStart1 = EgtGetInfo( nSplitId, WIN_MIXED_START_CHILDREN .. '1', 'i')
|
|
local bSashFill = EgtIf( nStart1 == WIN_CHILDREN_TYPES.FILL, true, false)
|
|
|
|
local nMill1, nMill2 = CalcMixedMillings( vPrevOutlines, nPrevProfileId, nSplitId, nSplitProfileId, true, bSashFill, nStart1 == WIN_CHILDREN_TYPES.FILL, nGrp)
|
|
EgtSetName( nMill1, WIN_MIXED_MILLING .. WIN_LEFT .. '1')
|
|
EgtSetName( nMill2, WIN_MIXED_MILLING .. WIN_LEFT .. '2')
|
|
|
|
-- copio le fresature sui pezzi su cui poggia
|
|
for i = 1, #vPrevOutlines do
|
|
local nPrevPartId = EgtGetInfo( abs( vPrevOutlines[i]), WIN_REF_PART, 'i')
|
|
local nMixedInters = EgtGetFirstNameInGroup( nPrevPartId, WIN_MIXED_CURVES)
|
|
if not nMixedInters then
|
|
nMixedInters = EgtGroup( nPrevPartId)
|
|
EgtSetName( nMixedInters, WIN_MIXED_CURVES)
|
|
EgtSetStatus( nMixedInters, GDB_ST.OFF)
|
|
end
|
|
local nCrv1 = EgtCopyGlob( nMill1, nMixedInters)
|
|
local nCrv2 = EgtCopyGlob( nMill2, nMixedInters)
|
|
local sSide = EgtIf( vPrevOutlines[i] > 0, WIN_IN, WIN_OUT)
|
|
EgtSetName( nCrv1, WIN_MIXED_MILLING .. sSide .. '1')
|
|
EgtSetName( nCrv2, WIN_MIXED_MILLING .. sSide .. '2')
|
|
end
|
|
end
|
|
|
|
-- end
|
|
if nPrfChange & WIN_PRF_CHANGE_TYPES.END > 0 then
|
|
local vNextOutlines = EgtGetInfo( nSplitId, WIN_NEXT_OUTLINES, 'vi')
|
|
local nNextProfileId = GetOutlineProfileId( abs( vNextOutlines[1]))
|
|
-- verifico se lungo la direzione del next outline l'ordine è sash/fill ( true) o fill/sash ( false)
|
|
local nEnd1 = EgtGetInfo( nSplitId, WIN_MIXED_END_CHILDREN .. '1', 'i')
|
|
local bSashFill = EgtIf( nEnd1 == WIN_CHILDREN_TYPES.FILL, false, true)
|
|
|
|
local nMill3, nMill4 = CalcMixedMillings( vNextOutlines, nNextProfileId, nSplitId, nSplitProfileId, false, bSashFill, nEnd1 == WIN_CHILDREN_TYPES.FILL, nGrp)
|
|
EgtSetName( nMill3, WIN_MIXED_MILLING .. WIN_RIGHT .. '1')
|
|
EgtSetName( nMill4, WIN_MIXED_MILLING .. WIN_RIGHT .. '2')
|
|
|
|
for i = 1, #vNextOutlines do
|
|
local nNextPartId = EgtGetInfo( abs( vNextOutlines[i]), WIN_REF_PART, 'i')
|
|
local nMixedInters = EgtGetFirstNameInGroup( nNextPartId, WIN_MIXED_CURVES)
|
|
if not nMixedInters then
|
|
nMixedInters = EgtGroup( nNextPartId)
|
|
EgtSetName( nMixedInters, WIN_MIXED_CURVES)
|
|
EgtSetStatus( nMixedInters, GDB_ST.OFF)
|
|
end
|
|
local nCrv1 = EgtCopyGlob( nMill3, nMixedInters)
|
|
local nCrv2 = EgtCopyGlob( nMill4, nMixedInters)
|
|
local sSide = EgtIf( vNextOutlines[i] > 0, WIN_IN, WIN_OUT)
|
|
EgtSetName( nCrv1, WIN_MIXED_MILLING .. sSide .. '1')
|
|
EgtSetName( nCrv2, WIN_MIXED_MILLING .. sSide .. '2')
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
|
|
----------------------------------------------------------------------------------
|
|
--------------------------- PROFILING PROCESSINGS --------------------------------
|
|
----------------------------------------------------------------------------------
|
|
-- funzione che copia sulla curva di lavorazione le informazioni prese dal semiprofilo corrispondente
|
|
local function GetProcessingInfoFromSemiProfile( nCrv, nSemiProfile)
|
|
|
|
if nSemiProfile then
|
|
-- setto info di lavorazione
|
|
EgtSetInfo( nCrv, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.PROFILING)
|
|
-- setto info con il tipo di profiling
|
|
local sName = EgtGetName( nCrv)
|
|
if sName == WIN_GEO_LEFT or sName == WIN_GEO_RIGHT then
|
|
EgtSetInfo( nCrv, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.HEAD)
|
|
else
|
|
EgtSetInfo( nCrv, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.LONGITUDINAL)
|
|
end
|
|
-- recupero le info di lavorazione dal semiprofilo
|
|
if sName == WIN_GEO_OUT or sName == WIN_GEO_IN then
|
|
-- recupero la fase solo se si tratta di in o out
|
|
CopyInfo( nCrv, nSemiProfile, WIN_PRC_PHASE)
|
|
end
|
|
local nTools = EgtGetInfo( nSemiProfile, WIN_PRC_NTOOLS , 'i') or 0
|
|
EgtSetInfo( nCrv, WIN_PRC_NTOOLS, nTools)
|
|
for j = 1, nTools do
|
|
CopyInfo( nCrv, nSemiProfile, WIN_PRC_TOOL_NAME .. '_' .. tostring(j))
|
|
CopyInfo( nCrv, nSemiProfile, WIN_PRC_OFFL .. '_' .. tostring(j))
|
|
CopyInfo( nCrv, nSemiProfile, WIN_PRC_OFFR .. '_' .. tostring(j))
|
|
end
|
|
CopyInfo( nCrv, nSemiProfile, WIN_PRC_ID)
|
|
else
|
|
-- se non ha semiprofilo associato è un taglio
|
|
EgtSetInfo( nCrv, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.CUT)
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che concatena, se possibile, lavorazioni con lo stesso semiprofilo
|
|
local function ChainProfilingProcessingCurves( vProcCrvsOrig, vRefCrvsOrig)
|
|
|
|
if #vProcCrvsOrig == 1 then
|
|
return vProcCrvsOrig, vRefCrvsOrig
|
|
end
|
|
|
|
local vProcCrvs = {}
|
|
local vRefCrvs = {}
|
|
|
|
local nCurrCrv = vProcCrvsOrig[1]
|
|
local vCurrRef = { vRefCrvsOrig[1]}
|
|
local sIdCurr = EgtGetInfo( vProcCrvsOrig[1], WIN_PRC_ID)
|
|
for i = 2, #vProcCrvsOrig do
|
|
local bChain = false
|
|
local sId = EgtGetInfo( vProcCrvsOrig[i] or GDB_ID.NULL, WIN_PRC_ID)
|
|
if sIdCurr == sId then
|
|
-- verifico se le curve si tagliano tra di loro
|
|
local ptInt = EgtIP( nCurrCrv, vProcCrvsOrig[i], EgtEP( nCurrCrv))
|
|
if ptInt then
|
|
bChain = true
|
|
local dPar1 = EgtCurveParamAtPoint( nCurrCrv, ptInt)
|
|
local dPar2 = EgtCurveParamAtPoint( vProcCrvsOrig[i], ptInt)
|
|
local vCompoCrvs = {}
|
|
-- se la curva non viene completamente trimmata la considero, altrimenti la cancello
|
|
if dPar1 > GEO.EPS_SMALL then
|
|
EgtTrimCurveEndAtParam( nCurrCrv, dPar1)
|
|
table.insert( vCompoCrvs, nCurrCrv)
|
|
else
|
|
EgtErase( nCurrCrv)
|
|
end
|
|
local _, dE = EgtCurveDomain( vProcCrvsOrig[i])
|
|
if abs( dPar2 - dE) > GEO.EPS_SMALL then
|
|
EgtTrimCurveStartAtParam( vProcCrvsOrig[i], dPar2)
|
|
table.insert( vCompoCrvs, vProcCrvsOrig[i])
|
|
else
|
|
EgtErase( vProcCrvsOrig[i])
|
|
end
|
|
nCurrCrv = EgtCurveCompo( EgtGetParent( vProcCrvsOrig[1]), vCompoCrvs)
|
|
table.insert( vCurrRef, vRefCrvsOrig[i])
|
|
end
|
|
end
|
|
if not bChain then
|
|
-- salvo la vecchia catena appena interrotta e inizializzo le variabili con la nuova
|
|
table.insert( vProcCrvs, nCurrCrv)
|
|
table.insert( vRefCrvs, vCurrRef)
|
|
nCurrCrv = vProcCrvsOrig[i]
|
|
vCurrRef = { vRefCrvsOrig[i]}
|
|
sIdCurr = sId
|
|
end
|
|
end
|
|
table.insert( vProcCrvs, nCurrCrv)
|
|
table.insert( vRefCrvs, vCurrRef)
|
|
|
|
-- se è stata creata una catena ( quindi una lavorazione ha più curve di riferimento associate), vanno risettate le info di lavorazione
|
|
for i = 1, #vRefCrvs do
|
|
if #vRefCrvs[i] > 1 then
|
|
EgtSetName( vProcCrvs[i], EgtGetName( vRefCrvs[i][1]))
|
|
local nSemiProfileId = EgtGetInfo( vRefCrvs[i][1], WIN_SEMI_PROFILE, 'i')
|
|
GetProcessingInfoFromSemiProfile( vProcCrvs[i], nSemiProfileId)
|
|
for j = 1, #vRefCrvs[i] do
|
|
EgtSetInfo( vRefCrvs[i][j], WIN_REF_PRC, vProcCrvs[i])
|
|
end
|
|
EgtSetInfo( vProcCrvs[i], WIN_REF_GEO, vRefCrvs[i])
|
|
end
|
|
end
|
|
|
|
return vProcCrvs, vRefCrvs
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che verifica se la lavorazione è veramente necessaria considerando le interferenze tra i profili
|
|
local function TestProcessings( vProcCrvs, vRefCrvs, nGeoOut, nGeoIn)
|
|
|
|
if #vProcCrvs == 1 then
|
|
return
|
|
end
|
|
|
|
local nGrpTmp = EgtGroup( 0)
|
|
|
|
-- creo le superifici delle lavorazioni e quelle estese da usare per i trim
|
|
local vSurfs = {}
|
|
for i = 1, #vProcCrvs do
|
|
local nSemiProfileId = EgtGetInfo( vRefCrvs[i][1], WIN_SEMI_PROFILE, 'i')
|
|
if nSemiProfileId then
|
|
local nGuideId = EgtCopyGlob( vProcCrvs[i], nGrpTmp)
|
|
local dOffs = EgtGetInfo( vRefCrvs[i][1], WIN_GEO_OFFS, 'd')
|
|
EgtOffsetCurve( nGuideId, - dOffs)
|
|
local nProfileId = EgtGetParent( nSemiProfileId)
|
|
local nSurf = CreateProfileSurfById( nGuideId, nProfileId, nSemiProfileId, 0, nGrpTmp)
|
|
local nSurfExt = CreateProfileSurf( nGuideId, nProfileId, WIN_OFST .. EgtGetName( nSemiProfileId), 1000, nGrpTmp)
|
|
vSurfs[i] = { nId = nSurf, nExtId = nSurfExt}
|
|
end
|
|
end
|
|
|
|
-- superfici che delimitano il pezzo
|
|
local nOutlineId = EgtGetInfo( nGeoOut, WIN_REF_OUTLINE, 'i')
|
|
local nSemiProfileOut = EgtGetInfo( nGeoOut, WIN_SEMI_PROFILE, 'i')
|
|
local nProfileId = EgtGetParent( nSemiProfileOut)
|
|
local nSurfOut
|
|
local sName = EgtGetName( nSemiProfileOut)
|
|
if sName == WIN_OUT then
|
|
nSurfOut = CreateProfileSurf( nOutlineId, nProfileId, WIN_OFST .. sName, 1000, nGrpTmp)
|
|
elseif sName == WIN_MIXED_COMMON .. WIN_IN .. '1' then
|
|
nSurfOut = CreateProfileSurf( nOutlineId, nProfileId, WIN_OFST .. WIN_FILL .. WIN_CTRIN .. '1', 1000, nGrpTmp)
|
|
EgtInvertSurf( nSurfOut)
|
|
else
|
|
nSurfOut = CreateProfileSurf( nOutlineId, nProfileId, WIN_OFST .. 'Ctr' .. sName, 1000, nGrpTmp)
|
|
EgtInvertSurf( nSurfOut)
|
|
end
|
|
local nSemiProfileIn = EgtGetInfo( nGeoIn, WIN_SEMI_PROFILE, 'i')
|
|
local sNameIn = EgtGetName( nSemiProfileIn)
|
|
if sNameIn == WIN_MIXED_COMMON .. WIN_IN then
|
|
sNameIn = WIN_FILL .. WIN_CTRIN
|
|
elseif sNameIn == WIN_MIXED_COMMON .. WIN_IN .. '2' then
|
|
sNameIn = WIN_FILL .. WIN_CTRIN .. '2'
|
|
else
|
|
sNameIn = 'Ctr' .. sNameIn
|
|
end
|
|
local nSurfIn = CreateProfileSurf( nOutlineId, nProfileId, WIN_OFST .. sNameIn, 1000, nGrpTmp)
|
|
EgtInvertSurf( nSurfIn)
|
|
|
|
for i = 1, #vSurfs do
|
|
-- taglio la superficie con le altre lavorazioni e con il bordo
|
|
for j = 1, #vSurfs do
|
|
if i ~= j then
|
|
EgtSurfTmCut( vSurfs[i].nId, vSurfs[j].nExtId, true, false)
|
|
end
|
|
end
|
|
EgtSurfTmCut( vSurfs[i].nId, nSurfOut, true, false)
|
|
EgtSurfTmCut( vSurfs[i].nId, nSurfIn, true, false)
|
|
-- se scompare la lavorazione non serve
|
|
if EgtSurfTmPartCount( vSurfs[i].nId) == 0 then
|
|
EgtErase( vProcCrvs[i])
|
|
for j = 1, #vRefCrvs[i] do
|
|
EgtRemoveInfo( vRefCrvs[i][j], WIN_REF_PRC)
|
|
end
|
|
end
|
|
end
|
|
|
|
EgtErase( nGrpTmp)
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function CreateProfilingProcessingCurve( nGeoCrvId, nPrevCrv, nSurfGeo, nPrcLayerId)
|
|
|
|
-- recupero il semiprofilo associato alla curva
|
|
local nSemiProfileId = EgtGetInfo( nGeoCrvId, WIN_SEMI_PROFILE, 'i')
|
|
local nPrcCrvId
|
|
|
|
-- se bisettrice
|
|
if not nSemiProfileId then
|
|
nPrcCrvId = EgtCopyGlob( nGeoCrvId, nPrcLayerId)
|
|
|
|
-- se lavorazione di controprofilo
|
|
else
|
|
local nGrpTmp = EgtGroup( nPrcLayerId)
|
|
|
|
local nProfileId = EgtGetParent( nSemiProfileId)
|
|
local nFrameId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME)
|
|
local frFrame = EgtFR( nFrameId, GDB_ID.ROOT)
|
|
local b3SemiProfile = EgtGetBBoxRef( nSemiProfileId, GDB_BB.STANDARD, frFrame)
|
|
local dOffs = b3SemiProfile:getDimX()
|
|
|
|
-- calcolo la curva di lavorazione interna ( partendo dall'outline e non dal geo per essere coerente con la info di estensione)
|
|
local nRefOutlineId = EgtGetInfo( nGeoCrvId, WIN_REF_OUTLINE, 'i')
|
|
local nOutlineId = EgtCopyGlob( abs( nRefOutlineId), nGrpTmp)
|
|
if nRefOutlineId < 0 then
|
|
EgtInvertCurve( nOutlineId)
|
|
end
|
|
local dGeoOffs = EgtGetInfo( nGeoCrvId, WIN_GEO_OFFS, 'd')
|
|
local nOrigInnerProcId = EgtOffsetCurveAdv( nOutlineId, dGeoOffs - dOffs)
|
|
|
|
-- adatto la curva di lavorazione interna al pezzo
|
|
CopyInfo( nOrigInnerProcId, nGeoCrvId, WIN_TANG_START, false)
|
|
CopyInfo( nOrigInnerProcId, nGeoCrvId, WIN_TANG_END, false)
|
|
|
|
local nInnerProcId = CreateCurveExtension( nOrigInnerProcId, nGrpTmp)
|
|
local nInId, nCnt = EgtTrimCurveWithRegion( nInnerProcId, nSurfGeo, true, false)
|
|
|
|
if not nInId then
|
|
nCnt = 0
|
|
end
|
|
if nCnt > 0 then
|
|
if nCnt > 1 and AreSamePointApprox( EgtSP( nInId), EgtEP( nInId + nCnt - 1)) then
|
|
if EgtGetType( nInId) == GDB_TY.CRV_ARC then
|
|
EgtModifyCurveStartPoint( nInId, EgtSP( nInId + nCnt - 1))
|
|
else
|
|
EgtAddCurveCompoCurve( nInId, nInId + nCnt - 1, true, false)
|
|
end
|
|
nCnt = nCnt - 1
|
|
end
|
|
-- se ottengo più tratti considero quello che ha porzione in comune con la curva originale
|
|
if nCnt > 1 then
|
|
local nTestCrv = EgtOffsetCurveAdv( nGeoCrvId, - dOffs)
|
|
EgtRelocateGlob( nTestCrv, nGrpTmp)
|
|
local vOverlapCrvs = {}
|
|
for nId = nInId, nInId + nCnt - 1 do
|
|
if CheckExtensionOverlap( nId, nTestCrv) then
|
|
table.insert( vOverlapCrvs, nId)
|
|
end
|
|
end
|
|
|
|
if #vOverlapCrvs == 1 then
|
|
nInId = vOverlapCrvs[1]
|
|
elseif #vOverlapCrvs > 0 then
|
|
-- se ottengo più tratti di overlap con il geo considero il più vicino al geo precedente
|
|
local nIdx = 1
|
|
local dMinDist = GEO.INFINITO
|
|
local ptRef = EgtEP( nPrevCrv)
|
|
for i = 1, #vOverlapCrvs do
|
|
local dDist = dist( EgtSP( vOverlapCrvs[i]), ptRef)
|
|
if dDist < dMinDist then
|
|
dMinDist = dDist
|
|
nIdx = i
|
|
end
|
|
end
|
|
nInId = vOverlapCrvs[nIdx]
|
|
end
|
|
end
|
|
|
|
-- la allineo alla curva di lavoro
|
|
EgtOffsetCurve( nInId, dOffs)
|
|
|
|
local bExtra = EgtGetInfo( nGeoCrvId, WIN_GEO_EXTRA, 'b') or false
|
|
if bExtra then
|
|
-- se la lavorazione fa overlap con la curva del geo allora considero direttamente la curva di lavorazione interna
|
|
if CheckExtensionOverlap( nInId, nGeoCrvId) then
|
|
nPrcCrvId = nInId
|
|
EgtRelocateGlob( nPrcCrvId, nPrcLayerId)
|
|
end
|
|
else
|
|
-- modifico la curva del geo in allungamento
|
|
nPrcCrvId = EgtCurveCompo( nPrcLayerId, nGeoCrvId, false)
|
|
|
|
local dParS = EgtCurveParamAtPoint( nPrcCrvId, EgtSP( nInId), 100 * GEO.EPS_SMALL)
|
|
if not dParS then
|
|
local dParTrim = EgtCurveParamAtPoint( nInId, EgtSP( nPrcCrvId), 100 * GEO.EPS_SMALL)
|
|
if dParTrim then
|
|
local nNewCrv = EgtCopyParamRange( nInId, 0, dParTrim, nGrpTmp)
|
|
EgtAddCurveCompoCurve( nPrcCrvId, nNewCrv, true, false)
|
|
end
|
|
end
|
|
|
|
local dParE = EgtCurveParamAtPoint( nPrcCrvId, EgtEP( nInId), 100 * GEO.EPS_SMALL)
|
|
if not dParE then
|
|
local dParTrim = EgtCurveParamAtPoint( nInId, EgtEP( nPrcCrvId), 100 * GEO.EPS_SMALL)
|
|
if dParTrim then
|
|
local _, dE = EgtCurveDomain( nInId)
|
|
local nNewCrv = EgtCopyParamRange( nInId, dParTrim, dE, nGrpTmp)
|
|
EgtAddCurveCompoCurve( nPrcCrvId, nNewCrv)
|
|
end
|
|
end
|
|
|
|
end
|
|
end
|
|
EgtErase( nGrpTmp)
|
|
end
|
|
|
|
-- sistemo la curva e setto le info
|
|
if nPrcCrvId then
|
|
EgtModifyCurveThickness( nPrcCrvId, 0)
|
|
EgtSetStatus( nPrcCrvId, GDB_ST.ON)
|
|
EgtSetName( nPrcCrvId, EgtGetName( nGeoCrvId))
|
|
GetProcessingInfoFromSemiProfile( nPrcCrvId, nSemiProfileId)
|
|
EgtSetInfo( nGeoCrvId, WIN_REF_PRC, nPrcCrvId)
|
|
EgtSetInfo( nPrcCrvId, WIN_REF_GEO, nGeoCrvId)
|
|
end
|
|
|
|
return nPrcCrvId
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function TrimTangentProcessings( nPrc1, nPrc2, ptRef)
|
|
-- se le due lavorazioni hanno lo stesso semiprofilo e sono in tangenza nel loro punto di intersezione, allora posso trimmarle per evitare di avere porzioni di lavorazioni superflue
|
|
local sId1 = EgtGetInfo( nPrc1, WIN_PRC_ID)
|
|
local sId2 = EgtGetInfo( nPrc2, WIN_PRC_ID)
|
|
if sId1 == sId2 then
|
|
local ptInt = EgtIP( nPrc1, nPrc2, ptRef)
|
|
if ptInt then
|
|
local dPar1 = EgtCurveParamAtPoint( nPrc1, ptInt)
|
|
local dPar2 = EgtCurveParamAtPoint( nPrc2, ptInt)
|
|
if AreSameVectorApprox( EgtUV( nPrc1, dPar1, -1), EgtUV( nPrc2, dPar2, -1)) then
|
|
EgtTrimCurveEndAtParam( nPrc1, dPar1)
|
|
EgtTrimCurveStartAtParam( nPrc2, dPar2)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che calcola le lavorazioni di profilatura a partire dalle curve del geo
|
|
local function CreateProfilingProcessingFromGeo( nGeoLayerId, nSurfGeo, nProcLayerId, nPartId)
|
|
|
|
-- a) out
|
|
local nOut = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_OUT)
|
|
local nPrcOut = CreateProfilingProcessingCurve( nOut, nil, nSurfGeo, nProcLayerId)
|
|
local sOutId = EgtGetInfo( nPrcOut, WIN_PRC_ID)
|
|
EgtSetInfo( nPartId, WIN_PRC_PROFILE_OUT, sOutId)
|
|
|
|
-- b) in
|
|
local nIn = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_IN)
|
|
local nPrcIn = CreateProfilingProcessingCurve( nIn, nil, nSurfGeo, nProcLayerId)
|
|
local sInId = EgtGetInfo( nPrcIn, WIN_PRC_ID)
|
|
EgtSetInfo( nPartId, WIN_PRC_PROFILE_IN, sInId)
|
|
|
|
-- c) right
|
|
-- costruisco le curve di lavorazione
|
|
local vRight = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_RIGHT)
|
|
local vProcRight = {}
|
|
local vRefRight = {}
|
|
for i = 1, #vRight do
|
|
local nCrvId = CreateProfilingProcessingCurve( vRight[i], nOut, nSurfGeo, nProcLayerId)
|
|
if nCrvId then
|
|
table.insert( vProcRight, nCrvId)
|
|
table.insert( vRefRight, vRight[i])
|
|
end
|
|
end
|
|
-- concateno
|
|
vProcRight, vRefRight = ChainProfilingProcessingCurves( vProcRight, vRefRight)
|
|
-- verifico se ci sono lavorazioni superflue
|
|
TestProcessings( vProcRight, vRefRight, nOut, nIn)
|
|
-- eventuale trim con out e in
|
|
local vPrcRight = EgtGetNameInGroup( nProcLayerId, WIN_RIGHT)
|
|
TrimTangentProcessings( nPrcOut, vPrcRight[1], EgtEP( nPrcOut))
|
|
TrimTangentProcessings( vPrcRight[#vPrcRight], nPrcIn, EgtSP( nPrcIn))
|
|
|
|
-- d) left
|
|
local vLeft = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_LEFT)
|
|
local vProcLeft = {}
|
|
local vRefLeft = {}
|
|
for i = 1, #vLeft do
|
|
local nCrvId = CreateProfilingProcessingCurve( vLeft[i], nIn, nSurfGeo, nProcLayerId)
|
|
if nCrvId then
|
|
table.insert( vProcLeft, nCrvId)
|
|
table.insert( vRefLeft, vLeft[i])
|
|
end
|
|
end
|
|
vProcLeft, vRefLeft = ChainProfilingProcessingCurves( vProcLeft, vRefLeft)
|
|
TestProcessings( vProcLeft, vRefLeft, nOut, nIn)
|
|
local vPrcLeft = EgtGetNameInGroup( nProcLayerId, WIN_LEFT)
|
|
TrimTangentProcessings( nPrcIn, vPrcLeft[1], EgtEP( nPrcIn))
|
|
TrimTangentProcessings( vPrcLeft[#vPrcLeft], nPrcOut, EgtSP( nPrcOut))
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che calcola le lavorazioni di profiling per un pezzo di telaio con cambio profilo
|
|
local function CalcMixedFrameProfilingProcessings( nPartId, nProcLayerId, nGeoLayerId, nMainProfileId, nSurfGeoId)
|
|
|
|
-- a) lavorazioni profili
|
|
-- per le lavorazioni dei profili out, left, right e in comune si usano le corrispondenti curve del geo
|
|
local nGeoArea = EgtGetLastInGroup( nGeoLayerId)
|
|
CreateProfilingProcessingFromGeo( nGeoLayerId, nGeoArea, nProcLayerId, nPartId)
|
|
|
|
-- b) lavorazioni per i sottotratti sash e fill
|
|
-- TO DO ( da capire bene soprattuto nei casi di cambio profilo che coinvolge pezzi distinti)
|
|
|
|
-- c) fresature
|
|
local nMixedIntersGrp = EgtGetFirstNameInGroup( nPartId, WIN_MIXED_CURVES)
|
|
local vMixedInters = EgtGetAllInGroup( nMixedIntersGrp)
|
|
local dDepth1 = EgtGetInfo( nMainProfileId, WIN_SASH_DEPTH .. '1', 'd')
|
|
for i = 1, #vMixedInters do
|
|
local nMilling = EgtCopyGlob( vMixedInters[i], nProcLayerId)
|
|
-- sistemo spessore ( solo della fresatura 1, la seconda ha già profondità corretta)
|
|
if EgtEndsWith( EgtGetName( nMilling), '1') then
|
|
EgtModifyCurveThickness( nMilling, - dDepth1)
|
|
end
|
|
EgtSetInfo( nMilling, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.PROFILING)
|
|
EgtSetInfo( nMilling, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.GENERIC)
|
|
EgtSetInfo( nMilling, WIN_PRC_SIDE, WIN_PRC_SIDETYPE.IN)
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che calcola le lavorazioni di profiling nel caso di uno split coinvolto da cambio profilo
|
|
local function CalcMixedSplitProfilingProcessings( nSplitId, nProcLayerId, nGeoLayerId, nMainProfileId)
|
|
|
|
-- a) lavorazione dei profili
|
|
local nGeoArea = EgtGetLastInGroup( nGeoLayerId)
|
|
CreateProfilingProcessingFromGeo( nGeoLayerId, nGeoArea, nProcLayerId, EgtGetParent( nProcLayerId))
|
|
|
|
-- b) fresature
|
|
local nMixedIntersGrp = EgtGetFirstNameInGroup( EgtGetParent( nProcLayerId), WIN_MIXED_CURVES)
|
|
|
|
-- estremo start ( solo se presenta cambio profilo)
|
|
local nMillingLeft = EgtGetFirstNameInGroup( nMixedIntersGrp, WIN_MIXED_MILLING .. WIN_LEFT .. '1')
|
|
if nMillingLeft then
|
|
local nPrcCrv = EgtCopyGlob( nMillingLeft, nProcLayerId)
|
|
EgtSetInfo( nPrcCrv, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.PROFILING)
|
|
EgtSetInfo( nPrcCrv, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.GENERIC)
|
|
EgtSetInfo( nPrcCrv, WIN_PRC_SIDE, WIN_PRC_SIDETYPE.LEFT)
|
|
end
|
|
|
|
-- estremo end
|
|
local nMillingRight = EgtGetFirstNameInGroup( nMixedIntersGrp, WIN_MIXED_MILLING .. WIN_RIGHT .. '1')
|
|
if nMillingRight then
|
|
local nPrcCrv = EgtCopyGlob( nMillingRight, nProcLayerId)
|
|
EgtInvertCurve( nPrcCrv)
|
|
EgtSetInfo( nPrcCrv, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.PROFILING)
|
|
EgtSetInfo( nPrcCrv, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.GENERIC)
|
|
EgtSetInfo( nPrcCrv, WIN_PRC_SIDE, WIN_PRC_SIDETYPE.RIGHT)
|
|
end
|
|
|
|
-- lavorazioni legate ad altro split con cambio profilo che si innesta sullo split corrente
|
|
local dDepth1 = EgtGetInfo( nMainProfileId, WIN_SASH_DEPTH .. '1')
|
|
local vCrvsOut = EgtGetNameInGroup( nMixedIntersGrp, WIN_MIXED_MILLING .. WIN_OUT .. '*')
|
|
for i = 1, #vCrvsOut do
|
|
local nMilling = EgtCopyGlob( vCrvsOut[i], nProcLayerId)
|
|
if EgtEndsWith( EgtGetName( nMilling), '1') then
|
|
EgtModifyCurveThickness( nMilling, - dDepth1)
|
|
end
|
|
EgtSetInfo( nMilling, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.PROFILING)
|
|
EgtSetInfo( nMilling, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.GENERIC)
|
|
EgtSetInfo( nMilling, WIN_PRC_SIDE, WIN_PRC_SIDETYPE.OUT)
|
|
end
|
|
|
|
local vCrvsIn = EgtGetNameInGroup( nMixedIntersGrp, WIN_MIXED_MILLING .. WIN_IN .. '*')
|
|
for i = 1, #vCrvsIn do
|
|
local nMilling = EgtCopyGlob( vCrvsIn[i], nProcLayerId)
|
|
if EgtEndsWith( EgtGetName( nMilling), '1') then
|
|
EgtModifyCurveThickness( nMilling, - dDepth1)
|
|
end
|
|
EgtSetInfo( nMilling, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.PROFILING)
|
|
EgtSetInfo( nMilling, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.GENERIC)
|
|
EgtSetInfo( nMilling, WIN_PRC_SIDE, WIN_PRC_SIDETYPE.IN)
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che calcola le lavorazioni di profiling
|
|
local function CalcProfilingProcessings( nPartId, nOutlineId)
|
|
|
|
-- creo gruppo delle lavorazioni
|
|
local nProcLayerId = EgtGroup( nPartId)
|
|
EgtSetName( nProcLayerId, WIN_PRC)
|
|
EgtSetStatus( nProcLayerId, GDB_ST.OFF)
|
|
|
|
-- recupero il geo e la superficie associata per limitare le lavorazioni
|
|
local nGeoLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO)
|
|
local vGeoCrvs = EgtGetAllInGroup( nGeoLayerId)
|
|
local nSurfGeo = vGeoCrvs[#vGeoCrvs]
|
|
|
|
-- recupero il gruppo dei profili
|
|
local nProfileLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE)
|
|
local nMainProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN)
|
|
|
|
-- recupero le info di sovramateriale dal profilo
|
|
CopyInfo( nPartId, nMainProfileId, WIN_PRC_OVERMAT_IN, 0)
|
|
CopyInfo( nPartId, nMainProfileId, WIN_PRC_OVERMAT_OUT, 0)
|
|
CopyInfo( nPartId, nMainProfileId, WIN_PRC_OVERMAT_LEFT, 0)
|
|
CopyInfo( nPartId, nMainProfileId, WIN_PRC_OVERMAT_RIGHT, 0)
|
|
|
|
-- calcolo lavorazioni dei profili
|
|
local nPrfChange = EgtGetInfo( nOutlineId, WIN_PRF_CHANGE, 'i') or WIN_PRF_CHANGE_TYPES.NULL
|
|
if nPrfChange > 0 then
|
|
-- 1) cambio profilo ( su split o telaio)
|
|
if EgtGetName( nOutlineId) == WIN_SPLIT then
|
|
CalcMixedSplitProfilingProcessings( nOutlineId, nProcLayerId, nGeoLayerId, nMainProfileId)
|
|
else
|
|
CalcMixedFrameProfilingProcessings( nPartId, nProcLayerId, nGeoLayerId, nMainProfileId, nSurfGeo)
|
|
end
|
|
else
|
|
-- 2) caso standard : costruisco le curve di lavorazione a partire da quelle del geo
|
|
CreateProfilingProcessingFromGeo( nGeoLayerId, nSurfGeo, nProcLayerId, nPartId)
|
|
end
|
|
|
|
-- calcolo eventuali lavorazioni per strip
|
|
local vStripDist = EgtGetInfo( nMainProfileId, WIN_STRIP_DIST, 'vi') or {}
|
|
local nGeoIn = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_IN)
|
|
local bTangStart = EgtGetInfo( nGeoIn, WIN_TANG_END, 'b') or false
|
|
local bTangEnd = EgtGetInfo( nGeoIn, WIN_TANG_START, 'b') or false
|
|
for i = 1, #vStripDist do
|
|
local nStripOutline = EgtCopyGlob( nOutlineId, nProcLayerId)
|
|
EgtOffsetCurve( nStripOutline, vStripDist[i])
|
|
-- estendo la curva per adattarla alla regione del geo basandomi sulle estensioni della curva in ( che dovrebbe essere quella più vicina)
|
|
EgtSetInfo( nStripOutline, WIN_TANG_START, bTangStart)
|
|
EgtSetInfo( nStripOutline, WIN_TANG_END, bTangEnd)
|
|
local nStripCut = CreateCurveExtension( nStripOutline, nProcLayerId)
|
|
local nRes, nCnt = EgtTrimCurveWithRegion( nStripCut, nSurfGeo, true, false)
|
|
-- se più di un tratto considero solo quello con sovrapposizione con la curva non estesa
|
|
if nCnt > 1 and AreSamePointApprox( EgtSP( nRes), EgtEP( nRes + nCnt - 1)) then
|
|
if EgtGetType( nRes) == GDB_TY.CRV_ARC then
|
|
EgtModifyCurveStartPoint( nRes, EgtSP( nRes + nCnt - 1))
|
|
EgtErase( nRes + nCnt - 1)
|
|
else
|
|
EgtAddCurveCompoCurve( nRes, nRes + nCnt - 1, true, false)
|
|
end
|
|
nCnt = nCnt - 1
|
|
end
|
|
if nCnt > 1 then
|
|
for nId = nRes, nRes + nCnt - 1 do
|
|
if CheckExtensionOverlap( nId, nStripOutline) then
|
|
nStripCut = nId
|
|
else
|
|
EgtErase( nId)
|
|
end
|
|
end
|
|
end
|
|
EgtErase( nStripOutline)
|
|
-- aggiusto orientamento per essere coerente con il geo corrispondente
|
|
if vStripDist[i] < 0 then
|
|
EgtInvertCurve( nStripCut)
|
|
end
|
|
-- setto info di lavorazione
|
|
EgtSetName( nStripCut, WIN_PRC_TYPE.STRIP_CUT)
|
|
EgtSetInfo( nStripCut, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.STRIP_CUT)
|
|
end
|
|
|
|
-- verifico se anta ricevente ( info necessaria per ottimizzazione lavorazioni)
|
|
local nAreaId = EgtGetParent( EgtGetParent( nOutlineId))
|
|
local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i')
|
|
if nAreaType == WIN_AREATYPES.SASH then
|
|
local nSashType = EgtGetInfo( nAreaId, WIN_SASHTYPE, 'i')
|
|
if nSashType == WIN_SASHTYPES.INACTIVE or nSashType == WIN_SASHTYPES.INACTIVE_IN then
|
|
local bOnFrenchSplit = EgtGetInfo( nOutlineId, WIN_CRV_ON_FRENCH_SPLIT, 'b')
|
|
if bOnFrenchSplit then
|
|
EgtSetInfo( nPartId, WIN_SASHTYPE, WIN_INACTIVE)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che calcola gli elementi ausiliari per la creazione del grezzo nell'automatismo delle lavorazioni
|
|
local function CalcGeoRaw( nPartId, nOutlineId)
|
|
|
|
-- se pezzo ad arco il geo raw sarà calcolato tramite i tronchetti
|
|
if EgtGetType( nOutlineId) == GDB_TY.CRV_ARC then
|
|
return
|
|
end
|
|
|
|
local nGeoLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO)
|
|
local nGeoRawLayerId = EgtCopyGlob( nGeoLayerId, nPartId)
|
|
EgtErase( EgtGetLastInGroup( nGeoRawLayerId)) -- elimino la regione
|
|
EgtSetName( nGeoRawLayerId, WIN_GEO_RAW)
|
|
EgtSetStatus( nGeoRawLayerId, GDB_ST.OFF)
|
|
|
|
-- recupero i sovramateriali da applicare alle curve
|
|
local dOvermatOut = EgtGetInfo( nPartId, WIN_PRC_OVERMAT_OUT, 'd')
|
|
local dOvermatRight = EgtGetInfo( nPartId, WIN_PRC_OVERMAT_RIGHT, 'd')
|
|
local dOvermatIn = EgtGetInfo( nPartId, WIN_PRC_OVERMAT_IN, 'd')
|
|
local dOvermatLeft = EgtGetInfo( nPartId, WIN_PRC_OVERMAT_LEFT, 'd')
|
|
|
|
-- recupero le curve del raw e applico i sovramateriali
|
|
local nOut = EgtGetFirstNameInGroup( nGeoRawLayerId, WIN_GEO_OUT)
|
|
if not EgtOffsetCurve( nOut, dOvermatOut) then
|
|
EgtErase( nOut)
|
|
end
|
|
local nIn = EgtGetFirstNameInGroup( nGeoRawLayerId, WIN_GEO_IN)
|
|
if not EgtOffsetCurve( nIn, dOvermatIn) then
|
|
EgtErase( nIn)
|
|
end
|
|
local vRight = EgtGetNameInGroup( nGeoRawLayerId, WIN_GEO_RIGHT)
|
|
for i = 1, #vRight do
|
|
if not EgtOffsetCurve( vRight[i], dOvermatRight) then
|
|
EgtErase( vRight[i])
|
|
end
|
|
end
|
|
local vLeft = EgtGetNameInGroup( nGeoRawLayerId, WIN_GEO_LEFT)
|
|
for i = 1, #vLeft do
|
|
if not EgtOffsetCurve( vLeft[i], dOvermatLeft) then
|
|
EgtErase( vLeft[i])
|
|
end
|
|
end
|
|
|
|
-- creo la composita del grezzo a partire dalle curve
|
|
local vCrvs = EgtGetAllInGroup( nGeoRawLayerId)
|
|
local nRegion = CalcIntersectionRegion( vCrvs, nGeoRawLayerId)
|
|
local nCompo = EgtExtractSurfFrChunkLoops( nRegion, 0, nGeoRawLayerId)
|
|
-- aggiungo spessore
|
|
local dDimH = EgtGetInfo( nGeoLayerId, WIN_GEOHEIGHT, 'd')
|
|
EgtModifyCurveThickness( nCompo, - dDimH)
|
|
|
|
-- creo frame ausiliario
|
|
local vtX = EgtSV( nOut)
|
|
local frGeo = Frame3d( ORIG(), vtX, Z_AX() ^ vtX, Z_AX())
|
|
local nFrameId = EgtFrame( nGeoRawLayerId, frGeo)
|
|
local b3Raw = EgtGetBBoxRef( nCompo, GDB_BB.STANDARD, frGeo)
|
|
local ptMin = b3Raw:getMin()
|
|
ptMin:toGlob( frGeo)
|
|
EgtMove( nFrameId, ( ptMin - ORIG()))
|
|
EgtSetName( nFrameId, WIN_PRC_FRAME)
|
|
|
|
EgtErase( vCrvs)
|
|
EgtErase( nRegion)
|
|
end
|
|
|
|
|
|
|
|
----------------------------------------------------------------------------------
|
|
---------------------------------- SOLIDO ----------------------------------------
|
|
----------------------------------------------------------------------------------
|
|
local function GetReferenceCurve( nCrv, nOrigCrv, dOffs, nSurfTrim)
|
|
|
|
local nRes, nCnt = EgtTrimCurveWithRegion( nCrv, nSurfTrim, true, false)
|
|
if nCnt == 1 then
|
|
EgtOffsetCurve( nRes, dOffs)
|
|
return nRes
|
|
else
|
|
-- se più di un tratto interno alla regione considero solo quello che fa overlap con l'originale
|
|
for nId = nRes, nRes + nCnt - 1 do
|
|
EgtOffsetCurve( nId, dOffs)
|
|
if CheckExtensionOverlap( nId, nOrigCrv) then
|
|
return nId
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che crea la guida per la superficie di trim, opportunamente estesa per avere booleane ben definite
|
|
local function CalcGuideExtension( nCrvId, nGeoId, nSemiProfile, nSurfTrimId, nLayerId)
|
|
|
|
local nGrpTmp = EgtGroup( nLayerId)
|
|
|
|
-- creo estensione della curva ( può essere fatta in tangenza perchè parto dalla curva di processing)
|
|
local nExtCrvId = EgtCurveCompo( nGrpTmp, nCrvId, false)
|
|
EgtAddCurveCompoLineTg( nExtCrvId, 10000, true)
|
|
EgtAddCurveCompoLineTg( nExtCrvId, 10000, false)
|
|
|
|
local nGuideId
|
|
if not nSemiProfile then
|
|
-- se bisettore controllo solamente la curva stessa
|
|
nGuideId = GetReferenceCurve( nExtCrvId, nCrvId, 0, nSurfTrimId)
|
|
-- piccola estensione per essere oltre il minimo indispensabile
|
|
EgtExtendCurveStartByLen( nGuideId, 2)
|
|
EgtExtendCurveEndByLen( nGuideId, 2)
|
|
else
|
|
-- se semiprofilo controllo estensione richiesta per la sua parte interna ed esterna
|
|
local nProfileId = EgtGetParent( nSemiProfile)
|
|
local nFrameId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME)
|
|
local frFrame = EgtFR( nFrameId, GDB_ID.ROOT)
|
|
local b3SemiProfile = EgtGetBBoxRef( nSemiProfile, GDB_BB.STANDARD, frFrame)
|
|
|
|
-- parametri di trim
|
|
local dParS = GEO.INFINITO
|
|
local dParE = -1
|
|
|
|
-- parte in
|
|
local nInExtCrvId = EgtOffsetCurveAdv( nExtCrvId, b3SemiProfile:getMin():getX())
|
|
local nInId = GetReferenceCurve( nInExtCrvId, nCrvId, - b3SemiProfile:getMin():getX(), nSurfTrimId)
|
|
if nInId then
|
|
dParS = EgtCurveParamAtPoint( nExtCrvId, EgtSP( nInId))
|
|
dParE = EgtCurveParamAtPoint( nExtCrvId, EgtEP( nInId))
|
|
end
|
|
|
|
-- parte out
|
|
local nOutExtCrvId = EgtOffsetCurveAdv( nExtCrvId, b3SemiProfile:getMax():getX())
|
|
local nOutId = GetReferenceCurve( nOutExtCrvId, nCrvId, - b3SemiProfile:getMax():getX(), nSurfTrimId)
|
|
if nOutId then
|
|
dParS = min( dParS, EgtCurveParamAtPoint( nExtCrvId, EgtSP( nOutId)))
|
|
dParE = max( dParE, EgtCurveParamAtPoint( nExtCrvId, EgtEP( nOutId)))
|
|
end
|
|
|
|
-- aggiusto la curva estesa tenendo conto di quanto realmente serve per il corretto trim del solido
|
|
EgtTrimCurveStartEndAtParam( nExtCrvId, dParS, dParE)
|
|
nGuideId = nExtCrvId
|
|
end
|
|
|
|
EgtRelocateGlob( nGuideId, nLayerId)
|
|
EgtErase( nGrpTmp)
|
|
return nGuideId
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che crea le superfici di trim
|
|
local function CreateTrimSurfs( vGeoIds, nLayerId, nMainGuideId, nMainProfileId)
|
|
|
|
-- creo la superficie di riferimento del solido originale per capire di quanto estendere le superfici di trim in modo da avere booleane ben definite tra le superfici
|
|
local b3Profile = GetProfileLocalBox( nMainProfileId)
|
|
local dRailOffs = EgtGetInfo( nMainProfileId, WIN_RAILOFFS, 'd') or 0
|
|
local nOffsMax = EgtOffsetCurveAdv( nMainGuideId, b3Profile:getMax():getX() - dRailOffs)
|
|
local nOffsMin = EgtOffsetCurveAdv( nMainGuideId, b3Profile:getMin():getX() - dRailOffs)
|
|
EgtInvertCurve( nOffsMin)
|
|
local nCompo = EgtCurveCompo( nLayerId, nOffsMax)
|
|
EgtAddCurveCompoLine( nCompo, EgtSP( nOffsMin))
|
|
EgtAddCurveCompoCurve( nCompo, nOffsMin)
|
|
EgtCloseCurveCompo( nCompo)
|
|
local nSurfTrim = EgtSurfFlatRegion( nLayerId, nCompo)
|
|
EgtSetStatus( nSurfTrim, GDB_ST.OFF)
|
|
EgtSetStatus( nCompo, GDB_ST.OFF)
|
|
|
|
local vTrimSurfs = {}
|
|
local tabPrcCrv = {}
|
|
for i = 1, #vGeoIds do
|
|
|
|
local nGuideId
|
|
local nTrimSurf
|
|
|
|
-- recupero profilo di riferimento dalla curva geo
|
|
local nSemiProfileId = EgtGetInfo( vGeoIds[i], WIN_SEMI_PROFILE, 'i')
|
|
|
|
-- 1) minizinken
|
|
if not nSemiProfileId then
|
|
nGuideId = CalcGuideExtension( vGeoIds[i], vGeoIds[i], nil, nSurfTrim, nLayerId)
|
|
EgtMove( nGuideId, Z_AX())
|
|
nTrimSurf = EgtSurfTmByExtrusion( nLayerId, nGuideId, - Z_AX() * 2 * b3Profile:getDimY(), WIN_SURF_APPROX)
|
|
EgtInvertSurf( nTrimSurf)
|
|
|
|
-- 2) controprofilo
|
|
else
|
|
-- recupero la curva di lavorazione associata e verifico se la sua superficie di trim è già stata calcolata ( una curva di lavorazione può essere associata
|
|
-- a più curve del geo)
|
|
local nPrcCrv = EgtGetInfo( vGeoIds[i], WIN_REF_PRC, 'i')
|
|
if nPrcCrv then
|
|
if tabPrcCrv[nPrcCrv] then
|
|
-- se la superficie di trim è già stata creata salvo associazione nella curva geo
|
|
EgtSetInfo( vGeoIds[i], WIN_REF_SURF, tabPrcCrv[nPrcCrv])
|
|
else
|
|
-- nel caso di trim di split con cambio profilo non deve essere usato il semiprofilo common salvato nel geo, ma devo usare quello sash
|
|
local sSemiProfileName = EgtGetName( nSemiProfileId)
|
|
if sSemiProfileName == WIN_MIXED_COMMON .. WIN_IN then
|
|
nSemiProfileId = EgtGetFirstNameInGroup( EgtGetParent( nSemiProfileId), WIN_SASH .. WIN_CTRIN)
|
|
elseif sSemiProfileName == WIN_MIXED_COMMON .. WIN_IN .. '1' then
|
|
nSemiProfileId = EgtGetFirstNameInGroup( EgtGetParent( nSemiProfileId), WIN_SASH .. WIN_CTRIN .. '1')
|
|
elseif sSemiProfileName == WIN_MIXED_COMMON .. WIN_IN .. '2' then
|
|
nSemiProfileId = EgtGetFirstNameInGroup( EgtGetParent( nSemiProfileId), WIN_SASH .. WIN_CTRIN .. '2')
|
|
end
|
|
|
|
-- riposiziono la curva di lavorazione in corrispondenza dell'outline
|
|
local dOffs = EgtGetInfo( vGeoIds[i], WIN_GEO_OFFS, 'd')
|
|
local nOffsCrv = EgtOffsetCurveAdv( nPrcCrv, - dOffs)
|
|
nGuideId = CalcGuideExtension( nOffsCrv, vGeoIds[i], nSemiProfileId, nSurfTrim, nLayerId)
|
|
EgtErase( nOffsCrv)
|
|
local nRefOutline = EgtGetInfo( vGeoIds[i], WIN_REF_OUTLINE, 'i')
|
|
if nRefOutline < 0 then
|
|
EgtInvertCurve( nGuideId)
|
|
end
|
|
-- recupero il controprofilo da estrudere
|
|
local sTrimProfileName = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. WIN_OFST .. EgtGetName( nSemiProfileId)
|
|
-- calcolo la superficie di estrusione
|
|
nTrimSurf = CreateProfileSurf( nGuideId, EgtGetParent( nSemiProfileId), sTrimProfileName, b3Profile:getDimX(), nLayerId)
|
|
tabPrcCrv[nPrcCrv] = nTrimSurf
|
|
end
|
|
end
|
|
end
|
|
|
|
-- taglio il solido principale
|
|
if nTrimSurf then
|
|
table.insert( vTrimSurfs, nTrimSurf)
|
|
EgtSetStatus( nTrimSurf, GDB_ST.OFF)
|
|
EgtErase( nGuideId)
|
|
EgtSetInfo( vGeoIds[i], WIN_REF_SURF, nTrimSurf)
|
|
end
|
|
end
|
|
|
|
EgtErase( nSurfTrim)
|
|
EgtErase( nCompo)
|
|
return vTrimSurfs
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che calcola la curva guida per il solido principale
|
|
local function CalcSolidGuide( nOutlineId, nSolidLayerId, nProfileId, nGeoLayerId)
|
|
|
|
local nGuideId
|
|
local dExtraLinearLen = 400
|
|
if EgtGetType( nOutlineId) == GDB_TY.CRV_LINE then
|
|
-- se tratto lineare non ci sono problemi per l'estensione
|
|
nGuideId = EgtCopyGlob( nOutlineId, nSolidLayerId)
|
|
EgtExtendCurveStartByLen( nGuideId, dExtraLinearLen)
|
|
EgtExtendCurveEndByLen( nGuideId, dExtraLinearLen)
|
|
|
|
else
|
|
nGuideId = EgtCurveCompo( nSolidLayerId, nOutlineId, false)
|
|
|
|
-- recupero il tipo di estensione
|
|
local nGeoOut = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_OUT)
|
|
local bTangS = EgtGetInfo( nGeoOut, WIN_TANG_START, 'b')
|
|
local bTangE = EgtGetInfo( nGeoOut, WIN_TANG_END, 'b')
|
|
|
|
-- calcolo la lunghezza di estensione per l'arco in modo che la parte interna non si chiuda in una circonferenza
|
|
local dRad = EgtArcRadius( nOutlineId)
|
|
local dAng = EgtArcAngCenter( nOutlineId) * pi / 180
|
|
local b3Profile = GetProfileLocalBox( nProfileId)
|
|
local dInnerRad = dRad - abs( b3Profile:getMin():getX())
|
|
local dExtraLen = ( pi - 0.5 * dAng) * dInnerRad * dRad / dInnerRad - 2
|
|
|
|
if bTangS then
|
|
EgtAddCurveCompoLineTg( nGuideId, dExtraLinearLen, false)
|
|
else
|
|
EgtExtendCurveStartByLen( nGuideId, dExtraLen)
|
|
end
|
|
|
|
if bTangE then
|
|
EgtAddCurveCompoLineTg( nGuideId, dExtraLinearLen, true)
|
|
else
|
|
EgtExtendCurveEndByLen( nGuideId, dExtraLen)
|
|
end
|
|
end
|
|
|
|
EgtSetName( nGuideId, WIN_MAINGUIDE)
|
|
EgtSetStatus( nGuideId, GDB_ST.OFF)
|
|
|
|
return nGuideId
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che crea la superficie di taglio corrispondente alle fresature del cambio profilo che separano le parti sash e fill
|
|
local function CalcMixedCurveTrimSurf( vMixedCurves, nSolidLayerId, dExtraLen)
|
|
|
|
local vStmInters = {}
|
|
for i = 1, #vMixedCurves do
|
|
local nSplitId = EgtGetInfo( vMixedCurves[i], WIN_MIXED_SPLIT_REF, 'i')
|
|
local vtDir = EgtSV( nSplitId)
|
|
local bFillOnSplitRight = EgtGetInfo( vMixedCurves[i], WIN_FILL_ON_SPLIT_RIGHT, 'b')
|
|
if bFillOnSplitRight then
|
|
vtDir = - vtDir
|
|
end
|
|
|
|
local nCrvTrim = EgtCopyGlob( vMixedCurves[i], nSolidLayerId)
|
|
EgtAddCurveCompoLine( nCrvTrim, EgtSP( nCrvTrim) + 3 * dExtraLen * vtDir, false)
|
|
EgtAddCurveCompoLine( nCrvTrim, EgtEP( nCrvTrim) - 3 * dExtraLen * vtDir)
|
|
EgtMove( nCrvTrim, Z_AX())
|
|
EgtSetStatus( nCrvTrim, GDB_ST.OFF)
|
|
vStmInters[i] = EgtSurfTmByExtrusion( nSolidLayerId, nCrvTrim, - 2 * dExtraLen * Z_AX())
|
|
EgtErase( nCrvTrim)
|
|
end
|
|
|
|
local nStmTrim = EgtSurfTmByTriangles( nSolidLayerId, vStmInters)
|
|
return nStmTrim
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che crea il solido di un pezzo di telaio con cambio profilo
|
|
local function CalcMixedFrameSolid( nOutlineId, nSolidLayerId, nMainProfileId, nGeoLayerId, dGeoWidth)
|
|
|
|
-- a) solido principale
|
|
local nGuideId = CalcSolidGuide( nOutlineId, nSolidLayerId, nMainProfileId, nGeoLayerId)
|
|
EgtSetName( nGuideId, WIN_MAINGUIDE)
|
|
EgtSetStatus( nGuideId, GDB_ST.OFF)
|
|
-- creo i solidi corrispondenti alla parte sash e alla parte fill
|
|
local sSectionSash = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. WIN_SASH .. WIN_SECTION
|
|
local nMainSash = CreateProfileSurf( nGuideId, nMainProfileId, sSectionSash, 0, nSolidLayerId)
|
|
local sSectionFill = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. WIN_FILL .. WIN_SECTION
|
|
local nMainFill = CreateProfileSurf( nGuideId, nMainProfileId, sSectionFill, 0, nSolidLayerId)
|
|
|
|
-- calcolo le superfici di taglio corrispondenti alle fresature del cambio profilo che separano la parte sash e fill
|
|
local nMixedIntersectionsGrp = EgtGetFirstNameInGroup( EgtGetParent( nSolidLayerId), WIN_MIXED_CURVES)
|
|
local vIntersections = EgtGetNameInGroup( nMixedIntersectionsGrp, WIN_MIXED_MILLING .. WIN_IN .. '1')
|
|
local nStmTrim = CalcMixedCurveTrimSurf( vIntersections, nSolidLayerId, dGeoWidth)
|
|
|
|
-- taglio le parti sash e fill e le riunisco in una sola superficie
|
|
EgtSurfTmIntersect( nMainFill, nStmTrim)
|
|
EgtSurfTmSubtract( nMainSash, nStmTrim)
|
|
EgtErase( nStmTrim)
|
|
EgtSurfTmAdd( nMainSash, nMainFill)
|
|
EgtErase( nMainFill)
|
|
local nMainSolid = nMainSash
|
|
EgtSetName( nMainSolid, WIN_SRF_MAIN)
|
|
|
|
-- creo una copia dell'estrusione principale ( usata per ferramenta)
|
|
local nOrigMainExtrusionId = EgtCopy( nMainSolid, nSolidLayerId)
|
|
EgtSetName( nOrigMainExtrusionId, WIN_SRF_ORIGMAIN)
|
|
EgtSetStatus( nOrigMainExtrusionId, GDB_ST.OFF)
|
|
|
|
-- b) trim start
|
|
local vPrevGeoIds = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_LEFT)
|
|
local vTrimStart = CreateTrimSurfs( vPrevGeoIds, nSolidLayerId, nGuideId, nMainProfileId)
|
|
for i = 1, #vTrimStart do
|
|
EgtSurfTmIntersect( nMainSolid, vTrimStart[i])
|
|
end
|
|
|
|
-- c) trim end
|
|
local vNextGeoIds = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_RIGHT)
|
|
local vTrimEnd = CreateTrimSurfs( vNextGeoIds, nSolidLayerId, nGuideId, nMainProfileId)
|
|
for i = 1, #vTrimEnd do
|
|
EgtSurfTmIntersect( nMainSolid, vTrimEnd[i])
|
|
end
|
|
|
|
return nMainSolid
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che crea la superficie di trim per uno split coinvolto da cambio profilo ( controprofilo della parte sash dei vicini e fresatura)
|
|
local function CreateMixedSplitTrimSurfs( vGeoCrvs, bStart, nSolidLayerId, nSplitId, nGuideId, nMainProfileId, dGeoWidth)
|
|
|
|
-- superfici di trim
|
|
local vTrimSurfs = CreateTrimSurfs( vGeoCrvs, nSolidLayerId, nGuideId, nMainProfileId)
|
|
|
|
-- recupero la fresatura
|
|
local nMixedIntersGrp = EgtGetFirstNameInGroup( EgtGetParent( nSolidLayerId), WIN_MIXED_CURVES)
|
|
local nMillingCrv = EgtGetFirstNameInGroup( nMixedIntersGrp, WIN_MIXED_MILLING .. EgtIf( bStart, WIN_LEFT, WIN_RIGHT) .. '1')
|
|
if nMillingCrv then
|
|
-- costruisco il solido associato alla fresatura
|
|
local nGuide = EgtCopyGlob( nMillingCrv, nSolidLayerId)
|
|
EgtAddCurveCompoLineTg( nGuide, 10, true)
|
|
EgtAddCurveCompoLineTg( nGuide, 10, false)
|
|
local vtDir = EgtSV( nSplitId)
|
|
if bStart then
|
|
vtDir = - vtDir
|
|
end
|
|
EgtAddCurveCompoLine( nGuide, EgtEP( nGuide) + 2 * dGeoWidth * vtDir)
|
|
EgtAddCurveCompoLine( nGuide, EgtSP( nGuide) + 2 * dGeoWidth * vtDir, false)
|
|
EgtCloseCurveCompo( nGuide)
|
|
EgtMove( nGuide, 0.01 * Z_AX())
|
|
local nMillStm = EgtSurfTmByRegionExtrusion( nSolidLayerId, nGuide, ( EgtCurveThickness( nGuide) - 2) * Z_AX())
|
|
|
|
-- lo sottraggo alle superfici di trim
|
|
for i = 1, #vTrimSurfs do
|
|
EgtSurfTmSubtract( vTrimSurfs[i], nMillStm)
|
|
end
|
|
|
|
EgtErase( nGuide)
|
|
EgtErase( nMillStm)
|
|
end
|
|
|
|
return vTrimSurfs
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che completa il semiprofilo per creare una sezione da estrudere per il solido di un mixed split
|
|
local function CreateExtrusionSection( nSemiProfileId)
|
|
|
|
-- recupero il Ref e lo taglio con il semiprofilo
|
|
local nProfileId = EgtGetParent( nSemiProfileId)
|
|
local nRefId = EgtGetFirstNameInGroup( nProfileId, WIN_REF)
|
|
|
|
local nSection = EgtCopyGlob( nRefId, nProfileId)
|
|
local dPar1 = EgtCurveParamAtPoint( nSection, EgtSP( nSemiProfileId))
|
|
local dPar2 = EgtCurveParamAtPoint( nSection, EgtEP( nSemiProfileId))
|
|
EgtTrimCurveStartEndAtParam( nSection, dPar2, dPar1)
|
|
EgtAddCurveCompoCurve( nSection, nSemiProfileId, false)
|
|
|
|
return nSection
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che crea il solido di un pezzo di split coinvolto da cambio profilo
|
|
local function CalcMixedSplitSolid( nOutlineId, nSolidLayerId, nMainProfileId, nGeoLayerId, dGeoWidth)
|
|
|
|
-- a) solido principale
|
|
local nGuideId = CalcSolidGuide( nOutlineId, nSolidLayerId, nMainProfileId, nGeoLayerId)
|
|
-- creo un solido per ogni lato dello split
|
|
local vSolids = {}
|
|
for i = 1, 2 do
|
|
-- verifico se ho un solo profilo definito
|
|
local nSemiProfile = EgtGetFirstNameInGroup( nMainProfileId, WIN_IN .. tostring( i))
|
|
if nSemiProfile then
|
|
local nSection = CreateExtrusionSection( nSemiProfile)
|
|
vSolids[i] = CreateProfileSurfById( nGuideId, nMainProfileId, nSection, 0, nSolidLayerId)
|
|
else
|
|
-- creo i solidi sash e fill
|
|
local nSemiProfileSash = EgtGetFirstNameInGroup( nMainProfileId, WIN_SASH .. WIN_IN .. tostring( i))
|
|
local nSashSection = CreateExtrusionSection( nSemiProfileSash)
|
|
local nSashSolid = CreateProfileSurfById( nGuideId, nMainProfileId, nSashSection, 0, nSolidLayerId)
|
|
local nSemiProfileFill = EgtGetFirstNameInGroup( nMainProfileId, WIN_FILL .. WIN_IN .. tostring( i))
|
|
local nFillSection = CreateExtrusionSection( nSemiProfileFill)
|
|
local nFillSolid = CreateProfileSurfById( nGuideId, nMainProfileId, nFillSection, 0, nSolidLayerId)
|
|
|
|
-- calcolo le superfici di taglio corrispondenti alle fresature del cambio profilo che separano la parte sash e fill
|
|
local nMixedIntersectionsGrp = EgtGetFirstNameInGroup( EgtGetParent( nSolidLayerId), WIN_MIXED_CURVES)
|
|
local vIntersections = EgtGetNameInGroup( nMixedIntersectionsGrp, WIN_MIXED_MILLING .. EgtIf( i == 1, WIN_OUT, WIN_IN) .. '1')
|
|
local nStmTrim = CalcMixedCurveTrimSurf( vIntersections, nSolidLayerId, dGeoWidth)
|
|
|
|
-- costruisco il solido combinando opportunamente le parti sash e fill
|
|
EgtSurfTmIntersect( nFillSolid, nStmTrim)
|
|
EgtSurfTmSubtract( nSashSolid, nStmTrim)
|
|
EgtErase( nStmTrim)
|
|
EgtSurfTmAdd( nSashSolid, nFillSolid)
|
|
EgtErase( nFillSolid)
|
|
vSolids[i] = nSashSolid
|
|
end
|
|
end
|
|
|
|
-- taglio e unisco le due metà
|
|
local b3Profile = GetProfileLocalBox( nMainProfileId)
|
|
local dOffs = ( b3Profile:getMax():getX() + b3Profile:getMin():getX()) * 0.5
|
|
local nOffsGuide = EgtOffsetCurveAdv( nGuideId, dOffs)
|
|
EgtMove( nOffsGuide, 2 * Z_AX())
|
|
local nStmTrim = EgtSurfTmByExtrusion( nSolidLayerId, nOffsGuide, - Z_AX() * ( b3Profile:getDimY() + 5))
|
|
EgtSurfTmCut( vSolids[1], nStmTrim, true, false)
|
|
EgtSurfTmCut( vSolids[2], nStmTrim, false, false)
|
|
EgtErase( nStmTrim)
|
|
local nMainExtrusionId = EgtSurfTmByTriangles( nSolidLayerId, vSolids)
|
|
EgtSetName( nMainExtrusionId, WIN_SRF_MAIN)
|
|
|
|
-- creo una copia ( usata per calcolo ferramenta)
|
|
local nOrigMainExtrusionId = EgtCopy( nMainExtrusionId, nSolidLayerId)
|
|
EgtSetName( nOrigMainExtrusionId, WIN_SRF_ORIGMAIN)
|
|
EgtSetStatus( nOrigMainExtrusionId, GDB_ST.OFF)
|
|
|
|
-- b) trim start
|
|
local vGeoLeft = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_LEFT)
|
|
local vTrimStart = CreateMixedSplitTrimSurfs( vGeoLeft, true, nSolidLayerId, nOutlineId, nGuideId, nMainProfileId, dGeoWidth)
|
|
for i = 1, #vTrimStart do
|
|
EgtSurfTmIntersect( nMainExtrusionId, vTrimStart[i])
|
|
end
|
|
|
|
-- c) trim end
|
|
local vGeoRight = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_RIGHT)
|
|
local vTrimEnd = CreateMixedSplitTrimSurfs( vGeoRight, false, nSolidLayerId, nOutlineId, nGuideId, nMainProfileId, dGeoWidth)
|
|
for i = 1, #vTrimEnd do
|
|
EgtSurfTmIntersect( nMainExtrusionId, vTrimEnd[i])
|
|
end
|
|
|
|
return nMainExtrusionId
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che crea il solido del pezzo
|
|
local function CalcSolid( nPartId, nOutlineId)
|
|
|
|
-- creo layer per solido
|
|
local nSolidLayerId = EgtGroup( nPartId)
|
|
EgtSetName( nSolidLayerId, WIN_SOLID)
|
|
|
|
-- recupero profilo principale
|
|
local nProfileLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE)
|
|
local nMainProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN)
|
|
|
|
-- recupero geo e la sua larghezza
|
|
local nGeoLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO)
|
|
local dGeoWidth = EgtGetInfo( nGeoLayerId, WIN_GEOWIDTH, 'd')
|
|
|
|
-- gestione speciale per pezzi con CAMBIO PROFILO
|
|
local nPrfChange = EgtGetInfo( nOutlineId, WIN_PRF_CHANGE, 'i') or WIN_PRF_CHANGE_TYPES.NULL
|
|
if nPrfChange > 0 then
|
|
if EgtGetName( nOutlineId) == WIN_SPLIT then
|
|
return CalcMixedSplitSolid( nOutlineId, nSolidLayerId, nMainProfileId, nGeoLayerId, dGeoWidth)
|
|
else
|
|
return CalcMixedFrameSolid( nOutlineId, nSolidLayerId, nMainProfileId, nGeoLayerId, dGeoWidth)
|
|
end
|
|
end
|
|
|
|
-- a) creo il solido di estrusione principale
|
|
local nGuideId = CalcSolidGuide( nOutlineId, nSolidLayerId, nMainProfileId, nGeoLayerId)
|
|
local sSection = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. WIN_SECTION
|
|
local nMainExtrusionId = CreateProfileSurf( nGuideId, nMainProfileId, sSection, 0, nSolidLayerId)
|
|
EgtSetName( nMainExtrusionId, WIN_SRF_MAIN)
|
|
|
|
-- creo una copia ( usata per calcolo ferramenta)
|
|
local nOrigMainExtrusionId = EgtCopy( nMainExtrusionId, nSolidLayerId)
|
|
EgtSetName( nOrigMainExtrusionId, WIN_SRF_ORIGMAIN)
|
|
EgtSetStatus( nOrigMainExtrusionId, GDB_ST.OFF)
|
|
|
|
-- b) trim con i controprofili su start
|
|
local vGeoLeft = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_LEFT)
|
|
local vTrimStart = CreateTrimSurfs( vGeoLeft, nSolidLayerId, nGuideId, nMainProfileId)
|
|
for i = 1, #vTrimStart do
|
|
EgtSurfTmIntersect( nMainExtrusionId, vTrimStart[i])
|
|
end
|
|
|
|
-- c) trim con i controprofili su end
|
|
local vGeoRight = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_RIGHT)
|
|
local vTrimEnd = CreateTrimSurfs( vGeoRight, nSolidLayerId, nGuideId, nMainProfileId)
|
|
for i = 1, #vTrimEnd do
|
|
EgtSurfTmIntersect( nMainExtrusionId, vTrimEnd[i])
|
|
end
|
|
|
|
return nMainExtrusionId
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che crea il solido del Fill
|
|
local function CalcFillSolid( nPartId, nGeoLayerId)
|
|
-- creo layer per solido
|
|
local nSolidLayerId = EgtGroup( nPartId)
|
|
EgtSetName( nSolidLayerId, WIN_SOLID)
|
|
-- creo compo dalle curve del geo
|
|
local vGeoList = EgtGetAllInGroup( nGeoLayerId)
|
|
local nCompoOutlineId = EgtCurveCompo( nSolidLayerId, vGeoList, false)
|
|
-- recupero spessore vetro
|
|
local dGlassThickness = EgtGetInfo( nGeoLayerId, WIN_GLASSTHICKNESS, 'd')
|
|
local nSurfId = EgtSurfTmByRegionExtrusion( nSolidLayerId, nCompoOutlineId, Z_AX() * dGlassThickness)
|
|
EgtErase( nCompoOutlineId)
|
|
end
|
|
|
|
----------------------------------------------------------------------------------
|
|
-- funzione che aggiorna il solido principale con quello associato ad una lavorazione partendo dalla sua curva
|
|
local function UpdateSolidWithProcessingCrv( nProcId, nSolidId, nLayerId)
|
|
|
|
if not EgtCurveIsClosed( nProcId) then
|
|
return
|
|
end
|
|
|
|
local vtExtr = EgtCurveExtrusion( nProcId)
|
|
local dThick = EgtCurveThickness( nProcId)
|
|
local nRefCrv = nProcId
|
|
-- se solidi semplificati approssimo in modo grossolano per velocizzare operazioni di subtract ( soprattuto su archi)
|
|
if s_bSimplSolid then
|
|
nRefCrv = EgtCopyGlob( nProcId, nLayerId)
|
|
EgtApproxCurve( nRefCrv, GDB_CA.LINES, s_dSimplSolidApprox)
|
|
end
|
|
local nProcSolidId = EgtSurfTmByRegionExtrusion( nLayerId, nRefCrv, ( dThick - 0.05) * vtExtr)
|
|
-- piccola traslazione per non essere a filo con la superficie
|
|
EgtMove( nProcSolidId, 0.05 * vtExtr)
|
|
|
|
-- sottraggo al solido
|
|
EgtSurfTmSubtract( nSolidId, nProcSolidId)
|
|
|
|
EgtErase( nProcSolidId)
|
|
if s_bSimplSolid then
|
|
EgtErase( nRefCrv)
|
|
end
|
|
end
|
|
|
|
|
|
|
|
----------------------------------------------------------------------------------
|
|
---------------------------------- DOWELS ----------------------------------------
|
|
----------------------------------------------------------------------------------
|
|
-- funzione che recupera la lunghezza del dowel
|
|
local function CalcDowelLen( nDowelId, sKey, bFullOrShort)
|
|
|
|
local sDefaultKey = EgtIf( bFullOrShort, WIN_DWL_TOP_PERP_LEN, WIN_DWL_TOP_PARA_LEN)
|
|
local dLen = EgtGetInfo( nDowelId, sKey, 'd') or EgtGetInfo( nDowelId, sDefaultKey, 'd')
|
|
dLen = dLen + s_dDowelTol
|
|
return dLen
|
|
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che calcola il riferimento dove posizionare i dowels
|
|
local function CreateDowelFrameDest( nPrevRight, nCurrLeft, nRefOutline, bCurrFullOrShort)
|
|
|
|
local vtZ
|
|
local ptOrig
|
|
if EgtGetType( nRefOutline) == GDB_TY.CRV_LINE then
|
|
vtZ = EgtEV( nRefOutline)
|
|
ptOrig = EgtIf( bCurrFullOrShort, EgtEP( nRefOutline), EgtSP( nRefOutline))
|
|
else
|
|
-- se pezzo ad arco, recupero la direzione dalla curva nel punto estremo del geo
|
|
local ptRef = EgtIf( bCurrFullOrShort, EgtSP( nPrevRight), EgtEP( nCurrLeft))
|
|
local _, ptInt, dPar = EgtPointCurveDist( ptRef, nRefOutline)
|
|
vtZ = EgtUV( nRefOutline, dPar, -1)
|
|
ptOrig = ptInt
|
|
end
|
|
|
|
local frDest = Frame3d( ptOrig, - vtZ)
|
|
return frDest
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che posiziona il dowel tramite i riferimenti
|
|
local function PositionDowel( nDowelId, frOrig, frDest, vtDir, nSurfId)
|
|
|
|
-- posiziono il dowel utilizzando i riferimenti
|
|
EgtTransform( nDowelId, frOrig, GDB_RT.GLOB)
|
|
EgtTransform( nDowelId, frDest, GDB_RT.GLOB)
|
|
EgtMove( nDowelId, 3000 * vtDir)
|
|
-- creo il tool corrispondente al dowel
|
|
local dRad = EgtArcRadius( nDowelId)
|
|
|
|
EgtCAvSetStdTool( s_dDowelTol, 2 * dRad, 0)
|
|
-- calcolo spostamento per posizionarlo in corrispondenza della superficie
|
|
local dStart = EgtCAvToolPosStm( EgtCP( nDowelId), - vtDir, nSurfId, - vtDir)
|
|
EgtMove( nDowelId, - dStart * vtDir)
|
|
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che crea il dowel e lo sottrae al solido
|
|
local function CreateDowel( nOrigDowelId, nLayerId, frOrig, frDest, vtDir, nTestSurfId, dLen, sDowelSide, nMainExtrusionId)
|
|
|
|
-- vtDir rivolta verso interno del pezzo
|
|
|
|
local nDowelId = EgtCopyGlob( nOrigDowelId, nLayerId)
|
|
EgtSetColor( nDowelId, Color3d( 128, 128, 128))
|
|
|
|
-- posiziono il dowel
|
|
PositionDowel( nDowelId, frOrig, frDest, vtDir, nTestSurfId)
|
|
|
|
-- assegno estrusione e spessore
|
|
EgtModifyCurveExtrusion( nDowelId, - vtDir)
|
|
EgtModifyCurveThickness( nDowelId, - dLen)
|
|
|
|
-- setto info di lavorazione
|
|
EgtSetInfo( nDowelId, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.HOLE)
|
|
EgtSetInfo( nDowelId, WIN_PRC_SIDE, sDowelSide)
|
|
|
|
-- eventuale aggiornamento del solido
|
|
if nMainExtrusionId then
|
|
UpdateSolidWithProcessingCrv( nDowelId, nMainExtrusionId, nLayerId)
|
|
end
|
|
|
|
return nDowelId
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che calcola i dowels tra due pezzi
|
|
local function CalcDowels( nOrigOutlineId, nOrigPrevOutlineId, bSashOrFrame, nBottomRail)
|
|
|
|
-- TODO correzione per non far uscire i dowels
|
|
|
|
-- se soglia non ci sono dowels
|
|
if EgtGetInfo( nOrigOutlineId, WIN_THRESHOLD, 'b') or EgtGetInfo( nOrigPrevOutlineId, WIN_THRESHOLD, 'b') then
|
|
return
|
|
end
|
|
|
|
-- recupero i pezzi
|
|
local nPart = EgtGetInfo( nOrigOutlineId, WIN_REF_PART, 'i')
|
|
local nPrevPart = EgtGetInfo( nOrigPrevOutlineId, WIN_REF_PART, 'i')
|
|
if nBottomRail then
|
|
if EgtGetName( nOrigOutlineId) == WIN_BOTTOM then
|
|
local vParts = EgtGetInfo( nOrigOutlineId, WIN_REF_BOTTOMRAIL_PART, 'vi')
|
|
nPart = vParts[nBottomRail]
|
|
else
|
|
local vParts = EgtGetInfo( nOrigPrevOutlineId, WIN_REF_BOTTOMRAIL_PART, 'vi')
|
|
nPrevPart = vParts[nBottomRail]
|
|
end
|
|
end
|
|
|
|
-- recupero i layer delle lavorazioni
|
|
local nLayerId = EgtGetFirstNameInGroup( nPart, WIN_PRC)
|
|
local nPrevLayerId = EgtGetFirstNameInGroup( nPrevPart, WIN_PRC)
|
|
|
|
-- recupero i profili
|
|
local nProfileLay = EgtGetFirstNameInGroup( nPart, WIN_PROFILE)
|
|
local nProfileId = EgtGetFirstNameInGroup( nProfileLay, WIN_PRF_MAIN)
|
|
local nPrevProfileLay = EgtGetFirstNameInGroup( nPrevPart, WIN_PROFILE)
|
|
local nPrevProfileId = EgtGetFirstNameInGroup( nPrevProfileLay, WIN_PRF_MAIN)
|
|
|
|
-- copio curve outlines
|
|
local nOutlineId = EgtCopyGlob( nOrigOutlineId, nLayerId)
|
|
local nPrevOutlineId = EgtCopyGlob( nOrigPrevOutlineId, nLayerId)
|
|
if nBottomRail then
|
|
-- eventuale offset per bottomrail
|
|
local dOffs
|
|
local nRefCrv
|
|
if EgtGetName( nOutlineId) == WIN_BOTTOM then
|
|
nRefCrv = nOutlineId
|
|
dOffs = EgtGetInfo( nProfileId, WIN_RAILOFFS, 'd')
|
|
else
|
|
nRefCrv = nPrevOutlineId
|
|
dOffs = EgtGetInfo( nPrevProfileId, WIN_RAILOFFS, 'd')
|
|
end
|
|
EgtOffsetCurve( nRefCrv, - dOffs)
|
|
end
|
|
|
|
-- recupero le curve di riferimento dei geo ( right per il prev e left per il corrente)
|
|
local nGeo = EgtGetFirstNameInGroup( nPart, WIN_GEO)
|
|
local nPrevGeo = EgtGetFirstNameInGroup( nPrevPart, WIN_GEO)
|
|
local vPrevGeoCrvs = EgtGetNameInGroup( nPrevGeo, WIN_GEO_RIGHT)
|
|
local nPrevRight = vPrevGeoCrvs[1]
|
|
for i = 2, #vPrevGeoCrvs do
|
|
local nRefOutline = EgtGetInfo( vPrevGeoCrvs[i], WIN_REF_OUTLINE, 'i')
|
|
if nRefOutline == nOrigOutlineId then
|
|
nPrevRight = vPrevGeoCrvs[i]
|
|
break
|
|
end
|
|
end
|
|
local vCurrGeoCrvs = EgtGetNameInGroup( nGeo, WIN_GEO_LEFT)
|
|
local nCurrLeft = vCurrGeoCrvs[1]
|
|
for i = 2, #vCurrGeoCrvs do
|
|
local nRefOutline = EgtGetInfo( vCurrGeoCrvs[i], WIN_REF_OUTLINE, 'i')
|
|
if nRefOutline == nOrigPrevOutlineId then
|
|
nCurrLeft = vCurrGeoCrvs[i]
|
|
break
|
|
end
|
|
end
|
|
|
|
-- recupero i solidi
|
|
local nPrevSolidId, nSolidId, nPrevSolidLay, nSolidLay
|
|
if s_bCalcSolid then
|
|
nSolidLay = EgtGetFirstNameInGroup( nPart, WIN_SOLID)
|
|
nSolidId = EgtGetFirstNameInGroup( nSolidLay, WIN_SRF_MAIN)
|
|
nPrevSolidLay = EgtGetFirstNameInGroup( nPrevPart, WIN_SOLID)
|
|
nPrevSolidId = EgtGetFirstNameInGroup( nPrevSolidLay, WIN_SRF_MAIN)
|
|
end
|
|
|
|
-- recupero il tipo di giunzione
|
|
local nJointType
|
|
if nBottomRail then
|
|
if EgtGetName( nOutlineId) == WIN_BOTTOM then
|
|
nJointType = WIN_PART_JNT.SHORT
|
|
else
|
|
nJointType = WIN_PART_JNT.FULL
|
|
end
|
|
else
|
|
local vJointTypes = EgtGetInfo( nOutlineId, WIN_STARTJOINT, 'vi')
|
|
local vPrevOutlines = EgtGetInfo( nOutlineId, WIN_PREV_OUTLINES, 'vi')
|
|
for i = 1, #vPrevOutlines do
|
|
if vPrevOutlines[i] == nOrigPrevOutlineId then
|
|
nJointType = vJointTypes[i]
|
|
break
|
|
end
|
|
end
|
|
end
|
|
|
|
if nJointType == WIN_PART_JNT.ANGLED then
|
|
-- TO DO
|
|
|
|
elseif nJointType == WIN_PART_JNT.FULL then
|
|
|
|
-- calcolo il riferimento del profilo
|
|
local nFrameProfile = EgtGetFirstNameInGroup( nPrevProfileId, WIN_SECTIONFRAME)
|
|
local frOrig = EgtFR( nFrameProfile, GDB_ID.ROOT)
|
|
frOrig:invert()
|
|
|
|
-- calcolo il riferimento su cui posizionare i dowels
|
|
local frDest = CreateDowelFrameDest( nPrevRight, nCurrLeft, nPrevOutlineId, true)
|
|
|
|
-- recupero info con la lunghezza ( dipendono dal profilo del pezzo full quindi dal corrente)
|
|
local sLenKey = WIN_DWL_TOP_PERP_LEN
|
|
local sPrevLenKey = WIN_DWL_TOP_PARA_LEN
|
|
if EgtGetName( nOutlineId) == WIN_BOTTOM then
|
|
sLenKey = WIN_DWL_BOTTOM_PERP_LEN
|
|
sPrevLenKey = WIN_DWL_BOTTOM_PARA_LEN
|
|
elseif EgtExistsInfo( nPart, WIN_SASHTYPE) then
|
|
-- verifico se è inactive sash dalla info settata per lavorazione
|
|
sLenKey = WIN_DWL_INACTIVE_PERP_LEN
|
|
sPrevLenKey = WIN_DWL_INACTIVE_PARA_LEN
|
|
end
|
|
|
|
-- superficie test per il posizionamento dei dowels : è la superficie in del pezzo full
|
|
local nTestSurf
|
|
if not s_bCalcSolid or s_bSimplSolid then
|
|
local sCtrIn = WIN_OFST .. GetProfileCtrIn( nOrigOutlineId, nPrevOutlineId, nProfileId, false) -- controprofilo in del pezzo corrente
|
|
nTestSurf = CreateProfileSurf( nOrigOutlineId, nProfileId, sCtrIn, 100, nLayerId)
|
|
else
|
|
-- è la superficie che viene utilizzata per trimmare l'end del pezzo prev
|
|
local nOrigSurf = EgtGetInfo( nPrevRight, WIN_REF_SURF, 'i')
|
|
nTestSurf = EgtCopyGlob( nOrigSurf, nLayerId)
|
|
end
|
|
local nTestSurfInverted = EgtCopyGlob( nTestSurf, nLayerId)
|
|
EgtInvertSurf( nTestSurfInverted)
|
|
|
|
-- analizzo le singole file di dowels
|
|
for k = 0, 3 do
|
|
-- recupero i dowels della fila k-esima
|
|
local vDowels = EgtGetNameInGroup( nPrevProfileId, WIN_DOWEL .. 'Row' .. tostring( k))
|
|
if #vDowels > 0 then
|
|
for i = 1, #vDowels do
|
|
-- dowels per pezzo corrente ( full)
|
|
local dLenFull = CalcDowelLen( vDowels[i], sLenKey, true)
|
|
CreateDowel( vDowels[i], nLayerId, frOrig, frDest, - frDest:getVersZ(), nTestSurfInverted, dLenFull, WIN_PRC_SIDETYPE.IN, nSolidId)
|
|
-- dowels per prezzo precedente ( short)
|
|
local dLenShort = CalcDowelLen( vDowels[i], sPrevLenKey, false)
|
|
CreateDowel( vDowels[i], nPrevLayerId, frOrig, frDest, frDest:getVersZ(), nTestSurf, dLenShort, WIN_PRC_SIDETYPE.RIGHT, nPrevSolidId)
|
|
end
|
|
end
|
|
end
|
|
|
|
EgtErase( nTestSurf)
|
|
EgtErase( nTestSurfInverted)
|
|
|
|
|
|
elseif nJointType == WIN_PART_JNT.SHORT then
|
|
|
|
-- calcolo il riferimento del profilo
|
|
local nFrameProfile = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME)
|
|
local frOrig = EgtFR( nFrameProfile, GDB_ID.ROOT)
|
|
frOrig:invert()
|
|
|
|
-- calcolo il riferimento su cui posizionare i dowels
|
|
local frDest = CreateDowelFrameDest( nPrevRight, nCurrLeft, nOutlineId, false)
|
|
|
|
-- recupero info con la lunghezza ( dipendono dal profilo del pezzo full, quindi da prezzo prev)
|
|
local sLenKey = WIN_DWL_TOP_PARA_LEN
|
|
local sPrevLenKey = WIN_DWL_TOP_PERP_LEN
|
|
if EgtGetName( nPrevOutlineId) == WIN_BOTTOM then
|
|
if not nBottomRail then
|
|
sLenKey = WIN_DWL_BOTTOM_PARA_LEN
|
|
sPrevLenKey = WIN_DWL_BOTTOM_PERP_LEN
|
|
else
|
|
sLenKey = WIN_DWL_BOTTOMRAIL_PARA_LEN
|
|
sPrevLenKey = WIN_DWL_BOTTOMRAIL_PERP_LEN
|
|
end
|
|
elseif EgtExistsInfo( nPrevPart, WIN_SASHTYPE) then
|
|
-- verifico se è inactive sash dalla info settata per lavorazione
|
|
sLenKey = WIN_DWL_INACTIVE_PARA_LEN
|
|
sPrevLenKey = WIN_DWL_INACTIVE_PERP_LEN
|
|
end
|
|
|
|
-- superficie test per il posizionamento dei dowels
|
|
-- è il controprofilo in del pezzo full quindi è la stessa superficie che viene utilizzata per trimmare lo start del pezzo corrente
|
|
local nTestSurf
|
|
if not s_bCalcSolid or s_bSimplSolid then
|
|
local sCtrIn = WIN_OFST .. GetProfileCtrIn( nOrigPrevOutlineId, nOutlineId, nPrevProfileId, true) -- controprofilo del pezzo full
|
|
nTestSurf = CreateProfileSurf( nOrigPrevOutlineId, nPrevProfileId, sCtrIn, 100, nLayerId)
|
|
else
|
|
local nOrigSurf = EgtGetInfo( nCurrLeft, WIN_REF_SURF, 'i')
|
|
nTestSurf = EgtCopyGlob( nOrigSurf, nLayerId)
|
|
end
|
|
local nTestSurfInverted = EgtCopyGlob( nTestSurf, nLayerId)
|
|
EgtInvertSurf( nTestSurfInverted)
|
|
|
|
-- analizzo le singole file di dowels
|
|
for k = 0, 3 do
|
|
-- recupero i dowels sulla fila k-esima
|
|
local vDowels = EgtGetNameInGroup( nProfileId, WIN_DOWEL .. 'Row' .. tostring(k))
|
|
if #vDowels > 0 then
|
|
for i = 1, #vDowels do
|
|
-- dowels per pezzo corrente ( short)
|
|
local dLenShort = CalcDowelLen( vDowels[i], sLenKey, false)
|
|
CreateDowel( vDowels[i], nLayerId, frOrig, frDest, - frDest:getVersZ(), nTestSurf, dLenShort, WIN_PRC_SIDETYPE.LEFT, nSolidId)
|
|
-- dowels per prezzo precedente ( full)
|
|
local dLenFull = CalcDowelLen( vDowels[i], sPrevLenKey, true)
|
|
CreateDowel( vDowels[i], nPrevLayerId, frOrig, frDest, frDest:getVersZ(), nTestSurfInverted, dLenFull, WIN_PRC_SIDETYPE.IN, nPrevSolidId)
|
|
end
|
|
end
|
|
end
|
|
|
|
EgtErase( nTestSurf)
|
|
EgtErase( nTestSurfInverted)
|
|
end
|
|
|
|
EgtErase( nOutlineId)
|
|
EgtErase( nPrevOutlineId)
|
|
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che calcola i dowels tra uno split e i pezzi sui cui poggia
|
|
local function CalcSplitDowels( nSplitId, bStartOrEnd)
|
|
|
|
-- TO DO : da gestire incrocio dowels di tre pezzi
|
|
-- TO DO : gestione split non lineare
|
|
|
|
-- recupero il pezzo dello split
|
|
local nSplitPart = EgtGetInfo( nSplitId, WIN_REF_PART, 'i')
|
|
|
|
-- recupero il profilo originale dello split e il suo frame
|
|
local nSplitProfile = GetOutlineProfileId( nSplitId, false)
|
|
local nSplitProfileFrameId = EgtGetFirstNameInGroup( nSplitProfile, WIN_SECTIONFRAME)
|
|
local frOrig = EgtFR( nSplitProfileFrameId, GDB_ID.ROOT)
|
|
frOrig:invert()
|
|
|
|
-- recupero il gruppo delle lavorazioni
|
|
local nSplitLayerId = EgtGetFirstNameInGroup( nSplitPart, WIN_PRC)
|
|
|
|
-- recupero eventuale solido e superifici usate per il suo trim
|
|
local nSplitSolidId
|
|
if s_bCalcSolid then
|
|
local nSplitSolidLayerId = EgtGetFirstNameInGroup( nSplitPart, WIN_SOLID)
|
|
nSplitSolidId = EgtGetFirstNameInGroup( nSplitSolidLayerId, WIN_SRF_MAIN)
|
|
end
|
|
|
|
-- indviduo il lato su cui andranno i dowels
|
|
local sSplitDowelSide = EgtIf( bStartOrEnd, WIN_PRC_SIDETYPE.LEFT, WIN_PRC_SIDETYPE.RIGHT)
|
|
|
|
-- recupero le curve del geo e la superficie del pezzo ( per verificare se dowel interno)
|
|
local nSplitGeo = EgtGetFirstNameInGroup( nSplitPart, WIN_GEO)
|
|
local vGeoCrvs = EgtGetNameInGroup( nSplitGeo, EgtIf( bStartOrEnd, WIN_LEFT, WIN_RIGHT))
|
|
local nSplitSurf = EgtGetFirstNameInGroup( nSplitGeo, WIN_GEO_SURF)
|
|
|
|
-- verifico se necessario calcolare le superifici di trim associate alle curve del geo
|
|
local vAuxSurfs = {}
|
|
if not s_bCalcSolid or s_bSimplSolid then
|
|
-- simulo la guida per il calcolo del solido
|
|
local nGuideId = CalcSolidGuide( nSplitId, nSplitLayerId, nSplitProfile, nSplitGeo)
|
|
if EgtGetInfo( nSplitId, WIN_SPLITTYPE, 'i') == WIN_SPLITTYPES.MIXED then
|
|
vAuxSurfs = CreateMixedSplitTrimSurfs( vGeoCrvs, bStartOrEnd, nSplitLayerId, nSplitId, nGuideId, nSplitProfile, 100)
|
|
else
|
|
vAuxSurfs = CreateTrimSurfs( vGeoCrvs, nSplitLayerId, nGuideId, nSplitProfile)
|
|
end
|
|
EgtErase( nGuideId)
|
|
end
|
|
|
|
for i = 1, #vGeoCrvs do
|
|
|
|
-- se la curva non ha lavorazione associata allora il pezzo non influisce direttamente sullo split e può essere ignorato
|
|
local nPrcRef = EgtGetInfo( vGeoCrvs[i], WIN_REF_PRC, 'i')
|
|
if nPrcRef then
|
|
local nOrigOutline = abs( EgtGetInfo( vGeoCrvs[i], WIN_REF_OUTLINE, 'i'))
|
|
-- verifico se soglia ( in quel caso non ci sono dowels quindi va ignorato)
|
|
local bThreshold = EgtGetInfo( nOrigOutline, WIN_THRESHOLD, 'b') or false
|
|
if not bThreshold then
|
|
|
|
-- recupero il pezzo associato e il suo outline di riferimento
|
|
local nPartId = FindAssociatedPart( nOrigOutline, true)
|
|
local nOutlineId = EgtGetInfo( nPartId, WIN_REF_OUTLINE, 'i')
|
|
|
|
local nGeoLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO)
|
|
local nGeoCrvId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_IN)
|
|
local sDowelSide = WIN_PRC_SIDETYPE.IN
|
|
-- se split verifico se interferisce con lato in o out del geo
|
|
if EgtGetName( nOutlineId) == WIN_SPLIT then
|
|
local _, _, nSide = EgtPointCurveDistSide( EgtMP( nSplitId), nOutlineId, Z_AX())
|
|
if nSide == 1 then
|
|
nGeoCrvId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_OUT)
|
|
sDowelSide = WIN_PRC_SIDETYPE.OUT
|
|
end
|
|
end
|
|
|
|
-- calcolo il frame di destinazione
|
|
local ptOrig = EgtIf( bStartOrEnd, EgtSP( nSplitId), EgtEP( nSplitId))
|
|
local frDest = Frame3d( ptOrig, - EgtSV( nSplitId))
|
|
|
|
-- recupero il layer con le lavorazioni
|
|
local nLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PRC)
|
|
|
|
-- nel layer dei profili del pezzo aggiungo il profilo dello split posizionato correttamente
|
|
local nProfileLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE)
|
|
local nSplitProfileCopyId = EgtCopy( nSplitProfile, nProfileLayerId)
|
|
CopyInfo( nSplitProfileCopyId, nSplitProfile, WIN_PROFILETYPE)
|
|
EgtSetName( nSplitProfileCopyId, WIN_PRF_SPLIT)
|
|
-- posiziono il profilo sulla curva di split
|
|
EgtTransform( EgtGetAllInGroup( nSplitProfileCopyId), frOrig, GDB_RT.GLOB)
|
|
EgtChangeGroupFrame( nSplitProfileCopyId, frDest, GDB_RT.GLOB)
|
|
|
|
-- recupero eventuale solido
|
|
local nSolidId
|
|
if s_bCalcSolid then
|
|
local nSolidLayerId = EgtGetFirstNameInGroup( nPartId, WIN_SOLID)
|
|
nSolidId = EgtGetFirstNameInGroup( nSolidLayerId, WIN_SRF_MAIN)
|
|
end
|
|
|
|
-- recupero le chiavi delle lunghezze ( dipendono dal profilo del pezzo su cui poggia lo split)
|
|
local sSplitLenKey = WIN_DWL_TOP_PARA_LEN
|
|
local sLenKey = WIN_DWL_TOP_PERP_LEN
|
|
if EgtGetName( nOutlineId) == WIN_BOTTOM then
|
|
-- verifico se ha bottomrails
|
|
local nBottomRails = EgtGetInfo( nOutlineId, WIN_BOTTOMRAIL, 'i') or 0
|
|
if nBottomRails == 0 then
|
|
sSplitLenKey = WIN_DWL_BOTTOM_PARA_LEN
|
|
sLenKey = WIN_DWL_BOTTOM_PERP_LEN
|
|
else
|
|
sSplitLenKey = WIN_DWL_RAILBOTTOM_PARA_LEN
|
|
sLenKey = WIN_DWL_RAILBOTTOM_PERP_LEN
|
|
end
|
|
elseif EgtGetName( nOutlineId) == WIN_SPLIT then
|
|
sSplitLenKey = WIN_DWL_SPLIT_PARA_LEN
|
|
sLenKey = WIN_DWL_SPLIT_PERP_LEN
|
|
end
|
|
|
|
-- creo la superficie di test per il posizionamento dei dowels
|
|
local nTrimSurf = EgtGetInfo( vGeoCrvs[i], WIN_REF_SURF, 'i')
|
|
local nTestSurf = EgtCopyGlob( nTrimSurf, nSplitLayerId)
|
|
local nTestSurfInverted = EgtCopyGlob( nTestSurf, nSplitLayerId)
|
|
EgtInvertSurf( nTestSurfInverted)
|
|
|
|
-- calcolo le direzioni entranti nei pezzi
|
|
local vtSplitDir = EgtIf( bStartOrEnd, - frDest:getVersZ(), frDest:getVersZ())
|
|
local vtDir = EgtIf( bStartOrEnd, - EgtSV( nSplitId), EgtSV( nSplitId))
|
|
|
|
-- recupero la superficie del pezzo per verificare se dowel interno
|
|
local nGeo = EgtGetFirstNameInGroup( nPartId, WIN_GEO)
|
|
local nSurf = EgtGetFirstNameInGroup( nGeo, WIN_GEO_SURF)
|
|
|
|
-- aggiungo i dowels
|
|
local vDowels = EgtGetNameInGroup( nSplitProfile, WIN_DOWEL .. '*') or {}
|
|
for i = 1, #vDowels do
|
|
-- split
|
|
local dLen1 = CalcDowelLen( vDowels[i], sSplitLenKey, false)
|
|
local nDowel1 = CreateDowel( vDowels[i], nSplitLayerId, frOrig, frDest, vtSplitDir, nTestSurf, dLen1, sSplitDowelSide, nSplitSolidId)
|
|
-- verifico se dowel è interno al pezzo ( TO DO : da migliorare!)
|
|
local ptTest = EgtCP( nDowel1) - vtSplitDir * EgtCurveThickness( nDowel1)
|
|
local nTestPoint = EgtPoint( nSplitLayerId, ptTest)
|
|
if EgtSurfFrTestExternal( nSplitSurf, nTestPoint) then
|
|
EgtErase( nDowel1)
|
|
end
|
|
EgtErase( nTestPoint)
|
|
|
|
-- pezzo
|
|
local dLen2 = CalcDowelLen( vDowels[i], sLenKey, true)
|
|
local nDowel2 = CreateDowel( vDowels[i], nLayerId, frOrig, frDest, vtDir, nTestSurfInverted, dLen2, sDowelSide, nSolidId)
|
|
ptTest = EgtCP( nDowel2) - vtDir * EgtCurveThickness( nDowel2)
|
|
nTestPoint = EgtPoint( nLayerId, ptTest)
|
|
if EgtSurfFrTestExternal( nSurf, nTestPoint) then
|
|
EgtErase( nDowel2)
|
|
end
|
|
EgtErase( nTestPoint)
|
|
end
|
|
|
|
EgtErase( nTestSurf)
|
|
EgtErase( nTestSurfInverted)
|
|
end
|
|
end
|
|
end
|
|
|
|
EgtErase( vAuxSurfs)
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che calcola le spine
|
|
local function CalculateAreaDowels( nAreaId)
|
|
|
|
local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i')
|
|
local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE)
|
|
if nAreaType == WIN_AREATYPES.FRAME or nAreaType == WIN_AREATYPES.SASH then
|
|
-- verifico se presente bottomrail
|
|
local nBottomRails = EgtGetInfo( nAreaId, WIN_BOTTOMRAIL, 'i') or 0
|
|
-- aggiungo le spine sui pezzi dell'area
|
|
local nOutline = EgtGetFirstInGroup( nOutlineLayerId)
|
|
local nPrevOutline = EgtGetLastInGroup( nOutlineLayerId)
|
|
while EgtGetInfo( nPrevOutline, WIN_EXTRA_CRV, 'b') do
|
|
nPrevOutline = EgtGetPrev( nPrevOutline)
|
|
end
|
|
while nOutline do
|
|
local bExtra = EgtGetInfo( nOutline, WIN_EXTRA_CRV, 'b') or false
|
|
if not bExtra then
|
|
-- aggiungo spine su nOutline e nPrevOutline nel loro punto di giunzione
|
|
CalcDowels( nOutline, nPrevOutline, nAreaType == WIN_AREATYPES.SASH)
|
|
-- bottomrail
|
|
if nBottomRails > 0 and ( EgtGetName( nOutline) == WIN_BOTTOM or EgtGetName( nPrevOutline) == WIN_BOTTOM) then
|
|
for j = 1, nBottomRails do
|
|
CalcDowels( nOutline, nPrevOutline, false, j)
|
|
end
|
|
end
|
|
-- aggiorno per iterazione successiva
|
|
nPrevOutline = nOutline
|
|
end
|
|
nOutline = EgtGetNext( nOutline)
|
|
end
|
|
|
|
elseif nAreaType == WIN_AREATYPES.SPLIT then
|
|
local nSplitType = EgtGetInfo( nAreaId, WIN_SPLITTYPE, 'i') or WIN_SPLITTYPES.NULL
|
|
-- se split non è di tipo french ha un pezzo associato per il quale vanno calcolate le spine
|
|
if nSplitType ~= WIN_SPLITTYPES.FRENCH then
|
|
local nSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_SPLIT)
|
|
local vSplitIds = EgtGetAllInGroup( nSplitLayerId)
|
|
for i = 1, #vSplitIds do
|
|
-- start
|
|
CalcSplitDowels( vSplitIds[i], true)
|
|
-- end
|
|
CalcSplitDowels( vSplitIds[i], false)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- calcolo le spine delle sottoaree
|
|
local nChildAreaId = EgtGetFirstNameInGroup( nAreaId, WIN_AREA .. '*')
|
|
while nChildAreaId do
|
|
CalculateAreaDowels( nChildAreaId)
|
|
nChildAreaId = EgtGetNextName( nChildAreaId, WIN_AREA .. '*')
|
|
end
|
|
end
|
|
|
|
|
|
|
|
----------------------------------------------------------------------------------
|
|
--------------------------------- STRIP ----------------------------------------
|
|
----------------------------------------------------------------------------------
|
|
-- funzione che restitutisce lo Strip piu' vicino
|
|
local function GetStripNearestToOutline( nProfileId, nOutlineId)
|
|
|
|
local sStripName = WIN_STRIP
|
|
-- gestione particolare del caso di profilo di split ( devo capire il lato corretto)
|
|
if not EgtGetFirstNameInGroup( nProfileId, sStripName) then
|
|
if nOutlineId < 0 then
|
|
sStripName = WIN_STRIP .. '1'
|
|
else
|
|
sStripName = WIN_STRIP .. '2'
|
|
end
|
|
end
|
|
|
|
if s_bSimplSolid then
|
|
sStripName = WIN_SIMPLIFIED .. sStripName
|
|
end
|
|
|
|
local nStripId = EgtGetFirstNameInGroup( nProfileId, sStripName)
|
|
return nStripId
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function CreateStripGuideLines( nOutlineId, nStripId, nProfileId, nSolidLayerId)
|
|
-- restutuisco le curve ordinate in modo che la prima sia quella più esterna e la seconda quella più interna
|
|
|
|
-- recupero il box dello strip nel frame del profilo
|
|
local nProfileFrameId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME)
|
|
local frProfile = EgtFR( nProfileFrameId, GDB_ID.ROOT)
|
|
local b3MainStrip = EgtGetBBoxRef( nStripId, GDB_BB.STANDARD, frProfile)
|
|
|
|
-- calcolo offset per strip
|
|
local dDelta = EgtGetInfo( nProfileId, WIN_RAILOFFS, 'd') or 0
|
|
local dMinOffs = b3MainStrip:getMin():getX() - dDelta
|
|
local dMaxOffs = b3MainStrip:getMax():getX() - dDelta
|
|
|
|
local nMinOffsetId = EgtCopy( abs( nOutlineId), nSolidLayerId)
|
|
EgtOffsetCurve( nMinOffsetId, dMinOffs)
|
|
local nMaxOffsetId = EgtCopy( abs( nOutlineId), nSolidLayerId)
|
|
EgtOffsetCurve( nMaxOffsetId, dMaxOffs)
|
|
|
|
-- verifico se le curve vanno invertite nel caso di split
|
|
if nOutlineId < 0 then
|
|
EgtInvertCurve( nMinOffsetId)
|
|
EgtInvertCurve( nMaxOffsetId)
|
|
return nMaxOffsetId, nMinOffsetId
|
|
end
|
|
|
|
return nMinOffsetId, nMaxOffsetId
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function TrimStripSurfByPoints( pt1, pt2, nStripSurfId, nSolidLayerId)
|
|
|
|
-- creo la superficie di trim
|
|
local nTrimGuideId = EgtLine( nSolidLayerId, pt1, pt2)
|
|
EgtExtendCurveStartByLen( nTrimGuideId, 100)
|
|
EgtExtendCurveEndByLen( nTrimGuideId, 100)
|
|
EgtMove( nTrimGuideId, Z_AX())
|
|
local dDim = 100
|
|
local nTrimSurfId = EgtSurfTmByExtrusion( nSolidLayerId, nTrimGuideId, - Z_AX() * dDim, WIN_SURF_APPROX)
|
|
|
|
-- intersezione con strip
|
|
EgtSurfTmIntersect( nStripSurfId, nTrimSurfId)
|
|
|
|
EgtErase( nTrimGuideId)
|
|
EgtErase( nTrimSurfId)
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function TrimStripSurfByCurve( nCrvId, nStripSurfId, nSolidLayerId, bPrev)
|
|
|
|
-- estendo la guida in tangenza
|
|
local nTrimGuideId = EgtCopyGlob( nCrvId, nSolidLayerId)
|
|
local dExtraLen = 100
|
|
if EgtGetType( nTrimGuideId) == GDB_TY.CRV_LINE then
|
|
EgtExtendCurveStartByLen( nTrimGuideId, dExtraLen)
|
|
EgtExtendCurveEndByLen( nTrimGuideId, dExtraLen)
|
|
else
|
|
nTrimGuideId = EgtCurveCompo( nSolidLayerId, nTrimGuideId)
|
|
EgtAddCurveCompoLineTg( nTrimGuideId, dExtraLen)
|
|
EgtAddCurveCompoLineTg( nTrimGuideId, dExtraLen, false)
|
|
end
|
|
EgtMove( nTrimGuideId, Z_AX())
|
|
EgtInvertCurve( nTrimGuideId)
|
|
|
|
-- creo la superficie di trim
|
|
local dDim = 100
|
|
local nTrimSurfId = EgtSurfTmByExtrusion( nSolidLayerId, nTrimGuideId, - Z_AX() * dDim, WIN_SURF_APPROX)
|
|
|
|
-- intersezione con strip
|
|
EgtSurfTmIntersect( nStripSurfId, nTrimSurfId)
|
|
|
|
EgtErase( nTrimGuideId)
|
|
EgtErase( nTrimSurfId)
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function CalcAreaStrip( nOutlineLayerId)
|
|
|
|
if not s_bCalcSolid then return end
|
|
|
|
-- gruppi temporanei per i conti
|
|
local nGrp = EgtGroup( GDB_ID.ROOT)
|
|
local nGrp1 = EgtGroup( GDB_ID.ROOT)
|
|
local nGrp2 = EgtGroup( GDB_ID.ROOT)
|
|
EgtSetStatus( nGrp, GDB_ST.OFF)
|
|
EgtSetStatus( nGrp1, GDB_ST.OFF)
|
|
EgtSetStatus( nGrp2, GDB_ST.OFF)
|
|
|
|
-- estrudo i fermavetri e calcolo le curve che li limitano ( Offs1 sono quelli più lontani dal pezzo, Offs2 quelli più vicini)
|
|
local vOutlineCrvs = EgtGetAllInGroup( nOutlineLayerId)
|
|
local tabStrip = {}
|
|
for i = 1, #vOutlineCrvs do
|
|
|
|
local nOutlineId = EgtGetInfo( vOutlineCrvs[i], WIN_SOU_OUTLINE, 'i')
|
|
-- verifico se pezzo ausiliario da ignorare
|
|
local bExtra = EgtGetInfo( nOutlineId, WIN_EXTRA_CRV, 'b')
|
|
local nPartId = FindAssociatedPart( abs( nOutlineId), true)
|
|
|
|
-- recupero profilo
|
|
local nProfileLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE)
|
|
local nProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN)
|
|
local nStripId = GetStripNearestToOutline( nProfileId, nOutlineId)
|
|
|
|
-- recupero layer per solido
|
|
local nStripExtrusionId
|
|
if not bExtra then
|
|
local nSolidLayerId = EgtGetFirstNameInGroup( nPartId, WIN_SOLID)
|
|
|
|
-- estrusione del fermavetro :
|
|
-- creazione della giuda
|
|
local nGuideId = EgtCurveCompo( nSolidLayerId, abs( nOutlineId), false)
|
|
local sProfileType = EgtGetInfo( nProfileId, WIN_PROFILETYPE)
|
|
if sProfileType == WIN_FILL_RAIL then
|
|
local dOffs = EgtGetInfo( nProfileId, WIN_RAILOFFS, 'd')
|
|
EgtOffsetCurve( nGuideId, - dOffs)
|
|
end
|
|
-- estensione : se in tangenza con le vicine estensione in tangenza altrimenti estensione standard
|
|
local nPrev = EgtGetPrev( vOutlineCrvs[i]) or EgtGetLastInGroup( nOutlineLayerId)
|
|
local nNext = EgtGetNext( vOutlineCrvs[i]) or EgtGetLastInGroup( nOutlineLayerId)
|
|
if AreSameVectorApprox( EgtEV( nPrev), EgtSV( nGuideId)) then
|
|
EgtAddCurveCompoLineTg( nGuideId, 100, false)
|
|
else
|
|
EgtExtendCurveStartByLen( nGuideId, 100)
|
|
end
|
|
if AreSameVectorApprox( EgtEV( nGuideId), EgtSV( nNext)) then
|
|
EgtAddCurveCompoLineTg( nGuideId, 100)
|
|
else
|
|
EgtExtendCurveEndByLen( nGuideId, 100)
|
|
end
|
|
-- sistemo il profilo da estrudere
|
|
local nSectionId = EgtCopyGlob( nStripId, nSolidLayerId)
|
|
local nFrameProfileId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME)
|
|
local frOrig = EgtFR( nFrameProfileId, GDB_ID.ROOT)
|
|
frOrig:invert()
|
|
local frDest = Frame3d( EgtSP( nGuideId), - EgtSV( nGuideId))
|
|
EgtTransform( nSectionId, frOrig)
|
|
EgtTransform( nSectionId, frDest)
|
|
nStripExtrusionId = EgtSurfTmSwept( nSolidLayerId, nSectionId, nGuideId, false, WIN_SURF_APPROX)
|
|
EgtSetName( nStripExtrusionId, WIN_SRF_STRIP)
|
|
EgtErase( nSectionId)
|
|
EgtErase( nGuideId)
|
|
end
|
|
|
|
-- curve limite del fermavetro
|
|
local nOffs1, nOffs2 = CreateStripGuideLines( nOutlineId, nStripId, nProfileId, nGrp)
|
|
EgtRelocateGlob( nOffs1, nGrp1)
|
|
EgtRelocateGlob( nOffs2, nGrp2)
|
|
EgtSetInfo( nOffs1, WIN_REF_OUTLINE, vOutlineCrvs[i])
|
|
EgtSetInfo( nOffs2, WIN_REF_OUTLINE, vOutlineCrvs[i])
|
|
|
|
tabStrip[vOutlineCrvs[i]] = { Offs1 = GDB_ID.NULL, Offs2 = GDB_ID.NULL, StripId = nStripExtrusionId}
|
|
end
|
|
|
|
-- taglio le curve limite dei fermavetri per individuare correttamente i pezzi con cui verranno tagliati
|
|
local vCrv1 = TrimOrderedCurves( EgtGetAllInGroup( nGrp1), true)
|
|
local vCrv2 = TrimOrderedCurves( EgtGetAllInGroup( nGrp2), true)
|
|
|
|
-- associo le curve trimmate alle curve geo corrispondenti
|
|
for i = 1, #vCrv1 do
|
|
local nOutlineRef = EgtGetInfo( vCrv1[i], WIN_REF_OUTLINE, 'i')
|
|
tabStrip[nOutlineRef].Offs1 = vCrv1[i]
|
|
end
|
|
for i = 1, #vCrv2 do
|
|
local nOutlineRef = EgtGetInfo( vCrv2[i], WIN_REF_OUTLINE, 'i')
|
|
tabStrip[nOutlineRef].Offs2 = vCrv2[i]
|
|
end
|
|
|
|
-- trim dei solidi fermavetro
|
|
for i = 1, #vOutlineCrvs do
|
|
if tabStrip[vOutlineCrvs[i]].StripId then
|
|
-- recupero solido del fermavetro
|
|
local nCrv = vOutlineCrvs[i]
|
|
local nStripId = tabStrip[nCrv].StripId
|
|
local nSolidLayerId = EgtGetParent( nStripId)
|
|
|
|
-- recupero le corrispondenti curve limite trimmate
|
|
local nCrvOffs1 = tabStrip[nCrv].Offs1
|
|
local nCrvOffs2 = tabStrip[nCrv].Offs2
|
|
|
|
-- se entrambe le curve valide
|
|
if nCrvOffs1 ~= GDB_ID.NULL and nCrvOffs2 ~= GDB_ID.NULL then
|
|
-- a) trim start
|
|
-- recupero le precedenti della curva 1 e 2
|
|
local nPrev1 = EgtGetPrev( nCrvOffs1) or EgtGetLastInGroup( nGrp1)
|
|
local nPrev2 = EgtGetPrev( nCrvOffs2) or EgtGetLastInGroup( nGrp2)
|
|
local nPrevCrv1 = EgtGetInfo( nPrev1, WIN_REF_OUTLINE, 'i')
|
|
local nPrevCrv2 = EgtGetInfo( nPrev2, WIN_REF_OUTLINE, 'i')
|
|
|
|
if nPrevCrv1 == nPrevCrv2 then
|
|
-- se le precedenti coincidono taglio basandomi solo sui riferimenti dello strip corrente
|
|
TrimStripSurfByPoints( EgtSP( nCrvOffs2), EgtSP( nCrvOffs1), nStripId, nSolidLayerId, true)
|
|
else
|
|
-- ci sono dei pezzi che scompaiono quindi vanno effettuati due tagli: uno per ricreare il bordo 2 dei pezzi che scompaiono e uno per
|
|
-- separare il pezzo corrente e il pezzo 1
|
|
|
|
-- a) recupero i pezzi che scompaiono
|
|
local nCurrCrv = tabStrip[nPrevCrv1].Offs2
|
|
nCurrCrv = EgtGetNext( nCurrCrv) or EgtGetFirstInGroup( nGrp2)
|
|
local vIds = {}
|
|
while nCurrCrv ~= nCrvOffs2 do
|
|
table.insert( vIds, nCurrCrv)
|
|
nCurrCrv = EgtGetNext( nCurrCrv) or EgtGetFirstInGroup( nGrp2)
|
|
end
|
|
local nCrvBorder = EgtCurveCompo( nGrp, vIds, false)
|
|
-- taglio
|
|
TrimStripSurfByCurve( nCrvBorder, nStripId, nSolidLayerId)
|
|
|
|
-- b) taglio che separa da pezzo 1
|
|
TrimStripSurfByPoints( EgtCP( nCrvBorder), EgtSP( nCrvOffs1), nStripId, nSolidLayerId, true)
|
|
EgtErase( nCrvBorder)
|
|
end
|
|
|
|
-- b) trim end
|
|
-- recupero le successive per le curve 1 e 2
|
|
local nNext1 = EgtGetNext( nCrvOffs1) or EgtGetFirstInGroup( nGrp1)
|
|
local nNext2 = EgtGetNext( nCrvOffs2) or EgtGetFirstInGroup( nGrp2)
|
|
local nNextCrv1 = EgtGetInfo( nNext1, WIN_REF_OUTLINE, 'i')
|
|
local nNextCrv2 = EgtGetInfo( nNext2, WIN_REF_OUTLINE, 'i')
|
|
|
|
if nNextCrv1 == nNextCrv2 then
|
|
TrimStripSurfByPoints( EgtEP( nCrvOffs1), EgtEP( nCrvOffs2), nStripId, nSolidLayerId)
|
|
else
|
|
local nCurrCrv = nCrvOffs2
|
|
nCurrCrv = EgtGetNext( nCurrCrv) or EgtGetFirstInGroup( nGrp2)
|
|
local vIds = {}
|
|
while nCurrCrv ~= tabStrip[nNextCrv1].Offs2 do
|
|
table.insert( vIds, nCurrCrv)
|
|
nCurrCrv = EgtGetNext( nCurrCrv) or EgtGetFirstInGroup( nGrp2)
|
|
end
|
|
local nCrvBorder = EgtCurveCompo( nGrp, vIds, false)
|
|
TrimStripSurfByCurve( nCrvBorder, nStripId, nSolidLayerId)
|
|
|
|
TrimStripSurfByPoints( EgtEP( nCrvOffs1), EgtCP( nCrvBorder), nStripId, nSolidLayerId)
|
|
EgtErase( nCrvBorder)
|
|
end
|
|
|
|
else
|
|
-- il pezzo scompare
|
|
EgtErase( nStripId)
|
|
end
|
|
end
|
|
end
|
|
|
|
EgtErase( nGrp)
|
|
EgtErase( nGrp1)
|
|
EgtErase( nGrp2)
|
|
end
|
|
|
|
|
|
|
|
----------------------------------------------------------------------------------
|
|
----------------------------- CALCOLO PEZZI ------------------------------------
|
|
----------------------------------------------------------------------------------
|
|
local function CalculateAreaParts( nFrameId)
|
|
|
|
-- recupero i pezzi del serramento
|
|
local vParts = {}
|
|
local vFillParts = {}
|
|
local vAuxParts = {} -- sono pezzi non fisicamente realizzabili che servono solo per i conti
|
|
local nPartId = EgtGetFirstPart( GDB_ID.ROOT)
|
|
while nPartId do
|
|
local nType = EgtGetInfo( nPartId, WIN_PART_TYPE, 'i')
|
|
if nType == WIN_PART_TYPES.FILL then
|
|
table.insert( vFillParts, nPartId)
|
|
else
|
|
local nOutlineId = EgtGetInfo( nPartId, WIN_REF_OUTLINE, 'i')
|
|
local bExtra = EgtGetInfo( nOutlineId, WIN_EXTRA_CRV, 'b') or false
|
|
if bExtra then
|
|
table.insert( vAuxParts, nPartId)
|
|
else
|
|
table.insert( vParts, { nId = nPartId, nOutlineId = nOutlineId})
|
|
end
|
|
end
|
|
nPartId = EgtGetNextPart( nPartId)
|
|
end
|
|
|
|
-- calcolo geo
|
|
for i = 1, #vParts do
|
|
CalcGeo( vParts[i].nId, vParts[i].nOutlineId)
|
|
end
|
|
|
|
-- calcolo cambio profilo sugli split di tipo mixed
|
|
for i = 1, #vParts do
|
|
if EgtGetName( vParts[i].nOutlineId) == WIN_SPLIT then
|
|
local nSplitType = EgtGetInfo( vParts[i].nOutlineId, WIN_SPLITTYPE, 'i')
|
|
if nSplitType == WIN_SPLITTYPES.MIXED then
|
|
CalcMixedCurves( vParts[i].nId, vParts[i].nOutlineId)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- calcolo le lavorazioni associate ai profili
|
|
for i = 1, #vParts do
|
|
CalcProfilingProcessings( vParts[i].nId, vParts[i].nOutlineId)
|
|
end
|
|
|
|
-- calcolo il georaw per automatismo lavorazioni
|
|
for i = 1, #vParts do
|
|
CalcGeoRaw( vParts[i].nId, vParts[i].nOutlineId)
|
|
end
|
|
|
|
-- disegno solido
|
|
if s_bCalcSolid then
|
|
for i = 1, #vParts do
|
|
CalcSolid( vParts[i].nId, vParts[i].nOutlineId)
|
|
end
|
|
end
|
|
|
|
-- pezzi fill
|
|
for i = 1, #vFillParts do
|
|
local nAreaId = EgtGetInfo( vFillParts[i], WIN_AREA, 'i')
|
|
local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE)
|
|
local nGeoLayerId = CalcFillGeo( vFillParts[i], nOutlineLayerId)
|
|
-- disegno solido
|
|
if s_bCalcSolid then
|
|
CalcFillSolid( vFillParts[i], nGeoLayerId)
|
|
end
|
|
-- calcolo fermavetro
|
|
CalcAreaStrip( nOutlineLayerId)
|
|
end
|
|
|
|
-- elimino i pezzi ausiliari
|
|
EgtErase( vAuxParts)
|
|
end
|
|
|
|
|
|
|
|
----------------------------------------------------------------------------------
|
|
---------------------------------- TRONCHETTI ----------------------------------
|
|
----------------------------------------------------------------------------------
|
|
-- funzione che spezza l'anta in corrispondenza dei tronchetti del telaio
|
|
local function SplitArcByAlignment( nGeoIn, nGrp)
|
|
|
|
-- recupero il pezzo del telaio corrispondente
|
|
local nPartId = EgtGetParent( EgtGetParent( nGeoIn))
|
|
local nOutlineId = EgtGetInfo( nPartId, WIN_REF_OUTLINE, 'i')
|
|
local nFrameOutlineId = EgtGetInfo( nOutlineId, WIN_SOU_OUTLINE, 'i')
|
|
local nFramePartId = EgtGetInfo( nFrameOutlineId, WIN_REF_PART, 'i')
|
|
|
|
-- recupero le parti in cui era stato diviso l'arco del telaio
|
|
local nFrameLogsLayer = EgtGetFirstNameInGroup( nFramePartId, WIN_LOGS)
|
|
local vFrameLogs = EgtGetNameInGroup( nFrameLogsLayer, WIN_GEO_IN)
|
|
local ptC = EgtCP( vFrameLogs[1])
|
|
|
|
local nCurrCrvId = EgtCopyGlob( nGeoIn, nGrp)
|
|
local bInters = false
|
|
for i = 1, #vFrameLogs - 1 do
|
|
-- ricavo il punto di split sull'arco dell'anta
|
|
local ptFrame = EgtEP( vFrameLogs[i])
|
|
local vtDir = ptFrame - ptC
|
|
local nLineSplit = EgtLinePVL( nGrp, ptC, vtDir, vtDir:len() + 1000)
|
|
local ptInt = EgtIP( nCurrCrvId, nLineSplit, ORIG())
|
|
EgtErase( nLineSplit)
|
|
if ptInt then
|
|
nCurrCrvId = EgtSplitCurveAtPoint( nCurrCrvId, ptInt) or GDB_ID.NULL
|
|
bInters = true
|
|
elseif bInters then
|
|
-- se non ci sono più intersezioni esco
|
|
return
|
|
end
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che spezza l'arco in base al numero di pezzi
|
|
local function SplitArcByNumber( nLogsNbr, nGeoIn, nGrp)
|
|
local nCopy = EgtCopyGlob( nGeoIn, nGrp)
|
|
EgtSplitCurve( nCopy, nLogsNbr)
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che spezza gli archi per i tronchetti
|
|
local function SplitArc( nLogsNbr, vSections, bAlign, dOverMatTot, nGeoIn, nGeoOut, nGrp)
|
|
|
|
-- per allineamento con telaio
|
|
if bAlign then
|
|
return SplitArcByAlignment( nGeoIn, nGrp)
|
|
|
|
-- per sezione
|
|
elseif #vSections == 1 and nLogsNbr == 0 then
|
|
-- dalla sezione ricavo il numero minimo di pezzi
|
|
local dSection = vSections[1] - dOverMatTot
|
|
local dROut = EgtArcRadius( nGeoOut)
|
|
local dRIn = EgtArcRadius( nGeoIn)
|
|
local dAng = abs( EgtArcAngCenter( nGeoIn))
|
|
local nParts
|
|
if dSection < dROut - dRIn + GEO.EPS_SMALL then
|
|
-- sezione troppo piccola
|
|
-- TO DO : gestione errore
|
|
EgtOutBox( 'Sezione tronchetto troppo piccola', '')
|
|
elseif dSection > dROut + dRIn - GEO.EPS_SMALL then
|
|
-- la sezione comprende già l'intero pezzo
|
|
nParts = 1
|
|
else
|
|
nParts = dAng / 2 / acos( ( dROut - dSection) / dRIn)
|
|
nParts = ceil( nParts)
|
|
end
|
|
return SplitArcByNumber( nParts, nGeoIn, nGrp)
|
|
|
|
-- per numero di pezzi
|
|
else
|
|
return SplitArcByNumber( nLogsNbr, nGeoIn, nGrp)
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che calcola la sezione dei tronchetti
|
|
local function CalcLogsSection( nLogsNbr, vSections, bAlign, dOverMatTot, nGeoIn, nGeoOut, nGrp)
|
|
|
|
-- se richiesta una sezione specifica senza vincoli sul numero di pezzi
|
|
if not bAlign and #vSections == 1 and nLogsNbr == 0 then
|
|
return vSections[1]
|
|
end
|
|
|
|
-- calcolo la sezione necessaria per la suddivisione scelta
|
|
local dMySection = 0
|
|
local dROut = EgtArcRadius( nGeoOut)
|
|
local dRIn = EgtArcRadius( nGeoIn)
|
|
if bAlign then
|
|
-- calcolo la massima sezione dai tronchetti ottenuti
|
|
local vSplits = EgtGetAllInGroup( nGrp)
|
|
for i = 1, #vSplits do
|
|
local dAng = abs( EgtArcAngCenter( vSplits[i]))
|
|
local dCurrSection = dROut - dRIn * cos( dAng / 2)
|
|
if dCurrSection > dMySection then
|
|
dMySection = dCurrSection
|
|
end
|
|
end
|
|
dMySection = dMySection + dOverMatTot
|
|
|
|
else
|
|
-- ricavo la sezione dal numero di pezzi
|
|
local dAng = abs( EgtArcAngCenter( nGeoIn))
|
|
dMySection = dROut - dRIn * cos( dAng / nLogsNbr / 2) + dOverMatTot
|
|
end
|
|
|
|
if #vSections == 0 then
|
|
-- se no vincoli sulla sezione
|
|
return dMySection
|
|
else
|
|
-- cerco la sezione più adatta dalla lista di sezioni disponibili
|
|
table.sort( vSections)
|
|
for i = 1, #vSections do
|
|
if vSections[i] > dMySection - GEO.EPS_SMALL then
|
|
return vSections[i]
|
|
end
|
|
end
|
|
-- se non ho trovato la sezione errore
|
|
EgtOutBox( 'Sezioni tronchetti troppo piccole per suddivisione richiesta', '')
|
|
return nil
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function CalcLogs( nGrp, nGeoOut, dOverMatIn, dOverMatOut, dOverMatExt, dOverMatInt, dRefSection, bCutExtremities)
|
|
|
|
-- recupero tutti i tratti dell'arco
|
|
local vCrvsIn = EgtGetAllInGroup( nGrp)
|
|
local ptC = EgtCP( vCrvsIn[1])
|
|
|
|
-- calcolo i tronchetti
|
|
local dLenTot = 0
|
|
for i = 1, #vCrvsIn do
|
|
|
|
local ptSIn = EgtSP( vCrvsIn[i])
|
|
local ptEIn = EgtEP( vCrvsIn[i])
|
|
|
|
-- recupero il tratto corrispondente sulla curva out
|
|
local ptSOut, dParSOut, ptEOut, dParEOut
|
|
if i == 1 then
|
|
-- forzo a coincidere con l'estremo della curva out
|
|
ptEOut = EgtEP( nGeoOut)
|
|
dParEOut = 1
|
|
else
|
|
_, ptEOut, dParEOut = EgtPointCurveDist( ptSIn, nGeoOut)
|
|
end
|
|
if i == #vCrvsIn then
|
|
-- forzo a coincidere con l'estremo della curva out
|
|
ptSOut = EgtSP( nGeoOut)
|
|
dParSOut = 0
|
|
else
|
|
_, ptSOut, dParSOut = EgtPointCurveDist( ptEIn, nGeoOut)
|
|
end
|
|
local nOut = EgtCopyGlob( nGeoOut, nGrp)
|
|
EgtTrimCurveStartEndAtParam( nOut, dParSOut, dParEOut)
|
|
|
|
-- creo composita corrispondente al pezzo
|
|
local nCompo = EgtCurveCompo( nGrp, {vCrvsIn[i]}, false)
|
|
EgtAddCurveCompoLine( nCompo, ptSOut)
|
|
EgtAddCurveCompoCurve( nCompo, nOut, false)
|
|
EgtCloseCurveCompo( nCompo)
|
|
|
|
-- calcolo il frame per il tronchetto
|
|
local ptM = EgtMP( vCrvsIn[i])
|
|
local vtRad = ptM - ptC
|
|
local frRef = Frame3d( ptM, vtRad ^ Z_AX(), vtRad, Z_AX())
|
|
|
|
-- calcolo il box locale al frame
|
|
local b3Ref = EgtGetBBoxRef( nCompo, GDB_BB.STANDARD, frRef)
|
|
local ptMax = b3Ref:getMax()
|
|
local ptMin = b3Ref:getMin()
|
|
ptMin:setZ( ptMax:getZ()) -- per avere curve sullo stesso piano ( e gestire correttamente le intersezioni)
|
|
|
|
-- verifico se necessario sovramateriale extra per raggiungere la sezione desiderata
|
|
local dExtraSection = max( 0, dRefSection - b3Ref:getDimY() - dOverMatIn - dOverMatOut)
|
|
|
|
-- lato bottom
|
|
local nLineBottom = EgtLinePVL( nGrp, ptMin - ( dOverMatIn + 0.5 * dExtraSection) * Y_AX(), X_AX(), 10000)
|
|
EgtExtendCurveStartByLen( nLineBottom, 10000)
|
|
EgtTransform( nLineBottom, frRef)
|
|
|
|
-- lato top
|
|
local nLineTop = EgtLinePVL( nGrp, ptMax + ( dOverMatOut + 0.5 * dExtraSection) * Y_AX(), - X_AX(), 10000)
|
|
EgtExtendCurveStartByLen( nLineTop, 10000)
|
|
EgtTransform( nLineTop, frRef)
|
|
|
|
-- lato right
|
|
local nLineRight
|
|
if i == 1 and not bCutExtremities then
|
|
nLineRight = EgtLinePVL( nGrp, ptMin, - Y_AX(), 10000)
|
|
EgtTransform( nLineRight, frRef)
|
|
else
|
|
nLineRight = EgtLine( nGrp, ptEOut, ptSIn)
|
|
EgtExtendCurveEndByLen( nLineRight, 10000)
|
|
end
|
|
EgtOffsetCurve( nLineRight, EgtIf( i == 1, dOverMatExt, dOverMatInt))
|
|
EgtExtendCurveStartByLen( nLineRight, 10000)
|
|
|
|
-- lato left
|
|
local nLineLeft
|
|
if i == #vCrvsIn and not bCutExtremities then
|
|
nLineLeft = EgtLinePVL( nGrp, ptMax, Y_AX(), 10000)
|
|
EgtTransform( nLineLeft, frRef)
|
|
else
|
|
nLineLeft = EgtLine( nGrp, ptEIn, ptSOut)
|
|
EgtExtendCurveEndByLen( nLineLeft, 10000)
|
|
end
|
|
EgtOffsetCurve( nLineLeft, EgtIf( i == #vCrvsIn, dOverMatExt, dOverMatInt))
|
|
EgtExtendCurveStartByLen( nLineLeft, 10000)
|
|
|
|
-- taglio le curve nei loro punti di intersezione
|
|
local vCrvs = { nLineTop, nLineRight, nLineBottom, nLineLeft}
|
|
vCrvs = TrimOrderedCurves( vCrvs, true)
|
|
|
|
-- TO DO : controllo lunghezza minima
|
|
-- local dLenTop = EgtCurveLength( nLineTop)
|
|
|
|
dLenTot = dLenTot + EgtCurveLength( nLineTop)
|
|
|
|
-- creo il tronchetto
|
|
local nLogCrv = EgtCurveCompo( nGrp, vCrvs)
|
|
EgtSetName( nLogCrv, WIN_LOGS)
|
|
EgtSetColor( nLogCrv, EgtStdColor( 'BLUE'))
|
|
|
|
-- salvo i sovramateriali utilizzati nella curva
|
|
EgtSetInfo( nLogCrv, WIN_PRC_OVERMAT_IN, dOverMatIn)
|
|
EgtSetInfo( nLogCrv, WIN_PRC_OVERMAT_OUT, dOverMatOut)
|
|
EgtSetInfo( nLogCrv, WIN_PRC_OVERMAT_LEFT, EgtIf( i == #vCrvsIn, dOverMatExt, dOverMatInt))
|
|
EgtSetInfo( nLogCrv, WIN_PRC_OVERMAT_RIGHT, EgtIf( i == 1, dOverMatExt, dOverMatInt))
|
|
|
|
EgtSetStatus( vCrvsIn[i], GDB_ST.OFF)
|
|
EgtSetStatus( nOut, GDB_ST.OFF)
|
|
EgtErase( nCompo)
|
|
end
|
|
|
|
-- salvo i dati della sezione ( analogamente a quanto fatto nel geo per pezzi lineari)
|
|
EgtSetInfo( nGrp, WIN_GEOWIDTH, dRefSection)
|
|
CopyInfo( nGrp, EgtGetParent( nGeoOut), WIN_GEOHEIGHT)
|
|
EgtSetInfo( nGrp, WIN_GEOLEN, dLenTot)
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che crea la spina per tronchetti
|
|
local function CalcLogDowel( nOrigPartId, nCrvOut, bLeftOrRight, nProcLayerId, nProfileId, nInfoGrp, nSolidId)
|
|
|
|
-- creo il frame per il posizionamento del dowel
|
|
local nOutlineRef = EgtGetInfo( nOrigPartId, WIN_REF_OUTLINE, 'i')
|
|
local ptRef = EgtIf( bLeftOrRight, EgtSP( nCrvOut), EgtEP( nCrvOut))
|
|
local _, ptOrig, dParOrig = EgtPointCurveDist( ptRef, nOutlineRef)
|
|
local vtFrame = EgtUV( nOutlineRef, dParOrig, -1)
|
|
local frDest = Frame3d( ptOrig, - vtFrame)
|
|
|
|
-- calcolo direzione verso interno del pezzo
|
|
local vtDir = frDest:getVersZ()
|
|
if bLeftOrRight then
|
|
vtDir = - vtDir
|
|
end
|
|
|
|
-- recupero i dati del dowel
|
|
local dDowelDiam = 5 -- EgtGetInfo( nInfoGrp, WIN_DWL_DIAM, 'd')
|
|
local dDowelLen = 10 -- EgtGetInfo( nInfoGrp, WIN_DWL_LOG_LEN, 'd')
|
|
|
|
-- creo il dowel nel riferimento della sezione
|
|
-- TO DO : recupero della sezione corretta nel caso di cambio profilo
|
|
local nSectionId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTION) or EgtGetFirstNameInGroup( nProfileId, WIN_SASH .. WIN_SECTION)
|
|
local nDowelId = EgtCircle( nProcLayerId, EgtGP( nSectionId), 0.5 * dDowelDiam)
|
|
|
|
-- posiziono il dowel usando i riferimenti
|
|
local nFrameId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME)
|
|
local frOrig = EgtFR( nFrameId)
|
|
frOrig:invert()
|
|
EgtTransform( nDowelId, frOrig)
|
|
EgtTransform( nDowelId, frDest)
|
|
|
|
local nPartId = EgtGetParent( nProcLayerId)
|
|
local dOverMat = EgtGetInfo( nPartId, EgtIf( bLeftOrRight, WIN_PRC_OVERMAT_LEFT, WIN_PRC_OVERMAT_RIGHT))
|
|
EgtMove( nDowelId, - vtDir * ( s_dDowelTol + dOverMat))
|
|
EgtModifyCurveExtrusion( nDowelId, - vtDir)
|
|
local dLen = dDowelLen + dOverMat + s_dDowelTol
|
|
EgtModifyCurveThickness( nDowelId, - dLen)
|
|
|
|
-- setto info di lavorazione
|
|
EgtSetInfo( nDowelId, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.HOLE)
|
|
EgtSetInfo( nDowelId, WIN_PRC_SIDE, EgtIf( bLeftOrRight, WIN_PRC_SIDETYPE.LEFT, WIN_PRC_SIDETYPE.RIGHT))
|
|
|
|
-- eventuale aggiornamento del solido
|
|
if nSolidId then
|
|
UpdateSolidWithProcessingCrv( nDowelId, nSolidId, nProcLayerId)
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che crea i pezzi dei tronchetti
|
|
local function CalcLogParts( nOrigPartId, bFinishedLogs)
|
|
|
|
local nProfileGrp = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_PROFILE)
|
|
-- local nInfoGrp = EgtGetFirstNameInGroup( nProfileGrp, WIN_INFO_GRP)
|
|
|
|
-- recupero i gruppi dal pezzo ad arco
|
|
local nProfileLayerId = EgtGetFirstNameInGroup( nOrigPartId, WIN_PROFILE)
|
|
local nProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN)
|
|
local nOrigSolidLayerId = EgtGetFirstNameInGroup( nOrigPartId, WIN_SOLID)
|
|
local nOrigProcLayerId = EgtGetFirstNameInGroup( nOrigPartId, WIN_PRC)
|
|
|
|
-- recupero dimensione del profilo
|
|
local nGeoLayerId = EgtGetFirstNameInGroup( nOrigPartId, WIN_GEO)
|
|
local dThick = EgtGetInfo( nGeoLayerId, WIN_GEOHEIGHT, 'd')
|
|
|
|
-- recupero i tronchetti
|
|
local nLogLayerId = EgtGetFirstNameInGroup( nOrigPartId, WIN_LOGS)
|
|
local vCrvIn = EgtGetNameInGroup( nLogLayerId, WIN_GEO_IN)
|
|
local vCrvOut = EgtGetNameInGroup( nLogLayerId, WIN_GEO_OUT)
|
|
local vLogs = {}
|
|
for i = 1, #vCrvIn do
|
|
-- creo il pezzo per il trochetto
|
|
local nPartId = EgtGroup( GDB_ID.ROOT)
|
|
EgtSetName( nPartId, WIN_LOGS)
|
|
EgtSetColor( nPartId, Color3d( 204, 102, 0))
|
|
EgtSetStatus( nPartId, GDB_ST.OFF)
|
|
table.insert( vLogs, nPartId)
|
|
|
|
local nCrvIn = vCrvIn[i]
|
|
local nCrvOut = vCrvOut[i]
|
|
local nLogCrv = EgtGetNext( nCrvOut)
|
|
|
|
-- setto le info con i sovramateriali corrispondenti
|
|
CopyInfo( nPartId, nLogCrv, WIN_PRC_OVERMAT_IN, 0)
|
|
CopyInfo( nPartId, nLogCrv, WIN_PRC_OVERMAT_OUT, 0)
|
|
CopyInfo( nPartId, nLogCrv, WIN_PRC_OVERMAT_LEFT, 0)
|
|
CopyInfo( nPartId, nLogCrv, WIN_PRC_OVERMAT_RIGHT, 0)
|
|
|
|
-- a) GEORAW
|
|
local nGeoRawLayerId = EgtGroup( nPartId)
|
|
EgtSetName( nGeoRawLayerId, WIN_GEO_RAW)
|
|
local nGeoRawCrvId = EgtCopyGlob( nLogCrv, nGeoRawLayerId)
|
|
EgtModifyCurveThickness( nGeoRawCrvId, - dThick)
|
|
-- creo il frame ausiliario
|
|
local vtX = EgtSV( nLogCrv)
|
|
local frGeo = Frame3d( EgtSP( nLogCrv), vtX, Z_AX() ^ vtX, Z_AX())
|
|
local nFrameId = EgtFrame( nGeoRawLayerId, frGeo)
|
|
EgtSetName( nFrameId, WIN_PRC_FRAME)
|
|
|
|
-- b) SOLIDO
|
|
local nSolidId
|
|
if s_bCalcSolid then
|
|
local nSolidLayerId = EgtGroup( nPartId)
|
|
EgtSetName( nSolidLayerId, WIN_SOLID)
|
|
if #vCrvIn == 1 then
|
|
-- essendo singolo pezzo il solido è quello originale
|
|
local nOrigSolidId = EgtGetFirstNameInGroup( nOrigSolidLayerId, WIN_SRF_MAIN)
|
|
EgtCopyGlob( nOrigSolidId, nSolidLayerId)
|
|
elseif bFinishedLogs then
|
|
-- recupero il solido originale e lo taglio opportunamente agli estremi
|
|
local nOrigSolidId = EgtGetFirstNameInGroup( nOrigSolidLayerId, WIN_SRF_MAIN)
|
|
nSolidId = EgtCopyGlob( nOrigSolidId, nSolidLayerId)
|
|
|
|
local bBox = GetProfileLocalBox( nProfileId)
|
|
local dDimY = bBox:getDimY()
|
|
if i ~= 1 then
|
|
local nTrimCrv = EgtLine( nSolidLayerId, EgtUP( nLogCrv, 2), EgtUP( nLogCrv, 1))
|
|
EgtMove( nTrimCrv, Z_AX())
|
|
local nTrimSrf = EgtSurfTmByExtrusion( nSolidLayerId, nTrimCrv, - Z_AX() * ( dDimY + 2), WIN_SURF_APPROX)
|
|
EgtSurfTmIntersect( nSolidId, nTrimSrf)
|
|
EgtErase( { nTrimCrv, nTrimSrf})
|
|
end
|
|
if i ~= #vCrvIn then
|
|
local nTrimCrv = EgtLine( nSolidLayerId, EgtSP( nLogCrv), EgtUP( nLogCrv, 3))
|
|
EgtMove( nTrimCrv, Z_AX())
|
|
local nTrimSrf = EgtSurfTmByExtrusion( nSolidLayerId, nTrimCrv, - Z_AX() * ( dDimY + 2), WIN_SURF_APPROX)
|
|
EgtSurfTmIntersect( nSolidId, nTrimSrf)
|
|
EgtErase( { nTrimCrv, nTrimSrf})
|
|
end
|
|
else
|
|
-- il solido è esattamente il tronchetto
|
|
local bBox = GetProfileLocalBox( nProfileId)
|
|
nSolidId = EgtSurfTmByRegionExtrusion( nSolidLayerId, nLogCrv, - bBox:getDimY() * Z_AX())
|
|
EgtSetName( nSolidId, WIN_SOLID)
|
|
end
|
|
end
|
|
|
|
-- c) LAVORAZIONI
|
|
-- se unico tronchetto le lavorazioni sono quelle del pezzo originale
|
|
if #vCrvIn == 1 then
|
|
EgtRelocateGlob( nOrigProcLayerId, nPartId)
|
|
EgtSetStatus( nOrigProcLayerId, GDB_ST.ON)
|
|
return
|
|
end
|
|
|
|
local nProcLayerId = EgtGroup( nPartId)
|
|
EgtSetName( nProcLayerId, WIN_PRC)
|
|
|
|
-- profili in e out
|
|
if bFinishedLogs then
|
|
local nCrvInCopy = EgtCopyGlob( nCrvIn, nProcLayerId)
|
|
local nSemiProfileInId = EgtGetInfo( nCrvInCopy, WIN_SEMI_PROFILE, 'i')
|
|
GetProcessingInfoFromSemiProfile( nCrvInCopy, nSemiProfileInId)
|
|
EgtSetStatus( nCrvInCopy, GDB_ST.ON)
|
|
local nCrvOutCopy = EgtCopyGlob( nCrvOut, nProcLayerId)
|
|
local nSemiProfileOutId = EgtGetInfo( nCrvOutCopy, WIN_SEMI_PROFILE, 'i')
|
|
GetProcessingInfoFromSemiProfile( nCrvOutCopy, nSemiProfileOutId)
|
|
EgtSetStatus( nCrvOutCopy, GDB_ST.ON)
|
|
end
|
|
|
|
-- profilo left
|
|
if i == #vCrvIn and bFinishedLogs then
|
|
-- recupero la curva di lavorazione dal pezzo originale
|
|
local nLeftPrc = EgtGetFirstNameInGroup( nOrigProcLayerId, WIN_GEO_LEFT)
|
|
EgtRelocateGlob( nLeftPrc, nProcLayerId)
|
|
elseif i ~= #vCrvIn then
|
|
-- minizinken
|
|
local nLeftId = EgtLine( nProcLayerId, EgtUP( nLogCrv, 3), EgtSP( nLogCrv))
|
|
EgtSetName( nLeftId, WIN_LEFT)
|
|
-- assegno le info di lavorazione
|
|
-- EgtSetInfo( nLeftId, WIN_PRC_NTOOLS, 1)
|
|
-- local sToolName = EgtGetInfo( nInfoGrp, WIN_PRC_TOOL_NAME)
|
|
-- EgtSetInfo( nLeftId, WIN_PRC_TOOL_NAME .. '_1', sToolName)
|
|
-- local dOffR = EgtGetInfo( nInfoGrp, WIN_PRC_OFFR, 'd')
|
|
-- -- TO DO : verificare valore OffsR
|
|
-- EgtSetInfo( nLeftId, WIN_PRC_OFFR .. '_1', dOffR)
|
|
-- local dOffL = EgtGetInfo( nInfoGrp, WIN_PRC_OFFL .. '_1', 'd')
|
|
-- EgtSetInfo( nLeftId, WIN_PRC_OFFL .. '_1', dOffL)
|
|
end
|
|
|
|
-- profilo right
|
|
if i == 1 and bFinishedLogs then
|
|
-- recupero la curva di lavorazione dal pezzo originale
|
|
local nRightPrc = EgtGetFirstNameInGroup( nOrigProcLayerId, WIN_GEO_RIGHT)
|
|
EgtRelocateGlob( nRightPrc, nProcLayerId)
|
|
elseif i ~= 1 then
|
|
-- minizinken
|
|
local nRightId = EgtLine( nProcLayerId, EgtUP( nLogCrv, 1), EgtUP( nLogCrv, 2))
|
|
EgtSetName( nRightId, WIN_RIGHT)
|
|
-- assegno info di lavorazione
|
|
-- EgtSetInfo( nRightId, WIN_PRC_NTOOLS, 1)
|
|
-- local sToolName = EgtGetInfo( nInfoGrp, WIN_PRC_TOOL_NAME)
|
|
-- EgtSetInfo( nRightId, WIN_PRC_TOOL_NAME .. '_1', sToolName)
|
|
-- local dOffR = EgtGetInfo( nInfoGrp, WIN_PRC_OFFR, 'd')
|
|
-- -- TO DO : verificare valore OffsR
|
|
-- EgtSetInfo( nRightId, WIN_PRC_OFFR .. '_1', dOffR)
|
|
-- local dOffL = EgtGetInfo( nInfoGrp, WIN_PRC_OFFL .. '_2', 'd')
|
|
-- EgtSetInfo( nRightId, WIN_PRC_OFFL .. '_1', dOffL)
|
|
end
|
|
|
|
-- dowels per incastro dei tronchetti
|
|
if i ~= 1 then
|
|
CalcLogDowel( nOrigPartId, nCrvOut, false, nProcLayerId, nProfileId, nInfoGrp, nSolidId)
|
|
end
|
|
if i ~= #vCrvIn then
|
|
CalcLogDowel( nOrigPartId, nCrvOut, true, nProcLayerId, nProfileId, nInfoGrp, nSolidId)
|
|
end
|
|
|
|
-- se i tronchetti sono gestiti come pezzi finiti cerco le lavorazioni del pezzo orginale che appartengono al tronchetto
|
|
if bFinishedLogs then
|
|
local vProcessings = EgtGetAllInGroup( nOrigProcLayerId)
|
|
local nSurfTest = EgtSurfFlatRegion( nProcLayerId, nLogCrv)
|
|
for i = 1, #vProcessings do
|
|
local sPrcType = EgtGetInfo( vProcessings[i], WIN_PRC_FEATURE_TYPE)
|
|
-- forature
|
|
if sPrcType == WIN_PRC_TYPE.HOLE then
|
|
local sSide = EgtGetInfo( vProcessings[i], WIN_PRC_SIDE)
|
|
-- se dowel sull'estremo lo assegno direttamente al tronchetto corrispondente
|
|
if ( sSide == WIN_PRC_SIDETYPE.LEFT and i == #vCrvIn) or ( sSide == WIN_PRC_SIDETYPE.RIGHT and i == 1) then
|
|
EgtRelocateGlob( vProcessings[i], nProcLayerId)
|
|
end
|
|
-- altrimenti verifico se interno al tronchetto corrente
|
|
if sSide == WIN_PRC_SIDETYPE.IN then
|
|
local _, _, nSide = EgtPointCurveDistSide( EgtCP( vProcessings[i]), nLogCrv, Z_AX())
|
|
if nSide == -1 then
|
|
-- copio perchè la stessa lavorazione potrebbe coinvolgere più tronchetti
|
|
EgtCopyGlob( vProcessings[i], nProcLayerId)
|
|
else
|
|
-- verifico anche la faccia di fondo
|
|
local vtExtr = EgtCurveExtrusion( vProcessings[i])
|
|
local dThickness = EgtCurveThickness( vProcessings[i])
|
|
_, _, nSide = EgtPointCurveDistSide( EgtCP( vProcessings[i]) + dThickness * vtExtr, nLogCrv, Z_AX())
|
|
if nSide == -1 then
|
|
EgtCopyGlob( vProcessings[i], nProcLayerId)
|
|
end
|
|
end
|
|
end
|
|
-- fermavetro
|
|
elseif sPrcType == WIN_PRC_TYPE.STRIP_CUT then
|
|
-- TO DO da sistemare
|
|
local nStrip = EgtCopyGlob( vProcessings[i], nProcLayerId)
|
|
EgtTrimCurveWithRegion( nStrip, nSurfTest, true, false)
|
|
else
|
|
-- TO DO lavorazioni legate alla ferramenta, cambio profilo
|
|
end
|
|
end
|
|
EgtErase( nSurfTest)
|
|
end
|
|
end
|
|
|
|
-- salvo nel pezzo ad arco i pezzi dei tronchetti associati
|
|
EgtSetInfo( nOrigPartId, WIN_LOGS, vLogs)
|
|
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che crea gli elementi ausiliari per la creazione del grezzo nell'automatismo delle lavorazioni
|
|
local function CalcGeoRawFromLogs( nPartId)
|
|
|
|
-- creo il GeoRaw per il pezzo ad arco
|
|
local nGeoRawLayerId = EgtGroup( nPartId)
|
|
EgtSetName( nGeoRawLayerId, WIN_GEO_RAW)
|
|
EgtSetStatus( nGeoRawLayerId, GDB_ST.OFF)
|
|
|
|
-- recupero i vari tronchetti
|
|
local nLogGrp = EgtGetFirstNameInGroup( nPartId, WIN_LOGS)
|
|
local vLogCrvs = EgtGetNameInGroup( nLogGrp, WIN_LOGS)
|
|
|
|
-- salvo le info di sovramateriale nel pezzo
|
|
CopyInfo( nPartId, vLogCrvs[1], WIN_PRC_OVERMAT_IN, 0)
|
|
CopyInfo( nPartId, vLogCrvs[1], WIN_PRC_OVERMAT_OUT, 0)
|
|
local nOvermatLateral = EgtGetInfo( vLogCrvs[1], WIN_PRC_OVERMAT_RIGHT, 'd')
|
|
EgtSetInfo( nPartId, WIN_PRC_OVERMAT_RIGHT, nOvermatLateral)
|
|
EgtSetInfo( nPartId, WIN_PRC_OVERMAT_LEFT, nOvermatLateral)
|
|
|
|
-- costruisco il grezzo a partire dai tronchetti
|
|
local vCrvs = {}
|
|
local vIdIn = {}
|
|
-- recupero le curve in e out dei tronchetti
|
|
for i = #vLogCrvs, 1, -1 do
|
|
local nLineOut = EgtLine( nGeoRawLayerId, EgtUP( vLogCrvs[i], 0), EgtUP( vLogCrvs[i], 1))
|
|
local nLineIn = EgtLine( nGeoRawLayerId, EgtUP( vLogCrvs[i], 2), EgtUP( vLogCrvs[i], 3))
|
|
table.insert( vCrvs, nLineOut)
|
|
table.insert( vIdIn, nLineIn)
|
|
end
|
|
local nLineR = EgtLine( nGeoRawLayerId, EgtEP( vCrvs[#vCrvs]), EgtSP( vIdIn[#vIdIn]))
|
|
table.insert( vCrvs, nLineR)
|
|
for i = #vIdIn, 1, -1 do
|
|
table.insert( vCrvs, vIdIn[i])
|
|
end
|
|
local nLineL = EgtLine( nGeoRawLayerId, EgtEP( vIdIn[1]), EgtSP( vCrvs[1]))
|
|
table.insert( vCrvs, nLineL)
|
|
|
|
-- taglio le curve nelle intersezioni ( va eliminato il sovramateriale per minizinken)
|
|
local nPrevId = vCrvs[#vCrvs]
|
|
local vPtInters = {}
|
|
for i = 1, #vCrvs do
|
|
vPtInters[i] = FindIntersectionPoint( nPrevId, vCrvs[i], EgtSP( vCrvs[i]))
|
|
nPrevId = vCrvs[i]
|
|
end
|
|
vPtInters[#vPtInters + 1] = vPtInters[1]
|
|
for i = 1, #vCrvs do
|
|
EgtExtendCurveStartByLen( vCrvs[i], 100)
|
|
EgtExtendCurveEndByLen( vCrvs[i], 100)
|
|
local dParS = EgtCurveParamAtPoint( vCrvs[i], vPtInters[i])
|
|
local dParE = EgtCurveParamAtPoint( vCrvs[i], vPtInters[i+1])
|
|
EgtTrimCurveStartEndAtParam( vCrvs[i], dParS, dParE)
|
|
end
|
|
|
|
-- costruisco la compo del grezzo
|
|
local nCompo = EgtCurveCompo( nGeoRawLayerId, vCrvs)
|
|
local nGeoLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO)
|
|
local dDimH = EgtGetInfo( nGeoLayerId, WIN_GEOHEIGHT, 'd')
|
|
EgtModifyCurveThickness( nCompo, - dDimH)
|
|
|
|
-- creo il frame ausiliario
|
|
local vtX = EgtSV( nCompo)
|
|
local frGeo = Frame3d( EgtSP( nCompo), vtX, Z_AX() ^ vtX, Z_AX())
|
|
local nFrameId = EgtFrame( nGeoRawLayerId, frGeo)
|
|
EgtSetName( nFrameId, WIN_PRC_FRAME)
|
|
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che calcola i tronchetti di un pezzo ad arco
|
|
function WinCalculate.CreateArcLogs( nPartId, nLogsNbr, vSections, bAlign, dOverMatOut, dOverMatIn, dOverMatExt, dOverMatInt, bCutExtremities)
|
|
|
|
-- verifico dati in ingresso
|
|
if bAlign then nLogsNbr = 0 end
|
|
if not bAlign and nLogsNbr == 0 and ( #vSections == 0 or #vSections > 1) then
|
|
return
|
|
end
|
|
|
|
-- recupero o creo il gruppo per i tronchetti
|
|
local nGrp = EgtGetFirstNameInGroup( nPartId, WIN_LOGS)
|
|
if not nGrp then
|
|
nGrp = EgtGroup( nPartId)
|
|
EgtSetName( nGrp, WIN_LOGS)
|
|
else
|
|
EgtEmptyGroup( nGrp)
|
|
end
|
|
|
|
-- recupero il geo del pezzo
|
|
local nGeoLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO)
|
|
local nGeoIn = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_IN)
|
|
local nGeoOut = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_OUT)
|
|
|
|
-- spezzo l'arco interno
|
|
SplitArc( nLogsNbr, vSections, bAlign, dOverMatOut + dOverMatIn, nGeoIn, nGeoOut, nGrp)
|
|
|
|
-- calcolo la sezione di riferimento per i tronchetti
|
|
local dSection = CalcLogsSection( nLogsNbr, vSections, bAlign, dOverMatOut + dOverMatIn, nGeoIn, nGeoOut, nGrp)
|
|
if not dSection then
|
|
return
|
|
end
|
|
|
|
-- creo i tronchetti
|
|
CalcLogs( nGrp, nGeoOut, dOverMatIn, dOverMatOut, dOverMatExt, dOverMatInt, dSection, bCutExtremities)
|
|
|
|
-- TODO : recupero modalità di lavorazione dei tronchetti
|
|
local bFinishedLogs = false
|
|
|
|
-- creo i pezzi associati ai tronchetti
|
|
local vLogs = EgtGetInfo( nPartId, WIN_LOGS, 'vi') or {}
|
|
EgtErase( vLogs)
|
|
CalcLogParts( nPartId, bFinishedLogs)
|
|
if not bFinishedLogs then
|
|
-- sistemo il Georaw per il pezzo ad arco
|
|
CalcGeoRawFromLogs( nPartId)
|
|
else
|
|
-- TODO segnalare che il pezzo non va lavorato
|
|
end
|
|
end
|
|
|
|
|
|
|
|
----------------------------------------------------------------------------------
|
|
---------------------------------- FERRAMENTA ----------------------------------
|
|
----------------------------------------------------------------------------------
|
|
-- funzione che disegna le cerniere
|
|
local function DrawHingesStd( nOutlineId, nSolidLayerId)
|
|
|
|
-- dimensioni cerniere
|
|
local dDimH = 16
|
|
local dDimV = 70
|
|
local dFilletRad = 5
|
|
|
|
local nFrameOutlineId = abs( EgtGetInfo( nOutlineId, WIN_SOU_OUTLINE, 'i'))
|
|
local dDelta = ( EgtSP( nOutlineId) - EgtSP( nFrameOutlineId)) * Z_AX()
|
|
if dDelta < GEO.EPS_SMALL then
|
|
return
|
|
end
|
|
local vtDir = EgtSV( nOutlineId)
|
|
local vtDirIn = Vector3d( vtDir)
|
|
vtDirIn:rotate( Z_AX(), -90)
|
|
|
|
-- prima cerniera
|
|
local pt1 = EgtSP( nOutlineId) - dDelta * Z_AX()
|
|
local nCompo = EgtCurveCompoFromPoints( nSolidLayerId, { pt1 + dFilletRad * vtDir, pt1 + ( dDimV - dFilletRad) * vtDir})
|
|
EgtAddCurveCompoArcTg( nCompo, pt1 + dDimV * vtDir + dFilletRad * vtDirIn)
|
|
EgtAddCurveCompoLine( nCompo, pt1 + dDimV * vtDir + ( dDimH - dFilletRad) * vtDirIn)
|
|
EgtAddCurveCompoArcTg( nCompo, pt1 + ( dDimV - dFilletRad) * vtDir + dDimH * vtDirIn)
|
|
EgtAddCurveCompoLine( nCompo, pt1 + dFilletRad * vtDir + dDimH * vtDirIn)
|
|
EgtAddCurveCompoArcTg( nCompo, pt1 + ( dDimH - dFilletRad) * vtDirIn)
|
|
EgtAddCurveCompoLine( nCompo, pt1 + dFilletRad * vtDirIn)
|
|
EgtAddCurveCompoArcTg( nCompo, EgtSP( nCompo))
|
|
local nStm1 = EgtSurfTmByRegionExtrusion( nSolidLayerId, nCompo, dDelta * Z_AX())
|
|
EgtSetColor( nStm1, Color3d( 128, 128, 128))
|
|
EgtSetName( nStm1, WIN_HDW_HINGES)
|
|
EgtErase( nCompo)
|
|
|
|
-- seconda cerniera
|
|
local pt2 = EgtEP( nOutlineId) - dDelta * Z_AX() - dDimV * vtDir
|
|
local nStm2 = EgtCopyGlob( nStm1, nSolidLayerId)
|
|
EgtMove( nStm2, pt2 - pt1)
|
|
|
|
-- correzioni per telai non rettangolari
|
|
local nFrameAreaId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_AREA .. '*')
|
|
local nFrameType = EgtGetInfo( nFrameAreaId, WIN_FRAME_TYPE, 'i')
|
|
|
|
-- a) arco
|
|
if nFrameType == WIN_FRAME_TYPES.ROUND_ARC or nFrameType == WIN_FRAME_TYPES.SEGMENTAL_ARC then
|
|
local sName = EgtGetName( nOutlineId)
|
|
-- calcolo il delta da applicare ( euristico, calcolato in base ai risultati ferramenta)
|
|
local dDelta = 24 -- caso di arco a tutto sesto
|
|
local dDeltaSegArc = 54.7 -- caso di arco ribassato
|
|
if nFrameType == WIN_FRAME_TYPES.SEGMENTAL_ARC then
|
|
-- nel caso di arco ribassato il delta va calcolato rispetto al frame della ferramenta
|
|
local nAreaId = EgtGetParent( EgtGetParent( nOutlineId))
|
|
local nHdwFramesId = EgtGetFirstNameInGroup( nAreaId, WIN_HDW_FRAME)
|
|
local sFrameName = EgtIf( sName == WIN_LEFT, 'B*', 'C*')
|
|
local nFrameId = EgtGetFirstNameInGroup( nHdwFramesId, sFrameName)
|
|
if sName == WIN_LEFT then
|
|
dDelta = ( EgtSP( nFrameId) - EgtSP( nOutlineId)) * vtDir
|
|
else
|
|
dDelta = ( EgtEP( nOutlineId) - EgtSP( nFrameId)) * vtDir
|
|
end
|
|
dDelta = dDelta + dDeltaSegArc
|
|
end
|
|
|
|
-- traslazione
|
|
if sName == WIN_LEFT then
|
|
EgtMove( nStm1, dDelta * vtDir)
|
|
else
|
|
EgtMove( nStm2, - dDelta * vtDir)
|
|
end
|
|
|
|
-- b) trapezio
|
|
elseif nFrameType == WIN_FRAME_TYPES.CHAMFER_SIDE then
|
|
-- calcolo il delta da applicare. Euristico. Dal calcolo della ferramenta si vede che la cerniera si trova circa nel punto di intersezione tra nOutlineId e una retta inclinata
|
|
-- come il top e passante per il frame della ferramenta
|
|
local sName = EgtGetName( nOutlineId)
|
|
local nOutlineLayId = EgtGetParent( nOutlineId)
|
|
local nAreaId = EgtGetParent( nOutlineLayId)
|
|
local nHdwFramesId = EgtGetFirstNameInGroup( nAreaId, WIN_HDW_FRAME)
|
|
local sFrameName = EgtIf( sName == WIN_LEFT, 'B*', 'C*')
|
|
local nFrameId = EgtGetFirstNameInGroup( nHdwFramesId , sFrameName)
|
|
local nTopId = EgtGetFirstNameInGroup( nOutlineLayId, WIN_TOP)
|
|
local vtTop = EgtSV( nTopId)
|
|
local ptRef = EgtIf( sName == WIN_LEFT, EgtSP( nOutlineId), EgtEP( nOutlineId))
|
|
local vtDist = EgtSP( nFrameId) - ptRef
|
|
local dDelta = ( vtDist ^ vtTop):len() / ( vtTop ^ vtDir):len()
|
|
|
|
if sName == WIN_LEFT then
|
|
EgtMove( nStm1, dDelta * vtDir)
|
|
else
|
|
EgtMove( nStm2, - dDelta * vtDir)
|
|
end
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che disegna le cerniere per la preview ( posizionamento più grossolano e disegno 2d)
|
|
local function DrawHingesPreview( nOutlineId, nLayerId)
|
|
|
|
-- dimensioni cerniere
|
|
local dDimL = 80
|
|
local dDimW = 20
|
|
|
|
local nFrameOutlineId = abs( EgtGetInfo( nOutlineId, WIN_SOU_OUTLINE, 'i'))
|
|
local dDelta = ( EgtSP( nOutlineId) - EgtSP( nFrameOutlineId)) * Z_AX()
|
|
if dDelta < GEO.EPS_SMALL then
|
|
return
|
|
end
|
|
|
|
local vtDir = EgtSV( nOutlineId)
|
|
local vtDirIn = Vector3d( vtDir)
|
|
vtDirIn:rotate( Z_AX(), -90)
|
|
-- alzo leggermente la quota in z per evitare sovrapposizioni problematiche nell'eportazione svg
|
|
local frHinge = Frame3d( EgtSP( nOutlineId) + Z_AX(), vtDir, vtDirIn, - Z_AX())
|
|
|
|
-- prima cerniera
|
|
local nSfr1 = EgtSurfFrStadium( nLayerId, ORIG(), Point3d( dDimL, dDimW, 0))
|
|
EgtSetColor( nSfr1, Color3d( 128, 128, 128))
|
|
EgtTransform( nSfr1, frHinge)
|
|
EgtInvertSurf( nSfr1)
|
|
|
|
-- seconda cerniera
|
|
local pt2 = EgtEP( nOutlineId) - dDimL * vtDir
|
|
local nSfr2 = EgtCopyGlob( nSfr1, nLayerId)
|
|
EgtMove( nSfr2, pt2 - EgtSP( nOutlineId))
|
|
|
|
-- contorni
|
|
local nLoop1 = EgtExtractSurfFrChunkLoops( nSfr1, 0, nLayerId)
|
|
EgtSetColor( nLoop1, EgtStdColor( 'BLACK'))
|
|
local nLoop2 = EgtExtractSurfFrChunkLoops( nSfr2, 0, nLayerId)
|
|
EgtSetColor( nLoop2, EgtStdColor( 'BLACK'))
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function DrawHinges( nOutlineId, nLayerId, bPreview)
|
|
if bPreview then
|
|
DrawHingesPreview( nOutlineId, nLayerId)
|
|
else
|
|
DrawHingesStd( nOutlineId, nLayerId)
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che disegna la maniglia
|
|
local function DrawHandleStd( nOutlineId, sHandleSide, dHandleH, nSolidLayerId, bSlide)
|
|
|
|
-- dati della maniglia
|
|
local dBase1T = 40
|
|
local dBase1B = 40
|
|
local dBase2 = 18
|
|
local dH = 9
|
|
local dLen1 = 53
|
|
local dLen2 = 115
|
|
local dRadH = 12.5
|
|
local dFillet = 10
|
|
local dExtraGapDelta = 15
|
|
if bSlide then
|
|
dBase1T = 50
|
|
dBase1B = 100
|
|
dBase2 = 18
|
|
dLen2 = 155
|
|
dRadH = 10
|
|
dExtraGapDelta = 35.5
|
|
end
|
|
|
|
local nPartId = EgtGetInfo( nOutlineId, WIN_REF_PART, 'i')
|
|
local ptRef = EgtIf( sHandleSide == 'Sx', EgtSP( nOutlineId), EgtEP( nOutlineId))
|
|
local vtDir = EgtIf( sHandleSide == 'Sx', EgtSV( nOutlineId), - EgtEV( nOutlineId))
|
|
local vtDirIn = Vector3d( vtDir)
|
|
vtDirIn:rotate( Z_AX(), EgtIf( sHandleSide == 'Sx', 90, -90))
|
|
|
|
-- recupero il riferimento rispetto a cui leggere l'altezza maniglia
|
|
local nProfileLayId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE)
|
|
local nProfileId = EgtGetFirstNameInGroup( nProfileLayId, EgtIf( sHandleSide == 'Sx', WIN_PRF_START, WIN_PRF_END))
|
|
local dGapHardware = EgtGetInfo( nProfileId, WIN_GAPDELTA, 'd')
|
|
-- recupero di quanto spostare la maniglia rispetto all'outline
|
|
local nMainProfileId = EgtGetFirstNameInGroup( nProfileLayId, WIN_PRF_MAIN)
|
|
local dGapDelta = EgtGetInfo( nMainProfileId, WIN_GAPDELTA, 'd')
|
|
local dDeltaIn = dGapDelta + dExtraGapDelta
|
|
|
|
-- punto su cui centrare la maniglia
|
|
local ptC = ptRef + ( dHandleH + dGapHardware) * vtDir + dDeltaIn * vtDirIn
|
|
|
|
local nCrv1 = EgtRectangle2P( nSolidLayerId, ptC - dBase1B * vtDir - dBase2 * vtDirIn, ptC + dBase1T * vtDir + dBase2 * vtDirIn)
|
|
local nStm1 = EgtSurfTmByRegionExtrusion( nSolidLayerId, {nCrv1}, dH * Z_AX())
|
|
|
|
local nCrv2 = EgtLinePVL( nSolidLayerId, ORIG(), X_AX(), dLen1 - dFillet)
|
|
local nCrv4 = EgtLinePVL( nSolidLayerId, Point3d( dLen1, -dFillet, 0), - Y_AX(), dLen2 - dFillet)
|
|
local nCrv3 = EgtArc2PR( nSolidLayerId, EgtEP( nCrv2), EgtSP( nCrv4), dFillet, false)
|
|
local nGuide = EgtCurveCompo( nSolidLayerId, { nCrv2, nCrv3, nCrv4})
|
|
local frTransf = Frame3d( ptC, Z_AX(), vtDir, Z_AX() ^ vtDir)
|
|
EgtTransform( nGuide, frTransf)
|
|
local nSection = EgtCircle( nSolidLayerId, EgtSP( nGuide), dRadH)
|
|
local nStm2 = EgtSurfTmSwept( nSolidLayerId, nSection, nGuide, true)
|
|
|
|
EgtSurfTmAdd( nStm1, nStm2)
|
|
EgtSetName( nStm1, WIN_HDW_HANDLE)
|
|
EgtSetColor( nStm1, Color3d( 128, 128, 128))
|
|
EgtErase( { nCrv1, nGuide, nSection, nStm2})
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- disegno della maniglia per preview
|
|
local function DrawHandlePreview( nOutlineId, sHandleSide, dHandleH, nLayerId, bSlide)
|
|
|
|
-- dati della maniglia
|
|
local dRad = 20
|
|
local dDimW = 20
|
|
local dDimH = 100
|
|
|
|
local ptRef = EgtIf( sHandleSide == 'Sx', EgtSP( nOutlineId), EgtEP( nOutlineId))
|
|
local vtDir = EgtIf( sHandleSide == 'Sx', - EgtSV( nOutlineId), EgtEV( nOutlineId))
|
|
local vtDirIn = Vector3d( vtDir)
|
|
vtDirIn:rotate( Z_AX(), EgtIf( sHandleSide == 'Sx', -90, 90))
|
|
|
|
-- recupero dati del profilo per centrare la maniglia sul pezzo
|
|
local nPartId = EgtGetInfo( nOutlineId, WIN_REF_PART, 'i')
|
|
local nProfileLayId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE)
|
|
local nMainProfileId = EgtGetFirstNameInGroup( nProfileLayId, WIN_PRF_MAIN)
|
|
local b3Profile = GetProfileLocalBox( nMainProfileId)
|
|
local dSide = abs( b3Profile:getMin():getX() + 0.5 * b3Profile:getDimX())
|
|
-- correzione per caso speciale di telaio e ante allineate ( euristica)
|
|
local nParentAreaId = EgtGetParent( EgtGetParent( nOutlineId))
|
|
local nSashType = EgtGetInfo( nParentAreaId, WIN_SASHTYPE, 'i') or WIN_SASHTYPES.NULL
|
|
if nSashType == WIN_SASHTYPES.NULL then
|
|
local nFrameOutlineId = abs( EgtGetInfo( nOutlineId, WIN_SOU_OUTLINE, 'i'))
|
|
local dDelta = ( EgtSP( nOutlineId) - EgtSP( nFrameOutlineId)) * Z_AX()
|
|
if dDelta < GEO.EPS_SMALL then
|
|
dSide = dSide + 9
|
|
end
|
|
end
|
|
|
|
-- punto su cui centrare la maniglia
|
|
local ptC = ptRef - dHandleH * vtDir + dSide * vtDirIn + Z_AX()
|
|
|
|
local nSfr1 = EgtSurfFrDisk( nLayerId, ptC, dRad)
|
|
EgtSetColor( nSfr1, Color3d( 128, 128, 128))
|
|
local nLoop = EgtExtractSurfFrChunkLoops( nSfr1, 0, nLayerId)
|
|
EgtSetColor( nLoop, EgtStdColor( 'BLACK'))
|
|
local nSfr2 = EgtSurfFrStadium( nLayerId, ORIG(), Point3d( dDimH, dDimW, 0))
|
|
local ptFrame = ptC + EgtIf( sHandleSide == 'Sx', 1, -1) * 0.5 * dDimW * vtDirIn + Z_AX()
|
|
local frHandle = Frame3d( ptFrame, vtDir, EgtIf( sHandleSide == 'Sx', - vtDirIn, vtDirIn), Z_AX())
|
|
EgtTransform( nSfr2, frHandle)
|
|
EgtSetColor( nSfr2, Color3d( 128, 128, 128))
|
|
local nLoop2 = EgtExtractSurfFrChunkLoops( nSfr2, 0, nLayerId)
|
|
EgtSetColor( nLoop2, EgtStdColor( 'BLACK'))
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function DrawHandle( nOutlineId, sHandleSide, dHandleH, nLayerId, bSlide, bPreview)
|
|
if bPreview then
|
|
DrawHandlePreview( nOutlineId, sHandleSide, dHandleH, nLayerId, bSlide)
|
|
else
|
|
DrawHandleStd( nOutlineId, sHandleSide, dHandleH, nLayerId, bSlide)
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function GetHandleHeight( nAreaId)
|
|
|
|
-- verifico se è definita tra le opzioni
|
|
local vOptions = EgtGetInfo( nAreaId, WIN_HDW_OPTIONS, 'vs') or {}
|
|
for i = 1, #vOptions do
|
|
local vString = EgtSplitString( vOptions[i], '=')
|
|
if #vString == 2 and vString[1] == WIN_HDW_HANDLE_HEIGHT then
|
|
local dVal = tonumber( vString[2])
|
|
if dVal then
|
|
return dVal
|
|
else
|
|
break
|
|
end
|
|
end
|
|
end
|
|
|
|
-- chiedo il file di opzioni dalla ferramenta
|
|
local _, _, tOptions = WinCalculate.AddHardware( nAreaId, false, false, false, true)
|
|
if #tOptions > 0 then
|
|
-- lettura della stringa xml delle opzioni
|
|
local handler = XMLHandler:new()
|
|
local parser = XML.parser( handler)
|
|
parser:parse( tOptions[1])
|
|
local tabOptions = handler.root
|
|
-- cerco parametro altezza maniglia
|
|
for i = 1, #tabOptions['ParametriOpzioni']['Parametri'] do
|
|
if tabOptions['ParametriOpzioni']['Parametri'][i]['NomeParametro'] == WIN_HDW_HANDLE_HEIGHT then
|
|
local sHandleH = tabOptions['ParametriOpzioni']['Parametri'][i]['ValoreCorrente']
|
|
return tonumber( sHandleH)
|
|
end
|
|
end
|
|
end
|
|
|
|
return 500 -- restituisco valore di default
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che disegna la ferramenta
|
|
local function DrawSashHardware( nAreaId, nRefAreaId, nLayerId, bPreview)
|
|
|
|
local nOutlineLayId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE)
|
|
local nOpeningType = EgtGetInfo( nAreaId, WIN_OPENING_TYPE, 'i')
|
|
|
|
if nOpeningType == WIN_OPENING_TYPES.NULL or nOpeningType == WIN_OPENING_TYPES.FIXED then
|
|
return
|
|
|
|
-- Vasistas
|
|
elseif nOpeningType == WIN_OPENING_TYPES.TILTONLY_TOP then
|
|
-- cerniere sul pezzo inferiore
|
|
local nBottomId = EgtGetFirstNameInGroup( nOutlineLayId, WIN_BOTTOM)
|
|
DrawHinges( nBottomId, nLayerId, bPreview)
|
|
|
|
-- recupero lato maniglia
|
|
local vOptions = EgtGetInfo( nRefAreaId, WIN_HDW_OPTIONS, 'vs') or {}
|
|
local sOptionHandleSide
|
|
for i = 1, #vOptions do
|
|
local vString = EgtSplitString( vOptions[i], '=')
|
|
if vString[1] == 'PosizioneManiglia' then
|
|
sOptionHandleSide = vString[2]
|
|
break
|
|
end
|
|
end
|
|
-- se non ho trovato l'opzione la recupero dalle opzioni di default ( simile a GetHandleHeigt)
|
|
if not sOptionHandleSide then
|
|
local _, _, tOptions = WinCalculate.AddHardware( nAreaId, false, false, false, true)
|
|
if #tOptions > 0 then
|
|
-- lettura della stringa xml delle opzioni
|
|
local handler = XMLHandler:new()
|
|
local parser = XML.parser( handler)
|
|
parser:parse( tOptions[1])
|
|
local tabOptions = handler.root
|
|
-- cerco parametro altezza maniglia
|
|
for i = 1, #tabOptions['ParametriOpzioni']['Parametri'] do
|
|
if tabOptions['ParametriOpzioni']['Parametri'][i]['NomeParametro'] == 'PosizioneManiglia' then
|
|
sOptionHandleSide = tabOptions['ParametriOpzioni']['Parametri'][i]['ValoreCorrente']
|
|
end
|
|
end
|
|
end
|
|
end
|
|
local sHandleSide = 'Sx'
|
|
local nOutlineId = EgtGetFirstNameInGroup( nOutlineLayId, WIN_RIGHT)
|
|
if sOptionHandleSide == 'destra' then
|
|
sHandleSide = 'Dx'
|
|
nOutlineId = EgtGetFirstNameInGroup( nOutlineLayId, WIN_LEFT)
|
|
elseif sOptionHandleSide == 'sopra' then
|
|
nOutlineId = EgtGetFirstNameInGroup( nOutlineLayId, WIN_TOP)
|
|
end
|
|
|
|
-- altezza maniglia è fissata a metà del lato ( con compensazione per frame di riferimento della ferramenta)
|
|
local nPartId = EgtGetInfo( nOutlineId, WIN_REF_PART, 'i')
|
|
local nProfileLayId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE)
|
|
local nProfileId = EgtGetFirstNameInGroup( nProfileLayId, EgtIf( sHandleSide == 'Sx', WIN_PRF_START, WIN_PRF_END))
|
|
local dGapHardware = EgtGetInfo( nProfileId, WIN_GAPDELTA, 'd')
|
|
local dHandleH = 0.5 * EgtCurveLength( nOutlineId) - dGapHardware
|
|
|
|
-- disegno maniglia
|
|
DrawHandle( nOutlineId, sHandleSide, dHandleH, nLayerId, false, bPreview)
|
|
|
|
-- Alzante scorrevole
|
|
elseif nOpeningType == WIN_OPENING_TYPES.COPLANARSLIDE_LEFT or nOpeningType == WIN_OPENING_TYPES.COPLANARSLIDE_RIGHT or
|
|
nOpeningType == WIN_OPENING_TYPES.LIFTSLIDE_LEFT or nOpeningType == WIN_OPENING_TYPES.LIFTSLIDE_RIGHT then
|
|
|
|
local bLeftSlide = ( nOpeningType == WIN_OPENING_TYPES.COPLANARSLIDE_LEFT or nOpeningType == WIN_OPENING_TYPES.LIFTSLIDE_LEFT)
|
|
local nOutlineId = EgtGetFirstNameInGroup( nOutlineLayId, EgtIf( bLeftSlide, WIN_RIGHT, WIN_LEFT))
|
|
local sHandleSide = EgtIf( bLeftSlide, 'Sx', 'Dx')
|
|
|
|
-- recupero altezza maniglia dalle opzioni
|
|
local dHandleH = GetHandleHeight( nRefAreaId)
|
|
|
|
DrawHandle( nOutlineId, sHandleSide, dHandleH, nLayerId, true, bPreview)
|
|
|
|
-- Standard
|
|
else
|
|
local nSashType = EgtGetInfo( nAreaId, WIN_SASHTYPE, 'i') or WIN_SASHTYPES.NULL
|
|
|
|
-- recupero pezzi interessati dalla ferramenta
|
|
local nLeftId = EgtGetFirstNameInGroup( nOutlineLayId, WIN_LEFT)
|
|
local nRightId = EgtGetFirstNameInGroup( nOutlineLayId, WIN_RIGHT)
|
|
|
|
-- recupero lato maniglia
|
|
local sHandleSide = EgtGetInfo( nRefAreaId, WIN_HDW_HANDLE)
|
|
|
|
-- cerniere
|
|
if nSashType == WIN_SASHTYPES.INACTIVE or nSashType == WIN_SASHTYPES.INACTIVE_OUT or
|
|
nSashType == WIN_SASHTYPES.ACTIVE or nSashType == WIN_SASHTYPES.ACTIVE_OUT then
|
|
-- le cerniere vanno messe sul lato che poggia sul telaio
|
|
local bLeftInactive = EgtGetInfo( nLeftId, WIN_CRV_ON_FRENCH_SPLIT, 'b') or false
|
|
DrawHinges( EgtIf( bLeftInactive, nRightId, nLeftId), nLayerId, bPreview)
|
|
|
|
elseif nSashType == WIN_SASHTYPES.NULL then
|
|
-- è il lato senza maniglia
|
|
if sHandleSide == 'Sx' then
|
|
DrawHinges( nLeftId, nLayerId, bPreview)
|
|
else
|
|
DrawHinges( nRightId, nLayerId, bPreview)
|
|
end
|
|
end
|
|
|
|
-- maniglia
|
|
if nSashType == WIN_SASHTYPES.ACTIVE or nSashType == WIN_SASHTYPES.ACTIVE_IN or nSashType == WIN_SASHTYPES.NULL then
|
|
-- recupero altezza maniglia
|
|
local dHandleH = GetHandleHeight( nRefAreaId)
|
|
if sHandleSide == 'Sx' then
|
|
DrawHandle( nRightId, sHandleSide, dHandleH, nLayerId, false, bPreview)
|
|
else
|
|
DrawHandle( nLeftId, sHandleSide, dHandleH, nLayerId, false, bPreview)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che calcola i dati necessari per la ferramenta
|
|
local function SearchSash( nAreaId, SashList)
|
|
-- verifico il tipo
|
|
local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i')
|
|
if nAreaType == WIN_AREATYPES.SASH then
|
|
|
|
-- creo gruppo temporaneo per i conti
|
|
local nOutlineOffsetLayerId = EgtGroup( nAreaId)
|
|
|
|
-- creo gruppo per i riferimenti della ferramenta per l'anta
|
|
local nHdwSashLayerId = EgtGroup( nAreaId)
|
|
EgtSetName( nHdwSashLayerId, WIN_HDW_FRAME)
|
|
EgtSetStatus( nHdwSashLayerId, GDB_ST.OFF)
|
|
|
|
-- recupero o creo gruppo per i riferimenti della ferramenta per il telaio
|
|
local nFrameAreaId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_AREA .. '*')
|
|
local nHdwFrameLayerId = EgtGetFirstNameInGroup( nFrameAreaId, WIN_HDW_FRAME)
|
|
if not nHdwFrameLayerId then
|
|
nHdwFrameLayerId = EgtGroup( nFrameAreaId)
|
|
EgtSetName( nHdwFrameLayerId, WIN_HDW_FRAME)
|
|
EgtSetStatus( nHdwFrameLayerId, GDB_ST.OFF)
|
|
end
|
|
|
|
-- verifico se alzante scorrevole
|
|
local bSlide = EgtGetInfo( nFrameAreaId, WIN_SLIDE_WINDOW, 'b') or false
|
|
|
|
-- ricostruisco gli outlines dell'anta in corrispondenza del canalino della ferramenta ( orgine dei riferimenti)
|
|
local vOutlineCopy = {}
|
|
local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE)
|
|
local nOutlineId = EgtGetFirstInGroup( nOutlineLayerId)
|
|
while nOutlineId do
|
|
local nSashProfileId = GetOutlineProfileId( nOutlineId)
|
|
local dGapDelta = EgtGetInfo( nSashProfileId, WIN_GAPDELTA, 'd')
|
|
local nOutlineCopyId = EgtCopy( nOutlineId, nOutlineOffsetLayerId)
|
|
EgtOffsetCurve( nOutlineCopyId, - dGapDelta)
|
|
table.insert( vOutlineCopy, nOutlineCopyId)
|
|
-- setto info ausiliarie sulla curva
|
|
EgtSetInfo( nOutlineCopyId, 'ORIG', nOutlineId)
|
|
CopyInfo( nOutlineCopyId, nSashProfileId, WIN_GAPDELTAZ)
|
|
local b3Profile = GetProfileLocalBox( nSashProfileId)
|
|
EgtSetInfo( nOutlineCopyId, WIN_GAPDELTAZ .. 2, b3Profile:getDimY())
|
|
nOutlineId = EgtGetNext( nOutlineId)
|
|
end
|
|
vOutlineCopy = TrimOrderedCurves( vOutlineCopy, true)
|
|
|
|
-- costruisco i riferimenti
|
|
local tFrame = {}
|
|
for i = 1, #vOutlineCopy do
|
|
-- 1) Riferimenti ANTA
|
|
local ptOrig = EgtEP( vOutlineCopy[i])
|
|
local sOrigName = string.char( string.byte( 'A') + #vOutlineCopy - i)
|
|
local vtDir = EgtEV( vOutlineCopy[i])
|
|
local nFA1Id = EgtFrame( nHdwSashLayerId, Frame3d( ptOrig, - vtDir, vtDir ^ Z_AX(), Z_AX()))
|
|
EgtSetName( nFA1Id, sOrigName .. '.FA1')
|
|
local vtIn = Vector3d( vtDir)
|
|
vtIn:rotate( Z_AX(), -90)
|
|
local dGapDeltaZ = EgtGetInfo( vOutlineCopy[i], WIN_GAPDELTAZ, 'd')
|
|
local nFA2Id = EgtFrame( nHdwSashLayerId, Frame3d( ptOrig - dGapDeltaZ * Z_AX(), - vtDir, vtDir ^ vtIn, vtIn))
|
|
EgtSetName( nFA2Id, sOrigName .. '.FA2')
|
|
local dGapDeltaZ2 = EgtGetInfo( vOutlineCopy[i], WIN_GAPDELTAZ .. 2, 'd')
|
|
local nFA3Id = EgtFrame( nHdwSashLayerId, Frame3d( ptOrig - dGapDeltaZ2 * Z_AX(), - vtDir, vtDir ^ -Z_AX(), -Z_AX()))
|
|
EgtSetName( nFA3Id, sOrigName .. '.FA3')
|
|
|
|
-- 2) Riferimenti TELAIO
|
|
-- ricavo elemento su cui poggia. Deve essere un elemento reale, quindi se fosse french split lo ignoro
|
|
local bFrenchSplit = EgtGetInfo( vOutlineCopy[i], WIN_CRV_ON_FRENCH_SPLIT, 'b')
|
|
if not bFrenchSplit then
|
|
local nSouId = EgtGetInfo( vOutlineCopy[i], WIN_SOU_OUTLINE, 'i')
|
|
-- ricavo aria lato telaio
|
|
local nFrameProfileId = GetOutlineProfileId( abs( nSouId))
|
|
local dGapDeltaOut = EgtGetInfo( nFrameProfileId, WIN_GAPDELTA, 'd')
|
|
if not dGapDeltaOut then
|
|
-- recupero informazione dal lato corretto ( split orizzontale)
|
|
if nSouId > 0 then
|
|
dGapDeltaOut = EgtGetInfo( nFrameProfileId, WIN_GAPDELTA .. '2', 'd')
|
|
else
|
|
dGapDeltaOut = EgtGetInfo( nFrameProfileId, WIN_GAPDELTA .. '1', 'd')
|
|
end
|
|
end
|
|
-- verifico il segno dell'offset
|
|
if nSouId < 0 then
|
|
dGapDeltaOut = - dGapDeltaOut
|
|
end
|
|
|
|
local nOutlineOutId = EgtCopy( abs( nSouId), nOutlineOffsetLayerId)
|
|
EgtOffsetCurve( nOutlineOutId, - dGapDeltaOut)
|
|
-- recupero origine come proiezione sul telaio dell'origine dell'anta
|
|
local _, ptOrigFr = EgtPointCurveDist( ptOrig, nOutlineOutId)
|
|
if bSlide then
|
|
-- nel caso di alzante scorrevole l'origine non è proiettata
|
|
ptOrigFr = EgtEP( nOutlineOutId)
|
|
end
|
|
local nFT1Id = EgtFrame( nHdwFrameLayerId, Frame3d( ptOrigFr, - vtDir, vtDir ^ Z_AX(), Z_AX()))
|
|
EgtSetName( nFT1Id, sOrigName .. '.FT1')
|
|
table.insert( tFrame, nFT1Id)
|
|
local vtFrameIn = Vector3d( vtDir)
|
|
vtFrameIn:rotate( Z_AX(), 90)
|
|
local dFrameGapDeltaZ = EgtGetInfo( nFrameProfileId, WIN_GAPDELTAZ, 'd')
|
|
local nFT2Id = EgtFrame( nHdwFrameLayerId, Frame3d( ptOrigFr - dFrameGapDeltaZ * Z_AX(), - vtDir, vtDir ^ vtFrameIn, vtFrameIn))
|
|
EgtSetName( nFT2Id, sOrigName .. '.FT2')
|
|
table.insert( tFrame, nFT2Id)
|
|
local b3FrameProfile = GetProfileLocalBox( nFrameProfileId)
|
|
local dGapDeltaZ2 = b3FrameProfile:getDimY()
|
|
local nFT3Id = EgtFrame( nHdwFrameLayerId, Frame3d( ptOrigFr - dGapDeltaZ2 * Z_AX(), - vtDir, vtDir ^ -Z_AX(), -Z_AX()))
|
|
EgtSetName( nFT3Id, sOrigName .. '.FT3')
|
|
table.insert( tFrame, nFT3Id)
|
|
end
|
|
end
|
|
|
|
-- preparo tabella per l'anta con i dati necessari per la ferramenta
|
|
local tSash = { nAreaId = nAreaId}
|
|
-- calcolo in centro per ordinamento
|
|
local b3Outline = EgtGetBBox( nOutlineLayerId, GDB_BB.STANDARD)
|
|
tSash.ptCenter = b3Outline:getCenter()
|
|
-- calcolo le dimensioni
|
|
tSash.LHeight = EgtCurveLength( vOutlineCopy[4])
|
|
tSash.RHeight = EgtCurveLength( vOutlineCopy[2])
|
|
tSash.BWidth = EgtCurveLength( vOutlineCopy[1])
|
|
if EgtGetType( vOutlineCopy[3]) == GDB_TY.CRV_ARC then
|
|
-- tSash.BCLength = EgtCurveLength( vOutlineCopy[3]) -- in alternativa a BCArrow, è il parametro LBBA nel file di richiesta
|
|
tSash.BCArrow = dist( EgtMP( vOutlineCopy[3]), 0.5 * ( EgtEP( vOutlineCopy[3]) + EgtSP( vOutlineCopy[3])))
|
|
end
|
|
-- salvo i frame del telaio associati
|
|
tSash.Frame = tFrame
|
|
table.insert( SashList, tSash)
|
|
|
|
EgtErase( nOutlineOffsetLayerId)
|
|
end
|
|
|
|
-- verifico se ci sono sotto-aree
|
|
local nChildAreaId = EgtGetFirstNameInGroup( nAreaId, WIN_AREA .. '*')
|
|
while nChildAreaId do
|
|
-- lancio costruzione pezzi di quell'area
|
|
SearchSash( nChildAreaId, SashList)
|
|
nChildAreaId = EgtGetNextName( nChildAreaId, WIN_AREA .. '*')
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che calcola le lavorazioni dell'hardware
|
|
local function CalcHdwMachining( tMachining, SashList)
|
|
local nFrameAreaId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_AREA .. '*')
|
|
local nHdwFrameLayerId = EgtGetFirstNameInGroup( nFrameAreaId, WIN_HDW_FRAME)
|
|
for i = 1, #tMachining do
|
|
local sPart = tMachining[i]['WindowPart']
|
|
local nSashIndex = tMachining[i]['SashIndex']
|
|
local sSashPart = tMachining[i]['SashPart']
|
|
local dPosX = tMachining[i]['PosX']
|
|
local dPosY = tMachining[i]['PosY']
|
|
local dPosZ = tMachining[i]['PosZ']
|
|
local sMacro = tMachining[i]['Macro']
|
|
local sSide = tMachining[i]['Side'] -- FT1, FT2, FT3, FA1, FA2, FA3
|
|
local sOrigin = tMachining[i]['Origin'] -- AB, BC, CD, DA
|
|
|
|
local nSashId = SashList[nSashIndex].nAreaId
|
|
local nOutlineLayerId = EgtGetFirstNameInGroup( nSashId, WIN_OUTLINE)
|
|
local vOutlineIds = EgtGetAllInGroup( nOutlineLayerId)
|
|
local nA = string.byte( 'A')
|
|
local nSashPart = string.byte( sSashPart)
|
|
local nOutlineIndex = #vOutlineIds - ( nSashPart - nA)
|
|
local nOutlineId = vOutlineIds[nOutlineIndex]
|
|
local nPartId = GDB_ID.NULL
|
|
local frHdw
|
|
if sPart == 'TELAIO' then
|
|
local nFrameOutlineId = abs( EgtGetInfo( nOutlineId, WIN_SOU_OUTLINE, 'i'))
|
|
nPartId = EgtGetInfo( nFrameOutlineId, WIN_REF_PART, 'i')
|
|
local nHdwFrameId = EgtGetLastNameInGroup( nHdwFrameLayerId, nSashIndex .. '.' .. sSashPart .. '.' .. sSide)
|
|
frHdw = EgtFR( nHdwFrameId)
|
|
elseif sPart == 'ANTA' then
|
|
nPartId = EgtGetInfo( nOutlineId, WIN_REF_PART, 'i')
|
|
local nHdwFrameLayerId = EgtGetFirstNameInGroup( nSashId, WIN_HDW_FRAME)
|
|
local nHdwFrameId = EgtGetLastNameInGroup( nHdwFrameLayerId, sSashPart .. '.' .. sSide)
|
|
frHdw = EgtFR( nHdwFrameId)
|
|
end
|
|
|
|
local nProcLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PRC)
|
|
|
|
-- recupero solido ( se non calcolato non vengono utilizzate)
|
|
local nSolidLayerId = EgtGetFirstNameInGroup( nPartId, WIN_SOLID) or GDB_ID.NULL
|
|
local nMainExtrusionId = EgtGetFirstNameInGroup( nSolidLayerId, WIN_SRF_MAIN)
|
|
local nOrigMainId = EgtGetFirstNameInGroup( nSolidLayerId, WIN_SRF_ORIGMAIN)
|
|
|
|
-- calcolo il punto centrale della lavorazione
|
|
local ptCenter = Point3d( dPosX, dPosY, dPosZ)
|
|
|
|
-- gestione particolare per traverso superiore ad arco
|
|
if EgtGetType( nOutlineId) == GDB_TY.CRV_ARC then
|
|
local nProfileLayId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE)
|
|
local nProfileId = EgtGetFirstNameInGroup( nProfileLayId, WIN_PRF_MAIN)
|
|
|
|
-- calcolo outline del telaio sul canalino della ferramenta
|
|
local nRefOutlineId = EgtGetInfo( nPartId, WIN_REF_OUTLINE, 'i')
|
|
local nOffsetId = EgtCopyGlob( nRefOutlineId, nPartId)
|
|
local dGapDelta = EgtGetInfo( nProfileId, WIN_GAPDELTA, 'd')
|
|
EgtOffsetCurve( nOffsetId, - dGapDelta)
|
|
|
|
-- recupero origine sulla curva di offset a partire dai frame dell'anta
|
|
local nHdwSashLayerId = EgtGetFirstNameInGroup( nSashId, WIN_HDW_FRAME)
|
|
local sHdwName = EgtIf( sOrigin == 'AB', 'B', 'C') .. '.FA1'
|
|
local nHdwSashId = EgtGetLastNameInGroup( nHdwSashLayerId, sHdwName)
|
|
local _, _, dParRef = EgtPointCurveDist( EgtSP( nHdwSashId), nOffsetId)
|
|
local dLen = EgtCurveLengthAtParam( nOffsetId, dParRef)
|
|
dLen = dLen + dPosX
|
|
local dPar = EgtCurveParamAtLength( nOffsetId, dLen)
|
|
local ptOrig = EgtUP( nOffsetId, dPar)
|
|
|
|
-- ricostruisco il frame in base alla nuova origine
|
|
local vtDir = EgtUV( nOffsetId, dPar, -1)
|
|
if sSide == 'FT1' or sSide == 'FA1' then
|
|
frHdw = Frame3d( ptOrig, - vtDir, vtDir ^ Z_AX(), Z_AX())
|
|
elseif sSide == 'FT2' or sSide == 'FA2' then
|
|
local vtDirIn = Vector3d( vtDir)
|
|
vtDirIn:rotate( Z_AX(), 90)
|
|
local dFrameGapDeltaZ = EgtGetInfo( nProfileId, WIN_GAPDELTAZ, 'd')
|
|
frHdw = Frame3d( ptOrig - dFrameGapDeltaZ * Z_AX(), - vtDir, vtDir ^ vtDirIn, vtDirIn)
|
|
elseif sSide == 'FT3' or sSide == 'FA3' then
|
|
local b3FrameProfile = GetProfileLocalBox( nProfileId)
|
|
local dGapDeltaZ2 = b3FrameProfile:getDimY()
|
|
frHdw = Frame3d( ptOrig - dGapDeltaZ2 * Z_AX(), - vtDir, vtDir ^ -Z_AX(), -Z_AX())
|
|
end
|
|
|
|
-- calcolo il centro della lavorazione riferito al nuovo frame
|
|
ptCenter = Point3d( 0, dPosY, dPosZ)
|
|
|
|
EgtErase( nOffsetId)
|
|
end
|
|
|
|
local vMacro = EgtSplitString( sMacro, '_')
|
|
if vMacro[1] == 'FRESATA' then
|
|
elseif vMacro[1] == 'ASOLA' or vMacro[1] == 'MANIGLIA' then
|
|
|
|
local dLength, dWidth, dHeight
|
|
if vMacro[1] == 'ASOLA' then
|
|
dLength = tonumber( vMacro[2])
|
|
dWidth = tonumber( vMacro[3])
|
|
dHeight = tonumber( vMacro[4])
|
|
-- NB in alcune macro ASOLA il secondo parametro non è la width ma la width/2 !
|
|
-- TODO Al momento sembra che questo avvenga solo quando il suo valore è 8. Da verificare
|
|
if abs( dWidth - 8) < GEO.EPS_SMALL then
|
|
dWidth = dWidth * 2
|
|
end
|
|
elseif vMacro[1] == 'MANIGLIA' and vMacro[2] == '160' then
|
|
-- macro speciale che corrisponde ad ASOLA_216_12_56 quindi forzo direttamente i valori
|
|
-- TODO gestione di queste macro non parlanti
|
|
dLength = 216
|
|
dWidth = 12
|
|
dHeight = 56
|
|
elseif vMacro[1] == 'MANIGLIA' then -- and vMacro[2] == '15'
|
|
-- corrisponde ad ASOLA_69_12_30
|
|
dLength = 69
|
|
dWidth = 12
|
|
dHeight = 30
|
|
end
|
|
local ptP1 = ptCenter + ( dLength / 2 - dWidth / 2) * X_AX() + dWidth / 2 * Y_AX()
|
|
local ptP2 = ptCenter - ( dLength / 2 - dWidth / 2) * X_AX() + dWidth / 2 * Y_AX()
|
|
local nPocketOutlineId = EgtCurveCompoFromPoints( nProcLayerId, { ptP1, ptP2})
|
|
EgtAddCurveCompoArcTg( nPocketOutlineId, ptCenter - ( dLength / 2 - dWidth / 2) * X_AX() - dWidth / 2 * Y_AX())
|
|
EgtAddCurveCompoArcTg( nPocketOutlineId, ptCenter + ( dLength / 2 - dWidth / 2) * X_AX() - dWidth / 2 * Y_AX(), false)
|
|
EgtCloseCurveCompo( nPocketOutlineId)
|
|
EgtSetColor( nPocketOutlineId, EgtStdColor( 'GRAY'))
|
|
-- setto info di lavorazione
|
|
EgtSetInfo( nPocketOutlineId, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.PROFILING)
|
|
EgtSetInfo( nPocketOutlineId, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.GENERIC)
|
|
EgtSetInfo( nPocketOutlineId, WIN_PRC_SIDE, WIN_PRC_SIDETYPE.IN)
|
|
EgtModifyCurveExtrusion( nPocketOutlineId, Z_AX())
|
|
EgtModifyCurveThickness( nPocketOutlineId, - dHeight)
|
|
-- porto la lavorazione in globale
|
|
EgtTransform( nPocketOutlineId, frHdw)
|
|
-- aggiornamento del solido
|
|
if s_bCalcSolid then
|
|
UpdateSolidWithProcessingCrv( nPocketOutlineId, nMainExtrusionId, nSolidLayerId)
|
|
end
|
|
|
|
elseif vMacro[1] == 'TASCA' then
|
|
elseif vMacro[1] == 'VITE' then
|
|
local dRadius = 1.5
|
|
local dDepth = 2
|
|
if vMacro[2] == 'CANALINO' then
|
|
dRadius = 2
|
|
dDepth = 3
|
|
elseif vMacro[2] == 'ANTA' then
|
|
dRadius = 2.5
|
|
dDepth = 4
|
|
end
|
|
local nHoleId = EgtCircle( nProcLayerId, ptCenter, dRadius)
|
|
EgtMove( nHoleId, Z_AX())
|
|
EgtModifyCurveExtrusion( nHoleId, Z_AX())
|
|
EgtModifyCurveThickness( nHoleId, - ( dDepth + 1))
|
|
EgtTransform( nHoleId, frHdw)
|
|
EgtSetInfo( nHoleId, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.HOLE)
|
|
|
|
elseif vMacro[1] == 'FORO' then
|
|
local sDiameter = EgtReplaceString( vMacro[2], 'D', '')
|
|
local dRadius = tonumber( sDiameter) / 2
|
|
local nHoleId = EgtCircle( nProcLayerId, ptCenter, dRadius)
|
|
-- setto info di lavorazione
|
|
EgtModifyCurveExtrusion( nHoleId, Z_AX())
|
|
-- TODO : come gestire profondità non definita?
|
|
local dDepth = tonumber(25)
|
|
if #vMacro == 3 then
|
|
dDepth = tonumber( vMacro[3])
|
|
end
|
|
EgtModifyCurveThickness( nHoleId, - dDepth)
|
|
EgtSetColor( nHoleId, EgtStdColor( 'GRAY'))
|
|
EgtSetInfo( nHoleId, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.HOLE)
|
|
-- porto la lavorazione in globale
|
|
EgtTransform( nHoleId, frHdw)
|
|
-- aggiornamento del solido
|
|
if s_bCalcSolid then
|
|
UpdateSolidWithProcessingCrv( nHoleId, nMainExtrusionId, nSolidLayerId)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che aggiunge l'hardware
|
|
local function AddHardwareForSash( nFrameId, nReturnMode, OutputKitList, OutputPositionList, OutputOptionList)
|
|
-- cerco ed indicizzo ante del serramento
|
|
local SashList = {}
|
|
SearchSash( nFrameId, SashList)
|
|
|
|
-- ordino per X e Y
|
|
local function compareXY(a,b)
|
|
if abs( a.ptCenter:getX() - b.ptCenter:getX()) < GEO.EPS_SMALL then
|
|
return a.ptCenter:getY() < b.ptCenter:getY()
|
|
else
|
|
return a.ptCenter:getX() < b.ptCenter:getX()
|
|
end
|
|
end
|
|
table.sort( SashList, compareXY)
|
|
|
|
-- correggo nomi Frame del telaio in base all'ordinamento delle ante
|
|
for nIndex = 1, #SashList do
|
|
for nFrameIndex = 1, #SashList[nIndex].Frame do
|
|
local nFrameId = SashList[nIndex].Frame[nFrameIndex]
|
|
local sName = EgtGetName( nFrameId)
|
|
EgtSetName( nFrameId, nIndex .. '.' .. sName)
|
|
end
|
|
end
|
|
|
|
-- recupero preferito della ferramenta
|
|
local nFavourite = EgtGetInfo( nFrameId, WIN_HDW_FAVOURITE)
|
|
if not nFavourite or nFavourite == WIN_HDW_NULL then
|
|
EgtOutLog('Warning! No hardware favourite set!')
|
|
return
|
|
end
|
|
local sHandle = EgtGetInfo( nFrameId, WIN_HDW_HANDLE)
|
|
if not sHandle then
|
|
EgtOutLog('Warning! No hardware handle set!')
|
|
return
|
|
end
|
|
|
|
local sText = 'S_NAME=' .. nFavourite .. '\n' ..
|
|
'RECORDID=15A' .. '\n'
|
|
|
|
-- recupero il tipo di apertura
|
|
local nOpeningType = WIN_OPENING_TYPES.NULL
|
|
if #SashList > 0 then
|
|
nOpeningType = EgtGetInfo( SashList[1].nAreaId, WIN_OPENING_TYPE, 'i')
|
|
end
|
|
-- recupero se scorrevole
|
|
local nFrameAreaId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_AREA .. '*')
|
|
local bSlide = EgtGetInfo( nFrameAreaId, WIN_SLIDE_WINDOW, 'b') or false
|
|
|
|
if bSlide then
|
|
-- le dimensioni per alzante scorrevole sono quelle del telaio
|
|
local nOutlineLayId = EgtGetFirstNameInGroup( nFrameId, WIN_AREAOUTLINE)
|
|
local nBottomId = EgtGetFirstNameInGroup( nOutlineLayId, WIN_BOTTOM)
|
|
local dMet = EgtCurveLength( nBottomId)
|
|
local nLeftId = EgtGetFirstNameInGroup( nOutlineLayId, WIN_LEFT)
|
|
local dHet = EgtCurveLength( nLeftId)
|
|
sText = sText .. 'MET=' .. tostring( dMet) .. '\n'
|
|
sText = sText .. 'HET=' .. tostring( dHet) .. '\n'
|
|
|
|
else
|
|
if #SashList >= 1 and abs( SashList[1].LHeight - SashList[1].RHeight) < GEO.EPS_SMALL then
|
|
sText = sText .. 'HBB=' .. tostring( SashList[1].LHeight) .. '\n'
|
|
else
|
|
for nSashIndex = 1, #SashList do
|
|
if nSashIndex == 1 then
|
|
sText = sText .. 'HBB_sx=' .. tostring( SashList[nSashIndex].LHeight) .. '\n'
|
|
else
|
|
sText = sText .. 'HBB_' .. tostring( nSashIndex - 1) .. 'B=' .. tostring( SashList[nSashIndex].LHeight) .. '\n'
|
|
end
|
|
if nSashIndex == #SashList then
|
|
sText = sText .. 'HBB_dx=' .. tostring( SashList[nSashIndex].RHeight) .. '\n'
|
|
else
|
|
sText = sText .. 'HBB_' .. tostring( nSashIndex) .. '=' .. tostring( SashList[nSashIndex].RHeight) .. '\n'
|
|
end
|
|
end
|
|
end
|
|
|
|
if #SashList == 1 then
|
|
sText = sText .. 'LBB=' .. tostring( SashList[1].BWidth) .. '\n'
|
|
if SashList[1].BCArrow then
|
|
sText = sText .. 'FRECCIA_1=' .. tostring( SashList[1].BCArrow) .. '\n'
|
|
end
|
|
else
|
|
for nSashIndex = 1, #SashList do
|
|
sText = sText .. 'LBB' .. nSashIndex .. '=' .. tostring( SashList[nSashIndex].BWidth) .. '\n'
|
|
if SashList[nSashIndex].BCArrow then
|
|
sText = sText .. 'FRECCIA_' .. nSashIndex .. '=' .. tostring( SashList[nSashIndex].BCArrow) .. '\n'
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
sText = sText .. 'FINESTRAPORTAFINESTRA=Finestra' .. '\n' ..
|
|
'Q=1' .. '\n'
|
|
|
|
-- opzione manoserramento ( non per vasistas altrimenti sovrascrive l'opzione)
|
|
if nOpeningType ~= WIN_OPENING_TYPES.TILTONLY_TOP then
|
|
sText = sText .. 'MANOSERRAMENTO=' .. sHandle .. '\n'
|
|
end
|
|
|
|
local vOptions = EgtGetInfo( nFrameId, WIN_HDW_OPTIONS, 'vs') or {}
|
|
for i = 1, #vOptions do
|
|
sText = sText .. vOptions[i] .. '\n'
|
|
end
|
|
|
|
-- Canali
|
|
local QuestionChannel = "EgwHardwareQuestion"
|
|
local AnswerChannel = "EgwHardwareAnswer" .. os.time()
|
|
|
|
local Question = { nThreadIndex = 0,
|
|
nId = 2,
|
|
ExecEnvironment = 1,
|
|
Args = { UID = 0,
|
|
OutputChannel = AnswerChannel,
|
|
Mode = 3,
|
|
SubMode = 2,
|
|
Manufacturer = 1,
|
|
ReturnMode = nReturnMode,
|
|
Input = sText}}
|
|
|
|
local JsonQuestion = JSON:encode( Question)
|
|
|
|
local bOk = EgtRedisAsyncPublish( s_nRedisConnectionId, QuestionChannel, JsonQuestion)
|
|
local AnswerArgs
|
|
if bOk then
|
|
-- EgtOutLog( 'Messaggio Redis pubblicato:' .. QuestionChannel .. ' ' .. JsonQuestion)
|
|
EgtOutLog( 'Messaggio Redis pubblicato')
|
|
local bOk, Answer = EgtRedisAsyncSubscribeOneMessage( s_nRedisConnectionId, AnswerChannel, 5000)
|
|
if bOk then
|
|
-- EgtOutLog( 'Risposta Redis ricevuta:' .. Answer)
|
|
EgtOutLog( 'Risposta Redis ricevuta')
|
|
local JsonAnswer = JSON:decode( Answer)
|
|
AnswerArgs = JsonAnswer['Args']
|
|
AnswerArgs.OutputChannel = nil
|
|
else
|
|
EgtOutLog( 'Errore! Risposta dal canale calcolo hardware Agb non arrivata!')
|
|
return
|
|
end
|
|
else
|
|
EgtOutLog( 'Errore! Pubblicazione sul canale calcolo hardware Agb fallita!')
|
|
return
|
|
end
|
|
|
|
if ( nReturnMode & WIN_HDW_RETURNMODE.HARDWARELIST) ~= 0 then
|
|
local tHardware = JSON:decode( AnswerArgs.HardwareList)
|
|
table.insert( OutputKitList, tHardware)
|
|
end
|
|
if ( nReturnMode & WIN_HDW_RETURNMODE.POSITIONLIST) ~= 0 then
|
|
local tPosition = JSON:decode( AnswerArgs.PositionList)
|
|
table.insert( OutputPositionList, tPosition)
|
|
end
|
|
if ( nReturnMode & WIN_HDW_RETURNMODE.MACHININGLIST) ~= 0 then
|
|
local tMachining = JSON:decode( AnswerArgs.MachiningList)
|
|
CalcHdwMachining( tMachining, SashList)
|
|
-- disegno la ferramenta
|
|
if s_bCalcSolid then
|
|
-- recupero o creo il gruppo per disegno ferramenta
|
|
local nAuxLayerId = GetAuxLayer()
|
|
for i = 1, #SashList do
|
|
DrawSashHardware( SashList[i].nAreaId, nFrameId, nAuxLayerId)
|
|
end
|
|
end
|
|
end
|
|
if ( nReturnMode & WIN_HDW_RETURNMODE.OPTIONLIST) ~= 0 then
|
|
table.insert( OutputOptionList, AnswerArgs.OptionList)
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function AddHardwareRec( nAreaId, nReturnMode, OutputKitList, OutputPositionList, OutputOptionList)
|
|
|
|
local sHardware = EgtGetInfo( nAreaId, WIN_HDW_FAVOURITE)
|
|
if sHardware and sHardware ~= WIN_HDW_NULL then
|
|
-- se area ha un preferito definito allora devo calcolare la ferramenta sulle sue ante
|
|
return AddHardwareForSash( nAreaId, nReturnMode, OutputKitList, OutputPositionList, OutputOptionList)
|
|
else
|
|
-- verifico se ci sono sotto-aree
|
|
local nChildAreaId = EgtGetFirstNameInGroup( nAreaId, WIN_AREA .. '*')
|
|
while nChildAreaId do
|
|
-- lancio verifica di quell'area
|
|
AddHardwareRec( nChildAreaId, nReturnMode, OutputKitList, OutputPositionList, OutputOptionList)
|
|
nChildAreaId = EgtGetNextName( nChildAreaId, WIN_AREA .. '*')
|
|
end
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che aggiunge l'hardware
|
|
function WinCalculate.AddHardware( nAreaId, bMachiningList, bHardwareList, bPositionList, bOptionList)
|
|
-- connessione a Redis
|
|
local bRedisConnect = false
|
|
if WDG and WDG.REDISID and WDG.REDISID > 0 then
|
|
-- connessione già creata dall'esterno
|
|
s_nRedisConnectionId = WDG.REDISID
|
|
elseif s_nRedisConnectionId == 0 then
|
|
-- se nessuna connessione la creo
|
|
bRedisConnect, s_nRedisConnectionId = EgtRedisAsyncConnect( 'redis.ufficio:26379, serviceName=devel, DefaultDatabase=6, keepAlive=180, connectTimeout=15000, syncTimeout=15000, asyncTimeout=15000, abortConnect=false, ssl=false, allowAdmin=true')
|
|
if not bRedisConnect then
|
|
EgtOutLog( 'Errore! Impossibile connettersi con il server Redis dal Lua!')
|
|
end
|
|
end
|
|
|
|
-- calcolo codice di ritorno, i.e. tipologie di conti da fare sulla ferramenta ( e.g calcolo lavorazioni, calcolo lista ferramenta, ...)
|
|
local nReturnMode = 0
|
|
if bMachiningList then
|
|
nReturnMode = nReturnMode + WIN_HDW_RETURNMODE.MACHININGLIST
|
|
end
|
|
if bHardwareList then
|
|
nReturnMode = nReturnMode + WIN_HDW_RETURNMODE.HARDWARELIST
|
|
end
|
|
if bPositionList then
|
|
nReturnMode = nReturnMode + WIN_HDW_RETURNMODE.POSITIONLIST
|
|
end
|
|
if bOptionList then
|
|
nReturnMode = nReturnMode + WIN_HDW_RETURNMODE.OPTIONLIST
|
|
end
|
|
|
|
local OutputKitList = {}
|
|
local OutputPositionList = {}
|
|
local OutputOptionList = {}
|
|
AddHardwareRec( nAreaId, nReturnMode, OutputKitList, OutputPositionList, OutputOptionList)
|
|
|
|
-- se la connessione è stata creata in questa funzione la chiudo
|
|
if bRedisConnect then
|
|
EgtRedisAsyncDisconnect( s_nRedisConnectionId)
|
|
s_nRedisConnectionId = 0
|
|
end
|
|
|
|
return OutputKitList, OutputPositionList, OutputOptionList
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che disegna l'hardware
|
|
local function DrawHardware( nAreaId, nAuxLayerId)
|
|
-- verifico il tipo
|
|
local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i')
|
|
|
|
if nAreaType == WIN_AREATYPES.SASH then
|
|
-- se anta disegno la ferramenta se è stato definito un preferito
|
|
local sFavourite = EgtGetInfo( nAreaId, WIN_HDW_FAVOURITE)
|
|
if sFavourite and sFavourite ~= WIN_HDW_NULL then
|
|
DrawSashHardware( nAreaId, nAreaId, nAuxLayerId)
|
|
end
|
|
return
|
|
|
|
elseif nAreaType == WIN_AREATYPES.SPLIT then
|
|
local nSplitType = EgtGetInfo( nAreaId, WIN_SPLITTYPE, 'i') or WIN_SPLITTYPES.NULL
|
|
if nSplitType == WIN_SPLITTYPES.FRENCH then
|
|
local sHdwFavourite = EgtGetInfo( nAreaId, WIN_HDW_FAVOURITE)
|
|
if sHdwFavourite and sHdwFavourite ~= WIN_HDW_NULL then
|
|
-- disegno ferramenta per tutte le ante avendo come gruppo di riferimento delle info il parent dell'area split french
|
|
local vSashes = EgtGetNameInGroup( nAreaId, WIN_AREA .. '*')
|
|
for j = 1, #vSashes do
|
|
DrawSashHardware( vSashes[j], nAreaId, nAuxLayerId)
|
|
end
|
|
end
|
|
return
|
|
else
|
|
local nChildAreaId = EgtGetFirstNameInGroup( nAreaId, WIN_AREA .. '*')
|
|
while nChildAreaId do
|
|
-- lancio verifica di quell'area
|
|
DrawHardware( nChildAreaId, nAuxLayerId)
|
|
nChildAreaId = EgtGetNextName( nChildAreaId, WIN_AREA .. '*')
|
|
end
|
|
end
|
|
|
|
else
|
|
-- verifico se ci sono sotto-aree
|
|
local nChildAreaId = EgtGetFirstNameInGroup( nAreaId, WIN_AREA .. '*')
|
|
while nChildAreaId do
|
|
-- lancio verifica di quell'area
|
|
DrawHardware( nChildAreaId, nAuxLayerId)
|
|
nChildAreaId = EgtGetNextName( nChildAreaId, WIN_AREA .. '*')
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
|
|
----------------------------------------------------------------------------------
|
|
----------------------------------- ACCESSORI ----------------------------------
|
|
----------------------------------------------------------------------------------
|
|
-- funzione che individua l'intersezione tra nOutlineId e la curva del geo indicata da sGeoRef del pezzo avente come outline nRefCrvId
|
|
local function GetTrimParamByGeo( nOutlineId, nRefCrvId, sGeoRef)
|
|
|
|
-- recupero la curva di interessa del geo
|
|
local nRefPart = EgtGetInfo( nRefCrvId, WIN_REF_PART, 'i')
|
|
local nRefGeo = EgtGetFirstNameInGroup( nRefPart, WIN_GEO)
|
|
local nGeoCrv = EgtGetFirstNameInGroup( nRefGeo, sGeoRef)
|
|
|
|
-- recupero punto di intersezione ( con eventuale estensione delle curve)
|
|
local ptInt = FindIntersectionPoint( nOutlineId, nGeoCrv, ORIG())
|
|
|
|
-- ricavo il parametro di intersezione sulla curva di outline ( senza estensione)
|
|
local dPar = EgtCurveParamAtPoint( nOutlineId, ptInt)
|
|
return dPar
|
|
end
|
|
|
|
----------------------------------------------------------------------------------
|
|
-- funzione che calcola e disegna la soglia
|
|
local function CalcThreshold( nOutlineId, nAreaId)
|
|
-- recupero il profilo della soglia
|
|
local nProfileId = GetOutlineProfileId( nOutlineId)
|
|
local dLenTot = 0
|
|
|
|
-- disegno
|
|
local nAuxGrp = GetAuxLayer()
|
|
local nStm = CreateProfileSurf( nOutlineId, nProfileId, WIN_SECTION, 0, nAuxGrp)
|
|
if nStm then
|
|
EgtSetColor( nStm, Color3d( 128, 128, 128))
|
|
EgtSetName( nStm, WIN_THRESHOLD)
|
|
dLenTot = EgtCurveLength( nOutlineId)
|
|
end
|
|
|
|
-- se slide window ci sono parti extra da estrudere in corrispondenza delle ante fisse
|
|
-- ( slide window ha una struttura di aree standard e forma rettangolare)
|
|
local bSlideWindow = EgtGetInfo( nAreaId, WIN_SLIDE_WINDOW, 'b') or false
|
|
if bSlideWindow then
|
|
|
|
-- 1) soglia extra per parte mobile
|
|
local nGuideId = EgtCopyGlob( nOutlineId, nAuxGrp)
|
|
-- taglio la curva guida con i pezzi di telaio vicini
|
|
local nPrevCrv = EgtGetLastInGroup( EgtGetParent( nOutlineId))
|
|
local dParS = GetTrimParamByGeo( nGuideId, nPrevCrv, WIN_GEO_IN)
|
|
local nNextCrv = EgtGetNext( nOutlineId)
|
|
local dParE = GetTrimParamByGeo( nGuideId, nNextCrv, WIN_GEO_IN)
|
|
EgtTrimCurveStartEndAtParam( nGuideId, dParS, dParE)
|
|
|
|
local vMovableSections = EgtGetNameInGroup( nProfileId, WIN_MOVABLE .. WIN_SECTION)
|
|
for i = 1, #vMovableSections do
|
|
local nStmExtra = CreateProfileSurfById( nGuideId, nProfileId, vMovableSections[i], 0, nAuxGrp)
|
|
EgtSetColor( nStmExtra, Color3d( 128, 128, 128))
|
|
EgtSetName( nStmExtra, WIN_MOVABLE .. WIN_SECTION)
|
|
end
|
|
dLenTot = dLenTot + #vMovableSections * EgtCurveLength( nGuideId)
|
|
EgtErase( nGuideId)
|
|
|
|
-- 2) soglia extra per le sottoante fisse
|
|
-- recupero i profili extra da estrudere
|
|
local vExtraSections = EgtGetNameInGroup( nProfileId, WIN_FIXED .. WIN_SECTION)
|
|
if #vExtraSections > 0 then
|
|
-- cerco tutte le sottoante fisse
|
|
local nSplitArea = EgtGetFirstNameInGroup( nAreaId, WIN_AREA .. '*')
|
|
local vSashAreas = EgtGetNameInGroup( nSplitArea, WIN_AREA .. '*')
|
|
for i = 1, #vSashAreas do
|
|
local nSashType = EgtGetInfo( vSashAreas[i], WIN_SASHTYPE, 'i')
|
|
if nSashType == WIN_SASHTYPES.SLIDE_FIXED then
|
|
|
|
local nGuideId = EgtCopyGlob( nOutlineId, nAuxGrp)
|
|
-- trim della guida con il geo dei pezzi vicini
|
|
local nOutlineLayerId = EgtGetFirstNameInGroup( vSashAreas[i], WIN_OUTLINE)
|
|
local nLeftCrv = EgtGetFirstNameInGroup( nOutlineLayerId, WIN_LEFT)
|
|
local dParS = GetTrimParamByGeo( nGuideId, nLeftCrv, WIN_GEO_OUT)
|
|
local nRightCrv = EgtGetFirstNameInGroup( nOutlineLayerId, WIN_RIGHT)
|
|
local dParE = GetTrimParamByGeo( nGuideId, nRightCrv, WIN_GEO_OUT)
|
|
EgtTrimCurveStartEndAtParam( nGuideId, dParS, dParE)
|
|
|
|
for j = 1, #vExtraSections do
|
|
local nStmExtra = CreateProfileSurfById( nGuideId, nProfileId, vExtraSections[j], 0, nAuxGrp)
|
|
EgtSetColor( nStmExtra, Color3d( 128, 128, 128))
|
|
EgtSetName( nStmExtra, WIN_FIXED .. WIN_THRESHOLD)
|
|
end
|
|
|
|
-- aggiorno lunghezza ( TODO da gestire separatamente con i tipi di soglia)
|
|
dLenTot = dLenTot + #vExtraSections * EgtCurveLength( nGuideId)
|
|
EgtErase( nGuideId)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- salvo info lunghezza
|
|
EgtSetInfo( nAreaId, WIN_THRESHOLD_LEN, dLenTot)
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che calcola e disegna il gocciolatoio
|
|
local function CalcWaterdrip( nPartId, nOutlineId, nAreaId, bDraw)
|
|
|
|
-- verifico presenza gocciolatoio
|
|
local nProfileLayId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE)
|
|
local nProfileId = EgtGetFirstNameInGroup( nProfileLayId, WIN_PRF_MAIN)
|
|
local nWaterdripId = EgtGetFirstNameInGroup( nProfileId, WIN_WATERDRIP)
|
|
if not nWaterdripId then
|
|
return
|
|
end
|
|
|
|
local dLenTot = 0
|
|
-- recupero il gruppo per il disegno dei solidi
|
|
local nSolidLayId
|
|
if bDraw and s_bCalcSolid then
|
|
nSolidLayId = GetAuxLayer()
|
|
end
|
|
|
|
local vParams = {}
|
|
|
|
-- calcolo i limiti del gocciolatoio in base ai pezzi vicini del telaio
|
|
local vPrevCrvs = EgtGetInfo( nOutlineId, WIN_PREV_OUTLINES, 'vi')
|
|
local dParS = GetTrimParamByGeo( nOutlineId, vPrevCrvs[1], WIN_GEO_IN)
|
|
table.insert( vParams, dParS)
|
|
local vNextCrvs = EgtGetInfo( nOutlineId, WIN_NEXT_OUTLINES, 'vi')
|
|
local dParE = GetTrimParamByGeo( nOutlineId, vNextCrvs[1], WIN_GEO_IN)
|
|
table.insert( vParams, dParE)
|
|
|
|
-- calcolo eventuali interruzioni nel gocciolatoio per la presenza di montanti
|
|
local vSplits = {}
|
|
local nBottomRail = EgtGetInfo( nOutlineId, WIN_REF_BOTTOMRAIL_PART, 'i')
|
|
if not nBottomRail then -- se ha bottomrail gli split non causano interruzioni nel gocciolatoio
|
|
local vStack = { nAreaId}
|
|
local i = 1
|
|
while vStack[i] do
|
|
local nAreaType = EgtGetInfo( vStack[i], WIN_AREATYPE, 'i')
|
|
if nAreaType == WIN_AREATYPES.SPLIT then
|
|
local nSplitType = EgtGetInfo( vStack[i], WIN_SPLITTYPE, 'i')
|
|
if nSplitType ~= WIN_SPLITTYPES.FRENCH then
|
|
local nSplitLayerId = EgtGetFirstNameInGroup( vStack[i], WIN_SPLIT)
|
|
local vCurrSplits = EgtGetAllInGroup( nSplitLayerId)
|
|
for j = 1, #vCurrSplits do
|
|
-- verifico se lo split poggia sulla curva bottom
|
|
local dDist1 = EgtPointCurveDist( EgtSP( vCurrSplits[j]), nOutlineId)
|
|
local dDist2 = EgtPointCurveDist( EgtEP( vCurrSplits[j]), nOutlineId)
|
|
if dDist1 < GEO.EPS_SMALL or dDist2 < GEO.EPS_SMALL then
|
|
-- recupero l'intervallo di interruzione dello split sull'outline
|
|
local dParIn = GetTrimParamByGeo( nOutlineId, vCurrSplits[j], WIN_GEO_IN)
|
|
table.insert( vParams, dParIn)
|
|
local dParOut = GetTrimParamByGeo( nOutlineId, vCurrSplits[j], WIN_GEO_OUT)
|
|
table.insert( vParams, dParOut)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- se non è anta ( che interrompe la cascata di pezzi relativi al telaio) salvo le sottaree per analizzarle
|
|
if nAreaType ~= WIN_AREATYPES.SASH then
|
|
local vChildren = EgtGetNameInGroup( vStack[i], WIN_AREA .. '*') or {}
|
|
vStack = EgtJoinTables( vStack, vChildren)
|
|
end
|
|
-- passo all'area successiva
|
|
i = i + 1
|
|
end
|
|
end
|
|
|
|
-- riordino i parametri ed elimino quelli coincidenti
|
|
table.sort( vParams)
|
|
local vNewParams = { vParams[1]}
|
|
for j = 2, #vParams do
|
|
if abs( vParams[j] - vNewParams[#vNewParams]) > GEO.EPS_ZERO then
|
|
table.insert( vNewParams, vParams[j])
|
|
end
|
|
end
|
|
vParams = vNewParams
|
|
|
|
for j = 1, #vParams, 2 do
|
|
-- ricavo la guida per il tratto di gocciolatoio
|
|
local nGuideId = EgtCopyParamRange( nOutlineId, vParams[j], vParams[j+1], nSolidLayId)
|
|
dLenTot = dLenTot + EgtCurveLength( nGuideId)
|
|
if bDraw and s_bCalcSolid then
|
|
-- estrudo la superficie
|
|
local nStm = CreateProfileSurf( nGuideId, nProfileId, WIN_WATERDRIP, 0, nSolidLayId)
|
|
EgtSetColor( nStm, Color3d( 128, 128, 128))
|
|
EgtSetName( nStm, WIN_WATERDRIP)
|
|
end
|
|
EgtErase( nGuideId)
|
|
end
|
|
|
|
-- salvo la lunghezza del gocciolatoio
|
|
EgtSetInfo( nAreaId, WIN_WATERDRIP_LEN, dLenTot)
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che calcola e disegna le guarnizioni
|
|
local function CalcGaskets( nAreaId, bDraw)
|
|
|
|
local nOutlineLayId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE)
|
|
local vOrigOutlines = EgtGetAllInGroup( nOutlineLayId)
|
|
local dLenTot = 0
|
|
|
|
-- recupero dati dei pezzi che serviranno nei conti e i veri outlines da considerare
|
|
local tParts = {}
|
|
local vOutlines = {}
|
|
for i = 1, #vOrigOutlines do
|
|
local bThreshold = EgtGetName( vOrigOutlines[i]) == WIN_BOTTOM and EgtGetInfo( vOrigOutlines[i], WIN_THRESHOLD, 'b')
|
|
if bThreshold then
|
|
-- gestione speciale per soglia che non ha pezzo associato
|
|
local nMainProfileId = GetOutlineProfileId( vOrigOutlines[i])
|
|
tParts[i] = { nProfileId = nMainProfileId, frProfile = nil}
|
|
vOutlines[i] = vOrigOutlines[i]
|
|
else
|
|
local nPartId = FindAssociatedPart( vOrigOutlines[i], false)
|
|
local nProfileLayId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE)
|
|
local nMainProfileId = EgtGetFirstNameInGroup( nProfileLayId, WIN_PRF_MAIN)
|
|
local nFrameId = EgtGetFirstNameInGroup( nMainProfileId, WIN_SECTIONFRAME)
|
|
local frProfile = EgtFR( nFrameId, GDB_ID.ROOT)
|
|
tParts[i] = { nProfileId = nMainProfileId, frProfile = frProfile}
|
|
vOutlines[i] = EgtGetInfo( nPartId, WIN_REF_OUTLINE, 'i')
|
|
end
|
|
end
|
|
|
|
-- gruppo temporaneo per i conti
|
|
local nGrp = EgtGroup( nAreaId)
|
|
|
|
-- cerco tutte le possibili guarnizioni
|
|
for i = 1, 3 do
|
|
-- nome della guarnizione corrente
|
|
local sGasket = WIN_GASKET .. tostring( i)
|
|
local vCrvs = {}
|
|
for i = 1, #vOutlines do
|
|
local nCrv = EgtCopyGlob( vOutlines[i], nGrp)
|
|
table.insert( vCrvs, nCrv)
|
|
|
|
-- calcolo offset da applicare alla curva
|
|
local dOffs
|
|
local vGasketIds = EgtGetNameInGroup( tParts[i].nProfileId, sGasket .. '*')
|
|
if #vGasketIds == 1 then
|
|
-- se guarnizione recupero offset dalla sua dimensione
|
|
local b3Box = EgtGetBBoxRef( vGasketIds[1], GDB_BB.STANDARD, tParts[i].frProfile)
|
|
dOffs = b3Box:getMax():getX()
|
|
tParts[i].sGasket = sGasket
|
|
elseif #vGasketIds > 1 then
|
|
-- se ho più guarnizioni devo identificare quella dal lato corretto ( caso di split)
|
|
local nCrvRef = EgtIf( i == 1, vOrigOutlines[2], vOrigOutlines[i-1])
|
|
local _, _, nSide = EgtPointCurveDistSide( EgtMP( nCrvRef), nCrv, Z_AX())
|
|
if nSide == 1 then
|
|
tParts[i].sGasket = sGasket .. '_1'
|
|
local nGasketId = EgtGetFirstNameInGroup( tParts[i].nProfileId, tParts[i].sGasket)
|
|
local b3Box = EgtGetBBoxRef( nGasketId, GDB_BB.STANDARD, tParts[i].frProfile)
|
|
dOffs = b3Box:getMin():getX()
|
|
else
|
|
tParts[i].sGasket = sGasket .. '_2'
|
|
local nGasketId = EgtGetFirstNameInGroup( tParts[i].nProfileId, tParts[i].sGasket)
|
|
local b3Box = EgtGetBBoxRef( nGasketId, GDB_BB.STANDARD, tParts[i].frProfile)
|
|
dOffs = b3Box:getMax():getX()
|
|
end
|
|
else
|
|
-- se non ha guarnizione è curva di trim ( quindi deve avere info)
|
|
dOffs = EgtGetInfo( tParts[i].nProfileId, WIN_TRIM .. sGasket, 'd')
|
|
if not dOffs then
|
|
-- se non ha info di trim significa che devo passare alla guarnizione successiva
|
|
vCrvs = {}
|
|
break
|
|
end
|
|
dOffs = - dOffs
|
|
tParts[i].sGasket = nil
|
|
end
|
|
|
|
-- offset
|
|
EgtOffsetCurve( nCrv, dOffs)
|
|
end
|
|
|
|
if #vCrvs > 0 then
|
|
-- taglio le curve
|
|
TrimOrderedCurves( vCrvs, true)
|
|
|
|
-- aggiorno lunghezza
|
|
for i = 1, #vCrvs do
|
|
if tParts[i].sGasket then -- devo ignorare le curve di trim
|
|
dLenTot = dLenTot + EgtCurveLength( vCrvs[i])
|
|
end
|
|
end
|
|
|
|
-- disegno
|
|
if bDraw and s_bCalcSolid then
|
|
-- recupero il gruppo per il disegno dei solidi
|
|
local nSolidLayerId = GetAuxLayer()
|
|
for i = 1, #vCrvs do
|
|
if tParts[i].sGasket then
|
|
-- estrusione principale della giunzione
|
|
local nGasketStm = CreateProfileSurf( vOutlines[i], tParts[i].nProfileId, tParts[i].sGasket, 100, nSolidLayerId)
|
|
EgtSetColor( nGasketStm, Color3d( 128, 128, 128))
|
|
EgtSetName( nGasketStm, sGasket)
|
|
|
|
-- trim start
|
|
local nPrev = EgtIf( i == 1, #vCrvs, i - 1)
|
|
local nGuideId
|
|
if not tParts[nPrev].sGasket then
|
|
-- se precedente è curva di trim la uso direttamente
|
|
nGuideId = EgtCopyGlob( vCrvs[nPrev], nSolidLayerId)
|
|
EgtInvertCurve( nGuideId)
|
|
else
|
|
-- taglio lungo la bisettrice
|
|
local vtDir = 0.5 * ( EgtSV( vCrvs[i]) - EgtEV( vCrvs[nPrev]))
|
|
if vtDir:isSmall() then
|
|
vtDir = EgtSV( vCrvs[i])
|
|
vtDir:rotate( Z_AX(), 90)
|
|
end
|
|
nGuideId = EgtLinePVL( nSolidLayerId, EgtSP( vCrvs[i]), vtDir, 200)
|
|
EgtExtendCurveStartByLen( nGuideId, 100)
|
|
end
|
|
local nTrimStart = EgtSurfTmByExtrusion( nSolidLayerId, nGuideId, - 200 * Z_AX())
|
|
EgtSurfTmIntersect( nGasketStm, nTrimStart)
|
|
EgtErase( { nGuideId, nTrimStart})
|
|
|
|
-- trim end
|
|
local nNext = EgtIf( i == #vCrvs, 1, i + 1)
|
|
if not tParts[nNext].sGasket then
|
|
nGuideId = EgtCopyGlob( vCrvs[nNext], nSolidLayerId)
|
|
else
|
|
local vtDir = 0.5 * ( EgtSV( vCrvs[nNext]) - EgtEV( vCrvs[i]))
|
|
if vtDir:isSmall() then
|
|
vtDir = EgtSV( vCrvs[nNext])
|
|
vtDir:rotate( Z_AX(), 90)
|
|
end
|
|
nGuideId = EgtLinePVL( nSolidLayerId, EgtEP( vCrvs[i]), vtDir, 200)
|
|
EgtExtendCurveStartByLen( nGuideId, 100)
|
|
end
|
|
local nTrimEnd = EgtSurfTmByExtrusion( nSolidLayerId, nGuideId, - 200 * Z_AX())
|
|
EgtInvertSurf( nTrimEnd)
|
|
EgtSurfTmIntersect( nGasketStm, nTrimEnd)
|
|
EgtErase( { nGuideId, nTrimEnd})
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- aggiorno valore lunghezza
|
|
EgtSetInfo( nAreaId, WIN_GASKET_LEN, dLenTot)
|
|
|
|
EgtErase( nGrp)
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function WinCalculate.AddAccessories( nAreaId, bDraw)
|
|
|
|
local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i')
|
|
if nAreaType == WIN_AREATYPES.FRAME then
|
|
local nOutlineLayId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE)
|
|
|
|
-- accessori del pezzo inferiore: soglia e gocciolatoio
|
|
local nBottomId = EgtGetFirstNameInGroup( nOutlineLayId, WIN_BOTTOM)
|
|
local bThreshold = EgtGetInfo( nBottomId, WIN_THRESHOLD, 'b') or false
|
|
if bThreshold then
|
|
-- soglia
|
|
CalcThreshold( nBottomId, nAreaId)
|
|
else
|
|
-- gocciolatoio
|
|
local nPartId = EgtGetInfo( nBottomId, WIN_REF_PART, 'i')
|
|
CalcWaterdrip( nPartId, nBottomId, nAreaId, bDraw)
|
|
end
|
|
|
|
-- guarnizioni se definisce direttamente anta
|
|
local nChildAreaId = EgtGetFirstNameInGroup( nAreaId, WIN_AREA .. '*') or GDB_ID.NULL
|
|
local nChildType = EgtGetInfo( nChildAreaId, WIN_AREATYPE, 'i') or WIN_AREATYPES.NULL
|
|
if nChildType == WIN_AREATYPES.SASH then
|
|
CalcGaskets( nAreaId, bDraw)
|
|
end
|
|
-- TODO guarnizioni per gocciolatoio
|
|
|
|
elseif nAreaType == WIN_AREATYPES.SASH then
|
|
-- guarnizioni
|
|
CalcGaskets( nAreaId, bDraw)
|
|
|
|
elseif nAreaType == WIN_AREATYPES.SPLIT then
|
|
-- guarnizioni se è french split
|
|
local nSplitId = EgtGetFirstNameInGroup( nAreaId, WIN_SPLIT)
|
|
local nSplitType = EgtGetInfo( nSplitId, WIN_SPLITTYPE, 'i') or WIN_SPLITTYPES.NULL
|
|
if nSplitType == WIN_SPLITTYPES.FRENCH then
|
|
CalcGaskets( nAreaId, bDraw)
|
|
end
|
|
|
|
elseif nAreaType == WIN_AREATYPES.NULL then
|
|
-- guarnizioni se ha come sottoarea un'anta
|
|
local nChildArea = EgtGetFirstNameInGroup( nAreaId, WIN_AREA .. '*') or GDB_ID.NULL
|
|
local nChildType = EgtGetInfo( nChildArea, WIN_AREATYPE, 'i') or WIN_AREATYPES.NULL
|
|
if nChildType == WIN_AREATYPES.SASH then
|
|
CalcGaskets( nAreaId, bDraw)
|
|
end
|
|
end
|
|
|
|
-- calcolo accessori per sotto-aree
|
|
local nChildAreaId = EgtGetFirstNameInGroup( nAreaId, WIN_AREA .. '*')
|
|
while nChildAreaId do
|
|
WinCalculate.AddAccessories( nChildAreaId, bDraw)
|
|
nChildAreaId = EgtGetNextName( nChildAreaId, WIN_AREA .. '*')
|
|
end
|
|
end
|
|
|
|
|
|
|
|
----------------------------------------------------------------------------------
|
|
--------------------------------- PREVIEW ----------------------------------------
|
|
----------------------------------------------------------------------------------
|
|
local function CalcBottomRailPreview( nPreviewGrp, nOutlineId, nBottomRail, nGeoGrp)
|
|
|
|
-- costruisco box complessivo degli zoccoli
|
|
local vCrvs = {}
|
|
|
|
-- la curva out corrisponde al geo in del pezzo bottom
|
|
local nPartGeoIn = EgtGetFirstNameInGroup( nGeoGrp, WIN_GEO_IN)
|
|
vCrvs[1] = EgtCopyGlob( nPartGeoIn, nPreviewGrp)
|
|
EgtInvertCurve( vCrvs[1])
|
|
|
|
-- la curva right corrisponde al geo in del pezzo adiacente
|
|
local vNextOutlines = EgtGetInfo( nOutlineId, WIN_NEXT_OUTLINES, 'vi')
|
|
local nNextPart = FindAssociatedPart( abs( vNextOutlines[1]), false)
|
|
local nNextGeo = EgtGetFirstNameInGroup( nNextPart, WIN_GEO)
|
|
local nNextIn = EgtGetFirstNameInGroup( nNextGeo, WIN_GEO_IN)
|
|
vCrvs[2] = EgtCopyGlob( nNextIn, nPreviewGrp)
|
|
EgtInvertCurve( vCrvs[2])
|
|
|
|
-- la curva in corrisponde al geo in dell'ultimo bottomrail
|
|
local vBottomRails = EgtGetInfo( nOutlineId, WIN_REF_BOTTOMRAIL_PART, 'vi')
|
|
local nBottomRailPart = vBottomRails[#vBottomRails]
|
|
local nGeoLayer = EgtGetFirstNameInGroup( nBottomRailPart, WIN_GEO)
|
|
local nGeoIn = EgtGetFirstNameInGroup( nGeoLayer, WIN_GEO_IN)
|
|
vCrvs[3] = EgtCopyGlob( nGeoIn, nPreviewGrp)
|
|
|
|
-- la curva left corrisponde al geo in del pezzo adiacente
|
|
local vPrevOutlines = EgtGetInfo( nOutlineId, WIN_PREV_OUTLINES, 'vi')
|
|
local nPrevPart = FindAssociatedPart( abs( vPrevOutlines[1]), false)
|
|
local nPrevGeo = EgtGetFirstNameInGroup( nPrevPart, WIN_GEO)
|
|
local nPrevIn = EgtGetFirstNameInGroup( nPrevGeo, WIN_GEO_IN)
|
|
vCrvs[4] = EgtCopyGlob( nPrevIn, nPreviewGrp)
|
|
EgtInvertCurve( vCrvs[4])
|
|
|
|
-- creo la regione e ne estraggo il bordo
|
|
local nAreaId = CalcIntersectionRegion( vCrvs, nPreviewGrp)
|
|
EgtSetColor( nAreaId, Color3d( 251, 128, 4))
|
|
local nCrvId = EgtExtractSurfFrChunkLoops( nAreaId, 0, nPreviewGrp)
|
|
EgtSetColor( nCrvId, EgtStdColor( 'BLACK'))
|
|
EgtModifyCurveThickness( nCrvId, 0)
|
|
|
|
-- creo linee di divisione tra gli zoccoli
|
|
if nBottomRail > 1 then
|
|
local b3Surf = EgtGetBBoxGlob( nAreaId, GDB_BB.STANDARD)
|
|
local dLen = b3Surf:getDimX()
|
|
local dH = b3Surf:getDimY()
|
|
local vBottomRailDims = EgtGetInfo( nOutlineId, WIN_BOTTOMRAIL .. WIN_PART_DIM, 'vd')
|
|
local dTotDim = 0
|
|
for i = 1, #vBottomRailDims do
|
|
dTotDim = dTotDim + vBottomRailDims[i]
|
|
end
|
|
local dPos = 0
|
|
for i = 1, nBottomRail - 1 do
|
|
dPos = dPos + vBottomRailDims[i] * dH / dTotDim
|
|
local pt = b3Surf:getMin() + dPos * Y_AX()
|
|
local nCrvId = EgtLinePVL( nPreviewGrp, pt, X_AX(), dLen)
|
|
EgtSetColor( nCrvId, EgtStdColor( 'BLACK'))
|
|
end
|
|
end
|
|
|
|
EgtErase( vCrvs)
|
|
end
|
|
|
|
----------------------------------------------------------------------------------
|
|
local function CalcPartPreview( nPartId, nPreviewGrp)
|
|
|
|
local nOutlineId = EgtGetInfo( nPartId, WIN_REF_OUTLINE, 'i')
|
|
local nGeoLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO)
|
|
|
|
-- recupero il tipo di giunzioni
|
|
local vStartJoints = EgtGetInfo( nOutlineId, WIN_STARTJOINT, 'vi')
|
|
local vEndJoints = EgtGetInfo( nOutlineId, WIN_ENDJOINT, 'vi')
|
|
|
|
local nAreaId
|
|
|
|
-- se pezzo semplice senza giunzioni short come preview posso considerare direttamente la regione del geo
|
|
if #vStartJoints == 1 and #vEndJoints == 1 and vStartJoints[1] ~= WIN_PART_JNT.SHORT and vEndJoints[1] ~= WIN_PART_JNT.SHORT then
|
|
local nGeoSurf = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_SURF)
|
|
nAreaId = EgtCopyGlob( nGeoSurf, nPreviewGrp)
|
|
EgtSetStatus( nAreaId, GDB_ST.ON)
|
|
|
|
-- altrimenti devo calcolare le curve che delimitano la regione ( in modo simile a quanto fatto in CreateGeoCurves)
|
|
else
|
|
|
|
local nGrpTmp = EgtGroup( nPreviewGrp)
|
|
|
|
local nProfileLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE)
|
|
local nProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN)
|
|
local b3Profile = GetProfileLocalBox( nProfileId)
|
|
|
|
-- a) curva out : ricalcolo curva del geo ( non posso utilizzare direttamente quella del geo perchè non deve avere estensioni)
|
|
local nOutId = EgtCopy( nOutlineId, nGrpTmp)
|
|
EgtOffsetCurve( nOutId, b3Profile:getMax():getX())
|
|
local nGeoOut = EgtGetFirstNameInGroup( nGeoLayerId, WIN_OUT)
|
|
CopyInfo( nOutId, nGeoOut, WIN_TANG_START, false)
|
|
CopyInfo( nOutId, nGeoOut, WIN_TANG_END, false)
|
|
|
|
-- b) curva in
|
|
local nInId = EgtCopy( nOutlineId, nGrpTmp)
|
|
EgtOffsetCurve( nInId, b3Profile:getMin():getX())
|
|
EgtInvertCurve( nInId)
|
|
local nGeoIn = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_IN)
|
|
CopyInfo( nInId, nGeoIn, WIN_TANG_START, false)
|
|
CopyInfo( nInId, nGeoIn, WIN_TANG_END, false)
|
|
|
|
-- c) curve left
|
|
local vGeoLeft = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_LEFT)
|
|
local vPrevOutlineId = EgtGetInfo( nOutlineId, WIN_PREV_OUTLINES, 'vi')
|
|
local vPrevProfileId = EgtGetNameInGroup( nProfileLayerId, WIN_PRF_START)
|
|
for i = 1, #vPrevOutlineId do
|
|
|
|
if vStartJoints[i] == WIN_PART_JNT.ANGLED then
|
|
-- recupero la bisettrice dal geo
|
|
for k = 1, #vGeoLeft do
|
|
if EgtGetInfo( vGeoLeft[k], WIN_REF_OUTLINE, 'i') == vPrevOutlineId[i] and not EgtExistsInfo( vGeoLeft[k], WIN_SEMI_PROFILE) then
|
|
EgtCopyGlob( vGeoLeft[k], nGrpTmp)
|
|
end
|
|
end
|
|
-- curva aux : considero l'out del pezzo precedente
|
|
local nCrvId = EgtCopyGlob( abs( vPrevOutlineId[1]), nGrpTmp)
|
|
local b3Profile = GetProfileLocalBox( vPrevProfileId[1])
|
|
EgtOffsetCurve( nCrvId, b3Profile:getMax():getX())
|
|
else
|
|
|
|
-- se è pezzo del telaio contro soglia lo tratto come se fosse full
|
|
if EgtGetName( nOutlineId) ~= WIN_SPLIT and EgtGetInfo( abs( vPrevOutlineId[i]), WIN_THRESHOLD, 'b') then
|
|
vStartJoints[i] = WIN_PART_JNT.FULL
|
|
end
|
|
|
|
if vStartJoints[i] == WIN_PART_JNT.SHORT then
|
|
local b3Profile = GetProfileLocalBox( vPrevProfileId[i])
|
|
local nCrvId = EgtCopy( abs( vPrevOutlineId[i]), nGrpTmp)
|
|
local dRailDelta = EgtGetInfo( vPrevProfileId[i], WIN_RAILOFFS, 'd') or 0
|
|
local dOffs = b3Profile:getMin():getX() - dRailDelta
|
|
if vPrevOutlineId[i] < 0 then
|
|
EgtInvertCurve( nCrvId)
|
|
dOffs = - b3Profile:getMax():getX()
|
|
end
|
|
EgtOffsetCurve( nCrvId, dOffs)
|
|
|
|
-- per un risultato graficamente migliore se il pezzo precedente è in tangenza con il vicino, impongo estensione in tangenza, altrimenti considero quella
|
|
-- calcolata dal geo
|
|
local nStartType = EgtGetInfo( abs( vPrevOutlineId[i]), WIN_STARTJOINT, 'i')
|
|
if nStartType == WIN_PART_JNT.ANGLED then
|
|
EgtSetInfo( nCrvId, WIN_TANG_START, true)
|
|
else
|
|
CopyInfo( nCrvId, vGeoLeft[i], WIN_TANG_START, false)
|
|
end
|
|
local nEndType = EgtGetInfo( abs( vPrevOutlineId[i]), WIN_ENDJOINT, 'i')
|
|
if nEndType == WIN_PART_JNT.ANGLED then
|
|
EgtSetInfo( nCrvId, WIN_TANG_END, true)
|
|
else
|
|
CopyInfo( nCrvId, vGeoLeft[i], WIN_TANG_END, false)
|
|
end
|
|
|
|
else -- full
|
|
-- considero l'out del pezzo precedente
|
|
local nCrvId = EgtCopy( abs( vPrevOutlineId[i]), nGrpTmp)
|
|
local b3Profile = GetProfileLocalBox( vPrevProfileId[i])
|
|
local dOffs = b3Profile:getMax():getX()
|
|
if vPrevOutlineId[i] < 0 then
|
|
EgtInvertCurve( nCrvId)
|
|
dOffs = - b3Profile:getMin():getX()
|
|
end
|
|
EgtOffsetCurve( nCrvId, dOffs)
|
|
CopyInfo( nCrvId, vGeoLeft[i], WIN_TANG_START, false)
|
|
CopyInfo( nCrvId, vGeoLeft[i], WIN_TANG_END, false)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- d) curve right
|
|
local vGeoRight = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_RIGHT)
|
|
local vNextOutlineId = EgtGetInfo( nOutlineId, WIN_NEXT_OUTLINES, 'vi')
|
|
local vNextProfileId = EgtGetNameInGroup( nProfileLayerId, WIN_PRF_END)
|
|
|
|
for i = 1, #vNextOutlineId do
|
|
|
|
if vEndJoints[i] == WIN_PART_JNT.ANGLED then
|
|
-- recupero la bisettrice dal geo
|
|
local nCrvId
|
|
for k = 1, #vGeoRight do
|
|
if EgtGetInfo( vGeoRight[k], WIN_REF_OUTLINE, 'i') == vNextOutlineId[i] and not EgtExistsInfo( vGeoRight[k], WIN_SEMI_PROFILE) then
|
|
nCrvId = EgtCopyGlob( vGeoRight[k], nGrpTmp)
|
|
EgtRelocateGlob( nCrvId, nInId, GDB_IN.BEFORE)
|
|
end
|
|
end
|
|
-- curva aux
|
|
local nAuxCrv = EgtCopyGlob( abs( vNextOutlineId[i]), nGrpTmp)
|
|
local b3Profile = GetProfileLocalBox( vNextProfileId[i])
|
|
EgtOffsetCurve( nAuxCrv, b3Profile:getMax():getX())
|
|
EgtRelocateGlob( nAuxCrv, nInId, GDB_IN.BEFORE)
|
|
else
|
|
|
|
local nCrvId
|
|
-- se è pezzo del telaio contro soglia lo tratto come se fosse full
|
|
if EgtGetName( nOutlineId) ~= WIN_SPLIT and EgtGetInfo( abs( vNextOutlineId[i]), WIN_THRESHOLD, 'b') then
|
|
vEndJoints[i] = WIN_PART_JNT.FULL
|
|
end
|
|
|
|
if vEndJoints[i] == WIN_PART_JNT.SHORT then
|
|
nCrvId = EgtCopyGlob( abs( vNextOutlineId[i]), nGrpTmp)
|
|
local b3Profile = GetProfileLocalBox( vNextProfileId[i])
|
|
local dRailDelta = EgtGetInfo( vNextProfileId[i], WIN_RAILOFFS, 'd') or 0
|
|
local dOffs = b3Profile:getMin():getX() - dRailDelta
|
|
if vNextOutlineId[i] < 0 then
|
|
EgtInvertCurve( nCrvId)
|
|
dOffs = - b3Profile:getMax():getX()
|
|
end
|
|
EgtOffsetCurve( nCrvId, dOffs)
|
|
|
|
local nStartType = EgtGetInfo( abs( vNextOutlineId[i]), WIN_STARTJOINT, 'i')
|
|
if nStartType == WIN_PART_JNT.ANGLED then
|
|
EgtSetInfo( nCrvId, WIN_TANG_START, true)
|
|
else
|
|
CopyInfo( nCrvId, vGeoRight[i], WIN_TANG_START, false)
|
|
end
|
|
local nEndType = EgtGetInfo( abs( vNextOutlineId[i]), WIN_ENDJOINT, 'i')
|
|
if nEndType == WIN_PART_JNT.ANGLED then
|
|
EgtSetInfo( nCrvId, WIN_TANG_END, true)
|
|
else
|
|
CopyInfo( nCrvId, vGeoRight[i], WIN_TANG_END, false)
|
|
end
|
|
|
|
else -- full
|
|
local b3Profile = GetProfileLocalBox( vNextProfileId[i])
|
|
nCrvId = EgtCopyGlob( abs( vNextOutlineId[i]), nGrpTmp)
|
|
local dOffs = b3Profile:getMax():getX()
|
|
if vNextOutlineId[i] < 0 then
|
|
EgtInvertCurve( nCrvId)
|
|
dOffs = - b3Profile:getMin():getX()
|
|
end
|
|
EgtOffsetCurve( nCrvId, dOffs)
|
|
CopyInfo( nCrvId, vGeoRight[i], WIN_TANG_START, false)
|
|
CopyInfo( nCrvId, vGeoRight[i], WIN_TANG_END, false)
|
|
end
|
|
EgtRelocateGlob( nCrvId, nInId, GDB_IN.BEFORE)
|
|
end
|
|
end
|
|
|
|
local vIds = EgtGetAllInGroup( nGrpTmp)
|
|
nAreaId = CalcGeoRegion( vIds, nPreviewGrp)
|
|
EgtErase( nGrpTmp)
|
|
end
|
|
|
|
-- se pezzo scompare
|
|
if not nAreaId then
|
|
return
|
|
end
|
|
|
|
-- sistemo la regione
|
|
local nParentAreaId = EgtGetParent( EgtGetParent( nOutlineId))
|
|
local nAreaType = EgtGetInfo( nParentAreaId, WIN_AREATYPE, 'i')
|
|
if nAreaType == WIN_AREATYPES.SASH then
|
|
-- se anta traslazione per gestire meglio i casi di telaio e ante allineati
|
|
EgtMove( nAreaId, Vector3d( 0, 0, - 0.1))
|
|
-- se anta con parte ricevente traslazione per evitare sovrapposizione con parte battente
|
|
local nSashType = EgtGetInfo( nParentAreaId, WIN_SASHTYPE, 'i')
|
|
if nSashType == WIN_SASHTYPES.INACTIVE or nSashType == WIN_SASHTYPES.INACTIVE_IN or nSashType == WIN_SASHTYPES.ACTIVE_OUT then
|
|
EgtMove( nAreaId, Vector3d( 0, 0, - 0.1))
|
|
elseif nSashType == WIN_SASHTYPES.INACTIVE_OUT then
|
|
EgtMove( nAreaId, Vector3d( 0, 0, - 0.2))
|
|
end
|
|
elseif nAreaType == WIN_AREATYPES.SPLIT then
|
|
-- se inglesina esterna la abbasso per averla sotto il vetro
|
|
if EgtGetInfo( nOutlineId, WIN_MUNTINFILL_SIDE, 'i') == WIN_MUNTINFILL_SIDES.OUT then
|
|
EgtMove( nAreaId, Vector3d( 0, 0, - 1000))
|
|
end
|
|
end
|
|
EgtSetColor( nAreaId, Color3d( 251, 128, 4))
|
|
-- estraggo il contorno
|
|
local nCompoId = EgtExtractSurfFrChunkLoops( nAreaId, 0, nPreviewGrp)
|
|
EgtSetColor( nCompoId, EgtStdColor( 'BLACK'))
|
|
|
|
-- se bottom aggiungo anche eventuale preview del bottomrail
|
|
if EgtGetName( nOutlineId) == WIN_BOTTOM then
|
|
local nBottomRail = EgtGetInfo( nOutlineId, WIN_BOTTOMRAIL, 'i') or 0
|
|
if nBottomRail > 0 then
|
|
CalcBottomRailPreview( nPreviewGrp, nOutlineId, nBottomRail, nGeoLayerId)
|
|
end
|
|
end
|
|
end
|
|
|
|
----------------------------------------------------------------------------------
|
|
local function CalcFillPreview( nPartId, nPreviewGrp)
|
|
-- creo bordo a partire dall'outline
|
|
local nAreaId = EgtGetInfo( nPartId, WIN_AREA, 'i')
|
|
local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE)
|
|
local vOutlineList = EgtGetAllInGroup( nOutlineLayerId)
|
|
local nCompoOutlineId = EgtCurveCompoByChain( nPreviewGrp, vOutlineList, EgtSP( vOutlineList[1]), false)
|
|
-- creo area
|
|
local nSurfId = EgtSurfFlatRegion( nPreviewGrp, {nCompoOutlineId})
|
|
EgtSetColor( nSurfId, EgtGetColor( nPartId))
|
|
EgtErase( nCompoOutlineId)
|
|
end
|
|
|
|
----------------------------------------------------------------------------------
|
|
local function CalcThresholdPreview( nAreaId, nPreviewGrp)
|
|
-- recupero il bottom del telaio
|
|
local nOutlineGrpId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE)
|
|
local nBottomId = EgtGetFirstNameInGroup( nOutlineGrpId, WIN_BOTTOM)
|
|
local nProfileId = GetOutlineProfileId( nBottomId, false)
|
|
local b3Profile = GetProfileLocalBox( nProfileId)
|
|
-- creo il rettangolo della soglia e lo posiziono sullo sfondo
|
|
local ptOrig = EgtSP( nBottomId)
|
|
local nSurfId = EgtSurfFrRectangle( nPreviewGrp, ptOrig, ptOrig + EgtCurveLength( nBottomId) * X_AX() + b3Profile:getDimX() * Y_AX())
|
|
EgtSetColor( nSurfId, Color3d( 128, 128, 128))
|
|
EgtMove( nSurfId, - 500 * Z_AX())
|
|
local nCompoId = EgtExtractSurfFrChunkLoops( nSurfId, 0, nPreviewGrp)
|
|
EgtSetColor( nCompoId, EgtStdColor( 'BLACK'))
|
|
end
|
|
|
|
----------------------------------------------------------------------------------
|
|
local function CalcHardwarePreview( nAreaId, nPreviewGrp)
|
|
|
|
local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i')
|
|
if nAreaType == WIN_AREATYPES.SASH then
|
|
-- se anta disegno la ferramenta se è definita
|
|
local sHdwFavourite = EgtGetInfo( nAreaId, WIN_HDW_FAVOURITE)
|
|
if sHdwFavourite and sHdwFavourite ~= WIN_HDW_NULL then
|
|
DrawSashHardware( nAreaId, nAreaId, nPreviewGrp, true)
|
|
end
|
|
return
|
|
|
|
elseif nAreaType == WIN_AREATYPES.SPLIT then
|
|
local nSplitType = EgtGetInfo( nAreaId, WIN_SPLITTYPE, 'i') or WIN_SPLITTYPES.NULL
|
|
if nSplitType == WIN_SPLITTYPES.FRENCH then
|
|
local sHdwFavourite = EgtGetInfo( nAreaId, WIN_HDW_FAVOURITE)
|
|
if sHdwFavourite and sHdwFavourite ~= WIN_HDW_NULL then
|
|
-- disegno ferramenta per tutte le ante avendo come gruppo di riferimento delle info il parent dell'area split french
|
|
local vSashes = EgtGetNameInGroup( nAreaId, WIN_AREA .. '*')
|
|
for j = 1, #vSashes do
|
|
DrawSashHardware( vSashes[j], nAreaId, nPreviewGrp, true)
|
|
end
|
|
end
|
|
return
|
|
else
|
|
-- se non è split french devo controllare le sue sottoaree
|
|
local vChildrenAreas = EgtGetNameInGroup( nAreaId, WIN_AREA .. '*') or {}
|
|
for i = 1, #vChildrenAreas do
|
|
CalcHardwarePreview( vChildrenAreas[i], nPreviewGrp)
|
|
end
|
|
end
|
|
else
|
|
-- controllo le sue sottoaree
|
|
local vChildrenAreas = EgtGetNameInGroup( nAreaId, WIN_AREA .. '*') or {}
|
|
for i = 1, #vChildrenAreas do
|
|
CalcHardwarePreview( vChildrenAreas[i], nPreviewGrp)
|
|
end
|
|
end
|
|
end
|
|
|
|
----------------------------------------------------------------------------------
|
|
local function CalcPreview( nFrameId)
|
|
|
|
-- creo gruppo per la preview
|
|
local nPreviewGrp = EgtGroup( GDB_ID.ROOT)
|
|
EgtSetName( nPreviewGrp, WIN_PREVIEW)
|
|
EgtSetLevel( nPreviewGrp, GDB_LV.SYSTEM)
|
|
EgtSetStatus( nPreviewGrp, GDB_ST.OFF)
|
|
|
|
-- scorro tutti i pezzi e ne realizzo la preview
|
|
local nPartId = EgtGetFirstPart()
|
|
while nPartId do
|
|
local nPartType = EgtGetInfo( nPartId, WIN_PART_TYPE, 'i') or WIN_PART_TYPES.NULL
|
|
if nPartType == WIN_PART_TYPES.FILL then
|
|
CalcFillPreview( nPartId, nPreviewGrp)
|
|
elseif nPartType == WIN_PART_TYPES.BOTTOMRAIL then
|
|
-- pezzo di bottomrail viene ignorato perchè già creato con il corrispondente pezzo bottom
|
|
else
|
|
CalcPartPreview( nPartId, nPreviewGrp)
|
|
end
|
|
nPartId = EgtGetNextPart( nPartId)
|
|
end
|
|
|
|
-- preview soglia
|
|
local nOutlineGrpId = EgtGetFirstNameInGroup( nFrameId, WIN_OUTLINE)
|
|
local nBottomId = EgtGetFirstNameInGroup( nOutlineGrpId, WIN_BOTTOM)
|
|
local bThreshold = EgtGetInfo( nBottomId, WIN_THRESHOLD, 'b') or false
|
|
if bThreshold then
|
|
CalcThresholdPreview( nFrameId, nPreviewGrp)
|
|
end
|
|
|
|
-- copio i disegni di apertura delle ante dal gruppo delle aree
|
|
local vStack = { nFrameId}
|
|
local i = 1
|
|
while i <= #vStack do
|
|
local nAreaType = EgtGetInfo( vStack[i], WIN_AREATYPE, 'i')
|
|
if nAreaType == WIN_AREATYPES.SASH then
|
|
local nOpeningGrp = EgtGetFirstNameInGroup( vStack[i], WIN_SASH_OPENING)
|
|
local vOpeningCrvs = EgtGetAllInGroup( nOpeningGrp)
|
|
for j = 1, #vOpeningCrvs do
|
|
local nId = EgtCopyGlob( vOpeningCrvs[j], nPreviewGrp)
|
|
EgtSetColor( nId, EgtStdColor( 'BLACK'))
|
|
end
|
|
else
|
|
-- aggiungo allo stack di aree da controllare le sue aree figlie
|
|
local vChildrenAreas = EgtGetNameInGroup( vStack[i], WIN_AREA .. '*') or {}
|
|
vStack = EgtJoinTables( vStack, vChildrenAreas)
|
|
end
|
|
i = i + 1
|
|
end
|
|
|
|
-- preview ferramenta
|
|
CalcHardwarePreview( nFrameId, nPreviewGrp)
|
|
end
|
|
|
|
|
|
|
|
----------------------------------------------------------------------------------
|
|
------------------------------ FUNZIONI ----------------------------------------
|
|
----------------------------------------------------------------------------------
|
|
-- funzione che crea tutti i pezzi della finestra partendo dal telaio
|
|
function WinCalculate.CreatePartFromArea( nFrameId)
|
|
s_nSashNbr = 0
|
|
|
|
-- assegno il tipo di profilo alle curve del base outline
|
|
CalculateAreaProfileType( nFrameId)
|
|
-- calcolo outline a partire dal base outline
|
|
CalculateAreaOutline( nFrameId)
|
|
SetAreaProfiles( nFrameId)
|
|
-- creo i pezzi con i profili
|
|
CreateAreaParts( nFrameId)
|
|
GetAreaPrevNextOutlines( nFrameId)
|
|
-- creo pezzi
|
|
CalculateAreaParts( nFrameId)
|
|
-- calcolo le spine
|
|
CalculateAreaDowels( nFrameId)
|
|
|
|
-- calcolo preview 2d se richiesta
|
|
if s_bCalcPreview then
|
|
CalcPreview( nFrameId)
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
return WinCalculate
|