Files
egwwindowlua/Profiles/WinLib/WinCalculate.lua
T
2024-05-21 10:25:50 +02:00

2079 lines
96 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')
local bCalcSolid = false
function WinCalculate.GetCalcSolid()
return bCalcSolid
end
function WinCalculate.SetCalcSolid( bValue)
bCalcSolid = bValue
end
---------------------------------------------------------------------
-- funzione che dato un gruppo contenente curve ordinate che creano una curva chiusa,
-- ne estende/taglia i contorni per ottenere una curva chiusa continua
local function TrimAndOrientOrderedCurveLayer( nLayerId)
local IntersCurveList = {}
local LastCurveInters
local ptInters
local nCurveId = EgtGetFirstInGroup( nLayerId)
-- ciclo sui segmenti per ottenere lista intersezioni
while nCurveId do
local nPrevId = EgtGetPrev( nCurveId)
if not nPrevId then
nPrevId = EgtGetLastInGroup( nLayerId)
end
ptInters = EgtIP( nCurveId, nPrevId, EgtSP( nCurveId))
if not ptInters then
local dDist = dist( EgtEP( nPrevId), EgtSP( nCurveId))
EgtExtendCurveStartByLen( nCurveId, 2 * dDist)
EgtExtendCurveEndByLen( nCurveId, 2 * dDist)
EgtExtendCurveStartByLen( nPrevId, 2 * dDist)
EgtExtendCurveEndByLen( nPrevId, 2 * dDist)
ptInters = EgtIP( nCurveId, nPrevId, EgtSP( nCurveId))
end
if LastCurveInters then
LastCurveInters.EndInters = Point3d( ptInters)
end
local NewCurveInters = { CurveId = nCurveId, StartInters = Point3d( ptInters)}
table.insert( IntersCurveList, NewCurveInters)
LastCurveInters = NewCurveInters
nCurveId = EgtGetNext( nCurveId)
end
IntersCurveList[#IntersCurveList].EndInters = IntersCurveList[1].StartInters
-- ciclo per tagliare ed orientare
for nIntersCurveIndex = 1, #IntersCurveList do
local CurveInters = IntersCurveList[nIntersCurveIndex]
local dStartParam = EgtCurveParamAtPoint( CurveInters.CurveId, CurveInters.StartInters)
local dEndParam = EgtCurveParamAtPoint( CurveInters.CurveId, CurveInters.EndInters)
EgtTrimCurveStartEndAtParam( CurveInters.CurveId, min( dStartParam, dEndParam), max( dStartParam, dEndParam))
if dStartParam > dEndParam then
EgtInvertCurve( CurveInters.CurveId)
end
end
end
---------------------------------------------------------------------
local function TrimSplitWithOutline( nSplitId)
-- lo taglio con outline
local nStartIntersId = EgtGetInfo( nSplitId, WIN_SPLIT_STARTINTERS, 'i')
local nOutlineId = EgtGetInfo( nStartIntersId, WIN_CHILD, '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_CHILD, 'i')
local ptEndInters = EgtIP( nSplitId, nOutlineId, EgtSP( nSplitId))
local dEndInters = EgtCurveParamAtPoint( nSplitId, ptEndInters)
EgtTrimCurveEndAtParam( nSplitId, dEndInters)
end
---------------------------------------------------------------------
-- funzione che data una curva di outline restituisce l'id del suo profilo
local function GetOutlineProfileId( nOutlineId, bUseBottomRail)
-- ciclo fino a trovare il primo parent che abbia un AreaType definito ( frame o sash)
local nCurrId = nOutlineId
local nAreaType = WIN_AREATYPES.NULL
while nCurrId and ( nAreaType == WIN_AREATYPES.SPLIT or nAreaType == WIN_AREATYPES.NULL) do
nCurrId = EgtGetParent( nCurrId)
nAreaType = EgtGetInfo( nCurrId 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)
-- verifico se bottom rail
if bUseBottomRail then
local nOutlineLay = EgtGetParent( nOutlineId)
local bBottomRail = EgtGetInfo( nOutlineLay, WIN_BOTTOMRAIL, 'b') or false
local sOutlineName = EgtGetName( nOutlineId)
if sOutlineName == WIN_BOTTOM and bBottomRail then
-- allora imposto profilo BottomRail
sProfileName = WIN_RAIL_BOTTOM
end
end
-- recupero il profilo
return EgtGetFirstNameInGroup( nLayerId, sProfileName)
end
---------------------------------------------------------------------
----------------- CALCOLO DEI PROFILI ------------------------------
---------------------------------------------------------------------
-- funzione che verifica se ci sono Sash dopo
local function VerifyChildArea( nAreaId)
local nChildAreaId = EgtGetFirstNameInGroup( nAreaId, WIN_AREAASTERISK)
local nChildAreaType
if nChildAreaId then
nChildAreaType = EgtGetInfo( nChildAreaId, WIN_AREATYPE, 'i')
if nChildAreaType == WIN_AREATYPES.SASH then
return true
end
if VerifyChildArea( nChildAreaId) then return true end
end
while nChildAreaId and nChildAreaType ~= WIN_AREATYPES.SASH do
nChildAreaId = EgtGetNextName( nChildAreaId, WIN_AREAASTERISK)
if nChildAreaId then
nChildAreaType = EgtGetInfo( nChildAreaId, WIN_AREATYPE, 'i')
if nChildAreaType == WIN_AREATYPES.SASH then
return true
end
end
if VerifyChildArea( nChildAreaId) then return true end
end
return false
end
---------------------------------------------------------------------
-- funzione che identifica il tipo di split ( mullion, french, null)
local function GetSplitType( nSplitLayerId)
local nSplitType = EgtGetInfo( nSplitLayerId, WIN_SPLITTYPE, 'i')
-- se non ha split impostato verifico se ha sash prima o dopo per capire se è implicitamente di tipo mullion
if not nSplitType then
local nParentAreaId = EgtGetParent( nSplitLayerId)
local nParentAreaType = EgtGetInfo( nParentAreaId, WIN_AREATYPE, 'i') or WIN_AREATYPES.NULL
while nParentAreaId and nParentAreaType ~= WIN_AREATYPES.SASH do
nParentAreaId = EgtGetParent( nParentAreaId)
nParentAreaType = EgtGetInfo( nParentAreaId or GDB_ID.NULL, WIN_AREATYPE, 'i') or WIN_AREATYPES.NULL
end
-- devi confrontare il type con sash
if not nParentAreaId or nParentAreaType ~= WIN_AREATYPES.SASH then
-- verifico se ci sono Sash dopo
local nAreaId = EgtGetParent( nSplitLayerId)
local bSashAfter = VerifyChildArea( nAreaId)
-- se ci sono assegno tipo di profilo a mullion
if bSashAfter then
EgtSetInfo( nSplitLayerId, WIN_SPLITTYPE, WIN_SPLITTYPES.MULLION)
nSplitType = WIN_SPLITTYPES.MULLION
end
end
end
if not nSplitType then
-- EgtSetInfo( nSplitLayerId, WIN_SPLITTYPE, WIN_SPLITTYPES.NULL)
nSplitType = WIN_SPLITTYPES.NULL
end
return nSplitType
end
---------------------------------------------------------------------
-- funzione che imposta i tipi di profilo per gli split
local function CalcSplitProfileType( nSplitLayerId, nAreaId)
local nSplitId = EgtGetFirstInGroup( nSplitLayerId)
-- verifico il tipo di split
local nSplitType = GetSplitType( nSplitLayerId)
if nSplitType == WIN_SPLITTYPES.MULLION then
-- verifico direzione per dare nome
local vtMedia = ( ( EgtEV( nSplitId) - EgtSV( nSplitId)) / 2)
if not vtMedia:normalize() then
vtMedia = EgtSV( nSplitId)
end
if abs( vtMedia:getX()) > abs( vtMedia:getY()) then
EgtSetInfo( nSplitId, WIN_PROFILETYPE, WIN_SASH_HORIZONTAL)
else
EgtSetInfo( nSplitId, WIN_PROFILETYPE, WIN_SASH_VERTICAL)
end
elseif nSplitType == WIN_SPLITTYPES.NULL then
-- verifico se interno ad anta o a frame
local nParentAreaId = nAreaId
local nParentAreaType = EgtGetInfo( nParentAreaId, WIN_AREATYPE, 'i')
while nParentAreaType ~= WIN_AREATYPES.FRAME and nParentAreaType ~= WIN_AREATYPES.SASH do
nParentAreaId = EgtGetParent( nParentAreaId)
nParentAreaType = EgtGetInfo( nParentAreaId, WIN_AREATYPE, 'i')
end
-- assegno tipo di profilo allo split
if nParentAreaType == WIN_AREATYPES.SASH then
EgtSetInfo( nSplitId, WIN_PROFILETYPE, WIN_SASH_SPLIT)
else
-- altrimenti vetro fisso
EgtSetInfo( nSplitId, WIN_PROFILETYPE, WIN_FRAME_SPLIT)
end
end
-- se split di tipo french non ha profilo assegnato perchè non ha un pezzo associato
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
-- assegno il profilo alle curve di outline
local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_AREAOUTLINE)
local nOutlineId = EgtGetFirstInGroup( nOutlineLayerId)
while nOutlineId do
-- recupero tipo del child
local nChildId = nOutlineId
local nChildAreaId
local nChildType
-- ciclo fino a trovare un child che non sia uno split
repeat
nChildId = EgtGetInfo( nChildId, WIN_CHILD)
nChildAreaId = EgtGetParent( EgtGetParent( nChildId))
nChildType = EgtGetInfo( nChildAreaId, WIN_AREATYPE, 'i')
until not nChildId or ( nChildType ~= WIN_AREATYPES.SPLIT and nChildType ~= WIN_AREATYPES.NULL)
local sName = EgtGetName( nOutlineId)
if nChildType == WIN_AREATYPES.SASH then
if sName == WIN_BOTTOM then
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SASH_BOTTOM)
else
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SASH_TOP)
end
elseif nChildType == WIN_AREATYPES.FILL then
if sName == WIN_BOTTOM then
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_FIXED_BOTTOM)
else
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_FIXED_TOP)
end
end
nOutlineId = EgtGetNext( nOutlineId)
end
-- verifico se ci sono split e ne assegno il profilo
local nSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_BASESPLIT)
if nSplitLayerId then
CalcSplitProfileType( nSplitLayerId, nAreaId)
end
-- SPLIT
elseif nAreaType == WIN_AREATYPES.SPLIT or nAreaType == WIN_AREATYPES.NULL then
-- verifico se ci sono split e ne assegno il profilo
local nSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_BASESPLIT)
if nSplitLayerId then
CalcSplitProfileType( nSplitLayerId, nAreaId)
end
-- SASH
elseif nAreaType == WIN_AREATYPES.SASH then
-- verifico se e' di tipo battente ricevente
local nSashType = EgtGetInfo( nAreaId, WIN_SASHTYPE, 'i')
if nSashType and nSashType ~= WIN_SASHTYPES.NULL then
-- imposto profili sash
local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_AREAOUTLINE)
local nOutlineId = EgtGetFirstInGroup( nOutlineLayerId)
while nOutlineId do
-- faccio sou due volte per trovare il tipo dell'outline originale da cui deriva
local nSouId = EgtGetInfo( nOutlineId, WIN_SOU, 'i')
nSouId = EgtGetInfo( nSouId, WIN_SOU, 'i')
local sSouName = EgtGetName( nSouId)
if sSouName == WIN_SPLIT then
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)
end
else
local sName = EgtGetName( nOutlineId)
if sName ~= WIN_BOTTOM then
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_FRAME_TOP)
else
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_FRAME_BOTTOM)
end
end
nOutlineId = EgtGetNext( nOutlineId)
end
else
-- imposto profili sash
local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_AREAOUTLINE)
local nOutlineId = EgtGetFirstInGroup( nOutlineLayerId)
while nOutlineId do
local sName = EgtGetName( nOutlineId)
if sName ~= WIN_BOTTOM then
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_FRAME_TOP)
else
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_FRAME_BOTTOM)
end
nOutlineId = EgtGetNext( nOutlineId)
end
end
-- verifico se ci sono split
local nSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_BASESPLIT)
if nSplitLayerId then
-- assegno tipo di profilo
local nSplitId = EgtGetFirstInGroup( nSplitLayerId)
EgtSetInfo( nSplitId, WIN_PROFILETYPE, WIN_SASH_SPLIT)
end
end
end
---------------------------------------------------------------------
--------------------- CALCOLO OUTLINE -------------------------------
---------------------------------------------------------------------
-- 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 lo copio
local nAreaOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_AREAOUTLINE)
local nOutlineLayerId = EgtCopyGlob( nAreaOutlineLayerId, nAreaId)
EgtSetName( nOutlineLayerId, WIN_OUTLINE)
-- FRAME
if nAreaType == WIN_AREATYPES.FRAME then
EgtSetStatus( nOutlineLayerId, GDB_ST.OFF)
-- sistemo le info
local nAreaOutlineId = EgtGetFirstInGroup( nAreaOutlineLayerId)
local nOutlineId = EgtGetFirstInGroup( nOutlineLayerId)
while nAreaOutlineId do
EgtSetInfo( nAreaOutlineId, WIN_COPY, nOutlineId)
EgtRemoveInfo( nOutlineId, WIN_SOU)
nAreaOutlineId = EgtGetNext( nAreaOutlineId)
nOutlineId = EgtGetNext( nOutlineId)
end
-- se presente, copio split
local nBaseSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_BASESPLIT)
if nBaseSplitLayerId then
local nSplitLayerId = EgtCopy( nBaseSplitLayerId, nAreaId)
EgtSetName( nSplitLayerId, WIN_SPLIT)
EgtSetStatus( nSplitLayerId, GDB_ST.OFF)
local nBaseSplitId = EgtGetFirstInGroup( nBaseSplitLayerId)
local nSplitId = EgtGetFirstInGroup( nSplitLayerId)
EgtSetInfo( nBaseSplitId, WIN_COPY, nSplitId)
EgtRemoveInfo( nSplitId, WIN_SOU)
end
-- SPLIT
elseif nAreaType == WIN_AREATYPES.SPLIT or nAreaType == WIN_AREATYPES.NULL then
-- svuoto il gruppo
EgtEmptyGroup( nOutlineLayerId)
EgtSetStatus( nOutlineLayerId, GDB_ST.OFF)
-- recupero outline di livello precedente e lo copio pezzo per pezzo
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')
local nOutlineId = EgtCopy( nCopyId, nOutlineLayerId)
-- se deriva da split devo aggiornare il nome
local sSouName = EgtGetName( nSouId)
if sSouName == WIN_SPLIT then
local sBaseName = EgtGetName( nBaseOutlineId)
EgtSetName( nOutlineId, sBaseName)
EgtSetStatus( nOutlineId, GDB_ST.OFF)
end
-- sistemo le info
EgtSetInfo( nOutlineId, WIN_SOU, nBaseOutlineId)
EgtSetInfo( nBaseOutlineId, WIN_COPY, nOutlineId)
EgtRemoveInfo( nOutlineId, WIN_CHILD)
EgtRemoveInfo( nOutlineId, WIN_COPY)
nBaseOutlineId = EgtGetNext( nBaseOutlineId)
end
-- taglio tutti i contorni
TrimAndOrientOrderedCurveLayer( nOutlineLayerId)
-- se presente, copio split
local nBaseSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_BASESPLIT)
if nBaseSplitLayerId then
local nSplitLayerId = EgtCopy( nBaseSplitLayerId, nAreaId)
EgtSetName( nSplitLayerId, WIN_SPLIT)
EgtSetStatus( nSplitLayerId, GDB_ST.OFF)
local nBaseSplitId = EgtGetFirstInGroup( nBaseSplitLayerId)
local nSplitId = EgtGetFirstInGroup( nSplitLayerId)
EgtSetInfo( nBaseSplitId, WIN_COPY, nSplitId)
EgtRemoveInfo( nSplitId, WIN_SOU)
-- lo taglio con outline
TrimSplitWithOutline( nSplitId)
-- se split interno ad anta
local nParentAreaId = EgtGetParent( nAreaId)
local nParentAreaType = EgtGetInfo( nParentAreaId, WIN_AREATYPE, 'i')
while nParentAreaType ~= WIN_AREATYPES.FRAME and nParentAreaType ~= WIN_AREATYPES.SASH do
nParentAreaId = EgtGetParent( nParentAreaId)
nParentAreaType = EgtGetInfo( nParentAreaId, WIN_AREATYPE, 'i')
end
if nParentAreaType == WIN_AREATYPES.SASH then
-- recupero tipo di profilo
local sSplitProfile = EgtGetInfo( nSplitId, WIN_PROFILETYPE)
-- recupero profilo usato per anta
local nProfileLayerId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_PROFILE)
local nSashProfileLayerId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_SASH)
local nSashProfileId = EgtGetFirstNameInGroup( nSashProfileLayerId, sSplitProfile)
-- calcolo offset sulla z dell'anta
local dSashZOffset = EgtGetInfo( nSashProfileId, WIN_DELTA, 'd')
-- sposto Split in Z
EgtMove( nSplitId, Z_AX() * dSashZOffset)
end
end
-- SASH
elseif nAreaType == WIN_AREATYPES.SASH then
-- svuoto il gruppo
EgtEmptyGroup( nOutlineLayerId)
EgtSetStatus( nOutlineLayerId, GDB_ST.OFF)
-- recupero se anta battente ricevente
local nSashType = EgtGetInfo( nAreaId, WIN_SASHTYPE, 'i') or WIN_SASHTYPES.NULL
-- 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')
local nOutlineId = EgtCopy( nCopyId, nOutlineLayerId)
-- recupero tipo di profili anta
local sSashProfile = EgtGetInfo( nBaseOutlineId, WIN_PROFILETYPE)
-- recupero profilo usato per anta
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
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_PROFILETYPE, sSashProfile)
EgtSetInfo( nOutlineId, WIN_COPY, nBaseOutlineId)
-- verifico se outline e' segmento battente o ricevente che quindi deriva da split
local bOnFrenchSplit = false
if nSashType ~= WIN_SASHTYPES.NULL then
-- faccio sou due volte per trovare il tipo dell'outline originale da cui deriva
local nSouId = EgtGetInfo( nBaseOutlineId, WIN_SOU, 'i')
nSouId = EgtGetInfo( nSouId, WIN_SOU, 'i')
local sSouName = EgtGetName( nSouId)
-- se deriva da split è segmento battente/ricevente
if sSouName == WIN_SPLIT then
bOnFrenchSplit = true
end
end
-- se outline non è segmento battente o ricevente ( che quindi deriva da split) necessita di offset
if not bOnFrenchSplit then
-- 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 nFrameProfileLayerId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_FRAME)
local nFrameProfileId = EgtGetFirstNameInGroup( nFrameProfileLayerId, sFrameProfile)
-- recupero le relative origini
local nFrameFrameProfileId = EgtGetFirstNameInGroup( nFrameProfileId, WIN_SECTIONFRAME)
local frFrameProfileId = EgtFR( nFrameFrameProfileId)
-- calcolo il box del riferimento del profilo del frame
local nRefFrameProfileId = EgtGetFirstNameInGroup( nFrameProfileId, WIN_REF)
local b3FrameProfile = EgtGetBBoxRef( nRefFrameProfileId, GDB_BB.STANDARD, frFrameProfileId)
-- calcolo offset perpendicolare
local dOverlap = EgtGetInfo( nSashProfileId, WIN_OVERLAP, 'd')
local dSashPerpOffset = abs( b3FrameProfile:getMin():getX()) - dOverlap
-- faccio offset
EgtOffsetCurve( nOutlineId, - dSashPerpOffset)
end
nBaseOutlineId = EgtGetNext( nBaseOutlineId)
end
-- accorcio gli offset
TrimAndOrientOrderedCurveLayer( nOutlineLayerId)
-- se presente, copio split
local nBaseSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_BASESPLIT)
if nBaseSplitLayerId then
local nBaseSplitId = EgtGetFirstInGroup( nBaseSplitLayerId)
-- creo copia
local nSplitLayerId = EgtCopy( nBaseSplitLayerId, nAreaId)
EgtSetName( nSplitLayerId, WIN_SPLIT)
EgtSetStatus( nSplitLayerId, GDB_ST.OFF)
local nSplitId = EgtGetFirstInGroup( nSplitLayerId)
EgtSetInfo( nBaseSplitId, WIN_COPY, nSplitId)
EgtRemoveInfo( nSplitId, WIN_SOU)
-- la taglio con outline
TrimSplitWithOutline( nSplitId)
-- recupero profilo usato per anta
local sSplitProfile = EgtGetInfo( nBaseSplitId, WIN_PROFILETYPE)
local nProfileLayerId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_PROFILE)
local nSplitProfileLayerId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_SASH)
local nSplitProfileId = EgtGetFirstNameInGroup( nSplitProfileLayerId, sSplitProfile)
-- calcolo offset sulla z dell'anta
local dSplitZOffset = EgtGetInfo( nSplitProfileId, WIN_DELTA, 'd')
-- sposto split in Z
EgtMove( nSplitId, Z_AX() * dSplitZOffset)
end
-- FILL
elseif nAreaType == WIN_AREATYPES.FILL then
-- svuoto il gruppo
EgtEmptyGroup( nOutlineLayerId)
EgtSetStatus( nOutlineLayerId, GDB_ST.OFF)
-- ciclo su BaseArea riempimento
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)
local nCopyId = EgtGetInfo( nSouId, WIN_COPY)
local nOutlineId = EgtCopy( nCopyId, nOutlineLayerId)
-- sistemo le info
EgtSetInfo( nBaseOutlineId, WIN_CHILD, nOutlineId)
-- recupero a ritroso il profilo dell'elemento su cui poggia ( anta, split o frame)
local nParentBaseOutlineId = nSouId
local sParentProfile = EgtGetInfo( nParentBaseOutlineId, WIN_PROFILETYPE)
while not sParentProfile and nParentBaseOutlineId do
nParentBaseOutlineId = EgtGetInfo( nParentBaseOutlineId, WIN_SOU , 'i')
sParentProfile = EgtGetInfo( nParentBaseOutlineId or GDB_ID.NULL, WIN_PROFILETYPE)
end
local nParentOutlineId = EgtGetInfo( nParentBaseOutlineId, WIN_COPY)
local nParentProfileId = GetOutlineProfileId( nParentOutlineId, true)
-- recupero le relative origini
local nFrameParentProfileId = EgtGetFirstNameInGroup( nParentProfileId, WIN_SECTIONFRAME)
local frParentProfileId = EgtFR(nFrameParentProfileId)
-- calcolo il box del riferimento del profilo del frame
local nRefParentProfileId = EgtGetFirstNameInGroup( nParentProfileId, WIN_REF)
local b3FrameProfile = EgtGetBBoxRef( nRefParentProfileId, GDB_BB.STANDARD, frParentProfileId)
-- calcolo offset perpendicolare e sulla z dell'anta
local dOverlap = EgtGetInfo( nParentProfileId, WIN_FILLOVERLAP, 'd')
local dFillPerpOffset = abs( b3FrameProfile:getMin():getX()) - dOverlap
local dFillZOffset = EgtGetInfo( nParentProfileId, WIN_FILLDELTA, 'd')
-- faccio offset e muovo in z
EgtOffsetCurve( nOutlineId, - dFillPerpOffset)
EgtMove( nOutlineId, Z_AX() * dFillZOffset)
nBaseOutlineId = EgtGetNext( nBaseOutlineId)
end
-- accorcio gli offset
TrimAndOrientOrderedCurveLayer( nOutlineLayerId)
end
-- disegno area di selezione per programma
local nSelectionLayerId = EgtGroup( nAreaId)
EgtSetName( nSelectionLayerId, WIN_SELECTION)
EgtSetStatus( nSelectionLayerId, GDB_ST.OFF)
local OutlineList = {}
local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE)
local nOutlineId = EgtGetFirstInGroup(nOutlineLayerId)
while nOutlineId do
table.insert( OutlineList, nOutlineId)
nOutlineId = EgtGetNext(nOutlineId)
end
local nCompoId = EgtCurveCompo( nSelectionLayerId, OutlineList, false)
local nSelectionArea = EgtSurfFlatRegion( nSelectionLayerId, nCompoId)
EgtSetColor( nSelectionArea, 'YELLOW')
EgtSetAlpha( nSelectionArea, 10)
EgtMove( nSelectionArea, 10 * Z_AX())
EgtErase( nCompoId)
end
---------------------------------------------------------------------
---------------------- CALCOLO PEZZI ------------------------------
---------------------------------------------------------------------
-- 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 nOutlineId = EgtGetFirstInGroup( nOutlineLayerId)
while nOutlineId do
EgtCopy( nOutlineId, nGeoLayerId)
nOutlineId = EgtGetNext( nOutlineId)
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_GEOWIDTH, dGlassThickness)
return nGeoLayerId
end
---------------------------------------------------------------------
-- funzione che crea il solido del Fill
local function CalcFillSolid( nPartId, nOutlineLayerId, nGeoLayerId)
-- creo layer per solido
local nSolidLayerId = EgtGroup( nPartId)
EgtSetName( nSolidLayerId, WIN_SOLID)
-- creo compo di outline
local OutlineList ={}
local nFirstSideId = EgtGetFirstInGroup( nOutlineLayerId)
local nOutlineId = nFirstSideId
while nOutlineId do
table.insert( OutlineList, nOutlineId)
nOutlineId = EgtGetNext( nOutlineId)
end
local nCompoOutlineId = EgtCurveCompoByChain( nSolidLayerId, OutlineList, EgtSP( nFirstSideId), false)
-- recupero spessore vetro
local dGlassThickness = EgtGetInfo( nGeoLayerId, WIN_GEOWIDTH, 'd')
local nSurfId = EgtSurfTmByRegionExtrusion( nSolidLayerId, nCompoOutlineId, Z_AX() * dGlassThickness)
EgtErase( nCompoOutlineId)
end
--------------------------------------------------------------------
-- funzione che restituisce il WIN_PRF in base al nome della curva
local function GetOutlineProfileType( nOutlineId, bBottomRail)
-- ricavo tipo dal nome
local sName = EgtGetName( nOutlineId)
local nProfileType = WIN_PRF.NULL
if bBottomRail then
nProfileType = WIN_PRF.BOTTOMRAIL
elseif sName == WIN_TOP then
nProfileType = WIN_PRF.TOP
elseif sName == WIN_BOTTOM then
nProfileType = WIN_PRF.BOTTOM
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 recupera l'outline precedente e successivo
local function GetPrevNextOutline( nProfileType, nOutlineId, nOutlineLayerId)
local nPrevOutlineId
local nNextOutlineId
if nProfileType == WIN_PRF.SPLIT then
-- se split individuo l'outline associato al base outline che lo taglia
local nPrevBaseOutlineId = EgtGetInfo( nOutlineId, WIN_SPLIT_STARTINTERS, 'i')
nPrevOutlineId = EgtGetInfo( nPrevBaseOutlineId, WIN_COPY, 'i')
local nNextBaseOutlineId = EgtGetInfo( nOutlineId, WIN_SPLIT_ENDINTERS, 'i')
nNextOutlineId = EgtGetInfo( nNextBaseOutlineId, WIN_COPY, 'i')
else
nPrevOutlineId = EgtGetPrev( nOutlineId)
if not nPrevOutlineId then
nPrevOutlineId = EgtGetLastInGroup( nOutlineLayerId)
end
nNextOutlineId = EgtGetNext( nOutlineId)
if not nNextOutlineId then
nNextOutlineId = EgtGetFirstInGroup( nOutlineLayerId)
end
end
return nPrevOutlineId, nNextOutlineId
end
---------------------------------------------------------------------
-- 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.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 restituisce il tipo di controprofilo dell'outline adiacente
local function GetProfileCtrIn( nProfileType, nPrevOutlineId, nOutlineId, nPrevProfileId)
local sPrevCtrIn = WIN_CTRIN
-- gestione particolare nel caso di split su split
if nProfileType == WIN_PRF.SPLIT then
-- verifico se il prev e' uno split
local nPrevSouId = nPrevOutlineId
local nPrevSouParentId
local sPrevSouParentId
repeat
nPrevSouId = EgtGetInfo( nPrevSouId, WIN_SOU)
if nPrevSouId then
nPrevSouParentId = EgtGetParent( nPrevSouId)
sPrevSouParentId = EgtGetName( nPrevSouParentId)
end
until not nPrevSouId or sPrevSouParentId == WIN_BASESPLIT
if nPrevSouId and sPrevSouParentId == WIN_BASESPLIT then
-- verifico da che lato sono dello split
local dOutlineDist, _, dSide = EgtPointCurveDistSide( EgtMP( nOutlineId), nPrevSouId, Z_AX())
-- recupero box dei controprofili rispetto al loro sistema di riferimento
local nSectionFrameId = EgtGetFirstNameInGroup( nPrevProfileId, WIN_SECTIONFRAME)
local frSectionFrame = EgtFR( nSectionFrameId, GDB_ID.ROOT)
local dMinDist = GEO.INFINITO
-- confronto distanze dei controprofili rispetto a distanza dell'outline per trovare il controprofilo piu' vicino
local nMinCtrInId
local nCtrInId = EgtGetFirstNameInGroup( nPrevProfileId, WIN_CTRIN .. '*')
while nCtrInId do
local b3CtrIn = EgtGetBBoxRef( nCtrInId, GDB_BB.STANDARD, frSectionFrame)
local dCtrInDist = abs( ( dSide * dOutlineDist) - b3CtrIn:getCenter():getX())
if dCtrInDist < dMinDist then
dMinDist = dCtrInDist
nMinCtrInId = nCtrInId
end
nCtrInId = EgtGetNextName( nCtrInId, WIN_CTRIN .. '*')
end
if nMinCtrInId then
sPrevCtrIn = EgtGetName( nMinCtrInId)
end
end
end
return sPrevCtrIn
end
---------------------------------------------------------------------
local function GetDeltaProfile( nProfileType, nPrevOutlineId, nOutlineId)
-- recupero il profilo dell'outline precedente
local nPrevProfileId = GetOutlineProfileId( nPrevOutlineId, nProfileType == WIN_PRF.SPLIT)
local sCtrIn = GetProfileCtrIn( nProfileType, nPrevOutlineId, nOutlineId, nPrevProfileId)
local dCPDelta = 0
local nSectionFrId = EgtGetFirstNameInGroup( nPrevProfileId, WIN_SECTIONFRAME)
local frSectionFrame = EgtFR( nSectionFrId)
local nCPId = EgtGetFirstNameInGroup( nPrevProfileId, 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
return dCPDelta
end
---------------------------------------------------------------------
-- funzione che crea le curve del geo
local function CreateFrameGeo( nOutlineId, nPrevOutlineId, nNextOutlineId, nStartPartJointType, nEndPartJointType, nProfileType, nGeoLayerId, bBottomRail)
local nCurrProfileId = GetOutlineProfileId( nOutlineId, bBottomRail)
local nCurrProfileRefId = EgtGetFirstNameInGroup( nCurrProfileId, WIN_REF)
-- calcolo spostamento della curva iniziale dovuto a posizione riferimento
local nProfileFrameId = EgtGetFirstNameInGroup( nCurrProfileId, WIN_SECTIONFRAME)
local frProfile = EgtFR( nProfileFrameId)
local b3CurrProfileFrame = EgtGetBBoxRef( nCurrProfileRefId, GDB_BB.STANDARD, frProfile)
local dCurrOffset = b3CurrProfileFrame:getMax():getX()
-- creo copie degli outline e le offsetto opportunamente
-- curva out
local nCurrCurveId = EgtCopy( nOutlineId, nGeoLayerId)
EgtOffsetCurve( nCurrCurveId, dCurrOffset)
EgtSetName( nCurrCurveId, WIN_GEO_OUT)
-- cruva in
local nCurrOffsetId = EgtCopy( nOutlineId, nGeoLayerId)
EgtOffsetCurve( nCurrOffsetId, dCurrOffset - b3CurrProfileFrame:getDimX())
EgtInvertCurve( nCurrOffsetId)
EgtSetName( nCurrOffsetId, WIN_GEO_IN)
-- curva left
local nPrevCurveId
if nStartPartJointType == WIN_PART_JNT.ANGLED then
-- calcolo la bisettrice
local vtMedia = ( ( EgtSV( nOutlineId) - EgtEV( nPrevOutlineId)) / 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( nPrevOutlineId, nGeoLayerId)
if nStartPartJointType == WIN_PART_JNT.SHORT then
local dPrevCPDelta = GetDeltaProfile( nProfileType, nPrevOutlineId, nOutlineId)
EgtOffsetCurve( nPrevCurveId, - dPrevCPDelta)
EgtSetInfo( nGeoLayerId, WIN_STARTCPDELTA, dPrevCPDelta)
end
end
EgtSetName( nPrevCurveId, WIN_GEO_LEFT)
-- curva right
local nNextCurveId
if nEndPartJointType == WIN_PART_JNT.ANGLED then
-- calcolo la bisettrice
local vtMedia = ( ( EgtSV( nNextOutlineId) - 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( nNextOutlineId, nGeoLayerId)
if nEndPartJointType == WIN_PART_JNT.SHORT then
local dNextCPDelta = GetDeltaProfile( nProfileType, nNextOutlineId, nOutlineId)
EgtOffsetCurve( nNextCurveId, - dNextCPDelta)
EgtSetInfo( nGeoLayerId, WIN_ENDCPDELTA, dNextCPDelta)
end
end
EgtSetName( nNextCurveId, WIN_GEO_RIGHT)
local dGeoWidth = b3CurrProfileFrame:getDimX()
return nCurrCurveId, nCurrOffsetId, nPrevCurveId, nNextCurveId, dGeoWidth
end
---------------------------------------------------------------------
-- funzione che calcola l'ingombro dei pezzi del telaio
local function CalcFrameGeo( nPartId, nOutlineId, nOutlineLayerId, bBottomRail)
-- creo layer per ingombro
local nGeoLayerId = EgtGroup( nPartId)
EgtSetName( nGeoLayerId, WIN_GEO)
-- ricavo tipo di profilo
local nProfileType = GetOutlineProfileType( nOutlineId, bBottomRail)
-- recupero outline precedente e successivo
local nPrevOutlineId, nNextOutlineId = GetPrevNextOutline( nProfileType, nOutlineId, nOutlineLayerId)
-- recupero il tipo di giunzioni
local nStartJointType
local nEndJointType
if nProfileType == WIN_PRF.TOP then
nStartJointType = EgtGetInfo( nOutlineLayerId, WIN_JOINT_TR, 'i')
nEndJointType = EgtGetInfo( nOutlineLayerId, WIN_JOINT_TL, 'i')
elseif nProfileType == WIN_PRF.BOTTOM then
nStartJointType = EgtGetInfo( nOutlineLayerId, WIN_JOINT_BL, 'i')
nEndJointType = EgtGetInfo( nOutlineLayerId, WIN_JOINT_BR, 'i')
elseif nProfileType == WIN_PRF.LEFT then
nStartJointType = EgtGetInfo( nOutlineLayerId, WIN_JOINT_TL, 'i')
nEndJointType = EgtGetInfo( nOutlineLayerId, WIN_JOINT_BL, 'i')
elseif nProfileType == WIN_PRF.RIGHT then
-- recupero tipo di giunzioni
nStartJointType = EgtGetInfo( nOutlineLayerId, WIN_JOINT_BR, 'i')
nEndJointType = EgtGetInfo( nOutlineLayerId, WIN_JOINT_TR, 'i')
else
-- nei casi di profilo BottomRail e Split non serve settare dei valori per StartJointType ed EndJointType perchè
-- in CalcPartJointType la loro giunzione viene settata a short
end
-- se pezzo non e' split, giunzione diversa da bisettrice ed arco a tutto sesto forzo il tipo a bisettrice
if nProfileType ~= WIN_PRF.SPLIT and nStartJointType ~= WIN_JNT.ANGLED and AreSameVectorApprox( EgtEV( nPrevOutlineId), EgtSV( nOutlineId)) then
nStartJointType = WIN_JNT.ANGLED
end
if nProfileType ~= WIN_PRF.SPLIT and nEndJointType ~= WIN_JNT.ANGLED and AreSameVectorApprox( EgtEV( nOutlineId), EgtSV( nNextOutlineId)) then
nEndJointType = WIN_JNT.ANGLED
end
-- calcolo il tipo di giunzione per la parte
local nStartPartJointType = CalcPartJointType( nProfileType, nStartJointType)
local nEndPartJointType = CalcPartJointType( nProfileType, nEndJointType)
-- salvo i valori joint su outline per disegno solido
if nProfileType ~= WIN_PRF.BOTTOMRAIL then
EgtSetInfo( nOutlineId, WIN_STARTJOINT, nStartPartJointType)
EgtSetInfo( nOutlineId, WIN_ENDJOINT, nEndPartJointType)
end
-- creo lati dell'outline
local nCurrCurveId, nCurrOffsetId, nPrevCurveId, nNextCurveId, dGeoWidth = CreateFrameGeo( nOutlineId, nPrevOutlineId, nNextOutlineId, nStartPartJointType, nEndPartJointType, nProfileType, nGeoLayerId, bBottomRail)
-- trim delle curve
-- se le curve fossero ordinate correttamente ( out-right-in-left) potresti usare la funzione TrimAndOrientOrderedCurveLayer( nGeoLayerId)
-- calcolo punti di intersezione
local ptIntersCurrPrev = EgtIP( nCurrCurveId, nPrevCurveId, EgtSP( nCurrCurveId))
if not ptIntersCurrPrev then
-- allungo per intersecare
EgtExtendCurveStartByLen( nCurrCurveId, 200)
EgtExtendCurveEndByLen( nPrevCurveId, 200)
ptIntersCurrPrev = EgtIP( nCurrCurveId, nPrevCurveId, EgtSP( nCurrCurveId))
end
local ptIntersCurrNext = EgtIP( nCurrCurveId, nNextCurveId, EgtEP( nCurrCurveId))
if not ptIntersCurrNext then
-- allungo per intersecare
EgtExtendCurveEndByLen( nCurrCurveId, 200)
EgtExtendCurveStartByLen( nNextCurveId, 200)
ptIntersCurrNext = EgtIP( nCurrCurveId, nNextCurveId, EgtEP( nCurrCurveId))
end
local ptIntersCurrOffsetPrev = EgtIP( nCurrOffsetId, nPrevCurveId, EgtEP( nCurrOffsetId))
if not ptIntersCurrOffsetPrev then
-- allungo per intersecare
EgtExtendCurveEndByLen( nCurrOffsetId, 1000)
EgtExtendCurveStartByLen( nPrevCurveId, 200)
ptIntersCurrOffsetPrev = EgtIP( nCurrOffsetId, nPrevCurveId, EgtEP( nCurrOffsetId))
end
local ptIntersCurrOffsetNext = EgtIP( nCurrOffsetId, nNextCurveId, EgtSP( nCurrOffsetId))
if not ptIntersCurrOffsetNext then
-- allungo per intersecare
EgtExtendCurveStartByLen( nCurrOffsetId, 1000)
EgtExtendCurveStartByLen( nNextCurveId, 200)
ptIntersCurrOffsetNext = EgtIP( nCurrOffsetId, nNextCurveId, EgtSP( nCurrOffsetId))
end
-- calcolo accorciamenti dei lati copiati alle intersezioni
local dIntersCurrPrevParam = EgtCurveParamAtPoint( nCurrCurveId, ptIntersCurrPrev)
EgtTrimCurveStartAtParam( nCurrCurveId, dIntersCurrPrevParam)
local dIntersCurrNextParam = EgtCurveParamAtPoint( nCurrCurveId, ptIntersCurrNext)
EgtTrimCurveEndAtParam( nCurrCurveId, dIntersCurrNextParam)
local dIntersCurrOffsetNextParam = EgtCurveParamAtPoint( nCurrOffsetId, ptIntersCurrOffsetNext)
EgtTrimCurveStartAtParam( nCurrOffsetId, dIntersCurrOffsetNextParam)
local dIntersCurrOffsetPrevParam = EgtCurveParamAtPoint( nCurrOffsetId, ptIntersCurrOffsetPrev)
EgtTrimCurveEndAtParam( nCurrOffsetId, dIntersCurrOffsetPrevParam)
local dIntersPrevOffsetParam = EgtCurveParamAtPoint( nPrevCurveId, ptIntersCurrOffsetPrev)
EgtTrimCurveStartAtParam( nPrevCurveId, dIntersPrevOffsetParam)
local dIntersPrevCurrParam = EgtCurveParamAtPoint( nPrevCurveId, ptIntersCurrPrev)
EgtTrimCurveEndAtParam( nPrevCurveId, dIntersPrevCurrParam)
local dIntersNextCurrParam = EgtCurveParamAtPoint( nNextCurveId, ptIntersCurrNext)
EgtTrimCurveStartAtParam( nNextCurveId, dIntersNextCurrParam)
local dIntersNextOffsetParam = EgtCurveParamAtPoint( nNextCurveId, ptIntersCurrOffsetNext)
EgtTrimCurveEndAtParam( nNextCurveId, dIntersNextOffsetParam)
-- salvo spessore serramento in geo
EgtSetInfo( nCurrCurveId, WIN_GEOWIDTH, dGeoWidth)
return nCurrCurveId
end
---------------------------------------------------------------------
-- funzione che recupera tipo di inizio e fine pezzo
local function CalcStartEndProfileType( nProfileType, nOutlineId, nStartProfileId, nEndProfileId)
local sStartProfileType
local sEndProfileType
local StartJointType = EgtGetInfo( nOutlineId, WIN_STARTJOINT, 'i')
if StartJointType == WIN_PART_JNT.ANGLED then
sStartProfileType = WIN_MINIZINKEN
elseif StartJointType == WIN_PART_JNT.SHORT then
sStartProfileType = WIN_CTRINOFST
elseif StartJointType == WIN_PART_JNT.FULL then
sStartProfileType = WIN_OUTOFST
end
local EndJointType = EgtGetInfo( nOutlineId, WIN_ENDJOINT, 'i')
if EndJointType == WIN_PART_JNT.ANGLED then
sEndProfileType = WIN_MINIZINKEN
elseif EndJointType == WIN_PART_JNT.SHORT then
sEndProfileType = WIN_CTRINOFST
elseif EndJointType == WIN_PART_JNT.FULL then
sEndProfileType = WIN_OUTOFST
end
if nProfileType == WIN_PRF.SPLIT then
local nStartId = EgtGetInfo( nOutlineId, WIN_SPLIT_STARTINTERS, 'i')
local nEndId = EgtGetInfo( nOutlineId, WIN_SPLIT_ENDINTERS, 'i')
local sStartName = EgtGetName( nStartId)
local sEndName = EgtGetName( nEndId)
sStartProfileType = GetProfileCtrIn( nProfileType, nStartId, nOutlineId, nStartProfileId)
sEndProfileType = GetProfileCtrIn( nProfileType, nEndId, nOutlineId, nEndProfileId)
sStartProfileType = WIN_OFST .. sStartProfileType
sEndProfileType = WIN_OFST .. sEndProfileType
elseif nProfileType == WIN_PRF.BOTTOMRAIL then
StartJointType = WIN_JNT.FULL_V
EndJointType = WIN_JNT.FULL_V
sStartProfileType = WIN_CTRINOFST
sEndProfileType = WIN_CTRINOFST
end
return sStartProfileType, sEndProfileType, StartJointType, EndJointType
end
---------------------------------------------------------------------
-- funzione che posiziona i profili, li estrude e crea il solido
local function MakeSolidByExtrusion( nGeoId, nOutlineId, nMainProfileId, nStartProfileId, nEndProfileId, nProfileType, nSolidLayerId, nAreaType)
-- recupero outline
local nPartId = EgtGetParent( nSolidLayerId)
local nGeoLayerId = EgtGetParent( nGeoId)
local nOutlineLayerId = EgtGetParent( nOutlineId)
-- recupero geo
local nPrevGeoId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_LEFT)
local nNextGeoId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_RIGHT)
-- recupero BBox e larghezza del geo
local dGeoWidth = EgtGetInfo( nGeoId, WIN_GEOWIDTH, 'd')
-- recupero tipo di giunzioni e i controprofili
local sStartProfileType, sEndProfileType, StartJointType, EndJointType = CalcStartEndProfileType( nProfileType, nOutlineId, nStartProfileId, nEndProfileId)
-- recupero outline precedente e successivo
local nPrevOutlineId, nEndOutlineId = GetPrevNextOutline( nProfileType, nOutlineId, nOutlineLayerId)
-- a) MAIN EXTRUSION
-- creo guida Main
local nGuideId = EgtCopy( nOutlineId, nSolidLayerId)
EgtSetName( nGuideId, WIN_MAINGUIDE)
EgtExtendCurveStartByLen( nGuideId, 2 * dGeoWidth)
EgtExtendCurveEndByLen( nGuideId, 2 * dGeoWidth)
-- recupero frame del profilo
local nMainProfileFrameId = EgtGetFirstNameInGroup( nMainProfileId, WIN_SECTIONFRAME)
local frInvertMainProfile = EgtFR( nMainProfileFrameId)
frInvertMainProfile:invert()
-- lo applico a tutte le geometrie del profilo
EgtTransform( EgtGetAllInGroup( nMainProfileId), frInvertMainProfile)
-- assegno come riferimento del profilo il punto start dell'outline
EgtChangeGroupFrame( nMainProfileId, Frame3d( EgtSP( nGuideId), - EgtSV( nGuideId)))
-- recupero outline del profilo Main e lo estrudo
local nMainOutlineId = EgtGetFirstNameInGroup( nMainProfileId, WIN_SECTION)
local nMainExtrusionId = EgtSurfTmSwept( nSolidLayerId, nMainOutlineId, nGuideId, false, WIN_SURF_APPROX)
EgtSetName( nMainExtrusionId, WIN_SRF_MAIN)
-- creo una copia dell'estrusione principale per trim successivi
local nOrigMainExtrusionId = EgtCopy( nMainExtrusionId, nSolidLayerId)
EgtSetName( nOrigMainExtrusionId, WIN_SRF_ORIGMAIN)
EgtSetStatus( nOrigMainExtrusionId, GDB_ST.OFF)
-- b) START PROFILE
-- posiziono il profilo Start
local nRefStartProfileId = EgtGetFirstNameInGroup( nStartProfileId, WIN_REF)
local b3RefStartProfile = EgtGetBBoxGlob(nRefStartProfileId, GDB_BB.STANDARD)
local dStartDelta = EgtGetInfo( nGeoLayerId, WIN_STARTCPDELTA, 'd') or 0
-- creo guida per estrusione
local nStartGuideId = EgtCopy( nPrevGeoId, nSolidLayerId)
EgtSetName( nStartGuideId, WIN_STARTGUIDE)
EgtExtendCurveStartByLen( nStartGuideId, 2 * dGeoWidth)
EgtExtendCurveEndByLen( nStartGuideId, 2 * dGeoWidth)
-- recupero frame del profilo
local nStartProfileFrameId = EgtGetFirstNameInGroup( nStartProfileId, WIN_SECTIONFRAME)
local frStartProfile = EgtFR( nStartProfileFrameId)
-- lo sposto se controprofilo
frStartProfile:move( - frStartProfile:getVersX() * dStartDelta)
frStartProfile:invert()
-- lo applico a tutte le geometrie del profilo
EgtTransform( EgtGetAllInGroup( nStartProfileId), frStartProfile)
-- assegno come riferimento del profilo il punto start dell'outline
EgtChangeGroupFrame( nStartProfileId, Frame3d( EgtSP( nStartGuideId), - EgtSV( nStartGuideId)))
-- se Start e' split verifico se è necessaria inversione del profilo
local nStartId = EgtGetInfo( nOutlineId, WIN_SPLIT_STARTINTERS, 'i')
local nStartProfileType
if nStartId then
local nStartAreaId = EgtGetParent( EgtGetParent( nStartId))
if nStartAreaId then
nStartProfileType = EgtGetInfo( nStartAreaId, WIN_AREATYPE, 'i')
end
end
if nProfileType == WIN_PRF.SPLIT and nStartProfileType and nStartProfileType == WIN_AREATYPES.SPLIT then
local nStartSouId = nStartId
local nStartSouLayerId
local sStartSouLayer
repeat
nStartSouId = EgtGetInfo( nStartSouId, WIN_SOU)
nStartSouLayerId = EgtGetParent( nStartSouId)
if nStartSouLayerId then
sStartSouLayer = EgtGetName( nStartSouLayerId)
end
until not nStartSouId or not nStartSouLayerId or sStartSouLayer == WIN_BASESPLIT
if nStartSouId and nStartSouLayerId and sStartSouLayer == WIN_BASESPLIT then
-- recupero vettore tangente nel punto medio della curva di contorno
local ptMidStart = EgtMP( nStartId)
local vtMidStart = EgtMV( nStartId)
-- recupero vettore tangente nello stesso punto della curva split originale
local dMidStartOnStartSou = EgtCurveParamAtPoint( nStartSouId, ptMidStart)
local vtMidStartSou = EgtUV( nStartSouId, dMidStartOnStartSou, -1)
-- se i due vettori non sono orientati nella stessa direzione
if not AreSameVectorExact( vtMidStart, vtMidStartSou) then
-- ruoto di 180 gradi il profilo
local frStartProfileS = EgtFR( nStartProfileFrameId, GDB_ID.ROOT)
EgtRotate( nStartProfileId, frStartProfileS:getOrigin(), frStartProfileS:getVersY(), 180, GDB_RT.GLOB)
local nStartCntProfileId = EgtGetFirstNameInGroup( nStartProfileId, sStartProfileType)
EgtInvertCurve( nStartCntProfileId)
end
end
end
-- recupero outline del profilo Start e lo estrudo
local nOutStartProfileId
if sStartProfileType == WIN_MINIZINKEN then
nOutStartProfileId = EgtLine( nStartProfileId, EgtSP( nPrevGeoId), EgtSP( nPrevGeoId) - Z_AX() * b3RefStartProfile:getDimY(), GDB_RT.GLOB)
EgtInvertCurve( nOutStartProfileId)
else
nOutStartProfileId = EgtGetFirstNameInGroup( nStartProfileId, sStartProfileType)
end
local nStartExtrusionId = EgtSurfTmSwept( nSolidLayerId, nOutStartProfileId, nStartGuideId, false, WIN_SURF_APPROX)
EgtSetName( nStartExtrusionId, WIN_SRF_START)
-- taglio estrusi per ottenere solido
local nExtrCopyId = EgtCopy( nMainExtrusionId, nSolidLayerId)
EgtSurfTmCut( nMainExtrusionId, nStartExtrusionId, true, false)
EgtSurfTmCut( nStartExtrusionId, nExtrCopyId, true, false)
-- creo fori per spine su Start
local nDowelLayerId = EgtGroup( nPartId)
EgtSetName( nDowelLayerId, WIN_DOWEL)
local sOutlineName = EgtGetName( nOutlineId)
local sPrevOutlineName = EgtGetName( nPrevOutlineId)
if StartJointType == WIN_PART_JNT.ANGLED then
elseif StartJointType == WIN_PART_JNT.FULL then
-- recupero profondita' d'inizio e fine
local sStart = EgtIf( sOutlineName == WIN_BOTTOM, WIN_DWL_BOTTOMPERPSTART, WIN_DWL_TOPPERPSTART)
local sEnd = EgtIf( sOutlineName == WIN_BOTTOM, WIN_DWL_BOTTOMPERPEND, WIN_DWL_TOPPERPEND)
-- ciclo sui fori trovati
local nOrigDowelId = EgtGetFirstNameInGroup( nStartProfileId, WIN_DOWEL .. '*')
while nOrigDowelId do
local dStart = EgtGetInfo( nOrigDowelId, sStart, 'd')
if not dStart then
dStart = EgtGetInfo( nOrigDowelId, WIN_DWL_TOPPERPSTART, 'd')
end
local dEnd = EgtGetInfo( nOrigDowelId, sEnd, 'd')
if not dEnd then
dEnd = EgtGetInfo( nOrigDowelId, WIN_DWL_TOPPERPEND, 'd')
end
local nDowelId = EgtCopyGlob( nOrigDowelId, nDowelLayerId)
EgtSetColor( nDowelId, Color3d( 128, 128, 128))
local nInGeoId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_IN)
local ptDowelCenter = EgtCP( nDowelId)
local vtPerpStartPoint = EgtSV( nOutlineId)
vtPerpStartPoint:rotate( Z_AX(), 90)
-- posiziono i fori e gli assegno estrusione e spessore
EgtMove( nDowelId, ( EgtSP( nInGeoId) - ptDowelCenter) * vtPerpStartPoint * vtPerpStartPoint - vtPerpStartPoint * dStart)
-- EgtMove( nDowelId, Point3d( ptDowelCenter:getX(), EgtSP( nInGeoId):getY(), ptDowelCenter:getZ()) - ptDowelCenter - vtPerpStartPoint * dStart)
EgtModifyCurveExtrusion( nDowelId, - vtPerpStartPoint)
EgtModifyCurveThickness( nDowelId, dEnd - dStart)
-- creo solido di estrusione
local nDowelExtrusionId = EgtSurfTmByRegionExtrusion( nSolidLayerId, nDowelId, - vtPerpStartPoint * ( dEnd - dStart + 1))
EgtMove( nDowelExtrusionId, vtPerpStartPoint)
EgtInvertSurf( nDowelExtrusionId)
-- taglio estrusi per ottenere solido
EgtSurfTmCut( nMainExtrusionId, nDowelExtrusionId, true, false)
EgtSurfTmCut( nDowelExtrusionId, nExtrCopyId, true, false)
nOrigDowelId = EgtGetNextName( nOrigDowelId, WIN_DOWEL .. '*')
end
elseif StartJointType == WIN_PART_JNT.SHORT then
-- recupero info di profondita' d'inizio e fine in base al profilo dello start
local sStart = WIN_DWL_TOPPARASTART
local sEnd = WIN_DWL_TOPPARAEND
if sPrevOutlineName == WIN_BOTTOM then
sStart = WIN_DWL_BOTTOMPARASTART
sEnd = WIN_DWL_BOTTOMPARAEND
end
if sOutlineName == WIN_SPLIT then
local sStartProfileType = EgtGetInfo( nStartProfileId, WIN_PRF_TYPE)
if sStartProfileType == WIN_RAIL_BOTTOM then
sStart = WIN_DWL_RAILBOTTOMPARASTART
sEnd = WIN_DWL_RAILBOTTOMPARAEND
elseif sStartProfileType == WIN_SASH_HORIZONTAL then
sStart = WIN_DWL_HORIZONTALSPLITPARASTART
sEnd = WIN_DWL_HORIZONTALSPLITPARAEND
elseif sStartProfileType == WIN_SASH_VERTICAL then
sStart = WIN_DWL_VERTICALSPLITPARASTART
sEnd = WIN_DWL_VERTICALSPLITPARAEND
elseif sStartProfileType == WIN_FRAME_SPLIT or sStartProfileType == WIN_SASH_SPLIT then
sStart = WIN_DWL_SPLITPARASTART
sEnd = WIN_DWL_SPLITPARAEND
end
end
-- ciclo sui fori trovati
local nOrigDowelId = EgtGetFirstNameInGroup( nMainProfileId, WIN_DOWEL .. '*')
while nOrigDowelId do
local dStart = EgtGetInfo( nOrigDowelId, sStart, 'd')
if not dStart then
dStart = EgtGetInfo( nOrigDowelId, WIN_DWL_TOPPARASTART, 'd')
end
local dEnd = EgtGetInfo( nOrigDowelId, sEnd, 'd')
if not dEnd then
dEnd = EgtGetInfo( nOrigDowelId, WIN_DWL_TOPPARAEND, 'd')
end
-- verifico che start ed end abbiano dei valori
if dStart and dEnd then
local nDowelId = EgtCopyGlob( nOrigDowelId, nDowelLayerId)
EgtSetColor( nDowelId, Color3d( 128, 128, 128))
local nLeftGeoId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_LEFT)
local ptDowelCenter = EgtCP( nDowelId)
local vtParaStartPoint = EgtSV( nOutlineId)
-- posiziono i fori e gli assegno estrusione e spessore
EgtMove( nDowelId, ( EgtSP( nLeftGeoId) - ptDowelCenter) * vtParaStartPoint * vtParaStartPoint + vtParaStartPoint * dStart)
EgtModifyCurveExtrusion( nDowelId, vtParaStartPoint)
EgtModifyCurveThickness( nDowelId, dEnd - dStart)
-- creo solido di estrusione
local nDowelExtrusionId = EgtSurfTmByRegionExtrusion( nSolidLayerId, nDowelId, vtParaStartPoint * ( dEnd - dStart + 1))
EgtMove( nDowelExtrusionId, - vtParaStartPoint)
EgtInvertSurf( nDowelExtrusionId)
-- taglio estrusi per ottenere solido
local nDowelExtrCopyId = EgtCopy( nDowelExtrusionId, nSolidLayerId)
EgtSurfTmCut( nDowelExtrusionId, nStartExtrusionId, true, false)
EgtSurfTmCut( nStartExtrusionId, nDowelExtrCopyId, true, false)
EgtErase( nDowelExtrCopyId)
end
nOrigDowelId = EgtGetNextName( nOrigDowelId, WIN_DOWEL .. '*')
end
end
-- c) END PROFILE
-- posiziono il profilo End
local nRefEndProfileId = EgtGetFirstNameInGroup( nEndProfileId, WIN_REF)
local b3RefEndProfile = EgtGetBBoxGlob(nRefEndProfileId, GDB_BB.STANDARD)
local dEndDelta = EgtGetInfo( nGeoLayerId, WIN_ENDCPDELTA, 'd') or 0
-- creo guida per estrusione
local nEndGuideId = EgtCopy( nNextGeoId, nSolidLayerId)
EgtSetName( nEndGuideId, WIN_ENDGUIDE)
EgtExtendCurveStartByLen( nEndGuideId, 2 * dGeoWidth)
EgtExtendCurveEndByLen( nEndGuideId, 2 * dGeoWidth)
-- recupero frame del profilo
local nEndProfileFrameId = EgtGetFirstNameInGroup( nEndProfileId, WIN_SECTIONFRAME)
local frEndProfile = EgtFR( nEndProfileFrameId)
frEndProfile:move( - frEndProfile:getVersX() * dEndDelta)
frEndProfile:invert()
-- lo applico a tutte le geometrie del profilo
EgtTransform( EgtGetAllInGroup( nEndProfileId), frEndProfile)
-- assegno come riferimento del profilo il punto start dell'outline
EgtChangeGroupFrame( nEndProfileId, Frame3d( EgtSP( nEndGuideId), - EgtSV( nEndGuideId)))
-- se End e' split, ruoto di 180 gradi il profilo
local nEndId = EgtGetInfo( nOutlineId, WIN_SPLIT_ENDINTERS, 'i')
local nEndProfileType
if nEndId then
local nEndAreaId = EgtGetParent( EgtGetParent( nEndId))
if nEndAreaId then
nEndProfileType = EgtGetInfo( nEndAreaId, WIN_AREATYPE, 'i')
end
end
if nProfileType == WIN_PRF.SPLIT and nEndProfileType and nEndProfileType == WIN_AREATYPES.SPLIT then
local nEndSouId = nEndId
local nEndSouLayerId
local sEndSouLayer
repeat
nEndSouId = EgtGetInfo( nEndSouId, WIN_SOU)
nEndSouLayerId = EgtGetParent( nEndSouId)
if nEndSouLayerId then
sEndSouLayer = EgtGetName( nEndSouLayerId)
end
until not nEndSouId or not nEndSouLayerId or sEndSouLayer == WIN_BASESPLIT
if nEndSouId and nEndSouLayerId and sEndSouLayer == WIN_BASESPLIT then
-- recupero vettore tangente nel punto medio della curva di contorno
local ptMidEnd = EgtMP( nEndId)
local vtMidEnd = EgtMV( nEndId)
-- recupero vettore tangente nello stesso punto della curva split originale
local dMidStartOnEndSou = EgtCurveParamAtPoint( nEndSouId, ptMidEnd)
local vtMidEndSou = EgtUV( nEndSouId, dMidStartOnEndSou, -1)
-- se i due vettori non sono orientati nella stessa direzione
if not AreSameVectorExact( vtMidEnd, vtMidEndSou) then
-- ruoto di 180 gradi il profilo
local frEndProfileS = EgtFR( nEndProfileFrameId, GDB_ID.ROOT)
EgtRotate( nEndProfileId, frEndProfileS:getOrigin(), frEndProfileS:getVersY(), 180, GDB_RT.GLOB)
local nEndCntProfileId = EgtGetFirstNameInGroup( nEndProfileId, sEndProfileType)
EgtInvertCurve( nEndCntProfileId)
end
end
end
-- recupero outline del profilo End e lo estrudo
local nOutEndProfileId
if sEndProfileType == WIN_MINIZINKEN then
nOutEndProfileId = EgtLine( nEndProfileId, EgtSP( nNextGeoId), EgtSP( nNextGeoId) - Z_AX() * b3RefEndProfile:getDimY(), GDB_RT.GLOB)
EgtInvertCurve( nOutEndProfileId)
else
nOutEndProfileId = EgtGetFirstNameInGroup( nEndProfileId, sEndProfileType)
end
local nEndExtrusionId = EgtSurfTmSwept( nSolidLayerId, nOutEndProfileId, nEndGuideId, false, WIN_SURF_APPROX)
EgtSetName( nEndExtrusionId, WIN_SRF_END)
-- taglio estrusi per ottenere solido
EgtSurfTmCut( nMainExtrusionId, nEndExtrusionId, true, false)
EgtSurfTmCut( nEndExtrusionId, nExtrCopyId, true, false)
-- creo fori per spine su End
local sEndOutlineName = EgtGetName( nEndOutlineId)
if EndJointType == WIN_PART_JNT.ANGLED then
elseif EndJointType == WIN_PART_JNT.FULL then
-- recupero profondita' d'inizio e fine
local sStart = EgtIf( sOutlineName == WIN_BOTTOM, WIN_DWL_BOTTOMPERPSTART, WIN_DWL_TOPPERPSTART)
local sEnd = EgtIf( sOutlineName == WIN_BOTTOM, WIN_DWL_BOTTOMPERPEND, WIN_DWL_TOPPERPEND)
-- ciclo sui fori trovati
local nOrigDowelId = EgtGetFirstNameInGroup( nEndProfileId, WIN_DOWEL .. '*')
while nOrigDowelId do
local dStart = EgtGetInfo( nOrigDowelId, sStart, 'd')
if not dStart then
dStart = EgtGetInfo( nOrigDowelId, WIN_DWL_TOPPERPSTART, 'd')
end
local dEnd = EgtGetInfo( nOrigDowelId, sEnd, 'd')
if not dEnd then
dEnd = EgtGetInfo( nOrigDowelId, WIN_DWL_TOPPERPEND, 'd')
end
local nDowelId = EgtCopyGlob( nOrigDowelId, nDowelLayerId)
EgtSetColor( nDowelId, Color3d( 128, 128, 128))
local nInGeoId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_IN)
local ptDowelCenter = EgtCP( nDowelId)
local vtPerpEndPoint = EgtEV( nOutlineId)
vtPerpEndPoint:rotate( Z_AX(), 90)
-- posiziono i fori e gli assegno estrusione e spessore
EgtMove( nDowelId, ( EgtSP( nInGeoId) - ptDowelCenter) * vtPerpEndPoint * vtPerpEndPoint - vtPerpEndPoint * dStart)
EgtModifyCurveExtrusion( nDowelId, - vtPerpEndPoint)
EgtModifyCurveThickness( nDowelId, dEnd - dStart)
-- creo solido di estrusione
local nDowelExtrusionId = EgtSurfTmByRegionExtrusion( nSolidLayerId, nDowelId, - vtPerpEndPoint * ( dEnd - dStart + 1))
EgtMove( nDowelExtrusionId, vtPerpEndPoint)
EgtInvertSurf( nDowelExtrusionId)
-- taglio estrusi per ottenere solido
EgtSurfTmCut( nMainExtrusionId, nDowelExtrusionId, true, false)
EgtSurfTmCut( nDowelExtrusionId, nExtrCopyId, true, false)
nOrigDowelId = EgtGetNextName( nOrigDowelId, WIN_DOWEL .. '*')
end
elseif EndJointType == WIN_PART_JNT.SHORT then
-- recupero profondita' d'inizio e fine
local sStart = WIN_DWL_TOPPARASTART
local sEnd = WIN_DWL_TOPPARAEND
if sEndOutlineName == WIN_BOTTOM then -- sOutlineName == WIN_BOTTOM or sEndOutlineName == WIN_BOTTOM then
sStart = WIN_DWL_BOTTOMPARASTART
sEnd = WIN_DWL_BOTTOMPARAEND
end
if sOutlineName == WIN_SPLIT then
local sEndProfileType = EgtGetInfo( nEndProfileId, WIN_PRF_TYPE)
if sEndProfileType == WIN_RAIL_BOTTOM then
sStart = WIN_DWL_RAILBOTTOMPARASTART
sEnd = WIN_DWL_RAILBOTTOMPARAEND
elseif sEndProfileType == WIN_SASH_HORIZONTAL then
-- non faccio nulla perche' e' uguale al top
elseif sEndProfileType == WIN_SASH_VERTICAL then
sStart = WIN_DWL_VERTICALSPLITPARASTART
sEnd = WIN_DWL_VERTICALSPLITPARAEND
elseif sEndProfileType == WIN_FRAME_SPLIT or sEndProfileType == WIN_SASH_SPLIT then -- sProfileType == WIN_FRAME_SPLIT
sStart = WIN_DWL_SPLITPARASTART
sEnd = WIN_DWL_SPLITPARAEND
end
end
-- ciclo sui fori trovati
local nOrigDowelId = EgtGetFirstNameInGroup( nMainProfileId, WIN_DOWEL .. '*')
while nOrigDowelId do
local dStart = EgtGetInfo( nOrigDowelId, sStart, 'd')
if not dStart then
dStart = EgtGetInfo( nOrigDowelId, WIN_DWL_TOPPARASTART, 'd')
end
local dEnd = EgtGetInfo( nOrigDowelId, sEnd, 'd')
if not dEnd then
dEnd = EgtGetInfo( nOrigDowelId, WIN_DWL_TOPPARAEND, 'd')
end
-- verifico che start ed end abbiano dei valori
if dStart and dEnd then
local nDowelId = EgtCopyGlob( nOrigDowelId, nDowelLayerId)
EgtSetColor( nDowelId, Color3d( 128, 128, 128))
local nRightGeoId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_RIGHT)
local ptDowelCenter = EgtCP( nDowelId)
local vtParaEndPoint = EgtEV( nOutlineId)
-- posiziono i fori e gli assegno estrusione e spessore
EgtMove( nDowelId, ( EgtSP( nRightGeoId) - ptDowelCenter) * vtParaEndPoint * vtParaEndPoint - vtParaEndPoint * dStart)
EgtModifyCurveExtrusion( nDowelId, - vtParaEndPoint)
EgtModifyCurveThickness( nDowelId, dEnd - dStart)
-- creo solido di estrusione
local nDowelExtrusionId = EgtSurfTmByRegionExtrusion( nSolidLayerId, nDowelId, - vtParaEndPoint * ( dEnd - dStart + 1))
EgtMove( nDowelExtrusionId, vtParaEndPoint)
EgtInvertSurf( nDowelExtrusionId)
-- taglio estrusi per ottenere solido
local nDowelExtrCopyId = EgtCopy( nDowelExtrusionId, nSolidLayerId)
EgtSurfTmCut( nDowelExtrusionId, nEndExtrusionId, true, false)
EgtSurfTmCut( nEndExtrusionId, nDowelExtrCopyId, true, false)
EgtErase( nDowelExtrCopyId)
end
nOrigDowelId = EgtGetNextName( nOrigDowelId, WIN_DOWEL .. '*')
end
end
-- elimino copia dell'estrusione principale
EgtErase( { nExtrCopyId})
end
---------------------------------------------------------------------
-- funzione che crea il solido del pezzo del telaio
local function CalcFrameSolid( nPartId, nOutlineId, nGeoId, nOutlineLayerId, bBottomRail)
-- creo layer per solido e per profili di estrusione
local nSolidLayerId = EgtGroup( nPartId)
EgtSetName( nSolidLayerId, WIN_SOLID)
local nFrameProfileLayerId = EgtGroup( nPartId)
EgtSetName( nFrameProfileLayerId, WIN_PROFILE)
-- ricavo tipo di profilo
local nProfileType = GetOutlineProfileType( nOutlineId, bBottomRail)
-- recupero outline precedente e successivo
local nPrevOutlineId, nNextOutlineId = GetPrevNextOutline( nProfileType, nOutlineId, nOutlineLayerId)
-- recupero profili e controprofili
local nOrigMainProfileId = GetOutlineProfileId( nOutlineId, bBottomRail)
-- se il tipo corrente è split il pezzo va tagliato con il bottomrail, altrimenti con il bottom
local nOrigStartProfileId = GetOutlineProfileId( nPrevOutlineId, nProfileType == WIN_PRF.SPLIT)
local nOrigEndProfileId = GetOutlineProfileId( nNextOutlineId, nProfileType == WIN_PRF.SPLIT)
-- creo copie di profilo e controprofili
local nMainProfileId = EgtCopy( nOrigMainProfileId, nFrameProfileLayerId)
local sMainProfileType = EgtGetName( nMainProfileId)
EgtSetInfo( nMainProfileId, WIN_PRF_TYPE, sMainProfileType)
EgtSetName( nMainProfileId, WIN_PRF_MAIN)
local nStartProfileId = EgtCopy( nOrigStartProfileId, nFrameProfileLayerId)
local sStartProfileType = EgtGetName( nStartProfileId)
EgtSetInfo( nStartProfileId, WIN_PRF_TYPE, sStartProfileType)
EgtSetName( nStartProfileId, WIN_PRF_START)
local nEndProfileId = EgtCopy( nOrigEndProfileId, nFrameProfileLayerId)
local sEndProfileType = EgtGetName( nEndProfileId)
EgtSetInfo( nEndProfileId, WIN_PRF_TYPE, sEndProfileType)
EgtSetName( nEndProfileId, WIN_PRF_END)
-- creo solido dai profili
MakeSolidByExtrusion( nGeoId, nOutlineId, nMainProfileId, nStartProfileId, nEndProfileId, nProfileType, nSolidLayerId)
end
---------------------------------------------------------------------
-- funzione che calcola l'ingombro dei pezzi del telaio e i loro solidi
local function CreatePartFromOutline( nAreaLayerId, nOutlineId, bBottomRail)
local nAreaType = EgtGetInfo( nAreaLayerId, WIN_AREATYPE, 'i')
-- creo pezzo
local nPartId = EgtGroup( GDB_ID.ROOT)
-- se BottomRail, creo riferimento
if bBottomRail then
EgtSetInfo( nOutlineId, WIN_BOTTOMRAIL, nPartId)
end
-- recupero outline
local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaLayerId, WIN_OUTLINE)
local nProfileType = WIN_PRF.NULL
if nAreaType == WIN_AREATYPES.FRAME or nAreaType == WIN_AREATYPES.SASH or nAreaType == WIN_AREATYPES.SPLIT then
-- se area senza outline, cerco quella superiore
if not nOutlineLayerId then
local nParentAreaLayerId = EgtGetParent( nAreaLayerId)
if nParentAreaLayerId then
nOutlineLayerId = EgtGetFirstNameInGroup( nParentAreaLayerId, WIN_OUTLINE)
end
end
-- imposto nome
local sName = EgtGetName( nOutlineId)
if bBottomRail then
sName = WIN_BOTTOMRAIL
end
EgtSetName( nPartId, sName)
-- imposto colore
if sName == WIN_BOTTOM or sName == WIN_TOP or bBottomRail then
EgtSetColor( nPartId, Color3d( 204, 102, 0))
elseif sName == WIN_RIGHT or sName == WIN_LEFT then
EgtSetColor( nPartId, Color3d( 251, 128, 4))
else
EgtSetColor( nPartId, Color3d( 255, 159, 57))
end
elseif nAreaType == WIN_AREATYPES.FILL then
-- imposto nome
EgtSetName( nPartId, WIN_FILL)
-- ricavo tipo
local nFillType = EgtGetInfo( nAreaLayerId, WIN_FILLTYPE, 'i')
if nFillType == WIN_FILLTYPES.GLASS then
EgtSetColor( nPartId, Color3d( 71, 161, 255))
EgtSetAlpha( nPartId, 30)
elseif nFillType == WIN_FILLTYPES.WOOD then
EgtSetColor( nPartId, Color3d( 194, 148, 103))
end
end
-- inserisco riferimento alla sua area ed al suo outline
EgtSetInfo( nPartId, WIN_AREA, nAreaLayerId)
if nAreaType ~= WIN_AREATYPES.FILL then
EgtSetInfo( nPartId, WIN_REF_OUTLINE, nOutlineId)
if not bBottomRail then EgtSetInfo( nOutlineId, WIN_REF_PART, nPartId) end
end
if nAreaType == WIN_AREATYPES.FRAME or nAreaType == WIN_AREATYPES.SASH or nAreaType == WIN_AREATYPES.SPLIT then
-- disegno ingombro
local nGeoId = CalcFrameGeo( nPartId, nOutlineId, nOutlineLayerId, bBottomRail)
-- disegno solido
if bCalcSolid then
CalcFrameSolid( nPartId, nOutlineId, nGeoId, nOutlineLayerId, bBottomRail)
end
elseif nAreaType == WIN_AREATYPES.FILL then
-- disegno ingombro
local nGeoLayerId = CalcFillGeo( nPartId, nOutlineLayerId)
-- disegno solido
if bCalcSolid then
CalcFillSolid(nPartId, nOutlineLayerId, nGeoLayerId)
end
end
end
---------------------------------------------------------------------
---------------------------- STRIP ----------------------------------
---------------------------------------------------------------------
-- funzione che restitutisce lo Strip piu' vicino
local function GetStripNearestToOutline( nProfileId, nOutlineId)
-- recupero strip
local ptStartOutline = EgtMP( nOutlineId)
local vtStartOutline = EgtSV( nOutlineId)
local nStartStripId = EgtGetFirstNameInGroup( nProfileId, WIN_STRIP)
if not nStartStripId then
local nStripMinDistId
local dMinDistance
local nStripId = EgtGetFirstNameInGroup( nProfileId, WIN_STRIP .. '*')
while nStripId do
local b3Strip = EgtGetBBoxGlob( nStripId, GDB_BB.STANDARD)
-- calcolo il vettore distanza
local vtDistance = b3Strip:getCenter() - ptStartOutline
-- ne ricavo la componente nella stessa direzione dell'outline
local dDistance = abs( vtDistance * vtStartOutline)
if not dMinDistance or dDistance < dMinDistance then
dMinDistance = dDistance
nStripMinDistId = nStripId
end
nStripId = EgtGetNextName( nStripId, WIN_STRIP .. '*')
end
nStartStripId = nStripMinDistId
end
return nStartStripId
end
---------------------------------------------------------------------
-- funzione che crea le linee di contorno massima e minima degli strip
local function CreateStripGuideLines( nOutlineId, nStripId, nProfileId, nSolidLayerId)
-- recupero il frame del profilo
local nProfileFrameId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME)
local frProfile = EgtFR( nProfileFrameId, GDB_ID.ROOT)
-- se profilo e direzione prev uguali ( Prev e' Split), cambio segno all'offset di modo che rimanga sempre dalla stessa parte
local vtE = EgtEV( nOutlineId)
local bMainInvertOffset = AreSameVectorApprox( frProfile:getVersZ(), vtE)
-- calcolo BBox
local b3MainStrip = EgtGetBBoxRef( nStripId, GDB_BB.STANDARD, frProfile, GDB_RT.GLOB)
-- calcolo offset per Strip
local dMainStripMinDelta = EgtIf( bMainInvertOffset, - b3MainStrip:getMax():getX(), b3MainStrip:getMin():getX())
local dMainStripMaxDelta = EgtIf( bMainInvertOffset, - b3MainStrip:getMin():getX(), b3MainStrip:getMax():getX())
local nStripMinOffsetId = EgtCopy( nOutlineId, nSolidLayerId)
EgtOffsetCurve( nStripMinOffsetId, dMainStripMinDelta)
local nStripMaxOffsetId = EgtCopy( nOutlineId, nSolidLayerId)
EgtOffsetCurve( nStripMaxOffsetId, dMainStripMaxDelta)
return nStripMinOffsetId, nStripMaxOffsetId
end
---------------------------------------------------------------------
-- funzione che crea gli Strip
local function CreateStripFromOutline( nAreaId, nOutlineId)
-- recupero il pezzo associato ( prendendo quello di bottomrail se esiste)
local nPartId = EgtGetInfo( nOutlineId, WIN_BOTTOMRAIL, 'i') or EgtGetInfo( nOutlineId, WIN_REF_PART, 'i')
-- recupero layer per solido e per profili di estrusione
local nSolidLayerId = EgtGetFirstNameInGroup( nPartId, WIN_SOLID)
local nMainProfileLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE)
-- recupero il pezzo precedente ( prendendo eventualmente quello di bottomrail)
local nOutlineLayerId = EgtGetParent( nOutlineId)
local nPrevOutlineId = EgtGetPrev( nOutlineId)
if not nPrevOutlineId then
nPrevOutlineId = EgtGetLastInGroup( nOutlineLayerId)
end
local nPrevPartId = EgtGetInfo( nPrevOutlineId, WIN_BOTTOMRAIL, 'i') or EgtGetInfo( nPrevOutlineId, WIN_REF_PART)
local nPrevProfileLayerId = EgtGetFirstNameInGroup( nPrevPartId, WIN_PROFILE)
-- recupero il pezzo successivo ( prendendo eventualmente quello di bottomrail)
local nNextOutlineId = EgtGetNext( nOutlineId)
if not nNextOutlineId then
nNextOutlineId = EgtGetFirstInGroup( nOutlineLayerId)
end
local nNextPartId = EgtGetInfo( nNextOutlineId, WIN_BOTTOMRAIL, 'i') or EgtGetInfo( nNextOutlineId, WIN_REF_PART)
local nNextProfileLayerId = EgtGetFirstNameInGroup( nNextPartId, WIN_PROFILE)
-- recupero profilo e controprofili
local nMainProfileId = EgtGetFirstNameInGroup( nMainProfileLayerId, WIN_PRF_MAIN)
local nStartProfileId = EgtGetFirstNameInGroup( nPrevProfileLayerId, WIN_PRF_MAIN)
local nEndProfileId = EgtGetFirstNameInGroup( nNextProfileLayerId, WIN_PRF_MAIN)
-- a) estrudo il fermavetro
-- recupero guida Main
local nGuideId = EgtGetFirstNameInGroup( nSolidLayerId, WIN_MAINGUIDE)
-- recupero strip piu' vicino a prev outline
local nMainStripId = GetStripNearestToOutline( nMainProfileId, nPrevOutlineId, WIN_STRIP)
-- estrudo MainStrip
local nMainStripExtrusionId = EgtSurfTmSwept( nSolidLayerId, nMainStripId, nGuideId, false, WIN_SURF_APPROX)
-- b) taglio con start
-- recupero strip dello start piu' vicino ad outline
local nStartStripId = GetStripNearestToOutline( nStartProfileId, nOutlineId, WIN_STRIP)
-- disegno guida start per lo strip trovando le intersezioni degli outline minimi e massimi tra MainStrip e StartStrip
local nMainStripMinOffsetId, nMainStripMaxOffsetId = CreateStripGuideLines( nOutlineId, nMainStripId, nMainProfileId, nSolidLayerId)
local nStartStripMinOffsetId, nStartStripMaxOffsetId = CreateStripGuideLines( nPrevOutlineId, nStartStripId, nStartProfileId, nSolidLayerId)
local ptStripMinStart = EgtIP( nMainStripMinOffsetId, nStartStripMinOffsetId, EgtSP( nMainStripMinOffsetId))
local ptStripMaxStart = EgtIP( nMainStripMaxOffsetId, nStartStripMaxOffsetId, EgtSP( nMainStripMaxOffsetId))
local nStartStripGuideId = EgtLine( nSolidLayerId, ptStripMinStart, ptStripMaxStart)
EgtExtendCurveStartByLen( nStartStripGuideId, 10)
EgtExtendCurveEndByLen( nStartStripGuideId, 10)
-- estrudo Strip start
local nStartProfileFrameId = EgtGetFirstNameInGroup( nStartProfileId, WIN_SECTIONFRAME)
local frStartProfile = EgtFR( nStartProfileFrameId, GDB_ID.ROOT)
local nRefStartProfileId = EgtGetFirstNameInGroup( nStartProfileId, WIN_REF)
local b3RefStartProfile = EgtGetBBoxRef( nRefStartProfileId, GDB_BB.STANDARD, frStartProfile)
local nStartStripProfileId = EgtLine( nStartProfileId, ptStripMinStart, ptStripMinStart - Z_AX() * b3RefStartProfile:getDimY(), GDB_RT.GLOB)
EgtInvertCurve( nStartStripProfileId)
local nStartStripExtrusionId = EgtSurfTmSwept( nSolidLayerId, nStartStripProfileId, nStartStripGuideId, false, WIN_SURF_APPROX)
-- taglio con main
local nStripExtrCopyId = EgtCopy( nMainStripExtrusionId, nSolidLayerId)
EgtSurfTmCut( nMainStripExtrusionId, nStartStripExtrusionId, true, false)
EgtSurfTmCut( nStartStripExtrusionId, nStripExtrCopyId, true, false)
-- c) taglio con end
-- recupero strip piu' vicino ad outline
local nEndStripId = GetStripNearestToOutline( nEndProfileId, nOutlineId, WIN_STRIP)
-- disegno guida end per lo strip trovando le intersezioni degli outline minimi e massimi tra MainStrip ed EndStrip
local nEndStripMinOffsetId, nEndStripMaxOffsetId = CreateStripGuideLines( nNextOutlineId, nEndStripId, nEndProfileId, nSolidLayerId)
local ptStripMinEnd = EgtIP( nMainStripMinOffsetId, nEndStripMinOffsetId, EgtSP( nMainStripMinOffsetId))
local ptStripMaxEnd = EgtIP( nMainStripMaxOffsetId, nEndStripMaxOffsetId, EgtSP( nMainStripMaxOffsetId))
local nEndStripGuideId = EgtLine( nSolidLayerId, ptStripMinEnd, ptStripMaxEnd)
EgtExtendCurveStartByLen( nEndStripGuideId, 10)
EgtExtendCurveEndByLen( nEndStripGuideId, 10)
EgtInvertCurve(nEndStripGuideId)
-- estrudo Strip end
local nEndProfileFrameId = EgtGetFirstNameInGroup( nEndProfileId, WIN_SECTIONFRAME)
local frEndProfile = EgtFR( nEndProfileFrameId, GDB_ID.ROOT)
local nRefEndProfileId = EgtGetFirstNameInGroup( nEndProfileId, WIN_REF)
local b3RefEndProfile = EgtGetBBoxRef(nRefEndProfileId, GDB_BB.STANDARD, frEndProfile)
local nEndStripProfileId = EgtLine( nEndProfileId, ptStripMinEnd, ptStripMinEnd - Z_AX() * b3RefEndProfile:getDimY(), GDB_RT.GLOB)
EgtInvertCurve( nEndStripProfileId)
local nEndStripExtrusionId = EgtSurfTmSwept( nSolidLayerId, nEndStripProfileId, nEndStripGuideId, false, WIN_SURF_APPROX)
-- taglio con main
EgtSurfTmCut( nMainStripExtrusionId, nEndStripExtrusionId, true, false)
EgtSurfTmCut( nEndStripExtrusionId, nStripExtrCopyId, true, false)
EgtErase( nStripExtrCopyId)
end
----------------------------------------------------------------------------------
------------------------------- SPLIT DOWELS -------------------------------------
----------------------------------------------------------------------------------
function WinCalculate.AddSplitDowelToParts( nAreaId)
-- se non ho calcolato i solidi, esco
if not bCalcSolid then
return
end
-- recupero tipo di area
local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i')
if nAreaType == WIN_AREATYPES.FRAME or nAreaType == WIN_AREATYPES.SASH then
-- recupero pezzi outline
local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE)
local nOutlineId = EgtGetFirstInGroup( nOutlineLayerId)
while nOutlineId do
WinCalculate.AddSplitDowelToExtrusion( nOutlineId, nAreaType, false)
-- se di tipo bottom
local sName = EgtGetName( nOutlineId)
if sName == WIN_BOTTOM then
-- se ha BottomRail
local nBottomRail = EgtGetInfo( nOutlineLayerId, WIN_BOTTOMRAIL, 'i')
if nBottomRail and nBottomRail == 1 then
WinCalculate.AddSplitDowelToExtrusion( nOutlineId, nAreaType, true)
end
end
nOutlineId = EgtGetNext( nOutlineId)
end
end
-- verifico se c'e' uno split
local nSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_SPLIT)
if nSplitLayerId then
local nSplitType = EgtGetInfo( nSplitLayerId, WIN_SPLITTYPE, 'i')
local bCalcSplit = false
-- se split di tipo montante
if nSplitType == WIN_SPLITTYPES.MULLION then
bCalcSplit = true
elseif nSplitType == WIN_SPLITTYPES.FRENCH then
bCalcSplit = false
else
-- o split dell'anta
local nParentArea = nAreaId
local nParentType = nAreaType
while nParentArea and nParentType ~= WIN_AREATYPES.FRAME and nParentType ~= WIN_AREATYPES.SASH do
nParentArea = EgtGetParent( nParentArea)
nParentType = EgtGetInfo( nParentArea, WIN_AREATYPE, 'i')
end
if nParentArea and nParentType == WIN_AREATYPES.SASH then
bCalcSplit = true
else
bCalcSplit = true
end
end
if bCalcSplit then
local nSplitId = EgtGetFirstInGroup( nSplitLayerId)
if nSplitId then
-- creo pezzo split
WinCalculate.AddSplitDowelToExtrusion( nSplitId, nAreaType, false)
end
end
end
-- verifico se ci sono aree
local nChildAreaId = EgtGetFirstNameInGroup( nAreaId, WIN_AREA .. '*')
while nChildAreaId do
-- lancio costruzione pezzi di quell'area
WinCalculate.AddSplitDowelToParts( nChildAreaId)
nChildAreaId = EgtGetNextName( nChildAreaId, WIN_AREA .. '*')
end
end
----------------------------------------------------------------------------------
-- funzione che calcola intersezione, geometrie e superfici dei dowel degli split
local function CalSplitDowel( nSplitLayerId, nOutlineId, nProfileFrameLayerId, nFrameProfileLayerId, nProfileType, nPartId, nSolidLayerId)
local nSplitId = EgtGetFirstInGroup( nSplitLayerId)
-- se presenti, verifico se intersecano l'outline che sto analizzando
local ptInters = EgtIP( nOutlineId, nSplitId, EgtSP( nSplitId))
if not ptInters then
return
end
-- se interseca, recupero il profilo dello split
local sSplitProfileType = EgtGetInfo( nSplitId, WIN_PROFILETYPE)
if not sSplitProfileType then
return
end
local nOrigSplitProfileId = EgtGetFirstNameInGroup( nProfileFrameLayerId, sSplitProfileType)
-- creo copia del profilo
local nSplitProfileId = EgtCopy( nOrigSplitProfileId, nFrameProfileLayerId)
local sSplitProfileType = EgtGetName( nOrigSplitProfileId)
EgtSetInfo( nSplitProfileId, WIN_PRF_TYPE, sSplitProfileType)
EgtSetName( nSplitProfileId, WIN_PRF_SPLIT)
-- recupero intersezione con lato In
local bIsGeoOut = false
local nGeoLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO)
local nGeoInId = EgtGetFirstNameInGroup(nGeoLayerId, WIN_GEO_IN)
local ptIntersIn = EgtIP( nGeoInId, nSplitId, EgtSP( nSplitId))
if not ptIntersIn and nProfileType == WIN_PRF.SPLIT then
bIsGeoOut = true
nGeoInId = EgtGetFirstNameInGroup(nGeoLayerId, WIN_GEO_OUT)
ptIntersIn = EgtIP( nGeoInId, nSplitId, EgtSP( nSplitId))
end
-- recupero frame del profilo
local nSplitProfileFrameId = EgtGetFirstNameInGroup( nSplitProfileId, WIN_SECTIONFRAME)
local frInvertSplitProfile = EgtFR( nSplitProfileFrameId)
frInvertSplitProfile:invert()
-- lo applico a tutte le geometrie del profilo
EgtTransform( EgtGetAllInGroup( nSplitProfileId), frInvertSplitProfile)
-- assegno come riferimento del profilo il punto di intersezione
local vtDir = - EgtSV( nSplitId)
if bIsGeoOut then
vtDir = - vtDir
end
EgtChangeGroupFrame( nSplitProfileId, Frame3d( ptIntersIn, vtDir))
-- recupero solido del pezzo
local nSolidLayerId = EgtGetFirstNameInGroup( nPartId, WIN_SOLID)
local nMainExtrusionId = EgtGetFirstNameInGroup( nSolidLayerId, WIN_SRF_MAIN)
local nOrigMainExtrusionId = EgtGetFirstNameInGroup( nSolidLayerId, WIN_SRF_ORIGMAIN)
-- creo fori per spine su Split
local nDowelLayerId = EgtGetFirstNameInGroup( nPartId, WIN_DOWEL)
-- recupero profondita' d'inizio e fine
local sStart = WIN_DWL_TOPPERPSTART
local sEnd = WIN_DWL_TOPPERPEND
if nProfileType == WIN_PRF.BOTTOM then
sStart = WIN_DWL_BOTTOMPERPSTART
sEnd = WIN_DWL_BOTTOMPERPEND
elseif nProfileType == WIN_PRF.BOTTOMRAIL then
sStart = WIN_DWL_RAILBOTTOMPERPSTART
sEnd = WIN_DWL_RAILBOTTOMPERPEND
elseif nProfileType == WIN_PRF.SPLIT then
local sProfileType = EgtGetInfo( nOutlineId, WIN_PROFILETYPE)
if sProfileType == WIN_SASH_HORIZONTAL then
sStart = WIN_DWL_HORIZONTALSPLITPERPSTART
sEnd = WIN_DWL_HORIZONTALSPLITPERPEND
elseif sProfileType == WIN_SASH_VERTICAL then
sStart = WIN_DWL_VERTICALSPLITPERPSTART
sEnd = WIN_DWL_VERTICALSPLITPERPEND
else -- sProfileType == WIN_FRAME_SPLIT
sStart = WIN_DWL_SPLITPERPSTART
sEnd = WIN_DWL_SPLITPERPEND
end
end
-- ciclo sui fori trovati
local nOrigDowelId = EgtGetFirstNameInGroup( nSplitProfileId, WIN_DOWEL .. '*')
while nOrigDowelId do
local dStart = EgtGetInfo( nOrigDowelId, sStart, 'd')
if not dStart then
dStart = EgtGetInfo( nOrigDowelId, WIN_DWL_TOPPERPSTART, 'd')
end
local dEnd = EgtGetInfo( nOrigDowelId, sEnd, 'd')
if not dEnd then
dEnd = EgtGetInfo( nOrigDowelId, WIN_DWL_TOPPERPEND, 'd')
end
local nDowelId = EgtCopyGlob( nOrigDowelId, nDowelLayerId)
EgtSetColor( nDowelId, Color3d( 128, 128, 128))
local ptDowelCenter = EgtCP( nDowelId)
local vtPerpStartPoint = EgtSV( nOutlineId)
if bIsGeoOut then
vtPerpStartPoint:rotate( Z_AX(), -90)
else
vtPerpStartPoint:rotate( Z_AX(), 90)
end
-- posiziono i fori e gli assegno estrusione e spessore
EgtMove( nDowelId, ( EgtSP( nGeoInId) - ptDowelCenter) * vtPerpStartPoint * vtPerpStartPoint - vtPerpStartPoint * dStart)
-- EgtMove( nDowelId, Point3d( ptDowelCenter:getX(), EgtSP( nInGeoId):getY(), ptDowelCenter:getZ()) - ptDowelCenter - vtPerpStartPoint * dStart)
EgtModifyCurveExtrusion( nDowelId, - vtPerpStartPoint)
EgtModifyCurveThickness( nDowelId, dEnd - dStart)
-- creo solido di estrusione
local nDowelExtrusionId = EgtSurfTmByRegionExtrusion( nSolidLayerId, nDowelId, - vtPerpStartPoint * ( dEnd - dStart + 1))
EgtMove( nDowelExtrusionId, vtPerpStartPoint)
EgtInvertSurf( nDowelExtrusionId)
-- taglio estrusi per ottenere solido
--local nExtrCopyId = EgtCopy( nMainExtrusionId, nSolidLayerId)
EgtSurfTmCut( nMainExtrusionId, nDowelExtrusionId, true, false)
EgtSurfTmCut( nDowelExtrusionId, nOrigMainExtrusionId, true, false)
--EgtErase( nExtrCopyId)
nOrigDowelId = EgtGetNextName( nOrigDowelId, WIN_DOWEL .. '*')
end
end
----------------------------------------------------------------------------------
-- funzione ricorsiva che cerca gli split che possono dare origine a dei dowel
local function VerifyDowelArea( nAreaLayerId, nOutlineId, nPartId, nProfileType, nOrigAreaType)
--EgtSaveFile('c://Temp//DowelSplit.nge')
-- recupero profilo
local nProfileLayerId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_PROFILE)
local nProfileFrameLayerId
if nOrigAreaType == WIN_AREATYPES.FRAME then
nProfileFrameLayerId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_FRAME)
elseif nOrigAreaType == WIN_AREATYPES.SASH then
nProfileFrameLayerId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_SASH)
end
-- creo layer per solido e per profili di estrusione
local nSolidLayerId = EgtGetFirstNameInGroup( nPartId, WIN_SOLID)
local nFrameProfileLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE)
-- verifico la presenza di eventuali Split
local nSplitLayerId = EgtGetFirstNameInGroup( nAreaLayerId, WIN_SPLIT)
if nSplitLayerId then
CalSplitDowel( nSplitLayerId, nOutlineId, nProfileFrameLayerId, nFrameProfileLayerId, nProfileType, nPartId, nSolidLayerId)
end
-- verifico la presenza di split in sotto aree
local nArea1LayerId = EgtGetFirstNameInGroup( nAreaLayerId, WIN_AREA1)
if nArea1LayerId then
local nAreaType = EgtGetInfo( nArea1LayerId, WIN_AREATYPE, 'i')
if nAreaType == WIN_AREATYPES.SPLIT then
VerifyDowelArea( nArea1LayerId, nOutlineId, nPartId, nProfileType, nOrigAreaType)
end
end
local nArea2LayerId = EgtGetFirstNameInGroup( nAreaLayerId, WIN_AREA2)
if nArea2LayerId then
local nAreaType = EgtGetInfo( nArea2LayerId, WIN_AREATYPE, 'i')
if nAreaType == WIN_AREATYPES.SPLIT then
VerifyDowelArea( nArea2LayerId, nOutlineId, nPartId, nProfileType, nOrigAreaType)
end
end
end
----------------------------------------------------------------------------------
-- funzione che posiziona i fori delle spine degli split, li estrude e crea il solido
function WinCalculate.AddSplitDowelToExtrusion(nOutlineId, nAreaType, bIsBottomRail)
-- ricavo tipo dal
local sPartRef = WIN_REF_PART
if bIsBottomRail then
sPartRef = WIN_BOTTOMRAIL
end
local nPartId = EgtGetInfo( nOutlineId, sPartRef, 'i')
local sName = EgtGetName( nPartId)
local nProfileType = WIN_PRF.NULL
if bIsBottomRail then
nProfileType = WIN_PRF.BOTTOMRAIL
elseif sName == WIN_TOP then
nProfileType = WIN_PRF.TOP
elseif sName == WIN_BOTTOM then
nProfileType = WIN_PRF.BOTTOM
elseif sName == WIN_LEFT then
nProfileType = WIN_PRF.LEFT
elseif sName == WIN_RIGHT then
nProfileType = WIN_PRF.RIGHT
elseif sName == WIN_VERTICAL then
nProfileType = WIN_PRF.VERTICAL
elseif sName == WIN_HORIZONTAL then
nProfileType = WIN_PRF.HORIZONTAL
elseif sName == WIN_SPLIT then
nProfileType = WIN_PRF.SPLIT
end
-- recupero l'area di cui fa parte il pezzo
local nOutlineLayerId = EgtGetParent( nOutlineId)
local nAreaLayerId = EgtGetParent( nOutlineLayerId)
-- se profilo Bottom con BottomRail, esco
if nProfileType == WIN_PRF.BOTTOM then
local nBaseOutlineLayerId = EgtGetFirstNameInGroup( nAreaLayerId, WIN_AREAOUTLINE)
local nBottomRailId = EgtGetInfo( nBaseOutlineLayerId, WIN_BOTTOMRAIL, 'i')
if nBottomRailId and nBottomRailId == 1 then
return
end
end
-- verifico la presenza di eventuali Split
VerifyDowelArea( nAreaLayerId, nOutlineId, nPartId, nProfileType, nAreaType)
end
---------------------------------------------------------------------
------------------------- FUNZIONI ----------------------------------
---------------------------------------------------------------------
-- funzione che cicla ricorsivamente sulla struttura per creare tutti i pezzi della finestra
function WinCalculate.CreatePartFromArea( nAreaId)
-- assengo il tipo di profilo alle curve del base outline
CalcProfileType(nAreaId)
-- calcolo outline a partire dal base outline
CalculateOutlineFromAreaOutline( nAreaId)
-- creo pezzo
local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i')
if nAreaType == WIN_AREATYPES.FRAME or nAreaType == WIN_AREATYPES.SASH then
-- creo pezzi per ogni outline
local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE)
local nOutlineId = EgtGetFirstInGroup( nOutlineLayerId)
while nOutlineId do
-- creo pezzo
CreatePartFromOutline( nAreaId, nOutlineId)
-- se di tipo bottom verifico se ha bottomrail
local sName = EgtGetName( nOutlineId)
if sName == WIN_BOTTOM then
local bBottomRail = EgtGetInfo( nOutlineLayerId, WIN_BOTTOMRAIL, 'b') or false
if bBottomRail then
CreatePartFromOutline( nAreaId, nOutlineId, true)
end
end
nOutlineId = EgtGetNext( nOutlineId)
end
elseif nAreaType == WIN_AREATYPES.FILL then
-- creo riempimento
CreatePartFromOutline( nAreaId)
end
-- verifico se c'e' uno split da realizzare
local nSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_SPLIT)
if nSplitLayerId then
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
local nSplitId = EgtGetFirstInGroup( nSplitLayerId)
if nSplitId then
-- creo pezzo split
CreatePartFromOutline( nAreaId, nSplitId)
end
end
elseif nAreaType ~= WIN_AREATYPES.FILL then
if WinCalculate.GetCalcSolid() then
-- verifico se c'e' un'area Sash prima di questa
local nParentAreaId = nAreaId
local nParentAreaType = EgtGetInfo( nParentAreaId, WIN_AREATYPE, "i")
while nParentAreaId and nParentAreaType and nParentAreaType ~= WIN_AREATYPES.SASH do
nParentAreaId = EgtGetParent( nParentAreaId)
nParentAreaType = EgtGetInfo( nParentAreaId, WIN_AREATYPE, "i")
end
if nParentAreaId and nParentAreaType == WIN_AREATYPES.SASH then
-- calcolo strip dell'outline
-- è uguale al codice sotto per area child di tipo fill???
local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE)
local nOutlineId = EgtGetFirstInGroup( nOutlineLayerId)
while nOutlineId do
CreateStripFromOutline( nAreaId, nOutlineId)
nOutlineId = EgtGetNext( nOutlineId)
end
else
--- verifico se area successiva e' un fill
local nChildAreaId = EgtGetFirstNameInGroup( nAreaId, WIN_AREAASTERISK)
local nChildAreaType = EgtGetInfo( nChildAreaId, WIN_AREATYPE, "i")
if nChildAreaType == WIN_AREATYPES.FILL then
-- se lo e', vuol dire che e' un vetro fisso, quindi calcolo strip dell'outline
local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE)
local nOutlineId = EgtGetFirstInGroup( nOutlineLayerId)
while nOutlineId do
CreateStripFromOutline( nAreaId, nOutlineId)
nOutlineId = EgtGetNext( nOutlineId)
end
end
end
end
end
-- verifico se ci sono sotto-aree da realizzare
local nChildAreaId = EgtGetFirstNameInGroup( nAreaId, WIN_AREA .. '*')
while nChildAreaId do
-- lancio costruzione pezzi di quell'area
WinCalculate.CreatePartFromArea( nChildAreaId)
nChildAreaId = EgtGetNextName( nChildAreaId, WIN_AREA .. '*')
end
end
---------------------------------------------------------------------
-- funzione che posiziona un pezzo
function WinCalculate.PositionPart(nPartId)
-- ricavo tipo dal nome
local sName = EgtGetName( nPartId)
local sDelta = ''
if sName == WIN_BOTTOM then
sDelta = WIN_STARTCPDELTA
elseif sName == WIN_RIGHT then
sDelta = WIN_STARTCPDELTA
elseif sName == WIN_TOP then
sDelta = WIN_STARTCPDELTA
elseif sName == WIN_LEFT then
sDelta = WIN_STARTCPDELTA
end
-- calcolo nuovo riferimento
local nGeoPartLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO)
local nGeoPartId = EgtGetFirstNameInGroup( nGeoPartLayerId, sName)
local dDelta = EgtGetInfo( nGeoPartId, sDelta, 'd') or 0
local nFrameLayerId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_FRAME)
local nOutlineLayerId = EgtGetFirstNameInGroup( nFrameLayerId, WIN_OUTLINE)
local nFramePartId = EgtGetFirstNameInGroup( nOutlineLayerId, sName)
local vtStart = EgtSV( nFramePartId)
local ptStart = EgtSP( nFramePartId) + vtStart * dDelta
local _, _, dAngRight = SphericalFromVector(vtStart)
local frStart = Frame3d( ptStart)
frStart:rotate( frStart:getOrigin(), Z_AX(), dAngRight)
EgtChangeGroupFrame( nPartId, frStart)
end
---------------------------------------------------------------------
-- funzione che assembla i pezzi
function WinCalculate.AssembleFrame()
local nBottomPartId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_BOTTOM)
WinCalculate.PositionPart(nBottomPartId)
local nRightPartId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_RIGHT)
WinCalculate.PositionPart(nRightPartId)
local nTopPartId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_TOP)
WinCalculate.PositionPart(nTopPartId)
local nLeftPartId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_LEFT)
WinCalculate.PositionPart(nLeftPartId)
-- assemblo i pezzi
--local nRightPartId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_RIGHT)
--local nGeoRightLayerId = EgtGetFirstNameInGroup( nRightPartId, WIN_GEO)
--local nGeoRightId = EgtGetFirstNameInGroup( nGeoRightLayerId, WIN_RIGHT)
--local dDelta = EgtGetInfo( nGeoRightId, WIN_BOTTOMCPDELTA, 'd')
--local nFrameLayerId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_FRAME)
--local nOutlineLayerId = EgtGetFirstNameInGroup( nFrameLayerId, WIN_OUTLINE)
--local nFrameRightId = EgtGetFirstNameInGroup( nOutlineLayerId, WIN_RIGHT)
--local vtRight = EgtSV( nFrameRightId)
--local ptRight = EgtSP( nFrameRightId) + vtRight * dDelta
--local _, _, dAngRight = SphericalFromVector(vtRight)
--local frRight = Frame3d( ptRight)
--frRight:rotate( frRight:getOrigin(), Z_AX(), dAngRight)
--EgtChangeGroupFrame( nRightPartId, frRight)
end
---------------------------------------------------------------------
return WinCalculate