057fb91994
- correzione a SetAreaProfiles.
7641 lines
332 KiB
Lua
7641 lines
332 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
|
|
|
|
---------------------------------------------------------------------
|
|
-- 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 formata da una sola sottocurva viene gestita come curva semplice
|
|
if nType1 == GDB_TY.CRV_COMPO then
|
|
local _, dE = EgtCurveDomain( nCrv1)
|
|
if abs( dE - 1) < GEO.EPS_SMALL then
|
|
nCrv1 = EgtCopyCompoSubCurve( nCrv1, 0, nGrp)
|
|
nType1 = EgtGetType( nCrv1)
|
|
end
|
|
end
|
|
if nType2 == GDB_TY.CRV_COMPO then
|
|
local _, dE = EgtCurveDomain( nCrv2)
|
|
if abs( dE - 1) < GEO.EPS_SMALL then
|
|
nCrv2 = EgtCopyCompoSubCurve( nCrv2, 0, nGrp)
|
|
nType2 = EgtGetType( nCrv2)
|
|
end
|
|
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 date due curve parzialmente sovrapposte con nCrvId composita, allunga nCrvId aggiungendo i tratti di nRefCrvId che fuoriescono da essa
|
|
local function AddExtension( nCrvId, nRefCrvId)
|
|
|
|
local dParS = EgtCurveParamAtPoint( nCrvId, EgtSP( nRefCrvId), 100 * GEO.EPS_SMALL)
|
|
if not dParS then
|
|
local dParTrim = EgtCurveParamAtPoint( nRefCrvId, EgtSP( nCrvId), 100 * GEO.EPS_SMALL)
|
|
local nNewCrv = EgtCopyParamRange( nRefCrvId, 0, dParTrim, EgtGetParent( nCrvId))
|
|
EgtAddCurveCompoCurve( nCrvId, nNewCrv, true, false)
|
|
end
|
|
|
|
local dParE = EgtCurveParamAtPoint( nCrvId, EgtEP( nRefCrvId), 100 * GEO.EPS_SMALL)
|
|
if not dParE then
|
|
local dParTrim = EgtCurveParamAtPoint( nRefCrvId, EgtEP( nCrvId), 100 * GEO.EPS_SMALL)
|
|
local _, dE = EgtCurveDomain( nRefCrvId)
|
|
local nNewCrv = EgtCopyParamRange( nRefCrvId, dParTrim, dE, EgtGetParent( nCrvId))
|
|
EgtAddCurveCompoCurve( nCrvId, nNewCrv)
|
|
end
|
|
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 ( verificando di non avere circonferenze coincidenti)
|
|
-- 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 dRad = EgtArcRadius( vCrvs[i])
|
|
|
|
-- se circonferenza verifico di non averla già considerata
|
|
local bTangentStart = EgtGetInfo( vCrvs[i], WIN_TANG_START, 'b') or false
|
|
local bTangentEnd = EgtGetInfo( vCrvs[i], WIN_TANG_END, 'b') or false
|
|
if not bTangentStart and not bTangentEnd then
|
|
local ptC = EgtCP( vCrvs[i])
|
|
local bOverlap = false
|
|
for j = 1, #tArcs do
|
|
if tArcs[j].ptC and AreSamePointApprox( tArcs[j].ptC, ptC) and abs( tArcs[j].dRad - dRad) < GEO.EPS_SMALL then
|
|
bOverlap = true
|
|
table.insert( tArcs[j].vOrigId, vCrvs[i])
|
|
break
|
|
end
|
|
end
|
|
if not bOverlap then
|
|
local nCrvId = CreateCurveExtension( vCrvs[i], nGrpTmp)
|
|
table.insert( tArcs, { nCrvId = nCrvId, vOrigId = { vCrvs[i]}, dRad = dRad, ptC = ptC})
|
|
end
|
|
else
|
|
local nCrvId = CreateCurveExtension( vCrvs[i], nGrpTmp)
|
|
table.insert( tArcs, { nCrvId = nCrvId, vOrigId = { vCrvs[i]}, dRad = dRad})
|
|
end
|
|
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, vOrigId = { 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 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
|
|
|
|
-- modifico il bordo corrente considerando solo i tratti che poggiano sulle curve originali
|
|
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
|
|
|
|
EgtRelocateGlob( nSurfId, nGrp)
|
|
EgtErase( nGrpTmp)
|
|
return nSurfId
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- Gestione delle curve superflue in TrimOrderedCurves : le modalità di trattamento sono indicate da nMode e sono le seguenti
|
|
-- 0/nil = curva eliminata ( caso standard)
|
|
-- 1 = curva eliminata rimuovendo la corrispondenza dalle info della curva di base outline da cui deriva ( se chiamata da outline)
|
|
-- 2 = curva non viene eliminata ma viene settata info che indica di ignorarla ( se chiamata dal geo)
|
|
local function AdjustExtraCurvesForTrim( nCrvId, nSurfId, nMode)
|
|
|
|
if not nMode or nMode == 0 then
|
|
EgtErase( nCrvId)
|
|
|
|
elseif nMode == 1 then
|
|
-- rimuovo la info che riconduce alla curva che sto per eliminare dalla curva corrispondente del base outline
|
|
local nBaseOutline = EgtGetInfo( nCrvId, WIN_COPY, 'i')
|
|
EgtRemoveInfo( nBaseOutline, WIN_COPY)
|
|
-- elimino la curva
|
|
EgtErase( nCrvId)
|
|
|
|
elseif nMode == 2 then
|
|
-- se la curva è fuori dalla regione non va eliminata ma viene settata info che indica di ignorarla
|
|
EgtSetInfo( nCrvId, WIN_GEO_EXTRA, true)
|
|
EgtSetStatus( nCrvId, GDB_ST.OFF)
|
|
end
|
|
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, nExtraCurvesMode, 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
|
|
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
|
|
|
|
-- 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 curve successive
|
|
nC = ( nC + 1) % #vCrvs
|
|
nB = ( nB + 1) % nCnt
|
|
|
|
until nB == nFirstIdxBorder
|
|
|
|
-- sostituisco le curve originali con quelle di bordo appena calcolate
|
|
local vResultCurves = {}
|
|
for i = 1, #vCrvs do
|
|
|
|
if not tabAss[vCrvs[i]] then
|
|
-- se non ha curve di bordo associate è extra curve da gestire in modo speciale
|
|
AdjustExtraCurvesForTrim( vCrvs[i], nSurfId, nExtraCurvesMode)
|
|
|
|
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
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che data una curva di outline restituisce l'id del suo profilo
|
|
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 recupera il pezzo associato ad un outline
|
|
local function FindAssociatedPart( nOutlineId, bUseBottomRail)
|
|
|
|
local nCrvId = nOutlineId
|
|
local nPartId = EgtGetInfo( nCrvId, WIN_REF_PART, 'i')
|
|
if not nPartId then
|
|
-- cerco la prima curva da cui deriva che ha un pezzo associato
|
|
-- recupero il base outline da cui deriva
|
|
local nBaseOutline = EgtGetInfo( nOutlineId, WIN_COPY, 'i')
|
|
nBaseOutline = EgtGetInfo( nBaseOutline, WIN_SOU, 'i')
|
|
while nBaseOutline and not nPartId do
|
|
-- verifico se ha un profilo associato ( e quindi un pezzo)
|
|
local sProfileType = EgtGetInfo( nBaseOutline, WIN_PROFILETYPE)
|
|
if sProfileType then
|
|
-- recupero l'outline associato
|
|
nCrvId = EgtGetInfo( nBaseOutline, WIN_COPY, 'i')
|
|
nPartId = EgtGetInfo( nCrvId, WIN_REF_PART, 'i')
|
|
end
|
|
nBaseOutline = EgtGetInfo( nBaseOutline, WIN_SOU, 'i')
|
|
end
|
|
end
|
|
|
|
-- 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)
|
|
local sPrevCtrIn = WIN_CTRIN
|
|
-- gestione particolare del caso di split o cambio profilo
|
|
if not EgtGetFirstNameInGroup( nPrevProfileId, sPrevCtrIn) then
|
|
|
|
local nRefSplitId = EgtGetInfo( nPrevOutlineId, WIN_REF_SPLIT, 'i')
|
|
if nRefSplitId or EgtGetName( nPrevOutlineId) == WIN_SPLIT then
|
|
-- 1) split
|
|
-- verifico da quale lato dello split originale si trova l'outline per decidere quale controprofilo considerare
|
|
local _, _, nSide = EgtPointCurveDistSide( EgtMP( nOutlineId), nRefSplitId or nPrevOutlineId, Z_AX())
|
|
if nSide == 1 then
|
|
sPrevCtrIn = WIN_CTRIN .. '1' -- dx
|
|
else
|
|
sPrevCtrIn = WIN_CTRIN .. '2' -- sx
|
|
end
|
|
else
|
|
-- 2) pezzo del telaio con cambio profilo
|
|
-- il profilo da usare dipende dal pezzo corrente: se ha figli di tipo fill allora è legato alla parte fill del cambio profilo, se ha figli di tipo sash è legato alla parte sash,
|
|
-- se ha entrambe le tipologie di figli allora è mixed split e va considerata la parte sash ( perchè è quella utilizzata per tagliare il pezzo)
|
|
local vSashChildren = EgtGetInfo( nOutlineId, WIN_SASH_CHILDREN, 'vi')
|
|
if vSashChildren then
|
|
sPrevCtrIn = WIN_SASH .. WIN_CTRIN
|
|
else
|
|
sPrevCtrIn = WIN_FILL .. WIN_CTRIN
|
|
end
|
|
end
|
|
end
|
|
|
|
return sPrevCtrIn
|
|
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
|
|
|
|
-- verifico se necessaria inversione della guida nel caso sia curva "virtuale" ( ovvero in area null o split) che deriva da pezzo di split
|
|
if EgtExistsInfo( nOutlineId, WIN_INV_SPLIT) then
|
|
EgtInvertCurve( nGuideId)
|
|
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 PER BASEOUTLINES ---------------------
|
|
----------------------------------------------------------------------------------
|
|
-- funzione che restituisce il primo tipo di area definito tra le sottoaree che si generano da nAreaId
|
|
local function GetAreaChildrenType( nAreaId)
|
|
|
|
local vStack = EgtGetNameInGroup( nAreaId, WIN_AREA .. '*') or {}
|
|
local i = 1
|
|
while vStack[i] do
|
|
local nType = EgtGetInfo( vStack[i], WIN_AREATYPE, 'i')
|
|
-- appena trovo un tipo definito esco
|
|
if nType == WIN_AREATYPES.FILL then
|
|
return WIN_CHILDREN_TYPES.FILL
|
|
elseif nType == WIN_AREATYPES.SASH then
|
|
return WIN_CHILDREN_TYPES.SASH
|
|
else
|
|
-- altrimenti analizzo le sottoaree
|
|
local vSubAreas = EgtGetNameInGroup( vStack[i], WIN_AREA .. '*') or {}
|
|
vStack = EgtJoinTables( vStack, vSubAreas)
|
|
end
|
|
i = i + 1
|
|
end
|
|
-- se non trovo un tipo definito
|
|
return WIN_CHILDREN_TYPES.NULL
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function GetClosestAreaChildrenType( nAreaId)
|
|
|
|
local nChildrenType = WIN_CHILDREN_TYPES.NULL
|
|
local nType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i')
|
|
while nChildrenType == WIN_CHILDREN_TYPES.NULL and nType ~= WIN_AREATYPES.FRAME do
|
|
nAreaId = EgtGetParent( nAreaId)
|
|
nType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i')
|
|
nChildrenType = GetAreaChildrenType( nAreaId)
|
|
end
|
|
|
|
return nChildrenType
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che verifica la tipologia delle curve figlie di una curva
|
|
local function GetChildrenType( 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( 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
|
|
-- recupero i suoi figli
|
|
local vChildren = EgtGetInfo( vStack[i], WIN_CHILD, 'vi') or {}
|
|
if #vChildren == 0 then
|
|
-- se non ha figli, per non creare problemi nel caso di cambio profilo ( in cui è necessario conoscere la struttura completa),
|
|
-- assegno come tipologia quella dell'area più "vicina" nella struttura delle aree
|
|
local nCurrType = GetClosestAreaChildrenType( nAreaId)
|
|
if nCurrType == WIN_CHILDREN_TYPES.FILL then
|
|
table.insert( vFillChildren, vStack[i])
|
|
elseif nCurrType == WIN_CHILDREN_TYPES.SASH then
|
|
table.insert( vSashChildren, vStack[i])
|
|
end
|
|
end
|
|
-- aggiungo i suoi figli tra gli elementi da analizzare
|
|
vStack = EgtJoinTables( vStack, vChildren)
|
|
end
|
|
-- aggiorno il contatore
|
|
i = i + 1
|
|
end
|
|
|
|
-- salvo i figli individuati come info della curva
|
|
EgtSetInfo( nCrvId, WIN_SASH_CHILDREN, vSashChildren)
|
|
EgtSetInfo( nCrvId, WIN_FILL_CHILDREN, vFillChildren)
|
|
|
|
if #vFillChildren > 0 and #vSashChildren > 0 then
|
|
return WIN_CHILDREN_TYPES.MIXED -- cambio profilo
|
|
elseif #vFillChildren > 0 then
|
|
return WIN_CHILDREN_TYPES.FILL
|
|
elseif #vSashChildren > 0 then
|
|
return WIN_CHILDREN_TYPES.SASH
|
|
else
|
|
return WIN_CHILDREN_TYPES.NULL
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che identifica il tipo di split ( mullion, mixed, ...)
|
|
local function GetSplitType( nSplitId, nSplitLayerId)
|
|
|
|
local nSplitType = EgtGetInfo( nSplitLayerId, WIN_SPLITTYPE, 'i')
|
|
-- la tipologia è salvata nel layer solo se si tratta di un french split, negli altri casi va calcolata
|
|
if not nSplitType then
|
|
-- controllo se è dentro anta o telaio
|
|
local nParentAreaId = EgtGetParent( nSplitLayerId)
|
|
local nParentAreaType = EgtGetInfo( nParentAreaId, WIN_AREATYPE, 'i') or WIN_AREATYPES.NULL
|
|
while nParentAreaId and nParentAreaType ~= WIN_AREATYPES.SASH and nParentAreaType ~= WIN_AREATYPES.FRAME do
|
|
nParentAreaId = EgtGetParent( nParentAreaId)
|
|
nParentAreaType = EgtGetInfo( nParentAreaId or GDB_ID.NULL, WIN_AREATYPE, 'i') or WIN_AREATYPES.NULL
|
|
end
|
|
|
|
if nParentAreaType == WIN_AREATYPES.SASH then
|
|
-- se dentro anta
|
|
nSplitType = WIN_SPLITTYPES.INSASH
|
|
else
|
|
-- se dentro telaio verifico la tipologia dei figli
|
|
local nChildrenType = GetChildrenType( nSplitId)
|
|
if nChildrenType == WIN_CHILDREN_TYPES.MIXED then
|
|
nSplitType = WIN_SPLITTYPES.MIXED
|
|
elseif nChildrenType == WIN_CHILDREN_TYPES.FILL then
|
|
nSplitType = WIN_SPLITTYPES.INFRAME
|
|
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, nCurrId)
|
|
-- recupero l'altro child dello split
|
|
local vSplitChildren = EgtGetInfo( nSplitId, WIN_CHILD, 'vi')
|
|
local nAdjChild = EgtIf( vSplitChildren[1] == nCurrId, vSplitChildren[2], vSplitChildren[1])
|
|
-- recupero la sua tipologia dalla sua area
|
|
local nAdjSash = EgtGetParent( EgtGetParent( nAdjChild))
|
|
local nAdjType = EgtGetInfo( nAdjSash, WIN_SASHTYPE, 'i')
|
|
return nAdjType
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che imposta i tipi di profilo in base al tipo di pezzi
|
|
local function CalcProfileType( 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 = GetChildrenType( nOutlineId)
|
|
|
|
-- a) se non definiti gestisco come anta o fixed
|
|
if nChildrenType == WIN_CHILDREN_TYPES.NULL then
|
|
local nBottomRail = EgtGetInfo( nAreaId, WIN_BOTTOMRAIL, 'i') or 0
|
|
if nBottomRail > 0 then
|
|
-- se bottomrail gestisco come fixed
|
|
if sName == WIN_BOTTOM then
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_RAIL .. '_' .. sThreshold)
|
|
else
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_FIXED_TOP)
|
|
end
|
|
else
|
|
-- se no bottomrail gestisco come anta
|
|
if sName == WIN_BOTTOM then
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SASH .. '_' .. sThreshold)
|
|
else
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SASH_TOP)
|
|
end
|
|
end
|
|
|
|
-- b) se anta
|
|
elseif nChildrenType == WIN_CHILDREN_TYPES.SASH then
|
|
EgtRemoveInfo( nAreaId, WIN_BOTTOMRAIL)
|
|
-- verifico tipologia di anta contro cui poggia
|
|
local vChildren = EgtGetInfo( nOutlineId, WIN_SASH_CHILDREN, 'vi')
|
|
local nSashArea = EgtGetParent( EgtGetParent( vChildren[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
|
|
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, #vChildren do
|
|
local nSashArea = EgtGetParent( EgtGetParent( vChildren[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
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SASH .. '_' .. sThreshold)
|
|
else
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SASH_TOP)
|
|
end
|
|
end
|
|
|
|
-- c) se riempimento
|
|
elseif nChildrenType == WIN_CHILDREN_TYPES.FILL 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
|
|
|
|
-- d) se cambio profilo
|
|
elseif nChildrenType == WIN_CHILDREN_TYPES.MIXED then
|
|
EgtRemoveInfo( nAreaId, WIN_BOTTOMRAIL)
|
|
EgtSetInfo( nOutlineId, WIN_PRF_CHANGE, true)
|
|
if sName == WIN_BOTTOM then
|
|
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], nSplitLayerId)
|
|
|
|
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.INSASH then
|
|
EgtSetInfo( vSplitIds[i], WIN_PROFILETYPE, WIN_SASH_SPLIT)
|
|
|
|
elseif nSplitType == WIN_SPLITTYPES.INFRAME then
|
|
EgtSetInfo( vSplitIds[i], WIN_PROFILETYPE, WIN_FRAME_SPLIT)
|
|
|
|
elseif nSplitType == WIN_SPLITTYPES.MIXED then
|
|
EgtSetInfo( vSplitIds[i], WIN_PROFILETYPE, WIN_MIXED_SPLIT)
|
|
EgtSetInfo( vSplitIds[i], WIN_PRF_CHANGE, true)
|
|
|
|
-- verifico se l'orientamento dello split è coerente con il cambio profilo ( vetro fisso a destra e anta a sinistra) :
|
|
-- recupero il lato da cui si trova il figlio di tipo anta
|
|
local nSashChild = EgtGetInfo( vSplitIds[i], WIN_SASH_CHILDREN, 'i')
|
|
local nRefCrv = EgtGetNext( nSashChild) or EgtGetPrev( nSashChild)
|
|
local _, _, nSide = EgtPointCurveDistSide( EgtMP( nRefCrv), vSplitIds[i], Z_AX())
|
|
-- se si trova a destra, lo split va invertito
|
|
if nSide == 1 then
|
|
EgtInvertCurve( vSplitIds[i])
|
|
-- scambio le info di intersezione
|
|
local vStartInters = EgtGetInfo( vSplitIds[i], WIN_SPLIT_STARTINTERS, 'vi')
|
|
local vEndInters = EgtGetInfo( vSplitIds[i], WIN_SPLIT_ENDINTERS, 'vi')
|
|
EgtSetInfo( vSplitIds[i], WIN_SPLIT_STARTINTERS, vEndInters)
|
|
EgtSetInfo( vSplitIds[i], WIN_SPLIT_ENDINTERS, vStartInters)
|
|
end
|
|
end
|
|
-- se split di tipo french non ha profilo assegnato perchè non ha un pezzo associato
|
|
end
|
|
|
|
-- SASH
|
|
elseif nAreaType == WIN_AREATYPES.SASH then
|
|
-- verifico tipologia di anta ( battente, ricevente, alzante scorrevole)
|
|
local nSashType = EgtGetInfo( nAreaId, WIN_SASHTYPE, 'i') or WIN_SASHTYPES.NULL
|
|
-- verifico se bottomrail
|
|
local nBottomRail = EgtGetInfo( nAreaId, WIN_BOTTOMRAIL, 'i') or 0
|
|
-- imposto profili sash
|
|
local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_AREAOUTLINE)
|
|
local nOutlineId = EgtGetFirstInGroup( nOutlineLayerId)
|
|
while nOutlineId do
|
|
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 ( e quindi deve avere profilo speciale e.g. battente/ricevente)
|
|
local nSouId = EgtGetInfo( nOutlineId, WIN_SOU, 'i')
|
|
if EgtGetName( nSouId) == WIN_SPLIT then
|
|
-- setto info sulla curva per ricordare che deriva da un french split
|
|
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 or nSashType == WIN_SASHTYPES.INACTIVE_IN then
|
|
-- devo verificare il tipo dell'anta adiacente
|
|
local nAdjSashType = FindAdjacentSashType( nSouId, nOutlineId)
|
|
if nSashType == WIN_SASHTYPES.ACTIVE_IN then
|
|
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
|
|
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
|
|
end
|
|
|
|
-- b) alzante scorrevole
|
|
elseif nSashType == WIN_SASHTYPES.SLIDE_MOVABLE then
|
|
local nAdjSashType = FindAdjacentSashType( nSouId, nOutlineId)
|
|
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
|
|
-- a) 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
|
|
|
|
-- b) 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
|
|
nOutlineId = EgtGetNext( nOutlineId)
|
|
end
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che cicla ricorsivamente su aree e sottoaree per impostare i tipi di profilo
|
|
local function CalculateAreaProfileType( nAreaId)
|
|
-- calcolo i profili per l'area corrente
|
|
CalcProfileType( nAreaId)
|
|
-- 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
|
|
|
|
EgtSetInfo( nProfileId, WIN_RAILOFFS, dRailOffs)
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che crea il profilo della dimensione corretta
|
|
local function AdjustProfileDimension( nOutlineId, nProfileId, dDimOld, dDim)
|
|
|
|
local bSplit = ( EgtGetName( nOutlineId) == WIN_SPLIT)
|
|
local sProfileName = EgtGetInfo( nProfileId, WIN_PROFILETYPE)
|
|
local bMixed = EgtStartsWith( sProfileName, WIN_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_SIMPLIFIED .. WIN_IN, WIN_SIMPLIFIED .. WIN_OFST .. WIN_CTRIN, WIN_SIMPLIFIED .. WIN_STRIP}
|
|
if bSplit then
|
|
vCurves = { WIN_IN .. '2', WIN_CTRIN .. '2', WIN_OFST .. WIN_CTRIN .. '2', WIN_STRIP .. '2',
|
|
WIN_SIMPLIFIED .. WIN_IN .. '2', WIN_SIMPLIFIED .. WIN_OFST .. WIN_CTRIN .. '2', WIN_SIMPLIFIED .. WIN_STRIP .. '2'}
|
|
elseif bMixed 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_STRIP,
|
|
WIN_SIMPLIFIED .. WIN_SASH .. WIN_IN, WIN_SIMPLIFIED .. WIN_FILL .. WIN_IN, WIN_SIMPLIFIED .. WIN_OFST .. WIN_SASH .. WIN_CTRIN,
|
|
WIN_SIMPLIFIED .. WIN_OFST .. WIN_FILL .. WIN_CTRIN, WIN_SIMPLIFIED .. WIN_STRIP, WIN_MIXED_COMMON .. WIN_IN}
|
|
end
|
|
|
|
for i = 1, #vCurves do
|
|
local nCrvId = EgtGetFirstNameInGroup( nProfileId, vCurves[i]) or GDB_ID.NULL
|
|
EgtMove( nCrvId, 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)
|
|
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( bMixed and not bSplit, { 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
|
|
|
|
-- 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 = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE)
|
|
if nProfileLayerId then
|
|
EgtEmptyGroup( nProfileLayerId)
|
|
else
|
|
nProfileLayerId = EgtGroup( nPartId)
|
|
EgtSetName( nProfileLayerId, WIN_PROFILE)
|
|
EgtSetStatus( nProfileLayerId, GDB_ST.OFF)
|
|
end
|
|
|
|
-- profilo principale :
|
|
-- 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)
|
|
end
|
|
|
|
-- recupero il nome del profilo
|
|
local sProfileName = EgtGetInfo( nOutlineId, WIN_PROFILETYPE)
|
|
-- controlli per bottomrail
|
|
if nBottomRail then
|
|
local nBottomRailTot = EgtGetInfo( nOutlineId, WIN_BOTTOMRAIL, 'i') or 0
|
|
if nBottomRail == nBottomRailTot then
|
|
sProfileName = WIN_FILL_RAIL
|
|
else
|
|
sProfileName = WIN_RAIL
|
|
end
|
|
end
|
|
|
|
-- recupero il profilo
|
|
local nOrigMainProfileId = EgtGetFirstNameInGroup( nLayerId, sProfileName)
|
|
|
|
-- creo copia
|
|
local nMainProfileId = EgtCopy( nOrigMainProfileId, nProfileLayerId)
|
|
local sMainProfileType = EgtGetName( nMainProfileId)
|
|
EgtSetInfo( nMainProfileId, WIN_PROFILETYPE, sMainProfileType)
|
|
EgtSetName( nMainProfileId, WIN_PRF_MAIN)
|
|
-- se bottomrail salvo info per scostamento dall'outline
|
|
if nBottomRail then
|
|
CalcRailOffset( nOutlineId, nMainProfileId, nBottomRail)
|
|
end
|
|
|
|
-- verifico se vanno modificate le dimensioni del profilo
|
|
local dDimStd = EgtGetInfo( nMainProfileId, WIN_DIM_STD, 'd')
|
|
if dDim then
|
|
if abs( dDimStd - dDim) > GEO.EPS_SMALL then
|
|
AdjustProfileDimension( nOutlineId, nMainProfileId, dDimStd, dDim)
|
|
end
|
|
else
|
|
-- se non ha dimensione imposto quella standard
|
|
if nBottomRail then
|
|
local vBottomRailDims = EgtGetInfo( nOutlineId, WIN_BOTTOMRAIL.. WIN_PART_DIM, 'vd') or {}
|
|
table.insert( vBottomRailDims, nBottomRail, dDimStd)
|
|
EgtSetInfo( nOutlineId, WIN_BOTTOMRAIL.. WIN_PART_DIM, vBottomRailDims)
|
|
else
|
|
EgtSetInfo( nOutlineId, WIN_PART_DIM, dDimStd)
|
|
end
|
|
end
|
|
|
|
-- recupero le info di pinzaggio dal profilo di estrusione
|
|
CopyInfo( nPartId, nMainProfileId, WIN_PRC_OFFY_1, 0)
|
|
CopyInfo( nPartId, nMainProfileId, WIN_PRC_OFFZ_1, 0)
|
|
CopyInfo( nPartId, nMainProfileId, WIN_PRC_OFFY_2, 0)
|
|
CopyInfo( nPartId, nMainProfileId, WIN_PRC_OFFZ_2, 0)
|
|
CopyInfo( nPartId, nMainProfileId, WIN_PRC_CLAMPV_1, 0)
|
|
CopyInfo( nPartId, nMainProfileId, 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
|
|
|
|
|
|
|
|
----------------------------------------------------------------------------------
|
|
------------------------------ CREAZIONE PEZZI ---------------------------------
|
|
----------------------------------------------------------------------------------
|
|
-- 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 GetOutlineJoints( vOutlineIds, vJoints)
|
|
|
|
for i = 1, #vOutlineIds do
|
|
|
|
local nPrevIdx = EgtIf( i == 1, #vOutlineIds, i - 1)
|
|
local nNextIdx = EgtIf( i == #vOutlineIds, 1, i + 1)
|
|
|
|
local nStartJoint, nEndJoint
|
|
if EgtGetName( vOutlineIds[i]) == WIN_BOTTOM then
|
|
nStartJoint = CalcPartJoint( vJoints[1], true)
|
|
nEndJoint = CalcPartJoint( vJoints[2], true)
|
|
elseif EgtGetName( vOutlineIds[i]) == WIN_RIGHT then
|
|
nStartJoint = CalcPartJoint( vJoints[2], false)
|
|
nEndJoint = CalcPartJoint( vJoints[3], false)
|
|
elseif EgtGetName( vOutlineIds[i]) == WIN_TOP then
|
|
nStartJoint = CalcPartJoint( vJoints[3], true)
|
|
nEndJoint = CalcPartJoint( vJoints[4], true)
|
|
-- correzioni per caso a triangolo : se l'outline vicino è di tipo bottom, il corrente deve essere trattato come un pezzo verticale
|
|
if EgtGetName( vOutlineIds[nPrevIdx]) == WIN_BOTTOM then
|
|
nStartJoint = CalcPartJoint( vJoints[2], false)
|
|
nEndJoint = CalcPartJoint( vJoints[3], true)
|
|
end
|
|
if EgtGetName( vOutlineIds[nNextIdx]) == WIN_BOTTOM then
|
|
nStartJoint = CalcPartJoint( vJoints[3], true)
|
|
nEndJoint = CalcPartJoint( vJoints[1], false)
|
|
end
|
|
elseif EgtGetName( vOutlineIds[i]) == WIN_LEFT then
|
|
nStartJoint = CalcPartJoint( vJoints[4] or vJoints[3], false) -- ( vJoints[3] per gestire caso a triangolo)
|
|
nEndJoint = CalcPartJoint( vJoints[1], false)
|
|
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( vOutlineIds[nPrevIdx]) * EgtSV( vOutlineIds[i]) > s_dAngledCos or EgtGetName( vOutlineIds[i]) == EgtGetName( vOutlineIds[nPrevIdx]) then
|
|
nStartJoint = WIN_PART_JNT.ANGLED
|
|
end
|
|
end
|
|
if nEndJoint ~= WIN_PART_JNT.ANGLED then
|
|
if EgtEV( vOutlineIds[i]) * EgtSV( vOutlineIds[nNextIdx]) > s_dAngledCos or EgtGetName( vOutlineIds[i]) == EgtGetName( vOutlineIds[nNextIdx]) then
|
|
nEndJoint = WIN_PART_JNT.ANGLED
|
|
end
|
|
end
|
|
|
|
-- b) forzatura a short se incontro con soglia
|
|
if EgtGetInfo( vOutlineIds[nPrevIdx], WIN_THRESHOLD, 'b') then
|
|
nStartJoint = WIN_PART_JNT.SHORT
|
|
end
|
|
if EgtGetInfo( vOutlineIds[nNextIdx], WIN_THRESHOLD, 'b') then
|
|
nEndJoint = WIN_PART_JNT.SHORT
|
|
end
|
|
|
|
-- salvo come info sulla curva
|
|
EgtSetInfo( vOutlineIds[i], WIN_STARTJOINT, nStartJoint)
|
|
EgtSetInfo( vOutlineIds[i], WIN_ENDJOINT, nEndJoint)
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- 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.FRAME and nParentType ~= WIN_AREATYPES.SASH do
|
|
nParentId = EgtGetParent( nParentId)
|
|
nParentType = EgtGetInfo( nParentId, WIN_AREATYPE, 'i')
|
|
end
|
|
sName = EgtGetInfo( nParentId, WIN_AREA_NAME, sName)
|
|
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
|
|
local vBottomRailParts = EgtGetInfo( nOutlineId, WIN_REF_BOTTOMRAIL_PART, 'vi') or {}
|
|
table.insert( vBottomRailParts, nPartId)
|
|
EgtSetInfo( nOutlineId, WIN_REF_BOTTOMRAIL_PART, vBottomRailParts)
|
|
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)
|
|
|
|
local vPartsDim = EgtGetInfo( nAreaId, WIN_PART_DIM, 'vd') or {}
|
|
local nBottomRail = EgtGetInfo( nAreaId, WIN_BOTTOMRAIL, 'i')
|
|
|
|
-- sistemo le dimensioni in modo che pezzi coinvolti da giunzione a bisettrice ( scelta o forzata) abbiano la stessa dimensione
|
|
for i = 2, #vOutlines do
|
|
local nStartJoint = EgtGetInfo( vOutlines[i], WIN_STARTJOINT, 'i')
|
|
if nStartJoint == WIN_PART_JNT.ANGLED then
|
|
vPartsDim[i] = vPartsDim[i-1]
|
|
end
|
|
end
|
|
if vPartsDim[1] ~= vPartsDim[#vOutlines] and EgtGetInfo( vOutlines[1], WIN_STARTJOINT, 'i') == WIN_PART_JNT.ANGLED then
|
|
for i = #vOutlines, 2, -1 do
|
|
local nEndJoint = EgtGetInfo( vOutlines[i], WIN_ENDJOINT, 'i')
|
|
if nEndJoint == WIN_PART_JNT.ANGLED then
|
|
vPartsDim[i] = vPartsDim[1]
|
|
else
|
|
break
|
|
end
|
|
end
|
|
end
|
|
|
|
-- creo i pezzi per ogni curva
|
|
for i = 1, #vOutlines do
|
|
EgtSetInfo( vOutlines[i], WIN_PART_DIM, vPartsDim[i])
|
|
CreateOutlinePart( vOutlines[i], sName, vPartsDim[i])
|
|
|
|
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 {}
|
|
EgtSetInfo( vOutlines[i], WIN_BOTTOMRAIL .. WIN_PART_DIM, vBottomRailDim)
|
|
for j = 1, nBottomRail do
|
|
CreateOutlinePart( vOutlines[i], sName, vBottomRailDim[j], j)
|
|
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 .. '_' .. WIN_FILL)
|
|
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
|
|
|
|
|
|
|
|
----------------------------------------------------------------------------------
|
|
------------------------------ CALCOLO OUTLINE ---------------------------------
|
|
----------------------------------------------------------------------------------
|
|
-- 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 = GetOutlineProfileId( vCrvs[i], true)
|
|
local b3FrameProfile = GetProfileLocalBox( nProfileId)
|
|
local dDeltaOffs = EgtGetInfo( nProfileId, WIN_RAILOFFS , 'd') or 0
|
|
local dOffs = b3FrameProfile:getMin():getX() - dDeltaOffs
|
|
EgtOffsetCurve( nCrv, dOffs)
|
|
end
|
|
vCrvs = TrimOrderedCurves( vCrvs)
|
|
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
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che corregge i profili del telaio individuati di tipo mixed dallo split
|
|
local function AdjustMixedFrames( vOutlines)
|
|
-- pezzi consecutivi coinvolti da cambio profilo devono avere : profilo di tipo mixed, stesse dimensioni, separazione con giunzione a bisettrice
|
|
if vOutlines == 1 then return end
|
|
|
|
-- fisso come dimensione quella del primo pezzo
|
|
local dDimRef = EgtGetInfo( vOutlines[1], WIN_PART_DIM, 'd')
|
|
|
|
for i = 1, #vOutlines do
|
|
local bMixed = EgtGetInfo( vOutlines[i], WIN_PRF_CHANGE, 'b') or false
|
|
local dDim = EgtGetInfo( vOutlines[i], WIN_PART_DIM, 'd')
|
|
-- se non era stato individuato correttamente come profilo mixed oppure la dimensione va modificata ricalcolo il profilo
|
|
if not bMixed or abs( dDim - dDimRef) > GEO.EPS_SMALL then
|
|
if not bMixed then
|
|
EgtSetInfo( vOutlines[i], WIN_PRF_CHANGE, true)
|
|
local sRealProfile = EgtIf( EgtGetName( vOutlines[i]) == WIN_BOTTOM, WIN_MIXED_BOTTOM, WIN_MIXED_TOP)
|
|
EgtSetInfo( vOutlines[i], WIN_PROFILETYPE, sRealProfile)
|
|
end
|
|
if abs( dDim - dDimRef) > GEO.EPS_SMALL then
|
|
EgtSetInfo( vOutlines[i], WIN_PART_DIM, dDimRef)
|
|
end
|
|
local nPartId = EgtGetInfo( vOutlines[i], WIN_REF_PART, 'i')
|
|
CreatePartProfile( nPartId, vOutlines[i], dDimRef)
|
|
end
|
|
|
|
-- imposto giunzione
|
|
if i ~= 1 then
|
|
EgtSetInfo( vOutlines[i], WIN_STARTJOINT, WIN_PART_JNT.ANGLED)
|
|
end
|
|
if i ~= #vOutlines then
|
|
EgtSetInfo( vOutlines[i], WIN_ENDJOINT, WIN_PART_JNT.ANGLED)
|
|
end
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che verifica gli outlines prev/next per lo split controllando l'interferenza tra i profili
|
|
local function TestSplitTrimOutlines( nOutlineId, vBaseTrimOutlines, tabOutlines, nMainProfile, b3Profile, nGrpTmp, bPrevOrNext)
|
|
|
|
local vTrimOutlines = {}
|
|
|
|
-- 1) recupero le curve da testare
|
|
local vTestOutlines = {}
|
|
|
|
-- a) curve individuate dalle intersezioni dei base outlines
|
|
for i = 1, #vBaseTrimOutlines do
|
|
vTestOutlines[i] = tabOutlines[vBaseTrimOutlines[i]]
|
|
end
|
|
|
|
-- b) curve vicine a quelle individuate dalle intersezioni che interferiscono con l'outline ( guardando interferenza grossolana dei pezzi)
|
|
-- recupero le curve di bordo del pezzo di split
|
|
local nOutlineCopyId = EgtCopyGlob( nOutlineId, nGrpTmp)
|
|
if bPrevOrNext then
|
|
EgtTrimCurveEndAtParam( nOutlineCopyId, 0.5)
|
|
else
|
|
EgtTrimCurveStartAtParam( nOutlineCopyId, 0.5)
|
|
end
|
|
local nOutId = EgtOffsetCurveAdv( nOutlineCopyId, b3Profile:getMax():getX())
|
|
local nInId = EgtOffsetCurveAdv( nOutlineCopyId, b3Profile:getMin():getX())
|
|
|
|
-- curve precedenti
|
|
local nTestCurve = EgtGetPrev( vBaseTrimOutlines[1]) or EgtGetLastInGroup( EgtGetParent( vBaseTrimOutlines[1]))
|
|
local bInters = true
|
|
while bInters and nTestCurve ~= vBaseTrimOutlines[#vBaseTrimOutlines] do
|
|
|
|
local nRefOutline = abs( tabOutlines[nTestCurve])
|
|
local nProfileId = GetOutlineProfileId( nRefOutline, true)
|
|
local b3Profile = GetProfileLocalBox( nProfileId)
|
|
local nRefSurf = EgtSurfFrFatCurve( nGrpTmp, nRefOutline, b3Profile:getMin():getX(), false)
|
|
|
|
local nClassOut = EgtCurveWithRegionClassify( nOutId, nRefSurf)
|
|
if nClassOut == GDB_CRC.OUT then
|
|
local nClassIn = EgtCurveWithRegionClassify( nInId, nRefSurf)
|
|
-- se non c'è interferenza interrompo la ricerca
|
|
if nClassIn == GDB_CRC.OUT then
|
|
bInters = false
|
|
end
|
|
end
|
|
-- se interferenza lo aggiungo tra le curve da controllare
|
|
if bInters then
|
|
table.insert( vTestOutlines, 1, tabOutlines[nTestCurve])
|
|
nTestCurve = EgtGetPrev( nTestCurve) or EgtGetLastInGroup( EgtGetParent( nTestCurve))
|
|
end
|
|
end
|
|
|
|
-- curve successive
|
|
nTestCurve = EgtGetNext( vBaseTrimOutlines[#vBaseTrimOutlines]) or EgtGetFirstInGroup( EgtGetParent( vBaseTrimOutlines[1]))
|
|
bInters = true
|
|
while bInters and nTestCurve ~= vBaseTrimOutlines[1] do
|
|
|
|
local nRefOutline = abs( tabOutlines[nTestCurve])
|
|
local nProfileId = GetOutlineProfileId( nRefOutline, true)
|
|
local b3Profile = GetProfileLocalBox( nProfileId)
|
|
local nRefSurf = EgtSurfFrFatCurve( nGrpTmp, nRefOutline, b3Profile:getMin():getX(), false)
|
|
|
|
local nClassOut = EgtCurveWithRegionClassify( nOutId, nRefSurf)
|
|
if nClassOut == GDB_CRC.OUT then
|
|
local nClassIn = EgtCurveWithRegionClassify( nInId, nRefSurf)
|
|
if nClassIn == GDB_CRC.OUT then
|
|
bInters = false
|
|
end
|
|
end
|
|
if bInters then
|
|
table.insert( vTestOutlines, tabOutlines[nTestCurve])
|
|
nTestCurve = EgtGetNext( nTestCurve) or EgtGetFirstInGroup( EgtGetParent( nTestCurve))
|
|
end
|
|
end
|
|
|
|
if #vTestOutlines == 1 then
|
|
return vTestOutlines
|
|
end
|
|
|
|
-- 2) testo le curve controllando intersezione tra le superfici dei pezzi
|
|
-- creo il solido principale
|
|
local dExtraLen = b3Profile:getDimX()
|
|
local nMainSurf = CreateProfileSurf( nOutlineId, nMainProfile, WIN_SECTION, 4 * dExtraLen, nGrpTmp)
|
|
EgtCutSurfTmPlane( nMainSurf, EgtMP( nOutlineId), EgtIf( bPrevOrNext, 1, -1) * EgtSV( nOutlineId))
|
|
|
|
-- recupero profili per i conti
|
|
local vProfiles = {}
|
|
local vsCtrIn = {}
|
|
for i = 1, #vTestOutlines do
|
|
vProfiles[i] = GetOutlineProfileId( abs( vTestOutlines[i]), true)
|
|
vsCtrIn[i] = GetProfileCtrIn( abs( vTestOutlines[i]), nOutlineId, vProfiles[i])
|
|
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]), vProfiles[i], vsCtrIn[i], 4 * dExtraLen, nGrpTmp)
|
|
if i > 1 then
|
|
if AreSameVectorApprox( EgtEV( abs( vTestOutlines[i-1])), EgtSV( abs( vTestOutlines[i]))) then
|
|
EgtCutSurfTmPlane( nTestSurf, EgtEP( abs( vTestOutlines[i-1])), - EgtEV( abs( vTestOutlines[i-1])), false)
|
|
else
|
|
local nTrimSurf = CreateProfileSurf( abs( vTestOutlines[i-1]), 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])), EgtSV( abs( vTestOutlines[i+1]))) then
|
|
EgtCutSurfTmPlane( nTestSurf, EgtEP( abs( vTestOutlines[i])), EgtEV( abs( vTestOutlines[i])), false)
|
|
else
|
|
local nTrimSurf = CreateProfileSurf( abs( vTestOutlines[i+1]), 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])
|
|
end
|
|
end
|
|
|
|
return vTrimOutlines
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che recupera gli outline precedenti e successivi
|
|
local function GetSplitPrevNextOutline( nSplitId)
|
|
|
|
local nGrpTmp = EgtGroup( GDB_ID.ROOT)
|
|
local nMainProfile = GetOutlineProfileId( nSplitId)
|
|
local b3Profile = GetProfileLocalBox( nMainProfile)
|
|
|
|
local vPrevBaseOutlineId = EgtGetInfo( nSplitId, WIN_SPLIT_STARTINTERS, 'vi')
|
|
local vNextBaseOutlineId = EgtGetInfo( nSplitId, WIN_SPLIT_ENDINTERS, 'vi')
|
|
|
|
-- ad ogni base outline dell'area di bordo che racchiude lo split associo l'outline non virtuale corrispondente ( per rendere più solidi i conti successivi)
|
|
local tabOutlines = {}
|
|
local nBaseOutlineLayerId = EgtGetParent( vPrevBaseOutlineId[1])
|
|
local vBaseOutlineIds = EgtGetAllInGroup( nBaseOutlineLayerId)
|
|
for i = 1, #vBaseOutlineIds do
|
|
local nBaseOutline = vBaseOutlineIds[i]
|
|
local nAreaType = WIN_AREATYPES.SPLIT
|
|
while not ( nAreaType == WIN_AREATYPES.FRAME or nAreaType == WIN_AREATYPES.SASH or EgtGetName( nBaseOutline) == WIN_SPLIT) do
|
|
nBaseOutline = EgtGetInfo( nBaseOutline, WIN_SOU, 'i')
|
|
local nAreaId = EgtGetParent( EgtGetParent( nBaseOutline))
|
|
nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i')
|
|
end
|
|
tabOutlines[vBaseOutlineIds[i]] = EgtGetInfo( nBaseOutline, WIN_COPY, 'i')
|
|
|
|
-- verifico la coerenza dell'orientamento ( se la curva virtuale deriva da split) e la indico con il segno ( > 0 concorde, < 0 discorde e andrà invertita)
|
|
local nOutlineId = EgtGetInfo( vBaseOutlineIds[i], WIN_COPY, 'i')
|
|
local bInvert = EgtGetInfo( nOutlineId, WIN_INV_SPLIT, 'b') or false
|
|
if bInvert then
|
|
tabOutlines[vBaseOutlineIds[i]] = - tabOutlines[vBaseOutlineIds[i]]
|
|
end
|
|
end
|
|
|
|
-- controllo validità delle curve trovate ed eventuali vicine verificando l'interferenza tra i profili
|
|
local vPrevOutlineId = TestSplitTrimOutlines( nSplitId, vPrevBaseOutlineId, tabOutlines, nMainProfile, b3Profile, nGrpTmp, true)
|
|
EgtSetInfo( nSplitId, WIN_PREV_OUTLINES, vPrevOutlineId)
|
|
local vNextOutlineId = TestSplitTrimOutlines( nSplitId, vNextBaseOutlineId, tabOutlines, nMainProfile, b3Profile, nGrpTmp, false)
|
|
EgtSetInfo( nSplitId, WIN_NEXT_OUTLINES, vNextOutlineId)
|
|
|
|
-- se split di tipo mixed i pezzi che incontra deve essere di tipo mixed ( anche se avevo trovato una sola tipologia di figli), devono essere separati da giunzione
|
|
-- a bisettrice e devono avere le stesse dimensioni. Impongo queste condizioni eventualmente ricalcolando i profili
|
|
local bChangeProfile = EgtGetInfo( nSplitId, WIN_PRF_CHANGE, 'b') or false
|
|
if bChangeProfile then
|
|
AdjustMixedFrames( vPrevOutlineId)
|
|
AdjustMixedFrames( vNextOutlineId)
|
|
end
|
|
|
|
EgtErase( nGrpTmp)
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function GetPrevNextOutline( nOutlineLayerId)
|
|
|
|
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]})
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function TrimSplitWithOutline( nSplitId)
|
|
-- estendo agli estremi ( TO DO : gestire caso di split non lineare)
|
|
EgtExtendCurveStartByLen( nSplitId, 50)
|
|
EgtExtendCurveEndByLen( nSplitId, 50)
|
|
-- lo taglio con outline
|
|
local nStartIntersId = EgtGetInfo( nSplitId, WIN_SPLIT_STARTINTERS, 'i')
|
|
local nOutlineId = EgtGetInfo( nStartIntersId, WIN_COPY, 'i')
|
|
local ptStartInters = EgtIP( nSplitId, nOutlineId, EgtSP( nSplitId))
|
|
local dStartInters = EgtCurveParamAtPoint( nSplitId, ptStartInters)
|
|
EgtTrimCurveStartAtParam( nSplitId, dStartInters)
|
|
local nEndIntersId = EgtGetInfo( nSplitId, WIN_SPLIT_ENDINTERS, 'i')
|
|
nOutlineId = EgtGetInfo( nEndIntersId, WIN_COPY, 'i')
|
|
local ptEndInters = EgtIP( nSplitId, nOutlineId, EgtEP( nSplitId))
|
|
local dEndInters = EgtCurveParamAtPoint( nSplitId, ptEndInters)
|
|
EgtTrimCurveEndAtParam( nSplitId, dEndInters)
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che calcola l'outline per aree virtuali ausiliarie di split a griglia
|
|
local function CalculateVirtualAreaOutline( nAreaId, dZmove)
|
|
|
|
local nOutlineLayerId = EgtGroup( nAreaId)
|
|
EgtSetName( nOutlineLayerId, WIN_OUTLINE)
|
|
EgtSetStatus( nOutlineLayerId, GDB_ST.OFF)
|
|
|
|
local nBaseOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_AREAOUTLINE)
|
|
local nBaseOutlineId = EgtGetFirstInGroup( nBaseOutlineLayerId)
|
|
while nBaseOutlineId do
|
|
local nSouId = EgtGetInfo( nBaseOutlineId, WIN_SOU, 'i')
|
|
local nOutlineId
|
|
|
|
if EgtGetName( nSouId) == WIN_SPLIT then
|
|
-- se deriva da split lo copio e lo traslo
|
|
nOutlineId = EgtCopy( nSouId, nOutlineLayerId)
|
|
EgtMove( nOutlineId, Z_AX() * dZmove)
|
|
EgtSetName( nOutlineId, EgtGetName( nBaseOutlineId))
|
|
-- salvo riferimento dello split da cui deriva
|
|
EgtSetInfo( nOutlineId, WIN_REF_SPLIT, nSouId)
|
|
-- verifico orientamento
|
|
local nCrvRef = EgtGetPrev( nBaseOutlineId) or EgtGetNext( nBaseOutlineId)
|
|
local _, _, nSide = EgtPointCurveDistSide( EgtMP( nCrvRef), nOutlineId, Z_AX())
|
|
if nSide == 1 then
|
|
EgtInvertCurve( nOutlineId)
|
|
EgtSetInfo( nOutlineId, WIN_INV_SPLIT, true)
|
|
end
|
|
else
|
|
local nCopyId = EgtGetInfo( nSouId, WIN_COPY, 'i') or GDB_ID.NULL
|
|
nOutlineId = EgtCopy( nCopyId, nOutlineLayerId)
|
|
end
|
|
|
|
if nOutlineId then
|
|
-- sistemo le info
|
|
EgtSetInfo( nOutlineId, WIN_COPY, nBaseOutlineId)
|
|
EgtSetInfo( nBaseOutlineId, WIN_COPY, nOutlineId)
|
|
EgtRemoveInfo( nOutlineId, WIN_CHILD)
|
|
end
|
|
|
|
nBaseOutlineId = EgtGetNext( nBaseOutlineId)
|
|
end
|
|
-- taglio tutti i contorni
|
|
TrimOrderedCurves( EgtGetAllInGroup( nOutlineLayerId), 1)
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function CalculateSplitOutline( nAreaId, sName)
|
|
|
|
-- copio il layer di base outline
|
|
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)
|
|
|
|
-- se split interni ad anta ricavo quota in z dal suo profilo
|
|
local dZMove = 0
|
|
local nSplitType = EgtGetInfo( vSplitIds[1], WIN_SPLITTYPE, 'i')
|
|
if nSplitType == WIN_SPLITTYPES.INSASH then
|
|
-- recupero area sash che lo contiene
|
|
local nSashAreaId = nAreaId
|
|
local nAreaType = EgtGetInfo( nSashAreaId, WIN_AREATYPE, 'i')
|
|
while nAreaType ~= WIN_AREATYPES.SASH do
|
|
nSashAreaId = EgtGetParent( nSashAreaId)
|
|
nAreaType = EgtGetInfo( nSashAreaId, WIN_AREATYPE, 'i')
|
|
end
|
|
-- recupero il profilo dell'anta da una curva dell'outline
|
|
local nSashBaseOutlineLayerId = EgtGetFirstNameInGroup( nSashAreaId, WIN_AREAOUTLINE)
|
|
local nSashBaseOutlineId = EgtGetFirstInGroup( nSashBaseOutlineLayerId)
|
|
local sSashProfile = EgtGetInfo( nSashBaseOutlineId, WIN_PROFILETYPE)
|
|
local nProfileLayerId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_PROFILE)
|
|
local nSashProfileLayerId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_SASH)
|
|
local nSashProfileId = EgtGetFirstNameInGroup( nSashProfileLayerId, sSashProfile)
|
|
-- calcolo offset sulla z dell'anta
|
|
dZMove = EgtGetInfo( nSashProfileId, WIN_DELTA, 'd')
|
|
end
|
|
|
|
-- verifico se presenti aree ausiliarie per split a griglia
|
|
local vAuxAreas = EgtGetNameInGroup( nAreaId, WIN_VIRTUAL_AREA) or {}
|
|
for i = 1, #vAuxAreas do
|
|
CalculateVirtualAreaOutline( vAuxAreas[i], dZMove)
|
|
end
|
|
|
|
-- sistemo gli outline degli split
|
|
local vSplitDim = EgtGetInfo( nAreaId, WIN_PART_DIM, 'vd') or {}
|
|
|
|
for i = 1, #vSplitIds do
|
|
-- sistemo le info
|
|
EgtSetInfo( vBaseSplitIds[i], WIN_COPY, vSplitIds[i])
|
|
EgtSetInfo( vSplitIds[i], WIN_COPY, vBaseSplitIds[i])
|
|
-- taglio con outline
|
|
TrimSplitWithOutline( vSplitIds[i])
|
|
-- aggiusto quota
|
|
EgtMove( vSplitIds[i], Z_AX() * dZMove)
|
|
|
|
if nSplitType ~= WIN_SPLITTYPES.FRENCH then
|
|
EgtSetInfo( vSplitIds[i], WIN_PART_DIM, vSplitDim[i])
|
|
-- imposto le giunzioni
|
|
EgtSetInfo( vSplitIds[i], WIN_STARTJOINT, WIN_PART_JNT.SHORT)
|
|
EgtSetInfo( vSplitIds[i], WIN_ENDJOINT, WIN_PART_JNT.SHORT)
|
|
-- creo il pezzo
|
|
CreateOutlinePart( vSplitIds[i], sName, vSplitDim[i])
|
|
-- ricavo prev e next
|
|
GetSplitPrevNextOutline( vSplitIds[i])
|
|
end
|
|
end
|
|
|
|
if nSplitType == WIN_SPLITTYPES.FRENCH then
|
|
local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE)
|
|
IdentifySashShape( nAreaId, nOutlineLayerId)
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function CalculateFillOutline( nAreaId, nAreaLayerId, nOutlineLayerId)
|
|
|
|
-- recupero area parent di tipo telaio/anta che la contiene
|
|
local vSplitAreas = {}
|
|
local nParentArea = EgtGetParent( nAreaId)
|
|
local nAreaType = EgtGetInfo( nParentArea, WIN_AREATYPE, 'i')
|
|
while nAreaType ~= WIN_AREATYPES.FRAME and nAreaType ~= WIN_AREATYPES.SASH do
|
|
if nAreaType == WIN_AREATYPES.SPLIT then
|
|
table.insert( vSplitAreas, nParentArea)
|
|
end
|
|
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 nParentOutlineId = EgtGetFirstInGroup( nParentOutlineLayer)
|
|
while nParentOutlineId do
|
|
-- copio la curva di outline del parent
|
|
local nOutlineId = EgtCopy( nParentOutlineId, nOutlineLayerId)
|
|
EgtSetInfo( nOutlineId, WIN_REF_OUTLINE, nParentOutlineId)
|
|
|
|
-- recupero il suo profilo per calcolare l'offset perpendicolare
|
|
local nParentProfileId = GetOutlineProfileId( nParentOutlineId, true)
|
|
local b3FrameProfile = GetProfileLocalBox( nParentProfileId)
|
|
local dOverlap = EgtGetInfo( nParentProfileId, WIN_FILLOVERLAP, 'd')
|
|
if dOverlap then
|
|
local dDimRef = b3FrameProfile:getMin():getX()
|
|
-- verifico se contributo per bottomrail
|
|
local dRailOffs = EgtGetInfo( nParentProfileId, WIN_RAILOFFS, 'd') or 0
|
|
local dFillPerpOffset = abs( dDimRef) - dOverlap + dRailOffs
|
|
EgtOffsetCurve( nOutlineId, - dFillPerpOffset)
|
|
-- movimento in z
|
|
if dDeltaZ < GEO.EPS_SMALL then
|
|
dDeltaZ = EgtGetInfo( nParentProfileId, WIN_FILLDELTA, 'd')
|
|
end
|
|
end
|
|
|
|
nParentOutlineId = EgtGetNext( nParentOutlineId)
|
|
end
|
|
-- accorcio gli offset
|
|
local vCrvs = TrimOrderedCurves( EgtGetAllInGroup( nOutlineLayerId), 1)
|
|
-- applico spostamento verticale
|
|
EgtMove( vCrvs, Z_AX() * dDeltaZ)
|
|
|
|
-- 2) taglio con split
|
|
if #vSplitAreas == 0 then
|
|
return
|
|
end
|
|
-- creo bordo complessivo dell'outline, salvando le info come temp prop della curva per non perderle
|
|
local vRefOutlines = {}
|
|
for i = 1, #vCrvs do
|
|
vRefOutlines[i] = EgtGetInfo( vCrvs[i], WIN_REF_OUTLINE, 'i')
|
|
end
|
|
local nCompo = EgtCurveCompo( nOutlineLayerId, vCrvs)
|
|
for i = 0, #vCrvs - 1 do
|
|
EgtCurveCompoSetTempProp( nCompo, i, vRefOutlines[i+1])
|
|
end
|
|
|
|
-- recupero gli split coinvolti nell'area fill
|
|
local tabSplits = {}
|
|
local vBaseOutlines = EgtGetAllInGroup( nAreaLayerId)
|
|
for i = 1, #vBaseOutlines do
|
|
-- verifico se deriva da split
|
|
local nSouId = EgtGetInfo( vBaseOutlines[i], WIN_SOU, 'i')
|
|
while nSouId and EgtGetName( nSouId) ~= WIN_SPLIT do
|
|
nSouId = EgtGetInfo( nSouId, WIN_SOU, 'i')
|
|
end
|
|
if nSouId then
|
|
tabSplits[nSouId] = vBaseOutlines[i]
|
|
end
|
|
end
|
|
|
|
-- taglio con split
|
|
for i = #vSplitAreas, 1, -1 do
|
|
local nSplitBaseOutline = EgtGetFirstNameInGroup( vSplitAreas[i], WIN_BASESPLIT)
|
|
local vSplitBaseOutlines = EgtGetAllInGroup( nSplitBaseOutline)
|
|
for j = 1, #vSplitBaseOutlines do
|
|
-- verifico sia uno split coinvolto nell'area fill considerata
|
|
if tabSplits[vSplitBaseOutlines[j]] then
|
|
|
|
-- a) creo la curva di outline corrispondente allo split
|
|
local nSplitOutline = EgtGetInfo( vSplitBaseOutlines[j], WIN_COPY, 'i')
|
|
local nOutlineId = EgtCopy( nSplitOutline, nOutlineLayerId)
|
|
-- verifico orientamento
|
|
local nRefCrv = EgtGetPrev( tabSplits[vSplitBaseOutlines[j]]) or EgtGetNext( tabSplits[vSplitBaseOutlines[j]])
|
|
local _, _, nSide = EgtPointCurveDistSide( EgtMP( nRefCrv), vSplitBaseOutlines[j], Z_AX())
|
|
if nSide == 1 then
|
|
EgtInvertCurve( nOutlineId)
|
|
end
|
|
-- calcolo gli offset
|
|
local nParentProfileId = GetOutlineProfileId( nSplitOutline, true)
|
|
local b3FrameProfile = GetProfileLocalBox( nParentProfileId)
|
|
local dOverlap = EgtGetInfo( nParentProfileId, WIN_FILLOVERLAP, 'd')
|
|
local bMixedSplit = EgtGetInfo( nSplitOutline, WIN_PRF_CHANGE, 'b') or false
|
|
local dDimRef = EgtIf( bMixedSplit, b3FrameProfile:getMax():getX(), b3FrameProfile:getMin():getX())
|
|
local dFillPerpOffset = abs( dDimRef) - dOverlap
|
|
EgtOffsetCurve( nOutlineId, - dFillPerpOffset)
|
|
-- movimento in z
|
|
local dFillZOffset = EgtGetInfo( nParentProfileId, WIN_FILLDELTA, 'd')
|
|
EgtMove( nOutlineId, Z_AX() * dFillZOffset)
|
|
|
|
-- b) 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, EgtIf( nSide == 1, - nSplitOutline, nSplitOutline))
|
|
end
|
|
end
|
|
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_REF_OUTLINE, vTempProps[i+1])
|
|
if vTempProps[i+1] < 0 then
|
|
EgtSetInfo( nCrv + i, WIN_INV_SPLIT, true)
|
|
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')
|
|
-- recupero il base outline e creo gruppo per outline
|
|
local nAreaOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_AREAOUTLINE)
|
|
local nOutlineLayerId = EgtGroup( nAreaId)
|
|
EgtSetName( nOutlineLayerId, WIN_OUTLINE)
|
|
EgtSetStatus( nOutlineLayerId, GDB_ST.OFF)
|
|
|
|
local sName = CalcPartName( nAreaId, nAreaType)
|
|
|
|
-- FRAME
|
|
if nAreaType == WIN_AREATYPES.FRAME then
|
|
local vBaseOutlines = EgtGetAllInGroup( nAreaOutlineLayerId)
|
|
local vOutlines = {}
|
|
for i = 1, #vBaseOutlines do
|
|
vOutlines[i] = EgtCopyGlob( vBaseOutlines[i], nOutlineLayerId)
|
|
EgtSetInfo( vBaseOutlines[i], WIN_COPY, vOutlines[i])
|
|
EgtSetInfo( vOutlines[i], WIN_COPY, vBaseOutlines[i])
|
|
end
|
|
GetPrevNextOutline( nOutlineLayerId)
|
|
-- sistemo le giunzioni
|
|
local vJoints = EgtGetInfo( nAreaId, WIN_JOINTS, 'vi')
|
|
GetOutlineJoints( vOutlines, vJoints)
|
|
-- creo i pezzi
|
|
CreatePartsFromOutlines( vOutlines, nAreaId, sName)
|
|
|
|
-- SPLIT / NULL
|
|
elseif nAreaType == WIN_AREATYPES.SPLIT or nAreaType == WIN_AREATYPES.NULL then
|
|
|
|
-- a) outline dell'area
|
|
local nBaseOutlineId = EgtGetFirstInGroup( nAreaOutlineLayerId)
|
|
while nBaseOutlineId do
|
|
-- recupero la curva di outline corrispondente alla curva del base outline da cui deriva e la copio
|
|
local nSouId = EgtGetInfo( nBaseOutlineId, WIN_SOU, 'i')
|
|
local nCopyId = EgtGetInfo( nSouId, WIN_COPY, 'i') or GDB_ID.NULL
|
|
local nOutlineId = EgtCopy( nCopyId, nOutlineLayerId)
|
|
|
|
if nOutlineId then
|
|
-- se deriva da split devo aggiornare il nome, controllare l'orientamento e settare il riferimento
|
|
local sSouName = EgtGetName( nSouId)
|
|
if sSouName == WIN_SPLIT then
|
|
local sBaseName = EgtGetName( nBaseOutlineId)
|
|
EgtSetName( nOutlineId, sBaseName)
|
|
EgtSetInfo( nOutlineId, WIN_REF_SPLIT, nSouId)
|
|
-- verifico orientamento
|
|
local nCrvRef = EgtGetPrev( nBaseOutlineId) or EgtGetNext( nBaseOutlineId)
|
|
local _, _, nSide = EgtPointCurveDistSide( EgtMP( nCrvRef), nOutlineId, Z_AX())
|
|
if nSide == 1 then
|
|
EgtInvertCurve( nOutlineId)
|
|
EgtSetInfo( nOutlineId, WIN_INV_SPLIT, true)
|
|
end
|
|
end
|
|
|
|
-- sistemo le info
|
|
EgtSetInfo( nOutlineId, WIN_COPY, nBaseOutlineId)
|
|
EgtSetInfo( nBaseOutlineId, WIN_COPY, nOutlineId)
|
|
EgtRemoveInfo( nOutlineId, WIN_CHILD)
|
|
end
|
|
|
|
nBaseOutlineId = EgtGetNext( nBaseOutlineId)
|
|
end
|
|
-- taglio tutti i contorni
|
|
TrimOrderedCurves( EgtGetAllInGroup( nOutlineLayerId), 1)
|
|
|
|
-- b) split
|
|
if nAreaType == WIN_AREATYPES.SPLIT then
|
|
CalculateSplitOutline( nAreaId, sName)
|
|
end
|
|
|
|
|
|
-- SASH
|
|
elseif nAreaType == WIN_AREATYPES.SASH then
|
|
-- recupero se anta battente ricevente
|
|
local nSashType = EgtGetInfo( nAreaId, WIN_SASHTYPE, 'i') or WIN_SASHTYPES.NULL
|
|
-- recupero gruppo profili anta
|
|
local nProfileLayerId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_PROFILE)
|
|
local nSashProfileLayerId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_SASH)
|
|
|
|
local vBaseOutlineIds = EgtGetAllInGroup( nAreaOutlineLayerId)
|
|
for i = 1, #vBaseOutlineIds do
|
|
-- recupero la curva di outline del base outline da cui deriva e la copio
|
|
local nSouId = EgtGetInfo( vBaseOutlineIds[i], WIN_SOU, 'i')
|
|
local nCopyId = EgtGetInfo( nSouId, WIN_COPY, 'i') or GDB_ID.NULL
|
|
local nOutlineId = EgtCopy( nCopyId, nOutlineLayerId)
|
|
|
|
if nOutlineId then
|
|
-- recupero profilo e ricavo l'offset in z dell'anta ( può essere fatto sui profili teorici perchè non cambia con le dimensioni)
|
|
local sSashProfile = EgtGetInfo( vBaseOutlineIds[i], WIN_PROFILETYPE)
|
|
local nSashProfileId = EgtGetFirstNameInGroup( nSashProfileLayerId, sSashProfile)
|
|
local dSashZOffset = EgtGetInfo( nSashProfileId, WIN_DELTA, 'd')
|
|
EgtMove( nOutlineId, Z_AX() * dSashZOffset)
|
|
|
|
-- sistemo le info
|
|
EgtRemoveInfo( nOutlineId, WIN_PRF_CHANGE)
|
|
EgtRemoveInfo( nOutlineId, WIN_REF_SPLIT)
|
|
EgtRemoveInfo( nOutlineId, WIN_INV_SPLIT)
|
|
EgtRemoveInfo( nOutlineId, WIN_THRESHOLD)
|
|
EgtRemoveInfo( nOutlineId, WIN_PART_DIM)
|
|
EgtSetInfo( vBaseOutlineIds[i], WIN_COPY, nOutlineId)
|
|
EgtSetInfo( nOutlineId, WIN_COPY, vBaseOutlineIds[i])
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, sSashProfile)
|
|
|
|
-- verifico se outline è segmento battente o ricevente ( che quindi deriva da split di tipo french)
|
|
local bOnFrenchSplit = EgtGetInfo( vBaseOutlineIds[i], WIN_CRV_ON_FRENCH_SPLIT, 'b') or false
|
|
if not bOnFrenchSplit then
|
|
-- se outline non è segmento battente o ricevente necessita di offset
|
|
-- recupero a ritroso il profilo dell'elemento del frame su cui poggia
|
|
local nFrameBaseOutlineId = nSouId
|
|
local sFrameProfile = EgtGetInfo( nFrameBaseOutlineId, WIN_PROFILETYPE)
|
|
while not sFrameProfile and nFrameBaseOutlineId do
|
|
nFrameBaseOutlineId = EgtGetInfo( nFrameBaseOutlineId, WIN_SOU , 'i')
|
|
sFrameProfile = EgtGetInfo( nFrameBaseOutlineId or GDB_ID.NULL, WIN_PROFILETYPE)
|
|
end
|
|
local nFrameOutlineId = EgtGetInfo( nFrameBaseOutlineId, WIN_COPY, 'i')
|
|
local nFrameProfileId = GetOutlineProfileId( nFrameOutlineId, false)
|
|
|
|
-- calcolo offset perpendicolare
|
|
local b3FrameProfile = GetProfileLocalBox( nFrameProfileId)
|
|
local sOverlapInfo = EgtIf( EgtGetName( nOutlineId) == WIN_BOTTOM, WIN_SASH_BOTTOM_OVERLAP, WIN_SASH_TOP_OVERLAP)
|
|
local dOverlap = EgtGetInfo( nFrameProfileId, sOverlapInfo, 'd')
|
|
local dSashPerpOffset = abs( b3FrameProfile:getMin():getX()) - dOverlap
|
|
EgtOffsetCurve( nOutlineId, - dSashPerpOffset)
|
|
|
|
else
|
|
-- se deriva da french split sistemo il nome
|
|
local sBaseName = EgtGetName( vBaseOutlineIds[i])
|
|
EgtSetName( nOutlineId, sBaseName)
|
|
-- controllo l'orientamento
|
|
local nCrvRef = EgtGetPrev( vBaseOutlineIds[i]) or EgtGetNext( vBaseOutlineIds[i])
|
|
local _, _, nSide = EgtPointCurveDistSide( EgtMP( nCrvRef), nOutlineId, Z_AX())
|
|
if nSide == 1 then
|
|
EgtInvertCurve( nOutlineId)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- accorcio gli offset
|
|
local vOutlines = TrimOrderedCurves( EgtGetAllInGroup( nOutlineLayerId), 1)
|
|
-- assegno prev e next
|
|
GetPrevNextOutline( nOutlineLayerId)
|
|
-- sistemo le giunzioni
|
|
local vJoints = EgtGetInfo( nAreaId, WIN_JOINTS, 'vi')
|
|
GetOutlineJoints( vOutlines, vJoints)
|
|
-- creo i pezzi
|
|
CreatePartsFromOutlines( vOutlines, nAreaId, sName)
|
|
-- identifico la forma
|
|
IdentifySashShape( nAreaId, nOutlineLayerId)
|
|
-- disegno apertura
|
|
DrawOpening( nAreaId)
|
|
|
|
|
|
-- FILL
|
|
elseif nAreaType == WIN_AREATYPES.FILL then
|
|
CalculateFillOutline( nAreaId, nAreaOutlineLayerId, nOutlineLayerId)
|
|
-- creo il pezzo associato
|
|
CreateFillPartFromArea( nAreaId, sName)
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che cicla ricorsivamente su aree e sottaree per calcolare gli outlines
|
|
local function CalculateAreaOutline( nAreaId)
|
|
-- calcolo outlines per l'area corrente
|
|
CalculateOutlineFromAreaOutline( nAreaId)
|
|
-- calcolo outlines per le eventuali sottoaree
|
|
local nChildAreaId = EgtGetFirstNameInGroup( nAreaId, WIN_AREA .. '*')
|
|
while nChildAreaId do
|
|
CalculateAreaOutline( nChildAreaId)
|
|
nChildAreaId = EgtGetNextName( nChildAreaId, WIN_AREA .. '*')
|
|
end
|
|
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 nSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_SPLIT)
|
|
local nSplitType = EgtGetInfo( nSplitLayerId, WIN_SPLITTYPE, 'i')
|
|
if nSplitType ~= WIN_SPLITTYPES.FRENCH then
|
|
-- recupero area parent per capire se dentro telaio o anta
|
|
local nParentAreaId = EgtGetParent( nAreaId)
|
|
local nParentAreaType = EgtGetInfo( nParentAreaId, WIN_AREATYPE, 'i')
|
|
while nParentAreaType ~= WIN_AREATYPES.FRAME and nParentAreaType ~= WIN_AREATYPES.SASH do
|
|
nParentAreaId = EgtGetParent( nParentAreaId)
|
|
nParentAreaType = EgtGetInfo( nParentAreaId, WIN_AREATYPE, 'i')
|
|
end
|
|
local sAreaName = EgtIf( nParentAreaType == WIN_AREATYPES.FRAME, WIN_FRAME, WIN_SASH)
|
|
|
|
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
|
|
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
|
|
-- 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
|
|
local vProfiles = {}
|
|
for i = 1, #vSplitIds do
|
|
vProfiles[i] = sAreaName .. '_' .. EgtGetInfo( vSplitIds[i], WIN_PROFILETYPE)
|
|
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
|
|
|
|
|
|
|
|
----------------------------------------------------------------------------------
|
|
-------------------------------- GEO -------------------------------------------
|
|
----------------------------------------------------------------------------------
|
|
-- 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
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione simile a CalcIntersectionRegion ma con considerazioni speciali per le curve del geo ( e.g. gestione bisettori)
|
|
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 ( con verifica su circonferenze coincidenti)
|
|
elseif EgtGetType( vCrvs[i]) == GDB_TY.CRV_ARC then
|
|
local dRad = EgtArcRadius( vCrvs[i])
|
|
|
|
local bTangentStart = EgtGetInfo( vCrvs[i], WIN_TANG_START, 'b') or false
|
|
local bTangentEnd = EgtGetInfo( vCrvs[i], WIN_TANG_END, 'b') or false
|
|
if not bTangentStart and not bTangentEnd then
|
|
local ptC = EgtCP( vCrvs[i])
|
|
local bOverlap = false
|
|
for j = 1, #tArcs do
|
|
if tArcs[j].ptC and AreSamePointApprox( tArcs[j].ptC, ptC) and abs( tArcs[j].dRad - dRad) < GEO.EPS_SMALL then
|
|
bOverlap = true
|
|
table.insert( tArcs[j].vOrigId, vCrvs[i])
|
|
break
|
|
end
|
|
end
|
|
if not bOverlap then
|
|
local nCrvId = CreateCurveExtension( vCrvs[i], nGrpTmp)
|
|
table.insert( tArcs, { nCrvId = nCrvId, vOrigId = { vCrvs[i]}, dRad = dRad, ptC = ptC})
|
|
end
|
|
else
|
|
local nCrvId = CreateCurveExtension( vCrvs[i], nGrpTmp)
|
|
table.insert( tArcs, { nCrvId = nCrvId, vOrigId = { vCrvs[i]}, dRad = dRad})
|
|
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
|
|
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 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
|
|
|
|
-- 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)
|
|
|
|
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 sCtrIn == WIN_CTRIN .. 1 then
|
|
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, nStartJoint, nEndJoint)
|
|
|
|
-- 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 giunzioni angled forzo estensioni 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])
|
|
if not bTangStart then
|
|
-- verifico se necessaria estensione in tangenza per giunzione angled o per la curva in
|
|
bTangStart = ( nStartJoint == 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 = ( nEndJoint == 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)
|
|
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)
|
|
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, nStartJointType, nEndJointType, 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) or EgtGetFirstNameInGroup( nCurrProfileId, WIN_IN .. '1')
|
|
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) or EgtGetFirstNameInGroup( nCurrProfileId, WIN_IN .. '2') or EgtGetFirstNameInGroup( nCurrProfileId, WIN_MIXED_COMMON .. WIN_IN)
|
|
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 nStartJointType == 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)
|
|
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)
|
|
end
|
|
|
|
else
|
|
local nPrevCurveId = EgtCopy( abs( vPrevOutlineId[i]), nGeoLayerId)
|
|
if vPrevOutlineId[i] < 0 then
|
|
EgtInvertCurve( nPrevCurveId)
|
|
end
|
|
local dOffs, nPrevSemiProfile
|
|
if nStartJointType == WIN_PART_JNT.SHORT then
|
|
-- la curva del geo corrisponde al bordo del controprofilo in del pezzo vicino
|
|
local sCtrIn = GetProfileCtrIn( abs( vPrevOutlineId[i]), nOutlineId, vPrevProfileId[i])
|
|
local dCPDelta = GetDeltaProfile( vPrevProfileId[i], sCtrIn)
|
|
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 nEndJointType == 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)
|
|
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)
|
|
end
|
|
|
|
else
|
|
local nNextCurveId = EgtCopy( abs( vNextOutlineId[i]), nGeoLayerId)
|
|
if vNextOutlineId[i] < 0 then
|
|
EgtInvertCurve( nNextCurveId)
|
|
end
|
|
local dOffs, nNextSemiProfile
|
|
if nEndJointType == WIN_PART_JNT.SHORT then
|
|
local sCtrIn = GetProfileCtrIn( abs( vNextOutlineId[i]), nOutlineId, vNextProfileId[i])
|
|
local dCPDelta = GetDeltaProfile( vNextProfileId[i], sCtrIn)
|
|
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, nStartJointType, nEndJointType)
|
|
|
|
-- costruisco la superficie
|
|
local vIds = EgtGetAllInGroup( nGeoLayerId)
|
|
local nAreaId = CalcGeoRegion( vIds, nGeoLayerId)
|
|
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
|
|
TrimOrderedCurves( vCrvs, 2, nAreaId)
|
|
|
|
-- 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
|
|
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 nStartJoint
|
|
local nEndJoint
|
|
local nBottomRail = EgtGetInfo( nPartId, WIN_BOTTOMRAIL, 'i')
|
|
if nBottomRail then
|
|
-- se bottomrail deve essere short ( l'info sulla curva di riferisce al pezzo bottom)
|
|
nStartJoint = WIN_PART_JNT.SHORT
|
|
nEndJoint = WIN_PART_JNT.SHORT
|
|
else
|
|
nStartJoint = EgtGetInfo( nOutlineId, WIN_STARTJOINT, 'i')
|
|
nEndJoint = EgtGetInfo( nOutlineId, WIN_ENDJOINT, 'i')
|
|
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
|
|
CreateGeoCurves( nOutlineId, vPrevOutlineId, vNextOutlineId, nStartJoint, nEndJoint, nGeoLayerId, nProfileLayerId)
|
|
|
|
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, bPrev, 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( bPrev, EgtSP( nSplitId), EgtEP( nSplitId))
|
|
|
|
-- calcolo le curve di riferimento per lo split
|
|
local b3SplitProfile = GetProfileLocalBox( nSplitProfileId)
|
|
local dSplitFixedOffs = EgtGetInfo( nSplitProfileId, WIN_FIXED_REF, 'd')
|
|
local nCrvSF = EgtOffsetCurveAdv( nSplitId, b3SplitProfile:getMax():getX() - dSplitFixedOffs)
|
|
EgtRelocateGlob( nCrvSF, nGrpTmp)
|
|
local dSplitSashOffs1 = EgtGetInfo( nSplitProfileId, WIN_SASH_REF .. '1', 'd')
|
|
local nCrvSS1 = EgtOffsetCurveAdv( nSplitId, b3SplitProfile:getMin():getX() + dSplitSashOffs1)
|
|
EgtRelocateGlob( nCrvSS1, nGrpTmp)
|
|
local dSplitSashOffs2 = EgtGetInfo( nSplitProfileId, WIN_SASH_REF .. '2', 'd')
|
|
local nCrvSS2 = EgtOffsetCurveAdv( nSplitId, b3SplitProfile:getMin():getX() + dSplitSashOffs2)
|
|
EgtRelocateGlob( nCrvSS2, nGrpTmp)
|
|
|
|
-- calcolo le curve di riferimento prev
|
|
local nOutlineCompo = EgtCurveCompo( nGrpTmp, vOutlines, false)
|
|
local b3FrameProfile = GetProfileLocalBox( nOutlineProfileId)
|
|
local dFrameFixedOffs = EgtGetInfo( nOutlineProfileId, WIN_FIXED_REF, 'd')
|
|
local nCrvFF = EgtOffsetCurveAdv( nOutlineCompo, b3FrameProfile:getMin():getX() + dFrameFixedOffs)
|
|
local dFrameSashOffs1 = EgtGetInfo( nOutlineProfileId, WIN_SASH_REF .. '1', 'd')
|
|
local nCrvFS1 = EgtOffsetCurveAdv( nOutlineCompo, b3FrameProfile:getMin():getX() + dFrameSashOffs1)
|
|
local dFrameSashOffs2 = EgtGetInfo( nOutlineProfileId, WIN_SASH_REF .. '2', 'd')
|
|
local nCrvFS2 = EgtOffsetCurveAdv( nOutlineCompo, b3FrameProfile:getMin():getX() + dFrameSashOffs2)
|
|
local dFrameExtra = EgtGetInfo( nOutlineProfileId, WIN_EXTRA_DIST, 'd')
|
|
local nCrvFIn = EgtOffsetCurveAdv( nOutlineCompo, b3FrameProfile:getMin():getX() + dFrameSashOffs2 + 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))
|
|
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)
|
|
-- bisettore è tratto di parabola
|
|
local dDim = b3Profile:getDimX()
|
|
if bPrev then
|
|
nBisector = CalcParabolicBisector( nArc, nCrvSF, dDim, nGrpTmp, true, false)
|
|
EgtInvertCurve( nBisector)
|
|
else
|
|
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() + dFrameSashOffs1 - 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 bPrev 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)
|
|
EgtModifyCurveThickness( nMilling, - dDepth)
|
|
if bPrev then
|
|
EgtSetInfo( nMilling, WIN_MIXED_SASHFILL, true)
|
|
else
|
|
EgtSetInfo( nMilling, WIN_MIXED_SASHFILL, false)
|
|
end
|
|
|
|
|
|
-- 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( bPrev, 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)
|
|
EgtInvertCurve( nMill5)
|
|
local dParG = EgtCurveParamAtPoint( nCrvFS2, pt5)
|
|
local nMill6
|
|
if bPrev then
|
|
nMill6 = EgtCopyParamRange( nCrvFS2, 0, dParG, nGrpTmp)
|
|
else
|
|
local _, dE = EgtCurveDomain( nCrvFS2)
|
|
nMill6 = EgtCopyParamRange( nCrvFS2, dParG, dE, nGrpTmp)
|
|
end
|
|
|
|
local nMilling2
|
|
if bPrev 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')
|
|
EgtModifyCurveThickness( nMilling2, - dDepth)
|
|
|
|
-- taglio sul punto finale della lavorazione di profilatura
|
|
local pt6 = EgtIP( nMilling2, nCircle2, ptRef)
|
|
if not pt6 then
|
|
_, pt6 = EgtPointCurveDist( EgtIf( bPrev, EgtSP( nMilling), EgtEP( nMilling)), nMilling2)
|
|
end
|
|
local dParH = EgtCurveParamAtPoint( nMilling2, pt6)
|
|
if bPrev 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)
|
|
|
|
-- prev
|
|
local vPrevOutlines = EgtGetInfo( nSplitId, WIN_PREV_OUTLINES, 'vi')
|
|
local nPrevProfileId = EgtGetFirstNameInGroup( nProfileGrpId, WIN_PRF_START)
|
|
local nMill1, nMill2 = CalcMixedMillings( vPrevOutlines, nPrevProfileId, nSplitId, nSplitProfileId, true, nGrp)
|
|
|
|
-- copio le fresature sui pezzi del telaio coinvolti
|
|
for i = 1, #vPrevOutlines do
|
|
local nPrevPartId = EgtGetInfo( 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
|
|
EgtCopyGlob( nMill1, nMixedInters)
|
|
EgtCopyGlob( nMill2, nMixedInters)
|
|
end
|
|
|
|
-- next
|
|
local vNextOutlines = EgtGetInfo( nSplitId, WIN_NEXT_OUTLINES, 'vi')
|
|
local nNextProfileId = EgtGetFirstNameInGroup( nProfileGrpId, WIN_PRF_END)
|
|
local nMill3, nMill4 = CalcMixedMillings( vNextOutlines, nNextProfileId, nSplitId, nSplitProfileId, false, nGrp)
|
|
|
|
for i = 1, #vNextOutlines do
|
|
local nPrevPartId = EgtGetInfo( vNextOutlines[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
|
|
EgtCopyGlob( nMill3, nMixedInters)
|
|
EgtCopyGlob( nMill4, nMixedInters)
|
|
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 crea la lavorazione a partire dalla curva del geo
|
|
local function CreateProfilingProcessingCurve( vCrvs, nPrevCrv, nSurfGeo, nProcLayerId)
|
|
|
|
-- recupero il semiprofilo associato al gruppo di curve
|
|
local nSemiProfileId = EgtGetInfo( vCrvs[1], WIN_SEMI_PROFILE, 'i')
|
|
local nCrvId
|
|
|
|
-- se bisettrice
|
|
if not nSemiProfileId then
|
|
nCrvId = EgtCopyGlob( vCrvs[1], nProcLayerId)
|
|
|
|
-- se lavorazioni di controprofilo
|
|
else
|
|
local nGrpTmp = EgtGroup( nProcLayerId)
|
|
|
|
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()
|
|
|
|
local vProcCrvs = {}
|
|
for i = 1, #vCrvs do
|
|
|
|
-- la curva di lavorazione si basa sulla curva del geo
|
|
local nCrvId = EgtCopyGlob( vCrvs[i], nGrpTmp)
|
|
|
|
-- calcolo la curva di lavorazione interna ( partendo dall'outline e non dal geo per essere coerente con la info di estensione)
|
|
local nRefOutlineId = EgtGetInfo( vCrvs[i], WIN_REF_OUTLINE, 'i')
|
|
local nOutlineId = EgtCopyGlob( abs( nRefOutlineId), nGrpTmp)
|
|
if nRefOutlineId < 0 then
|
|
EgtInvertCurve( nOutlineId)
|
|
end
|
|
local dGeoOffs = EgtGetInfo( vCrvs[i], WIN_GEO_OFFS, 'd')
|
|
local nOrigInnerProcId = EgtOffsetCurveAdv( nOutlineId, dGeoOffs - dOffs)
|
|
|
|
-- adatto la curva di lavorazione interna al pezzo
|
|
CopyInfo( nOrigInnerProcId, vCrvs[1], WIN_TANG_START, false)
|
|
CopyInfo( nOrigInnerProcId, vCrvs[#vCrvs], 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( vCrvs[i], - 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]
|
|
else
|
|
-- 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
|
|
end
|
|
|
|
-- la allineo alla curva di lavoro
|
|
EgtOffsetCurve( nInId, dOffs)
|
|
|
|
local bExtra = EgtGetInfo( vCrvs[i], WIN_GEO_EXTRA, 'b') or false
|
|
if bExtra then
|
|
-- se curva extra la curva di lavorazione è la corrispondente di quella interna
|
|
nCrvId = nInId
|
|
else
|
|
-- la curva va modificata solo in allungamento
|
|
nCrvId = EgtCurveCompo( nProcLayerId, nCrvId)
|
|
AddExtension( nCrvId, nInId)
|
|
end
|
|
|
|
-- se compo verifico se può diventare curva singola
|
|
if EgtGetType( nCrvId) == GDB_TY.CRV_COMPO then
|
|
EgtMergeCurvesInCurveCompo( nCrvId)
|
|
end
|
|
table.insert( vProcCrvs, nCrvId)
|
|
end
|
|
|
|
-- combino le curve
|
|
if #vProcCrvs == 1 then
|
|
nCrvId = vProcCrvs[1]
|
|
EgtRelocateGlob( nCrvId, nProcLayerId)
|
|
|
|
else
|
|
for i = 1, #vProcCrvs - 1 do
|
|
local ptInt = FindIntersectionPoint( vProcCrvs[i], vProcCrvs[i+1], EgtEP( vProcCrvs[i]))
|
|
local dPar1 = EgtCurveParamAtPoint( vProcCrvs[i], ptInt)
|
|
local dPar2 = EgtCurveParamAtPoint( vProcCrvs[i+1], ptInt)
|
|
if dPar1 then
|
|
EgtTrimCurveEndAtParam( vProcCrvs[i], dPar1)
|
|
else
|
|
EgtModifyCurveEndPoint( vProcCrvs[i], ptInt)
|
|
end
|
|
if dPar2 then
|
|
EgtTrimCurveStartAtParam( vProcCrvs[i+1], dPar2)
|
|
else
|
|
EgtModifyCurveStartPoint( vProcCrvs[i+1], ptInt)
|
|
end
|
|
end
|
|
nCrvId = EgtCurveCompo( nProcLayerId, vProcCrvs, true)
|
|
end
|
|
|
|
EgtErase( nGrpTmp)
|
|
end
|
|
|
|
-- sistemo la curva e setto le info
|
|
EgtModifyCurveThickness( nCrvId, 0)
|
|
EgtSetStatus( nCrvId, GDB_ST.ON)
|
|
EgtSetName( nCrvId, EgtGetName( vCrvs[1]))
|
|
GetProcessingInfoFromSemiProfile( nCrvId, nSemiProfileId)
|
|
for i = 1, #vCrvs do
|
|
EgtSetInfo( vCrvs[i], WIN_REF_PRC, nCrvId)
|
|
end
|
|
|
|
return nCrvId
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che calcola le lavorazioni di profilatura a partire dalle curve del geo
|
|
local function CreateProfilingProcessingFromGeo( nGeoLayerId, nSurfGeo, nProcLayerId, nPartId)
|
|
-- out e in vengono gestite singolarmente, right e left vengono raggruppate in base al semiprofilo
|
|
|
|
-- 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)
|
|
|
|
-- right
|
|
local vRight = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_RIGHT)
|
|
local vCurrRight = { vRight[1]}
|
|
local nSemiProfilePrev = EgtGetInfo( vRight[1], WIN_SEMI_PROFILE, 'i')
|
|
local sIdPrev = EgtGetInfo( nSemiProfilePrev or GDB_ID.NULL, WIN_PRC_ID)
|
|
local vsRightIds = { sIdPrev}
|
|
for i = 2, #vRight do
|
|
local nSemiProfileCurr = EgtGetInfo( vRight[i], WIN_SEMI_PROFILE, 'i')
|
|
local sIdCurr = EgtGetInfo( nSemiProfileCurr or GDB_ID.NULL, WIN_PRC_ID)
|
|
if nSemiProfilePrev and nSemiProfileCurr and sIdPrev == sIdCurr then
|
|
-- se hanno lo stesso semiprofilo vanno gestite insieme
|
|
table.insert( vCurrRight, vRight[i])
|
|
else
|
|
-- se hanno un diverso semiprofilo calcolo la lavorazione del gruppo associato al semiprofilo precedente e inizio a creare il gruppo del semiprofilo della curva corrente
|
|
CreateProfilingProcessingCurve( vCurrRight, nOut, nSurfGeo, nProcLayerId)
|
|
vCurrRight = { vRight[i]}
|
|
table.insert( vsRightIds, sIdCurr)
|
|
sIdPrev = sIdCurr
|
|
end
|
|
end
|
|
CreateProfilingProcessingCurve( vCurrRight, nOut, nSurfGeo, nProcLayerId)
|
|
EgtSetInfo( nPartId, WIN_PRC_PROFILE_RIGHT, vsRightIds)
|
|
|
|
-- 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)
|
|
|
|
-- left
|
|
local vLeft = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_LEFT)
|
|
local vCurrLeft = { vLeft[1]}
|
|
nSemiProfilePrev = EgtGetInfo( vLeft[1], WIN_SEMI_PROFILE, 'i')
|
|
sIdPrev = EgtGetInfo( nSemiProfilePrev or GDB_ID.NULL, WIN_PRC_ID)
|
|
local vsLeftIds = { sIdPrev}
|
|
for i = 2, #vLeft do
|
|
local nSemiProfileCurr = EgtGetInfo( vLeft[i], WIN_SEMI_PROFILE, 'i')
|
|
local sIdCurr = EgtGetInfo( nSemiProfileCurr or GDB_ID.NULL, WIN_PRC_ID)
|
|
if nSemiProfilePrev and nSemiProfileCurr and sIdPrev == sIdCurr then
|
|
table.insert( vCurrLeft, vLeft[i])
|
|
else
|
|
CreateProfilingProcessingCurve( vCurrLeft, nIn, nSurfGeo, nProcLayerId)
|
|
vCurrLeft = { vLeft[i]}
|
|
table.insert( vsLeftIds, sIdCurr)
|
|
sIdPrev = sIdCurr
|
|
end
|
|
end
|
|
CreateProfilingProcessingCurve( vCurrLeft, nIn, nSurfGeo, nProcLayerId)
|
|
EgtSetInfo( nPartId, WIN_PRC_PROFILE_LEFT, vsLeftIds)
|
|
|
|
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 = EgtGetNameInGroup( nMixedIntersGrp, WIN_MIXED_MILLING .. '*')
|
|
local dDepth1 = EgtGetInfo( nMainProfileId, WIN_SASH_DEPTH .. '1')
|
|
for i = 1, #vMixedInters do
|
|
local nMilling = EgtCopyGlob( vMixedInters[i], nProcLayerId)
|
|
-- sistemo spessore
|
|
if EgtGetName( nMilling) == WIN_MIXED_MILLING .. '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)
|
|
|
|
-- a) lavorazione dei profili
|
|
local nGeoArea = EgtGetLastInGroup( nGeoLayerId)
|
|
CreateProfilingProcessingFromGeo( nGeoLayerId, nGeoArea, nProcLayerId, EgtGetParent( nProcLayerId))
|
|
|
|
-- b) fresature
|
|
local nMixedIntersGrp = EgtGetFirstNameInGroup( EgtGetParent( nProcLayerId), WIN_MIXED_CURVES)
|
|
local nIntersLeft = EgtGetFirstNameInGroup( nMixedIntersGrp, WIN_MIXED_MILLING .. '1')
|
|
local nMillingLeft = EgtCopyGlob( nIntersLeft, nProcLayerId)
|
|
EgtSetInfo( nMillingLeft, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.PROFILING)
|
|
EgtSetInfo( nMillingLeft, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.GENERIC)
|
|
EgtSetInfo( nMillingLeft, WIN_PRC_SIDE, WIN_PRC_SIDETYPE.LEFT)
|
|
|
|
local nIntersRight = EgtGetLastNameInGroup( nMixedIntersGrp, WIN_MIXED_MILLING .. '1')
|
|
local nMillingRight = EgtCopyGlob( nIntersRight, nProcLayerId)
|
|
EgtInvertCurve( nMillingRight)
|
|
EgtSetInfo( nMillingRight, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.PROFILING)
|
|
EgtSetInfo( nMillingRight, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.GENERIC)
|
|
EgtSetInfo( nMillingRight, WIN_PRC_SIDE, WIN_PRC_SIDETYPE.RIGHT)
|
|
|
|
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 bChangeProfile = EgtGetInfo( nOutlineId, WIN_PRF_CHANGE, 'b') or false
|
|
if bChangeProfile then
|
|
-- 1) caso cambio profilo : telaio o split
|
|
if EgtGetName( nOutlineId) == WIN_SPLIT then
|
|
CalcMixedSplitProfilingProcessings( nOutlineId, nProcLayerId, nGeoLayerId)
|
|
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 nBaseOutlineId = EgtGetInfo( nOutlineId, WIN_COPY, 'i')
|
|
local bOnFrenchSplit = EgtGetInfo( nBaseOutlineId, 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 ----------------------------------------
|
|
----------------------------------------------------------------------------------
|
|
-- funzione che crea le superfici di trim e taglia il solido
|
|
local function TrimSolid( vGeoIds, dGeoWidth, nLayerId, nMainExtrusionId)
|
|
|
|
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 = EgtCurveCompo( nLayerId, vGeoIds[i], false)
|
|
EgtExtendCurveStartByLen( nGuideId, 5)
|
|
EgtExtendCurveEndByLen( nGuideId, 5)
|
|
EgtMove( nGuideId, Z_AX())
|
|
nTrimSurf = EgtSurfTmByExtrusion( nLayerId, nGuideId, - Z_AX() * 2 * dGeoWidth, 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') or GDB_ID.NULL
|
|
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
|
|
-- riposiziono la curva di lavorazione in corrispondenza dell'outline
|
|
local dOffs = EgtGetInfo( vGeoIds[i], WIN_GEO_OFFS, 'd')
|
|
nGuideId = EgtOffsetCurveAdv( nPrcCrv, - dOffs)
|
|
local nRefOutline = EgtGetInfo( vGeoIds[i], WIN_REF_OUTLINE, 'i')
|
|
if nRefOutline < 0 then
|
|
EgtInvertCurve( nGuideId)
|
|
end
|
|
-- recupero il controprofilo da estrudere
|
|
local sTrimProfileName = EgtGetName( nSemiProfileId)
|
|
sTrimProfileName = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. WIN_OFST .. sTrimProfileName
|
|
-- calcolo la superficie di estrusione
|
|
nTrimSurf = CreateProfileSurf( nGuideId, EgtGetParent( nSemiProfileId), sTrimProfileName, dGeoWidth, nLayerId)
|
|
tabPrcCrv[nPrcCrv] = nTrimSurf
|
|
end
|
|
end
|
|
|
|
-- taglio il solido principale
|
|
if nTrimSurf then
|
|
EgtSetStatus( nTrimSurf, GDB_ST.OFF)
|
|
EgtSurfTmIntersect( nMainExtrusionId, nTrimSurf)
|
|
EgtErase( nGuideId)
|
|
EgtSetInfo( vGeoIds[i], WIN_REF_SURF, nTrimSurf)
|
|
end
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che calcola la curva guida per il solido principale
|
|
local function CalcSolidGuide( nOutlineId, nSolidLayerId, nProfileId)
|
|
|
|
local nGuideId
|
|
if EgtGetType( nOutlineId) == GDB_TY.CRV_LINE then
|
|
-- se tratto lineare non ci sono problemi di estensione
|
|
nGuideId = EgtCopyGlob( nOutlineId, nSolidLayerId)
|
|
EgtExtendCurveStartByLen( nGuideId, 400)
|
|
EgtExtendCurveEndByLen( nGuideId, 400)
|
|
|
|
else
|
|
nGuideId = EgtCurveCompo( nSolidLayerId, nOutlineId, false)
|
|
|
|
-- se tratto ad arco verifico l'allungamento minimo richiesto guardando le curve di lavorazione in e out
|
|
local nPartId = EgtGetParent( nSolidLayerId)
|
|
local nProcLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PRC)
|
|
local nGeoLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO)
|
|
|
|
-- in
|
|
local nPrcIn = EgtGetFirstNameInGroup( nProcLayerId, WIN_GEO_IN)
|
|
local nInId = EgtCopyGlob( nPrcIn, nSolidLayerId)
|
|
EgtInvertCurve( nInId)
|
|
-- riporto la curva di lavorazione allineata all'outline
|
|
local nGeoIn = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_IN)
|
|
local dOffsIn = EgtGetInfo( nGeoIn, WIN_GEO_OFFS, 'd') or 0
|
|
EgtOffsetCurve( nInId, dOffsIn)
|
|
-- aggiungo tratti di estensione se necessari
|
|
AddExtension( nGuideId, nInId)
|
|
|
|
-- out
|
|
local nPrcOut = EgtGetFirstNameInGroup( nProcLayerId, WIN_GEO_OUT)
|
|
local nOutId = EgtCopyGlob( nPrcOut, nSolidLayerId)
|
|
local nGeoOut = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_OUT)
|
|
local dOffsOut = EgtGetInfo( nGeoOut, WIN_GEO_OFFS, 'd') or 0
|
|
EgtOffsetCurve( nOutId, dOffsOut)
|
|
AddExtension( nGuideId, nOutId)
|
|
|
|
-- piccola estensione per avere un po' di margine dal minimo indispensabile appena calcolato
|
|
EgtExtendCurveStartByLen( nGuideId, 5)
|
|
EgtExtendCurveEndByLen( nGuideId, 5)
|
|
|
|
EgtErase( nInId)
|
|
EgtErase( nOutId)
|
|
end
|
|
|
|
EgtSetName( nGuideId, WIN_MAINGUIDE)
|
|
EgtSetStatus( nGuideId, GDB_ST.OFF)
|
|
|
|
-- se bottomrail sposto opportunamente la guida
|
|
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
|
|
|
|
return nGuideId
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che crea il solido di estrusione principale
|
|
local function CreateMainSurf( nGuideId, nProfileId, sSectionName, nLayerId)
|
|
|
|
-- posiziono il profilo sulla curva guida :
|
|
-- recupero il frame del profilo
|
|
local nProfileFrameId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME)
|
|
local frInvert = EgtFR( nProfileFrameId)
|
|
frInvert:invert()
|
|
-- lo applico a tutte le geometrie del profilo
|
|
EgtTransform( EgtGetAllInGroup( nProfileId), frInvert)
|
|
-- assegno come riferimento del profilo il punto start dell'outline
|
|
EgtChangeGroupFrame( nProfileId, Frame3d( EgtSP( nGuideId), - EgtSV( nGuideId)))
|
|
|
|
-- recupero outline del profilo Main e lo estrudo
|
|
local nSectionId = EgtGetFirstNameInGroup( nProfileId, sSectionName)
|
|
local nMainExtrusionId = EgtSurfTmSwept( nLayerId, nSectionId, nGuideId, false, WIN_SURF_APPROX)
|
|
EgtSetName( nMainExtrusionId, WIN_SRF_MAIN)
|
|
|
|
return nMainExtrusionId
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che crea il solido di un pezzo di telaio con cambio profilo
|
|
local function CalcMixedFrameSolid( nOutlineId, nSolidLayerId, nProfileLayerId, nGeoLayerId, dGeoWidth)
|
|
|
|
-- a) SOLIDO PRINCIPALE
|
|
-- creo i solidi corrispondenti alla parte sash e alla parte fill
|
|
local nMainProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN)
|
|
local nGuideId = CalcSolidGuide( nOutlineId, nSolidLayerId, nMainProfileId)
|
|
EgtSetName( nGuideId, WIN_MAINGUIDE)
|
|
EgtSetStatus( nGuideId, GDB_ST.OFF)
|
|
local sSectionSash = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. WIN_SASH .. WIN_SECTION
|
|
local nMainSash = CreateMainSurf( nGuideId, nMainProfileId, sSectionSash, nSolidLayerId)
|
|
local sSectionFill = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. WIN_FILL .. WIN_SECTION
|
|
local nMainFill = CreateMainSurf( nGuideId, nMainProfileId, sSectionFill, 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 .. '1')
|
|
local vStmInters = {}
|
|
for i = 1, #vIntersections do
|
|
local nSplitId = EgtGetInfo( vIntersections[i], WIN_MIXED_SPLIT_REF, 'i')
|
|
local vtDir = EgtSV( nSplitId)
|
|
local nCrvTrim = EgtCopyGlob( vIntersections[i], nSolidLayerId)
|
|
EgtAddCurveCompoLine( nCrvTrim, EgtSP( nCrvTrim) - 3 * dGeoWidth * vtDir, false)
|
|
EgtAddCurveCompoLine( nCrvTrim, EgtEP( nCrvTrim) + 3 * dGeoWidth * vtDir)
|
|
EgtMove( nCrvTrim, Z_AX())
|
|
EgtSetStatus( nCrvTrim, GDB_ST.OFF)
|
|
vStmInters[i] = EgtSurfTmByExtrusion( nSolidLayerId, nCrvTrim, - 2 * dGeoWidth * Z_AX())
|
|
EgtErase( nCrvTrim)
|
|
end
|
|
-- taglio le parti sash e fill e le riunisco in una sola superficie
|
|
local nStmTrim = EgtSurfTmByTriangles( nSolidLayerId, vStmInters)
|
|
EgtSurfTmIntersect( nMainFill, nStmTrim)
|
|
EgtSurfTmSubtract( nMainSash, nStmTrim)
|
|
EgtErase( nStmTrim)
|
|
EgtSurfTmAdd( nMainSash, nMainFill)
|
|
EgtErase( nMainFill)
|
|
local nMainSolid = nMainSash
|
|
|
|
-- 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)
|
|
TrimSolid( vPrevGeoIds, dGeoWidth, nSolidLayerId, nMainSolid)
|
|
|
|
-- c) TRIM END
|
|
local vNextGeoIds = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_RIGHT)
|
|
TrimSolid( vNextGeoIds, dGeoWidth, nSolidLayerId, nMainSolid)
|
|
|
|
return nMainSolid
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che calcola il solido corrispondente alla fresatura del cambio profilo per uno split
|
|
local function CalcMixedSplitMillingSolid( nMillingCrv, nSplitId, nSolidLayerId, dExtraLen, bPrev)
|
|
|
|
local nGuide = EgtCopyGlob( nMillingCrv, nSolidLayerId)
|
|
EgtAddCurveCompoLineTg( nGuide, 10, not bPrev)
|
|
local vtDir = EgtSV( nSplitId)
|
|
if bPrev then
|
|
vtDir = - vtDir
|
|
end
|
|
EgtAddCurveCompoLine( nGuide, EgtEP( nGuide) + dExtraLen * vtDir)
|
|
EgtAddCurveCompoLine( nGuide, EgtSP( nGuide) + dExtraLen * vtDir, false)
|
|
EgtCloseCurveCompo( nGuide)
|
|
EgtMove( nGuide, 0.01 * Z_AX())
|
|
local nCutStm = EgtSurfTmByRegionExtrusion( nSolidLayerId, nGuide, ( EgtCurveThickness( nGuide) - 2) * Z_AX())
|
|
EgtErase( nGuide)
|
|
return nCutStm
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che crea la superficie di trim per uno split coinvolto da cambio profilo ( controprofilo della parte sash del telaio e fresatura)
|
|
local function CreateMixedSplitTrimSurf( nSplitId, vOutlines, nProfileId, dExtraLen, bPrev, bNext, nSolidLayerId)
|
|
|
|
-- curva base
|
|
local nGuideId = EgtCurveCompo( nSolidLayerId, vOutlines, false)
|
|
local sTrimProfile = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. WIN_OFST .. WIN_SASH .. WIN_CTRIN
|
|
local nTrimStmId = CreateProfileSurf( nGuideId, nProfileId, sTrimProfile, dExtraLen, nSolidLayerId)
|
|
-- creo i blocchi per le milling
|
|
local nMixedIntersGrp = EgtGetFirstNameInGroup( EgtGetParent( nSolidLayerId), WIN_MIXED_CURVES)
|
|
if bPrev then
|
|
local nMillingCrv = EgtGetFirstNameInGroup( nMixedIntersGrp, WIN_MIXED_MILLING .. '1')
|
|
local nMillStmId = CalcMixedSplitMillingSolid( nMillingCrv, nSplitId, nSolidLayerId, dExtraLen, true)
|
|
EgtSurfTmSubtract( nTrimStmId, nMillStmId)
|
|
EgtErase( nMillStmId)
|
|
end
|
|
if bNext then
|
|
local nMillingCrv = EgtGetLastNameInGroup( nMixedIntersGrp, WIN_MIXED_MILLING .. '1')
|
|
local nMillStmId = CalcMixedSplitMillingSolid( nMillingCrv, nSplitId, nSolidLayerId, dExtraLen, false)
|
|
EgtSurfTmSubtract( nTrimStmId, nMillStmId)
|
|
EgtErase( nMillStmId)
|
|
end
|
|
EgtSetStatus( nTrimStmId, GDB_ST.OFF)
|
|
EgtErase( nGuideId)
|
|
return nTrimStmId
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che crea il solido di un pezzo di split coinvolto da cambio profilo
|
|
local function CalcMixedSplitSolid( nOutlineId, nSolidLayerId, nProfileLayerId, dGeoWidth)
|
|
|
|
-- a) creo il solido di estrusione principale
|
|
local nMainProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN)
|
|
local nGuideId = CalcSolidGuide( nOutlineId, nSolidLayerId, nMainProfileId)
|
|
local sSection = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. WIN_SECTION
|
|
local nMainExtrusionId = CreateMainSurf( nGuideId, nMainProfileId, sSection, nSolidLayerId)
|
|
-- creo una copia
|
|
local nOrigMainExtrusionId = EgtCopy( nMainExtrusionId, nSolidLayerId)
|
|
EgtSetName( nOrigMainExtrusionId, WIN_SRF_ORIGMAIN)
|
|
EgtSetStatus( nOrigMainExtrusionId, GDB_ST.OFF)
|
|
|
|
-- b) calcolo le superfici di trim con i controprofili sash e le curve di fresatura verificando se i tratti prev e next possono essere uniti per evitare di fare
|
|
-- booleane con superfici in parte sovrapposte
|
|
local vPrevOutlines = EgtGetInfo( nOutlineId, WIN_PREV_OUTLINES, 'vi')
|
|
local vNextOutlines = EgtGetInfo( nOutlineId, WIN_NEXT_OUTLINES, 'vi')
|
|
local nGeoLayerId = EgtGetFirstNameInGroup( EgtGetParent( nSolidLayerId), WIN_GEO)
|
|
local vPrevGeo = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_LEFT)
|
|
local vNextGeo = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_RIGHT)
|
|
|
|
if vPrevOutlines[1] == vNextOutlines[#vNextOutlines] or vPrevOutlines[#vPrevOutlines] == vNextOutlines[1] then
|
|
-- se prev e next hanno una curva comune gestisco come unica superficie
|
|
local vCrvs
|
|
if vPrevOutlines[1] == vNextOutlines[#vNextOutlines] then
|
|
vNextOutlines[#vNextOutlines] = nil
|
|
vCrvs = EgtJoinTables( vNextOutlines, vPrevOutlines)
|
|
else
|
|
vPrevOutlines[#vPrevOutlines] = nil
|
|
vCrvs = EgtJoinTables( vPrevOutlines, vNextOutlines)
|
|
end
|
|
local nPrevProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_START)
|
|
local nTrimStmId = CreateMixedSplitTrimSurf( nOutlineId, vCrvs, nPrevProfileId, 2 * dGeoWidth, true, true, nSolidLayerId)
|
|
EgtSurfTmIntersect( nMainExtrusionId, nTrimStmId)
|
|
for i = 1, #vPrevGeo do
|
|
EgtSetInfo( vPrevGeo[i], WIN_REF_SURF, nTrimStmId)
|
|
end
|
|
for i = 1, #vNextGeo do
|
|
EgtSetInfo( vNextGeo[i], WIN_REF_SURF, nTrimStmId)
|
|
end
|
|
|
|
else
|
|
local nPrevProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_START)
|
|
local nTrimStmId1 = CreateMixedSplitTrimSurf( nOutlineId, vPrevOutlines, nPrevProfileId, 2 * dGeoWidth, true, false, nSolidLayerId)
|
|
EgtSurfTmIntersect( nMainExtrusionId, nTrimStmId1)
|
|
for i = 1, #vPrevGeo do
|
|
EgtSetInfo( vPrevGeo[i], WIN_REF_SURF, nTrimStmId1)
|
|
end
|
|
|
|
local nNextProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_END)
|
|
local nTrimStmId2 = CreateMixedSplitTrimSurf( nOutlineId, vNextOutlines, nNextProfileId, 2 * dGeoWidth, false, true, nSolidLayerId)
|
|
EgtSurfTmIntersect( nMainExtrusionId, nTrimStmId2)
|
|
for i = 1, #vNextGeo do
|
|
EgtSetInfo( vNextGeo[i], WIN_REF_SURF, nTrimStmId2)
|
|
end
|
|
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)
|
|
|
|
-- 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 bChangeProfile = EgtGetInfo( nOutlineId, WIN_PRF_CHANGE, 'b') or false
|
|
if bChangeProfile then
|
|
if EgtGetName( nOutlineId) == WIN_SPLIT then
|
|
return CalcMixedSplitSolid( nOutlineId, nSolidLayerId, nProfileLayerId, dGeoWidth)
|
|
else
|
|
return CalcMixedFrameSolid( nOutlineId, nSolidLayerId, nProfileLayerId, nGeoLayerId, dGeoWidth)
|
|
end
|
|
end
|
|
|
|
-- a) creo il solido di estrusione principale
|
|
local nMainProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN)
|
|
local nGuideId = CalcSolidGuide( nOutlineId, nSolidLayerId, nMainProfileId)
|
|
local sSection = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. WIN_SECTION
|
|
local nMainExtrusionId = CreateMainSurf( nGuideId, nMainProfileId, sSection, nSolidLayerId)
|
|
|
|
-- 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 e su end
|
|
local nGeoRight = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_RIGHT)
|
|
TrimSolid( nGeoRight, dGeoWidth, nSolidLayerId, nMainExtrusionId)
|
|
local nGeoLeft = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_LEFT)
|
|
TrimSolid( nGeoLeft, dGeoWidth, nSolidLayerId, nMainExtrusionId)
|
|
|
|
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 UpdateSolidWithProcessingSurf( 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( nPrevGeo, nGeo, nRefOutline, bCurrFullOrShort, bSashOrFrame)
|
|
|
|
-- 1) la direzione z è determinata dal pezzo short
|
|
local vtZ
|
|
if EgtGetType( nRefOutline) == GDB_TY.CRV_LINE then
|
|
vtZ = EgtEV( nRefOutline)
|
|
else
|
|
-- se pezzo ad arco, recupero la direzione dalla curva nel punto estremo del geo
|
|
local nGeoRefCrv
|
|
if bCurrFullOrShort then
|
|
nGeoRefCrv = EgtGetFirstNameInGroup( nPrevGeo, WIN_RIGHT)
|
|
else
|
|
nGeoRefCrv = EgtGetFirstNameInGroup( nGeo, WIN_LEFT)
|
|
end
|
|
local ptInt = EgtIP( nGeoRefCrv, nRefOutline, ORIG())
|
|
local dPar = EgtCurveParamAtPoint( nRefOutline, ptInt, 100 * GEO.EPS_SMALL)
|
|
vtZ = EgtUV( nRefOutline, dPar, -1)
|
|
end
|
|
|
|
local frDest = Frame3d( ORIG(), - vtZ)
|
|
|
|
-- 2) punto di origine
|
|
local nPrevRight = EgtGetFirstNameInGroup( nPrevGeo, WIN_GEO_RIGHT)
|
|
local ptRef1 = EgtIf( bCurrFullOrShort, EgtSP( nPrevRight), EgtEP( nPrevRight))
|
|
local nLeft = EgtGetFirstNameInGroup( nGeo, WIN_GEO_LEFT)
|
|
local ptRef2 = EgtIf( bCurrFullOrShort, EgtSP( nLeft), EgtEP( nLeft))
|
|
-- riporto i punti sulla curva di outline su cui va posizionato il profilo con le spine
|
|
local _, ptInt1 = EgtPointCurveDist( ptRef1, nRefOutline)
|
|
local _, ptInt2 = EgtPointCurveDist( ptRef2, nRefOutline)
|
|
|
|
-- nel caso di telaio conviene tenere il punto più "interno" visto che la correzione sarà fatta verso l'esterno
|
|
-- nel caso di anta conviene tenere quello più "esterno" visto che la correzione sarà fatta verso l'interno
|
|
ptInt1:toLoc( frDest)
|
|
ptInt2:toLoc( frDest)
|
|
local ptInt
|
|
if ptInt1:getX() > ptInt2:getX() then
|
|
ptInt = EgtIf( bSashOrFrame, Point3d( ptInt1), Point3d( ptInt2))
|
|
else
|
|
ptInt = EgtIf( bSashOrFrame, Point3d( ptInt2), Point3d( ptInt1))
|
|
end
|
|
ptInt:toGlob( frDest)
|
|
|
|
-- modifico il punto di origine del frame nel punto individuato
|
|
frDest:move( ptInt - ORIG())
|
|
|
|
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
|
|
UpdateSolidWithProcessingSurf( nDowelId, nMainExtrusionId, nLayerId)
|
|
end
|
|
|
|
return nDowelId
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che calcola la correzione da applicare al frame dei dowels per evitare che fuoriescano dal pezzo da un lato visibile ( esterno per ante ed interno per telaio)
|
|
local function CalcDowelFrameCorrection( nOutlineId, nPrevOutlineId, nDowelRef, frOrig, frDest, nTestSurfPos, nTestSurfPosPrev, nTestSurf, vtMove, nLayerId, dLen, dPrevLen)
|
|
|
|
local dMove = 0
|
|
-- se le curve sono due linee non serve correzione
|
|
if EgtGetType( nOutlineId) == GDB_TY.CRV_LINE and EgtGetType( nPrevOutlineId) == GDB_TY.CRV_LINE then
|
|
return dMove
|
|
end
|
|
|
|
-- 1) verifico posizione per il pezzo corrente
|
|
-- posiziono il dowel
|
|
local nDowel1 = EgtCopyGlob( nDowelRef, nLayerId)
|
|
PositionDowel( nDowel1, frOrig, frDest, - frDest:getVersZ(), nTestSurfPos)
|
|
-- verifico se la faccia di fondo fuoriesce dalla superficie di test
|
|
local dMove1 = EgtCAvToolPosStm( EgtCP( nDowel1) - frDest:getVersZ() * dLen, frDest:getVersZ(), nTestSurf, vtMove)
|
|
|
|
-- 2) verifico posizione per il pezzo precedente
|
|
-- posiziono il dowel
|
|
local nDowel2 = EgtCopyGlob( nDowelRef, nLayerId)
|
|
PositionDowel( nDowel2, frOrig, frDest, frDest:getVersZ(), nTestSurfPosPrev)
|
|
-- verifico se la faccia di fondo fuoriesce dalla superficie di test
|
|
local dMove2 = EgtCAvToolPosStm( EgtCP( nDowel2) + frDest:getVersZ() * dPrevLen, - frDest:getVersZ(), nTestSurf, vtMove)
|
|
|
|
EgtErase( nDowel1)
|
|
EgtErase( nDowel2)
|
|
|
|
-- calcolo la correzione complessiva
|
|
dMove = max( dMove1, dMove2) + s_dDowelTol
|
|
return dMove
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che calcola i dowels tra due pezzi
|
|
local function CalcDowels( nOrigOutlineId, nOrigPrevOutlineId, bSashOrFrame, nBottomRail)
|
|
|
|
-- 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 i geo
|
|
local nGeo = EgtGetFirstNameInGroup( nPart, WIN_GEO)
|
|
local nPrevGeo = EgtGetFirstNameInGroup( nPrevPart, WIN_GEO)
|
|
|
|
-- 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 = EgtGetInfo( nOutlineId, WIN_STARTJOINT, 'i')
|
|
if nBottomRail then
|
|
if EgtGetName( nOutlineId) == WIN_BOTTOM then
|
|
nJointType = WIN_PART_JNT.SHORT
|
|
else
|
|
nJointType = WIN_PART_JNT.FULL
|
|
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( nPrevGeo, nGeo, nPrevOutlineId, true, bSashOrFrame)
|
|
|
|
-- 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) -- 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 nGeoCrv = EgtGetFirstNameInGroup( nPrevGeo, WIN_GEO_RIGHT)
|
|
local nOrigSurf = EgtGetInfo( nGeoCrv, WIN_REF_SURF, 'i')
|
|
nTestSurf = EgtCopyGlob( nOrigSurf, nLayerId)
|
|
end
|
|
local nTestSurfInverted = EgtCopyGlob( nTestSurf, nLayerId)
|
|
EgtInvertSurf( nTestSurfInverted)
|
|
|
|
-- superficie test per la traslazione dei dowels
|
|
local nTestSurf2
|
|
if bSashOrFrame then
|
|
-- se anta la superficie da cui non fuoriuscire è quella esterna del pezzo short, ovvero la superficie usata per trimmare lo start del pezzo corrente
|
|
if not s_bCalcSolid or s_bSimplSolid then
|
|
nTestSurf2 = CreateProfileSurf( nOrigPrevOutlineId, nPrevProfileId, WIN_OFST .. WIN_OUT, 100, nLayerId)
|
|
else
|
|
local nGeoCrv = EgtGetFirstNameInGroup( nGeo, WIN_GEO_LEFT)
|
|
local nOrigSurf = EgtGetInfo( nGeoCrv, WIN_REF_SURF, 'i')
|
|
nTestSurf2 = EgtCopyGlob( nOrigSurf, nLayerId)
|
|
end
|
|
EgtInvertSurf( nTestSurf2)
|
|
else
|
|
-- se telaio la superficie da cui non fuoriuscire è quella interna del pezzo short
|
|
local sCtrIn2 = WIN_OFST .. GetProfileCtrIn( nOrigPrevOutlineId, nOutlineId, nPrevProfileId)
|
|
nTestSurf2 = CreateProfileSurf( nOrigPrevOutlineId, nPrevProfileId, sCtrIn2, 100, nLayerId)
|
|
end
|
|
|
|
-- direzione per la traslazione dei dowels
|
|
local vtMove = EgtIf( bSashOrFrame, - frDest:getVersX(), frDest:getVersX())
|
|
|
|
-- 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
|
|
|
|
-- recupero il dowel nella posizione più problematica ( per le ante è quello più esterno, per il telaio quello più interno)
|
|
local nDowelRef = EgtIf( bSashOrFrame, vDowels[1], vDowels[#vDowels])
|
|
-- calcolo correzione da applicare al frame affinchè i dowels non fuoriescano da un lato visibile ( esterno per ante ed interno per telaio)
|
|
local dLenCurr = CalcDowelLen( nDowelRef, sLenKey, true)
|
|
local dLenPrev = CalcDowelLen( nDowelRef, sPrevLenKey, false)
|
|
local dMove = CalcDowelFrameCorrection( nOutlineId, nPrevOutlineId, nDowelRef, frOrig, frDest, nTestSurfInverted, nTestSurf, nTestSurf2, vtMove, nLayerId, dLenCurr, dLenPrev)
|
|
local frDestDowel = Frame3d( frDest)
|
|
frDestDowel:move( dMove * vtMove)
|
|
|
|
for i = 1, #vDowels do
|
|
-- dowels per pezzo corrente ( full)
|
|
local dLenFull = CalcDowelLen( vDowels[i], sLenKey, true)
|
|
CreateDowel( vDowels[i], nLayerId, frOrig, frDestDowel, - frDestDowel: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, frDestDowel, frDestDowel:getVersZ(), nTestSurf, dLenShort, WIN_PRC_SIDETYPE.RIGHT, nPrevSolidId)
|
|
end
|
|
end
|
|
end
|
|
|
|
EgtErase( nTestSurf)
|
|
EgtErase( nTestSurfInverted)
|
|
EgtErase( nTestSurf2)
|
|
|
|
|
|
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( nPrevGeo, nGeo, nOutlineId, false, bSashOrFrame)
|
|
|
|
-- 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) -- controprofilo del pezzo full
|
|
nTestSurf = CreateProfileSurf( nOrigPrevOutlineId, nPrevProfileId, sCtrIn, 100, nLayerId)
|
|
else
|
|
local nGeoCrv = EgtGetFirstNameInGroup( nGeo, WIN_GEO_LEFT)
|
|
local nOrigSurf = EgtGetInfo( nGeoCrv, WIN_REF_SURF, 'i')
|
|
nTestSurf = EgtCopyGlob( nOrigSurf, nLayerId)
|
|
end
|
|
local nTestSurfInverted = EgtCopyGlob( nTestSurf, nLayerId)
|
|
EgtInvertSurf( nTestSurfInverted)
|
|
|
|
-- superficie test per la traslazione dei dowels
|
|
local nTestSurf2
|
|
if bSashOrFrame then
|
|
if not s_bCalcSolid or s_bSimplSolid then
|
|
nTestSurf2 = CreateProfileSurf( nOrigOutlineId, nProfileId, WIN_OFST .. WIN_OUT, 100, nLayerId)
|
|
else
|
|
local nGeoCrv = EgtGetFirstNameInGroup( nPrevGeo, WIN_GEO_RIGHT)
|
|
local nOrigSurf = EgtGetInfo( nGeoCrv, WIN_REF_SURF, 'i')
|
|
nTestSurf2 = EgtCopyGlob( nOrigSurf, nLayerId)
|
|
end
|
|
EgtInvertSurf( nTestSurf2)
|
|
else
|
|
local sCtrIn2 = WIN_OFST .. GetProfileCtrIn( nOutlineId, nPrevOutlineId, nProfileId) -- controprofilo del pezzo short
|
|
nTestSurf2 = CreateProfileSurf( nOrigOutlineId, nProfileId, sCtrIn2, 100, nLayerId)
|
|
end
|
|
|
|
-- direzione per la traslazione dei dowels
|
|
local vtMove = EgtIf( bSashOrFrame, - frDest:getVersX(), frDest:getVersX())
|
|
|
|
-- 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
|
|
|
|
-- recupero il dowel nella posizione più problematica ( per le ante è quello più esterno, per il telaio quello più interno)
|
|
local nDowelRef = EgtIf( bSashOrFrame, vDowels[1], vDowels[#vDowels])
|
|
-- calcolo correzione da applicare al frame affinchè i dowels non fuoriescano da un lato visibile ( esterno per ante ed interno per telaio)
|
|
local dLenCurr = CalcDowelLen( nDowelRef, sLenKey, false)
|
|
local dLenPrev = CalcDowelLen( nDowelRef, sPrevLenKey, true)
|
|
local dMove = CalcDowelFrameCorrection( nOutlineId, nPrevOutlineId, nDowelRef, frOrig, frDest, nTestSurf, nTestSurfInverted, nTestSurf2, vtMove, nLayerId, dLenCurr, dLenPrev)
|
|
local frDestDowel = Frame3d( frDest)
|
|
frDestDowel:move( dMove * vtMove)
|
|
|
|
for i = 1, #vDowels do
|
|
-- dowels per pezzo corrente ( short)
|
|
local dLenShort = CalcDowelLen( vDowels[i], sLenKey, false)
|
|
CreateDowel( vDowels[i], nLayerId, frOrig, frDestDowel, - frDestDowel: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, frDestDowel, frDestDowel:getVersZ(), nTestSurfInverted, dLenFull, WIN_PRC_SIDETYPE.IN, nPrevSolidId)
|
|
end
|
|
end
|
|
end
|
|
|
|
EgtErase( nTestSurf)
|
|
EgtErase( nTestSurfInverted)
|
|
EgtErase( nTestSurf2)
|
|
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 = WIN_PRC_SIDETYPE.RIGHT
|
|
if bStartOrEnd then
|
|
sSplitDowelSide = WIN_PRC_SIDETYPE.LEFT
|
|
end
|
|
|
|
-- recupero la superficie del pezzo per verificare se dowel interno
|
|
local nSplitGeo = EgtGetFirstNameInGroup( nSplitPart, WIN_GEO)
|
|
local nSplitSurf = EgtGetFirstNameInGroup( nSplitGeo, WIN_GEO_SURF)
|
|
|
|
local vGeoCrvs = EgtGetNameInGroup( nSplitGeo, EgtIf( bStartOrEnd, WIN_LEFT, WIN_RIGHT))
|
|
local ptRef = EgtIf( bStartOrEnd, EgtSP( nSplitId), EgtEP( nSplitId))
|
|
|
|
for i = 1, #vGeoCrvs do
|
|
|
|
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 nProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN)
|
|
local nTestSurf
|
|
if not s_bCalcSolid or s_bSimplSolid then
|
|
local bChangeProfile = EgtGetInfo( nSplitId, WIN_PRF_CHANGE, 'b') or false
|
|
if bChangeProfile then
|
|
local vOutlines
|
|
if bStartOrEnd then
|
|
vOutlines = EgtGetInfo( nSplitId, WIN_PREV_OUTLINES, 'vi')
|
|
else
|
|
vOutlines = EgtGetInfo( nSplitId, WIN_NEXT_OUTLINES, 'vi')
|
|
end
|
|
nTestSurf = CreateMixedSplitTrimSurf( nSplitId, vOutlines, nProfileId, 100, bStartOrEnd, not bStartOrEnd, nLayerId)
|
|
else
|
|
local sCtr = WIN_OFST .. GetProfileCtrIn( nOutlineId, nSplitId, nProfileId)
|
|
nTestSurf = CreateProfileSurf( nOutlineId, nProfileId, sCtr, 100, nLayerId)
|
|
end
|
|
else
|
|
-- è la stessa superficie utilizzata per il trim del solido
|
|
local nTrimSurf = EgtGetInfo( vGeoCrvs[i], WIN_REF_SURF, 'i')
|
|
nTestSurf = EgtCopyGlob( nTrimSurf, nSplitLayerId)
|
|
end
|
|
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
|
|
|
|
---------------------------------------------------------------------
|
|
-- 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 nOutline do
|
|
-- 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
|
|
nOutline = EgtGetNext( nOutline)
|
|
end
|
|
|
|
elseif nAreaType == WIN_AREATYPES.SPLIT then
|
|
local nSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_SPLIT)
|
|
local nSplitType = EgtGetInfo( nSplitLayerId, 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 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
|
|
local bInverted = EgtGetInfo( nOutlineId, WIN_INV_SPLIT, 'b') or false
|
|
if bInverted 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, nRefOutlineId, 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( nOutlineId, nSolidLayerId)
|
|
EgtOffsetCurve( nMinOffsetId, dMinOffs)
|
|
local nMaxOffsetId = EgtCopy( nOutlineId, nSolidLayerId)
|
|
EgtOffsetCurve( nMaxOffsetId, dMaxOffs)
|
|
|
|
-- verifico se le curve vanno invertite nel caso di split
|
|
local bInverted = EgtGetInfo( nRefOutlineId, WIN_INV_SPLIT, 'b') or false
|
|
if bInverted 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( nGeoFillId)
|
|
|
|
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 vGeoCrvs = EgtGetAllInGroup( nGeoFillId)
|
|
local tabStrip = {}
|
|
for i = 1, #vGeoCrvs do
|
|
|
|
local nCrvId = abs( EgtGetInfo( vGeoCrvs[i], WIN_REF_OUTLINE, 'i'))
|
|
local nOutlineId = abs( EgtGetInfo( nCrvId, WIN_REF_OUTLINE, 'i'))
|
|
local nPartId = FindAssociatedPart( nOutlineId, true)
|
|
|
|
-- recupero profilo
|
|
local nProfileLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE)
|
|
local nProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN)
|
|
local nStripId = GetStripNearestToOutline( nProfileId, nCrvId)
|
|
|
|
-- recupero layer per solido
|
|
local nSolidLayerId = EgtGetFirstNameInGroup( nPartId, WIN_SOLID)
|
|
|
|
-- estrusione del fermavetro :
|
|
-- creazione della giuda
|
|
local nGuideId = EgtCurveCompo( nSolidLayerId, 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( vGeoCrvs[i]) or EgtGetLastInGroup( nGeoFillId)
|
|
local nNext = EgtGetNext( vGeoCrvs[i]) or EgtGetLastInGroup( nGeoFillId)
|
|
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)
|
|
local nStripExtrusionId = EgtSurfTmSwept( nSolidLayerId, nSectionId, nGuideId, false, WIN_SURF_APPROX)
|
|
EgtSetName( nStripExtrusionId, WIN_SRF_STRIP)
|
|
EgtErase( nSectionId)
|
|
EgtErase( nGuideId)
|
|
|
|
-- curve limite del fermavetro
|
|
local nOffs1, nOffs2 = CreateStripGuideLines( nOutlineId, nCrvId, nStripId, nProfileId, nGrp)
|
|
EgtSetInfo( nOffs1, WIN_REF_GEO, vGeoCrvs[i])
|
|
EgtSetInfo( nOffs2, WIN_REF_GEO, vGeoCrvs[i])
|
|
|
|
tabStrip[vGeoCrvs[i]] = { OrigOffs1 = nOffs1, OrigOffs2 = nOffs2, Offs1 = GDB_ID.NULL, Offs2 = GDB_ID.NULL, StripId = nStripExtrusionId}
|
|
EgtCopyGlob( nOffs1, nGrp1)
|
|
EgtCopyGlob( nOffs2, nGrp2)
|
|
end
|
|
|
|
-- taglio le curve limite dei fermavetri per individuare correttamente i pezzi con cui verranno tagliati
|
|
TrimOrderedCurves( EgtGetAllInGroup( nGrp1))
|
|
TrimOrderedCurves( EgtGetAllInGroup( nGrp2))
|
|
|
|
-- associo le curve trimmate alle curve geo corrispondenti
|
|
local nCrvId = EgtGetFirstInGroup( nGrp1)
|
|
while nCrvId do
|
|
local nGeoRef = EgtGetInfo( nCrvId, WIN_REF_GEO, 'i')
|
|
tabStrip[nGeoRef].Offs1 = nCrvId
|
|
nCrvId = EgtGetNext( nCrvId)
|
|
end
|
|
nCrvId = EgtGetFirstInGroup( nGrp2)
|
|
while nCrvId do
|
|
local nGeoRef = EgtGetInfo( nCrvId, WIN_REF_GEO, 'i')
|
|
tabStrip[nGeoRef].Offs2 = nCrvId
|
|
nCrvId = EgtGetNext( nCrvId)
|
|
end
|
|
|
|
-- trim dei solidi fermavetro
|
|
for i = 1, #vGeoCrvs do
|
|
|
|
-- recupero solido del fermavetro
|
|
local nGeoCrv = vGeoCrvs[i]
|
|
local nStripId = tabStrip[nGeoCrv].StripId
|
|
local nSolidLayerId = EgtGetParent( nStripId)
|
|
|
|
-- recupero le corrispondenti curve limite trimmate
|
|
local nCrvOffs1 = tabStrip[nGeoCrv].Offs1
|
|
local nCrvOffs2 = tabStrip[nGeoCrv].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_GEO, 'i')
|
|
local nPrevCrv2 = EgtGetInfo( nPrev2, WIN_REF_GEO, '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 nStartCrv = tabStrip[nPrevCrv1].Offs2
|
|
nStartCrv = EgtGetNext( nStartCrv) or EgtGetFirstInGroup( EgtGetParent( nStartCrv))
|
|
local vIds = {}
|
|
while nStartCrv ~= nCrvOffs2 do
|
|
table.insert( vIds, nStartCrv)
|
|
nStartCrv = EgtGetNext( nStartCrv) or EgtGetFirstInGroup( EgtGetParent( nStartCrv))
|
|
end
|
|
local nCrvRef2 = EgtCurveCompo( nGrp, vIds, false)
|
|
-- taglio
|
|
TrimStripSurfByCurve( nCrvRef2, nStripId, nSolidLayerId)
|
|
|
|
-- b) taglio che separa da pezzo 1
|
|
TrimStripSurfByPoints( EgtCP( nCrvRef2), EgtSP( nCrvOffs1), nStripId, nSolidLayerId, true)
|
|
EgtErase( nCrvRef2)
|
|
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_GEO, 'i')
|
|
local nNextCrv2 = EgtGetInfo( nNext2, WIN_REF_GEO, 'i')
|
|
|
|
if nNextCrv1 == nNextCrv2 then
|
|
TrimStripSurfByPoints( EgtEP( nCrvOffs1), EgtEP( nCrvOffs2), nStripId, nSolidLayerId)
|
|
else
|
|
local nStartCrv = nCrvOffs2
|
|
nStartCrv = EgtGetNext( nStartCrv) or EgtGetFirstInGroup( EgtGetParent( nStartCrv))
|
|
local vIds = {}
|
|
while nStartCrv ~= tabStrip[nNextCrv1].Offs2 do
|
|
table.insert( vIds, nStartCrv)
|
|
nStartCrv = EgtGetNext( nStartCrv) or EgtGetFirstInGroup( EgtGetParent( nStartCrv))
|
|
end
|
|
local nCrvRef2 = EgtCurveCompo( nGrp, vIds, false)
|
|
TrimStripSurfByCurve( nCrvRef2, nStripId, nSolidLayerId)
|
|
|
|
TrimStripSurfByPoints( EgtEP( nCrvOffs1), EgtCP( nCrvRef2), nStripId, nSolidLayerId)
|
|
EgtErase( nCrvRef2)
|
|
end
|
|
|
|
else
|
|
-- il pezzo scompare
|
|
EgtErase( nStripId)
|
|
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 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')
|
|
table.insert( vParts, { nId = nPartId, nOutlineId = nOutlineId})
|
|
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( nGeoLayerId)
|
|
end
|
|
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 nSouId = EgtGetInfo( nOutlineId, WIN_COPY, 'i')
|
|
local nAreaType = WIN_AREATYPES.NULL
|
|
while nSouId and nAreaType ~= WIN_AREATYPES.FRAME do
|
|
nSouId = EgtGetInfo( nSouId, WIN_SOU, 'i') or GDB_ID.NULL
|
|
local nParentArea = EgtGetParent( EgtGetParent( nSouId)) or GDB_ID.NULL
|
|
nAreaType = EgtGetInfo( nParentArea, WIN_AREATYPE, 'i')
|
|
end
|
|
if not nSouId then return end
|
|
local nFrameOutlineId = EgtGetInfo( nSouId, WIN_COPY, '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)
|
|
|
|
-- 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 = EgtGetInfo( nInfoGrp, WIN_DWL_DIAM, 'd')
|
|
local dDowelLen = 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
|
|
UpdateSolidWithProcessingSurf( 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 nBaseOutlineId = EgtGetInfo( nOutlineId, WIN_COPY, 'i')
|
|
local dDelta = ( EgtSP( nOutlineId) - EgtSP( nBaseOutlineId)) * 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 nBaseOutlineId = EgtGetInfo( nOutlineId, WIN_COPY, 'i')
|
|
local dDelta = ( EgtSP( nOutlineId) - EgtSP( nBaseOutlineId)) * 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 nBaseOutlineId = EgtGetInfo( nOutlineId, WIN_COPY, 'i')
|
|
local dDelta = ( EgtSP( nOutlineId) - EgtSP( nBaseOutlineId)) * 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 nBaseOutlineId = EgtGetInfo( nLeftId, WIN_COPY, 'i')
|
|
local bLeftInactive = EgtGetInfo( nBaseOutlineId, 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)
|
|
|
|
-- costruisco i riferimenti
|
|
local tFrame = {}
|
|
for nIndex = 1, #vOutlineCopy do
|
|
-- 1) Riferimenti ANTA
|
|
local ptOrig = EgtEP( vOutlineCopy[nIndex])
|
|
local sOrigName = string.char( string.byte( 'A') + #vOutlineCopy - nIndex)
|
|
local vtDir = EgtEV( vOutlineCopy[nIndex])
|
|
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[nIndex], WIN_GAPDELTAZ, 'd')
|
|
local nFA2Id = EgtFrame( nHdwSashLayerId, Frame3d( ptOrig - dGapDeltaZ * Z_AX(), - vtDir, vtDir ^ vtIn, vtIn))
|
|
EgtSetName( nFA2Id, sOrigName .. '.FA2')
|
|
local dGapDeltaZ2 = EgtGetInfo( vOutlineCopy[nIndex], 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 ( è il primo parent con un profilo associato. Potrebbe essere uno split in sottoarea del telaio o potrebbe non
|
|
-- esistere nel caso di french split)
|
|
local nOrigOutlineId = EgtGetInfo( vOutlineCopy[nIndex], 'ORIG', 'i')
|
|
local nBaseOutlineId = EgtGetInfo( nOrigOutlineId, WIN_COPY, 'i')
|
|
local nSouId = EgtGetInfo( nBaseOutlineId, WIN_SOU, 'i')
|
|
local sProfileFrame = EgtGetInfo( nSouId, WIN_PROFILETYPE)
|
|
while nSouId and not sProfileFrame do
|
|
nSouId = EgtGetInfo( nSouId, WIN_SOU, 'i')
|
|
sProfileFrame = EgtGetInfo( nSouId or GDB_ID.NULL, WIN_PROFILETYPE)
|
|
end
|
|
|
|
if nSouId then
|
|
-- ricavo aria lato telaio
|
|
local nFrameOutlineId = EgtGetInfo( nSouId, WIN_COPY, 'i')
|
|
local nFrameProfileId = GetOutlineProfileId( nFrameOutlineId)
|
|
local dGapDeltaOut = EgtGetInfo( nFrameProfileId, WIN_GAPDELTA, 'd')
|
|
-- se deriva da split verifico il lato
|
|
if EgtGetName( nSouId) == WIN_SPLIT then
|
|
local bSameDir = AreSameVectorApprox( EgtSV( nSouId), EgtSV( nBaseOutlineId))
|
|
-- recupero informazione dal lato corretto ( split orizzontale)
|
|
if not dGapDeltaOut then
|
|
if bSameDir then
|
|
dGapDeltaOut = EgtGetInfo( nFrameProfileId, WIN_GAPDELTA .. '2', 'd')
|
|
else
|
|
dGapDeltaOut = EgtGetInfo( nFrameProfileId, WIN_GAPDELTA .. '1', 'd')
|
|
end
|
|
end
|
|
-- verifico il segno dell'offset
|
|
if not bSameDir then
|
|
dGapDeltaOut = - dGapDeltaOut
|
|
end
|
|
end
|
|
local nOutlineOutId = EgtCopy( 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 nSashBaseOutlineId = EgtGetInfo( nOutlineId, WIN_COPY, 'i')
|
|
local nSouId = EgtGetInfo( nSashBaseOutlineId, WIN_SOU, 'i')
|
|
local sSouProfile = EgtGetInfo( nSouId, WIN_PROFILETYPE)
|
|
while nSouId and not sSouProfile do
|
|
nSouId = EgtGetInfo( nSouId, WIN_SOU, 'i')
|
|
sSouProfile = EgtGetInfo( nSouId or GDB_ID.NULL, WIN_PROFILETYPE)
|
|
end
|
|
local nFrameOutlineId = EgtGetInfo( nSouId, WIN_COPY, '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
|
|
UpdateSolidWithProcessingSurf( 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
|
|
UpdateSolidWithProcessingSurf( 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 nSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_SPLIT) or GDB_ID.NULL
|
|
local nSplitType = EgtGetInfo( nSplitLayerId, 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
|
|
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 vChildren = EgtGetInfo( nOutlineId, WIN_SASH_CHILDREN, 'vi')
|
|
for i = 1, #vChildren do
|
|
local nSashAreaId = EgtGetParent( EgtGetParent( vChildren[i]))
|
|
local nSashType = EgtGetInfo( nSashAreaId, WIN_SASHTYPE, 'i')
|
|
if nSashType == WIN_SASHTYPES.SLIDE_FIXED then
|
|
|
|
local nGuideId = EgtCopyGlob( vChildren[i], nAuxGrp)
|
|
EgtExtendCurveStartByLen( nGuideId, 1000)
|
|
EgtExtendCurveEndByLen( nGuideId, 1000)
|
|
-- trim della guida con il geo dei pezzi vicini
|
|
local nOutlineId = EgtGetInfo( vChildren[i], WIN_COPY, 'i')
|
|
local nPrevCrv = EgtGetInfo( nOutlineId, WIN_PREV_OUTLINES, 'i')
|
|
local dParS = GetTrimParamByGeo( nGuideId, nPrevCrv, WIN_GEO_OUT)
|
|
local nNextCrv = EgtGetInfo( nOutlineId, WIN_NEXT_OUTLINES, 'i')
|
|
local dParE = GetTrimParamByGeo( nGuideId, nNextCrv, 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 nSplitId = EgtGetFirstNameInGroup( vStack[i], WIN_SPLIT)
|
|
local nSplitType = EgtGetInfo( nSplitId, WIN_SPLITTYPE, 'i')
|
|
if nSplitType ~= WIN_SPLITTYPES.FRENCH then
|
|
local vCurrSplits = EgtGetAllInGroup( nSplitId)
|
|
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 o vetro ( che interrompono la cascata di pezzi relativi al telaio) salvo le sottaree per analizzarle
|
|
if nAreaType ~= WIN_AREATYPES.SASH and nAreaType ~= WIN_AREATYPES.FILL 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 ( non dovrebbero mai capitare parametri coincidenti)
|
|
table.sort( vParams)
|
|
|
|
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)
|
|
|
|
-- 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, color)
|
|
|
|
-- 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, color)
|
|
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 nStartJoint = EgtGetInfo( nOutlineId, WIN_STARTJOINT, 'i')
|
|
local nEndJoint = EgtGetInfo( nOutlineId, WIN_ENDJOINT, 'i')
|
|
|
|
local nAreaId
|
|
|
|
-- se non ha giunzioni short come preview posso considerare direttamente la regione del geo
|
|
if nStartJoint ~= WIN_PART_JNT.SHORT and nEndJoint ~= 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)
|
|
if nStartJoint == WIN_PART_JNT.ANGLED then
|
|
|
|
-- recupero la bisettrice dal geo
|
|
EgtCopyGlob( vGeoLeft[1], nGrpTmp)
|
|
|
|
-- 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
|
|
for i = 1, #vPrevOutlineId do
|
|
|
|
-- 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
|
|
nStartJoint = WIN_PART_JNT.FULL
|
|
end
|
|
|
|
if nStartJoint == 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)
|
|
if nEndJoint == WIN_PART_JNT.ANGLED then
|
|
|
|
-- recupero la bisettrice dal geo
|
|
local nCrvId = EgtCopyGlob( vGeoRight[1], nGrpTmp)
|
|
EgtRelocateGlob( nCrvId, nInId, GDB_IN.BEFORE)
|
|
|
|
-- curva aux
|
|
local nAuxCrv = EgtCopyGlob( abs( vNextOutlineId[1]), nGrpTmp)
|
|
local b3Profile = GetProfileLocalBox( vNextProfileId[1])
|
|
EgtOffsetCurve( nAuxCrv, b3Profile:getMax():getX())
|
|
EgtRelocateGlob( nAuxCrv, nInId, GDB_IN.BEFORE)
|
|
|
|
else
|
|
for i = 1, #vNextOutlineId do
|
|
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
|
|
nEndJoint = WIN_PART_JNT.FULL
|
|
end
|
|
|
|
if nEndJoint == 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
|
|
|
|
-- 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
|
|
end
|
|
local color = EgtGetColor( nPartId)
|
|
EgtSetColor( nAreaId, color)
|
|
-- 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, color)
|
|
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 nSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_SPLIT) or GDB_ID.NULL
|
|
local nSplitType = EgtGetInfo( nSplitLayerId, 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)
|
|
-- assegno il tipo di profilo alle curve del base outline
|
|
CalculateAreaProfileType( nFrameId)
|
|
-- calcolo outline a partire dal base outline
|
|
CalculateAreaOutline( nFrameId)
|
|
SetAreaProfiles( nFrameId)
|
|
-- creo pezzi
|
|
s_nSashNbr = 0 -- resetto il numero di ante del progetto
|
|
CalculateAreaParts( nFrameId)
|
|
-- calcolo le spine
|
|
CalculateAreaDowels( nFrameId)
|
|
|
|
-- calcolo preview 2d se richiesta
|
|
if s_bCalcPreview then
|
|
CalcPreview( nFrameId)
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che ricalcola i solidi ( per cambio modalità visualizzazione)
|
|
function WinCalculate.RecalcSolids( nFrameId)
|
|
|
|
-- scorro tutti i pezzi
|
|
local nPartId = EgtGetFirstPart()
|
|
while nPartId do
|
|
-- se solidi non vanno calcolati elimino semplicemente il gruppo dei solidi da ogni pezzo
|
|
if not s_bCalcSolid then
|
|
local nSolidLayId = EgtGetFirstNameInGroup( nPartId, WIN_SOLID) or GDB_ID.NULL
|
|
EgtErase( nSolidLayId)
|
|
|
|
-- ricalcolo dei solidi
|
|
else
|
|
-- se fill, lo uso per ricalcolare strip
|
|
local nPartType = EgtGetInfo( nPartId, WIN_PART_TYPE, 'i')
|
|
if nPartType == WIN_PART_TYPES.FILL then
|
|
local nAreaId = EgtGetInfo( nPartId, WIN_AREA, 'i')
|
|
local nParentAreaId = EgtGetParent( nAreaId)
|
|
local nParentOutlineLayId = EgtGetFirstNameInGroup( nParentAreaId, WIN_OUTLINE)
|
|
local vParentOutlines = EgtGetAllInGroup( nParentOutlineLayId)
|
|
for i = 1, #vParentOutlines do
|
|
CreateStripFromOutline( nParentAreaId, vParentOutlines[i])
|
|
end
|
|
|
|
-- verifico se solido da calcolare
|
|
local nSolidLayId = EgtGetFirstNameInGroup( nPartId, WIN_SOLID)
|
|
if not nSolidLayId then
|
|
local nOutlineLayId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE)
|
|
local nGeoLayId = EgtGetFirstNameInGroup( nPartId, WIN_GEO)
|
|
CalcFillSolid( nPartId, nOutlineLayId, nGeoLayId)
|
|
end
|
|
|
|
-- se pezzo, ricalcolo il suo solido
|
|
else
|
|
-- elimino gruppo dei solidi
|
|
local nSolidLayId = EgtGetFirstNameInGroup( nPartId, WIN_SOLID) or GDB_ID.NULL
|
|
EgtErase( nSolidLayId)
|
|
-- ricalcolo il solido principale
|
|
local nOutlineId = EgtGetInfo( nPartId, WIN_REF_OUTLINE, 'i')
|
|
local nSolidId = CalcSolid( nPartId, nOutlineId)
|
|
-- aggiungo lavorazioni
|
|
local nProcLayId = EgtGetFirstNameInGroup( nPartId, WIN_PRC)
|
|
local vProc = EgtGetAllInGroup( nProcLayId)
|
|
for i = 1, #vProc do
|
|
local nType = EgtGetInfo( vProc[i], WIN_PRC_FEATURE_TYPE)
|
|
local nProfilingType = EgtGetInfo( vProc[i], WIN_PRC_PROFILE_INFO)
|
|
if nType == WIN_PRC_TYPE.HOLE or ( nType == WIN_PRC_TYPE.PROFILING and nProfilingType == WIN_PRC_PROFILE_TYPE.GENERIC) then
|
|
UpdateSolidWithProcessingSurf( vProc[i], nSolidId, nProcLayId)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
nPartId = EgtGetNextPart( nPartId)
|
|
end
|
|
|
|
-- accessori e ferramenta
|
|
local nAuxGrp = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_AUX)
|
|
if not s_bCalcSolid then
|
|
EgtErase( nAuxGrp or GDB_ID.NULL)
|
|
elseif not nAuxGrp then
|
|
nAuxGrp = GetAuxLayer()
|
|
-- ferramenta
|
|
DrawHardware( nFrameId, nAuxGrp)
|
|
-- accessori
|
|
WinCalculate.AddAccessories( nFrameId, true)
|
|
end
|
|
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
return WinCalculate
|