From c8a7fa0c11b8a56f502c022ead3ddd6c52bc7469 Mon Sep 17 00:00:00 2001 From: SaraP Date: Mon, 22 Dec 2025 11:03:38 +0100 Subject: [PATCH] =?UTF-8?q?DataWindow=20:=20-=20gestione=20di=20cambio=20p?= =?UTF-8?q?rofilo=20che=20coinvolge=20pi=C3=B9=20pezzi=20(=20prima=20versi?= =?UTF-8?q?one).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Designing/WinConst.lua | 22 +- Designing/WinLib/WinCalculate.lua | 2210 ++++++++++++++--------------- 2 files changed, 1043 insertions(+), 1189 deletions(-) diff --git a/Designing/WinConst.lua b/Designing/WinConst.lua index 2ef69f4..12ccb7e 100644 --- a/Designing/WinConst.lua +++ b/Designing/WinConst.lua @@ -316,22 +316,8 @@ WIN_PRF_MAIN = 'Main' WIN_PRF_START = 'Start' WIN_PRF_END = 'End' WIN_PRF_SPLIT = 'Split' -WIN_PRF_TYPE = 'Type' WIN_PROFILETYPE = 'ProfileType' --- tipi di profilo -WIN_PRF = { - NULL = 0, - TOP = 1, - BOTTOM = 2, - LEFT = 3, - RIGHT = 4, - SPLIT = 5, - BOTTOMRAIL = 6, - BOTTOMRAIL_FINAL = 7, -} - - -- GIUNZIONI WIN_JOINTS = 'Joints' WIN_JOINT_BL = 'JointBL' @@ -379,12 +365,10 @@ WIN_TANG_END = 'ExtendTangEnd' -- CAMBIO PROFILO WIN_PRF_CHANGE = 'ProfileChange' -WIN_MIXED_OUTLINES = 'ProfileChangeOutlines' -WIN_MIXED_INTERSECTIONS = 'ProfileChangeIntersections' +WIN_MIXED_CURVES = 'ProfileChangeCurves' +WIN_MIXED_MILLING = 'ProfileChangeMilling' WIN_MIXED_SPLIT_REF = 'MixedSplitRef' -WIN_MIXED_INTERS_REF = 'MixedIntersRef' -WIN_MIXED_REF_START = 'MixedRefEnd' -WIN_MIXED_REF_END = 'MixedRefStart' +WIN_MIXED_SASHFILL = 'MixedSashFill' -- SOLIDI diff --git a/Designing/WinLib/WinCalculate.lua b/Designing/WinLib/WinCalculate.lua index d31d094..16e8825 100644 --- a/Designing/WinLib/WinCalculate.lua +++ b/Designing/WinLib/WinCalculate.lua @@ -138,9 +138,6 @@ end -- funzione che crea una copia estesa della curva con estensione di lunghezza "illimitata" local function CreateCurveExtension( nCrvId, nGrpId) - -- se il risultato è una composita tutti i sottotratti aggiunti come estensione lineare hanno come temp prop l'id della curva originaria per facilitare eventuale - -- identificazione nei conti successivi - -- recupero tipo di estensione local bTangStart = EgtGetInfo( nCrvId, WIN_TANG_START, 'b') or false local bTangEnd = EgtGetInfo( nCrvId, WIN_TANG_END, 'b') or false @@ -166,8 +163,6 @@ local function CreateCurveExtension( nCrvId, nGrpId) nExtId = EgtCurveCompo( nGrpId, nCrvId, false) EgtAddCurveCompoLineTg( nExtId, dExtraLen, true) EgtAddCurveCompoLineTg( nExtId, dExtraLen, false) - EgtCurveCompoSetTempProp( nExtId, 0, nCrvId) - EgtCurveCompoSetTempProp( nExtId, 2, nCrvId) elseif bTangStart and not bTangEnd then local nExtArcId = EgtCopyGlob( nCrvId, nGrpId) @@ -175,7 +170,6 @@ local function CreateCurveExtension( nCrvId, nGrpId) EgtModifyArcAngCenter( nExtArcId, EgtIf( dAngOld > 0, 340, -340)) nExtId = EgtCurveCompo( nGrpId, nExtArcId) EgtAddCurveCompoLineTg( nExtId, dExtraLen, false) - EgtCurveCompoSetTempProp( nExtId, 0, nCrvId) elseif not bTangStart and bTangEnd then local nExtArcId = EgtCopyGlob( nCrvId,nGrpId) @@ -185,7 +179,6 @@ local function CreateCurveExtension( nCrvId, nGrpId) EgtInvertCurve( nExtArcId) nExtId = EgtCurveCompo( nGrpId, nExtArcId) EgtAddCurveCompoLineTg( nExtId, dExtraLen) - EgtCurveCompoSetTempProp( nExtId, 1, nCrvId) end elseif EgtGetType( nCrvId) == GDB_TY.CRV_COMPO then @@ -195,7 +188,6 @@ local function CreateCurveExtension( nCrvId, nGrpId) if EgtCurveCompoRadius( nExtId, 0) > 0 then if bTangStart then EgtAddCurveCompoLineTg( nExtId, dExtraLen, false) - EgtCurveCompoSetTempProp( nExtId, 0, nCrvId) else local ptC = EgtCurveCompoCenter( nExtId, 0) local dAngOld = EgtCurveCompoAngCenter( nExtId, 0) @@ -212,7 +204,6 @@ local function CreateCurveExtension( nCrvId, nGrpId) if EgtCurveCompoRadius( nExtId, dEnd - 1) > 0 then if bTangEnd then EgtAddCurveCompoLineTg( nExtId, dExtraLen) - EgtCurveCompoSetTempProp( nExtId, dEnd, nCrvId) else local ptC = EgtCurveCompoCenter( nExtId, dEnd - 1) local dAngOld = EgtCurveCompoAngCenter( nExtId, dEnd - 1) @@ -322,11 +313,7 @@ local function CalcIntersectionRegion( vCrvs, nGrp) EgtModifyCurveStartPoint( nCrv, EgtSP( nCrv + nCnt - 1)) EgtErase( nCrv + nCnt - 1) else - local vNewProps = EgtCurveCompoGetTempProp( nCrv + nCnt - 1) or {} EgtAddCurveCompoCurve( nCrv, nCrv + nCnt - 1, true, false) - for i = 1, #vNewProps do - EgtCurveCompoSetTempProp( nCrv, i-1, vNewProps[i]) - end end nCnt = nCnt - 1 end @@ -349,7 +336,7 @@ local function CalcIntersectionRegion( vCrvs, nGrp) end end - -- modifico il bordo corrente considerando solo i tratti che poggiano sulle curve orginali + -- modifico il bordo corrente considerando solo i tratti che poggiano sulle curve originali for j = 1, #vArcs do for k = 1, #tArcs[i].vOrigId do if CheckExtensionOverlap( vArcs[j], tArcs[i].vOrigId[k]) then @@ -417,7 +404,6 @@ local function TrimOrderedCurves( vCrvs, nExtraCurvesMode, nSurfId) -- recupero le curve di bordo della regione local nBorderId = EgtExtractSurfFrChunkLoops( nSurfId, 0, nGrpTmp) - local vTempProps = EgtCurveCompoGetTempProp( nBorderId) local nCrvBorder, nCnt = EgtExplodeCurveCompo( nBorderId) -- associo ad ogni curva originale le curve di bordo corrispondenti @@ -446,39 +432,31 @@ local function TrimOrderedCurves( vCrvs, nExtraCurvesMode, nSurfId) local nC = nFirstIdxCrv local nB = nFirstIdxBorder repeat - local nOrigCrv - -- se curva di bordo è curva di estensione la curva originale associata è salvata nella sua temp prop - if vTempProps[nB + 1] ~= 0 then - nOrigCrv = vTempProps[nB + 1] - else - -- cerco la curva originale associata ( visto che scorro in modo ordinato dovrebbe essere tra i primi elementi del while) - local dDist = EgtPointCurveDist( EgtMP( nCrvBorder + nB), vExtCrvs[nC+1]) - local nSafeCnt = 0 - while dDist > GEO.EPS_SMALL and nSafeCnt < #vExtCrvs do - nSafeCnt = nSafeCnt + 1 - nC = ( nC + 1) % #vCrvs - dDist = EgtPointCurveDist( EgtMP( nCrvBorder + nB), vExtCrvs[nC+1]) - end - -- se non ho trovato curva associata errore - if nSafeCnt == #vExtCrvs then - return - end - - nOrigCrv = vCrvs[nC + 1] - -- passo alla curva originale successiva + -- cerco la curva originale associata + local dDist = EgtPointCurveDist( EgtMP( nCrvBorder + nB), vExtCrvs[nC+1]) + local nSafeCnt = 0 + while dDist > 2 * GEO.EPS_SMALL and nSafeCnt < #vExtCrvs do + nSafeCnt = nSafeCnt + 1 nC = ( nC + 1) % #vCrvs + dDist = EgtPointCurveDist( EgtMP( nCrvBorder + nB), vExtCrvs[nC+1]) + end + -- se non ho trovato curva associata errore + if nSafeCnt == #vExtCrvs then + return end -- aggiungo associazione + local nOrigCrv = vCrvs[nC + 1] if tabAss[nOrigCrv] then table.insert( tabAss[nOrigCrv], nCrvBorder + nB) else tabAss[nOrigCrv] = { nCrvBorder + nB} end - -- passo alla curva di bordo successiva + -- passo alla curve successive + nC = ( nC + 1) % #vCrvs nB = ( nB + 1) % nCnt - + until nB == nFirstIdxBorder -- sostituisco le curve originali con quelle di bordo appena calcolate @@ -525,11 +503,11 @@ end --------------------------------------------------------------------- -- funzione che data una curva di outline restituisce l'id del suo profilo -local function GetOutlineProfileId( nOutlineId, bForceBottomRail, nProfileType) +local function GetOutlineProfileId( nOutlineId, bForceBottomRail, nBottomRail) -- ciclo fino a trovare il primo parent che abbia un AreaType definito ( frame o sash) - local nParentId = EgtGetParent( nOutlineId) - local nAreaType = WIN_AREATYPES.NULL + 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 @@ -548,15 +526,31 @@ local function GetOutlineProfileId( nOutlineId, bForceBottomRail, nProfileType) local sProfileName = EgtGetInfo( nOutlineId, WIN_PROFILETYPE) -- controlli per bottomrail - if EgtGetName( nOutlineId) == WIN_BOTTOM and bForceBottomRail then + if EgtGetName( nOutlineId) == WIN_BOTTOM then local nBottomRailTot = EgtGetInfo( nOutlineId, WIN_BOTTOMRAIL, 'i') or 0 if nBottomRailTot > 0 then - sProfileName = WIN_FILL_RAIL + if bForceBottomRail then + sProfileName = WIN_FILL_RAIL + else + if nBottomRail then + if nBottomRail == nBottomRailTot then + sProfileName = WIN_FILL_RAIL + else + sProfileName = WIN_RAIL + end + end + end + end + end + + -- controlli per pezzi di cambio profilo sul telaio + local bChangeProfile = EgtGetInfo( nOutlineId, WIN_PRF_CHANGE, 'b') or false + if bChangeProfile and sProfileName ~= WIN_MIXED_SPLIT then + if EgtGetName( nOutlineId) == WIN_BOTTOM then + sProfileName = WIN_MIXED_BOTTOM + else + sProfileName = WIN_MIXED_TOP end - elseif nProfileType == WIN_PRF.BOTTOMRAIL then - sProfileName = WIN_RAIL - elseif nProfileType == WIN_PRF.BOTTOMRAIL_FINAL then - sProfileName = WIN_FILL_RAIL end -- recupero il profilo @@ -609,6 +603,96 @@ local function GetProfileLocalBox( nProfileId) return b3Box end +--------------------------------------------------------------------- +-- funzione che restituisce il tipo di controprofilo dell'outline adiacente +local function GetProfileCtrIn( nPrevOutlineId, nOutlineId, nPrevProfileId) + local sPrevCtrIn = WIN_CTRIN + -- gestione particolare del caso di split o cambio profilo + if not EgtGetFirstNameInGroup( nPrevProfileId, sPrevCtrIn) then + + local nRefSplitId = EgtGetInfo( nPrevOutlineId, WIN_REF_SPLIT, 'i') + if nRefSplitId or EgtGetName( nPrevOutlineId) == WIN_SPLIT then + -- 1) split + -- verifico da quale lato dello split originale si trova l'outline per decidere quale controprofilo considerare + local _, _, nSide = EgtPointCurveDistSide( EgtMP( nOutlineId), nRefSplitId or nPrevOutlineId, Z_AX()) + if nSide == 1 then + sPrevCtrIn = WIN_CTRIN .. '1' -- dx + else + sPrevCtrIn = WIN_CTRIN .. '2' -- sx + end + else + -- 2) pezzo del telaio con cambio profilo + -- il profilo da usare dipende dal pezzo corrente: se ha figli di tipo fill allora è legato alla parte fill del cambio profilo, se ha figli di tipo sash è legato alla parte sash, + -- se ha entrambe le tipologie di figli allora è mixed split e va considerata la parte sash ( perchè è quella utilizzata per tagliare il pezzo) + local vSashChildren = EgtGetInfo( nOutlineId, WIN_SASH_CHILDREN, 'vi') + if vSashChildren then + sPrevCtrIn = WIN_SASH .. WIN_CTRIN + else + sPrevCtrIn = WIN_FILL .. WIN_CTRIN + end + end + end + + return sPrevCtrIn +end + +--------------------------------------------------------------------- +-- funzione che costruisce una superficie estrudendo il nSectionId lungo l'outline +local function CreateProfileSurfById( nOutlineId, nProfileId, nSectionId, dExtraLen, nLayerId) + + -- creo guida con estensione in tangenza + local nGuideId = EgtCopy( nOutlineId, nLayerId) + if EgtGetType( nGuideId) == GDB_TY.CRV_LINE then + EgtExtendCurveStartByLen( nGuideId, dExtraLen) + EgtExtendCurveEndByLen( nGuideId, dExtraLen) + else + nGuideId = EgtCurveCompo( nLayerId, nGuideId) + EgtAddCurveCompoLineTg( nGuideId, dExtraLen) + EgtAddCurveCompoLineTg( nGuideId, dExtraLen, false) + end + -- correzione nel caso di bottomrail + local sProfileType = EgtGetInfo( nProfileId, WIN_PROFILETYPE) + if sProfileType == WIN_RAIL or sProfileType == WIN_FILL_RAIL then + local dOffs = EgtGetInfo( nProfileId, WIN_RAILDELTA, 'd') + EgtOffsetCurve( nGuideId, - dOffs) + end + + -- verifico se necessaria inversione della guida nel caso sia curva "virtuale" ( ovvero in area null o split) che deriva da pezzo di split + if EgtExistsInfo( nOutlineId, WIN_INV_SPLIT) then + EgtInvertCurve( nGuideId) + end + + -- recupero il profilo da estrudere + local nSectionRefId = EgtCopyGlob( nSectionId, nLayerId) + + -- posiziono la sezione di estrusione sulla guida : + -- recupero frame del profilo + local nProfileFrameId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME) + local frProfile = EgtFR( nProfileFrameId, GDB_ID.ROOT) + frProfile:invert() + -- calcolo il frame di destinazione sulla guida + local frDest = Frame3d( EgtSP( nGuideId), - EgtSV( nGuideId), GDB_RT.GLOB) + -- posiziono con i riferimenti + EgtTransform( nSectionRefId, frProfile, GDB_RT.GLOB) + EgtTransform( nSectionRefId, frDest, GDB_RT.GLOB) + + -- creo la superfice di estrusione + local nStmId = EgtSurfTmSwept( nLayerId, nSectionRefId, nGuideId, false, WIN_SURF_APPROX) + EgtErase( nGuideId) + EgtErase( nSectionRefId) + + return nStmId +end + +--------------------------------------------------------------------- +-- come CreateProfileSurfById ma riceve il nome della sezione da estrudere +local function CreateProfileSurf( nOutlineId, nProfileId, sSectionName, dExtraLen, nLayerId) + -- recupero l'id della sezione da estrudere + local nSectionId = EgtGetFirstNameInGroup( nProfileId, sSectionName) + if not nSectionId then return end + return CreateProfileSurfById( nOutlineId, nProfileId, nSectionId, dExtraLen, nLayerId) +end + ---------------------------------------------------------------------------------- @@ -1052,6 +1136,214 @@ end ---------------------------------------------------------------------------------- ------------------------------ CALCOLO OUTLINE --------------------------------- ---------------------------------------------------------------------------------- +-- funzione che verifica gli outlines prev/next per lo split controllando l'interferenza tra i profili +local function TestSplitTrimOutlines( nOutlineId, vTrimOutlines, nMainProfile, b3Profile, nGrpTmp, bPrevOrNext) + + local vRealTrimOutlines = {} + + -- 1) recupero le curve da testare + local vTestOutlines = {} + + -- a) curve individuate dalle intersezioni degli outlines + for i = 1, #vTrimOutlines do + vTestOutlines[i] = vTrimOutlines[i] + end + + -- b) curve vicine a quelle individuate dalle intersezioni che interferiscono con l'outline ( 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( vTrimOutlines[1]) or EgtGetLastInGroup( EgtGetParent( vTrimOutlines[1])) + local bInters = true + while bInters and nTestCurve ~= vTrimOutlines[#vTrimOutlines] do + + local nProfileId = GetOutlineProfileId( nTestCurve, true) + local b3Profile = GetProfileLocalBox( nProfileId) + local nRefSurf = EgtSurfFrFatCurve( nGrpTmp, nTestCurve, 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, nTestCurve) + nTestCurve = EgtGetPrev( nTestCurve) or EgtGetLastInGroup( EgtGetParent( nTestCurve)) + end + end + + -- curve successive + nTestCurve = EgtGetNext( vTrimOutlines[#vTrimOutlines]) or EgtGetFirstInGroup( EgtGetParent( vTrimOutlines[1])) + bInters = true + while bInters and nTestCurve ~= vTrimOutlines[1] do + + local nProfileId = GetOutlineProfileId( nTestCurve, true) + local b3Profile = GetProfileLocalBox( nProfileId) + local nRefSurf = EgtSurfFrFatCurve( nGrpTmp, nTestCurve, 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, 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( 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( vTestOutlines[i], vProfiles[i], vsCtrIn[i], 4 * dExtraLen, nGrpTmp) + if i > 1 then + if AreSameVectorApprox( EgtEV( vTestOutlines[i-1]), EgtSV( vTestOutlines[i])) then + EgtCutSurfTmPlane( nTestSurf, EgtEP( vTestOutlines[i-1]), - EgtEV( vTestOutlines[i-1]), false) + else + local nTrimSurf = CreateProfileSurf( 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( vTestOutlines[i]), EgtSV( vTestOutlines[i+1])) then + EgtCutSurfTmPlane( nTestSurf, EgtEP( vTestOutlines[i]), EgtEV( vTestOutlines[i]), false) + else + local nTrimSurf = CreateProfileSurf( 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( vRealTrimOutlines, vTestOutlines[i]) + end + end + + return vRealTrimOutlines +end + +--------------------------------------------------------------------- +-- funzione che recupera gli outline precedenti e successivi +local function GetSplitPrevNextOutline( nSplitId) + + local nGrpTmp = EgtGroup( GDB_ID.ROOT) + local nMainProfile = GetOutlineProfileId( nSplitId) + local b3Profile = GetProfileLocalBox( nMainProfile) + local bChangeProfile = EgtGetInfo( nSplitId, WIN_PRF_CHANGE, 'b') or false + + -- 1) PREV + local vPrevOutlineId = {} + -- recupero le curve di base outline che tagliano lo split e gli outline associati + local vPrevBaseOutlineId = EgtGetInfo( nSplitId, WIN_SPLIT_STARTINTERS, 'vi') + for i = 1, #vPrevBaseOutlineId do + vPrevOutlineId[i] = EgtGetInfo( vPrevBaseOutlineId[i], WIN_COPY, 'i') + end + -- controllo validità delle curve trovate ed eventuali vicine verificando l'interferenza tra i profili + vPrevOutlineId = TestSplitTrimOutlines( nSplitId, vPrevOutlineId, nMainProfile, b3Profile, nGrpTmp, true) + -- considero come curve prev solo curve non virtuali per rendere più solidi i conti successivi + -- verifico la coerenza dell'orientamento e la indico con il segno ( > 0 concorde, < 0 discorde e va invertita) + for i = 1, #vPrevOutlineId do + local bInvert = EgtGetInfo( vPrevOutlineId[i], WIN_INV_SPLIT, 'b') or false + + local nBaseOutline = EgtGetInfo( vPrevOutlineId[i], WIN_COPY, 'i') + local nAreaId = EgtGetParent( EgtGetParent( nBaseOutline)) + local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i') + while not ( nAreaType == WIN_AREATYPES.FRAME or nAreaType == WIN_AREATYPES.SASH or EgtGetName( nBaseOutline) == WIN_SPLIT) do + nBaseOutline = EgtGetInfo( nBaseOutline, WIN_SOU, 'i') + nAreaId = EgtGetParent( EgtGetParent( nBaseOutline)) + nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i') + end + vPrevOutlineId[i] = EgtGetInfo( nBaseOutline, WIN_COPY, 'i') + if bInvert then + vPrevOutlineId[i] = - vPrevOutlineId[i] + end + -- se split mixed il pezzo che incontra deve essere con cambio profilo + if bChangeProfile then + EgtSetInfo( vPrevOutlineId[i], WIN_PRF_CHANGE, true) + end + end + EgtSetInfo( nSplitId, WIN_PREV_OUTLINES, vPrevOutlineId) + + -- 2) NEXT + local vNextOutlineId = {} + local vNextBaseOutlineId = EgtGetInfo( nSplitId, WIN_SPLIT_ENDINTERS, 'vi') + for i = 1, #vNextBaseOutlineId do + vNextOutlineId[i] = EgtGetInfo( vNextBaseOutlineId[i], WIN_COPY, 'i') + end + vNextOutlineId = TestSplitTrimOutlines( nSplitId, vNextOutlineId, nMainProfile, b3Profile, nGrpTmp, false) + for i = 1, #vNextOutlineId do + local bInvert = EgtGetInfo( vNextOutlineId[i], WIN_INV_SPLIT, 'b') or false + + local nBaseOutline = EgtGetInfo( vNextOutlineId[i], WIN_COPY, 'i') + local nAreaId = EgtGetParent( EgtGetParent( nBaseOutline)) + local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i') + while not ( nAreaType == WIN_AREATYPES.FRAME or nAreaType == WIN_AREATYPES.SASH or EgtGetName( nBaseOutline) == WIN_SPLIT) do + nBaseOutline = EgtGetInfo( nBaseOutline, WIN_SOU, 'i') + nAreaId = EgtGetParent( EgtGetParent( nBaseOutline)) + nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i') + end + vNextOutlineId[i] = EgtGetInfo( nBaseOutline, WIN_COPY, 'i') + if bInvert then + vNextOutlineId[i] = - vNextOutlineId[i] + end + + if bChangeProfile then + EgtSetInfo( vNextOutlineId[i], WIN_PRF_CHANGE, true) + end + end + EgtSetInfo( nSplitId, WIN_NEXT_OUTLINES, vNextOutlineId) + + EgtErase( nGrpTmp) +end + +--------------------------------------------------------------------- +local function GetPrevNextOutline( nOutlineLayerId) + + local vOutlines = EgtGetAllInGroup( 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 + +--------------------------------------------------------------------- local function TrimSplitWithOutline( nSplitId) -- estendo agli estremi ( TO DO : gestire caso di split non lineare) EgtExtendCurveStartByLen( nSplitId, 50) @@ -1164,6 +1456,10 @@ local function CalculateSplitOutline( nAreaId) TrimSplitWithOutline( vSplitIds[i]) -- aggiusto quota EgtMove( vSplitIds[i], Z_AX() * dZMove) + + if nSplitType ~= WIN_SPLITTYPES.FRENCH then + GetSplitPrevNextOutline( vSplitIds[i]) + end end end @@ -1340,6 +1636,7 @@ local function CalculateOutlineFromAreaOutline( nAreaId) end nAreaOutlineId = EgtGetNext( nAreaOutlineId) end + GetPrevNextOutline( nOutlineLayerId) -- SPLIT / NULL @@ -1467,12 +1764,13 @@ local function CalculateOutlineFromAreaOutline( nAreaId) end -- accorcio gli offset TrimOrderedCurves( EgtGetAllInGroup( nOutlineLayerId), 1) + -- assegno prev e next + GetPrevNextOutline( nOutlineLayerId) -- FILL elseif nAreaType == WIN_AREATYPES.FILL then CalculateFillOutline( nAreaId, nAreaOutlineLayerId, nOutlineLayerId) - end end @@ -1492,306 +1790,11 @@ end ----------------------------------------------------------------------------------- ------------------------- FUNZIONI AUX PER CALCOLO PEZZI ------------------------ ----------------------------------------------------------------------------------- --- funzione che restituisce il WIN_PRF in base al nome della curva -local function GetOutlineProfileType( nOutlineId, bForceBottomRail, nBottomRail) - -- ricavo tipo dal nome - local sName = EgtGetName( nOutlineId) - local nProfileType = WIN_PRF.NULL - if sName == WIN_TOP then - nProfileType = WIN_PRF.TOP - elseif sName == WIN_BOTTOM then - local nBottomRailTot = EgtGetInfo( nOutlineId, WIN_BOTTOMRAIL, 'i') or 0 - if bForceBottomRail and nBottomRailTot > 0 then - nProfileType = WIN_PRF.BOTTOMRAIL_FINAL - elseif nBottomRail then - -- verifico se bottomrail intermedio o finale - if nBottomRail == nBottomRailTot then - nProfileType = WIN_PRF.BOTTOMRAIL_FINAL - else - nProfileType = WIN_PRF.BOTTOMRAIL - end - else - nProfileType = WIN_PRF.BOTTOM - end - elseif sName == WIN_LEFT then - nProfileType = WIN_PRF.LEFT - elseif sName == WIN_RIGHT then - nProfileType = WIN_PRF.RIGHT - elseif sName == WIN_SPLIT then - nProfileType = WIN_PRF.SPLIT - end - return nProfileType -end - ---------------------------------------------------------------------- --- funzione che restituisce il tipo di controprofilo dell'outline adiacente -local function GetProfileCtrIn( nPrevOutlineId, nOutlineId, nPrevProfileId) - local sPrevCtrIn = WIN_CTRIN - -- gestione particolare del caso di split o cambio profilo - if not EgtGetFirstNameInGroup( nPrevProfileId, sPrevCtrIn) then - - local nRefSplitId = EgtGetInfo( nPrevOutlineId, WIN_REF_SPLIT, 'i') - if nRefSplitId or EgtGetName( nPrevOutlineId) == WIN_SPLIT then - -- 1) split - -- verifico da quale lato dello split originale si trova l'outline per decidere quale controprofilo considerare - local _, _, nSide = EgtPointCurveDistSide( EgtMP( nOutlineId), nRefSplitId or nPrevOutlineId, Z_AX()) - if nSide == 1 then - sPrevCtrIn = WIN_CTRIN .. '1' -- dx - else - sPrevCtrIn = WIN_CTRIN .. '2' -- sx - end - else - -- 2) pezzo del telaio con cambio profilo - -- il profilo da usare dipende dal pezzo corrente: se ha figli di tipo fill allora è legato alla parte fill del cambio profilo, se ha figli di tipo sash è legato alla parte sash, - -- se ha entrambe le tipologie di figli allora è mixed split e va considerata la parte sash ( perchè è quella utilizzata per tagliare il pezzo) - local vSashChildren = EgtGetInfo( nOutlineId, WIN_SASH_CHILDREN, 'vi') - if vSashChildren then - sPrevCtrIn = WIN_SASH .. WIN_CTRIN - else - sPrevCtrIn = WIN_FILL .. WIN_CTRIN - end - end - end - - return sPrevCtrIn -end - ---------------------------------------------------------------------- --- funzione che costruisce una superficie estrudendo il nSectionId lungo l'outline -local function CreateProfileSurfById( nOutlineId, nProfileId, nSectionId, dExtraLen, nLayerId) - - -- creo guida con estensione in tangenza - local nGuideId = EgtCopy( nOutlineId, nLayerId) - if EgtGetType( nGuideId) == GDB_TY.CRV_LINE then - EgtExtendCurveStartByLen( nGuideId, dExtraLen) - EgtExtendCurveEndByLen( nGuideId, dExtraLen) - else - nGuideId = EgtCurveCompo( nLayerId, nGuideId) - EgtAddCurveCompoLineTg( nGuideId, dExtraLen) - EgtAddCurveCompoLineTg( nGuideId, dExtraLen, false) - end - -- correzione nel caso di bottomrail - local sProfileType = EgtGetInfo( nProfileId, WIN_PRF_TYPE) - if sProfileType == WIN_RAIL or sProfileType == WIN_FILL_RAIL then - local dOffs = EgtGetInfo( nProfileId, WIN_RAILDELTA, 'd') - EgtOffsetCurve( nGuideId, - dOffs) - end - - -- verifico se necessaria inversione della guida nel caso sia curva "virtuale" ( ovvero in area null o split) che deriva da pezzo di split - if EgtExistsInfo( nOutlineId, WIN_INV_SPLIT) then - EgtInvertCurve( nGuideId) - end - - -- recupero il profilo da estrudere - local nSectionRefId = EgtCopyGlob( nSectionId, nLayerId) - - -- posiziono la sezione di estrusione sulla guida : - -- recupero frame del profilo - local nProfileFrameId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME) - local frProfile = EgtFR( nProfileFrameId, GDB_ID.ROOT) - frProfile:invert() - -- calcolo il frame di destinazione sulla guida - local frDest = Frame3d( EgtSP( nGuideId), - EgtSV( nGuideId), GDB_RT.GLOB) - -- posiziono con i riferimenti - EgtTransform( nSectionRefId, frProfile, GDB_RT.GLOB) - EgtTransform( nSectionRefId, frDest, GDB_RT.GLOB) - - -- creo la superfice di estrusione - local nStmId = EgtSurfTmSwept( nLayerId, nSectionRefId, nGuideId, false, WIN_SURF_APPROX) - EgtErase( nGuideId) - EgtErase( nSectionRefId) - - return nStmId -end - ---------------------------------------------------------------------- --- come CreateProfileSurfById ma riceve il nome della sezione da estrudere -local function CreateProfileSurf( nOutlineId, nProfileId, sSectionName, dExtraLen, nLayerId) - -- recupero l'id della sezione da estrudere - local nSectionId = EgtGetFirstNameInGroup( nProfileId, sSectionName) - if not nSectionId then return end - return CreateProfileSurfById( nOutlineId, nProfileId, nSectionId, dExtraLen, nLayerId) -end - ---------------------------------------------------------------------- --- funzione che verifica gli outlines prev/next per lo split controllando l'interferenza tra i profili -local function TestSplitTrimOutlines( nOutlineId, vTrimOutlines, nMainProfile, b3Profile, nGrpTmp, bPrevOrNext) - - local vRealTrimOutlines = {} - - -- 1) recupero le curve da testare - local vTestOutlines = {} - - -- a) curve individuate dalle intersezioni degli outlines - for i = 1, #vTrimOutlines do - vTestOutlines[i] = vTrimOutlines[i] - end - - -- b) curve vicine a quelle individuate dalle intersezioni che interferiscono con l'outline ( 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( vTrimOutlines[1]) or EgtGetLastInGroup( EgtGetParent( vTrimOutlines[1])) - local bInters = true - while bInters and nTestCurve ~= vTrimOutlines[#vTrimOutlines] do - - local nRefPart = FindAssociatedPart( nTestCurve, true) - local nRefGeo = EgtGetFirstNameInGroup( nRefPart, WIN_GEO) - local nRefSurf = EgtGetFirstNameInGroup( nRefGeo, WIN_GEO_SURF) - - 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, nTestCurve) - nTestCurve = EgtGetPrev( nTestCurve) or EgtGetLastInGroup( EgtGetParent( nTestCurve)) - end - end - - -- curve successive - nTestCurve = EgtGetNext( vTrimOutlines[#vTrimOutlines]) or EgtGetFirstInGroup( EgtGetParent( vTrimOutlines[1])) - bInters = true - while bInters and nTestCurve ~= vTrimOutlines[1] do - - local nRefPart = FindAssociatedPart( nTestCurve, true) - local nRefGeo = EgtGetFirstNameInGroup( nRefPart, WIN_GEO) - local nRefSurf = EgtGetFirstNameInGroup( nRefGeo, WIN_GEO_SURF) - - 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, nTestCurve) - nTestCurve = EgtGetNext( nTestCurve) or EgtGetFirstInGroup( EgtGetParent( nTestCurve)) - end - 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( 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( vTestOutlines[i], vProfiles[i], vsCtrIn[i], 4 * dExtraLen, nGrpTmp) - if i > 1 then - if AreSameVectorApprox( EgtEV( vTestOutlines[i-1]), EgtSV( vTestOutlines[i])) then - EgtCutSurfTmPlane( nTestSurf, EgtEP( vTestOutlines[i-1]), - EgtEV( vTestOutlines[i-1]), false) - else - local nTrimSurf = CreateProfileSurf( 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( vTestOutlines[i]), EgtSV( vTestOutlines[i+1])) then - EgtCutSurfTmPlane( nTestSurf, EgtEP( vTestOutlines[i]), EgtEV( vTestOutlines[i]), false) - else - local nTrimSurf = CreateProfileSurf( 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( vRealTrimOutlines, vTestOutlines[i]) - end - end - - return vRealTrimOutlines -end - ---------------------------------------------------------------------- --- funzione che recupera gli outline precedenti e successivi -local function GetPrevNextOutline( nProfileType, nOutlineId, nOutlineLayerId) - - local vPrevOutlineId = {} - local vNextOutlineId = {} - - if nProfileType ~= WIN_PRF.SPLIT then - vPrevOutlineId = { EgtGetPrev( nOutlineId) or EgtGetLastInGroup( nOutlineLayerId)} - vNextOutlineId = { EgtGetNext( nOutlineId) or EgtGetFirstInGroup( nOutlineLayerId)} - - else - -- se split recupero tutte le curve di base outline che lo tagliano dalle info - local vPrevBaseOutlineId = EgtGetInfo( nOutlineId, WIN_SPLIT_STARTINTERS, 'vi') - local vNextBaseOutlineId = EgtGetInfo( nOutlineId, WIN_SPLIT_ENDINTERS, 'vi') - -- recupero gli outlines associati - for i = 1, #vPrevBaseOutlineId do - vPrevOutlineId[i] = EgtGetInfo( vPrevBaseOutlineId[i], WIN_COPY, 'i') - end - for i = 1, #vNextBaseOutlineId do - vNextOutlineId[i] = EgtGetInfo( vNextBaseOutlineId[i], WIN_COPY, 'i') - end - - -- controllo validità delle curve trovate verificando l'interferenza tra i profili - local nGrpTmp = EgtGroup( GDB_ID.ROOT) - local nMainProfile = GetOutlineProfileId( nOutlineId) - local b3Profile = GetProfileLocalBox( nMainProfile) - vPrevOutlineId = TestSplitTrimOutlines( nOutlineId, vPrevOutlineId, nMainProfile, b3Profile, nGrpTmp, true) - vNextOutlineId = TestSplitTrimOutlines( nOutlineId, vNextOutlineId, nMainProfile, b3Profile, nGrpTmp, false) - EgtErase( nGrpTmp) - - -- considero come curve prev e next quelle associate ad un pezzo e non curve virtuali per rendere più solidi i conti successivi - -- verifico la coerenza dell'orientamento e la indico con il segno ( > 0 concorde, < 0 discorde e va invertita) - for i = 1, #vPrevOutlineId do - local nPart = FindAssociatedPart( vPrevOutlineId[i], true) - local bInvert = EgtGetInfo( vPrevOutlineId[i], WIN_INV_SPLIT, 'b') or false - vPrevOutlineId[i] = EgtGetInfo( nPart, WIN_REF_OUTLINE, 'i') - if bInvert then - vPrevOutlineId[i] = - vPrevOutlineId[i] - end - end - for i = 1, #vNextOutlineId do - local nPart = FindAssociatedPart( vNextOutlineId[i], true) - local bInvert = EgtGetInfo( vNextOutlineId[i], WIN_INV_SPLIT, 'b') or false - vNextOutlineId[i] = EgtGetInfo( nPart, WIN_REF_OUTLINE, 'i') - if bInvert then - vNextOutlineId[i] = - vNextOutlineId[i] - end - end - end - - return vPrevOutlineId, vNextOutlineId -end - - - ---------------------------------------------------------------------------------- -------------------------------- GEO ------------------------------------------- ---------------------------------------------------------------------------------- -- funzione che crea il bisettore parabolico tra linea e arco -local function CalcParabolicBisector( nCrv1, nCrv2, dDim, nGrp) +local function CalcParabolicBisector( nCrv1, nCrv2, dDim, nGrp, bArcExternal, bLineExternal) -- modifico le curve affinchè abbiano estremo in comune local ptInt = FindIntersectionPoint( nCrv1, nCrv2, EgtSP( nCrv2)) @@ -1800,7 +1803,7 @@ local function CalcParabolicBisector( nCrv1, nCrv2, dDim, nGrp) -- calcolo coefficienti dell'equazione del bisettore ( equazione presa da Vroni) local nArc, nLine, nSign - if EgtGetType( nCrv1) == GDB_TY.CRV_ARC and EgtGetType( nCrv2) == GDB_TY.CRV_LINE then + if EgtGetType( nCrv1) == GDB_TY.CRV_ARC then nArc = nCrv1 nLine = nCrv2 nSign = -1 @@ -1820,22 +1823,23 @@ local function CalcParabolicBisector( nCrv1, nCrv2, dDim, nGrp) local dA = ptC:getX() - dCoeffA * dDist local dB = ptC:getY() - dCoeffB * dDist local dZ = ptC:getZ() - -- k1 = -1 deve essere dentro la circonferenza - -- k2 = -1 deve essere a sinistra della linea + 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 = 10 + local nTot = 50 for i = 1, nTot do local t = dDim / ( nTot - 1) * ( i - 1) - local dDiscriminant = dRad * dRad + 2 * t * ( - dRad + dDist) - dDist * dDist + local dDiscriminant = dRad * dRad + 2 * t * ( k1 * dRad - k2 * dDist) - dDist * dDist local dX, dY if dDiscriminant < GEO.EPS_ZERO then - dX = dA + dCoeffA * t - dY = dB + dCoeffB * t + dX = dA - k2 * dCoeffA * t + dY = dB - k2 * dCoeffB * t else - dX = dA + dCoeffA * t + nSign * dCoeffB * sqrt( dDiscriminant) - dY = dB + dCoeffB * t - nSign * dCoeffA * sqrt( dDiscriminant) + 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 @@ -1934,11 +1938,7 @@ local function CalcGeoRegion( vCrvs, nGrp) EgtModifyCurveStartPoint( nCrv, EgtSP( nCrv + nCnt - 1)) EgtErase( nCrv + nCnt - 1) else - local vNewProps = EgtCurveCompoGetTempProp( nCrv + nCnt - 1) or {} EgtAddCurveCompoCurve( nCrv, nCrv + nCnt - 1, true, false) - for i = 1, #vNewProps do - EgtCurveCompoSetTempProp( nCrv, i-1, vNewProps[i]) - end end nCnt = nCnt - 1 end @@ -2002,25 +2002,22 @@ local function CalcGeoRegion( vCrvs, nGrp) end --------------------------------------------------------------------- --- funzione che dato il tipo di pezzo e di giunzione, restituisce se e' corto, lungo o angolato -local function CalcPartJointType( nProfileType, JointType) +-- funzione che dato il tipo di pezzo giunzione e di pezzo ( orizzontale o verticale) restituisce se è corto, lungo o angolato +local function CalcPartJoint( nJointType, bHorizontal) - if JointType == WIN_JNT.ANGLED then + if nJointType == WIN_JNT.ANGLED then return WIN_PART_JNT.ANGLED - end - if nProfileType == WIN_PRF.BOTTOMRAIL or nProfileType == WIN_PRF.BOTTOMRAIL_FINAL or nProfileType == WIN_PRF.SPLIT then - return WIN_PART_JNT.SHORT - elseif nProfileType == WIN_PRF.BOTTOM or nProfileType == WIN_PRF.TOP then - if JointType == WIN_JNT.FULL_H then + elseif nJointType == WIN_JNT.FULL_H then + if bHorizontal then return WIN_PART_JNT.FULL - elseif JointType == WIN_JNT.FULL_V then + else return WIN_PART_JNT.SHORT end - elseif nProfileType == WIN_PRF.LEFT or nProfileType == WIN_PRF.RIGHT then - if JointType == WIN_JNT.FULL_V then - return WIN_PART_JNT.FULL - elseif JointType == WIN_JNT.FULL_H then + elseif nJointType == WIN_JNT.FULL_V then + if bHorizontal then return WIN_PART_JNT.SHORT + else + return WIN_PART_JNT.FULL end end end @@ -2036,7 +2033,7 @@ end --------------------------------------------------------------------- -- funzione che crea il gruppo con i profili di un pezzo -local function CalcProfiles( nPartId, nOutlineId, vPrevOutlineId, vNextOutlineId, nProfileType, nBottomRail) +local function CalcProfiles( nPartId, nOutlineId, vPrevOutlineId, vNextOutlineId, nBottomRail) -- creo gruppo per i profili local nProfileLayerId = EgtGroup( nPartId) @@ -2044,10 +2041,10 @@ local function CalcProfiles( nPartId, nOutlineId, vPrevOutlineId, vNextOutlineId EgtSetStatus( nProfileLayerId, GDB_ST.OFF) -- recupero profilo principale e ne creo copia - local nOrigMainProfileId = GetOutlineProfileId( nOutlineId, false, nProfileType) + local nOrigMainProfileId = GetOutlineProfileId( nOutlineId, false, nBottomRail) local nMainProfileId = EgtCopy( nOrigMainProfileId, nProfileLayerId) local sMainProfileType = EgtGetName( nMainProfileId) - EgtSetInfo( nMainProfileId, WIN_PRF_TYPE, sMainProfileType) + EgtSetInfo( nMainProfileId, WIN_PROFILETYPE, sMainProfileType) EgtSetName( nMainProfileId, WIN_PRF_MAIN) -- se bottomrail salvo info per scostamento dall'outline if sMainProfileType == WIN_FILL_RAIL or sMainProfileType == WIN_RAIL then @@ -2057,10 +2054,10 @@ local function CalcProfiles( nPartId, nOutlineId, vPrevOutlineId, vNextOutlineId -- recupero profili start e ne creo copia -- se il tipo corrente è split il pezzo va tagliato con il bottomrail, altrimenti con il bottom for i = 1, #vPrevOutlineId do - local nOrigStartProfileId = GetOutlineProfileId( abs( vPrevOutlineId[i]), nProfileType == WIN_PRF.SPLIT) + local nOrigStartProfileId = GetOutlineProfileId( abs( vPrevOutlineId[i]), EgtGetName( nOutlineId) == WIN_SPLIT) local nStartProfileId = EgtCopy( nOrigStartProfileId, nProfileLayerId) local sStartProfileType = EgtGetName( nStartProfileId) - EgtSetInfo( nStartProfileId, WIN_PRF_TYPE, sStartProfileType) + EgtSetInfo( nStartProfileId, WIN_PROFILETYPE, sStartProfileType) EgtSetName( nStartProfileId, WIN_PRF_START) if sStartProfileType == WIN_FILL_RAIL then local nBottomRailTot = EgtGetInfo( abs( vPrevOutlineId[i]), WIN_BOTTOMRAIL, 'i') @@ -2070,10 +2067,10 @@ local function CalcProfiles( nPartId, nOutlineId, vPrevOutlineId, vNextOutlineId -- recupero profili end e ne creo copia for i = 1, #vNextOutlineId do - local nOrigEndProfileId = GetOutlineProfileId( abs( vNextOutlineId[i]), nProfileType == WIN_PRF.SPLIT) + local nOrigEndProfileId = GetOutlineProfileId( abs( vNextOutlineId[i]), EgtGetName( nOutlineId) == WIN_SPLIT) local nEndProfileId = EgtCopy( nOrigEndProfileId, nProfileLayerId) local sEndProfileType = EgtGetName( nEndProfileId) - EgtSetInfo( nEndProfileId, WIN_PRF_TYPE, sEndProfileType) + EgtSetInfo( nEndProfileId, WIN_PROFILETYPE, sEndProfileType) EgtSetName( nEndProfileId, WIN_PRF_END) if sEndProfileType == WIN_FILL_RAIL then local nBottomRailTot = EgtGetInfo( abs( vNextOutlineId[i]), WIN_BOTTOMRAIL, 'i') @@ -2106,7 +2103,7 @@ local function GetDeltaProfile( nProfileId, sCtrIn) dCPDelta = abs( b3CP:getMax():getX()) end -- se bottomrail considero anche scostamento dall'outline - local sProfileType = EgtGetInfo( nProfileId, WIN_PRF_TYPE) + local sProfileType = EgtGetInfo( nProfileId, WIN_PROFILETYPE) if sProfileType == WIN_FILL_RAIL then local dDelta = EgtGetInfo( nProfileId, WIN_RAILDELTA, 'd') dCPDelta = dCPDelta + dDelta @@ -2198,13 +2195,13 @@ end --------------------------------------------------------------------- -- funzione che crea le curve del geo -local function CreateGeoCurves( nOutlineId, vPrevOutlineId, vNextOutlineId, nStartPartJointType, nEndPartJointType, nGeoLayerId, nProfileLayerId) +local function CreateGeoCurves( nOutlineId, vPrevOutlineId, vNextOutlineId, nStartJointType, nEndJointType, nGeoLayerId, nProfileLayerId) local nCurrProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN) -- calcolo spostamento della curva iniziale dovuto a posizione riferimento local b3CurrProfileFrame = GetProfileLocalBox( nCurrProfileId) local dCurrOffset = b3CurrProfileFrame:getMax():getX() - local sProfileType = EgtGetInfo( nCurrProfileId, WIN_PRF_TYPE) + local sProfileType = EgtGetInfo( nCurrProfileId, WIN_PROFILETYPE) if sProfileType == WIN_FILL_RAIL or sProfileType == WIN_RAIL then -- scostamento extra legato al bottomrail local dDelta = EgtGetInfo( nCurrProfileId, WIN_RAILDELTA, 'd') @@ -2230,13 +2227,12 @@ local function CreateGeoCurves( nOutlineId, vPrevOutlineId, vNextOutlineId, nSta EgtSetInfo( nInId, WIN_SEMI_PROFILE, nSemiProfileIn) EgtSetInfo( nInId, WIN_REF_OUTLINE, - nOutlineId) EgtSetInfo( nInId, WIN_GEO_OFFS, - dCurrOffset + b3CurrProfileFrame:getDimX()) - -- curve left local vPrevProfileId = EgtGetNameInGroup( nProfileLayerId, WIN_PRF_START) for i = 1, #vPrevOutlineId do - if nStartPartJointType == WIN_PART_JNT.ANGLED then + if nStartJointType == WIN_PART_JNT.ANGLED then -- recupero bordo out dell'altro pezzo ( non è detto coincida con l'outline) local b3Profile = GetProfileLocalBox( vPrevProfileId[i]) @@ -2263,9 +2259,9 @@ local function CreateGeoCurves( nOutlineId, vPrevOutlineId, vNextOutlineId, nSta EgtRelocateGlob( nBisector, nGeoLayerId, GDB_IN.LAST_SON) -- b) se profili diversi per taglio corretto dei profili serve considerare anche il bordo out del pezzo adiacente - local sCurrProfile = EgtGetInfo( nCurrProfileId, WIN_PRF_TYPE) - local sPrevProfile = EgtGetInfo( vPrevProfileId[i], WIN_PRF_TYPE) - if sCurrProfile ~= sPrevProfile then + local sCurrProfile = EgtGetInfo( nCurrProfileId, WIN_PROFILETYPE) + local sPrevProfile = EgtGetInfo( vPrevProfileId[i], WIN_PROFILETYPE) + if sCurrProfile ~= sPrevProfile and not AreSameVectorApprox( EgtSV( nOutlineId), EgtEV( vPrevOutlineId[i])) then EgtSetName( nOtherOut, WIN_GEO_LEFT) EgtRelocateGlob( nOtherOut, nGeoLayerId, GDB_IN.LAST_SON) local nSemiProfileId = EgtGetFirstNameInGroup( vPrevProfileId[i], WIN_OUT) @@ -2283,7 +2279,7 @@ local function CreateGeoCurves( nOutlineId, vPrevOutlineId, vNextOutlineId, nSta EgtInvertCurve( nPrevCurveId) end local dOffs, nPrevSemiProfile - if nStartPartJointType == WIN_PART_JNT.SHORT then + if nStartJointType == WIN_PART_JNT.SHORT then -- la curva del geo corrisponde al bordo del controprofilo in del pezzo vicino local sCtrIn = GetProfileCtrIn( abs( vPrevOutlineId[i]), nOutlineId, vPrevProfileId[i]) local dCPDelta = GetDeltaProfile( vPrevProfileId[i], sCtrIn) @@ -2308,7 +2304,7 @@ local function CreateGeoCurves( nOutlineId, vPrevOutlineId, vNextOutlineId, nSta local vNextProfileId = EgtGetNameInGroup( nProfileLayerId, WIN_PRF_END) for i = 1, #vNextOutlineId do - if nEndPartJointType == WIN_PART_JNT.ANGLED then + if nEndJointType == WIN_PART_JNT.ANGLED then local b3Profile = GetProfileLocalBox( vNextProfileId[i]) local nOtherOut = EgtCopyGlob( vNextOutlineId[i], nGeoLayerId) @@ -2333,9 +2329,9 @@ local function CreateGeoCurves( nOutlineId, vPrevOutlineId, vNextOutlineId, nSta EgtRelocateGlob( nBisector, nInId, GDB_IN.BEFORE) -- gestione per profili diversi - local sCurrProfile = EgtGetInfo( nCurrProfileId, WIN_PRF_TYPE) - local sNextProfile = EgtGetInfo( vNextProfileId[i], WIN_PRF_TYPE) - if sCurrProfile ~= sNextProfile then + local sCurrProfile = EgtGetInfo( nCurrProfileId, WIN_PROFILETYPE) + local sNextProfile = EgtGetInfo( vNextProfileId[i], WIN_PROFILETYPE) + if sCurrProfile ~= sNextProfile and not AreSameVectorApprox( EgtEV( nOutlineId), EgtSV( vNextOutlineId[i])) then EgtSetName( nOtherOut, WIN_GEO_RIGHT) local nSemiProfileId = EgtGetFirstNameInGroup( vNextProfileId[i], WIN_OUT) EgtSetInfo( nOtherOut, WIN_SEMI_PROFILE, nSemiProfileId) @@ -2352,7 +2348,7 @@ local function CreateGeoCurves( nOutlineId, vPrevOutlineId, vNextOutlineId, nSta EgtInvertCurve( nNextCurveId) end local dOffs, nNextSemiProfile - if nEndPartJointType == WIN_PART_JNT.SHORT then + if nEndJointType == WIN_PART_JNT.SHORT then local sCtrIn = GetProfileCtrIn( abs( vNextOutlineId[i]), nOutlineId, vNextProfileId[i]) local dCPDelta = GetDeltaProfile( vNextProfileId[i], sCtrIn) dOffs = - dCPDelta @@ -2374,7 +2370,7 @@ local function CreateGeoCurves( nOutlineId, vPrevOutlineId, vNextOutlineId, nSta -- verifico se necessaria estensione in tangenza per pezzi ad arco local vLeftIds = EgtGetNameInGroup( nGeoLayerId, WIN_LEFT) local vRightIds = EgtGetNameInGroup( nGeoLayerId, WIN_RIGHT) - ComputeArcExtensions( nOutId, nInId, vLeftIds, vRightIds, nStartPartJointType, nEndPartJointType) + ComputeArcExtensions( nOutId, nInId, vLeftIds, vRightIds, nStartJointType, nEndJointType) -- costruisco la superficie local vIds = EgtGetAllInGroup( nGeoLayerId) @@ -2412,85 +2408,90 @@ end --------------------------------------------------------------------- -- funzione che calcola l'ingombro dei pezzi del telaio -local function CalcGeo( nPartId, nOutlineId, nOutlineCrvNbr, nOutlineLayerId, nProfileType, nBottomRail) +local function CalcGeo( nPartId, nOutlineId) -- creo layer per ingombro local nGeoLayerId = EgtGroup( nPartId) EgtSetName( nGeoLayerId, WIN_GEO) - -- recupero outline precedenti e successivi ( solo nel caso di split possono essere più di uno) - local vPrevOutlineId, vNextOutlineId = GetPrevNextOutline( nProfileType, nOutlineId, nOutlineLayerId) - EgtSetInfo( nOutlineId, WIN_PREV_OUTLINES, vPrevOutlineId) - EgtSetInfo( nOutlineId, WIN_NEXT_OUTLINES, vNextOutlineId) + -- recupero outline precedenti e successivi + local vPrevOutlineId = EgtGetInfo( nOutlineId, WIN_PREV_OUTLINES, 'vi') + local vNextOutlineId = EgtGetInfo( nOutlineId, WIN_NEXT_OUTLINES, 'vi') + + local nBottomRail = EgtGetInfo( nPartId, WIN_BOTTOMRAIL, 'i') + local bMixed = EgtGetInfo( nOutlineId, WIN_PRF_CHANGE, 'b') or false -- recupero il tipo di giunzioni - local nStartJointType - local nEndJointType - local nProfileTypeS = nProfileType - local nProfileTypeE = nProfileType - if nProfileType == WIN_PRF.SPLIT or nProfileType == WIN_PRF.BOTTOMRAIL or nProfileType == WIN_PRF.BOTTOMRAIL_FINAL then - -- non serve settare dei valori per StartJointType ed EndJointType perchè in CalcPartJointType la loro giunzione viene settata a short + local nStartJoint + local nEndJoint + + if EgtGetName( nOutlineId) == WIN_SPLIT or nBottomRail then + -- se split o bottomrail la giunzione deve essere short + nStartJoint = WIN_PART_JNT.SHORT + nEndJoint = WIN_PART_JNT.SHORT + else -- recupero i joints opportuni dal vettore + local nOutlineLayerId = EgtGetParent( nOutlineId) local vJoints = EgtGetInfo( nOutlineLayerId, WIN_JOINTS, 'vi') if EgtGetName( nOutlineId) == WIN_BOTTOM then - nStartJointType = vJoints[1] - nEndJointType = vJoints[2] + nStartJoint = CalcPartJoint( vJoints[1], true) + nEndJoint = CalcPartJoint( vJoints[2], true) elseif EgtGetName( nOutlineId) == WIN_RIGHT then - nStartJointType = vJoints[2] - nEndJointType = vJoints[3] + nStartJoint = CalcPartJoint( vJoints[2], false) + nEndJoint = CalcPartJoint( vJoints[3], false) elseif EgtGetName( nOutlineId) == WIN_TOP then - nStartJointType = vJoints[3] - nEndJointType = vJoints[4] - -- correzioni per caso a triangolo + nStartJoint = CalcPartJoint( vJoints[3], true) + nEndJoint = CalcPartJoint( vJoints[4], true) + -- correzioni per caso a triangolo : se l'outline vicino è di tipo bottom, il corrente deve essere trattato come un pezzo verticale if EgtGetName( abs( vPrevOutlineId[#vPrevOutlineId])) == WIN_BOTTOM then - nStartJointType = vJoints[2] - nEndJointType = vJoints[3] - -- il lato top deve essere trattato come un left/right nel calcolo della giunzione - nProfileTypeS = WIN_PRF.LEFT + nStartJoint = CalcPartJoint( vJoints[2], false) + nEndJoint = CalcPartJoint( vJoints[3], true) end if EgtGetName( abs( vNextOutlineId[1])) == WIN_BOTTOM then - nStartJointType = vJoints[3] - nEndJointType = vJoints[1] - nProfileTypeE = WIN_PRF.LEFT + nStartJoint = CalcPartJoint( vJoints[3], true) + nEndJoint = CalcPartJoint( vJoints[1], false) end elseif EgtGetName( nOutlineId) == WIN_LEFT then - nStartJointType = vJoints[4] or vJoints[3] -- ( vJoints[3] per gestire caso a triangolo) - nEndJointType = vJoints[1] + nStartJoint = CalcPartJoint( vJoints[4] or vJoints[3], false) -- ( vJoints[3] per gestire caso a triangolo) + nEndJoint = CalcPartJoint( vJoints[1], false) end - -- se giunzione diversa da bisettrice ed elementi in tangenza ( entro 6°) o dello stesso tipo, forzo il tipo a bisettrice - if nStartJointType ~= WIN_JNT.ANGLED and ( EgtEV( abs( vPrevOutlineId[1])) * EgtSV( nOutlineId) > s_dAngledCos or EgtGetName( nOutlineId) == EgtGetName( abs( vPrevOutlineId[1]))) then - nStartJointType = WIN_JNT.ANGLED + -- se giunzione diversa da bisettrice ed elementi in tangenza ( entro 6°) o dello stesso tipo o entrambi con cambio profilo, forzo il tipo a bisettrice + if nStartJoint ~= WIN_JNT.ANGLED then + local bMixedPrev = EgtGetInfo( vPrevOutlineId[1], WIN_PRF_CHANGE, 'b') or false + if EgtEV( abs( vPrevOutlineId[1])) * EgtSV( nOutlineId) > s_dAngledCos or EgtGetName( nOutlineId) == EgtGetName( abs( vPrevOutlineId[1])) or ( bMixed and bMixedPrev) then + nStartJoint = WIN_JNT.ANGLED + end end - if nEndJointType ~= WIN_JNT.ANGLED and ( EgtEV( nOutlineId) * EgtSV( abs( vNextOutlineId[1])) > s_dAngledCos or EgtGetName( nOutlineId) == EgtGetName( abs( vNextOutlineId[1]))) then - nEndJointType = WIN_JNT.ANGLED + if nEndJoint ~= WIN_JNT.ANGLED then + local bMixedNext = EgtGetInfo( vNextOutlineId[1], WIN_PRF_CHANGE, 'b') or false + if EgtEV( nOutlineId) * EgtSV( abs( vNextOutlineId[1])) > s_dAngledCos or EgtGetName( nOutlineId) == EgtGetName( abs( vNextOutlineId[1])) or ( bMixed and bMixedNext) then + nEndJoint = WIN_JNT.ANGLED + end end end - -- calcolo il tipo di giunzione per la parte - local nStartPartJointType = CalcPartJointType( nProfileTypeS, nStartJointType) - local nEndPartJointType = CalcPartJointType( nProfileTypeE, nEndJointType) -- nel caso di incontro con soglia la giunzione deve essere full if EgtGetInfo( abs( vPrevOutlineId[1]), WIN_THRESHOLD, 'b') then - nStartPartJointType = WIN_JNT.FULL + nStartJoint = WIN_JNT.FULL end if EgtGetInfo( abs( vNextOutlineId[1]), WIN_THRESHOLD, 'b') then - nEndPartJointType = WIN_JNT.FULL + nEndJoint = WIN_JNT.FULL end -- salvo il valore dei joints su outline -- se bottomrail è sicuramente short quindi non salvo il valore che sovrascriverebbe quello del pezzo bottom ( che potrebbe essere short o full) - if nProfileType ~= WIN_PRF.BOTTOMRAIL and nProfileType ~= WIN_PRF.BOTTOMRAIL_FINAL then - EgtSetInfo( nOutlineId, WIN_STARTJOINT, nStartPartJointType) - EgtSetInfo( nOutlineId, WIN_ENDJOINT, nEndPartJointType) + if not nBottomRail then + EgtSetInfo( nOutlineId, WIN_STARTJOINT, nStartJoint) + EgtSetInfo( nOutlineId, WIN_ENDJOINT, nEndJoint) end -- creo il gruppo con i profili del pezzo - local nProfileLayerId = CalcProfiles( nPartId, nOutlineId, vPrevOutlineId, vNextOutlineId, nProfileType, nBottomRail) + local nProfileLayerId = CalcProfiles( nPartId, nOutlineId, vPrevOutlineId, vNextOutlineId, nBottomRail) -- creo lati dell'outline - CreateGeoCurves( nOutlineId, vPrevOutlineId, vNextOutlineId, nStartPartJointType, nEndPartJointType, nGeoLayerId, nProfileLayerId) + CreateGeoCurves( nOutlineId, vPrevOutlineId, vNextOutlineId, nStartJoint, nEndJoint, nGeoLayerId, nProfileLayerId) end @@ -2537,165 +2538,209 @@ end ---------------------------------------------------------------------------------- ----------------------- CURVE AUX PER CAMBIO PROFILO ----------------------------- ---------------------------------------------------------------------------------- --- funzione che individua e crea i diversi tratti uniformi della curva di outline -local function CalcMixedOutlines( nPartId, nOutlineId) +local function CalcMixedMillings( vOutlines, nOutlineProfileId, nSplitId, nSplitProfileId, bPrev, nGrp) - -- creo gruppo dove salvare i sottotratti - local nGrp = EgtGroup( nPartId) - EgtSetName( nGrp, WIN_MIXED_OUTLINES) - EgtSetStatus( nGrp, GDB_ST.OFF) + -- 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 - -- recupero i tratti di tipo sash e li concateno - local vSashChildren = EgtGetInfo( nOutlineId, WIN_SASH_CHILDREN, 'vi') - local vSash = {} - for i = 1, #vSashChildren do - local nCrv = EgtCopyGlob( vSashChildren[i], nGrp) - table.insert( vSash, nCrv) - end - local nCrvS, nCntS = EgtCurveCompoByReorder( nGrp, vSash, EgtSP( nOutlineId)) - for nId = nCrvS, nCrvS + nCntS - 1 do - -- da curva compo ricavo la curva linea/arco corrispondente - EgtMergeCurvesInCurveCompo( nId) - local nNewId = EgtExplodeCurveCompo( nId) - EgtSetName( nNewId, WIN_SASH) - end + local nGrpTmp = EgtGroup( nGrp) - -- recupero i tratti di tipo fill e li concateno - local vFillChildren = EgtGetInfo( nOutlineId, WIN_FILL_CHILDREN, 'vi') - local vFill = {} - for i = 1, #vFillChildren do - local nCrv = EgtCopyGlob( vFillChildren[i], nGrp) - table.insert( vFill, nCrv) - end - local nCrvF, nCntF = EgtCurveCompoByReorder( nGrp, vFill, EgtSP( nOutlineId)) - for nId = nCrvF, nCrvF + nCntF - 1 do - EgtMergeCurvesInCurveCompo( nId) - local nNewId = EgtExplodeCurveCompo( nId) - EgtSetName( nNewId, WIN_FILL) - end + local dDim1 = 61 + local dDim2 = 45 + local dRad = EgtGetInfo( nSplitProfileId, WIN_RAD_REF .. '1', 'd') + local ptRef = EgtIf( bPrev, EgtSP( nSplitId), EgtEP( nSplitId)) + + -- calcolo le curve di riferimento per lo split + local dSplitFixedOffs = EgtGetInfo( nSplitProfileId, WIN_FIXED_REF, 'd') + local nCrvSF = EgtOffsetCurveAdv( nSplitId, dSplitFixedOffs) + EgtRelocateGlob( nCrvSF, nGrpTmp) + local dSplitSashOffs1 = EgtGetInfo( nSplitProfileId, WIN_SASH_REF .. '1', 'd') + local nCrvSS1 = EgtOffsetCurveAdv( nSplitId, - dSplitSashOffs1) + EgtRelocateGlob( nCrvSS1, nGrpTmp) + local dSplitSashOffs2 = EgtGetInfo( nSplitProfileId, WIN_SASH_REF .. '2', 'd') + local nCrvSS2 = EgtOffsetCurveAdv( nSplitId, - dSplitSashOffs2) + EgtRelocateGlob( nCrvSS2, nGrpTmp) - -- riordino le curve nel gruppo per ricostruire l'outline - EgtReorderCurvesInGroup( nGrp, EgtSP( nOutlineId)) + -- calcolo le curve di riferimento prev + local nOutlineCompo = EgtCurveCompo( nGrpTmp, vOutlines, false) + local dFrameFixedOffs = EgtGetInfo( nOutlineProfileId, WIN_FIXED_REF, 'd') + local nCrvFF = EgtOffsetCurveAdv( nOutlineCompo, - dFrameFixedOffs) + local dFrameSashOffs1 = EgtGetInfo( nOutlineProfileId, WIN_SASH_REF .. '1', 'd') + local nCrvFS1 = EgtOffsetCurveAdv( nOutlineCompo, - dFrameSashOffs1) + local dFrameSashOffs2 = EgtGetInfo( nOutlineProfileId, WIN_SASH_REF .. '2', 'd') + local nCrvFS2 = EgtOffsetCurveAdv( nOutlineCompo, - dFrameSashOffs2) + local dFrameExtra = EgtGetInfo( nOutlineProfileId, WIN_EXTRA_DIST, 'd') + local nCrvFIn = EgtOffsetCurveAdv( nOutlineCompo, - dFrameSashOffs2 + dFrameExtra) + + local dDepth = EgtGetInfo( nOutlineProfileId, WIN_SASH_DEPTH .. '2', 'd') + + -- calcolo il bisettore a partire dall'incontro delle parti fixed del telaio e dello split + local nBisector + local pt1 = EgtIP( nCrvSF, nCrvFF, ptRef) + local dParRef = EgtCurveParamAtPoint( nCrvFF, pt1) + local nCrvRef = floor( dParRef) + + 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)) + nBisector = EgtLinePVL( nGrpTmp, pt1, vtDir, 1000) + EgtExtendCurveStartByLen( nBisector, 1000) + + else + -- 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 + nBisector = CalcParabolicBisector( nArc, nCrvSF, dDim, nGrpTmp, true, false) + EgtInvertCurve( nBisector) + else + nBisector = CalcParabolicBisector( nCrvSF, nArc, dDim, nGrpTmp, true, false) + end + EgtErase( nArc) + end - -- creo associazione tra le sottocurve di outline e gli split che le separano : - -- recupero tutti gli split coinvolti - local nBaseOutline = EgtGetInfo( nOutlineId, WIN_COPY, 'i') - local vStack = { nBaseOutline} - local vSplitIds = {} - local i = 1 - while vStack[i] do - -- recupero il tipo di area - local nAreaId = EgtGetParent( EgtGetParent( vStack[i])) - local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i') - if nAreaType ~= WIN_AREATYPES.SASH and nAreaType ~= WIN_AREATYPES.FILL then - -- salvo i suo eventuali split mixed - local nSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_SPLIT) - if nSplitLayerId then - local vCurrSplits = EgtGetAllInGroup( nSplitLayerId) - for j = 1, #vCurrSplits do - if EgtGetInfo( vCurrSplits[j], WIN_SPLITTYPE, 'i') == WIN_SPLITTYPES.MIXED then - table.insert( vSplitIds, vCurrSplits[j]) - end - end - end - -- analizzo eventuali figli - local vChildren = EgtGetInfo( vStack[i], WIN_CHILD, 'vi') or {} - vStack = EgtJoinTables( vStack, vChildren) - end - i = i + 1 + -- posizione finale del tool di profilatura che determina il limite delle fresature + local nBisectTool = EgtCopyGlob( nBisector, nGrpTmp) + EgtOffsetCurve( nBisectTool, - dDim1 * 0.5) + EgtExtendCurveStartByLen( nBisectTool, 10) + EgtExtendCurveEndByLen( nBisectTool, 10) + local nCrvSash = EgtOffsetCurveAdv( nOutlineCompo, - dFrameSashOffs1 - 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) + + + -- 1) Fresatura #1 + local pt2 = EgtIP( nBisector, nCrvFS1, ptRef) + local dPar1 = EgtCurveParamAtPoint( nBisector, pt1) + local dPar2 = EgtCurveParamAtPoint( nBisector, pt2) + local nMill1 = EgtCopyParamRange( nBisector, min( dPar2, dPar1), max( dPar1, dPar2), nGrpTmp) + local dPar3 = EgtCurveParamAtPoint( nCrvFS1, pt2) + local _, _, dPar4 = EgtPointCurveDist( ptEnd, nCrvFS1) + local nMill2 = EgtCopyParamRange( nCrvFS1, min( dPar4, dPar3), max( dPar3, dPar4), nGrpTmp) + + local nMilling + if bPrev then + nMilling = EgtCurveCompo( nGrpTmp, { nMill2, nMill1}) + else + nMilling = EgtCurveCompo( nGrpTmp, { nMill1, nMill2}) + end + -- offset e contro-offset per creare fillet + local nMillingOffs = EgtOffsetCurveAdv( nMilling, - dRad) + nMilling = EgtOffsetCurveAdv( nMillingOffs, dRad) + + EgtRelocateGlob( nMilling, nGrp) + EgtSetColor( nMilling, EgtStdColor( 'BLUE')) + EgtSetName( nMilling, WIN_MIXED_MILLING .. '1') + EgtSetInfo( nMilling, WIN_MIXED_SPLIT_REF, nSplitId) + EgtModifyCurveThickness( nMilling, - dDepth) + if bPrev then + EgtSetInfo( nMilling, WIN_MIXED_SASHFILL, true) + else + EgtSetInfo( nMilling, WIN_MIXED_SASHFILL, false) end - -- associo le curve con lo split che le taglia nel loro punto finale - local vCrvs = EgtGetAllInGroup( nGrp) - for i = 1, #vSplitIds do - local ptS = EgtSP( vSplitIds[i]) - local ptE = EgtEP( vSplitIds[i]) - for j = 1, #vCrvs - 1 do - local ptTest = EgtEP( vCrvs[j]) - if AreSamePointApprox( ptS, ptTest) then - EgtSetInfo( vSplitIds[i], WIN_MIXED_REF_START, vCrvs[j]) - EgtSetInfo( vCrvs[j], WIN_MIXED_SPLIT_REF, vSplitIds[i]) - break - elseif AreSamePointApprox( ptE, ptTest) then - EgtSetInfo( vSplitIds[i], WIN_MIXED_REF_END, vCrvs[j]) - EgtSetInfo( vCrvs[j], WIN_MIXED_SPLIT_REF, vSplitIds[i]) - break - end - end + + -- 2) Fresatura #2 + -- calcolo i punti di riferimento + local pt3 = EgtIP( nBisector, nCrvFIn, ptRef) + 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 dParB = EgtCurveParamAtPoint( nBisector, pt3) + local nMill3 = EgtCopyParamRange( nBisector, min( dParA, dParB), max( dParA, dParB), nGrpTmp) + local dParC = EgtCurveParamAtPoint( nCrvFIn, pt3) + local dParD = EgtCurveParamAtPoint( nCrvFIn, pt4) + local nMill4 = EgtCopyParamRange( nCrvFIn, min( dParC, dParD), max( dParC, dParD), nGrpTmp) + local dParE = EgtCurveParamAtPoint( nCrvSS1, pt4) + local dParF = EgtCurveParamAtPoint( nCrvSS1, pt5) + local nMill5 = EgtCopyParamRange( nCrvSS1, min( dParE, dParF), max( dParE, dParF), nGrpTmp) + EgtInvertCurve( nMill5) + local dParG = EgtCurveParamAtPoint( nCrvFS2, pt5) + local nMill6 + if bPrev then + nMill6 = EgtCopyParamRange( nCrvFS2, 0, dParG, nGrpTmp) + else + local _, dE = EgtCurveDomain( nCrvFS2) + nMill6 = EgtCopyParamRange( nCrvFS2, dParG, dE, nGrpTmp) end - return nGrp + local nMilling2 + if bPrev 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') + 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) + end + local dParH = EgtCurveParamAtPoint( nMilling2, pt6) + if bPrev then + EgtTrimCurveStartAtParam( nMilling2, dParH) + else + EgtTrimCurveEndAtParam( nMilling2, dParH) + end + + EgtErase( nGrpTmp) + return nMilling, nMilling2 end --------------------------------------------------------------------- --- funzione che crea la curva di riferimento sulla giunzione tra il pezzo di split e il pezzo di telaio con cambio profilo -local function CalcMixedIntersections( nPartId, nOutline, vOutlines) +-- funzione che calcola le curve legate al cambio profilo +local function CalcMixedCurves( nPartId, nSplitId) local nGrp = EgtGroup( nPartId) - EgtSetName( nGrp, WIN_MIXED_INTERSECTIONS) + EgtSetName( nGrp, WIN_MIXED_CURVES) EgtSetStatus( nGrp, GDB_ST.OFF) - -- recupero il profilo dell'outline - local nProfileLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE) - local nMainProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN) + local nProfileGrpId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE) + local nSplitProfileId = EgtGetFirstNameInGroup( nProfileGrpId, WIN_PRF_MAIN) - for i = 1, #vOutlines - 1 do - - -- recupero la curva di split che separa i due tratti di outline - local nSplitId = EgtGetInfo( vOutlines[i], WIN_MIXED_SPLIT_REF, 'i') - local nSplitProfileId = GetOutlineProfileId( nSplitId, false) - - -- verifico ordinamento - local bSashFill = ( EgtGetName( vOutlines[i]) == WIN_SASH) - - -- ricavo il punto di incontro tra le due parti dei profili che vanno contro il vetro - local nCrv1 = EgtCopyGlob( nSplitId, nGrp) - local dDeltaFixedSplit = EgtGetInfo( nSplitProfileId, WIN_FIXED_REF, 'd') - EgtOffsetCurve( nCrv1, dDeltaFixedSplit) - local nCrv2 = EgtCopyGlob( nOutline, nGrp) - local dDeltaFixedFrame = EgtGetInfo( nMainProfileId, WIN_FIXED_REF, 'd') - EgtOffsetCurve( nCrv2, - dDeltaFixedFrame) - local ptRef1 = EgtIP( nCrv1, nCrv2, ORIG()) - - -- ricavo il punto di incontro tra il taglio a 45° e la parte del telaio contro anta - -- TO DO : capire come gestire correttamente la rotazione nel caso di arco - local dParRef = EgtCurveParamAtPoint( nCrv2, ptRef1) - local vtDir45 = EgtUV( nCrv2, dParRef, -1) - vtDir45:rotate( Z_AX(), EgtIf( bSashFill, 225, -45)) - local nCrv3 = EgtLinePVL( nGrp, ptRef1, vtDir45, 100) - local nCrv4 = EgtCopyGlob( nOutline, nGrp) - local dDeltaSashFrame = EgtGetInfo( nMainProfileId, WIN_SASH_REF .. '1', 'd') - EgtOffsetCurve( nCrv4, - dDeltaSashFrame) - local ptRef2 = EgtIP( nCrv3, nCrv4, ORIG()) - - -- curva di intersezione da usare come riferimento per i conti successivi - local nCrv = EgtCurveCompoFromPoints( nGrp, { ptRef1, ptRef2}) - - -- calcolo il raccordo - local dRad = EgtGetInfo( nMainProfileId, WIN_RAD_REF .. '1', 'd') - local dParFillet = EgtCurveParamAtPoint( nCrv4, ptRef2) - dParFillet = dParFillet + EgtIf( bSashFill, -10, 10) * GEO.EPS_SMALL - local nFillet = EgtCurveFillet( nGrp, nCrv, EgtUP( nCrv1, 0.9), nCrv4, EgtUP( nCrv4, dParFillet), dRad, true) or GDB_ID.NULL - EgtAddCurveCompoCurve( nCrv, nFillet) - - -- cancello curve di costruzione - EgtErase( { nCrv1, nCrv2, nCrv3, nCrv4}) - - -- assegno riferimento - EgtSetInfo( vOutlines[i], WIN_MIXED_INTERS_REF, nCrv) + -- 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) + end + EgtCopyGlob( nMill1, nMixedInters) + EgtCopyGlob( nMill2, nMixedInters) + 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 + EgtCopyGlob( nMill3, nMixedInters) + EgtCopyGlob( nMill4, nMixedInters) end end ---------------------------------------------------------------------- --- funzione che calcola curve ausiliarie per la gestione del cambio profilo -local function CalcMixedFrameCurves( nPartId, nOutlineId) - -- calcolo i sottotratti uniformi della curva di outline - local nOutlinesGrp = CalcMixedOutlines( nPartId, nOutlineId) - local vCrvs = EgtGetAllInGroup( nOutlinesGrp) - -- calcolo le curve di intersezione con gli split - CalcMixedIntersections( nPartId, nOutlineId, vCrvs) -end - ---------------------------------------------------------------------------------- @@ -2732,136 +2777,10 @@ local function GetProcessingInfoFromSemiProfile( nCrv, nSemiProfile) end end ---------------------------------------------------------------------- --- funzione che calcola la prima lavorazione per l'innesto dello split sul telaio nel caso di cambio profilo -local function CalcMixedFrameMilling1( nIntersCrv, nOutlineId, nMainProfileId, nSplitRef, bSashFill, nProcLayerId, nSurfGeoId) - - local dOffs = EgtGetInfo( nMainProfileId, WIN_SASH_REF .. '1', 'd') - local dDepth = EgtGetInfo( nMainProfileId, WIN_SASH_DEPTH .. '1', 'd') - local dFilletRad = EgtGetInfo( nMainProfileId, WIN_RAD_REF .. '1', 'd') - - -- primo tratto : taglio a 45° e fillet - local nCrv1 = EgtCopyGlob( nIntersCrv, nProcLayerId) - EgtExtendCurveStartByLen( nCrv1, 100) - - -- calcolo il tratto di outline - local nCrv2 = EgtCopyGlob( nOutlineId, nProcLayerId) - EgtOffsetCurve( nCrv2, - dOffs) - if bSashFill then - EgtInvertCurve( nCrv2) - end - local dParS = EgtCurveParamAtPoint( nCrv2, EgtEP( nCrv1)) - local ptEnd = EgtIP( nCrv2, nSplitRef, ORIG()) - local dParE = EgtCurveParamAtPoint( nCrv2, ptEnd) - EgtTrimCurveStartEndAtParam( nCrv2, dParS, dParE) - - -- tratto di uscita a 45° - local vtDir2 = EgtEV( nCrv2) - vtDir2:rotate( Z_AX(), EgtIf( bSashFill, - 45, 45)) - local nCrv3 = EgtLinePVL( nProcLayerId, ptEnd, vtDir2, 100) - - -- creo fillet - local nFillet = EgtCurveFillet( nProcLayerId, nCrv2, EgtUP( nCrv2, 0.9), nCrv3, EgtUP( nCrv3, 0.1), dFilletRad, true) - - -- creo curva di lavorazione - local nMillingCrv = EgtCurveCompo( nProcLayerId, {nCrv1, nCrv2, nFillet, nCrv3}) - if bSashFill then - EgtInvertCurve( nMillingCrv) - end - EgtModifyCurveThickness( nMillingCrv, - dDepth) - -- setto info di lavorazione - EgtSetInfo( nMillingCrv, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.PROFILING) - EgtSetInfo( nMillingCrv, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.GENERIC) - EgtSetInfo( nMillingCrv, WIN_PRC_SIDE, WIN_PRC_SIDETYPE.IN) - EgtTrimCurveWithRegion( nMillingCrv, nSurfGeoId, true, false) - -end - ---------------------------------------------------------------------- --- funzione che calcola la seconda lavorazione per l'innesto dello split sul telaio nel caso di cambio profilo -local function CalcMixedFrameMilling2( nIntersCrv, nOutlineId, nMainProfileId, nSplitProfileId, nSplitRef, bSashFill, nProcLayerId, nSurfGeoId) - - local dOffs = EgtGetInfo( nMainProfileId, WIN_SASH_REF .. '2', 'd') - local dDepth = EgtGetInfo( nMainProfileId, WIN_SASH_DEPTH .. '2', 'd') - local dFilletRad = EgtGetInfo( nMainProfileId, WIN_RAD_REF .. '2', 'd') - local dExtraDist = EgtGetInfo( nMainProfileId, WIN_EXTRA_DIST, 'd') - - local nCrv1 = EgtCopyGlob( nIntersCrv, nProcLayerId) - EgtExtendCurveStartByLen( nCrv1, 100) - - -- calcolo il primo tratto di outline - local nCrv2 = EgtCopyGlob( nOutlineId, nProcLayerId) - EgtOffsetCurve( nCrv2, - dOffs + dExtraDist) - if bSashFill then - EgtInvertCurve( nCrv2) - end - - -- taglio i due tratti per unirli - local pt1 = EgtIP( nCrv1, nCrv2, ORIG()) - local dParE1 = EgtCurveParamAtPoint( nCrv1, pt1) - EgtTrimCurveEndAtParam( nCrv1, dParE1) - local dParS2 = EgtCurveParamAtPoint( nCrv2, pt1) - EgtTrimCurveStartAtParam( nCrv2, dParS2) - - -- calcolo fillet - local nFillet1 = EgtCurveFillet( nProcLayerId, nCrv1, EgtUP( nCrv1, 0.9), nCrv2, EgtUP( nCrv2, 0.1), dFilletRad, true) - - -- calcolo il secondo tratto di outline - local nCrv3 = EgtCopyGlob( nOutlineId, nProcLayerId) - EgtOffsetCurve( nCrv3, - dOffs) - if bSashFill then - EgtInvertCurve( nCrv3) - end - local nSplitRef2 = EgtCopyGlob( nSplitRef, nProcLayerId) - local dOffs1 = EgtGetInfo( nSplitProfileId, WIN_SASH_REF .. '1', 'd') - local dOffs2 = EgtGetInfo( nSplitProfileId, WIN_SASH_REF .. '2', 'd') - EgtOffsetCurve( nSplitRef2, dOffs2 - dOffs1) - local pt2 = EgtIP( nCrv3, nSplitRef2, ORIG()) - local pt3 = EgtIP( nCrv3, nSplitRef, ORIG()) - local dParS3 = EgtCurveParamAtPoint( nCrv3, pt2) - local dParE3 = EgtCurveParamAtPoint( nCrv3, pt3) - EgtTrimCurveStartEndAtParam( nCrv3, dParS3, dParE3) - EgtErase( nSplitRef2) - - -- calcolo il raccordo tra i due tratti di outline : è arco di raggio dFilletRad, tangente a nCrv2 e con punto finale pt2 - -- calcolo il centro dell'arco - local nCircleTmp = EgtCircle( nProcLayerId, pt2, dFilletRad) - local nCrvTmp = EgtCopyGlob( nOutlineId, nProcLayerId) - EgtOffsetCurve( nCrvTmp, - dOffs + dExtraDist - dFilletRad) - local ptC = EgtIP( nCircleTmp, nCrvTmp, EgtIf( bSashFill, EgtEP( nCrvTmp), EgtSP( nCrvTmp))) - EgtErase( {nCircleTmp, nCrvTmp}) - local nFillet2 = EgtArcC2PEx( nProcLayerId, ptC, EgtSP( nCrv2), GDB_PT.TG, nCrv2, pt2) - - -- taglio il primo tratto di outline per collegarlo al raccordo - local dParE2 = EgtCurveParamAtPoint( nCrv2, EgtSP( nFillet2)) - EgtTrimCurveEndAtParam( nCrv2, dParE2) - - -- tratto di uscita a 45° - local vtDir2 = EgtEV( nCrv3) - vtDir2:rotate( Z_AX(), EgtIf( bSashFill, - 45, 45)) - local nCrv4 = EgtLinePVL( nProcLayerId, EgtEP( nCrv3), vtDir2, 100) - - -- creo fillet - local nFillet3 = EgtCurveFillet( nProcLayerId, nCrv3, EgtUP( nCrv3, 0.9), nCrv4, EgtUP( nCrv4, 0.1), dFilletRad, true) or GDB_ID.NULL - - -- creo curva di lavorazione - local nMillingCrv = EgtCurveCompo( nProcLayerId, {nCrv1, nFillet1, nCrv2, nFillet2, nCrv3, nFillet3, nCrv4}) - if bSashFill then - EgtInvertCurve( nMillingCrv) - end - EgtModifyCurveThickness( nMillingCrv, - dDepth) - -- setto info di lavorazione - EgtSetInfo( nMillingCrv, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.PROFILING) - EgtSetInfo( nMillingCrv, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.GENERIC) - EgtSetInfo( nMillingCrv, WIN_PRC_SIDE, WIN_PRC_SIDETYPE.IN) - EgtTrimCurveWithRegion( nMillingCrv, nSurfGeoId, true, false) - -end - --------------------------------------------------------------------- -- funzione che calcola le lavorazioni di profiling per un pezzo di telaio con cambio profilo local function CalcMixedFrameProfilingProcessings( nPartId, nProcLayerId, nGeoLayerId, nMainProfileId, nSurfGeoId) - + -- a) lavorazioni profili -- per le lavorazioni dei profili out, left, right e in comune si usano le corrispondenti curve del geo local vGeoCrvs = EgtGetAllInGroup( nGeoLayerId) @@ -2874,46 +2793,22 @@ local function CalcMixedFrameProfilingProcessings( nPartId, nProcLayerId, nGeoLa GetProcessingInfoFromSemiProfile( nCrv, nSemiProfile) end - -- lavorazioni dei sottotratti in di sash e fill - local nOutlinesGrp = EgtGetFirstNameInGroup( nPartId, WIN_MIXED_OUTLINES) - local vCrvs = EgtGetAllInGroup( nOutlinesGrp) - local b3Profile = GetProfileLocalBox( nMainProfileId) - local dOffs = b3Profile:getMin():getX() - for i = #vCrvs, 1, -1 do - -- calcolo la curva di lavorazione - local nCrv = EgtCopyGlob( vCrvs[i], nProcLayerId) - EgtOffsetCurve( nCrv, dOffs) - EgtInvertCurve( nCrv) - nCrv = EgtTrimCurveWithRegion( nCrv, nSurfGeoId, true, true) - -- setto le info di lavorazione dal semiprofilo - local nSemiProfile = EgtGetFirstNameInGroup( nMainProfileId, EgtGetName( vCrvs[i]) .. WIN_IN) - GetProcessingInfoFromSemiProfile( nCrv, nSemiProfile) - -- sistemo info di lavorazione - EgtSetInfo( nCrv, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.MIXED) - EgtSetInfo( nCrv, WIN_PRC_SIDE, WIN_PRC_SIDETYPE.IN) - -- TO DO : calcolo di AddLen ? - end - - -- b) lavorazioni sulle intersezioni con gli split - local nIntersGrp = EgtGetFirstNameInGroup( nPartId, WIN_MIXED_INTERSECTIONS) - local vInters = EgtGetAllInGroup( nIntersGrp) - local nOutlineId = EgtGetInfo( nPartId, WIN_REF_OUTLINE, 'i') - for i = 1, #vInters do - - local bSashFill = ( EgtGetName( vCrvs[i]) == WIN_SASH) - -- recupero lo split associato e creo la curva di riferimento per le fresature - local nSplitId = EgtGetInfo( vCrvs[i], WIN_MIXED_SPLIT_REF, 'i') - local nSplitProfileId = GetOutlineProfileId( nSplitId, false) - local dRefSplit = EgtGetInfo( nSplitProfileId, WIN_SASH_REF .. '2', 'd') - local nSplitRef = EgtCopyGlob( nSplitId, nProcLayerId) - EgtOffsetCurve( nSplitRef, - dRefSplit) - - -- Fresatura 1 - CalcMixedFrameMilling1( vInters[i], nOutlineId, nMainProfileId, nSplitRef, bSashFill, nProcLayerId, nSurfGeoId) - -- Fresatura 2 - CalcMixedFrameMilling2( vInters[i], nOutlineId, nMainProfileId, nSplitProfileId, nSplitRef, bSashFill, nProcLayerId, nSurfGeoId) + -- a) lavorazioni per i sottotratti sash e fill + -- TO DO ( da capire bene soprattuto nei casi di cambio profilo che coinvolge pezzi distinti) - EgtErase( nSplitRef) + -- b) fresature + local nMixedIntersGrp = EgtGetFirstNameInGroup( nPartId, WIN_MIXED_CURVES) + local vMixedInters = EgtGetNameInGroup( nMixedIntersGrp, WIN_MIXED_MILLING .. '*') + local dDepth1 = EgtGetInfo( nMainProfileId, WIN_SASH_DEPTH .. '1') + for i = 1, #vMixedInters do + local nMilling = EgtCopyGlob( vMixedInters[i], nProcLayerId) + -- sistemo spessore + if EgtGetName( nMilling) == WIN_MIXED_MILLING .. '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 @@ -2927,38 +2822,22 @@ local function CalcMixedSplitProfilingProcessings( nSplitId, nProcLayerId, nGeoL -- copio la curva local nCrvId = EgtCopyGlob( vGeoCrvs[i], nProcLayerId) EgtModifyCurveThickness( nCrvId, 0) - -- recupero il semiprofilo associato ( per left e right è stato salvato il profilo di tipo sash) + -- recupero il semiprofilo associato e le sue info ( per left e right è già stato salvato il profilo di tipo sash) local nSemiProfileId = EgtGetInfo( nCrvId, WIN_SEMI_PROFILE, 'i') - -- setto le info dal semiprofilo GetProcessingInfoFromSemiProfile( nCrvId, nSemiProfileId) end - -- b) tagli a 45° - -- left - local nMixedLeft = EgtGetInfo( nSplitId, WIN_MIXED_REF_START, 'i') - local nIntersLeft = EgtGetInfo( nMixedLeft, WIN_MIXED_INTERS_REF, 'i') + -- b) fresature + local nMixedIntersGrp = EgtGetFirstNameInGroup( EgtGetParent( nProcLayerId), WIN_MIXED_CURVES) + local nIntersLeft = EgtGetFirstNameInGroup( nMixedIntersGrp, WIN_MIXED_MILLING .. '1') local nMillingLeft = EgtCopyGlob( nIntersLeft, nProcLayerId) - -- recupero profondità - local vOutlineLeft = EgtGetInfo( nSplitId, WIN_PREV_OUTLINES, 'vi') - local nProfileLeft = GetOutlineProfileId( abs( vOutlineLeft[1]), false) - local dDepthLeft = EgtGetInfo( nProfileLeft, WIN_SASH_DEPTH .. '2', 'd') - EgtModifyCurveThickness( nMillingLeft, - dDepthLeft) - -- setto info di lavorazione EgtSetInfo( nMillingLeft, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.PROFILING) EgtSetInfo( nMillingLeft, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.GENERIC) EgtSetInfo( nMillingLeft, WIN_PRC_SIDE, WIN_PRC_SIDETYPE.LEFT) - -- right - local nMixedRight = EgtGetInfo( nSplitId, WIN_MIXED_REF_END, 'i') - local nIntersRight = EgtGetInfo( nMixedRight, WIN_MIXED_INTERS_REF, 'i') + local nIntersRight = EgtGetLastNameInGroup( nMixedIntersGrp, WIN_MIXED_MILLING .. '1') local nMillingRight = EgtCopyGlob( nIntersRight, nProcLayerId) - -- recupero profondità - local vOutlineRight = EgtGetInfo( nSplitId, WIN_NEXT_OUTLINES, 'vi') - local nProfileRight = GetOutlineProfileId( abs( vOutlineRight[1]), false) - local dDepthRight = EgtGetInfo( nProfileRight, WIN_SASH_DEPTH .. '2', 'd') - EgtModifyCurveThickness( nMillingRight, - dDepthRight) EgtInvertCurve( nMillingRight) - -- setto info di lavorazione EgtSetInfo( nMillingRight, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.PROFILING) EgtSetInfo( nMillingRight, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.GENERIC) EgtSetInfo( nMillingRight, WIN_PRC_SIDE, WIN_PRC_SIDETYPE.RIGHT) @@ -3269,43 +3148,6 @@ local function CreateTrimSurf( nGeoId, nOutlineId, dGeoWidth, nLayerId) end end ---------------------------------------------------------------------- --- funzione che crea le superfici di trim per uno split coinvolto da cambio profilo ( controprofilo della parte sash del telaio e taglio a 45°) -local function CreateMixedSplitTrimSurf( nMixedOutlineId, nProfileId, dExtraLen, nLayerId) - - -- estrudo il controprofilo di tipo sash - local nPartId = EgtGetParent( EgtGetParent( nMixedOutlineId)) - local nOutlineId = EgtGetInfo( nPartId, WIN_REF_OUTLINE, 'i') - local sTrimProfile = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. WIN_OFST .. WIN_SASH .. WIN_CTRIN - local nTrimStmId = CreateProfileSurf( nOutlineId, nProfileId, sTrimProfile, dExtraLen, nLayerId) - - -- creo il solido da intersecare con il controprofilo per il taglio a 45° - local nIntersCrvId = EgtGetInfo( nMixedOutlineId, WIN_MIXED_INTERS_REF, 'i') - local nGuideId = EgtCopyGlob( nIntersCrvId, nLayerId) - local bSashFill = ( EgtGetName( nMixedOutlineId) ~= WIN_SASH) - local vtDirH = EgtSV( nGuideId) - vtDirH:rotate( Z_AX(), EgtIf( bSashFill, -135, 135)) - local vtDirV = EgtSV( nGuideId) - vtDirV:rotate( Z_AX(), EgtIf( bSashFill, -45, 45)) - EgtAddCurveCompoLine( nGuideId, EgtEP( nGuideId) + dExtraLen * vtDirV) - EgtAddCurveCompoLine( nGuideId, EgtSP( nGuideId) + dExtraLen * vtDirH, false) - EgtAddCurveCompoLine( nGuideId, EgtSP( nGuideId) + dExtraLen * vtDirV, false) - EgtCloseCurveCompo( nGuideId) - EgtMove( nGuideId, 0.01 * Z_AX()) - if bSashFill then - EgtInvertCurve( nGuideId) - end - local dDepth = EgtGetInfo( nProfileId, WIN_SASH_DEPTH .. '2', 'd') - local nCutStmId = EgtSurfTmByRegionExtrusion( nLayerId, nGuideId, - ( dDepth + 2) * Z_AX()) - - -- creo una superficie di trim unica - EgtSurfTmSubtract( nTrimStmId, nCutStmId) - - EgtErase( { nGuideId, nCutStmId}) - - return nTrimStmId -end - --------------------------------------------------------------------- -- funzione che calcola la curva guida per il solido principale local function CalcSolidGuide( nOutlineId, nSolidLayerId, nProfileId) @@ -3360,7 +3202,7 @@ local function CalcSolidGuide( nOutlineId, nSolidLayerId, nProfileId) EgtSetStatus( nGuideId, GDB_ST.OFF) -- se bottomrail sposto opportunamente la guida - local sProfileType = EgtGetInfo( nProfileId, WIN_PRF_TYPE) + local sProfileType = EgtGetInfo( nProfileId, WIN_PROFILETYPE) if sProfileType == WIN_RAIL or sProfileType == WIN_FILL_RAIL then local dOffs = EgtGetInfo( nProfileId, WIN_RAILDELTA, 'd') EgtOffsetCurve( nGuideId, - dOffs) @@ -3396,67 +3238,51 @@ end local function CalcMixedFrameSolid( nOutlineId, nSolidLayerId, nProfileLayerId, nGeoLayerId, dGeoWidth) -- a) SOLIDO PRINCIPALE + -- creo i solidi corrispondenti alla parte sash e alla parte fill local nMainProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN) - -- creo i solidi corrispondenti ai diversi sottotratti uniformi del pezzo - local nMixedOutlinesGrp = EgtGetFirstNameInGroup( EgtGetParent( nSolidLayerId), WIN_MIXED_OUTLINES) - local vMixedOutlines = EgtGetAllInGroup( nMixedOutlinesGrp) local nGuideId = CalcSolidGuide( nOutlineId, nSolidLayerId, nMainProfileId) - local vMainExtrusions = {} - for i = 1, #vMixedOutlines do - local sSection = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. EgtGetName( vMixedOutlines[i]) .. WIN_SECTION - local nMainExtrusionId = CreateMainSurf( nGuideId, nMainProfileId, sSection, nSolidLayerId) - table.insert( vMainExtrusions, nMainExtrusionId) - end - - -- taglio i sottopezzi nei punti di intersezione per unirli - local nMixedIntersectionsGrp = EgtGetFirstNameInGroup( EgtGetParent( nSolidLayerId), WIN_MIXED_INTERSECTIONS) - local vIntersections = EgtGetAllInGroup( nMixedIntersectionsGrp) + EgtSetName( nGuideId, WIN_MAINGUIDE) + EgtSetStatus( nGuideId, GDB_ST.OFF) + local sSectionSash = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. WIN_SASH .. WIN_SECTION + local nMainSash = CreateMainSurf( nGuideId, nMainProfileId, sSectionSash, nSolidLayerId) + local sSectionFill = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. WIN_FILL .. WIN_SECTION + local nMainFill = CreateMainSurf( nGuideId, nMainProfileId, sSectionFill, 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 - -- creo la superficie di separazione tra i due sottopezzi - local bSashFill = ( EgtGetName( vMixedOutlines[i]) == WIN_SASH) - local vtDirS = EgtSV( vIntersections[i]) - vtDirS:rotate( Z_AX(), EgtIf( bSashFill, -135, 135)) - local vtDirE = EgtSV( vIntersections[i]) - vtDirE:rotate( Z_AX(), EgtIf( bSashFill, 45, -45)) - local nCrvTrim = EgtCurveCompo( nSolidLayerId, vIntersections[i], false) - EgtAddCurveCompoLine( nCrvTrim, EgtSP( nCrvTrim) + dGeoWidth * vtDirS, false) - EgtAddCurveCompoLine( nCrvTrim, EgtEP( nCrvTrim) + dGeoWidth * vtDirE) + 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()) - local nStmTrim = EgtSurfTmByExtrusion( nSolidLayerId, nCrvTrim, - 2 * dGeoWidth * Z_AX()) - - -- taglio i due sottopezzi - EgtSurfTmSubtract( vMainExtrusions[i+1], nStmTrim) - EgtInvertSurf( nStmTrim) - EgtSurfTmSubtract( vMainExtrusions[i], nStmTrim) - + EgtSetStatus( nCrvTrim, GDB_ST.OFF) + vStmInters[i] = EgtSurfTmByExtrusion( nSolidLayerId, nCrvTrim, - 2 * dGeoWidth * Z_AX()) EgtErase( nCrvTrim) - EgtErase( nStmTrim) end + -- 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 - -- unisco i sottopezzi in una sola superficie - for i = 2, #vMainExtrusions do - EgtSurfTmAdd( vMainExtrusions[1], vMainExtrusions[i]) - EgtErase( vMainExtrusions[i]) - end - -- creo una copia dell'estrusione principale ( usata per ferramenta) - local nOrigMainExtrusionId = EgtCopy( vMainExtrusions[1], nSolidLayerId) + local nOrigMainExtrusionId = EgtCopy( nMainSolid, nSolidLayerId) EgtSetName( nOrigMainExtrusionId, WIN_SRF_ORIGMAIN) EgtSetStatus( nOrigMainExtrusionId, GDB_ST.OFF) - - -- come guida tengo solo una copia della curva di outline - local vMainGuideIds = EgtGetNameInGroup( nSolidLayerId, WIN_MAINGUIDE) - EgtErase( vMainGuideIds) - local nMainGuideId = EgtCopyGlob( nOutlineId, nSolidLayerId) - EgtSetName( nMainGuideId, WIN_MAINGUIDE) - EgtSetStatus( nMainGuideId, GDB_ST.OFF) - + -- b) TRIM START local nPrevGeoId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_LEFT) local nStartOutlineId = EgtGetInfo( nPrevGeoId, WIN_REF_OUTLINE, 'i') local nTrimSurfStart = CreateTrimSurf( nPrevGeoId, nStartOutlineId, dGeoWidth, nSolidLayerId) EgtSetStatus( nTrimSurfStart, GDB_ST.OFF) - EgtSurfTmIntersect( vMainExtrusions[1], nTrimSurfStart) + EgtSurfTmIntersect( nMainSolid, nTrimSurfStart) EgtSetInfo( nPrevGeoId, WIN_REF_SURF, nTrimSurfStart) -- c) TRIM END @@ -3464,10 +3290,56 @@ local function CalcMixedFrameSolid( nOutlineId, nSolidLayerId, nProfileLayerId, local nEndOutlineId = EgtGetInfo( nNextGeoId, WIN_REF_OUTLINE, 'i') local nTrimSurfEnd = CreateTrimSurf( nNextGeoId, nEndOutlineId, dGeoWidth, nSolidLayerId) EgtSetStatus( nTrimSurfEnd, GDB_ST.OFF) - EgtSurfTmIntersect( vMainExtrusions[1], nTrimSurfEnd) + EgtSurfTmIntersect( nMainSolid, nTrimSurfEnd) EgtSetInfo( nNextGeoId, WIN_REF_SURF, nTrimSurfEnd) - return vMainExtrusions[1] + 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) + + local nGuide = EgtCopyGlob( nMillingCrv, nSolidLayerId) + EgtAddCurveCompoLineTg( nGuide, 10, not bPrev) + local vtDir = EgtSV( nSplitId) + if bPrev then + vtDir = - vtDir + 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 +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) + + -- 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 end --------------------------------------------------------------------- @@ -3484,25 +3356,50 @@ local function CalcMixedSplitSolid( nOutlineId, nSolidLayerId, nProfileLayerId, EgtSetName( nOrigMainExtrusionId, WIN_SRF_ORIGMAIN) EgtSetStatus( nOrigMainExtrusionId, GDB_ST.OFF) - -- b) trim start - local nPrevProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_START) - local nPrevMixedOutline = EgtGetInfo( nOutlineId, WIN_MIXED_REF_START, 'i') - local nStmTrimStart = CreateMixedSplitTrimSurf( nPrevMixedOutline, nPrevProfileId, dGeoWidth, nSolidLayerId) - EgtSetStatus( nStmTrimStart, GDB_ST.OFF) - EgtSurfTmIntersect( nMainExtrusionId, nStmTrimStart) + -- 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 nGeoLayerId = EgtGetFirstNameInGroup( EgtGetParent( nSolidLayerId), WIN_GEO) - local nPrevGeoId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_LEFT) - EgtSetInfo( nPrevGeoId, WIN_REF_SURF, nStmTrimStart) - - -- c) trim end - local nNextProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_END) - local nNextMixedOutline = EgtGetInfo( nOutlineId, WIN_MIXED_REF_END, 'i') - local nStmTrimEnd = CreateMixedSplitTrimSurf( nNextMixedOutline, nNextProfileId, dGeoWidth, nSolidLayerId) - EgtSetStatus( nStmTrimEnd, GDB_ST.OFF) - EgtSurfTmIntersect( nMainExtrusionId, nStmTrimEnd) - local nNextGeoId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_RIGHT) - EgtSetInfo( nNextGeoId, WIN_REF_SURF, nStmTrimEnd) + 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 + end + return nMainExtrusionId end @@ -3533,7 +3430,7 @@ local function CalcSolid( nPartId, nOutlineId) -- creo layer per solido local nSolidLayerId = EgtGroup( nPartId) EgtSetName( nSolidLayerId, WIN_SOLID) - + -- recupero profilo principale local nProfileLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE) @@ -3671,7 +3568,7 @@ end --------------------------------------------------------------------- -- funzione che calcola il riferimento dove posizionare i dowels -local function CreateDowelFrameDest( nRefProfileType, nPrevGeo, nGeo, nRefOutline, bCurrFullOrShort, bSashOrFrame) +local function CreateDowelFrameDest( nPrevGeo, nGeo, nRefOutline, bCurrFullOrShort, bSashOrFrame) -- 1) la direzione z è determinata dal pezzo short local vtZ @@ -3726,7 +3623,7 @@ local function PositionDowel( nDowelId, frOrig, frDest, vtDir, nSurfId) -- posiziono il dowel utilizzando i riferimenti EgtTransform( nDowelId, frOrig, GDB_RT.GLOB) EgtTransform( nDowelId, frDest, GDB_RT.GLOB) - EgtMove( nDowelId, 300 * vtDir) + EgtMove( nDowelId, 3000 * vtDir) -- creo il tool corrispondente al dowel local dRad = EgtArcRadius( nDowelId) @@ -3850,16 +3747,6 @@ local function CalcDowels( nOrigOutlineId, nOrigPrevOutlineId, bSashOrFrame, nBo local nGeo = EgtGetFirstNameInGroup( nPart, WIN_GEO) local nPrevGeo = EgtGetFirstNameInGroup( nPrevPart, WIN_GEO) - -- recupero i tipi di profilo - local nPrevProfileType = GetOutlineProfileType( nPrevOutlineId, false, nBottomRail) - local nProfileType = GetOutlineProfileType( nOutlineId, false, nBottomRail) - -- caso particolare del triangolo : se lato top contro bottom il top deve essere gestito come un left/right - if nProfileType == WIN_PRF.TOP and nPrevProfileType == WIN_PRF.BOTTOM then - nProfileType = WIN_PRF.RIGHT - elseif nProfileType == WIN_PRF.BOTTOM and nPrevProfileType == WIN_PRF.TOP then - nPrevProfileType = WIN_PRF.LEFT - end - -- recupero i solidi local nPrevSolidId, nSolidId, nPrevSolidLay, nSolidLay if s_bCalcSolid then @@ -3890,12 +3777,12 @@ local function CalcDowels( nOrigOutlineId, nOrigPrevOutlineId, bSashOrFrame, nBo frOrig:invert() -- calcolo il riferimento su cui posizionare i dowels - local frDest = CreateDowelFrameDest( nPrevProfileType, nPrevGeo, nGeo, nPrevOutlineId, true, bSashOrFrame) + local frDest = CreateDowelFrameDest( nPrevGeo, nGeo, nPrevOutlineId, true, bSashOrFrame) -- recupero info con la lunghezza ( dipendono dal profilo del pezzo full quindi dal corrente) local sLenKey = WIN_DWL_TOP_PERP_LEN local sPrevLenKey = WIN_DWL_TOP_PARA_LEN - if nProfileType == WIN_PRF.BOTTOM then + if EgtGetName( nOutlineId) == WIN_BOTTOM then sLenKey = WIN_DWL_BOTTOM_PERP_LEN sPrevLenKey = WIN_DWL_BOTTOM_PARA_LEN elseif EgtExistsInfo( nPart, WIN_SASHTYPE) then @@ -3978,17 +3865,19 @@ local function CalcDowels( nOrigOutlineId, nOrigPrevOutlineId, bSashOrFrame, nBo frOrig:invert() -- calcolo il riferimento su cui posizionare i dowels - local frDest = CreateDowelFrameDest( nProfileType, nPrevGeo, nGeo, nOutlineId, false, bSashOrFrame) + local frDest = CreateDowelFrameDest( nPrevGeo, nGeo, nOutlineId, false, bSashOrFrame) -- recupero info con la lunghezza ( dipendono dal profilo del pezzo full, quindi da prezzo prev) local sLenKey = WIN_DWL_TOP_PARA_LEN local sPrevLenKey = WIN_DWL_TOP_PERP_LEN - if nPrevProfileType == WIN_PRF.BOTTOM then - sLenKey = WIN_DWL_BOTTOM_PARA_LEN - sPrevLenKey = WIN_DWL_BOTTOM_PERP_LEN - elseif nPrevProfileType == WIN_PRF.BOTTOMRAIL or nPrevProfileType == WIN_PRF.BOTTOMRAIL_FINAL then - sLenKey = WIN_DWL_BOTTOMRAIL_PARA_LEN - sPrevLenKey = WIN_DWL_BOTTOMRAIL_PERP_LEN + if EgtGetName( nPrevOutlineId) == WIN_BOTTOM then + if not nBottomRail then + sLenKey = WIN_DWL_BOTTOM_PARA_LEN + sPrevLenKey = WIN_DWL_BOTTOM_PERP_LEN + else + sLenKey = WIN_DWL_BOTTOMRAIL_PARA_LEN + sPrevLenKey = WIN_DWL_BOTTOMRAIL_PERP_LEN + end elseif EgtExistsInfo( nPrevPart, WIN_SASHTYPE) then -- verifico se è inactive sash dalla info settata per lavorazione sLenKey = WIN_DWL_INACTIVE_PARA_LEN @@ -4069,6 +3958,7 @@ end local function CalcSplitDowels( nSplitId, bStartOrEnd) -- TO DO : da gestire incrocio dowels di tre pezzi + -- TO DO : gestione split non lineare -- recupero il pezzo dello split local nSplitPart = EgtGetInfo( nSplitId, WIN_REF_PART, 'i') @@ -4113,121 +4003,123 @@ local function CalcSplitDowels( nSplitId, bStartOrEnd) -- recupero il pezzo associato e il suo outline di riferimento local nPartId = FindAssociatedPart( nOrigOutline, true) local nOutlineId = EgtGetInfo( nPartId, WIN_REF_OUTLINE, 'i') - local nProfileType = GetOutlineProfileType( nOutlineId, true) - - -- calcolo il frame di destinazione - -- trovo intersezione dello split con lato In o Out del geo + local nGeoLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO) local nGeoCrvId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_IN) - local ptInters = EgtIP( nGeoCrvId, nSplitId, ptRef) local sDowelSide = WIN_PRC_SIDETYPE.IN - if not ptInters and nProfileType == WIN_PRF.SPLIT then - nGeoCrvId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_OUT) - ptInters = EgtIP( nGeoCrvId, nSplitId, ptRef) - sDowelSide = WIN_PRC_SIDETYPE.OUT - end - -- se non trovo intersezione passo al successivo - if ptInters then - - -- TO DO : gestione split non lineare - local frDest = Frame3d( ptInters, - EgtSV( nSplitId)) - - -- recupero il layer con le lavorazioni - local nLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PRC) - - -- nel layer dei profili del pezzo aggiungo il profilo dello split posizionato correttamente - local nProfileLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE) - local nSplitProfileCopyId = EgtCopy( nSplitProfile, nProfileLayerId) - local sSplitProfileType = EgtGetName( nSplitProfile) - EgtSetInfo( nSplitProfileCopyId, WIN_PRF_TYPE, sSplitProfileType) - EgtSetName( nSplitProfileCopyId, WIN_PRF_SPLIT) - -- posiziono il profilo sulla curva di split - EgtTransform( EgtGetAllInGroup( nSplitProfileCopyId), frOrig, GDB_RT.GLOB) - EgtChangeGroupFrame( nSplitProfileCopyId, frDest, GDB_RT.GLOB) - - -- recupero eventuale solido - local nSolidId - if s_bCalcSolid then - local nSolidLayerId = EgtGetFirstNameInGroup( nPartId, WIN_SOLID) - nSolidId = EgtGetFirstNameInGroup( nSolidLayerId, WIN_SRF_MAIN) + -- se split verifico se interferisce con lato in o out del geo + if EgtGetName( nOutlineId) == WIN_SPLIT then + local _, _, nSide = EgtPointCurveDistSide( EgtMP( nSplitId), nOutlineId, Z_AX()) + if nSide == 1 then + nGeoCrvId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_OUT) + sDowelSide = WIN_PRC_SIDETYPE.OUT end + end + + -- calcolo il frame di destinazione + local ptOrig = EgtIf( bStartOrEnd, EgtSP( nSplitId), EgtEP( nSplitId)) + local frDest = Frame3d( ptOrig, - EgtSV( nSplitId)) + + -- recupero il layer con le lavorazioni + local nLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PRC) + + -- nel layer dei profili del pezzo aggiungo il profilo dello split posizionato correttamente + local nProfileLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE) + local nSplitProfileCopyId = EgtCopy( nSplitProfile, nProfileLayerId) + local sSplitProfileType = EgtGetName( nSplitProfile) + EgtSetInfo( nSplitProfileCopyId, WIN_PROFILETYPE, sSplitProfileType) + EgtSetName( nSplitProfileCopyId, WIN_PRF_SPLIT) + -- posiziono il profilo sulla curva di split + EgtTransform( EgtGetAllInGroup( nSplitProfileCopyId), frOrig, GDB_RT.GLOB) + EgtChangeGroupFrame( nSplitProfileCopyId, frDest, GDB_RT.GLOB) + + -- recupero eventuale solido + local nSolidId + if s_bCalcSolid then + local nSolidLayerId = EgtGetFirstNameInGroup( nPartId, WIN_SOLID) + nSolidId = EgtGetFirstNameInGroup( nSolidLayerId, WIN_SRF_MAIN) + end - -- recupero le chiavi delle lunghezze ( dipendono dal profilo del pezzo su cui poggia lo split) - local sSplitLenKey = WIN_DWL_TOP_PARA_LEN - local sLenKey = WIN_DWL_TOP_PERP_LEN - if nProfileType == WIN_PRF.BOTTOM then + -- recupero le chiavi delle lunghezze ( dipendono dal profilo del pezzo su cui poggia lo split) + local sSplitLenKey = WIN_DWL_TOP_PARA_LEN + local sLenKey = WIN_DWL_TOP_PERP_LEN + if EgtGetName( nOutlineId) == WIN_BOTTOM then + -- verifico se ha bottomrails + local nBottomRails = EgtGetInfo( nOutlineId, WIN_BOTTOMRAIL, 'i') or 0 + if nBottomRails == 0 then sSplitLenKey = WIN_DWL_BOTTOM_PARA_LEN sLenKey = WIN_DWL_BOTTOM_PERP_LEN - elseif nProfileType == WIN_PRF.BOTTOMRAIL_FINAL then + else sSplitLenKey = WIN_DWL_RAILBOTTOM_PARA_LEN sLenKey = WIN_DWL_RAILBOTTOM_PERP_LEN - elseif nProfileType == WIN_PRF.SPLIT then - sSplitLenKey = WIN_DWL_SPLIT_PARA_LEN - sLenKey = WIN_DWL_SPLIT_PERP_LEN end - - -- creo la superficie di test per il posizionamento dei dowels - local nProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN) - local nTestSurf - if not s_bCalcSolid or s_bSimplSolid then - local bChangeProfile = EgtGetInfo( nSplitId, WIN_PRF_CHANGE, 'b') or false - if bChangeProfile then - local nMixedOutline = EgtGetInfo( nSplitId, EgtIf( bStartOrEnd, WIN_MIXED_REF_START, WIN_MIXED_REF_END), 'i') - nTestSurf = CreateMixedSplitTrimSurf( nMixedOutline, nProfileId, 100, nLayerId) - else - local sCtr = WIN_OFST .. GetProfileCtrIn( nOutlineId, nSplitId, nProfileId) - nTestSurf = CreateProfileSurf( nOutlineId, nProfileId, sCtr, 100, nLayerId) - end - else - -- è la stessa superficie utilizzata per il trim del solido - local nTrimSurf = EgtGetInfo( vGeoCrvs[i], WIN_REF_SURF, 'i') - nTestSurf = EgtCopyGlob( nTrimSurf, nSplitLayerId) - end - local nTestSurfInverted = EgtCopyGlob( nTestSurf, nSplitLayerId) - EgtInvertSurf( nTestSurfInverted) - - -- calcolo le direzioni entranti nei pezzi - local vtSplitDir = EgtIf( bStartOrEnd, - frDest:getVersZ(), frDest:getVersZ()) - local vtDir = frDest:getVersZ() - local _, _, nSide = EgtPointCurveDistSide( ptInters + vtDir, nGeoCrvId, Z_AX()) - if nSide == 1 then - -- se a destra della curva significa che la direzione è uscente dal pezzo e va invertita - vtDir = - vtDir - end - - -- recupero la superficie del pezzo per verificare se dowel interno - local nGeo = EgtGetFirstNameInGroup( nPartId, WIN_GEO) - local nSurf = EgtGetFirstNameInGroup( nGeo, WIN_GEO_SURF) - - -- aggiungo i dowels - local vDowels = EgtGetNameInGroup( nSplitProfile, WIN_DOWEL .. '*') or {} - for i = 1, #vDowels do - -- split - local dLen1 = CalcDowelLen( vDowels[i], sSplitLenKey, false) - local nDowel1 = CreateDowel( vDowels[i], nSplitLayerId, frOrig, frDest, vtSplitDir, nTestSurf, dLen1, sSplitDowelSide, nSplitSolidId) - -- verifico se dowel è interno al pezzo ( TO DO : da migliorare!) - local ptTest = EgtCP( nDowel1) - vtSplitDir * EgtCurveThickness( nDowel1) - local nTestPoint = EgtPoint( nSplitLayerId, ptTest) - if EgtSurfFrTestExternal( nSplitSurf, nTestPoint) then - EgtErase( nDowel1) - end - EgtErase( nTestPoint) - - -- pezzo - local dLen2 = CalcDowelLen( vDowels[i], sLenKey, true) - local nDowel2 = CreateDowel( vDowels[i], nLayerId, frOrig, frDest, vtDir, nTestSurfInverted, dLen2, sDowelSide, nSolidId) - ptTest = EgtCP( nDowel2) - vtDir * EgtCurveThickness( nDowel2) - nTestPoint = EgtPoint( nLayerId, ptTest) - if EgtSurfFrTestExternal( nSurf, nTestPoint) then - EgtErase( nDowel2) - end - EgtErase( nTestPoint) - - end - - EgtErase( nTestSurf) - EgtErase( nTestSurfInverted) + elseif EgtGetName( nOutlineId) == WIN_SPLIT then + sSplitLenKey = WIN_DWL_SPLIT_PARA_LEN + sLenKey = WIN_DWL_SPLIT_PERP_LEN end + + -- creo la superficie di test per il posizionamento dei dowels + local nProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN) + local nTestSurf + if not s_bCalcSolid or s_bSimplSolid then + local bChangeProfile = EgtGetInfo( nSplitId, WIN_PRF_CHANGE, 'b') or false + if bChangeProfile then + local 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 nTestSurfInverted = EgtCopyGlob( nTestSurf, nSplitLayerId) + EgtInvertSurf( nTestSurfInverted) + + -- calcolo le direzioni entranti nei pezzi + local vtSplitDir = EgtIf( bStartOrEnd, - frDest:getVersZ(), frDest:getVersZ()) + local vtDir = EgtIf( bStartOrEnd, - EgtSV( nSplitId), EgtSV( nSplitId)) + + -- recupero la superficie del pezzo per verificare se dowel interno + local nGeo = EgtGetFirstNameInGroup( nPartId, WIN_GEO) + local nSurf = EgtGetFirstNameInGroup( nGeo, WIN_GEO_SURF) + + -- aggiungo i dowels + local vDowels = EgtGetNameInGroup( nSplitProfile, WIN_DOWEL .. '*') or {} + for i = 1, #vDowels do + -- split + local dLen1 = CalcDowelLen( vDowels[i], sSplitLenKey, false) + local nDowel1 = CreateDowel( vDowels[i], nSplitLayerId, frOrig, frDest, vtSplitDir, nTestSurf, dLen1, sSplitDowelSide, nSplitSolidId) + -- verifico se dowel è interno al pezzo ( TO DO : da migliorare!) + local ptTest = EgtCP( nDowel1) - vtSplitDir * EgtCurveThickness( nDowel1) + local nTestPoint = EgtPoint( nSplitLayerId, ptTest) + if EgtSurfFrTestExternal( nSplitSurf, nTestPoint) then + EgtErase( nDowel1) + end + EgtErase( nTestPoint) + + -- pezzo + local dLen2 = CalcDowelLen( vDowels[i], sLenKey, true) + local nDowel2 = CreateDowel( vDowels[i], nLayerId, frOrig, frDest, vtDir, nTestSurfInverted, dLen2, sDowelSide, nSolidId) + ptTest = EgtCP( nDowel2) - vtDir * EgtCurveThickness( nDowel2) + nTestPoint = EgtPoint( nLayerId, ptTest) + if EgtSurfFrTestExternal( nSurf, nTestPoint) then + EgtErase( nDowel2) + end + EgtErase( nTestPoint) + + end + + EgtErase( nTestSurf) + EgtErase( nTestSurfInverted) + end end end @@ -4417,7 +4309,7 @@ local function CalcAreaStrip( nGeoFillId) -- estrusione del fermavetro : -- creazione della giuda local nGuideId = EgtCurveCompo( nSolidLayerId, nOutlineId, false) - local sProfileType = EgtGetInfo( nProfileId, WIN_PRF_TYPE) + local sProfileType = EgtGetInfo( nProfileId, WIN_PROFILETYPE) if sProfileType == WIN_FILL_RAIL then local dOffs = EgtGetInfo( nProfileId, WIN_RAILDELTA, 'd') EgtOffsetCurve( nGuideId, - dOffs) @@ -4715,119 +4607,92 @@ local function DrawOpening( nAreaId) end --------------------------------------------------------------------- --- funzione che calcola l'ingombro dei pezzi del telaio e i loro solidi -local function CreatePartFromOutline( nAreaLayerId, sName, nOutlineId, nOutlineCrvNbr, nBottomRail) +local function CreatePartFromOutline( nAreaId, sName, nOutlineId, 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) - -- inserisco riferimento alla sua area - EgtSetInfo( nPartId, WIN_AREA, nAreaLayerId) - local nAreaType = EgtGetInfo( nAreaLayerId, WIN_AREATYPE, 'i') - local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaLayerId, WIN_OUTLINE) - - -- a) Telaio, anta o split - if nAreaType == WIN_AREATYPES.FRAME or nAreaType == WIN_AREATYPES.SASH or nAreaType == WIN_AREATYPES.SPLIT then - - -- creo riferimenti tra pezzo e outline - EgtSetInfo( nPartId, WIN_REF_OUTLINE, nOutlineId) - if 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) - else - EgtSetInfo( nOutlineId, WIN_REF_PART, nPartId) - end - - -- imposto nome del pezzo - local sOutlineName = EgtIf( nBottomRail, WIN_BOTTOMRAIL .. '_' .. tostring( nBottomRail), EgtGetName( nOutlineId)) - local sPartName = sName .. '_' .. sOutlineName - EgtSetName( nPartId, sPartName) - - -- imposto il 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 - - -- ricavo il tipo di profilo - local nProfileType = GetOutlineProfileType( nOutlineId, false, nBottomRail) - -- disegno ingombro - CalcGeo( nPartId, nOutlineId, nOutlineCrvNbr, nOutlineLayerId, nProfileType, nBottomRail) - -- calcolo eventuali curve ausiliarie per cambio profilo - local bChangeProfile = EgtGetInfo( nOutlineId, WIN_PRF_CHANGE, 'b') or false - if bChangeProfile and nProfileType ~= WIN_PRF.SPLIT then - CalcMixedFrameCurves( nPartId, nOutlineId) - end - -- calcolo le lavorazioni associate ai profili - CalcProfilingProcessings( nPartId, nOutlineId) - -- calcolo il georaw per automatismo lavorazioni - CalcGeoRaw( nPartId, nOutlineId) - -- disegno solido - if s_bCalcSolid then - CalcSolid( nPartId, nOutlineId) - end - - -- b) Fill - elseif nAreaType == WIN_AREATYPES.FILL then - -- imposto nome del pezzo - EgtSetName( nPartId, sName .. '_' .. WIN_FILL) - EgtSetInfo( nPartId, WIN_PART_TYPE, WIN_PART_TYPES.FILL) - -- ricavo tipo - local nFillType = EgtGetInfo( nAreaLayerId, WIN_FILLTYPE, 'i') - - -- imposto colore e tipologia di riempimento - if nFillType == WIN_FILLTYPES.GLASS then - EgtSetColor( nPartId, Color3d( 71, 161, 255)) - EgtSetAlpha( nPartId, 30) - EgtSetInfo( nPartId, WIN_FILLTYPE, WIN_GLASS) - elseif nFillType == WIN_FILLTYPES.WOOD then - EgtSetColor( nPartId, Color3d( 194, 148, 103)) - EgtSetInfo( nPartId, WIN_FILLTYPE, WIN_WOOD) - end - - -- disegno ingombro - local nGeoLayerId = CalcFillGeo( nPartId, nOutlineLayerId) - -- disegno solido - if s_bCalcSolid then - CalcFillSolid( nPartId, nGeoLayerId) - end - -- calcolo fermavetro - CalcAreaStrip( nGeoLayerId) + -- 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) end + + -- imposto nome del pezzo + local sOutlineName = EgtIf( nBottomRail, WIN_BOTTOMRAIL .. '_' .. tostring( nBottomRail), EgtGetName( nOutlineId)) + local sPartName = sName .. '_' .. sOutlineName + EgtSetName( nPartId, sPartName) + + -- imposto il 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 + return nPartId end --------------------------------------------------------------------- --- funzione che cicla ricorsivamente su aree e sottoaree per calcolare i pezzi -local function CalculateAreaParts( nAreaId) +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 .. '_' .. WIN_FILL) + 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 cicla ricorsivamente su aree e sottoaree per creare i layer dei pezzi +local function CreateParts( nAreaId, vParts, vFillParts) local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i') -- recupero nome dei pezzi in quest'area local sName = CalcPartName( nAreaId, nAreaType) if nAreaType == WIN_AREATYPES.FRAME or nAreaType == WIN_AREATYPES.SASH then - -- creo pezzi per ogni outline + -- creo pezzo per ogni outline local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE) local vOutlines = EgtGetAllInGroup( nOutlineLayerId) for i = 1, #vOutlines do - -- creo pezzo - CreatePartFromOutline( nAreaId, sName, vOutlines[i], i) - -- se di tipo bottom verifico se ha bottomrail + local nPartId = CreatePartFromOutline( nAreaId, sName, vOutlines[i]) + table.insert( vParts, nPartId) + -- se bottom verifico se ha bottomrails if EgtGetName( vOutlines[i]) == WIN_BOTTOM then local nBottomRail = EgtGetInfo( nAreaId, WIN_BOTTOMRAIL, 'i') or 0 for j = 1, nBottomRail do - CreatePartFromOutline( nAreaId, sName, vOutlines[i], i, j) + local nPartId = CreatePartFromOutline( nAreaId, sName, vOutlines[i], j) + table.insert( vParts, nPartId) end end end @@ -4838,38 +4703,19 @@ local function CalculateAreaParts( nAreaId) end elseif nAreaType == WIN_AREATYPES.FILL then - -- creo riempimento - CreatePartFromOutline( nAreaId, sName) + local nPartId = CreateFillPartFromArea( nAreaId, sName) + table.insert( vFillParts, nPartId) elseif nAreaType == WIN_AREATYPES.SPLIT then + -- se split non è di tipo french ha un pezzo associato local nSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_SPLIT) local nSplitType = EgtGetInfo( nSplitLayerId, WIN_SPLITTYPE, 'i') or WIN_SPLITTYPES.NULL - -- se split non è di tipo french ha un pezzo associato if nSplitType ~= WIN_SPLITTYPES.FRENCH then - -- creo gruppo per area di selezione per programma - local nSelectionLayerId = EgtGroup( nAreaId) - EgtSetName( nSelectionLayerId, WIN_SPLITSELECTION) - EgtSetStatus( nSelectionLayerId, GDB_ST.OFF) - EgtSetColor( nSelectionLayerId, 'YELLOW') - EgtSetAlpha( nSelectionLayerId, 10) - local nSelectionArea - local vSplitIds = EgtGetAllInGroup( nSplitLayerId) for i = 1, #vSplitIds do - -- creo pezzo split - local nSplitPartId = CreatePartFromOutline( nAreaId, sName, vSplitIds[i]) - - -- aggiorno area di selezione - local nSplitPartGeoId = EgtGetFirstNameInGroup( nSplitPartId, WIN_GEO) - local nSplitArea = EgtGetFirstNameInGroup( nSplitPartGeoId, WIN_GEO_SURF) - if not nSelectionArea then - nSelectionArea = EgtCopyGlob( nSplitArea, nSelectionLayerId) - EgtSetStatus( nSelectionArea, GDB_ST.ON) - else - EgtSurfFrAdd( nSelectionArea, nSplitArea) - end + local nPartId = CreatePartFromOutline( nAreaId, sName, vSplitIds[i]) + table.insert( vParts, nPartId) end - EgtMove( nSelectionArea, 10 * Z_AX()) end end @@ -4889,11 +4735,71 @@ local function CalculateAreaParts( nAreaId) -- calcolo i pezzi delle sottoaree local nChildAreaId = EgtGetFirstNameInGroup( nAreaId, WIN_AREA .. '*') while nChildAreaId do - CalculateAreaParts( nChildAreaId) + CreateParts( nChildAreaId, vParts, vFillParts) nChildAreaId = EgtGetNextName( nChildAreaId, WIN_AREA .. '*') end end +--------------------------------------------------------------------- +local function CalculateAreaParts( nFrameId) + + -- creo i pezzi del serramento + local vParts = {} + local vFillParts = {} + CreateParts( nFrameId, vParts, vFillParts) + + -- recupero gli outlines per ogni pezzo + local vOutlines = {} + for i = 1, #vParts do + vOutlines[i] = EgtGetInfo( vParts[i], WIN_REF_OUTLINE, 'i') + end + + -- calcolo geo + for i = 1, #vParts do + CalcGeo( vParts[i], vOutlines[i]) + end + + -- calcolo cambio profilo sugli split di tipo mixed + for i = 1, #vParts do + if EgtGetName( vOutlines[i]) == WIN_SPLIT then + local nSplitType = EgtGetInfo( vOutlines[i], WIN_SPLITTYPE, 'i') + if nSplitType == WIN_SPLITTYPES.MIXED then + CalcMixedCurves( vParts[i], vOutlines[i]) + end + end + end + + -- calcolo le lavorazioni associate ai profili + for i = 1, #vParts do + CalcProfilingProcessings( vParts[i], vOutlines[i]) + end + + -- calcolo il georaw per automatismo lavorazioni + for i = 1, #vParts do + CalcGeoRaw( vParts[i], vOutlines[i]) + end + + -- disegno solido + if s_bCalcSolid then + for i = 1, #vParts do + CalcSolid( vParts[i], vOutlines[i]) + end + end + + -- pezzi fill + for i = 1, #vFillParts do + local nAreaId = EgtGetInfo( vFillParts[i], WIN_AREA, 'i') + local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE) + local nGeoLayerId = CalcFillGeo( vFillParts[i], nOutlineLayerId) + -- disegno solido + if s_bCalcSolid then + CalcFillSolid( vFillParts[i], nGeoLayerId) + end + -- calcolo fermavetro + CalcAreaStrip( nGeoLayerId) + end +end + ---------------------------------------------------------------------------------- @@ -5757,7 +5663,7 @@ local function DrawHandlePreview( nOutlineId, sHandleSide, dHandleH, nLayerId, b dSide = dSide + 9 end end - + -- punto su cui centrare la maniglia local ptC = ptRef - dHandleH * vtDir + dSide * vtDirIn + Z_AX() @@ -6651,11 +6557,21 @@ local function CalcWaterdrip( nPartId, nOutlineId, nAreaId, bDraw) nSolidLayId = GetAuxLayer() end - -- recupero tutti gli split che possono creare interruzioni nel gocciolatoio + local vParams = {} + + -- calcolo i limiti del gocciolatoio in base ai pezzi vicini del telaio + local vPrevCrvs = EgtGetInfo( nOutlineId, WIN_PREV_OUTLINES, 'vi') + local dParS = GetTrimParamByGeo( nOutlineId, vPrevCrvs[1], WIN_GEO_IN) + table.insert( vParams, dParS) + local vNextCrvs = EgtGetInfo( nOutlineId, WIN_NEXT_OUTLINES, 'vi') + local dParE = GetTrimParamByGeo( nOutlineId, vNextCrvs[1], WIN_GEO_IN) + table.insert( vParams, dParE) + + -- calcolo eventuali interruzioni nel gocciolatoio per la presenza di montanti local vSplits = {} local nBottomRail = EgtGetInfo( nOutlineId, WIN_REF_BOTTOMRAIL_PART, 'i') if not nBottomRail then -- se ha bottomrail gli split non causano interruzioni nel gocciolatoio - local vStack = {nAreaId} + local vStack = { nAreaId} local i = 1 while vStack[i] do local nAreaType = EgtGetInfo( vStack[i], WIN_AREATYPE, 'i') @@ -6669,7 +6585,11 @@ local function CalcWaterdrip( nPartId, nOutlineId, nAreaId, bDraw) local dDist1 = EgtPointCurveDist( EgtSP( vCurrSplits[j]), nOutlineId) local dDist2 = EgtPointCurveDist( EgtEP( vCurrSplits[j]), nOutlineId) if dDist1 < GEO.EPS_SMALL or dDist2 < GEO.EPS_SMALL then - table.insert( vSplits, vCurrSplits[j]) + -- recupero l'intervallo di interruzione dello split sull'outline + local dParIn = GetTrimParamByGeo( nOutlineId, vCurrSplits[j], WIN_GEO_IN) + table.insert( vParams, dParIn) + local dParOut = GetTrimParamByGeo( nOutlineId, vCurrSplits[j], WIN_GEO_OUT) + table.insert( vParams, dParOut) end end end @@ -6684,71 +6604,21 @@ local function CalcWaterdrip( nPartId, nOutlineId, nAreaId, bDraw) i = i + 1 end end - - -- recupero le curve sulle quali costruire il gocciolatoio: in generale è solo l'outline bottom, nel caso di cambio profilo sono solo i suoi sottotratti che poggiano - -- contro le ante - local vBottomOutlines = { nOutlineId} - local bProfileChange = EgtGetInfo( nOutlineId, WIN_PRF_CHANGE, 'b') or false - if bProfileChange then - local nMixedOutlinesLay = EgtGetFirstNameInGroup( nPartId, WIN_MIXED_OUTLINES) - local vSashOutlines = EgtGetNameInGroup( nMixedOutlinesLay, WIN_SASH) - vBottomOutlines = vSashOutlines - end - - -- recupero curve vicine - local nPrevCrv = EgtGetLastInGroup( EgtGetParent( nOutlineId)) - local nNextCrv = EgtGetNext( nOutlineId) - - for i = 1, #vBottomOutlines do - local vParams = {} - - -- verifico se interruzioni per i pezzi vicini del telaio - if AreSamePointApprox( EgtSP( vBottomOutlines[i]), EgtEP( nPrevCrv)) then - local dPar = GetTrimParamByGeo( vBottomOutlines[i], nPrevCrv, WIN_GEO_IN) - table.insert( vParams, dPar) - end - if AreSamePointApprox( EgtEP( vBottomOutlines[i]), EgtSP( nNextCrv)) then - local dPar = GetTrimParamByGeo( vBottomOutlines[i], nNextCrv, WIN_GEO_IN) - table.insert( vParams, dPar) - end - - -- verifico se interruzioni per split - for j = 1, #vSplits do - -- verifico se lo split poggia sulla curva - local dDist1 = EgtPointCurveDist( EgtSP( vSplits[j]), vBottomOutlines[i]) - local dDist2 = EgtPointCurveDist( EgtEP( vSplits[j]), vBottomOutlines[i]) - if dDist1 < GEO.EPS_SMALL or dDist2 < GEO.EPS_SMALL then - -- recupero i parametri di intersezione con il geo dello split - local dParIn = GetTrimParamByGeo( vBottomOutlines[i], vSplits[j], WIN_GEO_IN) - if dParIn then - table.insert( vParams, dParIn) - end - local dParOut = GetTrimParamByGeo( vBottomOutlines[i], vSplits[j], WIN_GEO_OUT) - if dParOut then - table.insert( vParams, dParOut) - end - end - end - - -- riordino i parametri ( non dovrebbero mai capitare parametri coincidenti) - table.sort( vParams) - for j = 1, #vParams, 2 do - -- creo la guida di estrusione per il gocciolatoio - local nGuideId = EgtCopyGlob( vBottomOutlines[i], nSolidLayId) - -- trim della curva - EgtTrimCurveStartEndAtParam( nGuideId, vParams[j], vParams[j+1]) - -- aggiorno la lunghezza - dLenTot = dLenTot + EgtCurveLength( nGuideId) - -- disegno - if bDraw and s_bCalcSolid then - -- estrudo la superficie - local nStm = CreateProfileSurf( nGuideId, nProfileId, WIN_WATERDRIP, 0, nSolidLayId) - EgtSetColor( nStm, Color3d( 128, 128, 128)) - EgtSetName( nStm, WIN_WATERDRIP) - end - EgtErase( nGuideId) + -- riordino i parametri ( non dovrebbero mai capitare parametri coincidenti) + table.sort( vParams) + + for j = 1, #vParams, 2 do + -- ricavo la guida per il tratto di gocciolatoio + local nGuideId = EgtCopyParamRange( nOutlineId, vParams[j], vParams[j+1], nSolidLayId) + dLenTot = dLenTot + EgtCurveLength( nGuideId) + if bDraw and s_bCalcSolid then + -- estrudo la superficie + local nStm = CreateProfileSurf( nGuideId, nProfileId, WIN_WATERDRIP, 0, nSolidLayId) + EgtSetColor( nStm, Color3d( 128, 128, 128)) + EgtSetName( nStm, WIN_WATERDRIP) end + EgtErase( nGuideId) end -- salvo la lunghezza del gocciolatoio @@ -7032,7 +6902,7 @@ local function CalcPartPreview( nPartId, nPreviewGrp) -- recupero il tipo di giunzioni local nStartJoint = EgtGetInfo( nOutlineId, WIN_STARTJOINT, 'i') local nEndJoint = EgtGetInfo( nOutlineId, WIN_ENDJOINT, 'i') - + local nAreaId -- se non ha giunzioni short come preview posso considerare direttamente la regione del geo