Files
egwwindowlua/Designing/WinLib/WinCalculate.lua
T
2025-03-19 11:05:46 +01:00

4583 lines
204 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 s_dDowelTol = 1
local s_nSashNbr = 0 -- contatore delle ante per assegnare nomi
local s_bCalcSolid = false
function WinCalculate.GetCalcSolid()
return s_bCalcSolid
end
function WinCalculate.SetCalcSolid( bValue)
s_bCalcSolid = bValue
end
local s_bSimplSolid = false
function WinCalculate.SetSimplifiedSolid( bValue)
s_bSimplSolid = bValue
end
---------------------------------------------------------------------
-- 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
-- trovo intersezione tra le due circonferenze
local nCircle1 = EgtCircle( GDB_ID.ROOT, EgtCP( nCrv1), EgtArcRadius( nCrv1))
local nCircle2 = EgtCircle( GDB_ID.ROOT, EgtCP( nCrv2), EgtArcRadius( nCrv2))
ptInt = EgtIP( nCircle1, nCircle2, ptRef)
EgtModifyCurveStartPoint( nCrv1, ptInt)
EgtModifyCurveEndPoint( nCrv2, ptInt)
EgtErase( nCircle1)
EgtErase( nCircle2)
-- 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 data una lista di curve ordinate che creano una curva chiusa,
-- ne estende/taglia i contorni per ottenere una curva chiusa continua
local function TrimAndOrientOrderedCurves( vCrvs, bOrient)
local IntersCurveList = {}
local LastCurveInters
-- ciclo sulle curve per ottenere lista intersezioni
for i = 1, #vCrvs do
-- recupero la precedente
local nPrevIndex = EgtIf( i == 1, #vCrvs, i - 1)
-- calcolo intersezione
local ptInters = FindIntersectionPoint( vCrvs[i], vCrvs[ nPrevIndex], EgtSP( vCrvs[i]))
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( vCrvs[i], vCrvs[ nPrevIndex], EgtEP( vCrvs[i]))
LastCurveInters.EndInters = Point3d( ptInters)
end
end
local NewCurveInters = { CurveId = vCrvs[i], StartInters = Point3d( ptInters)}
table.insert( IntersCurveList, NewCurveInters)
LastCurveInters = NewCurveInters
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)
-- estendo agli estremi ( TO DO : gestire caso di split non lineare)
EgtExtendCurveStartByLen( nSplitId, 50)
EgtExtendCurveEndByLen( nSplitId, 50)
-- lo taglio con outline
local nStartIntersId = EgtGetInfo( nSplitId, WIN_SPLIT_STARTINTERS, 'i')
local nOutlineId = EgtGetInfo( nStartIntersId, WIN_COPY, 'i')
local ptStartInters = EgtIP( nSplitId, nOutlineId, EgtSP( nSplitId))
local dStartInters = EgtCurveParamAtPoint( nSplitId, ptStartInters)
EgtTrimCurveStartAtParam( nSplitId, dStartInters)
local nEndIntersId = EgtGetInfo( nSplitId, WIN_SPLIT_ENDINTERS, 'i')
nOutlineId = EgtGetInfo( nEndIntersId, WIN_COPY, 'i')
local ptEndInters = EgtIP( nSplitId, nOutlineId, 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 nParentId = EgtGetParent( nOutlineId)
local nAreaType = WIN_AREATYPES.NULL
while nParentId and ( nAreaType == WIN_AREATYPES.SPLIT or nAreaType == WIN_AREATYPES.NULL) do
nParentId = EgtGetParent( nParentId)
nAreaType = EgtGetInfo( nParentId or GDB_ID.NULL, WIN_AREATYPE, 'i') or WIN_AREATYPES.NULL
end
-- recupero il gruppo contenente il profilo
local nProfilesGrpId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_PROFILE)
local nLayerId
if nAreaType == WIN_AREATYPES.FRAME then
nLayerId = EgtGetFirstNameInGroup( nProfilesGrpId, WIN_FRAME)
elseif nAreaType == WIN_AREATYPES.SASH then
nLayerId = EgtGetFirstNameInGroup( nProfilesGrpId, WIN_SASH)
end
-- recupero il nome del profilo
local sProfileName = EgtGetInfo( nOutlineId, WIN_PROFILETYPE)
-- verifico se bottom rail
if bUseBottomRail then
local nOutlineLay = EgtGetFirstNameInGroup( nParentId, WIN_AREAOUTLINE)
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
---------------------------------------------------------------------
-- funzione che calcola il box di un profilo ( guardando la sua curva Ref) rispetto al suo frame
local function GetProfileLocalBox( nProfileId)
-- recupero il frame del profilo
local nFrameId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME)
local frFrame = EgtFR( nFrameId, GDB_ID.ROOT)
-- recupero il Ref del profilo e ne calcolo il box
local nRefId = EgtGetFirstNameInGroup( nProfileId, WIN_REF)
local b3Box = EgtGetBBoxRef( nRefId, GDB_BB.STANDARD, frFrame, GDB_RT.GLOB)
return b3Box
end
----------------------------------------------------------------------------------
----------------------------- CALCOLO DEI PROFILI ------------------------------
----------------------------------------------------------------------------------
-- funzione che restituisce il primo tipo di area definito tra le sottoaree che si generano da nAreaId
local function GetAreaChildrenType( nAreaId)
local vStack = EgtGetNameInGroup( nAreaId, WIN_AREA .. '*') or {}
local i = 1
while vStack[i] do
local nType = EgtGetInfo( vStack[i], WIN_AREATYPE, 'i')
-- appena trovo un tipo definito esco
if nType == WIN_AREATYPES.FILL then
return WIN_CHILDREN_TYPES.FILL
elseif nType == WIN_AREATYPES.SASH then
return WIN_CHILDREN_TYPES.SASH
else
-- altrimenti analizzo le sottoaree
local vSubAreas = EgtGetNameInGroup( vStack[i], WIN_AREA .. '*') or {}
vStack = EgtJoinTables( vStack, vSubAreas)
end
i = i + 1
end
-- se non trovo un tipo definito
return WIN_CHILDREN_TYPES.NULL
end
---------------------------------------------------------------------
local function GetClosestAreaChildrenType( nAreaId)
local nChildrenType = WIN_CHILDREN_TYPES.NULL
local nType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i')
while nChildrenType == WIN_CHILDREN_TYPES.NULL and nType ~= WIN_AREATYPES.FRAME do
nAreaId = EgtGetParent( nAreaId)
nType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i')
nChildrenType = GetAreaChildrenType( nAreaId)
end
return nChildrenType
end
---------------------------------------------------------------------
-- funzione che verifica la tipologia delle curve figlie di una curva
local function GetChildrenType( nCrvId)
local vStack = EgtGetInfo( nCrvId, WIN_CHILD, 'vi') or {}
local i = 1
local vFillChildren = {}
local vSashChildren = {}
while vStack[i] do
-- verifico se la sua area è di tipo sash o fill
local nAreaId = EgtGetParent( EgtGetParent( vStack[i]))
local nType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i')
if nType == WIN_AREATYPES.FILL then
table.insert( vFillChildren, vStack[i])
elseif nType == WIN_AREATYPES.SASH then
table.insert( vSashChildren, vStack[i])
else
-- recupero i suoi figli
local vChildren = EgtGetInfo( vStack[i], WIN_CHILD, 'vi') or {}
if #vChildren == 0 then
-- se non ha figli, per non creare problemi nel caso di cambio profilo ( in cui è necessario conoscere la struttura completa),
-- assegno come tipologia quella dell'area più "vicina" nella struttura delle aree
local nCurrType = GetClosestAreaChildrenType( nAreaId)
if nCurrType == WIN_CHILDREN_TYPES.FILL then
table.insert( vFillChildren, vStack[i])
elseif nCurrType == WIN_CHILDREN_TYPES.SASH then
table.insert( vSashChildren, vStack[i])
end
end
-- aggiungo i suoi figli tra gli elementi da analizzare
vStack = EgtJoinTables( vStack, vChildren)
end
-- aggiorno il contatore
i = i + 1
end
-- salvo i figli individuati come info della curva
EgtSetInfo( nCrvId, WIN_SASH_CHILDREN, vSashChildren)
EgtSetInfo( nCrvId, WIN_FILL_CHILDREN, vFillChildren)
if #vFillChildren > 0 and #vSashChildren > 0 then
return WIN_CHILDREN_TYPES.MIXED -- cambio profilo
elseif #vFillChildren > 0 then
return WIN_CHILDREN_TYPES.FILL
elseif #vSashChildren > 0 then
return WIN_CHILDREN_TYPES.SASH
else
return WIN_CHILDREN_TYPES.NULL
end
end
---------------------------------------------------------------------
-- funzione che identifica il tipo di split ( null, mullion, french, mixed)
local function GetSplitType( nSplitLayerId)
local nSplitType = EgtGetInfo( nSplitLayerId, WIN_SPLITTYPE, 'i')
-- se non ha split specifico impostato verifico se ha sash prima o dopo per capire se è di tipo mullion
if not nSplitType or nSplitType == WIN_SPLITTYPES.NULL 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
-- se dentro anta è di tipo null, se non è dentro anta devo verificare le tipologie dei figli
if not nParentAreaId or nParentAreaType ~= WIN_AREATYPES.SASH then
local nSplitId = EgtGetFirstInGroup( nSplitLayerId)
local nChildrenType = GetChildrenType( nSplitId)
if nChildrenType == WIN_CHILDREN_TYPES.MIXED then
nSplitType = WIN_SPLITTYPES.MIXED
elseif nChildrenType == WIN_CHILDREN_TYPES.SASH or nChildrenType == WIN_CHILDREN_TYPES.NULL then
nSplitType = WIN_SPLITTYPES.MULLION
end
end
end
if not nSplitType then
nSplitType = WIN_SPLITTYPES.NULL
end
EgtSetInfo( nSplitLayerId, WIN_SPLITTYPE, nSplitType)
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
EgtSetInfo( nSplitId, WIN_PROFILETYPE, WIN_FRAME_SPLIT)
end
elseif nSplitType == WIN_SPLITTYPES.MIXED then
EgtSetInfo( nSplitId, WIN_PROFILETYPE, WIN_MIXED_SPLIT)
EgtSetInfo( nSplitId, WIN_PRF_CHANGE, true)
-- verifico se l'orientamento dello split è coerente con il cambio profilo ( vetro fisso a destra e anta a sinistra) :
-- recupero il lato da cui si trova il figlio di tipo anta
local nSashChild = EgtGetInfo( nSplitId, WIN_SASH_CHILDREN, 'i')
local nRefCrv = EgtGetNext( nSashChild) or EgtGetPrev( nSashChild)
local _, _, nSide = EgtPointCurveDistSide( EgtMP( nRefCrv), nSplitId, Z_AX())
-- se si trova a destra, lo split va invertito
if nSide == 1 then
EgtInvertCurve( nSplitId)
-- scambio le info di intersezione
local vStartInters = EgtGetInfo( nSplitId, WIN_SPLIT_STARTINTERS, 'vi')
local vEndInters = EgtGetInfo( nSplitId, WIN_SPLIT_ENDINTERS, 'vi')
EgtSetInfo( nSplitId, WIN_SPLIT_STARTINTERS, vEndInters)
EgtSetInfo( nSplitId, WIN_SPLIT_ENDINTERS, vStartInters)
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
---------------------------------------------------------------------
-- funzione che imposta i tipi di profilo in base al tipo di pezzi
local function CalcProfileType( nAreaId)
local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i')
-- FRAME
if nAreaType == WIN_AREATYPES.FRAME then
-- assegno il profilo alle curve di outline
local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_AREAOUTLINE)
local nOutlineId = EgtGetFirstInGroup( nOutlineLayerId)
while nOutlineId do
local sName = EgtGetName( nOutlineId)
-- recupero il tipo dei figli
local nChildrenType = GetChildrenType( nOutlineId)
-- a) se non definiti gestisco come anta
if nChildrenType == WIN_CHILDREN_TYPES.NULL then
if sName == WIN_BOTTOM then
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SASH_BOTTOM)
else
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SASH_TOP)
end
-- b) se anta
elseif nChildrenType == WIN_CHILDREN_TYPES.SASH then
-- verifico tipologia di anta contro cui poggia
local vChildren = EgtGetInfo( nOutlineId, WIN_SASH_CHILDREN, 'vi')
local nSashArea = EgtGetParent( EgtGetParent( vChildren[1]))
local nSashType = EgtGetInfo( nSashArea, WIN_SASHTYPE, 'i') or WIN_SASHTYPES.NULL
-- b1) alzante scorrevole
if nSashType == WIN_SASHTYPES.SLIDE_MOVABLE or nSashType == WIN_SASHTYPES.SLIDE_FIXED or nSashType == WIN_SASHTYPES.SLIDE_MOVABLE_BACK then
if sName == WIN_BOTTOM then
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_BOTTOM)
-- se le ante contro cui poggia sono tutte mobili devo aggiornare il profilo
if nSashType == WIN_SASHTYPES.SLIDE_MOVABLE_BACK then
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_BOTTOM_MOVABLEBACK)
elseif nSashType == WIN_SASHTYPES.SLIDE_MOVABLE then
for i = 2, #vChildren do
local nSashArea = EgtGetParent( EgtGetParent( vChildren[i]))
local nSashType = EgtGetInfo( nSashArea, WIN_SASHTYPE, 'i') or WIN_SASHTYPES.NULL
if nSashType == WIN_SASHTYPES.SLIDE_MOVABLE_BACK then
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_BOTTOM_MOVABLEBACK)
break
elseif nSashType == WIN_SASHTYPES.SLIDE_FIXED then
break
end
end
end
elseif sName == WIN_TOP then
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_TOP)
else
if nSashType == WIN_SASHTYPES.SLIDE_MOVABLE then
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_MOVABLE)
else
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_FIXED)
end
end
-- b2) standard
else
if sName == WIN_BOTTOM then
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SASH_BOTTOM)
else
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SASH_TOP)
end
end
-- c) se riempimento
elseif nChildrenType == WIN_CHILDREN_TYPES.FILL then
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
-- d) se cambio profilo
elseif nChildrenType == WIN_CHILDREN_TYPES.MIXED then
EgtSetInfo( nOutlineId, WIN_PRF_CHANGE, true)
if sName == WIN_BOTTOM then
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_MIXED_BOTTOM)
else
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_MIXED_TOP)
end
end
nOutlineId = EgtGetNext( nOutlineId)
end
-- 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 tipologia di anta ( battente, ricevente, alzante scorrevole)
local nSashType = EgtGetInfo( nAreaId, WIN_SASHTYPE, 'i') or WIN_SASHTYPES.NULL
-- imposto profili sash
local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_AREAOUTLINE)
local nOutlineId = EgtGetFirstInGroup( nOutlineLayerId)
while nOutlineId do
local sName = EgtGetName( nOutlineId)
-- se non è definita tipologia
if nSashType == WIN_SASHTYPES.NULL then
if sName == WIN_BOTTOM then
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_FRAME_BOTTOM)
else
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_FRAME_TOP)
end
else
-- verifico se deriva da una curva di split di tipo french ( e quindi deve avere profilo speciale e.g. 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)
-- a) battente/ricevente
if nSashType == WIN_SASHTYPES.ACTIVE then
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SASH_ACTIVE)
elseif nSashType == WIN_SASHTYPES.INACTIVE then
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SASH_INACTIVE)
elseif nSashType == WIN_SASHTYPES.ACTIVE_OUT or nSashType == WIN_SASHTYPES.INACTIVE_OUT then
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_FRENCH_OUT)
elseif nSashType == WIN_SASHTYPES.ACTIVE_IN or nSashType == WIN_SASHTYPES.INACTIVE_IN then
-- devo verificare il tipo dell'anta adiacente
local nAdjSashType = FindAdjacentSashType( nSouId, 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
-- b) alzante scorrevole
elseif nSashType == WIN_SASHTYPES.SLIDE_MOVABLE then
local nAdjSashType = FindAdjacentSashType( nSouId, nSouPrevId)
if nAdjSashType == WIN_SASHTYPES.SLIDE_MOVABLE then
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_ACTIVE_IN)
else
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_ACTIVE)
end
elseif nSashType == WIN_SASHTYPES.SLIDE_FIXED then
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_INACTIVE)
elseif nSashType == WIN_SASHTYPES.SLIDE_MOVABLE_BACK then
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_INACTIVE)
end
else
-- a) alzante scorrevole
if nSashType == WIN_SASHTYPES.SLIDE_MOVABLE then
if sName == WIN_BOTTOM then
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_MOVABLE_BOTTOM)
else
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_MOVABLE_TOP)
end
elseif nSashType == WIN_SASHTYPES.SLIDE_FIXED then
if sName == WIN_BOTTOM then
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_FIXED_BOTTOM)
else
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_FIXED_TOP)
end
elseif nSashType == WIN_SASHTYPES.SLIDE_MOVABLE_BACK then
if sName == WIN_BOTTOM then
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_MOVABLE_BACK_BOTTOM)
else
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_MOVABLE_BACK_TOP)
end
-- b) standard
else
if sName == WIN_BOTTOM then
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_FRAME_BOTTOM)
else
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_FRAME_TOP)
end
end
end
end
nOutlineId = EgtGetNext( nOutlineId)
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 e setto il riferimento
local sSouName = EgtGetName( nSouId)
if sSouName == WIN_SPLIT then
local sBaseName = EgtGetName( nBaseOutlineId)
EgtSetName( nOutlineId, sBaseName)
EgtSetInfo( nOutlineId, WIN_REF_SPLIT, nSouId)
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
TrimAndOrientOrderedCurves( EgtGetAllInGroup( 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 devo alzarlo in z come l'anta che lo contiene
if sSplitProfile == WIN_SASH_SPLIT then
-- recupero l'anta
local nSashAreaId = EgtGetParent( nAreaId)
local nAreaType = EgtGetInfo( nSashAreaId, WIN_AREATYPE, 'i')
while nAreaType ~= WIN_AREATYPES.SASH do
nSashAreaId = EgtGetParent( nSashAreaId)
nAreaType = EgtGetInfo( nSashAreaId, WIN_AREATYPE, 'i')
end
local nSashBaseOutlineLayerId = EgtGetFirstNameInGroup( nSashAreaId, WIN_AREAOUTLINE)
local nSashBaseOutlineId = EgtGetFirstInGroup( nSashBaseOutlineLayerId)
-- recupero il profilo dell'anta
local sSashProfile = EgtGetInfo( nSashBaseOutlineId, WIN_PROFILETYPE)
local nProfileLayerId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_PROFILE)
local nSashProfileLayerId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_SASH)
local nSashProfileId = EgtGetFirstNameInGroup( nSashProfileLayerId, sSashProfile)
-- calcolo offset sulla z dell'anta
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
-- recupero gruppo profili anta e telaio
local nProfileLayerId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_PROFILE)
local nSashProfileLayerId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_SASH)
local nFrameProfileLayerId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_FRAME)
-- ciclo su profilo disegnato anta
local nBaseOutlineId = EgtGetFirstInGroup( nAreaOutlineLayerId)
while nBaseOutlineId do
-- recupero la curva di outline del base outline da cui deriva e la copio
local nSouId = EgtGetInfo( nBaseOutlineId, WIN_SOU, 'i')
local nCopyId = EgtGetInfo( nSouId, WIN_COPY, 'i')
local nOutlineId = EgtCopy( nCopyId, nOutlineLayerId)
-- recupero profilo
local sSashProfile = EgtGetInfo( nBaseOutlineId, WIN_PROFILETYPE)
local nSashProfileId = EgtGetFirstNameInGroup( nSashProfileLayerId, sSashProfile)
-- calcolo offset sulla z dell'anta
local dSashZOffset = EgtGetInfo( nSashProfileId, WIN_DELTA, 'd')
-- sposto anta in Z
EgtMove( nOutlineId, Z_AX() * dSashZOffset)
-- sistemo le info
EgtSetInfo( nBaseOutlineId, WIN_COPY, nOutlineId)
EgtSetInfo( nOutlineId, WIN_COPY, nBaseOutlineId)
EgtSetInfo( nOutlineId, WIN_PROFILETYPE, sSashProfile)
EgtRemoveInfo( nOutlineId, WIN_PRF_CHANGE)
EgtRemoveInfo( nOutlineId, WIN_REF_SPLIT)
-- 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 nFrameProfileId = EgtGetFirstNameInGroup( nFrameProfileLayerId, sFrameProfile)
-- calcolo il box del riferimento del profilo del frame
local b3FrameProfile = GetProfileLocalBox( nFrameProfileId)
-- calcolo offset perpendicolare
local sOverlapInfo = EgtIf( EgtGetName( nOutlineId) == WIN_BOTTOM, WIN_SASH_BOTTOM_OVERLAP, WIN_SASH_TOP_OVERLAP)
local dOverlap = EgtGetInfo( nFrameProfileId, sOverlapInfo, 'd')
local dSashPerpOffset = abs( b3FrameProfile:getMin():getX()) - dOverlap
-- faccio offset
EgtOffsetCurve( nOutlineId, - dSashPerpOffset)
end
nBaseOutlineId = EgtGetNext( nBaseOutlineId)
end
-- accorcio gli offset
TrimAndOrientOrderedCurves( EgtGetAllInGroup( 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)
-- calcolo offset sulla z dal profilo dell'anta
local nPrevId = EgtGetInfo( nBaseSplitId, WIN_SPLIT_STARTINTERS, 'i')
local sSashProfile = EgtGetInfo( nPrevId, WIN_PROFILETYPE)
local nSashProfileId = EgtGetFirstNameInGroup( nSashProfileLayerId, sSashProfile)
local dSplitZOffset = EgtGetInfo( nSashProfileId, 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, 'i')
local nCopyId = EgtGetInfo( nSouId, WIN_COPY, 'i')
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, 'i')
local nParentProfileId = GetOutlineProfileId( nParentOutlineId, true)
-- calcolo il box del riferimento del profilo del frame
local b3FrameProfile = GetProfileLocalBox( nParentProfileId)
-- calcolo offset perpendicolare e sulla z dell'anta
local dOverlap = EgtGetInfo( nParentProfileId, WIN_FILLOVERLAP, 'd')
local bMixedSplit = ( EgtGetInfo( nParentOutlineId, WIN_PRF_CHANGE, 'b') or false) and EgtGetName( nParentOutlineId) == WIN_SPLIT
local dDimRef = EgtIf( bMixedSplit, b3FrameProfile:getMax():getX(), b3FrameProfile:getMin():getX())
local dFillPerpOffset = abs( dDimRef) - 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
TrimAndOrientOrderedCurves( EgtGetAllInGroup( 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
----------------------------------------------------------------------------------
------------------------ FUNZIONI AUX PER CALCOLO PEZZI ------------------------
----------------------------------------------------------------------------------
-- 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 sName == WIN_TOP then
nProfileType = WIN_PRF.TOP
elseif sName == WIN_BOTTOM then
nProfileType = EgtIf( bBottomRail, WIN_PRF.BOTTOMRAIL, 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)
local dParTest = 0.2
if bPrevOutline then
-- considero solo la parte finale del pezzo
EgtTrimCurveStartAtParam( nCompoTest, 1 - dParTest)
EgtAddCurveCompoLine( nCompoTest, EgtSP( nCrv2))
EgtTrimCurveEndAtParam( nCrv2, dParTest)
else
-- considero solo la parte iniziale del pezzo
EgtTrimCurveEndAtParam( nCompoTest, dParTest)
EgtTrimCurveStartAtParam( nCrv2, 1 - dParTest)
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
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 b3Profile = GetProfileLocalBox( nSplitProfileId)
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 split o cambio profilo
if not EgtGetFirstNameInGroup( nPrevProfileId, sPrevCtrIn) then
local nRefSplitId = EgtGetInfo( nPrevOutlineId, WIN_REF_SPLIT, 'i')
if nRefSplitId or EgtGetName( nPrevOutlineId) == WIN_SPLIT then
-- 1) split
-- verifico da quale lato dello split originale si trova l'outline per decidere quale controprofilo considerare
local _, _, nSide = EgtPointCurveDistSide( EgtMP( nOutlineId), nRefSplitId or nPrevOutlineId, Z_AX())
if nSide == 1 then
sPrevCtrIn = WIN_CTRIN .. '1' -- dx
else
sPrevCtrIn = WIN_CTRIN .. '2' -- sx
end
else
-- 2) pezzo del telaio con cambio profilo
-- il profilo da usare dipende dal pezzo corrente: se ha figli di tipo fill allora è legato alla parte fill del cambio profilo, se ha figli di tipo sash è legato alla parte sash,
-- se ha entrambe le tipologie di figli allora è mixed split e va considerata la parte sash ( perchè è quella utilizzata per tagliare il pezzo)
local vSashChildren = EgtGetInfo( nOutlineId, WIN_SASH_CHILDREN, 'vi')
if vSashChildren then
sPrevCtrIn = WIN_SASH .. WIN_CTRIN
else
sPrevCtrIn = WIN_FILL .. WIN_CTRIN
end
end
end
return sPrevCtrIn
end
---------------------------------------------------------------------
-- funzione che crea la superficie corrispondente al Geo di un pezzo gestendo i casi di autointersezione
local function CreateGeoArea( nGeoLayId, nDestLayId)
-- recupero le curve left e right e verifico se hanno orientamento coerente ( quindi non generano autointersezioni)
local bAutointers = false
local vLeft = EgtGetNameInGroup( nGeoLayId, WIN_LEFT)
local vRight = EgtGetNameInGroup( nGeoLayId, WIN_RIGHT)
if #vLeft == 2 and not AreSamePointApprox( EgtEP( vLeft[1]), EgtSP( vLeft[2])) then
bAutointers = true
-- se orientamento non coerente devo ignorare la prima curva
vLeft[1] = GDB_ID.NULL
end
if #vRight == 2 and not AreSamePointApprox( EgtEP( vRight[1]), EgtSP( vRight[2])) then
bAutointers = true
-- se orientamento non coerente devo ignorare la seconda curva
vRight[2] = GDB_ID.NULL
end
local nCompoId
if not bAutointers then
-- se no autointersezioni costruisco il bordo del geo usando direttamente le sue curve
local vCrvs = EgtGetAllInGroup( nGeoLayId)
nCompoId = EgtCurveCompo( nDestLayId, vCrvs, false)
else
-- nel caso di autointersezione devo ignorare le curve left e right con orientamento non coerente
local vGeoCrvs = {}
local nOutId = EgtGetFirstNameInGroup( nGeoLayId, WIN_GEO_OUT)
vGeoCrvs[1] = EgtCopyGlob( nOutId, nDestLayId)
for i = 1, #vRight do
if vRight[i] ~= GDB_ID.NULL then
table.insert( vGeoCrvs, EgtCopyGlob( vRight[i], nDestLayId))
end
end
local nInId = EgtGetFirstNameInGroup( nGeoLayId, WIN_GEO_IN)
table.insert( vGeoCrvs, EgtCopyGlob( nInId, nDestLayId))
for i = 1, #vLeft do
if vLeft[i] ~= GDB_ID.NULL then
table.insert( vGeoCrvs, EgtCopyGlob( vLeft[i], nDestLayId))
end
end
-- taglio le curve
TrimAndOrientOrderedCurves( vGeoCrvs, false)
-- creo compo
nCompoId = EgtCurveCompo( nDestLayId, vGeoCrvs)
end
local nArea = EgtSurfFlatRegion( nDestLayId, nCompoId)
EgtErase( nCompoId)
return nArea
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 CalcProfiles( 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 profili start e ne creo copia
-- se il tipo corrente è split il pezzo va tagliato con il bottomrail, altrimenti con il bottom
for i = 1, #vPrevOutlineId do
local nOrigStartProfileId = GetOutlineProfileId( 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 profili 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)
CopyInfo( nPartId, nMainProfileId, WIN_PRC_CLAMPV_1, 0)
CopyInfo( nPartId, nMainProfileId, WIN_PRC_CLAMPV_2, 0)
return nProfileLayerId
end
---------------------------------------------------------------------
local function GetDeltaProfile( nProfileId, sCtrIn)
local dCPDelta = 0
local nSectionFrId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME)
local frSectionFrame = EgtFR( nSectionFrId, GDB_ID.ROOT)
local nCPId = EgtGetFirstNameInGroup( nProfileId, sCtrIn)
local b3CP = EgtGetBBoxRef( nCPId, GDB_BB.STANDARD, frSectionFrame)
if sCtrIn == WIN_CTRIN .. 1 then
dCPDelta = abs( b3CP:getMin():getX())
else
dCPDelta = abs( b3CP:getMax():getX())
end
return dCPDelta
end
---------------------------------------------------------------------
-- funzione che crea le curve del geo
local function CreateFrameGeo( nOutlineId, vPrevOutlineId, vNextOutlineId, nStartPartJointType, nEndPartJointType, nGeoLayerId, nProfileLayerId)
local nCurrProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN)
-- calcolo spostamento della curva iniziale dovuto a posizione riferimento
local b3CurrProfileFrame = GetProfileLocalBox( nCurrProfileId)
local dCurrOffset = b3CurrProfileFrame:getMax():getX()
-- 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') or EgtGetFirstNameInGroup( nCurrProfileId, WIN_MIXED_COMMON .. WIN_IN)
EgtSetInfo( nCurrOffsetId, WIN_SEMI_PROFILE, nSemiProfileIn)
-- curve left
local vPrevProfileId = EgtGetNameInGroup( nProfileLayerId, WIN_PRF_START)
for i = 1, #vPrevOutlineId do
local nPrevCurveId
local nPrevSemiProfile
if nStartPartJointType == WIN_PART_JNT.ANGLED then
-- calcolo la bisettrice
local vtMedia = ( ( EgtSV( nOutlineId) - EgtEV( vPrevOutlineId[i])) / 2)
if not vtMedia:normalize() then
vtMedia = EgtSV( nOutlineId)
vtMedia:rotate( Z_AX(), 90)
end
nPrevCurveId = EgtLinePVL( nGeoLayerId, EgtSP( nOutlineId), vtMedia, 3 * b3CurrProfileFrame:getDimX())
EgtInvertCurve( nPrevCurveId)
else
nPrevCurveId = EgtCopy( vPrevOutlineId[i], nGeoLayerId)
if nStartPartJointType == WIN_PART_JNT.SHORT then
local sCtrIn = GetProfileCtrIn( vPrevOutlineId[i], nOutlineId, vPrevProfileId[i])
local dCPDelta = GetDeltaProfile( vPrevProfileId[i], sCtrIn)
EgtOffsetCurve( nPrevCurveId, - dCPDelta)
-- ricavo il semiprofilo associato
nPrevSemiProfile = EgtGetFirstNameInGroup( vPrevProfileId[i], sCtrIn)
else
nPrevSemiProfile = EgtGetFirstNameInGroup( vPrevProfileId[i], WIN_OUT)
end
end
EgtSetName( nPrevCurveId, WIN_GEO_LEFT)
EgtSetInfo( nPrevCurveId, WIN_SEMI_PROFILE, nPrevSemiProfile)
EgtSetInfo( nPrevCurveId, WIN_REF_OUTLINE, vPrevOutlineId[i])
EgtRelocateGlob( nPrevCurveId, nGeoLayerId, GDB_IN.LAST_SON)
end
-- curve right
local vNextProfileId = EgtGetNameInGroup( nProfileLayerId, WIN_PRF_END)
for i = 1, #vNextOutlineId do
local nNextCurveId
local nNextSemiProfile
if nEndPartJointType == WIN_PART_JNT.ANGLED then
-- calcolo la bisettrice
local vtMedia = ( ( EgtSV( vNextOutlineId[i]) - EgtEV( nOutlineId)) / 2)
if not vtMedia:normalize() then
vtMedia = EgtEV( nOutlineId)
vtMedia:rotate( Z_AX(), 90)
end
nNextCurveId = EgtLinePVL( nGeoLayerId, EgtEP( nOutlineId), vtMedia, 3 * b3CurrProfileFrame:getDimX())
else
nNextCurveId = EgtCopy( vNextOutlineId[i], nGeoLayerId)
if nEndPartJointType == WIN_PART_JNT.SHORT then
local sCtrIn = GetProfileCtrIn( vNextOutlineId[i], nOutlineId, vNextProfileId[i])
local dCPDelta = GetDeltaProfile( vNextProfileId[i], sCtrIn)
EgtOffsetCurve( nNextCurveId, - dCPDelta)
-- ricavo il semiprofilo associato
nNextSemiProfile = EgtGetFirstNameInGroup( vNextProfileId[i], sCtrIn)
else
nNextSemiProfile = EgtGetFirstNameInGroup( vNextProfileId[i], WIN_OUT)
end
end
EgtSetName( nNextCurveId, WIN_GEO_RIGHT)
EgtSetInfo( nNextCurveId, WIN_SEMI_PROFILE, nNextSemiProfile)
EgtSetInfo( nNextCurveId, WIN_REF_OUTLINE, vNextOutlineId[i])
EgtRelocateGlob( nNextCurveId, nCurrOffsetId, GDB_IN.BEFORE)
end
-- trim delle curve
TrimAndOrientOrderedCurves( EgtGetAllInGroup( nGeoLayerId), false)
-- salvo spessore serramento nel gruppo
local dGeoWidth = b3CurrProfileFrame:getDimX()
EgtSetInfo( nGeoLayerId, WIN_GEOWIDTH, dGeoWidth)
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)
EgtSetInfo( nOutlineId, WIN_PREV_OUTLINES, vPrevOutlineId)
EgtSetInfo( nOutlineId, WIN_NEXT_OUTLINES, vNextOutlineId)
-- 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 il valore di start joint su outline per calcolo dowels
-- se bottomrail è sicuramente short quindi non salvo il valore che sovrascriverebbe quello del pezzo bottom ( che potrebbe essere short o full)
if nProfileType ~= WIN_PRF.BOTTOMRAIL then
EgtSetInfo( nOutlineId, WIN_STARTJOINT, nStartPartJointType)
end
-- creo il gruppo con i profili del pezzo
local nProfileLayerId = CalcProfiles( nPartId, nOutlineId, vPrevOutlineId, vNextOutlineId, nProfileType)
-- creo lati dell'outline
CreateFrameGeo( nOutlineId, vPrevOutlineId, vNextOutlineId, nStartPartJointType, nEndPartJointType, nGeoLayerId, nProfileLayerId)
end
---------------------------------------------------------------------
-- funzione che calcola l'ingombro del fill
local function CalcFillGeo( nPartId, nOutlineLayerId)
-- creo layer per ingombro
local nGeoLayerId = EgtGroup( nPartId)
EgtSetName( nGeoLayerId, WIN_GEO)
-- copio lati da Outline
local 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
----------------------------------------------------------------------------------
----------------------- CURVE AUX PER CAMBIO PROFILO -----------------------------
----------------------------------------------------------------------------------
-- funzione che individua e crea i diversi tratti uniformi della curva di outline
local function CalcMixedOutlines( nPartId, nOutlineId)
-- creo gruppo dove salvare i sottotratti
local nGrp = EgtGroup( nPartId)
EgtSetName( nGrp, WIN_MIXED_OUTLINES)
EgtSetStatus( nGrp, GDB_ST.OFF)
-- recupero i tratti di tipo sash e li concateno
local vSashChildren = EgtGetInfo( nOutlineId, WIN_SASH_CHILDREN, 'vi')
local vSash = {}
for i = 1, #vSashChildren do
local nCrv = EgtCopyGlob( vSashChildren[i], nGrp)
table.insert( vSash, nCrv)
end
local nCrvS, nCntS = EgtCurveCompoByReorder( nGrp, vSash, EgtSP( nOutlineId))
for nId = nCrvS, nCrvS + nCntS - 1 do
EgtSetName( nId, WIN_SASH)
end
-- recupero i tratti di tipo fill e li concateno
local vFillChildren = EgtGetInfo( nOutlineId, WIN_FILL_CHILDREN, 'vi')
local vFill = {}
for i = 1, #vFillChildren do
local nCrv = EgtCopyGlob( vFillChildren[i], nGrp)
table.insert( vFill, nCrv)
end
local nCrvF, nCntF = EgtCurveCompoByReorder( nGrp, vFill, EgtSP( nOutlineId))
for nId = nCrvF, nCrvF + nCntF - 1 do
EgtSetName( nId, WIN_FILL)
end
-- riordino le curve nel gruppo per ricostruire l'outline
EgtReorderCurvesInGroup( nGrp, EgtSP( nOutlineId))
-- creo associazione tra le sottocurve di outline e gli split che le separano :
-- recupero tutti gli split coinvolti
local nBaseOutline = EgtGetInfo( nOutlineId, WIN_COPY, 'i')
local vStack = { nBaseOutline}
local vSplitIds = {}
local i = 1
while vStack[i] do
-- recupero il tipo di area
local nAreaId = EgtGetParent( EgtGetParent( vStack[i]))
local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i')
if nAreaType ~= WIN_AREATYPES.SASH and nAreaType ~= WIN_AREATYPES.FILL then
-- salvo il suo eventuale split
local nSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_SPLIT)
if nSplitLayerId then
local nSplitId = EgtGetFirstInGroup( nSplitLayerId)
table.insert( vSplitIds, nSplitId)
end
-- analizzo eventuali figli
local vChildren = EgtGetInfo( vStack[i], WIN_CHILD, 'vi') or {}
vStack = EgtJoinTables( vStack, vChildren)
end
i = i + 1
end
-- associo le curve con lo split che le taglia nel loro punto finale
local vCrvs = EgtGetAllInGroup( nGrp)
for i = 1, #vSplitIds do
local ptS = EgtSP( vSplitIds[i])
local ptE = EgtEP( vSplitIds[i])
for j = 1, #vCrvs - 1 do
local ptTest = EgtEP( vCrvs[j])
if AreSamePointApprox( ptS, ptTest) then
EgtSetInfo( vSplitIds[i], WIN_MIXED_REF_START, vCrvs[j])
EgtSetInfo( vCrvs[j], WIN_MIXED_SPLIT_REF, vSplitIds[i])
break
elseif AreSamePointApprox( ptE, ptTest) then
EgtSetInfo( vSplitIds[i], WIN_MIXED_REF_END, vCrvs[j])
EgtSetInfo( vCrvs[j], WIN_MIXED_SPLIT_REF, vSplitIds[i])
break
end
end
end
return nGrp
end
---------------------------------------------------------------------
-- funzione che crea la curva di riferimento sulla giunzione tra il pezzo di split e il pezzo di telaio con cambio profilo
local function CalcMixedIntersections( nPartId, nOutline, vOutlines)
local nGrp = EgtGroup( nPartId)
EgtSetName( nGrp, WIN_MIXED_INTERSECTIONS)
EgtSetStatus( nGrp, GDB_ST.OFF)
-- recupero il profilo dell'outline
local nProfileLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE)
local nMainProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN)
for i = 1, #vOutlines - 1 do
-- recupero la curva di split che separa i due tratti di outline
local nSplitId = EgtGetInfo( vOutlines[i], WIN_MIXED_SPLIT_REF, 'i')
local nSplitProfileId = GetOutlineProfileId( nSplitId, false)
-- verifico ordinamento
local bSashFill = ( EgtGetName( vOutlines[i]) == WIN_SASH)
-- ricavo il punto di incontro tra le due parti dei profili che vanno contro il vetro
local nCrv1 = EgtCopyGlob( nSplitId, nGrp)
local dDeltaFixedSplit = EgtGetInfo( nSplitProfileId, WIN_FIXED_REF, 'd')
EgtOffsetCurve( nCrv1, dDeltaFixedSplit)
local nCrv2 = EgtCopyGlob( nOutline, nGrp)
local dDeltaFixedFrame = EgtGetInfo( nMainProfileId, WIN_FIXED_REF, 'd')
EgtOffsetCurve( nCrv2, - dDeltaFixedFrame)
local ptRef1 = EgtIP( nCrv1, nCrv2, ORIG())
-- ricavo il punto di incontro tra il taglio a 45° e la parte del telaio contro anta
-- TO DO : capire come gestire correttamente la rotazione nel caso di arco
local dParRef = EgtCurveParamAtPoint( nCrv2, ptRef1)
local vtDir45 = EgtUV( nCrv2, dParRef, -1)
vtDir45:rotate( Z_AX(), EgtIf( bSashFill, 225, -45))
local nCrv3 = EgtLinePVL( nGrp, ptRef1, vtDir45, 100)
local nCrv4 = EgtCopyGlob( nOutline, nGrp)
local dDeltaSashFrame = EgtGetInfo( nMainProfileId, WIN_SASH_REF .. '1', 'd')
EgtOffsetCurve( nCrv4, - dDeltaSashFrame)
local ptRef2 = EgtIP( nCrv3, nCrv4, ORIG())
-- curva di intersezione da usare come riferimento per i conti successivi
local nCrv = EgtCurveCompoFromPoints( nGrp, { ptRef1, ptRef2})
-- calcolo il raccordo
local dRad = EgtGetInfo( nMainProfileId, WIN_RAD_REF .. '1', 'd')
local dParFillet = EgtCurveParamAtPoint( nCrv4, ptRef2)
dParFillet = dParFillet + EgtIf( bSashFill, -10, 10) * GEO.EPS_SMALL
local nFillet = EgtCurveFillet( nGrp, nCrv, EgtUP( nCrv1, 0.9), nCrv4, EgtUP( nCrv4, dParFillet), dRad, true) or GDB_ID.NULL
EgtAddCurveCompoCurve( nCrv, nFillet)
-- cancello curve di costruzione
EgtErase( { nCrv1, nCrv2, nCrv3, nCrv4})
-- assegno riferimento
EgtSetInfo( vOutlines[i], WIN_MIXED_INTERS_REF, nCrv)
end
end
---------------------------------------------------------------------
-- funzione che calcola curve ausiliarie per la gestione del cambio profilo
local function CalcMixedFrameCurves( nPartId, nOutlineId)
-- calcolo i sottotratti uniformi della curva di outline
local nOutlinesGrp = CalcMixedOutlines( nPartId, nOutlineId)
local vCrvs = EgtGetAllInGroup( nOutlinesGrp)
-- calcolo le curve di intersezione con gli split
CalcMixedIntersections( nPartId, nOutlineId, vCrvs)
end
----------------------------------------------------------------------------------
--------------------------- PROFILING PROCESSINGS --------------------------------
----------------------------------------------------------------------------------
-- funzione che copia sulla curva di lavorazione le informazioni prese dal semiprofilo corrispondente
local function GetProcessingInfoFromSemiProfile( nCrv, nSemiProfile)
if nSemiProfile then
-- setto info di lavorazione
EgtSetInfo( nCrv, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.PROFILING)
-- setto info con il tipo di profiling
local sName = EgtGetName( nCrv)
if sName == WIN_GEO_LEFT or sName == WIN_GEO_RIGHT then
EgtSetInfo( nCrv, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.HEAD)
else
EgtSetInfo( nCrv, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.LONGITUDINAL)
end
-- recupero le info di lavorazione dal semiprofilo
CopyInfo( nCrv, nSemiProfile, WIN_PRC_PHASE)
local nTools = EgtGetInfo( nSemiProfile, WIN_PRC_NTOOLS , 'i') or 0
EgtSetInfo( nCrv, WIN_PRC_NTOOLS, nTools)
for j = 1, nTools do
CopyInfo( nCrv, nSemiProfile, WIN_PRC_TOOL_NAME .. '_' .. tostring(j))
CopyInfo( nCrv, nSemiProfile, WIN_PRC_OFFL .. '_' .. tostring(j))
CopyInfo( nCrv, nSemiProfile, WIN_PRC_OFFR .. '_' .. tostring(j))
end
else
-- se non ha semiprofilo associato è un taglio
EgtSetInfo( nCrv, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.CUT)
end
end
---------------------------------------------------------------------
-- funzione che calcola la prima lavorazione per l'innesto dello split sul telaio nel caso di cambio profilo
local function CalcMixedFrameMilling1( nIntersCrv, nOutlineId, nMainProfileId, nSplitRef, bSashFill, nProcLayerId, nSurfGeoId)
local dOffs = EgtGetInfo( nMainProfileId, WIN_SASH_REF .. '1', 'd')
local dDepth = EgtGetInfo( nMainProfileId, WIN_SASH_DEPTH .. '1', 'd')
local dFilletRad = EgtGetInfo( nMainProfileId, WIN_RAD_REF .. '1', 'd')
-- primo tratto : taglio a 45° e fillet
local nCrv1 = EgtCopyGlob( nIntersCrv, nProcLayerId)
EgtExtendCurveStartByLen( nCrv1, 100)
-- calcolo il tratto di outline
local nCrv2 = EgtCopyGlob( nOutlineId, nProcLayerId)
EgtOffsetCurve( nCrv2, - dOffs)
if bSashFill then
EgtInvertCurve( nCrv2)
end
local dParS = EgtCurveParamAtPoint( nCrv2, EgtEP( nCrv1))
local ptEnd = EgtIP( nCrv2, nSplitRef, ORIG())
local dParE = EgtCurveParamAtPoint( nCrv2, ptEnd)
EgtTrimCurveStartEndAtParam( nCrv2, dParS, dParE)
-- tratto di uscita a 45°
local vtDir2 = EgtEV( nCrv2)
vtDir2:rotate( Z_AX(), EgtIf( bSashFill, - 45, 45))
local nCrv3 = EgtLinePVL( nProcLayerId, ptEnd, vtDir2, 100)
-- creo fillet
local nFillet = EgtCurveFillet( nProcLayerId, nCrv2, EgtUP( nCrv2, 0.9), nCrv3, EgtUP( nCrv3, 0.1), dFilletRad, true)
-- creo curva di lavorazione
local nMillingCrv = EgtCurveCompo( nProcLayerId, {nCrv1, nCrv2, nFillet, nCrv3})
if bSashFill then
EgtInvertCurve( nMillingCrv)
end
EgtModifyCurveThickness( nMillingCrv, - dDepth)
-- setto info di lavorazione
EgtSetInfo( nMillingCrv, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.PROFILING)
EgtSetInfo( nMillingCrv, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.GENERIC)
EgtSetInfo( nMillingCrv, WIN_PRC_SIDE, WIN_PRC_SIDETYPE.IN)
EgtTrimCurveWithRegion( nMillingCrv, nSurfGeoId, true, false)
end
---------------------------------------------------------------------
-- funzione che calcola la seconda lavorazione per l'innesto dello split sul telaio nel caso di cambio profilo
local function CalcMixedFrameMilling2( nIntersCrv, nOutlineId, nMainProfileId, nSplitProfileId, nSplitRef, bSashFill, nProcLayerId, nSurfGeoId)
local dOffs = EgtGetInfo( nMainProfileId, WIN_SASH_REF .. '2', 'd')
local dDepth = EgtGetInfo( nMainProfileId, WIN_SASH_DEPTH .. '2', 'd')
local dFilletRad = EgtGetInfo( nMainProfileId, WIN_RAD_REF .. '2', 'd')
local dExtraDist = EgtGetInfo( nMainProfileId, WIN_EXTRA_DIST, 'd')
local nCrv1 = EgtCopyGlob( nIntersCrv, nProcLayerId)
EgtExtendCurveStartByLen( nCrv1, 100)
-- calcolo il primo tratto di outline
local nCrv2 = EgtCopyGlob( nOutlineId, nProcLayerId)
EgtOffsetCurve( nCrv2, - dOffs + dExtraDist)
if bSashFill then
EgtInvertCurve( nCrv2)
end
-- taglio i due tratti per unirli
local pt1 = EgtIP( nCrv1, nCrv2, ORIG())
local dParE1 = EgtCurveParamAtPoint( nCrv1, pt1)
EgtTrimCurveEndAtParam( nCrv1, dParE1)
local dParS2 = EgtCurveParamAtPoint( nCrv2, pt1)
EgtTrimCurveStartAtParam( nCrv2, dParS2)
-- calcolo fillet
local nFillet1 = EgtCurveFillet( nProcLayerId, nCrv1, EgtUP( nCrv1, 0.9), nCrv2, EgtUP( nCrv2, 0.1), dFilletRad, true)
-- calcolo il secondo tratto di outline
local nCrv3 = EgtCopyGlob( nOutlineId, nProcLayerId)
EgtOffsetCurve( nCrv3, - dOffs)
if bSashFill then
EgtInvertCurve( nCrv3)
end
local nSplitRef2 = EgtCopyGlob( nSplitRef, nProcLayerId)
local dOffs1 = EgtGetInfo( nSplitProfileId, WIN_SASH_REF .. '1', 'd')
local dOffs2 = EgtGetInfo( nSplitProfileId, WIN_SASH_REF .. '2', 'd')
EgtOffsetCurve( nSplitRef2, dOffs2 - dOffs1)
local pt2 = EgtIP( nCrv3, nSplitRef2, ORIG())
local pt3 = EgtIP( nCrv3, nSplitRef, ORIG())
local dParS3 = EgtCurveParamAtPoint( nCrv3, pt2)
local dParE3 = EgtCurveParamAtPoint( nCrv3, pt3)
EgtTrimCurveStartEndAtParam( nCrv3, dParS3, dParE3)
EgtErase( nSplitRef2)
-- calcolo il raccordo tra i due tratti di outline : è arco di raggio dFilletRad, tangente a nCrv2 e con punto finale pt2
-- calcolo il centro dell'arco
local nCircleTmp = EgtCircle( nProcLayerId, pt2, dFilletRad)
local nCrvTmp = EgtCopyGlob( nOutlineId, nProcLayerId)
EgtOffsetCurve( nCrvTmp, - dOffs + dExtraDist - dFilletRad)
local ptC = EgtIP( nCircleTmp, nCrvTmp, EgtIf( bSashFill, EgtEP( nCrvTmp), EgtSP( nCrvTmp)))
EgtErase( {nCircleTmp, nCrvTmp})
local nFillet2 = EgtArcC2PEx( nProcLayerId, ptC, EgtSP( nCrv2), GDB_PT.TG, nCrv2, pt2)
-- taglio il primo tratto di outline per collegarlo al raccordo
local dParE2 = EgtCurveParamAtPoint( nCrv2, EgtSP( nFillet2))
EgtTrimCurveEndAtParam( nCrv2, dParE2)
-- tratto di uscita a 45°
local vtDir2 = EgtEV( nCrv3)
vtDir2:rotate( Z_AX(), EgtIf( bSashFill, - 45, 45))
local nCrv4 = EgtLinePVL( nProcLayerId, EgtEP( nCrv3), vtDir2, 100)
-- creo fillet
local nFillet3 = EgtCurveFillet( nProcLayerId, nCrv3, EgtUP( nCrv3, 0.9), nCrv4, EgtUP( nCrv4, 0.1), dFilletRad, true) or GDB_ID.NULL
-- creo curva di lavorazione
local nMillingCrv = EgtCurveCompo( nProcLayerId, {nCrv1, nFillet1, nCrv2, nFillet2, nCrv3, nFillet3, nCrv4})
if bSashFill then
EgtInvertCurve( nMillingCrv)
end
EgtModifyCurveThickness( nMillingCrv, - dDepth)
-- setto info di lavorazione
EgtSetInfo( nMillingCrv, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.PROFILING)
EgtSetInfo( nMillingCrv, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.GENERIC)
EgtSetInfo( nMillingCrv, WIN_PRC_SIDE, WIN_PRC_SIDETYPE.IN)
EgtTrimCurveWithRegion( nMillingCrv, nSurfGeoId, true, false)
end
---------------------------------------------------------------------
-- funzione che calcola le lavorazioni di profiling per un pezzo di telaio con cambio profilo
local function CalcMixedFrameProfilingProcessings( nPartId, nProcLayerId, nGeoLayerId, nMainProfileId, nSurfGeoId)
-- a) lavorazioni profili
-- per le lavorazioni dei profili out, left, right e in comune si usano le corrispondenti curve del geo
local vGeoCrvs = EgtGetAllInGroup( nGeoLayerId)
for i = 1, #vGeoCrvs do
-- copio curva
local nCrv = EgtCopyGlob( vGeoCrvs[i], nProcLayerId)
-- recupero il semiprofilo associato
local nSemiProfile = EgtGetInfo( nCrv, WIN_SEMI_PROFILE, 'i')
GetProcessingInfoFromSemiProfile( nCrv, nSemiProfile)
end
-- lavorazioni dei sottotratti in di sash e fill
local nOutlinesGrp = EgtGetFirstNameInGroup( nPartId, WIN_MIXED_OUTLINES)
local vCrvs = EgtGetAllInGroup( nOutlinesGrp)
local b3Profile = GetProfileLocalBox( nMainProfileId)
local dOffs = b3Profile:getMin():getX()
for i = #vCrvs, 1, -1 do
-- calcolo la curva di lavorazione
local nCrv = EgtCopyGlob( vCrvs[i], nProcLayerId)
EgtOffsetCurve( nCrv, dOffs)
EgtInvertCurve( nCrv)
nCrv = EgtTrimCurveWithRegion( nCrv, nSurfGeoId, true, true)
-- setto le info di lavorazione dal semiprofilo
local nSemiProfile = EgtGetFirstNameInGroup( nMainProfileId, EgtGetName( vCrvs[i]) .. WIN_IN)
GetProcessingInfoFromSemiProfile( nCrv, nSemiProfile)
-- sistemo info di lavorazione
EgtSetInfo( nCrv, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.MIXED)
EgtSetInfo( nCrv, WIN_PRC_SIDE, WIN_PRC_SIDETYPE.IN)
-- TO DO : calcolo di AddLen ?
end
-- b) lavorazioni sulle intersezioni con gli split
local nIntersGrp = EgtGetFirstNameInGroup( nPartId, WIN_MIXED_INTERSECTIONS)
local vInters = EgtGetAllInGroup( nIntersGrp)
local nOutlineId = EgtGetInfo( nPartId, WIN_REF_OUTLINE, 'i')
for i = 1, #vInters do
local bSashFill = ( EgtGetName( vCrvs[i]) == WIN_SASH)
-- recupero lo split associato e creo la curva di riferimento per le fresature
local nSplitId = EgtGetInfo( vCrvs[i], WIN_MIXED_SPLIT_REF, 'i')
local nSplitProfileId = GetOutlineProfileId( nSplitId, false)
local dRefSplit = EgtGetInfo( nSplitProfileId, WIN_SASH_REF .. '2', 'd')
local nSplitRef = EgtCopyGlob( nSplitId, nProcLayerId)
EgtOffsetCurve( nSplitRef, - dRefSplit)
-- Fresatura 1
CalcMixedFrameMilling1( vInters[i], nOutlineId, nMainProfileId, nSplitRef, bSashFill, nProcLayerId, nSurfGeoId)
-- Fresatura 2
CalcMixedFrameMilling2( vInters[i], nOutlineId, nMainProfileId, nSplitProfileId, nSplitRef, bSashFill, nProcLayerId, nSurfGeoId)
EgtErase( nSplitRef)
end
end
---------------------------------------------------------------------
-- funzione che calcola le lavorazioni di profiling nel caso di uno split coinvolto da cambio profilo
local function CalcMixedSplitProfilingProcessings( nSplitId, nProcLayerId, nGeoLayerId)
-- a) lavorazione dei profili
local vGeoCrvs = EgtGetAllInGroup( nGeoLayerId)
for i = 1, #vGeoCrvs do
-- copio la curva
local nCrvId = EgtCopyGlob( vGeoCrvs[i], nProcLayerId)
-- recupero il semiprofilo associato ( per left e right è stato salvato il profilo di tipo sash)
local nSemiProfileId = EgtGetInfo( nCrvId, WIN_SEMI_PROFILE, 'i')
-- setto le info dal semiprofilo
GetProcessingInfoFromSemiProfile( nCrvId, nSemiProfileId)
end
-- b) tagli a 45°
-- left
local nMixedLeft = EgtGetInfo( nSplitId, WIN_MIXED_REF_START, 'i')
local nIntersLeft = EgtGetInfo( nMixedLeft, WIN_MIXED_INTERS_REF, 'i')
local nMillingLeft = EgtCopyGlob( nIntersLeft, nProcLayerId)
-- recupero profondità
local vOutlineLeft = EgtGetInfo( nSplitId, WIN_PREV_OUTLINES, 'vi')
local nProfileLeft = GetOutlineProfileId( vOutlineLeft[1], false)
local dDepthLeft = EgtGetInfo( nProfileLeft, WIN_SASH_DEPTH .. '2', 'd')
EgtModifyCurveThickness( nMillingLeft, - dDepthLeft)
-- setto info di lavorazione
EgtSetInfo( nMillingLeft, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.PROFILING)
EgtSetInfo( nMillingLeft, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.GENERIC)
EgtSetInfo( nMillingLeft, WIN_PRC_SIDE, WIN_PRC_SIDETYPE.LEFT)
-- right
local nMixedRight = EgtGetInfo( nSplitId, WIN_MIXED_REF_END, 'i')
local nIntersRight = EgtGetInfo( nMixedRight, WIN_MIXED_INTERS_REF, 'i')
local nMillingRight = EgtCopyGlob( nIntersRight, nProcLayerId)
-- recupero profondità
local vOutlineRight = EgtGetInfo( nSplitId, WIN_NEXT_OUTLINES, 'vi')
local nProfileRight = GetOutlineProfileId( vOutlineRight[1], false)
local dDepthRight = EgtGetInfo( nProfileRight, WIN_SASH_DEPTH .. '2', 'd')
EgtModifyCurveThickness( nMillingRight, - dDepthRight)
EgtInvertCurve( nMillingRight)
-- setto info di lavorazione
EgtSetInfo( nMillingRight, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.PROFILING)
EgtSetInfo( nMillingRight, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.GENERIC)
EgtSetInfo( nMillingRight, WIN_PRC_SIDE, WIN_PRC_SIDETYPE.RIGHT)
end
---------------------------------------------------------------------
-- funzione che calcola le lavorazioni di profiling
local function CalcProfilingProcessings( nPartId, nOutlineId)
-- creo gruppo delle lavorazioni
local nProcLayerId = EgtGroup( nPartId)
EgtSetName( nProcLayerId, WIN_PRC)
EgtSetStatus( nProcLayerId, GDB_ST.OFF)
-- recupero il geo e creo la superficie associata per limitare le lavorazioni
local nGeoLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO)
local nSurfGeo = CreateGeoArea( nGeoLayerId, nProcLayerId)
EgtSurfFrOffset( nSurfGeo, 50 * GEO.EPS_SMALL)
-- recupero il gruppo dei profili
local nProfileLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE)
local nMainProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN)
-- recupero le info di sovramateriale dal profilo
CopyInfo( nPartId, nMainProfileId, WIN_PRC_OVERMAT_IN, 0)
CopyInfo( nPartId, nMainProfileId, WIN_PRC_OVERMAT_OUT, 0)
CopyInfo( nPartId, nMainProfileId, WIN_PRC_OVERMAT_LEFT, 0)
CopyInfo( nPartId, nMainProfileId, WIN_PRC_OVERMAT_RIGHT, 0)
-- calcolo lavorazioni dei profili
local bChangeProfile = EgtGetInfo( nOutlineId, WIN_PRF_CHANGE, 'b') or false
if bChangeProfile then
-- 1) caso cambio profilo : telaio o split
if EgtGetName( nOutlineId) == WIN_SPLIT then
CalcMixedSplitProfilingProcessings( nOutlineId, nProcLayerId, nGeoLayerId)
else
CalcMixedFrameProfilingProcessings( nPartId, nProcLayerId, nGeoLayerId, nMainProfileId, nSurfGeo)
end
else
-- 2) caso standard
-- recupero tutte le curve del geo
local vGeoCrvs = EgtGetAllInGroup( nGeoLayerId)
for i = 1, #vGeoCrvs do
-- copio curva
local nCrvId = EgtCopyGlob( vGeoCrvs[i], nProcLayerId)
-- recupero il semiprofilo associato
local nSemiProfileId = EgtGetInfo( nCrvId, WIN_SEMI_PROFILE, 'i')
-- setto le info dal semiprofilo
GetProcessingInfoFromSemiProfile( nCrvId, nSemiProfileId)
end
end
-- calcolo eventuali lavorazioni per strip
local vStripDist = EgtGetInfo( nMainProfileId, WIN_STRIP_DIST, 'vi') or {}
for i = 1, #vStripDist do
local nStripCut = EgtCopyGlob( nOutlineId, nProcLayerId)
EgtOffsetCurve( nStripCut, vStripDist[i])
-- modifico la curva in modo che sia a filo del geo
EgtExtendCurveStartByLen( nStripCut, 1000)
EgtExtendCurveEndByLen( nStripCut, 1000)
nStripCut = EgtTrimCurveWithRegion( nStripCut, nSurfGeo, true, false)
-- aggiusto orientamento per essere coerente con il geo corrispondente
if vStripDist[i] < 0 then
EgtInvertCurve( nStripCut)
end
-- setto info di lavorazione
EgtSetName( nStripCut, WIN_PRC_TYPE.STRIP_CUT)
EgtSetInfo( nStripCut, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.STRIP_CUT)
end
EgtErase( nSurfGeo)
-- verifico se anta ricevente ( info necessaria per ottimizzazione lavorazioni)
local nAreaId = EgtGetParent( EgtGetParent( nOutlineId))
local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i')
if nAreaType == WIN_AREATYPES.SASH then
local nSashType = EgtGetInfo( nAreaId, WIN_SASHTYPE, 'i')
if nSashType == WIN_SASHTYPES.INACTIVE or nSashType == WIN_SASHTYPES.INACTIVE_IN then
local nBaseOutlineId = EgtGetInfo( nOutlineId, WIN_COPY, 'i')
local bOnFrenchSplit = EgtGetInfo( nBaseOutlineId, WIN_CRV_ON_FRENCH_SPLIT, 'b')
if bOnFrenchSplit then
EgtSetInfo( nPartId, WIN_SASHTYPE, WIN_INACTIVE)
end
end
end
end
---------------------------------------------------------------------
-- funzione che calcola gli elementi ausiliari per la creazione del grezzo nell'automatismo delle lavorazioni
local function CalcGeoRaw( nPartId)
local nGeoLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO)
local nGeoRawLayerId = EgtCopyGlob( nGeoLayerId, nPartId)
EgtSetName( nGeoRawLayerId, WIN_GEO_RAW)
EgtSetStatus( nGeoRawLayerId, GDB_ST.OFF)
-- recupero le curve del geo
local nOut = EgtGetFirstNameInGroup( nGeoRawLayerId, WIN_GEO_OUT)
local nIn = EgtGetFirstNameInGroup( nGeoRawLayerId, WIN_GEO_IN)
local vRight = EgtGetNameInGroup( nGeoRawLayerId, WIN_GEO_RIGHT)
local vLeft = EgtGetNameInGroup( nGeoRawLayerId, WIN_GEO_LEFT)
-- verifico se le curve right e left hanno direzioni coerenti
if #vRight == 2 and not AreSamePointApprox( EgtEP( vRight[1]), EgtSP( vRight[2])) then
-- la seconda curva va ignorata
EgtErase( vRight[2])
vRight = { vRight[1]}
end
if #vLeft == 2 and not AreSamePointApprox( EgtEP( vLeft[1]), EgtSP( vLeft[2])) then
-- la prima curva va ignorata
EgtErase( vLeft[1])
vLeft = { vLeft[2]}
end
-- recupero i sovramateriali da applicare alle curve
local dOvermatOut = EgtGetInfo( nPartId, WIN_PRC_OVERMAT_OUT, 'd')
local dOvermatRight = EgtGetInfo( nPartId, WIN_PRC_OVERMAT_RIGHT, 'd')
local dOvermatIn = EgtGetInfo( nPartId, WIN_PRC_OVERMAT_IN, 'd')
local dOvermatLeft = EgtGetInfo( nPartId, WIN_PRC_OVERMAT_LEFT, 'd')
-- applico i sovramateriali
EgtOffsetCurve( nOut, dOvermatOut)
for i = 1, #vRight do
EgtOffsetCurve( vRight[i], dOvermatRight)
end
EgtOffsetCurve( nIn, dOvermatIn)
for i = 1, #vLeft do
EgtOffsetCurve( vLeft[i], dOvermatLeft)
end
-- creo la composita del grezzo a partire dalle curve
local vCrvs = EgtGetAllInGroup( nGeoRawLayerId)
TrimAndOrientOrderedCurves( vCrvs, false)
local nCompo = EgtCurveCompo( nGeoRawLayerId, vCrvs)
-- creo frame ausiliario
local vtX = EgtSV( nCompo)
local frGeo = Frame3d( EgtSP( nCompo), vtX, Z_AX() ^ vtX, Z_AX())
local nFrameId = EgtFrame( nGeoRawLayerId, frGeo)
EgtSetName( nFrameId, WIN_PRC_FRAME)
end
----------------------------------------------------------------------------------
---------------------------------- SOLIDO ----------------------------------------
----------------------------------------------------------------------------------
-- funzione che costruisce una superficie estrudendo il profilo sProfileName lungo l'outline
local function CreateProfileSurf( nOutlineId, nProfileId, sProfileName, dExtraLen, nLayerId)
-- creo guida con estensione in tangenza
local nGuideId = EgtCopy( nOutlineId, nLayerId)
if EgtGetType( nGuideId) == GDB_TY.CRV_LINE then
EgtExtendCurveStartByLen( nGuideId, dExtraLen)
EgtExtendCurveEndByLen( nGuideId, dExtraLen)
else
nGuideId = EgtCurveCompo( nLayerId, nGuideId)
EgtAddCurveCompoLineTg( nGuideId, dExtraLen)
EgtAddCurveCompoLineTg( nGuideId, dExtraLen, false)
end
-- verifico se necessaria inversione della guida nel caso sia curva "virtuale" ( ovvero in area null o split) che deriva da pezzo di split
local nRefSplitId = EgtGetInfo( nOutlineId, WIN_REF_SPLIT, 'i')
if nRefSplitId then
-- recupero base outline per confrontarlo con lo split da cui deriva
local nBaseOutlineId = EgtGetInfo( nOutlineId, WIN_COPY, 'i')
-- recupero vettore tangente nel punto medio del base outline
local ptM = EgtMP( nBaseOutlineId)
local vtM = EgtMV( nBaseOutlineId)
-- recupero vettore tangente nello stesso punto della curva di split da cui deriva
local dRefSplitPar = EgtCurveParamAtPoint( nRefSplitId, ptM)
local vtMRefSplit = EgtUV( nRefSplitId, dRefSplitPar, -1)
-- se i due vettori non sono orientati nella stessa direzione inverto la guida
if not AreSameVectorApprox( vtM, vtMRefSplit) then
EgtInvertCurve( nGuideId)
end
end
-- recupero il profilo da estrudere
local nOrigProfileId = EgtGetFirstNameInGroup( nProfileId, sProfileName)
local nSectionId = EgtCopyGlob( nOrigProfileId, nLayerId)
-- posiziono la sezione di estrusione sulla guida :
-- recupero frame del profilo
local nProfileFrameId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME)
local frProfile = EgtFR( nProfileFrameId, GDB_ID.ROOT)
frProfile:invert()
-- calcolo il frame di destinazione sulla guida
local frDest = Frame3d( EgtSP( nGuideId), - EgtSV( nGuideId), GDB_RT.GLOB)
-- posiziono con i riferimenti
EgtTransform( nSectionId, frProfile, GDB_RT.GLOB)
EgtTransform( nSectionId, frDest, GDB_RT.GLOB)
-- creo la superfice di estrusione
local nStmId = EgtSurfTmSwept( nLayerId, nSectionId, nGuideId, false, WIN_SURF_APPROX)
EgtErase( nGuideId)
EgtErase( nSectionId)
return nStmId
end
---------------------------------------------------------------------
-- funzione che crea la superficie di trim per il solido
local function CreateTrimSurf( nGeoId, nProfileId, dGeoWidth, nLayerId)
-- recupero profilo di riferimento dalla curva geo
local nOrigTrimProfileId = EgtGetInfo( nGeoId, WIN_SEMI_PROFILE, 'i')
-- 1) minizinken
if not nOrigTrimProfileId then
local nGuideId = EgtCopy( nGeoId, nLayerId)
EgtExtendCurveStartByLen( nGuideId, 4 * dGeoWidth)
EgtExtendCurveEndByLen( nGuideId, 4 * dGeoWidth)
EgtMove( nGuideId, Z_AX())
local b3Profile = GetProfileLocalBox( nProfileId)
local nTrimSurf = EgtSurfTmByExtrusion( nLayerId, nGuideId, - Z_AX() * ( b3Profile:getDimY() + 2), WIN_SURF_APPROX)
EgtInvertSurf( nTrimSurf)
EgtErase( nGuideId)
return nTrimSurf
-- 2) controprofilo
else
-- recupero il controprofilo da estrudere
local sTrimProfileName = EgtGetName( nOrigTrimProfileId)
sTrimProfileName = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. WIN_OFST .. sTrimProfileName
-- recupero la curva di outline associata alla curva di geo
local nRefOutline = EgtGetInfo( nGeoId, WIN_REF_OUTLINE, 'i')
-- calcolo la superficie di estrusione
return CreateProfileSurf( nRefOutline, nProfileId, sTrimProfileName, 4 * dGeoWidth, nLayerId)
end
end
---------------------------------------------------------------------
-- funzione che crea le superfici di trim per uno split coinvolto da cambio profilo ( controprofilo della parte sash del telaio e taglio a 45°)
local function CreateMixedSplitTrimSurf( nMixedOutlineId, nProfileId, dExtraLen, nLayerId)
-- estrudo il controprofilo di tipo sash
local nPartId = EgtGetParent( EgtGetParent( nMixedOutlineId))
local nOutlineId = EgtGetInfo( nPartId, WIN_REF_OUTLINE, 'i')
local sTrimProfile = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. WIN_OFST .. WIN_SASH .. WIN_CTRIN
local nTrimStmId = CreateProfileSurf( nOutlineId, nProfileId, sTrimProfile, dExtraLen, nLayerId)
-- creo il solido da intersecare con il controprofilo per il taglio a 45°
local nIntersCrvId = EgtGetInfo( nMixedOutlineId, WIN_MIXED_INTERS_REF, 'i')
local nGuideId = EgtCopyGlob( nIntersCrvId, nLayerId)
local bSashFill = ( EgtGetName( nMixedOutlineId) ~= WIN_SASH)
local vtDirH = EgtSV( nGuideId)
vtDirH:rotate( Z_AX(), EgtIf( bSashFill, -135, 135))
local vtDirV = EgtSV( nGuideId)
vtDirV:rotate( Z_AX(), EgtIf( bSashFill, -45, 45))
EgtAddCurveCompoLine( nGuideId, EgtEP( nGuideId) + dExtraLen * vtDirV)
EgtAddCurveCompoLine( nGuideId, EgtSP( nGuideId) + dExtraLen * vtDirH, false)
EgtAddCurveCompoLine( nGuideId, EgtSP( nGuideId) + dExtraLen * vtDirV, false)
EgtCloseCurveCompo( nGuideId)
EgtMove( nGuideId, 0.01 * Z_AX())
if bSashFill then
EgtInvertCurve( nGuideId)
end
local dDepth = EgtGetInfo( nProfileId, WIN_SASH_DEPTH .. '2', 'd')
local nCutStmId = EgtSurfTmByRegionExtrusion( nLayerId, nGuideId, - ( dDepth + 2) * Z_AX())
-- creo una superficie di trim unica
EgtSurfTmSubtract( nTrimStmId, nCutStmId)
EgtErase( { nGuideId, nCutStmId})
return nTrimStmId
end
---------------------------------------------------------------------
-- funzione che crea il solido di estrusione principale
local function CreateMainSurf( nOutlineId, dExtraLen, nProfileId, sSectionName, nLayerId)
-- curva guida
local nGuideId = EgtCopy( nOutlineId, nLayerId)
EgtSetName( nGuideId, WIN_MAINGUIDE)
EgtSetStatus( nGuideId, GDB_ST.OFF)
EgtExtendCurveStartByLen( nGuideId, dExtraLen)
EgtExtendCurveEndByLen( nGuideId, dExtraLen)
-- posiziono il profilo sulla curva guida :
-- recupero il frame del profilo
local nProfileFrameId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME)
local frInvert = EgtFR( nProfileFrameId)
frInvert:invert()
-- lo applico a tutte le geometrie del profilo
EgtTransform( EgtGetAllInGroup( nProfileId), frInvert)
-- assegno come riferimento del profilo il punto start dell'outline
EgtChangeGroupFrame( nProfileId, Frame3d( EgtSP( nGuideId), - EgtSV( nGuideId)))
-- recupero outline del profilo Main e lo estrudo
local nSectionId = EgtGetFirstNameInGroup( nProfileId, sSectionName)
local nMainExtrusionId = EgtSurfTmSwept( nLayerId, nSectionId, nGuideId, false, WIN_SURF_APPROX)
EgtSetName( nMainExtrusionId, WIN_SRF_MAIN)
return nMainExtrusionId
end
---------------------------------------------------------------------
-- funzione che crea il solido di un pezzo di telaio con cambio profilo
local function CalcMixedFrameSolid( nOutlineId, nSolidLayerId, nProfileLayerId, nGeoLayerId, dGeoWidth)
-- a) SOLIDO PRINCIPALE
local nMainProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN)
-- creo i solidi corrispondenti ai diversi sottotratti uniformi del pezzo
local nMixedOutlinesGrp = EgtGetFirstNameInGroup( EgtGetParent( nSolidLayerId), WIN_MIXED_OUTLINES)
local vMixedOutlines = EgtGetAllInGroup( nMixedOutlinesGrp)
local vMainExtrusions = {}
for i = 1, #vMixedOutlines do
local sSection = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. EgtGetName( vMixedOutlines[i]) .. WIN_SECTION
local nMainExtrusionId = CreateMainSurf( vMixedOutlines[i], 2 * dGeoWidth, nMainProfileId, sSection, nSolidLayerId)
table.insert( vMainExtrusions, nMainExtrusionId)
end
-- taglio i sottopezzi nei punti di intersezione per unirli
local nMixedIntersectionsGrp = EgtGetFirstNameInGroup( EgtGetParent( nSolidLayerId), WIN_MIXED_INTERSECTIONS)
local vIntersections = EgtGetAllInGroup( nMixedIntersectionsGrp)
for i = 1, #vIntersections do
-- creo la superficie di separazione tra i due sottopezzi
local bSashFill = ( EgtGetName( vMixedOutlines[i]) == WIN_SASH)
local vtDirS = EgtSV( vIntersections[i])
vtDirS:rotate( Z_AX(), EgtIf( bSashFill, -135, 135))
local vtDirE = EgtSV( vIntersections[i])
vtDirE:rotate( Z_AX(), EgtIf( bSashFill, 45, -45))
local nCrvTrim = EgtCurveCompo( nSolidLayerId, vIntersections[i], false)
EgtAddCurveCompoLine( nCrvTrim, EgtSP( nCrvTrim) + dGeoWidth * vtDirS, false)
EgtAddCurveCompoLine( nCrvTrim, EgtEP( nCrvTrim) + dGeoWidth * vtDirE)
EgtMove( nCrvTrim, Z_AX())
local nStmTrim = EgtSurfTmByExtrusion( nSolidLayerId, nCrvTrim, - 2 * dGeoWidth * Z_AX())
-- taglio i due sottopezzi
EgtSurfTmSubtract( vMainExtrusions[i+1], nStmTrim)
EgtInvertSurf( nStmTrim)
EgtSurfTmSubtract( vMainExtrusions[i], nStmTrim)
EgtErase( nCrvTrim)
EgtErase( nStmTrim)
end
-- unisco i sottopezzi in una sola superficie
for i = 2, #vMainExtrusions do
EgtSurfTmAdd( vMainExtrusions[1], vMainExtrusions[i])
EgtErase( vMainExtrusions[i])
end
-- creo una copia dell'estrusione principale ( usata per ferramenta)
local nOrigMainExtrusionId = EgtCopy( vMainExtrusions[1], nSolidLayerId)
EgtSetName( nOrigMainExtrusionId, WIN_SRF_ORIGMAIN)
EgtSetStatus( nOrigMainExtrusionId, GDB_ST.OFF)
-- come guida tengo solo una copia della curva di outline
local vMainGuideIds = EgtGetNameInGroup( nSolidLayerId, WIN_MAINGUIDE)
EgtErase( vMainGuideIds)
local nMainGuideId = EgtCopyGlob( nOutlineId, nSolidLayerId)
EgtSetName( nMainGuideId, WIN_MAINGUIDE)
EgtSetStatus( nMainGuideId, GDB_ST.OFF)
-- b) TRIM START
local nPrevGeoId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_LEFT)
local nStartProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_START)
local nTrimSurfStart = CreateTrimSurf( nPrevGeoId, nStartProfileId, dGeoWidth, nSolidLayerId)
EgtSetName( nTrimSurfStart, WIN_SRF_START)
EgtSetStatus( nTrimSurfStart, GDB_ST.OFF)
EgtSurfTmIntersect( vMainExtrusions[1], nTrimSurfStart)
-- c) TRIM END
local nNextGeoId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_RIGHT)
local nEndProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_END)
local nTrimSurfEnd = CreateTrimSurf( nNextGeoId, nEndProfileId, dGeoWidth, nSolidLayerId)
EgtSetName( nTrimSurfEnd, WIN_SRF_END)
EgtSetStatus( nTrimSurfEnd, GDB_ST.OFF)
EgtSurfTmIntersect( vMainExtrusions[1], nTrimSurfEnd)
end
---------------------------------------------------------------------
-- funzione che crea il solido di un pezzo di split coinvolto da cambio profilo
local function CalcMixedSplitSolid( nOutlineId, nSolidLayerId, nProfileLayerId, dGeoWidth)
-- a) creo il solido di estrusione principale
local nMainProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN)
local sSection = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. WIN_SECTION
local nMainExtrusionId = CreateMainSurf( nOutlineId, 2 * dGeoWidth, nMainProfileId, sSection, nSolidLayerId)
-- creo una copia
local nOrigMainExtrusionId = EgtCopy( nMainExtrusionId, nSolidLayerId)
EgtSetName( nOrigMainExtrusionId, WIN_SRF_ORIGMAIN)
EgtSetStatus( nOrigMainExtrusionId, GDB_ST.OFF)
-- b) trim start
local nPrevProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_START)
local nPrevMixedOutline = EgtGetInfo( nOutlineId, WIN_MIXED_REF_START, 'i')
local nStmTrimStart = CreateMixedSplitTrimSurf( nPrevMixedOutline, nPrevProfileId, dGeoWidth, nSolidLayerId)
EgtSetName( nStmTrimStart, WIN_SRF_START)
EgtSetStatus( nStmTrimStart, GDB_ST.OFF)
EgtSurfTmIntersect( nMainExtrusionId, nStmTrimStart)
-- c) trim end
local nNextProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_END)
local nNextMixedOutline = EgtGetInfo( nOutlineId, WIN_MIXED_REF_END, 'i')
local nStmTrimEnd = CreateMixedSplitTrimSurf( nNextMixedOutline, nNextProfileId, dGeoWidth, nSolidLayerId)
EgtSetName( nStmTrimEnd, WIN_SRF_END)
EgtSetStatus( nStmTrimEnd, GDB_ST.OFF)
EgtSurfTmIntersect( nMainExtrusionId, nStmTrimEnd)
end
---------------------------------------------------------------------
-- funzione che crea il solido del pezzo
local function CalcSolid( nPartId, nOutlineId)
-- creo layer per solido
local nSolidLayerId = EgtGroup( nPartId)
EgtSetName( nSolidLayerId, WIN_SOLID)
-- recupero profilo principale
local nProfileLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE)
-- recupero geo e la sua larghezza
local nGeoLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO)
local dGeoWidth = EgtGetInfo( nGeoLayerId, WIN_GEOWIDTH, 'd')
-- gestione speciale per pezzi con CAMBIO PROFILO
local bChangeProfile = EgtGetInfo( nOutlineId, WIN_PRF_CHANGE, 'b') or false
if bChangeProfile then
if EgtGetName( nOutlineId) == WIN_SPLIT then
return CalcMixedSplitSolid( nOutlineId, nSolidLayerId, nProfileLayerId, dGeoWidth)
else
return CalcMixedFrameSolid( nOutlineId, nSolidLayerId, nProfileLayerId, nGeoLayerId, dGeoWidth)
end
end
-- a) creo il solido di estrusione principale
local nMainProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN)
local sSection = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. WIN_SECTION
local nMainExtrusionId = CreateMainSurf( nOutlineId, 2 * dGeoWidth, nMainProfileId, sSection, nSolidLayerId)
-- creo una copia ( usata per calcolo ferramenta)
local nOrigMainExtrusionId = EgtCopy( nMainExtrusionId, nSolidLayerId)
EgtSetName( nOrigMainExtrusionId, WIN_SRF_ORIGMAIN)
EgtSetStatus( nOrigMainExtrusionId, GDB_ST.OFF)
-- b) trim con i controprofili sullo start
local vPrevGeoId = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_LEFT)
local vStartProfileId = EgtGetNameInGroup( nProfileLayerId, WIN_PRF_START)
for i = 1, #vPrevGeoId do
-- creo la superficie di trim
local nTrimSurf = CreateTrimSurf( vPrevGeoId[i], vStartProfileId[i], dGeoWidth, nSolidLayerId)
EgtSetStatus( nTrimSurf, GDB_ST.OFF)
EgtSetName( nTrimSurf, WIN_SRF_START)
-- 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, nTrimSurf)
end
-- c) trim con i controprofili sull'end
local vNextGeoId = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_RIGHT)
local vEndProfileId = EgtGetNameInGroup( nProfileLayerId, WIN_PRF_END)
for i = 1, #vNextGeoId do
-- creo la superficie di trim
local nTrimSurf = CreateTrimSurf( vNextGeoId[i], vEndProfileId[i], dGeoWidth, nSolidLayerId)
EgtSetStatus( nTrimSurf, GDB_ST.OFF)
EgtSetName( nTrimSurf, WIN_SRF_END)
-- eseguo intersezione per ottenere un solido unico
EgtSurfTmIntersect( nMainExtrusionId, nTrimSurf)
end
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
----------------------------------------------------------------------------------
---------------------------------- DOWELS ----------------------------------------
----------------------------------------------------------------------------------
-- funzione che sottrae il dowel al solido
local function UpdateSolidWithDowel( nDowelId, nSolidId, vtDir, dLen, nLayerId)
-- creo il solido del dowel a partire dalla circonferenza che lo definisce
local nDowelSolidId
if s_bSimplSolid then
-- se solidi semplificati creo foro grossolano per velocizzare operazioni di subtract
local nDowelApprox = EgtCopyGlob( nDowelId, nLayerId)
EgtApproxCurve( nDowelApprox, GDB_CA.LINES, 0.2)
nDowelSolidId = EgtSurfTmByRegionExtrusion( nLayerId, nDowelApprox, vtDir * dLen)
EgtErase( nDowelApprox)
else
nDowelSolidId = EgtSurfTmByRegionExtrusion( nLayerId, nDowelId, vtDir * dLen)
end
-- sottraggo il dowel al solido
EgtSurfTmSubtract( nSolidId, nDowelSolidId)
EgtErase( nDowelSolidId)
end
---------------------------------------------------------------------
-- funzione che calcola il riferimento dove posizionare i dowels
local function CreateDowelFrameDest( nRefProfileType, nPrevGeo, nGeo, nRefOutline, bFullOrShort, bSashOrFrame)
-- 1) la direzione z è quella del pezzo short nel caso rettangolare
local vtZ
if nRefProfileType == WIN_PRF.TOP then
vtZ = - X_AX()
elseif nRefProfileType == WIN_PRF.BOTTOM or nRefProfileType == WIN_PRF.BOTTOMRAIL then
vtZ = X_AX()
elseif nRefProfileType == WIN_PRF.LEFT then
vtZ = - Y_AX()
elseif nRefProfileType == WIN_PRF.RIGHT then
vtZ = Y_AX()
end
local frDest = Frame3d( ORIG(), - vtZ)
-- 2) punto di origine
local nPrevRight = EgtGetFirstNameInGroup( nPrevGeo, WIN_GEO_RIGHT)
local ptRef1 = EgtIf( bFullOrShort, EgtSP( nPrevRight), EgtEP( nPrevRight))
local nLeft = EgtGetFirstNameInGroup( nGeo, WIN_GEO_LEFT)
local ptRef2 = EgtIf( bFullOrShort, EgtSP( nLeft), EgtEP( nLeft))
-- riporto i punti sulla curva di outline su cui va posizionato il profilo con le spine
local _, ptInt1 = EgtPointCurveDist( ptRef1, nRefOutline)
local _, ptInt2 = EgtPointCurveDist( ptRef2, nRefOutline)
-- nel caso di telaio conviene tenere il punto più "interno" visto che la correzione sarà fatta verso l'esterno
-- nel caso di anta conviene tenere quello più "esterno" visto che la correzione sarà fatta verso l'interno
ptInt1:toLoc( frDest)
ptInt2:toLoc( frDest)
local ptInt
if ptInt1:getX() > ptInt2:getX() then
ptInt = EgtIf( bSashOrFrame, Point3d( ptInt1), Point3d( ptInt2))
else
ptInt = EgtIf( bSashOrFrame, Point3d( ptInt2), Point3d( ptInt1))
end
ptInt:toGlob( frDest)
-- modifico il punto di origine del frame nel punto individuato
frDest:move( ptInt - ORIG())
return frDest
end
---------------------------------------------------------------------
-- funzione che posiziona il dowel tramite i riferimenti
local function PositionDowel( nDowelId, frOrig, frDest, vtDir, nSurfId)
-- posiziono il dowel utilizzando i riferimenti
EgtTransform( nDowelId, frOrig, GDB_RT.GLOB)
EgtTransform( nDowelId, frDest, GDB_RT.GLOB)
EgtMove( nDowelId, 300 * vtDir)
-- creo il tool corrispondente al dowel
local dRad = EgtArcRadius( nDowelId)
EgtCAvSetStdTool( s_dDowelTol, 2 * dRad, 0)
-- calcolo spostamento per posizionarlo in corrispondenza della superficie
local dStart = EgtCAvToolPosStm( EgtCP( nDowelId), - vtDir, nSurfId, - vtDir)
EgtMove( nDowelId, - dStart * vtDir)
end
---------------------------------------------------------------------
-- funzione che crea il dowel e lo sottrae al solido
local function CreateDowel( nOrigDowelId, nLayerId, frOrig, frDest, vtDir, nTestSurfId, sLenKey, sDowelSide, nMainExtrusionId)
-- vtDir rivolta verso interno del pezzo
local nDowelId = EgtCopyGlob( nOrigDowelId, nLayerId)
EgtSetColor( nDowelId, Color3d( 128, 128, 128))
-- posiziono il dowel
PositionDowel( nDowelId, frOrig, frDest, vtDir, nTestSurfId)
-- assegno estrusione e spessore
local dLen = EgtGetInfo( nOrigDowelId, sLenKey, 'd') + s_dDowelTol
EgtModifyCurveExtrusion( nDowelId, - vtDir)
EgtModifyCurveThickness( nDowelId, - dLen)
-- setto info di lavorazione
EgtSetInfo( nDowelId, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.HOLE)
EgtSetInfo( nDowelId, WIN_PRC_SIDE, sDowelSide)
-- eventuale aggiornamento del solido
if nMainExtrusionId then
UpdateSolidWithDowel( nDowelId, nMainExtrusionId, vtDir, dLen, nLayerId)
end
return nDowelId
end
---------------------------------------------------------------------
-- funzione che calcola la correzione da applicare al frame dei dowels per evitare che fuoriescano dal pezzo da un lato visibile ( esterno per ante ed interno per telaio)
local function CalcDowelFrameCorrection( nOutlineId, nPrevOutlineId, nDowelRef, frOrig, frDest, nTestSurfPos, nTestSurfPosPrev, nTestSurf, vtMove, nLayerId, sLenKey, sPrevLenKey)
local dMove = 0
-- se le curve sono due linee ortogonali non serve correzione
if EgtGetType( nOutlineId) == GDB_TY.CRV_LINE and EgtGetType( nPrevOutlineId) == GDB_TY.CRV_LINE then
local vt1 = EgtSV( nPrevOutlineId)
local vt2 = EgtSV( nOutlineId)
local dAng = GetAngleXY( vt1, vt2)
if abs( abs( dAng) - 90) < GEO.EPS_SMALL then
return dMove
end
end
-- 1) verifico posizione per il pezzo corrente
-- posiziono il dowel
local nDowel1 = EgtCopyGlob( nDowelRef, nLayerId)
PositionDowel( nDowel1, frOrig, frDest, - frDest:getVersZ(), nTestSurfPos)
-- verifico se la faccia di fondo fuoriesce dalla superficie di test
local dLen = EgtGetInfo( nDowel1, sLenKey, 'd') + s_dDowelTol
local dMove1 = EgtCAvToolPosStm( EgtCP( nDowel1) - frDest:getVersZ() * dLen, frDest:getVersZ(), nTestSurf, vtMove)
-- 2) verifico posizione per il pezzo precedente
-- posiziono il dowel
local nDowel2 = EgtCopyGlob( nDowelRef, nLayerId)
PositionDowel( nDowel2, frOrig, frDest, frDest:getVersZ(), nTestSurfPosPrev)
-- verifico se la faccia di fondo fuoriesce dalla superficie di test
local dPrevLen = EgtGetInfo( nDowel2, sPrevLenKey, 'd') + s_dDowelTol
local dMove2 = EgtCAvToolPosStm( EgtCP( nDowel2) + frDest:getVersZ() * dPrevLen, - frDest:getVersZ(), nTestSurf, vtMove)
EgtErase( nDowel1)
EgtErase( nDowel2)
-- calcolo la correzione complessiva
dMove = max( dMove1, dMove2)
return dMove
end
---------------------------------------------------------------------
-- funzione che calcola i dowels tra due pezzi
local function CalcDowels( nOutlineId, nPrevOutlineId, bSashOrFrame, bBottomRail)
-- recupero i pezzi
local nPart = EgtGetInfo( nOutlineId, WIN_REF_PART, 'i')
local nPrevPart = EgtGetInfo( nPrevOutlineId, WIN_REF_PART, 'i')
if bBottomRail then
if EgtGetName( nOutlineId) == WIN_BOTTOM then
nPart = EgtGetInfo( nOutlineId, WIN_REF_BOTTOMRAIL_PART, 'i')
else
nPrevPart = EgtGetInfo( nPrevOutlineId, WIN_REF_BOTTOMRAIL_PART, 'i')
end
end
-- recupero i layer delle lavorazioni
local nLayerId = EgtGetFirstNameInGroup( nPart, WIN_PRC)
local nPrevLayerId = EgtGetFirstNameInGroup( nPrevPart, WIN_PRC)
-- recupero i profili
local nProfileLay = EgtGetFirstNameInGroup( nPart, WIN_PROFILE)
local nProfileId = EgtGetFirstNameInGroup( nProfileLay, WIN_PRF_MAIN)
local nPrevProfileLay = EgtGetFirstNameInGroup( nPrevPart, WIN_PROFILE)
local nPrevProfileId = EgtGetFirstNameInGroup( nPrevProfileLay, WIN_PRF_MAIN)
-- recupero i geo
local nGeo = EgtGetFirstNameInGroup( nPart, WIN_GEO)
local nPrevGeo = EgtGetFirstNameInGroup( nPrevPart, WIN_GEO)
-- recupero i tipi di profilo
local nPrevProfileType = GetOutlineProfileType( nPrevOutlineId, bBottomRail)
local nProfileType = GetOutlineProfileType( nOutlineId, bBottomRail)
-- caso particolare del triangolo : se lato top contro bottom il top deve essere gestito come un left/right
if nProfileType == WIN_PRF.TOP and nPrevProfileType == WIN_PRF.BOTTOM then
nProfileType = WIN_PRF.RIGHT
elseif nProfileType == WIN_PRF.BOTTOM and nPrevProfileType == WIN_PRF.TOP then
nPrevProfileType = WIN_PRF.LEFT
end
-- recupero i solidi
local nPrevSolidId, nSolidId, nPrevSolidLay, nSolidLay
if s_bCalcSolid then
nSolidLay = EgtGetFirstNameInGroup( nPart, WIN_SOLID)
nSolidId = EgtGetFirstNameInGroup( nSolidLay, WIN_SRF_MAIN)
nPrevSolidLay = EgtGetFirstNameInGroup( nPrevPart, WIN_SOLID)
nPrevSolidId = EgtGetFirstNameInGroup( nPrevSolidLay, WIN_SRF_MAIN)
end
-- recupero il tipo di giunzione
local nJointType = EgtGetInfo( nOutlineId, WIN_STARTJOINT, 'i')
if bBottomRail then
if EgtGetName( nOutlineId) == WIN_BOTTOM then
nJointType = WIN_PART_JNT.SHORT
else
nJointType = WIN_PART_JNT.FULL
end
end
if nJointType == WIN_PART_JNT.ANGLED then
-- TO DO
elseif nJointType == WIN_PART_JNT.FULL then
-- calcolo il riferimento del profilo
local nFrameProfile = EgtGetFirstNameInGroup( nPrevProfileId, WIN_SECTIONFRAME)
local frOrig = EgtFR( nFrameProfile, GDB_ID.ROOT)
frOrig:invert()
-- calcolo il riferimento su cui posizionare i dowels
local frDest = CreateDowelFrameDest( nPrevProfileType, nPrevGeo, nGeo, nPrevOutlineId, true, bSashOrFrame)
-- recupero info con la lunghezza ( dipendono dal profilo del pezzo full)
local sLenKey = EgtIf( nProfileType == WIN_PRF.BOTTOM, WIN_DWL_BOTTOM_PERP_LEN, WIN_DWL_TOP_PERP_LEN)
local sPrevLenKey = EgtIf( nProfileType == WIN_PRF.BOTTOM, WIN_DWL_BOTTOM_PARA_LEN, WIN_DWL_TOP_PARA_LEN)
-- superficie test per il posizionamento dei dowels : è la superficie in del pezzo full
local nTestSurf
if not s_bCalcSolid or s_bSimplSolid then
local sCtrIn = WIN_OFST .. GetProfileCtrIn( nOutlineId, nPrevOutlineId, nProfileId) -- controprofilo in del pezzo corrente
nTestSurf = CreateProfileSurf( nOutlineId, nProfileId, sCtrIn, 100, nLayerId)
else
-- è la superficie che viene utilizzata per trimmare l'end del pezzo prev
local nOrigSurf = EgtGetFirstNameInGroup( nPrevSolidLay, WIN_SRF_END)
nTestSurf = EgtCopyGlob( nOrigSurf, nLayerId)
end
local nTestSurfInverted = EgtCopyGlob( nTestSurf, nLayerId)
EgtInvertSurf( nTestSurfInverted)
-- superficie test per la traslazione dei dowels
local nTestSurf2
if bSashOrFrame then
-- se anta la superficie da cui non fuoriuscire è quella esterna del pezzo short, ovvero la superficie usata per trimmare lo start del pezzo corrente
if not s_bCalcSolid or s_bSimplSolid then
nTestSurf2 = CreateProfileSurf( nPrevOutlineId, nPrevProfileId, WIN_OFST .. WIN_OUT, 100, nLayerId)
else
local nOrigSurf = EgtGetFirstNameInGroup( nSolidLay, WIN_SRF_START)
nTestSurf2 = EgtCopyGlob( nOrigSurf, nLayerId)
end
EgtInvertSurf( nTestSurf2)
else
-- se telaio la superficie da cui non fuoriuscire è quella interna del pezzo short
local sCtrIn2 = WIN_OFST .. GetProfileCtrIn( nPrevOutlineId, nOutlineId, nPrevProfileId)
nTestSurf2 = CreateProfileSurf( nPrevOutlineId, nPrevProfileId, sCtrIn2, 100, nLayerId)
end
-- direzione per la traslazione dei dowels
local vtMove = EgtIf( bSashOrFrame, - frDest:getVersX(), frDest:getVersX())
-- analizzo le singole file di dowels
for k = 1, 3 do
-- recupero i dowels della fila k-esima
local vDowels = EgtGetNameInGroup( nPrevProfileId, WIN_DOWEL .. 'Row' .. tostring( k))
if #vDowels == 0 then
break
end
-- recupero il dowel nella posizione più problematica ( per le ante è quello più esterno, per il telaio quello più interno)
local nDowelRef = EgtIf( bSashOrFrame, vDowels[1], vDowels[#vDowels])
-- calcolo correzione da applicare al frame affinchè i dowels non fuoriescano da un lato visibile ( esterno per ante ed interno per telaio)
local dMove = CalcDowelFrameCorrection( nOutlineId, nPrevOutlineId, nDowelRef, frOrig, frDest, nTestSurfInverted, nTestSurf, nTestSurf2, vtMove, nLayerId, sLenKey, sPrevLenKey)
local frDestDowel = Frame3d( frDest)
frDestDowel:move( dMove * vtMove)
for i = 1, #vDowels do
-- dowels per pezzo corrente ( full)
CreateDowel( vDowels[i], nLayerId, frOrig, frDestDowel, - frDestDowel:getVersZ(), nTestSurfInverted, sLenKey, WIN_PRC_SIDETYPE.IN, nSolidId)
-- dowels per prezzo precedente ( short)
CreateDowel( vDowels[i], nPrevLayerId, frOrig, frDestDowel, frDestDowel:getVersZ(), nTestSurf, sPrevLenKey, WIN_PRC_SIDETYPE.RIGHT, nPrevSolidId)
end
end
EgtErase( nTestSurf)
EgtErase( nTestSurfInverted)
EgtErase( nTestSurf2)
elseif nJointType == WIN_PART_JNT.SHORT then
-- calcolo il riferimento del profilo
local nFrameProfile = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME)
local frOrig = EgtFR( nFrameProfile, GDB_ID.ROOT)
frOrig:invert()
-- calcolo il riferimento su cui posizionare i dowels
local frDest = CreateDowelFrameDest( nProfileType, nPrevGeo, nGeo, nOutlineId, false, bSashOrFrame)
-- recupero info con la lunghezza ( dipendono dal profilo del pezzo full, quindi da prezzo prev)
local sLenKey = WIN_DWL_TOP_PARA_LEN
local sPrevLenKey = WIN_DWL_TOP_PERP_LEN
if nPrevProfileType == WIN_PRF.BOTTOM then
sLenKey = WIN_DWL_BOTTOM_PARA_LEN
sPrevLenKey = WIN_DWL_BOTTOM_PERP_LEN
elseif nPrevProfileType == WIN_PRF.BOTTOM_RAIL then
sLenKey = WIN_DWL_BOTTOMRAIL_PARA_LEN
sPrevLenKey = WIN_DWL_BOTTOMRAIL_PERP_LEN
end
-- superficie test per il posizionamento dei dowels
-- è il controprofilo in del pezzo full quindi è la stessa superficie che viene utilizzata per trimmare lo start del pezzo corrente
local nTestSurf
if not s_bCalcSolid or s_bSimplSolid then
local sCtrIn = WIN_OFST .. GetProfileCtrIn( nPrevOutlineId, nOutlineId, nPrevProfileId) -- controprofilo del pezzo full
nTestSurf = CreateProfileSurf( nPrevOutlineId, nPrevProfileId, sCtrIn, 100, nLayerId)
else
local nOrigSurf = EgtGetFirstNameInGroup( nSolidLay, WIN_SRF_START)
nTestSurf = EgtCopyGlob( nOrigSurf, nLayerId)
end
local nTestSurfInverted = EgtCopyGlob( nTestSurf, nLayerId)
EgtInvertSurf( nTestSurfInverted)
-- superficie test per la traslazione dei dowels
local nTestSurf2
if bSashOrFrame then
if not s_bCalcSolid or s_bSimplSolid then
nTestSurf2 = CreateProfileSurf( nOutlineId, nProfileId, WIN_OFST .. WIN_OUT, 100, nLayerId)
else
local nOrigSurf = EgtGetFirstNameInGroup( nPrevSolidLay, WIN_SRF_END)
nTestSurf2 = EgtCopyGlob( nOrigSurf, nLayerId)
end
EgtInvertSurf( nTestSurf2)
else
local sCtrIn2 = WIN_OFST .. GetProfileCtrIn( nOutlineId, nPrevOutlineId, nProfileId) -- controprofilo del pezzo short
nTestSurf2 = CreateProfileSurf( nOutlineId, nProfileId, sCtrIn2, 100, nLayerId)
end
-- direzione per la traslazione dei dowels
local vtMove = EgtIf( bSashOrFrame, - frDest:getVersX(), frDest:getVersX())
-- analizzo le singole file di dowels
for k = 1, 3 do
-- recupero i dowels sulla fila k-esima
local vDowels = EgtGetNameInGroup( nProfileId, WIN_DOWEL .. 'Row' .. tostring(k))
if #vDowels == 0 then
break
end
-- recupero il dowel nella posizione più problematica ( per le ante è quello più esterno, per il telaio quello più interno)
local nDowelRef = EgtIf( bSashOrFrame, vDowels[1], vDowels[#vDowels])
-- calcolo correzione da applicare al frame affinchè i dowels non fuoriescano da un lato visibile ( esterno per ante ed interno per telaio)
local dMove = CalcDowelFrameCorrection( nOutlineId, nPrevOutlineId, nDowelRef, frOrig, frDest, nTestSurf, nTestSurfInverted, nTestSurf2, vtMove, nLayerId, sLenKey, sPrevLenKey)
local frDestDowel = Frame3d( frDest)
frDestDowel:move( dMove * vtMove)
for i = 1, #vDowels do
-- dowels per pezzo corrente ( short)
CreateDowel( vDowels[i], nLayerId, frOrig, frDestDowel, - frDestDowel:getVersZ(), nTestSurf, sLenKey, WIN_PRC_SIDETYPE.LEFT, nSolidId)
-- dowels per prezzo precedente ( full)
CreateDowel( vDowels[i], nPrevLayerId, frOrig, frDestDowel, frDestDowel:getVersZ(), nTestSurfInverted, sPrevLenKey, WIN_PRC_SIDETYPE.IN, nPrevSolidId)
end
end
EgtErase( nTestSurf)
EgtErase( nTestSurfInverted)
EgtErase( nTestSurf2)
end
end
---------------------------------------------------------------------
-- funzione che calcola i dowels tra uno split e i pezzi sui cui poggia
local function CalcSplitDowels( nSplitId, vOutlines, bStartOrEnd)
-- TO DO : da gestire incrocio dowels di tre pezzi
-- recupero il pezzo dello split
local nSplitPart = EgtGetInfo( nSplitId, WIN_REF_PART, 'i')
-- recupero il profilo originale dello split e il suo frame
local nSplitProfile = GetOutlineProfileId( nSplitId, false)
local nSplitProfileFrameId = EgtGetFirstNameInGroup( nSplitProfile, WIN_SECTIONFRAME)
local frOrig = EgtFR( nSplitProfileFrameId, GDB_ID.ROOT)
frOrig:invert()
-- recupero il gruppo delle lavorazioni
local nSplitLayerId = EgtGetFirstNameInGroup( nSplitPart, WIN_PRC)
-- recupero eventuale solido e superifici usate per il suo trim
local nSplitSolidId, vTestSurf
if s_bCalcSolid then
local nSplitSolidLayerId = EgtGetFirstNameInGroup( nSplitPart, WIN_SOLID)
nSplitSolidId = EgtGetFirstNameInGroup( nSplitSolidLayerId, WIN_SRF_MAIN)
vTestSurf = EgtGetNameInGroup( nSplitSolidLayerId, EgtIf( bStartOrEnd, WIN_SRF_START, WIN_SRF_END))
end
-- indviduo il lato su cui andranno i dowels
local sSplitDowelSide = WIN_PRC_SIDETYPE.RIGHT
if bStartOrEnd then
sSplitDowelSide = WIN_PRC_SIDETYPE.LEFT
end
-- creo la superficie di test per verificare se dowel interno al pezzo
local nSplitGeo = EgtGetFirstNameInGroup( nSplitPart, WIN_GEO)
local nSplitSurf = CreateGeoArea( nSplitGeo, nSplitLayerId)
local ptRef = EgtIf( bStartOrEnd, EgtSP( nSplitId), EgtEP( nSplitId))
for i = 1, #vOutlines do
-- recupero il pezzo associato e il suo outline di riferimento
local nPartId = FindAssociatedPart( vOutlines[i])
local nOutlineId = EgtGetInfo( nPartId, WIN_REF_OUTLINE, 'i')
local nProfileType = GetOutlineProfileType( nOutlineId, true)
-- calcolo il frame di destinazione
-- trovo intersezione dello split con lato In o Out del geo
local nGeoLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO)
local nGeoCrvId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_IN)
local ptInters = EgtIP( nGeoCrvId, nSplitId, ptRef)
local sDowelSide = WIN_PRC_SIDETYPE.IN
if not ptInters and nProfileType == WIN_PRF.SPLIT then
nGeoCrvId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_OUT)
ptInters = EgtIP( nGeoCrvId, nSplitId, ptRef)
sDowelSide = WIN_PRC_SIDETYPE.OUT
end
-- se non trovo intersezione passo al successivo
if ptInters then
-- TO DO : gestione split non lineare
local frDest = Frame3d( ptInters, - EgtSV( nSplitId))
-- recupero il layer con le lavorazioni
local nLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PRC)
-- nel layer dei profili del pezzo aggiungo il profilo dello split posizionato correttamente
local nProfileLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE)
local nSplitProfileCopyId = EgtCopy( nSplitProfile, nProfileLayerId)
local sSplitProfileType = EgtGetName( nSplitProfile)
EgtSetInfo( nSplitProfileCopyId, WIN_PRF_TYPE, sSplitProfileType)
EgtSetName( nSplitProfileCopyId, WIN_PRF_SPLIT)
-- posiziono il profilo sulla curva di split
EgtTransform( EgtGetAllInGroup( nSplitProfileCopyId), frOrig, GDB_RT.GLOB)
EgtChangeGroupFrame( nSplitProfileCopyId, frDest, GDB_RT.GLOB)
-- recupero eventuale solido
local nSolidId
if s_bCalcSolid then
local nSolidLayerId = EgtGetFirstNameInGroup( nPartId, WIN_SOLID)
nSolidId = EgtGetFirstNameInGroup( nSolidLayerId, WIN_SRF_MAIN)
end
-- recupero le chiavi delle lunghezze ( dipendono dal profilo del pezzo su cui poggia lo split)
local sSplitLenKey = WIN_DWL_TOP_PARA_LEN
local sLenKey = WIN_DWL_TOP_PERP_LEN
if nProfileType == WIN_PRF.BOTTOM then
sSplitLenKey = WIN_DWL_BOTTOM_PARA_LEN
sLenKey = WIN_DWL_BOTTOM_PERP_LEN
elseif nProfileType == WIN_PRF.BOTTOMRAIL then
sSplitLenKey = WIN_DWL_RAILBOTTOM_PARA_LEN
sLenKey = WIN_DWL_RAILBOTTOM_PERP_LEN
elseif nProfileType == WIN_PRF.SPLIT then
sSplitLenKey = WIN_DWL_SPLIT_PARA_LEN
sLenKey = WIN_DWL_SPLIT_PERP_LEN
end
-- creo la superficie di test per il posizionamento dei dowels
local nProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN)
local nTestSurf
if not s_bCalcSolid or s_bSimplSolid then
local bChangeProfile = EgtGetInfo( nSplitId, WIN_PRF_CHANGE, 'b') or false
if bChangeProfile then
local nMixedOutline = EgtGetInfo( nSplitId, EgtIf( bStartOrEnd, WIN_MIXED_REF_START, WIN_MIXED_REF_END), 'i')
nTestSurf = CreateMixedSplitTrimSurf( nMixedOutline, nProfileId, 100, nLayerId)
else
local sCtr = WIN_OFST .. GetProfileCtrIn( nOutlineId, nSplitId, nProfileId)
nTestSurf = CreateProfileSurf( nOutlineId, nProfileId, sCtr, 100, nLayerId)
end
else
-- è la stessa superficie utilizzata per il trim del solido
nTestSurf = EgtCopyGlob( vTestSurf[i], nSplitLayerId)
end
local nTestSurfInverted = EgtCopyGlob( nTestSurf, nSplitLayerId)
EgtInvertSurf( nTestSurfInverted)
-- calcolo le direzioni entranti nei pezzi
local vtSplitDir = EgtIf( bStartOrEnd, - frDest:getVersZ(), frDest:getVersZ())
local vtDir = frDest:getVersZ()
local _, _, nSide = EgtPointCurveDistSide( ptInters + vtDir, nGeoCrvId, Z_AX())
if nSide == 1 then
-- se a destra della curva significa che la direzione è uscente dal pezzo e va invertita
vtDir = - vtDir
end
-- creo la superficie di test per verificare se dowel interno al pezzo
local nGeo = EgtGetFirstNameInGroup( nPartId, WIN_GEO)
local nSurf = CreateGeoArea( nGeo, nLayerId)
-- aggiungo i dowels
local vDowels = EgtGetNameInGroup( nSplitProfile, WIN_DOWEL .. '*') or {}
for i = 1, #vDowels do
-- split
local nDowel1 = CreateDowel( vDowels[i], nSplitLayerId, frOrig, frDest, vtSplitDir, nTestSurf, sSplitLenKey, sSplitDowelSide, nSplitSolidId)
-- verifico se dowel è interno al pezzo ( TO DO : da migliorare!)
local ptTest = EgtCP( nDowel1) - vtSplitDir * EgtCurveThickness( nDowel1)
local nTestPoint = EgtPoint( nSplitLayerId, ptTest)
if EgtSurfFrTestExternal( nSplitSurf, nTestPoint) then
EgtErase( nDowel1)
end
EgtErase( nTestPoint)
-- pezzo
local nDowel2 = CreateDowel( vDowels[i], nLayerId, frOrig, frDest, vtDir, nTestSurfInverted, sLenKey, sDowelSide, nSolidId)
ptTest = EgtCP( nDowel2) - vtDir * EgtCurveThickness( nDowel2)
nTestPoint = EgtPoint( nLayerId, ptTest)
if EgtSurfFrTestExternal( nSurf, nTestPoint) then
EgtErase( nDowel2)
end
EgtErase( nTestPoint)
end
EgtErase( nTestSurf)
EgtErase( nTestSurfInverted)
EgtErase( nSurf)
end
end
EgtErase( nSplitSurf)
end
---------------------------------------------------------------------
-- funzione che calcola le spine
local function CalculateAreaDowels( nAreaId)
local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i')
local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE)
if nAreaType == WIN_AREATYPES.FRAME or nAreaType == WIN_AREATYPES.SASH then
-- verifico se presente bottomrail
local bBottomRail = EgtGetInfo( nOutlineLayerId, WIN_BOTTOMRAIL, 'b') or false
-- aggiungo le spine sui pezzi dell'area
local nOutline = EgtGetFirstInGroup( nOutlineLayerId)
local nPrevOutline = EgtGetLastInGroup( nOutlineLayerId)
while nOutline do
-- aggiungo spine su nOutline e nPrevOutline nel loro punto di giunzione
CalcDowels( nOutline, nPrevOutline, nAreaType == WIN_AREATYPES.SASH, false)
-- bottomrail
if bBottomRail and ( EgtGetName( nOutline) == WIN_BOTTOM or EgtGetName( nPrevOutline) == WIN_BOTTOM) then
CalcDowels( nOutline, nPrevOutline, false, true)
end
-- aggiorno per iterazione successiva
nPrevOutline = nOutline
nOutline = EgtGetNext( nOutline)
end
end
-- verifico se c'e' uno split
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 per il quale vanno calcolate le spine
if nSplitType ~= WIN_SPLITTYPES.FRENCH then
local nSplitId = EgtGetFirstInGroup( nSplitLayerId)
-- start
local vPrevOutlineId = EgtGetInfo( nSplitId, WIN_PREV_OUTLINES, 'vi')
CalcSplitDowels( nSplitId, vPrevOutlineId, true)
-- end
local vNextOutlineId = EgtGetInfo( nSplitId, WIN_NEXT_OUTLINES, 'vi')
CalcSplitDowels( nSplitId, vNextOutlineId, false)
end
end
-- calcolo le spine delle sottoaree
local nChildAreaId = EgtGetFirstNameInGroup( nAreaId, WIN_AREA .. '*')
while nChildAreaId do
CalculateAreaDowels( nChildAreaId)
nChildAreaId = EgtGetNextName( nChildAreaId, WIN_AREA .. '*')
end
end
----------------------------------------------------------------------------------
--------------------------------- STRIP ----------------------------------------
----------------------------------------------------------------------------------
-- funzione che restitutisce lo Strip piu' vicino
-- ( analoga a GetProfileCtrIn)
local function GetStripNearestToOutline( nPrevProfileId, nPrevOutlineId, nOutlineId)
local sStripName = WIN_STRIP
-- gestione particolare del caso di profilo di split
if not EgtGetFirstNameInGroup( nPrevProfileId, sStripName) 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 _, _, nSide = EgtPointCurveDistSide( EgtMP( nOutlineId), nPrevSouId, Z_AX())
if nSide == 1 then
sStripName = WIN_STRIP .. '1' -- dx
else
sStripName = WIN_STRIP .. '2' -- sx
end
end
if s_bSimplSolid then
sStripName = WIN_SIMPLIFIED .. sStripName
end
local nStripId = EgtGetFirstNameInGroup( nPrevProfileId, sStripName)
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)
-- 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)
-- recupero i pezzi precedente e successivo, prendendo eventualmente quelli di bottomrail
local nPrevPartId = FindAssociatedPart( vPrevOutlineId[1])
local nNextPartId = FindAssociatedPart( vNextOutlineId[1])
-- recupero profilo e controprofili
local nMainProfileLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE)
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 e lo posiziono sulla guida
local nMainStripId = GetStripNearestToOutline( nMainProfileId, nOutlineId, vPrevOutlineId[1])
local nSectionId = EgtCopyGlob( nMainStripId, nSolidLayerId)
local nFrameProfileId = EgtGetFirstNameInGroup( nMainProfileId, WIN_SECTIONFRAME)
local frOrig = EgtFR( nFrameProfileId, GDB_ID.ROOT)
frOrig:invert()
local frDest = Frame3d( EgtSP( nGuideId), - EgtSV( nGuideId))
EgtTransform( nSectionId, frOrig)
EgtTransform( nSectionId, frDest)
-- creo estrusione
local nMainStripExtrusionId = EgtSurfTmSwept( nSolidLayerId, nSectionId, 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, vPrevOutlineId[1], 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( vPrevOutlineId[1], 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)
EgtMove( nStartStripGuideId, Z_AX())
-- estrudo Strip start
local b3RefStartProfile = GetProfileLocalBox( nStartProfileId)
local nStartStripExtrusionId = EgtSurfTmByExtrusion( nSolidLayerId, nStartStripGuideId, - Z_AX() * ( b3RefStartProfile:getDimY() + 2), WIN_SURF_APPROX)
EgtInvertSurf( nStartStripExtrusionId)
-- intersezione con main
EgtSurfTmIntersect( nMainStripExtrusionId, nStartStripExtrusionId)
-- c) taglio con end
-- recupero strip piu' vicino ad outline
local nEndStripId = GetStripNearestToOutline( nEndProfileId, vNextOutlineId[1], nOutlineId)
-- disegno guida end per lo strip trovando le intersezioni degli outline minimi e massimi tra MainStrip ed EndStrip
local nEndStripMinOffsetId, nEndStripMaxOffsetId = CreateStripGuideLines( vNextOutlineId[1], 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)
EgtMove( nEndStripGuideId, Z_AX())
-- estrudo Strip end
local b3RefEndProfile = GetProfileLocalBox( nEndProfileId)
local nEndStripExtrusionId = EgtSurfTmByExtrusion( nSolidLayerId, nEndStripGuideId, - Z_AX() * ( b3RefEndProfile:getDimY() + 2), WIN_SURF_APPROX)
-- intersezione con main
EgtSurfTmIntersect( nMainStripExtrusionId, nEndStripExtrusionId)
-- cancello curve e superfici di costruzione
EgtErase( nSectionId)
EgtErase( { nMainStripMinOffsetId, nMainStripMaxOffsetId})
EgtErase( { nStartStripMinOffsetId, nStartStripMaxOffsetId, nStartStripGuideId, nStartStripExtrusionId})
EgtErase( { nEndStripMinOffsetId, nEndStripMaxOffsetId, nEndStripGuideId, nEndStripExtrusionId})
end
----------------------------------------------------------------------------------
----------------------------- CALCOLO PEZZI ------------------------------------
----------------------------------------------------------------------------------
-- funzione che stabilisce il nome del pezzo
local function CalcPartName( nAreaId, nAreaType)
local sName = ''
if nAreaType == WIN_AREATYPES.FRAME then
sName = WIN_FRAME
EgtSetInfo( nAreaId, WIN_AREA_NAME, sName)
elseif nAreaType == WIN_AREATYPES.SASH then
s_nSashNbr = s_nSashNbr + 1
sName = WIN_SASH .. '_'.. tostring( s_nSashNbr)
EgtSetInfo( nAreaId, WIN_AREA_NAME, sName)
else
-- per split o riempimento devo ricavare il nome del parent che lo contiene
local nParentId = EgtGetParent( nAreaId)
local nParentType = EgtGetInfo( nParentId, WIN_AREATYPE, 'i')
while nParentType ~= WIN_AREATYPES.FRAME and nParentType ~= WIN_AREATYPES.SASH do
nParentId = EgtGetParent( nParentId)
nParentType = EgtGetInfo( nParentId, WIN_AREATYPE, 'i')
end
sName = EgtGetInfo( nParentId, WIN_AREA_NAME, sName)
end
return sName
end
---------------------------------------------------------------------
-- funzione che disegna l'apertura dell'anta
local function DrawOpening( nAreaId)
local nOpeningType = EgtGetInfo( nAreaId, WIN_OPENING_TYPE, 'i')
if nOpeningType == WIN_OPENING_TYPES.NULL then
return
end
-- creo gruppo per aperture
local nOpeningLayId = EgtGroup( nAreaId)
EgtSetName( nOpeningLayId, WIN_SASH_OPENING)
-- verifico se anta ricevente per impostare tratteggio
local nFactor = 7
local nPattern = 0xAAAA
local nType = EgtGetInfo( nAreaId, WIN_SASHTYPE, 'i')
local bStippled = ( nType == WIN_SASHTYPES.INACTIVE)
-- calcolo la curva di riferimento per il disegno dell'apertura
local nOutlineLayId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE)
local vOutlines = EgtGetAllInGroup( nOutlineLayId)
-- TODO gestire caso di triangolo
if #vOutlines == 3 then
return
end
local vCrvs = {}
for i = 1, #vOutlines do
local nCrv = EgtCopyGlob( vOutlines[i], nOpeningLayId)
table.insert( vCrvs, nCrv)
local nProfileId = GetOutlineProfileId( vCrvs[i], false)
local b3FrameProfile = GetProfileLocalBox( nProfileId)
local dOffs = b3FrameProfile:getMin():getX()
EgtOffsetCurve( nCrv, dOffs)
end
TrimAndOrientOrderedCurves( vCrvs, false)
local nGuideId = EgtCurveCompo( nOpeningLayId, vCrvs)
local _, dParE = EgtCurveDomain( nGuideId)
-- ribalta
if nOpeningType == WIN_OPENING_TYPES.TILTONLY_TOP or nOpeningType == WIN_OPENING_TYPES.TILTTURN_LEFT or nOpeningType == WIN_OPENING_TYPES.TILTTURN_RIGHT then
-- ricavo il punto sul top
local ptMid = EgtUP( nGuideId, 2.5)
if not EgtCurveIsARectangle( nGuideId) then
-- per maggiore simmetria ricavo il punto sul top in corrispondenza del punto medio del bottom
local ptTest = EgtUP( nGuideId, 0.5)
local nLineTest = EgtLinePVL( nOpeningLayId, ptTest + Y_AX(), Y_AX(), 10000)
ptMid = EgtIP( nGuideId, nLineTest, ORIG())
EgtErase( nLineTest)
end
EgtCurveCompoFromPoints( nOpeningLayId, { EgtSP( nGuideId), ptMid, EgtUP( nGuideId, 1)})
elseif nOpeningType == WIN_OPENING_TYPES.TILTONLY_BOTTOM then
-- ricavo il punto sul bottom
local ptMid = EgtUP( nGuideId, 0.5)
EgtCurveCompoFromPoints( nOpeningLayId, { EgtUP( nGuideId, 2), ptMid, EgtUP( nGuideId, dParE - 1)})
end
-- altre tipologie
if nOpeningType == WIN_OPENING_TYPES.TILTTURN_LEFT or nOpeningType == WIN_OPENING_TYPES.TURNONLY_LEFT then
-- battente sx
local dLenRight = EgtCurveCompoLength( nGuideId, 1)
local dLenLeft = EgtCurveCompoLength( nGuideId, dParE - 1)
local dParMid = 1.5
-- se lato sinistro è il più corto, prendo sul destro il corrispondente del suo punto medio
if dLenLeft < dLenRight - GEO.EPS_SMALL then
dParMid = EgtCurveParamAtLength( nGuideId, EgtCurveCompoLength( nGuideId, 0) + dLenLeft * 0.5)
end
local nCrv = EgtCurveCompoFromPoints( nOpeningLayId, { EgtSP( nGuideId), EgtUP( nGuideId, dParMid), EgtUP( nGuideId, dParE - 1)})
-- tratteggio
if bStippled then
EgtSetStipple( nCrv, nFactor, nPattern)
end
elseif nOpeningType == WIN_OPENING_TYPES.TILTTURN_RIGHT or nOpeningType == WIN_OPENING_TYPES.TURNONLY_RIGHT then
-- battente dx
local dLenRight = EgtCurveCompoLength( nGuideId, 1)
local dLenLeft = EgtCurveCompoLength( nGuideId, dParE - 1)
local dParMid = dParE - 0.5
-- se lato destro è il più corto, prendo sul sinistro il corrispondente del suo punto medio
if dLenRight < dLenLeft - GEO.EPS_SMALL then
dParMid = EgtCurveParamAtLength( nGuideId, EgtCurveLength( nGuideId) - dLenRight * 0.5)
end
local nCrv = EgtCurveCompoFromPoints( nOpeningLayId, { EgtUP( nGuideId, 1), EgtUP( nGuideId, dParMid), EgtUP( nGuideId, 2)})
-- tratteggio
if bStippled then
EgtSetStipple( nCrv, nFactor, nPattern)
end
elseif nOpeningType == WIN_OPENING_TYPES.COPLANARSLIDE_LEFT or nOpeningType == WIN_OPENING_TYPES.COPLANARSLIDE_RIGHT or
nOpeningType == WIN_OPENING_TYPES.LIFTSLIDE_LEFT or nOpeningType == WIN_OPENING_TYPES.LIFTSLIDE_RIGHT then
-- scorrevole e alzante scorrevole ( solo forma rettangolare)
local bRight = ( nOpeningType == WIN_OPENING_TYPES.COPLANARSLIDE_RIGHT or nOpeningType == WIN_OPENING_TYPES.LIFTSLIDE_RIGHT)
local dLen0 = EgtCurveCompoLength( nGuideId, 0)
local dLen1 = EgtCurveCompoLength( nGuideId, 1)
local dCoeff = 0.15
local ptS = EgtUP( nGuideId, 1.5) - dCoeff * dLen0 * X_AX()
local ptE = EgtUP( nGuideId, dParE - 0.5) + dCoeff * dLen0 * X_AX()
if bRight then
ptS, ptE = ptE, ptS
end
local nCompo = EgtCurveCompoFromPoints( nOpeningLayId, { ptS, ptE})
if nOpeningType == WIN_OPENING_TYPES.LIFTSLIDE_LEFT or nOpeningType == WIN_OPENING_TYPES.LIFTSLIDE_RIGHT then
EgtAddCurveCompoLine( nCompo, ptS - dCoeff * dLen1 * Y_AX(), false)
end
local dAng = EgtIf( bRight, 135, 45)
EgtLinePDL( nOpeningLayId, ptE, dAng, dCoeff * dLen0)
EgtLinePDL( nOpeningLayId, ptE, - dAng, dCoeff * dLen0)
elseif nOpeningType == WIN_OPENING_TYPES.FIXED then
-- fisso ( solo forma rettangolare)
EgtLine( nOpeningLayId, EgtSP( nGuideId), EgtUP( nGuideId, 2))
EgtLine( nOpeningLayId, EgtUP( nGuideId, 1), EgtUP( nGuideId, 3))
elseif nOpeningType == WIN_OPENING_TYPES.PIVOT then
-- bilico rettangolare
local nCompo = EgtCurveCompoFromPoints( nOpeningLayId, { EgtUP( nGuideId, 0.5), EgtUP( nGuideId, 1.5), EgtUP( nGuideId, 2.5), EgtUP( nGuideId, 3.5)})
EgtCloseCurveCompo( nCompo)
-- TODO oblò
end
EgtErase( nGuideId)
end
---------------------------------------------------------------------
-- funzione che calcola l'ingombro dei pezzi del telaio e i loro solidi
local function CreatePartFromOutline( nAreaLayerId, sName, nOutlineId, nOutlineCrvNbr, 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 sOutlineName = EgtIf( bBottomRail, WIN_BOTTOMRAIL, EgtGetName( nOutlineId))
local sPartName = sName .. '_' .. sOutlineName
EgtSetName( nPartId, sPartName)
-- imposto il colore
if sOutlineName == WIN_BOTTOM or sOutlineName == WIN_TOP or bBottomRail then
EgtSetColor( nPartId, Color3d( 204, 102, 0))
elseif sOutlineName == WIN_RIGHT or sOutlineName == WIN_LEFT then
EgtSetColor( nPartId, Color3d( 251, 128, 4))
else
EgtSetColor( nPartId, Color3d( 255, 159, 57))
end
-- ricavo il tipo di profilo
local nProfileType = GetOutlineProfileType( nOutlineId, bBottomRail)
-- disegno ingombro
CalcFrameGeo( nPartId, nOutlineId, nOutlineCrvNbr, nOutlineLayerId, nProfileType)
-- calcolo eventuali curve ausiliarie per cambio profilo
local bChangeProfile = EgtGetInfo( nOutlineId, WIN_PRF_CHANGE, 'b') or false
if bChangeProfile and nProfileType ~= WIN_PRF.SPLIT then
CalcMixedFrameCurves( nPartId, nOutlineId)
end
-- calcolo le lavorazioni associate ai profili
CalcProfilingProcessings( nPartId, nOutlineId)
-- calcolo il georaw per automatismo lavorazioni
CalcGeoRaw( nPartId)
-- disegno solido
if s_bCalcSolid then
CalcSolid( nPartId, nOutlineId)
end
-- b) Fill
elseif nAreaType == WIN_AREATYPES.FILL then
-- imposto nome del pezzo
EgtSetName( nPartId, sName .. '_' .. WIN_FILL)
-- ricavo tipo
local nFillType = EgtGetInfo( nAreaLayerId, WIN_FILLTYPE, 'i')
-- imposto colore e tipologia di riempimento
if nFillType == WIN_FILLTYPES.GLASS then
EgtSetColor( nPartId, Color3d( 71, 161, 255))
EgtSetAlpha( nPartId, 30)
EgtSetInfo( nPartId, WIN_FILLTYPE, WIN_GLASS)
elseif nFillType == WIN_FILLTYPES.WOOD then
EgtSetColor( nPartId, Color3d( 194, 148, 103))
EgtSetInfo( nPartId, WIN_FILLTYPE, WIN_WOOD)
end
-- disegno ingombro
local nGeoLayerId = CalcFillGeo( nPartId, nOutlineLayerId)
-- disegno solido
if s_bCalcSolid then
CalcFillSolid( nPartId, nOutlineLayerId, nGeoLayerId)
end
end
return nPartId
end
---------------------------------------------------------------------
-- funzione che cicla ricorsivamente su aree e sottoaree per calcolare i pezzi
local function CalculateAreaParts( nAreaId)
local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i')
-- recupero nome dei pezzi in quest'area
local sName = CalcPartName( nAreaId, nAreaType)
if nAreaType == WIN_AREATYPES.FRAME or nAreaType == WIN_AREATYPES.SASH then
-- creo pezzi per ogni outline
local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE)
local vOutlines = EgtGetAllInGroup( nOutlineLayerId)
for i = 1, #vOutlines do
-- creo pezzo
CreatePartFromOutline( nAreaId, sName, vOutlines[i], i)
-- se di tipo bottom verifico se ha bottomrail
local sName = EgtGetName( vOutlines[i])
if sName == WIN_BOTTOM then
local bBottomRail = EgtGetInfo( nOutlineLayerId, WIN_BOTTOMRAIL, 'b') or false
if bBottomRail then
CreatePartFromOutline( nAreaId, sName, vOutlines[i], i, true)
end
end
end
elseif nAreaType == WIN_AREATYPES.FILL then
-- creo riempimento
CreatePartFromOutline( nAreaId, sName)
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, sName, 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)
local nSelectionArea = CreateGeoArea( nSplitPartGeoId, nSelectionLayerId)
EgtSetColor( nSelectionArea, 'YELLOW')
EgtSetAlpha( nSelectionArea, 10)
EgtMove( nSelectionArea, 10 * Z_AX())
end
end
elseif nAreaType ~= WIN_AREATYPES.FILL then
if s_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
-- se anta disegno apertura
if nAreaType == WIN_AREATYPES.SASH then
DrawOpening( nAreaId)
end
-- disegno area di selezione per programma
local nSelectionLayerId = EgtGroup( nAreaId)
EgtSetName( nSelectionLayerId, WIN_SELECTION)
EgtSetStatus( nSelectionLayerId, GDB_ST.OFF)
local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE)
local vOutlineList = EgtGetAllInGroup( nOutlineLayerId)
local nCompoId = EgtCurveCompo( nSelectionLayerId, vOutlineList, false)
local nSelectionArea = EgtSurfFlatRegion( nSelectionLayerId, nCompoId)
EgtSetColor( nSelectionArea, 'YELLOW')
EgtSetAlpha( nSelectionArea, 10)
EgtMove( nSelectionArea, 10 * Z_AX())
EgtErase( nCompoId)
-- calcolo i pezzi delle sottoaree
local nChildAreaId = EgtGetFirstNameInGroup( nAreaId, WIN_AREA .. '*')
while nChildAreaId do
CalculateAreaParts( nChildAreaId)
nChildAreaId = EgtGetNextName( nChildAreaId, WIN_AREA .. '*')
end
end
----------------------------------------------------------------------------------
---------------------------------- TRONCHETTI ----------------------------------
----------------------------------------------------------------------------------
-- funzione che spezza l'anta in corrispondenza dei tronchetti del telaio
local function SplitArcByAlignment( nGeoIn, nGrp)
-- recupero il pezzo del telaio corrispondente
local nPartId = EgtGetParent( EgtGetParent( nGeoIn))
local nOutlineId = EgtGetInfo( nPartId, WIN_REF_OUTLINE, 'i')
local nSouId = EgtGetInfo( nOutlineId, WIN_COPY, 'i')
local nAreaType = WIN_AREATYPES.NULL
while nSouId and nAreaType ~= WIN_AREATYPES.FRAME do
nSouId = EgtGetInfo( nSouId, WIN_SOU, 'i') or GDB_ID.NULL
local nParentArea = EgtGetParent( EgtGetParent( nSouId)) or GDB_ID.NULL
nAreaType = EgtGetInfo( nParentArea, WIN_AREATYPE, 'i')
end
if not nSouId then return end
local nFrameOutlineId = EgtGetInfo( nSouId, WIN_COPY, 'i')
local nFramePartId = EgtGetInfo( nFrameOutlineId, WIN_REF_PART, 'i')
-- recupero le parti in cui era stato diviso l'arco del telaio
local nFrameLogsLayer = EgtGetFirstNameInGroup( nFramePartId, WIN_LOGS)
local vFrameLogs = EgtGetNameInGroup( nFrameLogsLayer, WIN_GEO_IN)
local ptC = EgtCP( vFrameLogs[1])
local nCurrCrvId = EgtCopyGlob( nGeoIn, nGrp)
local bInters = false
for i = 1, #vFrameLogs - 1 do
-- ricavo il punto di split sull'arco dell'anta
local ptFrame = EgtEP( vFrameLogs[i])
local vtDir = ptFrame - ptC
local nLineSplit = EgtLinePVL( nGrp, ptC, vtDir, vtDir:len() + 1000)
local ptInt = EgtIP( nCurrCrvId, nLineSplit, ORIG())
EgtErase( nLineSplit)
if ptInt then
nCurrCrvId = EgtSplitCurveAtPoint( nCurrCrvId, ptInt) or GDB_ID.NULL
bInters = true
elseif bInters then
-- se non ci sono più intersezioni esco
return
end
end
end
---------------------------------------------------------------------
-- funzione che spezza l'arco in base al numero di pezzi
local function SplitArcByNumber( nLogsNbr, nGeoIn, nGrp)
local nCopy = EgtCopyGlob( nGeoIn, nGrp)
EgtSplitCurve( nCopy, nLogsNbr)
end
---------------------------------------------------------------------
-- funzione che spezza gli archi per i tronchetti
local function SplitArc( nLogsNbr, vSections, bAlign, dOverMatTot, nGeoIn, nGeoOut, nGrp)
-- per allineamento con telaio
if bAlign then
return SplitArcByAlignment( nGeoIn, nGrp)
-- per sezione
elseif #vSections == 1 and nLogsNbr == 0 then
-- dalla sezione ricavo il numero minimo di pezzi
local dSection = vSections[1] - dOverMatTot
local dROut = EgtArcRadius( nGeoOut)
local dRIn = EgtArcRadius( nGeoIn)
local dAng = abs( EgtArcAngCenter( nGeoIn))
local nParts
if dSection < dROut - dRIn + GEO.EPS_SMALL then
-- sezione troppo piccola
-- TO DO : gestione errore
EgtOutBox( 'Sezione tronchetto troppo piccola', '')
elseif dSection > dROut + dRIn - GEO.EPS_SMALL then
-- la sezione comprende già l'intero pezzo
nParts = 1
else
nParts = dAng / 2 / acos( ( dROut - dSection) / dRIn)
nParts = ceil( nParts)
end
return SplitArcByNumber( nParts, nGeoIn, nGrp)
-- per numero di pezzi
else
return SplitArcByNumber( nLogsNbr, nGeoIn, nGrp)
end
end
---------------------------------------------------------------------
-- funzione che calcola la sezione dei tronchetti
local function CalcLogsSection( nLogsNbr, vSections, bAlign, dOverMatTot, nGeoIn, nGeoOut, nGrp)
-- se richiesta una sezione specifica senza vincoli sul numero di pezzi
if not bAlign and #vSections == 1 and nLogsNbr == 0 then
return vSections[1]
end
-- calcolo la sezione necessaria per la suddivisione scelta
local dMySection = 0
local dROut = EgtArcRadius( nGeoOut)
local dRIn = EgtArcRadius( nGeoIn)
if bAlign then
-- calcolo la massima sezione dai tronchetti ottenuti
local vSplits = EgtGetAllInGroup( nGrp)
for i = 1, #vSplits do
local dAng = abs( EgtArcAngCenter( vSplits[i]))
local dCurrSection = dROut - dRIn * cos( dAng / 2)
if dCurrSection > dMySection then
dMySection = dCurrSection
end
end
dMySection = dMySection + dOverMatTot
else
-- ricavo la sezione dal numero di pezzi
local dAng = abs( EgtArcAngCenter( nGeoIn))
dMySection = dROut - dRIn * cos( dAng / nLogsNbr / 2) + dOverMatTot
end
if #vSections == 0 then
-- se no vincoli sulla sezione
return dMySection
else
-- cerco la sezione più adatta dalla lista di sezioni disponibili
table.sort( vSections)
for i = 1, #vSections do
if vSections[i] > dMySection - GEO.EPS_SMALL then
return vSections[i]
end
end
-- se non ho trovato la sezione errore
EgtOutBox( 'Sezioni tronchetti troppo piccole per suddivisione richiesta', '')
return nil
end
end
---------------------------------------------------------------------
local function CalcLogs( nGrp, nGeoOut, dOverMatIn, dOverMatOut, dOverMatExt, dOverMatInt, dRefSection, bCutExtremities)
-- recupero tutti i tratti dell'arco
local vCrvsIn = EgtGetAllInGroup( nGrp)
local ptC = EgtCP( vCrvsIn[1])
-- calcolo i tronchetti
for i = 1, #vCrvsIn do
local ptSIn = EgtSP( vCrvsIn[i])
local ptEIn = EgtEP( vCrvsIn[i])
-- recupero il tratto corrispondente sulla curva out
local ptSOut, dParSOut, ptEOut, dParEOut
if i == 1 then
-- forzo a coincidere con l'estremo della curva out
ptEOut = EgtEP( nGeoOut)
dParEOut = 1
else
_, ptEOut, dParEOut = EgtPointCurveDist( ptSIn, nGeoOut)
end
if i == #vCrvsIn then
-- forzo a coincidere con l'estremo della curva out
ptSOut = EgtSP( nGeoOut)
dParSOut = 0
else
_, ptSOut, dParSOut = EgtPointCurveDist( ptEIn, nGeoOut)
end
local nOut = EgtCopyGlob( nGeoOut, nGrp)
EgtTrimCurveStartEndAtParam( nOut, dParSOut, dParEOut)
-- creo composita corrispondente al pezzo
local nCompo = EgtCurveCompo( nGrp, {vCrvsIn[i]}, false)
EgtAddCurveCompoLine( nCompo, ptSOut)
EgtAddCurveCompoCurve( nCompo, nOut, false)
EgtCloseCurveCompo( nCompo)
-- calcolo il frame per il tronchetto
local ptM = EgtMP( vCrvsIn[i])
local vtRad = ptM - ptC
local frRef = Frame3d( ptM, vtRad ^ Z_AX(), vtRad, Z_AX())
-- calcolo il box locale al frame
local b3Ref = EgtGetBBoxRef( nCompo, GDB_BB.STANDARD, frRef)
local ptMin = b3Ref:getMin()
local ptMax = b3Ref:getMax()
-- verifico se necessario sovramateriale extra per raggiungere la sezione desiderata
local dExtraSection = max( 0, dRefSection - b3Ref:getDimY() - dOverMatIn - dOverMatOut)
-- lato bottom
local nLineBottom = EgtLinePVL( nGrp, ptMin - ( dOverMatIn + 0.5 * dExtraSection) * Y_AX(), X_AX(), 10000)
EgtExtendCurveStartByLen( nLineBottom, 10000)
EgtTransform( nLineBottom, frRef)
-- lato top
local nLineTop = EgtLinePVL( nGrp, ptMax + ( dOverMatOut + 0.5 * dExtraSection) * Y_AX(), - X_AX(), 10000)
EgtExtendCurveStartByLen( nLineTop, 10000)
EgtTransform( nLineTop, frRef)
-- lato right
local nLineRight
if i == 1 and not bCutExtremities then
nLineRight = EgtLinePVL( nGrp, ptMin, - Y_AX(), 10000)
EgtTransform( nLineRight, frRef)
else
nLineRight = EgtLine( nGrp, ptEOut, ptSIn)
EgtExtendCurveEndByLen( nLineRight, 10000)
end
EgtOffsetCurve( nLineRight, EgtIf( i == 1, dOverMatExt, dOverMatInt))
EgtExtendCurveStartByLen( nLineRight, 10000)
-- lato left
local nLineLeft
if i == #vCrvsIn and not bCutExtremities then
nLineLeft = EgtLinePVL( nGrp, ptMax, Y_AX(), 10000)
EgtTransform( nLineLeft, frRef)
else
nLineLeft = EgtLine( nGrp, ptEIn, ptSOut)
EgtExtendCurveEndByLen( nLineLeft, 10000)
end
EgtOffsetCurve( nLineLeft, EgtIf( i == #vCrvsIn, dOverMatExt, dOverMatInt))
EgtExtendCurveStartByLen( nLineLeft, 10000)
-- taglio le curve nei loro punti di intersezione
local vCrvs = { nLineTop, nLineRight, nLineBottom, nLineLeft}
TrimAndOrientOrderedCurves( vCrvs, false)
-- TO DO : controllo lunghezza minima
-- local dLenTop = EgtCurveLength( nLineTop)
-- creo il tronchetto
local nLogCrv = EgtCurveCompo( nGrp, vCrvs)
EgtSetName( nLogCrv, WIN_LOGS)
EgtSetColor( nLogCrv, EgtStdColor( 'BLUE'))
-- salvo i sovramateriali utilizzati nella curva
EgtSetInfo( nLogCrv, WIN_PRC_OVERMAT_IN, dOverMatIn)
EgtSetInfo( nLogCrv, WIN_PRC_OVERMAT_OUT, dOverMatOut)
EgtSetInfo( nLogCrv, WIN_PRC_OVERMAT_LEFT, EgtIf( i == #vCrvsIn, dOverMatExt, dOverMatInt))
EgtSetInfo( nLogCrv, WIN_PRC_OVERMAT_RIGHT, EgtIf( i == 1, dOverMatExt, dOverMatInt))
EgtSetStatus( vCrvsIn[i], GDB_ST.OFF)
EgtSetStatus( nOut, GDB_ST.OFF)
EgtErase( nCompo)
end
end
---------------------------------------------------------------------
-- funzione che crea la spina per tronchetti
local function CalcLogDowel( nOrigPartId, nCrvOut, bLeftOrRight, nProcLayerId, nProfileId, nInfoGrp, nSolidId)
-- creo il frame per il posizionamento del dowel
local nOutlineRef = EgtGetInfo( nOrigPartId, WIN_REF_OUTLINE, 'i')
local ptRef = EgtIf( bLeftOrRight, EgtSP( nCrvOut), EgtEP( nCrvOut))
local _, ptOrig, dParOrig = EgtPointCurveDist( ptRef, nOutlineRef)
local vtFrame = EgtUV( nOutlineRef, dParOrig, -1)
local frDest = Frame3d( ptOrig, - vtFrame)
-- calcolo direzione verso interno del pezzo
local vtDir = frDest:getVersZ()
if bLeftOrRight then
vtDir = - vtDir
end
-- recupero i dati del dowel
local dDowelDiam = EgtGetInfo( nInfoGrp, WIN_DWL_DIAM, 'd')
local dDowelLen = EgtGetInfo( nInfoGrp, WIN_DWL_LOG_LEN, 'd')
-- creo il dowel nel riferimento della sezione
-- TO DO : recupero della sezione corretta nel caso di cambio profilo
local nSectionId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTION) or EgtGetFirstNameInGroup( nProfileId, WIN_SASH .. WIN_SECTION)
local nDowelId = EgtCircle( nProcLayerId, EgtGP( nSectionId), 0.5 * dDowelDiam)
-- posiziono il dowel usando i riferimenti
local nFrameId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME)
local frOrig = EgtFR( nFrameId)
frOrig:invert()
EgtTransform( nDowelId, frOrig)
EgtTransform( nDowelId, frDest)
local nPartId = EgtGetParent( nProcLayerId)
local dOverMat = EgtGetInfo( nPartId, EgtIf( bLeftOrRight, WIN_PRC_OVERMAT_LEFT, WIN_PRC_OVERMAT_RIGHT))
EgtMove( nDowelId, - vtDir * ( s_dDowelTol + dOverMat))
EgtModifyCurveExtrusion( nDowelId, - vtDir)
local dLen = dDowelLen + dOverMat + s_dDowelTol
EgtModifyCurveThickness( nDowelId, - dLen)
-- setto info di lavorazione
EgtSetInfo( nDowelId, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.HOLE)
EgtSetInfo( nDowelId, WIN_PRC_SIDE, EgtIf( bLeftOrRight, WIN_PRC_SIDETYPE.LEFT, WIN_PRC_SIDETYPE.RIGHT))
-- eventuale aggiornamento del solido
if nSolidId then
UpdateSolidWithDowel( nDowelId, nSolidId, vtDir, dLen, nProcLayerId)
end
end
---------------------------------------------------------------------
-- funzione che crea i pezzi dei tronchetti
local function CalcLogParts( nOrigPartId, bFinishedLogs)
local nProfileGrp = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_PROFILE)
local nInfoGrp = EgtGetFirstNameInGroup( nProfileGrp, WIN_INFO_GRP)
-- recupero i gruppi dal pezzo ad arco
local nProfileLayerId = EgtGetFirstNameInGroup( nOrigPartId, WIN_PROFILE)
local nProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN)
local nOrigSolidLayerId = EgtGetFirstNameInGroup( nOrigPartId, WIN_SOLID)
local nOrigProcLayerId = EgtGetFirstNameInGroup( nOrigPartId, WIN_PRC)
-- recupero i tronchetti
local nLogLayerId = EgtGetFirstNameInGroup( nOrigPartId, WIN_LOGS)
local vCrvIn = EgtGetNameInGroup( nLogLayerId, WIN_GEO_IN)
local vCrvOut = EgtGetNameInGroup( nLogLayerId, WIN_GEO_OUT)
local vLogs = {}
for i = 1, #vCrvIn do
-- creo il pezzo per il trochetto
local nPartId = EgtGroup( GDB_ID.ROOT)
EgtSetName( nPartId, WIN_LOGS)
EgtSetColor( nPartId, Color3d( 204, 102, 0))
EgtSetStatus( nPartId, GDB_ST.OFF)
table.insert( vLogs, nPartId)
local nCrvIn = vCrvIn[i]
local nCrvOut = vCrvOut[i]
local nLogCrv = EgtGetNext( nCrvOut)
-- setto le info con i sovramateriali corrispondenti
CopyInfo( nPartId, nLogCrv, WIN_PRC_OVERMAT_IN, 0)
CopyInfo( nPartId, nLogCrv, WIN_PRC_OVERMAT_OUT, 0)
CopyInfo( nPartId, nLogCrv, WIN_PRC_OVERMAT_LEFT, 0)
CopyInfo( nPartId, nLogCrv, WIN_PRC_OVERMAT_RIGHT, 0)
-- a) GEORAW
local nGeoRawLayerId = EgtGroup( nPartId)
EgtSetName( nGeoRawLayerId, WIN_GEO_RAW)
EgtCopyGlob( nLogCrv, nGeoRawLayerId)
-- creo il frame ausiliario
local vtX = EgtSV( nLogCrv)
local frGeo = Frame3d( EgtSP( nLogCrv), vtX, Z_AX() ^ vtX, Z_AX())
local nFrameId = EgtFrame( nGeoRawLayerId, frGeo)
EgtSetName( nFrameId, WIN_PRC_FRAME)
-- b) SOLIDO
local nSolidId
if s_bCalcSolid then
local nSolidLayerId = EgtGroup( nPartId)
EgtSetName( nSolidLayerId, WIN_SOLID)
if #vCrvIn == 1 then
-- essendo singolo pezzo il solido è quello originale
local nOrigSolidId = EgtGetFirstNameInGroup( nOrigSolidLayerId, WIN_SRF_MAIN)
EgtRelocateGlob( nOrigSolidId, nSolidLayerId)
elseif bFinishedLogs then
-- recupero il solido originale e lo taglio opportunamente agli estremi
local nOrigSolidId = EgtGetFirstNameInGroup( nOrigSolidLayerId, WIN_SRF_MAIN)
nSolidId = EgtCopyGlob( nOrigSolidId, nSolidLayerId)
local bBox = GetProfileLocalBox( nProfileId)
local dDimY = bBox:getDimY()
if i ~= 1 then
local nTrimCrv = EgtLine( nSolidLayerId, EgtUP( nLogCrv, 2), EgtUP( nLogCrv, 1))
EgtMove( nTrimCrv, Z_AX())
local nTrimSrf = EgtSurfTmByExtrusion( nSolidLayerId, nTrimCrv, - Z_AX() * ( dDimY + 2), WIN_SURF_APPROX)
EgtSurfTmIntersect( nSolidId, nTrimSrf)
EgtErase( { nTrimCrv, nTrimSrf})
end
if i ~= #vCrvIn then
local nTrimCrv = EgtLine( nSolidLayerId, EgtSP( nLogCrv), EgtUP( nLogCrv, 3))
EgtMove( nTrimCrv, Z_AX())
local nTrimSrf = EgtSurfTmByExtrusion( nSolidLayerId, nTrimCrv, - Z_AX() * ( dDimY + 2), WIN_SURF_APPROX)
EgtSurfTmIntersect( nSolidId, nTrimSrf)
EgtErase( { nTrimCrv, nTrimSrf})
end
else
-- il solido è esattamente il tronchetto
local bBox = GetProfileLocalBox( nProfileId)
nSolidId = EgtSurfTmByRegionExtrusion( nSolidLayerId, nLogCrv, - bBox:getDimY() * Z_AX())
EgtSetName( nSolidId, WIN_SOLID)
end
end
-- c) LAVORAZIONI
-- se unico tronchetto le lavorazioni sono quelle del pezzo originale
if #vCrvIn == 1 then
EgtRelocateGlob( nOrigProcLayerId, nPartId)
EgtSetStatus( nOrigProcLayerId, GDB_ST.ON)
return
end
local nProcLayerId = EgtGroup( nPartId)
EgtSetName( nProcLayerId, WIN_PRC)
-- profili in e out
if bFinishedLogs then
EgtRelocateGlob( nCrvIn, nProcLayerId)
local nSemiProfileInId = EgtGetInfo( nCrvIn, WIN_SEMI_PROFILE, 'i')
GetProcessingInfoFromSemiProfile( nCrvIn, nSemiProfileInId)
EgtSetStatus( nCrvIn, GDB_ST.ON)
EgtRelocateGlob( nCrvOut, nProcLayerId)
local nSemiProfileOutId = EgtGetInfo( nCrvOut, WIN_SEMI_PROFILE, 'i')
GetProcessingInfoFromSemiProfile( nCrvOut, nSemiProfileOutId)
EgtSetStatus( nCrvOut, GDB_ST.ON)
end
-- profilo left
if i == #vCrvIn and bFinishedLogs then
-- recupero la curva di lavorazione dal pezzo originale
local nLeftPrc = EgtGetFirstNameInGroup( nOrigProcLayerId, WIN_GEO_LEFT)
EgtRelocateGlob( nLeftPrc, nProcLayerId)
elseif i ~= #vCrvIn then
-- minizinken
local nLeftId = EgtLine( nProcLayerId, EgtUP( nLogCrv, 3), EgtSP( nLogCrv))
EgtSetName( nLeftId, WIN_LEFT)
-- assegno le info di lavorazione
EgtSetInfo( nLeftId, WIN_PRC_NTOOLS, 1)
local sToolName = EgtGetInfo( nInfoGrp, WIN_PRC_TOOL_NAME)
EgtSetInfo( nLeftId, WIN_PRC_TOOL_NAME .. '_1', sToolName)
local dOffR = EgtGetInfo( nInfoGrp, WIN_PRC_OFFR, 'd')
-- TO DO : verificare valore OffsR
EgtSetInfo( nLeftId, WIN_PRC_OFFR .. '_1', dOffR)
local dOffL = EgtGetInfo( nInfoGrp, WIN_PRC_OFFL .. '_1', 'd')
EgtSetInfo( nLeftId, WIN_PRC_OFFL .. '_1', dOffL)
end
-- profilo right
if i == 1 and bFinishedLogs then
-- recupero la curva di lavorazione dal pezzo originale
local nRightPrc = EgtGetFirstNameInGroup( nOrigProcLayerId, WIN_GEO_RIGHT)
EgtRelocateGlob( nRightPrc, nProcLayerId)
elseif i ~= 1 then
-- minizinken
local nRightId = EgtLine( nProcLayerId, EgtUP( nLogCrv, 1), EgtUP( nLogCrv, 2))
EgtSetName( nRightId, WIN_RIGHT)
-- assegno info di lavorazione
EgtSetInfo( nRightId, WIN_PRC_NTOOLS, 1)
local sToolName = EgtGetInfo( nInfoGrp, WIN_PRC_TOOL_NAME)
EgtSetInfo( nRightId, WIN_PRC_TOOL_NAME .. '_1', sToolName)
local dOffR = EgtGetInfo( nInfoGrp, WIN_PRC_OFFR, 'd')
-- TO DO : verificare valore OffsR
EgtSetInfo( nRightId, WIN_PRC_OFFR .. '_1', dOffR)
local dOffL = EgtGetInfo( nInfoGrp, WIN_PRC_OFFL .. '_2', 'd')
EgtSetInfo( nRightId, WIN_PRC_OFFL .. '_1', dOffL)
end
-- dowels per incastro dei tronchetti
if i ~= 1 then
CalcLogDowel( nOrigPartId, nCrvOut, false, nProcLayerId, nProfileId, nInfoGrp, nSolidId)
end
if i ~= #vCrvIn then
CalcLogDowel( nOrigPartId, nCrvOut, true, nProcLayerId, nProfileId, nInfoGrp, nSolidId)
end
-- se i tronchetti sono gestiti come pezzi finiti cerco le lavorazioni del pezzo orginale che appartengono al tronchetto
if bFinishedLogs then
local vProcessings = EgtGetAllInGroup( nOrigProcLayerId)
local nSurfTest = EgtSurfFlatRegion( nProcLayerId, nLogCrv)
for i = 1, #vProcessings do
local sPrcType = EgtGetInfo( vProcessings[i], WIN_PRC_FEATURE_TYPE)
-- forature
if sPrcType == WIN_PRC_TYPE.HOLE then
local sSide = EgtGetInfo( vProcessings[i], WIN_PRC_SIDE)
-- se dowel sull'estremo lo assegno direttamente al tronchetto corrispondente
if ( sSide == WIN_PRC_SIDETYPE.LEFT and i == #vCrvIn) or ( sSide == WIN_PRC_SIDETYPE.RIGHT and i == 1) then
EgtRelocateGlob( vProcessings[i], nProcLayerId)
end
-- altrimenti verifico se interno al tronchetto corrente
if sSide == WIN_PRC_SIDETYPE.IN then
local _, _, nSide = EgtPointCurveDistSide( EgtCP( vProcessings[i]), nLogCrv, Z_AX())
if nSide == -1 then
-- copio perchè la stessa lavorazione potrebbe coinvolgere più tronchetti
EgtCopyGlob( vProcessings[i], nProcLayerId)
else
-- verifico anche la faccia di fondo
local vtExtr = EgtCurveExtrusion( vProcessings[i])
local dThickness = EgtCurveThickness( vProcessings[i])
_, _, nSide = EgtPointCurveDistSide( EgtCP( vProcessings[i]) + dThickness * vtExtr, nLogCrv, Z_AX())
if nSide == -1 then
EgtCopyGlob( vProcessings[i], nProcLayerId)
end
end
end
-- fermavetro
elseif sPrcType == WIN_PRC_TYPE.STRIP_CUT then
-- TO DO da sistemare
local nStrip = EgtCopyGlob( vProcessings[i], nProcLayerId)
EgtTrimCurveWithRegion( nStrip, nSurfTest, true, false)
else
-- TO DO lavorazioni legate alla ferramenta, cambio profilo
end
end
EgtErase( nSurfTest)
end
end
-- salvo nel pezzo ad arco i pezzi dei tronchetti associati
EgtSetInfo( nOrigPartId, WIN_LOGS, vLogs)
end
---------------------------------------------------------------------
-- funzione che crea gli elementi ausiliari per la creazione del grezzo nell'automatismo delle lavorazioni
local function CalcGeoRawFromLogs( nPartId)
-- svuoto il GeoRaw per ricalcolarlo
local nGeoRawLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO_RAW)
EgtEmptyGroup( nGeoRawLayerId)
-- recupero i vari tronchetti
local nLogGrp = EgtGetFirstNameInGroup( nPartId, WIN_LOGS)
local vLogCrvs = EgtGetNameInGroup( nLogGrp, WIN_LOGS)
-- salvo le info di sovramateriale nel pezzo
CopyInfo( nPartId, vLogCrvs[1], WIN_PRC_OVERMAT_IN, 0)
CopyInfo( nPartId, vLogCrvs[1], WIN_PRC_OVERMAT_OUT, 0)
local nOvermatLateral = EgtGetInfo( vLogCrvs[1], WIN_PRC_OVERMAT_RIGHT, 'd')
EgtSetInfo( nPartId, WIN_PRC_OVERMAT_RIGHT, nOvermatLateral)
EgtSetInfo( nPartId, WIN_PRC_OVERMAT_LEFT, nOvermatLateral)
-- costruisco il grezzo a partire dai tronchetti
local vCrvs = {}
local vIdIn = {}
-- recupero le curve in e out dei tronchetti
for i = #vLogCrvs, 1, -1 do
local nLineOut = EgtLine( nGeoRawLayerId, EgtUP( vLogCrvs[i], 0), EgtUP( vLogCrvs[i], 1))
local nLineIn = EgtLine( nGeoRawLayerId, EgtUP( vLogCrvs[i], 2), EgtUP( vLogCrvs[i], 3))
table.insert( vCrvs, nLineOut)
table.insert( vIdIn, nLineIn)
end
local nLineR = EgtLine( nGeoRawLayerId, EgtEP( vCrvs[#vCrvs]), EgtSP( vIdIn[#vIdIn]))
table.insert( vCrvs, nLineR)
for i = #vIdIn, 1, -1 do
table.insert( vCrvs, vIdIn[i])
end
local nLineL = EgtLine( nGeoRawLayerId, EgtEP( vIdIn[1]), EgtSP( vCrvs[1]))
table.insert( vCrvs, nLineL)
-- taglio le curve nelle intersezioni ( va eliminato il sovramateriale per minizinken)
TrimAndOrientOrderedCurves( vCrvs, false)
-- costruisco la compo del grezzo
local nCompo = EgtCurveCompo( nGeoRawLayerId, vCrvs)
-- creo il frame ausiliario
local vtX = EgtSV( nCompo)
local frGeo = Frame3d( EgtSP( nCompo), vtX, Z_AX() ^ vtX, Z_AX())
local nFrameId = EgtFrame( nGeoRawLayerId, frGeo)
EgtSetName( nFrameId, WIN_PRC_FRAME)
end
---------------------------------------------------------------------
-- funzione che calcola i tronchetti di un pezzo ad arco
function WinCalculate.CreateArcLogs( nPartId, nLogsNbr, vSections, bAlign, dOverMatOut, dOverMatIn, dOverMatExt, dOverMatInt, bCutExtremities)
-- verifico dati in ingresso
if bAlign then nLogsNbr = 0 end
if not bAlign and nLogsNbr == 0 and ( #vSections == 0 or #vSections > 1) then
return
end
-- recupero o creo il gruppo per i tronchetti
local nGrp = EgtGetFirstNameInGroup( nPartId, WIN_LOGS)
if not nGrp then
nGrp = EgtGroup( nPartId)
EgtSetName( nGrp, WIN_LOGS)
else
EgtEmptyGroup( nGrp)
end
-- recupero il geo del pezzo
local nGeoLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO)
local nGeoIn = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_IN)
local nGeoOut = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_OUT)
-- spezzo l'arco interno
SplitArc( nLogsNbr, vSections, bAlign, dOverMatOut + dOverMatIn, nGeoIn, nGeoOut, nGrp)
-- calcolo la sezione di riferimento per i tronchetti
local dSection = CalcLogsSection( nLogsNbr, vSections, bAlign, dOverMatOut + dOverMatIn, nGeoIn, nGeoOut, nGrp)
if not dSection then
return
end
-- creo i tronchetti
CalcLogs( nGrp, nGeoOut, dOverMatIn, dOverMatOut, dOverMatExt, dOverMatInt, dSection, bCutExtremities)
-- TODO : recupero modalità di lavorazione dei tronchetti
local bFinishedLogs = false
-- creo i pezzi associati ai tronchetti
local vLogs = EgtGetInfo( nPartId, WIN_LOGS, 'vi') or {}
EgtErase( vLogs)
CalcLogParts( nPartId, bFinishedLogs)
if not bFinishedLogs then
-- sistemo il Georaw per il pezzo ad arco
CalcGeoRawFromLogs( nPartId)
else
-- TODO segnalare che il pezzo non va lavorato
end
end
----------------------------------------------------------------------------------
------------------------------ FUNZIONI ----------------------------------------
----------------------------------------------------------------------------------
-- funzione che crea tutti i pezzi della finestra partendo dal telaio
function WinCalculate.CreatePartFromArea( nFrameId)
-- assegno il tipo di profilo alle curve del base outline
CalculateAreaProfileType( nFrameId)
-- calcolo outline a partire dal base outline
CalculateAreaOutline( nFrameId)
-- creo pezzi
s_nSashNbr = 0 -- resetto il numero di ante del progetto
CalculateAreaParts( nFrameId)
-- calcolo le spine
CalculateAreaDowels( nFrameId)
end
----------------------------------------------------------------------------------
---------------------------------- FERRAMENTA ----------------------------------
----------------------------------------------------------------------------------
-- funzione che disegna le cerniere
local function DrawHinges( nOutlineId)
-- dimensioni cerniere
local dDimH = 16
local dDimV = 70
local dFilletRad = 5
-- recupero il pezzo del telaio su cui poggia
local nSouId = EgtGetInfo( nOutlineId, WIN_COPY, 'i')
local nParentAreaType = WIN_AREATYPES.SASH
while nParentAreaType ~= WIN_AREATYPES.FRAME do
nSouId = EgtGetInfo( nSouId, WIN_SOU, 'i')
local nParentArea = EgtGetParent( EgtGetParent( nSouId))
nParentAreaType = EgtGetInfo( nParentArea, WIN_AREATYPE, 'i')
end
local nSouOutlineId = EgtGetInfo( nSouId, WIN_COPY, 'i')
local nPartId = EgtGetInfo( nSouOutlineId, WIN_REF_PART, 'i')
local nSolidLayerId = EgtGetFirstNameInGroup( nPartId, WIN_SOLID)
local nBaseOutlineId = EgtGetInfo( nOutlineId, WIN_COPY, 'i')
local dDelta = ( EgtSP( nOutlineId) - EgtSP( nBaseOutlineId)) * Z_AX()
local vtDir = EgtSV( nOutlineId)
local vtDirIn = Vector3d( vtDir)
vtDirIn:rotate( Z_AX(), -90)
-- prima cerniera
local pt1 = EgtSP( nOutlineId) - dDelta * Z_AX()
local nCompo = EgtCurveCompoFromPoints( nSolidLayerId, { pt1 + dFilletRad * vtDir, pt1 + ( dDimV - dFilletRad) * vtDir})
EgtAddCurveCompoArcTg( nCompo, pt1 + dDimV * vtDir + dFilletRad * vtDirIn)
EgtAddCurveCompoLine( nCompo, pt1 + dDimV * vtDir + ( dDimH - dFilletRad) * vtDirIn)
EgtAddCurveCompoArcTg( nCompo, pt1 + ( dDimV - dFilletRad) * vtDir + dDimH * vtDirIn)
EgtAddCurveCompoLine( nCompo, pt1 + dFilletRad * vtDir + dDimH * vtDirIn)
EgtAddCurveCompoArcTg( nCompo, pt1 + ( dDimH - dFilletRad) * vtDirIn)
EgtAddCurveCompoLine( nCompo, pt1 + dFilletRad * vtDirIn)
EgtAddCurveCompoArcTg( nCompo, EgtSP( nCompo))
local nStm1 = EgtSurfTmByRegionExtrusion( nSolidLayerId, nCompo, dDelta * Z_AX())
EgtSetColor( nStm1, Color3d( 128, 128, 128))
EgtSetName( nStm1, WIN_HDW_HINGES)
EgtErase( nCompo)
-- seconda cerniera
local pt2 = EgtEP( nOutlineId) - dDelta * Z_AX() - dDimV * vtDir
local nStm2 = EgtCopyGlob( nStm1, nSolidLayerId)
EgtMove( nStm2, pt2 - pt1)
end
---------------------------------------------------------------------
-- funzione che disegna la maniglia
local function DrawHandle( nPartId, nOutlineId, sHandleSide, dHandleH)
-- dati della maniglia
local dRad1 = 40
local dRad2 = 19
local dH = 9
local dLen1 = 53
local dLen2 = 115
local dRadH = 12
local dFillet = 10
local dOffset = 27
local ptRef = EgtIf( sHandleSide == 'Sx', EgtSP( nOutlineId), EgtEP( nOutlineId))
local vtRef = EgtIf( sHandleSide == 'Sx', EgtSV( nOutlineId), - EgtEV( nOutlineId))
local vtDirIn = Vector3d( vtRef)
vtDirIn:rotate( Z_AX(), EgtIf( sHandleSide == 'Sx', 90, -90))
-- recupero il riferimento rispetto a cui leggere l'altezza maniglia
local nProfileLayId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE)
local nProfileId = EgtGetFirstNameInGroup( nProfileLayId, EgtIf( sHandleSide == 'Sx', WIN_PRF_START, WIN_PRF_END))
local dGapHardware = EgtGetInfo( nProfileId, WIN_GAPDELTA, 'd')
-- recupero di quanto spostare la maniglia rispetto all'outline
local nGeoLayId = EgtGetFirstNameInGroup( nPartId, WIN_GEO)
local nGeoOut = EgtGetFirstNameInGroup( nGeoLayId, WIN_OUT)
local dDeltaIn = dOffset - ( EgtSP( nOutlineId) - EgtSP( nGeoOut)) * vtDirIn
-- punto su cui centrare la maniglia
local ptC = ptRef + ( dHandleH + dGapHardware) * vtRef + dDeltaIn * vtDirIn
local nSolidLayerId = EgtGetFirstNameInGroup( nPartId, WIN_SOLID)
local nCrv1 = EgtRectangle2P( nSolidLayerId, ptC - dRad1 * Y_AX() - dRad2 * X_AX(), ptC + dRad1 * Y_AX() + dRad2 * X_AX())
local nStm1 = EgtSurfTmByRegionExtrusion( nSolidLayerId, {nCrv1}, dH * Z_AX())
local nCrv2 = EgtLinePVL( nSolidLayerId, ORIG(), X_AX(), dLen1 - dFillet)
local nCrv4 = EgtLinePVL( nSolidLayerId, Point3d( dLen1, -dFillet, 0), - Y_AX(), dLen2)
local nCrv3 = EgtArc2PR( nSolidLayerId, EgtEP( nCrv2), EgtSP( nCrv4), dFillet, false)
local nGuide = EgtCurveCompo( nSolidLayerId, { nCrv2, nCrv3, nCrv4})
local frTransf = Frame3d( ptC, Z_AX(), Y_AX(), - X_AX())
EgtTransform( nGuide, frTransf)
local nSection = EgtCircle( nSolidLayerId, EgtSP( nGuide), dRadH)
local nStm2 = EgtSurfTmSwept( nSolidLayerId, nSection, nGuide, true)
EgtSurfTmAdd( nStm1, nStm2)
EgtSetName( nStm1, WIN_HDW_HANDLE)
EgtSetColor( nStm1, Color3d( 128, 128, 128))
EgtErase( { nCrv1, nGuide, nSection, nStm2})
end
---------------------------------------------------------------------
-- funzione che disegna la ferramenta
local function DrawSashHardware( nAreaId, nRefAreaId)
-- recupero pezzi interessati dalla ferramenta
local nOutlineLayId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE)
local nLeftId = EgtGetFirstNameInGroup( nOutlineLayId, WIN_LEFT)
local nLeftPartId = EgtGetInfo( nLeftId, WIN_REF_PART, 'i')
local nRightId = EgtGetFirstNameInGroup( nOutlineLayId, WIN_RIGHT)
local nRightPartId = EgtGetInfo( nRightId, WIN_REF_PART, 'i')
local nSashType = EgtGetInfo( nAreaId, WIN_SASHTYPE, 'i')
-- se anta ricevente solo cerniere
if nSashType == WIN_SASHTYPES.INACTIVE or nSashType == WIN_SASHTYPES.INACTIVE_IN or nSashType == WIN_SASHTYPES.INACTIVE_OUT or nSashType == WIN_SASHTYPES.SLIDE_FIXED then
-- individuo il lato che poggia sul telaio
local nBaseOutlineId = EgtGetInfo( nLeftId, WIN_COPY, 'i')
local bLeftInactive = EgtGetInfo( nBaseOutlineId, WIN_CRV_ON_FRENCH_SPLIT, 'b') or false
if bLeftInactive then
DrawHinges( nRightId)
else
DrawHinges( nLeftId)
end
-- se anta battente o singola ha maniglia e cerniere
else
-- recupero i dati della maniglia
local sHandleSide = EgtGetInfo( nRefAreaId, WIN_HDW_HANDLE) or 'Sx'
local dHandleH = EgtGetInfo( nRefAreaId, WIN_HDW_HANDLE_HEIGHT, 'd') or 500
if sHandleSide == 'Sx' then
-- maniglia su right e cerniere su left
DrawHandle( nRightPartId, nRightId, sHandleSide, dHandleH)
DrawHinges( nLeftId)
else
-- maniglia su left e cerniere su right
DrawHandle( nLeftPartId, nLeftId, sHandleSide, dHandleH)
DrawHinges( nRightId)
end
end
end
---------------------------------------------------------------------
-- funzione che calcola i dati necessari per la ferramenta
local function SearchSash( nAreaId, SashList)
-- verifico il tipo
local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i')
if nAreaType == WIN_AREATYPES.SASH then
-- 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)
EgtSetStatus( nSashFrameLayerId, GDB_ST.OFF)
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 then
local nFrameFrameLayerId = EgtGetFirstNameInGroup( nSouAreaId, WIN_HDW_FRAME)
if not nFrameFrameLayerId then
nFrameFrameLayerId = EgtGroup( nSouAreaId)
EgtSetName( nFrameFrameLayerId, WIN_HDW_FRAME)
EgtSetStatus( nFrameFrameLayerId, GDB_ST.OFF)
end
-- ricavo aria lato telaio
local sProfileType = EgtGetInfo( nSouId, WIN_PROFILETYPE)
if sProfileType then -- controllo non sia french split
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')
if EgtGetName( nSouId) == WIN_SPLIT then
-- se dervia da split verifico il lato
if not AreSameVectorApprox( EgtSV( nSouId), EgtSV( nBaseOutlineId)) then
dGapDeltaOut = - dGapDeltaOut
end
end
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
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, bOnlyRequest)
-- 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 bOnlyRequest then
nFavourite = WDG.HDWFAVOURITE
end
if not nFavourite or nFavourite == '000000' then
EgtOutLog('Warning! No hardware favourite set!')
return
end
local sHandle = EgtGetInfo( nFrameId, WIN_HDW_HANDLE)
if bOnlyRequest then
sHandle = WDG.HDWHANDLE
end
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 abs( SashList[1].LHeight - SashList[1].RHeight) < GEO.EPS_SMALL then
sText = sText .. 'HBB=' .. tostring( SashList[1].LHeight) .. '\n'
else
for nSashIndex = 1, #SashList do
if nSashIndex == 1 then
sText = sText .. 'HBB_sx=' .. tostring( SashList[nSashIndex].LHeight) .. '\n'
else
sText = sText .. 'HBB_' .. tostring(nSashIndex - 1) .. 'B=' .. tostring( SashList[nSashIndex].LHeight) .. '\n'
end
if nSashIndex == #SashList then
sText = sText .. 'HBB_dx=' .. tostring( SashList[nSashIndex].RHeight) .. '\n'
else
sText = sText .. 'HBB_' .. tostring(nSashIndex) .. '=' .. tostring( SashList[nSashIndex].RHeight) .. '\n'
end
end
end
if #SashList == 1 then
sText = sText .. 'LBB=' .. tostring( SashList[1].BWidth) .. '\n'
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'
local vOptions = EgtGetInfo( nFrameId, WIN_HDW_OPTIONS, 'vs') or {}
for i = 1, #vOptions do
sText = sText .. vOptions[i] .. '\n'
end
sText = sText .. 'CNCOUTPUT=' .. sAGBOutputLavFile .. '\n' ..
'RUN'
-- Scrittura nuova linea
fhInput:write( sText .. '\n')
-- Chiudo file
fhInput:close()
if bOnlyRequest then
return sInputFile
end
-- 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 = EgtGetLastNameInGroup( 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 = EgtGetLastNameInGroup( 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 nPocketOutlineId = EgtCurveCompoFromPoints( nProcLayerId, { ptP1, ptP2})
EgtAddCurveCompoArcTg( nPocketOutlineId, ptCenter - dLength / 2 * X_AX())
EgtAddCurveCompoArcTg( nPocketOutlineId, ptCenter + dLength / 2 * X_AX(), false)
EgtSetColor( nPocketOutlineId, EgtStdColor( 'GRAY'))
-- setto info di lavorazione
EgtSetInfo( nPocketOutlineId, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.PROFILING)
EgtSetInfo( nPocketOutlineId, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.GENERIC)
EgtSetInfo( nPocketOutlineId, WIN_PRC_SIDE, WIN_PRC_SIDETYPE.IN)
EgtModifyCurveExtrusion( nPocketOutlineId, Z_AX())
EgtModifyCurveThickness( nPocketOutlineId, - dHeight)
-- aggiornamento del solido
if s_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
local nOutlineId = EgtCopyGlob( nPocketOutlineId, nSolidLayerId)
EgtAddCurveCompoLineTg( nOutlineId, dExtra)
EgtAddCurveCompoLineTg( nOutlineId, dExtra, false)
EgtCloseCurveCompo( nOutlineId)
EgtMove( nOutlineId, dExtra * Z_AX())
local nSolidId = EgtSurfTmByRegionExtrusion( nProcLayerId, nOutlineId, - ( dHeight + dExtra) * Z_AX())
EgtTransform( nSolidId, frHdwFrame)
EgtSurfTmSubtract( nMainExtrusionId, nSolidId)
EgtErase( {nSolidId, nOutlineId})
end
-- porto la lavorazione in globale
EgtTransform( nPocketOutlineId, frHdwFrame)
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)
-- setto info di 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)
-- aggiornamento del solido
if s_bCalcSolid then
local nSolidHoleId = EgtSurfTmByRegionExtrusion( nProcLayerId, nHoleId, - ( dDepth + 1) * Z_AX())
EgtMove( nSolidHoleId, Z_AX())
EgtTransform( nSolidHoleId, frHdwFrame)
EgtSurfTmSubtract( nMainExtrusionId, nSolidHoleId)
EgtErase( nSolidHoleId)
end
-- porto la lavorazione in globale
EgtTransform( nHoleId, frHdwFrame)
end
end
-- Chiudo file Output in lettura
fhOutput:close()
-- disegno la ferramenta
for i = 1, #SashList do
DrawSashHardware( SashList[i].nAreaId, nFrameId)
end
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
return WinCalculate.AddHardwareForSash( nAreaId)
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