Files
egwwindowlua/Designing/WinLib/WinCalculate.lua
T
SaraP 67589d44ef DataWindow :
- arco a 3 centri
- migliorie e correzioni varie per gestire correttamente l'arco a 3 centri ( calcolo solidi, strip, outline del fill).
2025-11-04 11:41:44 +01:00

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