67589d44ef
- arco a 3 centri - migliorie e correzioni varie per gestire correttamente l'arco a 3 centri ( calcolo solidi, strip, outline del fill).
6702 lines
292 KiB
Lua
6702 lines
292 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
|
|
require( 'EgtBase')
|
|
require( 'WinConst')
|
|
|
|
_G.package.loaded.JSON = nil
|
|
local JSON = require( 'JSON')
|
|
_G.package.loaded.XML = nil
|
|
local XML = require( 'xml2lua')
|
|
_G.package.loaded.XMLHandler = nil
|
|
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_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 = EgtGetParent( nCrv1)
|
|
local dExtraLen = 10000
|
|
local nCrvA, nCrvB
|
|
if EgtGetType( nCrv1) == GDB_TY.CRV_LINE and EgtGetType( nCrv2) == 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 EgtGetType( nCrv1) == GDB_TY.CRV_ARC and EgtGetType( nCrv2) == 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))
|
|
|
|
else
|
|
-- 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( { nCrvA, nCrvB})
|
|
end
|
|
|
|
return ptInt
|
|
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
|
|
-- costruisco le circonferenze associate agli archi verificando non ve ne siano di coincidenti
|
|
local dExtraLen = 10000
|
|
local vSemiPlaneSurfs = {}
|
|
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( vSemiPlaneSurfs, nSemiPlaneId)
|
|
|
|
else
|
|
-- creo circonferenza corrispondente
|
|
local nCircleId = EgtCopyGlob( vCrvs[i], nGrpTmp)
|
|
local dAngOld = EgtArcAngCenter( vCrvs[i])
|
|
EgtModifyArcAngCenter( nCircleId, EgtIf( dAngOld > 0, 360, -360))
|
|
-- verifico se coincide con altra circonferenza già costruita
|
|
local dRad = EgtArcRadius( nCircleId)
|
|
local ptC = EgtCP( nCircleId)
|
|
local bOverlap = false
|
|
for j = 1, #tArcs do
|
|
if AreSamePointApprox( tArcs[j].ptC, ptC) and abs( tArcs[j].dRad - dRad) < GEO.EPS_SMALL then
|
|
bOverlap = true
|
|
table.insert( tArcs[j].nArcId, vCrvs[i])
|
|
break
|
|
end
|
|
end
|
|
if not bOverlap then
|
|
table.insert( tArcs, { nCircleId = nCircleId, nArcId = {vCrvs[i]}, dRad = dRad, ptC = ptC})
|
|
end
|
|
end
|
|
end
|
|
|
|
-- calcolo la regione definita dai semipiani
|
|
for i = 2, #vSemiPlaneSurfs do
|
|
EgtSurfFrIntersect( vSemiPlaneSurfs[1], vSemiPlaneSurfs[i])
|
|
EgtErase( vSemiPlaneSurfs[i])
|
|
end
|
|
nSurfId = vSemiPlaneSurfs[1]
|
|
|
|
-- se presenti archi, calcolo il loro contributo alla regione
|
|
if #tArcs > 0 then
|
|
|
|
local nCrvBorder = EgtExtractSurfFrChunkLoops( nSurfId, 0, nGrpTmp)
|
|
|
|
-- riordino circonferenze 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
|
|
local nCircleId = tArcs[i].nCircleId
|
|
-- limito la circonferenza alla regione
|
|
local nSurfTrim = EgtSurfFlatRegion( nGrpTmp, nCrvBorder)
|
|
local nCrv, nCnt = EgtTrimCurveWithRegion( nCircleId, nSurfTrim, true, false)
|
|
|
|
if not nCrv then
|
|
-- è errore, lo ignoro
|
|
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
|
|
EgtModifyCurveStartPoint( nCrv, EgtSP( nCrv + nCnt - 1))
|
|
EgtErase( nCrv + nCnt - 1)
|
|
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)
|
|
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
|
|
|
|
-- considero solo i tratti che poggiano sulle curve orginali
|
|
for j = 1, #vArcs do
|
|
|
|
local bOk = false
|
|
for k = 1, #tArcs[i].nArcId do
|
|
local nOrigArc = tArcs[i].nArcId[k]
|
|
local dParS = EgtCurveParamAtPoint( nOrigArc, EgtSP( vArcs[j]))
|
|
local dParE = EgtCurveParamAtPoint( nOrigArc, EgtEP( vArcs[j]))
|
|
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( vArcs[j], EgtSP( nOrigArc))
|
|
local dPar2 = EgtCurveParamAtPoint( vArcs[j], EgtEP( nOrigArc))
|
|
if dPar1 or dPar2 then
|
|
bOk = true
|
|
break
|
|
end
|
|
elseif dParS and abs( dParS - 1) > GEO.EPS_SMALL then
|
|
bOk = true
|
|
break
|
|
elseif dParE and dParE > GEO.EPS_SMALL then
|
|
bOk = true
|
|
break
|
|
end
|
|
end
|
|
|
|
if not bOk then
|
|
EgtErase( vArcs[j])
|
|
else
|
|
-- modifico il bordo con il nuovo tratto
|
|
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])
|
|
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. Se è on o in allora il suo contributo è lo stesso di un'altra
|
|
-- curva di bordo quindi può essere eliminata
|
|
local nTestCrv = EgtCopyGlob( nCrvId, EgtGetParent( nSurfId))
|
|
local nTmp, nCnt = EgtTrimCurveWithRegion( nTestCrv, nSurfId, true, true)
|
|
if nCnt > 0 then
|
|
-- elimino il profilo corrispondente solo se non è curva in o out ( per non eliminare il profilo principale)
|
|
local nSemiProfileId = EgtGetInfo( nCrvId, WIN_SEMI_PROFILE, 'i')
|
|
local nProfileId = EgtGetParent( nSemiProfileId)
|
|
if EgtGetName( nProfileId) ~= WIN_PRF_MAIN then
|
|
EgtErase( nProfileId)
|
|
end
|
|
-- elimino la curva
|
|
EgtErase( nCrvId)
|
|
else
|
|
EgtSetInfo( nCrvId, WIN_GEO_EXTRA, true)
|
|
EgtSetStatus( nCrvId, GDB_ST.OFF)
|
|
end
|
|
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)
|
|
|
|
-- costruisco la regione definita dalle curve
|
|
local nGrpTmp = EgtGroup( GDB_ID.ROOT)
|
|
EgtSetStatus( nGrpTmp, GDB_ST.OFF)
|
|
local nSurfId = CalcIntersectionRegion( vCrvs, nGrpTmp)
|
|
|
|
-- copia estesa delle curve
|
|
local dExtraLen = 10000
|
|
local vCopies = {}
|
|
for i = 1, #vCrvs do
|
|
vCopies[i] = EgtCopyGlob( vCrvs[i], nGrpTmp)
|
|
if EgtGetType( vCrvs[i]) == GDB_TY.CRV_LINE then
|
|
-- se linea allungo le estremità
|
|
EgtExtendCurveStartByLen( vCopies[i], dExtraLen)
|
|
EgtExtendCurveEndByLen( vCopies[i], dExtraLen)
|
|
else
|
|
-- se arco lo trasformo in una circonferenza
|
|
local dAngOld = EgtArcAngCenter( vCrvs[i])
|
|
EgtModifyArcAngCenter( vCopies[i], EgtIf( dAngOld > 0, 360, -360))
|
|
end
|
|
end
|
|
|
|
-- recupero le curve di bordo della regione
|
|
local nBorderId = EgtExtractSurfFrChunkLoops( nSurfId, 0, nGrpTmp)
|
|
local nCrvBorder, nCnt = EgtExplodeCurveCompo( nBorderId)
|
|
|
|
-- individuo una curva di vCrvs e un tratto di nCrvBorder in corrispondenza biunivoca per gestire correttamente il ciclo
|
|
-- ( 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), vCopies[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
|
|
|
|
local vResultCurves = {}
|
|
local nC = nFirstIdxCrv
|
|
local nB = nFirstIdxBorder
|
|
repeat
|
|
-- se ho terminato le curve di bordo da associare devo cancellare tutte le curve rimaste
|
|
if nB == nFirstIdxBorder and nC ~= nFirstIdxCrv then
|
|
AdjustExtraCurvesForTrim( vCrvs[nC+1], nSurfId, nExtraCurvesMode)
|
|
|
|
else
|
|
local dDist = EgtPointCurveDist( EgtMP( nCrvBorder + nB), vCopies[nC+1])
|
|
-- se trovo corrispondenza
|
|
if dDist < GEO.EPS_SMALL then
|
|
-- assegno il nome
|
|
local sName = EgtGetName( vCrvs[nC+1])
|
|
if sName then
|
|
EgtSetName( nCrvBorder + nB, sName)
|
|
end
|
|
-- copio le info
|
|
local vInfo = EgtGetAllInfo( vCrvs[nC+1])
|
|
for j = 1, #vInfo do
|
|
local sInfo = EgtSplitString( vInfo[j], '=')
|
|
EgtSetInfo( nCrvBorder + nB, sInfo[1], sInfo[2])
|
|
end
|
|
-- riposiziono
|
|
EgtRelocateGlob( nCrvBorder + nB, vCrvs[nC+1], GDB_IN.AFTER)
|
|
-- modifico l'id sostutuendolo alla curva originale
|
|
EgtErase( vCrvs[nC+1])
|
|
EgtChangeId( nCrvBorder + nB, vCrvs[nC+1])
|
|
|
|
table.insert( vResultCurves, vCrvs[nC+1])
|
|
-- passo alla curva di bordo successiva
|
|
nB = ( nB + 1) % nCnt
|
|
else
|
|
-- la curva non appartiene al bordo, quindi va gestita opportunamente
|
|
AdjustExtraCurvesForTrim( vCrvs[nC+1], nSurfId, nExtraCurvesMode)
|
|
end
|
|
end
|
|
|
|
-- passo alla curva successiva
|
|
nC = ( nC + 1) % #vCrvs
|
|
until nC == nFirstIdxCrv
|
|
|
|
EgtErase( nGrpTmp)
|
|
return vResultCurves
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che data una curva di outline restituisce l'id del suo profilo
|
|
local function GetOutlineProfileId( nOutlineId, bForceBottomRail, nProfileType)
|
|
|
|
-- ciclo fino a trovare il primo parent che abbia un AreaType definito ( frame o sash)
|
|
local nParentId = EgtGetParent( nOutlineId)
|
|
local nAreaType = 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 EgtGetName( nOutlineId) == WIN_BOTTOM and bForceBottomRail then
|
|
local nBottomRailTot = EgtGetInfo( nOutlineId, WIN_BOTTOMRAIL, 'i') or 0
|
|
if nBottomRailTot > 0 then
|
|
sProfileName = WIN_FILL_RAIL
|
|
end
|
|
elseif nProfileType == WIN_PRF.BOTTOMRAIL then
|
|
sProfileName = WIN_RAIL
|
|
elseif nProfileType == WIN_PRF.BOTTOMRAIL_FINAL then
|
|
sProfileName = WIN_FILL_RAIL
|
|
end
|
|
|
|
-- recupero il profilo
|
|
return EgtGetFirstNameInGroup( nLayerId, sProfileName)
|
|
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, GDB_RT.GLOB)
|
|
return b3Box
|
|
end
|
|
|
|
|
|
|
|
----------------------------------------------------------------------------------
|
|
----------------------------- CALCOLO DEI PROFILI ------------------------------
|
|
----------------------------------------------------------------------------------
|
|
-- 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)
|
|
-- 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
|
|
bThreshold = false
|
|
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
|
|
bThreshold = false
|
|
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)
|
|
bThreshold = false
|
|
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
|
|
-- assegno info soglia
|
|
if bThreshold then
|
|
EgtSetInfo( nAreaId, WIN_THRESHOLD, true)
|
|
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
|
|
|
|
|
|
|
|
----------------------------------------------------------------------------------
|
|
------------------------------ CALCOLO OUTLINE ---------------------------------
|
|
----------------------------------------------------------------------------------
|
|
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)
|
|
|
|
-- 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
|
|
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)
|
|
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 vAdjustZ = {}
|
|
local nRefZ
|
|
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') or 0
|
|
local dDimRef = b3FrameProfile:getMin():getX()
|
|
local dFillPerpOffset = abs( dDimRef) - dOverlap
|
|
if EgtGetName( nParentProfileId) == WIN_FILL_RAIL then
|
|
-- se bottom rail considero la distanza necessaria per il numero di bottomrail richiesti
|
|
local nBottomRails = EgtGetInfo( nParentOutlineId, WIN_BOTTOMRAIL, 'i')
|
|
local dRailDelta1 = EgtGetInfo( nParentProfileId, WIN_RAILDELTA .. '1', 'd')
|
|
local dRailDelta2 = EgtGetInfo( nParentProfileId, WIN_RAILDELTA .. '2', 'd')
|
|
dFillPerpOffset = dFillPerpOffset + dRailDelta1 + ( nBottomRails - 1) * dRailDelta2
|
|
end
|
|
EgtOffsetCurve( nOutlineId, - dFillPerpOffset)
|
|
|
|
-- movimento in z : se non è definito ( come nel caso di alcuni pezzi di telaio con cambio profilo) salvo la curva per correggere la sua z in seguito, se è definito salvo
|
|
-- una curva come riferimento per le curve da correggere
|
|
local dFillZOffset = EgtGetInfo( nParentProfileId, WIN_FILLDELTA, 'd')
|
|
if not dFillZOffset then
|
|
table.insert( vAdjustZ, nOutlineId)
|
|
else
|
|
nRefZ = nOutlineId
|
|
EgtMove( nOutlineId, Z_AX() * dFillZOffset)
|
|
end
|
|
|
|
nParentOutlineId = EgtGetNext( nParentOutlineId)
|
|
end
|
|
-- sistemo quote per tratti che non avevano movimento in z definito nel profilo
|
|
for i = 1, #vAdjustZ do
|
|
EgtMove( vAdjustZ[i], ( EgtSP( nRefZ):getZ() - EgtSP( vAdjustZ[i]):getZ()) * Z_AX())
|
|
end
|
|
-- accorcio gli offset
|
|
local vCrvs = TrimOrderedCurves( EgtGetAllInGroup( nOutlineLayerId), 1)
|
|
|
|
|
|
-- 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 dall'area outline ( base outline)
|
|
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)
|
|
CopyInfo( nOutlineLayerId, nAreaOutlineLayerId, WIN_JOINTS)
|
|
|
|
-- FRAME
|
|
if nAreaType == WIN_AREATYPES.FRAME then
|
|
-- sistemo le info
|
|
local nAreaOutlineId = EgtGetFirstInGroup( nAreaOutlineLayerId)
|
|
while nAreaOutlineId do
|
|
local nOutlineId = EgtCopyGlob( nAreaOutlineId, nOutlineLayerId)
|
|
EgtSetInfo( nAreaOutlineId, WIN_COPY, nOutlineId)
|
|
EgtSetInfo( nOutlineId, WIN_COPY, nAreaOutlineId)
|
|
-- se bottom riporto informazione dei bottomrail e soglia
|
|
if EgtGetName( nOutlineId) == WIN_BOTTOM then
|
|
CopyInfo( nOutlineId, nAreaId, WIN_BOTTOMRAIL)
|
|
CopyInfo( nOutlineId, nAreaId, WIN_THRESHOLD)
|
|
end
|
|
nAreaOutlineId = EgtGetNext( nAreaOutlineId)
|
|
end
|
|
|
|
|
|
-- SPLIT
|
|
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)
|
|
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 e telaio
|
|
local nProfileLayerId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_PROFILE)
|
|
local nSashProfileLayerId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_SASH)
|
|
local nFrameProfileLayerId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_FRAME)
|
|
|
|
-- ciclo su profilo disegnato anta
|
|
local nBaseOutlineId = EgtGetFirstInGroup( nAreaOutlineLayerId)
|
|
while nBaseOutlineId do
|
|
-- recupero la curva di outline 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
|
|
-- recupero profilo
|
|
local sSashProfile = EgtGetInfo( nBaseOutlineId, WIN_PROFILETYPE)
|
|
local nSashProfileId = EgtGetFirstNameInGroup( nSashProfileLayerId, sSashProfile)
|
|
|
|
-- calcolo offset sulla z dell'anta
|
|
local dSashZOffset = EgtGetInfo( nSashProfileId, WIN_DELTA, 'd')
|
|
|
|
-- sposto anta in Z
|
|
EgtMove( nOutlineId, Z_AX() * dSashZOffset)
|
|
|
|
-- sistemo le info
|
|
EgtSetInfo( nBaseOutlineId, WIN_COPY, nOutlineId)
|
|
EgtSetInfo( nOutlineId, WIN_COPY, nBaseOutlineId)
|
|
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, sSashProfile)
|
|
if EgtGetName( nOutlineId) == WIN_BOTTOM then
|
|
CopyInfo( nOutlineId, nAreaId, WIN_BOTTOMRAIL)
|
|
end
|
|
EgtRemoveInfo( nOutlineId, WIN_PRF_CHANGE)
|
|
EgtRemoveInfo( nOutlineId, WIN_REF_SPLIT)
|
|
EgtRemoveInfo( nOutlineId, WIN_INV_SPLIT)
|
|
EgtRemoveInfo( nOutlineId, WIN_THRESHOLD)
|
|
|
|
-- verifico se outline e' segmento battente o ricevente ( che quindi deriva da split di tipo french)
|
|
local bOnFrenchSplit = EgtGetInfo( nBaseOutlineId, 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 nFrameProfileId = EgtGetFirstNameInGroup( nFrameProfileLayerId, sFrameProfile)
|
|
|
|
-- calcolo il box del riferimento del profilo del frame
|
|
local b3FrameProfile = GetProfileLocalBox( nFrameProfileId)
|
|
-- calcolo offset perpendicolare
|
|
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
|
|
|
|
-- faccio offset
|
|
EgtOffsetCurve( nOutlineId, - dSashPerpOffset)
|
|
|
|
else
|
|
-- se deriva da french split sistemo il nome
|
|
local sBaseName = EgtGetName( nBaseOutlineId)
|
|
EgtSetName( nOutlineId, sBaseName)
|
|
-- controllo l'orientamento
|
|
local nCrvRef = EgtGetPrev( nBaseOutlineId) or EgtGetNext( nBaseOutlineId)
|
|
local _, _, nSide = EgtPointCurveDistSide( EgtMP( nCrvRef), nOutlineId, Z_AX())
|
|
if nSide == 1 then
|
|
EgtInvertCurve( nOutlineId)
|
|
end
|
|
end
|
|
end
|
|
|
|
nBaseOutlineId = EgtGetNext( nBaseOutlineId)
|
|
end
|
|
-- accorcio gli offset
|
|
TrimOrderedCurves( EgtGetAllInGroup( nOutlineLayerId), 1)
|
|
|
|
|
|
-- FILL
|
|
elseif nAreaType == WIN_AREATYPES.FILL then
|
|
CalculateFillOutline( nAreaId, nAreaOutlineLayerId, nOutlineLayerId)
|
|
|
|
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
|
|
|
|
|
|
|
|
----------------------------------------------------------------------------------
|
|
------------------------ FUNZIONI AUX PER CALCOLO PEZZI ------------------------
|
|
----------------------------------------------------------------------------------
|
|
-- funzione che restituisce il WIN_PRF in base al nome della curva
|
|
local function GetOutlineProfileType( nOutlineId, bForceBottomRail, nBottomRail)
|
|
-- ricavo tipo dal nome
|
|
local sName = EgtGetName( nOutlineId)
|
|
local nProfileType = WIN_PRF.NULL
|
|
if sName == WIN_TOP then
|
|
nProfileType = WIN_PRF.TOP
|
|
elseif sName == WIN_BOTTOM then
|
|
local nBottomRailTot = EgtGetInfo( nOutlineId, WIN_BOTTOMRAIL, 'i') or 0
|
|
if bForceBottomRail and nBottomRailTot > 0 then
|
|
nProfileType = WIN_PRF.BOTTOMRAIL_FINAL
|
|
elseif nBottomRail then
|
|
-- verifico se bottomrail intermedio o finale
|
|
if nBottomRail == nBottomRailTot then
|
|
nProfileType = WIN_PRF.BOTTOMRAIL_FINAL
|
|
else
|
|
nProfileType = WIN_PRF.BOTTOMRAIL
|
|
end
|
|
else
|
|
nProfileType = WIN_PRF.BOTTOM
|
|
end
|
|
elseif sName == WIN_LEFT then
|
|
nProfileType = WIN_PRF.LEFT
|
|
elseif sName == WIN_RIGHT then
|
|
nProfileType = WIN_PRF.RIGHT
|
|
elseif sName == WIN_SPLIT then
|
|
nProfileType = WIN_PRF.SPLIT
|
|
end
|
|
return nProfileType
|
|
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_PRF_TYPE)
|
|
if sProfileType == WIN_RAIL or sProfileType == WIN_FILL_RAIL then
|
|
local dOffs = EgtGetInfo( nProfileId, WIN_RAILDELTA, '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
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che verifica gli outlines prev/next per lo split controllando l'interferenza tra i profili
|
|
local function TestSplitTrimOutlines( nOutlineId, vTrimOutlines, nMainProfile, b3Profile, nGrpTmp, bPrevOrNext)
|
|
|
|
local vRealTrimOutlines = {}
|
|
|
|
-- 1) recupero le curve da testare
|
|
local vTestOutlines = {}
|
|
|
|
-- a) curve individuate dalle intersezioni degli outlines
|
|
for i = 1, #vTrimOutlines do
|
|
vTestOutlines[i] = vTrimOutlines[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( vTrimOutlines[1]) or EgtGetLastInGroup( EgtGetParent( vTrimOutlines[1]))
|
|
local bInters = true
|
|
while bInters and nTestCurve ~= vTrimOutlines[#vTrimOutlines] do
|
|
|
|
local nRefPart = FindAssociatedPart( nTestCurve, true)
|
|
local nRefGeo = EgtGetFirstNameInGroup( nRefPart, WIN_GEO)
|
|
local nRefSurf = EgtGetFirstNameInGroup( nRefGeo, WIN_GEO_SURF)
|
|
|
|
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, nTestCurve)
|
|
nTestCurve = EgtGetPrev( nTestCurve) or EgtGetLastInGroup( EgtGetParent( nTestCurve))
|
|
end
|
|
end
|
|
|
|
-- curve successive
|
|
nTestCurve = EgtGetNext( vTrimOutlines[#vTrimOutlines]) or EgtGetFirstInGroup( EgtGetParent( vTrimOutlines[1]))
|
|
bInters = true
|
|
while bInters and nTestCurve ~= vTrimOutlines[1] do
|
|
|
|
local nRefPart = FindAssociatedPart( nTestCurve, true)
|
|
local nRefGeo = EgtGetFirstNameInGroup( nRefPart, WIN_GEO)
|
|
local nRefSurf = EgtGetFirstNameInGroup( nRefGeo, WIN_GEO_SURF)
|
|
|
|
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, nTestCurve)
|
|
nTestCurve = EgtGetNext( nTestCurve) or EgtGetFirstInGroup( EgtGetParent( nTestCurve))
|
|
end
|
|
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( vTestOutlines[i], true)
|
|
vsCtrIn[i] = GetProfileCtrIn( 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( vTestOutlines[i], vProfiles[i], vsCtrIn[i], 4 * dExtraLen, nGrpTmp)
|
|
if i > 1 then
|
|
if AreSameVectorApprox( EgtEV( vTestOutlines[i-1]), EgtSV( vTestOutlines[i])) then
|
|
EgtCutSurfTmPlane( nTestSurf, EgtEP( vTestOutlines[i-1]), - EgtEV( vTestOutlines[i-1]), false)
|
|
else
|
|
local nTrimSurf = CreateProfileSurf( 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( vTestOutlines[i]), EgtSV( vTestOutlines[i+1])) then
|
|
EgtCutSurfTmPlane( nTestSurf, EgtEP( vTestOutlines[i]), EgtEV( vTestOutlines[i]), false)
|
|
else
|
|
local nTrimSurf = CreateProfileSurf( 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( vRealTrimOutlines, vTestOutlines[i])
|
|
end
|
|
end
|
|
|
|
return vRealTrimOutlines
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che recupera gli outline precedenti e successivi
|
|
local function GetPrevNextOutline( nProfileType, nOutlineId, nOutlineLayerId)
|
|
|
|
local vPrevOutlineId = {}
|
|
local vNextOutlineId = {}
|
|
|
|
if nProfileType ~= WIN_PRF.SPLIT then
|
|
vPrevOutlineId = { EgtGetPrev( nOutlineId) or EgtGetLastInGroup( nOutlineLayerId)}
|
|
vNextOutlineId = { EgtGetNext( nOutlineId) or EgtGetFirstInGroup( nOutlineLayerId)}
|
|
|
|
else
|
|
-- se split recupero tutte le curve di base outline che lo tagliano dalle info
|
|
local vPrevBaseOutlineId = EgtGetInfo( nOutlineId, WIN_SPLIT_STARTINTERS, 'vi')
|
|
local vNextBaseOutlineId = EgtGetInfo( nOutlineId, WIN_SPLIT_ENDINTERS, 'vi')
|
|
-- recupero gli outlines associati
|
|
for i = 1, #vPrevBaseOutlineId do
|
|
vPrevOutlineId[i] = EgtGetInfo( vPrevBaseOutlineId[i], WIN_COPY, 'i')
|
|
end
|
|
for i = 1, #vNextBaseOutlineId do
|
|
vNextOutlineId[i] = EgtGetInfo( vNextBaseOutlineId[i], WIN_COPY, 'i')
|
|
end
|
|
|
|
-- controllo validità delle curve trovate verificando l'interferenza tra i profili
|
|
local nGrpTmp = EgtGroup( GDB_ID.ROOT)
|
|
local nMainProfile = GetOutlineProfileId( nOutlineId)
|
|
local b3Profile = GetProfileLocalBox( nMainProfile)
|
|
vPrevOutlineId = TestSplitTrimOutlines( nOutlineId, vPrevOutlineId, nMainProfile, b3Profile, nGrpTmp, true)
|
|
vNextOutlineId = TestSplitTrimOutlines( nOutlineId, vNextOutlineId, nMainProfile, b3Profile, nGrpTmp, false)
|
|
EgtErase( nGrpTmp)
|
|
|
|
-- considero come curve prev e next quelle associate ad un pezzo e non curve virtuali per rendere più solidi i conti successivi
|
|
-- verifico la coerenza dell'orientamento e la indico con il segno ( > 0 concorde, < 0 discorde e va invertita)
|
|
for i = 1, #vPrevOutlineId do
|
|
local nPart = FindAssociatedPart( vPrevOutlineId[i], true)
|
|
local bInvert = EgtGetInfo( vPrevOutlineId[i], WIN_INV_SPLIT, 'b') or false
|
|
vPrevOutlineId[i] = EgtGetInfo( nPart, WIN_REF_OUTLINE, 'i')
|
|
if bInvert then
|
|
vPrevOutlineId[i] = - vPrevOutlineId[i]
|
|
end
|
|
end
|
|
for i = 1, #vNextOutlineId do
|
|
local nPart = FindAssociatedPart( vNextOutlineId[i], true)
|
|
local bInvert = EgtGetInfo( vNextOutlineId[i], WIN_INV_SPLIT, 'b') or false
|
|
vNextOutlineId[i] = EgtGetInfo( nPart, WIN_REF_OUTLINE, 'i')
|
|
if bInvert then
|
|
vNextOutlineId[i] = - vNextOutlineId[i]
|
|
end
|
|
end
|
|
end
|
|
|
|
return vPrevOutlineId, vNextOutlineId
|
|
end
|
|
|
|
|
|
|
|
----------------------------------------------------------------------------------
|
|
-------------------------------- GEO -------------------------------------------
|
|
----------------------------------------------------------------------------------
|
|
-- funzione che dato il tipo di pezzo e di giunzione, restituisce se e' corto, lungo o angolato
|
|
local function CalcPartJointType( nProfileType, JointType)
|
|
|
|
if JointType == WIN_JNT.ANGLED then
|
|
return WIN_PART_JNT.ANGLED
|
|
end
|
|
if nProfileType == WIN_PRF.BOTTOMRAIL or nProfileType == WIN_PRF.BOTTOMRAIL_FINAL or nProfileType == WIN_PRF.SPLIT then
|
|
return WIN_PART_JNT.SHORT
|
|
elseif nProfileType == WIN_PRF.BOTTOM or nProfileType == WIN_PRF.TOP then
|
|
if JointType == WIN_JNT.FULL_H then
|
|
return WIN_PART_JNT.FULL
|
|
elseif JointType == WIN_JNT.FULL_V then
|
|
return WIN_PART_JNT.SHORT
|
|
end
|
|
elseif nProfileType == WIN_PRF.LEFT or nProfileType == WIN_PRF.RIGHT then
|
|
if JointType == WIN_JNT.FULL_V then
|
|
return WIN_PART_JNT.FULL
|
|
elseif JointType == WIN_JNT.FULL_H then
|
|
return WIN_PART_JNT.SHORT
|
|
end
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che calcola e salva nel profilo il delta del bottomrail corrente rispetto alla sua curva di outline
|
|
local function SaveRailDelta( nProfileId, nBottomRail)
|
|
local dDelta1 = EgtGetInfo( nProfileId, WIN_RAILDELTA .. '1', 'd')
|
|
local dDelta2 = EgtGetInfo( nProfileId, WIN_RAILDELTA .. '2', 'd')
|
|
local dOffs = dDelta1 + ( nBottomRail - 1) * dDelta2
|
|
EgtSetInfo( nProfileId, WIN_RAILDELTA, dOffs)
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che crea il gruppo con i profili di un pezzo
|
|
local function CalcProfiles( nPartId, nOutlineId, vPrevOutlineId, vNextOutlineId, nProfileType, nBottomRail)
|
|
|
|
-- creo gruppo per i profili
|
|
local nProfileLayerId = EgtGroup( nPartId)
|
|
EgtSetName( nProfileLayerId, WIN_PROFILE)
|
|
EgtSetStatus( nProfileLayerId, GDB_ST.OFF)
|
|
|
|
-- recupero profilo principale e ne creo copia
|
|
local nOrigMainProfileId = GetOutlineProfileId( nOutlineId, false, nProfileType)
|
|
local nMainProfileId = EgtCopy( nOrigMainProfileId, nProfileLayerId)
|
|
local sMainProfileType = EgtGetName( nMainProfileId)
|
|
EgtSetInfo( nMainProfileId, WIN_PRF_TYPE, sMainProfileType)
|
|
EgtSetName( nMainProfileId, WIN_PRF_MAIN)
|
|
-- se bottomrail salvo info per scostamento dall'outline
|
|
if sMainProfileType == WIN_FILL_RAIL or sMainProfileType == WIN_RAIL then
|
|
SaveRailDelta( nMainProfileId, nBottomRail)
|
|
end
|
|
|
|
-- recupero profili start e ne creo copia
|
|
-- se il tipo corrente è split il pezzo va tagliato con il bottomrail, altrimenti con il bottom
|
|
for i = 1, #vPrevOutlineId do
|
|
local nOrigStartProfileId = GetOutlineProfileId( abs( vPrevOutlineId[i]), nProfileType == WIN_PRF.SPLIT)
|
|
local nStartProfileId = EgtCopy( nOrigStartProfileId, nProfileLayerId)
|
|
local sStartProfileType = EgtGetName( nStartProfileId)
|
|
EgtSetInfo( nStartProfileId, WIN_PRF_TYPE, sStartProfileType)
|
|
EgtSetName( nStartProfileId, WIN_PRF_START)
|
|
if sStartProfileType == WIN_FILL_RAIL then
|
|
local nBottomRailTot = EgtGetInfo( abs( vPrevOutlineId[i]), WIN_BOTTOMRAIL, 'i')
|
|
SaveRailDelta( nStartProfileId, nBottomRailTot)
|
|
end
|
|
end
|
|
|
|
-- recupero profili end e ne creo copia
|
|
for i = 1, #vNextOutlineId do
|
|
local nOrigEndProfileId = GetOutlineProfileId( abs( vNextOutlineId[i]), nProfileType == WIN_PRF.SPLIT)
|
|
local nEndProfileId = EgtCopy( nOrigEndProfileId, nProfileLayerId)
|
|
local sEndProfileType = EgtGetName( nEndProfileId)
|
|
EgtSetInfo( nEndProfileId, WIN_PRF_TYPE, sEndProfileType)
|
|
EgtSetName( nEndProfileId, WIN_PRF_END)
|
|
if sEndProfileType == WIN_FILL_RAIL then
|
|
local nBottomRailTot = EgtGetInfo( abs( vNextOutlineId[i]), WIN_BOTTOMRAIL, 'i')
|
|
SaveRailDelta( nEndProfileId, nBottomRailTot)
|
|
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)
|
|
|
|
return nProfileLayerId
|
|
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_PRF_TYPE)
|
|
if sProfileType == WIN_FILL_RAIL then
|
|
local dDelta = EgtGetInfo( nProfileId, WIN_RAILDELTA, 'd')
|
|
dCPDelta = dCPDelta + dDelta
|
|
end
|
|
return dCPDelta
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che crea le curve del geo
|
|
local function CreateFrameGeo( nOutlineId, vPrevOutlineId, vNextOutlineId, nStartPartJointType, nEndPartJointType, 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_PRF_TYPE)
|
|
if sProfileType == WIN_FILL_RAIL or sProfileType == WIN_RAIL then
|
|
-- scostamento extra legato al bottomrail
|
|
local dDelta = EgtGetInfo( nCurrProfileId, WIN_RAILDELTA, '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)
|
|
|
|
-- 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)
|
|
|
|
-- curve left
|
|
local vPrevProfileId = EgtGetNameInGroup( nProfileLayerId, WIN_PRF_START)
|
|
for i = 1, #vPrevOutlineId do
|
|
local nPrevCurveId
|
|
local nPrevSemiProfile
|
|
if nStartPartJointType == WIN_PART_JNT.ANGLED then
|
|
-- calcolo la bisettrice
|
|
local vtMedia = ( ( EgtSV( nOutlineId) - EgtEV( abs( vPrevOutlineId[i]))) / 2)
|
|
if not vtMedia:normalize() then
|
|
vtMedia = EgtSV( nOutlineId)
|
|
vtMedia:rotate( Z_AX(), 90)
|
|
end
|
|
nPrevCurveId = EgtLinePVL( nGeoLayerId, EgtSP( nOutlineId), vtMedia, 3 * b3CurrProfileFrame:getDimX())
|
|
EgtInvertCurve( nPrevCurveId)
|
|
else
|
|
nPrevCurveId = EgtCopy( abs( vPrevOutlineId[i]), nGeoLayerId)
|
|
if vPrevOutlineId[i] < 0 then
|
|
EgtInvertCurve( nPrevCurveId)
|
|
end
|
|
if nStartPartJointType == WIN_PART_JNT.SHORT then
|
|
local sCtrIn = GetProfileCtrIn( abs( vPrevOutlineId[i]), nOutlineId, vPrevProfileId[i])
|
|
local dCPDelta = GetDeltaProfile( vPrevProfileId[i], sCtrIn)
|
|
EgtOffsetCurve( nPrevCurveId, - dCPDelta)
|
|
-- ricavo il semiprofilo associato
|
|
nPrevSemiProfile = EgtGetFirstNameInGroup( vPrevProfileId[i], sCtrIn)
|
|
else
|
|
nPrevSemiProfile = EgtGetFirstNameInGroup( vPrevProfileId[i], WIN_OUT)
|
|
end
|
|
end
|
|
EgtSetName( nPrevCurveId, WIN_GEO_LEFT)
|
|
EgtSetInfo( nPrevCurveId, WIN_SEMI_PROFILE, nPrevSemiProfile)
|
|
EgtSetInfo( nPrevCurveId, WIN_REF_OUTLINE, vPrevOutlineId[i])
|
|
EgtRelocateGlob( nPrevCurveId, nGeoLayerId, GDB_IN.LAST_SON)
|
|
end
|
|
|
|
-- curve right
|
|
local vNextProfileId = EgtGetNameInGroup( nProfileLayerId, WIN_PRF_END)
|
|
for i = 1, #vNextOutlineId do
|
|
local nNextCurveId
|
|
local nNextSemiProfile
|
|
if nEndPartJointType == WIN_PART_JNT.ANGLED then
|
|
-- calcolo la bisettrice
|
|
local vtMedia = ( ( EgtSV( abs( vNextOutlineId[i])) - EgtEV( nOutlineId)) / 2)
|
|
if not vtMedia:normalize() then
|
|
vtMedia = EgtEV( nOutlineId)
|
|
vtMedia:rotate( Z_AX(), 90)
|
|
end
|
|
nNextCurveId = EgtLinePVL( nGeoLayerId, EgtEP( nOutlineId), vtMedia, 3 * b3CurrProfileFrame:getDimX())
|
|
else
|
|
nNextCurveId = EgtCopy( abs( vNextOutlineId[i]), nGeoLayerId)
|
|
if vNextOutlineId[i] < 0 then
|
|
EgtInvertCurve( nNextCurveId)
|
|
end
|
|
if nEndPartJointType == WIN_PART_JNT.SHORT then
|
|
local sCtrIn = GetProfileCtrIn( abs( vNextOutlineId[i]), nOutlineId, vNextProfileId[i])
|
|
local dCPDelta = GetDeltaProfile( vNextProfileId[i], sCtrIn)
|
|
EgtOffsetCurve( nNextCurveId, - dCPDelta)
|
|
-- ricavo il semiprofilo associato
|
|
nNextSemiProfile = EgtGetFirstNameInGroup( vNextProfileId[i], sCtrIn)
|
|
else
|
|
nNextSemiProfile = EgtGetFirstNameInGroup( vNextProfileId[i], WIN_OUT)
|
|
end
|
|
end
|
|
EgtSetName( nNextCurveId, WIN_GEO_RIGHT)
|
|
EgtSetInfo( nNextCurveId, WIN_SEMI_PROFILE, nNextSemiProfile)
|
|
EgtSetInfo( nNextCurveId, WIN_REF_OUTLINE, vNextOutlineId[i])
|
|
EgtRelocateGlob( nNextCurveId, nInId, GDB_IN.BEFORE)
|
|
end
|
|
|
|
-- trim delle curve
|
|
local vIds = EgtGetAllInGroup( nGeoLayerId)
|
|
local vMainCrvs = TrimOrderedCurves( vIds, 2)
|
|
|
|
-- costruisco la regione
|
|
local nCompoId = EgtCurveCompo( nGeoLayerId, vMainCrvs, false)
|
|
local nAreaId = EgtSurfFlatRegion( nGeoLayerId, nCompoId)
|
|
EgtSetName( nAreaId, WIN_GEO_SURF)
|
|
EgtSetStatus( nAreaId, GDB_ST.OFF)
|
|
EgtErase( nCompoId)
|
|
|
|
-- 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 CalcFrameGeo( nPartId, nOutlineId, nOutlineCrvNbr, nOutlineLayerId, nProfileType, nBottomRail)
|
|
|
|
-- creo layer per ingombro
|
|
local nGeoLayerId = EgtGroup( nPartId)
|
|
EgtSetName( nGeoLayerId, WIN_GEO)
|
|
|
|
-- recupero outline precedenti e successivi ( solo nel caso di split possono essere più di uno)
|
|
local vPrevOutlineId, vNextOutlineId = GetPrevNextOutline( nProfileType, nOutlineId, nOutlineLayerId)
|
|
EgtSetInfo( nOutlineId, WIN_PREV_OUTLINES, vPrevOutlineId)
|
|
EgtSetInfo( nOutlineId, WIN_NEXT_OUTLINES, vNextOutlineId)
|
|
|
|
-- recupero il tipo di giunzioni
|
|
local nStartJointType
|
|
local nEndJointType
|
|
local nProfileTypeS = nProfileType
|
|
local nProfileTypeE = nProfileType
|
|
if nProfileType == WIN_PRF.SPLIT or nProfileType == WIN_PRF.BOTTOMRAIL or nProfileType == WIN_PRF.BOTTOMRAIL_FINAL then
|
|
-- non serve settare dei valori per StartJointType ed EndJointType perchè in CalcPartJointType la loro giunzione viene settata a short
|
|
else
|
|
-- recupero i joints opportuni dal vettore
|
|
local vJoints = EgtGetInfo( nOutlineLayerId, WIN_JOINTS, 'vi')
|
|
if EgtGetName( nOutlineId) == WIN_BOTTOM then
|
|
nStartJointType = vJoints[1]
|
|
nEndJointType = vJoints[2]
|
|
elseif EgtGetName( nOutlineId) == WIN_RIGHT then
|
|
nStartJointType = vJoints[2]
|
|
nEndJointType = vJoints[3]
|
|
elseif EgtGetName( nOutlineId) == WIN_TOP then
|
|
nStartJointType = vJoints[3]
|
|
nEndJointType = vJoints[4]
|
|
-- correzioni per caso a triangolo
|
|
if EgtGetName( abs( vPrevOutlineId[#vPrevOutlineId])) == WIN_BOTTOM then
|
|
nStartJointType = vJoints[2]
|
|
nEndJointType = vJoints[3]
|
|
-- il lato top deve essere trattato come un left/right nel calcolo della giunzione
|
|
nProfileTypeS = WIN_PRF.LEFT
|
|
end
|
|
if EgtGetName( abs( vNextOutlineId[1])) == WIN_BOTTOM then
|
|
nStartJointType = vJoints[3]
|
|
nEndJointType = vJoints[1]
|
|
nProfileTypeE = WIN_PRF.LEFT
|
|
end
|
|
elseif EgtGetName( nOutlineId) == WIN_LEFT then
|
|
nStartJointType = vJoints[4] or vJoints[3] -- ( vJoints[3] per gestire caso a triangolo)
|
|
nEndJointType = vJoints[1]
|
|
end
|
|
|
|
-- se giunzione diversa da bisettrice e arco a tutto sesto oppure elementi entrambi dello stesso tipo, forzo il tipo a bisettrice
|
|
if nStartJointType ~= WIN_JNT.ANGLED and ( AreSameVectorApprox( EgtEV( abs( vPrevOutlineId[1])), EgtSV( nOutlineId)) or EgtGetName( nOutlineId) == EgtGetName( abs( vPrevOutlineId[1]))) then
|
|
nStartJointType = WIN_JNT.ANGLED
|
|
end
|
|
if nEndJointType ~= WIN_JNT.ANGLED and ( AreSameVectorApprox( EgtEV( nOutlineId), EgtSV( abs( vNextOutlineId[1]))) or EgtGetName( nOutlineId) == EgtGetName( abs( vNextOutlineId[1]))) then
|
|
nEndJointType = WIN_JNT.ANGLED
|
|
end
|
|
end
|
|
|
|
-- calcolo il tipo di giunzione per la parte
|
|
local nStartPartJointType = CalcPartJointType( nProfileTypeS, nStartJointType)
|
|
local nEndPartJointType = CalcPartJointType( nProfileTypeE, nEndJointType)
|
|
-- nel caso di incontro con soglia la giunzione deve essere full
|
|
if EgtGetInfo( abs( vPrevOutlineId[1]), WIN_THRESHOLD, 'b') then
|
|
nStartPartJointType = WIN_JNT.FULL
|
|
end
|
|
if EgtGetInfo( abs( vNextOutlineId[1]), WIN_THRESHOLD, 'b') then
|
|
nEndPartJointType = WIN_JNT.FULL
|
|
end
|
|
|
|
-- salvo il valore dei joints su outline
|
|
-- se bottomrail è sicuramente short quindi non salvo il valore che sovrascriverebbe quello del pezzo bottom ( che potrebbe essere short o full)
|
|
if nProfileType ~= WIN_PRF.BOTTOMRAIL and nProfileType ~= WIN_PRF.BOTTOMRAIL_FINAL then
|
|
EgtSetInfo( nOutlineId, WIN_STARTJOINT, nStartPartJointType)
|
|
EgtSetInfo( nOutlineId, WIN_ENDJOINT, nEndPartJointType)
|
|
end
|
|
|
|
-- creo il gruppo con i profili del pezzo
|
|
local nProfileLayerId = CalcProfiles( nPartId, nOutlineId, vPrevOutlineId, vNextOutlineId, nProfileType, nBottomRail)
|
|
|
|
-- creo lati dell'outline
|
|
CreateFrameGeo( nOutlineId, vPrevOutlineId, vNextOutlineId, nStartPartJointType, nEndPartJointType, 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 -----------------------------
|
|
----------------------------------------------------------------------------------
|
|
-- funzione che individua e crea i diversi tratti uniformi della curva di outline
|
|
local function CalcMixedOutlines( nPartId, nOutlineId)
|
|
|
|
-- creo gruppo dove salvare i sottotratti
|
|
local nGrp = EgtGroup( nPartId)
|
|
EgtSetName( nGrp, WIN_MIXED_OUTLINES)
|
|
EgtSetStatus( nGrp, GDB_ST.OFF)
|
|
|
|
-- recupero i tratti di tipo sash e li concateno
|
|
local vSashChildren = EgtGetInfo( nOutlineId, WIN_SASH_CHILDREN, 'vi')
|
|
local vSash = {}
|
|
for i = 1, #vSashChildren do
|
|
local nCrv = EgtCopyGlob( vSashChildren[i], nGrp)
|
|
table.insert( vSash, nCrv)
|
|
end
|
|
local nCrvS, nCntS = EgtCurveCompoByReorder( nGrp, vSash, EgtSP( nOutlineId))
|
|
for nId = nCrvS, nCrvS + nCntS - 1 do
|
|
-- da curva compo ricavo la curva linea/arco corrispondente
|
|
EgtMergeCurvesInCurveCompo( nId)
|
|
local nNewId = EgtExplodeCurveCompo( nId)
|
|
EgtSetName( nNewId, WIN_SASH)
|
|
end
|
|
|
|
-- recupero i tratti di tipo fill e li concateno
|
|
local vFillChildren = EgtGetInfo( nOutlineId, WIN_FILL_CHILDREN, 'vi')
|
|
local vFill = {}
|
|
for i = 1, #vFillChildren do
|
|
local nCrv = EgtCopyGlob( vFillChildren[i], nGrp)
|
|
table.insert( vFill, nCrv)
|
|
end
|
|
local nCrvF, nCntF = EgtCurveCompoByReorder( nGrp, vFill, EgtSP( nOutlineId))
|
|
for nId = nCrvF, nCrvF + nCntF - 1 do
|
|
EgtMergeCurvesInCurveCompo( nId)
|
|
local nNewId = EgtExplodeCurveCompo( nId)
|
|
EgtSetName( nNewId, WIN_FILL)
|
|
end
|
|
|
|
-- riordino le curve nel gruppo per ricostruire l'outline
|
|
EgtReorderCurvesInGroup( nGrp, EgtSP( nOutlineId))
|
|
|
|
-- creo associazione tra le sottocurve di outline e gli split che le separano :
|
|
-- recupero tutti gli split coinvolti
|
|
local nBaseOutline = EgtGetInfo( nOutlineId, WIN_COPY, 'i')
|
|
local vStack = { nBaseOutline}
|
|
local vSplitIds = {}
|
|
local i = 1
|
|
while vStack[i] do
|
|
-- recupero il tipo di area
|
|
local nAreaId = EgtGetParent( EgtGetParent( vStack[i]))
|
|
local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i')
|
|
if nAreaType ~= WIN_AREATYPES.SASH and nAreaType ~= WIN_AREATYPES.FILL then
|
|
-- salvo i suo eventuali split mixed
|
|
local nSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_SPLIT)
|
|
if nSplitLayerId then
|
|
local vCurrSplits = EgtGetAllInGroup( nSplitLayerId)
|
|
for j = 1, #vCurrSplits do
|
|
if EgtGetInfo( vCurrSplits[j], WIN_SPLITTYPE, 'i') == WIN_SPLITTYPES.MIXED then
|
|
table.insert( vSplitIds, vCurrSplits[j])
|
|
end
|
|
end
|
|
end
|
|
-- analizzo eventuali figli
|
|
local vChildren = EgtGetInfo( vStack[i], WIN_CHILD, 'vi') or {}
|
|
vStack = EgtJoinTables( vStack, vChildren)
|
|
end
|
|
i = i + 1
|
|
end
|
|
|
|
-- associo le curve con lo split che le taglia nel loro punto finale
|
|
local vCrvs = EgtGetAllInGroup( nGrp)
|
|
for i = 1, #vSplitIds do
|
|
local ptS = EgtSP( vSplitIds[i])
|
|
local ptE = EgtEP( vSplitIds[i])
|
|
for j = 1, #vCrvs - 1 do
|
|
local ptTest = EgtEP( vCrvs[j])
|
|
if AreSamePointApprox( ptS, ptTest) then
|
|
EgtSetInfo( vSplitIds[i], WIN_MIXED_REF_START, vCrvs[j])
|
|
EgtSetInfo( vCrvs[j], WIN_MIXED_SPLIT_REF, vSplitIds[i])
|
|
break
|
|
elseif AreSamePointApprox( ptE, ptTest) then
|
|
EgtSetInfo( vSplitIds[i], WIN_MIXED_REF_END, vCrvs[j])
|
|
EgtSetInfo( vCrvs[j], WIN_MIXED_SPLIT_REF, vSplitIds[i])
|
|
break
|
|
end
|
|
end
|
|
end
|
|
|
|
return nGrp
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che crea la curva di riferimento sulla giunzione tra il pezzo di split e il pezzo di telaio con cambio profilo
|
|
local function CalcMixedIntersections( nPartId, nOutline, vOutlines)
|
|
|
|
local nGrp = EgtGroup( nPartId)
|
|
EgtSetName( nGrp, WIN_MIXED_INTERSECTIONS)
|
|
EgtSetStatus( nGrp, GDB_ST.OFF)
|
|
|
|
-- recupero il profilo dell'outline
|
|
local nProfileLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE)
|
|
local nMainProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN)
|
|
|
|
for i = 1, #vOutlines - 1 do
|
|
|
|
-- recupero la curva di split che separa i due tratti di outline
|
|
local nSplitId = EgtGetInfo( vOutlines[i], WIN_MIXED_SPLIT_REF, 'i')
|
|
local nSplitProfileId = GetOutlineProfileId( nSplitId, false)
|
|
|
|
-- verifico ordinamento
|
|
local bSashFill = ( EgtGetName( vOutlines[i]) == WIN_SASH)
|
|
|
|
-- ricavo il punto di incontro tra le due parti dei profili che vanno contro il vetro
|
|
local nCrv1 = EgtCopyGlob( nSplitId, nGrp)
|
|
local dDeltaFixedSplit = EgtGetInfo( nSplitProfileId, WIN_FIXED_REF, 'd')
|
|
EgtOffsetCurve( nCrv1, dDeltaFixedSplit)
|
|
local nCrv2 = EgtCopyGlob( nOutline, nGrp)
|
|
local dDeltaFixedFrame = EgtGetInfo( nMainProfileId, WIN_FIXED_REF, 'd')
|
|
EgtOffsetCurve( nCrv2, - dDeltaFixedFrame)
|
|
local ptRef1 = EgtIP( nCrv1, nCrv2, ORIG())
|
|
|
|
-- ricavo il punto di incontro tra il taglio a 45° e la parte del telaio contro anta
|
|
-- TO DO : capire come gestire correttamente la rotazione nel caso di arco
|
|
local dParRef = EgtCurveParamAtPoint( nCrv2, ptRef1)
|
|
local vtDir45 = EgtUV( nCrv2, dParRef, -1)
|
|
vtDir45:rotate( Z_AX(), EgtIf( bSashFill, 225, -45))
|
|
local nCrv3 = EgtLinePVL( nGrp, ptRef1, vtDir45, 100)
|
|
local nCrv4 = EgtCopyGlob( nOutline, nGrp)
|
|
local dDeltaSashFrame = EgtGetInfo( nMainProfileId, WIN_SASH_REF .. '1', 'd')
|
|
EgtOffsetCurve( nCrv4, - dDeltaSashFrame)
|
|
local ptRef2 = EgtIP( nCrv3, nCrv4, ORIG())
|
|
|
|
-- curva di intersezione da usare come riferimento per i conti successivi
|
|
local nCrv = EgtCurveCompoFromPoints( nGrp, { ptRef1, ptRef2})
|
|
|
|
-- calcolo il raccordo
|
|
local dRad = EgtGetInfo( nMainProfileId, WIN_RAD_REF .. '1', 'd')
|
|
local dParFillet = EgtCurveParamAtPoint( nCrv4, ptRef2)
|
|
dParFillet = dParFillet + EgtIf( bSashFill, -10, 10) * GEO.EPS_SMALL
|
|
local nFillet = EgtCurveFillet( nGrp, nCrv, EgtUP( nCrv1, 0.9), nCrv4, EgtUP( nCrv4, dParFillet), dRad, true) or GDB_ID.NULL
|
|
EgtAddCurveCompoCurve( nCrv, nFillet)
|
|
|
|
-- cancello curve di costruzione
|
|
EgtErase( { nCrv1, nCrv2, nCrv3, nCrv4})
|
|
|
|
-- assegno riferimento
|
|
EgtSetInfo( vOutlines[i], WIN_MIXED_INTERS_REF, nCrv)
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che calcola curve ausiliarie per la gestione del cambio profilo
|
|
local function CalcMixedFrameCurves( nPartId, nOutlineId)
|
|
-- calcolo i sottotratti uniformi della curva di outline
|
|
local nOutlinesGrp = CalcMixedOutlines( nPartId, nOutlineId)
|
|
local vCrvs = EgtGetAllInGroup( nOutlinesGrp)
|
|
-- calcolo le curve di intersezione con gli split
|
|
CalcMixedIntersections( nPartId, nOutlineId, vCrvs)
|
|
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
|
|
else
|
|
-- se non ha semiprofilo associato è un taglio
|
|
EgtSetInfo( nCrv, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.CUT)
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che calcola la prima lavorazione per l'innesto dello split sul telaio nel caso di cambio profilo
|
|
local function CalcMixedFrameMilling1( nIntersCrv, nOutlineId, nMainProfileId, nSplitRef, bSashFill, nProcLayerId, nSurfGeoId)
|
|
|
|
local dOffs = EgtGetInfo( nMainProfileId, WIN_SASH_REF .. '1', 'd')
|
|
local dDepth = EgtGetInfo( nMainProfileId, WIN_SASH_DEPTH .. '1', 'd')
|
|
local dFilletRad = EgtGetInfo( nMainProfileId, WIN_RAD_REF .. '1', 'd')
|
|
|
|
-- primo tratto : taglio a 45° e fillet
|
|
local nCrv1 = EgtCopyGlob( nIntersCrv, nProcLayerId)
|
|
EgtExtendCurveStartByLen( nCrv1, 100)
|
|
|
|
-- calcolo il tratto di outline
|
|
local nCrv2 = EgtCopyGlob( nOutlineId, nProcLayerId)
|
|
EgtOffsetCurve( nCrv2, - dOffs)
|
|
if bSashFill then
|
|
EgtInvertCurve( nCrv2)
|
|
end
|
|
local dParS = EgtCurveParamAtPoint( nCrv2, EgtEP( nCrv1))
|
|
local ptEnd = EgtIP( nCrv2, nSplitRef, ORIG())
|
|
local dParE = EgtCurveParamAtPoint( nCrv2, ptEnd)
|
|
EgtTrimCurveStartEndAtParam( nCrv2, dParS, dParE)
|
|
|
|
-- tratto di uscita a 45°
|
|
local vtDir2 = EgtEV( nCrv2)
|
|
vtDir2:rotate( Z_AX(), EgtIf( bSashFill, - 45, 45))
|
|
local nCrv3 = EgtLinePVL( nProcLayerId, ptEnd, vtDir2, 100)
|
|
|
|
-- creo fillet
|
|
local nFillet = EgtCurveFillet( nProcLayerId, nCrv2, EgtUP( nCrv2, 0.9), nCrv3, EgtUP( nCrv3, 0.1), dFilletRad, true)
|
|
|
|
-- creo curva di lavorazione
|
|
local nMillingCrv = EgtCurveCompo( nProcLayerId, {nCrv1, nCrv2, nFillet, nCrv3})
|
|
if bSashFill then
|
|
EgtInvertCurve( nMillingCrv)
|
|
end
|
|
EgtModifyCurveThickness( nMillingCrv, - dDepth)
|
|
-- setto info di lavorazione
|
|
EgtSetInfo( nMillingCrv, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.PROFILING)
|
|
EgtSetInfo( nMillingCrv, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.GENERIC)
|
|
EgtSetInfo( nMillingCrv, WIN_PRC_SIDE, WIN_PRC_SIDETYPE.IN)
|
|
EgtTrimCurveWithRegion( nMillingCrv, nSurfGeoId, true, false)
|
|
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che calcola la seconda lavorazione per l'innesto dello split sul telaio nel caso di cambio profilo
|
|
local function CalcMixedFrameMilling2( nIntersCrv, nOutlineId, nMainProfileId, nSplitProfileId, nSplitRef, bSashFill, nProcLayerId, nSurfGeoId)
|
|
|
|
local dOffs = EgtGetInfo( nMainProfileId, WIN_SASH_REF .. '2', 'd')
|
|
local dDepth = EgtGetInfo( nMainProfileId, WIN_SASH_DEPTH .. '2', 'd')
|
|
local dFilletRad = EgtGetInfo( nMainProfileId, WIN_RAD_REF .. '2', 'd')
|
|
local dExtraDist = EgtGetInfo( nMainProfileId, WIN_EXTRA_DIST, 'd')
|
|
|
|
local nCrv1 = EgtCopyGlob( nIntersCrv, nProcLayerId)
|
|
EgtExtendCurveStartByLen( nCrv1, 100)
|
|
|
|
-- calcolo il primo tratto di outline
|
|
local nCrv2 = EgtCopyGlob( nOutlineId, nProcLayerId)
|
|
EgtOffsetCurve( nCrv2, - dOffs + dExtraDist)
|
|
if bSashFill then
|
|
EgtInvertCurve( nCrv2)
|
|
end
|
|
|
|
-- taglio i due tratti per unirli
|
|
local pt1 = EgtIP( nCrv1, nCrv2, ORIG())
|
|
local dParE1 = EgtCurveParamAtPoint( nCrv1, pt1)
|
|
EgtTrimCurveEndAtParam( nCrv1, dParE1)
|
|
local dParS2 = EgtCurveParamAtPoint( nCrv2, pt1)
|
|
EgtTrimCurveStartAtParam( nCrv2, dParS2)
|
|
|
|
-- calcolo fillet
|
|
local nFillet1 = EgtCurveFillet( nProcLayerId, nCrv1, EgtUP( nCrv1, 0.9), nCrv2, EgtUP( nCrv2, 0.1), dFilletRad, true)
|
|
|
|
-- calcolo il secondo tratto di outline
|
|
local nCrv3 = EgtCopyGlob( nOutlineId, nProcLayerId)
|
|
EgtOffsetCurve( nCrv3, - dOffs)
|
|
if bSashFill then
|
|
EgtInvertCurve( nCrv3)
|
|
end
|
|
local nSplitRef2 = EgtCopyGlob( nSplitRef, nProcLayerId)
|
|
local dOffs1 = EgtGetInfo( nSplitProfileId, WIN_SASH_REF .. '1', 'd')
|
|
local dOffs2 = EgtGetInfo( nSplitProfileId, WIN_SASH_REF .. '2', 'd')
|
|
EgtOffsetCurve( nSplitRef2, dOffs2 - dOffs1)
|
|
local pt2 = EgtIP( nCrv3, nSplitRef2, ORIG())
|
|
local pt3 = EgtIP( nCrv3, nSplitRef, ORIG())
|
|
local dParS3 = EgtCurveParamAtPoint( nCrv3, pt2)
|
|
local dParE3 = EgtCurveParamAtPoint( nCrv3, pt3)
|
|
EgtTrimCurveStartEndAtParam( nCrv3, dParS3, dParE3)
|
|
EgtErase( nSplitRef2)
|
|
|
|
-- calcolo il raccordo tra i due tratti di outline : è arco di raggio dFilletRad, tangente a nCrv2 e con punto finale pt2
|
|
-- calcolo il centro dell'arco
|
|
local nCircleTmp = EgtCircle( nProcLayerId, pt2, dFilletRad)
|
|
local nCrvTmp = EgtCopyGlob( nOutlineId, nProcLayerId)
|
|
EgtOffsetCurve( nCrvTmp, - dOffs + dExtraDist - dFilletRad)
|
|
local ptC = EgtIP( nCircleTmp, nCrvTmp, EgtIf( bSashFill, EgtEP( nCrvTmp), EgtSP( nCrvTmp)))
|
|
EgtErase( {nCircleTmp, nCrvTmp})
|
|
local nFillet2 = EgtArcC2PEx( nProcLayerId, ptC, EgtSP( nCrv2), GDB_PT.TG, nCrv2, pt2)
|
|
|
|
-- taglio il primo tratto di outline per collegarlo al raccordo
|
|
local dParE2 = EgtCurveParamAtPoint( nCrv2, EgtSP( nFillet2))
|
|
EgtTrimCurveEndAtParam( nCrv2, dParE2)
|
|
|
|
-- tratto di uscita a 45°
|
|
local vtDir2 = EgtEV( nCrv3)
|
|
vtDir2:rotate( Z_AX(), EgtIf( bSashFill, - 45, 45))
|
|
local nCrv4 = EgtLinePVL( nProcLayerId, EgtEP( nCrv3), vtDir2, 100)
|
|
|
|
-- creo fillet
|
|
local nFillet3 = EgtCurveFillet( nProcLayerId, nCrv3, EgtUP( nCrv3, 0.9), nCrv4, EgtUP( nCrv4, 0.1), dFilletRad, true) or GDB_ID.NULL
|
|
|
|
-- creo curva di lavorazione
|
|
local nMillingCrv = EgtCurveCompo( nProcLayerId, {nCrv1, nFillet1, nCrv2, nFillet2, nCrv3, nFillet3, nCrv4})
|
|
if bSashFill then
|
|
EgtInvertCurve( nMillingCrv)
|
|
end
|
|
EgtModifyCurveThickness( nMillingCrv, - dDepth)
|
|
-- setto info di lavorazione
|
|
EgtSetInfo( nMillingCrv, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.PROFILING)
|
|
EgtSetInfo( nMillingCrv, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.GENERIC)
|
|
EgtSetInfo( nMillingCrv, WIN_PRC_SIDE, WIN_PRC_SIDETYPE.IN)
|
|
EgtTrimCurveWithRegion( nMillingCrv, nSurfGeoId, true, false)
|
|
|
|
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 vGeoCrvs = EgtGetAllInGroup( nGeoLayerId)
|
|
for i = 1, #vGeoCrvs - 1 do
|
|
-- copio curva
|
|
local nCrv = EgtCopyGlob( vGeoCrvs[i], nProcLayerId)
|
|
EgtModifyCurveThickness( nCrv, 0)
|
|
-- recupero il semiprofilo associato
|
|
local nSemiProfile = EgtGetInfo( nCrv, WIN_SEMI_PROFILE, 'i')
|
|
GetProcessingInfoFromSemiProfile( nCrv, nSemiProfile)
|
|
end
|
|
|
|
-- lavorazioni dei sottotratti in di sash e fill
|
|
local nOutlinesGrp = EgtGetFirstNameInGroup( nPartId, WIN_MIXED_OUTLINES)
|
|
local vCrvs = EgtGetAllInGroup( nOutlinesGrp)
|
|
local b3Profile = GetProfileLocalBox( nMainProfileId)
|
|
local dOffs = b3Profile:getMin():getX()
|
|
for i = #vCrvs, 1, -1 do
|
|
-- calcolo la curva di lavorazione
|
|
local nCrv = EgtCopyGlob( vCrvs[i], nProcLayerId)
|
|
EgtOffsetCurve( nCrv, dOffs)
|
|
EgtInvertCurve( nCrv)
|
|
nCrv = EgtTrimCurveWithRegion( nCrv, nSurfGeoId, true, true)
|
|
-- setto le info di lavorazione dal semiprofilo
|
|
local nSemiProfile = EgtGetFirstNameInGroup( nMainProfileId, EgtGetName( vCrvs[i]) .. WIN_IN)
|
|
GetProcessingInfoFromSemiProfile( nCrv, nSemiProfile)
|
|
-- sistemo info di lavorazione
|
|
EgtSetInfo( nCrv, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.MIXED)
|
|
EgtSetInfo( nCrv, WIN_PRC_SIDE, WIN_PRC_SIDETYPE.IN)
|
|
-- TO DO : calcolo di AddLen ?
|
|
end
|
|
|
|
-- b) lavorazioni sulle intersezioni con gli split
|
|
local nIntersGrp = EgtGetFirstNameInGroup( nPartId, WIN_MIXED_INTERSECTIONS)
|
|
local vInters = EgtGetAllInGroup( nIntersGrp)
|
|
local nOutlineId = EgtGetInfo( nPartId, WIN_REF_OUTLINE, 'i')
|
|
for i = 1, #vInters do
|
|
|
|
local bSashFill = ( EgtGetName( vCrvs[i]) == WIN_SASH)
|
|
-- recupero lo split associato e creo la curva di riferimento per le fresature
|
|
local nSplitId = EgtGetInfo( vCrvs[i], WIN_MIXED_SPLIT_REF, 'i')
|
|
local nSplitProfileId = GetOutlineProfileId( nSplitId, false)
|
|
local dRefSplit = EgtGetInfo( nSplitProfileId, WIN_SASH_REF .. '2', 'd')
|
|
local nSplitRef = EgtCopyGlob( nSplitId, nProcLayerId)
|
|
EgtOffsetCurve( nSplitRef, - dRefSplit)
|
|
|
|
-- Fresatura 1
|
|
CalcMixedFrameMilling1( vInters[i], nOutlineId, nMainProfileId, nSplitRef, bSashFill, nProcLayerId, nSurfGeoId)
|
|
-- Fresatura 2
|
|
CalcMixedFrameMilling2( vInters[i], nOutlineId, nMainProfileId, nSplitProfileId, nSplitRef, bSashFill, nProcLayerId, nSurfGeoId)
|
|
|
|
EgtErase( nSplitRef)
|
|
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 vGeoCrvs = EgtGetAllInGroup( nGeoLayerId)
|
|
for i = 1, #vGeoCrvs - 1 do
|
|
-- copio la curva
|
|
local nCrvId = EgtCopyGlob( vGeoCrvs[i], nProcLayerId)
|
|
EgtModifyCurveThickness( nCrvId, 0)
|
|
-- recupero il semiprofilo associato ( per left e right è stato salvato il profilo di tipo sash)
|
|
local nSemiProfileId = EgtGetInfo( nCrvId, WIN_SEMI_PROFILE, 'i')
|
|
-- setto le info dal semiprofilo
|
|
GetProcessingInfoFromSemiProfile( nCrvId, nSemiProfileId)
|
|
end
|
|
|
|
-- b) tagli a 45°
|
|
-- left
|
|
local nMixedLeft = EgtGetInfo( nSplitId, WIN_MIXED_REF_START, 'i')
|
|
local nIntersLeft = EgtGetInfo( nMixedLeft, WIN_MIXED_INTERS_REF, 'i')
|
|
local nMillingLeft = EgtCopyGlob( nIntersLeft, nProcLayerId)
|
|
-- recupero profondità
|
|
local vOutlineLeft = EgtGetInfo( nSplitId, WIN_PREV_OUTLINES, 'vi')
|
|
local nProfileLeft = GetOutlineProfileId( abs( vOutlineLeft[1]), false)
|
|
local dDepthLeft = EgtGetInfo( nProfileLeft, WIN_SASH_DEPTH .. '2', 'd')
|
|
EgtModifyCurveThickness( nMillingLeft, - dDepthLeft)
|
|
-- setto info di lavorazione
|
|
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)
|
|
|
|
-- right
|
|
local nMixedRight = EgtGetInfo( nSplitId, WIN_MIXED_REF_END, 'i')
|
|
local nIntersRight = EgtGetInfo( nMixedRight, WIN_MIXED_INTERS_REF, 'i')
|
|
local nMillingRight = EgtCopyGlob( nIntersRight, nProcLayerId)
|
|
-- recupero profondità
|
|
local vOutlineRight = EgtGetInfo( nSplitId, WIN_NEXT_OUTLINES, 'vi')
|
|
local nProfileRight = GetOutlineProfileId( abs( vOutlineRight[1]), false)
|
|
local dDepthRight = EgtGetInfo( nProfileRight, WIN_SASH_DEPTH .. '2', 'd')
|
|
EgtModifyCurveThickness( nMillingRight, - dDepthRight)
|
|
EgtInvertCurve( nMillingRight)
|
|
-- setto info di lavorazione
|
|
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 aggiusta le lunghezze delle lavorazioni per garantire lavorazione completa del profilo
|
|
local function AdjustProcessingLength( nCrvId, nSemiProfileId, nGeoAreaId, nPrevGeo, nNextGeo)
|
|
|
|
-- se giunzione angled non serve allungamento
|
|
if not nSemiProfileId then return end
|
|
|
|
-- calcolo la curva di lavorazione interna
|
|
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, GDB_RT.GLOB)
|
|
local dOffs = b3SemiProfile:getDimX()
|
|
local nInnerProcId = EgtCopyGlob( nCrvId, EgtGetParent( nCrvId))
|
|
EgtOffsetCurve( nInnerProcId, - dOffs)
|
|
|
|
-- adatto la curva di lavorazione interna al pezzo
|
|
if EgtGetType( nInnerProcId) == GDB_TY.CRV_LINE then
|
|
EgtExtendCurveStartByLen( nInnerProcId, 10000)
|
|
EgtExtendCurveEndByLen( nInnerProcId, 10000)
|
|
else
|
|
local dAng = EgtArcAngCenter( nInnerProcId)
|
|
EgtModifyArcAngCenter( nInnerProcId, EgtIf( dAng > 0, 1, -1) * 360)
|
|
end
|
|
local nNewId, nCnt = EgtTrimCurveWithRegion( nInnerProcId, nGeoAreaId, true, false)
|
|
|
|
if nCnt == 0 then
|
|
return
|
|
end
|
|
|
|
if nCnt > 1 then
|
|
-- nel caso di archi possono generarsi più intersezioni quindi va conservata solo quella corretta
|
|
-- TODO può capitare anche nel caso in/out?
|
|
if AreSamePointApprox( EgtSP( nNewId), EgtEP( nNewId + nCnt - 1)) then
|
|
EgtModifyCurveStartPoint( nNewId, EgtSP( nNewId + nCnt - 1))
|
|
EgtErase( nNewId + nCnt - 1)
|
|
nCnt = nCnt - 1
|
|
end
|
|
local nPrcOutId = EgtGetFirstNameInGroup( EgtGetParent( nGeoAreaId), WIN_GEO_OUT)
|
|
local ptRef = EgtIf( EgtGetName( nCrvId) == WIN_LEFT, EgtSP( nPrcOutId), EgtEP( nPrcOutId))
|
|
local nIdRef
|
|
local dSqMinDist = GEO.INFINITO
|
|
for nId = nNewId, nNewId + nCnt - 1 do
|
|
local ptTest = EgtIf( EgtGetName( nCrvId) == WIN_LEFT, EgtEP( nId), EgtSP( nId))
|
|
local dSqDist = sqdist( ptTest, ptRef)
|
|
if dSqDist < dSqMinDist then
|
|
dSqMinDist = dSqDist
|
|
nIdRef = nId
|
|
end
|
|
end
|
|
|
|
for nId = nNewId, nNewId + nCnt - 1 do
|
|
if nId ~= nIdRef then
|
|
EgtErase( nId)
|
|
end
|
|
end
|
|
nNewId = nIdRef
|
|
end
|
|
|
|
-- la allineo alla curva di lavoro
|
|
EgtOffsetCurve( nNewId, dOffs)
|
|
|
|
-- aggiusto la curva di lavoro
|
|
local ptS = EgtSP( nNewId)
|
|
local ptE = EgtEP( nNewId)
|
|
local bExtra = EgtGetInfo( nCrvId, WIN_GEO_EXTRA, 'b') or false
|
|
if bExtra then
|
|
-- se è una curva speciale del geo va modificata su entrambi gli estremi
|
|
EgtModifyCurveStartPoint( nCrvId, ptS)
|
|
EgtModifyCurveEndPoint( nCrvId, ptE)
|
|
else
|
|
-- se è una curva standard va modificata solo in allungamento se non è in tangenza con quella vicina
|
|
local dParS = EgtCurveParamAtPoint( nCrvId, ptS)
|
|
local bTang = AreSameVectorApprox( EgtSV( nCrvId), EgtEV( nPrevGeo))
|
|
if not dParS and not bTang then
|
|
EgtModifyCurveStartPoint( nCrvId, ptS)
|
|
end
|
|
bTang = AreSameVectorApprox( EgtEV( nCrvId), EgtSV( nNextGeo))
|
|
local dParE = EgtCurveParamAtPoint( nCrvId, ptE)
|
|
if not dParE and not bTang then
|
|
EgtModifyCurveEndPoint( nCrvId, ptE)
|
|
end
|
|
end
|
|
|
|
EgtErase( nNewId)
|
|
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 creo la superficie associata per limitare le lavorazioni
|
|
local nGeoLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO)
|
|
local nSurfGeo = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_SURF)
|
|
|
|
-- 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
|
|
-- recupero tutte le curve del geo e le copio nel gruppo processings
|
|
local vGeoCrvs = EgtGetAllInGroup( nGeoLayerId)
|
|
for i = 1, #vGeoCrvs - 1 do
|
|
-- copio curva
|
|
local nCrvId = EgtCopyGlob( vGeoCrvs[i], nProcLayerId)
|
|
EgtModifyCurveThickness( nCrvId, 0)
|
|
-- recupero il semiprofilo associato
|
|
local nSemiProfileId = EgtGetInfo( nCrvId, WIN_SEMI_PROFILE, 'i')
|
|
-- aggiusto la lunghezza della lavorazione
|
|
local nPrevIdx = EgtIf( i == 1, #vGeoCrvs - 1, i - 1)
|
|
local nNextIdx = EgtIf( i == #vGeoCrvs - 1, 1, i + 1)
|
|
AdjustProcessingLength( nCrvId, nSemiProfileId, nSurfGeo, vGeoCrvs[nPrevIdx], vGeoCrvs[nNextIdx])
|
|
-- setto le info dal semiprofilo
|
|
GetProcessingInfoFromSemiProfile( nCrvId, nSemiProfileId)
|
|
end
|
|
end
|
|
|
|
-- calcolo eventuali lavorazioni per strip
|
|
local vStripDist = EgtGetInfo( nMainProfileId, WIN_STRIP_DIST, 'vi') or {}
|
|
for i = 1, #vStripDist do
|
|
local nStripCut = EgtCopyGlob( nOutlineId, nProcLayerId)
|
|
EgtOffsetCurve( nStripCut, vStripDist[i])
|
|
-- modifico la curva in modo che sia a filo del geo
|
|
EgtExtendCurveStartByLen( nStripCut, 1000)
|
|
EgtExtendCurveEndByLen( nStripCut, 1000)
|
|
nStripCut = EgtTrimCurveWithRegion( nStripCut, nSurfGeo, true, false)
|
|
-- 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)
|
|
|
|
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
|
|
local bExtra = EgtGetInfo( vRight[i], WIN_GEO_EXTRA, 'b') or false
|
|
if bExtra then
|
|
EgtErase( vRight[i])
|
|
else
|
|
if not EgtOffsetCurve( vRight[i], dOvermatRight) then
|
|
EgtErase( vRight[i])
|
|
end
|
|
end
|
|
end
|
|
local vLeft = EgtGetNameInGroup( nGeoRawLayerId, WIN_GEO_LEFT)
|
|
for i = 1, #vLeft do
|
|
local bExtra = EgtGetInfo( vLeft[i], WIN_GEO_EXTRA, 'b') or false
|
|
if bExtra then
|
|
EgtErase( vLeft[i])
|
|
else
|
|
if not EgtOffsetCurve( vLeft[i], dOvermatLeft) then
|
|
EgtErase( vLeft[i])
|
|
end
|
|
end
|
|
end
|
|
|
|
-- creo la composita del grezzo a partire dalle curve
|
|
local vCrvs = EgtGetAllInGroup( nGeoRawLayerId)
|
|
vCrvs = TrimOrderedCurves( vCrvs)
|
|
local nCompo = EgtCurveCompo( nGeoRawLayerId, vCrvs)
|
|
-- aggiungo spessore
|
|
local dDimH = EgtGetInfo( nGeoLayerId, WIN_GEOHEIGHT, 'd')
|
|
EgtModifyCurveThickness( nCompo, - dDimH)
|
|
|
|
-- creo 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
|
|
|
|
|
|
|
|
----------------------------------------------------------------------------------
|
|
---------------------------------- SOLIDO ----------------------------------------
|
|
----------------------------------------------------------------------------------
|
|
-- funzione che crea la superficie di trim per il solido
|
|
local function CreateTrimSurf( nGeoId, nOutlineId, dGeoWidth, nLayerId)
|
|
|
|
-- recupero profilo di riferimento dalla curva geo
|
|
local nOrigTrimProfileId = EgtGetInfo( nGeoId, WIN_SEMI_PROFILE, 'i')
|
|
|
|
-- 1) minizinken
|
|
if not nOrigTrimProfileId then
|
|
|
|
local nGuideId = EgtCopy( nGeoId, nLayerId)
|
|
EgtExtendCurveStartByLen( nGuideId, 4 * dGeoWidth)
|
|
EgtExtendCurveEndByLen( nGuideId, 4 * dGeoWidth)
|
|
EgtMove( nGuideId, Z_AX())
|
|
local nTrimSurf = EgtSurfTmByExtrusion( nLayerId, nGuideId, - Z_AX() * dGeoWidth * 2, WIN_SURF_APPROX)
|
|
EgtInvertSurf( nTrimSurf)
|
|
EgtErase( nGuideId)
|
|
return nTrimSurf
|
|
|
|
-- 2) controprofilo
|
|
else
|
|
-- recupero il controprofilo da estrudere
|
|
local sTrimProfileName = EgtGetName( nOrigTrimProfileId)
|
|
sTrimProfileName = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. WIN_OFST .. sTrimProfileName
|
|
-- calcolo la superficie di estrusione
|
|
return CreateProfileSurf( nOutlineId, EgtGetParent( nOrigTrimProfileId), sTrimProfileName, 4 * dGeoWidth, nLayerId)
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che crea le superfici di trim per uno split coinvolto da cambio profilo ( controprofilo della parte sash del telaio e taglio a 45°)
|
|
local function CreateMixedSplitTrimSurf( nMixedOutlineId, nProfileId, dExtraLen, nLayerId)
|
|
|
|
-- estrudo il controprofilo di tipo sash
|
|
local nPartId = EgtGetParent( EgtGetParent( nMixedOutlineId))
|
|
local nOutlineId = EgtGetInfo( nPartId, WIN_REF_OUTLINE, 'i')
|
|
local sTrimProfile = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. WIN_OFST .. WIN_SASH .. WIN_CTRIN
|
|
local nTrimStmId = CreateProfileSurf( nOutlineId, nProfileId, sTrimProfile, dExtraLen, nLayerId)
|
|
|
|
-- creo il solido da intersecare con il controprofilo per il taglio a 45°
|
|
local nIntersCrvId = EgtGetInfo( nMixedOutlineId, WIN_MIXED_INTERS_REF, 'i')
|
|
local nGuideId = EgtCopyGlob( nIntersCrvId, nLayerId)
|
|
local bSashFill = ( EgtGetName( nMixedOutlineId) ~= WIN_SASH)
|
|
local vtDirH = EgtSV( nGuideId)
|
|
vtDirH:rotate( Z_AX(), EgtIf( bSashFill, -135, 135))
|
|
local vtDirV = EgtSV( nGuideId)
|
|
vtDirV:rotate( Z_AX(), EgtIf( bSashFill, -45, 45))
|
|
EgtAddCurveCompoLine( nGuideId, EgtEP( nGuideId) + dExtraLen * vtDirV)
|
|
EgtAddCurveCompoLine( nGuideId, EgtSP( nGuideId) + dExtraLen * vtDirH, false)
|
|
EgtAddCurveCompoLine( nGuideId, EgtSP( nGuideId) + dExtraLen * vtDirV, false)
|
|
EgtCloseCurveCompo( nGuideId)
|
|
EgtMove( nGuideId, 0.01 * Z_AX())
|
|
if bSashFill then
|
|
EgtInvertCurve( nGuideId)
|
|
end
|
|
local dDepth = EgtGetInfo( nProfileId, WIN_SASH_DEPTH .. '2', 'd')
|
|
local nCutStmId = EgtSurfTmByRegionExtrusion( nLayerId, nGuideId, - ( dDepth + 2) * Z_AX())
|
|
|
|
-- creo una superficie di trim unica
|
|
EgtSurfTmSubtract( nTrimStmId, nCutStmId)
|
|
|
|
EgtErase( { nGuideId, nCutStmId})
|
|
|
|
return nTrimStmId
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che crea il solido di estrusione principale
|
|
local function CreateMainSurf( nOutlineId, dExtraLen, nProfileId, sSectionName, nLayerId)
|
|
|
|
-- curva guida
|
|
local nGuideId = EgtCopy( nOutlineId, nLayerId)
|
|
EgtSetName( nGuideId, WIN_MAINGUIDE)
|
|
EgtSetStatus( nGuideId, GDB_ST.OFF)
|
|
EgtExtendCurveStartByLen( nGuideId, dExtraLen)
|
|
EgtExtendCurveEndByLen( nGuideId, dExtraLen)
|
|
|
|
-- se bottomrail sposto opportunamente l'outline
|
|
local sProfileType = EgtGetInfo( nProfileId, WIN_PRF_TYPE)
|
|
if sProfileType == WIN_RAIL or sProfileType == WIN_FILL_RAIL then
|
|
local dOffs = EgtGetInfo( nProfileId, WIN_RAILDELTA, 'd')
|
|
EgtOffsetCurve( nGuideId, -dOffs)
|
|
end
|
|
|
|
-- 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
|
|
local nMainProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN)
|
|
-- creo i solidi corrispondenti ai diversi sottotratti uniformi del pezzo
|
|
local nMixedOutlinesGrp = EgtGetFirstNameInGroup( EgtGetParent( nSolidLayerId), WIN_MIXED_OUTLINES)
|
|
local vMixedOutlines = EgtGetAllInGroup( nMixedOutlinesGrp)
|
|
local vMainExtrusions = {}
|
|
for i = 1, #vMixedOutlines do
|
|
local sSection = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. EgtGetName( vMixedOutlines[i]) .. WIN_SECTION
|
|
local nMainExtrusionId = CreateMainSurf( vMixedOutlines[i], 2 * dGeoWidth, nMainProfileId, sSection, nSolidLayerId)
|
|
table.insert( vMainExtrusions, nMainExtrusionId)
|
|
end
|
|
|
|
-- taglio i sottopezzi nei punti di intersezione per unirli
|
|
local nMixedIntersectionsGrp = EgtGetFirstNameInGroup( EgtGetParent( nSolidLayerId), WIN_MIXED_INTERSECTIONS)
|
|
local vIntersections = EgtGetAllInGroup( nMixedIntersectionsGrp)
|
|
for i = 1, #vIntersections do
|
|
-- creo la superficie di separazione tra i due sottopezzi
|
|
local bSashFill = ( EgtGetName( vMixedOutlines[i]) == WIN_SASH)
|
|
local vtDirS = EgtSV( vIntersections[i])
|
|
vtDirS:rotate( Z_AX(), EgtIf( bSashFill, -135, 135))
|
|
local vtDirE = EgtSV( vIntersections[i])
|
|
vtDirE:rotate( Z_AX(), EgtIf( bSashFill, 45, -45))
|
|
local nCrvTrim = EgtCurveCompo( nSolidLayerId, vIntersections[i], false)
|
|
EgtAddCurveCompoLine( nCrvTrim, EgtSP( nCrvTrim) + dGeoWidth * vtDirS, false)
|
|
EgtAddCurveCompoLine( nCrvTrim, EgtEP( nCrvTrim) + dGeoWidth * vtDirE)
|
|
EgtMove( nCrvTrim, Z_AX())
|
|
local nStmTrim = EgtSurfTmByExtrusion( nSolidLayerId, nCrvTrim, - 2 * dGeoWidth * Z_AX())
|
|
|
|
-- taglio i due sottopezzi
|
|
EgtSurfTmSubtract( vMainExtrusions[i+1], nStmTrim)
|
|
EgtInvertSurf( nStmTrim)
|
|
EgtSurfTmSubtract( vMainExtrusions[i], nStmTrim)
|
|
|
|
EgtErase( nCrvTrim)
|
|
EgtErase( nStmTrim)
|
|
end
|
|
|
|
-- unisco i sottopezzi in una sola superficie
|
|
for i = 2, #vMainExtrusions do
|
|
EgtSurfTmAdd( vMainExtrusions[1], vMainExtrusions[i])
|
|
EgtErase( vMainExtrusions[i])
|
|
end
|
|
|
|
-- creo una copia dell'estrusione principale ( usata per ferramenta)
|
|
local nOrigMainExtrusionId = EgtCopy( vMainExtrusions[1], nSolidLayerId)
|
|
EgtSetName( nOrigMainExtrusionId, WIN_SRF_ORIGMAIN)
|
|
EgtSetStatus( nOrigMainExtrusionId, GDB_ST.OFF)
|
|
|
|
-- come guida tengo solo una copia della curva di outline
|
|
local vMainGuideIds = EgtGetNameInGroup( nSolidLayerId, WIN_MAINGUIDE)
|
|
EgtErase( vMainGuideIds)
|
|
local nMainGuideId = EgtCopyGlob( nOutlineId, nSolidLayerId)
|
|
EgtSetName( nMainGuideId, WIN_MAINGUIDE)
|
|
EgtSetStatus( nMainGuideId, GDB_ST.OFF)
|
|
|
|
-- b) TRIM START
|
|
local nPrevGeoId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_LEFT)
|
|
local nStartOutlineId = EgtGetInfo( nPrevGeoId, WIN_REF_OUTLINE, 'i')
|
|
local nTrimSurfStart = CreateTrimSurf( nPrevGeoId, nStartOutlineId, dGeoWidth, nSolidLayerId)
|
|
EgtSetStatus( nTrimSurfStart, GDB_ST.OFF)
|
|
EgtSurfTmIntersect( vMainExtrusions[1], nTrimSurfStart)
|
|
EgtSetInfo( nPrevGeoId, WIN_REF_SURF, nTrimSurfStart)
|
|
|
|
-- c) TRIM END
|
|
local nNextGeoId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_RIGHT)
|
|
local nEndOutlineId = EgtGetInfo( nNextGeoId, WIN_REF_OUTLINE, 'i')
|
|
local nTrimSurfEnd = CreateTrimSurf( nNextGeoId, nEndOutlineId, dGeoWidth, nSolidLayerId)
|
|
EgtSetStatus( nTrimSurfEnd, GDB_ST.OFF)
|
|
EgtSurfTmIntersect( vMainExtrusions[1], nTrimSurfEnd)
|
|
EgtSetInfo( nNextGeoId, WIN_REF_SURF, nTrimSurfEnd)
|
|
|
|
return vMainExtrusions[1]
|
|
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 sSection = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. WIN_SECTION
|
|
local nMainExtrusionId = CreateMainSurf( nOutlineId, 2 * dGeoWidth, nMainProfileId, sSection, nSolidLayerId)
|
|
-- creo una copia
|
|
local nOrigMainExtrusionId = EgtCopy( nMainExtrusionId, nSolidLayerId)
|
|
EgtSetName( nOrigMainExtrusionId, WIN_SRF_ORIGMAIN)
|
|
EgtSetStatus( nOrigMainExtrusionId, GDB_ST.OFF)
|
|
|
|
-- b) trim start
|
|
local nPrevProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_START)
|
|
local nPrevMixedOutline = EgtGetInfo( nOutlineId, WIN_MIXED_REF_START, 'i')
|
|
local nStmTrimStart = CreateMixedSplitTrimSurf( nPrevMixedOutline, nPrevProfileId, dGeoWidth, nSolidLayerId)
|
|
EgtSetStatus( nStmTrimStart, GDB_ST.OFF)
|
|
EgtSurfTmIntersect( nMainExtrusionId, nStmTrimStart)
|
|
local nGeoLayerId = EgtGetFirstNameInGroup( EgtGetParent( nSolidLayerId), WIN_GEO)
|
|
local nPrevGeoId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_LEFT)
|
|
EgtSetInfo( nPrevGeoId, WIN_REF_SURF, nStmTrimStart)
|
|
|
|
-- c) trim end
|
|
local nNextProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_END)
|
|
local nNextMixedOutline = EgtGetInfo( nOutlineId, WIN_MIXED_REF_END, 'i')
|
|
local nStmTrimEnd = CreateMixedSplitTrimSurf( nNextMixedOutline, nNextProfileId, dGeoWidth, nSolidLayerId)
|
|
EgtSetStatus( nStmTrimEnd, GDB_ST.OFF)
|
|
EgtSurfTmIntersect( nMainExtrusionId, nStmTrimEnd)
|
|
local nNextGeoId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_RIGHT)
|
|
EgtSetInfo( nNextGeoId, WIN_REF_SURF, nStmTrimEnd)
|
|
|
|
return nMainExtrusionId
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che verifica se due curve del geo sono concatenabili, ovvero se hanno lo stesso profilo e i corrispondenti outline coincidono o sono in tangenza
|
|
local function CheckChainability( nGeoCrv1, nGeoCrv2)
|
|
|
|
-- verifico profili
|
|
local sProfile1 = EgtGetInfo( nGeoCrv1, WIN_PROFILETYPE)
|
|
local sProfile2 = EgtGetInfo( nGeoCrv2, WIN_PROFILETYPE)
|
|
local nSemiProfileId1 = EgtGetInfo( nGeoCrv1, WIN_SEMI_PROFILE, 'i')
|
|
local nSemiProfileId2 = EgtGetInfo( nGeoCrv2, WIN_SEMI_PROFILE, 'i')
|
|
if sProfile1 == sProfile2 and nSemiProfileId1 and nSemiProfileId2 and EgtGetName( nSemiProfileId1) == EgtGetName( nSemiProfileId2) then
|
|
-- verifico outlines
|
|
local nRefOutline1 = EgtGetInfo( nGeoCrv1, WIN_REF_OUTLINE, 'i')
|
|
local nRefOutline2 = EgtGetInfo( nGeoCrv2, WIN_REF_OUTLINE, 'i')
|
|
if nRefOutline1 == nRefOutline2 or AreSameVectorApprox( EgtEV( nRefOutline1), EgtSV( nRefOutline2)) then
|
|
return true
|
|
end
|
|
end
|
|
return false
|
|
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 sSection = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. WIN_SECTION
|
|
local nMainExtrusionId = CreateMainSurf( nOutlineId, 4 * dGeoWidth, 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 vGeoId = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_RIGHT)
|
|
local vPrevGeoId = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_LEFT)
|
|
EgtJoinTables( vGeoId, vPrevGeoId)
|
|
-- verifico quali curve di trim conviene concatenare per evitare booleane problematiche con tratti sovrapposti
|
|
local vChains = {{ vGeoId[1]}}
|
|
for i = 2, #vGeoId do
|
|
if CheckChainability( vGeoId[i-1], vGeoId[i]) then
|
|
-- aggiugno alla catena corrente
|
|
table.insert( vChains[#vChains], vGeoId[i])
|
|
else
|
|
-- creo una nuova catena
|
|
table.insert( vChains, { vGeoId[i]})
|
|
end
|
|
end
|
|
|
|
-- calcolo le superfici di trim
|
|
for i = 1, #vChains do
|
|
local nTrimSurf
|
|
if #vChains[i] == 1 then
|
|
local nRefOutlineId = EgtGetInfo( vChains[i][1], WIN_REF_OUTLINE, 'i')
|
|
nTrimSurf = CreateTrimSurf( vChains[i][1], abs( nRefOutlineId), dGeoWidth, nSolidLayerId)
|
|
-- assegno alla curva del geo la superficie di trim creata
|
|
EgtSetInfo( vChains[i][1], WIN_REF_SURF, nTrimSurf)
|
|
else
|
|
-- costruisco la guida a partire dagli outlines
|
|
local vRefOutlineIds = {}
|
|
for j = 1, #vChains[i] do
|
|
local nCurrOutline = EgtGetInfo( vChains[i][j], WIN_REF_OUTLINE, 'i')
|
|
-- verifico di non inserire un outline doppio
|
|
if j == 1 or nCurrOutline ~= vRefOutlineIds[#vRefOutlineIds] then
|
|
table.insert( vRefOutlineIds, abs( nCurrOutline))
|
|
end
|
|
end
|
|
local nGuideId = EgtCurveCompo( nSolidLayerId, vRefOutlineIds, false)
|
|
nTrimSurf = CreateTrimSurf( vChains[i][1], nGuideId, dGeoWidth, nSolidLayerId)
|
|
-- assegno ad ogni curva del geo la superficie di trim creata
|
|
for j = 1, #vChains[i] do
|
|
EgtSetInfo( vChains[i][j], WIN_REF_SURF, nTrimSurf)
|
|
end
|
|
EgtErase( nGuideId)
|
|
end
|
|
|
|
EgtSetStatus( nTrimSurf, GDB_ST.OFF)
|
|
EgtSurfTmIntersect( nMainExtrusionId, nTrimSurf)
|
|
end
|
|
|
|
return nMainExtrusionId
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che crea il solido del Fill
|
|
local function CalcFillSolid( nPartId, nGeoLayerId)
|
|
-- creo layer per solido
|
|
local nSolidLayerId = EgtGroup( nPartId)
|
|
EgtSetName( nSolidLayerId, WIN_SOLID)
|
|
-- creo compo dalle curve del geo
|
|
local vGeoList = EgtGetAllInGroup( nGeoLayerId)
|
|
local nCompoOutlineId = EgtCurveCompo( nSolidLayerId, vGeoList, false)
|
|
-- recupero spessore vetro
|
|
local dGlassThickness = EgtGetInfo( nGeoLayerId, WIN_GLASSTHICKNESS, 'd')
|
|
local nSurfId = EgtSurfTmByRegionExtrusion( nSolidLayerId, nCompoOutlineId, Z_AX() * dGlassThickness)
|
|
EgtErase( nCompoOutlineId)
|
|
end
|
|
|
|
----------------------------------------------------------------------------------
|
|
-- funzione che aggiorna il solido principale con quello associato ad una lavorazione partendo dalla sua curva
|
|
local function 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 * 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( nRefProfileType, 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, 300 * 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_RAILDELTA, 'd')
|
|
else
|
|
nRefCrv = nPrevOutlineId
|
|
dOffs = EgtGetInfo( nPrevProfileId, WIN_RAILDELTA, 'd')
|
|
end
|
|
EgtOffsetCurve( nRefCrv, - dOffs)
|
|
end
|
|
|
|
-- recupero i geo
|
|
local nGeo = EgtGetFirstNameInGroup( nPart, WIN_GEO)
|
|
local nPrevGeo = EgtGetFirstNameInGroup( nPrevPart, WIN_GEO)
|
|
|
|
-- recupero i tipi di profilo
|
|
local nPrevProfileType = GetOutlineProfileType( nPrevOutlineId, false, nBottomRail)
|
|
local nProfileType = GetOutlineProfileType( nOutlineId, false, nBottomRail)
|
|
-- caso particolare del triangolo : se lato top contro bottom il top deve essere gestito come un left/right
|
|
if nProfileType == WIN_PRF.TOP and nPrevProfileType == WIN_PRF.BOTTOM then
|
|
nProfileType = WIN_PRF.RIGHT
|
|
elseif nProfileType == WIN_PRF.BOTTOM and nPrevProfileType == WIN_PRF.TOP then
|
|
nPrevProfileType = WIN_PRF.LEFT
|
|
end
|
|
|
|
-- recupero i solidi
|
|
local nPrevSolidId, nSolidId, nPrevSolidLay, nSolidLay
|
|
if s_bCalcSolid then
|
|
nSolidLay = EgtGetFirstNameInGroup( nPart, WIN_SOLID)
|
|
nSolidId = EgtGetFirstNameInGroup( nSolidLay, WIN_SRF_MAIN)
|
|
nPrevSolidLay = EgtGetFirstNameInGroup( nPrevPart, WIN_SOLID)
|
|
nPrevSolidId = EgtGetFirstNameInGroup( nPrevSolidLay, WIN_SRF_MAIN)
|
|
end
|
|
|
|
-- recupero il tipo di giunzione
|
|
local nJointType = 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( nPrevProfileType, 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 nProfileType == WIN_PRF.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( nProfileType, 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 nPrevProfileType == WIN_PRF.BOTTOM then
|
|
sLenKey = WIN_DWL_BOTTOM_PARA_LEN
|
|
sPrevLenKey = WIN_DWL_BOTTOM_PERP_LEN
|
|
elseif nPrevProfileType == WIN_PRF.BOTTOMRAIL or nPrevProfileType == WIN_PRF.BOTTOMRAIL_FINAL then
|
|
sLenKey = WIN_DWL_BOTTOMRAIL_PARA_LEN
|
|
sPrevLenKey = WIN_DWL_BOTTOMRAIL_PERP_LEN
|
|
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
|
|
|
|
-- 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 nProfileType = GetOutlineProfileType( nOutlineId, true)
|
|
|
|
-- calcolo il frame di destinazione
|
|
-- trovo intersezione dello split con lato In o Out del geo
|
|
local nGeoLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO)
|
|
local nGeoCrvId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_IN)
|
|
local ptInters = EgtIP( nGeoCrvId, nSplitId, ptRef)
|
|
local sDowelSide = WIN_PRC_SIDETYPE.IN
|
|
if not ptInters and nProfileType == WIN_PRF.SPLIT then
|
|
nGeoCrvId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_OUT)
|
|
ptInters = EgtIP( nGeoCrvId, nSplitId, ptRef)
|
|
sDowelSide = WIN_PRC_SIDETYPE.OUT
|
|
end
|
|
-- se non trovo intersezione passo al successivo
|
|
if ptInters then
|
|
|
|
-- TO DO : gestione split non lineare
|
|
local frDest = Frame3d( ptInters, - 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)
|
|
local sSplitProfileType = EgtGetName( nSplitProfile)
|
|
EgtSetInfo( nSplitProfileCopyId, WIN_PRF_TYPE, sSplitProfileType)
|
|
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 nProfileType == WIN_PRF.BOTTOM then
|
|
sSplitLenKey = WIN_DWL_BOTTOM_PARA_LEN
|
|
sLenKey = WIN_DWL_BOTTOM_PERP_LEN
|
|
elseif nProfileType == WIN_PRF.BOTTOMRAIL_FINAL then
|
|
sSplitLenKey = WIN_DWL_RAILBOTTOM_PARA_LEN
|
|
sLenKey = WIN_DWL_RAILBOTTOM_PERP_LEN
|
|
elseif nProfileType == WIN_PRF.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 nMixedOutline = EgtGetInfo( nSplitId, EgtIf( bStartOrEnd, WIN_MIXED_REF_START, WIN_MIXED_REF_END), 'i')
|
|
nTestSurf = CreateMixedSplitTrimSurf( nMixedOutline, nProfileId, 100, 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 = frDest:getVersZ()
|
|
local _, _, nSide = EgtPointCurveDistSide( ptInters + vtDir, nGeoCrvId, Z_AX())
|
|
if nSide == 1 then
|
|
-- se a destra della curva significa che la direzione è uscente dal pezzo e va invertita
|
|
vtDir = - vtDir
|
|
end
|
|
|
|
-- 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
|
|
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, GDB_RT.GLOB)
|
|
|
|
-- calcolo offset per strip
|
|
local dDelta = EgtGetInfo( nProfileId, WIN_RAILDELTA, '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_PRF_TYPE)
|
|
if sProfileType == WIN_FILL_RAIL then
|
|
local dOffs = EgtGetInfo( nProfileId, WIN_RAILDELTA, '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 ------------------------------------
|
|
----------------------------------------------------------------------------------
|
|
-- 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
|
|
|
|
---------------------------------------------------------------------
|
|
-- 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 dOffs = b3FrameProfile:getMin():getX()
|
|
local nBottomRail = EgtGetInfo( nCrv, WIN_BOTTOMRAIL, 'i') or 0
|
|
if nBottomRail > 0 then
|
|
-- aggiusto offset per bottomrail
|
|
local dDelta1 = EgtGetInfo( nProfileId, WIN_RAILDELTA .. '1', 'd')
|
|
local dDelta2 = EgtGetInfo( nProfileId, WIN_RAILDELTA .. '2', 'd')
|
|
dOffs = dOffs - dDelta1 - ( nBottomRail - 1) * dDelta2
|
|
end
|
|
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 calcola l'ingombro dei pezzi del telaio e i loro solidi
|
|
local function CreatePartFromOutline( nAreaLayerId, sName, nOutlineId, nOutlineCrvNbr, 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)
|
|
-- inserisco riferimento alla sua area
|
|
EgtSetInfo( nPartId, WIN_AREA, nAreaLayerId)
|
|
|
|
local nAreaType = EgtGetInfo( nAreaLayerId, WIN_AREATYPE, 'i')
|
|
local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaLayerId, WIN_OUTLINE)
|
|
|
|
-- a) Telaio, anta o split
|
|
if nAreaType == WIN_AREATYPES.FRAME or nAreaType == WIN_AREATYPES.SASH or nAreaType == WIN_AREATYPES.SPLIT then
|
|
|
|
-- 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)
|
|
else
|
|
EgtSetInfo( nOutlineId, WIN_REF_PART, nPartId)
|
|
end
|
|
|
|
-- imposto nome del pezzo
|
|
local sOutlineName = EgtIf( nBottomRail, WIN_BOTTOMRAIL .. '_' .. tostring( nBottomRail), EgtGetName( nOutlineId))
|
|
local sPartName = sName .. '_' .. sOutlineName
|
|
EgtSetName( nPartId, sPartName)
|
|
|
|
-- imposto il 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
|
|
|
|
-- ricavo il tipo di profilo
|
|
local nProfileType = GetOutlineProfileType( nOutlineId, false, nBottomRail)
|
|
-- disegno ingombro
|
|
CalcFrameGeo( nPartId, nOutlineId, nOutlineCrvNbr, nOutlineLayerId, nProfileType, nBottomRail)
|
|
-- calcolo eventuali curve ausiliarie per cambio profilo
|
|
local bChangeProfile = EgtGetInfo( nOutlineId, WIN_PRF_CHANGE, 'b') or false
|
|
if bChangeProfile and nProfileType ~= WIN_PRF.SPLIT then
|
|
CalcMixedFrameCurves( nPartId, nOutlineId)
|
|
end
|
|
-- calcolo le lavorazioni associate ai profili
|
|
CalcProfilingProcessings( nPartId, nOutlineId)
|
|
-- calcolo il georaw per automatismo lavorazioni
|
|
CalcGeoRaw( nPartId)
|
|
-- disegno solido
|
|
if s_bCalcSolid then
|
|
CalcSolid( nPartId, nOutlineId)
|
|
end
|
|
|
|
-- b) Fill
|
|
elseif nAreaType == WIN_AREATYPES.FILL then
|
|
-- imposto nome del pezzo
|
|
EgtSetName( nPartId, sName .. '_' .. WIN_FILL)
|
|
EgtSetInfo( nPartId, WIN_PART_TYPE, WIN_PART_TYPES.FILL)
|
|
-- ricavo tipo
|
|
local nFillType = EgtGetInfo( nAreaLayerId, WIN_FILLTYPE, 'i')
|
|
|
|
-- imposto colore e tipologia di riempimento
|
|
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
|
|
|
|
-- disegno ingombro
|
|
local nGeoLayerId = CalcFillGeo( nPartId, nOutlineLayerId)
|
|
-- disegno solido
|
|
if s_bCalcSolid then
|
|
CalcFillSolid( nPartId, nGeoLayerId)
|
|
end
|
|
-- calcolo fermavetro
|
|
CalcAreaStrip( nGeoLayerId)
|
|
end
|
|
return nPartId
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- funzione che cicla ricorsivamente su aree e sottoaree per calcolare i pezzi
|
|
local function CalculateAreaParts( nAreaId)
|
|
|
|
local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i')
|
|
-- recupero nome dei pezzi in quest'area
|
|
local sName = CalcPartName( nAreaId, nAreaType)
|
|
if nAreaType == WIN_AREATYPES.FRAME or nAreaType == WIN_AREATYPES.SASH then
|
|
-- creo pezzi per ogni outline
|
|
local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE)
|
|
local vOutlines = EgtGetAllInGroup( nOutlineLayerId)
|
|
for i = 1, #vOutlines do
|
|
-- creo pezzo
|
|
CreatePartFromOutline( nAreaId, sName, vOutlines[i], i)
|
|
-- se di tipo bottom verifico se ha bottomrail
|
|
if EgtGetName( vOutlines[i]) == WIN_BOTTOM then
|
|
local nBottomRail = EgtGetInfo( nAreaId, WIN_BOTTOMRAIL, 'i') or 0
|
|
for j = 1, nBottomRail do
|
|
CreatePartFromOutline( nAreaId, sName, vOutlines[i], i, j)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- se anta disegno apertura
|
|
if nAreaType == WIN_AREATYPES.SASH then
|
|
DrawOpening( nAreaId)
|
|
end
|
|
|
|
elseif nAreaType == WIN_AREATYPES.FILL then
|
|
-- creo riempimento
|
|
CreatePartFromOutline( nAreaId, sName)
|
|
|
|
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
|
|
if nSplitType ~= WIN_SPLITTYPES.FRENCH then
|
|
-- creo gruppo per area di selezione per programma
|
|
local nSelectionLayerId = EgtGroup( nAreaId)
|
|
EgtSetName( nSelectionLayerId, WIN_SPLITSELECTION)
|
|
EgtSetStatus( nSelectionLayerId, GDB_ST.OFF)
|
|
EgtSetColor( nSelectionLayerId, 'YELLOW')
|
|
EgtSetAlpha( nSelectionLayerId, 10)
|
|
local nSelectionArea
|
|
|
|
local vSplitIds = EgtGetAllInGroup( nSplitLayerId)
|
|
for i = 1, #vSplitIds do
|
|
-- creo pezzo split
|
|
local nSplitPartId = CreatePartFromOutline( nAreaId, sName, vSplitIds[i])
|
|
|
|
-- aggiorno area di selezione
|
|
local nSplitPartGeoId = EgtGetFirstNameInGroup( nSplitPartId, WIN_GEO)
|
|
local nSplitArea = EgtGetFirstNameInGroup( nSplitPartGeoId, WIN_GEO_SURF)
|
|
if not nSelectionArea then
|
|
nSelectionArea = EgtCopyGlob( nSplitArea, nSelectionLayerId)
|
|
EgtSetStatus( nSelectionArea, GDB_ST.ON)
|
|
else
|
|
EgtSurfFrAdd( nSelectionArea, nSplitArea)
|
|
end
|
|
end
|
|
EgtMove( nSelectionArea, 10 * Z_AX())
|
|
end
|
|
end
|
|
|
|
-- disegno area di selezione per programma
|
|
local nSelectionLayerId = EgtGroup( nAreaId)
|
|
EgtSetName( nSelectionLayerId, WIN_SELECTION)
|
|
EgtSetStatus( nSelectionLayerId, GDB_ST.OFF)
|
|
local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE)
|
|
local vOutlineList = EgtGetAllInGroup( nOutlineLayerId)
|
|
local nCompoId = EgtCurveCompo( nSelectionLayerId, vOutlineList, false)
|
|
local nSelectionArea = EgtSurfFlatRegion( nSelectionLayerId, nCompoId)
|
|
EgtSetColor( nSelectionArea, 'YELLOW')
|
|
EgtSetAlpha( nSelectionArea, 10)
|
|
EgtMove( nSelectionArea, 10 * Z_AX())
|
|
EgtErase( nCompoId)
|
|
|
|
-- calcolo i pezzi delle sottoaree
|
|
local nChildAreaId = EgtGetFirstNameInGroup( nAreaId, WIN_AREA .. '*')
|
|
while nChildAreaId do
|
|
CalculateAreaParts( nChildAreaId)
|
|
nChildAreaId = EgtGetNextName( nChildAreaId, WIN_AREA .. '*')
|
|
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)
|
|
|
|
-- svuoto il GeoRaw per ricalcolarlo
|
|
local nGeoRawLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO_RAW)
|
|
EgtEmptyGroup( nGeoRawLayerId)
|
|
|
|
-- 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 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 = 0.5 * b3Profile:getDimX()
|
|
|
|
-- 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])
|
|
return dVal
|
|
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 sHandleSide = 'Sx'
|
|
local nOutlineId = EgtGetFirstNameInGroup( nOutlineLayId, WIN_RIGHT)
|
|
for i = 1, #vOptions do
|
|
local vString = EgtSplitString( vOptions[i], '=')
|
|
if vString[1] == 'PosizioneManiglia' then
|
|
if vString[2] == 'destra' then
|
|
sHandleSide = 'Dx'
|
|
nOutlineId = EgtGetFirstNameInGroup( nOutlineLayId, WIN_LEFT)
|
|
elseif vString[2] == 'sopra' then
|
|
nOutlineId = EgtGetFirstNameInGroup( nOutlineLayId, WIN_TOP)
|
|
end
|
|
break
|
|
end
|
|
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)
|
|
|
|
-- recupero gruppi dei profili
|
|
local nProfileId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_PROFILE)
|
|
local nSashProfileLayerId = EgtGetFirstNameInGroup( nProfileId, WIN_SASH)
|
|
local nFrameProfileLayerId = EgtGetFirstNameInGroup( nProfileId, WIN_FRAME)
|
|
|
|
-- 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 sProfileType = EgtGetInfo( nOutlineId, WIN_PROFILETYPE)
|
|
local nSashProfileId = EgtGetFirstNameInGroup( nSashProfileLayerId, sProfileType)
|
|
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 nFrameProfileId = EgtGetFirstNameInGroup( nFrameProfileLayerId, sProfileFrame, 'i')
|
|
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 bSlide = EgtGetInfo( nFrameId, WIN_SLIDE_WINDOW, 'b') or false
|
|
|
|
if bSlide then
|
|
-- le dimensioni per alzante scorrevole sono quelle del telaio
|
|
local nOutlineLayId = EgtGetFirstInGroup( 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
|
|
|
|
-- recupero tutti gli split che possono creare interruzioni nel gocciolatoio
|
|
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
|
|
table.insert( vSplits, vCurrSplits[j])
|
|
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
|
|
|
|
-- recupero le curve sulle quali costruire il gocciolatoio: in generale è solo l'outline bottom, nel caso di cambio profilo sono solo i suoi sottotratti che poggiano
|
|
-- contro le ante
|
|
local vBottomOutlines = { nOutlineId}
|
|
local bProfileChange = EgtGetInfo( nOutlineId, WIN_PRF_CHANGE, 'b') or false
|
|
if bProfileChange then
|
|
local nMixedOutlinesLay = EgtGetFirstNameInGroup( nPartId, WIN_MIXED_OUTLINES)
|
|
local vSashOutlines = EgtGetNameInGroup( nMixedOutlinesLay, WIN_SASH)
|
|
vBottomOutlines = vSashOutlines
|
|
end
|
|
|
|
-- recupero curve vicine
|
|
local nPrevCrv = EgtGetLastInGroup( EgtGetParent( nOutlineId))
|
|
local nNextCrv = EgtGetNext( nOutlineId)
|
|
|
|
for i = 1, #vBottomOutlines do
|
|
local vParams = {}
|
|
|
|
-- verifico se interruzioni per i pezzi vicini del telaio
|
|
if AreSamePointApprox( EgtSP( vBottomOutlines[i]), EgtEP( nPrevCrv)) then
|
|
local dPar = GetTrimParamByGeo( vBottomOutlines[i], nPrevCrv, WIN_GEO_IN)
|
|
table.insert( vParams, dPar)
|
|
end
|
|
if AreSamePointApprox( EgtEP( vBottomOutlines[i]), EgtSP( nNextCrv)) then
|
|
local dPar = GetTrimParamByGeo( vBottomOutlines[i], nNextCrv, WIN_GEO_IN)
|
|
table.insert( vParams, dPar)
|
|
end
|
|
|
|
-- verifico se interruzioni per split
|
|
for j = 1, #vSplits do
|
|
-- verifico se lo split poggia sulla curva
|
|
local dDist1 = EgtPointCurveDist( EgtSP( vSplits[j]), vBottomOutlines[i])
|
|
local dDist2 = EgtPointCurveDist( EgtEP( vSplits[j]), vBottomOutlines[i])
|
|
if dDist1 < GEO.EPS_SMALL or dDist2 < GEO.EPS_SMALL then
|
|
-- recupero i parametri di intersezione con il geo dello split
|
|
local dParIn = GetTrimParamByGeo( vBottomOutlines[i], vSplits[j], WIN_GEO_IN)
|
|
if dParIn then
|
|
table.insert( vParams, dParIn)
|
|
end
|
|
local dParOut = GetTrimParamByGeo( vBottomOutlines[i], vSplits[j], WIN_GEO_OUT)
|
|
if dParOut then
|
|
table.insert( vParams, dParOut)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- riordino i parametri ( non dovrebbero mai capitare parametri coincidenti)
|
|
table.sort( vParams)
|
|
|
|
for j = 1, #vParams, 2 do
|
|
-- creo la guida di estrusione per il gocciolatoio
|
|
local nGuideId = EgtCopyGlob( vBottomOutlines[i], nSolidLayId)
|
|
-- trim della curva
|
|
EgtTrimCurveStartEndAtParam( nGuideId, vParams[j], vParams[j+1])
|
|
-- aggiorno la lunghezza
|
|
dLenTot = dLenTot + EgtCurveLength( nGuideId)
|
|
-- disegno
|
|
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
|
|
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( nAreaId, 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, nProfileGrp, 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])
|
|
|
|
local vNextOutlines = EgtGetInfo( nOutlineId, WIN_NEXT_OUTLINES, 'vi')
|
|
local vEndProfiles = EgtGetNameInGroup( nProfileGrp, WIN_PRF_END)
|
|
local b3ProfileEnd = GetProfileLocalBox( vEndProfiles[1])
|
|
vCrvs[2] = EgtCopyGlob( abs( vNextOutlines[1]), nPreviewGrp)
|
|
EgtOffsetCurve( vCrvs[2], b3ProfileEnd:getMin():getX())
|
|
|
|
-- 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)
|
|
|
|
local vPrevOutlines = EgtGetInfo( nOutlineId, WIN_PREV_OUTLINES, 'vi')
|
|
local vStartProfiles = EgtGetNameInGroup( nProfileGrp, WIN_PRF_START)
|
|
local b3ProfileStart = GetProfileLocalBox( vStartProfiles[1])
|
|
vCrvs[4] = EgtCopyGlob( abs( vPrevOutlines[1]), nPreviewGrp)
|
|
EgtOffsetCurve( vCrvs[4], b3ProfileStart:getMin():getX())
|
|
|
|
-- 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 dStep = b3Surf:getDimY() / nBottomRail
|
|
for i = 1, nBottomRail - 1 do
|
|
local pt = b3Surf:getMin() + i * dStep * 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 nAreaId
|
|
|
|
local nOutlineId = EgtGetInfo( nPartId, WIN_REF_OUTLINE, 'i')
|
|
local nGeoGrp = EgtGetFirstNameInGroup( nPartId, WIN_GEO)
|
|
local nProfileGrp = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE)
|
|
|
|
-- verifico se è sash active/inactive per gestione speciale
|
|
local nBaseOutlineId = EgtGetInfo( nOutlineId, WIN_COPY, 'i')
|
|
local bOnSplit = EgtGetInfo( nBaseOutlineId, WIN_CRV_ON_FRENCH_SPLIT, 'b')
|
|
|
|
-- recupero il tipo di giunzione
|
|
local nStartJoint = EgtGetInfo( nOutlineId, WIN_STARTJOINT, 'i')
|
|
local nEndJoint = EgtGetInfo( nOutlineId, WIN_ENDJOINT, 'i')
|
|
|
|
-- se non ha giunzioni short e non è active/inactive come preview posso considerare direttamente la regione del geo
|
|
if nStartJoint ~= WIN_PART_JNT.SHORT and nEndJoint ~= WIN_PART_JNT.SHORT and not bOnSplit then
|
|
local nGeoSurf = EgtGetFirstNameInGroup( nGeoGrp, WIN_GEO_SURF)
|
|
nAreaId = EgtCopyGlob( nGeoSurf, nPreviewGrp)
|
|
EgtSetStatus( nAreaId, GDB_ST.ON)
|
|
|
|
-- altrimenti devi calcolare le curve che delimitano la regione
|
|
else
|
|
-- gruppo temporaneo per i conti
|
|
local nGrpTmp = EgtGroup( nPreviewGrp)
|
|
|
|
-- curva out è il geo out tranne nel caso di sash active/inactive per le quali considero l'outline per evitare sovrapposizioni
|
|
if bOnSplit then
|
|
EgtCopyGlob( nOutlineId, nGrpTmp)
|
|
else
|
|
local nGeoOut = EgtGetFirstNameInGroup( nGeoGrp, WIN_GEO_OUT)
|
|
EgtCopyGlob( nGeoOut, nGrpTmp)
|
|
end
|
|
|
|
-- curva right
|
|
local vGeoRight = EgtGetNameInGroup( nGeoGrp, WIN_GEO_RIGHT)
|
|
if nEndJoint == WIN_PART_JNT.SHORT then
|
|
-- se giunzione short per evitare sovrapposizioni devo fermarla al box del pezzo adiacente
|
|
local vEndProfiles = EgtGetNameInGroup( nProfileGrp, WIN_PRF_END)
|
|
for i = 1, #vGeoRight do
|
|
local nNextOutline = EgtGetInfo( vGeoRight[i], WIN_REF_OUTLINE, 'i')
|
|
local nCrv = EgtCopyGlob( abs( nNextOutline), nGrpTmp)
|
|
local b3Profile = GetProfileLocalBox( vEndProfiles[i])
|
|
local dRailDelta = EgtGetInfo( vEndProfiles[i], WIN_RAILDELTA, 'd') or 0
|
|
local dOffs = b3Profile:getMin():getX() - dRailDelta
|
|
if nNextOutline < 0 then
|
|
EgtInvertCurve( nCrv)
|
|
dOffs = - ( b3Profile:getMax():getX() - dRailDelta)
|
|
end
|
|
EgtOffsetCurve( nCrv, dOffs)
|
|
end
|
|
else
|
|
-- altrimenti posso utilizzare direttamente la curva del geo
|
|
for i = 1, #vGeoRight do
|
|
EgtCopyGlob( vGeoRight[i], nGrpTmp)
|
|
end
|
|
end
|
|
|
|
-- curva in
|
|
local nGeoIn = EgtGetFirstNameInGroup( nGeoGrp, WIN_GEO_IN)
|
|
EgtCopyGlob( nGeoIn, nGrpTmp)
|
|
|
|
-- curva left
|
|
local vGeoLeft = EgtGetNameInGroup( nGeoGrp, WIN_LEFT)
|
|
if nStartJoint == WIN_PART_JNT.SHORT then
|
|
local vStartProfiles = EgtGetNameInGroup( nProfileGrp, WIN_PRF_START)
|
|
for i = 1, #vGeoLeft do
|
|
local nPrevOutline = EgtGetInfo( vGeoLeft[i], WIN_REF_OUTLINE, 'i')
|
|
local nCrv = EgtCopyGlob( abs( nPrevOutline), nGrpTmp)
|
|
local b3Profile = GetProfileLocalBox( vStartProfiles[i])
|
|
local dRailDelta = EgtGetInfo( vStartProfiles[i], WIN_RAILDELTA, 'd') or 0
|
|
local dOffs = b3Profile:getMin():getX() - dRailDelta
|
|
if nPrevOutline < 0 then
|
|
EgtInvertCurve( nCrv)
|
|
dOffs = - ( b3Profile:getMax():getX() - dRailDelta)
|
|
end
|
|
EgtOffsetCurve( nCrv, dOffs)
|
|
end
|
|
else
|
|
for i = 1, #vGeoLeft do
|
|
EgtCopyGlob( vGeoLeft[i], nGrpTmp)
|
|
end
|
|
end
|
|
|
|
-- creo la regione
|
|
nAreaId = CalcIntersectionRegion( EgtGetAllInGroup( nGrpTmp), nPreviewGrp)
|
|
EgtErase( nGrpTmp)
|
|
end
|
|
|
|
-- sistemo la regione
|
|
local color = EgtGetColor( nPartId)
|
|
EgtSetColor( nAreaId, color)
|
|
-- estraggo il contorno
|
|
local nCompoId = EgtExtractSurfFrChunkLoops( nAreaId, 0, nPreviewGrp)
|
|
EgtSetColor( nCompoId, EgtStdColor( 'BLACK'))
|
|
EgtModifyCurveThickness( nCompoId, 0)
|
|
|
|
-- 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, nProfileGrp, nGeoGrp, 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 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
|
|
|
|
-- 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)
|
|
-- 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
|