Files
egwwindowlua/Profiles/WinLib/WinCalculate.lua
T
2024-12-11 09:55:38 +01:00

4344 lines
193 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_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)
-- 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)
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 not vDowels 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 not vDowels 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 calcola l'ingombro dei pezzi del telaio e i loro solidi
local function CreatePartFromOutline( nAreaLayerId, nOutlineId, nOutlineCrvNbr, bBottomRail)
-- creo pezzo
local nPartId = EgtGroup( GDB_ID.ROOT)
-- inserisco riferimento alla sua area
EgtSetInfo( nPartId, WIN_AREA, nAreaLayerId)
local nAreaType = EgtGetInfo( nAreaLayerId, WIN_AREATYPE, 'i')
local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaLayerId, WIN_OUTLINE)
-- a) Telaio, anta o split
if nAreaType == WIN_AREATYPES.FRAME or nAreaType == WIN_AREATYPES.SASH or nAreaType == WIN_AREATYPES.SPLIT then
-- creo riferimenti tra pezzo e outline
EgtSetInfo( nPartId, WIN_REF_OUTLINE, nOutlineId)
if bBottomRail then
EgtSetInfo( nOutlineId, WIN_REF_BOTTOMRAIL_PART, nPartId)
else
EgtSetInfo( nOutlineId, WIN_REF_PART, nPartId)
end
-- imposto nome del pezzo
local sName = EgtGetName( nOutlineId)
if bBottomRail then
sName = WIN_BOTTOMRAIL
end
EgtSetName( nPartId, sName)
-- imposto colore
if sName == WIN_BOTTOM or sName == WIN_TOP or bBottomRail then
EgtSetColor( nPartId, Color3d( 204, 102, 0))
elseif sName == WIN_RIGHT or sName == WIN_LEFT then
EgtSetColor( nPartId, Color3d( 251, 128, 4))
else
EgtSetColor( nPartId, Color3d( 255, 159, 57))
end
-- setto le info di sovramateriale ( TO DO : capire da dove devono essere ricavate)
EgtSetInfo( nPartId, WIN_PRC_OVERMAT_IN, 0)
EgtSetInfo( nPartId, WIN_PRC_OVERMAT_OUT, 0)
EgtSetInfo( nPartId, WIN_PRC_OVERMAT_LEFT, 0)
EgtSetInfo( nPartId, WIN_PRC_OVERMAT_RIGHT, 0)
-- ricavo il tipo di profilo
local nProfileType = GetOutlineProfileType( nOutlineId, bBottomRail)
-- disegno ingombro
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)
-- disegno solido
if s_bCalcSolid then
CalcSolid( nPartId, nOutlineId)
end
-- b) Fill
elseif nAreaType == WIN_AREATYPES.FILL then
-- imposto nome del pezzo
EgtSetName( nPartId, WIN_FILL)
-- ricavo tipo
local nFillType = EgtGetInfo( nAreaLayerId, WIN_FILLTYPE, 'i')
-- imposto colore
if nFillType == WIN_FILLTYPES.GLASS then
EgtSetColor( nPartId, Color3d( 71, 161, 255))
EgtSetAlpha( nPartId, 30)
elseif nFillType == WIN_FILLTYPES.WOOD then
EgtSetColor( nPartId, Color3d( 194, 148, 103))
end
-- disegno ingombro
local nGeoLayerId = CalcFillGeo( nPartId, nOutlineLayerId)
-- disegno solido
if 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')
if nAreaType == WIN_AREATYPES.FRAME or nAreaType == WIN_AREATYPES.SASH then
-- creo pezzi per ogni outline
local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE)
local vOutlines = EgtGetAllInGroup( nOutlineLayerId)
for i = 1, #vOutlines do
-- creo pezzo
CreatePartFromOutline( nAreaId, vOutlines[i], i)
-- se di tipo bottom verifico se ha bottomrail
local sName = EgtGetName( vOutlines[i])
if sName == WIN_BOTTOM then
local bBottomRail = EgtGetInfo( nOutlineLayerId, WIN_BOTTOMRAIL, 'b') or false
if bBottomRail then
CreatePartFromOutline( nAreaId, vOutlines[i], i, true)
end
end
end
elseif nAreaType == WIN_AREATYPES.FILL then
-- creo riempimento
CreatePartFromOutline( nAreaId)
end
-- verifico se c'e' uno split da realizzare
local nSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_SPLIT)
if nSplitLayerId then
local nSplitType = EgtGetInfo( nSplitLayerId, WIN_SPLITTYPE, 'i') or WIN_SPLITTYPES.NULL
-- se split non è di tipo french ha un pezzo associato
if nSplitType ~= WIN_SPLITTYPES.FRENCH then
local nSplitId = EgtGetFirstInGroup( nSplitLayerId)
if nSplitId then
-- creo pezzo split
local nSplitPartId = CreatePartFromOutline( nAreaId, nSplitId)
-- disegno area di selezione per programma
local nSelectionLayerId = EgtGroup( nAreaId)
EgtSetName( nSelectionLayerId, WIN_SPLITSELECTION)
EgtSetStatus( nSelectionLayerId, GDB_ST.OFF)
local nSplitPartGeoId = EgtGetFirstNameInGroup( nSplitPartId, WIN_GEO)
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
-- 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 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)
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
CalculateAreaParts( nFrameId)
-- calcolo le spine
CalculateAreaDowels( nFrameId)
end
---------------------------------------------------------------------
-- funzione che posiziona un pezzo
function WinCalculate.PositionPart(nPartId)
-- ricavo tipo dal nome
local sName = EgtGetName( nPartId)
local sDelta = ''
if sName == WIN_BOTTOM then
sDelta = WIN_STARTCPDELTA
elseif sName == WIN_RIGHT then
sDelta = WIN_STARTCPDELTA
elseif sName == WIN_TOP then
sDelta = WIN_STARTCPDELTA
elseif sName == WIN_LEFT then
sDelta = WIN_STARTCPDELTA
end
-- calcolo nuovo riferimento
local nGeoPartLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO)
local nGeoPartId = EgtGetFirstNameInGroup( nGeoPartLayerId, sName)
local dDelta = EgtGetInfo( nGeoPartId, sDelta, 'd') or 0
local nFrameLayerId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_FRAME)
local nOutlineLayerId = EgtGetFirstNameInGroup( nFrameLayerId, WIN_OUTLINE)
local nFramePartId = EgtGetFirstNameInGroup( nOutlineLayerId, sName)
local vtStart = EgtSV( nFramePartId)
local ptStart = EgtSP( nFramePartId) + vtStart * dDelta
local _, _, dAngRight = SphericalFromVector(vtStart)
local frStart = Frame3d( ptStart)
frStart:rotate( frStart:getOrigin(), Z_AX(), dAngRight)
EgtChangeGroupFrame( nPartId, frStart)
end
---------------------------------------------------------------------
-- funzione che assembla i pezzi
function WinCalculate.AssembleFrame()
local nBottomPartId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_BOTTOM)
WinCalculate.PositionPart(nBottomPartId)
local nRightPartId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_RIGHT)
WinCalculate.PositionPart(nRightPartId)
local nTopPartId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_TOP)
WinCalculate.PositionPart(nTopPartId)
local nLeftPartId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_LEFT)
WinCalculate.PositionPart(nLeftPartId)
-- assemblo i pezzi
--local nRightPartId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_RIGHT)
--local nGeoRightLayerId = EgtGetFirstNameInGroup( nRightPartId, WIN_GEO)
--local nGeoRightId = EgtGetFirstNameInGroup( nGeoRightLayerId, WIN_RIGHT)
--local dDelta = EgtGetInfo( nGeoRightId, WIN_BOTTOMCPDELTA, 'd')
--local nFrameLayerId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_FRAME)
--local nOutlineLayerId = EgtGetFirstNameInGroup( nFrameLayerId, WIN_OUTLINE)
--local nFrameRightId = EgtGetFirstNameInGroup( nOutlineLayerId, WIN_RIGHT)
--local vtRight = EgtSV( nFrameRightId)
--local ptRight = EgtSP( nFrameRightId) + vtRight * dDelta
--local _, _, dAngRight = SphericalFromVector(vtRight)
--local frRight = Frame3d( ptRight)
--frRight:rotate( frRight:getOrigin(), Z_AX(), dAngRight)
--EgtChangeGroupFrame( nRightPartId, frRight)
end
----------------------------------------------------------------------------------
------------------- POST PROCESSING PER AUTOMATISMO LAVORAZIONI ------------------
----------------------------------------------------------------------------------
-- 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 il pezzo del tronchetto
local function PrepareLogPart( nOrigPartId, nCrvIn, nCrvOut, bFirst, bLast, bFinishedLog, nInfoGrp)
local nPartId = EgtGroup( GDB_ID.ROOT)
EgtSetName( nPartId, WIN_LOGS)
EgtSetColor( nPartId, Color3d( 204, 102, 0))
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)
-- recupero il profilo
local nProfileLayerId = EgtGetFirstNameInGroup( nOrigPartId, WIN_PROFILE)
local nProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN)
-- 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 bFirst and bLast then
-- essendo singolo pezzo il solido è quello originale
local nOrigSolidLayerId = EgtGetFirstNameInGroup( nOrigPartId, WIN_SOLID)
local nOrigSolidId = EgtGetFirstNameInGroup( nOrigSolidLayerId, WIN_SRF_MAIN)
EgtRelocateGlob( nOrigSolidId, nSolidLayerId)
elseif bFinishedLog then
-- recupero il solido originale e lo taglio opportunamente agli estremi
local nOrigSolidLayerId = EgtGetFirstNameInGroup( nOrigPartId, WIN_SOLID)
local nOrigSolidId = EgtGetFirstNameInGroup( nOrigSolidLayerId, WIN_SRF_MAIN)
nSolidId = EgtCopyGlob( nOrigSolidId, nSolidLayerId)
local bBox = GetProfileLocalBox( nProfileId)
local dDimY = bBox:getDimY()
if not bFirst 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 not bLast 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
local nOrigProcLayerId = EgtGetFirstNameInGroup( nOrigPartId, WIN_PRC)
-- se unico tronchetto le lavorazioni sono quelle del pezzo originale
if bFirst and bLast then
EgtRelocateGlob( nOrigProcLayerId, nPartId)
EgtSetStatus( nOrigProcLayerId, GDB_ST.ON)
return
end
local nProcLayerId = EgtGroup( nPartId)
EgtSetName( nProcLayerId, WIN_PRC)
-- profili in e out
if bFinishedLog 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 bLast and bFinishedLog then
-- recupero la curva di lavorazione dal pezzo originale
local nLeftPrc = EgtGetFirstNameInGroup( nOrigProcLayerId, WIN_GEO_LEFT)
EgtRelocateGlob( nLeftPrc, nProcLayerId)
elseif not bLast 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 bFirst and bFinishedLog then
-- recupero la curva di lavorazione dal pezzo originale
local nRightPrc = EgtGetFirstNameInGroup( nOrigProcLayerId, WIN_GEO_RIGHT)
EgtRelocateGlob( nRightPrc, nProcLayerId)
elseif not bFirst 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 not bFirst then
CalcLogDowel( nOrigPartId, nCrvOut, false, nProcLayerId, nProfileId, nInfoGrp, nSolidId)
end
if not bLast 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 bFinishedLog 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 bLast) or ( sSide == WIN_PRC_SIDETYPE.RIGHT and bFirst) 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
---------------------------------------------------------------------
-- funzione che crea gli elementi ausiliari per la creazione del grezzo nell'automatismo
local function PrepareGeoRawCurve( nPartId, nGeoRawLayerId, nGeoLayerId)
-- recupero le curve del geo
local nOut = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_OUT)
local nIn = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_IN)
local vRight = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_RIGHT)
local vLeft = EgtGetNameInGroup( nGeoLayerId, 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 a partire dalle curve
local vCrvs = EgtGetAllInGroup( nGeoLayerId)
TrimAndOrientOrderedCurves( vCrvs, false)
local nCompo = EgtCurveCompo( nGeoRawLayerId, vCrvs)
return nCompo
end
---------------------------------------------------------------------
-- funzione che crea gli elementi ausiliari per la creazione del grezzo nell'automatismo nel caso di arco spezzato in tronchetti
local function PrepareGeoRawCurveFromLogs( nPartId, nGeoRawLayerId, nLogsLayerId)
-- recupero i vari tronchetti
local vLogCrvs = EgtGetNameInGroup( nLogsLayerId, 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)
return nCompo
end
---------------------------------------------------------------------
-- funzione che prepara il progetto per passarlo all'automatismo delle lavorazioni
function WinCalculate.PrepareProject()
-- recupero il gruppo dei profili
local nProfileLay = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_PROFILE)
local nInfoGrp = EgtGetFirstNameInGroup( nProfileLay, WIN_INFO_GRP)
-- elimino i pezzi di tipo fill
local vFills = EgtGetNameInGroup( GDB_ID.ROOT, WIN_FILL)
EgtErase( vFills)
-- TO DO : recupero modalità di lavorazione dei tronchetti
local bFinishedLogs = true
-- preparo ogni pezzo per l'automatismo ( quindi salto i primi due che sono il gruppo dei profili e delle aree)
local vParts = EgtGetAllInGroup( GDB_ID.ROOT)
for i = 3, #vParts do
local bDeletePart = false
-- verifico se tronchetti
local nLogsLayerId = EgtGetFirstNameInGroup( vParts[i], WIN_LOGS)
if nLogsLayerId then
-- calcolo i pezzi corrispondenti ai tronchetti
local vCrvIn = EgtGetNameInGroup( nLogsLayerId, WIN_GEO_IN)
local vCrvOut = EgtGetNameInGroup( nLogsLayerId, WIN_GEO_OUT)
for j = 1, #vCrvIn do
PrepareLogPart( vParts[i], vCrvIn[j], vCrvOut[j], j == 1, j == #vCrvIn, bFinishedLogs, nInfoGrp)
end
-- il pezzo originale va cancellato se i tronchetti sono lavorati come pezzi finiti oppure se c'è un solo tronchetto
bDeletePart = bFinishedLogs or ( #vCrvIn == 1)
end
if bDeletePart then
EgtErase( vParts[i])
else
-- cancello il gruppo dei profili
local nProfileGrp = EgtGetFirstNameInGroup( vParts[i], WIN_PROFILE)
EgtErase( nProfileGrp or GDB_ID.NULL)
-- cancello eventuali gruppi ausiliari per cambio profilo
local nMixedOutlines = EgtGetFirstNameInGroup( vParts[i], WIN_MIXED_OUTLINES)
EgtErase( nMixedOutlines or GDB_ID.NULL)
local nMixedIntersections = EgtGetFirstNameInGroup( vParts[i], WIN_MIXED_INTERSECTIONS)
EgtErase( nMixedIntersections or GDB_ID.NULL)
-- accendo gruppo delle lavorazioni
local nProcLay = EgtGetFirstNameInGroup( vParts[i], WIN_PRC)
EgtSetStatus( nProcLay, GDB_ST.ON)
-- nel gruppo dei solidi conservo solo quello principale
local nSolidGrp = EgtGetFirstNameInGroup( vParts[i], WIN_SOLID)
if nSolidGrp then
local nMainSolid = EgtGetFirstNameInGroup( nSolidGrp, WIN_SRF_MAIN)
local vIds = EgtGetAllInGroup( nSolidGrp)
for i = 1, #vIds do
if vIds[i] ~= nMainSolid then
EgtErase( vIds[i])
end
end
end
-- creo il GeoRaw per il calcolo del grezzo
local nGeoRawLayerId = EgtGroup( vParts[i])
EgtSetName( nGeoRawLayerId, WIN_GEO_RAW)
local nGeoLayerId = EgtGetFirstNameInGroup( vParts[i], WIN_GEO)
local nCompo
if nLogsLayerId then
nCompo = PrepareGeoRawCurveFromLogs( vParts[i], nGeoRawLayerId, nLogsLayerId)
EgtErase( nLogsLayerId)
else
nCompo = PrepareGeoRawCurve( vParts[i], nGeoRawLayerId, nGeoLayerId)
end
EgtErase( nGeoLayerId)
-- 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
end
-- elimino il gruppo delle aree
local nAreaLay = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_AREA .. '*')
EgtErase( nAreaLay)
-- elimino il gruppo dei profili
EgtErase( nProfileLay)
end
----------------------------------------------------------------------------------
---------------------------------- FERRAMENTA ----------------------------------
----------------------------------------------------------------------------------
local function SearchSash( nAreaId, SashList)
-- verifico il tipo
local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i')
--if nAreaType == WIN_AREATYPES.FRAME then
if nAreaType == WIN_AREATYPES.SASH then
-- calcolo il Box
local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE)
local b3Outline = EgtGetBBox( nOutlineLayerId, GDB_BB.STANDARD)
-- recupero punti di origine
local nSashFrameLayerId = EgtGroup( nAreaId)
EgtSetName( nSashFrameLayerId, WIN_HDW_FRAME)
local vOutlineCopy = {}
local nOutlineOffsetLayerId = EgtGroup( nAreaId)
local nOutlineId = EgtGetFirstInGroup( nOutlineLayerId)
while nOutlineId do
local sProfileType = EgtGetInfo( nOutlineId, WIN_PROFILETYPE)
local nProfileId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_PROFILE, 'i')
local nSashProfileId = EgtGetFirstNameInGroup( nProfileId, WIN_SASH, 'i')
local nSashProfileTypeId = EgtGetFirstNameInGroup( nSashProfileId, sProfileType, 'i')
local dGapDelta = EgtGetInfo( nSashProfileTypeId, WIN_GAPDELTA, 'd')
local dGapDeltaZ = EgtGetInfo( nSashProfileTypeId, WIN_GAPDELTAZ, 'd')
local nOutlineCopyId = EgtCopy( nOutlineId, nOutlineOffsetLayerId)
EgtSetInfo( nOutlineCopyId, 'ORIG', nOutlineId)
EgtSetInfo( nOutlineCopyId, WIN_GAPDELTAZ, dGapDeltaZ)
local nSectionFrameId = EgtGetFirstNameInGroup( nSashProfileTypeId, WIN_SECTIONFRAME)
local frSectionFrame = EgtFR( nSectionFrameId)
local nSashProfileRefId = EgtGetFirstNameInGroup( nSashProfileTypeId, WIN_REF)
local b3SashProfileType = EgtGetBBoxRef( nSashProfileRefId, GDB_BB.STANDARD, frSectionFrame)
EgtSetInfo( nOutlineCopyId, WIN_GAPDELTAZ .. 2, b3SashProfileType:getDimY())
EgtOffsetCurve( nOutlineCopyId, - dGapDelta)
table.insert( vOutlineCopy, nOutlineCopyId)
nOutlineId = EgtGetNext( nOutlineId)
end
local tSash = { nAreaId = nAreaId, ptCenter = b3Outline:getCenter()}
local tFrame = {}
local nA_FA1Id = GDB_ID.NULL
local nB_FA1Id = GDB_ID.NULL
local nC_FA1Id = GDB_ID.NULL
local nD_FA1Id = GDB_ID.NULL
for nIndex = 1, #vOutlineCopy do
local nNext = EgtIf( nIndex < #vOutlineCopy, nIndex + 1, 1)
local ptOrig = EgtIP( vOutlineCopy[nIndex], vOutlineCopy[nNext], ORIG())
local dParam = EgtCurveParamAtPoint( vOutlineCopy[nIndex], ptOrig)
EgtTrimCurveEndAtParam( vOutlineCopy[nIndex], dParam)
dParam = EgtCurveParamAtPoint( vOutlineCopy[nNext], ptOrig)
EgtTrimCurveStartAtParam( vOutlineCopy[nNext], dParam)
local sOrigName = string.char(string.byte('A') + #vOutlineCopy - nIndex)
tSash[sOrigName] = ptOrig
local vtDir = EgtEV( vOutlineCopy[nIndex])
local nFA1Id = EgtFrame( nSashFrameLayerId, Frame3d( ptOrig, - vtDir, vtDir ^ Z_AX() , Z_AX()))
EgtSetName( nFA1Id, sOrigName .. '.FA1')
local vtIn = Vector3d( vtDir)
vtIn:rotate( Z_AX(), -90)
local dGapDeltaZ = EgtGetInfo( vOutlineCopy[nIndex], WIN_GAPDELTAZ, 'd')
local nFA2Id = EgtFrame( nSashFrameLayerId, Frame3d( ptOrig - dGapDeltaZ * Z_AX(), - vtDir, vtDir ^ vtIn , vtIn))
EgtSetName( nFA2Id, sOrigName .. '.FA2')
local dGapDeltaZ2 = EgtGetInfo( vOutlineCopy[nIndex], WIN_GAPDELTAZ .. 2, 'd')
local nFA3Id = EgtFrame( nSashFrameLayerId, Frame3d( ptOrig - dGapDeltaZ2 * Z_AX(), - vtDir, vtDir ^ -Z_AX() , -Z_AX()))
EgtSetName( nFA3Id, sOrigName .. '.FA3')
if sOrigName == 'A' then
nA_FA1Id = nFA1Id
elseif sOrigName == 'B' then
nB_FA1Id = nFA1Id
elseif sOrigName == 'C' then
nC_FA1Id = nFA1Id
elseif sOrigName == 'D' then
nD_FA1Id = nFA1Id
end
-- ricavo posizione sul telaio
local nOrigOutlineId = EgtGetInfo( vOutlineCopy[nIndex], 'ORIG', 'i')
local nBaseOutlineId = EgtGetInfo( nOrigOutlineId, WIN_COPY, 'i')
local nSouId = EgtGetInfo( nBaseOutlineId, WIN_SOU, 'i')
local nSouAreaId = EgtGetParent( EgtGetParent( nSouId))
local nSouAreaType = EgtGetInfo( nSouAreaId, WIN_AREATYPE, 'i')
while nSouId and nSouAreaType ~= WIN_AREATYPES.FRAME do
nSouId = EgtGetInfo( nSouId, WIN_SOU, 'i')
nSouAreaId = EgtGetParent( EgtGetParent( nSouId or GDB_ID.NULL))
nSouAreaType = EgtGetInfo( nSouAreaId or GDB_ID.NULL, WIN_AREATYPE, 'i')
end
if nSouId and EgtGetName( nSouId) ~= WIN_SPLIT then
local nFrameFrameLayerId = EgtGetFirstNameInGroup( nSouAreaId, WIN_HDW_FRAME)
if not nFrameFrameLayerId then
nFrameFrameLayerId = EgtGroup( nSouAreaId)
EgtSetName( nFrameFrameLayerId, WIN_HDW_FRAME)
end
-- ricavo aria lato telaio
local sProfileType = EgtGetInfo( nSouId, WIN_PROFILETYPE)
local nProfileId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_PROFILE, 'i')
local nFrameProfileId = EgtGetFirstNameInGroup( nProfileId, WIN_FRAME, 'i')
local nFrameProfileTypeId = EgtGetFirstNameInGroup( nFrameProfileId, sProfileType, 'i')
local dGapDeltaOut = EgtGetInfo( nFrameProfileTypeId, WIN_GAPDELTAOUT, 'd')
local dFrameGapDeltaZ = EgtGetInfo( nFrameProfileTypeId, WIN_GAPDELTAZ, 'd')
local nOutlineOutId = EgtCopy( nSouId, nOutlineOffsetLayerId)
EgtSetName( nOutlineOutId, 'Frame')
EgtOffsetCurve( nOutlineOutId, - dGapDeltaOut)
-- prendo la proiezione
_, ptOrig = EgtPointCurveDist( ptOrig, nOutlineOutId)
-- recupero DeltaZ2
local nSectionFrameId = EgtGetFirstNameInGroup( nFrameProfileTypeId, WIN_SECTIONFRAME)
local frSectionFrame = EgtFR( nSectionFrameId)
local nFrameProfileRefId = EgtGetFirstNameInGroup( nFrameProfileTypeId, WIN_REF)
local b3SashProfileType = EgtGetBBoxRef( nFrameProfileRefId, GDB_BB.STANDARD, frSectionFrame)
local nFT1Id = EgtFrame( nFrameFrameLayerId, Frame3d( ptOrig - dFrameGapDeltaZ * Z_AX(), - vtDir, vtDir ^ Z_AX() , Z_AX()))
EgtSetName( nFT1Id, sOrigName .. '.FT1')
table.insert( tFrame, nFT1Id)
local vtFrameIn = Vector3d( vtDir)
vtFrameIn:rotate( Z_AX(), 90)
local nFT2Id = EgtFrame( nFrameFrameLayerId, Frame3d( ptOrig - dFrameGapDeltaZ * Z_AX(), - vtDir, vtDir ^ vtFrameIn , vtFrameIn))
EgtSetName( nFT2Id, sOrigName .. '.FT2')
table.insert( tFrame, nFT2Id)
local dGapDeltaZ2 = b3SashProfileType:getDimY()
local nFT3Id = EgtFrame( nFrameFrameLayerId, Frame3d( ptOrig - dGapDeltaZ2 * Z_AX(), - vtDir, vtDir ^ -Z_AX() , -Z_AX()))
EgtSetName( nFT3Id, sOrigName .. '.FT3')
table.insert( tFrame, nFT3Id)
end
end
tSash.Frame = tFrame
tSash.LHeight = ( EgtSP( nB_FA1Id) - EgtSP( nA_FA1Id)):getY()
tSash.RHeight = ( EgtSP( nC_FA1Id) - EgtSP( nD_FA1Id)):getY()
tSash.TWidth = ( EgtSP( nC_FA1Id) - EgtSP( nB_FA1Id)):getX()
tSash.BWidth = ( EgtSP( nD_FA1Id) - EgtSP( nA_FA1Id)):getX()
if EgtGetType( vOutlineCopy[3]) == GDB_TY.CRV_ARC then
tSash.BCLength = EgtCurveLength( vOutlineCopy[3])
tSash.BCArrow = EgtMP( vOutlineCopy[3]) - (( EgtEP( vOutlineCopy[3]) - EgtSP( vOutlineCopy[3])) / 2)
end
EgtErase( nOutlineOffsetLayerId)
table.insert( SashList, tSash)
end
-- verifico se ci sono sotto-aree
local nChildAreaId = EgtGetFirstNameInGroup( nAreaId, WIN_AREA .. '*')
while nChildAreaId do
-- lancio costruzione pezzi di quell'area
SearchSash( nChildAreaId, SashList)
nChildAreaId = EgtGetNextName( nChildAreaId, WIN_AREA .. '*')
end
end
-- funzione che aggiunge l'hardware
function WinCalculate.AddHardwareForSash( nFrameId, 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 not nFavourite or nFavourite == '000000' then
EgtOutLog('Warning! No hardware favourite set!')
return
end
local sHandle = EgtGetInfo( nFrameId, WIN_HDW_HANDLE)
if not sHandle then
EgtOutLog('Warning! No hardware handle set!')
return
end
-- creo file di richiesta ferramenta
local sNow = os.date( '_%Y_%m_%d_%H_%M_%S', os.time())
local sInputFile = 'a:\\InputBatch\\Input' .. sNow .. '.txt'
local sAGBOutputFile = 'C:\\AGB3000NG\\OutputBatch\\Output' .. sNow .. '.txt'
local sAGBOutputLavFile = 'C:\\AGB3000NG\\OutputBatch\\OutputLav' .. sNow .. '.txt'
local sOutputFile = 'a:\\OutputBatch\\Output' .. sNow .. '.txt'
local sOutputLavFile = 'a:\\OutputBatch\\OutputLav' .. sNow .. '.txt'
-- Apro file Input in scrittura
local fhInput = io.open( sInputFile, 'w')
if not fhInput then
EgtOutLog( 'Error opening file ' .. sInputFile)
return false
end
local sText = 'OUTPUTKIT=' .. sAGBOutputFile .. '\n' ..
'S_NAME=' .. nFavourite .. '\n' ..
'RECORDID=15A' .. '\n'
if #SashList >= 1 and SashList[1].LHeight == SashList[1].RHeight then
sText = sText .. 'HBB=' .. tostring( SashList[1].LHeight) .. '\n'
else
for nSashIndex = 1, #SashList do
if nSashIndex == 1 then
sText = sText .. 'HBB_sx=' .. tostring( SashList[nSashIndex].LHeight) .. '\n'
else
sText = sText .. 'HBB_' .. tostring(nSashIndex - 1) .. 'B=' .. tostring( SashList[nSashIndex].LHeight) .. '\n'
end
if nSashIndex == #SashList then
sText = sText .. 'HBB_dx=' .. tostring( SashList[nSashIndex].RHeight) .. '\n'
else
sText = sText .. 'HBB_' .. tostring(nSashIndex) .. '=' .. tostring( SashList[nSashIndex].RHeight) .. '\n'
end
end
end
if #SashList == 1 then
sText = sText .. 'LBB=' .. tostring( SashList[1].BWidth) .. '\n'
else
for nSashIndex = 1, #SashList do
sText = sText .. 'LBB' .. nSashIndex .. '=' .. tostring( SashList[nSashIndex].BWidth) .. '\n'
if SashList[nSashIndex].BCLength then
sText = sText .. 'LBBA' .. nSashIndex .. '=' .. tostring( SashList[nSashIndex].BCLength) .. '\n'
end
if SashList[nSashIndex].BCArrow then
sText = sText .. 'FRECCIA_' .. nSashIndex .. '=' .. tostring( SashList[nSashIndex].BCArrow) .. '\n'
end
end
end
sText = sText .. 'FINESTRAPORTAFINESTRA=Finestra' .. '\n' ..
'Q=1' .. '\n' ..
'MANOSERRAMENTO=' .. sHandle .. '\n' ..
'CNCOUTPUT=' .. sAGBOutputLavFile .. '\n' ..
'RUN'
-- Scrittura nuova linea
fhInput:write( sText .. '\n')
-- Chiudo file
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 = EgtGetFirstNameInGroup( nHdwFrameLayerId, nSashIndex .. '.' .. sSashPart .. '.' .. sSide)
frHdwFrame = EgtFR( nHdwFrameId)
elseif sPart == 'ANTA' then
nPartId = EgtGetInfo( nOutlineId, WIN_REF_PART, 'i')
local nHdwFrameLayerId = EgtGetFirstNameInGroup( nSashId, WIN_HDW_FRAME)
local nHdwFrameId = EgtGetFirstNameInGroup( nHdwFrameLayerId, sSashPart .. '.' .. sSide)
frHdwFrame = EgtFR( nHdwFrameId)
end
local vMacro = EgtSplitString( sMacro, '_')
local nProcLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PRC)
-- recupero solido ( se non calcolato non vengono utilizzate)
local nSolidLayerId = EgtGetFirstNameInGroup( nPartId, WIN_SOLID) or GDB_ID.NULL
local nMainExtrusionId = EgtGetFirstNameInGroup( nSolidLayerId, WIN_SRF_MAIN)
local nOrigMainId = EgtGetFirstNameInGroup( nSolidLayerId, WIN_SRF_ORIGMAIN)
if vMacro[1] == 'FRESATA' then
elseif vMacro[1] == 'ASOLA' then
local ptCenter = Point3d( dPosX, dPosY, dPosZ)
local dLength = tonumber( vMacro[2])
local dWidth = tonumber( vMacro[3])
local dHeight = tonumber( vMacro[4])
local ptP1 = ptCenter + ( dLength / 2 - dWidth) * X_AX() + dWidth * Y_AX()
local ptP2 = ptCenter - ( dLength / 2 - dWidth) * X_AX() + dWidth * Y_AX()
local 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()
end
-- funzione che aggiunge l'hardware
function WinCalculate.AddHardware( nAreaId)
-- verifico il tipo
local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i')
local nSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_SPLIT)
local nSplitType = WIN_SPLITTYPES.NULL
if nSplitLayerId then
nSplitType = EgtGetInfo( nSplitLayerId, WIN_SPLITTYPE, 'i')
end
if nAreaType == WIN_AREATYPES.SASH or ( nSplitLayerId and nSplitType == WIN_SPLITTYPES.FRENCH) then
-- lancio calcolo sash
WinCalculate.AddHardwareForSash( nAreaId)
return
else
-- verifico se ci sono sotto-aree
local nChildAreaId = EgtGetFirstNameInGroup( nAreaId, WIN_AREA .. '*')
while nChildAreaId do
-- lancio verifica di quell'area
WinCalculate.AddHardware( nChildAreaId)
nChildAreaId = EgtGetNextName( nChildAreaId, WIN_AREA .. '*')
end
end
end
---------------------------------------------------------------------
return WinCalculate