From 182f5c91db23d7c1cfea8003c2e55924139de89d Mon Sep 17 00:00:00 2001 From: SaraP Date: Mon, 12 Jan 2026 12:23:44 +0100 Subject: [PATCH] =?UTF-8?q?DataWindow=20:=20-=20correzioni=20e=20migliorie?= =?UTF-8?q?=20nel=20calcolo=20delle=20lavorazioni=20e=20dei=20solidi=20qua?= =?UTF-8?q?ndo=20vi=20=C3=A8=20taglio=20con=20pi=C3=B9=20pezzi=20-=20corre?= =?UTF-8?q?zione=20estensione=20archi.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Designing/WinConst.lua | 3 +- Designing/WinLib/WinCalculate.lua | 849 ++++++++++++++++-------------- 2 files changed, 450 insertions(+), 402 deletions(-) diff --git a/Designing/WinConst.lua b/Designing/WinConst.lua index 12ccb7e..b59f716 100644 --- a/Designing/WinConst.lua +++ b/Designing/WinConst.lua @@ -193,7 +193,6 @@ WIN_THRESHOLD_PROFILE = 'ThresholdProfile' WIN_SLIDE_WINDOW = 'SlideWindow' WIN_SASH_NBR = 'SashNbr' WIN_AREA_NBR = 'AreaNbr' -WIN_REF_SURF = 'SurfRef' -- PROFILI @@ -361,6 +360,8 @@ WIN_REF_GEO = 'GeoRef' WIN_GEO_OFFS = 'GeoOffs' WIN_TANG_START = 'ExtendTangStart' WIN_TANG_END = 'ExtendTangEnd' +WIN_REF_SURF = 'SurfRef' +WIN_REF_PRC = 'PrcRef' -- CAMBIO PROFILO diff --git a/Designing/WinLib/WinCalculate.lua b/Designing/WinLib/WinCalculate.lua index bbbf53f..cca7f24 100644 --- a/Designing/WinLib/WinCalculate.lua +++ b/Designing/WinLib/WinCalculate.lua @@ -79,10 +79,30 @@ local function FindIntersectionPoint( nCrv1, nCrv2, ptRef) -- se il punto di intersezione non esiste ritento estendendo le curve if not ptInt then - local nGrp = EgtGetParent( nCrv1) + local nGrp = EgtGroup( EgtGetParent( nCrv1)) local dExtraLen = 10000 local nCrvA, nCrvB - if EgtGetType( nCrv1) == GDB_TY.CRV_LINE and EgtGetType( nCrv2) == GDB_TY.CRV_LINE then + + local nType1 = EgtGetType( nCrv1) + local nType2 = EgtGetType( nCrv2) + + -- se compo formata da una sola sottocurva viene gestita come curva semplice + if nType1 == GDB_TY.CRV_COMPO then + local _, dE = EgtCurveDomain( nCrv1) + if abs( dE - 1) < GEO.EPS_SMALL then + nCrv1 = EgtCopyCompoSubCurve( nCrv1, 0, nGrp) + nType1 = EgtGetType( nCrv1) + end + end + if nType2 == GDB_TY.CRV_COMPO then + local _, dE = EgtCurveDomain( nCrv2) + if abs( dE - 1) < GEO.EPS_SMALL then + nCrv2 = EgtCopyCompoSubCurve( nCrv2, 0, nGrp) + nType2 = EgtGetType( nCrv2) + end + end + + if nType1 == GDB_TY.CRV_LINE and nType2 == GDB_TY.CRV_LINE then -- caso linea-linea : estendo le due linee nCrvA = EgtCopyGlob( nCrv1, nGrp) nCrvB = EgtCopyGlob( nCrv2, nGrp) @@ -91,12 +111,13 @@ local function FindIntersectionPoint( nCrv1, nCrv2, ptRef) EgtExtendCurveStartByLen( nCrvB, dExtraLen) EgtExtendCurveEndByLen( nCrvB, dExtraLen) - elseif EgtGetType( nCrv1) == GDB_TY.CRV_ARC and EgtGetType( nCrv2) == GDB_TY.CRV_ARC then + elseif nType1 == GDB_TY.CRV_ARC and nType2 == GDB_TY.CRV_ARC then -- caso arco-arco : cerco intersezione tra le due circonferenze nCrvA = EgtCircle( nGrp, EgtCP( nCrv1), EgtArcRadius( nCrv1)) nCrvB = EgtCircle( nGrp, EgtCP( nCrv2), EgtArcRadius( nCrv2)) - else + elseif ( nType1 == GDB_TY.CRV_ARC and nType2 == GDB_TY.CRV_LINE) or + ( nType1 == GDB_TY.CRV_LINE and nType2 == GDB_TY.CRV_ARC) then -- caso arco-linea : cerco intersezione fra la linea e la circonferenza local nArc = EgtIf( EgtGetType( nCrv1) == GDB_TY.CRV_ARC, nCrv1, nCrv2) local nLine = EgtIf( nArc == nCrv1, nCrv2, nCrv1) @@ -107,7 +128,7 @@ local function FindIntersectionPoint( nCrv1, nCrv2, ptRef) end ptInt = EgtIP( nCrvA, nCrvB, ptRef) - EgtErase( { nCrvA, nCrvB}) + EgtErase( nGrp) end return ptInt @@ -126,9 +147,9 @@ local function CheckExtensionOverlap( nCrvId, nOrigId) if dPar1 or dPar2 then return true end - elseif dParS and abs( dParS - 1) > GEO.EPS_SMALL then + elseif dParS and not AreSamePointApprox( EgtSP( nCrvId), EgtEP( nOrigId)) then return true - elseif dParE and dParE > GEO.EPS_SMALL then + elseif dParE and not AreSamePointApprox( EgtEP( nCrvId), EgtSP( nOrigId)) then return true end return false @@ -143,7 +164,7 @@ local function CreateCurveExtension( nCrvId, nGrpId) local bTangEnd = EgtGetInfo( nCrvId, WIN_TANG_END, 'b') or false local dExtraLen = 10000 local nExtId - + if EgtGetType( nCrvId) == GDB_TY.CRV_LINE then -- estensione immediata nExtId = EgtCopyGlob( nCrvId, nGrpId) @@ -182,43 +203,73 @@ local function CreateCurveExtension( nCrvId, nGrpId) end elseif EgtGetType( nCrvId) == GDB_TY.CRV_COMPO then - - nExtId = EgtCopyGlob( nCrvId, nGrpId) - -- start - if EgtCurveCompoRadius( nExtId, 0) > 0 then - if bTangStart then - EgtAddCurveCompoLineTg( nExtId, dExtraLen, false) - else - local ptC = EgtCurveCompoCenter( nExtId, 0) - local dAngOld = EgtCurveCompoAngCenter( nExtId, 0) - EgtRemoveCurveCompoCurve( nExtId, false) - local nNewArc = EgtArcCPA( nGrpId, ptC, EgtSP( nExtId), EgtIf( dAngOld > 0, -340, 340), 0) - EgtInvertCurve( nNewArc) - EgtAddCurveCompoCurve( nExtId, nNewArc, true, false) - end + -- se composita formata da una sola sottocurva la gestisco come curva semplice + local _, dEnd = EgtCurveDomain( nCrvId) + if abs( dEnd - 1) < GEO.EPS_SMALL then + local nSimpleCrv = EgtCopyCompoSubCurve( nCrvId, 0, nGrpId) + EgtSetInfo( nSimpleCrv, WIN_TANG_START, bTangStart) + EgtSetInfo( nSimpleCrv, WIN_TANG_END, bTangEnd) + nExtId = CreateCurveExtension( nSimpleCrv, nGrpId) + EgtErase( nSimpleCrv) + else - EgtExtendCurveStartByLen( nExtId, dExtraLen) - end - -- end - local _, dEnd = EgtCurveDomain( nExtId) - if EgtCurveCompoRadius( nExtId, dEnd - 1) > 0 then - if bTangEnd then - EgtAddCurveCompoLineTg( nExtId, dExtraLen) + nExtId = EgtCopyGlob( nCrvId, nGrpId) + -- start + if EgtCurveCompoRadius( nExtId, 0) > 0 then + if bTangStart then + EgtAddCurveCompoLineTg( nExtId, dExtraLen, false) + else + local ptC = EgtCurveCompoCenter( nExtId, 0) + local dAngOld = EgtCurveCompoAngCenter( nExtId, 0) + EgtRemoveCurveCompoCurve( nExtId, false) + local nNewArc = EgtArcCPA( nGrpId, ptC, EgtSP( nExtId), EgtIf( dAngOld > 0, -340, 340), 0) + EgtInvertCurve( nNewArc) + EgtAddCurveCompoCurve( nExtId, nNewArc, true, false) + end else - local ptC = EgtCurveCompoCenter( nExtId, dEnd - 1) - local dAngOld = EgtCurveCompoAngCenter( nExtId, dEnd - 1) - EgtRemoveCurveCompoCurve( nExtId, true) - local nNewArc = EgtArcCPA( nGrpId, ptC, EgtEP( nExtId), EgtIf( dAngOld > 0, 340, -340), 0) - EgtAddCurveCompoCurve( nExtId, nNewArc) + EgtExtendCurveStartByLen( nExtId, dExtraLen) end - else - EgtExtendCurveEndByLen( nExtId, dExtraLen) - end + -- end + local _, dEnd = EgtCurveDomain( nExtId) + if EgtCurveCompoRadius( nExtId, dEnd - 1) > 0 then + if bTangEnd then + EgtAddCurveCompoLineTg( nExtId, dExtraLen) + else + local ptC = EgtCurveCompoCenter( nExtId, dEnd - 1) + local dAngOld = EgtCurveCompoAngCenter( nExtId, dEnd - 1) + EgtRemoveCurveCompoCurve( nExtId, true) + local nNewArc = EgtArcCPA( nGrpId, ptC, EgtEP( nExtId), EgtIf( dAngOld > 0, 340, -340), 0) + EgtAddCurveCompoCurve( nExtId, nNewArc) + end + else + EgtExtendCurveEndByLen( nExtId, dExtraLen) + end + end end return nExtId end +--------------------------------------------------------------------- +-- funzione che date due curve parzialmente sovrapposte con nCrvId composita, allunga nCrvId aggiungendo i tratti di nRefCrvId che fuoriescono da essa +local function AddExtension( nCrvId, nRefCrvId) + + local dParS = EgtCurveParamAtPoint( nCrvId, EgtSP( nRefCrvId), 100 * GEO.EPS_SMALL) + if not dParS then + local dParTrim = EgtCurveParamAtPoint( nRefCrvId, EgtSP( nCrvId), 100 * GEO.EPS_SMALL) + local nNewCrv = EgtCopyParamRange( nRefCrvId, 0, dParTrim, EgtGetParent( nCrvId)) + EgtAddCurveCompoCurve( nCrvId, nNewCrv, true, false) + end + + local dParE = EgtCurveParamAtPoint( nCrvId, EgtEP( nRefCrvId), 100 * GEO.EPS_SMALL) + if not dParE then + local dParTrim = EgtCurveParamAtPoint( nRefCrvId, EgtEP( nCrvId), 100 * GEO.EPS_SMALL) + local _, dE = EgtCurveDomain( nRefCrvId) + local nNewCrv = EgtCopyParamRange( nRefCrvId, dParTrim, dE, EgtGetParent( nCrvId)) + EgtAddCurveCompoCurve( nCrvId, nNewCrv) + end +end + --------------------------------------------------------------------- -- funzione che data una lista di curve ordinate e orientate che creano una curva chiusa, ne individua la regione definita local function CalcIntersectionRegion( vCrvs, nGrp) @@ -693,7 +744,15 @@ local function CreateProfileSurf( nOutlineId, nProfileId, sSectionName, dExtraLe return CreateProfileSurfById( nOutlineId, nProfileId, nSectionId, dExtraLen, nLayerId) end - +--------------------------------------------------------------------- +-- funzione che verifica se i due semiprofili coincidono +local function IsSameSemiProfile( nSemiProfile1, nSemiProfile2) + -- TODO al momento controllo che appartengano allo stesso profilo ma non è il controllo ottimale ( profili diversi possono avere semiprofili uguali). + -- Con la gestione delle librerie di semiprofili nella creazione del file dei profili basterà guardare se sono copie dello stesso semiprofilo ( info?) + local sName1 = EgtGetInfo( EgtGetParent( nSemiProfile1), WIN_PROFILETYPE) + local sName2 = EgtGetInfo( EgtGetParent( nSemiProfile2), WIN_PROFILETYPE) + return ( sName1 == sName2 and EgtGetName( nSemiProfile1) == EgtGetName( nSemiProfile2)) +end ---------------------------------------------------------------------------------- ----------------------------- CALCOLO DEI PROFILI ------------------------------ @@ -1137,16 +1196,16 @@ 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 function TestSplitTrimOutlines( nOutlineId, vBaseTrimOutlines, tabOutlines, nMainProfile, b3Profile, nGrpTmp, bPrevOrNext) - local vRealTrimOutlines = {} + local vTrimOutlines = {} -- 1) recupero le curve da testare local vTestOutlines = {} - -- a) curve individuate dalle intersezioni degli outlines - for i = 1, #vTrimOutlines do - vTestOutlines[i] = vTrimOutlines[i] + -- a) curve individuate dalle intersezioni dei base outlines + for i = 1, #vBaseTrimOutlines do + vTestOutlines[i] = tabOutlines[vBaseTrimOutlines[i]] end -- b) curve vicine a quelle individuate dalle intersezioni che interferiscono con l'outline ( guardando interferenza grossolana dei pezzi) @@ -1161,13 +1220,14 @@ local function TestSplitTrimOutlines( nOutlineId, vTrimOutlines, nMainProfile, b local nInId = EgtOffsetCurveAdv( nOutlineCopyId, b3Profile:getMin():getX()) -- curve precedenti - local nTestCurve = EgtGetPrev( vTrimOutlines[1]) or EgtGetLastInGroup( EgtGetParent( vTrimOutlines[1])) + local nTestCurve = EgtGetPrev( vBaseTrimOutlines[1]) or EgtGetLastInGroup( EgtGetParent( vBaseTrimOutlines[1])) local bInters = true - while bInters and nTestCurve ~= vTrimOutlines[#vTrimOutlines] do + while bInters and nTestCurve ~= vBaseTrimOutlines[#vBaseTrimOutlines] do - local nProfileId = GetOutlineProfileId( nTestCurve, true) + local nRefOutline = abs( tabOutlines[nTestCurve]) + local nProfileId = GetOutlineProfileId( nRefOutline, true) local b3Profile = GetProfileLocalBox( nProfileId) - local nRefSurf = EgtSurfFrFatCurve( nGrpTmp, nTestCurve, b3Profile:getMin():getX(), false) + local nRefSurf = EgtSurfFrFatCurve( nGrpTmp, nRefOutline, b3Profile:getMin():getX(), false) local nClassOut = EgtCurveWithRegionClassify( nOutId, nRefSurf) if nClassOut == GDB_CRC.OUT then @@ -1179,19 +1239,20 @@ local function TestSplitTrimOutlines( nOutlineId, vTrimOutlines, nMainProfile, b end -- se interferenza lo aggiungo tra le curve da controllare if bInters then - table.insert( vTestOutlines, 1, nTestCurve) + table.insert( vTestOutlines, 1, tabOutlines[nTestCurve]) nTestCurve = EgtGetPrev( nTestCurve) or EgtGetLastInGroup( EgtGetParent( nTestCurve)) end end -- curve successive - nTestCurve = EgtGetNext( vTrimOutlines[#vTrimOutlines]) or EgtGetFirstInGroup( EgtGetParent( vTrimOutlines[1])) + nTestCurve = EgtGetNext( vBaseTrimOutlines[#vBaseTrimOutlines]) or EgtGetFirstInGroup( EgtGetParent( vBaseTrimOutlines[1])) bInters = true - while bInters and nTestCurve ~= vTrimOutlines[1] do + while bInters and nTestCurve ~= vBaseTrimOutlines[1] do - local nProfileId = GetOutlineProfileId( nTestCurve, true) + local nRefOutline = abs( tabOutlines[nTestCurve]) + local nProfileId = GetOutlineProfileId( nRefOutline, true) local b3Profile = GetProfileLocalBox( nProfileId) - local nRefSurf = EgtSurfFrFatCurve( nGrpTmp, nTestCurve, b3Profile:getMin():getX(), false) + local nRefSurf = EgtSurfFrFatCurve( nGrpTmp, nRefOutline, b3Profile:getMin():getX(), false) local nClassOut = EgtCurveWithRegionClassify( nOutId, nRefSurf) if nClassOut == GDB_CRC.OUT then @@ -1201,7 +1262,7 @@ local function TestSplitTrimOutlines( nOutlineId, vTrimOutlines, nMainProfile, b end end if bInters then - table.insert( vTestOutlines, nTestCurve) + table.insert( vTestOutlines, tabOutlines[nTestCurve]) nTestCurve = EgtGetNext( nTestCurve) or EgtGetFirstInGroup( EgtGetParent( nTestCurve)) end end @@ -1220,38 +1281,38 @@ local function TestSplitTrimOutlines( nOutlineId, vTrimOutlines, nMainProfile, b local vProfiles = {} local vsCtrIn = {} for i = 1, #vTestOutlines do - vProfiles[i] = GetOutlineProfileId( vTestOutlines[i], true) - vsCtrIn[i] = GetProfileCtrIn( vTestOutlines[i], nOutlineId, vProfiles[i]) + vProfiles[i] = GetOutlineProfileId( abs( vTestOutlines[i]), true) + vsCtrIn[i] = GetProfileCtrIn( abs( 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) + local nTestSurf = CreateProfileSurf( abs( 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) + if AreSameVectorApprox( EgtEV( abs( vTestOutlines[i-1])), EgtSV( abs( vTestOutlines[i]))) then + EgtCutSurfTmPlane( nTestSurf, EgtEP( abs( vTestOutlines[i-1])), - EgtEV( abs( vTestOutlines[i-1])), false) else - local nTrimSurf = CreateProfileSurf( vTestOutlines[i-1], vProfiles[i-1], WIN_OFST .. vsCtrIn[i-1], 4 * dExtraLen, nGrpTmp) + local nTrimSurf = CreateProfileSurf( abs( vTestOutlines[i-1]), vProfiles[i-1], WIN_OFST .. vsCtrIn[i-1], 4 * dExtraLen, nGrpTmp) EgtSurfTmCut( nTestSurf, nTrimSurf, true, false) end end if i < #vTestOutlines then - if AreSameVectorApprox( EgtEV( vTestOutlines[i]), EgtSV( vTestOutlines[i+1])) then - EgtCutSurfTmPlane( nTestSurf, EgtEP( vTestOutlines[i]), EgtEV( vTestOutlines[i]), false) + if AreSameVectorApprox( EgtEV( abs( vTestOutlines[i])), EgtSV( abs( vTestOutlines[i+1]))) then + EgtCutSurfTmPlane( nTestSurf, EgtEP( abs( vTestOutlines[i])), EgtEV( abs( vTestOutlines[i])), false) else - local nTrimSurf = CreateProfileSurf( vTestOutlines[i+1], vProfiles[i+1], WIN_OFST .. vsCtrIn[i+1], 4 * dExtraLen, nGrpTmp) + local nTrimSurf = CreateProfileSurf( abs( vTestOutlines[i+1]), vProfiles[i+1], WIN_OFST .. vsCtrIn[i+1], 4 * dExtraLen, nGrpTmp) EgtSurfTmCut( nTestSurf, nTrimSurf, true, false) end end -- calcolo intersezione con il solido : se c'è intersezione è una vera curva di trim, altrimenti non va considerata local nId, _, nCrvCnt = EgtSurfTmSurfTmInters( nMainSurf, nTestSurf, nGrpTmp) if nId and nCrvCnt > 0 then - table.insert( vRealTrimOutlines, vTestOutlines[i]) + table.insert( vTrimOutlines, vTestOutlines[i]) end end - return vRealTrimOutlines + return vTrimOutlines end --------------------------------------------------------------------- @@ -1261,70 +1322,49 @@ 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') + local vNextBaseOutlineId = EgtGetInfo( nSplitId, WIN_SPLIT_ENDINTERS, 'vi') + + -- ad ogni base outline dell'area di bordo che racchiude lo split associo l'outline non virtuale corrispondente ( per rendere più solidi i conti successivi) + local tabOutlines = {} + local nBaseOutlineLayerId = EgtGetParent( vPrevBaseOutlineId[1]) + local vBaseOutlineIds = EgtGetAllInGroup( nBaseOutlineLayerId) + for i = 1, #vBaseOutlineIds do + local nBaseOutline = vBaseOutlineIds[i] + local nAreaType = WIN_AREATYPES.SPLIT 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)) + local nAreaId = EgtGetParent( EgtGetParent( nBaseOutline)) nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i') end - vPrevOutlineId[i] = EgtGetInfo( nBaseOutline, WIN_COPY, 'i') + tabOutlines[vBaseOutlineIds[i]] = EgtGetInfo( nBaseOutline, WIN_COPY, 'i') + + -- verifico la coerenza dell'orientamento ( se la curva virtuale deriva da split) e la indico con il segno ( > 0 concorde, < 0 discorde e andrà invertita) + local nOutlineId = EgtGetInfo( vBaseOutlineIds[i], WIN_COPY, 'i') + local bInvert = EgtGetInfo( nOutlineId, WIN_INV_SPLIT, 'b') or false if bInvert then - vPrevOutlineId[i] = - vPrevOutlineId[i] + tabOutlines[vBaseOutlineIds[i]] = - tabOutlines[vBaseOutlineIds[i]] end - -- se split mixed il pezzo che incontra deve essere con cambio profilo - if bChangeProfile then + end + + -- controllo validità delle curve trovate ed eventuali vicine verificando l'interferenza tra i profili + local vPrevOutlineId = TestSplitTrimOutlines( nSplitId, vPrevBaseOutlineId, tabOutlines, nMainProfile, b3Profile, nGrpTmp, true) + EgtSetInfo( nSplitId, WIN_PREV_OUTLINES, vPrevOutlineId) + local vNextOutlineId = TestSplitTrimOutlines( nSplitId, vNextBaseOutlineId, tabOutlines, nMainProfile, b3Profile, nGrpTmp, false) + EgtSetInfo( nSplitId, WIN_NEXT_OUTLINES, vNextOutlineId) + + -- se split di tipo mixed il pezzo che incontra deve essere di tipo cambio profilo anche se ha una sola tipologia di figli + local bChangeProfile = EgtGetInfo( nSplitId, WIN_PRF_CHANGE, 'b') or false + if bChangeProfile then + for i = 1, #vPrevOutlineId do 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 + for i = 1, #vNextOutlineId do EgtSetInfo( vNextOutlineId[i], WIN_PRF_CHANGE, true) end end - EgtSetInfo( nSplitId, WIN_NEXT_OUTLINES, vNextOutlineId) - + EgtErase( nGrpTmp) end @@ -1446,7 +1486,7 @@ local function CalculateSplitOutline( nAreaId) for i = 1, #vAuxAreas do CalculateVirtualAreaOutline( vAuxAreas[i], dZMove) end - + -- sistemo gli outline degli split for i = 1, #vSplitIds do -- sistemo le info @@ -2119,27 +2159,19 @@ local function CheckSemiprofileIntersection( nGeoId, nPrevGeoId, nNextGeoId) local nSemiProfileId = EgtGetInfo( nGeoId, WIN_SEMI_PROFILE, 'i') local nProfileId = EgtGetParent( nSemiProfileId) local nFrameId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME) - local frFrame = EgtFR( nFrameId) - local b3Box = EgtGetBBoxRef( nSemiProfileId, GDB_BB.STANDARD, frFrame) + local frFrame = EgtFR( nFrameId, GDB_ID.ROOT) + local b3Box = EgtGetBBoxRef( nSemiProfileId, GDB_BB.STANDARD, frFrame, GDB_RT.GLOB) local nInnerCrv = EgtCopyGlob( nOutlineId, EgtGetParent( nGeoId)) EgtOffsetCurve( nInnerCrv, b3Box:getMin():getX()) -- verifico se con estensione standard ( ovvero seguendo la circonferenza associata) arriva alle curve vicine del geo local ptInt1 = FindIntersectionPoint( nInnerCrv, nPrevGeoId, ORIG()) - if ptInt1 then - EgtSetInfo( nGeoId, WIN_TANG_START, false) - else - EgtSetInfo( nGeoId, WIN_TANG_START, true) - end - + local bTangStart = ( not ptInt1) local ptInt2 = FindIntersectionPoint( nInnerCrv, nNextGeoId, ORIG()) - if ptInt2 then - EgtSetInfo( nGeoId, WIN_TANG_END, false) - else - EgtSetInfo( nGeoId, WIN_TANG_END, true) - end + local bTangEnd = ( not ptInt2) EgtErase( nInnerCrv) + return bTangStart, bTangEnd end --------------------------------------------------------------------- @@ -2154,40 +2186,36 @@ local function ComputeArcExtensions( nOutId, nInId, vLeftIds, vRightIds, nStartJ -- se il pezzo corrente è arco devo verificare estensione per in e out if EgtGetType( nOutId) == GDB_TY.CRV_ARC then - -- in : la curva più interna del semiprofilo associato è la curva in stessa - if nEndJoint == WIN_PART_JNT.ANGLED or not FindIntersectionPoint( nInId, vRightIds[#vRightIds], ORIG()) then - EgtSetInfo( nInId, WIN_TANG_START, true) - else - EgtSetInfo( nInId, WIN_TANG_START, false) - end - if nStartJoint == WIN_PART_JNT.ANGLED or not FindIntersectionPoint( nInId, vLeftIds[1], ORIG()) then - EgtSetInfo( nInId, WIN_TANG_END, true) - else - EgtSetInfo( nInId, WIN_TANG_END, false) + local bTangStart, bTangEnd = CheckSemiprofileIntersection( nOutId, vLeftIds[#vLeftIds], vRightIds[1]) + if not bTangStart then + -- verifico se necessaria estensione in tangenza per giunzione angled o per la curva in + bTangStart = ( nStartJoint == WIN_PART_JNT.ANGLED or not FindIntersectionPoint( nInId, vLeftIds[1], ORIG())) end + EgtSetInfo( nOutId, WIN_TANG_START, bTangStart) + EgtSetInfo( nInId, WIN_TANG_END, bTangStart) - -- out - CheckSemiprofileIntersection( nOutId, vLeftIds[#vLeftIds], vRightIds[1]) - if nStartJoint == WIN_PART_JNT.ANGLED then - EgtSetInfo( nOutId, WIN_TANG_START, true) + if not bTangEnd then + bTangEnd = ( nEndJoint == WIN_PART_JNT.ANGLED or not FindIntersectionPoint( nInId, vRightIds[#vRightIds], ORIG())) end - if nEndJoint == WIN_PART_JNT.ANGLED then - EgtSetInfo( nOutId, WIN_TANG_END, true) - end - + EgtSetInfo( nOutId, WIN_TANG_END, bTangEnd) + EgtSetInfo( nInId, WIN_TANG_START, bTangEnd) end -- verifico estensione left for i = 1, #vLeftIds do if EgtGetType( vLeftIds[i]) == GDB_TY.CRV_ARC then - CheckSemiprofileIntersection( vLeftIds[i], nInId, nOutId) + local bTangS, bTangE = CheckSemiprofileIntersection( vLeftIds[i], nInId, nOutId) + EgtSetInfo( vLeftIds[i], WIN_TANG_START, bTangS) + EgtSetInfo( vLeftIds[i], WIN_TANG_END, bTangE) end end -- verifico estensione right for i = 1, #vRightIds do if EgtGetType( vRightIds[i]) == GDB_TY.CRV_ARC then - CheckSemiprofileIntersection( vRightIds[i], nOutId, nInId) + local bTangS, bTangE = CheckSemiprofileIntersection( vRightIds[i], nOutId, nInId) + EgtSetInfo( vRightIds[i], WIN_TANG_START, bTangS) + EgtSetInfo( vRightIds[i], WIN_TANG_END, bTangE) end end end @@ -2776,26 +2804,208 @@ local function GetProcessingInfoFromSemiProfile( nCrv, nSemiProfile) end end +--------------------------------------------------------------------- +-- funzione che crea la lavorazione a partire dalla curva del geo +local function CreateProfilingProcessingCurve( vCrvs, nPrevCrv, nSurfGeo, nProcLayerId) + + -- recupero il semiprofilo associato al gruppo di curve + local nSemiProfileId = EgtGetInfo( vCrvs[1], WIN_SEMI_PROFILE, 'i') + local nCrvId + + -- se bisettrice + if not nSemiProfileId then + nCrvId = EgtCopyGlob( vCrvs[1], nProcLayerId) + + -- se lavorazioni di controprofilo + else + local nGrpTmp = EgtGroup( nProcLayerId) + + local dGeoOffs = EgtGetInfo( vCrvs[1], WIN_GEO_OFFS, 'd') + local nProfileId = EgtGetParent( nSemiProfileId) + local nFrameId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME) + local frFrame = EgtFR( nFrameId, GDB_ID.ROOT) + local b3SemiProfile = EgtGetBBoxRef( nSemiProfileId, GDB_BB.STANDARD, frFrame, GDB_RT.GLOB) + local dOffs = b3SemiProfile:getDimX() + + local vProcCrvs = {} + for i = 1, #vCrvs do + + -- la curva di lavorazione si basa sulla curva del geo + local nCrvId = EgtCopyGlob( vCrvs[i], nGrpTmp) + + -- calcolo la curva di lavorazione interna ( partendo dall'outline e non dal geo per essere coerente con la info di estensione) + local nRefOutlineId = EgtGetInfo( vCrvs[i], WIN_REF_OUTLINE, 'i') + local nOutlineId = EgtCopyGlob( abs( nRefOutlineId), nGrpTmp) + if nRefOutlineId < 0 then + EgtInvertCurve( nOutlineId) + end + local nOrigInnerProcId = EgtOffsetCurveAdv( nOutlineId, dGeoOffs - dOffs) + + -- adatto la curva di lavorazione interna al pezzo + CopyInfo( nOrigInnerProcId, vCrvs[1], WIN_TANG_START, false) + CopyInfo( nOrigInnerProcId, vCrvs[#vCrvs], WIN_TANG_END, false) + local nInnerProcId = CreateCurveExtension( nOrigInnerProcId, nGrpTmp) + local nInId, nCnt = EgtTrimCurveWithRegion( nInnerProcId, nSurfGeo, true, false) + + if not nInId then + nCnt = 0 + end + if nCnt > 0 then + if nCnt > 1 and AreSamePointApprox( EgtSP( nInId), EgtEP( nInId + nCnt - 1)) then + if EgtGetType( nInId) == GDB_TY.CRV_ARC then + EgtModifyCurveStartPoint( nInId, EgtSP( nInId + nCnt - 1)) + else + EgtAddCurveCompoCurve( nInId, nInId + nCnt - 1, true, false) + end + nCnt = nCnt - 1 + end + -- se ottengo più tratti considero quello che ha porzione in comune con la curva originale + if nCnt > 1 then + local vOverlapCrvs = {} + for nId = nInId, nInId + nCnt - 1 do + if CheckExtensionOverlap( nId, nOrigInnerProcId) then + table.insert( vOverlapCrvs, nId) + end + end + + if #vOverlapCrvs == 1 then + nInId = vOverlapCrvs[1] + else + -- se ottengo più tratti di overlap con il geo considero il più vicino al geo precedente + local nIdx = 1 + local dMinDist = GEO.INFINITO + local ptRef = EgtEP( nPrevCrv) + for i = 1, #vOverlapCrvs do + local dDist = dist( EgtSP( vOverlapCrvs[i]), ptRef) + if dDist < dMinDist then + dMinDist = dDist + nIdx = i + end + end + nInId = vOverlapCrvs[nIdx] + end + end + end + + -- la allineo alla curva di lavoro + EgtOffsetCurve( nInId, dOffs) + + local bExtra = EgtGetInfo( vCrvs[i], WIN_GEO_EXTRA, 'b') or false + if bExtra then + -- se curva extra la curva di lavorazione è la corrispondente di quella interna + nCrvId = nInId + else + -- la curva va modificata solo in allungamento + nCrvId = EgtCurveCompo( nProcLayerId, nCrvId) + AddExtension( nCrvId, nInId) + end + + -- se compo verifico se può diventare curva singola + if EgtGetType( nCrvId) == GDB_TY.CRV_COMPO then + EgtMergeCurvesInCurveCompo( nCrvId) + end + table.insert( vProcCrvs, nCrvId) + end + + -- combino le curve + if #vProcCrvs == 1 then + nCrvId = vProcCrvs[1] + EgtRelocateGlob( nCrvId, nProcLayerId) + + else + for i = 1, #vProcCrvs - 1 do + local ptInt = FindIntersectionPoint( vProcCrvs[i], vProcCrvs[i+1], EgtEP( vProcCrvs[i])) + local dPar1 = EgtCurveParamAtPoint( vProcCrvs[i], ptInt) + local dPar2 = EgtCurveParamAtPoint( vProcCrvs[i+1], ptInt) + if dPar1 then + EgtTrimCurveEndAtParam( vProcCrvs[i], dPar1) + else + EgtModifyCurveEndPoint( vProcCrvs[i], ptInt) + end + if dPar2 then + EgtTrimCurveStartAtParam( vProcCrvs[i+1], dPar2) + else + EgtModifyCurveStartPoint( vProcCrvs[i+1], ptInt) + end + end + nCrvId = EgtCurveCompo( nProcLayerId, vProcCrvs, true) + end + + EgtErase( nGrpTmp) + end + + -- sistemo la curva e setto le info + EgtModifyCurveThickness( nCrvId, 0) + EgtSetStatus( nCrvId, GDB_ST.ON) + EgtSetName( nCrvId, EgtGetName( vCrvs[1])) + GetProcessingInfoFromSemiProfile( nCrvId, nSemiProfileId) + for i = 1, #vCrvs do + EgtSetInfo( vCrvs[i], WIN_REF_PRC, nCrvId) + end +end + +--------------------------------------------------------------------- +-- funzione che calcola le lavorazioni di profilatura a partire dalle curve del geo +local function CreateProfilingProcessingFromGeo( nGeoLayerId, nSurfGeo, nProcLayerId) + -- out e in vengono gestite singolarmente, right e left vengono raggruppate in base al semiprofilo + + -- out + local nOut = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_OUT) + CreateProfilingProcessingCurve( { nOut}, nil, nSurfGeo, nProcLayerId) + + -- right + local vRight = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_RIGHT) + local vCurrRight = { vRight[1]} + local nSemiProfilePrev = EgtGetInfo( vRight[1], WIN_SEMI_PROFILE, 'i') + for i = 2, #vRight do + local nSemiProfileCurr = EgtGetInfo( vRight[i], WIN_SEMI_PROFILE, 'i') + if nSemiProfilePrev and nSemiProfileCurr and IsSameSemiProfile( nSemiProfilePrev, nSemiProfileCurr) then + -- se hanno lo stesso semiprofilo vanno gestite insieme + table.insert( vCurrRight, vRight[i]) + else + -- se hanno un diverso semiprofilo calcolo la lavorazione del gruppo associato al semiprofilo precedente e inizio a creare il gruppo del semiprofilo della curva corrente + CreateProfilingProcessingCurve( vCurrRight, nOut, nSurfGeo, nProcLayerId) + vCurrRight = { vRight[i]} + nSemiProfilePrev = nSemiProfileCurr + end + end + CreateProfilingProcessingCurve( vCurrRight, nOut, nSurfGeo, nProcLayerId) + + -- in + local nIn = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_IN) + CreateProfilingProcessingCurve( { nIn}, nil, nSurfGeo, nProcLayerId) + + -- left + local vLeft = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_LEFT) + local vCurrLeft = { vLeft[1]} + nSemiProfilePrev = EgtGetInfo( vLeft[1], WIN_SEMI_PROFILE, 'i') + for i = 2, #vLeft do + local nSemiProfileCurr = EgtGetInfo( vLeft[i], WIN_SEMI_PROFILE, 'i') + if nSemiProfilePrev and nSemiProfileCurr and IsSameSemiProfile( nSemiProfilePrev, nSemiProfileCurr) then + table.insert( vCurrLeft, vLeft[i]) + else + CreateProfilingProcessingCurve( vCurrLeft, nIn, nSurfGeo, nProcLayerId) + vCurrLeft = { vLeft[i]} + nSemiProfilePrev = nSemiProfileCurr + end + end + CreateProfilingProcessingCurve( vCurrLeft, nIn, nSurfGeo, nProcLayerId) + +end + --------------------------------------------------------------------- -- funzione che calcola le lavorazioni di profiling per un pezzo di telaio con cambio profilo local function CalcMixedFrameProfilingProcessings( nPartId, nProcLayerId, nGeoLayerId, nMainProfileId, nSurfGeoId) -- a) lavorazioni profili -- per le lavorazioni dei profili out, left, right e in comune si usano le corrispondenti curve del geo - local vGeoCrvs = EgtGetAllInGroup( nGeoLayerId) - for i = 1, #vGeoCrvs - 1 do - -- copio curva - local nCrv = EgtCopyGlob( vGeoCrvs[i], nProcLayerId) - EgtModifyCurveThickness( nCrv, 0) - -- recupero il semiprofilo associato - local nSemiProfile = EgtGetInfo( nCrv, WIN_SEMI_PROFILE, 'i') - GetProcessingInfoFromSemiProfile( nCrv, nSemiProfile) - end - - -- a) lavorazioni per i sottotratti sash e fill + local nGeoArea = EgtGetLastInGroup( nGeoLayerId) + CreateProfilingProcessingFromGeo( nGeoLayerId, nGeoArea, nProcLayerId) + + -- b) lavorazioni per i sottotratti sash e fill -- TO DO ( da capire bene soprattuto nei casi di cambio profilo che coinvolge pezzi distinti) - -- b) fresature + -- c) fresature local nMixedIntersGrp = EgtGetFirstNameInGroup( nPartId, WIN_MIXED_CURVES) local vMixedInters = EgtGetNameInGroup( nMixedIntersGrp, WIN_MIXED_MILLING .. '*') local dDepth1 = EgtGetInfo( nMainProfileId, WIN_SASH_DEPTH .. '1') @@ -2816,15 +3026,8 @@ end local function CalcMixedSplitProfilingProcessings( nSplitId, nProcLayerId, nGeoLayerId) -- a) lavorazione dei profili - local vGeoCrvs = EgtGetAllInGroup( nGeoLayerId) - for i = 1, #vGeoCrvs - 1 do - -- copio la curva - local nCrvId = EgtCopyGlob( vGeoCrvs[i], nProcLayerId) - EgtModifyCurveThickness( nCrvId, 0) - -- 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') - GetProcessingInfoFromSemiProfile( nCrvId, nSemiProfileId) - end + local nGeoArea = EgtGetLastInGroup( nGeoLayerId) + CreateProfilingProcessingFromGeo( nGeoLayerId, nGeoArea, nProcLayerId) -- b) fresature local nMixedIntersGrp = EgtGetFirstNameInGroup( EgtGetParent( nProcLayerId), WIN_MIXED_CURVES) @@ -2843,113 +3046,6 @@ local function CalcMixedSplitProfilingProcessings( nSplitId, nProcLayerId, nGeoL end ---------------------------------------------------------------------- --- funzione che crea la lavorazione a partire dalla curva del geo -local function CreateProfilingProcessingCurve( nGeoCrvId, nPrevGeo, nNextGeo, nSurfGeo, nProcLayerId) - - -- copio curva del geo - local nCrvId = EgtCopyGlob( nGeoCrvId, nProcLayerId) - EgtModifyCurveThickness( nCrvId, 0) - EgtSetStatus( nCrvId, GDB_ST.ON) - - -- recupero il semiprofilo associato - local nSemiProfileId = EgtGetInfo( nCrvId, WIN_SEMI_PROFILE, 'i') - - -- aggiusto la lunghezza per assicurarmi che la lavorazione sia completa - if nSemiProfileId and not ( AreSameVectorApprox( EgtSV( nCrvId), EgtEV( nPrevGeo)) and AreSameVectorApprox( EgtEV( nCrvId), EgtSV( nNextGeo))) then - - -- calcolo la curva di lavorazione interna : - -- dall'outline ricalcolo la curva del geo ( per essere allineati con l'info di estensione) - local nOutlineId = EgtGetInfo( nGeoCrvId, WIN_REF_OUTLINE, 'i') - local nOrigInnerProcId = EgtCopyGlob( abs( nOutlineId), nProcLayerId) - if nOutlineId < 0 then - EgtInvertCurve( nOrigInnerProcId) - end - local dGeoOffs = EgtGetInfo( nGeoCrvId, WIN_GEO_OFFS, 'd') - EgtOffsetCurve( nOrigInnerProcId, dGeoOffs) - -- ricavo l'offset per trovare la curva interna - local nProfileId = EgtGetParent( nSemiProfileId) - local nFrameId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME) - local frFrame = EgtFR( nFrameId, GDB_ID.ROOT) - local b3SemiProfile = EgtGetBBoxRef( nSemiProfileId, GDB_BB.STANDARD, frFrame, GDB_RT.GLOB) - local dOffs = b3SemiProfile:getDimX() - EgtOffsetCurve( nOrigInnerProcId, - dOffs) - - -- adatto la curva di lavorazione interna al pezzo - CopyInfo( nOrigInnerProcId, nGeoCrvId, WIN_TANG_START, false) - CopyInfo( nOrigInnerProcId, nGeoCrvId, WIN_TANG_END, false) - local nInnerProcId = CreateCurveExtension( nOrigInnerProcId, nProcLayerId) - local nNewId, nCnt = EgtTrimCurveWithRegion( nInnerProcId, nSurfGeo, true, false) - - if not nNewId then - nCnt = 0 - end - if nCnt > 0 then - if nCnt > 1 and AreSamePointApprox( EgtSP( nNewId), EgtEP( nNewId + nCnt - 1)) then - if EgtGetType( nNewId) == GDB_TY.CRV_ARC then - EgtModifyCurveStartPoint( nNewId, EgtSP( nNewId + nCnt - 1)) - EgtErase( nNewId + nCnt - 1) - else - EgtAddCurveCompoCurve( nNewId, nNewId + nCnt - 1, true, false) - end - nCnt = nCnt - 1 - end - -- se ottengo più tratti considero quello che ha porzione in comune con la curva del geo ( garantisce risultati migliori dell'outline perchè più limitata) - if nCnt > 1 then - local nTestOverlap = EgtCopyGlob( nGeoCrvId, nProcLayerId) - EgtOffsetCurve( nTestOverlap, - dOffs) - local bFound = false - for nId = nNewId, nNewId + nCnt - 1 do - if bFound then - EgtErase( nId) - elseif CheckExtensionOverlap( nId, nTestOverlap) then - nNewId = nId - bFound = true - else - EgtErase( nId) - end - end - EgtErase( nTestOverlap) - end - - -- la allineo alla curva di lavoro - EgtOffsetCurve( nNewId, dOffs) - - -- aggiusto la curva di lavoro - local bExtra = EgtGetInfo( nCrvId, WIN_GEO_EXTRA, 'b') or false - if bExtra then - -- se è una curva speciale del geo la curva di lavoro è la curva ottenuta dalla lavorazione interna - EgtErase( nCrvId) - nCrvId = nNewId - else - -- se è una curva standard non in tangenza con la vicina va modificata solo in allungamento - local nCompo = EgtCurveCompo( nProcLayerId, nCrvId) - local dParS = EgtCurveParamAtPoint( nCrvId, EgtSP( nNewId)) - if not dParS and not AreSameVectorApprox( EgtSV( nCompo), EgtEV( nPrevGeo)) then - local dParTrim = EgtCurveParamAtPoint( nNewId, EgtSP( nCompo)) - local nTrimCrv = EgtCopyGlob( nNewId, nProcLayerId) - EgtTrimCurveEndAtParam( nTrimCrv, dParTrim) - EgtAddCurveCompoCurve( nCompo, nTrimCrv, true, false) - end - local dParE = EgtCurveParamAtPoint( nCrvId, EgtEP( nNewId)) - if not dParE and not AreSameVectorApprox( EgtEV( nCrvId), EgtSV( nNextGeo)) then - local dParTrim = EgtCurveParamAtPoint( nNewId, EgtEP( nCompo)) - local nTrimCrv = EgtCopyGlob( nNewId, nProcLayerId) - EgtTrimCurveStartAtParam( nTrimCrv, dParTrim) - EgtAddCurveCompoCurve( nCompo, nTrimCrv) - end - EgtErase( nNewId) - nCrvId = nCompo - end - end - EgtErase( nOrigInnerProcId) - end - - -- setto le info dal semiprofilo - EgtSetName( nCrvId, EgtGetName( nGeoCrvId)) - GetProcessingInfoFromSemiProfile( nCrvId, nSemiProfileId) -end - --------------------------------------------------------------------- -- funzione che calcola le lavorazioni di profiling local function CalcProfilingProcessings( nPartId, nOutlineId) @@ -2985,11 +3081,7 @@ local function CalcProfilingProcessings( nPartId, nOutlineId) end else -- 2) caso standard : costruisco le curve di lavorazione a partire da quelle del geo - for i = 1, #vGeoCrvs - 1 do - local nPrevIdx = EgtIf( i == 1, #vGeoCrvs - 1, i - 1) - local nNextIdx = EgtIf( i == #vGeoCrvs - 1, 1, i + 1) - CreateProfilingProcessingCurve( vGeoCrvs[i], vGeoCrvs[nPrevIdx], vGeoCrvs[nNextIdx], nSurfGeo, nProcLayerId) - end + CreateProfilingProcessingFromGeo( nGeoLayerId, nSurfGeo, nProcLayerId) end -- calcolo eventuali lavorazioni per strip @@ -3119,31 +3211,59 @@ end ---------------------------------------------------------------------------------- ---------------------------------- SOLIDO ---------------------------------------- ---------------------------------------------------------------------------------- --- funzione che crea la superficie di trim per il solido -local function CreateTrimSurf( nGeoId, nOutlineId, dGeoWidth, nLayerId) +-- funzione che crea le superfici di trim e taglia il solido +local function TrimSolid( vGeoIds, dGeoWidth, nLayerId, nMainExtrusionId) - -- recupero profilo di riferimento dalla curva geo - local nOrigTrimProfileId = EgtGetInfo( nGeoId, WIN_SEMI_PROFILE, 'i') + local tabPrcCrv = {} + for i = 1, #vGeoIds do + + local nGuideId + local nTrimSurf - -- 1) minizinken - if not nOrigTrimProfileId then + -- recupero profilo di riferimento dalla curva geo + local nSemiProfileId = EgtGetInfo( vGeoIds[i], WIN_SEMI_PROFILE, 'i') - local nGuideId = EgtCopy( nGeoId, nLayerId) - EgtExtendCurveStartByLen( nGuideId, 4 * dGeoWidth) - EgtExtendCurveEndByLen( nGuideId, 4 * dGeoWidth) - EgtMove( nGuideId, Z_AX()) - local nTrimSurf = EgtSurfTmByExtrusion( nLayerId, nGuideId, - Z_AX() * dGeoWidth * 2, WIN_SURF_APPROX) - EgtInvertSurf( nTrimSurf) - EgtErase( nGuideId) - return nTrimSurf - - -- 2) controprofilo - else - -- recupero il controprofilo da estrudere - local sTrimProfileName = EgtGetName( nOrigTrimProfileId) - sTrimProfileName = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. WIN_OFST .. sTrimProfileName - -- calcolo la superficie di estrusione - return CreateProfileSurf( nOutlineId, EgtGetParent( nOrigTrimProfileId), sTrimProfileName, 10 * dGeoWidth, nLayerId) + -- 1) minizinken + if not nSemiProfileId then + nGuideId = EgtCurveCompo( nLayerId, vGeoIds[i], false) + EgtExtendCurveStartByLen( nGuideId, 5) + EgtExtendCurveEndByLen( nGuideId, 5) + EgtMove( nGuideId, Z_AX()) + nTrimSurf = EgtSurfTmByExtrusion( nLayerId, nGuideId, - Z_AX() * 2 * dGeoWidth, WIN_SURF_APPROX) + EgtInvertSurf( nTrimSurf) + + -- 2) controprofilo + else + -- recupero la curva di lavorazione associata e verifico se la sua superficie di trim è già stata calcolata ( una curva di lavorazione può essere associata + -- a più curve del geo) + local nPrcCrv = EgtGetInfo( vGeoIds[i], WIN_REF_PRC, 'i') or GDB_ID.NULL + if tabPrcCrv[nPrcCrv] then + -- se la superficie di trim è già stata creata salvo associazione nella curva geo + EgtSetInfo( vGeoIds[i], WIN_REF_SURF, tabPrcCrv[nPrcCrv]) + else + -- riposiziono la curva di lavorazione in corrispondenza dell'outline + local dOffs = EgtGetInfo( vGeoIds[i], WIN_GEO_OFFS, 'd') + nGuideId = EgtOffsetCurveAdv( nPrcCrv, - dOffs) + local nRefOutline = EgtGetInfo( vGeoIds[i], WIN_REF_OUTLINE, 'i') + if nRefOutline < 0 then + EgtInvertCurve( nGuideId) + end + -- recupero il controprofilo da estrudere + local sTrimProfileName = EgtGetName( nSemiProfileId) + sTrimProfileName = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. WIN_OFST .. sTrimProfileName + -- calcolo la superficie di estrusione + nTrimSurf = CreateProfileSurf( nGuideId, EgtGetParent( nSemiProfileId), sTrimProfileName, dGeoWidth, nLayerId) + tabPrcCrv[nPrcCrv] = nTrimSurf + end + end + + -- taglio il solido principale + if nTrimSurf then + EgtSetStatus( nTrimSurf, GDB_ST.OFF) + EgtSurfTmIntersect( nMainExtrusionId, nTrimSurf) + EgtErase( nGuideId) + EgtSetInfo( vGeoIds[i], WIN_REF_SURF, nTrimSurf) + end end end @@ -3161,40 +3281,36 @@ local function CalcSolidGuide( nOutlineId, nSolidLayerId, nProfileId) else nGuideId = EgtCurveCompo( nSolidLayerId, nOutlineId, false) - -- se tratto ad arco verifico l'allungamento minimo richiesto guardando la curva di lavorazione interna, che dovrebbe essere la più completa + -- se tratto ad arco verifico l'allungamento minimo richiesto guardando le curve di lavorazione in e out local nPartId = EgtGetParent( nSolidLayerId) local nProcLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PRC) + local nGeoLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO) + + -- in local nPrcIn = EgtGetFirstNameInGroup( nProcLayerId, WIN_GEO_IN) local nInId = EgtCopyGlob( nPrcIn, nSolidLayerId) EgtInvertCurve( nInId) -- riporto la curva di lavorazione allineata all'outline - local nGeoLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO) local nGeoIn = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_IN) local dOffsIn = EgtGetInfo( nGeoIn, WIN_GEO_OFFS, 'd') or 0 EgtOffsetCurve( nInId, dOffsIn) - - -- aggiungo tratti di estensione se necessari - local dParS = EgtCurveParamAtPoint( nGuideId, EgtSP( nInId), 100 * GEO.EPS_SMALL) - if not dParS then - local dParTrim = EgtCurveParamAtPoint( nInId, EgtSP( nGuideId), 100 * GEO.EPS_SMALL) - local nNewCrv = EgtCopyGlob( nInId, nSolidLayerId) - EgtTrimCurveEndAtParam( nNewCrv, dParTrim) - EgtAddCurveCompoCurve( nGuideId, nNewCrv, true, false) - end - local dParE = EgtCurveParamAtPoint( nGuideId, EgtEP( nInId), 100 * GEO.EPS_SMALL) - if not dParE then - local dParTrim = EgtCurveParamAtPoint( nInId, EgtEP( nGuideId), 100 * GEO.EPS_SMALL) - local nNewCrv = EgtCopyGlob( nInId, nSolidLayerId) - EgtTrimCurveStartAtParam( nNewCrv, dParTrim) - EgtAddCurveCompoCurve( nGuideId, nNewCrv) - end + AddExtension( nGuideId, nInId) + -- out + local nPrcOut = EgtGetFirstNameInGroup( nProcLayerId, WIN_GEO_OUT) + local nOutId = EgtCopyGlob( nPrcOut, nSolidLayerId) + local nGeoOut = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_OUT) + local dOffsOut = EgtGetInfo( nGeoOut, WIN_GEO_OFFS, 'd') or 0 + EgtOffsetCurve( nOutId, dOffsOut) + AddExtension( nGuideId, nOutId) + -- piccola estensione per avere un po' di margine dal minimo indispensabile appena calcolato EgtExtendCurveStartByLen( nGuideId, 5) EgtExtendCurveEndByLen( nGuideId, 5) EgtErase( nInId) + EgtErase( nOutId) end EgtSetName( nGuideId, WIN_MAINGUIDE) @@ -3277,20 +3393,12 @@ local function CalcMixedFrameSolid( nOutlineId, nSolidLayerId, nProfileLayerId, EgtSetStatus( nOrigMainExtrusionId, 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( nMainSolid, nTrimSurfStart) - EgtSetInfo( nPrevGeoId, WIN_REF_SURF, nTrimSurfStart) + local vPrevGeoIds = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_LEFT) + TrimSolid( vPrevGeoIds, dGeoWidth, nSolidLayerId, nMainSolid) -- c) TRIM END - local nNextGeoId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_RIGHT) - local nEndOutlineId = EgtGetInfo( nNextGeoId, WIN_REF_OUTLINE, 'i') - local nTrimSurfEnd = CreateTrimSurf( nNextGeoId, nEndOutlineId, dGeoWidth, nSolidLayerId) - EgtSetStatus( nTrimSurfEnd, GDB_ST.OFF) - EgtSurfTmIntersect( nMainSolid, nTrimSurfEnd) - EgtSetInfo( nNextGeoId, WIN_REF_SURF, nTrimSurfEnd) + local vNextGeoIds = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_RIGHT) + TrimSolid( vNextGeoIds, dGeoWidth, nSolidLayerId, nMainSolid) return nMainSolid end @@ -3402,26 +3510,6 @@ local function CalcMixedSplitSolid( nOutlineId, nSolidLayerId, nProfileLayerId, return nMainExtrusionId end ---------------------------------------------------------------------- --- funzione che verifica se due curve del geo sono concatenabili, ovvero se hanno lo stesso profilo e i corrispondenti outline coincidono o sono in tangenza -local function CheckChainability( nGeoCrv1, nGeoCrv2) - - -- verifico profili - local sProfile1 = EgtGetInfo( nGeoCrv1, WIN_PROFILETYPE) - local sProfile2 = EgtGetInfo( nGeoCrv2, WIN_PROFILETYPE) - local nSemiProfileId1 = EgtGetInfo( nGeoCrv1, WIN_SEMI_PROFILE, 'i') - local nSemiProfileId2 = EgtGetInfo( nGeoCrv2, WIN_SEMI_PROFILE, 'i') - if sProfile1 == sProfile2 and nSemiProfileId1 and nSemiProfileId2 and EgtGetName( nSemiProfileId1) == EgtGetName( nSemiProfileId2) then - -- verifico outlines - local nRefOutline1 = EgtGetInfo( nGeoCrv1, WIN_REF_OUTLINE, 'i') - local nRefOutline2 = EgtGetInfo( nGeoCrv2, WIN_REF_OUTLINE, 'i') - if nRefOutline1 == nRefOutline2 or AreSameVectorApprox( EgtEV( nRefOutline1), EgtSV( nRefOutline2)) then - return true - end - end - return false -end - --------------------------------------------------------------------- -- funzione che crea il solido del pezzo local function CalcSolid( nPartId, nOutlineId) @@ -3459,52 +3547,11 @@ local function CalcSolid( nPartId, nOutlineId) EgtSetStatus( nOrigMainExtrusionId, GDB_ST.OFF) -- b) trim con i controprofili su start e su end - local vGeoId = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_RIGHT) - local vPrevGeoId = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_LEFT) - EgtJoinTables( vGeoId, vPrevGeoId) - -- verifico quali curve di trim conviene concatenare per evitare booleane problematiche con tratti sovrapposti - local vChains = {{ vGeoId[1]}} - for i = 2, #vGeoId do - if CheckChainability( vGeoId[i-1], vGeoId[i]) then - -- aggiugno alla catena corrente - table.insert( vChains[#vChains], vGeoId[i]) - else - -- creo una nuova catena - table.insert( vChains, { vGeoId[i]}) - end - end - - -- calcolo le superfici di trim - for i = 1, #vChains do - local nTrimSurf - if #vChains[i] == 1 then - local nRefOutlineId = EgtGetInfo( vChains[i][1], WIN_REF_OUTLINE, 'i') or GDB_ID.NULL - nTrimSurf = CreateTrimSurf( vChains[i][1], abs( nRefOutlineId), dGeoWidth, nSolidLayerId) - -- assegno alla curva del geo la superficie di trim creata - EgtSetInfo( vChains[i][1], WIN_REF_SURF, nTrimSurf) - else - -- costruisco la guida a partire dagli outlines - local vRefOutlineIds = {} - for j = 1, #vChains[i] do - local nCurrOutline = EgtGetInfo( vChains[i][j], WIN_REF_OUTLINE, 'i') or GDB_ID.NULL - -- verifico di non inserire un outline doppio - if j == 1 or nCurrOutline ~= vRefOutlineIds[#vRefOutlineIds] then - table.insert( vRefOutlineIds, abs( nCurrOutline)) - end - end - local nGuideId = EgtCurveCompo( nSolidLayerId, vRefOutlineIds, false) - nTrimSurf = CreateTrimSurf( vChains[i][1], nGuideId, dGeoWidth, nSolidLayerId) - -- assegno ad ogni curva del geo la superficie di trim creata - for j = 1, #vChains[i] do - EgtSetInfo( vChains[i][j], WIN_REF_SURF, nTrimSurf) - end - EgtErase( nGuideId) - end - - EgtSetStatus( nTrimSurf, GDB_ST.OFF) - EgtSurfTmIntersect( nMainExtrusionId, nTrimSurf) - end - + local nGeoRight = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_RIGHT) + TrimSolid( nGeoRight, dGeoWidth, nSolidLayerId, nMainExtrusionId) + local nGeoLeft = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_LEFT) + TrimSolid( nGeoLeft, dGeoWidth, nSolidLayerId, nMainExtrusionId) + return nMainExtrusionId end