Files
egwwindowlua/Profiles/WinLib/WinCalculate.lua
T
SaraP 5dd44069bc - correzione telaio triangolare
- gestione delle giunzioni come vettore
- modificato il calcolo delle sottaree generate da uno split
- aggiunta info lato di riferimento per lavorazione dowels
- correzioni varie per telai non rettangolari.
2024-07-05 12:15:11 +02:00

2836 lines
128 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 copia la info di chiave sInfo da nSou a nDest
local function CopyInfo( nDest, nSou, sInfo, Default)
local sVal = EgtGetInfo( nSou, sInfo) or Default
EgtSetInfo( nDest, sInfo, sVal)
end
---------------------------------------------------------------------
-- funzione che trova punto di intersezione fra due curve eventualmente estendendole
local function FindIntersectionPoint( nCrv1, nCrv2, ptRef)
local ptInt = EgtIP( nCrv1, nCrv2, ptRef)
if not ptInt then
-- se entrambe linee
if EgtGetType( nCrv1) == GDB_TY.CRV_LINE and EgtGetType( nCrv2) == GDB_TY.CRV_LINE then
EgtExtendCurveStartByLen( nCrv1, 10000)
EgtExtendCurveEndByLen( nCrv1, 10000)
EgtExtendCurveStartByLen( nCrv2, 10000)
EgtExtendCurveEndByLen( nCrv2, 10000)
ptInt = EgtIP( nCrv1, nCrv2, ptRef)
-- se entrambi archi
elseif EgtGetType( nCrv1) == GDB_TY.CRV_ARC and EgtGetType( nCrv2) == GDB_TY.CRV_ARC then
-- TO DO. Al momento non ci sono esempi di questo tipo
-- se arco e linea
else
local nLine = EgtIf( EgtGetType( nCrv1) == GDB_TY.CRV_LINE, nCrv1, nCrv2)
local nArc = EgtIf( nLine == nCrv1, nCrv2, nCrv1)
-- tento di trovare intersezione prolungando la linea
EgtExtendCurveStartByLen( nLine, 10000)
EgtExtendCurveEndByLen( nLine, 10000)
ptInt = EgtIP( nArc, nLine, ptRef)
if not ptInt then
-- creo circonferenza corrispondente all'arco
local nCircle = EgtCircle( GDB_ID.ROOT, EgtCP( nArc), EgtArcRadius( nArc))
-- trovo l'intersezione tra retta e circonferenza
local ptDist = EgtIf( nArc == nCrv2, EgtEP( nArc), EgtSP( nArc))
local _, ptRef = EgtPointCurveDist( ptDist, nLine)
ptInt = EgtIP( nCircle, nLine, ptRef)
EgtErase( nCircle)
-- allungo l'arco per arrivare al punto di intersezione
if nArc == nCrv2 then
EgtModifyCurveEndPoint( nArc, ptInt)
else
EgtModifyCurveStartPoint( nArc, ptInt)
end
end
end
end
return ptInt
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, bOrient)
local IntersCurveList = {}
local LastCurveInters
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
local ptInters = FindIntersectionPoint( nCurveId, nPrevId, EgtSP( nCurveId))
if LastCurveInters then
LastCurveInters.EndInters = Point3d( ptInters)
-- se il punto di intersezione è lo stesso trovato nell'iterazione precedente cerco una seconda
-- intersezione tra le due curve
if AreSamePointApprox( ptInters, LastCurveInters.StartInters) then
ptInters = FindIntersectionPoint( nCurveId, nPrevId, EgtEP( nCurveId))
LastCurveInters.EndInters = Point3d( ptInters)
end
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, 100 * GEO.EPS_SMALL)
local dEndParam = EgtCurveParamAtPoint( CurveInters.CurveId, CurveInters.EndInters, 100 * GEO.EPS_SMALL)
EgtTrimCurveStartEndAtParam( CurveInters.CurveId, min( dStartParam, dEndParam), max( dStartParam, dEndParam))
if bOrient and 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_COPY, 'i')
local ptStartInters = EgtIP( nSplitId, nOutlineId, EgtSP( nSplitId))
local dStartInters = EgtCurveParamAtPoint( nSplitId, ptStartInters)
EgtTrimCurveStartAtParam( nSplitId, dStartInters)
local nEndIntersId = EgtGetInfo( nSplitId, WIN_SPLIT_ENDINTERS, 'i')
nOutlineId = EgtGetInfo( nEndIntersId, WIN_COPY, 'i')
local ptEndInters = EgtIP( nSplitId, nOutlineId, 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
---------------------------------------------------------------------
-- funzione che recupera il pezzo associato ad un outline
local function FindAssociatedPart( nOutlineId)
local nPartId = EgtGetInfo( nOutlineId, WIN_REF_BOTTOMRAIL_PART, 'i') or EgtGetInfo( nOutlineId, WIN_REF_PART, 'i')
if not nPartId then
-- cerco la prima curva da cui deriva che ha un pezzo associato
local nBaseOutline = EgtGetInfo( nOutlineId, WIN_COPY, 'i')
while not nPartId do
-- recupero il base outline da cui deriva
nBaseOutline = EgtGetInfo( nBaseOutline, WIN_SOU, 'i')
-- verifico se ha un profilo associato ( e quindi un pezzo)
local sProfileType = EgtGetInfo( nBaseOutline, WIN_PROFILETYPE)
if sProfileType then
-- recupero l'outline associato
local nCrvId = EgtGetInfo( nBaseOutline, WIN_COPY, 'i')
nPartId = EgtGetInfo( nCrvId, WIN_REF_BOTTOMRAIL_PART, 'i') or EgtGetInfo( nCrvId, WIN_REF_PART, 'i')
end
end
end
return nPartId
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
---------------------------------------------------------------------
local function FindAdjacentSashType( nSplitId, nSouId)
-- recupero l'altro child dello split
local vSplitChildren = EgtGetInfo( nSplitId, WIN_CHILD, 'vi')
local vChildren = EgtIf( vSplitChildren[1] == nSouId, {vSplitChildren[2]}, {vSplitChildren[1]})
-- cerco il suo primo figlio di tipo sash
local nAreaType
local nArea
repeat
vChildren = EgtGetInfo( vChildren[1], WIN_CHILD, 'vi')
if vChildren then
nArea = EgtGetParent( EgtGetParent( vChildren[1]))
nAreaType = EgtGetInfo( nArea or GDB_ID.NULL, WIN_AREATYPE, 'i')
end
until not vChildren or nAreaType == WIN_AREATYPES.SASH
-- recupero il sash type
local nSashType = EgtGetInfo( nArea or GDB_ID.NULL, WIN_SASHTYPE, 'i')
return nSashType
end
---------------------------------------------------------------------
local function GetSubAreaType( nAreaId)
local vStack = { nAreaId}
local i = 1
while vStack[i] do
-- verifico se area è di tipo sash o fill
local nType = EgtGetInfo( vStack[i], WIN_AREATYPE, 'i')
if nType == WIN_AREATYPES.FILL or nType == WIN_AREATYPES.SASH then
return nType
end
-- aggiungo le sue sottoaree ( se esistono) tra gli elementi da analizzare
local vSubAreas = EgtGetNameInGroup( vStack[i], WIN_AREA .. '*') or {}
vStack = EgtJoinTables( vStack, vSubAreas)
-- aggiorno il contatore
i = i + 1
end
return nil
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
-- recupero il tipo delle sottoaree
local nChildType = GetSubAreaType( nAreaId)
-- assegno il profilo alle curve di outline
local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_AREAOUTLINE)
local nOutlineId = EgtGetFirstInGroup( nOutlineLayerId)
while nOutlineId do
local sName = EgtGetName( nOutlineId)
if not nChildType or 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
else -- nChildType == WIN_AREATYPES.FILL
if sName == WIN_BOTTOM then
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_FIXED_BOTTOM)
EgtSetInfo( nOutlineLayerId, WIN_BOTTOMRAIL, true)
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
-- verifico se deriva da una curva di split di tipo french ( e quindi deve avere profilo battente/ricevente)
local nSouId = EgtGetInfo( nOutlineId, WIN_SOU, 'i')
local nSouPrevId
local nSplitType
repeat
nSouPrevId = nSouId
nSouId = EgtGetInfo( nSouId, WIN_SOU, 'i')
if nSouId then
local sName = EgtGetName( nSouId)
if sName == WIN_SPLIT then
local nParentId = EgtGetParent( nSouId)
nSplitType = EgtGetInfo( nParentId, WIN_SPLITTYPE, 'i')
end
end
until not nSouId or nSplitType == WIN_SPLITTYPES.FRENCH
if nSplitType == WIN_SPLITTYPES.FRENCH then
-- setto info sulla curva per ricordare che deriva da un french split ( utile nel calcolo degli outlines)
EgtSetInfo( nOutlineId, WIN_CRV_ON_FRENCH_SPLIT, true)
if nSashType == WIN_SASHTYPES.ACTIVE then
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SASH_ACTIVE)
elseif nSashType == WIN_SASHTYPES.INACTIVE then
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SASH_INACTIVE)
elseif nSashType == WIN_SASHTYPES.ACTIVE_OUT or nSashType == WIN_SASHTYPES.INACTIVE_OUT then
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_FRENCH_OUT)
else
-- devo verificare il tipo dell'anta adiacente
local nAdjSashType = FindAdjacentSashType( nSouId, nSouPrevId)
if nSashType == WIN_SASHTYPES.ACTIVE_IN then
if nAdjSashType == WIN_SASHTYPES.ACTIVE_OUT then
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_FRENCH_IN)
else -- adiacente è inactive
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SASH_ACTIVE)
end
elseif nSashType == WIN_SASHTYPES.INACTIVE_IN then
if nAdjSashType == WIN_SASHTYPES.INACTIVE_OUT then
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_FRENCH_IN)
else -- adiacente è active
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SASH_INACTIVE)
end
end
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
---------------------------------------------------------------------
-- funzione che cicla ricorsivamente su aree e sottoaree per impostare i tipi di profilo
local function CalculateAreaProfileType( nAreaId)
-- calcolo i profili per l'area corrente
CalcProfileType( nAreaId)
-- calcolo i profili per le eventuali sottoaree
local nChildAreaId = EgtGetFirstNameInGroup( nAreaId, WIN_AREA .. '*')
while nChildAreaId do
CalculateAreaProfileType( nChildAreaId)
nChildAreaId = EgtGetNextName( nChildAreaId, WIN_AREA .. '*')
end
end
---------------------------------------------------------------------
--------------------- CALCOLO OUTLINE -------------------------------
---------------------------------------------------------------------
-- funzione che calcola l'outline dall'area outline ( base outline)
local function CalculateOutlineFromAreaOutline( nAreaId)
local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i')
-- recupero il base outline e creo gruppo per outline
local nAreaOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_AREAOUTLINE)
local nOutlineLayerId = EgtGroup( nAreaId)
EgtSetName( nOutlineLayerId, WIN_OUTLINE)
EgtSetStatus( nOutlineLayerId, GDB_ST.OFF)
CopyInfo( nOutlineLayerId, nAreaOutlineLayerId, WIN_JOINTS)
CopyInfo( nOutlineLayerId, nAreaOutlineLayerId, WIN_BOTTOMRAIL)
-- FRAME
if nAreaType == WIN_AREATYPES.FRAME then
-- sistemo le info
local nAreaOutlineId = EgtGetFirstInGroup( nAreaOutlineLayerId)
while nAreaOutlineId do
local nOutlineId = EgtCopyGlob( nAreaOutlineId, nOutlineLayerId)
EgtSetInfo( nAreaOutlineId, WIN_COPY, nOutlineId)
EgtSetInfo( nOutlineId, WIN_COPY, nAreaOutlineId)
nAreaOutlineId = EgtGetNext( nAreaOutlineId)
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)
EgtSetInfo( nSplitId, WIN_COPY, nBaseSplitId)
end
-- SPLIT
elseif nAreaType == WIN_AREATYPES.SPLIT or nAreaType == WIN_AREATYPES.NULL then
-- 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)
end
-- sistemo le info
EgtSetInfo( nOutlineId, WIN_COPY, nBaseOutlineId)
EgtSetInfo( nBaseOutlineId, WIN_COPY, nOutlineId)
EgtRemoveInfo( nOutlineId, WIN_CHILD)
nBaseOutlineId = EgtGetNext( nBaseOutlineId)
end
-- taglio tutti i contorni
TrimAndOrientOrderedCurveLayer( nOutlineLayerId, true)
-- 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)
EgtSetInfo( nSplitId, WIN_COPY, nBaseSplitId)
EgtRemoveInfo( nSplitId, WIN_SOU)
-- lo taglio con outline
TrimSplitWithOutline( nSplitId)
-- recupero tipo di profilo
local sSplitProfile = EgtGetInfo( nSplitId, WIN_PROFILETYPE)
-- se split interno ad anta
if sSplitProfile == WIN_SASH_SPLIT then
-- 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
-- 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_COPY, nBaseOutlineId)
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, sSashProfile)
-- verifico se outline e' segmento battente o ricevente ( che quindi deriva da split di tipo french)
local bOnFrenchSplit = EgtGetInfo( nBaseOutlineId, WIN_CRV_ON_FRENCH_SPLIT, 'b') or false
-- se outline non è segmento battente o ricevente 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, true)
-- 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)
EgtSetInfo( nSplitId, WIN_COPY, nBaseSplitId)
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
-- 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_COPY, nOutlineId)
EgtSetInfo( nOutlineId, WIN_COPY, nBaseOutlineId)
-- 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, true)
end
end
---------------------------------------------------------------------
-- funzione che cicla ricorsivamente su aree e sottaree per calcolare gli outlines
local function CalculateAreaOutline( nAreaId)
-- calcolo outlines per l'area corrente
CalculateOutlineFromAreaOutline( nAreaId)
-- calcolo outlines per le eventuali sottoaree
local nChildAreaId = EgtGetFirstNameInGroup( nAreaId, WIN_AREA .. '*')
while nChildAreaId do
CalculateAreaOutline( nChildAreaId)
nChildAreaId = EgtGetNextName( nChildAreaId, WIN_AREA .. '*')
end
end
---------------------------------------------------------------------
---------------------- 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 vOutlineList = EgtGetAllInGroup( nOutlineLayerId)
local nCompoOutlineId = EgtCurveCompoByChain( nSolidLayerId, vOutlineList, EgtSP( vOutlineList[1]), 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 calcola gli outline precedenti e successivi nel caso di split
local function GetSplitOtherOutline( nSplitId, nSurfSplit, nOutlineId, bPrevOrNext)
local vOutlineIds = {}
-- verifico se devo controllare la curva precedente o successiva dell'outline corrente
local nCrv
local bPrevOutline = false
local ptRef = EgtIf( bPrevOrNext, EgtSP( nSplitId), EgtEP( nSplitId))
local dPar = EgtCurveParamAtPoint( nOutlineId, ptRef)
local dLenInt = EgtCurveLengthAtParam( nOutlineId, dPar)
local dLenTot = EgtCurveLength( nOutlineId)
-- se l'intersezione è più vicina alla fine dell'outline devo controllare il suo next, altrimenti il suo prev
if abs( dLenTot - dLenInt) < dLenInt then
nCrv = EgtGetNext( nOutlineId) or EgtGetFirstInGroup( EgtGetParent( nOutlineId))
else
bPrevOutline = true
nCrv = EgtGetPrev( nOutlineId) or EgtGetLastInGroup( EgtGetParent( nOutlineId))
end
-- recupero il geo associato e costruisco superficie test
local nPartId = FindAssociatedPart( nCrv)
local nGeoId = EgtGetFirstNameInGroup( nPartId, WIN_GEO)
local nGeoOut = EgtGetFirstNameInGroup( nGeoId, WIN_GEO_OUT)
local nGeoIn = EgtGetFirstNameInGroup( nGeoId, WIN_GEO_IN)
local nCrv1 = EgtCopyGlob( nGeoOut, nGeoId)
local nCrv2 = EgtCopyGlob( nGeoIn, nGeoId)
local nCompoTest = EgtCurveCompo( nGeoId, nCrv1)
if bPrevOutline then
-- considero solo la parte finale del pezzo
EgtTrimCurveStartAtParam( nCompoTest, 0.5)
EgtAddCurveCompoLine( nCompoTest, EgtSP( nCrv2))
EgtTrimCurveEndAtParam( nCrv2, 0.5)
else
-- considero solo la parte iniziale del pezzo
EgtTrimCurveEndAtParam( nCompoTest, 0.5)
EgtTrimCurveStartAtParam( nCrv2, 0.5)
EgtAddCurveCompoLine( nCompoTest, EgtSP( nCrv2))
end
EgtAddCurveCompoCurve( nCompoTest, nCrv2)
EgtCloseCurveCompo( nCompoTest)
local nSurfTest = EgtSurfFlatRegion( nGeoId, { nCompoTest})
-- verifico se le due regioni interferiscono
if EgtSurfFrTestExternal( nSurfSplit, nSurfTest) then
vOutlineIds = { nOutlineId}
else
-- aggiungo la curva trovata tra le curve di outline da considerare rispettando l'ordinamento
if bPrevOutline then
vOutlineIds = { nCrv, nOutlineId}
else
vOutlineIds = { nOutlineId, nCrv}
end
-- aggiorno le info di intersezione dello split per non dover ripetere questo calcolo nelle future chiamate a GetPrevNextOutline
local vBaseOutlineId = { EgtGetInfo( vOutlineIds[1], WIN_COPY, 'i'), EgtGetInfo( vOutlineIds[2], WIN_COPY, 'i')}
EgtSetInfo( nSplitId, EgtIf( bPrevOrNext, WIN_SPLIT_STARTINTERS, WIN_SPLIT_ENDINTERS), vBaseOutlineId)
end
EgtErase( nCompoTest)
EgtErase( nSurfTest)
return vOutlineIds
end
---------------------------------------------------------------------
-- funzione che recupera gli outline precedenti e successivi
local function GetPrevNextOutline( nProfileType, nOutlineId, nOutlineLayerId)
local vPrevOutlineId = {}
local vNextOutlineId = {}
if nProfileType ~= WIN_PRF.SPLIT then
vPrevOutlineId = { EgtGetPrev( nOutlineId) or EgtGetLastInGroup( nOutlineLayerId)}
vNextOutlineId = { EgtGetNext( nOutlineId) or EgtGetFirstInGroup( nOutlineLayerId)}
else
-- se split recupero tutte le curve di base outline che lo tagliano
local vPrevBaseOutlineId = EgtGetInfo( nOutlineId, WIN_SPLIT_STARTINTERS, 'vi')
for i = 1, #vPrevBaseOutlineId do
-- recupero l'outline associato al base outline che lo taglia
table.insert( vPrevOutlineId, EgtGetInfo( vPrevBaseOutlineId[i], WIN_COPY, 'i'))
end
local vNextBaseOutlineId = EgtGetInfo( nOutlineId, WIN_SPLIT_ENDINTERS, 'vi')
for i = 1, #vNextBaseOutlineId do
table.insert( vNextOutlineId, EgtGetInfo( vNextBaseOutlineId[i], WIN_COPY, 'i'))
end
-- se lo split è tagliato da una sola curva di base outline, verifico se coinvolge altre curve
if #vPrevBaseOutlineId == 1 or #vNextBaseOutlineId == 1 then
-- costruisco una regione approssimata per il pezzo dello split
local nGrp = EgtGetParent( nOutlineId)
local nSplitProfileId = GetOutlineProfileId( nOutlineId, false)
local nRefId = EgtGetFirstNameInGroup( nSplitProfileId, WIN_REF)
local nFrameId = EgtGetFirstNameInGroup( nSplitProfileId, WIN_SECTIONFRAME)
local frProfile = EgtFR( nFrameId)
local b3Profile = EgtGetBBoxRef( nRefId, GDB_BB.STANDARD, frProfile)
local nCrvOut = EgtCopyGlob( nOutlineId, nGrp)
local nCrvIn = EgtCopyGlob( nOutlineId, nGrp)
EgtOffsetCurve( nCrvOut, b3Profile:getMax():getX())
EgtOffsetCurve( nCrvIn, b3Profile:getMin():getX())
EgtInvertCurve( nCrvIn)
local nCompoTest = EgtCurveCompo( nGrp, nCrvOut)
EgtAddCurveCompoLine( nCompoTest, EgtSP( nCrvIn))
EgtAddCurveCompoCurve( nCompoTest, nCrvIn)
EgtCloseCurveCompo( nCompoTest)
local nSurfTest = EgtSurfFlatRegion( nGrp, nCompoTest)
-- se necessario aggiorno il prev
if #vPrevBaseOutlineId == 1 and EgtGetName( vPrevBaseOutlineId[1]) ~= WIN_SPLIT then
vPrevOutlineId = GetSplitOtherOutline( nOutlineId, nSurfTest, vPrevOutlineId[1], true)
end
-- se necessario aggiorno il next
if #vNextOutlineId == 1 and EgtGetName( vNextBaseOutlineId[1]) ~= WIN_SPLIT then
vNextOutlineId = GetSplitOtherOutline( nOutlineId, nSurfTest, vNextOutlineId[1], false)
end
EgtErase( nSurfTest)
EgtErase( nCompoTest)
end
end
return vPrevOutlineId, vNextOutlineId
end
---------------------------------------------------------------------
-- funzione che restituisce il tipo di controprofilo dell'outline adiacente
local function GetProfileCtrIn( nPrevOutlineId, nOutlineId, nPrevProfileId)
local sPrevCtrIn = WIN_CTRIN
-- gestione particolare del caso di profilo di split
if not EgtGetFirstNameInGroup( nPrevProfileId, sPrevCtrIn) then
-- recupero la curva di base outline da cui deriva il precedente
local nPrevSouId = EgtGetInfo( nPrevOutlineId, WIN_COPY, 'i')
local sPrevSouName
repeat
nPrevSouId = EgtGetInfo( nPrevSouId, WIN_SOU, 'i')
sPrevSouName = EgtGetName( nPrevSouId or GDB_ID.NULL)
until not nPrevSouId or sPrevSouName == WIN_SPLIT
-- verifico da quale lato si trova la curva per decidere quale controprofilo considerare
local _, _, dSide = EgtPointCurveDistSide( EgtMP( nOutlineId), nPrevSouId, Z_AX())
if dSide == 1 then
sPrevCtrIn = WIN_CTRIN .. '1' -- dx
else
sPrevCtrIn = WIN_CTRIN .. '2' -- sx
end
end
return sPrevCtrIn
end
---------------------------------------------------------------------
--------------------------- GEO -----------------------------------
---------------------------------------------------------------------
-- funzione che dato il tipo di pezzo e di giunzione, restituisce se e' corto, lungo o angolato
local function CalcPartJointType( nProfileType, JointType)
if JointType == WIN_JNT.ANGLED then
return WIN_PART_JNT.ANGLED
end
if nProfileType == WIN_PRF.BOTTOMRAIL or nProfileType == WIN_PRF.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 crea il gruppo con i profili di un pezzo
local function CalcFrameProfiles( nPartId, nOutlineId, vPrevOutlineId, vNextOutlineId, nProfileType)
-- creo gruppo per i profili
local nProfileLayerId = EgtGroup( nPartId)
EgtSetName( nProfileLayerId, WIN_PROFILE)
EgtSetStatus( nProfileLayerId, GDB_ST.OFF)
-- recupero profilo principale e ne creo copia
local nOrigMainProfileId = GetOutlineProfileId( nOutlineId, nProfileType == WIN_PRF.BOTTOMRAIL)
local nMainProfileId = EgtCopy( nOrigMainProfileId, nProfileLayerId)
local sMainProfileType = EgtGetName( nMainProfileId)
EgtSetInfo( nMainProfileId, WIN_PRF_TYPE, sMainProfileType)
EgtSetName( nMainProfileId, WIN_PRF_MAIN)
-- recupero controprofili start e ne creo copia
for i = 1, #vPrevOutlineId do
-- se il tipo corrente è split il pezzo va tagliato con il bottomrail, altrimenti con il bottom
local nOrigStartProfileId = GetOutlineProfileId( vPrevOutlineId[i], nProfileType == WIN_PRF.SPLIT)
local nStartProfileId = EgtCopy( nOrigStartProfileId, nProfileLayerId)
local sStartProfileType = EgtGetName( nStartProfileId)
EgtSetInfo( nStartProfileId, WIN_PRF_TYPE, sStartProfileType)
EgtSetName( nStartProfileId, WIN_PRF_START)
end
-- recupero controprofili end e ne creo copia
for i = 1, #vNextOutlineId do
local nOrigEndProfileId = GetOutlineProfileId( vNextOutlineId[i], nProfileType == WIN_PRF.SPLIT)
local nEndProfileId = EgtCopy( nOrigEndProfileId, nProfileLayerId)
local sEndProfileType = EgtGetName( nEndProfileId)
EgtSetInfo( nEndProfileId, WIN_PRF_TYPE, sEndProfileType)
EgtSetName( nEndProfileId, WIN_PRF_END)
end
-- recupero le info di pinzaggio dal profilo di estrusione
CopyInfo( nPartId, nMainProfileId, WIN_PRC_OFFY_1, 0)
CopyInfo( nPartId, nMainProfileId, WIN_PRC_OFFZ_1, 0)
CopyInfo( nPartId, nMainProfileId, WIN_PRC_OFFY_2, 0)
CopyInfo( nPartId, nMainProfileId, WIN_PRC_OFFZ_2, 0)
return nProfileLayerId
end
---------------------------------------------------------------------
local function GetDeltaProfile( nProfileId, sCtrIn)
local dCPDelta = 0
local nSectionFrId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME)
local frSectionFrame = EgtFR( nSectionFrId)
local nCPId = EgtGetFirstNameInGroup( nProfileId, sCtrIn)
local b3CP = EgtGetBBoxRef( nCPId, GDB_BB.STANDARD, frSectionFrame)
if sCtrIn == WIN_CTRIN .. 1 then
dCPDelta = abs( b3CP:getMin():getX())
else
dCPDelta = abs( b3CP:getMax():getX())
end
return dCPDelta
end
---------------------------------------------------------------------
-- funzione che crea le curve del geo
local function CreateFrameGeo( nOutlineId, vPrevOutlineId, vNextOutlineId, nStartPartJointType, nEndPartJointType, nGeoLayerId, nProfileLayerId)
local nCurrProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN)
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)
local nSemiProfileOut = EgtGetFirstNameInGroup( nCurrProfileId, WIN_OUT) or EgtGetFirstNameInGroup( nCurrProfileId, WIN_IN .. '1')
EgtSetInfo( nCurrCurveId, WIN_SEMI_PROFILE, nSemiProfileOut)
-- cruva in
local nCurrOffsetId = EgtCopy( nOutlineId, nGeoLayerId)
EgtOffsetCurve( nCurrOffsetId, dCurrOffset - b3CurrProfileFrame:getDimX())
EgtInvertCurve( nCurrOffsetId)
EgtSetName( nCurrOffsetId, WIN_GEO_IN)
local nSemiProfileIn = EgtGetFirstNameInGroup( nCurrProfileId, WIN_IN) or EgtGetFirstNameInGroup( nCurrProfileId, WIN_IN .. '2')
EgtSetInfo( nCurrOffsetId, WIN_SEMI_PROFILE, nSemiProfileIn)
-- curve left
local vPrevProfileId = EgtGetNameInGroup( nProfileLayerId, WIN_PRF_START)
local vStartCPDelta = {}
for i = 1, #vPrevOutlineId do
local nPrevCurveId
local nPrevSemiProfile
if nStartPartJointType == WIN_PART_JNT.ANGLED then
-- calcolo la bisettrice
local vtMedia = ( ( EgtSV( nOutlineId) - EgtEV( vPrevOutlineId[i])) / 2)
if not vtMedia:normalize() then
vtMedia = EgtSV( nOutlineId)
vtMedia:rotate( Z_AX(), 90)
end
table.insert( vStartCPDelta, 0)
nPrevCurveId = EgtLinePVL( nGeoLayerId, EgtSP( nOutlineId), vtMedia, 3 * b3CurrProfileFrame:getDimX())
EgtInvertCurve( nPrevCurveId)
else
nPrevCurveId = EgtCopy( vPrevOutlineId[i], nGeoLayerId)
if nStartPartJointType == WIN_PART_JNT.SHORT then
local sCtrIn = GetProfileCtrIn( vPrevOutlineId[i], nOutlineId, vPrevProfileId[i])
local dPrevCPDelta = GetDeltaProfile( vPrevProfileId[i], sCtrIn)
EgtOffsetCurve( nPrevCurveId, - dPrevCPDelta)
table.insert( vStartCPDelta, dPrevCPDelta)
-- ricavo il semiprofilo associato
nPrevSemiProfile = EgtGetFirstNameInGroup( vPrevProfileId[i], sCtrIn)
else
table.insert( vStartCPDelta, 0)
nPrevSemiProfile = EgtGetFirstNameInGroup( vPrevProfileId[i], WIN_OUT)
end
end
EgtSetName( nPrevCurveId, WIN_GEO_LEFT)
EgtSetInfo( nPrevCurveId, WIN_SEMI_PROFILE, nPrevSemiProfile)
EgtRelocateGlob( nPrevCurveId, nGeoLayerId, GDB_IN.LAST_SON)
end
EgtSetInfo( nGeoLayerId, WIN_STARTCPDELTA, vStartCPDelta)
-- curve right
local vNextProfileId = EgtGetNameInGroup( nProfileLayerId, WIN_PRF_END)
local vNextCPDelta = {}
for i = 1, #vNextOutlineId do
local nNextCurveId
local nNextSemiProfile
if nEndPartJointType == WIN_PART_JNT.ANGLED then
-- calcolo la bisettrice
local vtMedia = ( ( EgtSV( vNextOutlineId[i]) - EgtEV( nOutlineId)) / 2)
if not vtMedia:normalize() then
vtMedia = EgtEV( nOutlineId)
vtMedia:rotate(Z_AX(), 90)
end
table.insert( vNextCPDelta, 0)
nNextCurveId = EgtLinePVL( nGeoLayerId, EgtEP( nOutlineId), vtMedia, 3 * b3CurrProfileFrame:getDimX())
else
nNextCurveId = EgtCopy( vNextOutlineId[i], nGeoLayerId)
if nEndPartJointType == WIN_PART_JNT.SHORT then
local sCtrIn = GetProfileCtrIn( vNextOutlineId[i], nOutlineId, vNextProfileId[i])
local dNextCPDelta = GetDeltaProfile( vNextProfileId[i], sCtrIn)
EgtOffsetCurve( nNextCurveId, - dNextCPDelta)
table.insert( vNextCPDelta, dNextCPDelta)
-- ricavo il semiprofilo associato
nNextSemiProfile = EgtGetFirstNameInGroup( vNextProfileId[i], sCtrIn)
else
table.insert( vNextCPDelta, 0)
nNextSemiProfile = EgtGetFirstNameInGroup( vNextProfileId[i], WIN_OUT)
end
end
EgtSetName( nNextCurveId, WIN_GEO_RIGHT)
EgtSetInfo( nNextCurveId, WIN_SEMI_PROFILE, nNextSemiProfile)
EgtRelocateGlob( nNextCurveId, nCurrOffsetId, GDB_IN.BEFORE)
end
EgtSetInfo( nGeoLayerId, WIN_ENDCPDELTA, vNextCPDelta)
-- trim delle curve
TrimAndOrientOrderedCurveLayer( nGeoLayerId, false)
-- salvo spessore serramento nella curva out
local dGeoWidth = b3CurrProfileFrame:getDimX()
EgtSetInfo( nCurrCurveId, WIN_GEOWIDTH, dGeoWidth)
return nCurrCurveId
end
---------------------------------------------------------------------
-- funzione che calcola le lavorazioni di profiling
local function CalcProfilingProcessings( nPartId, nGeoLayerId)
-- creo gruppo delle lavorazioni
local nProcGrp = EgtGroup( nPartId)
EgtSetName( nProcGrp, WIN_PRC)
EgtSetStatus( nProcGrp, GDB_ST.OFF)
-- recupero tutte le curve del geo
local vGeoCrvs = EgtGetAllInGroup( nGeoLayerId)
for i = 1, #vGeoCrvs do
-- copio curva
local nCrv = EgtCopyGlob( vGeoCrvs[i], nProcGrp)
-- recupero il semiprofilo associato
local nSemiProfile = EgtGetInfo( nCrv, WIN_SEMI_PROFILE, 'i')
if nSemiProfile then
-- setto info di lavorazione
EgtSetInfo( nCrv, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.PROFILING)
-- recupero le info di lavorazione dal semiprofilo
CopyInfo( nCrv, nSemiProfile, WIN_PRC_PHASE)
CopyInfo( nCrv, nSemiProfile, WIN_PRC_PROFILE_TYPE)
local nTools = EgtGetInfo( nSemiProfile, WIN_PRC_NTOOLS , 'i') or 0
EgtSetInfo( nCrv, WIN_PRC_NTOOLS, nTools)
for j = 1, nTools do
CopyInfo( nCrv, nSemiProfile, WIN_PRC_TOOL_NAME .. '_' .. tostring(j))
CopyInfo( nCrv, nSemiProfile, WIN_PRC_OFFL .. '_' .. tostring(j))
CopyInfo( nCrv, nSemiProfile, WIN_PRC_OFFR .. '_' .. tostring(j))
end
else
-- se non ha semiprofilo associato è un taglio
EgtSetInfo( nCrv, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.CUT)
end
end
end
---------------------------------------------------------------------
-- funzione che calcola l'ingombro dei pezzi del telaio
local function CalcFrameGeo( nPartId, nOutlineId, nOutlineCrvNbr, nOutlineLayerId, nProfileType)
-- creo layer per ingombro
local nGeoLayerId = EgtGroup( nPartId)
EgtSetName( nGeoLayerId, WIN_GEO)
-- recupero outline precedenti e successivi ( solo nel caso di split possono essere più di uno)
local vPrevOutlineId, vNextOutlineId = GetPrevNextOutline( nProfileType, nOutlineId, nOutlineLayerId)
-- recupero il tipo di giunzioni
local nStartJointType
local nEndJointType
if nProfileType == WIN_PRF.SPLIT or nProfileType == WIN_PRF.BOTTOMRAIL then
-- non serve settare dei valori per StartJointType ed EndJointType perchè in CalcPartJointType la loro giunzione viene settata a short
else
-- recupero i joints dal vettore
local vJoints = EgtGetInfo( nOutlineLayerId, WIN_JOINTS, 'vi')
nStartJointType = vJoints[nOutlineCrvNbr]
nEndJointType = vJoints[nOutlineCrvNbr + 1] or vJoints[1]
-- se giunzione diversa da bisettrice e arco a tutto sesto oppure elementi entrambi dello stesso tipo, forzo il tipo a bisettrice
if nStartJointType ~= WIN_JNT.ANGLED and ( AreSameVectorApprox( EgtEV( vPrevOutlineId[1]), EgtSV( nOutlineId)) or EgtGetName( nOutlineId) == EgtGetName( vPrevOutlineId[1])) then
nStartJointType = WIN_JNT.ANGLED
end
if nEndJointType ~= WIN_JNT.ANGLED and ( AreSameVectorApprox( EgtEV( nOutlineId), EgtSV( vNextOutlineId[1])) or EgtGetName( nOutlineId) == EgtGetName( vNextOutlineId[1])) then
nEndJointType = WIN_JNT.ANGLED
end
end
-- correzione per caso del triangolo
local nProfileTypeS = nProfileType
local nProfileTypeE = nProfileType
if nProfileType == WIN_PRF.TOP then
-- se lato top contro lato bottom, il lato top deve essere trattato come un left/right nel calcolo della giunzione
if EgtGetName( vPrevOutlineId[1]) == WIN_BOTTOM then
nProfileTypeS = WIN_PRF.LEFT
end
if EgtGetName( vNextOutlineId[1]) == WIN_BOTTOM then
nProfileTypeE = WIN_PRF.LEFT
end
end
-- calcolo il tipo di giunzione per la parte
local nStartPartJointType = CalcPartJointType( nProfileTypeS, nStartJointType)
local nEndPartJointType = CalcPartJointType( nProfileTypeE, nEndJointType)
-- salvo i valori joint su outline per disegno solido e calcolo dowels
EgtSetInfo( nOutlineId, WIN_STARTJOINT, nStartPartJointType)
EgtSetInfo( nOutlineId, WIN_ENDJOINT, nEndPartJointType)
-- creo il gruppo con i profili del pezzo
local nProfileLayerId = CalcFrameProfiles( nPartId, nOutlineId, vPrevOutlineId, vNextOutlineId, nProfileType)
-- creo lati dell'outline
local nGeoOutId = CreateFrameGeo( nOutlineId, vPrevOutlineId, vNextOutlineId, nStartPartJointType, nEndPartJointType, nGeoLayerId, nProfileLayerId)
-- calcolo le lavorazioni associate ai profili
CalcProfilingProcessings( nPartId, nGeoLayerId)
return nGeoOutId
end
---------------------------------------------------------------------------------
---------------------------------- DOWELS ----------------------------------------
----------------------------------------------------------------------------------
local function AddStartDowels( nOutlineId, nPrevOutlineId, nProfileLayerId, nDowelLayerId, nGeoLayerId, nMainExtrusionId)
local sOutlineName = EgtGetName( nOutlineId)
local sPrevOutlineName = EgtGetName( nPrevOutlineId)
local nGeoInId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_IN)
local nGeoLeftId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_LEFT)
local nMainProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN)
local nStartProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_START)
local nStartJointType = EgtGetInfo( nOutlineId, WIN_STARTJOINT, 'i')
if nStartJointType == WIN_PART_JNT.ANGLED then
elseif nStartJointType == 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)
-- calcolo il riferimento del profilo
local nFrameProfile = EgtGetFirstNameInGroup( nStartProfileId, WIN_SECTIONFRAME)
local frOrig = EgtFR( nFrameProfile, GDB_ID.ROOT)
frOrig:invert()
-- calcolo il riferimento su cui posizionare i dowel
local ptInt = EgtSP( nGeoLeftId)
local vtRef = EgtSV( nGeoLeftId)
local frDest = Frame3d( ptInt, - vtRef)
-- 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') or 0
end
local dEnd = EgtGetInfo( nOrigDowelId, sEnd, 'd')
if not dEnd then
dEnd = EgtGetInfo( nOrigDowelId, WIN_DWL_TOPPERPEND, 'd') or 0
end
local nDowelId = EgtCopyGlob( nOrigDowelId, nDowelLayerId)
EgtSetColor( nDowelId, Color3d( 128, 128, 128))
-- posiziono il dowel grazie ai riferimenti e assegno estrusione e spessore
EgtTransform( nDowelId, frOrig, GDB_RT.GLOB)
EgtTransform( nDowelId, frDest, GDB_RT.GLOB)
EgtMove( nDowelId, dStart * vtRef)
EgtModifyCurveExtrusion( nDowelId, - vtRef)
EgtModifyCurveThickness( nDowelId, - ( dEnd - dStart))
-- setto info di lavorazione
EgtSetInfo( nDowelId, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.HOLE)
EgtSetInfo( nDowelId, WIN_PRC_DWL_SIDE, WIN_PRC_DWL_SIDETYPE.IN)
if bCalcSolid then
-- creo solido di estrusione
local nDowelExtrusionId = EgtSurfTmByRegionExtrusion( nDowelLayerId, nDowelId, vtRef * ( dEnd - dStart + 1))
EgtMove( nDowelExtrusionId, - vtRef)
-- sottraggo il dowel al solido
EgtSurfTmSubtract( nMainExtrusionId, nDowelExtrusionId)
EgtErase( nDowelExtrusionId)
end
nOrigDowelId = EgtGetNextName( nOrigDowelId, WIN_DOWEL .. '*')
end
elseif nStartJointType == 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
-- calcolo il riferimento del profilo
local nFrameProfile = EgtGetFirstNameInGroup( nMainProfileId, WIN_SECTIONFRAME)
local frOrig = EgtFR( nFrameProfile, GDB_ID.ROOT)
frOrig:invert()
-- calcolo il riferimento su cui posizionare i dowel
local nLeftCopy = EgtCopyGlob( nGeoLeftId, nDowelLayerId)
EgtExtendCurveStartByLen( nLeftCopy, 200)
EgtExtendCurveEndByLen( nLeftCopy, 200)
local ptInt = EgtIP( nOutlineId, nLeftCopy, ORIG())
EgtErase( nLeftCopy)
if not ptInt then
return
end
local dParRef = EgtCurveParamAtPoint( nOutlineId, ptInt)
local vtRef = EgtUV( nOutlineId, dParRef, -1)
local frDest = Frame3d( ptInt, - vtRef)
-- 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') or 0
end
local dEnd = EgtGetInfo( nOrigDowelId, sEnd, 'd')
if not dEnd then
dEnd = EgtGetInfo( nOrigDowelId, WIN_DWL_TOPPARAEND, 'd') or 0
end
local nDowelId = EgtCopyGlob( nOrigDowelId, nDowelLayerId)
EgtSetColor( nDowelId, Color3d( 128, 128, 128))
-- posiziono il dowel grazie ai riferimenti e assegno estrusione e spessore
EgtTransform( nDowelId, frOrig)
EgtTransform( nDowelId, frDest)
EgtMove( nDowelId, vtRef * dStart)
EgtModifyCurveExtrusion( nDowelId, - vtRef)
EgtModifyCurveThickness( nDowelId, - ( dEnd - dStart))
-- setto info di lavorazione
EgtSetInfo( nDowelId, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.HOLE)
EgtSetInfo( nDowelId, WIN_PRC_DWL_SIDE, WIN_PRC_DWL_SIDETYPE.LEFT)
if bCalcSolid then
-- creo solido di estrusione
local nDowelExtrusionId = EgtSurfTmByRegionExtrusion( nDowelLayerId, nDowelId, vtRef * ( dEnd - dStart + 1))
EgtMove( nDowelExtrusionId, - vtRef)
-- sottraggo il dowel al solido
EgtSurfTmSubtract( nMainExtrusionId, nDowelExtrusionId)
EgtErase( nDowelExtrusionId)
end
nOrigDowelId = EgtGetNextName( nOrigDowelId, WIN_DOWEL .. '*')
end
end
end
---------------------------------------------------------------------
local function AddEndDowels( nOutlineId, nEndOutlineId, nProfileLayerId, nDowelLayerId, nGeoLayerId, nMainExtrusionId)
local sOutlineName = EgtGetName( nOutlineId)
local sEndOutlineName = EgtGetName( nEndOutlineId)
local nGeoInId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_IN)
local nGeoRightId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_RIGHT)
local nMainProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN)
local nEndProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_END)
local nEndJointType = EgtGetInfo( nOutlineId, WIN_ENDJOINT, 'i')
if nEndJointType == WIN_PART_JNT.ANGLED then
elseif nEndJointType == 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)
-- calcolo il riferimento del profilo
local nFrameProfile = EgtGetFirstNameInGroup( nEndProfileId, WIN_SECTIONFRAME)
local frOrig = EgtFR( nFrameProfile, GDB_ID.ROOT)
frOrig:invert()
-- calcolo il riferimento su cui posizionare i dowel
local ptInt = EgtEP( nGeoRightId)
local vtRef = EgtEV( nGeoRightId)
local frDest = Frame3d( ptInt, - vtRef)
-- 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') or 0
end
local dEnd = EgtGetInfo( nOrigDowelId, sEnd, 'd')
if not dEnd then
dEnd = EgtGetInfo( nOrigDowelId, WIN_DWL_TOPPERPEND, 'd') or 0
end
local nDowelId = EgtCopyGlob( nOrigDowelId, nDowelLayerId)
EgtSetColor( nDowelId, Color3d( 128, 128, 128))
-- posiziono i fori grazie ai riferimenti e assegno estrusione e spessore
EgtTransform( nDowelId, frOrig)
EgtTransform( nDowelId, frDest)
EgtMove( nDowelId, - vtRef * dStart)
EgtModifyCurveExtrusion( nDowelId, vtRef)
EgtModifyCurveThickness( nDowelId, - ( dEnd - dStart))
-- setto info di lavorazione
EgtSetInfo( nDowelId, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.HOLE)
EgtSetInfo( nDowelId, WIN_PRC_DWL_SIDE, WIN_PRC_DWL_SIDETYPE.IN)
if bCalcSolid then
-- creo solido di estrusione
local nDowelExtrusionId = EgtSurfTmByRegionExtrusion( nDowelLayerId, nDowelId, - vtRef * ( dEnd - dStart + 1))
EgtMove( nDowelExtrusionId, vtRef)
-- sottraggo il dowel al solido
EgtSurfTmSubtract( nMainExtrusionId, nDowelExtrusionId)
EgtErase( nDowelExtrusionId)
end
nOrigDowelId = EgtGetNextName( nOrigDowelId, WIN_DOWEL .. '*')
end
elseif nEndJointType == 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
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
sStart = WIN_DWL_SPLITPARASTART
sEnd = WIN_DWL_SPLITPARAEND
end
end
-- calcolo il riferimento del profilo
local nFrameProfile = EgtGetFirstNameInGroup( nMainProfileId, WIN_SECTIONFRAME)
local frOrig = EgtFR( nFrameProfile, GDB_ID.ROOT)
frOrig:invert()
-- calcolo il riferimento su cui posizionare i dowel
local nRightCopy = EgtCopyGlob( nGeoRightId, nDowelLayerId)
EgtExtendCurveStartByLen( nRightCopy, 200)
EgtExtendCurveEndByLen( nRightCopy, 200)
local ptInt = EgtIP( nOutlineId, nRightCopy, ORIG())
EgtErase( nRightCopy)
if not ptInt then
return
end
local dParRef = EgtCurveParamAtPoint( nOutlineId, ptInt)
local vtRef = EgtUV( nOutlineId, dParRef, -1)
local frDest = Frame3d( ptInt, - vtRef)
-- 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') or 0
end
local dEnd = EgtGetInfo( nOrigDowelId, sEnd, 'd')
if not dEnd then
dEnd = EgtGetInfo( nOrigDowelId, WIN_DWL_TOPPARAEND, 'd') or 0
end
local nDowelId = EgtCopyGlob( nOrigDowelId, nDowelLayerId)
EgtSetColor( nDowelId, Color3d( 128, 128, 128))
-- posiziono i fori grazie ai riferimenti e assegno estrusione e spessore
EgtTransform( nDowelId, frOrig, GDB_RT.GLOB)
EgtTransform( nDowelId, frDest, GDB_RT.GLOB)
EgtMove( nDowelId, - vtRef * dStart)
EgtModifyCurveExtrusion( nDowelId, vtRef)
EgtModifyCurveThickness( nDowelId, - ( dEnd - dStart))
-- setto info di lavorazione
EgtSetInfo( nDowelId, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.HOLE)
EgtSetInfo( nDowelId, WIN_PRC_DWL_SIDE, WIN_PRC_DWL_SIDETYPE.RIGHT)
if bCalcSolid then
-- creo solido di estrusione
local nDowelExtrusionId = EgtSurfTmByRegionExtrusion( nDowelLayerId, nDowelId, - vtRef * ( dEnd - dStart + 1))
EgtMove( nDowelExtrusionId, vtRef)
-- sottraggo il dowel al solido
EgtSurfTmSubtract( nMainExtrusionId, nDowelExtrusionId)
EgtErase( nDowelExtrusionId)
end
nOrigDowelId = EgtGetNextName( nOrigDowelId, WIN_DOWEL .. '*')
end
end
end
---------------------------------------------------------------------
-- funzione che calcola intersezione, geometrie e superfici dei dowel degli split
local function CalSplitDowel( nSplitLayerId, nOutlineId, nProfileType, nPartId)
-- verifico se interseca l'outline che sto analizzando
local nSplitId = EgtGetFirstInGroup( nSplitLayerId)
local ptInt = EgtIP( nOutlineId, nSplitId, EgtSP( nSplitId))
if not ptInt then
return
end
-- TO DO gestire il caso in cui lo split ha due intersezioni con l'outline
-- se interseca, recupero il profilo dello split
local nOrigSplitProfileId = GetOutlineProfileId( nSplitId, false)
-- creo copia del profilo
local nFrameProfileLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE)
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 o Out del geo
local nGeoLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO)
local nGeoCrvId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_IN)
local ptInters = EgtIP( nGeoCrvId, nSplitId, EgtSP( nSplitId))
local sDowelRefSide = WIN_PRC_DWL_SIDETYPE.IN
if not ptInters and nProfileType == WIN_PRF.SPLIT then
nGeoCrvId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_OUT)
ptInters = EgtIP( nGeoCrvId, nSplitId, EgtSP( nSplitId))
sDowelRefSide = WIN_PRC_DWL_SIDETYPE.OUT
end
-- se non trovo intersezione esco ( TO DO da sistemare perchè anche se non trova intersezione potrebbe essere coinvolto dai dowels dello split!)
if not ptInters then
return
end
-- recupero frame del profilo e lo applico a tutte le sue geometrie
local nSplitProfileFrameId = EgtGetFirstNameInGroup( nSplitProfileId, WIN_SECTIONFRAME)
local frInvertSplitProfile = EgtFR( nSplitProfileFrameId)
frInvertSplitProfile:invert()
EgtTransform( EgtGetAllInGroup( nSplitProfileId), frInvertSplitProfile)
-- assegno come riferimento del profilo il punto di intersezione e la direzione dello split
local vtDir = - EgtSV( nSplitId) -- se non fosse lineare potrebbe essere end vector ?
EgtChangeGroupFrame( nSplitProfileId, Frame3d( ptInters, vtDir))
-- calcolo la direzione del dowel sempre verso l'interno del pezzo
local vtDowelDir = Vector3d( vtDir)
local _, _, nSide = EgtPointCurveDistSide( ptInters + vtDowelDir, nGeoCrvId, Z_AX())
if nSide == 1 then
-- se a destra della curva significa che la direzione è uscente dal pezzo e va invertita
vtDowelDir = - vtDowelDir
end
-- recupero solido del pezzo ( se non esiste è nil)
local nSolidLayerId = EgtGetFirstNameInGroup( nPartId, WIN_SOLID) or GDB_ID.NULL
local nMainExtrusionId = EgtGetFirstNameInGroup( nSolidLayerId, WIN_SRF_MAIN)
-- creo fori per spine su Split
local nProcLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PRC)
-- 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
-- se poggia sul controprofilo CntrIn2 leggo le info dello split orizzontale, altrimenti vanno bene quelle del top
-- ( cfr AddStartDowels e AddEndDowels)
if AreSamePointApprox( ptInt, EgtSP( nSplitId)) then
sStart = WIN_DWL_HORIZONTALSPLITPERPSTART
sEnd = WIN_DWL_HORIZONTALSPLITPERPEND
end
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, nProcLayerId)
EgtSetColor( nDowelId, Color3d( 128, 128, 128))
-- posiziono il dowel e gli assegno estrusione e spessore
EgtMove( nDowelId, vtDowelDir * dStart)
EgtModifyCurveExtrusion( nDowelId, - vtDowelDir)
EgtModifyCurveThickness( nDowelId, - ( dEnd - dStart))
-- setto info di lavorazione
EgtSetInfo( nDowelId, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.HOLE)
EgtSetInfo( nDowelId, WIN_PRC_DWL_SIDE, sDowelRefSide)
if bCalcSolid then
-- creo solido di estrusione
local nDowelExtrusionId = EgtSurfTmByRegionExtrusion( nSolidLayerId, nDowelId, vtDowelDir * ( dEnd - dStart + 1))
EgtMove( nDowelExtrusionId, - vtDowelDir)
-- sottraggo il dowel al solido
EgtSurfTmSubtract( nMainExtrusionId, nDowelExtrusionId)
EgtErase( nDowelExtrusionId)
end
nOrigDowelId = EgtGetNextName( nOrigDowelId, WIN_DOWEL .. '*')
end
end
----------------------------------------------------------------------------------
-- funzione che cicla ricorsivamente sulle aree e sottoaree relative al pezzo per aggiungere gli split dowels
local function AddAreaSplitDowels( nOutlineId, nPartId, nProfileType, nAreaLayerId)
-- verifico la presenza di eventuali split nell'area corrente
local nSplitLayerId = EgtGetFirstNameInGroup( nAreaLayerId, WIN_SPLIT)
if nSplitLayerId then
local nSplitType = EgtGetInfo( nSplitLayerId, WIN_SPLITTYPE, 'i') or WIN_SPLITTYPES.NULL
if nSplitType ~= WIN_SPLITTYPES.FRENCH then
CalSplitDowel( nSplitLayerId, nOutlineId, nProfileType, nPartId)
end
end
-- verifico la presenza di split nelle sottoaree
local nChildAreaId = EgtGetFirstNameInGroup( nAreaLayerId, WIN_AREA .. '*')
while nChildAreaId do
local nAreaType = EgtGetInfo( nChildAreaId, WIN_AREATYPE, 'i')
if nAreaType == WIN_AREATYPES.SPLIT then
AddAreaSplitDowels( nOutlineId, nPartId, nProfileType, nChildAreaId)
end
nChildAreaId = EgtGetNextName( nChildAreaId, WIN_AREA .. '*')
end
end
----------------------------------------------------------------------------------
-- funzione che aggiunge al solido i dowels degli split che lo intersecano
local function AddSplitDowels( nOutlineId, nOutlineLayerId, nPartId, nProfileType)
-- se profilo bottom con BottomRail esco ( gli split dowels saranno aggiuti sul BottomRail associato)
if nProfileType == WIN_PRF.BOTTOM then
local bBottomRail = EgtGetInfo( nOutlineLayerId, WIN_BOTTOMRAIL, 'b') or false
if bBottomRail then
return
end
end
-- recupero area del pezzo
local nAreaLayerId = EgtGetParent( nOutlineLayerId)
-- aggiungo gli split dowels a partire dall'area corrente
AddAreaSplitDowels( nOutlineId, nPartId, nProfileType, nAreaLayerId)
end
---------------------------------------------------------------------
-- funzione che crea i fori per le spine
local function CalcFrameDowels( nPartId, nOutlineId, nOutlineLayerId, nProfileType)
-- creo fori per spine su Start ed End
local vPrevOutlineId, vNextOutlineId = GetPrevNextOutline( nProfileType, nOutlineId, nOutlineLayerId)
local nProfileLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE)
local nProcLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PRC)
local nGeoLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO)
local nMainExtrusionId
if bCalcSolid then
local nSolidLayerId = EgtGetFirstNameInGroup( nPartId, WIN_SOLID)
nMainExtrusionId = EgtGetFirstNameInGroup( nSolidLayerId, WIN_SRF_MAIN)
end
for i = 1, #vPrevOutlineId do
AddStartDowels( nOutlineId, vPrevOutlineId[i], nProfileLayerId, nProcLayerId, nGeoLayerId, nMainExtrusionId)
end
for i = 1, #vNextOutlineId do
AddEndDowels( nOutlineId, vNextOutlineId[i], nProfileLayerId, nProcLayerId, nGeoLayerId, nMainExtrusionId)
end
-- split dowels
AddSplitDowels( nOutlineId, nOutlineLayerId, nPartId, nProfileType)
end
----------------------------------------------------------------------------------
---------------------------------- SOLIDO ----------------------------------------
----------------------------------------------------------------------------------
-- funzione che recupera tipo di inizio e fine pezzo
local function CalcStartEndProfileType( nProfileType, nOutlineId, vStartProfileId, vEndProfileId)
local vsStartProfileType = {}
local vsEndProfileType = {}
if nProfileType == WIN_PRF.SPLIT then
local vStartBaseOutlineId = EgtGetInfo( nOutlineId, WIN_SPLIT_STARTINTERS, 'vi')
for i = 1, #vStartProfileId do
local nStartId = EgtGetInfo( vStartBaseOutlineId[i], WIN_COPY, 'i')
local sStartProfileType = GetProfileCtrIn( nStartId, nOutlineId, vStartProfileId[i])
table.insert( vsStartProfileType, WIN_OFST .. sStartProfileType)
end
local vEndBaseOutlineId = EgtGetInfo( nOutlineId, WIN_SPLIT_ENDINTERS, 'vi')
for i = 1, #vEndProfileId do
local nEndId = EgtGetInfo( vEndBaseOutlineId[i], WIN_COPY, 'i')
local sEndProfileType = GetProfileCtrIn( nEndId, nOutlineId, vEndProfileId[i])
table.insert( vsEndProfileType, WIN_OFST .. sEndProfileType)
end
else
local StartJointType = EgtGetInfo( nOutlineId, WIN_STARTJOINT, 'i')
if StartJointType == WIN_PART_JNT.ANGLED then
vsStartProfileType = { WIN_MINIZINKEN}
elseif StartJointType == WIN_PART_JNT.SHORT then
vsStartProfileType = { WIN_CTRINOFST}
elseif StartJointType == WIN_PART_JNT.FULL then
vsStartProfileType = { WIN_OUTOFST}
end
local EndJointType = EgtGetInfo( nOutlineId, WIN_ENDJOINT, 'i')
if EndJointType == WIN_PART_JNT.ANGLED then
vsEndProfileType = { WIN_MINIZINKEN}
elseif EndJointType == WIN_PART_JNT.SHORT then
vsEndProfileType = { WIN_CTRINOFST}
elseif EndJointType == WIN_PART_JNT.FULL then
vsEndProfileType = { WIN_OUTOFST}
end
end
return vsStartProfileType, vsEndProfileType
end
---------------------------------------------------------------------
-- funzione che crea il solido del pezzo del telaio
local function CalcFrameSolid( nPartId, nOutlineId, nGeoId, nProfileType)
-- creo layer per solido
local nSolidLayerId = EgtGroup( nPartId)
EgtSetName( nSolidLayerId, WIN_SOLID)
-- recupero layer delle lavorazioni per i dowels
local nProcLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PRC)
-- recupero profili e controprofili
local nProfileLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE)
local nMainProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN)
local vStartProfileId = EgtGetNameInGroup( nProfileLayerId, WIN_PRF_START)
local vEndProfileId = EgtGetNameInGroup( nProfileLayerId, WIN_PRF_END)
-- recupero geo
local nGeoLayerId = EgtGetParent( nGeoId)
local vPrevGeoId = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_LEFT)
local vNextGeoId = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_RIGHT)
-- recupero BBox e larghezza del geo
local dGeoWidth = EgtGetInfo( nGeoId, WIN_GEOWIDTH, 'd')
-- recupero i controprofili in base al tipo di giunzioni
local vsStartProfileType, vsEndProfileType = CalcStartEndProfileType( nProfileType, nOutlineId, vStartProfileId, vEndProfileId)
-- verifico se outline è split interno ad area di split per controlli su inversione del profilo
local bSplitInsideSplitArea = false
if nProfileType == WIN_PRF.SPLIT then
local nAreaId = EgtGetParent( EgtGetParent( nOutlineId))
local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i')
bSplitInsideSplitArea = ( nAreaType == WIN_AREATYPES.SPLIT)
end
-- a) MAIN EXTRUSION
-- creo guida Main
local nGuideId = EgtCopy( nOutlineId, nSolidLayerId)
EgtSetName( nGuideId, WIN_MAINGUIDE)
EgtSetStatus( nGuideId, GDB_ST.OFF)
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
local vStartDelta = EgtGetInfo( nGeoLayerId, WIN_STARTCPDELTA, 'vd')
for i = 1, #vPrevGeoId do
-- posiziono il profilo Start
local nRefStartProfileId = EgtGetFirstNameInGroup( vStartProfileId[i], WIN_REF)
local b3RefStartProfile = EgtGetBBoxGlob( nRefStartProfileId, GDB_BB.STANDARD)
-- creo guida per estrusione con estensione in tangenza
local nStartGuideId = EgtCopy( vPrevGeoId[i], nSolidLayerId)
if EgtGetType( nStartGuideId) == GDB_TY.CRV_LINE then
EgtExtendCurveStartByLen( nStartGuideId, 4 * dGeoWidth)
EgtExtendCurveEndByLen( nStartGuideId, 4 * dGeoWidth)
else
nStartGuideId = EgtCurveCompo( nSolidLayerId, nStartGuideId)
EgtAddCurveCompoLineTg( nStartGuideId, 4 * dGeoWidth)
EgtAddCurveCompoLineTg( nStartGuideId, 4 * dGeoWidth, false)
end
-- recupero frame del profilo
local nStartProfileFrameId = EgtGetFirstNameInGroup( vStartProfileId[i], WIN_SECTIONFRAME)
local frStartProfile = EgtFR( nStartProfileFrameId)
-- lo sposto se controprofilo
frStartProfile:move( - frStartProfile:getVersX() * vStartDelta[i])
frStartProfile:invert()
-- lo applico a tutte le geometrie del profilo
EgtTransform( EgtGetAllInGroup( vStartProfileId[i]), frStartProfile)
-- assegno come riferimento del profilo il punto start dell'outline
EgtChangeGroupFrame( vStartProfileId[i], Frame3d( EgtSP( nStartGuideId), - EgtSV( nStartGuideId)))
if bSplitInsideSplitArea then
-- verifico se il suo start deriva da uno split
local vStartId = EgtGetInfo( nOutlineId, WIN_SPLIT_STARTINTERS, 'vi')
local nStartSouId = vStartId[i]
local sStartSouName
repeat
nStartSouId = EgtGetInfo( nStartSouId, WIN_SOU, 'i')
sStartSouName = EgtGetName( nStartSouId or GDB_ID.NULL)
until not nStartSouId or sStartSouName == WIN_SPLIT
if sStartSouName == WIN_SPLIT then
-- recupero vettore tangente nel punto medio della curva di contorno
local ptMidStart = EgtMP( vStartId[i])
local vtMidStart = EgtMV( vStartId[i])
-- 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 AreSameVectorApprox( vtMidStart, vtMidStartSou) then
-- ruoto di 180 gradi il profilo
local frStartProfileS = EgtFR( nStartProfileFrameId, GDB_ID.ROOT)
EgtRotate( vStartProfileId[i], frStartProfileS:getOrigin(), frStartProfileS:getVersY(), 180, GDB_RT.GLOB)
end
end
end
-- recupero outline del profilo Start e lo estrudo
local nOutStartProfileId
if vsStartProfileType[i] == WIN_MINIZINKEN then
nOutStartProfileId = EgtLine( vStartProfileId[i], EgtSP( vPrevGeoId[i]), EgtSP( vPrevGeoId[i]) - Z_AX() * b3RefStartProfile:getDimY(), GDB_RT.GLOB)
EgtInvertCurve( nOutStartProfileId)
else
nOutStartProfileId = EgtGetFirstNameInGroup( vStartProfileId[i], vsStartProfileType[i])
end
local nStartExtrusionId = EgtSurfTmSwept( nSolidLayerId, nOutStartProfileId, nStartGuideId, false, WIN_SURF_APPROX)
-- eseguo intersezione per ottenere un solido unico
-- ( tagliare le due superfici con EgtSurfTmCut e poi unirle potrebbe creare piccoli buchi legati alle diverse approssimazioni)
EgtSurfTmIntersect( nMainExtrusionId, nStartExtrusionId)
EgtErase( nStartExtrusionId)
EgtErase( nStartGuideId)
end
-- c) END PROFILE
local vEndDelta = EgtGetInfo( nGeoLayerId, WIN_ENDCPDELTA, 'vd')
for i = 1, #vNextGeoId do
-- posiziono il profilo End
local nRefEndProfileId = EgtGetFirstNameInGroup( vEndProfileId[i], WIN_REF)
local b3RefEndProfile = EgtGetBBoxGlob( nRefEndProfileId, GDB_BB.STANDARD)
-- creo guida per estrusione
local nEndGuideId = EgtCopy( vNextGeoId[i], nSolidLayerId)
if EgtGetType( nEndGuideId) == GDB_TY.CRV_LINE then
EgtExtendCurveStartByLen( nEndGuideId, 4 * dGeoWidth)
EgtExtendCurveEndByLen( nEndGuideId, 4 * dGeoWidth)
else
nEndGuideId = EgtCurveCompo( nSolidLayerId, nEndGuideId)
EgtAddCurveCompoLineTg( nEndGuideId, 4 * dGeoWidth)
EgtAddCurveCompoLineTg( nEndGuideId, 4 * dGeoWidth, false)
end
-- recupero frame del profilo
local nEndProfileFrameId = EgtGetFirstNameInGroup( vEndProfileId[i], WIN_SECTIONFRAME)
local frEndProfile = EgtFR( nEndProfileFrameId)
frEndProfile:move( - frEndProfile:getVersX() * vEndDelta[i])
frEndProfile:invert()
-- lo applico a tutte le geometrie del profilo
EgtTransform( EgtGetAllInGroup( vEndProfileId[i]), frEndProfile)
-- assegno come riferimento del profilo il punto start dell'outline
EgtChangeGroupFrame( vEndProfileId[i], Frame3d( EgtSP( nEndGuideId), - EgtSV( nEndGuideId)))
-- verifico se necessario ruotare di 180 gradi il profilo
if bSplitInsideSplitArea then
-- verifico se end deriva da split
local vEndId = EgtGetInfo( nOutlineId, WIN_SPLIT_ENDINTERS, 'vi')
local nEndSouId = vEndId[i]
local sEndSouName
repeat
nEndSouId = EgtGetInfo( nEndSouId, WIN_SOU)
sEndSouName = EgtGetName( nEndSouId or GDB_ID.NULL)
until not nEndSouId or sEndSouName == WIN_SPLIT
if sEndSouName == WIN_SPLIT then
-- recupero vettore tangente nel punto medio della curva di contorno
local ptMidEnd = EgtMP( vEndId[i])
local vtMidEnd = EgtMV( vEndId[i])
-- 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 AreSameVectorApprox( vtMidEnd, vtMidEndSou) then
-- ruoto di 180 gradi il profilo
local frEndProfileS = EgtFR( nEndProfileFrameId, GDB_ID.ROOT)
EgtRotate( vEndProfileId[i], frEndProfileS:getOrigin(), frEndProfileS:getVersY(), 180, GDB_RT.GLOB)
end
end
end
-- recupero outline del profilo End e lo estrudo
local nOutEndProfileId
if vsEndProfileType[i] == WIN_MINIZINKEN then
nOutEndProfileId = EgtLine( vEndProfileId[i], EgtSP( vNextGeoId[i]), EgtSP( vNextGeoId[i]) - Z_AX() * b3RefEndProfile:getDimY(), GDB_RT.GLOB)
EgtInvertCurve( nOutEndProfileId)
else
nOutEndProfileId = EgtGetFirstNameInGroup( vEndProfileId[i], vsEndProfileType[i])
end
local nEndExtrusionId = EgtSurfTmSwept( nSolidLayerId, nOutEndProfileId, nEndGuideId, false, WIN_SURF_APPROX)
-- eseguo intersezione per ottenere un solido unico
EgtSurfTmIntersect( nMainExtrusionId, nEndExtrusionId)
EgtErase( nEndExtrusionId)
EgtErase( nEndGuideId)
end
end
---------------------------------------------------------------------
-- funzione che calcola l'ingombro dei pezzi del telaio e i loro solidi
local function CreatePartFromOutline( nAreaLayerId, nOutlineId, nOutlineCrvNbr, bBottomRail)
-- creo pezzo
local nPartId = EgtGroup( GDB_ID.ROOT)
-- inserisco riferimento alla sua area
EgtSetInfo( nPartId, WIN_AREA, nAreaLayerId)
local nAreaType = EgtGetInfo( nAreaLayerId, WIN_AREATYPE, 'i')
local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaLayerId, WIN_OUTLINE)
-- a) Telaio, anta o split
if nAreaType == WIN_AREATYPES.FRAME or nAreaType == WIN_AREATYPES.SASH or nAreaType == WIN_AREATYPES.SPLIT then
-- creo riferimenti tra pezzo e outline
EgtSetInfo( nPartId, WIN_REF_OUTLINE, nOutlineId)
if bBottomRail then
EgtSetInfo( nOutlineId, WIN_REF_BOTTOMRAIL_PART, nPartId)
else
EgtSetInfo( nOutlineId, WIN_REF_PART, nPartId)
end
-- imposto nome del pezzo
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
-- setto le info di sovramateriale ( TO DO : capire da dove devono essere ricavate)
EgtSetInfo( nPartId, WIN_PRC_OVERMAT_IN, 0)
EgtSetInfo( nPartId, WIN_PRC_OVERMAT_OUT, 0)
EgtSetInfo( nPartId, WIN_PRC_OVERMAT_LEFT, 0)
EgtSetInfo( nPartId, WIN_PRC_OVERMAT_RIGHT, 0)
-- ricavo il tipo di profilo
local nProfileType = GetOutlineProfileType( nOutlineId, bBottomRail)
-- disegno ingombro
local nGeoId = CalcFrameGeo( nPartId, nOutlineId, nOutlineCrvNbr, nOutlineLayerId, nProfileType)
-- disegno solido
if bCalcSolid then
CalcFrameSolid( nPartId, nOutlineId, nGeoId, nProfileType)
end
-- calcolo i fori per le spine
CalcFrameDowels( nPartId, nOutlineId, nOutlineLayerId, nProfileType)
-- b) Fill
elseif nAreaType == WIN_AREATYPES.FILL then
-- imposto nome del pezzo
EgtSetName( nPartId, WIN_FILL)
-- ricavo tipo
local nFillType = EgtGetInfo( nAreaLayerId, WIN_FILLTYPE, 'i')
-- imposto colore
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
-- disegno ingombro
local nGeoLayerId = CalcFillGeo( nPartId, nOutlineLayerId)
-- disegno solido
if bCalcSolid then
CalcFillSolid( nPartId, nOutlineLayerId, nGeoLayerId)
end
end
return nPartId
end
---------------------------------------------------------------------
---------------------------- STRIP ----------------------------------
---------------------------------------------------------------------
-- funzione che restitutisce lo Strip piu' vicino
-- ( analoga a GetProfileCtrIn)
local function GetStripNearestToOutline( nPrevProfileId, nPrevOutlineId, nOutlineId)
local nStripId = EgtGetFirstNameInGroup( nPrevProfileId, WIN_STRIP)
-- gestione particolare del caso di profilo di split
if not nStripId then
-- recupero la curva di base outline da cui deriva il precedente
local nPrevSouId = EgtGetInfo( nPrevOutlineId, WIN_COPY, 'i')
local sPrevSouName
repeat
nPrevSouId = EgtGetInfo( nPrevSouId, WIN_SOU, 'i')
sPrevSouName = EgtGetName( nPrevSouId or GDB_ID.NULL)
until not nPrevSouId or sPrevSouName == WIN_SPLIT
-- verifico da quale lato si trova la curva per decidere quale controprofilo considerare
local _, _, dSide = EgtPointCurveDistSide( EgtMP( nOutlineId), nPrevSouId, Z_AX())
if dSide == 1 then
nStripId = EgtGetFirstNameInGroup( nPrevProfileId, WIN_STRIP .. '1') -- dx
else
nStripId = EgtGetFirstNameInGroup( nPrevProfileId, WIN_STRIP .. '2') -- sx
end
end
return nStripId
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 = FindAssociatedPart( nOutlineId)
-- recupero layer per solido e per profili di estrusione
local nSolidLayerId = EgtGetFirstNameInGroup( nPartId, WIN_SOLID)
local nMainProfileLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE)
-- recupero gli outline precedente e successivo ( non serve utilizzare un WIN_PRF accurato perchè conta solo sia diverso da split)
local nOutlineLayerId = EgtGetParent( nOutlineId)
local vPrevOutlineId, vNextOutlineId = GetPrevNextOutline( WIN_PRF.NULL, nOutlineId, nOutlineLayerId)
local nPrevOutlineId = vPrevOutlineId[1]
local nNextOutlineId = vNextOutlineId[1]
-- recupero i pezzi precedente e successivo, prendendo eventualmente quelli di bottomrail
local nPrevPartId = FindAssociatedPart( nPrevOutlineId)
local nNextPartId = FindAssociatedPart( nNextOutlineId)
-- recupero profilo e controprofili
local nMainProfileId = EgtGetFirstNameInGroup( nMainProfileLayerId, WIN_PRF_MAIN)
local nPrevProfileLayerId = EgtGetFirstNameInGroup( nPrevPartId, WIN_PROFILE)
local nStartProfileId = EgtGetFirstNameInGroup( nPrevProfileLayerId, WIN_PRF_MAIN)
local nNextProfileLayerId = EgtGetFirstNameInGroup( nNextPartId, WIN_PROFILE)
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, nOutlineId, nPrevOutlineId)
-- estrudo MainStrip
local nMainStripExtrusionId = EgtSurfTmSwept( nSolidLayerId, nMainStripId, nGuideId, false, WIN_SURF_APPROX)
EgtSetName( nMainStripExtrusionId, WIN_SRF_STRIP)
-- b) taglio con start
-- recupero strip dello start piu' vicino ad outline
local nStartStripId = GetStripNearestToOutline( nStartProfileId, nPrevOutlineId, nOutlineId)
-- 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 = FindIntersectionPoint( nMainStripMinOffsetId, nStartStripMinOffsetId, EgtSP( nMainStripMinOffsetId))
local ptStripMaxStart = FindIntersectionPoint( nMainStripMaxOffsetId, nStartStripMaxOffsetId, EgtSP( nMainStripMinOffsetId))
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)
-- intersezione con main
EgtSurfTmIntersect( nMainStripExtrusionId, nStartStripExtrusionId)
-- c) taglio con end
-- recupero strip piu' vicino ad outline
local nEndStripId = GetStripNearestToOutline( nEndProfileId, nNextOutlineId, nOutlineId)
-- 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 = FindIntersectionPoint( nMainStripMinOffsetId, nEndStripMinOffsetId, EgtEP( nMainStripMinOffsetId))
local ptStripMaxEnd = FindIntersectionPoint( nMainStripMaxOffsetId, nEndStripMaxOffsetId, EgtEP( 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)
-- intersezione con main
EgtSurfTmIntersect( nMainStripExtrusionId, nEndStripExtrusionId)
-- cancello curve e superfici di costruzione
EgtErase( { nMainStripMinOffsetId, nMainStripMaxOffsetId})
EgtErase( { nStartStripMinOffsetId, nStartStripMaxOffsetId, nStartStripGuideId, nStartStripProfileId, nStartStripExtrusionId})
EgtErase( { nEndStripMinOffsetId, nEndStripMaxOffsetId, nEndStripGuideId, nEndStripProfileId, nEndStripExtrusionId})
end
---------------------------------------------------------------------
-- funzione che cicla ricorsivamente su aree e sottoaree per calcolare i pezzi
local function CalculateAreaParts( nAreaId)
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 vOutlines = EgtGetAllInGroup( nOutlineLayerId)
for i = 1, #vOutlines do
-- creo pezzo
CreatePartFromOutline( nAreaId, vOutlines[i], i)
-- se di tipo bottom verifico se ha bottomrail
local sName = EgtGetName( vOutlines[i])
if sName == WIN_BOTTOM then
local bBottomRail = EgtGetInfo( nOutlineLayerId, WIN_BOTTOMRAIL, 'b') or false
if bBottomRail then
CreatePartFromOutline( nAreaId, vOutlines[i], i, true)
end
end
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
local nSplitPartId = CreatePartFromOutline( nAreaId, nSplitId)
-- disegno area di selezione per programma
local nSelectionLayerId = EgtGroup( nAreaId)
EgtSetName( nSelectionLayerId, WIN_SPLITSELECTION)
EgtSetStatus( nSelectionLayerId, GDB_ST.OFF)
local nSplitPartGeoId = EgtGetFirstNameInGroup( nSplitPartId, WIN_GEO)
-- costruisco curva semplificata a partire dai lati out e in per evitare problemi con autointersezioni del geo
local nGeoOut = EgtGetFirstNameInGroup( nSplitPartGeoId, WIN_GEO_OUT)
local nGeoIn = EgtGetFirstNameInGroup( nSplitPartGeoId, WIN_GEO_IN)
local nCompoId = EgtCurveCompo( nSelectionLayerId, nGeoOut, false)
EgtAddCurveCompoLine( nCompoId, EgtSP( nGeoIn))
EgtAddCurveCompoCurve( nCompoId, nGeoIn, false)
EgtCloseCurveCompo( nCompoId)
local nSelectionArea = EgtSurfFlatRegion( nSelectionLayerId, nCompoId)
EgtSetColor( nSelectionArea, 'YELLOW')
EgtSetAlpha( nSelectionArea, 10)
EgtMove( nSelectionArea, 10 * Z_AX())
EgtErase( nCompoId)
end
end
elseif nAreaType ~= WIN_AREATYPES.FILL then
if bCalcSolid then
--- verifico se area successiva e' un fill
local nChildAreaId = EgtGetFirstNameInGroup( nAreaId, WIN_AREAASTERISK)
local nChildAreaType = EgtGetInfo( nChildAreaId or GDB_ID.NULL, 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
-- disegno area di selezione per programma
local nSelectionLayerId = EgtGroup( nAreaId)
EgtSetName( nSelectionLayerId, WIN_SELECTION)
EgtSetStatus( nSelectionLayerId, GDB_ST.OFF)
local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE)
local vOutlineList = EgtGetAllInGroup( nOutlineLayerId)
local nCompoId = EgtCurveCompo( nSelectionLayerId, vOutlineList, false)
local nSelectionArea = EgtSurfFlatRegion( nSelectionLayerId, nCompoId)
EgtSetColor( nSelectionArea, 'YELLOW')
EgtSetAlpha( nSelectionArea, 10)
EgtMove( nSelectionArea, 10 * Z_AX())
EgtErase( nCompoId)
-- calcolo i pezzi delle sottoaree
local nChildAreaId = EgtGetFirstNameInGroup( nAreaId, WIN_AREA .. '*')
while nChildAreaId do
CalculateAreaParts( nChildAreaId)
nChildAreaId = EgtGetNextName( nChildAreaId, WIN_AREA .. '*')
end
end
---------------------------------------------------------------------
------------------------- FUNZIONI ----------------------------------
---------------------------------------------------------------------
-- funzione che crea tutti i pezzi della finestra partendo dal telaio
function WinCalculate.CreatePartFromArea( nFrameId)
-- assengo il tipo di profilo alle curve del base outline
CalculateAreaProfileType( nFrameId)
-- calcolo outline a partire dal base outline
CalculateAreaOutline( nFrameId)
-- creo pezzi
CalculateAreaParts( nFrameId)
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
---------------------------------------------------------------------
-- funzione che prepara il progetto per passarlo all'automatismo delle lavorazioni
function WinCalculate.PrepareProject()
-- elimino il gruppo dei profili
local nProfileLay = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_PROFILE)
EgtErase( nProfileLay)
-- elimino il gruppo delle aree
local nAreaLay = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_AREA .. '*')
EgtErase( nAreaLay)
-- elimino i pezzi di tipo fill
local vFills = EgtGetNameInGroup( GDB_ID.ROOT, WIN_FILL)
EgtErase( vFills)
-- in ogni pezzo
local nPartId = EgtGetFirstInGroup( GDB_ID.ROOT)
while nPartId do
-- cancello il gruppo dei profili
local nProfileGrp = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE)
EgtErase( nProfileGrp)
-- accendo gruppo delle lavorazioni
local nProcLay = EgtGetFirstNameInGroup( nPartId, WIN_PRC)
EgtSetStatus( nProcLay, GDB_ST.ON)
-- nel gruppo dei solidi conservo solo quello principale
local nSolidGrp = EgtGetFirstNameInGroup( nPartId, WIN_SOLID)
if nSolidGrp then
local nMainSolid = EgtGetFirstNameInGroup( nSolidGrp, WIN_SRF_MAIN)
local vIds = EgtGetAllInGroup( nSolidGrp)
for i = 1, #vIds do
if vIds[i] ~= nMainSolid then
EgtErase( vIds[i])
end
end
end
-- nel gruppo geo creo frame ausiliario
local nGeoLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO)
local nOutCrv = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_OUT)
local vtS = EgtSV( nOutCrv)
local frGeo = Frame3d( EgtSP( nOutCrv), vtS, Z_AX() ^ vtS, Z_AX())
local nFrameId = EgtFrame( nGeoLayerId, frGeo)
EgtSetName( nFrameId, WIN_PRC_FRAME)
-- passo al pezzo successivo
nPartId = EgtGetNext( nPartId)
end
end
---------------------------------------------------------------------
------------------------ FERRAMENTA ---------------------------------
---------------------------------------------------------------------
local function SearchSash( nAreaId, SashList)
-- verifico il tipo
local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i')
--if nAreaType == WIN_AREATYPES.FRAME then
if nAreaType == WIN_AREATYPES.SASH then
-- calcolo il Box
local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE)
local b3Outline = EgtGetBBox( nOutlineLayerId, GDB_BB.STANDARD)
-- recupero punti di origine
local nSashFrameLayerId = EgtGroup( nAreaId)
EgtSetName( nSashFrameLayerId, WIN_HDW_FRAME)
local vOutlineCopy = {}
local nOutlineOffsetLayerId = EgtGroup( nAreaId)
local nOutlineId = EgtGetFirstInGroup( nOutlineLayerId)
while nOutlineId do
local sProfileType = EgtGetInfo( nOutlineId, WIN_PROFILETYPE)
local nProfileId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_PROFILE, 'i')
local nSashProfileId = EgtGetFirstNameInGroup( nProfileId, WIN_SASH, 'i')
local nSashProfileTypeId = EgtGetFirstNameInGroup( nSashProfileId, sProfileType, 'i')
local dGapDelta = EgtGetInfo( nSashProfileTypeId, WIN_GAPDELTA, 'd')
local dGapDeltaZ = EgtGetInfo( nSashProfileTypeId, WIN_GAPDELTAZ, 'd')
local nOutlineCopyId = EgtCopy( nOutlineId, nOutlineOffsetLayerId)
EgtSetInfo( nOutlineCopyId, 'ORIG', nOutlineId)
EgtSetInfo( nOutlineCopyId, WIN_GAPDELTAZ, dGapDeltaZ)
local nSectionFrameId = EgtGetFirstNameInGroup( nSashProfileTypeId, WIN_SECTIONFRAME)
local frSectionFrame = EgtFR( nSectionFrameId)
local nSashProfileRefId = EgtGetFirstNameInGroup( nSashProfileTypeId, WIN_REF)
local b3SashProfileType = EgtGetBBoxRef( nSashProfileRefId, GDB_BB.STANDARD, frSectionFrame)
EgtSetInfo( nOutlineCopyId, WIN_GAPDELTAZ .. 2, b3SashProfileType:getDimY())
EgtOffsetCurve( nOutlineCopyId, - dGapDelta)
table.insert( vOutlineCopy, nOutlineCopyId)
nOutlineId = EgtGetNext( nOutlineId)
end
local tSash = { nAreaId = nAreaId, ptCenter = b3Outline:getCenter()}
local tFrame = {}
local nA_FA1Id = GDB_ID.NULL
local nB_FA1Id = GDB_ID.NULL
local nC_FA1Id = GDB_ID.NULL
local nD_FA1Id = GDB_ID.NULL
for nIndex = 1, #vOutlineCopy do
local nNext = EgtIf( nIndex < #vOutlineCopy, nIndex + 1, 1)
local ptOrig = EgtIP( vOutlineCopy[nIndex], vOutlineCopy[nNext], ORIG())
local dParam = EgtCurveParamAtPoint( vOutlineCopy[nIndex], ptOrig)
EgtTrimCurveEndAtParam( vOutlineCopy[nIndex], dParam)
dParam = EgtCurveParamAtPoint( vOutlineCopy[nNext], ptOrig)
EgtTrimCurveStartAtParam( vOutlineCopy[nNext], dParam)
local sOrigName = string.char(string.byte('A') + #vOutlineCopy - nIndex)
tSash[sOrigName] = ptOrig
local vtDir = EgtEV( vOutlineCopy[nIndex])
local nFA1Id = EgtFrame( nSashFrameLayerId, Frame3d( ptOrig, - vtDir, vtDir ^ Z_AX() , Z_AX()))
EgtSetName( nFA1Id, sOrigName .. '.FA1')
local vtIn = Vector3d( vtDir)
vtIn:rotate( Z_AX(), -90)
local dGapDeltaZ = EgtGetInfo( vOutlineCopy[nIndex], WIN_GAPDELTAZ, 'd')
local nFA2Id = EgtFrame( nSashFrameLayerId, Frame3d( ptOrig - dGapDeltaZ * Z_AX(), - vtDir, vtDir ^ vtIn , vtIn))
EgtSetName( nFA2Id, sOrigName .. '.FA2')
local dGapDeltaZ2 = EgtGetInfo( vOutlineCopy[nIndex], WIN_GAPDELTAZ .. 2, 'd')
local nFA3Id = EgtFrame( nSashFrameLayerId, Frame3d( ptOrig - dGapDeltaZ2 * Z_AX(), - vtDir, vtDir ^ -Z_AX() , -Z_AX()))
EgtSetName( nFA3Id, sOrigName .. '.FA3')
if sOrigName == 'A' then
nA_FA1Id = nFA1Id
elseif sOrigName == 'B' then
nB_FA1Id = nFA1Id
elseif sOrigName == 'C' then
nC_FA1Id = nFA1Id
elseif sOrigName == 'D' then
nD_FA1Id = nFA1Id
end
-- ricavo posizione sul telaio
local nOrigOutlineId = EgtGetInfo( vOutlineCopy[nIndex], 'ORIG', 'i')
local nBaseOutlineId = EgtGetInfo( nOrigOutlineId, WIN_COPY, 'i')
local nSouId = EgtGetInfo( nBaseOutlineId, WIN_SOU, 'i')
local nSouAreaId = EgtGetParent( EgtGetParent( nSouId))
local nSouAreaType = EgtGetInfo( nSouAreaId, WIN_AREATYPE, 'i')
while nSouId and nSouAreaType ~= WIN_AREATYPES.FRAME do
nSouId = EgtGetInfo( nSouId, WIN_SOU, 'i')
nSouAreaId = EgtGetParent( EgtGetParent( nSouId or GDB_ID.NULL))
nSouAreaType = EgtGetInfo( nSouAreaId or GDB_ID.NULL, WIN_AREATYPE, 'i')
end
if nSouId and EgtGetName( nSouId) ~= WIN_SPLIT then
local nFrameFrameLayerId = EgtGetFirstNameInGroup( nSouAreaId, WIN_HDW_FRAME)
if not nFrameFrameLayerId then
nFrameFrameLayerId = EgtGroup( nSouAreaId)
EgtSetName( nFrameFrameLayerId, WIN_HDW_FRAME)
end
-- ricavo aria lato telaio
local sProfileType = EgtGetInfo( nSouId, WIN_PROFILETYPE)
local nProfileId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_PROFILE, 'i')
local nFrameProfileId = EgtGetFirstNameInGroup( nProfileId, WIN_FRAME, 'i')
local nFrameProfileTypeId = EgtGetFirstNameInGroup( nFrameProfileId, sProfileType, 'i')
local dGapDeltaOut = EgtGetInfo( nFrameProfileTypeId, WIN_GAPDELTAOUT, 'd')
local dFrameGapDeltaZ = EgtGetInfo( nFrameProfileTypeId, WIN_GAPDELTAZ, 'd')
local nOutlineOutId = EgtCopy( nSouId, nOutlineOffsetLayerId)
EgtSetName( nOutlineOutId, 'Frame')
EgtOffsetCurve( nOutlineOutId, - dGapDeltaOut)
-- prendo la proiezione
_, ptOrig = EgtPointCurveDist( ptOrig, nOutlineOutId)
-- recupero DeltaZ2
local nSectionFrameId = EgtGetFirstNameInGroup( nFrameProfileTypeId, WIN_SECTIONFRAME)
local frSectionFrame = EgtFR( nSectionFrameId)
local nFrameProfileRefId = EgtGetFirstNameInGroup( nFrameProfileTypeId, WIN_REF)
local b3SashProfileType = EgtGetBBoxRef( nFrameProfileRefId, GDB_BB.STANDARD, frSectionFrame)
local nFT1Id = EgtFrame( nFrameFrameLayerId, Frame3d( ptOrig - dFrameGapDeltaZ * Z_AX(), - vtDir, vtDir ^ Z_AX() , Z_AX()))
EgtSetName( nFT1Id, sOrigName .. '.FT1')
table.insert( tFrame, nFT1Id)
local vtFrameIn = Vector3d( vtDir)
vtFrameIn:rotate( Z_AX(), 90)
local nFT2Id = EgtFrame( nFrameFrameLayerId, Frame3d( ptOrig - dFrameGapDeltaZ * Z_AX(), - vtDir, vtDir ^ vtFrameIn , vtFrameIn))
EgtSetName( nFT2Id, sOrigName .. '.FT2')
table.insert( tFrame, nFT2Id)
local dGapDeltaZ2 = b3SashProfileType:getDimY()
local nFT3Id = EgtFrame( nFrameFrameLayerId, Frame3d( ptOrig - dGapDeltaZ2 * Z_AX(), - vtDir, vtDir ^ -Z_AX() , -Z_AX()))
EgtSetName( nFT3Id, sOrigName .. '.FT3')
table.insert( tFrame, nFT3Id)
end
end
tSash.Frame = tFrame
tSash.LHeight = ( EgtSP( nB_FA1Id) - EgtSP( nA_FA1Id)):getY()
tSash.RHeight = ( EgtSP( nC_FA1Id) - EgtSP( nD_FA1Id)):getY()
tSash.TWidth = ( EgtSP( nC_FA1Id) - EgtSP( nB_FA1Id)):getX()
tSash.BWidth = ( EgtSP( nD_FA1Id) - EgtSP( nA_FA1Id)):getX()
if EgtGetType( vOutlineCopy[3]) == GDB_TY.CRV_ARC then
tSash.BCLength = EgtCurveLength( vOutlineCopy[3])
tSash.BCArrow = EgtMP( vOutlineCopy[3]) - (( EgtEP( vOutlineCopy[3]) - EgtSP( vOutlineCopy[3])) / 2)
end
EgtErase( nOutlineOffsetLayerId)
table.insert( SashList, tSash)
end
-- verifico se ci sono sotto-aree
local nChildAreaId = EgtGetFirstNameInGroup( nAreaId, WIN_AREA .. '*')
while nChildAreaId do
-- lancio costruzione pezzi di quell'area
SearchSash( nChildAreaId, SashList)
nChildAreaId = EgtGetNextName( nChildAreaId, WIN_AREA .. '*')
end
end
-- funzione che aggiunge l'hardware
function WinCalculate.AddHardwareForSash( nFrameId)
-- cerco ed indicizzo ante del serramento
local SashList = {}
SearchSash( nFrameId, SashList)
-- ordino per X e Y
local function compareXY(a,b)
if abs( a.ptCenter:getX() - b.ptCenter:getX()) < GEO.EPS_SMALL then
return a.ptCenter:getY() < b.ptCenter:getY()
else
return a.ptCenter:getX() < b.ptCenter:getX()
end
end
table.sort(SashList, compareXY)
-- correggo nomi Frame del telaio
for nIndex = 1, #SashList do
for nFrameIndex = 1, #SashList[nIndex].Frame do
local nFrameId = SashList[nIndex].Frame[nFrameIndex]
local sName = EgtGetName( nFrameId)
EgtSetName( nFrameId, nIndex .. '.' .. sName)
end
end
-- recupero preferito della ferramenta
local nFavourite = EgtGetInfo( nFrameId, WIN_HDW_FAVOURITE)
if not nFavourite or nFavourite == '000000' then
EgtOutLog('Warning! No hardware favourite set!')
return
end
local sHandle = EgtGetInfo( nFrameId, WIN_HDW_HANDLE)
if not sHandle then
EgtOutLog('Warning! No hardware handle set!')
return
end
-- creo file di richiesta ferramenta
local sNow = os.date( '_%Y_%m_%d_%H_%M_%S', os.time())
local sInputFile = 'a:\\InputBatch\\Input' .. sNow .. '.txt'
local sAGBOutputFile = 'C:\\AGB3000NG\\OutputBatch\\Output' .. sNow .. '.txt'
local sAGBOutputLavFile = 'C:\\AGB3000NG\\OutputBatch\\OutputLav' .. sNow .. '.txt'
local sOutputFile = 'a:\\OutputBatch\\Output' .. sNow .. '.txt'
local sOutputLavFile = 'a:\\OutputBatch\\OutputLav' .. sNow .. '.txt'
-- Apro file Input in scrittura
local fhInput = io.open( sInputFile, 'w')
if not fhInput then
EgtOutLog( 'Error opening file ' .. sInputFile)
return false
end
local sText = 'OUTPUTKIT=' .. sAGBOutputFile .. '\n' ..
'S_NAME=' .. nFavourite .. '\n' ..
'RECORDID=15A' .. '\n'
if #SashList >= 1 and SashList[1].LHeight == SashList[1].RHeight then
sText = sText .. 'HBB=' .. tostring( SashList[1].LHeight) .. '\n'
else
for nSashIndex = 1, #SashList do
if nSashIndex == 1 then
sText = sText .. 'HBB_sx=' .. tostring( SashList[nSashIndex].LHeight) .. '\n'
else
sText = sText .. 'HBB_' .. tostring(nSashIndex - 1) .. 'B=' .. tostring( SashList[nSashIndex].LHeight) .. '\n'
end
if nSashIndex == #SashList then
sText = sText .. 'HBB_dx=' .. tostring( SashList[nSashIndex].RHeight) .. '\n'
else
sText = sText .. 'HBB_' .. tostring(nSashIndex) .. '=' .. tostring( SashList[nSashIndex].RHeight) .. '\n'
end
end
end
if #SashList == 1 then
sText = sText .. 'LBB=' .. tostring( SashList[1].BWidth) .. '\n'
else
for nSashIndex = 1, #SashList do
sText = sText .. 'LBB' .. nSashIndex .. '=' .. tostring( SashList[nSashIndex].BWidth) .. '\n'
if SashList[nSashIndex].BCLength then
sText = sText .. 'LBBA' .. nSashIndex .. '=' .. tostring( SashList[nSashIndex].BCLength) .. '\n'
end
if SashList[nSashIndex].BCArrow then
sText = sText .. 'FRECCIA_' .. nSashIndex .. '=' .. tostring( SashList[nSashIndex].BCArrow) .. '\n'
end
end
end
sText = sText .. 'FINESTRAPORTAFINESTRA=Finestra' .. '\n' ..
'Q=1' .. '\n' ..
'MANOSERRAMENTO=' .. sHandle .. '\n' ..
'CNCOUTPUT=' .. sAGBOutputLavFile .. '\n' ..
'RUN'
-- Scrittura nuova linea
fhInput:write( sText .. '\n')
-- Chiudo file CNC
fhInput:close()
-- attendo scrittura output
local nWait = 0
while not EgtExistsFile( sOutputFile) and nWait < 20 do
nWait = nWait + 1
EgtPause( 500)
end
EgtPause( 500)
-- Apro file Output in lettura
local fhOutput = io.open( sOutputLavFile, 'r')
if not fhOutput then
EgtOutLog( 'Error opening file ' .. sOutputLavFile)
return false
end
local sOutputLine = fhOutput:lines('l')
for sMach in fhOutput:lines('l') do
local MachParams = EgtSplitString( sMach, ';')
local sPart = MachParams[3]
local nSashIndex = tonumber( MachParams[4])
local sSashPart = MachParams[5]
local dPosX = tonumber( MachParams[6])
local dPosY = tonumber( MachParams[7])
local dPosZ = tonumber( MachParams[8])
local sMacro = MachParams[9]
local sSide = MachParams[21] -- FT1, FT2, FT3, FA1, FA2, FA3
local sOrigin = MachParams[24] -- AB, BC, CD, DA
local nSashId = SashList[nSashIndex].nAreaId
local nOutlineLayerId = EgtGetFirstNameInGroup( nSashId, WIN_OUTLINE)
local vOutlineIds = EgtGetAllInGroup( nOutlineLayerId)
local nA = string.byte('A')
local nSashPart = string.byte(sSashPart)
local nOutlineIndex = #vOutlineIds - (nSashPart - nA)
local nOutlineId = vOutlineIds[nOutlineIndex]
local nPartId = GDB_ID.NULL
local frHdwFrame
if sPart == 'TELAIO' then
local nSashBaseOutlineId = EgtGetInfo( nOutlineId, WIN_COPY, 'i')
local nSouId = EgtGetInfo( nSashBaseOutlineId, WIN_SOU, 'i')
local nSouAreaId = EgtGetParent( EgtGetParent( nSouId))
local nSouAreaType = EgtGetInfo( nSouAreaId, WIN_AREATYPE, 'i')
while nSouAreaType ~= WIN_AREATYPES.FRAME do
nSouId = EgtGetInfo( nSouId, WIN_SOU, 'i')
nSouAreaId = EgtGetParent( EgtGetParent( nSouId))
nSouAreaType = EgtGetInfo( nSouAreaId, WIN_AREATYPE, 'i')
end
local nFrameOutlineId = EgtGetInfo( nSouId, WIN_COPY, 'i')
nPartId = EgtGetInfo( nFrameOutlineId, WIN_REF_PART, 'i')
local nHdwFrameLayerId = EgtGetFirstNameInGroup( nSouAreaId, WIN_HDW_FRAME)
local nHdwFrameId = EgtGetFirstNameInGroup( nHdwFrameLayerId, nSashIndex .. '.' .. sSashPart .. '.' .. sSide)
frHdwFrame = EgtFR( nHdwFrameId)
elseif sPart == 'ANTA' then
nPartId = EgtGetInfo( nOutlineId, WIN_REF_PART, 'i')
local nHdwFrameLayerId = EgtGetFirstNameInGroup( nSashId, WIN_HDW_FRAME)
local nHdwFrameId = EgtGetFirstNameInGroup( nHdwFrameLayerId, sSashPart .. '.' .. sSide)
frHdwFrame = EgtFR( nHdwFrameId)
end
local vMacro = EgtSplitString( sMacro, '_')
local nProcLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PRC)
-- recupero solido ( se non calcolato non vengono utilizzate)
local nSolidLayerId = EgtGetFirstNameInGroup( nPartId, WIN_SOLID) or GDB_ID.NULL
local nMainExtrusionId = EgtGetFirstNameInGroup( nSolidLayerId, WIN_SRF_MAIN)
local nOrigMainId = EgtGetFirstNameInGroup( nSolidLayerId, WIN_SRF_ORIGMAIN)
if vMacro[1] == 'FRESATA' then
elseif vMacro[1] == 'ASOLA' then
local ptCenter = Point3d( dPosX, dPosY, dPosZ)
local dLength = tonumber( vMacro[2])
local dWidth = tonumber( vMacro[3])
local dHeight = tonumber( vMacro[4])
local ptP1 = ptCenter + ( dLength / 2 - dWidth) * X_AX() + dWidth * Y_AX()
local ptP2 = ptCenter - ( dLength / 2 - dWidth) * X_AX() + dWidth * Y_AX()
local nSolidPocketOutlineId = EgtCurveCompoFromPoints( nProcLayerId, { ptP1, ptP2})
EgtAddCurveCompoArcTg( nSolidPocketOutlineId, ptCenter - dLength / 2 * X_AX())
EgtAddCurveCompoArcTg( nSolidPocketOutlineId, ptCenter + dLength / 2 * X_AX(), false)
-- per solido
local nSolidPocketId
if bCalcSolid then
-- costruisco asola come volume chiuso per eseguire operazioni booleane con il solido e la creo più grande per non avere geometrie a filo
local dExtra = 1
EgtAddCurveCompoLineTg( nSolidPocketOutlineId, dExtra)
EgtAddCurveCompoLineTg( nSolidPocketOutlineId, dExtra, false)
EgtCloseCurveCompo( nSolidPocketOutlineId)
EgtMove( nSolidPocketOutlineId, dExtra * Z_AX())
nSolidPocketId = EgtSurfTmByRegionExtrusion( nProcLayerId, nSolidPocketOutlineId, - ( dHeight + dExtra) * Z_AX())
EgtTransform( nSolidPocketId, frHdwFrame)
EgtSurfTmSubtract( nMainExtrusionId, nSolidPocketId)
EgtInvertSurf( nSolidPocketId)
EgtSurfTmCut( nSolidPocketId, nOrigMainId, true, false)
else
-- costruisco asola esatta
EgtTransform( nSolidPocketOutlineId, frHdwFrame)
local nStmLat = EgtSurfTmByExtrusion( nProcLayerId, nSolidPocketOutlineId, - dHeight * Z_AX())
EgtCloseCurveCompo( nSolidPocketOutlineId)
local nStmBase = EgtSurfTmByFlatContour( nProcLayerId, nSolidPocketOutlineId)
EgtMove( nStmBase, - dHeight * Z_AX())
nSolidPocketId = EgtSurfTmBySewing( nProcLayerId, { nStmBase, nStmLat})
end
EgtErase( nSolidPocketOutlineId)
EgtSetColor( nSolidPocketId, EgtStdColor( 'GRAY'))
EgtSetInfo( nSolidPocketId, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.POCKET)
elseif vMacro[1] == 'TASCA' then
elseif vMacro[1] == 'VITE' then
local dRadius = 1.5
local dDepth = 2
if vMacro[2] == 'CANALINO' then
dRadius = 2
dDepth = 3
elseif vMacro[2] == 'ANTA' then
dRadius = 2.5
dDepth = 4
end
local ptCenter = Point3d( dPosX, dPosY, dPosZ)
local nHoleId = EgtCircle( nProcLayerId, ptCenter, dRadius)
EgtModifyCurveExtrusion( nHoleId, Z_AX())
EgtModifyCurveThickness( nHoleId, - dDepth)
EgtTransform( nHoleId, frHdwFrame)
EgtSetInfo( nHoleId, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.HOLE)
elseif vMacro[1] == 'FORO' then
local ptCenter = Point3d( dPosX, dPosY, dPosZ)
local sDiameter = EgtReplaceString( vMacro[2], 'D', '')
local dRadius = tonumber( sDiameter) / 2
local nHoleId = EgtCircle( nProcLayerId, ptCenter, dRadius)
-- per lavorazione
EgtModifyCurveExtrusion( nHoleId, Z_AX())
local dDepth = tonumber(25)
if #vMacro == 3 then
dDepth = tonumber( vMacro[3])
end
EgtModifyCurveThickness( nHoleId, - dDepth)
EgtSetColor( nHoleId, EgtStdColor( 'GRAY'))
EgtSetInfo( nHoleId, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.HOLE)
-- per solido
if bCalcSolid then
local nSolidHoleId = EgtSurfTmByRegionExtrusion( nProcLayerId, nHoleId, - ( dDepth + 1) * Z_AX())
EgtMove( nSolidHoleId, Z_AX())
EgtTransform( nSolidHoleId, frHdwFrame)
EgtSurfTmSubtract( nMainExtrusionId, nSolidHoleId)
EgtErase( nSolidHoleId)
end
EgtTransform( nHoleId, frHdwFrame)
end
end
-- Chiudo file Output in lettura
fhOutput:close()
end
-- funzione che aggiunge l'hardware
function WinCalculate.AddHardware( nAreaId)
-- verifico il tipo
local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i')
local nSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_SPLIT)
local nSplitType = WIN_SPLITTYPES.NULL
if nSplitLayerId then
nSplitType = EgtGetInfo( nSplitLayerId, WIN_SPLITTYPE, 'i')
end
if nAreaType == WIN_AREATYPES.SASH or ( nSplitLayerId and nSplitType == WIN_SPLITTYPES.FRENCH) then
-- lancio calcolo sash
WinCalculate.AddHardwareForSash( nAreaId)
return
else
-- verifico se ci sono sotto-aree
local nChildAreaId = EgtGetFirstNameInGroup( nAreaId, WIN_AREA .. '*')
while nChildAreaId do
-- lancio verifica di quell'area
WinCalculate.AddHardware( nChildAreaId)
nChildAreaId = EgtGetNextName( nChildAreaId, WIN_AREA .. '*')
end
end
end
---------------------------------------------------------------------
return WinCalculate