From 65e0b550c6fe84e93e018fa54c1a6ec019597b6e Mon Sep 17 00:00:00 2001 From: SaraP Date: Thu, 23 Apr 2026 15:39:35 +0200 Subject: [PATCH] DataWindow : - cambio profilo su split - sistemata identificazione dei cambi profilo dopo gli spostamenti degli outlines degli split per misura luce - preview con pezzi dello stesso colore. --- Designing/WinConst.lua | 30 +- Designing/WinLib/WinCalculate.lua | 4158 +++++++++++++++++------------ Designing/WinLib/WinCreate.lua | 16 +- 3 files changed, 2532 insertions(+), 1672 deletions(-) diff --git a/Designing/WinConst.lua b/Designing/WinConst.lua index fc1d5e8..06a8f37 100644 --- a/Designing/WinConst.lua +++ b/Designing/WinConst.lua @@ -59,6 +59,7 @@ WIN_MEASURE = { } -- tipologia di figli +WIN_CHILDREN_TYPE = 'ChildrenType' WIN_CHILDREN_TYPES = { NULL = 0, SASH = 1, @@ -187,25 +188,26 @@ WIN_TOP = 'Top' WIN_LEFT = 'Left' -- info varie su aree e curve +WIN_SLIDE_WINDOW = 'SlideWindow' +WIN_MIXED_WINDOW = 'ProfileChangeWindow' WIN_PART_DIM = 'PartDim' -WIN_SOU = 'SOU' WIN_CHILD = 'CHILD' -WIN_COPY = 'COPY' +WIN_SASH_CHILDREN = 'SashChildren' +WIN_FILL_CHILDREN = 'FillChildren' WIN_SOU_OUTLINE = 'SouOutline' +WIN_CHILD_OUTLINE = 'ChildOutline' +WIN_CHILD_VIRTUAL_OUTLINE = 'ChildVirtualOutline' +WIN_CHILD_PRFCHANGE_SPLIT = 'ChildPrfChangeSplit' WIN_REF_OUTLINE = 'OutlineRef' WIN_REF_MUNTIN = 'MuntinRef' WIN_REF_PART = 'PartRef' WIN_REF_BOTTOMRAIL_PART = 'BottomRailPartRef' WIN_PREV_OUTLINES = 'PrevOutlines' WIN_NEXT_OUTLINES = 'NextOutlines' -WIN_INV_SPLIT = 'InvSplit' WIN_CRV_ON_FRENCH_SPLIT = 'OutlineOnFrenchSplit' WIN_SPLIT_STARTINTERS = 'SplitStartInters' WIN_SPLIT_ENDINTERS = 'SplitEndInters' -WIN_SASH_CHILDREN = 'SashChildren' -WIN_FILL_CHILDREN = 'FillChildren' WIN_THRESHOLD_PROFILE = 'ThresholdProfile' -WIN_SLIDE_WINDOW = 'SlideWindow' WIN_SASH_NBR = 'SashNbr' WIN_AREA_NBR = 'AreaNbr' WIN_AREA_PROFILES = 'AreaProfiles' @@ -221,7 +223,6 @@ WIN_SPECIAL_CRV = 'Special' -- PROFILI WIN_PROFILE = 'Profile' WIN_PROFILEPATH = 'ProfilePath' -WIN_INFO_GRP = 'Info' -- nomi dei profili WIN_SASH_TOP = 'Sash_Top' @@ -351,10 +352,6 @@ WIN_PROFILETYPE = 'ProfileType' -- GIUNZIONI WIN_JOINTS = 'Joints' -WIN_JOINT_BL = 'JointBL' -WIN_JOINT_BR = 'JointBR' -WIN_JOINT_TL = 'JointTL' -WIN_JOINT_TR = 'JointTR' WIN_STARTJOINT = 'StartJoint' WIN_ENDJOINT = 'EndJoint' @@ -398,10 +395,19 @@ WIN_REF_PRC = 'PrcRef' -- CAMBIO PROFILO WIN_PRF_CHANGE = 'ProfileChange' +WIN_PRF_CHANGE_TYPES = { -- binario + NULL = 0, + OUT = 1, -- cambio profilo sul lato esterno + IN = 2, -- cambio profilo sul lato interno + START = 4, -- cambio profilo sull'estremo iniziale + END = 8, -- cambio profilo sull'estremo finale +} WIN_MIXED_CURVES = 'ProfileChangeCurves' WIN_MIXED_MILLING = 'ProfileChangeMilling' WIN_MIXED_SPLIT_REF = 'MixedSplitRef' -WIN_MIXED_SASHFILL = 'MixedSashFill' +WIN_FILL_ON_SPLIT_RIGHT = 'FillOnSplitRight' +WIN_MIXED_START_CHILDREN = 'StartChildrenType' +WIN_MIXED_END_CHILDREN = 'EndChildrenType' -- SOLIDI diff --git a/Designing/WinLib/WinCalculate.lua b/Designing/WinLib/WinCalculate.lua index 34f563c..d215001 100644 --- a/Designing/WinLib/WinCalculate.lua +++ b/Designing/WinLib/WinCalculate.lua @@ -27,6 +27,7 @@ local s_dSimplSolidApprox = 0.2 -- approssimazione lineare nel caso di solidi s local s_nSashNbr = 0 -- contatore delle ante per assegnare nomi local s_dAngledCos = 0.995 -- coseno limite oltre il quale viene forzata giunzione angled +--------------------------------------------------------------------- local s_bCalcSolid = false function WinCalculate.GetCalcSolid() @@ -53,6 +54,13 @@ local function CopyInfo( nDest, nSou, sInfo, Default) EgtSetInfo( nDest, sInfo, sVal) end +--------------------------------------------------------------------- +local function AddInfo( nId, sInfo, sVal) + local vInfo = EgtGetInfo( nId, sInfo, 'vs') or {} + table.insert( vInfo, sVal) + EgtSetInfo( nId, sInfo, vInfo) +end + --------------------------------------------------------------------- -- funzione che restituisce o crea il layer ausiliario per soldi di ferramenta e accessori local function GetAuxLayer() @@ -239,30 +247,6 @@ local function CreateCurveExtension( nCrvId, nGrpId) return nExtId end ---------------------------------------------------------------------- --- funzione che date due curve parzialmente sovrapposte con nCrvId composita, allunga nCrvId aggiungendo i tratti di nRefCrvId che fuoriescono da essa -local function AddExtension( nCrvId, nRefCrvId) - - local dParS = EgtCurveParamAtPoint( nCrvId, EgtSP( nRefCrvId), 100 * GEO.EPS_SMALL) - if not dParS then - local dParTrim = EgtCurveParamAtPoint( nRefCrvId, EgtSP( nCrvId), 100 * GEO.EPS_SMALL) - if dParTrim then - local nNewCrv = EgtCopyParamRange( nRefCrvId, 0, dParTrim, EgtGetParent( nCrvId)) - EgtAddCurveCompoCurve( nCrvId, nNewCrv, true, false) - end - end - - local dParE = EgtCurveParamAtPoint( nCrvId, EgtEP( nRefCrvId), 100 * GEO.EPS_SMALL) - if not dParE then - local dParTrim = EgtCurveParamAtPoint( nRefCrvId, EgtEP( nCrvId), 100 * GEO.EPS_SMALL) - if dParTrim then - local _, dE = EgtCurveDomain( nRefCrvId) - local nNewCrv = EgtCopyParamRange( nRefCrvId, dParTrim, dE, EgtGetParent( nCrvId)) - EgtAddCurveCompoCurve( nCrvId, nNewCrv) - end - end -end - --------------------------------------------------------------------- -- funzione che data una lista di curve ordinate e orientate che creano una curva chiusa, ne individua la regione definita local function CalcIntersectionRegion( vCrvs, nGrp) @@ -404,7 +388,7 @@ local function TrimOrderedCurves( vCrvs, bDelete, nSurfId) -- recupero le curve di bordo della regione local nBorderId = EgtExtractSurfFrChunkLoops( nSurfId, 0, nGrpTmp) local nCrvBorder, nCnt = EgtExplodeCurveCompo( nBorderId) - + -- associo ad ogni curva originale le curve di bordo corrispondenti -- per gestire correttamente associazione devo partire da una curva di vCrvs e un tratto di nCrvBorder in corrispondenza biunivoca -- ( possono esserci curve di vCrvs senza corrispondente o con più corrispondenti tra le curve di bordo) @@ -518,7 +502,149 @@ local function TrimOrderedCurves( vCrvs, bDelete, nSurfId) end --------------------------------------------------------------------- --- funzione che data una curva di outline restituisce l'id del suo profilo +-- funzione che crea il bisettore parabolico tra linea e arco +local function CalcParabolicBisector( nCrv1, nCrv2, dDim, nGrp, bArcExternal, bLineExternal) + + -- modifico le curve affinchè abbiano estremo in comune + local ptInt = FindIntersectionPoint( nCrv1, nCrv2, EgtSP( nCrv2)) + EgtModifyCurveStartPoint( nCrv2, ptInt) + EgtModifyCurveEndPoint( nCrv1, ptInt) + + -- calcolo coefficienti dell'equazione del bisettore ( equazione presa da Vroni) + local nArc, nLine, nSign + if EgtGetType( nCrv1) == GDB_TY.CRV_ARC then + nArc = nCrv1 + nLine = nCrv2 + nSign = -1 + else + nArc = nCrv2 + nLine = nCrv1 + nSign = 1 + end + local ptC = EgtCP( nArc) + local dRad = EgtArcRadius( nArc) + -- equazione della retta + local dCoeffA = - EgtSV( nLine):getY() + local dCoeffB = EgtSV( nLine):getX() + local dCoeffC = - dCoeffA * ptInt:getX() - dCoeffB * ptInt:getY() + + local dDist = dCoeffA * ptC:getX() + dCoeffB * ptC:getY() + dCoeffC + local dA = ptC:getX() - dCoeffA * dDist + local dB = ptC:getY() - dCoeffB * dDist + local dZ = ptC:getZ() + + local k1 = EgtIf( bArcExternal, 1, -1) -- 1 esterno alla circonferenza / -1 interno alla circonferenza + local k2 = EgtIf( bLineExternal, 1, -1) -- 1 a destra della linea / -1 a sinistra della linea + + -- campiono il bisettore ( è parametrizzato sul valore di offset t) + local vPoints = {} + local nTot = 50 + for i = 1, nTot do + local t = dDim / ( nTot - 1) * ( i - 1) + local dDiscriminant = dRad * dRad + 2 * t * ( k1 * dRad - k2 * dDist) - dDist * dDist + local dX, dY + if dDiscriminant < GEO.EPS_ZERO then + dX = dA - k2 * dCoeffA * t + dY = dB - k2 * dCoeffB * t + else + dX = dA - k2 * dCoeffA * t + nSign * dCoeffB * sqrt( dDiscriminant) + dY = dB - k2 * dCoeffB * t - nSign * dCoeffA * sqrt( dDiscriminant) + end + vPoints[i] = Point3d( dX, dY, dZ) + end + + local nCompo = EgtCurveCompoFromPoints( nGrp, vPoints) + return nCompo +end + +--------------------------------------------------------------------- +local function CreateTestBoxFromOutline( nOutlineId, nProfileId, b3Profile) + + local frBox + local b3Box + + local dDimStd = b3Profile:getDimX() + local dDimReal = EgtGetInfo( nOutlineId, WIN_PART_DIM, 'd') + + if EgtGetType( nOutlineId) == GDB_TY.CRV_LINE then + -- oriento il box come la curva + frBox = Frame3d( EgtSP( nOutlineId), Z_AX(), EgtSV( nOutlineId)) + b3Box = EgtGetBBoxRef( nOutlineId, GDB_BB.STANDARD, frBox) + + -- ingrandisco il box con punti opportuni per tenere conto delle dimensioni del pezzo + local vtDir = VectorFromRotated( EgtSV( nOutlineId), Z_AX(), 90) + local ptMin = EgtSP( nOutlineId) + vtDir * abs( b3Profile:getMin():getX() * dDimReal / dDimStd) + local ptMax = EgtSP( nOutlineId) - vtDir * abs( b3Profile:getMax():getX() * dDimReal / dDimStd) + ptMin:toLoc( frBox) + ptMax:toLoc( frBox) + b3Box:Add( ptMin) + b3Box:Add( ptMax) + + else + -- calcolo il rettangolo di area minima che racchiude il pezzo + local nOffsMax = EgtOffsetCurveAdv( nOutlineId, b3Profile:getMax():getX() * dDimReal / dDimStd) + local nOffsMin = EgtOffsetCurveAdv( nOutlineId, b3Profile:getMin():getX() * dDimReal / dDimStd) + EgtInvertCurve( nOffsMin) + local nCompo = EgtCurveCompo( EgtGetParent( nOutlineId), nOffsMax) + EgtAddCurveCompoLine( nCompo, EgtSP( nOffsMin)) + EgtAddCurveCompoCurve( nCompo, nOffsMin) + EgtCloseCurveCompo( nCompo) + frBox = EgtCurveMinAreaRectangleXY( nCompo) + b3Box = EgtGetBBoxRef( nCompo, GDB_BB.STANDARD, frBox) + EgtErase( nCompo) + end + + return b3Box, frBox +end + +--------------------------------------------------------------------- +-- funzione che data una curva di outline restituisce l'id del suo profilo teorico ( ovvero quello del file dei profili) +local function GetOutlineTheoricProfileId( nOutlineId, bForceBottomRail, nBottomRail) + + -- recupero se è pezzo di telaio o anta + local nParentId = EgtGetParent( EgtGetParent( nOutlineId)) + local nAreaType = EgtGetInfo( nParentId or GDB_ID.NULL, WIN_AREATYPE, 'i') or 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) + elseif nAreaType == WIN_AREATYPES.FILL then + nLayerId = EgtGetFirstNameInGroup( nProfilesGrpId, WIN_FILL) + end + + -- recupero il nome del profilo + local sProfileName = EgtGetInfo( nOutlineId, WIN_PROFILETYPE) + + -- controlli per bottomrail + if EgtGetName( nOutlineId) == WIN_BOTTOM then + local nBottomRailTot = EgtGetInfo( nOutlineId, WIN_BOTTOMRAIL, 'i') or 0 + if nBottomRailTot > 0 then + if bForceBottomRail then + sProfileName = WIN_FILL_RAIL + elseif nBottomRail then + if nBottomRail == nBottomRailTot then + sProfileName = WIN_FILL_RAIL + else + sProfileName = WIN_RAIL + end + end + end + end + + -- restituisco il profilo + return EgtGetFirstNameInGroup( nLayerId, sProfileName) +end + +--------------------------------------------------------------------- +-- funzione che data una curva di outline restituisce l'id del suo profilo reale ( preso dal pezzo) local function GetOutlineProfileId( nOutlineId, bForceBottomRail, nBottomRail) -- recupero il pezzo associato all'outline @@ -605,42 +731,82 @@ end --------------------------------------------------------------------- -- funzione che restituisce il tipo di controprofilo dell'outline adiacente -local function GetProfileCtrIn( nPrevOutlineId, nOutlineId, nPrevProfileId) - local sPrevCtrIn = WIN_CTRIN +local function GetProfileCtrIn( nPrevOutlineId, nOutlineId, nPrevProfileId, bStart) - -- 1) se è inglesina interna deve finire contro il fermavetro ( dal lato corretto nel caso di split) oppure contro il bordo interno se finisce contro altra inglesina + local sCtrIn = WIN_CTRIN + local nPrfChange = EgtGetInfo( abs( nPrevOutlineId), WIN_PRF_CHANGE, 'i') or 0 + local nSide = EgtIf( nPrevOutlineId < 0, 1, 2) + + -- 1) se è inglesina interna if EgtGetName( nOutlineId) == WIN_SPLIT and EgtGetInfo( nOutlineId, WIN_MUNTINFILL_SIDE, 'i') == WIN_MUNTINFILL_SIDES.IN then + -- deve finire contro il fermavetro ( dal lato corretto nel caso di split) oppure contro il bordo interno se finisce contro altra inglesina if EgtGetName( abs( nPrevOutlineId)) == WIN_SPLIT then if EgtGetInfo( abs( nPrevOutlineId), WIN_SPLITTYPE, 'i') ~= WIN_SPLITTYPES.MUNTIN_FILL then - sPrevCtrIn = WIN_CTRIN .. WIN_STRIP + sCtrIn = WIN_CTRIN .. WIN_STRIP end - -- recupero il lato da cui si trova - sPrevCtrIn = sPrevCtrIn .. EgtIf( nPrevOutlineId < 0, '1', '2') else - sPrevCtrIn = WIN_CTRIN .. WIN_STRIP + sCtrIn = WIN_CTRIN .. WIN_STRIP end - -- 2) se finisce contro split devo individuare da quale lato dello split originale si trova l'outline per decidere quale controprofilo considerare - elseif EgtGetName( abs( nPrevOutlineId)) == WIN_SPLIT then - if nPrevOutlineId < 0 then - sPrevCtrIn = sPrevCtrIn .. '1' -- dx + -- 2) se finisce contro cambio profilo devo capire se va tagliato il controprofilo sash o fill + elseif nPrfChange & nSide > 0 then + local nPrfChangeCurr = EgtGetInfo( nOutlineId, WIN_PRF_CHANGE, 'i') or WIN_PRF_CHANGE_TYPES.NULL + if ( bStart and nPrfChangeCurr & WIN_PRF_CHANGE_TYPES.START > 0) or ( not bStart and nPrfChangeCurr & WIN_PRF_CHANGE_TYPES.END > 0) then + -- se il cambio profilo è stato determinato dall'outline allora devo tagliarlo con la parte sash + sCtrIn = WIN_SASH .. WIN_CTRIN else - sPrevCtrIn = sPrevCtrIn .. '2' -- sx - end - - -- 3) se finisce contro pezzo con cambio profilo - elseif not EgtGetFirstNameInGroup( nPrevProfileId, sPrevCtrIn) then - -- 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 + -- per capire contro quale parte finisce posso guardare i figli dell'outline. Se l'outline non ha cambio profilo posso considerare un figlio qualsiasi, + -- altrimenti devo considerare un figlio sull'estremo in analisi per essere sicuri di individuare la tipologia corretta + local nType + if nPrfChangeCurr == WIN_PRF_CHANGE_TYPES.NULL then + local vChildren = EgtGetInfo( nOutlineId, WIN_CHILD_OUTLINE, 'vi') + if not vChildren then + -- l'unico caso senza figli è inglesina, quindi sicuramente finisce contro la parte fill + nType = WIN_AREATYPES.FILL + else + local nAreaId = EgtGetParent( EgtGetParent( abs( vChildren[1]))) + nType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i') + end + else + if EgtGetName( nOutlineId) == WIN_SPLIT then + -- il figlio sull'estremo è salvato in una info + local sKey = EgtIf( bStart, WIN_MIXED_START_CHILDREN, WIN_MIXED_END_CHILDREN) .. '1' + local nChildrenType = EgtGetInfo( nOutlineId, sKey, 'i') + nType = EgtIf( nChildrenType == WIN_CHILDREN_TYPES.SASH, WIN_AREATYPES.SASH, WIN_AREATYPES.FILL) + else + -- per trovare il figlio nell'estremo corretto controllo quale figlio ha l'area in comune con un figlio di PrevOutline + local vChildren = EgtGetInfo( nOutlineId, WIN_CHILD_OUTLINE, 'vi') + local vChildrenPrev = EgtGetInfo( abs( nPrevOutlineId), WIN_CHILD_OUTLINE, 'vi') + for i = 1, #vChildren do + if nType then + break + end + local nRefArea = EgtGetParent( EgtGetParent( abs( vChildren[i]))) + for j = 1, #vChildrenPrev do + local nArea = EgtGetParent( EgtGetParent( abs( vChildrenPrev[j]))) + if nArea == nRefArea then + nType = EgtGetInfo( nArea, WIN_AREATYPE, 'i') + break + end + end + end + end + end + + if nType == WIN_AREATYPES.SASH then + sCtrIn = WIN_SASH .. WIN_CTRIN + else + sCtrIn = WIN_FILL .. WIN_CTRIN + end end end - return sPrevCtrIn + -- se finisce contro split recupero il controprofilo dal lato corretto ( destro (1) o sinistro (2)) + if EgtGetName( abs( nPrevOutlineId)) == WIN_SPLIT then + sCtrIn = sCtrIn .. tostring( nSide) + end + + return sCtrIn end --------------------------------------------------------------------- @@ -698,48 +864,10 @@ end ---------------------------------------------------------------------------------- ----------------------- CALCOLO DEI PROFILI PER BASEOUTLINES --------------------- +------------------------------ 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) +-- funzione che verifica la tipologia dei figli di una curva analizzando i base outlines +local function GetBaseChildrenType( nCrvId) local vStack = EgtGetInfo( nCrvId, WIN_CHILD, 'vi') or {} local i = 1 @@ -747,45 +875,37 @@ local function GetChildrenType( nCrvId) local vSashChildren = {} while vStack[i] do -- verifico se la sua area è di tipo sash o fill - local nAreaId = EgtGetParent( EgtGetParent( vStack[i])) + local nAreaId = EgtGetParent( EgtGetParent( abs( 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) + local vChildren = EgtGetInfo( abs( vStack[i]), WIN_CHILD, 'vi') or {} + EgtJoinTables( vStack, vChildren) end -- aggiorno il contatore i = i + 1 end + + local nChildrenType + if #vFillChildren > 0 and #vSashChildren > 0 then + nChildrenType = WIN_CHILDREN_TYPES.MIXED -- cambio profilo + elseif #vFillChildren > 0 then + nChildrenType = WIN_CHILDREN_TYPES.FILL + elseif #vSashChildren > 0 then + nChildrenType = WIN_CHILDREN_TYPES.SASH + else + nChildrenType = WIN_CHILDREN_TYPES.NULL + end - -- salvo i figli individuati come info della curva + EgtSetInfo( nCrvId, WIN_CHILDREN_TYPE, nChildrenType) 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 + return nChildrenType end --------------------------------------------------------------------- @@ -811,7 +931,7 @@ local function GetSplitType( nSplitId, nAreaId) nSplitType = WIN_SPLITTYPES.MUNTIN_FILL -- se dentro telaio verifico la tipologia dei figli elseif nParentAreaType == WIN_AREATYPES.FRAME then - local nChildrenType = GetChildrenType( nSplitId) + local nChildrenType = GetBaseChildrenType( nSplitId) if nChildrenType == WIN_CHILDREN_TYPES.MIXED then nSplitType = WIN_SPLITTYPES.MIXED elseif nChildrenType == WIN_CHILDREN_TYPES.FILL then @@ -835,10 +955,10 @@ local function FindAdjacentSashType( nSplitId, nCurrType) -- i figli della curva nSouId sono base outlines e non posso sapere a quali outlines corrispondono quindi per capire se sto guardando il figlio -- corretto controllo se il tipo di anta è lo stesso del corrente oppure no local vSplitChildren = EgtGetInfo( nSplitId, WIN_CHILD, 'vi') - local nAdjSashType = EgtGetInfo( EgtGetParent( EgtGetParent( vSplitChildren[1])), WIN_SASHTYPE, 'i') + local nAdjSashType = EgtGetInfo( EgtGetParent( EgtGetParent( abs( vSplitChildren[1]))), WIN_SASHTYPE, 'i') if nAdjSashType == nCurrType then -- se il tipo è lo stesso allora devo guardare l'altro figlio dello split - nAdjSashType = EgtGetInfo( EgtGetParent( EgtGetParent( vSplitChildren[2])), WIN_SASHTYPE, 'i') + nAdjSashType = EgtGetInfo( EgtGetParent( EgtGetParent( abs( vSplitChildren[2]))), WIN_SASHTYPE, 'i') end return nAdjSashType end @@ -914,7 +1034,7 @@ local function CalcSashProfiles( vOutlines, nAreaId) end else - -- a) alzante scorrevole + -- b) alzante scorrevole if nSashType == WIN_SASHTYPES.SLIDE_MOVABLE then if sName == WIN_BOTTOM then EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_MOVABLE_BOTTOM) @@ -940,7 +1060,7 @@ local function CalcSashProfiles( vOutlines, nAreaId) EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_MOVABLEBACK_SIDE) end - -- b) standard + -- a) standard else if sName == WIN_BOTTOM then -- verifico se bottomrail @@ -959,8 +1079,9 @@ local function CalcSashProfiles( vOutlines, nAreaId) end --------------------------------------------------------------------- --- funzione che imposta i tipi di profilo in base al tipo di pezzi -local function CalcProfileType( nAreaId) +-- funzione che cicla ricorsivamente su aree e sottoaree per impostare i tipi di profilo +local function CalculateAreaProfileType( nAreaId) + local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i') -- FRAME @@ -968,7 +1089,7 @@ local function CalcProfileType( nAreaId) -- gestione soglia local sThreshold = EgtGetInfo( nAreaId, WIN_THRESHOLD_PROFILE) or WIN_BOTTOM local bThreshold = ( sThreshold == WIN_THRESHOLD) - + -- assegno il profilo alle curve di outline local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_AREAOUTLINE) local nOutlineId = EgtGetFirstInGroup( nOutlineLayerId) @@ -981,45 +1102,41 @@ local function CalcProfileType( nAreaId) end -- recupero il tipo dei figli - local nChildrenType = GetChildrenType( nOutlineId) + local nChildrenType = GetBaseChildrenType( nOutlineId) - -- a) se non definiti gestisco come anta o fixed - if nChildrenType == WIN_CHILDREN_TYPES.NULL then - local nBottomRail = EgtGetInfo( nAreaId, WIN_BOTTOMRAIL, 'i') or 0 - if nBottomRail > 0 then - -- se bottomrail gestisco come fixed - if sName == WIN_BOTTOM then - EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_RAIL .. '_' .. sThreshold) + -- a) se riempimento o non definiti + if nChildrenType == WIN_CHILDREN_TYPES.FILL or nChildrenType == WIN_CHILDREN_TYPES.NULL then + if sName == WIN_BOTTOM then + -- verifico presenza bottomrail + local nBottomRail = EgtGetInfo( nAreaId, WIN_BOTTOMRAIL, 'i') or 0 + if nBottomRail == 0 then + EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_FIXED .. '_' .. sThreshold) else - EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_FIXED_TOP) + EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_RAIL .. '_' .. sThreshold) end else - -- se no bottomrail gestisco come anta - if sName == WIN_BOTTOM then - EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SASH .. '_' .. sThreshold) - else - EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SASH_TOP) - end + EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_FIXED_TOP) end -- b) se anta elseif nChildrenType == WIN_CHILDREN_TYPES.SASH then - EgtRemoveInfo( nAreaId, WIN_BOTTOMRAIL) -- verifico tipologia di anta contro cui poggia - local vChildren = EgtGetInfo( nOutlineId, WIN_SASH_CHILDREN, 'vi') - local nSashArea = EgtGetParent( EgtGetParent( vChildren[1])) + local vSashChildren = EgtGetInfo( nOutlineId, WIN_SASH_CHILDREN, 'vi') + local nSashArea = EgtGetParent( EgtGetParent( vSashChildren[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 EgtSetInfo( nAreaId, WIN_SLIDE_WINDOW, true) if sName == WIN_BOTTOM then + EgtRemoveInfo( nAreaId, WIN_BOTTOMRAIL) EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE .. '_' .. sThreshold) -- 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_MOVABLEBACK .. '_' .. sThreshold) elseif nSashType == WIN_SASHTYPES.SLIDE_MOVABLE then - for i = 2, #vChildren do - local nSashArea = EgtGetParent( EgtGetParent( vChildren[i])) + for i = 2, #vSashChildren do + local nSashArea = EgtGetParent( EgtGetParent( vSashChildren[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_MOVABLEBACK .. '_' .. sThreshold) @@ -1041,31 +1158,18 @@ local function CalcProfileType( nAreaId) -- b2) standard else if sName == WIN_BOTTOM then + EgtRemoveInfo( nAreaId, WIN_BOTTOMRAIL) EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SASH .. '_' .. sThreshold) 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 - -- verifico presenza bottomrail - local nBottomRail = EgtGetInfo( nAreaId, WIN_BOTTOMRAIL, 'i') or 0 - if nBottomRail == 0 then - EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_FIXED .. '_' .. sThreshold) - else - EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_RAIL .. '_' .. sThreshold) - end - else - EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_FIXED_TOP) - end - - -- d) se cambio profilo + -- c) se cambio profilo elseif nChildrenType == WIN_CHILDREN_TYPES.MIXED then - EgtRemoveInfo( nAreaId, WIN_BOTTOMRAIL) - EgtSetInfo( nOutlineId, WIN_PRF_CHANGE, true) + EgtSetInfo( nAreaId, WIN_MIXED_WINDOW, true) if sName == WIN_BOTTOM then + EgtRemoveInfo( nAreaId, WIN_BOTTOMRAIL) EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_MIXED_BOTTOM) else EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_MIXED_TOP) @@ -1098,10 +1202,10 @@ local function CalcProfileType( nAreaId) elseif nSplitType == WIN_SPLITTYPES.MUNTIN_SASH then EgtSetInfo( vSplitIds[i], WIN_PROFILETYPE, WIN_SASH_SPLIT) - + elseif nSplitType == WIN_SPLITTYPES.MUNTIN_FRAME then - EgtSetInfo( vSplitIds[i], WIN_PROFILETYPE, WIN_FRAME_SPLIT) - + EgtSetInfo( vSplitIds[i], WIN_PROFILETYPE, WIN_FRAME_SPLIT) + elseif nSplitType == WIN_SPLITTYPES.MUNTIN_FILL then -- se solo interne o entrambe assegno il profilo in ( l'out verrà aggiunto successivamente durante il calcolo del suo outline), se solo out assegno direttamente -- il profilo corretto @@ -1118,46 +1222,20 @@ local function CalcProfileType( nAreaId) elseif nSplitType == WIN_SPLITTYPES.MIXED then EgtSetInfo( vSplitIds[i], WIN_PROFILETYPE, WIN_MIXED_SPLIT) - EgtSetInfo( vSplitIds[i], 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( vSplitIds[i], WIN_SASH_CHILDREN, 'i') - local nRefCrv = EgtGetNext( nSashChild) or EgtGetPrev( nSashChild) - local _, _, nSide = EgtPointCurveDistSide( EgtMP( nRefCrv), vSplitIds[i], Z_AX()) - -- se si trova a destra, lo split va invertito - if nSide == 1 then - EgtInvertCurve( vSplitIds[i]) - EgtSetInfo( vSplitIds[i], WIN_INV_SPLIT, true) - end end -- se split di tipo french non ha profilo assegnato perchè non ha un pezzo associato end + -- NULL elseif nAreaType == WIN_AREATYPES.NULL then -- le aree null sono aree virtuali quindi non hanno pezzi ( e dunque profili) associati -- SASH elseif nAreaType == WIN_AREATYPES.SASH then - -- i profili verranno calcolati direttamente sulle curve di outline - - -- dimensioni - local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_AREAOUTLINE) - local vOutlineIds = EgtGetAllInGroup( nOutlineLayerId) - local vPartDim = EgtGetInfo( nAreaId, WIN_PART_DIM, 'vi') or {} - for i = 1, #vOutlineIds do - EgtSetInfo( vOutlineIds[i], WIN_PART_DIM, vPartDim[i]) - end + -- i profili verranno calcolati direttamente sulle curve di outline perchè non è detto che corrispondano alle curve di base outline 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 @@ -1185,31 +1263,83 @@ local function CalcRailOffset( nOutlineId, nProfileId, nBottomRail) end dRailOffs = dRailOffs - nBottomRail * dOverlap - EgtSetInfo( nProfileId, WIN_RAILOFFS, dRailOffs) + return dRailOffs +end + +---------------------------------------------------------------------------------- +-- funzione che nel caso di profilo mixed split conserva solamente le curve veramente necessarie per le tipologie di figli +local function CreateMixedSplitProfile( nOutlineId, nProfileId) + -- sistemo i profili dx (1) e sx (2) : se da un lato è presente una sola tipologia di figli allora : + -- a) elimino le curve legate all'altra tipologia e la curva common legata al cambio profilo + -- b) rinomino le curve della tipologia presente + -- In questo modo si può gestire quel lato come in uno split non mixed. Se invece da un lato sono presenti entrambe le tipologie di figli allora non servono modifiche + + local vSashProfiles = { WIN_SASH .. WIN_IN, WIN_SASH .. WIN_CTRIN, WIN_OFST .. WIN_SASH .. WIN_CTRIN} + local vFillProfiles = { WIN_FILL .. WIN_IN, WIN_FILL .. WIN_CTRIN, WIN_OFST .. WIN_FILL .. WIN_CTRIN, WIN_STRIP, WIN_CTRIN .. WIN_STRIP, WIN_OFST .. WIN_CTRIN .. WIN_STRIP} + local nNewNames = { WIN_IN, WIN_CTRIN, WIN_OFST .. WIN_CTRIN, WIN_STRIP, WIN_CTRIN .. WIN_STRIP, WIN_OFST .. WIN_CTRIN .. WIN_STRIP} + + local nPrfChange = EgtGetInfo( nOutlineId, WIN_PRF_CHANGE, 'i') + for i = 1, 2 do + -- verifico se lato con cambio profilo + if nPrfChange & i == 0 then + -- recupero la tipologia di figli da quel lato + local nChildrenType = EgtGetInfo( nOutlineId, WIN_MIXED_START_CHILDREN .. tostring( i), 'i') + local vToBeRenamed = {} + local vToBeErased = {} + if nChildrenType == WIN_CHILDREN_TYPES.SASH then + vToBeRenamed = vSashProfiles + vToBeErased = vFillProfiles + elseif nChildrenType == WIN_CHILDREN_TYPES.FILL then + vToBeRenamed = vFillProfiles + vToBeErased = vSashProfiles + end + + -- a) cancello + if #vToBeErased > 0 then + for j = 1, #vToBeErased do + local nId = EgtGetFirstNameInGroup( nProfileId, vToBeErased[j] .. tostring( i)) or GDB_ID.NULL + local nSimplId = EgtGetFirstNameInGroup( nProfileId, WIN_SIMPLIFIED .. vToBeErased[j] .. tostring( i)) or GDB_ID.NULL + EgtErase( { nId, nSimplId}) + end + local nId = EgtGetFirstNameInGroup( nProfileId, WIN_MIXED_COMMON .. WIN_IN .. tostring( i)) or GDB_ID.NULL + local nSimplId = EgtGetFirstNameInGroup( nProfileId, WIN_SIMPLIFIED .. WIN_MIXED_COMMON .. WIN_IN .. tostring( i)) or GDB_ID.NULL + EgtErase( { nId, nSimplId}) + end + + -- b) rinomino + for j = 1, #vToBeRenamed do + local nId = EgtGetFirstNameInGroup( nProfileId, vToBeRenamed[j] .. tostring( i)) or GDB_ID.NULL + EgtSetName( nId, nNewNames[j] .. tostring( i)) + local nSimplId = EgtGetFirstNameInGroup( nProfileId, WIN_SIMPLIFIED .. vToBeRenamed[j] .. tostring( i)) or GDB_ID.NULL + EgtSetName( nSimplId, WIN_SIMPLIFIED .. nNewNames[j] .. tostring( i)) + end + end + end end --------------------------------------------------------------------- -- funzione che crea il profilo della dimensione corretta local function AdjustProfileDimension( nOutlineId, nProfileId, dDimOld, dDim) - + local bSplit = ( EgtGetName( nOutlineId) == WIN_SPLIT) - local sProfileName = EgtGetInfo( nProfileId, WIN_PROFILETYPE) - local bMixed = EgtStartsWith( sProfileName, WIN_MIXED) - local dDeltaDim = dDim - dDimOld + local bPrfChange = ( EgtGetInfo( nOutlineId, WIN_PRF_CHANGE, 'i') == WIN_PRF_CHANGE_TYPES.IN) + local bMixedSplit = ( bSplit and EgtGetInfo( nOutlineId, WIN_SPLITTYPE, 'i') == WIN_SPLITTYPES.MIXED) + local dDeltaDim = dDim - dDimOld local nFrameId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME) local frSection = EgtFR( nFrameId, GDB_RT.GLOB) local vtMove = - frSection:getVersX() -- traslo le curve "interne" local vCurves = { WIN_IN, WIN_CTRIN, WIN_OFST .. WIN_CTRIN, WIN_STRIP, WIN_CTRIN .. WIN_STRIP, WIN_OFST .. WIN_CTRIN .. WIN_STRIP} + if bPrfChange then + vCurves = { WIN_SASH .. WIN_IN, WIN_FILL .. WIN_IN, WIN_SASH .. WIN_CTRIN, WIN_FILL .. WIN_CTRIN, WIN_OFST .. WIN_SASH .. WIN_CTRIN, WIN_OFST .. WIN_FILL .. WIN_CTRIN, + WIN_MIXED_COMMON .. WIN_IN, WIN_STRIP, WIN_CTRIN .. WIN_STRIP, WIN_OFST .. WIN_CTRIN .. WIN_STRIP} + end if bSplit then for i = 1, #vCurves do vCurves[i] = vCurves[i] .. '2' end - elseif bMixed then - vCurves = { WIN_SASH .. WIN_IN, WIN_FILL .. WIN_IN, WIN_SASH .. WIN_CTRIN, WIN_FILL .. WIN_CTRIN, WIN_OFST .. WIN_SASH .. WIN_CTRIN, WIN_OFST .. WIN_FILL .. WIN_CTRIN, - WIN_MIXED_COMMON .. WIN_IN, WIN_STRIP, WIN_CTRIN .. WIN_STRIP, WIN_OFST .. WIN_CTRIN .. WIN_STRIP} end for i = 1, #vCurves do @@ -1223,25 +1353,27 @@ local function AdjustProfileDimension( nOutlineId, nProfileId, dDimOld, dDim) local vDowels = EgtGetNameInGroup( nProfileId, WIN_DOWEL .. '*') EgtMove( vDowels, 0.5 * dDeltaDim * vtMove) - -- ricostruisco la sezione ( i=1) e la sezione semplificata ( i=2) - for i = 1, 2 do - -- prefisso al nome delle curve per sezione standard o semplificata - local sSimplPrefix = EgtIf( i == 1, '', WIN_SIMPLIFIED) - -- prefisso al nome delle curve per gestire parte sash o fill ( cambio profilo) - local vsPartPrefix = EgtIf( bMixed and not bSplit, { WIN_SASH, WIN_FILL}, {''}) - -- nome dei semiprofili da combinare per creare la sezione - local vsProfiles = EgtIf( bSplit, { WIN_IN .. '1', WIN_IN .. '2'}, { WIN_IN, WIN_OUT}) - - for j = 1, #vsPartPrefix do - local nSectionId = EgtGetFirstNameInGroup( nProfileId, sSimplPrefix .. vsPartPrefix[j] .. WIN_SECTION) - EgtErase( nSectionId) - local vSemiProfileNames = { sSimplPrefix .. vsPartPrefix[j] .. vsProfiles[1], sSimplPrefix .. vsProfiles[2]} - local vSemiProfiles = { EgtGetFirstNameInGroup( nProfileId, vSemiProfileNames[1]), EgtGetFirstNameInGroup( nProfileId, vSemiProfileNames[2])} - nSectionId = EgtCurveCompo( nProfileId, vSemiProfiles[1], false) - EgtAddCurveCompoLine( nSectionId, EgtSP( vSemiProfiles[2])) - EgtAddCurveCompoCurve( nSectionId, vSemiProfiles[2], false) - EgtCloseCurveCompo( nSectionId) - EgtSetName( nSectionId, sSimplPrefix .. vsPartPrefix[j] .. WIN_SECTION) + -- ricostruisco la sezione ( i=1) e la sezione semplificata ( i=2) tranne nel caso di split mixed ( perchè la sezione non è definita) + if not bMixedSplit then + for i = 1, 2 do + -- prefisso al nome delle curve per sezione standard o semplificata + local sSimplPrefix = EgtIf( i == 1, '', WIN_SIMPLIFIED) + -- prefisso al nome delle curve per gestire parte sash o fill ( cambio profilo) + local vsPartPrefix = EgtIf( bPrfChange, { WIN_SASH, WIN_FILL}, {''}) + -- nome dei semiprofili da combinare per creare la sezione + local vsProfiles = EgtIf( bSplit, { WIN_IN .. '1', WIN_IN .. '2'}, { WIN_IN, WIN_OUT}) + + for j = 1, #vsPartPrefix do + local nSectionId = EgtGetFirstNameInGroup( nProfileId, sSimplPrefix .. vsPartPrefix[j] .. WIN_SECTION) + EgtErase( nSectionId) + local vSemiProfileNames = { sSimplPrefix .. vsPartPrefix[j] .. vsProfiles[1], sSimplPrefix .. vsProfiles[2]} + local vSemiProfiles = { EgtGetFirstNameInGroup( nProfileId, vSemiProfileNames[1]), EgtGetFirstNameInGroup( nProfileId, vSemiProfileNames[2])} + nSectionId = EgtCurveCompo( nProfileId, vSemiProfiles[1], false) + EgtAddCurveCompoLine( nSectionId, EgtSP( vSemiProfiles[2])) + EgtAddCurveCompoCurve( nSectionId, vSemiProfiles[2], false) + EgtCloseCurveCompo( nSectionId) + EgtSetName( nSectionId, sSimplPrefix .. vsPartPrefix[j] .. WIN_SECTION) + end end end @@ -1264,84 +1396,43 @@ end local function CreatePartProfile( nPartId, nOutlineId, dDim, nBottomRail) -- gruppo per i profili - local nProfileLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE) - if nProfileLayerId then - EgtEmptyGroup( nProfileLayerId) - else - nProfileLayerId = EgtGroup( nPartId) - EgtSetName( nProfileLayerId, WIN_PROFILE) - EgtSetStatus( nProfileLayerId, GDB_ST.OFF) - end + local nProfileLayerId = EgtGroup( nPartId) + EgtSetName( nProfileLayerId, WIN_PROFILE) + EgtSetStatus( nProfileLayerId, GDB_ST.OFF) - -- profilo principale : - -- recupero se è pezzo di telaio o anta - local nParentId = EgtGetParent( EgtGetParent( nOutlineId)) - local nAreaType = EgtGetInfo( nParentId or GDB_ID.NULL, WIN_AREATYPE, 'i') or 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) - elseif nAreaType == WIN_AREATYPES.FILL then - nLayerId = EgtGetFirstNameInGroup( nProfilesGrpId, WIN_FILL) - end - - -- recupero il nome del profilo - local sProfileName = EgtGetInfo( nOutlineId, WIN_PROFILETYPE) - -- controlli per bottomrail - if nBottomRail then - local nBottomRailTot = EgtGetInfo( nOutlineId, WIN_BOTTOMRAIL, 'i') or 0 - if nBottomRail == nBottomRailTot then - sProfileName = WIN_FILL_RAIL - else - sProfileName = WIN_RAIL - end - end - - -- recupero il profilo - local nOrigMainProfileId = EgtGetFirstNameInGroup( nLayerId, sProfileName) + -- recupero il profilo teorico + local nOrigProfileId = GetOutlineTheoricProfileId( nOutlineId, false, nBottomRail) -- creo copia - local nMainProfileId = EgtCopy( nOrigMainProfileId, nProfileLayerId) - local sMainProfileType = EgtGetName( nMainProfileId) - EgtSetInfo( nMainProfileId, WIN_PROFILETYPE, sMainProfileType) - EgtSetName( nMainProfileId, WIN_PRF_MAIN) + local nProfileId = EgtCopy( nOrigProfileId, nProfileLayerId) + local sProfileType = EgtGetName( nProfileId) + EgtSetInfo( nProfileId, WIN_PROFILETYPE, sProfileType) + EgtSetName( nProfileId, WIN_PRF_MAIN) + -- se bottomrail salvo info per scostamento dall'outline if nBottomRail then - CalcRailOffset( nOutlineId, nMainProfileId, nBottomRail) + local dRailOffs = CalcRailOffset( nOutlineId, nProfileId, nBottomRail) + EgtSetInfo( nProfileId, WIN_RAILOFFS, dRailOffs) + end + + -- se split mixed aggiusto le curve del profilo in base alla reale tipologia di figli + if sProfileType == WIN_MIXED_SPLIT then + CreateMixedSplitProfile( nOutlineId, nProfileId) end -- verifico se vanno modificate le dimensioni del profilo - local dDimStd = EgtGetInfo( nMainProfileId, WIN_DIM_STD, 'd') - if dDim then - if abs( dDimStd - dDim) > GEO.EPS_SMALL then - AdjustProfileDimension( nOutlineId, nMainProfileId, dDimStd, dDim) - end - else - -- se non ha dimensione imposto quella standard - if nBottomRail then - local vBottomRailDims = EgtGetInfo( nOutlineId, WIN_BOTTOMRAIL.. WIN_PART_DIM, 'vd') or {} - table.insert( vBottomRailDims, nBottomRail, dDimStd) - EgtSetInfo( nOutlineId, WIN_BOTTOMRAIL.. WIN_PART_DIM, vBottomRailDims) - else - EgtSetInfo( nOutlineId, WIN_PART_DIM, dDimStd) - end + local dDimStd = EgtGetInfo( nProfileId, WIN_DIM_STD, 'd') + if abs( dDimStd - dDim) > GEO.EPS_SMALL then + AdjustProfileDimension( nOutlineId, nProfileId, dDimStd, dDim) 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) + CopyInfo( nPartId, nProfileId, WIN_PRC_OFFY_1, 0) + CopyInfo( nPartId, nProfileId, WIN_PRC_OFFZ_1, 0) + CopyInfo( nPartId, nProfileId, WIN_PRC_OFFY_2, 0) + CopyInfo( nPartId, nProfileId, WIN_PRC_OFFZ_2, 0) + CopyInfo( nPartId, nProfileId, WIN_PRC_CLAMPV_1, 0) + CopyInfo( nPartId, nProfileId, WIN_PRC_CLAMPV_2, 0) end --------------------------------------------------------------------- @@ -1370,259 +1461,9 @@ end ----------------------------------------------------------------------------------- ------------------------------- CREAZIONE PEZZI --------------------------------- ----------------------------------------------------------------------------------- --- funzione che dato il tipo di giunzione e di pezzo ( orizzontale o verticale) restituisce se è corto, lungo o angolato -local function CalcPartJoint( nJointType, bHorizontal) - - if nJointType == WIN_JNT.ANGLED then - return WIN_PART_JNT.ANGLED - elseif nJointType == WIN_JNT.FULL_H then - if bHorizontal then - return WIN_PART_JNT.FULL - else - return WIN_PART_JNT.SHORT - end - elseif nJointType == WIN_JNT.FULL_V then - if bHorizontal then - return WIN_PART_JNT.SHORT - else - return WIN_PART_JNT.FULL - end - end -end - ---------------------------------------------------------------------- -local function CalcOutlineStartJoint( nOutlineId, nPrevOutlineId, vJoints) - - local nStartJoint - - if EgtGetName( nOutlineId) == WIN_BOTTOM then - nStartJoint = CalcPartJoint( vJoints[1], true) - elseif EgtGetName( nOutlineId) == WIN_RIGHT then - nStartJoint = CalcPartJoint( vJoints[2], false) - elseif EgtGetName( nOutlineId) == WIN_TOP then - nStartJoint = CalcPartJoint( vJoints[3], true) - -- correzione per caso a triangolo : se l'outline vicino è di tipo bottom, il corrente deve essere trattato come un pezzo verticale - if EgtGetName( nPrevOutlineId) == WIN_BOTTOM then - nStartJoint = CalcPartJoint( vJoints[2], false) - end - elseif EgtGetName( nOutlineId) == WIN_LEFT then - nStartJoint = CalcPartJoint( vJoints[4] or vJoints[3], false) -- ( vJoints[3] per gestire caso a triangolo) - end - - -- eventuali correzioni : - -- a) forzatura a bisettrice se elementi in tangenza ( entro 6°) o dello stesso tipo - if nStartJoint ~= WIN_PART_JNT.ANGLED then - if EgtEV( nPrevOutlineId) * EgtSV( nOutlineId) > s_dAngledCos or EgtGetName( nOutlineId) == EgtGetName( nPrevOutlineId) then - nStartJoint = WIN_PART_JNT.ANGLED - end - end - -- b) forzatura a short se incontro con soglia - if EgtGetInfo( nPrevOutlineId, WIN_THRESHOLD, 'b') then - nStartJoint = WIN_PART_JNT.SHORT - end - - return nStartJoint -end - ---------------------------------------------------------------------- -local function CalcOutlineEndJoint( nOutlineId, nNextOutlineId, vJoints) - - local nEndJoint - - if EgtGetName( nOutlineId) == WIN_BOTTOM then - nEndJoint = CalcPartJoint( vJoints[2], true) - elseif EgtGetName( nOutlineId) == WIN_RIGHT then - nEndJoint = CalcPartJoint( vJoints[3], false) - elseif EgtGetName( nOutlineId) == WIN_TOP then - nEndJoint = CalcPartJoint( vJoints[4] or vJoints[3], true) -- ( vJoints[3] per gestire caso a triangolo) - -- correzione per caso a triangolo : se l'outline vicino è di tipo bottom, il corrente deve essere trattato come un pezzo verticale - if EgtGetName( nNextOutlineId) == WIN_BOTTOM then - nEndJoint = CalcPartJoint( vJoints[1], false) - end - elseif EgtGetName( nOutlineId) == WIN_LEFT then - nEndJoint = CalcPartJoint( vJoints[1], false) - end - - -- eventuali correzioni : - -- a) forzatura a bisettrice se elementi in tangenza ( entro 6°) o dello stesso tipo - if nEndJoint ~= WIN_PART_JNT.ANGLED then - if EgtEV( nOutlineId) * EgtSV( nNextOutlineId) > s_dAngledCos or EgtGetName( nOutlineId) == EgtGetName( nNextOutlineId) then - nEndJoint = WIN_PART_JNT.ANGLED - end - end - - -- b) forzatura a short se incontro con soglia - if EgtGetInfo( nNextOutlineId, WIN_THRESHOLD, 'b') then - nEndJoint = WIN_PART_JNT.SHORT - end - - return nEndJoint -end - ---------------------------------------------------------------------- -local function GetOutlineJoints( vOutlineIds, nAreaId) - - local vJoints = EgtGetInfo( nAreaId, WIN_JOINTS, 'vi') - for i = 1, #vOutlineIds do - local nPrevIdx = EgtIf( i == 1, #vOutlineIds, i - 1) - local nNextIdx = EgtIf( i == #vOutlineIds, 1, i + 1) - local nStartJoint = CalcOutlineStartJoint( vOutlineIds[i], vOutlineIds[nPrevIdx], vJoints) - local nEndJoint = CalcOutlineEndJoint( vOutlineIds[i], vOutlineIds[nNextIdx], vJoints) - EgtSetInfo( vOutlineIds[i], WIN_STARTJOINT, nStartJoint) - EgtSetInfo( vOutlineIds[i], WIN_ENDJOINT, nEndJoint) - end -end - ---------------------------------------------------------------------- --- 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.SPLIT or nParentType == WIN_AREATYPES.NULL do - nParentId = EgtGetParent( nParentId) - nParentType = EgtGetInfo( nParentId, WIN_AREATYPE, 'i') - end - sName = EgtGetInfo( nParentId, WIN_AREA_NAME) - - if nAreaType == WIN_AREATYPES.FILL then - sName = sName .. '_' .. WIN_FILL - EgtSetInfo( nAreaId, WIN_AREA_NAME, sName) - end - end - - return sName -end - ---------------------------------------------------------------------- -local function CreateOutlinePart( nOutlineId, sName, dDim, nBottomRail) - - -- se soglia ignoro - local bThreshold = EgtGetInfo( nOutlineId or GDB_ID.NULL, WIN_THRESHOLD, 'b') or false - if bThreshold then - return - end - - -- creo pezzo - local nPartId = EgtGroup( GDB_ID.ROOT) - - -- creo riferimenti tra pezzo e outline - EgtSetInfo( nPartId, WIN_REF_OUTLINE, nOutlineId) - if nBottomRail then - -- aggiorno i riferimenti del bottomrail - local vBottomRailParts = EgtGetInfo( nOutlineId, WIN_REF_BOTTOMRAIL_PART, 'vi') or {} - table.insert( vBottomRailParts, nPartId) - EgtSetInfo( nOutlineId, WIN_REF_BOTTOMRAIL_PART, vBottomRailParts) - EgtSetInfo( nPartId, WIN_PART_TYPE, WIN_PART_TYPES.BOTTOMRAIL) - EgtSetInfo( nPartId, WIN_BOTTOMRAIL, nBottomRail) - else - EgtSetInfo( nOutlineId, WIN_REF_PART, nPartId) - EgtSetInfo( nPartId, WIN_PART_TYPE, WIN_PART_TYPES.STD) - end - - -- imposto nome - local sOutlineName = EgtIf( nBottomRail, WIN_BOTTOMRAIL .. '_' .. tostring( nBottomRail), EgtGetName( nOutlineId)) - local sPartName = sName .. '_' .. sOutlineName - EgtSetName( nPartId, sPartName) - - -- imposto colore - if sOutlineName == WIN_BOTTOM or sOutlineName == WIN_TOP or nBottomRail 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 - - -- creo il profilo associato al pezzo con la dimensione opportuna - CreatePartProfile( nPartId, nOutlineId, dDim, nBottomRail) - - return nPartId -end - ---------------------------------------------------------------------- -local function CreatePartsFromOutlines( vOutlines, nAreaId, sName) - - local nBottomRail = EgtGetInfo( nAreaId, WIN_BOTTOMRAIL, 'i') - - -- calcolo le giunzioni - GetOutlineJoints( vOutlines, nAreaId) - - -- TODO segnalare errore se pezzi con giunzione angled non hanno le stesse dimensioni - local vPartsDim = EgtGetInfo( nAreaId, WIN_PART_DIM, 'vd') or {} - - -- creo i pezzi per ogni curva - for i = 1, #vOutlines do - EgtSetInfo( vOutlines[i], WIN_PART_DIM, vPartsDim[i]) - CreateOutlinePart( vOutlines[i], sName, vPartsDim[i]) - - if nBottomRail and EgtGetName( vOutlines[i]) == WIN_BOTTOM then - EgtSetInfo( vOutlines[i], WIN_BOTTOMRAIL, nBottomRail) - local vBottomRailDim = EgtGetInfo( nAreaId, WIN_BOTTOMRAIL .. WIN_PART_DIM, 'vd') or {} - EgtSetInfo( vOutlines[i], WIN_BOTTOMRAIL .. WIN_PART_DIM, vBottomRailDim) - for j = 1, nBottomRail do - CreateOutlinePart( vOutlines[i], sName, vBottomRailDim[j], j) - end - end - end -end - ---------------------------------------------------------------------- -local function CreateFillPartFromArea( nAreaId, sName) - - local nPartId = EgtGroup( GDB_ID.ROOT) - -- inserisco riferimento alla sua area - EgtSetInfo( nPartId, WIN_AREA, nAreaId) - - -- imposto nome del pezzo - EgtSetName( nPartId, sName) - EgtSetInfo( nPartId, WIN_PART_TYPE, WIN_PART_TYPES.FILL) - - -- imposto colore e tipologia - local nFillType = EgtGetInfo( nAreaId, WIN_FILLTYPE, 'i') - 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 - - return nPartId -end - - - ---------------------------------------------------------------------------------- ------------------------------ CALCOLO OUTLINE --------------------------------- ---------------------------------------------------------------------------------- -local function GetFramePrevNextOutline( vOutlines, nOutlineLayerId) - - for i = 2, #vOutlines - 1 do - EgtSetInfo( vOutlines[i], WIN_PREV_OUTLINES, { vOutlines[i-1]}) - EgtSetInfo( vOutlines[i], WIN_NEXT_OUTLINES, { vOutlines[i+1]}) - end - -- gestione particolare per primo e ultimo - EgtSetInfo( vOutlines[1], WIN_PREV_OUTLINES, { vOutlines[#vOutlines]}) - EgtSetInfo( vOutlines[1], WIN_NEXT_OUTLINES, { vOutlines[2]}) - EgtSetInfo( vOutlines[#vOutlines], WIN_PREV_OUTLINES, { vOutlines[#vOutlines - 1]}) - EgtSetInfo( vOutlines[#vOutlines], WIN_NEXT_OUTLINES, { vOutlines[1]}) -end - ------------------------------ NULL ------------------------------ --------------------------------------------------------------------- @@ -1647,13 +1488,23 @@ local function GetBorderRegions( nSplitId, nCompo, nAreaId) EgtAddCurveCompoCurve( nCrv2, nSplitId2) local _, dParE2 = EgtCurveDomain( nCrv2) EgtCurveCompoSetTempProp( nCrv2, dParE2 - 1, - nSplitId) - - -- se mixed split inverito le regioni finali vanno scambiate - local bInvert = EgtGetInfo( nSplitId, WIN_INV_SPLIT, 'b') or false - if bInvert then - return nCrv2, nCrv1 - else - return nCrv1, nCrv2 + + return nCrv1, nCrv2 +end + +--------------------------------------------------------------------- +local function AssignSplitName( nCrvId) + -- sceglie il nome della curva di split in base al suo orientamento + -- TODO forme non lineari o con orientamento diverso dagli assi principali + local vtS = EgtSV( nCrvId) + if AreSameVectorApprox( vtS, X_AX()) then + EgtSetName( nCrvId, WIN_BOTTOM) + elseif AreOppositeVectorApprox( vtS, X_AX()) then + EgtSetName( nCrvId, WIN_TOP) + elseif AreSameVectorApprox( vtS, Y_AX()) then + EgtSetName( nCrvId, WIN_RIGHT) + elseif AreOppositeVectorApprox( vtS, Y_AX()) then + EgtSetName( nCrvId, WIN_LEFT) end end @@ -1693,18 +1544,16 @@ local function CalculateNullOutline( nCompoOutline, vSplitIds, vChildAreas) for j = 0, nCnt - 1 do local nCrvId = nFirst + j EgtSetInfo( nCrvId, WIN_SOU_OUTLINE, vSouCrvs[j+1]) + + if vSouCrvs[j+1] < 0 then + AddInfo( abs( vSouCrvs[j+1]), WIN_CHILD_VIRTUAL_OUTLINE, -nCrvId) + else + AddInfo( vSouCrvs[j+1], WIN_CHILD_VIRTUAL_OUTLINE, nCrvId) + end + -- assengo il nome : se deriva da split lo scelgo in base all'orientamento, se deriva da outline lo copio if EgtGetName( abs( vSouCrvs[j+1])) == WIN_SPLIT then - local vtS = EgtSV( nCrvId) - if AreSameVectorApprox( vtS, X_AX()) then - EgtSetName( nCrvId, WIN_BOTTOM) - elseif AreOppositeVectorApprox( vtS, X_AX()) then - EgtSetName( nCrvId, WIN_TOP) - elseif AreSameVectorApprox( vtS, Y_AX()) then - EgtSetName( nCrvId, WIN_RIGHT) - elseif AreOppositeVectorApprox( vtS, Y_AX()) then - EgtSetName( nCrvId, WIN_LEFT) - end + AssignSplitName( nCrvId) else EgtSetName( nCrvId, EgtGetName( abs( vSouCrvs[j+1]))) end @@ -1728,211 +1577,6 @@ end ------------------------------ SPLIT ------------------------------ ---------------------------------------------------------------------- --- funzione che corregge i profili del telaio individuati di tipo mixed dallo split -local function AdjustMixedFrames( vOutlines) - -- pezzi consecutivi coinvolti da cambio profilo devono avere : profilo di tipo mixed, stesse dimensioni, separazione con giunzione a bisettrice - if vOutlines == 1 then return end - - -- fisso come dimensione quella del primo pezzo - local dDimRef = EgtGetInfo( vOutlines[1], WIN_PART_DIM, 'd') - - for i = 1, #vOutlines do - local bMixed = EgtGetInfo( vOutlines[i], WIN_PRF_CHANGE, 'b') or false - local dDim = EgtGetInfo( vOutlines[i], WIN_PART_DIM, 'd') - -- se non era stato individuato correttamente come profilo mixed oppure la dimensione va modificata ricalcolo il profilo - if not bMixed or abs( dDim - dDimRef) > GEO.EPS_SMALL then - if not bMixed then - EgtSetInfo( vOutlines[i], WIN_PRF_CHANGE, true) - local sRealProfile = EgtIf( EgtGetName( vOutlines[i]) == WIN_BOTTOM, WIN_MIXED_BOTTOM, WIN_MIXED_TOP) - EgtSetInfo( vOutlines[i], WIN_PROFILETYPE, sRealProfile) - end - if abs( dDim - dDimRef) > GEO.EPS_SMALL then - EgtSetInfo( vOutlines[i], WIN_PART_DIM, dDimRef) - end - local nPartId = EgtGetInfo( vOutlines[i], WIN_REF_PART, 'i') - CreatePartProfile( nPartId, vOutlines[i], dDimRef) - end - - -- imposto giunzione - if i ~= 1 then - EgtSetInfo( vOutlines[i], WIN_STARTJOINT, WIN_PART_JNT.ANGLED) - end - if i ~= #vOutlines then - EgtSetInfo( vOutlines[i], WIN_ENDJOINT, WIN_PART_JNT.ANGLED) - end - end -end - ---------------------------------------------------------------------- --- funzione che verifica gli outlines prev/next per lo split controllando l'interferenza tra i profili -local function TestSplitTrimOutlines( nOutlineId, nTrimOutline, tabOutlines, nMainProfile, b3Profile, nGrpTmp, bPrevOrNext) - - local vTrimOutlines = {} - - -- 1) recupero le curve da testare : - -- a) curva individuata dall'intersezione dello split con l'outline - local vTestOutlines = { tabOutlines[nTrimOutline]} - - -- b) curve vicine a quella individuata dall'intersezione che interferiscono con lo split ( guardando interferenza grossolana dei pezzi) - -- recupero le curve di bordo del pezzo di split - local nOutlineCopyId = EgtCopyGlob( nOutlineId, nGrpTmp) - if bPrevOrNext then - EgtTrimCurveEndAtParam( nOutlineCopyId, 0.5) - else - EgtTrimCurveStartAtParam( nOutlineCopyId, 0.5) - end - local nOutId = EgtOffsetCurveAdv( nOutlineCopyId, b3Profile:getMax():getX()) - local nInId = EgtOffsetCurveAdv( nOutlineCopyId, b3Profile:getMin():getX()) - - -- curve precedenti - local nTestCurve = EgtGetPrev( nTrimOutline) or EgtGetLastInGroup( EgtGetParent( nTrimOutline)) - local bInters = true - while bInters and nTestCurve ~= nTrimOutline do - - local nRefOutline = abs( tabOutlines[nTestCurve]) - local nProfileId = GetOutlineProfileId( nRefOutline, true) - local b3Profile = GetProfileLocalBox( nProfileId) - local nRefSurf = EgtSurfFrFatCurve( nGrpTmp, nRefOutline, b3Profile:getMin():getX(), false) - - local nClassOut = EgtCurveWithRegionClassify( nOutId, nRefSurf) - if nClassOut == GDB_CRC.OUT then - local nClassIn = EgtCurveWithRegionClassify( nInId, nRefSurf) - -- se non c'è interferenza interrompo la ricerca - if nClassIn == GDB_CRC.OUT then - bInters = false - end - end - -- se interferenza lo aggiungo tra le curve da controllare - if bInters then - table.insert( vTestOutlines, 1, tabOutlines[nTestCurve]) - nTestCurve = EgtGetPrev( nTestCurve) or EgtGetLastInGroup( EgtGetParent( nTestCurve)) - end - end - - -- curve successive - nTestCurve = EgtGetNext( nTrimOutline) or EgtGetFirstInGroup( EgtGetParent( nTrimOutline)) - bInters = true - while bInters and nTestCurve ~= nTrimOutline do - - local nRefOutline = abs( tabOutlines[nTestCurve]) - local nProfileId = GetOutlineProfileId( nRefOutline, true) - local b3Profile = GetProfileLocalBox( nProfileId) - local nRefSurf = EgtSurfFrFatCurve( nGrpTmp, nRefOutline, b3Profile:getMin():getX(), false) - - local nClassOut = EgtCurveWithRegionClassify( nOutId, nRefSurf) - if nClassOut == GDB_CRC.OUT then - local nClassIn = EgtCurveWithRegionClassify( nInId, nRefSurf) - if nClassIn == GDB_CRC.OUT then - bInters = false - end - end - if bInters then - table.insert( vTestOutlines, tabOutlines[nTestCurve]) - nTestCurve = EgtGetNext( nTestCurve) or EgtGetFirstInGroup( EgtGetParent( nTestCurve)) - end - end - - if #vTestOutlines == 1 then - return vTestOutlines - end - - -- 2) testo le curve controllando intersezione tra le superfici dei pezzi - -- creo il solido principale - local dExtraLen = b3Profile:getDimX() - local nMainSurf = CreateProfileSurf( nOutlineId, nMainProfile, WIN_SECTION, 4 * dExtraLen, nGrpTmp) - EgtCutSurfTmPlane( nMainSurf, EgtMP( nOutlineId), EgtIf( bPrevOrNext, 1, -1) * EgtSV( nOutlineId)) - - -- recupero profili per i conti - local vProfiles = {} - local vsCtrIn = {} - for i = 1, #vTestOutlines do - vProfiles[i] = GetOutlineProfileId( abs( vTestOutlines[i]), true) - vsCtrIn[i] = GetProfileCtrIn( vTestOutlines[i], nOutlineId, vProfiles[i]) - end - - -- testo le curve - for i = 1, #vTestOutlines do - -- creo la superficie di test limitandola con le sue vicine - local nTestSurf = CreateProfileSurf( abs( vTestOutlines[i]), vProfiles[i], vsCtrIn[i], 4 * dExtraLen, nGrpTmp) - if i > 1 then - if AreSameVectorApprox( EgtEV( abs( vTestOutlines[i-1])), EgtSV( abs( vTestOutlines[i]))) then - EgtCutSurfTmPlane( nTestSurf, EgtEP( abs( vTestOutlines[i-1])), - EgtEV( abs( vTestOutlines[i-1])), false) - else - local nTrimSurf = CreateProfileSurf( abs( vTestOutlines[i-1]), vProfiles[i-1], WIN_OFST .. vsCtrIn[i-1], 4 * dExtraLen, nGrpTmp) - EgtSurfTmCut( nTestSurf, nTrimSurf, true, false) - end - end - if i < #vTestOutlines then - if AreSameVectorApprox( EgtEV( abs( vTestOutlines[i])), EgtSV( abs( vTestOutlines[i+1]))) then - EgtCutSurfTmPlane( nTestSurf, EgtEP( abs( vTestOutlines[i])), EgtEV( abs( vTestOutlines[i])), false) - else - local nTrimSurf = CreateProfileSurf( abs( vTestOutlines[i+1]), vProfiles[i+1], WIN_OFST .. vsCtrIn[i+1], 4 * dExtraLen, nGrpTmp) - EgtSurfTmCut( nTestSurf, nTrimSurf, true, false) - end - end - -- calcolo intersezione con il solido : se c'è intersezione è una vera curva di trim, altrimenti non va considerata - local nId, _, nCrvCnt = EgtSurfTmSurfTmInters( nMainSurf, nTestSurf, nGrpTmp) - if nId and nCrvCnt > 0 then - table.insert( vTrimOutlines, vTestOutlines[i]) - end - end - - return vTrimOutlines -end - ---------------------------------------------------------------------- --- funzione che recupera gli outline precedenti e successivi degli split -local function GetSplitsPrevNextOutline( vSplitIds, vOutlineIds) - - local nGrpTmp = EgtGroup( GDB_ID.ROOT) - - -- ad ogni outline dell'area di split associo l'outline non virtuale corrispondente ( per rendere più solidi i conti successivi) - local tabOutlines = {} - for i = 1, #vOutlineIds do - tabOutlines[vOutlineIds[i]] = GetNonVirtualOutline( vOutlineIds[i]) - end - - -- per ogni split individuo i prev e i next - for i = 1, #vSplitIds do - - local nMainProfile = GetOutlineProfileId( vSplitIds[i]) - local b3Profile = GetProfileLocalBox( nMainProfile) - - -- controllo la validità delle curve prev/next trovate dall'intersezione degli outlines e la validità di eventuali curve vicine verificando l'interferenza tra i profili - local nPrevOutlineId = EgtGetInfo( vSplitIds[i], WIN_SPLIT_STARTINTERS, 'i') - local vPrevOutlineIds = TestSplitTrimOutlines( vSplitIds[i], nPrevOutlineId, tabOutlines, nMainProfile, b3Profile, nGrpTmp, true) - EgtSetInfo( vSplitIds[i], WIN_PREV_OUTLINES, vPrevOutlineIds) - -- setto tutte le giunzioni a short - local vStartJoints = {} - for i = 1, #vPrevOutlineIds do - vStartJoints[i] = WIN_PART_JNT.SHORT - end - EgtSetInfo( vSplitIds[i], WIN_STARTJOINT, vStartJoints) - - - local nNextOutlineId = EgtGetInfo( vSplitIds[i], WIN_SPLIT_ENDINTERS, 'i') - local vNextOutlineIds = TestSplitTrimOutlines( vSplitIds[i], nNextOutlineId, tabOutlines, nMainProfile, b3Profile, nGrpTmp, false) - EgtSetInfo( vSplitIds[i], WIN_NEXT_OUTLINES, vNextOutlineIds) - local vEndJoints = {} - for i = 1, #vNextOutlineIds do - vEndJoints[i] = WIN_PART_JNT.SHORT - end - EgtSetInfo( vSplitIds[i], WIN_ENDJOINT, vEndJoints) - - - -- se split di tipo mixed i pezzi che incontra deve essere di tipo mixed ( anche se avevo trovato una sola tipologia di figli), devono essere separati da giunzione - -- a bisettrice e devono avere le stesse dimensioni. Impongo queste condizioni eventualmente ricalcolando i profili - local bChangeProfile = EgtGetInfo( vSplitIds[i], WIN_PRF_CHANGE, 'b') or false - if bChangeProfile then - AdjustMixedFrames( vPrevOutlineIds) - AdjustMixedFrames( vNextOutlineIds) - end - end - - EgtErase( nGrpTmp) -end - --------------------------------------------------------------------- -- funzione che adatta la curva di split al bordo local function TrimSplitWithOutline( nSplitId, nOutlineCompo, vOutlineIds) @@ -2032,31 +1676,36 @@ local function CalcStandardSplitContributions( nSplitDir, nOutlineLayerId, vSpli -- recupero il pezzo contro cui poggia local nSouId = GetNonVirtualOutline( vCrvs[i]) -- recupero il profilo ( eventualmente di bottomrail) - local nProfileId = GetOutlineProfileId( abs( nSouId), true) - local dRailOffs = EgtGetInfo( nProfileId, WIN_RAILOFFS, 'd') or 0 + local nProfileId = GetOutlineTheoricProfileId( abs( nSouId), true) + local dRealDim = EgtGetInfo( abs( nSouId), WIN_PART_DIM, 'd') + -- se bottomrail calcolo scostamento + local dRailOffs = 0 + if EgtGetName( nProfileId) == WIN_FILL_RAIL then + local nBottomRail = EgtGetInfo( abs( nSouId), WIN_BOTTOMRAIL, 'i') + dRailOffs = CalcRailOffset( abs( nSouId), nProfileId, nBottomRail) + local vBottomRailDims = EgtGetInfo( abs( nSouId), WIN_BOTTOMRAIL .. WIN_PART_DIM, 'vd') + dRealDim = vBottomRailDims[#vBottomRailDims] + end local b3Profile = GetProfileLocalBox( nProfileId) -- calcolo il contributo if nSouId < 0 then - vDim[i] = b3Profile:getMax():getX() + dRailOffs + vDim[i] = b3Profile:getMax():getX() else - vDim[i] = abs( b3Profile:getMin():getX()) + dRailOffs + vDim[i] = abs( b3Profile:getMin():getX()) end + vDim[i] = vDim[i] * dRealDim / b3Profile:getDimX() + dRailOffs end tPartsDim[1] = { 0, vDim[1]} -- 2) contributo degli split for i = 1, #vSplitIds do - local nProfileId = GetOutlineProfileId( vSplitIds[i]) + local nProfileId = GetOutlineTheoricProfileId( vSplitIds[i]) local b3Profile = GetProfileLocalBox( nProfileId) + local dRealDim = EgtGetInfo( vSplitIds[i], WIN_PART_DIM, 'd') local vCurrSplitDim = {} - vCurrSplitDim[1] = abs( b3Profile:getMin():getX()) - vCurrSplitDim[2] = b3Profile:getMax():getX() - -- se cambio profilo invertito devo scambiare le dimensioni del profilo - local bInvert = EgtGetInfo( vSplitIds[i], WIN_INV_SPLIT, 'b') or false - if bInvert then - vCurrSplitDim[1], vCurrSplitDim[2] = vCurrSplitDim[2], vCurrSplitDim[1] - end + vCurrSplitDim[1] = abs( b3Profile:getMin():getX()) * dRealDim / b3Profile:getDimX() + vCurrSplitDim[2] = b3Profile:getMax():getX() * dRealDim / b3Profile:getDimX() table.insert( tPartsDim, vCurrSplitDim) end @@ -2066,7 +1715,7 @@ local function CalcStandardSplitContributions( nSplitDir, nOutlineLayerId, vSpli end --------------------------------------------------------------------- -local function CalcFrenchSplitContributions( nSplitDir, nOutlineLayerId, nBaseOutlineLayerId, vSplitIds, bDaylight) +local function CalcFrenchSplitContributions( nOutlineLayerId, nBaseOutlineLayerId, vSplitIds, bDaylight) -- nel caso di french split ( gruppo di ante) la dimensione può essere di tipo luce o esterno anta local tPartsDim = {} @@ -2075,60 +1724,42 @@ local function CalcFrenchSplitContributions( nSplitDir, nOutlineLayerId, nBaseOu -- 1) contributo dei pezzi che delimitano la regione degli split local vDim = {} - local vCrvs = GetSplitAreaBorderCurves( nSplitDir, nOutlineLayerId) - local vBaseCrvs = GetSplitAreaBorderCurves( nSplitDir, nBaseOutlineLayerId) + local vCrvs = GetSplitAreaBorderCurves( WIN_SPLITORIENTATION.VERTICAL, nOutlineLayerId) + local vBaseCrvs = GetSplitAreaBorderCurves( WIN_SPLITORIENTATION.VERTICAL, nBaseOutlineLayerId) for i = 1, 2 do - - -- recupero l'outline del pezzo telaio/split su cui poggia e il base outline dell'anta che poggerà - local nSouId = GetNonVirtualOutline( vCrvs[i]) - local nSashBaseOutline = EgtGetInfo( vBaseCrvs[i], WIN_CHILD, 'i') -- a) contributo del telaio - local nProfileId = GetOutlineProfileId( abs( nSouId)) + local nSouId = GetNonVirtualOutline( vCrvs[i]) + local nProfileId = GetOutlineTheoricProfileId( abs( nSouId)) local b3Profile = GetProfileLocalBox( nProfileId) if nSouId < 0 then vDim[i] = abs( b3Profile:getMax():getX()) else vDim[i] = abs( b3Profile:getMin():getX()) end - -- considero l'overlap in base all'anta che vi poggerà - local sKey = EgtIf( EgtGetName( nSashBaseOutline) == WIN_BOTTOM, WIN_SASH_BOTTOM_OVERLAP, WIN_SASH_TOP_OVERLAP) - local dSashOverlap = EgtGetInfo( nProfileId, sKey, 'd') - vDim[i] = vDim[i] - dSashOverlap + local dRealDim = EgtGetInfo( abs( nSouId), WIN_PART_DIM, 'd') + local dSashOverlap = EgtGetInfo( nProfileId, WIN_SASH_TOP_OVERLAP, 'd') + vDim[i] = vDim[i] * dRealDim / b3Profile:getDimX() - dSashOverlap -- b) se luce devo considerare anche il contributo dell'anta if bDaylight then - -- anta non è ancora calcolata quindi devo usare profilo e dimensione teorica ricavandole dal base outline - local sSashName = EgtGetName( nSashBaseOutline) - local sSashProfile = EgtIf( sSashName == WIN_BOTTOM, WIN_FRAME_BOTTOM, WIN_FRAME_TOP) - local nSashType = EgtGetInfo( EgtGetParent( EgtGetParent( nSashBaseOutline)), WIN_SASHTYPE, 'i') - if nSashType == WIN_SASHTYPES.SLIDE_MOVABLE then - if sSashName == WIN_BOTTOM then - sSashProfile = WIN_SLIDE_MOVABLE_BOTTOM - elseif sSashName == WIN_TOP then - sSashProfile = WIN_SLIDE_MOVABLE_TOP - else - sSashProfile = WIN_SLIDE_MOVABLE_SIDE - end - elseif nSashType == WIN_SASHTYPES.SLIDE_FIXED then - if sSashName == WIN_BOTTOM then - sSashProfile = WIN_SLIDE_FIXED_BOTTOM - elseif sSashName == WIN_TOP then - sSashProfile = WIN_SLIDE_FIXED_TOP - else - sSashProfile = WIN_SLIDE_FIXED_SIDE - end - elseif nSashType == WIN_SASHTYPES.SLIDE_MOVABLE_BACK then - if sSashName == WIN_BOTTOM then - sSashProfile = WIN_SLIDE_MOVABLEBACK_BOTTOM - elseif sSashName == WIN_TOP then - sSashProfile = WIN_SLIDE_MOVABLEBACK_TOP - else - sSashProfile = WIN_SLIDE_MOVABLEBACK_SIDE + -- anta non è ancora calcolata quindi devo calcolare la sua dimensione ricavandola dal base outline + local nSashBaseOutline = EgtGetInfo( vBaseCrvs[i], WIN_CHILD, 'i') + local vDimensions = EgtGetInfo( EgtGetParent( EgtGetParent( nSashBaseOutline)), WIN_PART_DIM, 'vd') + local dDim + if not vDimensions then + local nFrameId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_AREA .. '*') + local bSlide = EgtGetInfo( nFrameId, WIN_SLIDE_WINDOW, 'b') + local sProfileName = WIN_FRAME_TOP + if bSlide then + sProfileName = WIN_SLIDE_MOVABLE_SIDE -- la dimensione standard dovrebbe essere la stessa indipendentemente dalla tipologia di anta slide end + local nProfileId = EgtGetFirstNameInGroup( nSashProfileGrp, sProfileName) + dDim = EgtGetInfo( nProfileId, WIN_DIM_STD, 'd') + else + local nIdx = EgtIf( i == 1, #vDimensions, 2) + dDim = vDimensions[nIdx] end - local nProfileId = EgtGetFirstNameInGroup( nSashProfileGrp, sSashProfile) - local dDim = EgtGetInfo( nSashBaseOutline, WIN_PART_DIM, 'd') or EgtGetInfo( nProfileId, WIN_DIM_STD, 'd') vDim[i] = vDim[i] + dDim end end @@ -2139,12 +1770,11 @@ local function CalcFrenchSplitContributions( nSplitDir, nOutlineLayerId, nBaseOu for i = 1, #vSplitIds do local vCurrSplitDim = { 0, 0} - -- ricavo i base outlines delle ante che poggeranno sullo split + -- ricavo dai base outlines le ante che poggeranno sullo split local vSashChildren = EgtGetInfo( vSplitIds[i], WIN_CHILD, 'vi') - local vSashTypes = {} - vSashTypes[1] = EgtGetInfo( EgtGetParent( EgtGetParent( vSashChildren[1])), WIN_SASHTYPE, 'i') - vSashTypes[2] = EgtGetInfo( EgtGetParent( EgtGetParent( vSashChildren[2])), WIN_SASHTYPE, 'i') + vSashTypes[1] = EgtGetInfo( EgtGetParent( EgtGetParent( abs( vSashChildren[1]))), WIN_SASHTYPE, 'i') + vSashTypes[2] = EgtGetInfo( EgtGetParent( EgtGetParent( abs( vSashChildren[2]))), WIN_SASHTYPE, 'i') for j = 1, 2 do -- recupero il profilo teorico local sSashProfile @@ -2183,7 +1813,15 @@ local function CalcFrenchSplitContributions( nSplitDir, nOutlineLayerId, nBaseOu local nProfileId = EgtGetFirstNameInGroup( nSashProfileGrp, sSashProfile) local b3Profile = GetProfileLocalBox( nProfileId) if bDaylight then - local dDim = EgtGetInfo( vSashChildren[j], WIN_PART_DIM, 'd') or EgtGetInfo( nProfileId, WIN_DIM_STD, 'd') + local dDim + local vDimensions = EgtGetInfo( EgtGetParent( EgtGetParent( abs( vSashChildren[j]))), WIN_PART_DIM, 'vd') + if not vDimensions then + dDim = EgtGetInfo( nProfileId, WIN_DIM_STD, 'd') + else + -- il primo figlio è quello di sx, il secondo figlio è quello di dx + local nIdx = EgtIf( j == 1, 2, #vDimensions) + dDim = vDimensions[nIdx] + end vCurrSplitDim[j] = dDim - b3Profile:getMax():getX() else vCurrSplitDim[j] = - b3Profile:getMax():getX() @@ -2210,7 +1848,7 @@ local function CalcSplitPositionOffsets( nAreaId, nAreaInfoId, vSplitIds, nSplit local tPartsDim if nSplitType == WIN_SPLITTYPES.FRENCH then local bDaylight = EgtGetInfo( nAreaInfoId, WIN_DAYLIGHT_MEASURE, 'b') or false - tPartsDim = CalcFrenchSplitContributions( nSplitDir, nOutlineLayerId, nBaseOutlineLayerId, vSplitIds, bDaylight) + tPartsDim = CalcFrenchSplitContributions( nOutlineLayerId, nBaseOutlineLayerId, vSplitIds, bDaylight) else tPartsDim = CalcStandardSplitContributions( nSplitDir, nOutlineLayerId, vSplitIds) end @@ -2238,10 +1876,6 @@ local function CalcSplitPositionOffsets( nAreaId, nAreaInfoId, vSplitIds, nSplit local dNewPos = dPrevPos + tPartsDim[i][2] + vSplitDimensions[i] + tPartsDim[i+1][1] local dOldPos = EgtGetInfo( vSplitIds[i], WIN_SPLIT_POSITION, 'd') vOffs[i] = dNewPos - dOldPos - local bInvert = EgtGetInfo( vSplitIds[i], WIN_INV_SPLIT, 'b') or false - if bInvert then - vOffs[i] = - vOffs[i] - end dPrevPos = dNewPos end @@ -2249,7 +1883,7 @@ local function CalcSplitPositionOffsets( nAreaId, nAreaInfoId, vSplitIds, nSplit end --------------------------------------------------------------------- -local function CalculateSplitOutline( nAreaId, vSplitIds, sName) +local function CalculateSplitOutline( nAreaId, vSplitIds) -- recupero l'outline e creo composita del bordo local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE) @@ -2261,15 +1895,16 @@ local function CalculateSplitOutline( nAreaId, vSplitIds, sName) local nSplitType = EgtGetInfo( vSplitIds[1], WIN_SPLITTYPE, 'i') - -- creo i pezzi associati ( per avere i profili corretti da usare per i conti del posizionamento) + -- assegno le dimensioni if nSplitType ~= WIN_SPLITTYPES.FRENCH then local vSplitDim = EgtGetInfo( nAreaId, WIN_PART_DIM, 'vd') or {} for i = 1, #vSplitIds do - CreateOutlinePart( vSplitIds[i], sName, vSplitDim[i]) + if not vSplitDim[i] then + -- se dimensione non è impostata recupero quella standard del profilo + local nProfileId = GetOutlineTheoricProfileId( vSplitIds[i]) + vSplitDim[i] = EgtGetInfo( nProfileId, WIN_DIM_STD, 'd') + end EgtSetInfo( vSplitIds[i], WIN_PART_DIM, vSplitDim[i]) - -- imposto le giunzioni - EgtSetInfo( vSplitIds[i], WIN_STARTJOINT, WIN_PART_JNT.SHORT) - EgtSetInfo( vSplitIds[i], WIN_ENDJOINT, WIN_PART_JNT.SHORT) end end @@ -2280,11 +1915,8 @@ local function CalculateSplitOutline( nAreaId, vSplitIds, sName) TrimSplitWithOutline( vSplitIds[i], nOutlineCompo, vOutlineIds) end + -- creo l'outline delle aree figlie di tipo null if nSplitType ~= WIN_SPLITTYPES.FRENCH then - -- ricavo prev e next - GetSplitsPrevNextOutline( vSplitIds, vOutlineIds) - - -- creo l'outline delle aree figlie di tipo null local vChildAreas = EgtGetNameInGroup( nAreaId, WIN_AREA .. '*') CalculateNullOutline( nOutlineCompo, vSplitIds, vChildAreas) end @@ -2293,7 +1925,7 @@ local function CalculateSplitOutline( nAreaId, vSplitIds, sName) end --------------------------------------------------------------------- -local function CalculateGridSplitOutline( nAreaId, vSplitIds, sName) +local function CalculateGridSplitOutline( nAreaId, vSplitIds) local vAreas = EgtGetNameInGroup( nAreaId, WIN_AREA .. '*') local vVirtualAreas = EgtGetNameInGroup( nAreaId, WIN_VIRTUAL_AREA) @@ -2319,17 +1951,18 @@ local function CalculateGridSplitOutline( nAreaId, vSplitIds, sName) end end - -- creo i pezzi + -- assegno le dimensioni local vDimMain = EgtGetInfo( nAreaId, WIN_PART_DIM, 'vd') or {} local vDimOther = EgtGetInfo( vVirtualAreas[1], WIN_PART_DIM, 'vd') or {} for i = 0, #tabGrid do for j = 1, #tabGrid[i] do local dDim = EgtIf( i == 0, vDimMain[j], vDimOther[j]) - CreateOutlinePart( tabGrid[i][j], sName, dDim) + if not dDim then + -- se dimensione non è impostata recupero quella standard del profilo + local nProfileId = GetOutlineTheoricProfileId( tabGrid[i][j]) + dDim = EgtGetInfo( nProfileId, WIN_DIM_STD, 'd') + end EgtSetInfo( tabGrid[i][j], WIN_PART_DIM, dDim) - -- imposto le giunzioni - EgtSetInfo( tabGrid[i][j], WIN_STARTJOINT, WIN_PART_JNT.SHORT) - EgtSetInfo( tabGrid[i][j], WIN_ENDJOINT, WIN_PART_JNT.SHORT) end end @@ -2352,16 +1985,12 @@ local function CalculateGridSplitOutline( nAreaId, vSplitIds, sName) for j = 1, #tabGrid[i] do EgtOffsetCurve( tabGrid[i][j], vOffs[j]) if not TrimSplitWithOutline( tabGrid[i][j], nOutlineCompo, vOutlineIds) then - -- se split fuoriesce dalla sottoarea lo elimino insieme al pezzo associato - local nPartId = EgtGetInfo( tabGrid[i][j], WIN_REF_PART, 'i') - EgtErase( nPartId) + -- se split fuoriesce dalla sottoarea lo elimino EgtErase( tabGrid[i][j]) tabGrid[i][j] = nil end end - -- ricavo prev e next - GetSplitsPrevNextOutline( tabGrid[i], vOutlineIds) -- creo gli outline delle aree figlie ( i.e. aree virtuali per split principale, sottoaree di ordine i-esimo per split secondari di ordine i-esimo) CalculateNullOutline( nOutlineCompo, tabGrid[i], EgtIf( i == 0, vVirtualAreas, tabAreas[i])) @@ -2401,10 +2030,17 @@ local function DrawOpening( nAreaId) for i = 1, #vOutlines do local nCrv = EgtCopyGlob( vOutlines[i], nOpeningLayId) table.insert( vCrvs, nCrv) - local nProfileId = GetOutlineProfileId( vCrvs[i], true) - local b3FrameProfile = GetProfileLocalBox( nProfileId) - local dDeltaOffs = EgtGetInfo( nProfileId, WIN_RAILOFFS , 'd') or 0 - local dOffs = b3FrameProfile:getMin():getX() - dDeltaOffs + local nProfileId = GetOutlineTheoricProfileId( vOutlines[i], true) + local dRealDim = EgtGetInfo( vOutlines[i], WIN_PART_DIM, 'd') + local dRailOffs = 0 + if EgtGetName( nProfileId) == WIN_FILL_RAIL then + local nBottomRail = EgtGetInfo( vOutlines[i], WIN_BOTTOMRAIL, 'i') + dRailOffs = CalcRailOffset( vOutlines[i], nProfileId, nBottomRail) + local vBottomRailDims = EgtGetInfo( vOutlines[i], WIN_BOTTOMRAIL .. WIN_PART_DIM, 'vd') + dRealDim = vBottomRailDims[#vBottomRailDims] + end + local b3Profile = GetProfileLocalBox( nProfileId) + local dOffs = b3Profile:getMin():getX() * dRealDim / b3Profile:getDimX() - dRailOffs EgtOffsetCurve( nCrv, dOffs) end vCrvs = TrimOrderedCurves( vCrvs, true) @@ -2552,13 +2188,14 @@ local function CalculateSashOutline( nAreaId, nAreaLayerId, nOutlineLayerId) local vFrameOffs = {} -- calcolo gli offset da applicare ad ogni curva for i = 1, #vFrameOutlines do - -- recupero il suo profilo per calcolare l'offset ( se pezzo contro vetro fisso non serve, sarà tagliato da uno split) - local nProfileId = GetOutlineProfileId( vFrameOutlines[i]) + -- recupero il suo profilo per calcolare l'offset + local nProfileId = GetOutlineTheoricProfileId( vFrameOutlines[i]) local sKey = EgtIf( EgtGetName( vFrameOutlines[i]) == WIN_BOTTOM, WIN_SASH_BOTTOM_OVERLAP, WIN_SASH_TOP_OVERLAP) local dOverlap = EgtGetInfo( nProfileId, sKey, 'd') if dOverlap then local b3Profile = GetProfileLocalBox( nProfileId) - vFrameOffs[i] = b3Profile:getMin():getX() + dOverlap + local dRealDim = EgtGetInfo( vFrameOutlines[i], WIN_PART_DIM, 'd') + vFrameOffs[i] = b3Profile:getMin():getX() * dRealDim / b3Profile:getDimX() + dOverlap end end -- costruisco l'outline @@ -2597,17 +2234,53 @@ local function CalculateSashOutline( nAreaId, nAreaLayerId, nOutlineLayerId) -- 2) taglio con eventuali split - local vSplitAreas = {} - local nParentArea = EgtGetParent( nAreaId) - while nParentArea ~= nFrameArea do - local nAreaType = EgtGetInfo( nParentArea, WIN_AREATYPE, 'i') - if nAreaType == WIN_AREATYPES.SPLIT then - table.insert( vSplitAreas, nParentArea) + local vSplitIds = {} + local tabSplitCrvName = {} -- associa allo split il nome della curva di outline che da esso deriva + local nParentId = EgtGetParent( nAreaId) + while nParentId ~= nFrameArea do + local nParentType = EgtGetInfo( nParentId, WIN_AREATYPE, 'i') + if nParentType == WIN_AREATYPES.NULL then + local nNullOutlineLay = EgtGetFirstNameInGroup( nParentId, WIN_OUTLINE) + local vNullOutlines = EgtGetAllInGroup( nNullOutlineLay) + for i = 1, #vNullOutlines do + local nSou = EgtGetInfo( vNullOutlines[i], WIN_SOU_OUTLINE, 'i') + if EgtGetName( EgtGetParent( EgtGetParent( abs( nSou)))) == WIN_VIRTUAL_AREA then + nSou = EgtGetInfo( abs( nSou), WIN_SOU_OUTLINE, 'i') + end + if EgtGetName( abs( nSou)) == WIN_SPLIT then + table.insert( vSplitIds, nSou) + tabSplitCrvName[abs( nSou)] = EgtGetName( vNullOutlines[i]) + end + end + elseif nParentType == WIN_AREATYPES.SPLIT and EgtGetInfo( nParentId, WIN_SPLITTYPE, 'i') == WIN_SPLITTYPES.FRENCH then + -- recupero l'indice dell'anta french dal suo nome + local sAreaName = EgtGetName( nAreaId) + local sAreaIdx = string.sub( sAreaName, string.len( WIN_AREA) + 1, string.len( WIN_AREA) + 1) + local nAreaIdx = tonumber( sAreaIdx) + local nSplitLayerId = EgtGetFirstNameInGroup( nParentId, WIN_SPLIT) + local vFrenchSplits = EgtGetAllInGroup( nSplitLayerId) + -- in base al numero di anta french recupero i french split che la definiscono con il corretto orientamento + if nAreaIdx > 1 then + table.insert( vSplitIds, - vFrenchSplits[nAreaIdx - 1]) + end + if nAreaIdx < #vFrenchSplits + 1 then + table.insert( vSplitIds, vFrenchSplits[nAreaIdx]) + end end - nParentArea = EgtGetParent( nParentArea) + nParentId = EgtGetParent( nParentId) end + + if #vSplitIds == 0 then + -- salvo associazioni sou/child sugli outlines + for i = 1, #vCrvs do + local nSouOutlineId = EgtGetInfo( vCrvs[i], WIN_SOU_OUTLINE, 'i') + AddInfo( nSouOutlineId, WIN_CHILD_OUTLINE, vCrvs[i]) + end + else - if #vSplitAreas > 0 then + -- li ordino per id crescente in modo da effettuare i tagli nell'ordine corretto + table.sort( vSplitIds, function ( a, b) return abs( a) < abs( b) end) + -- creo bordo complessivo dell'outline, salvando le info di SouOutline come temp prop della curva per non perderle local vSouOutlines = {} for i = 1, #vCrvs do @@ -2618,68 +2291,44 @@ local function CalculateSashOutline( nAreaId, nAreaLayerId, nOutlineLayerId) EgtCurveCompoSetTempProp( nCompo, i, vSouOutlines[i+1]) end - -- recupero gli split coinvolti dalle ante - local vBaseOutlines = EgtGetAllInGroup( nAreaLayerId) - local tabSplits = {} - for i = 1, #vBaseOutlines do - -- verifico se deriva da split - local nSouId = EgtGetInfo( vBaseOutlines[i], WIN_SOU, 'i') - while nSouId and EgtGetName( nSouId) ~= WIN_SPLIT do - nSouId = EgtGetInfo( nSouId, WIN_SOU, 'i') - end - if nSouId then - tabSplits[nSouId] = vBaseOutlines[i] - end - end - -- taglio con split - for i = #vSplitAreas, 1, -1 do - local nSplitBaseOutline = EgtGetFirstNameInGroup( vSplitAreas[i], WIN_BASESPLIT) - local vSplitBaseOutlines = EgtGetAllInGroup( nSplitBaseOutline) - for j = 1, #vSplitBaseOutlines do - -- verifico sia uno split coinvolto nell'area sash considerata - if tabSplits[vSplitBaseOutlines[j]] then - - -- a) creo la curva di outline corrispondente allo split - local nSplitOutline = EgtGetInfo( vSplitBaseOutlines[j], WIN_COPY, 'i') - local nOutlineId = EgtCopy( nSplitOutline, nOutlineLayerId) - -- rimuovo info che non voglio trasferire - EgtRemoveInfo( nOutlineId, WIN_PRF_CHANGE) - EgtRemoveInfo( nOutlineId, WIN_INV_SPLIT) - -- verifico orientamento - local nRefCrv = EgtGetPrev( tabSplits[vSplitBaseOutlines[j]]) or EgtGetNext( tabSplits[vSplitBaseOutlines[j]]) - local _, _, nSide = EgtPointCurveDistSide( EgtMP( nRefCrv), vSplitBaseOutlines[j], Z_AX()) - if nSide == 1 then - EgtInvertCurve( nOutlineId) - end - -- calcolo gli offset - local nProfileId = GetOutlineProfileId( nSplitOutline) - if nProfileId then - local b3Profile = GetProfileLocalBox( nProfileId) - local sKey = EgtIf( EgtGetName( tabSplits[vSplitBaseOutlines[j]]) == WIN_BOTTOM, WIN_SASH_BOTTOM_OVERLAP, WIN_SASH_TOP_OVERLAP) - local dOverlap = EgtGetInfo( nProfileId, sKey, 'd') - local dFillPerpOffset = abs( b3Profile:getMin():getX()) - dOverlap - EgtOffsetCurve( nOutlineId, - dFillPerpOffset) - else - -- è french split quindi non ha offset - end - - -- b) aggiorno la curva complessiva di outline con la curva appena calcolata - EgtExtendCurveStartByLen( nOutlineId, 1000) - EgtExtendCurveEndByLen( nOutlineId, 1000) - local ptS = EgtIP( nOutlineId, nCompo, EgtSP( nOutlineId)) - local ptE = EgtIP( nOutlineId, nCompo, EgtEP( nOutlineId)) - local dBorderParS = EgtCurveParamAtPoint( nCompo, ptS) - local dBorderParE = EgtCurveParamAtPoint( nCompo, ptE) - EgtTrimCurveStartEndAtParam( nCompo, dBorderParE, dBorderParS) - local dSplitParS = EgtCurveParamAtPoint( nOutlineId, ptS) - local dSplitParE = EgtCurveParamAtPoint( nOutlineId, ptE) - EgtTrimCurveStartEndAtParam( nOutlineId, dSplitParS, dSplitParE) - EgtAddCurveCompoCurve( nCompo, nOutlineId) - local _, dParEnd = EgtCurveDomain( nCompo) - EgtCurveCompoSetTempProp( nCompo, dParEnd - 1, EgtIf( nSide == 1, - nSplitOutline, nSplitOutline)) - end + for i = 1, #vSplitIds do + + -- a) creo la curva di outline corrispondente allo split + local nOutlineId = EgtCopy( abs( vSplitIds[i]), nOutlineLayerId) + -- rimuovo info che non voglio trasferire + EgtRemoveInfo( nOutlineId, WIN_PRF_CHANGE) + -- verifico orientamento + if vSplitIds[i] < 0 then + EgtInvertCurve( nOutlineId) end + -- calcolo gli offset + local nProfileId = GetOutlineTheoricProfileId( abs( vSplitIds[i])) + if nProfileId then + local b3Profile = GetProfileLocalBox( nProfileId) + local sKey = EgtIf( tabSplitCrvName[abs( vSplitIds[i])] == WIN_BOTTOM, WIN_SASH_BOTTOM_OVERLAP, WIN_SASH_TOP_OVERLAP) + local dOverlap = EgtGetInfo( nProfileId, sKey, 'd') + local dRealDim = EgtGetInfo( abs( vSplitIds[i]), WIN_PART_DIM, 'd') + local dFillPerpOffset = abs( b3Profile:getMin():getX()) * dRealDim / b3Profile:getDimX() - dOverlap + EgtOffsetCurve( nOutlineId, - dFillPerpOffset) + else + -- è french split quindi non ha offset + end + + -- b) aggiorno la curva complessiva di outline con la curva appena calcolata + EgtExtendCurveStartByLen( nOutlineId, 1000) + EgtExtendCurveEndByLen( nOutlineId, 1000) + local ptS = EgtIP( nOutlineId, nCompo, EgtSP( nOutlineId)) + local ptE = EgtIP( nOutlineId, nCompo, EgtEP( nOutlineId)) + local dBorderParS = EgtCurveParamAtPoint( nCompo, ptS) + local dBorderParE = EgtCurveParamAtPoint( nCompo, ptE) + EgtTrimCurveStartEndAtParam( nCompo, dBorderParE, dBorderParS) + local dSplitParS = EgtCurveParamAtPoint( nOutlineId, ptS) + local dSplitParE = EgtCurveParamAtPoint( nOutlineId, ptE) + EgtTrimCurveStartEndAtParam( nOutlineId, dSplitParS, dSplitParE) + EgtAddCurveCompoCurve( nCompo, nOutlineId) + local _, dParEnd = EgtCurveDomain( nCompo) + EgtCurveCompoSetTempProp( nCompo, dParEnd - 1, vSplitIds[i]) end -- spezzo la curva di outline nelle sue sottocurve e riassegno le info @@ -2687,11 +2336,22 @@ local function CalculateSashOutline( nAreaId, nAreaLayerId, nOutlineLayerId) local nCrv, nCnt = EgtExplodeCurveCompo( nCompo) for i = 0, nCnt - 1 do local nOutlineId = nCrv + i + -- assegno le info sou/child EgtSetInfo( nOutlineId, WIN_SOU_OUTLINE, vTempProps[i+1]) + if vTempProps[i+1] > 0 then + AddInfo( vTempProps[i+1], WIN_CHILD_OUTLINE, nOutlineId) + else + AddInfo( abs( vTempProps[i+1]), WIN_CHILD_OUTLINE, - nOutlineId) + end -- sistemo il nome if EgtGetName( abs( vTempProps[i+1])) == WIN_SPLIT then - local nBaseSplit = EgtGetInfo( abs( vTempProps[i+1]), WIN_COPY, 'i') - EgtSetName( nOutlineId, EgtGetName( tabSplits[nBaseSplit])) + -- se deriva da split il nome è salvato nella tabella, se non lo fosse si tratta di un french split e lo calcolo al momento + local sName = tabSplitCrvName[abs( vTempProps[i+1])] + if sName then + EgtSetName( nOutlineId, sName) + else + AssignSplitName( nOutlineId) + end else EgtSetName( nOutlineId, EgtGetName( abs( vTempProps[i+1]))) end @@ -2723,7 +2383,7 @@ local function CalculateSashOutline( nAreaId, nAreaLayerId, nOutlineLayerId) end --------------------------------------------------------------------- -local function VerifySashParts( vOutlines, nAreaId) +local function VerifySashOutlines( vOutlines, nAreaId) -- controlla se i pezzi di un'anta sono validi e se necessitano di gestione speciale nel calcolo dei prev e dei next. Vi sono due tipologie di pezzi che richiedono gestione speciale : -- a) extra : il pezzo non serve, il suo contributo si limita al trim dei suoi pezzi vicini con il suo bordo out @@ -2739,22 +2399,24 @@ local function VerifySashParts( vOutlines, nAreaId) for i = 1, #vOutlines do -- recupero il semiprofilo in - local nProfileId = GetOutlineProfileId( vOutlines[i]) + local nProfileId = GetOutlineTheoricProfileId( vOutlines[i]) local nSectionFrId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME) local frSectionFrame = EgtFR( nSectionFrId, GDB_ID.ROOT) local nInId = EgtGetFirstNameInGroup( nProfileId, WIN_IN) local b3In = EgtGetBBoxRef( nInId, GDB_BB.STANDARD, frSectionFrame) + local dDimStd = EgtGetInfo( nProfileId, WIN_DIM_STD, 'd') + local dRealDim = EgtGetInfo( vOutlines[i], WIN_PART_DIM, 'd') vInSemiProfile[i] = EgtCopyGlob( vOutlines[i], nGrpTmp1) EgtSetInfo( vInSemiProfile[i], 'SouIdx', i) -- se non è possibile calcolare l'interno ( e.g. arco con raggio inferiore alla sua dimensione) il pezzo è sicuramente extra ma considero comunque le sue curve nel fare i conti -- per non sfalsare gli indici - if not EgtOffsetCurve( vInSemiProfile[i], b3In:getMin():getX()) then + if not EgtOffsetCurve( vInSemiProfile[i], b3In:getMin():getX() * dRealDim / dDimStd) then EgtSetInfo( vOutlines[i], WIN_EXTRA_CRV, true) end vOutSemiProfile[i] = EgtCopyGlob( vOutlines[i], nGrpTmp2) - EgtOffsetCurve( vOutSemiProfile[i], b3In:getMax():getX()) + EgtOffsetCurve( vOutSemiProfile[i], b3In:getMax():getX() * dRealDim / dDimStd) EgtSetInfo( vOutSemiProfile[i], 'SouIdx', i) end @@ -2812,12 +2474,14 @@ local function VerifySashParts( vOutlines, nAreaId) vCurrOutlines[j] = vOutlines[nIdx] end local nCompoOutline = EgtCurveCompo( nGrpTmp1, vCurrOutlines, false) - local nProfileId = GetOutlineProfileId( vCurrOutlines[1]) + local nProfileId = GetOutlineTheoricProfileId( vCurrOutlines[1]) + local dDimStd = EgtGetInfo( nProfileId, WIN_DIM_STD, 'd') + local dRealDim = EgtGetInfo( vCurrOutlines[1], WIN_PART_DIM, 'd') local nSectionFrId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME) local frSectionFrame = EgtFR( nSectionFrId, GDB_ID.ROOT) local nCPId = EgtGetFirstNameInGroup( nProfileId, WIN_OUT) local b3CP = EgtGetBBoxRef( nCPId, GDB_BB.STANDARD, frSectionFrame) - local nRefCrv = EgtOffsetCurveAdv( nCompoOutline, b3CP:getMin():getX()) + local nRefCrv = EgtOffsetCurveAdv( nCompoOutline, b3CP:getMin():getX() * dRealDim / dDimStd) local _, _, nSide = EgtPointCurveDistSide( ptInters, nRefCrv, Z_AX()) for j = 1, #vCurrOutlines do @@ -2834,15 +2498,1397 @@ local function VerifySashParts( vOutlines, nAreaId) EgtErase( nGrpTmp2) end + +------------------------------ FILL ------------------------------- --------------------------------------------------------------------- -local function GetSashPrevNextOutlines( vOutlineIds, nOutlineLayerId, nAreaId) +local function CalculateFillOutline( nAreaId, nOutlineLayerId) + + -- recupero area parent di tipo telaio/anta che la contiene + local nParentArea = EgtGetParent( nAreaId) + local nAreaType = EgtGetInfo( nParentArea, WIN_AREATYPE, 'i') + while nAreaType ~= WIN_AREATYPES.FRAME and nAreaType ~= WIN_AREATYPES.SASH do + nParentArea = EgtGetParent( nParentArea) + nAreaType = EgtGetInfo( nParentArea, WIN_AREATYPE, 'i') + end + + -- 1) calcolo l'area complessiva di fill definita dal suo parent + local nParentOutlineLayer = EgtGetFirstNameInGroup( nParentArea, WIN_OUTLINE) + local dDeltaZ = 0 + local vParentOutlines = EgtGetAllInGroup( nParentOutlineLayer) + local vParentOffs = {} + -- calcolo gli offset + for i = 1, #vParentOutlines do + -- recupero il suo profilo per calcolare l'offset perpendicolare + local nParentProfileId = GetOutlineTheoricProfileId( vParentOutlines[i], true) + local dOverlap = EgtGetInfo( nParentProfileId, WIN_FILLOVERLAP, 'd') + if dOverlap then + local dRealDim = EgtGetInfo( vParentOutlines[i], WIN_PART_DIM, 'd') + -- verifico se contributo per bottomrail + local dRailOffs = 0 + if EgtGetName( nParentProfileId) == WIN_FILL_RAIL then + local nBottomRail = EgtGetInfo( vParentOutlines[i], WIN_BOTTOMRAIL, 'i') + dRailOffs = CalcRailOffset( vParentOutlines[i], nParentProfileId, nBottomRail) + local vBottomRailDims = EgtGetInfo( vParentOutlines[i], WIN_BOTTOMRAIL .. WIN_PART_DIM, 'vd') + dRealDim = vBottomRailDims[#vBottomRailDims] + end + local b3FrameProfile = GetProfileLocalBox( nParentProfileId) + local dDimRef = b3FrameProfile:getMin():getX() * dRealDim / b3FrameProfile:getDimX() + vParentOffs[i] = abs( dDimRef) - dOverlap + dRailOffs + -- movimento in z + if dDeltaZ < GEO.EPS_SMALL then + dDeltaZ = EgtGetInfo( nParentProfileId, WIN_FILLDELTA, 'd') + end + end + end + -- creo le curve di outlines + for i = 1, #vParentOutlines do + -- copio la curva di outline del parent + local nOutlineId = EgtCopy( vParentOutlines[i], nOutlineLayerId) + EgtSetInfo( nOutlineId, WIN_SOU_OUTLINE, vParentOutlines[i]) + -- applico offset + if vParentOffs[i] then + EgtOffsetCurve( nOutlineId, - vParentOffs[i]) + else + -- se non ha offset definito è un pezzo che verrà tagliato da uno split ma, affinchè la forma del telaio sia coerente, devo applicare lo stesso offset a curve + -- che sono in tangenza + local nPrevIdx = EgtIf( i == 1, #vParentOutlines, i-1) + local nNextIdx = EgtIf( i == #vParentOutlines, 1, i+1) + if AreSameVectorApprox( EgtSV( vParentOutlines[i]), EgtEV( vParentOutlines[nPrevIdx])) then + while not vParentOffs[nPrevIdx] do + nPrevIdx = EgtIf( nPrevIdx == 1, #vParentOutlines, nPrevIdx-1) + end + EgtOffsetCurve( nOutlineId, - vParentOffs[nPrevIdx]) + vParentOffs[i] = vParentOffs[nPrevIdx] + elseif AreSameVectorApprox( EgtEV( vParentOutlines[i]), EgtSV( vParentOutlines[nNextIdx])) then + while not vParentOffs[nNextIdx] do + nNextIdx = EgtIf( nNextIdx == #vParentOutlines, 1, nNextIdx+1) + end + EgtOffsetCurve( nOutlineId, - vParentOffs[nNextIdx]) + vParentOffs[i] = vParentOffs[nNextIdx] + end + end + end + -- accorcio gli offset + local vCrvs = TrimOrderedCurves( EgtGetAllInGroup( nOutlineLayerId), true) + -- applico spostamento verticale + EgtMove( vCrvs, Z_AX() * dDeltaZ) + + + -- 2) taglio con split + local nParentType = EgtGetInfo( EgtGetParent( nAreaId), WIN_AREATYPE, 'i') + if nParentType ~= WIN_AREATYPES.NULL then + -- salvo associazioni sou/child + for i = 1, #vCrvs do + local nSouOutlineId = EgtGetInfo( vCrvs[i], WIN_SOU_OUTLINE, 'i') + AddInfo( nSouOutlineId, WIN_CHILD_OUTLINE, vCrvs[i]) + end + return + end + + -- creo bordo complessivo dell'outline, salvando le info come temp prop della curva per non perderle + local vSouOutlines = {} + for i = 1, #vCrvs do + vSouOutlines[i] = EgtGetInfo( vCrvs[i], WIN_SOU_OUTLINE, 'i') + end + local nCompo = EgtCurveCompo( nOutlineLayerId, vCrvs) + for i = 0, #vCrvs - 1 do + EgtCurveCompoSetTempProp( nCompo, i, vSouOutlines[i+1]) + end + + -- recupero gli split che definiscono l'area fill cercando gli split in tutte le aree parent di tipo null + local vSplitIds = {} + local nParentId = EgtGetParent( nAreaId) + while nParentId ~= nParentArea do + local nParentType = EgtGetInfo( nParentId, WIN_AREATYPE, 'i') + if nParentType == WIN_AREATYPES.NULL then + local nNullOutlineLay = EgtGetFirstNameInGroup( nParentId, WIN_OUTLINE) + local vNullOutlines = EgtGetAllInGroup( nNullOutlineLay) + for i = 1, #vNullOutlines do + local nSou = EgtGetInfo( vNullOutlines[i], WIN_SOU_OUTLINE, 'i') + if EgtGetName( EgtGetParent( EgtGetParent( abs( nSou)))) == WIN_VIRTUAL_AREA then + nSou = EgtGetInfo( abs( nSou), WIN_SOU_OUTLINE, 'i') + end + if EgtGetName( abs( nSou)) == WIN_SPLIT then + table.insert( vSplitIds, nSou) + end + end + end + nParentId = EgtGetParent( nParentId) + end + + -- li ordino per id crescente in modo da effettuare i tagli nell'ordine corretto + table.sort( vSplitIds, function ( a, b) return abs( a) < abs( b) end) + + for i = 1, #vSplitIds do + + -- creo la curva di outline corrispondente allo split + local nOutlineId = EgtCopy( abs( vSplitIds[i]), nOutlineLayerId) + if vSplitIds[i] < 0 then + EgtInvertCurve( nOutlineId) + end + -- calcolo gli offset + local nProfileId = GetOutlineTheoricProfileId( abs( vSplitIds[i]), true) + local b3Profile = GetProfileLocalBox( nProfileId) + local dOverlap = EgtGetInfo( nProfileId, WIN_FILLOVERLAP, 'd') + local dDimRef = EgtIf( vSplitIds[i] < 0, b3Profile:getMax():getX(), b3Profile:getMin():getX()) + local dRealDim = EgtGetInfo( abs( vSplitIds[i]), WIN_PART_DIM, 'd') + local dOffs = abs( dDimRef) * dRealDim / b3Profile:getDimX() - dOverlap + EgtOffsetCurve( nOutlineId, - dOffs) + -- movimento in z + local dFillZOffset = EgtGetInfo( nProfileId, WIN_FILLDELTA, 'd') + EgtMove( nOutlineId, Z_AX() * dFillZOffset) + + -- aggiorno la curva complessiva di outline con la curva appena calcolata + local ptS = EgtIP( nOutlineId, nCompo, EgtSP( nOutlineId)) + local ptE = EgtIP( nOutlineId, nCompo, EgtEP( nOutlineId)) + local dBorderParS = EgtCurveParamAtPoint( nCompo, ptS) + local dBorderParE = EgtCurveParamAtPoint( nCompo, ptE) + EgtTrimCurveStartEndAtParam( nCompo, dBorderParE, dBorderParS) + local dSplitParS = EgtCurveParamAtPoint( nOutlineId, ptS) + local dSplitParE = EgtCurveParamAtPoint( nOutlineId, ptE) + EgtTrimCurveStartEndAtParam( nOutlineId, dSplitParS, dSplitParE) + EgtAddCurveCompoCurve( nCompo, nOutlineId) + local _, dParEnd = EgtCurveDomain( nCompo) + EgtCurveCompoSetTempProp( nCompo, dParEnd - 1, vSplitIds[i]) + end + + -- spezzo la curva di outline nelle sue sottocurve e riassegno le info + local vTempProps = EgtCurveCompoGetTempProp( nCompo) + local nCrv, nCnt = EgtExplodeCurveCompo( nCompo) + for i = 0, nCnt - 1 do + EgtSetInfo( nCrv + i, WIN_SOU_OUTLINE, vTempProps[i+1]) + if vTempProps[i+1] > 0 then + AddInfo( vTempProps[i+1], WIN_CHILD_OUTLINE, nCrv + i) + else + AddInfo( abs( vTempProps[i+1]), WIN_CHILD_OUTLINE, - ( nCrv + i)) + end + end +end + + +-------------------- AGGIORNAMENTO TIPOLOGIE ---------------------- +--------------------------------------------------------------------- +-- funzione ricorsiva che aggiorna le tipologie di split guardando le curve di outlines ( e non quelle di base outlines come fatto in CalcProfileType) +local function UpdateSplitTypes( nAreaId) + + local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i') + + if nAreaType == WIN_AREATYPES.SASH or nAreaType == WIN_AREATYPES.FILL then + return + + elseif nAreaType == WIN_AREATYPES.SPLIT then + if EgtGetInfo( nAreaId, WIN_SPLITTYPE, 'i') ~= WIN_SPLITTYPES.FRENCH then + local nSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_SPLIT) + local vSplits = EgtGetAllInGroup( nSplitLayerId) + for i = 1, #vSplits do + + -- identifico la tipologia di figli dal lato destro (1) e sinistro (2) + local tabChildren = {{}, {}} + local vSashNbr = { 0, 0} + local vFillNbr = { 0, 0} + local vBaseChildren = EgtGetInfo( vSplits[i], WIN_CHILD_VIRTUAL_OUTLINE, 'vi') + -- ordino i figli letti dalle info in modo tale che quello di destra ( che ha segno negativo) sia il primo e quello di sinistra ( che ha segno positivo) sia il secondo + if vBaseChildren[1] > vBaseChildren[2] then + vBaseChildren[1], vBaseChildren[2] = vBaseChildren[2], vBaseChildren[1] + end + + for k = 1, 2 do + local vCurrChildren = { vBaseChildren[k]} + local j = 1 + while vCurrChildren[j] do + local vNewChildren = EgtGetInfo( abs( vCurrChildren[j]), WIN_CHILD_VIRTUAL_OUTLINE, 'vi') + if vNewChildren then + EgtJoinTables( vCurrChildren, vNewChildren) + else + -- se non ha ulteriori figli allora è l'area null finale che deve essere studiata + local nNullAreaId = EgtGetParent( EgtGetParent( abs( vCurrChildren[j]))) + local nAreaId = EgtGetFirstNameInGroup( nNullAreaId, WIN_AREA .. '*') + local nAreaType + if nAreaId then + nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i') + if nAreaType == WIN_AREATYPES.SASH then + vSashNbr[k] = vSashNbr[k] + 1 + elseif nAreaType == WIN_AREATYPES.FILL then + vFillNbr[k] = vFillNbr[k] + 1 + end + end + table.insert( tabChildren[k], { nId = abs( vCurrChildren[j]), nType = nAreaType}) + end + j = j + 1 + end + end + + -- ricavo la nuova tipologia di split ed eventualmente aggiorno il profilo se fosse diverso da quello calcolato dai base outlines + local nOldType = EgtGetInfo( vSplits[i], WIN_SPLITTYPE, 'i') + + -- se figli sono solo ante è montante + if vFillNbr[1] == 0 and vFillNbr[2] == 0 then + if nOldType ~= WIN_SPLITTYPES.MULLION then + EgtSetInfo( vSplits[i], WIN_SPLITTYPE, WIN_SPLITTYPES.MULLION) + if AreSameOrOppositeVectorApprox( EgtSV( vSplits[i]), X_AX()) then + EgtSetInfo( vSplits[i], WIN_PROFILETYPE, WIN_SASH_HORIZONTAL) + else + EgtSetInfo( vSplits[i], WIN_PROFILETYPE, WIN_SASH_VERTICAL) + end + end + + -- se figli sono solo vetri fissi è muntin interno al telaio + elseif vSashNbr[1] == 0 and vSashNbr[2] == 0 then + if nOldType ~= WIN_SPLITTYPES.MUNTIN_FRAME then + EgtSetInfo( vSplits[i], WIN_SPLITTYPE, WIN_SPLITTYPES.MUNTIN_FRAME) + EgtSetInfo( vSplits[i], WIN_PROFILETYPE, WIN_FRAME_SPLIT) + end + + -- se figli di entrambe le tipologie è mixed e verifico quali sono le parti dello split coinvolte dal cambio profilo + else + local nPrfChange = 0 + -- ricavo le tipologie di figli su start ed end a destra + local nStart1, nEnd1 + if vSashNbr[1] > 0 and vFillNbr[1] == 0 then + nStart1 = WIN_CHILDREN_TYPES.SASH + nEnd1 = WIN_CHILDREN_TYPES.SASH + elseif vSashNbr[1] == 0 and vFillNbr[1] > 0 then + nStart1 = WIN_CHILDREN_TYPES.FILL + nEnd1 = WIN_CHILDREN_TYPES.FILL + else + nPrfChange = nPrfChange + WIN_PRF_CHANGE_TYPES.OUT -- ha cambio profilo sul lato esterno + for j = 1, #tabChildren[1] do + if AreSamePointApprox( EgtSP( vSplits[i]), EgtEP( tabChildren[1][j].nId)) then + nStart1 = EgtIf( tabChildren[1][j].nType == WIN_AREATYPES.SASH, WIN_CHILDREN_TYPES.SASH, WIN_CHILDREN_TYPES.FILL) + end + if AreSamePointApprox( EgtEP( vSplits[i]), EgtSP( tabChildren[1][j].nId)) then + nEnd1 = EgtIf( tabChildren[1][j].nType == WIN_AREATYPES.SASH, WIN_CHILDREN_TYPES.SASH, WIN_CHILDREN_TYPES.FILL) + end + end + end + + -- ricavo le tipologie di figli su start ed end a sinistra + local nStart2, nEnd2 + if vSashNbr[2] > 0 and vFillNbr[2] == 0 then + nStart2 = WIN_CHILDREN_TYPES.SASH + nEnd2 = WIN_CHILDREN_TYPES.SASH + elseif vSashNbr[2] == 0 and vFillNbr[2] > 0 then + nStart2 = WIN_CHILDREN_TYPES.FILL + nEnd2 = WIN_CHILDREN_TYPES.FILL + else + nPrfChange = nPrfChange + WIN_PRF_CHANGE_TYPES.IN -- ha cambio profilo su lato interno + for j = 1, #tabChildren[2] do + if AreSamePointApprox( EgtSP( vSplits[i]), EgtSP( tabChildren[2][j].nId)) then + nStart2 = EgtIf( tabChildren[2][j].nType == WIN_AREATYPES.SASH, WIN_CHILDREN_TYPES.SASH, WIN_CHILDREN_TYPES.FILL) + end + if AreSamePointApprox( EgtEP( vSplits[i]), EgtEP( tabChildren[2][j].nId)) then + nEnd2 = EgtIf( tabChildren[2][j].nType == WIN_AREATYPES.SASH, WIN_CHILDREN_TYPES.SASH, WIN_CHILDREN_TYPES.FILL) + end + end + end + + -- se le tipologie di figli sugli estremi sono diverse tra destra e sinistra allora l'estremo è coinvolto dal cambio profilo + if nStart1 ~= nStart2 then + nPrfChange = nPrfChange + WIN_PRF_CHANGE_TYPES.START + end + if nEnd1 ~= nEnd2 then + nPrfChange = nPrfChange + WIN_PRF_CHANGE_TYPES.END + end + + EgtSetInfo( vSplits[i], WIN_SPLITTYPE, WIN_SPLITTYPES.MIXED) + EgtSetInfo( vSplits[i], WIN_PRF_CHANGE, nPrfChange) + EgtSetInfo( vSplits[i], WIN_MIXED_START_CHILDREN .. '1', nStart1) + EgtSetInfo( vSplits[i], WIN_MIXED_START_CHILDREN .. '2', nStart2) + EgtSetInfo( vSplits[i], WIN_MIXED_END_CHILDREN .. '1', nEnd1) + EgtSetInfo( vSplits[i], WIN_MIXED_END_CHILDREN .. '2', nEnd2) + end + end + end + end + + -- analizzo le sottoaree + local vChildren = EgtGetNameInGroup( nAreaId, WIN_AREA .. '*') + for i = 1, #vChildren do + UpdateSplitTypes( vChildren[i]) + end +end + +--------------------------------------------------------------------- +local function VerifyOutlinesInterferenceWithMixedSplit( nAreaId, vOutlines) + + local vInterference = {} + local vToBeTested = {} + for i = 1, #vOutlines do + vInterference[i] = false + vToBeTested[i] = false + end + + local nGrpTmp = EgtGroup( nAreaId) + EgtSetStatus( nGrpTmp, GDB_ST.OFF) + + -- ricavo i profili mixed teorici + local nProfileGrp = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_PROFILE) + local nFrameProfileGrp = EgtGetFirstNameInGroup( nProfileGrp, WIN_FRAME) + local nBottomProfileId = EgtGetFirstNameInGroup( nFrameProfileGrp, WIN_MIXED_BOTTOM) + local b3Bottom = GetProfileLocalBox( nBottomProfileId) + local nTopProfileId = EgtGetFirstNameInGroup( nFrameProfileGrp, WIN_MIXED_TOP) + local b3Top = GetProfileLocalBox( nTopProfileId) + local nSplitProfileId = EgtGetFirstNameInGroup( nFrameProfileGrp, WIN_MIXED_SPLIT) + local b3Split = GetProfileLocalBox( nSplitProfileId) + + -- calcolo i box delle curve di outlines + local tabBox = {} + for i = 1, #vOutlines do + local nProfileId = EgtIf( i == 1, nBottomProfileId, nTopProfileId) + local b3Profile = EgtIf( i == 1, b3Bottom, b3Top) + local b3Box, frRef = CreateTestBoxFromOutline( vOutlines[i], nProfileId, b3Profile) + tabBox[i] = { frRef = frRef, b3Box = b3Box} + end + + + -- recupero tutti gli split con cambio profilo sugli estremi che arrivano sul telaio + local tabSplits = {} + local vChildAreas = EgtGetNameInGroup( nAreaId, WIN_AREA .. '*') + local i = 1 + while vChildAreas[i] do + local nAreaType = EgtGetInfo( vChildAreas[i], WIN_AREATYPE, 'i') + if nAreaType == WIN_AREATYPES.SASH or nAreaType == WIN_AREATYPES.FILL then + -- la ricerca a cascata si interrompe + else + if nAreaType == WIN_AREATYPES.SPLIT then + local nSplitLayerId = EgtGetFirstNameInGroup( vChildAreas[i], WIN_SPLIT) + local vSplits = EgtGetAllInGroup( nSplitLayerId) + for j = 1, #vSplits do + + local nPrfChange = EgtGetInfo( vSplits[j], WIN_PRF_CHANGE, 'i') or WIN_PRF_CHANGE_TYPES.NULL + if nPrfChange & WIN_PRF_CHANGE_TYPES.START > 0 then + local nBaseStart = EgtGetInfo( vSplits[j], WIN_SPLIT_STARTINTERS, 'i') + local nStart = GetNonVirtualOutline( nBaseStart) + if EgtGetName( abs( nStart)) ~= WIN_SPLIT then + -- controllo con quanti outlines fa interferenza controllando l'overlap dei box + local nRefCrv = EgtCopyGlob( vSplits[j], nGrpTmp) + EgtTrimCurveEndAtLen( nRefCrv, 0.5 * EgtCurveLength( nRefCrv)) + local b3Box, frRef = CreateTestBoxFromOutline( nRefCrv, nSplitProfileId, b3Split) + + local vTest = {} -- indici degli outlines con cui fa interferenza + for k = 1, #tabBox do + if Overlaps( tabBox[k].b3Box, tabBox[k].frRef, b3Box, frRef) then + table.insert( vTest, k) + end + end + + if #vTest == 1 then + -- se fa intereferenza con una sola curva non servono ulteriori controlli, l'interferenza è confermata + vInterference[vTest[1]] = true + AddInfo( vOutlines[vTest[1]], WIN_CHILD_PRFCHANGE_SPLIT, vSplits[j]) + EgtSetInfo( vSplits[j], WIN_PREV_OUTLINES, vOutlines[vTest[1]]) + EgtSetInfo( vSplits[j], WIN_STARTJOINT, WIN_PART_JNT.SHORT) + elseif #vTest > 1 then + -- se fa interferenza con più curve allora dovrò controllare quali sono le vere interferenze controllando i profili + table.insert( tabSplits, { nId = vSplits[j], bStart = true, vTest = vTest}) + for k = 1, #vTest do + vToBeTested[vTest[k]] = true + end + end + end + end + + if nPrfChange & WIN_PRF_CHANGE_TYPES.END > 0 then + local nBaseEnd = EgtGetInfo( vSplits[j], WIN_SPLIT_ENDINTERS, 'i') + local nEnd = GetNonVirtualOutline( nBaseEnd) + if EgtGetName( abs( nEnd)) ~= WIN_SPLIT then + local nRefCrv = EgtCopyGlob( vSplits[j], nGrpTmp) + EgtTrimCurveStartAtLen( nRefCrv, 0.5 * EgtCurveLength( nRefCrv)) + local b3Box, frRef = CreateTestBoxFromOutline( nRefCrv, nSplitProfileId, b3Split) + + local vTest = {} + for k = 1, #tabBox do + if Overlaps( tabBox[k].b3Box, tabBox[k].frRef, b3Box, frRef) then + table.insert( vTest, k) + end + end + + if #vTest == 1 then + vInterference[vTest[1]] = true + AddInfo( vOutlines[vTest[1]], WIN_CHILD_PRFCHANGE_SPLIT, vSplits[j]) + EgtSetInfo( vSplits[j], WIN_NEXT_OUTLINES, vOutlines[vTest[1]]) + EgtSetInfo( vSplits[j], WIN_ENDJOINT, WIN_PART_JNT.SHORT) + elseif #vTest > 1 then + table.insert( tabSplits, { nId = vSplits[j], bStart = false, vTest = vTest}) + for k = 1, #vTest do + vToBeTested[vTest[k]] = true + end + end + end + end + end + end + -- analizzo le sottaree + local vCurrChildAreas = EgtGetNameInGroup( vChildAreas[i], WIN_AREA .. '*') + EgtJoinTables( vChildAreas, vCurrChildAreas) + end + i = i + 1 + end + + -- per ogni curva di outline che deve essere testata costruisco la superficie in con il controprofilo sash ( perchè è quella che verrà usata per tagliare lo split) + local vTestSurfs = {} + for i = 1, #vOutlines do + if vToBeTested[i] then + local nProfileId = EgtIf( i == 1, nBottomProfileId, nTopProfileId) + local nGuideId = EgtCopyGlob( vOutlines[i], nGrpTmp) + local dDimStd = EgtGetInfo( nProfileId, WIN_DIM_STD, 'd') + local dDimReal = EgtGetInfo( vOutlines[i], WIN_PART_DIM, 'd') + if abs( dDimReal - dDimStd) > GEO.EPS_SMALL then + local dOffs = dDimReal / dDimStd + EgtOffsetCurve( nGuideId, - dOffs) + end + vTestSurfs[i] = CreateProfileSurf( nGuideId, nProfileId, WIN_SASH .. WIN_CTRIN, 100, nGrpTmp) + end + end + + -- taglio le superfici con bisettrice ( perchè se entrambi i pezzi hanno cambio profilo la giunzione viene forzata a angled) + for i = 1, #vOutlines do + local nPrevIdx = EgtIf( i == 1, #vOutlines, i - 1) + if vTestSurfs[i] or vTestSurfs[nPrevIdx] then + if EgtGetType( vOutlines[i]) == GDB_TY.CRV_LINE and EgtGetType( vOutlines[nPrevIdx]) == GDB_TY.CRV_LINE then + local vtDir = 0.5 * ( EgtSV( vOutlines[i]) - EgtEV( vOutlines[nPrevIdx])) + if vtDir:isZero() then + vtDir = - EgtSV( vOutlines[i]) + else + vtDir:rotate( Z_AX(), 90) + end + if vTestSurfs[i] then + EgtCutSurfTmPlane( vTestSurfs[i], EgtSP( vOutlines[i]), vtDir, false) + end + if vTestSurfs[nPrevIdx] then + EgtCutSurfTmPlane( vTestSurfs[nPrevIdx], EgtSP( vOutlines[i]), - vtDir, false) + end + else + -- calcolo bisettore + local nBisector = CalcParabolicBisector( vOutlines[nPrevIdx], vOutlines[i], 100, nGrpTmp, false, false) + local nBisectorSurf = EgtSurfTmByRegionExtrusion( nGrpTmp, nBisector, - 100 * Z_AX()) + if vTestSurfs[i] then + EgtSurfTmCut( vTestSurfs[i], nBisectorSurf, true, false) + end + if vTestSurfs[nPrevIdx] then + EgtSurfTmCut( vTestSurfs[nPrevIdx], nBisectorSurf, false, false) + end + end + end + end + + -- verifico le intereferernze + for i = 1, #tabSplits do + + -- costruisco il profilo dello split sull'estremo considerato in base alla tipologia di figli + local nChildrenType1 = EgtGetInfo( tabSplits[i].nId, EgtIf( tabSplits[i].bStart, WIN_MIXED_START_CHILDREN, WIN_MIXED_END_CHILDREN) .. '1', 'i') + local sSemiProfileName1 = EgtIf( nChildrenType1 == WIN_CHILDREN_TYPES.SASH, WIN_SASH, WIN_FILL) .. WIN_IN .. '1' + local nSemiProfile1 = EgtGetFirstNameInGroup( nSplitProfileId, sSemiProfileName1) + + local nChildrenType2 = EgtGetInfo( tabSplits[i].nId, EgtIf( tabSplits[i].bStart, WIN_MIXED_START_CHILDREN, WIN_MIXED_END_CHILDREN) .. '2', 'i') + local sSemiProfileName2 = EgtIf( nChildrenType2 == WIN_CHILDREN_TYPES.SASH, WIN_SASH, WIN_FILL) .. WIN_IN .. '2' + local nSemiProfile2 = EgtGetFirstNameInGroup( nSplitProfileId, sSemiProfileName2) + + local dDimStd = EgtGetInfo( nSplitProfileId, WIN_DIM_STD, 'd') + local dDimReal = EgtGetInfo( tabSplits[i].nId, WIN_PART_DIM, 'd') + if abs( dDimReal - dDimStd) > GEO.EPS_SMALL then + local nSectionFrame = EgtGetFirstNameInGroup( nSplitProfileId, WIN_SECTIONFRAME) + local frProfile = EgtFR( nSectionFrame, GDB_ID.ROOT) + EgtMove( nSemiProfile1, b3Split:getMax():getX() * dDimReal / dDimStd * frProfile:getVersX(), GDB_RT.GLOB) + EgtMove( nSemiProfile1, b3Split:getMin():getX() * dDimReal / dDimStd * frProfile:getVersX(), GDB_RT.GLOB) + end + local nSection = EgtCurveCompo( nGrpTmp, nSemiProfile1, false) + EgtAddCurveCompoLine( nSection, EgtSP( nSemiProfile2, GDB_ID.ROOT), GDB_RT.GLOB) + EgtAddCurveCompoCurve( nSection, nSemiProfile2, false) + EgtCloseCurveCompo( nSection) + + -- costruisco il solido di split + local nSplitSolid = CreateProfileSurfById( tabSplits[i].nId, nSplitProfileId, nSection, 400, nGrpTmp) + EgtCutSurfTmPlane( nSplitSolid, EgtMP( tabSplits[i].nId), EgtIf( tabSplits[i].bStart, 1, -1) * EgtSV( tabSplits[i].nId)) + + -- testo con quali superfici degli outlines fa interferenza + for j = 1, #( tabSplits[i].vTest) do + local nIdx = tabSplits[i].vTest[j] + local nId, _, nCrvCnt = EgtSurfTmSurfTmInters( nSplitSolid, vTestSurfs[nIdx], nGrpTmp) + if nId and nCrvCnt > 0 then + vInterference[nIdx] = true + AddInfo( vOutlines[nIdx], WIN_CHILD_PRFCHANGE_SPLIT, tabSplits[i].nId) + AddInfo( tabSplits[i].nId, EgtIf( tabSplits[i].bStart, WIN_PREV_OUTLINES, WIN_NEXT_OUTLINES), vOutlines[nIdx]) + AddInfo( tabSplits[i].nId, EgtIf( tabSplits[i].bStart, WIN_STARTJOINT, WIN_ENDJOINT), WIN_PART_JNT.SHORT) + end + end + end + + EgtErase( nGrpTmp) + return vInterference +end + +--------------------------------------------------------------------- +-- funzione che aggiorna i profili del telaio guardando le curve di outlines ( e non quelle di base outlines come fatto in CalcProfileType) +local function UpdateFrameTypes( nAreaId) + + local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE) + local vOutlines = EgtGetAllInGroup( nOutlineLayerId) + + -- per ogni outline verifico se fa interferenza con uno split con cambio profilo sull'estremo + local vInterference = VerifyOutlinesInterferenceWithMixedSplit( nAreaId, vOutlines) + + for i = 1, #vOutlines do + local nOldType = EgtGetInfo( vOutlines[i], WIN_CHILDREN_TYPE, 'i') + + if vInterference[i] then + -- se fa interferenza con uno split con cambio profilo sull'estremo deve avere un profilo mixed + EgtSetInfo( vOutlines[i], WIN_PRF_CHANGE, WIN_PRF_CHANGE_TYPES.IN) + -- verifico se devo aggiornare il profilo + if nOldType ~= WIN_CHILDREN_TYPES.MIXED then + if EgtGetName( vOutlines[i]) == WIN_BOTTOM then + EgtSetInfo( vOutlines[i], WIN_PROFILETYPE, WIN_MIXED_BOTTOM) + else + EgtSetInfo( vOutlines[i], WIN_PROFILETYPE, WIN_MIXED_TOP) + end + end + + else + -- se non fa interferenza con cambio profilo devo controllare la tipologia dei figli. + -- Se non era stato classificato come mixed allora basta trovare la tipologia di un figlio qualunque, se invece era mixed allora ha entrambe le tipologie di figli, + -- devo considerare quella della curva più lunga ( euristicamente se non è più mixed vuol dire che il cambio profilo avviene vicino al suo estremo quindi + -- uno dei due figli è molto più corto dell'altro) + local dFillLen = 0 + local dSashLen = 0 + local vChildren = EgtGetInfo( vOutlines[i], WIN_CHILD_VIRTUAL_OUTLINE, 'vi') + local j = 1 + while vChildren[j] do + -- verifico se ho cascata di children + local vNewChildren = EgtGetInfo( abs( vChildren[j]), WIN_CHILD_VIRTUAL_OUTLINE, 'vi') + if vNewChildren then + EgtJoinTables( vChildren, vNewChildren) + else + -- recupero la tipologia di figli dell'area null + local nNullAreaId = EgtGetParent( EgtGetParent( abs( vChildren[j]))) + local nAreaId = EgtGetFirstNameInGroup( nNullAreaId, WIN_AREA .. '*') + if nAreaId then + local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i') + if nAreaType == WIN_AREATYPES.SASH then + dSashLen = dSashLen + EgtCurveLength( abs( vChildren[j])) + else + dFillLen = dFillLen + EgtCurveLength( abs( vChildren[j])) + end + end + end + j = j + 1 + end + local nChildrenType = EgtIf( dSashLen > dFillLen, WIN_CHILDREN_TYPES.SASH, WIN_CHILDREN_TYPES.FILL) + + -- verifico se devo aggiornare il profilo + if nChildrenType ~= nOldType then + if nChildrenType == WIN_CHILDREN_TYPES.FILL then + if EgtGetName( vOutlines[i]) == WIN_BOTTOM then + -- verifico presenza bottomrail + local nBottomRail = EgtGetInfo( vOutlines[i], WIN_BOTTOMRAIL, 'i') or 0 + local sThreshold = EgtGetInfo( EgtetParent( EgtGetParent( vOutlines[i])), WIN_THRESHOLD_PROFILE) or WIN_BOTTOM + if nBottomRail == 0 then + EgtSetInfo( vOutlines[i], WIN_PROFILETYPE, WIN_FIXED .. '_' .. sThreshold) + else + EgtSetInfo( vOutlines[i], WIN_PROFILETYPE, WIN_RAIL .. '_' .. sThreshold) + end + else + EgtSetInfo( vOutlines[i], WIN_PROFILETYPE, WIN_FIXED_TOP) + end + + else -- sash + if EgtGetName( vOutlines[i]) == WIN_BOTTOM then + local sThreshold = EgtGetInfo( nAreaId, WIN_THRESHOLD_PROFILE) or WIN_BOTTOM + EgtSetInfo( vOutlines[i], WIN_PROFILETYPE, WIN_SASH .. '_' .. sThreshold) + else + EgtSetInfo( vOutlines[i], WIN_PROFILETYPE, WIN_SASH_TOP) + end + end + end + end + end +end + + +--------------------------------------------------------------------- +-------------------------------------------------------------------- +local function CalcOutlineDimensions( vOutlines, nAreaId) + + local vPartsDim = EgtGetInfo( nAreaId, WIN_PART_DIM, 'vd') or {} + local nBottomRail = EgtGetInfo( nAreaId, WIN_BOTTOMRAIL, 'i') or 0 + for i = 1, #vOutlines do + + if not vPartsDim[i] or EgtGetInfo( vOutlines[i], WIN_THRESHOLD, 'b') then + -- se dimensione non è impostata oppure soglia recupero quella standard del profilo + local nProfileId = GetOutlineTheoricProfileId( vOutlines[i], false) + vPartsDim[i] = EgtGetInfo( nProfileId, WIN_DIM_STD, 'd') + end + EgtSetInfo( vOutlines[i], WIN_PART_DIM, vPartsDim[i]) + + -- dimensioni dei bottomrails + if nBottomRail and EgtGetName( vOutlines[i]) == WIN_BOTTOM then + EgtSetInfo( vOutlines[i], WIN_BOTTOMRAIL, nBottomRail) + local vBottomRailDim = EgtGetInfo( nAreaId, WIN_BOTTOMRAIL .. WIN_PART_DIM, 'vd') or {} + if #vBottomRailDim ~= nBottomRail then + for j = 1, nBottomRail do + if not vBottomRailDim[j] then + local nProfileId = GetOutlineTheoricProfileId( vOutlines[i], false, j) + vBottomRailDim[j] = EgtGetInfo( nProfileId, WIN_DIM_STD, 'd') + end + end + end + EgtSetInfo( vOutlines[i], WIN_BOTTOMRAIL .. WIN_PART_DIM, vBottomRailDim) + end + end +end + +--------------------------------------------------------------------- +-- funzione che calcola l'outline dal base outline e i pezzi associati +local function CalculateOutlineFromAreaOutline( nAreaId) + + local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i') + + -- se area null il suo outline è già stato calcolato dalla sua area split parent + if nAreaType == WIN_AREATYPES.NULL then + return + end + + -- creo gruppo per outline + local nOutlineLayerId = EgtGroup( nAreaId) + EgtSetName( nOutlineLayerId, WIN_OUTLINE) + EgtSetStatus( nOutlineLayerId, GDB_ST.OFF) + + -- FRAME + if nAreaType == WIN_AREATYPES.FRAME then + -- l'outline è la copia del base outline + local nBaseOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_AREAOUTLINE) + local vBaseOutlineIds = EgtGetAllInGroup( nBaseOutlineLayerId) + local nBottomRail = EgtGetInfo( nAreaId, WIN_BOTTOMRAIL, 'i') or 0 + local vOutlines = {} + for i = 1, #vBaseOutlineIds do + vOutlines[i] = EgtCopyGlob( vBaseOutlineIds[i], nOutlineLayerId) + if i == 1 and nBottomRail > 0 then + EgtSetInfo( vOutlines[i], WIN_BOTTOMRAIL, nBottomRail) + end + end + CalcOutlineDimensions( vOutlines, nAreaId) + + + -- SPLIT + elseif nAreaType == WIN_AREATYPES.SPLIT then + + -- l'outline è copia del parent outline + local nParentId = EgtGetParent( nAreaId) + if EgtGetInfo( nParentId, WIN_AREATYPE, 'i') == WIN_AREATYPES.FILL then + -- se inglesina il parent è un vetro. Il pezzo però non va tagliato con il vetro ma con l'elemento che contiene il vetro, quindi considero come outline quello del parent del vetro + nParentId = EgtGetParent( nParentId) + end + local nParentOutlineId = EgtGetFirstNameInGroup( nParentId, WIN_OUTLINE) + local vParentOutlines = EgtGetAllInGroup( nParentOutlineId) + for i = 1, #vParentOutlines do + local nOutlineId = EgtCopyGlob( vParentOutlines[i], nOutlineLayerId) + EgtSetInfo( nOutlineId, WIN_SOU_OUTLINE, vParentOutlines[i]) + AddInfo( vParentOutlines[i], WIN_CHILD_VIRTUAL_OUTLINE, nOutlineId) + end + + -- copio il layer di base split + local nBaseSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_BASESPLIT) + local nSplitLayerId = EgtCopy( nBaseSplitLayerId, nAreaId) + EgtSetName( nSplitLayerId, WIN_SPLIT) + EgtSetStatus( nSplitLayerId, GDB_ST.OFF) + local vBaseSplitIds = EgtGetAllInGroup( nBaseSplitLayerId) + local vSplitIds = EgtGetAllInGroup( nSplitLayerId) + + -- aggiusto la quota degli split per allinearli all'outline + local dZMove = ( EgtSP( vParentOutlines[1]) - EgtSP( vSplitIds[1])) * Z_AX() + EgtMove( vSplitIds, dZMove * Z_AX()) + + -- aggiusto gli outlines e calcolo l'outline delle sottoaree null generate + local bGrid = EgtGetInfo( nAreaId, WIN_GRID_SPLIT, 'b') or false + if bGrid then + CalculateGridSplitOutline( nAreaId, vSplitIds) + else + CalculateSplitOutline( nAreaId, vSplitIds) + end + + local nSplitType = EgtGetInfo( vSplitIds[1], WIN_SPLITTYPE, 'i') + + if nSplitType == WIN_SPLITTYPES.FRENCH then + IdentifySashShape( nAreaId, nOutlineLayerId) + end + + -- se inglesina su entrambi i lati creo copia degli outline per le inglesine esterne + if nSplitType == WIN_SPLITTYPES.MUNTIN_FILL then + local nMuntinType = EgtGetInfo( nAreaId, WIN_MUNTINFILL_SIDE, 'i') + if nMuntinType == WIN_MUNTINFILL_SIDES.BOTH then + local bSlide = EgtGetInfo( EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_AREA .. '*'), WIN_SLIDE_WINDOW, 'b') or false + for i = 1, #vSplitIds do + local nId = EgtCopyGlob( vSplitIds[i], nSplitLayerId) + EgtSetInfo( vSplitIds[i], WIN_REF_MUNTIN, nId) + EgtSetInfo( vSplitIds[i], WIN_MUNTINFILL_SIDE, WIN_MUNTINFILL_SIDES.IN) + EgtSetInfo( nId, WIN_PROFILETYPE, EgtIf( bSlide, WIN_SLIDE .. '_', '') .. WIN_FILL_SPLIT_OUT) + EgtSetInfo( nId, WIN_MUNTINFILL_SIDE, WIN_MUNTINFILL_SIDES.OUT) + end + else + for i = 1, #vSplitIds do + EgtSetInfo( vSplitIds[i], WIN_MUNTINFILL_SIDE, nMuntinType) + end + end + end + + + -- SASH + elseif nAreaType == WIN_AREATYPES.SASH then + local nBaseOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_AREAOUTLINE) + local vOutlines = CalculateSashOutline( nAreaId, nBaseOutlineLayerId, nOutlineLayerId) + CalcOutlineDimensions( vOutlines, nAreaId) + -- ne verifico validità + VerifySashOutlines( vOutlines, nAreaId) + -- identifico la forma + IdentifySashShape( nAreaId, nOutlineLayerId) + -- disegno apertura + DrawOpening( nAreaId) + + + -- FILL + elseif nAreaType == WIN_AREATYPES.FILL then + CalculateFillOutline( nAreaId, nOutlineLayerId) + end +end + +--------------------------------------------------------------------- +local function CalculateFrameAreasOutlines( nAreaId) + + local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i') + + -- se area di telaio o split calcolo l'outline + if nAreaType == WIN_AREATYPES.FRAME or nAreaType == WIN_AREATYPES.SPLIT then + CalculateOutlineFromAreaOutline( nAreaId) + + -- se area anta o fill devo interrompere la ricerca + elseif nAreaType == WIN_AREATYPES.SASH or nAreaType == WIN_AREATYPES.FILL then + return + end + + local vChildrenAreas = EgtGetNameInGroup( nAreaId, WIN_AREA .. '*') + for i = 1, #vChildrenAreas do + CalculateFrameAreasOutlines( vChildrenAreas[i]) + end +end + +--------------------------------------------------------------------- +local function CalculateResidualAreaOutlines( nAreaId) + + local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i') + + if nAreaType == WIN_AREATYPES.SASH or nAreaType == WIN_AREATYPES.FILL then + CalculateOutlineFromAreaOutline( nAreaId) + + elseif nAreaType == WIN_AREATYPES.SPLIT then + -- devo calcolarla solo se non è già stato fatto ( quindi non è uno split che dipende dal telaio) + local nOutlineLayer = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE) + if not nOutlineLayer then + CalculateOutlineFromAreaOutline( nAreaId) + end + end + + local vChildAreas = EgtGetNameInGroup( nAreaId, WIN_AREA .. '*') + for i = 1, #vChildAreas do + CalculateResidualAreaOutlines( vChildAreas[i]) + end +end + +--------------------------------------------------------------------- +local function CalculateAreaOutline( nAreaId) + + -- calcolo l'outline del telaio e di tutti gli split ad esso riferiti + CalculateFrameAreasOutlines( nAreaId) + + -- se cambio profilo lo spostamento degli split per le misure luce/esterno anta potrebbe aver modificato la tipologia dei figli delle curve del telaio e di altri split, + -- quindi la aggiorno in base agli outlines appena calcolati ( e non più rispetto ai base outlines) + local bChangeProfile = EgtGetInfo( nAreaId, WIN_MIXED_WINDOW, 'b') + if bChangeProfile then + UpdateSplitTypes( nAreaId) + UpdateFrameTypes( nAreaId) + end + + -- calcolo gli outlines delle ante, dei vetri e degli split in essi contenuti + CalculateResidualAreaOutlines( nAreaId) +end + +--------------------------------------------------------------------- +-- funzione che cicla ricorsivamente su aree e sottoaree per assegnare i profili all'area +local function SetAreaProfiles( nAreaId) + + local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i') + if nAreaType == WIN_AREATYPES.FRAME or nAreaType == WIN_AREATYPES.SASH then + -- recupero i profili dalle curve di outline + local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE) + local vOutlines = EgtGetAllInGroup( nOutlineLayerId) + local sAreaName = EgtIf( nAreaType == WIN_AREATYPES.FRAME, WIN_FRAME, WIN_SASH) + local vProfiles = {} + for i = 1, #vOutlines do + vProfiles[i] = sAreaName .. '_' .. EgtGetInfo( vOutlines[i], WIN_PROFILETYPE) + end + EgtSetInfo( nAreaId, WIN_AREA_PROFILES, vProfiles) + + elseif nAreaType == WIN_AREATYPES.SPLIT then + local nSplitType = EgtGetInfo( nAreaId, WIN_SPLITTYPE, 'i') + if nSplitType ~= WIN_SPLITTYPES.FRENCH then + -- recupero area parent per capire se dentro telaio, anta o vetro + local nParentAreaId = EgtGetParent( nAreaId) + local nParentAreaType = EgtGetInfo( nParentAreaId, WIN_AREATYPE, 'i') + while nParentAreaType == WIN_AREATYPES.SPLIT or nParentAreaType == WIN_AREATYPES.NULL do + nParentAreaId = EgtGetParent( nParentAreaId) + nParentAreaType = EgtGetInfo( nParentAreaId, WIN_AREATYPE, 'i') + end + local sAreaName + if nParentAreaType == WIN_AREATYPES.FRAME then + sAreaName = WIN_FRAME + elseif nParentAreaType == WIN_AREATYPES.SASH then + sAreaName = WIN_SASH + else + sAreaName = WIN_FILL + end + + local nSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_SPLIT) + local vSplitIds = EgtGetAllInGroup( nSplitLayerId) + local bGridSplit = EgtGetInfo( nAreaId, WIN_GRID_SPLIT, 'b') or false + if bGridSplit then + -- recupero i profili distinguendoli per ordine di split + local tabProfiles = {} + for i = 1, #vSplitIds do + if not EgtExistsInfo( vSplitIds[i], WIN_REF_MUNTIN) then + local nOrder = EgtGetInfo( vSplitIds[i], WIN_GRIDSPLIT_ORDER, 'i') + local sProfile = sAreaName .. '_' .. EgtGetInfo( vSplitIds[i], WIN_PROFILETYPE) + if tabProfiles[nOrder+1] then + table.insert( tabProfiles[nOrder+1], sProfile) + else + tabProfiles[nOrder+1] = { sProfile} + end + end + end + -- salvo in info separate + for i = 1, #tabProfiles do + EgtSetInfo( nAreaId, WIN_AREA_PROFILES .. tostring( i-1), tabProfiles[i]) + end + else + -- recupero tutti i profili degli split + -- se ha info WIN_REF_MUNTIN significa che split è inglesina sia interna che esterna, non ha senso considerarla due volte anche se sono due outlines distinti perchè + -- lo split che la definisce è uno solo + local vProfiles = {} + for i = 1, #vSplitIds do + if not EgtExistsInfo( vSplitIds[i], WIN_REF_MUNTIN) then + table.insert( vProfiles, sAreaName .. '_' .. EgtGetInfo( vSplitIds[i], WIN_PROFILETYPE)) + end + end + EgtSetInfo( nAreaId, WIN_AREA_PROFILES, vProfiles) + end + end + end + + -- analizzo le sottoaree + local nChildAreaId = EgtGetFirstNameInGroup( nAreaId, WIN_AREA .. '*') + while nChildAreaId do + SetAreaProfiles( nChildAreaId) + nChildAreaId = EgtGetNextName( nChildAreaId, WIN_AREA .. '*') + end +end + + + +---------------------------------------------------------------------------------- +------------------------------ CALCOLO JOINTS ---------------------------------- +---------------------------------------------------------------------------------- +-- funzione che dato il tipo di giunzione e di pezzo ( orizzontale o verticale) restituisce se è corto, lungo o angolato +local function CalcPartJoint( nJointType, bHorizontal) + + if nJointType == WIN_JNT.ANGLED then + return WIN_PART_JNT.ANGLED + elseif nJointType == WIN_JNT.FULL_H then + if bHorizontal then + return WIN_PART_JNT.FULL + else + return WIN_PART_JNT.SHORT + end + elseif nJointType == WIN_JNT.FULL_V then + if bHorizontal then + return WIN_PART_JNT.SHORT + else + return WIN_PART_JNT.FULL + end + end +end + +--------------------------------------------------------------------- +local function CalcOutlineStartJoint( nOutlineId, nPrevOutlineId, vJoints) + + local nStartJoint + + if EgtGetName( nOutlineId) == WIN_BOTTOM then + nStartJoint = CalcPartJoint( vJoints[1], true) + elseif EgtGetName( nOutlineId) == WIN_RIGHT then + nStartJoint = CalcPartJoint( vJoints[2], false) + elseif EgtGetName( nOutlineId) == WIN_TOP then + nStartJoint = CalcPartJoint( vJoints[3], true) + -- correzione per caso a triangolo : se l'outline vicino è di tipo bottom, il corrente deve essere trattato come un pezzo verticale + if EgtGetName( nPrevOutlineId) == WIN_BOTTOM then + nStartJoint = CalcPartJoint( vJoints[2], false) + end + elseif EgtGetName( nOutlineId) == WIN_LEFT then + nStartJoint = CalcPartJoint( vJoints[4] or vJoints[3], false) -- ( vJoints[3] per gestire caso a triangolo) + end + + -- eventuali correzioni : + -- a) forzatura a bisettrice se elementi in tangenza ( entro 6°) o dello stesso tipo + if nStartJoint ~= WIN_PART_JNT.ANGLED then + if EgtEV( nPrevOutlineId) * EgtSV( nOutlineId) > s_dAngledCos or EgtGetName( nOutlineId) == EgtGetName( nPrevOutlineId) then + nStartJoint = WIN_PART_JNT.ANGLED + end + end + + -- b) forzatura a short se incontro con soglia + if EgtGetInfo( nPrevOutlineId, WIN_THRESHOLD, 'b') then + nStartJoint = WIN_PART_JNT.SHORT + end + + -- c) forzatura ad angled se cambio profilo sul punto di incontro + local nProfileChange = EgtGetInfo( nOutlineId, WIN_PRF_CHANGE, 'i') + local nProfileChangeP = EgtGetInfo( nPrevOutlineId, WIN_PRF_CHANGE, 'i') + if nProfileChange == WIN_PRF_CHANGE_TYPES.IN and nProfileChangeP == WIN_PRF_CHANGE_TYPES.IN then + -- per vedere se il cambio profilo è sul punto di incontro verifico se hanno uno split con cambio profilo sull'estremo in comune + local vSplits1 = EgtGetInfo( nOutlineId, WIN_CHILD_PRFCHANGE_SPLIT, 'vi') + local vSplits2 = EgtGetInfo( nPrevOutlineId, WIN_CHILD_PRFCHANGE_SPLIT, 'vi') + for i = 1, #vSplits1 do + for j = 1, #vSplits2 do + if vSplits1[i] == vSplits2[j] then + return WIN_PART_JNT.ANGLED + end + end + end + end + + return nStartJoint +end + +--------------------------------------------------------------------- +local function CalcOutlineEndJoint( nOutlineId, nNextOutlineId, vJoints) + + local nEndJoint + + if EgtGetName( nOutlineId) == WIN_BOTTOM then + nEndJoint = CalcPartJoint( vJoints[2], true) + elseif EgtGetName( nOutlineId) == WIN_RIGHT then + nEndJoint = CalcPartJoint( vJoints[3], false) + elseif EgtGetName( nOutlineId) == WIN_TOP then + nEndJoint = CalcPartJoint( vJoints[4] or vJoints[3], true) -- ( vJoints[3] per gestire caso a triangolo) + -- correzione per caso a triangolo : se l'outline vicino è di tipo bottom, il corrente deve essere trattato come un pezzo verticale + if EgtGetName( nNextOutlineId) == WIN_BOTTOM then + nEndJoint = CalcPartJoint( vJoints[1], false) + end + elseif EgtGetName( nOutlineId) == WIN_LEFT then + nEndJoint = CalcPartJoint( vJoints[1], false) + end + + -- eventuali correzioni : + -- a) forzatura a bisettrice se elementi in tangenza ( entro 6°) o dello stesso tipo + if nEndJoint ~= WIN_PART_JNT.ANGLED then + if EgtEV( nOutlineId) * EgtSV( nNextOutlineId) > s_dAngledCos or EgtGetName( nOutlineId) == EgtGetName( nNextOutlineId) then + nEndJoint = WIN_PART_JNT.ANGLED + end + end + + -- b) forzatura a short se incontro con soglia + if EgtGetInfo( nNextOutlineId, WIN_THRESHOLD, 'b') then + nEndJoint = WIN_PART_JNT.SHORT + end + + -- c) forzatura ad angled se cambio profilo sul punto di incontro + local nProfileChange = EgtGetInfo( nOutlineId, WIN_PRF_CHANGE, 'i') + local nProfileChangeN = EgtGetInfo( nNextOutlineId, WIN_PRF_CHANGE, 'i') + if nProfileChange == WIN_PRF_CHANGE_TYPES.IN and nProfileChangeN == WIN_PRF_CHANGE_TYPES.IN then + -- per vedere se il cambio profilo è sul punto di incontro verifico se hanno uno split con cambio profilo sull'estremo in comune + local vSplits1 = EgtGetInfo( nOutlineId, WIN_CHILD_PRFCHANGE_SPLIT, 'vi') + local vSplits2 = EgtGetInfo( nNextOutlineId, WIN_CHILD_PRFCHANGE_SPLIT, 'vi') + for i = 1, #vSplits1 do + for j = 1, #vSplits2 do + if vSplits1[i] == vSplits2[j] then + return WIN_PART_JNT.ANGLED + end + end + end + end + + return nEndJoint +end + +--------------------------------------------------------------------- +local function GetOutlineJoints( vOutlineIds, nAreaId) local vJoints = EgtGetInfo( nAreaId, WIN_JOINTS, 'vi') + for i = 1, #vOutlineIds do + local nPrevIdx = EgtIf( i == 1, #vOutlineIds, i - 1) + local nNextIdx = EgtIf( i == #vOutlineIds, 1, i + 1) + local nStartJoint = CalcOutlineStartJoint( vOutlineIds[i], vOutlineIds[nPrevIdx], vJoints) + local nEndJoint = CalcOutlineEndJoint( vOutlineIds[i], vOutlineIds[nNextIdx], vJoints) + EgtSetInfo( vOutlineIds[i], WIN_STARTJOINT, nStartJoint) + EgtSetInfo( vOutlineIds[i], WIN_ENDJOINT, nEndJoint) + end +end + + +---------------------------------------------------------------------------------- +------------------------------ CREAZIONE 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.SPLIT or nParentType == WIN_AREATYPES.NULL do + nParentId = EgtGetParent( nParentId) + nParentType = EgtGetInfo( nParentId, WIN_AREATYPE, 'i') + end + sName = EgtGetInfo( nParentId, WIN_AREA_NAME) + + if nAreaType == WIN_AREATYPES.FILL then + sName = sName .. '_' .. WIN_FILL + EgtSetInfo( nAreaId, WIN_AREA_NAME, sName) + end + end + + return sName +end + +--------------------------------------------------------------------- +local function CreateOutlinePart( nOutlineId, sName, dDim, nBottomRail) + + -- se soglia ignoro + local bThreshold = EgtGetInfo( nOutlineId or GDB_ID.NULL, WIN_THRESHOLD, 'b') or false + if bThreshold then + return + end + + -- creo pezzo + local nPartId = EgtGroup( GDB_ID.ROOT) + + -- creo riferimenti tra pezzo e outline + EgtSetInfo( nPartId, WIN_REF_OUTLINE, nOutlineId) + if nBottomRail then + -- aggiorno i riferimenti del bottomrail + AddInfo( nOutlineId, WIN_REF_BOTTOMRAIL_PART, nPartId) + EgtSetInfo( nPartId, WIN_PART_TYPE, WIN_PART_TYPES.BOTTOMRAIL) + EgtSetInfo( nPartId, WIN_BOTTOMRAIL, nBottomRail) + else + EgtSetInfo( nOutlineId, WIN_REF_PART, nPartId) + EgtSetInfo( nPartId, WIN_PART_TYPE, WIN_PART_TYPES.STD) + end + + -- imposto nome + local sOutlineName = EgtIf( nBottomRail, WIN_BOTTOMRAIL .. '_' .. tostring( nBottomRail), EgtGetName( nOutlineId)) + local sPartName = sName .. '_' .. sOutlineName + EgtSetName( nPartId, sPartName) + + -- imposto colore + if sOutlineName == WIN_BOTTOM or sOutlineName == WIN_TOP or nBottomRail 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 + + -- creo il profilo associato al pezzo con la dimensione opportuna + CreatePartProfile( nPartId, nOutlineId, dDim, nBottomRail) + + return nPartId +end + +--------------------------------------------------------------------- +local function CreatePartsFromOutlines( vOutlines, nAreaId, sName) + + -- calcolo le giunzioni + GetOutlineJoints( vOutlines, nAreaId) + + -- creo i pezzi per ogni curva + for i = 1, #vOutlines do + local dDim = EgtGetInfo( vOutlines[i], WIN_PART_DIM, 'd') + CreateOutlinePart( vOutlines[i], sName, dDim) + + if EgtGetName( vOutlines[i]) == WIN_BOTTOM then + local nBottomRail = EgtGetInfo( vOutlines[i], WIN_BOTTOMRAIL, 'i') or 0 + if nBottomRail > 0 then + local vBottomRailDim = EgtGetInfo( vOutlines[i], WIN_BOTTOMRAIL .. WIN_PART_DIM, 'vd') + for j = 1, nBottomRail do + CreateOutlinePart( vOutlines[i], sName, vBottomRailDim[j], j) + end + end + end + end +end + +--------------------------------------------------------------------- +local function CreateFillPartFromArea( nAreaId, sName) + + local nPartId = EgtGroup( GDB_ID.ROOT) + -- inserisco riferimento alla sua area + EgtSetInfo( nPartId, WIN_AREA, nAreaId) + + -- imposto nome del pezzo + EgtSetName( nPartId, sName) + EgtSetInfo( nPartId, WIN_PART_TYPE, WIN_PART_TYPES.FILL) + + -- imposto colore e tipologia + local nFillType = EgtGetInfo( nAreaId, WIN_FILLTYPE, 'i') + 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 + + return nPartId +end + +--------------------------------------------------------------------- +-- funzione che crea ricorsivamente i pezzi con i relativi profili +local function CreateAreaParts( nAreaId) + + local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i') + local sName = CalcPartName( nAreaId, nAreaType) + + -- FRAME + if nAreaType == WIN_AREATYPES.FRAME then + local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE) + local vOutlines = EgtGetAllInGroup( nOutlineLayerId) + CreatePartsFromOutlines( vOutlines, nAreaId, sName) + + -- SPLIT + elseif nAreaType == WIN_AREATYPES.SPLIT then + if EgtGetInfo( nAreaId, WIN_SPLITTYPE, 'i') ~= WIN_SPLITTYPES.FRENCH then + local nSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_SPLIT) + local vSplits = EgtGetAllInGroup( nSplitLayerId) + for i = 1, #vSplits do + local dDim = EgtGetInfo( vSplits[i], WIN_PART_DIM, 'd') + CreateOutlinePart( vSplits[i], sName, dDim) + end + end + + -- SASH + elseif nAreaType == WIN_AREATYPES.SASH then + local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE) + local vOutlines = EgtGetAllInGroup( nOutlineLayerId) + CreatePartsFromOutlines( vOutlines, nAreaId, sName) + + -- FILL + elseif nAreaType == WIN_AREATYPES.FILL then + CreateFillPartFromArea( nAreaId, sName) + end + + -- analizzo le sottoaree + local vAreas = EgtGetNameInGroup( nAreaId, WIN_AREA .. '*') + for i = 1, #vAreas do + CreateAreaParts( vAreas[i]) + end +end + + + +---------------------------------------------------------------------------------- +------------------------ PREV & NEXT OUTLINES ---------------------------------- +---------------------------------------------------------------------------------- +local function TestSplitTrimOutlines( nOutlineId, nSplitType, nTrimOutline, tabOutlines, nMainProfile, b3Profile, nGrpTmp, bPrevOrNext) + + local vTrimOutlines = {} + + -- 1) recupero le curve da testare : + -- a) curva individuata dall'intersezione dello split con l'outline + local vTestOutlines = { tabOutlines[nTrimOutline]} + + -- b) curve vicine a quella individuata dall'intersezione che interferiscono con lo split ( guardando interferenza grossolana dei box dei pezzi) + -- creo il box della curva di split + local nOutlineCopyId = EgtCopyGlob( nOutlineId, nGrpTmp) + if bPrevOrNext then + EgtTrimCurveEndAtParam( nOutlineCopyId, 0.5) + else + EgtTrimCurveStartAtParam( nOutlineCopyId, 0.5) + end + local b3Split, frSplit = CreateTestBoxFromOutline( nOutlineCopyId, nMainProfile, b3Profile) + + -- curve precedenti + local nTestCurve = EgtGetPrev( nTrimOutline) or EgtGetLastInGroup( EgtGetParent( nTrimOutline)) + local bInters = true + while bInters and nTestCurve ~= nTrimOutline do + -- verifico interferenza tra i box + if Overlaps( tabOutlines[nTestCurve].b3Box, tabOutlines[nTestCurve].frRef, b3Split, frSplit) then + table.insert( vTestOutlines, 1, tabOutlines[nTestCurve]) + nTestCurve = EgtGetPrev( nTestCurve) or EgtGetLastInGroup( EgtGetParent( nTestCurve)) + else + bInters = false + end + end + + -- curve successive ( solo se non ho già considerato tutto il loop, potrebbe capitare a causa di archi il cui box non è ottimizzato con un frame) + if nTestCurve ~= nTrimOutline then + nTestCurve = EgtGetNext( nTrimOutline) or EgtGetFirstInGroup( EgtGetParent( nTrimOutline)) + bInters = true + while bInters and nTestCurve ~= nTrimOutline do + -- verifico interferenza tra i box + if Overlaps( tabOutlines[nTestCurve].b3Box, tabOutlines[nTestCurve].frRef, b3Split, frSplit) then + table.insert( vTestOutlines, tabOutlines[nTestCurve]) + nTestCurve = EgtGetNext( nTestCurve) or EgtGetFirstInGroup( EgtGetParent( nTestCurve)) + else + bInters = false + end + end + end + + if #vTestOutlines == 1 then + return { vTestOutlines[1].nId} + end + + -- 2) testo le curve controllando intersezione tra le superfici dei pezzi + -- creo il solido principale + local dExtraLen = b3Profile:getDimX() + local nMainSurf + if nSplitType == WIN_SPLITTYPES.MIXED then + -- nel caso di profilo split mixed non è definita una sezione quindi devo costruirla recuperando i semiprofili in in base alla tipologia di figli sull'estremo + local nSemiProfile1 = EgtGetFirstNameInGroup( nMainProfile, WIN_IN .. '1') + if not nSemiProfile1 then + local nChildrenType1 = EgtGetInfo( nOutlineId, EgtIf( bPrevOrNext, WIN_MIXED_START_CHILDREN, WIN_MIXED_END_CHILDREN) .. '1', 'i') + local sSemiProfileName = EgtIf( nChildrenType1 == WIN_CHILDREN_TYPES.SASH, WIN_SASH, WIN_FILL) .. WIN_IN .. '1' + nSemiProfile1 = EgtGetFirstNameInGroup( nMainProfile, sSemiProfileName) + end + local nSemiProfile2 = EgtGetFirstNameInGroup( nMainProfile, WIN_IN .. '2') + if not nSemiProfile2 then + local nChildrenType2 = EgtGetInfo( nOutlineId, EgtIf( bPrevOrNext, WIN_MIXED_START_CHILDREN, WIN_MIXED_END_CHILDREN) .. '2', 'i') + local sSemiProfileName = EgtIf( nChildrenType2 == WIN_CHILDREN_TYPES.SASH, WIN_SASH, WIN_FILL) .. WIN_IN .. '2' + nSemiProfile2 = EgtGetFirstNameInGroup( nMainProfile, sSemiProfileName) + end + + local nSection = EgtCurveCompo( nGrpTmp, nSemiProfile1, false) + EgtAddCurveCompoLine( nSection, EgtSP( nSemiProfile2, GDB_ID.ROOT), GDB_RT.GLOB) + EgtAddCurveCompoCurve( nSection, nSemiProfile2, false) + EgtCloseCurveCompo( nSection) + + nMainSurf = CreateProfileSurfById( nOutlineId, nMainProfile, nSection, 4 * dExtraLen, nGrpTmp) + + else + nMainSurf = CreateProfileSurf( nOutlineId, nMainProfile, WIN_SECTION, 4 * dExtraLen, nGrpTmp) + end + EgtCutSurfTmPlane( nMainSurf, EgtMP( nOutlineId), EgtIf( bPrevOrNext, 1, -1) * EgtSV( nOutlineId)) + + -- recupero profili delle curve di test per i conti + local vProfiles = {} + local vsCtrIn = {} + for i = 1, #vTestOutlines do + vProfiles[i] = vTestOutlines[i].nProfile + vsCtrIn[i] = GetProfileCtrIn( vTestOutlines[i].nId, nOutlineId, vProfiles[i], bPrevOrNext) + end + + -- testo le curve + for i = 1, #vTestOutlines do + -- creo la superficie di test limitandola con le sue vicine + local nTestSurf = CreateProfileSurf( abs( vTestOutlines[i].nId), vProfiles[i], vsCtrIn[i], 4 * dExtraLen, nGrpTmp) + + if i > 1 then + if AreSameVectorApprox( EgtEV( abs( vTestOutlines[i-1].nId)), EgtSV( abs( vTestOutlines[i].nId))) then + EgtCutSurfTmPlane( nTestSurf, EgtEP( abs( vTestOutlines[i-1].nId)), - EgtEV( abs( vTestOutlines[i-1].nId)), false) + else + local nTrimSurf = CreateProfileSurf( abs( vTestOutlines[i-1].nId), vProfiles[i-1], WIN_OFST .. vsCtrIn[i-1], 4 * dExtraLen, nGrpTmp) + EgtSurfTmCut( nTestSurf, nTrimSurf, true, false) + end + end + if i < #vTestOutlines then + if AreSameVectorApprox( EgtEV( abs( vTestOutlines[i].nId)), EgtSV( abs( vTestOutlines[i+1].nId))) then + EgtCutSurfTmPlane( nTestSurf, EgtEP( abs( vTestOutlines[i].nId)), EgtEV( abs( vTestOutlines[i].nId)), false) + else + local nTrimSurf = CreateProfileSurf( abs( vTestOutlines[i+1].nId), vProfiles[i+1], WIN_OFST .. vsCtrIn[i+1], 4 * dExtraLen, nGrpTmp) + EgtSurfTmCut( nTestSurf, nTrimSurf, true, false) + end + end + + -- calcolo intersezione con il solido : se c'è intersezione è una vera curva di trim, altrimenti non va considerata + local nId, _, nCrvCnt = EgtSurfTmSurfTmInters( nMainSurf, nTestSurf, nGrpTmp) + if nId and nCrvCnt > 0 then + table.insert( vTrimOutlines, vTestOutlines[i].nId) + end + end + + return vTrimOutlines +end + +------------------------------------------------------------------- +-- funzione che recupera gli outline precedenti e successivi degli split +local function GetSplitsPrevNextOutline( vSplitIds, vOutlineIds) + + local nGrpTmp = EgtGroup( GDB_ID.ROOT) + + -- ad ogni outline dell'area di split associo l'outline non virtuale corrispondente ( per rendere più solidi i conti successivi) + local tabOutlines = {} + for i = 1, #vOutlineIds do + local nId = GetNonVirtualOutline( vOutlineIds[i]) + -- calcolo il suo box + local nProfileId = GetOutlineProfileId( abs( nId)) + local b3Profile = GetProfileLocalBox( nProfileId) + local b3Box, frRef = CreateTestBoxFromOutline( abs( nId), nProfileId, b3Profile) + tabOutlines[vOutlineIds[i]] = { nId = nId, frRef = frRef, b3Box = b3Box, nProfile = nProfileId} + end + + -- per ogni split controllo la validità delle curve prev/next trovate dall'intersezione degli outlines e la validità di eventuali curve vicine verificando l'interferenza tra i profili + for i = 1, #vSplitIds do + + local nMainProfile = GetOutlineProfileId( vSplitIds[i]) + local b3Profile = GetProfileLocalBox( nMainProfile) + local nSplitType = EgtGetInfo( vSplitIds[i], WIN_SPLITTYPE, 'i') + + -- prev + if not EgtExistsInfo( vSplitIds[i], WIN_PREV_OUTLINES) then + local nPrevOutlineId = EgtGetInfo( vSplitIds[i], WIN_SPLIT_STARTINTERS, 'i') + local vPrevOutlineIds = TestSplitTrimOutlines( vSplitIds[i], nSplitType, nPrevOutlineId, tabOutlines, nMainProfile, b3Profile, nGrpTmp, true) + EgtSetInfo( vSplitIds[i], WIN_PREV_OUTLINES, vPrevOutlineIds) + -- setto tutte le giunzioni a short + local vStartJoints = {} + for j = 1, #vPrevOutlineIds do + vStartJoints[j] = WIN_PART_JNT.SHORT + end + EgtSetInfo( vSplitIds[i], WIN_STARTJOINT, vStartJoints) + end + + -- next + if not EgtExistsInfo( vSplitIds[i], WIN_NEXT_OUTLINES) then + local nNextOutlineId = EgtGetInfo( vSplitIds[i], WIN_SPLIT_ENDINTERS, 'i') + local vNextOutlineIds = TestSplitTrimOutlines( vSplitIds[i], nSplitType, nNextOutlineId, tabOutlines, nMainProfile, b3Profile, nGrpTmp, false) + EgtSetInfo( vSplitIds[i], WIN_NEXT_OUTLINES, vNextOutlineIds) + local vEndJoints = {} + for j = 1, #vNextOutlineIds do + vEndJoints[j] = WIN_PART_JNT.SHORT + end + EgtSetInfo( vSplitIds[i], WIN_ENDJOINT, vEndJoints) + end + end + + EgtErase( nGrpTmp) +end + +--------------------------------------------------------------------- +local function GetSashPrevNextOutlines( nAreaId) + + local vJoints = EgtGetInfo( nAreaId, WIN_JOINTS, 'vi') + local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE) + local vOutlineIds = EgtGetAllInGroup( nOutlineLayerId) + for i = 1, #vOutlineIds do if EgtGetInfo( vOutlineIds[i], WIN_EXTRA_CRV, 'b') then - -- non c'è bisogno di settare prev/next perchè il pezzo viene ignorato + -- non ha bisogno di prev/next perchè il pezzo viene ignorato else -- a) prev @@ -2956,261 +4002,97 @@ local function GetSashPrevNextOutlines( vOutlineIds, nOutlineLayerId, nAreaId) end end - ------------------------------- FILL ------------------------------- --------------------------------------------------------------------- -local function CalculateFillOutline( nAreaId, nOutlineLayerId) - - -- recupero area parent di tipo telaio/anta che la contiene - local nParentArea = EgtGetParent( nAreaId) - local nAreaType = EgtGetInfo( nParentArea, WIN_AREATYPE, 'i') - while nAreaType ~= WIN_AREATYPES.FRAME and nAreaType ~= WIN_AREATYPES.SASH do - nParentArea = EgtGetParent( nParentArea) - nAreaType = EgtGetInfo( nParentArea, WIN_AREATYPE, 'i') - end - - -- 1) calcolo l'area complessiva di fill definita dal suo parent - local nParentOutlineLayer = EgtGetFirstNameInGroup( nParentArea, WIN_OUTLINE) - local dDeltaZ = 0 - local vParentOutlines = EgtGetAllInGroup( nParentOutlineLayer) - local vParentOffs = {} - -- calcolo gli offset - for i = 1, #vParentOutlines do - -- recupero il suo profilo per calcolare l'offset perpendicolare - local nParentProfileId = GetOutlineProfileId( vParentOutlines[i], true) - local dOverlap = EgtGetInfo( nParentProfileId, WIN_FILLOVERLAP, 'd') - if dOverlap then - local b3FrameProfile = GetProfileLocalBox( nParentProfileId) - local dDimRef = b3FrameProfile:getMin():getX() - -- verifico se contributo per bottomrail - local dRailOffs = EgtGetInfo( nParentProfileId, WIN_RAILOFFS, 'd') or 0 - vParentOffs[i] = abs( dDimRef) - dOverlap + dRailOffs - -- movimento in z - if dDeltaZ < GEO.EPS_SMALL then - dDeltaZ = EgtGetInfo( nParentProfileId, WIN_FILLDELTA, 'd') - end - end - end - -- creo le curve di outlines - for i = 1, #vParentOutlines do - -- copio la curva di outline del parent - local nOutlineId = EgtCopy( vParentOutlines[i], nOutlineLayerId) - EgtSetInfo( nOutlineId, WIN_SOU_OUTLINE, vParentOutlines[i]) - -- applico offset - if vParentOffs[i] then - EgtOffsetCurve( nOutlineId, - vParentOffs[i]) - else - -- se non ha offset definito è un pezzo che verrà tagliato da uno split ma, affinchè la forma del telaio sia coerente, devo applicare lo stesso offset a curve - -- che sono in tangenza - local nPrevIdx = EgtIf( i == 1, #vParentOutlines, i-1) - local nNextIdx = EgtIf( i == #vParentOutlines, 1, i+1) - if AreSameVectorApprox( EgtSV( vParentOutlines[i]), EgtEV( vParentOutlines[nPrevIdx])) then - while not vParentOffs[nPrevIdx] do - nPrevIdx = EgtIf( nPrevIdx == 1, #vParentOutlines, nPrevIdx-1) - end - EgtOffsetCurve( nOutlineId, - vParentOffs[nPrevIdx]) - vParentOffs[i] = vParentOffs[nPrevIdx] - elseif AreSameVectorApprox( EgtEV( vParentOutlines[i]), EgtSV( vParentOutlines[nNextIdx])) then - while not vParentOffs[nNextIdx] do - nNextIdx = EgtIf( nNextIdx == #vParentOutlines, 1, nNextIdx+1) - end - EgtOffsetCurve( nOutlineId, - vParentOffs[nNextIdx]) - vParentOffs[i] = vParentOffs[nNextIdx] - end - end - end - -- accorcio gli offset - local vCrvs = TrimOrderedCurves( EgtGetAllInGroup( nOutlineLayerId), true) - -- applico spostamento verticale - EgtMove( vCrvs, Z_AX() * dDeltaZ) - - - -- 2) taglio con split - local nParentType = EgtGetInfo( EgtGetParent( nAreaId), WIN_AREATYPE, 'i') - if nParentType ~= WIN_AREATYPES.NULL then - return - end - -- creo bordo complessivo dell'outline, salvando le info come temp prop della curva per non perderle - local vSouOutlines = {} - for i = 1, #vCrvs do - vSouOutlines[i] = EgtGetInfo( vCrvs[i], WIN_SOU_OUTLINE, 'i') - end - local nCompo = EgtCurveCompo( nOutlineLayerId, vCrvs) - for i = 0, #vCrvs - 1 do - EgtCurveCompoSetTempProp( nCompo, i, vSouOutlines[i+1]) - end - - -- recupero gli split che definiscono l'area fill cercando gli split da cui derviano gli elementi dell'area null parent - local vSplitIds = {} - local nNullOutlineLayer = EgtGetFirstNameInGroup( EgtGetParent( nAreaId), WIN_OUTLINE) - local vNullOutlines = EgtGetAllInGroup( nNullOutlineLayer) - for i = 1, #vNullOutlines do - local nSouOutline = GetNonVirtualOutline( vNullOutlines[i]) - if EgtGetName( abs( nSouOutline)) == WIN_SPLIT then - table.insert( vSplitIds, nSouOutline) - end - end - - -- li ordino per id crescente in modo da effettuare i tagli nell'ordine corretto - table.sort( vSplitIds, function ( a, b) return abs( a) < abs( b) end) - - for i = 1, #vSplitIds do - - -- creo la curva di outline corrispondente allo split - local nOutlineId = EgtCopy( abs( vSplitIds[i]), nOutlineLayerId) - if vSplitIds[i] < 0 then - EgtInvertCurve( nOutlineId) - end - -- calcolo gli offset - local nParentProfileId = GetOutlineProfileId( abs( vSplitIds[i]), true) - local b3FrameProfile = GetProfileLocalBox( nParentProfileId) - local dOverlap = EgtGetInfo( nParentProfileId, WIN_FILLOVERLAP, 'd') - local dDimRef = EgtIf( vSplitIds[i] < 0, b3FrameProfile:getMax():getX(), b3FrameProfile:getMin():getX()) - local dOffs = abs( dDimRef) - dOverlap - EgtOffsetCurve( nOutlineId, - dOffs) - -- movimento in z - local dFillZOffset = EgtGetInfo( nParentProfileId, WIN_FILLDELTA, 'd') - EgtMove( nOutlineId, Z_AX() * dFillZOffset) - - -- aggiorno la curva complessiva di outline con la curva appena calcolata - local ptS = EgtIP( nOutlineId, nCompo, EgtSP( nOutlineId)) - local ptE = EgtIP( nOutlineId, nCompo, EgtEP( nOutlineId)) - local dBorderParS = EgtCurveParamAtPoint( nCompo, ptS) - local dBorderParE = EgtCurveParamAtPoint( nCompo, ptE) - EgtTrimCurveStartEndAtParam( nCompo, dBorderParE, dBorderParS) - local dSplitParS = EgtCurveParamAtPoint( nOutlineId, ptS) - local dSplitParE = EgtCurveParamAtPoint( nOutlineId, ptE) - EgtTrimCurveStartEndAtParam( nOutlineId, dSplitParS, dSplitParE) - EgtAddCurveCompoCurve( nCompo, nOutlineId) - local _, dParEnd = EgtCurveDomain( nCompo) - EgtCurveCompoSetTempProp( nCompo, dParEnd - 1, vSplitIds[i]) - end - - -- spezzo la curva di outline nelle sue sottocurve e riassegno le info - local vTempProps = EgtCurveCompoGetTempProp( nCompo) - local nCrv, nCnt = EgtExplodeCurveCompo( nCompo) - for i = 0, nCnt - 1 do - EgtSetInfo( nCrv + i, WIN_SOU_OUTLINE, vTempProps[i+1]) - end -end - ---------------------------------------------------------------------- ---------------------------------------------------------------------- --- funzione che calcola l'outline dal base outline e i pezzi associati -local function CalculateOutlineFromAreaOutline( nAreaId) +local function GetAreaPrevNextOutlines( nAreaId) local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i') - local sName = CalcPartName( nAreaId, nAreaType) - - -- se area null il suo outline è già stato calcolato dalla sua area split parent - if nAreaType == WIN_AREATYPES.NULL then - return - end - - -- creo gruppo per outline - local nOutlineLayerId = EgtGroup( nAreaId) - EgtSetName( nOutlineLayerId, WIN_OUTLINE) - EgtSetStatus( nOutlineLayerId, GDB_ST.OFF) - -- FRAME if nAreaType == WIN_AREATYPES.FRAME then - -- l'outline è la copia del base outline - local nBaseOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_AREAOUTLINE) - local nBaseOutlineId = EgtGetFirstInGroup( nBaseOutlineLayerId) - while nBaseOutlineId do - EgtCopyGlob( nBaseOutlineId, nOutlineLayerId) - nBaseOutlineId = EgtGetNext( nBaseOutlineId) - end + local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE) local vOutlines = EgtGetAllInGroup( nOutlineLayerId) - GetFramePrevNextOutline( vOutlines, nOutlineLayerId) - -- creo i pezzi - CreatePartsFromOutlines( vOutlines, nAreaId, sName) + for i = 2, #vOutlines - 1 do + EgtSetInfo( vOutlines[i], WIN_PREV_OUTLINES, vOutlines[i-1]) + EgtSetInfo( vOutlines[i], WIN_NEXT_OUTLINES, vOutlines[i+1]) + end + -- gestione particolare per primo e ultimo + EgtSetInfo( vOutlines[1], WIN_PREV_OUTLINES, vOutlines[#vOutlines]) + EgtSetInfo( vOutlines[1], WIN_NEXT_OUTLINES, vOutlines[2]) + EgtSetInfo( vOutlines[#vOutlines], WIN_PREV_OUTLINES, vOutlines[#vOutlines - 1]) + EgtSetInfo( vOutlines[#vOutlines], WIN_NEXT_OUTLINES, vOutlines[1]) -- SPLIT elseif nAreaType == WIN_AREATYPES.SPLIT then + if EgtGetInfo( nAreaId, WIN_SPLITTYPE, 'i') ~= WIN_SPLITTYPES.FRENCH then + local nSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_SPLIT) + local vSplits = EgtGetAllInGroup( nSplitLayerId) + + -- se inglesine da entrambi i lati calcolo prev/next solo per quelle interne, quelle esterne verranno sistemate in base a quelle interne di cui sono copia + local bFillMuntin = false + if EgtGetInfo( vSplits[1], WIN_SPLITTYPE, 'i') == WIN_SPLITTYPES.MUNTIN_FILL and EgtGetInfo( nAreaId, WIN_MUNTINFILL_SIDE, 'i') == WIN_MUNTINFILL_SIDES.BOTH then + bFillMuntin = true + local vInSplits = {} + for i = 1, #vSplits do + local nSide = EgtGetInfo( vSplits[i], WIN_MUNTINFILL_SIDE, 'i') + if nSide == WIN_MUNTINFILL_SIDES.OUT then + break + end + vInSplits[i] = vSplits[i] + end + vSplits = vInSplits + end - -- l'outline è copia del parent outline - local nParentId = EgtGetParent( nAreaId) - if EgtGetInfo( nParentId, WIN_AREATYPE, 'i') == WIN_AREATYPES.FILL then - -- se inglesina il parent è un vetro. Il pezzo però non va tagliato con il vetro ma con l'elemento che contiene il vetro, quindi considero come outline quello del parent del vetro - nParentId = EgtGetParent( nParentId) - end - local nParentOutlineId = EgtGetFirstNameInGroup( nParentId, WIN_OUTLINE) - local vParentOutlines = EgtGetAllInGroup( nParentOutlineId) - for i = 1, #vParentOutlines do - local nOutlineId = EgtCopyGlob( vParentOutlines[i], nOutlineLayerId) - EgtSetInfo( nOutlineId, WIN_SOU_OUTLINE, vParentOutlines[i]) - end - - -- copio il layer di base split - local nBaseSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_BASESPLIT) - local nSplitLayerId = EgtCopy( nBaseSplitLayerId, nAreaId) - EgtSetName( nSplitLayerId, WIN_SPLIT) - EgtSetStatus( nSplitLayerId, GDB_ST.OFF) - local vBaseSplitIds = EgtGetAllInGroup( nBaseSplitLayerId) - local vSplitIds = EgtGetAllInGroup( nSplitLayerId) - for i = 1, #vSplitIds do - -- TODO verificare se possibile evitare questa associazione ( calcolo sash outline) - EgtSetInfo( vSplitIds[i], WIN_COPY, vBaseSplitIds[i]) - EgtSetInfo( vBaseSplitIds[i], WIN_COPY, vSplitIds[i]) - end - - -- aggiusto la quota degli split per allinearli all'outline - local dZMove = ( EgtSP( vParentOutlines[1]) - EgtSP( vSplitIds[1])) * Z_AX() - EgtMove( vSplitIds, dZMove * Z_AX()) - - -- aggiusto gli outlines e calcolo l'outline delle sottoaree null generate - local bGrid = EgtGetInfo( nAreaId, WIN_GRID_SPLIT, 'b') or false - if bGrid then - CalculateGridSplitOutline( nAreaId, vSplitIds, sName) - else - CalculateSplitOutline( nAreaId, vSplitIds, sName) - end - - local nSplitType = EgtGetInfo( vSplitIds[1], WIN_SPLITTYPE, 'i') - - if nSplitType == WIN_SPLITTYPES.FRENCH then - IdentifySashShape( nAreaId, nOutlineLayerId) - end - - -- se inglesina su entrambi i lati creo copia degli outline per le inglesine esterne - if nSplitType == WIN_SPLITTYPES.MUNTIN_FILL then - local nMuntinType = EgtGetInfo( nAreaId, WIN_MUNTINFILL_SIDE, 'i') - if nMuntinType == WIN_MUNTINFILL_SIDES.BOTH then - local bSlide = EgtGetInfo( EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_AREA .. '*'), WIN_SLIDE_WINDOW, 'b') or false - for i = 1, #vSplitIds do - local nId = EgtCopyGlob( vSplitIds[i], nSplitLayerId) - EgtSetInfo( vSplitIds[i], WIN_REF_MUNTIN, nId) - EgtSetInfo( nId, WIN_PROFILETYPE, EgtIf( bSlide, WIN_SLIDE .. '_', '') .. WIN_FILL_SPLIT_OUT) - local dDim = EgtGetInfo( nId, WIN_PART_DIM, 'd') - CreateOutlinePart( nId, sName, dDim) - - EgtSetInfo( vSplitIds[i], WIN_MUNTINFILL_SIDE, WIN_MUNTINFILL_SIDES.IN) - EgtSetInfo( nId, WIN_MUNTINFILL_SIDE, WIN_MUNTINFILL_SIDES.OUT) - + -- se split a griglia + local bGrid = EgtGetInfo( nAreaId, WIN_GRID_SPLIT, 'b') or false + if bGrid then + local vVirtualAreas = EgtGetNameInGroup( nAreaId, WIN_VIRTUAL_AREA) + -- raggruppo gli split per ordine + local tabGrid = {} + for i = 1, #vSplits do + local nOrder = EgtGetInfo( vSplits[i], WIN_GRIDSPLIT_ORDER, 'i') + if tabGrid[nOrder] then + table.insert( tabGrid[nOrder], vSplits[i]) + else + tabGrid[nOrder] = { vSplits[i]} + end + end + + for i = 0, #tabGrid do + local nRefAreaId = EgtIf( i == 0, nAreaId, vVirtualAreas[i]) + local nOutlineLayerId = EgtGetFirstNameInGroup( nRefAreaId, WIN_OUTLINE) + local vOutlineIds = EgtGetAllInGroup( nOutlineLayerId) + GetSplitsPrevNextOutline( tabGrid[i], vOutlineIds) + end + + else + local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE) + GetSplitsPrevNextOutline( vSplits, EgtGetAllInGroup( nOutlineLayerId)) + end + + -- aggiorno eventuali inglesine out + if bFillMuntin then + for i = 1, #vSplits do + local nOutSplit = EgtGetInfo( vSplits[i], WIN_REF_MUNTIN, 'i') -- verifico se devo aggiornare i prev/next ( caso di inglesina contro inglesina) - local vPrevOutlines = EgtGetInfo( nId, WIN_PREV_OUTLINES, 'vi') + local vPrevOutlines = EgtGetInfo( vSplits[i], WIN_PREV_OUTLINES, 'vi') for j = 1, #vPrevOutlines do local nRef = EgtGetInfo( abs( vPrevOutlines[j]), WIN_REF_MUNTIN, 'i') if nRef then vPrevOutlines[j] = EgtIf( vPrevOutlines[j] > 0, nRef, - nRef) end end - EgtSetInfo( nId, WIN_PREV_OUTLINES, vPrevOutlines) - local vNextOutlines = EgtGetInfo( nId, WIN_NEXT_OUTLINES, 'vi') + local vNextOutlines = EgtGetInfo( vSplits[i], WIN_NEXT_OUTLINES, 'vi') for j = 1, #vNextOutlines do local nRef = EgtGetInfo( abs( vNextOutlines[j]), WIN_REF_MUNTIN, 'i') if nRef then vNextOutlines[j] = EgtIf( vNextOutlines[j] > 0, nRef, - nRef) end end - EgtSetInfo( nId, WIN_NEXT_OUTLINES, vNextOutlines) - end - else - for i = 1, #vSplitIds do - EgtSetInfo( vSplitIds[i], WIN_MUNTINFILL_SIDE, nMuntinType) + EgtSetInfo( nOutSplit, WIN_PREV_OUTLINES, vPrevOutlines) + EgtSetInfo( nOutSplit, WIN_NEXT_OUTLINES, vNextOutlines) + CopyInfo( nOutSplit, vSplits[i], WIN_STARTJOINT) + CopyInfo( nOutSplit, vSplits[i], WIN_ENDJOINT) end end end @@ -3218,117 +4100,13 @@ local function CalculateOutlineFromAreaOutline( nAreaId) -- SASH elseif nAreaType == WIN_AREATYPES.SASH then - local nBaseOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_AREAOUTLINE) - local vOutlines = CalculateSashOutline( nAreaId, nBaseOutlineLayerId, nOutlineLayerId) - -- creo i pezzi - CreatePartsFromOutlines( vOutlines, nAreaId, sName) - -- ne verifico validità - VerifySashParts( vOutlines, nAreaId) - -- assegno i prev e i next - GetSashPrevNextOutlines( vOutlines, nOutlineLayerId, nAreaId) - -- identifico la forma - IdentifySashShape( nAreaId, nOutlineLayerId) - -- disegno apertura - DrawOpening( nAreaId) - - - -- FILL - elseif nAreaType == WIN_AREATYPES.FILL then - CalculateFillOutline( nAreaId, nOutlineLayerId) - -- creo il pezzo associato - CreateFillPartFromArea( nAreaId, sName) + GetSashPrevNextOutlines( nAreaId) 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 - ---------------------------------------------------------------------- --- funzione che cicla ricorsivamente su aree e sottoaree per assegnare i profili all'area -local function SetAreaProfiles( nAreaId) - - local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i') - if nAreaType == WIN_AREATYPES.FRAME or nAreaType == WIN_AREATYPES.SASH then - -- recupero i profili dalle curve di outline - local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE) - local vOutlines = EgtGetAllInGroup( nOutlineLayerId) - local sAreaName = EgtIf( nAreaType == WIN_AREATYPES.FRAME, WIN_FRAME, WIN_SASH) - local vProfiles = {} - for i = 1, #vOutlines do - vProfiles[i] = sAreaName .. '_' .. EgtGetInfo( vOutlines[i], WIN_PROFILETYPE) - end - EgtSetInfo( nAreaId, WIN_AREA_PROFILES, vProfiles) - - elseif nAreaType == WIN_AREATYPES.SPLIT then - local nSplitType = EgtGetInfo( nAreaId, WIN_SPLITTYPE, 'i') - if nSplitType ~= WIN_SPLITTYPES.FRENCH then - -- recupero area parent per capire se dentro telaio, anta o vetro - local nParentAreaId = EgtGetParent( nAreaId) - local nParentAreaType = EgtGetInfo( nParentAreaId, WIN_AREATYPE, 'i') - while nParentAreaType == WIN_AREATYPES.SPLIT or nParentAreaType == WIN_AREATYPES.NULL do - nParentAreaId = EgtGetParent( nParentAreaId) - nParentAreaType = EgtGetInfo( nParentAreaId, WIN_AREATYPE, 'i') - end - local sAreaName - if nParentAreaType == WIN_AREATYPES.FRAME then - sAreaName = WIN_FRAME - elseif nParentAreaType == WIN_AREATYPES.SASH then - sAreaName = WIN_SASH - else - sAreaName = WIN_FILL - end - - local nSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_SPLIT) - local vSplitIds = EgtGetAllInGroup( nSplitLayerId) - local bGridSplit = EgtGetInfo( nAreaId, WIN_GRID_SPLIT, 'b') or false - if bGridSplit then - -- recupero i profili distinguendoli per ordine di split - local tabProfiles = {} - for i = 1, #vSplitIds do - if not EgtExistsInfo( vSplitIds[i], WIN_REF_MUNTIN) then - local nOrder = EgtGetInfo( vSplitIds[i], WIN_GRIDSPLIT_ORDER, 'i') - local sProfile = sAreaName .. '_' .. EgtGetInfo( vSplitIds[i], WIN_PROFILETYPE) - if tabProfiles[nOrder+1] then - table.insert( tabProfiles[nOrder+1], sProfile) - else - tabProfiles[nOrder+1] = { sProfile} - end - end - end - -- salvo in info separate - for i = 1, #tabProfiles do - EgtSetInfo( nAreaId, WIN_AREA_PROFILES .. tostring( i-1), tabProfiles[i]) - end - else - -- recupero tutti i profili degli split - -- se ha info WIN_REF_MUNTIN significa che split è inglesina sia interna che esterna, non ha senso considerarla due volte anche se sono due outlines distinti perchè - -- lo split che la definisce è uno solo - local vProfiles = {} - for i = 1, #vSplitIds do - if not EgtExistsInfo( vSplitIds[i], WIN_REF_MUNTIN) then - table.insert( vProfiles, sAreaName .. '_' .. EgtGetInfo( vSplitIds[i], WIN_PROFILETYPE)) - end - end - EgtSetInfo( nAreaId, WIN_AREA_PROFILES, vProfiles) - end - end - end - - -- analizzo le sottoaree - local nChildAreaId = EgtGetFirstNameInGroup( nAreaId, WIN_AREA .. '*') - while nChildAreaId do - SetAreaProfiles( nChildAreaId) - nChildAreaId = EgtGetNextName( nChildAreaId, WIN_AREA .. '*') + -- analizzo le sottaree + local vAreas = EgtGetNameInGroup( nAreaId, WIN_AREA .. '*') + for i = 1, #vAreas do + GetAreaPrevNextOutlines( vAreas[i]) end end @@ -3337,62 +4115,6 @@ end ---------------------------------------------------------------------------------- -------------------------------- GEO ------------------------------------------- ---------------------------------------------------------------------------------- --- funzione che crea il bisettore parabolico tra linea e arco -local function CalcParabolicBisector( nCrv1, nCrv2, dDim, nGrp, bArcExternal, bLineExternal) - - -- modifico le curve affinchè abbiano estremo in comune - local ptInt = FindIntersectionPoint( nCrv1, nCrv2, EgtSP( nCrv2)) - EgtModifyCurveStartPoint( nCrv2, ptInt) - EgtModifyCurveEndPoint( nCrv1, ptInt) - - -- calcolo coefficienti dell'equazione del bisettore ( equazione presa da Vroni) - local nArc, nLine, nSign - if EgtGetType( nCrv1) == GDB_TY.CRV_ARC then - nArc = nCrv1 - nLine = nCrv2 - nSign = -1 - else - nArc = nCrv2 - nLine = nCrv1 - nSign = 1 - end - local ptC = EgtCP( nArc) - local dRad = EgtArcRadius( nArc) - -- equazione della retta - local dCoeffA = - EgtSV( nLine):getY() - local dCoeffB = EgtSV( nLine):getX() - local dCoeffC = - dCoeffA * ptInt:getX() - dCoeffB * ptInt:getY() - - local dDist = dCoeffA * ptC:getX() + dCoeffB * ptC:getY() + dCoeffC - local dA = ptC:getX() - dCoeffA * dDist - local dB = ptC:getY() - dCoeffB * dDist - local dZ = ptC:getZ() - - local k1 = EgtIf( bArcExternal, 1, -1) -- 1 esterno alla circonferenza / -1 interno alla circonferenza - local k2 = EgtIf( bLineExternal, 1, -1) -- 1 a destra della linea / -1 a sinistra della linea - - -- campiono il bisettore ( è parametrizzato sul valore di offset t) - local vPoints = {} - local nTot = 50 - for i = 1, nTot do - local t = dDim / ( nTot - 1) * ( i - 1) - local dDiscriminant = dRad * dRad + 2 * t * ( k1 * dRad - k2 * dDist) - dDist * dDist - local dX, dY - if dDiscriminant < GEO.EPS_ZERO then - dX = dA - k2 * dCoeffA * t - dY = dB - k2 * dCoeffB * t - else - dX = dA - k2 * dCoeffA * t + nSign * dCoeffB * sqrt( dDiscriminant) - dY = dB - k2 * dCoeffB * t - nSign * dCoeffA * sqrt( dDiscriminant) - end - vPoints[i] = Point3d( dX, dY, dZ) - end - - local nCompo = EgtCurveCompoFromPoints( nGrp, vPoints) - return nCompo -end - ---------------------------------------------------------------------- -- funzione simile a CalcIntersectionRegion ma con considerazioni speciali per le curve del geo ( e.g. gestione bisettori, curve doppie) local function CalcGeoRegion( vCrvs, nGrp) @@ -3421,16 +4143,23 @@ local function CalcGeoRegion( vCrvs, nGrp) -- se arco calcolo estensione verificando se la curva è doppia elseif EgtGetType( vCrvs[i]) == GDB_TY.CRV_ARC then + local nCrvId = CreateCurveExtension( vCrvs[i], nGrpTmp) local bFound = false local nRefOutline = EgtGetInfo( vCrvs[i], WIN_REF_OUTLINE, 'i') if nRefOutline then for j = 1, #tArcs do if tArcs[j].nRefOutline == nRefOutline then - local nCopy = EgtCopyGlob( vCrvs[i], nGrpTmp) - CopyInfo( nCopy, tArcs[j].vOrigId[1], WIN_TANG_START, false) - CopyInfo( nCopy, vCrvs[i], WIN_TANG_END, false) - local nCrvId = CreateCurveExtension( nCopy, nGrpTmp) - tArcs[j].nCrvId = nCrvId + -- taglio le due estensioni e le unisco nel loro punto centrale + local ptM = EgtMP( nRefOutline) + local _, _, dPar1 = EgtPointCurveDist( ptM, tArcs[j].nCrvId) + local _, _, dPar2 = EgtPointCurveDist( ptM, nCrvId) + EgtTrimCurveStartAtParam( nCrvId, dPar2) + EgtTrimCurveEndAtParam( tArcs[j].nCrvId, dPar1) + local nNewExt = EgtCurveCompo( nGrpTmp, nCrvId) + EgtAddCurveCompoLine( nNewExt, EgtSP( tArcs[j].nCrvId)) + EgtAddCurveCompoCurve( nNewExt, tArcs[j].nCrvId) + + tArcs[j].nCrvId = nNewExt table.insert( tArcs[j].vOrigId, vCrvs[i]) bFound = true break @@ -3438,7 +4167,6 @@ local function CalcGeoRegion( vCrvs, nGrp) end end if not bFound then - local nCrvId = CreateCurveExtension( vCrvs[i], nGrpTmp) table.insert( tArcs, { nCrvId = nCrvId, vOrigId = { vCrvs[i]}, nRefOutline = nRefOutline, dRad = EgtArcRadius( vCrvs[i])}) end @@ -3630,21 +4358,17 @@ local function ComputeArcExtensions( nOutId, nInId, vLeftIds, vRightIds, vStartJ -- se outline in tangenza con i vicini forzo estensione in tangenza if not bTangS then - if vStartJoints[i] == WIN_PART_JNT.FULL or i == 1 or vStartJoints[i] == vStartJoints[i-1] then - local nOutlineId = EgtGetInfo( vLeftIds[i], WIN_REF_OUTLINE, 'i') - local nPrevOutlineId = EgtGetPrev( nOutlineId) or EgtGetLastInGroup( EgtGetParent( nOutlineId)) - if AreSameVectorApprox( EgtEV( nPrevOutlineId), EgtSV( nOutlineId)) then - bTangS = true - end + local nOutlineId = EgtGetInfo( vLeftIds[i], WIN_REF_OUTLINE, 'i') + local nPrevOutlineId = EgtGetPrev( nOutlineId) or EgtGetLastInGroup( EgtGetParent( nOutlineId)) + if AreSameVectorApprox( EgtEV( nPrevOutlineId), EgtSV( nOutlineId)) then + bTangS = true end end if not bTangE then - if vStartJoints[i] == WIN_PART_JNT.FULL or i == #vLeftIds or vStartJoints[i] == vStartJoints[i+1] then - local nOutlineId = EgtGetInfo( vLeftIds[i], WIN_REF_OUTLINE, 'i') - local nNextOutlineId = EgtGetNext( nOutlineId) or EgtGetFirstInGroup( EgtGetParent( nOutlineId)) - if AreSameVectorApprox( EgtEV( nOutlineId), EgtSV( nNextOutlineId)) then - bTangE = true - end + local nOutlineId = EgtGetInfo( vLeftIds[i], WIN_REF_OUTLINE, 'i') + local nNextOutlineId = EgtGetNext( nOutlineId) or EgtGetFirstInGroup( EgtGetParent( nOutlineId)) + if AreSameVectorApprox( EgtEV( nOutlineId), EgtSV( nNextOutlineId)) then + bTangE = true end end @@ -3658,24 +4382,20 @@ local function ComputeArcExtensions( nOutId, nInId, vLeftIds, vRightIds, vStartJ if EgtGetType( vRightIds[i]) == GDB_TY.CRV_ARC then local bTangS, bTangE = CheckSemiprofileIntersection( vRightIds[i], nOutId, nInId) - if not bTangS then - if vEndJoints[i] == WIN_PART_JNT.FULL or i == 1 or vEndJoints[i] == vEndJoints[i-1] then - local nOutlineId = EgtGetInfo( vRightIds[i], WIN_REF_OUTLINE, 'i') - local nPrevOutlineId = EgtGetPrev( nOutlineId) or EgtGetLastInGroup( EgtGetParent( nOutlineId)) - if AreSameVectorApprox( EgtEV( nPrevOutlineId), EgtSV( nOutlineId)) then - bTangS = true - end - end - end - if not bTangE then - if vEndJoints[i] == WIN_PART_JNT.FULL or i == #vRightIds or vEndJoints[i] == vEndJoints[i+1] then - local nOutlineId = EgtGetInfo( vRightIds[i], WIN_REF_OUTLINE, 'i') - local nNextOutlineId = EgtGetNext( nOutlineId) or EgtGetFirstInGroup( EgtGetParent( nOutlineId)) - if AreSameVectorApprox( EgtEV( nOutlineId), EgtSV( nNextOutlineId)) then - bTangE = true - end - end - end + if not bTangS then + local nOutlineId = EgtGetInfo( vRightIds[i], WIN_REF_OUTLINE, 'i') + local nPrevOutlineId = EgtGetPrev( nOutlineId) or EgtGetLastInGroup( EgtGetParent( nOutlineId)) + if AreSameVectorApprox( EgtEV( nPrevOutlineId), EgtSV( nOutlineId)) then + bTangS = true + end + end + if not bTangE then + local nOutlineId = EgtGetInfo( vRightIds[i], WIN_REF_OUTLINE, 'i') + local nNextOutlineId = EgtGetNext( nOutlineId) or EgtGetFirstInGroup( EgtGetParent( nOutlineId)) + if AreSameVectorApprox( EgtEV( nOutlineId), EgtSV( nNextOutlineId)) then + bTangE = true + end + end EgtSetInfo( vRightIds[i], WIN_TANG_START, bTangS) EgtSetInfo( vRightIds[i], WIN_TANG_END, bTangE) @@ -3703,7 +4423,10 @@ local function CreateGeoCurves( nOutlineId, vPrevOutlineId, vNextOutlineId, vSta local nOutId = EgtCopy( nOutlineId, nGeoLayerId) EgtOffsetCurve( nOutId, dCurrOffset) EgtSetName( nOutId, WIN_GEO_OUT) - local nSemiProfileOut = EgtGetFirstNameInGroup( nCurrProfileId, WIN_OUT) or EgtGetFirstNameInGroup( nCurrProfileId, WIN_IN .. '1') + local nSemiProfileOut = EgtGetFirstNameInGroup( nCurrProfileId, WIN_OUT) + if not nSemiProfileOut then + nSemiProfileOut = EgtGetFirstNameInGroup( nCurrProfileId, WIN_IN .. '1') or EgtGetFirstNameInGroup( nCurrProfileId, WIN_MIXED_COMMON .. WIN_IN .. '1') + end EgtSetInfo( nOutId, WIN_SEMI_PROFILE, nSemiProfileOut) EgtSetInfo( nOutId, WIN_REF_OUTLINE, nOutlineId) EgtSetInfo( nOutId, WIN_GEO_OFFS, dCurrOffset) @@ -3713,7 +4436,11 @@ local function CreateGeoCurves( nOutlineId, vPrevOutlineId, vNextOutlineId, vSta EgtOffsetCurve( nInId, dCurrOffset - b3CurrProfileFrame:getDimX()) EgtInvertCurve( nInId) EgtSetName( nInId, WIN_GEO_IN) - local nSemiProfileIn = EgtGetFirstNameInGroup( nCurrProfileId, WIN_IN) or EgtGetFirstNameInGroup( nCurrProfileId, WIN_IN .. '2') or EgtGetFirstNameInGroup( nCurrProfileId, WIN_MIXED_COMMON .. WIN_IN) + local nSemiProfileIn = EgtGetFirstNameInGroup( nCurrProfileId, WIN_IN) + if not nSemiProfileIn then + nSemiProfileIn = EgtGetFirstNameInGroup( nCurrProfileId, WIN_IN .. '2') or EgtGetFirstNameInGroup( nCurrProfileId, WIN_MIXED_COMMON .. WIN_IN .. '2') or + EgtGetFirstNameInGroup( nCurrProfileId, WIN_MIXED_COMMON .. WIN_IN) + end EgtSetInfo( nInId, WIN_SEMI_PROFILE, nSemiProfileIn) EgtSetInfo( nInId, WIN_REF_OUTLINE, - nOutlineId) EgtSetInfo( nInId, WIN_GEO_OFFS, - dCurrOffset + b3CurrProfileFrame:getDimX()) @@ -3774,7 +4501,7 @@ local function CreateGeoCurves( nOutlineId, vPrevOutlineId, vNextOutlineId, vSta local dOffs, nPrevSemiProfile if vStartJoints[i] == WIN_PART_JNT.SHORT then -- la curva del geo corrisponde al bordo del controprofilo in del pezzo vicino - local sCtrIn = GetProfileCtrIn( vPrevOutlineId[i], nOutlineId, vPrevProfileId[i]) + local sCtrIn = GetProfileCtrIn( vPrevOutlineId[i], nOutlineId, vPrevProfileId[i], true) local dCPDelta = GetDeltaProfile( vPrevProfileId[i], sCtrIn, vPrevOutlineId[i]) dOffs = - dCPDelta nPrevSemiProfile = EgtGetFirstNameInGroup( vPrevProfileId[i], sCtrIn) @@ -3845,7 +4572,7 @@ local function CreateGeoCurves( nOutlineId, vPrevOutlineId, vNextOutlineId, vSta end local dOffs, nNextSemiProfile if vEndJoints[i] == WIN_PART_JNT.SHORT then - local sCtrIn = GetProfileCtrIn( vNextOutlineId[i], nOutlineId, vNextProfileId[i]) + local sCtrIn = GetProfileCtrIn( vNextOutlineId[i], nOutlineId, vNextProfileId[i], false) local dCPDelta = GetDeltaProfile( vNextProfileId[i], sCtrIn, vNextOutlineId[i]) dOffs = - dCPDelta nNextSemiProfile = EgtGetFirstNameInGroup( vNextProfileId[i], sCtrIn) @@ -3890,7 +4617,7 @@ local function CreateGeoCurves( nOutlineId, vPrevOutlineId, vNextOutlineId, vSta for i = 1, #vExtraCrvs do EgtSetInfo( vExtraCrvs[i], WIN_GEO_EXTRA, true) end - + -- assegno spessore local dGeoH = b3CurrProfileFrame:getDimY() EgtModifyCurveThickness( vIds, - dGeoH) @@ -3987,7 +4714,7 @@ end ---------------------------------------------------------------------------------- ----------------------- CURVE AUX PER CAMBIO PROFILO ----------------------------- ---------------------------------------------------------------------------------- -local function CalcMixedMillings( vOutlines, nOutlineProfileId, nSplitId, nSplitProfileId, bPrev, nGrp) +local function CalcMixedMillings( vOutlines, nOutlineProfileId, nSplitId, nSplitProfileId, bStart, bSashFill, bFillOnRight, nGrp) -- TO DO : da capire bene come gestire il caso di cambio profilo che coinvolge più pezzi -- TO DO : da capire quali info serve riportare nel profilo @@ -3997,31 +4724,46 @@ local function CalcMixedMillings( vOutlines, nOutlineProfileId, nSplitId, nSplit local dDim1 = 61 local dDim2 = 45 local dRad = EgtGetInfo( nSplitProfileId, WIN_RAD_REF .. '1', 'd') - local ptRef = EgtIf( bPrev, EgtSP( nSplitId), EgtEP( nSplitId)) - + local ptRef = EgtIf( bStart, EgtSP( nSplitId), EgtEP( nSplitId)) + -- calcolo le curve di riferimento per lo split local b3SplitProfile = GetProfileLocalBox( nSplitProfileId) - local dSplitFixedOffs = EgtGetInfo( nSplitProfileId, WIN_FIXED_REF, 'd') - local nCrvSF = EgtOffsetCurveAdv( nSplitId, b3SplitProfile:getMax():getX() - dSplitFixedOffs) + local dSplitFixedOverl = EgtGetInfo( nSplitProfileId, WIN_FIXED_REF, 'd') + local dSplitSashOverl1 = EgtGetInfo( nSplitProfileId, WIN_SASH_REF .. '1', 'd') + local dSplitSashOverl2 = EgtGetInfo( nSplitProfileId, WIN_SASH_REF .. '2', 'd') + local nCrvSF, nCrvSS1, nCrvSS2 + if bFillOnRight then + nCrvSF = EgtOffsetCurveAdv( nSplitId, b3SplitProfile:getMax():getX() - dSplitFixedOverl) + nCrvSS1 = EgtOffsetCurveAdv( nSplitId, b3SplitProfile:getMin():getX() + dSplitSashOverl1) + nCrvSS2 = EgtOffsetCurveAdv( nSplitId, b3SplitProfile:getMin():getX() + dSplitSashOverl2) + else + nCrvSF = EgtOffsetCurveAdv( nSplitId, b3SplitProfile:getMin():getX() + dSplitFixedOverl) + nCrvSS1 = EgtOffsetCurveAdv( nSplitId, b3SplitProfile:getMax():getX() - dSplitSashOverl1) + nCrvSS2 = EgtOffsetCurveAdv( nSplitId, b3SplitProfile:getMax():getX() - dSplitSashOverl2) + end EgtRelocateGlob( nCrvSF, nGrpTmp) - local dSplitSashOffs1 = EgtGetInfo( nSplitProfileId, WIN_SASH_REF .. '1', 'd') - local nCrvSS1 = EgtOffsetCurveAdv( nSplitId, b3SplitProfile:getMin():getX() + dSplitSashOffs1) EgtRelocateGlob( nCrvSS1, nGrpTmp) - local dSplitSashOffs2 = EgtGetInfo( nSplitProfileId, WIN_SASH_REF .. '2', 'd') - local nCrvSS2 = EgtOffsetCurveAdv( nSplitId, b3SplitProfile:getMin():getX() + dSplitSashOffs2) EgtRelocateGlob( nCrvSS2, nGrpTmp) -- calcolo le curve di riferimento prev - local nOutlineCompo = EgtCurveCompo( nGrpTmp, vOutlines, false) + local vCompoOutlines = {} + for i = 1, #vOutlines do + vCompoOutlines[i] = EgtCopyGlob( abs( vOutlines[i]), nGrpTmp) + if vOutlines[i] < 0 then + EgtInvertCurve( vCompoOutlines[i]) + end + end + local nOutlineCompo = EgtCurveCompo( nGrpTmp, vCompoOutlines) + local b3FrameProfile = GetProfileLocalBox( nOutlineProfileId) - local dFrameFixedOffs = EgtGetInfo( nOutlineProfileId, WIN_FIXED_REF, 'd') - local nCrvFF = EgtOffsetCurveAdv( nOutlineCompo, b3FrameProfile:getMin():getX() + dFrameFixedOffs) - local dFrameSashOffs1 = EgtGetInfo( nOutlineProfileId, WIN_SASH_REF .. '1', 'd') - local nCrvFS1 = EgtOffsetCurveAdv( nOutlineCompo, b3FrameProfile:getMin():getX() + dFrameSashOffs1) - local dFrameSashOffs2 = EgtGetInfo( nOutlineProfileId, WIN_SASH_REF .. '2', 'd') - local nCrvFS2 = EgtOffsetCurveAdv( nOutlineCompo, b3FrameProfile:getMin():getX() + dFrameSashOffs2) + local dFrameFixedOverl = EgtGetInfo( nOutlineProfileId, WIN_FIXED_REF, 'd') + local nCrvFF = EgtOffsetCurveAdv( nOutlineCompo, b3FrameProfile:getMin():getX() + dFrameFixedOverl) + local dFrameSashOverl1 = EgtGetInfo( nOutlineProfileId, WIN_SASH_REF .. '1', 'd') + local nCrvFS1 = EgtOffsetCurveAdv( nOutlineCompo, b3FrameProfile:getMin():getX() + dFrameSashOverl1) + local dFrameSashOverl2 = EgtGetInfo( nOutlineProfileId, WIN_SASH_REF .. '2', 'd') + local nCrvFS2 = EgtOffsetCurveAdv( nOutlineCompo, b3FrameProfile:getMin():getX() + dFrameSashOverl2) local dFrameExtra = EgtGetInfo( nOutlineProfileId, WIN_EXTRA_DIST, 'd') - local nCrvFIn = EgtOffsetCurveAdv( nOutlineCompo, b3FrameProfile:getMin():getX() + dFrameSashOffs2 + dFrameExtra) + local nCrvFIn = EgtOffsetCurveAdv( nOutlineCompo, b3FrameProfile:getMin():getX() + dFrameSashOverl2 + dFrameExtra) local dDepth = EgtGetInfo( nOutlineProfileId, WIN_SASH_DEPTH .. '2', 'd') @@ -4034,6 +4776,9 @@ local function CalcMixedMillings( vOutlines, nOutlineProfileId, nSplitId, nSplit if EgtCurveCompoRadius( nCrvFF, nCrvRef) == -1 then -- se l'incontro tra la parte fixed del telaio e dello split avviene su un tratto lineare il bisettore è linea local vtDir = ( EgtUV( nCrvFF, dParRef, -1) + EgtSV( nSplitId)) + if not bFillOnRight then + vtDir = ( EgtUV( nCrvFF, dParRef, -1) - EgtSV( nSplitId)) + end nBisector = EgtLinePVL( nGrpTmp, pt1, vtDir, 1000) EgtExtendCurveStartByLen( nBisector, 1000) @@ -4041,14 +4786,20 @@ local function CalcMixedMillings( vOutlines, nOutlineProfileId, nSplitId, nSplit -- se l'incontro tra la parte fixed del telaio e dello split avviene su un tratto ad arco il bisettore è porzione di parabola local nArc = EgtCopyCompoSubCurve( nCrvFF, nCrvRef, nGrpTmp) local b3Profile = GetProfileLocalBox( nSplitProfileId) - -- bisettore è tratto di parabola local dDim = b3Profile:getDimX() - if bPrev then + + if bStart and bFillOnRight then nBisector = CalcParabolicBisector( nArc, nCrvSF, dDim, nGrpTmp, true, false) EgtInvertCurve( nBisector) - else + elseif bStart and not bFillOnRight then + nBisector = CalcParabolicBisector( nArc, nCrvSF, dDim, nGrpTmp, true, true) + elseif not bStart and not bFillOnRight then + nBisector = CalcParabolicBisector( nCrvSF, nArc, dDim, nGrpTmp, true, true) + EgtInvertCurve( nBisector) + elseif not bStart and bFillOnRight then nBisector = CalcParabolicBisector( nCrvSF, nArc, dDim, nGrpTmp, true, false) end + EgtErase( nArc) end @@ -4057,7 +4808,7 @@ local function CalcMixedMillings( vOutlines, nOutlineProfileId, nSplitId, nSplit EgtOffsetCurve( nBisectTool, - dDim1 * 0.5) EgtExtendCurveStartByLen( nBisectTool, 10) EgtExtendCurveEndByLen( nBisectTool, 10) - local nCrvSash = EgtOffsetCurveAdv( nOutlineCompo, b3FrameProfile:getMin():getX() + dFrameSashOffs1 - dDim1 * 0.5) + local nCrvSash = EgtOffsetCurveAdv( nOutlineCompo, b3FrameProfile:getMin():getX() + dFrameSashOverl1 - dDim1 * 0.5) local ptEnd = EgtIP( nCrvSash, nBisectTool, ptRef) local nCircle = EgtCircle( nGrpTmp, ptEnd, dDim1 * 0.5) local nCircle2 = EgtCircle( nGrpTmp, ptEnd, dDim2 * 0.5) @@ -4073,7 +4824,7 @@ local function CalcMixedMillings( vOutlines, nOutlineProfileId, nSplitId, nSplit local nMill2 = EgtCopyParamRange( nCrvFS1, min( dPar4, dPar3), max( dPar3, dPar4), nGrpTmp) local nMilling - if bPrev then + if bSashFill then nMilling = EgtCurveCompo( nGrpTmp, { nMill2, nMill1}) else nMilling = EgtCurveCompo( nGrpTmp, { nMill1, nMill2}) @@ -4086,12 +4837,10 @@ local function CalcMixedMillings( vOutlines, nOutlineProfileId, nSplitId, nSplit EgtSetColor( nMilling, EgtStdColor( 'BLUE')) EgtSetName( nMilling, WIN_MIXED_MILLING .. '1') EgtSetInfo( nMilling, WIN_MIXED_SPLIT_REF, nSplitId) + EgtModifyCurveExtrusion( nMilling, Z_AX()) EgtModifyCurveThickness( nMilling, - dDepth) - if bPrev then - EgtSetInfo( nMilling, WIN_MIXED_SASHFILL, true) - else - EgtSetInfo( nMilling, WIN_MIXED_SASHFILL, false) - end + + EgtSetInfo( nMilling, WIN_FILL_ON_SPLIT_RIGHT, bFillOnRight) -- 2) Fresatura #2 @@ -4100,7 +4849,7 @@ local function CalcMixedMillings( vOutlines, nOutlineProfileId, nSplitId, nSplit local pt4 = EgtIP( nCrvFIn, nCrvSS1, ptRef) local pt5 = EgtIP( nCrvSS1, nCrvFS2, ptRef) -- calcolo le curve - local dParA = EgtCurveParamAtPoint( nBisector, EgtIf( bPrev, EgtEP( nMilling), EgtSP( nMilling))) + local dParA = EgtCurveParamAtPoint( nBisector, EgtIf( bSashFill, EgtEP( nMilling), EgtSP( nMilling))) local dParB = EgtCurveParamAtPoint( nBisector, pt3) local nMill3 = EgtCopyParamRange( nBisector, min( dParA, dParB), max( dParA, dParB), nGrpTmp) local dParC = EgtCurveParamAtPoint( nCrvFIn, pt3) @@ -4109,10 +4858,12 @@ local function CalcMixedMillings( vOutlines, nOutlineProfileId, nSplitId, nSplit local dParE = EgtCurveParamAtPoint( nCrvSS1, pt4) local dParF = EgtCurveParamAtPoint( nCrvSS1, pt5) local nMill5 = EgtCopyParamRange( nCrvSS1, min( dParE, dParF), max( dParE, dParF), nGrpTmp) - EgtInvertCurve( nMill5) + if bFillOnRight then + EgtInvertCurve( nMill5) + end local dParG = EgtCurveParamAtPoint( nCrvFS2, pt5) local nMill6 - if bPrev then + if bSashFill then nMill6 = EgtCopyParamRange( nCrvFS2, 0, dParG, nGrpTmp) else local _, dE = EgtCurveDomain( nCrvFS2) @@ -4120,22 +4871,23 @@ local function CalcMixedMillings( vOutlines, nOutlineProfileId, nSplitId, nSplit end local nMilling2 - if bPrev then + if bSashFill then nMilling2 = EgtCurveCompo( nGrp, { nMill6, nMill5, nMill4, nMill3}) else nMilling2 = EgtCurveCompo( nGrp, { nMill3, nMill4, nMill5, nMill6}) end EgtSetColor( nMilling2, EgtStdColor( 'BLUE')) EgtSetName( nMilling2, WIN_MIXED_MILLING .. '2') + EgtModifyCurveExtrusion( nMilling2, Z_AX()) EgtModifyCurveThickness( nMilling2, - dDepth) -- taglio sul punto finale della lavorazione di profilatura local pt6 = EgtIP( nMilling2, nCircle2, ptRef) if not pt6 then - _, pt6 = EgtPointCurveDist( EgtIf( bPrev, EgtSP( nMilling), EgtEP( nMilling)), nMilling2) + _, pt6 = EgtPointCurveDist( EgtIf( bSashFill, EgtSP( nMilling), EgtEP( nMilling)), nMilling2) end local dParH = EgtCurveParamAtPoint( nMilling2, pt6) - if bPrev then + if bSashFill then EgtTrimCurveStartAtParam( nMilling2, dParH) else EgtTrimCurveEndAtParam( nMilling2, dParH) @@ -4155,40 +4907,64 @@ local function CalcMixedCurves( nPartId, nSplitId) local nProfileGrpId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE) local nSplitProfileId = EgtGetFirstNameInGroup( nProfileGrpId, WIN_PRF_MAIN) + local nPrfChange = EgtGetInfo( nSplitId, WIN_PRF_CHANGE, 'i') - -- prev - local vPrevOutlines = EgtGetInfo( nSplitId, WIN_PREV_OUTLINES, 'vi') - local nPrevProfileId = EgtGetFirstNameInGroup( nProfileGrpId, WIN_PRF_START) - local nMill1, nMill2 = CalcMixedMillings( vPrevOutlines, nPrevProfileId, nSplitId, nSplitProfileId, true, nGrp) - - -- copio le fresature sui pezzi del telaio coinvolti - for i = 1, #vPrevOutlines do - local nPrevPartId = EgtGetInfo( vPrevOutlines[i], WIN_REF_PART, 'i') - local nMixedInters = EgtGetFirstNameInGroup( nPrevPartId, WIN_MIXED_CURVES) - if not nMixedInters then - nMixedInters = EgtGroup( nPrevPartId) - EgtSetName( nMixedInters, WIN_MIXED_CURVES) - EgtSetStatus( nMixedInters, GDB_ST.OFF) + -- start + -- se cambio profilo sull'estremo start allora serve fresatura per cambio profilo + if nPrfChange & WIN_PRF_CHANGE_TYPES.START > 0 then + local vPrevOutlines = EgtGetInfo( nSplitId, WIN_PREV_OUTLINES, 'vi') + local nPrevProfileId = GetOutlineProfileId( abs( vPrevOutlines[1])) + -- verifico se lungo la direzione del prev outline l'ordine è sash/fill ( true) o fill/sash ( false) + local nStart1 = EgtGetInfo( nSplitId, WIN_MIXED_START_CHILDREN .. '1', 'i') + local bSashFill = EgtIf( nStart1 == WIN_CHILDREN_TYPES.FILL, true, false) + + local nMill1, nMill2 = CalcMixedMillings( vPrevOutlines, nPrevProfileId, nSplitId, nSplitProfileId, true, bSashFill, nStart1 == WIN_CHILDREN_TYPES.FILL, nGrp) + EgtSetName( nMill1, WIN_MIXED_MILLING .. WIN_LEFT .. '1') + EgtSetName( nMill2, WIN_MIXED_MILLING .. WIN_LEFT .. '2') + + -- copio le fresature sui pezzi su cui poggia + for i = 1, #vPrevOutlines do + local nPrevPartId = EgtGetInfo( abs( vPrevOutlines[i]), WIN_REF_PART, 'i') + local nMixedInters = EgtGetFirstNameInGroup( nPrevPartId, WIN_MIXED_CURVES) + if not nMixedInters then + nMixedInters = EgtGroup( nPrevPartId) + EgtSetName( nMixedInters, WIN_MIXED_CURVES) + EgtSetStatus( nMixedInters, GDB_ST.OFF) + end + local nCrv1 = EgtCopyGlob( nMill1, nMixedInters) + local nCrv2 = EgtCopyGlob( nMill2, nMixedInters) + local sSide = EgtIf( vPrevOutlines[i] > 0, WIN_IN, WIN_OUT) + EgtSetName( nCrv1, WIN_MIXED_MILLING .. sSide .. '1') + EgtSetName( nCrv2, WIN_MIXED_MILLING .. sSide .. '2') end - EgtCopyGlob( nMill1, nMixedInters) - EgtCopyGlob( nMill2, nMixedInters) - end + end - -- next - local vNextOutlines = EgtGetInfo( nSplitId, WIN_NEXT_OUTLINES, 'vi') - local nNextProfileId = EgtGetFirstNameInGroup( nProfileGrpId, WIN_PRF_END) - local nMill3, nMill4 = CalcMixedMillings( vNextOutlines, nNextProfileId, nSplitId, nSplitProfileId, false, nGrp) - - for i = 1, #vNextOutlines do - local nPrevPartId = EgtGetInfo( vNextOutlines[i], WIN_REF_PART, 'i') - local nMixedInters = EgtGetFirstNameInGroup( nPrevPartId, WIN_MIXED_CURVES) - if not nMixedInters then - nMixedInters = EgtGroup( nPrevPartId) - EgtSetName( nMixedInters, WIN_MIXED_CURVES) - EgtSetStatus( nMixedInters, GDB_ST.OFF) + -- end + if nPrfChange & WIN_PRF_CHANGE_TYPES.END > 0 then + local vNextOutlines = EgtGetInfo( nSplitId, WIN_NEXT_OUTLINES, 'vi') + local nNextProfileId = GetOutlineProfileId( abs( vNextOutlines[1])) + -- verifico se lungo la direzione del next outline l'ordine è sash/fill ( true) o fill/sash ( false) + local nEnd1 = EgtGetInfo( nSplitId, WIN_MIXED_END_CHILDREN .. '1', 'i') + local bSashFill = EgtIf( nEnd1 == WIN_CHILDREN_TYPES.FILL, false, true) + + local nMill3, nMill4 = CalcMixedMillings( vNextOutlines, nNextProfileId, nSplitId, nSplitProfileId, false, bSashFill, nEnd1 == WIN_CHILDREN_TYPES.FILL, nGrp) + EgtSetName( nMill3, WIN_MIXED_MILLING .. WIN_RIGHT .. '1') + EgtSetName( nMill4, WIN_MIXED_MILLING .. WIN_RIGHT .. '2') + + for i = 1, #vNextOutlines do + local nNextPartId = EgtGetInfo( abs( vNextOutlines[i]), WIN_REF_PART, 'i') + local nMixedInters = EgtGetFirstNameInGroup( nNextPartId, WIN_MIXED_CURVES) + if not nMixedInters then + nMixedInters = EgtGroup( nNextPartId) + EgtSetName( nMixedInters, WIN_MIXED_CURVES) + EgtSetStatus( nMixedInters, GDB_ST.OFF) + end + local nCrv1 = EgtCopyGlob( nMill3, nMixedInters) + local nCrv2 = EgtCopyGlob( nMill4, nMixedInters) + local sSide = EgtIf( vNextOutlines[i] > 0, WIN_IN, WIN_OUT) + EgtSetName( nCrv1, WIN_MIXED_MILLING .. sSide .. '1') + EgtSetName( nCrv2, WIN_MIXED_MILLING .. sSide .. '2') end - EgtCopyGlob( nMill3, nMixedInters) - EgtCopyGlob( nMill4, nMixedInters) end end @@ -4333,6 +5109,9 @@ local function TestProcessings( vProcCrvs, vRefCrvs, nGeoOut, nGeoIn) local sName = EgtGetName( nSemiProfileOut) if sName == WIN_OUT then nSurfOut = CreateProfileSurf( nOutlineId, nProfileId, WIN_OFST .. sName, 1000, nGrpTmp) + elseif sName == WIN_MIXED_COMMON .. WIN_IN .. '1' then + nSurfOut = CreateProfileSurf( nOutlineId, nProfileId, WIN_OFST .. WIN_FILL .. WIN_CTRIN .. '1', 1000, nGrpTmp) + EgtInvertSurf( nSurfOut) else nSurfOut = CreateProfileSurf( nOutlineId, nProfileId, WIN_OFST .. 'Ctr' .. sName, 1000, nGrpTmp) EgtInvertSurf( nSurfOut) @@ -4341,6 +5120,8 @@ local function TestProcessings( vProcCrvs, vRefCrvs, nGeoOut, nGeoIn) local sNameIn = EgtGetName( nSemiProfileIn) if sNameIn == WIN_MIXED_COMMON .. WIN_IN then sNameIn = WIN_FILL .. WIN_CTRIN + elseif sNameIn == WIN_MIXED_COMMON .. WIN_IN .. '2' then + sNameIn = WIN_FILL .. WIN_CTRIN .. '2' else sNameIn = 'Ctr' .. sNameIn end @@ -4459,7 +5240,26 @@ local function CreateProfilingProcessingCurve( nGeoCrvId, nPrevCrv, nSurfGeo, nP else -- modifico la curva del geo in allungamento nPrcCrvId = EgtCurveCompo( nPrcLayerId, nGeoCrvId, false) - AddExtension( nPrcCrvId, nInId) + + local dParS = EgtCurveParamAtPoint( nPrcCrvId, EgtSP( nInId), 100 * GEO.EPS_SMALL) + if not dParS then + local dParTrim = EgtCurveParamAtPoint( nInId, EgtSP( nPrcCrvId), 100 * GEO.EPS_SMALL) + if dParTrim then + local nNewCrv = EgtCopyParamRange( nInId, 0, dParTrim, nGrpTmp) + EgtAddCurveCompoCurve( nPrcCrvId, nNewCrv, true, false) + end + end + + local dParE = EgtCurveParamAtPoint( nPrcCrvId, EgtEP( nInId), 100 * GEO.EPS_SMALL) + if not dParE then + local dParTrim = EgtCurveParamAtPoint( nInId, EgtEP( nPrcCrvId), 100 * GEO.EPS_SMALL) + if dParTrim then + local _, dE = EgtCurveDomain( nInId) + local nNewCrv = EgtCopyParamRange( nInId, dParTrim, dE, nGrpTmp) + EgtAddCurveCompoCurve( nPrcCrvId, nNewCrv) + end + end + end end EgtErase( nGrpTmp) @@ -4565,12 +5365,12 @@ local function CalcMixedFrameProfilingProcessings( nPartId, nProcLayerId, nGeoLa -- c) fresature local nMixedIntersGrp = EgtGetFirstNameInGroup( nPartId, WIN_MIXED_CURVES) - local vMixedInters = EgtGetNameInGroup( nMixedIntersGrp, WIN_MIXED_MILLING .. '*') - local dDepth1 = EgtGetInfo( nMainProfileId, WIN_SASH_DEPTH .. '1') + local vMixedInters = EgtGetAllInGroup( nMixedIntersGrp) + local dDepth1 = EgtGetInfo( nMainProfileId, WIN_SASH_DEPTH .. '1', 'd') for i = 1, #vMixedInters do local nMilling = EgtCopyGlob( vMixedInters[i], nProcLayerId) - -- sistemo spessore - if EgtGetName( nMilling) == WIN_MIXED_MILLING .. '1' then + -- sistemo spessore ( solo della fresatura 1, la seconda ha già profondità corretta) + if EgtEndsWith( EgtGetName( nMilling), '1') then EgtModifyCurveThickness( nMilling, - dDepth1) end EgtSetInfo( nMilling, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.PROFILING) @@ -4581,7 +5381,7 @@ end --------------------------------------------------------------------- -- funzione che calcola le lavorazioni di profiling nel caso di uno split coinvolto da cambio profilo -local function CalcMixedSplitProfilingProcessings( nSplitId, nProcLayerId, nGeoLayerId) +local function CalcMixedSplitProfilingProcessings( nSplitId, nProcLayerId, nGeoLayerId, nMainProfileId) -- a) lavorazione dei profili local nGeoArea = EgtGetLastInGroup( nGeoLayerId) @@ -4589,19 +5389,49 @@ local function CalcMixedSplitProfilingProcessings( nSplitId, nProcLayerId, nGeoL -- b) fresature local nMixedIntersGrp = EgtGetFirstNameInGroup( EgtGetParent( nProcLayerId), WIN_MIXED_CURVES) - local nIntersLeft = EgtGetFirstNameInGroup( nMixedIntersGrp, WIN_MIXED_MILLING .. '1') - local nMillingLeft = EgtCopyGlob( nIntersLeft, nProcLayerId) - 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) - local nIntersRight = EgtGetLastNameInGroup( nMixedIntersGrp, WIN_MIXED_MILLING .. '1') - local nMillingRight = EgtCopyGlob( nIntersRight, nProcLayerId) - EgtInvertCurve( nMillingRight) - 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) + -- estremo start ( solo se presenta cambio profilo) + local nMillingLeft = EgtGetFirstNameInGroup( nMixedIntersGrp, WIN_MIXED_MILLING .. WIN_LEFT .. '1') + if nMillingLeft then + local nPrcCrv = EgtCopyGlob( nMillingLeft, nProcLayerId) + EgtSetInfo( nPrcCrv, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.PROFILING) + EgtSetInfo( nPrcCrv, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.GENERIC) + EgtSetInfo( nPrcCrv, WIN_PRC_SIDE, WIN_PRC_SIDETYPE.LEFT) + end + -- estremo end + local nMillingRight = EgtGetFirstNameInGroup( nMixedIntersGrp, WIN_MIXED_MILLING .. WIN_RIGHT .. '1') + if nMillingRight then + local nPrcCrv = EgtCopyGlob( nMillingRight, nProcLayerId) + EgtInvertCurve( nPrcCrv) + EgtSetInfo( nPrcCrv, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.PROFILING) + EgtSetInfo( nPrcCrv, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.GENERIC) + EgtSetInfo( nPrcCrv, WIN_PRC_SIDE, WIN_PRC_SIDETYPE.RIGHT) + end + + -- lavorazioni legate ad altro split con cambio profilo che si innesta sullo split corrente + local dDepth1 = EgtGetInfo( nMainProfileId, WIN_SASH_DEPTH .. '1') + local vCrvsOut = EgtGetNameInGroup( nMixedIntersGrp, WIN_MIXED_MILLING .. WIN_OUT .. '*') + for i = 1, #vCrvsOut do + local nMilling = EgtCopyGlob( vCrvsOut[i], nProcLayerId) + if EgtEndsWith( EgtGetName( nMilling), '1') then + EgtModifyCurveThickness( nMilling, - dDepth1) + end + EgtSetInfo( nMilling, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.PROFILING) + EgtSetInfo( nMilling, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.GENERIC) + EgtSetInfo( nMilling, WIN_PRC_SIDE, WIN_PRC_SIDETYPE.OUT) + end + + local vCrvsIn = EgtGetNameInGroup( nMixedIntersGrp, WIN_MIXED_MILLING .. WIN_IN .. '*') + for i = 1, #vCrvsIn do + local nMilling = EgtCopyGlob( vCrvsIn[i], nProcLayerId) + if EgtEndsWith( EgtGetName( nMilling), '1') then + EgtModifyCurveThickness( nMilling, - dDepth1) + end + EgtSetInfo( nMilling, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.PROFILING) + EgtSetInfo( nMilling, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.GENERIC) + EgtSetInfo( nMilling, WIN_PRC_SIDE, WIN_PRC_SIDETYPE.IN) + end end --------------------------------------------------------------------- @@ -4629,11 +5459,11 @@ local function CalcProfilingProcessings( nPartId, nOutlineId) 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 + local nPrfChange = EgtGetInfo( nOutlineId, WIN_PRF_CHANGE, 'i') or WIN_PRF_CHANGE_TYPES.NULL + if nPrfChange > 0 then + -- 1) cambio profilo ( su split o telaio) if EgtGetName( nOutlineId) == WIN_SPLIT then - CalcMixedSplitProfilingProcessings( nOutlineId, nProcLayerId, nGeoLayerId) + CalcMixedSplitProfilingProcessings( nOutlineId, nProcLayerId, nGeoLayerId, nMainProfileId) else CalcMixedFrameProfilingProcessings( nPartId, nProcLayerId, nGeoLayerId, nMainProfileId, nSurfGeo) end @@ -4787,9 +5617,8 @@ end --------------------------------------------------------------------- -- funzione che crea la guida per la superficie di trim, opportunamente estesa per avere booleane ben definite -local function CalcGuideExtension( nCrvId, nGeoId, nSurfTrimId, nLayerId) - - local nSemiProfile = EgtGetInfo( nGeoId, WIN_SEMI_PROFILE, 'i') +local function CalcGuideExtension( nCrvId, nGeoId, nSemiProfile, nSurfTrimId, nLayerId) + local nGrpTmp = EgtGroup( nLayerId) -- creo estensione della curva ( può essere fatta in tangenza perchè parto dalla curva di processing) @@ -4842,13 +5671,14 @@ local function CalcGuideExtension( nCrvId, nGeoId, nSurfTrimId, nLayerId) end --------------------------------------------------------------------- --- funzione che crea le superfici di trim e taglia il solido -local function TrimSolid( vGeoIds, nLayerId, nMainExtrusionId, nMainGuideId, nMainProfileId) +-- funzione che crea le superfici di trim +local function CreateTrimSurfs( vGeoIds, nLayerId, nMainGuideId, nMainProfileId) -- creo la superficie di riferimento del solido originale per capire di quanto estendere le superfici di trim in modo da avere booleane ben definite tra le superfici local b3Profile = GetProfileLocalBox( nMainProfileId) - local nOffsMax = EgtOffsetCurveAdv( nMainGuideId, b3Profile:getMax():getX()) - local nOffsMin = EgtOffsetCurveAdv( nMainGuideId, b3Profile:getMin():getX()) + local dRailOffs = EgtGetInfo( nMainProfileId, WIN_RAILOFFS, 'd') or 0 + local nOffsMax = EgtOffsetCurveAdv( nMainGuideId, b3Profile:getMax():getX() - dRailOffs) + local nOffsMin = EgtOffsetCurveAdv( nMainGuideId, b3Profile:getMin():getX() - dRailOffs) EgtInvertCurve( nOffsMin) local nCompo = EgtCurveCompo( nLayerId, nOffsMax) EgtAddCurveCompoLine( nCompo, EgtSP( nOffsMin)) @@ -4858,7 +5688,7 @@ local function TrimSolid( vGeoIds, nLayerId, nMainExtrusionId, nMainGuideId, nMa EgtSetStatus( nSurfTrim, GDB_ST.OFF) EgtSetStatus( nCompo, GDB_ST.OFF) - + local vTrimSurfs = {} local tabPrcCrv = {} for i = 1, #vGeoIds do @@ -4870,7 +5700,7 @@ local function TrimSolid( vGeoIds, nLayerId, nMainExtrusionId, nMainGuideId, nMa -- 1) minizinken if not nSemiProfileId then - nGuideId = CalcGuideExtension( vGeoIds[i], vGeoIds[i], nSurfTrim, nLayerId) + nGuideId = CalcGuideExtension( vGeoIds[i], vGeoIds[i], nil, nSurfTrim, nLayerId) EgtMove( nGuideId, Z_AX()) nTrimSurf = EgtSurfTmByExtrusion( nLayerId, nGuideId, - Z_AX() * 2 * b3Profile:getDimY(), WIN_SURF_APPROX) EgtInvertSurf( nTrimSurf) @@ -4885,10 +5715,20 @@ local function TrimSolid( vGeoIds, nLayerId, nMainExtrusionId, nMainGuideId, nMa -- se la superficie di trim è già stata creata salvo associazione nella curva geo EgtSetInfo( vGeoIds[i], WIN_REF_SURF, tabPrcCrv[nPrcCrv]) else + -- nel caso di trim di split con cambio profilo non deve essere usato il semiprofilo common salvato nel geo, ma devo usare quello sash + local sSemiProfileName = EgtGetName( nSemiProfileId) + if sSemiProfileName == WIN_MIXED_COMMON .. WIN_IN then + nSemiProfileId = EgtGetFirstNameInGroup( EgtGetParent( nSemiProfileId), WIN_SASH .. WIN_CTRIN) + elseif sSemiProfileName == WIN_MIXED_COMMON .. WIN_IN .. '1' then + nSemiProfileId = EgtGetFirstNameInGroup( EgtGetParent( nSemiProfileId), WIN_SASH .. WIN_CTRIN .. '1') + elseif sSemiProfileName == WIN_MIXED_COMMON .. WIN_IN .. '2' then + nSemiProfileId = EgtGetFirstNameInGroup( EgtGetParent( nSemiProfileId), WIN_SASH .. WIN_CTRIN .. '2') + end + -- riposiziono la curva di lavorazione in corrispondenza dell'outline local dOffs = EgtGetInfo( vGeoIds[i], WIN_GEO_OFFS, 'd') local nOffsCrv = EgtOffsetCurveAdv( nPrcCrv, - dOffs) - nGuideId = CalcGuideExtension( nOffsCrv, vGeoIds[i], nSurfTrim, nLayerId) + nGuideId = CalcGuideExtension( nOffsCrv, vGeoIds[i], nSemiProfileId, nSurfTrim, nLayerId) EgtErase( nOffsCrv) local nRefOutline = EgtGetInfo( vGeoIds[i], WIN_REF_OUTLINE, 'i') if nRefOutline < 0 then @@ -4905,8 +5745,8 @@ local function TrimSolid( vGeoIds, nLayerId, nMainExtrusionId, nMainGuideId, nMa -- taglio il solido principale if nTrimSurf then + table.insert( vTrimSurfs, nTrimSurf) EgtSetStatus( nTrimSurf, GDB_ST.OFF) - EgtSurfTmIntersect( nMainExtrusionId, nTrimSurf) EgtErase( nGuideId) EgtSetInfo( vGeoIds[i], WIN_REF_SURF, nTrimSurf) end @@ -4914,7 +5754,7 @@ local function TrimSolid( vGeoIds, nLayerId, nMainExtrusionId, nMainGuideId, nMa EgtErase( nSurfTrim) EgtErase( nCompo) - + return vTrimSurfs end --------------------------------------------------------------------- @@ -4960,196 +5800,208 @@ local function CalcSolidGuide( nOutlineId, nSolidLayerId, nProfileId, nGeoLayerI EgtSetName( nGuideId, WIN_MAINGUIDE) EgtSetStatus( nGuideId, GDB_ST.OFF) - -- se bottomrail sposto opportunamente la guida - local sProfileType = EgtGetInfo( nProfileId, WIN_PROFILETYPE) - if sProfileType == WIN_RAIL or sProfileType == WIN_FILL_RAIL then - local dOffs = EgtGetInfo( nProfileId, WIN_RAILOFFS, 'd') - EgtOffsetCurve( nGuideId, - dOffs) - end - return nGuideId end --------------------------------------------------------------------- --- funzione che crea il solido di estrusione principale -local function CreateMainSurf( nGuideId, nProfileId, sSectionName, nLayerId) - - -- 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 +-- funzione che crea la superficie di taglio corrispondente alle fresature del cambio profilo che separano le parti sash e fill +local function CalcMixedCurveTrimSurf( vMixedCurves, nSolidLayerId, dExtraLen) + + local vStmInters = {} + for i = 1, #vMixedCurves do + local nSplitId = EgtGetInfo( vMixedCurves[i], WIN_MIXED_SPLIT_REF, 'i') + local vtDir = EgtSV( nSplitId) + local bFillOnSplitRight = EgtGetInfo( vMixedCurves[i], WIN_FILL_ON_SPLIT_RIGHT, 'b') + if bFillOnSplitRight then + vtDir = - vtDir + end + + local nCrvTrim = EgtCopyGlob( vMixedCurves[i], nSolidLayerId) + EgtAddCurveCompoLine( nCrvTrim, EgtSP( nCrvTrim) + 3 * dExtraLen * vtDir, false) + EgtAddCurveCompoLine( nCrvTrim, EgtEP( nCrvTrim) - 3 * dExtraLen * vtDir) + EgtMove( nCrvTrim, Z_AX()) + EgtSetStatus( nCrvTrim, GDB_ST.OFF) + vStmInters[i] = EgtSurfTmByExtrusion( nSolidLayerId, nCrvTrim, - 2 * dExtraLen * Z_AX()) + EgtErase( nCrvTrim) + end + + local nStmTrim = EgtSurfTmByTriangles( nSolidLayerId, vStmInters) + return nStmTrim end --------------------------------------------------------------------- -- funzione che crea il solido di un pezzo di telaio con cambio profilo -local function CalcMixedFrameSolid( nOutlineId, nSolidLayerId, nProfileLayerId, nGeoLayerId, dGeoWidth) +local function CalcMixedFrameSolid( nOutlineId, nSolidLayerId, nMainProfileId, nGeoLayerId, dGeoWidth) - -- a) SOLIDO PRINCIPALE - -- creo i solidi corrispondenti alla parte sash e alla parte fill - local nMainProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN) + -- a) solido principale local nGuideId = CalcSolidGuide( nOutlineId, nSolidLayerId, nMainProfileId, nGeoLayerId) EgtSetName( nGuideId, WIN_MAINGUIDE) EgtSetStatus( nGuideId, GDB_ST.OFF) + -- creo i solidi corrispondenti alla parte sash e alla parte fill local sSectionSash = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. WIN_SASH .. WIN_SECTION - local nMainSash = CreateMainSurf( nGuideId, nMainProfileId, sSectionSash, nSolidLayerId) + local nMainSash = CreateProfileSurf( nGuideId, nMainProfileId, sSectionSash, 0, nSolidLayerId) local sSectionFill = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. WIN_FILL .. WIN_SECTION - local nMainFill = CreateMainSurf( nGuideId, nMainProfileId, sSectionFill, nSolidLayerId) + local nMainFill = CreateProfileSurf( nGuideId, nMainProfileId, sSectionFill, 0, nSolidLayerId) -- calcolo le superfici di taglio corrispondenti alle fresature del cambio profilo che separano la parte sash e fill local nMixedIntersectionsGrp = EgtGetFirstNameInGroup( EgtGetParent( nSolidLayerId), WIN_MIXED_CURVES) - local vIntersections = EgtGetNameInGroup( nMixedIntersectionsGrp, WIN_MIXED_MILLING .. '1') - local vStmInters = {} - for i = 1, #vIntersections do - local nSplitId = EgtGetInfo( vIntersections[i], WIN_MIXED_SPLIT_REF, 'i') - local vtDir = EgtSV( nSplitId) - local nCrvTrim = EgtCopyGlob( vIntersections[i], nSolidLayerId) - EgtAddCurveCompoLine( nCrvTrim, EgtSP( nCrvTrim) - 3 * dGeoWidth * vtDir, false) - EgtAddCurveCompoLine( nCrvTrim, EgtEP( nCrvTrim) + 3 * dGeoWidth * vtDir) - EgtMove( nCrvTrim, Z_AX()) - EgtSetStatus( nCrvTrim, GDB_ST.OFF) - vStmInters[i] = EgtSurfTmByExtrusion( nSolidLayerId, nCrvTrim, - 2 * dGeoWidth * Z_AX()) - EgtErase( nCrvTrim) - end + local vIntersections = EgtGetNameInGroup( nMixedIntersectionsGrp, WIN_MIXED_MILLING .. WIN_IN .. '1') + local nStmTrim = CalcMixedCurveTrimSurf( vIntersections, nSolidLayerId, dGeoWidth) + -- taglio le parti sash e fill e le riunisco in una sola superficie - local nStmTrim = EgtSurfTmByTriangles( nSolidLayerId, vStmInters) EgtSurfTmIntersect( nMainFill, nStmTrim) EgtSurfTmSubtract( nMainSash, nStmTrim) EgtErase( nStmTrim) EgtSurfTmAdd( nMainSash, nMainFill) EgtErase( nMainFill) local nMainSolid = nMainSash + EgtSetName( nMainSolid, WIN_SRF_MAIN) -- creo una copia dell'estrusione principale ( usata per ferramenta) local nOrigMainExtrusionId = EgtCopy( nMainSolid, nSolidLayerId) EgtSetName( nOrigMainExtrusionId, WIN_SRF_ORIGMAIN) EgtSetStatus( nOrigMainExtrusionId, GDB_ST.OFF) - -- b) TRIM START + -- b) trim start local vPrevGeoIds = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_LEFT) - TrimSolid( vPrevGeoIds, nSolidLayerId, nMainSolid, nGuideId, nMainProfileId) + local vTrimStart = CreateTrimSurfs( vPrevGeoIds, nSolidLayerId, nGuideId, nMainProfileId) + for i = 1, #vTrimStart do + EgtSurfTmIntersect( nMainSolid, vTrimStart[i]) + end - -- c) TRIM END + -- c) trim end local vNextGeoIds = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_RIGHT) - TrimSolid( vNextGeoIds, nSolidLayerId, nMainSolid, nGuideId, nMainProfileId) + local vTrimEnd = CreateTrimSurfs( vNextGeoIds, nSolidLayerId, nGuideId, nMainProfileId) + for i = 1, #vTrimEnd do + EgtSurfTmIntersect( nMainSolid, vTrimEnd[i]) + end return nMainSolid end --------------------------------------------------------------------- --- funzione che calcola il solido corrispondente alla fresatura del cambio profilo per uno split -local function CalcMixedSplitMillingSolid( nMillingCrv, nSplitId, nSolidLayerId, dExtraLen, bPrev) +-- funzione che crea la superficie di trim per uno split coinvolto da cambio profilo ( controprofilo della parte sash dei vicini e fresatura) +local function CreateMixedSplitTrimSurfs( vGeoCrvs, bStart, nSolidLayerId, nSplitId, nGuideId, nMainProfileId, dGeoWidth) - local nGuide = EgtCopyGlob( nMillingCrv, nSolidLayerId) - EgtAddCurveCompoLineTg( nGuide, 10, not bPrev) - local vtDir = EgtSV( nSplitId) - if bPrev then - vtDir = - vtDir + -- superfici di trim + local vTrimSurfs = CreateTrimSurfs( vGeoCrvs, nSolidLayerId, nGuideId, nMainProfileId) + + -- recupero la fresatura + local nMixedIntersGrp = EgtGetFirstNameInGroup( EgtGetParent( nSolidLayerId), WIN_MIXED_CURVES) + local nMillingCrv = EgtGetFirstNameInGroup( nMixedIntersGrp, WIN_MIXED_MILLING .. EgtIf( bStart, WIN_LEFT, WIN_RIGHT) .. '1') + if nMillingCrv then + -- costruisco il solido associato alla fresatura + local nGuide = EgtCopyGlob( nMillingCrv, nSolidLayerId) + EgtAddCurveCompoLineTg( nGuide, 10, true) + EgtAddCurveCompoLineTg( nGuide, 10, false) + local vtDir = EgtSV( nSplitId) + if bStart then + vtDir = - vtDir + end + EgtAddCurveCompoLine( nGuide, EgtEP( nGuide) + 2 * dGeoWidth * vtDir) + EgtAddCurveCompoLine( nGuide, EgtSP( nGuide) + 2 * dGeoWidth * vtDir, false) + EgtCloseCurveCompo( nGuide) + EgtMove( nGuide, 0.01 * Z_AX()) + local nMillStm = EgtSurfTmByRegionExtrusion( nSolidLayerId, nGuide, ( EgtCurveThickness( nGuide) - 2) * Z_AX()) + + -- lo sottraggo alle superfici di trim + for i = 1, #vTrimSurfs do + EgtSurfTmSubtract( vTrimSurfs[i], nMillStm) + end + + EgtErase( nGuide) + EgtErase( nMillStm) end - EgtAddCurveCompoLine( nGuide, EgtEP( nGuide) + dExtraLen * vtDir) - EgtAddCurveCompoLine( nGuide, EgtSP( nGuide) + dExtraLen * vtDir, false) - EgtCloseCurveCompo( nGuide) - EgtMove( nGuide, 0.01 * Z_AX()) - local nCutStm = EgtSurfTmByRegionExtrusion( nSolidLayerId, nGuide, ( EgtCurveThickness( nGuide) - 2) * Z_AX()) - EgtErase( nGuide) - return nCutStm + + return vTrimSurfs end --------------------------------------------------------------------- --- funzione che crea la superficie di trim per uno split coinvolto da cambio profilo ( controprofilo della parte sash del telaio e fresatura) -local function CreateMixedSplitTrimSurf( nSplitId, vOutlines, nProfileId, dExtraLen, bPrev, bNext, nSolidLayerId) +-- funzione che completa il semiprofilo per creare una sezione da estrudere per il solido di un mixed split +local function CreateExtrusionSection( nSemiProfileId) + + -- recupero il Ref e lo taglio con il semiprofilo + local nProfileId = EgtGetParent( nSemiProfileId) + local nRefId = EgtGetFirstNameInGroup( nProfileId, WIN_REF) - -- curva base - local nGuideId = EgtCurveCompo( nSolidLayerId, vOutlines, false) - local sTrimProfile = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. WIN_OFST .. WIN_SASH .. WIN_CTRIN - local nTrimStmId = CreateProfileSurf( nGuideId, nProfileId, sTrimProfile, dExtraLen, nSolidLayerId) - -- creo i blocchi per le milling - local nMixedIntersGrp = EgtGetFirstNameInGroup( EgtGetParent( nSolidLayerId), WIN_MIXED_CURVES) - if bPrev then - local nMillingCrv = EgtGetFirstNameInGroup( nMixedIntersGrp, WIN_MIXED_MILLING .. '1') - local nMillStmId = CalcMixedSplitMillingSolid( nMillingCrv, nSplitId, nSolidLayerId, dExtraLen, true) - EgtSurfTmSubtract( nTrimStmId, nMillStmId) - EgtErase( nMillStmId) - end - if bNext then - local nMillingCrv = EgtGetLastNameInGroup( nMixedIntersGrp, WIN_MIXED_MILLING .. '1') - local nMillStmId = CalcMixedSplitMillingSolid( nMillingCrv, nSplitId, nSolidLayerId, dExtraLen, false) - EgtSurfTmSubtract( nTrimStmId, nMillStmId) - EgtErase( nMillStmId) - end - EgtSetStatus( nTrimStmId, GDB_ST.OFF) - EgtErase( nGuideId) - return nTrimStmId + local nSection = EgtCopyGlob( nRefId, nProfileId) + local dPar1 = EgtCurveParamAtPoint( nSection, EgtSP( nSemiProfileId)) + local dPar2 = EgtCurveParamAtPoint( nSection, EgtEP( nSemiProfileId)) + EgtTrimCurveStartEndAtParam( nSection, dPar2, dPar1) + EgtAddCurveCompoCurve( nSection, nSemiProfileId, false) + + return nSection end --------------------------------------------------------------------- -- funzione che crea il solido di un pezzo di split coinvolto da cambio profilo -local function CalcMixedSplitSolid( nOutlineId, nSolidLayerId, nProfileLayerId, nGeoLayerId, dGeoWidth) +local function CalcMixedSplitSolid( nOutlineId, nSolidLayerId, nMainProfileId, nGeoLayerId, dGeoWidth) - -- a) creo il solido di estrusione principale - local nMainProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN) + -- a) solido principale local nGuideId = CalcSolidGuide( nOutlineId, nSolidLayerId, nMainProfileId, nGeoLayerId) - local sSection = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. WIN_SECTION - local nMainExtrusionId = CreateMainSurf( nGuideId, nMainProfileId, sSection, nSolidLayerId) - -- creo una copia + -- creo un solido per ogni lato dello split + local vSolids = {} + for i = 1, 2 do + -- verifico se ho un solo profilo definito + local nSemiProfile = EgtGetFirstNameInGroup( nMainProfileId, WIN_IN .. tostring( i)) + if nSemiProfile then + local nSection = CreateExtrusionSection( nSemiProfile) + vSolids[i] = CreateProfileSurfById( nGuideId, nMainProfileId, nSection, 0, nSolidLayerId) + else + -- creo i solidi sash e fill + local nSemiProfileSash = EgtGetFirstNameInGroup( nMainProfileId, WIN_SASH .. WIN_IN .. tostring( i)) + local nSashSection = CreateExtrusionSection( nSemiProfileSash) + local nSashSolid = CreateProfileSurfById( nGuideId, nMainProfileId, nSashSection, 0, nSolidLayerId) + local nSemiProfileFill = EgtGetFirstNameInGroup( nMainProfileId, WIN_FILL .. WIN_IN .. tostring( i)) + local nFillSection = CreateExtrusionSection( nSemiProfileFill) + local nFillSolid = CreateProfileSurfById( nGuideId, nMainProfileId, nFillSection, 0, nSolidLayerId) + + -- calcolo le superfici di taglio corrispondenti alle fresature del cambio profilo che separano la parte sash e fill + local nMixedIntersectionsGrp = EgtGetFirstNameInGroup( EgtGetParent( nSolidLayerId), WIN_MIXED_CURVES) + local vIntersections = EgtGetNameInGroup( nMixedIntersectionsGrp, WIN_MIXED_MILLING .. EgtIf( i == 1, WIN_OUT, WIN_IN) .. '1') + local nStmTrim = CalcMixedCurveTrimSurf( vIntersections, nSolidLayerId, dGeoWidth) + + -- costruisco il solido combinando opportunamente le parti sash e fill + EgtSurfTmIntersect( nFillSolid, nStmTrim) + EgtSurfTmSubtract( nSashSolid, nStmTrim) + EgtErase( nStmTrim) + EgtSurfTmAdd( nSashSolid, nFillSolid) + EgtErase( nFillSolid) + vSolids[i] = nSashSolid + end + end + + -- taglio e unisco le due metà + local b3Profile = GetProfileLocalBox( nMainProfileId) + local dOffs = ( b3Profile:getMax():getX() + b3Profile:getMin():getX()) * 0.5 + local nOffsGuide = EgtOffsetCurveAdv( nGuideId, dOffs) + EgtMove( nOffsGuide, 2 * Z_AX()) + local nStmTrim = EgtSurfTmByExtrusion( nSolidLayerId, nOffsGuide, - Z_AX() * ( b3Profile:getDimY() + 5)) + EgtSurfTmCut( vSolids[1], nStmTrim, true, false) + EgtSurfTmCut( vSolids[2], nStmTrim, false, false) + EgtErase( nStmTrim) + local nMainExtrusionId = EgtSurfTmByTriangles( nSolidLayerId, vSolids) + EgtSetName( nMainExtrusionId, WIN_SRF_MAIN) + + -- creo una copia ( usata per calcolo ferramenta) local nOrigMainExtrusionId = EgtCopy( nMainExtrusionId, nSolidLayerId) EgtSetName( nOrigMainExtrusionId, WIN_SRF_ORIGMAIN) EgtSetStatus( nOrigMainExtrusionId, GDB_ST.OFF) - -- b) calcolo le superfici di trim con i controprofili sash e le curve di fresatura verificando se i tratti prev e next possono essere uniti per evitare di fare - -- booleane con superfici in parte sovrapposte - local vPrevOutlines = EgtGetInfo( nOutlineId, WIN_PREV_OUTLINES, 'vi') - local vNextOutlines = EgtGetInfo( nOutlineId, WIN_NEXT_OUTLINES, 'vi') - local vPrevGeo = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_LEFT) - local vNextGeo = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_RIGHT) - - if vPrevOutlines[1] == vNextOutlines[#vNextOutlines] or vPrevOutlines[#vPrevOutlines] == vNextOutlines[1] then - -- se prev e next hanno una curva comune gestisco come unica superficie - local vCrvs - if vPrevOutlines[1] == vNextOutlines[#vNextOutlines] then - vNextOutlines[#vNextOutlines] = nil - vCrvs = EgtJoinTables( vNextOutlines, vPrevOutlines) - else - vPrevOutlines[#vPrevOutlines] = nil - vCrvs = EgtJoinTables( vPrevOutlines, vNextOutlines) - end - local nPrevProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_START) - local nTrimStmId = CreateMixedSplitTrimSurf( nOutlineId, vCrvs, nPrevProfileId, 2 * dGeoWidth, true, true, nSolidLayerId) - EgtSurfTmIntersect( nMainExtrusionId, nTrimStmId) - for i = 1, #vPrevGeo do - EgtSetInfo( vPrevGeo[i], WIN_REF_SURF, nTrimStmId) - end - for i = 1, #vNextGeo do - EgtSetInfo( vNextGeo[i], WIN_REF_SURF, nTrimStmId) - end - - else - local nPrevProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_START) - local nTrimStmId1 = CreateMixedSplitTrimSurf( nOutlineId, vPrevOutlines, nPrevProfileId, 2 * dGeoWidth, true, false, nSolidLayerId) - EgtSurfTmIntersect( nMainExtrusionId, nTrimStmId1) - for i = 1, #vPrevGeo do - EgtSetInfo( vPrevGeo[i], WIN_REF_SURF, nTrimStmId1) - end - - local nNextProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_END) - local nTrimStmId2 = CreateMixedSplitTrimSurf( nOutlineId, vNextOutlines, nNextProfileId, 2 * dGeoWidth, false, true, nSolidLayerId) - EgtSurfTmIntersect( nMainExtrusionId, nTrimStmId2) - for i = 1, #vNextGeo do - EgtSetInfo( vNextGeo[i], WIN_REF_SURF, nTrimStmId2) - end + -- b) trim start + local vGeoLeft = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_LEFT) + local vTrimStart = CreateMixedSplitTrimSurfs( vGeoLeft, true, nSolidLayerId, nOutlineId, nGuideId, nMainProfileId, dGeoWidth) + for i = 1, #vTrimStart do + EgtSurfTmIntersect( nMainExtrusionId, vTrimStart[i]) end - + + -- c) trim end + local vGeoRight = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_RIGHT) + local vTrimEnd = CreateMixedSplitTrimSurfs( vGeoRight, false, nSolidLayerId, nOutlineId, nGuideId, nMainProfileId, dGeoWidth) + for i = 1, #vTrimEnd do + EgtSurfTmIntersect( nMainExtrusionId, vTrimEnd[i]) + end + return nMainExtrusionId end @@ -5163,37 +6015,46 @@ local function CalcSolid( nPartId, nOutlineId) -- recupero profilo principale local nProfileLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE) - + local nMainProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN) + -- 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 + local nPrfChange = EgtGetInfo( nOutlineId, WIN_PRF_CHANGE, 'i') or WIN_PRF_CHANGE_TYPES.NULL + if nPrfChange > 0 then if EgtGetName( nOutlineId) == WIN_SPLIT then - return CalcMixedSplitSolid( nOutlineId, nSolidLayerId, nProfileLayerId, nGeoLayerId, dGeoWidth) + return CalcMixedSplitSolid( nOutlineId, nSolidLayerId, nMainProfileId, nGeoLayerId, dGeoWidth) else - return CalcMixedFrameSolid( nOutlineId, nSolidLayerId, nProfileLayerId, nGeoLayerId, dGeoWidth) + return CalcMixedFrameSolid( nOutlineId, nSolidLayerId, nMainProfileId, nGeoLayerId, dGeoWidth) end end -- a) creo il solido di estrusione principale - local nMainProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN) local nGuideId = CalcSolidGuide( nOutlineId, nSolidLayerId, nMainProfileId, nGeoLayerId) local sSection = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. WIN_SECTION - local nMainExtrusionId = CreateMainSurf( nGuideId, nMainProfileId, sSection, nSolidLayerId) + local nMainExtrusionId = CreateProfileSurf( nGuideId, nMainProfileId, sSection, 0, nSolidLayerId) + EgtSetName( nMainExtrusionId, WIN_SRF_MAIN) -- 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 su start e su end - local nGeoRight = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_RIGHT) - TrimSolid( nGeoRight, nSolidLayerId, nMainExtrusionId, nGuideId, nMainProfileId) - local nGeoLeft = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_LEFT) - TrimSolid( nGeoLeft, nSolidLayerId, nMainExtrusionId, nGuideId, nMainProfileId) + -- b) trim con i controprofili su start + local vGeoLeft = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_LEFT) + local vTrimStart = CreateTrimSurfs( vGeoLeft, nSolidLayerId, nGuideId, nMainProfileId) + for i = 1, #vTrimStart do + EgtSurfTmIntersect( nMainExtrusionId, vTrimStart[i]) + end + + -- c) trim con i controprofili su end + local vGeoRight = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_RIGHT) + local vTrimEnd = CreateTrimSurfs( vGeoRight, nSolidLayerId, nGuideId, nMainProfileId) + for i = 1, #vTrimEnd do + EgtSurfTmIntersect( nMainExtrusionId, vTrimEnd[i]) + end return nMainExtrusionId end @@ -5215,7 +6076,7 @@ end ---------------------------------------------------------------------------------- -- funzione che aggiorna il solido principale con quello associato ad una lavorazione partendo dalla sua curva -local function UpdateSolidWithProcessingSurf( nProcId, nSolidId, nLayerId) +local function UpdateSolidWithProcessingCrv( nProcId, nSolidId, nLayerId) if not EgtCurveIsClosed( nProcId) then return @@ -5318,7 +6179,7 @@ local function CreateDowel( nOrigDowelId, nLayerId, frOrig, frDest, vtDir, nTest -- eventuale aggiornamento del solido if nMainExtrusionId then - UpdateSolidWithProcessingSurf( nDowelId, nMainExtrusionId, nLayerId) + UpdateSolidWithProcessingCrv( nDowelId, nMainExtrusionId, nLayerId) end return nDowelId @@ -5453,7 +6314,7 @@ local function CalcDowels( nOrigOutlineId, nOrigPrevOutlineId, bSashOrFrame, nBo -- 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( nOrigOutlineId, nPrevOutlineId, nProfileId) -- controprofilo in del pezzo corrente + local sCtrIn = WIN_OFST .. GetProfileCtrIn( nOrigOutlineId, nPrevOutlineId, nProfileId, false) -- controprofilo in del pezzo corrente nTestSurf = CreateProfileSurf( nOrigOutlineId, nProfileId, sCtrIn, 100, nLayerId) else -- è la superficie che viene utilizzata per trimmare l'end del pezzo prev @@ -5514,7 +6375,7 @@ local function CalcDowels( nOrigOutlineId, nOrigPrevOutlineId, bSashOrFrame, nBo -- è 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( nOrigPrevOutlineId, nOutlineId, nPrevProfileId) -- controprofilo del pezzo full + local sCtrIn = WIN_OFST .. GetProfileCtrIn( nOrigPrevOutlineId, nOutlineId, nPrevProfileId, true) -- controprofilo del pezzo full nTestSurf = CreateProfileSurf( nOrigPrevOutlineId, nPrevProfileId, sCtrIn, 100, nLayerId) else local nOrigSurf = EgtGetInfo( nCurrLeft, WIN_REF_SURF, 'i') @@ -5575,17 +6436,25 @@ local function CalcSplitDowels( nSplitId, bStartOrEnd) end -- indviduo il lato su cui andranno i dowels - local sSplitDowelSide = WIN_PRC_SIDETYPE.RIGHT - if bStartOrEnd then - sSplitDowelSide = WIN_PRC_SIDETYPE.LEFT - end + local sSplitDowelSide = EgtIf( bStartOrEnd, WIN_PRC_SIDETYPE.LEFT, WIN_PRC_SIDETYPE.RIGHT) - -- recupero la superficie del pezzo per verificare se dowel interno + -- recupero le curve del geo e la superficie del pezzo ( per verificare se dowel interno) local nSplitGeo = EgtGetFirstNameInGroup( nSplitPart, WIN_GEO) - local nSplitSurf = EgtGetFirstNameInGroup( nSplitGeo, WIN_GEO_SURF) - local vGeoCrvs = EgtGetNameInGroup( nSplitGeo, EgtIf( bStartOrEnd, WIN_LEFT, WIN_RIGHT)) - local ptRef = EgtIf( bStartOrEnd, EgtSP( nSplitId), EgtEP( nSplitId)) + local nSplitSurf = EgtGetFirstNameInGroup( nSplitGeo, WIN_GEO_SURF) + + -- verifico se necessario calcolare le superifici di trim associate alle curve del geo + local vAuxSurfs = {} + if not s_bCalcSolid or s_bSimplSolid then + -- simulo la guida per il calcolo del solido + local nGuideId = CalcSolidGuide( nSplitId, nSplitLayerId, nSplitProfile, nSplitGeo) + if EgtGetInfo( nSplitId, WIN_SPLITTYPE, 'i') == WIN_SPLITTYPES.MIXED then + vAuxSurfs = CreateMixedSplitTrimSurfs( vGeoCrvs, bStartOrEnd, nSplitLayerId, nSplitId, nGuideId, nSplitProfile, 100) + else + vAuxSurfs = CreateTrimSurfs( vGeoCrvs, nSplitLayerId, nGuideId, nSplitProfile) + end + EgtErase( nGuideId) + end for i = 1, #vGeoCrvs do @@ -5595,7 +6464,6 @@ local function CalcSplitDowels( nSplitId, bStartOrEnd) local nOrigOutline = abs( EgtGetInfo( vGeoCrvs[i], WIN_REF_OUTLINE, 'i')) -- verifico se soglia ( in quel caso non ci sono dowels quindi va ignorato) local bThreshold = EgtGetInfo( nOrigOutline, WIN_THRESHOLD, 'b') or false - if not bThreshold then -- recupero il pezzo associato e il suo outline di riferimento @@ -5656,27 +6524,8 @@ local function CalcSplitDowels( nSplitId, bStartOrEnd) 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 vOutlines - if bStartOrEnd then - vOutlines = EgtGetInfo( nSplitId, WIN_PREV_OUTLINES, 'vi') - else - vOutlines = EgtGetInfo( nSplitId, WIN_NEXT_OUTLINES, 'vi') - end - nTestSurf = CreateMixedSplitTrimSurf( nSplitId, vOutlines, nProfileId, 100, bStartOrEnd, not bStartOrEnd, 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 - local nTrimSurf = EgtGetInfo( vGeoCrvs[i], WIN_REF_SURF, 'i') - nTestSurf = EgtCopyGlob( nTrimSurf, nSplitLayerId) - end + local nTrimSurf = EgtGetInfo( vGeoCrvs[i], WIN_REF_SURF, 'i') + local nTestSurf = EgtCopyGlob( nTrimSurf, nSplitLayerId) local nTestSurfInverted = EgtCopyGlob( nTestSurf, nSplitLayerId) EgtInvertSurf( nTestSurfInverted) @@ -5711,15 +6560,15 @@ local function CalcSplitDowels( nSplitId, bStartOrEnd) EgtErase( nDowel2) end EgtErase( nTestPoint) - end EgtErase( nTestSurf) EgtErase( nTestSurfInverted) - end end end + + EgtErase( vAuxSurfs) end --------------------------------------------------------------------- @@ -6420,7 +7269,7 @@ local function CalcLogDowel( nOrigPartId, nCrvOut, bLeftOrRight, nProcLayerId, n -- eventuale aggiornamento del solido if nSolidId then - UpdateSolidWithProcessingSurf( nDowelId, nSolidId, nProcLayerId) + UpdateSolidWithProcessingCrv( nDowelId, nSolidId, nProcLayerId) end end @@ -7432,7 +8281,7 @@ local function CalcHdwMachining( tMachining, SashList) EgtTransform( nPocketOutlineId, frHdw) -- aggiornamento del solido if s_bCalcSolid then - UpdateSolidWithProcessingSurf( nPocketOutlineId, nMainExtrusionId, nSolidLayerId) + UpdateSolidWithProcessingCrv( nPocketOutlineId, nMainExtrusionId, nSolidLayerId) end elseif vMacro[1] == 'TASCA' then @@ -7471,7 +8320,7 @@ local function CalcHdwMachining( tMachining, SashList) EgtTransform( nHoleId, frHdw) -- aggiornamento del solido if s_bCalcSolid then - UpdateSolidWithProcessingSurf( nHoleId, nMainExtrusionId, nSolidLayerId) + UpdateSolidWithProcessingCrv( nHoleId, nMainExtrusionId, nSolidLayerId) end end end @@ -8160,7 +9009,7 @@ end ---------------------------------------------------------------------------------- --------------------------------- PREVIEW ---------------------------------------- ---------------------------------------------------------------------------------- -local function CalcBottomRailPreview( nPreviewGrp, nOutlineId, nBottomRail, nGeoGrp, color) +local function CalcBottomRailPreview( nPreviewGrp, nOutlineId, nBottomRail, nGeoGrp) -- costruisco box complessivo degli zoccoli local vCrvs = {} @@ -8195,7 +9044,7 @@ local function CalcBottomRailPreview( nPreviewGrp, nOutlineId, nBottomRail, nGeo -- creo la regione e ne estraggo il bordo local nAreaId = CalcIntersectionRegion( vCrvs, nPreviewGrp) - EgtSetColor( nAreaId, color) + EgtSetColor( nAreaId, Color3d( 251, 128, 4)) local nCrvId = EgtExtractSurfFrChunkLoops( nAreaId, 0, nPreviewGrp) EgtSetColor( nCrvId, EgtStdColor( 'BLACK')) EgtModifyCurveThickness( nCrvId, 0) @@ -8428,8 +9277,7 @@ local function CalcPartPreview( nPartId, nPreviewGrp) EgtMove( nAreaId, Vector3d( 0, 0, - 1000)) end end - local color = EgtGetColor( nPartId) - EgtSetColor( nAreaId, color) + EgtSetColor( nAreaId, Color3d( 251, 128, 4)) -- estraggo il contorno local nCompoId = EgtExtractSurfFrChunkLoops( nAreaId, 0, nPreviewGrp) EgtSetColor( nCompoId, EgtStdColor( 'BLACK')) @@ -8438,7 +9286,7 @@ local function CalcPartPreview( nPartId, nPreviewGrp) if EgtGetName( nOutlineId) == WIN_BOTTOM then local nBottomRail = EgtGetInfo( nOutlineId, WIN_BOTTOMRAIL, 'i') or 0 if nBottomRail > 0 then - CalcBottomRailPreview( nPreviewGrp, nOutlineId, nBottomRail, nGeoLayerId, color) + CalcBottomRailPreview( nPreviewGrp, nOutlineId, nBottomRail, nGeoLayerId) end end end @@ -8574,18 +9422,22 @@ end ---------------------------------------------------------------------------------- -- funzione che crea tutti i pezzi della finestra partendo dal telaio function WinCalculate.CreatePartFromArea( nFrameId) + s_nSashNbr = 0 + -- assegno il tipo di profilo alle curve del base outline CalculateAreaProfileType( nFrameId) -- calcolo outline a partire dal base outline CalculateAreaOutline( nFrameId) SetAreaProfiles( nFrameId) + -- creo i pezzi con i profili + CreateAreaParts( nFrameId) + GetAreaPrevNextOutlines( nFrameId) -- creo pezzi - s_nSashNbr = 0 -- resetto il numero di ante del progetto - CalculateAreaParts( nFrameId) + CalculateAreaParts( nFrameId) -- calcolo le spine CalculateAreaDowels( nFrameId) - - -- calcolo preview 2d se richiesta + + -- calcolo preview 2d se richiesta if s_bCalcPreview then CalcPreview( nFrameId) end diff --git a/Designing/WinLib/WinCreate.lua b/Designing/WinLib/WinCreate.lua index 3b64e56..fe7e73f 100644 --- a/Designing/WinLib/WinCreate.lua +++ b/Designing/WinLib/WinCreate.lua @@ -35,7 +35,6 @@ local function CopyParentOutline( nAreaId, nParentAreaId) -- copio le curve di outline del parent e setto le corrispondenze sou/child for i = 1, #vParentCrvs do local nOutlineId = EgtCopy( vParentCrvs[i], nOutlineLayerId) - EgtSetInfo( nOutlineId, WIN_SOU, vParentCrvs[i]) EgtSetInfo( vParentCrvs[i], WIN_CHILD, nOutlineId) end return nOutlineLayerId @@ -390,7 +389,7 @@ local function GetBorderRegions( nSplitId, nCompo, nAreaId) EgtInvertCurve( nSplitId2) EgtAddCurveCompoCurve( nCrv2, nSplitId2) local _, dParE2 = EgtCurveDomain( nCrv2) - EgtCurveCompoSetTempProp( nCrv2, dParE2 - 1, nSplitId) + EgtCurveCompoSetTempProp( nCrv2, dParE2 - 1, - nSplitId) return nCrv1, nCrv2 end @@ -445,14 +444,17 @@ local function CreateAreasFromSplits( nAreaId, vSplitCrvs) -- assegno nome e info a tutte le curve di bordo a partire dalla curva da cui derviano ( salvata nella temp prop della curva) for j = 0, nCnt - 1 do - -- assegno le info di child e source - EgtSetInfo( nFirst + j, WIN_SOU, vOrigCrvs[j+1]) - AddInfo( vOrigCrvs[j+1], WIN_CHILD, nFirst + j) + -- assegno le info di child + if vOrigCrvs[j+1] < 0 then + AddInfo( abs( vOrigCrvs[j+1]), WIN_CHILD, -( nFirst + j)) + else + AddInfo( vOrigCrvs[j+1], WIN_CHILD, nFirst + j) + end -- assengo il nome : se deriva da outline lo copio, se deriva da split lo scelgo in base all'orientamento - if EgtGetName( vOrigCrvs[j+1]) == WIN_SPLIT then + if EgtGetName( abs( vOrigCrvs[j+1])) == WIN_SPLIT then SetSplitName( nFirst + j) else - EgtSetName( nFirst + j, EgtGetName( vOrigCrvs[j+1])) + EgtSetName( nFirst + j, EgtGetName( abs( vOrigCrvs[j+1]))) end end