Files
egwwindowlua/Designing/WinLib/WinCreate.lua
T
SaraP 407e32d6b0 DataWindow :
- se non definita altezza maniglia, richiesta delle opzioni della ferramenta per ricavarne valore di default
- aggiunta forma dell'anta.
2025-10-21 10:04:35 +02:00

754 lines
31 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 WinCreate = {}
-- Include
require( 'EgtBase')
require( 'WinConst')
-- funzioni
----------------------------------------------------------------------------------
local function AddInfo( nId, sInfo, nVal)
local vInfo = EgtGetInfo( nId, sInfo, 'vi') or {}
table.insert( vInfo, nVal)
EgtSetInfo( nId, sInfo, vInfo)
end
----------------------------------------------------------------------------------
local function CopyParentOutline( nAreaId, nParentAreaId)
-- recupero outline del parent
local nParentOutlineLayerId = EgtGetFirstNameInGroup( nParentAreaId, WIN_AREAOUTLINE)
local vParentCrvs = EgtGetAllInGroup( nParentOutlineLayerId)
-- creo outline per area corrente
local nOutlineLayerId = EgtGroup( nAreaId)
EgtSetName( nOutlineLayerId, WIN_AREAOUTLINE)
-- copio le curve di outline del parent e setto le corrispondenze sou/child
for i = 1, #vParentCrvs do
local nOutlineId = EgtCopy( vParentCrvs[i], nOutlineLayerId)
EgtSetInfo( nOutlineId, WIN_SOU, vParentCrvs[i])
EgtSetInfo( vParentCrvs[i], WIN_CHILD, nOutlineId)
end
return nOutlineLayerId
end
----------------------------------------------------------------------------------
------------------------------------ PROFILO -------------------------------------
----------------------------------------------------------------------------------
-- funzione che importa il profilo
function WinCreate.ImportProfile( sProfilePath)
-- verifico esistenza file
if not EgtExistsFile( sProfilePath) then
EgtOutLog( 'File del profilo non trovato! ' .. sProfilePath)
EgtOutText( 'File del profilo non trovato! ' .. sProfilePath)
EgtPause(5000)
return false
end
-- creo gruppo per il profilo
local nProfileId = EgtGroup( GDB_ID.ROOT)
EgtSetName( nProfileId, WIN_PROFILE)
EgtSetLevel( nProfileId, GDB_LV.SYSTEM)
-- importo profilo prescelto
local bOk = EgtInsertFile( sProfilePath)
-- recupero gruppi importati e li sposto nel gruppo profilo
local nGroupId = EgtGetFirstInGroup( GDB_ID.ROOT)
while nGroupId do
if nGroupId ~= nProfileId then
local nCurrId = nGroupId
nGroupId = EgtGetNext( nGroupId)
EgtRelocateGlob( nCurrId, nProfileId)
EgtSetStatus( nCurrId, GDB_ST.OFF)
else
nGroupId = EgtGetNext( nGroupId)
end
end
-- riporto path nel Part del profilo
EgtSetInfo( nProfileId, WIN_PROFILEPATH, sProfilePath)
return true
end
----------------------------------------------------------------------------------
------------------------------------- TELAIO -------------------------------------
----------------------------------------------------------------------------------
-- funzione che crea le curve che definiscono il telaio in base alla geometria richiesta
local function CreateFrameCurves( nLayerId, nType, dWidth, dHeight, dVal)
-- rettangolo
if nType == WIN_FRAME_TYPES.RECT then
-- telaio rettangolare
local nBottomId = EgtLine( nLayerId, ORIG(), Point3d( dWidth, 0, 0))
EgtSetName( nBottomId, WIN_BOTTOM)
local nRightId = EgtLine( nLayerId, Point3d( dWidth, 0, 0), Point3d( dWidth, dHeight, 0))
EgtSetName( nRightId, WIN_RIGHT)
local nTopId = EgtLine( nLayerId, Point3d( dWidth, dHeight, 0), Point3d( 0, dHeight, 0))
EgtSetName( nTopId, WIN_TOP)
local nLeftId = EgtLine( nLayerId, Point3d( 0, dHeight, 0), ORIG())
EgtSetName( nLeftId, WIN_LEFT)
-- lato top inclinato
elseif nType == WIN_FRAME_TYPES.CHAMFER_SIDE then
-- dHeight è l'altezza del lato sx, dVal è l'altezza del lato dx
local nBottomId = EgtLine( nLayerId, ORIG(), Point3d( dWidth, 0, 0))
EgtSetName( nBottomId, WIN_BOTTOM)
local nRightId = EgtLine( nLayerId, Point3d( dWidth, 0, 0), Point3d( dWidth, dVal, 0))
EgtSetName( nRightId, WIN_RIGHT)
local nTopId = EgtLine( nLayerId, Point3d( dWidth, dVal, 0), Point3d( 0, dHeight, 0))
EgtSetName( nTopId, WIN_TOP)
local nLeftId = EgtLine( nLayerId, Point3d( 0, dHeight, 0), ORIG())
EgtSetName( nLeftId, WIN_LEFT)
-- triangular arch
elseif nType == WIN_FRAME_TYPES.CHAMFER then
-- dHeight è l'altezza dei lati verticali, dVal è l'altezza complessiva della finestra
local nBottomId = EgtLine( nLayerId, ORIG(), Point3d( dWidth, 0, 0))
EgtSetName( nBottomId, WIN_BOTTOM)
local nRightId = EgtLine( nLayerId, Point3d( dWidth, 0, 0), Point3d( dWidth, dHeight, 0))
EgtSetName( nRightId, WIN_RIGHT)
local nTop1Id = EgtLine( nLayerId, Point3d( dWidth, dHeight, 0), Point3d( dWidth / 2, dVal, 0))
local nTop2Id = EgtLine( nLayerId, Point3d( dWidth / 2, dVal, 0), Point3d( 0, dHeight, 0))
EgtSetName( nTop1Id, WIN_TOP)
EgtSetName( nTop2Id, WIN_TOP)
local nLeftId = EgtLine( nLayerId, Point3d( 0, dHeight, 0), ORIG())
EgtSetName( nLeftId, WIN_LEFT)
-- arco a tutto sesto
elseif nType == WIN_FRAME_TYPES.ROUND_ARC then
local nBottomId = EgtLine( nLayerId, ORIG(), Point3d( dWidth, 0, 0))
EgtSetName( nBottomId, WIN_BOTTOM)
local nRightId = EgtLine( nLayerId, Point3d( dWidth, 0, 0), Point3d( dWidth, dHeight - 0.5 * dWidth, 0))
EgtSetName( nRightId, WIN_RIGHT)
local nTopId = EgtArcCPA( nLayerId, Point3d( 0.5 * dWidth, dHeight - 0.5 * dWidth, 0), Point3d( dWidth, dHeight - 0.5 * dWidth, 0), 180, 0)
EgtSetName( nTopId, WIN_TOP)
local nLeftId = EgtLine( nLayerId, Point3d( 0, dHeight - 0.5 * dWidth, 0), ORIG())
EgtSetName( nLeftId, WIN_LEFT)
-- arco ribassato
elseif nType == WIN_FRAME_TYPES.SEGMENTAL_ARC then
-- dHeight è l'altezza dei lati verticali, dVal è l'altezza complessiva della finestra
local nBottomId = EgtLine( nLayerId, ORIG(), Point3d( dWidth, 0, 0))
EgtSetName( nBottomId, WIN_BOTTOM)
local nRightId = EgtLine( nLayerId, Point3d( dWidth, 0, 0), Point3d( dWidth, dHeight, 0))
EgtSetName( nRightId, WIN_RIGHT)
local nTopId = EgtArc3P( nLayerId, Point3d( dWidth, dHeight, 0), Point3d( 0.5 * dWidth, dVal, 0), Point3d( 0, dHeight, 0))
EgtSetName( nTopId, WIN_TOP)
local nLeftId = EgtLine( nLayerId, Point3d( 0, dHeight, 0), ORIG())
EgtSetName( nLeftId, WIN_LEFT)
-- arco a tutto sesto
elseif nType == WIN_FRAME_TYPES.POINTED_ARC then
-- dHeight è l'altezza dei lati verticali, dVal è l'altezza complessiva della finestra
-- verifico che le due altezze abbiano valori sensati per realizzare i due archi
if dVal - dHeight < 0.5 * dWidth then
return
end
local nBottomId = EgtLine( nLayerId, ORIG(), Point3d( dWidth, 0, 0))
EgtSetName( nBottomId, WIN_BOTTOM)
local nRightId = EgtLine( nLayerId, Point3d( dWidth, 0, 0), Point3d( dWidth, dHeight, 0))
EgtSetName( nRightId, WIN_RIGHT)
local nTop1Id = EgtArc2PV( nLayerId, Point3d( dWidth, dHeight, 0), Point3d( 0.5 * dWidth, dVal, 0), Y_AX())
EgtSetName( nTop1Id, WIN_TOP)
local nTop2Id = EgtArc2PV( nLayerId, Point3d( 0, dHeight, 0), Point3d( 0.5 * dWidth, dVal, 0), Y_AX())
EgtInvertCurve( nTop2Id)
EgtSetName( nTop2Id, WIN_TOP)
local nLeftId = EgtLine( nLayerId, Point3d( 0, dHeight, 0), ORIG())
EgtSetName( nLeftId, WIN_LEFT)
-- triangolo
elseif nType == WIN_FRAME_TYPES.TRG then
local nBottomId = EgtLine( nLayerId, ORIG(), Point3d( dWidth, 0, 0))
EgtSetName( nBottomId, WIN_BOTTOM)
local nEdge1Id = EgtLine( nLayerId, Point3d( dWidth, 0, 0), Point3d( dVal, dHeight, 0))
local nEdge2Id = EgtLine( nLayerId, Point3d( dVal, dHeight, 0), ORIG())
-- un lato verticale è right/left, un lato inclinato è top
if dVal < GEO.EPS_SMALL then
EgtSetName( nEdge1Id, WIN_TOP)
EgtSetName( nEdge2Id, WIN_LEFT)
elseif abs( dVal - dWidth) < GEO.EPS_SMALL then
EgtSetName( nEdge1Id, WIN_RIGHT)
EgtSetName( nEdge2Id, WIN_TOP)
else
EgtSetName( nEdge1Id, WIN_TOP)
EgtSetName( nEdge2Id, WIN_TOP)
end
end
end
----------------------------------------------------------------------------------
-- funzione che crea il telaio a partire da una specifica geometria ( rettangolo, chamfer...)
function WinCreate.CreateFrame( nType, vJoints, dWidth, dHeight, dHeight2, nAreaNbr)
-- creo gruppo per telaio
local nAreaId = EgtGroup( GDB_ID.ROOT)
EgtSetName( nAreaId, WIN_AREA .. '(' .. WIN_FRAME .. ')')
EgtSetLevel( nAreaId, GDB_LV.SYSTEM)
-- imposto il tipo
EgtSetInfo( nAreaId, WIN_AREATYPE, WIN_AREATYPES.FRAME)
-- costruisco le curve di outline
local nOutlineLayerId = EgtGroup( nAreaId)
EgtSetName( nOutlineLayerId, WIN_AREAOUTLINE)
CreateFrameCurves( nOutlineLayerId, nType, dWidth, dHeight, dHeight2)
EgtSetInfo( nAreaId, WIN_FRAME_TYPE, nType)
-- imposto tipo giunzioni
EgtSetInfo( nOutlineLayerId, WIN_JOINTS, vJoints)
-- numerazione
if nAreaNbr then
EgtSetInfo( nAreaId, WIN_AREA_NBR, nAreaNbr)
end
return nAreaId
end
----------------------------------------------------------------------------------
-------------------------------------- ANTA --------------------------------------
----------------------------------------------------------------------------------
-- funzione che identifica la forma dell'anta/gruppo di ante
local function IdentifySashShape( nAreaId, nOutlineLayerId)
local vOutlines = EgtGetAllInGroup( nOutlineLayerId)
local nCompoId = EgtCurveCompo( nOutlineLayerId, vOutlines, false)
-- verifico se trapezio
local bTrap, ptOrig, vtB1, vtE1, vtB2 = EgtCurveIsATrapezoid( nCompoId)
if bTrap then
-- verifico se rettangolo controllando se lati sono paralleli
local vtE2 = vtB1 + vtE1 - vtB2
if AreSameOrOppositeVectorApprox( vtE1, vtE2) then
EgtSetInfo( nAreaId, WIN_SASH_SHAPE, WIN_SASH_SHAPES.RECT)
else
EgtSetInfo( nAreaId, WIN_SASH_SHAPE, WIN_SASH_SHAPES.TRAP)
end
else
-- verifico se cerchio
local bCircle = EgtCurveIsACircle( nCompoId)
if bCircle then
EgtSetInfo( nAreaId, WIN_SASH_SHAPE, WIN_SASH_SHAPES.CIRCLE)
-- verifico se forma con arco
elseif #vOutlines == 4 and EgtGetType( vOutlines[3]) == GDB_TY.CRV_ARC then
local dAngCenter = EgtArcAngCenter( vOutlines[3])
if abs( dAngCenter - 180) < GEO.EPS_SMALL then
EgtSetInfo( nAreaId, WIN_SASH_SHAPE, WIN_SASH_SHAPES.ROUND_ARC)
else
if abs( EgtCurveLength( vOutlines[2]) - EgtCurveLength( vOutlines[4])) < GEO.EPS_SMALL then
EgtSetInfo( nAreaId, WIN_SASH_SHAPE, WIN_SASH_SHAPES.SEGMENTAL_ARC)
else
-- verifico se metà di arco a tutto sesto o ribassato
if abs( dAngCenter - 90) < GEO.EPS_SMALL then
EgtSetInfo( nAreaId, WIN_SASH_SHAPE, WIN_SASH_SHAPES.SEMI_ROUND_ARC)
else
local ptS = EgtSP( vOutlines[3])
local ptE = EgtEP( vOutlines[3])
local ptC = EgtCP( vOutlines[3])
if abs( ptS:getX() - ptC:getX()) < GEO.EPS_SMALL or abs( ptE:getX() - ptC:getX()) < GEO.EPS_SMALL then
EgtSetInfo( nAreaId, WIN_SASH_SHAPE, WIN_SASH_SHAPES.SEMI_SEGMENTAL_ARC)
else
EgtSetInfo( nAreaId, WIN_SASH_SHAPE, WIN_SASH_SHAPES.GENERIC)
end
end
end
end
else
EgtSetInfo( nAreaId, WIN_SASH_SHAPE, WIN_SASH_SHAPES.GENERIC)
end
end
EgtErase( nCompoId)
end
----------------------------------------------------------------------------------
-- funzione che aggiunge una anta
function WinCreate.AddSash( nParentAreaId, vJoints, nOpeningType, nAreaNbr)
-- se già presente area errore
if EgtGetFirstNameInGroup( nParentAreaId, WIN_AREA .. '*') then
return
end
-- creo nuova area
local nAreaId = EgtGroup( nParentAreaId)
EgtSetName( nAreaId, WIN_AREA .. '(' .. WIN_SASH .. ')')
-- imposto il tipo
EgtSetInfo( nAreaId, WIN_AREATYPE, WIN_AREATYPES.SASH)
-- copio outline dall'area parent
local nOutlineLayerId = CopyParentOutline( nAreaId, nParentAreaId)
IdentifySashShape( nAreaId, nOutlineLayerId)
EgtSetInfo( nOutlineLayerId, WIN_JOINTS, vJoints)
-- imposto apertura se presente
if nOpeningType then
EgtSetInfo( nAreaId, WIN_OPENING_TYPE, nOpeningType)
end
-- numerazione
if nAreaNbr then
EgtSetInfo( nAreaId, WIN_AREA_NBR, nAreaNbr)
EgtSetInfo( nAreaId, WIN_SASH_NBR, 1)
end
return nAreaId
end
----------------------------------------------------------------------------------
-- funzione che aggiunge un gruppo di ante
function WinCreate.AddSashGroup( nParentAreaId, nMeasureType, vDimensions, vJoints, vSashTypes, vOpeningTypes, nAreaNbr, vSashNbrs)
-- se già presente sottoarea errore
if EgtGetFirstNameInGroup( nParentAreaId, WIN_AREA .. '*') then
return
end
-- creo gli split di tipo french
local vAreas = WinCreate.AddSplits( nParentAreaId, WIN_SPLITORIENTATION.VERTICAL, nMeasureType, vDimensions, true, nAreaNbr)
-- identifico la forma del gruppo di ante
local nAreaSplit = EgtGetParent( vAreas[1])
local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaSplit, WIN_AREAOUTLINE)
IdentifySashShape( nAreaSplit, nOutlineLayerId)
-- trasformo le aree risultanti ( che sono null) nelle aree dell'anta settando le info opportune
for i = 1, #vAreas do
EgtSetName( vAreas[i], EgtGetName( vAreas[i]) .. '(' .. WIN_SASH .. ')')
EgtSetInfo( vAreas[i], WIN_AREATYPE, WIN_AREATYPES.SASH)
local nOutlineLayId = EgtGetFirstNameInGroup( vAreas[i], WIN_AREAOUTLINE)
EgtSetInfo( nOutlineLayId, WIN_JOINTS, vJoints)
EgtSetInfo( vAreas[i], WIN_SASHTYPE, vSashTypes[i])
EgtSetInfo( vAreas[i], WIN_OPENING_TYPE, vOpeningTypes[i])
if vSashNbrs then
EgtSetInfo( vAreas[i], WIN_SASH_NBR, vSashNbrs[i])
end
end
return vAreas
end
----------------------------------------------------------------------------------
-------------------------------------- FILL --------------------------------------
----------------------------------------------------------------------------------
-- funzione che aggiunge un riempimento
function WinCreate.AddFill( nParentAreaId, nFillType, nAreaNbr)
-- se area ha già sottoarea errore
if EgtGetFirstNameInGroup( nParentAreaId, WIN_AREA .. '*') then
return
end
local nAreaId = EgtGroup( nParentAreaId)
EgtSetName( nAreaId, WIN_AREA .. '(' .. WIN_FILL .. ')')
EgtSetInfo( nAreaId, WIN_AREATYPE, WIN_AREATYPES.FILL)
-- copio outline dall'area parent
CopyParentOutline( nAreaId, nParentAreaId)
-- imposto tipo di fill
EgtSetInfo( nAreaId, WIN_FILLTYPE, nFillType)
-- numerazione
if nAreaNbr then
EgtSetInfo( nAreaId, WIN_AREA_NBR, nAreaNbr)
end
return nAreaId
end
----------------------------------------------------------------------------------
------------------------------------- SPLIT --------------------------------------
----------------------------------------------------------------------------------
-- funzione che assegna il nome alla curva di split nella sottoarea in base alla sua direzione
local function SetSplitName( nSplitId)
local vtMedia = ( ( EgtEV( nSplitId) - EgtSV( nSplitId)) / 2)
if not vtMedia:normalize() then
vtMedia = EgtSV( nSplitId)
end
if abs( vtMedia:getX()) > abs( vtMedia:getY()) then
if vtMedia:getX() > 0 then
EgtSetName( nSplitId, WIN_BOTTOM)
else
EgtSetName( nSplitId, WIN_TOP)
end
else
if vtMedia:getY() > 0 then
EgtSetName( nSplitId, WIN_RIGHT)
else
EgtSetName( nSplitId, WIN_LEFT)
end
end
end
----------------------------------------------------------------------------------
-- funzione che taglia lo split con il bordo della regione
local function AdjustSplitCurve( nSplitId, nCompo, vOutlineCrvs, nOutlineLayerId)
-- trimmo lo split a filo con l'outline
EgtExtendCurveStartByLen( nSplitId, 10)
EgtExtendCurveEndByLen( nSplitId, 10)
local ptS = EgtIP( nSplitId, nCompo, EgtSP( nSplitId))
local ptE = EgtIP( nSplitId, nCompo, EgtEP( nSplitId))
local dParS = EgtCurveParamAtPoint( nSplitId, ptS)
local dParE = EgtCurveParamAtPoint( nSplitId, ptE)
EgtTrimCurveStartEndAtParam( nSplitId, dParS, dParE)
-- recupero le curve con cui avviene l'intersezione e le salvo come info
-- start
local dParCrvS = EgtCurveParamAtPoint( nCompo, ptS)
if abs( dParCrvS - ceil( dParCrvS)) < GEO.EPS_SMALL then
local nCrv = vOutlineCrvs[ ceil( dParCrvS) + 1]
local nOther = EgtGetPrev( nCrv) or EgtGetLastInGroup( nOutlineLayerId)
EgtSetInfo( nSplitId, WIN_SPLIT_STARTINTERS, { nOther, nCrv})
elseif abs( dParCrvS - floor( dParCrvS)) < GEO.EPS_SMALL then
local nCrv = vOutlineCrvs[ floor( dParCrvS) + 1]
local nOther = EgtGetPrev( nCrv) or EgtGetLastInGroup( nOutlineLayerId)
EgtSetInfo( nSplitId, WIN_SPLIT_STARTINTERS, { nOther, nCrv})
else
-- se il parametro non è intero allora l'intersezione coinvolge una sola curva
local nCrv = vOutlineCrvs[ floor( dParCrvS) + 1]
EgtSetInfo( nSplitId, WIN_SPLIT_STARTINTERS, { nCrv})
end
-- end
local dParCrvE = EgtCurveParamAtPoint( nCompo, ptE)
if abs( dParCrvE - ceil( dParCrvE)) < GEO.EPS_SMALL then
local nCrv = vOutlineCrvs[ ceil( dParCrvE) + 1]
local nOther = EgtGetPrev( nCrv) or EgtGetLastInGroup( nOutlineLayerId)
EgtSetInfo( nSplitId, WIN_SPLIT_ENDINTERS, { nOther, nCrv})
elseif abs( dParCrvE - floor( dParCrvE)) < GEO.EPS_SMALL then
local nCrv = vOutlineCrvs[ floor( dParCrvE) + 1]
local nOther = EgtGetPrev( nCrv) or EgtGetLastInGroup( nOutlineLayerId)
EgtSetInfo( nSplitId, WIN_SPLIT_ENDINTERS, { nOther, nCrv})
else
local nCrv = vOutlineCrvs[ floor( dParCrvE) + 1]
EgtSetInfo( nSplitId, WIN_SPLIT_ENDINTERS, { nCrv})
end
end
----------------------------------------------------------------------------------
-- funzione che restituisce il bordo delle due regioni definite da uno split
local function GetBorderRegions( nSplitId, nCompo, nAreaId)
-- taglio il bordo in due in corrispondenza dello split
local nCrv1 = EgtCopyGlob( nCompo, nAreaId)
local nCrv2 = EgtCopyGlob( nCompo, nAreaId)
local dPar1 = EgtCurveParamAtPoint( nCompo, EgtSP( nSplitId), 100 * GEO.EPS_SMALL)
local dPar2 = EgtCurveParamAtPoint( nCompo, EgtEP( nSplitId), 100 * GEO.EPS_SMALL)
EgtTrimCurveStartEndAtParam( nCrv1, dPar2, dPar1)
EgtTrimCurveStartEndAtParam( nCrv2, dPar1, dPar2)
-- aggiungo la curva di split al bordo per chiuderlo orientandola opportunamente
local nSplitId1 = EgtCopyGlob( nSplitId, nAreaId)
if AreSamePointApprox( EgtSP( nSplitId1), EgtSP( nCrv1)) then
EgtInvertCurve( nSplitId1)
end
EgtAddCurveCompoCurve( nCrv1, nSplitId1)
local _, dParE1 = EgtCurveDomain( nCrv1)
EgtCurveCompoSetTempProp( nCrv1, dParE1 - 1, nSplitId)
local nSplitId2 = EgtCopyGlob( nSplitId, nAreaId)
if AreSamePointApprox( EgtSP( nSplitId2), EgtSP( nCrv2)) then
EgtInvertCurve( nSplitId2)
end
EgtAddCurveCompoCurve( nCrv2, nSplitId2)
local _, dParE2 = EgtCurveDomain( nCrv2)
EgtCurveCompoSetTempProp( nCrv2, dParE2 - 1, nSplitId)
return nCrv1, nCrv2
end
----------------------------------------------------------------------------------
-- funzione che crea le aree generate da una sequenza di curve di split
local function CreateAreasFromSplits( nAreaId, vSplitCrvs)
local nGrpTmp = EgtGroup( nAreaId)
-- creo la curva composita dell'outline
local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_AREAOUTLINE)
local vOutlineCrvs = EgtGetAllInGroup( nOutlineLayerId)
local nCompo = EgtCurveCompo( nGrpTmp, vOutlineCrvs, false)
for i = 1, #vOutlineCrvs do
EgtCurveCompoSetTempProp( nCompo, i - 1, vOutlineCrvs[i])
end
-- creo le curve associate ad ogni regione degli split
local vBorders = {}
local nCompoRef = nCompo
for i = 1, #vSplitCrvs do
-- aggiusto lo split per averlo a filo con l'outline
AdjustSplitCurve( vSplitCrvs[i], nCompo, vOutlineCrvs, nOutlineLayerId)
-- calcolo i bordi delle due regioni definite dallo split
local nCrv1, nCrv2 = GetBorderRegions( vSplitCrvs[i], nCompoRef, nGrpTmp)
table.insert( vBorders, nCrv1)
-- il secondo bordo è quello da suddividere con lo split successivo ( se esiste)
nCompoRef = nCrv2
if i == #vSplitCrvs then
table.insert( vBorders, nCrv2)
end
end
-- creo le sottoaree a partire dai contorni
local vAreas = {}
for i = 1, #vBorders do
-- creo area
local nSplitAreaId = EgtGroup( nAreaId)
EgtSetName( nSplitAreaId , WIN_AREA .. tostring( i))
EgtSetInfo( nSplitAreaId, WIN_AREATYPE, WIN_AREATYPES.NULL)
vAreas[i] = nSplitAreaId
-- creo outline con la curva di bordo
local nOutlineLayerId = EgtGroup( nSplitAreaId)
EgtSetName( nOutlineLayerId, WIN_AREAOUTLINE)
EgtRelocateGlob( vBorders[i], nOutlineLayerId)
local vOrigCrvs = EgtCurveCompoGetTempProp( vBorders[i])
local nFirst, nCnt = EgtExplodeCurveCompo( vBorders[i])
-- assegno nome e info a tutte le curve di bordo a partire dalla curva da cui derviano ( salvata nella temp prop della curva)
for j = 0, nCnt - 1 do
-- assegno le info di child e source
EgtSetInfo( nFirst + j, WIN_SOU, vOrigCrvs[j+1])
AddInfo( vOrigCrvs[j+1], WIN_CHILD, nFirst + j)
-- assengo il nome : se deriva da outline lo copio, se deriva da split lo scelgo in base all'orientamento
if EgtGetName( vOrigCrvs[j+1]) == WIN_SPLIT then
SetSplitName( nFirst + j)
else
EgtSetName( nFirst + j, EgtGetName( vOrigCrvs[j+1]))
end
end
-- riordino le curve dell'outline per avere bottom come primo
local nCrvId = EgtGetFirstInGroup( nOutlineLayerId)
while EgtGetName( nCrvId) ~= WIN_BOTTOM do
EgtRelocate( nCrvId, nOutlineLayerId)
nCrvId = EgtGetFirstInGroup( nOutlineLayerId)
end
end
EgtErase( nGrpTmp)
return vAreas
end
----------------------------------------------------------------------------------
local function CalcSplitCurves( nLayerId, b3OutlineLayer, b3Limit, nSplitType, nMeasureType, PositionList)
local vSplitCurves = {}
local nProportion = 0
if nMeasureType == WIN_MEASURE.PROPORTIONAL then
for i = 1, #PositionList do
nProportion = nProportion + PositionList[i]
end
end
local dCurrPosition = 0
for i = 1, #PositionList do
-- calcolo la posizione corrente
dCurrPosition = dCurrPosition + PositionList[i]
local dCalcPosition
local nSplitCrv
if nSplitType == WIN_SPLITORIENTATION.VERTICAL then
-- aree ordinate da sx a dx
if nMeasureType == WIN_MEASURE.ABSOLUT then
dCalcPosition = dCurrPosition
elseif nMeasureType == WIN_MEASURE.PROPORTIONAL then
dCalcPosition = b3OutlineLayer:getDimX() * dCurrPosition / nProportion
elseif nMeasureType == WIN_MEASURE.PERCENTAGE then
dCalcPosition = b3OutlineLayer:getDimX() * dCurrPosition
end
-- creo la linea se rientra nella regione limite
local dX = b3OutlineLayer:getMin():getX() + dCalcPosition
if dX > b3Limit:getMin():getX() + GEO.EPS_SMALL and dX < b3Limit:getMax():getX() - GEO.EPS_SMALL then
nSplitCrv = EgtLinePVL( nLayerId, b3OutlineLayer:getMin() + X_AX() * dCalcPosition, Y_AX(), b3OutlineLayer:getDimY())
end
elseif nSplitType == WIN_SPLITORIENTATION.HORIZONTAL then
-- aree ordinate dall'alto al basso
if nMeasureType == WIN_MEASURE.ABSOLUT then
dCalcPosition = b3OutlineLayer:getDimY() - dCurrPosition
elseif nMeasureType == WIN_MEASURE.PROPORTIONAL then
dCalcPosition = b3OutlineLayer:getDimY() * ( 1 - dCurrPosition / nProportion)
elseif nMeasureType == WIN_MEASURE.PERCENTAGE then
dCalcPosition = b3OutlineLayer:getDimY() * ( 1 - dCurrPosition)
end
-- creo la linea se rientra nella regione limite
local dY = b3OutlineLayer:getMin():getY() + dCalcPosition
if dY > b3Limit:getMin():getY() + GEO.EPS_SMALL and dY < b3Limit:getMax():getY() - GEO.EPS_SMALL then
nSplitCrv = EgtLinePVL( nLayerId, b3OutlineLayer:getMin() + Y_AX() * dCalcPosition, X_AX(), b3OutlineLayer:getDimX())
end
end
if nSplitCrv then
EgtSetName( nSplitCrv, WIN_SPLIT)
table.insert( vSplitCurves, nSplitCrv)
end
end
return vSplitCurves
end
----------------------------------------------------------------------------------
-- funzione che crea tagli split multipli
function WinCreate.AddSplits( nParentAreaId, nSplitType, nMeasureType, PositionList, bFrench, nAreaNbr)
-- se area ha già sottoarea errore
if EgtGetFirstNameInGroup( nParentAreaId, WIN_AREA .. '*') then
return
end
-- creo area di split
local nAreaId = EgtGroup( nParentAreaId)
EgtSetInfo( nAreaId, WIN_AREATYPE, WIN_AREATYPES.SPLIT)
EgtSetName( nAreaId, WIN_AREA .. '(' .. WIN_SPLIT .. ')')
if nAreaNbr then
EgtSetInfo( nAreaId, WIN_AREA_NBR, nAreaNbr)
end
-- copio il contorno dall'area parent e setto opportune corrispondenze sou/child
local nOutlineLayerId = CopyParentOutline( nAreaId, nParentAreaId)
local b3OutlineLayer = EgtGetBBox( nOutlineLayerId, GDB_BB.STANDARD)
-- creo layer per split
local nSplitLayerId = EgtGroup( nAreaId)
EgtSetName( nSplitLayerId, WIN_BASESPLIT)
-- verifico se va impostato il tipo french
if bFrench then
EgtSetInfo( nSplitLayerId, WIN_SPLITTYPE, WIN_SPLITTYPES.FRENCH)
end
-- creo le curve di split
local vSplitCurves = CalcSplitCurves( nSplitLayerId, b3OutlineLayer, b3OutlineLayer, nSplitType, nMeasureType, PositionList)
-- se non ci sono curve valide cancello tutto ed esco
if #vSplitCurves == 0 then
EgtErase( nAreaId)
return
end
-- creo le aree generate dagli split
local vAreas = CreateAreasFromSplits( nAreaId, vSplitCurves)
return vAreas
end
----------------------------------------------------------------------------------
-- funzione che crea tagli split grid
function WinCreate.AddGridSplits( nParentAreaId, nMeasureType, PositionListVert, PositionListHoriz, bStartVertical, nAreaNbr)
local AreaResult = {}
-- se area ha già sottoarea errore
if EgtGetFirstNameInGroup( nParentAreaId, WIN_AREA .. '*') then
return
end
-- creo area di split
local nAreaId = EgtGroup( nParentAreaId)
EgtSetInfo( nAreaId, WIN_AREATYPE, WIN_AREATYPES.SPLIT)
EgtSetName( nAreaId, WIN_AREA .. '(' .. WIN_SPLIT .. ')')
if nAreaNbr then
EgtSetInfo( nAreaId, WIN_AREA_NBR, nAreaNbr)
end
-- copio il contorno dall'area parent e setto opportune corrispondenze sou/child
local nOutlineLayerId = CopyParentOutline( nAreaId, nParentAreaId)
local b3OutlineLayer = EgtGetBBox( nOutlineLayerId, GDB_BB.STANDARD)
-- creo layer per split
local nSplitLayerId = EgtGroup( nAreaId)
EgtSetName( nSplitLayerId, WIN_BASESPLIT)
-- stabilisco direzione principale e secondaria
local PositionListMain, PositionListOther, nSplitOrientationMain, nSplitOrientationOther
if bStartVertical then
PositionListMain = PositionListVert
PositionListOther = PositionListHoriz
nSplitOrientationMain = WIN_SPLITORIENTATION.VERTICAL
nSplitOrientationOther = WIN_SPLITORIENTATION.HORIZONTAL
else
PositionListMain = PositionListHoriz
PositionListOther = PositionListVert
nSplitOrientationMain = WIN_SPLITORIENTATION.HORIZONTAL
nSplitOrientationOther = WIN_SPLITORIENTATION.VERTICAL
end
-- calcolo la suddivisione nella direzione principale
local vMainSplit = CalcSplitCurves( nSplitLayerId, b3OutlineLayer, b3OutlineLayer, nSplitOrientationMain, nMeasureType, PositionListMain)
local vMainAreas = CreateAreasFromSplits( nAreaId, vMainSplit)
-- per ogni area della direzione principale calcolo la suddivisione nella direzione secondaria
for i = 1, #vMainAreas do
-- recupero outline per calcolare il limite delle curve di split
local nAreaOutlineLayerId = EgtGetFirstNameInGroup( vMainAreas[i], WIN_AREAOUTLINE)
local b3Limit = EgtGetBBox( nAreaOutlineLayerId, GDB_BB.STANDARD)
-- calcolo gli split nella direzione secondaria
local vOtherSplit = CalcSplitCurves( nSplitLayerId, b3OutlineLayer, b3Limit, nSplitOrientationOther, nMeasureType, PositionListOther)
if #vOtherSplit > 0 then
local vNewAreas = CreateAreasFromSplits( vMainAreas[i], vOtherSplit)
AreaResult = EgtJoinTables( AreaResult, vNewAreas)
end
end
-- sposto le aree secondarie nell'area di split e le rinomino
for i = 1, #AreaResult do
EgtRelocateGlob( AreaResult[i], nAreaId)
EgtSetName( AreaResult[i], WIN_AREA .. EgtNumToString( i))
end
-- le aree dello split principale diventano aree virtuali ausiliarie per i conti
for i = 1, #vMainAreas do
EgtSetName( vMainAreas[i], WIN_VIRTUAL_AREA)
end
return AreaResult
end
----------------------------------------------------------------------------------
---------------------------------- BOTTOMRAIL ------------------------------------
----------------------------------------------------------------------------------
-- funzione che aggiunge uno zoccolo
function WinCreate.AddBottomRail( nAreaId, nNbr)
local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i')
if nAreaType == WIN_AREATYPES.FRAME or nAreaType == WIN_AREATYPES.SASH then
EgtSetInfo( nAreaId, WIN_BOTTOMRAIL, nNbr)
end
end
----------------------------------------------------------------------------------
---------------------------------- SOGLIA ------------------------------------
----------------------------------------------------------------------------------
-- funzione che aggiunge la soglia
function WinCreate.AddThreshold( nAreaId, sThresholdProfile)
local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i')
if nAreaType == WIN_AREATYPES.FRAME then
EgtSetInfo( nAreaId, WIN_THRESHOLD_PROFILE, sThresholdProfile)
end
end
----------------------------------------------------------------------------------
---------------------------------- FERRAMENTA ------------------------------------
----------------------------------------------------------------------------------
function WinCreate.AddHardware( nFrameId, sFavourite, sHandle)
EgtSetInfo( nFrameId, WIN_HDW_FAVOURITE, sFavourite)
EgtSetInfo( nFrameId, WIN_HDW_HANDLE, sHandle)
end
---------------------------------------------------------------------
return WinCreate