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