From a79836db69e3910a0732b6f47ce7894cf6b55dd1 Mon Sep 17 00:00:00 2001 From: SaraP Date: Mon, 17 Nov 2025 15:49:47 +0100 Subject: [PATCH] DataWindow : - estensione in tangenza per pezzi ad arco nel caso di giunzioni problematiche. --- Designing/WinConst.lua | 3 + Designing/WinLib/WinCalculate.lua | 992 +++++++++++++++++++----------- 2 files changed, 647 insertions(+), 348 deletions(-) diff --git a/Designing/WinConst.lua b/Designing/WinConst.lua index 6ebd013..918fedb 100644 --- a/Designing/WinConst.lua +++ b/Designing/WinConst.lua @@ -372,6 +372,9 @@ WIN_GLASS_RECT = 'GlassRectangle' WIN_GEO_SURF = 'GeoRegion' WIN_GEO_EXTRA = 'GeoExtra' WIN_REF_GEO = 'GeoRef' +WIN_GEO_OFFS = 'GeoOffs' +WIN_TANG_START = 'ExtendTangStart' +WIN_TANG_END = 'ExtendTangEnd' -- CAMBIO PROFILO diff --git a/Designing/WinLib/WinCalculate.lua b/Designing/WinLib/WinCalculate.lua index 71223bf..1436ceb 100644 --- a/Designing/WinLib/WinCalculate.lua +++ b/Designing/WinLib/WinCalculate.lua @@ -93,7 +93,7 @@ local function FindIntersectionPoint( nCrv1, nCrv2, ptRef) -- caso arco-arco : cerco intersezione tra le due circonferenze nCrvA = EgtCircle( nGrp, EgtCP( nCrv1), EgtArcRadius( nCrv1)) nCrvB = EgtCircle( nGrp, EgtCP( nCrv2), EgtArcRadius( nCrv2)) - + else -- caso arco-linea : cerco intersezione fra la linea e la circonferenza local nArc = EgtIf( EgtGetType( nCrv1) == GDB_TY.CRV_ARC, nCrv1, nCrv2) @@ -111,18 +111,133 @@ local function FindIntersectionPoint( nCrv1, nCrv2, ptRef) return ptInt end +--------------------------------------------------------------------- +-- funzione che controlla se vi è overlap tra nOrigId e una porzione della sua estensione ( nCrvId) +local function CheckExtensionOverlap( nCrvId, nOrigId) + + local dParS = EgtCurveParamAtPoint( nOrigId, EgtSP( nCrvId)) + local dParE = EgtCurveParamAtPoint( nOrigId, EgtEP( nCrvId)) + if not dParS and not dParE then + -- se il nuovo tratto non poggia sull'originale, verifico se è l'originale a poggiare sul nuovo + local dPar1 = EgtCurveParamAtPoint( nCrvId, EgtSP( nOrigId)) + local dPar2 = EgtCurveParamAtPoint( nCrvId, EgtEP( nOrigId)) + if dPar1 or dPar2 then + return true + end + elseif dParS and abs( dParS - 1) > GEO.EPS_SMALL then + return true + elseif dParE and dParE > GEO.EPS_SMALL then + return true + end + return false +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 + local dExtraLen = 10000 + local nExtId + + if EgtGetType( nCrvId) == GDB_TY.CRV_LINE then + -- estensione immediata + nExtId = EgtCopyGlob( nCrvId, nGrpId) + EgtExtendCurveStartByLen( nExtId, dExtraLen) + EgtExtendCurveEndByLen( nExtId, dExtraLen) + + elseif EgtGetType( nCrvId) == GDB_TY.CRV_ARC then + -- il risultato sarà una circonferenza ( se start ed end non vanno estesi in tangenza) oppure una composita ( se uno degli estremi va esteso in tangenza) + + if not bTangStart and not bTangEnd then + -- se estensione standard su entrambi gli estremi trasformo arco in circonferenza + nExtId = EgtCopyGlob( nCrvId, nGrpId) + local dAngOld = EgtArcAngCenter( nCrvId) + EgtModifyArcAngCenter( nExtId, EgtIf( dAngOld > 0, 360, -360)) + + elseif bTangStart and bTangEnd then + 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) + local dAngOld = EgtArcAngCenter( nCrvId) + 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) + EgtInvertCurve( nExtArcId) + local dAngOld = EgtArcAngCenter( nExtArcId) + EgtModifyArcAngCenter( nExtArcId, EgtIf( dAngOld > 0, 340, -340)) + EgtInvertCurve( nExtArcId) + nExtId = EgtCurveCompo( nGrpId, nExtArcId) + EgtAddCurveCompoLineTg( nExtId, dExtraLen) + EgtCurveCompoSetTempProp( nExtId, 1, nCrvId) + 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) + EgtCurveCompoSetTempProp( nExtId, 0, nCrvId) + 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 + EgtExtendCurveStartByLen( nExtId, dExtraLen) + end + -- end + local _, dEnd = EgtCurveDomain( nExtId) + 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) + 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 + + return nExtId +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) - + local nSurfId -- gruppo temporaneo per i conti local nGrpTmp = EgtGroup( nGrp) EgtSetStatus( nGrpTmp, GDB_ST.OFF) - - -- costruisco le regioni definite dai semipiani delle linee che compongono il contorno e - -- costruisco le circonferenze associate agli archi verificando non ve ne siano di coincidenti + + -- costruisco le regioni definite dai semipiani delle linee che compongono il contorno e calcolo le estensioni per gli archi ( verificando di non avere circonferenze coincidenti) + -- e le composite ( che vanno gestite come gli archi) local dExtraLen = 10000 local vSemiPlaneSurfs = {} local tArcs = {} @@ -136,25 +251,40 @@ local function CalcIntersectionRegion( vCrvs, nGrp) EgtTransform( nSemiPlaneId, frRect) table.insert( vSemiPlaneSurfs, nSemiPlaneId) - else - -- creo circonferenza corrispondente - local nCircleId = EgtCopyGlob( vCrvs[i], nGrpTmp) - local dAngOld = EgtArcAngCenter( vCrvs[i]) - EgtModifyArcAngCenter( nCircleId, EgtIf( dAngOld > 0, 360, -360)) - -- verifico se coincide con altra circonferenza già costruita - local dRad = EgtArcRadius( nCircleId) - local ptC = EgtCP( nCircleId) - local bOverlap = false - for j = 1, #tArcs do - if AreSamePointApprox( tArcs[j].ptC, ptC) and abs( tArcs[j].dRad - dRad) < GEO.EPS_SMALL then - bOverlap = true - table.insert( tArcs[j].nArcId, vCrvs[i]) - break + elseif EgtGetType( vCrvs[i]) == GDB_TY.CRV_ARC then + local dRad = EgtArcRadius( vCrvs[i]) + + -- se circonferenza verifico di non averla già considerata + local bTangentStart = EgtGetInfo( vCrvs[i], WIN_TANG_START, 'b') or false + local bTangentEnd = EgtGetInfo( vCrvs[i], WIN_TANG_END, 'b') or false + if not bTangentStart and not bTangentEnd then + local ptC = EgtCP( vCrvs[i]) + local bOverlap = false + for j = 1, #tArcs do + if tArcs[j].ptC and AreSamePointApprox( tArcs[j].ptC, ptC) and abs( tArcs[j].dRad - dRad) < GEO.EPS_SMALL then + bOverlap = true + table.insert( tArcs[j].vOrigId, vCrvs[i]) + break + end end + if not bOverlap then + local nCrvId = CreateCurveExtension( vCrvs[i], nGrpTmp) + table.insert( tArcs, { nCrvId = nCrvId, vOrigId = { vCrvs[i]}, dRad = dRad, ptC = ptC}) + end + else + local nCrvId = CreateCurveExtension( vCrvs[i], nGrpTmp) + table.insert( tArcs, { nCrvId = nCrvId, vOrigId = { vCrvs[i]}, dRad = dRad}) end - if not bOverlap then - table.insert( tArcs, { nCircleId = nCircleId, nArcId = {vCrvs[i]}, dRad = dRad, ptC = ptC}) + else + -- se composita deve contenere un arco, recupero il suo raggio + local _, dEnd = EgtCurveDomain( vCrvs[i]) + local dRad + for j = 0, dEnd - 1 do + dRad = EgtCurveCompoRadius( vCrvs[i], j) + if dRad > 0 then break end end + local nCrvId = CreateCurveExtension( vCrvs[i], nGrpTmp) + table.insert( tArcs, { nCrvId = nCrvId, vOrigId = { vCrvs[i]}, dRad = dRad}) end end @@ -170,25 +300,31 @@ local function CalcIntersectionRegion( vCrvs, nGrp) local nCrvBorder = EgtExtractSurfFrChunkLoops( nSurfId, 0, nGrpTmp) - -- riordino circonferenze per raggio decrescente ( per gestire prima quelle più grandi che potrebbero contenere le altre) + -- riordino per raggio decrescente ( per gestire prima quelle più grandi che potrebbero contenere le altre) table.sort( tArcs, function ( a, b) return a.dRad > b.dRad end) for i = 1, #tArcs do - local nCircleId = tArcs[i].nCircleId - -- limito la circonferenza alla regione + -- limito la curva estesa alla regione local nSurfTrim = EgtSurfFlatRegion( nGrpTmp, nCrvBorder) - local nCrv, nCnt = EgtTrimCurveWithRegion( nCircleId, nSurfTrim, true, false) - + local nCrv, nCnt = EgtTrimCurveWithRegion( tArcs[i].nCrvId, nSurfTrim, true, false) + -- se errore lo ignoro if not nCrv then - -- è errore, lo ignoro nCnt = 0 end if nCnt > 0 then -- unisco tratto iniziale e finale se consecutivi if nCnt > 1 and AreSamePointApprox( EgtSP( nCrv), EgtEP( nCrv + nCnt - 1)) then - EgtModifyCurveStartPoint( nCrv, EgtSP( nCrv + nCnt - 1)) - EgtErase( nCrv + nCnt - 1) + if EgtGetType( nCrv) == GDB_TY.CRV_ARC then + 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 @@ -210,40 +346,17 @@ local function CalcIntersectionRegion( vCrvs, nGrp) end end - -- considero solo i tratti che poggiano sulle curve orginali + -- modifico il bordo corrente considerando solo i tratti che poggiano sulle curve orginali for j = 1, #vArcs do - - local bOk = false - for k = 1, #tArcs[i].nArcId do - local nOrigArc = tArcs[i].nArcId[k] - local dParS = EgtCurveParamAtPoint( nOrigArc, EgtSP( vArcs[j])) - local dParE = EgtCurveParamAtPoint( nOrigArc, EgtEP( vArcs[j])) - if not dParS and not dParE then - -- se il nuovo tratto non poggia sull'originale, verifico se è l'originale a poggiare sul nuovo - local dPar1 = EgtCurveParamAtPoint( vArcs[j], EgtSP( nOrigArc)) - local dPar2 = EgtCurveParamAtPoint( vArcs[j], EgtEP( nOrigArc)) - if dPar1 or dPar2 then - bOk = true - break - end - elseif dParS and abs( dParS - 1) > GEO.EPS_SMALL then - bOk = true - break - elseif dParE and dParE > GEO.EPS_SMALL then - bOk = true + for k = 1, #tArcs[i].vOrigId do + if CheckExtensionOverlap( vArcs[j], tArcs[i].vOrigId[k]) then + local dParS = EgtCurveParamAtPoint( nCrvBorder, EgtSP( vArcs[j]), 100 * GEO.EPS_SMALL) + local dParE = EgtCurveParamAtPoint( nCrvBorder, EgtEP( vArcs[j]), 100 * GEO.EPS_SMALL) + EgtTrimCurveStartEndAtParam( nCrvBorder, dParE, dParS) + EgtAddCurveCompoCurve( nCrvBorder, vArcs[j]) break end end - - if not bOk then - EgtErase( vArcs[j]) - else - -- modifico il bordo con il nuovo tratto - local dParS = EgtCurveParamAtPoint( nCrvBorder, EgtSP( vArcs[j]), 100 * GEO.EPS_SMALL) - local dParE = EgtCurveParamAtPoint( nCrvBorder, EgtEP( vArcs[j]), 100 * GEO.EPS_SMALL) - EgtTrimCurveStartEndAtParam( nCrvBorder, dParE, dParS) - EgtAddCurveCompoCurve( nCrvBorder, vArcs[j]) - end end end end @@ -256,9 +369,9 @@ local function CalcIntersectionRegion( vCrvs, nGrp) EgtErase( nGrpTmp) return nSurfId end - + --------------------------------------------------------------------- --- Gestione delle curve superflue in TrimOrderedCurves : le modalità di trattamento sono indicate da nMode e sono le seguenti +-- Gestione delle curve superflue in TrimOrderedCurves : le modalità di trattamento sono indicate da nMode e sono le seguenti -- 0/nil = curva eliminata ( caso standard) -- 1 = curva eliminata rimuovendo la corrispondenza dalle info della curva di base outline da cui deriva ( se chiamata da outline) -- 2 = curva non viene eliminata ma viene settata info che indica di ignorarla ( se chiamata dal geo) @@ -275,23 +388,9 @@ local function AdjustExtraCurvesForTrim( nCrvId, nSurfId, nMode) EgtErase( nCrvId) elseif nMode == 2 then - -- se la curva è fuori dalla regione non va eliminata ma viene settata info che indica di ignorarla. Se è on o in allora il suo contributo è lo stesso di un'altra - -- curva di bordo quindi può essere eliminata - local nTestCrv = EgtCopyGlob( nCrvId, EgtGetParent( nSurfId)) - local nTmp, nCnt = EgtTrimCurveWithRegion( nTestCrv, nSurfId, true, true) - if nCnt > 0 then - -- elimino il profilo corrispondente solo se non è curva in o out ( per non eliminare il profilo principale) - local nSemiProfileId = EgtGetInfo( nCrvId, WIN_SEMI_PROFILE, 'i') - local nProfileId = EgtGetParent( nSemiProfileId) - if EgtGetName( nProfileId) ~= WIN_PRF_MAIN then - EgtErase( nProfileId) - end - -- elimino la curva - EgtErase( nCrvId) - else - EgtSetInfo( nCrvId, WIN_GEO_EXTRA, true) - EgtSetStatus( nCrvId, GDB_ST.OFF) - end + -- se la curva è fuori dalla regione non va eliminata ma viene settata info che indica di ignorarla + EgtSetInfo( nCrvId, WIN_GEO_EXTRA, true) + EgtSetStatus( nCrvId, GDB_ST.OFF) end end @@ -299,92 +398,120 @@ end -- funzione che data una lista di curve ordinate e orientate le estende o le taglia per creare una curva chiusa local function TrimOrderedCurves( vCrvs, nExtraCurvesMode) - -- costruisco la regione definita dalle curve - local nGrpTmp = EgtGroup( GDB_ID.ROOT) - EgtSetStatus( nGrpTmp, GDB_ST.OFF) - local nSurfId = CalcIntersectionRegion( vCrvs, nGrpTmp) + -- costruisco la regione definita dalle curve + local nGrpTmp = EgtGroup( GDB_ID.ROOT) + EgtSetStatus( nGrpTmp, GDB_ST.OFF) + local nSurfId = CalcIntersectionRegion( vCrvs, nGrpTmp) - -- copia estesa delle curve - local dExtraLen = 10000 - local vCopies = {} - for i = 1, #vCrvs do - vCopies[i] = EgtCopyGlob( vCrvs[i], nGrpTmp) - if EgtGetType( vCrvs[i]) == GDB_TY.CRV_LINE then - -- se linea allungo le estremità - EgtExtendCurveStartByLen( vCopies[i], dExtraLen) - EgtExtendCurveEndByLen( vCopies[i], dExtraLen) - else - -- se arco lo trasformo in una circonferenza - local dAngOld = EgtArcAngCenter( vCrvs[i]) - EgtModifyArcAngCenter( vCopies[i], EgtIf( dAngOld > 0, 360, -360)) - end - end + -- copia estesa delle curve per verificare gli overlaps + local vExtCrvs = {} + for i = 1, #vCrvs do + vExtCrvs[i] = CreateCurveExtension( vCrvs[i], nGrpTmp) + end - -- recupero le curve di bordo della regione - local nBorderId = EgtExtractSurfFrChunkLoops( nSurfId, 0, nGrpTmp) - local nCrvBorder, nCnt = EgtExplodeCurveCompo( nBorderId) - - -- individuo una curva di vCrvs e un tratto di nCrvBorder in corrispondenza biunivoca per gestire correttamente il ciclo - -- ( possono esserci curve di vCrvs senza corrispondente o con più corrispondenti tra le curve di bordo) - local nFirstIdxCrv = 1 - local nFirstIdxBorder = 1 - for i = 1, #vCrvs do - local vCrvBorderRef = {} - for nId = nCrvBorder, nCrvBorder + nCnt - 1 do - local dDist = EgtPointCurveDist( EgtMP( nId), vCopies[i]) - if dDist < GEO.EPS_SMALL then - table.insert( vCrvBorderRef, nId) - end - end - if #vCrvBorderRef == 1 then - -- preparo indici in modo che siano 0-based - nFirstIdxCrv = i - 1 - nFirstIdxBorder = vCrvBorderRef[1] - nCrvBorder - break - end - end + -- 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 + -- per gestire correttamente associazione devo partire da una curva di vCrvs e un tratto di nCrvBorder in corrispondenza biunivoca + -- ( possono esserci curve di vCrvs senza corrispondente o con più corrispondenti tra le curve di bordo) + local nFirstIdxCrv = 1 + local nFirstIdxBorder = 1 + for i = 1, #vCrvs do + local vCrvBorderRef = {} + for nId = nCrvBorder, nCrvBorder + nCnt - 1 do + local dDist = EgtPointCurveDist( EgtMP( nId), vExtCrvs[i]) + if dDist < GEO.EPS_SMALL then + table.insert( vCrvBorderRef, nId) + end + end + if #vCrvBorderRef == 1 then + -- preparo indici in modo che siano 0-based + nFirstIdxCrv = i - 1 + nFirstIdxBorder = vCrvBorderRef[1] - nCrvBorder + break + end + end - local vResultCurves = {} - local nC = nFirstIdxCrv - local nB = nFirstIdxBorder - repeat - -- se ho terminato le curve di bordo da associare devo cancellare tutte le curve rimaste - if nB == nFirstIdxBorder and nC ~= nFirstIdxCrv then - AdjustExtraCurvesForTrim( vCrvs[nC+1], nSurfId, nExtraCurvesMode) - - else - local dDist = EgtPointCurveDist( EgtMP( nCrvBorder + nB), vCopies[nC+1]) - -- se trovo corrispondenza - if dDist < GEO.EPS_SMALL then - -- assegno il nome - local sName = EgtGetName( vCrvs[nC+1]) - if sName then - EgtSetName( nCrvBorder + nB, sName) - end - -- copio le info - local vInfo = EgtGetAllInfo( vCrvs[nC+1]) - for j = 1, #vInfo do - local sInfo = EgtSplitString( vInfo[j], '=') - EgtSetInfo( nCrvBorder + nB, sInfo[1], sInfo[2]) - end - -- riposiziono - EgtRelocateGlob( nCrvBorder + nB, vCrvs[nC+1], GDB_IN.AFTER) - -- modifico l'id sostutuendolo alla curva originale - EgtErase( vCrvs[nC+1]) - EgtChangeId( nCrvBorder + nB, vCrvs[nC+1]) - - table.insert( vResultCurves, vCrvs[nC+1]) - -- passo alla curva di bordo successiva - nB = ( nB + 1) % nCnt - else - -- la curva non appartiene al bordo, quindi va gestita opportunamente - AdjustExtraCurvesForTrim( vCrvs[nC+1], nSurfId, nExtraCurvesMode) - end - end - - -- passo alla curva successiva - nC = ( nC + 1) % #vCrvs - until nC == nFirstIdxCrv + -- creo tabella di corrispondenze vCrvs -> CrvBorder + local tabAss = {} + 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 + nC = ( nC + 1) % #vCrvs + end + + -- aggiungo associazione + if tabAss[nOrigCrv] then + table.insert( tabAss[nOrigCrv], nCrvBorder + nB) + else + tabAss[nOrigCrv] = { nCrvBorder + nB} + end + + -- passo alla curva di bordo successiva + nB = ( nB + 1) % nCnt + + until nB == nFirstIdxBorder + + -- sostituisco le curve originali con quelle di bordo appena calcolate + local vResultCurves = {} + for i = 1, #vCrvs do + + if not tabAss[vCrvs[i]] then + -- se non ha curve di bordo associate è extra curve da gestire in modo speciale + AdjustExtraCurvesForTrim( vCrvs[i], nSurfId, nExtraCurvesMode) + + else + local nCrvId + if #tabAss[vCrvs[i]] > 1 then + -- se ha associata più di una curva di bordo creo la compo corrispondente + nCrvId = EgtCurveCompo( nGrpTmp, tabAss[vCrvs[i]]) + else + nCrvId = tabAss[vCrvs[i]][1] + end + + -- assegno il nome + local sName = EgtGetName( vCrvs[i]) + if sName then + EgtSetName( nCrvId, sName) + end + -- copio le info + local vInfo = EgtGetAllInfo( vCrvs[i]) + for j = 1, #vInfo do + local sInfo = EgtSplitString( vInfo[j], '=') + EgtSetInfo( nCrvId, sInfo[1], sInfo[2]) + end + -- riposiziono + EgtRelocateGlob( nCrvId, vCrvs[i], GDB_IN.AFTER) + -- modifico l'id assegnando quello della curva originale che sostituisce + EgtErase( vCrvs[i]) + EgtChangeId( nCrvId, vCrvs[i]) + + table.insert( vResultCurves, vCrvs[i]) + end + end EgtErase( nGrpTmp) return vResultCurves @@ -1209,7 +1336,7 @@ local function CalculateOutlineFromAreaOutline( nAreaId) end - -- SPLIT + -- SPLIT / NULL elseif nAreaType == WIN_AREATYPES.SPLIT or nAreaType == WIN_AREATYPES.NULL then -- a) outline dell'area @@ -1769,6 +1896,79 @@ local function GetDeltaProfile( nProfileId, sCtrIn) return dCPDelta end +--------------------------------------------------------------------- +local function CheckSemiprofileIntersection( nGeoId, nProfileId, nPrevGeoId, nNextGeoId) + + local nOutlineId = EgtGetInfo( nGeoId, WIN_REF_OUTLINE, 'i') + + -- recupero la curva più interna del semiprofilo + local nSemiProfileId = EgtGetInfo( nGeoId, WIN_SEMI_PROFILE, 'i') + local nFrameId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME) + local frFrame = EgtFR( nFrameId) + local b3Box = EgtGetBBoxRef( nSemiProfileId, GDB_BB.STANDARD, frFrame) + 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 ptInt2 = FindIntersectionPoint( nInnerCrv, nNextGeoId, ORIG()) + if ptInt2 then + EgtSetInfo( nGeoId, WIN_TANG_END, false) + else + EgtSetInfo( nGeoId, WIN_TANG_END, true) + end + + EgtErase( nInnerCrv) +end + +--------------------------------------------------------------------- +-- funzione che stabilisce il tipo di estensione ( standard seguendo la circonferenza o lineare in tangenza) per curve del geo ad arco in base a condizioni euristiche per evitare giunzioni +-- problematiche +local function ComputeArcExtensions( nOutId, nInId, nCurrProfileId, vLeftIds, vLeftProfileIds, vRightIds, vRightProfileIds) + + -- controllo euristico : verifico se la parte più interna del semiprofilo associato alla curva del geo ( ovvero considero tra i due archi che limitano il semiprofilo quello + -- con raggio minore perchè dovrebbe essere il più problematico) arriva alla curva di geo vicina con estensione standard oppure no + + -- 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 FindIntersectionPoint( nInId, vRightIds[#vRightIds], ORIG()) then + EgtSetInfo( nInId, WIN_TANG_START, false) + else + EgtSetInfo( nInId, WIN_TANG_START, true) + end + if FindIntersectionPoint( nInId, vLeftIds[1], ORIG()) then + EgtSetInfo( nInId, WIN_TANG_END, false) + else + EgtSetInfo( nInId, WIN_TANG_END, true) + end + + -- out + CheckSemiprofileIntersection( nOutId, nCurrProfileId, vLeftIds[#vLeftIds], vRightIds[1]) + end + + -- verifico estensione left + for i = 1, #vLeftIds do + if EgtGetType( vLeftIds[i]) == GDB_TY.CRV_ARC then + CheckSemiprofileIntersection( vLeftIds[i], vLeftProfileIds[i], nInId, nOutId) + end + end + + -- verifico estensione right + for i = 1, #vRightIds do + if EgtGetType( vRightIds[i]) == GDB_TY.CRV_ARC then + CheckSemiprofileIntersection( vRightIds[i], vRightProfileIds[i], nOutId, nInId) + end + end +end + --------------------------------------------------------------------- -- funzione che crea le curve del geo local function CreateFrameGeo( nOutlineId, vPrevOutlineId, vNextOutlineId, nStartPartJointType, nEndPartJointType, nGeoLayerId, nProfileLayerId) @@ -1792,6 +1992,7 @@ local function CreateFrameGeo( nOutlineId, vPrevOutlineId, vNextOutlineId, nStar local nSemiProfileOut = EgtGetFirstNameInGroup( nCurrProfileId, WIN_OUT) or EgtGetFirstNameInGroup( nCurrProfileId, WIN_IN .. '1') EgtSetInfo( nOutId, WIN_SEMI_PROFILE, nSemiProfileOut) EgtSetInfo( nOutId, WIN_REF_OUTLINE, nOutlineId) + EgtSetInfo( nOutId, WIN_GEO_OFFS, dCurrOffset) -- curva in local nInId = EgtCopy( nOutlineId, nGeoLayerId) @@ -1801,6 +2002,7 @@ local function CreateFrameGeo( nOutlineId, vPrevOutlineId, vNextOutlineId, nStar local nSemiProfileIn = EgtGetFirstNameInGroup( nCurrProfileId, WIN_IN) or EgtGetFirstNameInGroup( nCurrProfileId, WIN_IN .. '2') or EgtGetFirstNameInGroup( nCurrProfileId, WIN_MIXED_COMMON .. WIN_IN) 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) @@ -1821,15 +2023,19 @@ local function CreateFrameGeo( nOutlineId, vPrevOutlineId, vNextOutlineId, nStar if vPrevOutlineId[i] < 0 then EgtInvertCurve( nPrevCurveId) end + local dOffs if nStartPartJointType == WIN_PART_JNT.SHORT then local sCtrIn = GetProfileCtrIn( abs( vPrevOutlineId[i]), nOutlineId, vPrevProfileId[i]) local dCPDelta = GetDeltaProfile( vPrevProfileId[i], sCtrIn) - EgtOffsetCurve( nPrevCurveId, - dCPDelta) - -- ricavo il semiprofilo associato + dOffs = - dCPDelta nPrevSemiProfile = EgtGetFirstNameInGroup( vPrevProfileId[i], sCtrIn) else + local b3Profile = GetProfileLocalBox( vPrevProfileId[i]) + dOffs = b3Profile:getMax():getX() nPrevSemiProfile = EgtGetFirstNameInGroup( vPrevProfileId[i], WIN_OUT) end + EgtOffsetCurve( nPrevCurveId, dOffs) + EgtSetInfo( nPrevCurveId, WIN_GEO_OFFS, dOffs) end EgtSetName( nPrevCurveId, WIN_GEO_LEFT) EgtSetInfo( nPrevCurveId, WIN_SEMI_PROFILE, nPrevSemiProfile) @@ -1855,22 +2061,32 @@ local function CreateFrameGeo( nOutlineId, vPrevOutlineId, vNextOutlineId, nStar if vNextOutlineId[i] < 0 then EgtInvertCurve( nNextCurveId) end + local dOffs if nEndPartJointType == WIN_PART_JNT.SHORT then local sCtrIn = GetProfileCtrIn( abs( vNextOutlineId[i]), nOutlineId, vNextProfileId[i]) local dCPDelta = GetDeltaProfile( vNextProfileId[i], sCtrIn) - EgtOffsetCurve( nNextCurveId, - dCPDelta) + dOffs = - dCPDelta -- ricavo il semiprofilo associato nNextSemiProfile = EgtGetFirstNameInGroup( vNextProfileId[i], sCtrIn) else + local b3Profile = GetProfileLocalBox( vNextProfileId[i]) + dOffs = b3Profile:getMax():getX() nNextSemiProfile = EgtGetFirstNameInGroup( vNextProfileId[i], WIN_OUT) end + EgtOffsetCurve( nNextCurveId, dOffs) + EgtSetInfo( nNextCurveId, WIN_GEO_OFFS, dOffs) end EgtSetName( nNextCurveId, WIN_GEO_RIGHT) EgtSetInfo( nNextCurveId, WIN_SEMI_PROFILE, nNextSemiProfile) EgtSetInfo( nNextCurveId, WIN_REF_OUTLINE, vNextOutlineId[i]) EgtRelocateGlob( nNextCurveId, nInId, GDB_IN.BEFORE) end - + + -- 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, nCurrProfileId, vLeftIds, vPrevProfileId, vRightIds, vNextProfileId) + -- trim delle curve local vIds = EgtGetAllInGroup( nGeoLayerId) local vMainCrvs = TrimOrderedCurves( vIds, 2) @@ -1949,11 +2165,11 @@ local function CalcFrameGeo( nPartId, nOutlineId, nOutlineCrvNbr, nOutlineLayerI nEndJointType = vJoints[1] end - -- se giunzione diversa da bisettrice e arco a tutto sesto oppure elementi entrambi dello stesso tipo, forzo il tipo a bisettrice - if nStartJointType ~= WIN_JNT.ANGLED and ( AreSameVectorApprox( EgtEV( abs( vPrevOutlineId[1])), EgtSV( nOutlineId)) or EgtGetName( nOutlineId) == EgtGetName( abs( vPrevOutlineId[1]))) then + -- se giunzione diversa da bisettrice ed elementi in tangenza ( entro 9°) o dello stesso tipo, forzo il tipo a bisettrice + if nStartJointType ~= WIN_JNT.ANGLED and ( EgtEV( abs( vPrevOutlineId[1])) * EgtSV( nOutlineId) > 0.987 or EgtGetName( nOutlineId) == EgtGetName( abs( vPrevOutlineId[1]))) then nStartJointType = WIN_JNT.ANGLED end - if nEndJointType ~= WIN_JNT.ANGLED and ( AreSameVectorApprox( EgtEV( nOutlineId), EgtSV( abs( vNextOutlineId[1]))) or EgtGetName( nOutlineId) == EgtGetName( abs( vNextOutlineId[1]))) then + if nEndJointType ~= WIN_JNT.ANGLED and ( EgtEV( nOutlineId) * EgtSV( abs( vNextOutlineId[1])) > 0.987 or EgtGetName( nOutlineId) == EgtGetName( abs( vNextOutlineId[1]))) then nEndJointType = WIN_JNT.ANGLED end end @@ -2456,90 +2672,97 @@ local function CalcMixedSplitProfilingProcessings( nSplitId, nProcLayerId, nGeoL end --------------------------------------------------------------------- --- funzione che aggiusta le lunghezze delle lavorazioni per garantire lavorazione completa del profilo -local function AdjustProcessingLength( nCrvId, nSemiProfileId, nGeoAreaId, nPrevGeo, nNextGeo) - - -- se giunzione angled non serve allungamento - if not nSemiProfileId then return end +-- funzione che crea la lavorazione a partire dalla curva del geo +local function CreateProfilingProcessingCurve( nGeoCrvId, nPrevGeo, nNextGeo, nSurfGeo, nProcLayerId) - -- calcolo la curva di lavorazione 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() - local nInnerProcId = EgtCopyGlob( nCrvId, EgtGetParent( nCrvId)) - EgtOffsetCurve( nInnerProcId, - dOffs) + -- copio curva del geo + local nCrvId = EgtCopyGlob( nGeoCrvId, nProcLayerId) + EgtModifyCurveThickness( nCrvId, 0) + EgtSetStatus( nCrvId, GDB_ST.ON) - -- adatto la curva di lavorazione interna al pezzo - if EgtGetType( nInnerProcId) == GDB_TY.CRV_LINE then - EgtExtendCurveStartByLen( nInnerProcId, 10000) - EgtExtendCurveEndByLen( nInnerProcId, 10000) - else - local dAng = EgtArcAngCenter( nInnerProcId) - EgtModifyArcAngCenter( nInnerProcId, EgtIf( dAng > 0, 1, -1) * 360) - end - local nNewId, nCnt = EgtTrimCurveWithRegion( nInnerProcId, nGeoAreaId, true, false) + -- recupero il semiprofilo associato + local nSemiProfileId = EgtGetInfo( nCrvId, WIN_SEMI_PROFILE, 'i') - if nCnt == 0 then - return - end + -- 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 - if nCnt > 1 then - -- nel caso di archi possono generarsi più intersezioni quindi va conservata solo quella corretta - -- TODO può capitare anche nel caso in/out? - if AreSamePointApprox( EgtSP( nNewId), EgtEP( nNewId + nCnt - 1)) then - EgtModifyCurveStartPoint( nNewId, EgtSP( nNewId + nCnt - 1)) - EgtErase( nNewId + nCnt - 1) - nCnt = nCnt - 1 - end - local nPrcOutId = EgtGetFirstNameInGroup( EgtGetParent( nGeoAreaId), WIN_GEO_OUT) - local ptRef = EgtIf( EgtGetName( nCrvId) == WIN_LEFT, EgtSP( nPrcOutId), EgtEP( nPrcOutId)) - local nIdRef - local dSqMinDist = GEO.INFINITO - for nId = nNewId, nNewId + nCnt - 1 do - local ptTest = EgtIf( EgtGetName( nCrvId) == WIN_LEFT, EgtEP( nId), EgtSP( nId)) - local dSqDist = sqdist( ptTest, ptRef) - if dSqDist < dSqMinDist then - dSqMinDist = dSqDist - nIdRef = nId - end - end + -- calcolo la curva di lavorazione 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() + local nOrigInnerProcId = EgtCopyGlob( nCrvId, nProcLayerId) + EgtOffsetCurve( nOrigInnerProcId, - dOffs) - for nId = nNewId, nNewId + nCnt - 1 do - if nId ~= nIdRef then - EgtErase( nId) + -- adatto la curva di lavorazione interna al pezzo + local nInnerProcId = CreateCurveExtension( nOrigInnerProcId, nProcLayerId) + local nNewId, nCnt = EgtTrimCurveWithRegion( nInnerProcId, nSurfGeo, true, false) + + if not nNewId then + nCnt = 0 + end + if nCnt > 0 then + -- se ottengo più tratti considero quello che ha porzione in comune con la curva non estesa + 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 + if nCnt > 1 then + local bFound = false + for nId = nNewId, nNewId + nCnt - 1 do + if bFound then + EgtErase( nId) + elseif CheckExtensionOverlap( nId, nOrigInnerProcId) then + nNewId = nId + bFound = true + else + EgtErase( nId) + end + end + 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 - nNewId = nIdRef + EgtErase( nOrigInnerProcId) end - - -- la allineo alla curva di lavoro - EgtOffsetCurve( nNewId, dOffs) - - -- aggiusto la curva di lavoro - local ptS = EgtSP( nNewId) - local ptE = EgtEP( nNewId) - local bExtra = EgtGetInfo( nCrvId, WIN_GEO_EXTRA, 'b') or false - if bExtra then - -- se è una curva speciale del geo va modificata su entrambi gli estremi - EgtModifyCurveStartPoint( nCrvId, ptS) - EgtModifyCurveEndPoint( nCrvId, ptE) - else - -- se è una curva standard va modificata solo in allungamento se non è in tangenza con quella vicina - local dParS = EgtCurveParamAtPoint( nCrvId, ptS) - local bTang = AreSameVectorApprox( EgtSV( nCrvId), EgtEV( nPrevGeo)) - if not dParS and not bTang then - EgtModifyCurveStartPoint( nCrvId, ptS) - end - bTang = AreSameVectorApprox( EgtEV( nCrvId), EgtSV( nNextGeo)) - local dParE = EgtCurveParamAtPoint( nCrvId, ptE) - if not dParE and not bTang then - EgtModifyCurveEndPoint( nCrvId, ptE) - end - end - - EgtErase( nNewId) + + -- setto le info dal semiprofilo + EgtSetName( nCrvId, EgtGetName( nGeoCrvId)) + GetProcessingInfoFromSemiProfile( nCrvId, nSemiProfileId) end --------------------------------------------------------------------- @@ -2551,9 +2774,10 @@ local function CalcProfilingProcessings( nPartId, nOutlineId) EgtSetName( nProcLayerId, WIN_PRC) EgtSetStatus( nProcLayerId, GDB_ST.OFF) - -- recupero il geo e creo la superficie associata per limitare le lavorazioni + -- recupero il geo e la superficie associata per limitare le lavorazioni local nGeoLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO) - local nSurfGeo = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_SURF) + local vGeoCrvs = EgtGetAllInGroup( nGeoLayerId) + local nSurfGeo = vGeoCrvs[#vGeoCrvs] -- recupero il gruppo dei profili local nProfileLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE) @@ -2575,33 +2799,47 @@ local function CalcProfilingProcessings( nPartId, nOutlineId) CalcMixedFrameProfilingProcessings( nPartId, nProcLayerId, nGeoLayerId, nMainProfileId, nSurfGeo) end else - -- 2) caso standard - -- recupero tutte le curve del geo e le copio nel gruppo processings - local vGeoCrvs = EgtGetAllInGroup( nGeoLayerId) + -- 2) caso standard : costruisco le curve di lavorazione a partire da quelle del geo for i = 1, #vGeoCrvs - 1 do - -- copio curva - local nCrvId = EgtCopyGlob( vGeoCrvs[i], nProcLayerId) - EgtModifyCurveThickness( nCrvId, 0) - -- recupero il semiprofilo associato - local nSemiProfileId = EgtGetInfo( nCrvId, WIN_SEMI_PROFILE, 'i') - -- aggiusto la lunghezza della lavorazione local nPrevIdx = EgtIf( i == 1, #vGeoCrvs - 1, i - 1) local nNextIdx = EgtIf( i == #vGeoCrvs - 1, 1, i + 1) - AdjustProcessingLength( nCrvId, nSemiProfileId, nSurfGeo, vGeoCrvs[nPrevIdx], vGeoCrvs[nNextIdx]) - -- setto le info dal semiprofilo - GetProcessingInfoFromSemiProfile( nCrvId, nSemiProfileId) + CreateProfilingProcessingCurve( vGeoCrvs[i], vGeoCrvs[nPrevIdx], vGeoCrvs[nNextIdx], nSurfGeo, nProcLayerId) end end -- calcolo eventuali lavorazioni per strip local vStripDist = EgtGetInfo( nMainProfileId, WIN_STRIP_DIST, 'vi') or {} + local nGeoIn = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_IN) + local bTangStart = EgtGetInfo( nGeoIn, WIN_TANG_END, 'b') or false + local bTangEnd = EgtGetInfo( nGeoIn, WIN_TANG_START, 'b') or false for i = 1, #vStripDist do - local nStripCut = EgtCopyGlob( nOutlineId, nProcLayerId) - EgtOffsetCurve( nStripCut, vStripDist[i]) - -- modifico la curva in modo che sia a filo del geo - EgtExtendCurveStartByLen( nStripCut, 1000) - EgtExtendCurveEndByLen( nStripCut, 1000) - nStripCut = EgtTrimCurveWithRegion( nStripCut, nSurfGeo, true, false) + local nStripOutline = EgtCopyGlob( nOutlineId, nProcLayerId) + EgtOffsetCurve( nStripOutline, vStripDist[i]) + -- estendo la curva per adattarla alla regione del geo basandomi sulle estensioni della curva in ( che dovrebbe essere quella più vicina) + EgtSetInfo( nStripOutline, WIN_TANG_START, bTangStart) + EgtSetInfo( nStripOutline, WIN_TANG_END, bTangEnd) + local nStripCut = CreateCurveExtension( nStripOutline, nProcLayerId) + local nRes, nCnt = EgtTrimCurveWithRegion( nStripCut, nSurfGeo, true, false) + -- se più di un tratto considero solo quello con sovrapposizione con la curva non estesa + if nCnt > 1 and AreSamePointApprox( EgtSP( nRes), EgtEP( nRes + nCnt - 1)) then + if EgtGetType( nRes) == GDB_TY.CRV_ARC then + EgtModifyCurveStartPoint( nRes, EgtSP( nRes + nCnt - 1)) + EgtErase( nRes + nCnt - 1) + else + EgtAddCurveCompoCurve( nRes, nRes + nCnt - 1, true, false) + end + nCnt = nCnt - 1 + end + if nCnt > 1 then + for nId = nRes, nRes + nCnt - 1 do + if CheckExtensionOverlap( nId, nStripOutline) then + nStripCut = nId + else + EgtErase( nId) + end + end + end + EgtErase( nStripOutline) -- aggiusto orientamento per essere coerente con il geo corrispondente if vStripDist[i] < 0 then EgtInvertCurve( nStripCut) @@ -2624,7 +2862,6 @@ local function CalcProfilingProcessings( nPartId, nOutlineId) end end end - end --------------------------------------------------------------------- @@ -2659,40 +2896,37 @@ local function CalcGeoRaw( nPartId, nOutlineId) end local vRight = EgtGetNameInGroup( nGeoRawLayerId, WIN_GEO_RIGHT) for i = 1, #vRight do - local bExtra = EgtGetInfo( vRight[i], WIN_GEO_EXTRA, 'b') or false - if bExtra then + if not EgtOffsetCurve( vRight[i], dOvermatRight) then EgtErase( vRight[i]) - else - if not EgtOffsetCurve( vRight[i], dOvermatRight) then - EgtErase( vRight[i]) - end end end local vLeft = EgtGetNameInGroup( nGeoRawLayerId, WIN_GEO_LEFT) for i = 1, #vLeft do - local bExtra = EgtGetInfo( vLeft[i], WIN_GEO_EXTRA, 'b') or false - if bExtra then + if not EgtOffsetCurve( vLeft[i], dOvermatLeft) then EgtErase( vLeft[i]) - else - if not EgtOffsetCurve( vLeft[i], dOvermatLeft) then - EgtErase( vLeft[i]) - end end end - + -- creo la composita del grezzo a partire dalle curve local vCrvs = EgtGetAllInGroup( nGeoRawLayerId) - vCrvs = TrimOrderedCurves( vCrvs) - local nCompo = EgtCurveCompo( nGeoRawLayerId, vCrvs) + local nRegion = CalcIntersectionRegion( vCrvs, nGeoRawLayerId) + local nCompo = EgtExtractSurfFrChunkLoops( nRegion, 0, nGeoRawLayerId) -- aggiungo spessore local dDimH = EgtGetInfo( nGeoLayerId, WIN_GEOHEIGHT, 'd') EgtModifyCurveThickness( nCompo, - dDimH) - + -- creo frame ausiliario - local vtX = EgtSV( nCompo) - local frGeo = Frame3d( EgtSP( nCompo), vtX, Z_AX() ^ vtX, Z_AX()) + local vtX = EgtSV( nOut) + local frGeo = Frame3d( ORIG(), vtX, Z_AX() ^ vtX, Z_AX()) local nFrameId = EgtFrame( nGeoRawLayerId, frGeo) + local b3Raw = EgtGetBBoxRef( nCompo, GDB_BB.STANDARD, frGeo) + local ptMin = b3Raw:getMin() + ptMin:toGlob( frGeo) + EgtMove( nFrameId, ( ptMin - ORIG())) EgtSetName( nFrameId, WIN_PRC_FRAME) + + EgtErase( vCrvs) + EgtErase( nRegion) end @@ -2724,7 +2958,7 @@ local function CreateTrimSurf( nGeoId, nOutlineId, dGeoWidth, nLayerId) local sTrimProfileName = EgtGetName( nOrigTrimProfileId) sTrimProfileName = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. WIN_OFST .. sTrimProfileName -- calcolo la superficie di estrusione - return CreateProfileSurf( nOutlineId, EgtGetParent( nOrigTrimProfileId), sTrimProfileName, 4 * dGeoWidth, nLayerId) + return CreateProfileSurf( nOutlineId, EgtGetParent( nOrigTrimProfileId), sTrimProfileName, 10 * dGeoWidth, nLayerId) end end @@ -2766,23 +3000,71 @@ local function CreateMixedSplitTrimSurf( nMixedOutlineId, nProfileId, dExtraLen, end --------------------------------------------------------------------- --- funzione che crea il solido di estrusione principale -local function CreateMainSurf( nOutlineId, dExtraLen, nProfileId, sSectionName, nLayerId) +-- funzione che calcola la curva guida per il solido principale +local function CalcSolidGuide( nOutlineId, nSolidLayerId, nProfileId) + + local nGuideId + if EgtGetType( nOutlineId) == GDB_TY.CRV_LINE then + -- se tratto lineare non ci sono problemi di estensione + nGuideId = EgtCopyGlob( nOutlineId, nSolidLayerId) + EgtExtendCurveStartByLen( nGuideId, 400) + EgtExtendCurveEndByLen( nGuideId, 400) + + 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 + local nPartId = EgtGetParent( nSolidLayerId) + local nProcLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PRC) + local nPrcIn = EgtGetFirstNameInGroup( nProcLayerId, WIN_GEO_IN) + local nInId = EgtCopyGlob( nPrcIn, nSolidLayerId) + -- 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) + EgtInvertCurve( nInId) + + -- aggiungo tratti di estensione se necessari + local dParS = EgtCurveParamAtPoint( nGuideId, EgtSP( nInId)) + if not dParS then + local dParTrim = EgtCurveParamAtPoint( nInId, EgtSP( nGuideId)) + local nNewCrv = EgtCopyGlob( nInId, nSolidLayerId) + EgtTrimCurveEndAtParam( nNewCrv, dParTrim) + EgtAddCurveCompoCurve( nGuideId, nNewCrv, true, false) + end + local dParE = EgtCurveParamAtPoint( nGuideId, EgtEP( nInId)) + if not dParE then + local dParTrim = EgtCurveParamAtPoint( nInId, EgtEP( nGuideId)) + local nNewCrv = EgtCopyGlob( nInId, nSolidLayerId) + EgtTrimCurveStartAtParam( nNewCrv, dParTrim) + EgtAddCurveCompoCurve( nGuideId, nNewCrv) + end + + -- piccola estensione per avere un po' di margine dal minimo indispensabile appena calcolato + EgtExtendCurveStartByLen( nGuideId, 5) + EgtExtendCurveEndByLen( nGuideId, 5) + + EgtErase( nInId) + end - -- curva guida - local nGuideId = EgtCopy( nOutlineId, nLayerId) EgtSetName( nGuideId, WIN_MAINGUIDE) EgtSetStatus( nGuideId, GDB_ST.OFF) - EgtExtendCurveStartByLen( nGuideId, dExtraLen) - EgtExtendCurveEndByLen( nGuideId, dExtraLen) - -- se bottomrail sposto opportunamente l'outline + -- se bottomrail sposto opportunamente la guida 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) + EgtOffsetCurve( nGuideId, - dOffs) end + return nGuideId +end + +--------------------------------------------------------------------- +-- funzione che crea il solido di estrusione principale +local function CreateMainSurf( nGuideId, nProfileId, sSectionName, nLayerId) + -- posiziono il profilo sulla curva guida : -- recupero il frame del profilo local nProfileFrameId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME) @@ -2810,10 +3092,11 @@ local function CalcMixedFrameSolid( nOutlineId, nSolidLayerId, nProfileLayerId, -- 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( vMixedOutlines[i], 2 * dGeoWidth, nMainProfileId, sSection, nSolidLayerId) + local nMainExtrusionId = CreateMainSurf( nGuideId, nMainProfileId, sSection, nSolidLayerId) table.insert( vMainExtrusions, nMainExtrusionId) end @@ -2885,8 +3168,9 @@ local function CalcMixedSplitSolid( nOutlineId, nSolidLayerId, nProfileLayerId, -- a) creo il solido di estrusione principale local nMainProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN) + local nGuideId = CalcSolidGuide( nOutlineId, nSolidLayerId, nMainProfileId) local sSection = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. WIN_SECTION - local nMainExtrusionId = CreateMainSurf( nOutlineId, 2 * dGeoWidth, nMainProfileId, sSection, nSolidLayerId) + local nMainExtrusionId = CreateMainSurf( nGuideId, nMainProfileId, sSection, nSolidLayerId) -- creo una copia local nOrigMainExtrusionId = EgtCopy( nMainExtrusionId, nSolidLayerId) EgtSetName( nOrigMainExtrusionId, WIN_SRF_ORIGMAIN) @@ -2961,13 +3245,14 @@ local function CalcSolid( nPartId, nOutlineId) -- a) creo il solido di estrusione principale local nMainProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN) + local nGuideId = CalcSolidGuide( nOutlineId, nSolidLayerId, nMainProfileId) local sSection = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. WIN_SECTION - local nMainExtrusionId = CreateMainSurf( nOutlineId, 4 * dGeoWidth, nMainProfileId, sSection, nSolidLayerId) + local nMainExtrusionId = CreateMainSurf( nGuideId, nMainProfileId, sSection, nSolidLayerId) -- creo una copia ( usata per calcolo ferramenta) local nOrigMainExtrusionId = EgtCopy( nMainExtrusionId, nSolidLayerId) EgtSetName( nOrigMainExtrusionId, WIN_SRF_ORIGMAIN) EgtSetStatus( nOrigMainExtrusionId, GDB_ST.OFF) - + -- b) trim con i controprofili su start e su end local vGeoId = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_RIGHT) local vPrevGeoId = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_LEFT) @@ -6354,7 +6639,7 @@ end ---------------------------------------------------------------------------------- --------------------------------- PREVIEW ---------------------------------------- ---------------------------------------------------------------------------------- -local function CalcBottomRailPreview( nPreviewGrp, nOutlineId, nBottomRail, nProfileGrp, nGeoGrp, color) +local function CalcBottomRailPreview( nPreviewGrp, nOutlineId, nBottomRail, nGeoGrp, color) -- costruisco box complessivo degli zoccoli local vCrvs = {} @@ -6363,12 +6648,14 @@ local function CalcBottomRailPreview( nPreviewGrp, nOutlineId, nBottomRail, nPro local nPartGeoIn = EgtGetFirstNameInGroup( nGeoGrp, WIN_GEO_IN) vCrvs[1] = EgtCopyGlob( nPartGeoIn, nPreviewGrp) EgtInvertCurve( vCrvs[1]) - + + -- la curva right corrisponde al geo in del pezzo adiacente local vNextOutlines = EgtGetInfo( nOutlineId, WIN_NEXT_OUTLINES, 'vi') - local vEndProfiles = EgtGetNameInGroup( nProfileGrp, WIN_PRF_END) - local b3ProfileEnd = GetProfileLocalBox( vEndProfiles[1]) - vCrvs[2] = EgtCopyGlob( abs( vNextOutlines[1]), nPreviewGrp) - EgtOffsetCurve( vCrvs[2], b3ProfileEnd:getMin():getX()) + local nNextPart = FindAssociatedPart( abs( vNextOutlines[1]), false) + local nNextGeo = EgtGetFirstNameInGroup( nNextPart, WIN_GEO) + local nNextIn = EgtGetFirstNameInGroup( nNextGeo, WIN_GEO_IN) + vCrvs[2] = EgtCopyGlob( nNextIn, nPreviewGrp) + EgtInvertCurve( vCrvs[2]) -- la curva in corrisponde al geo in dell'ultimo bottomrail local vBottomRails = EgtGetInfo( nOutlineId, WIN_REF_BOTTOMRAIL_PART, 'vi') @@ -6377,11 +6664,13 @@ local function CalcBottomRailPreview( nPreviewGrp, nOutlineId, nBottomRail, nPro local nGeoIn = EgtGetFirstNameInGroup( nGeoLayer, WIN_GEO_IN) vCrvs[3] = EgtCopyGlob( nGeoIn, nPreviewGrp) + -- la curva left corrisponde al geo in del pezzo adiacente local vPrevOutlines = EgtGetInfo( nOutlineId, WIN_PREV_OUTLINES, 'vi') - local vStartProfiles = EgtGetNameInGroup( nProfileGrp, WIN_PRF_START) - local b3ProfileStart = GetProfileLocalBox( vStartProfiles[1]) - vCrvs[4] = EgtCopyGlob( abs( vPrevOutlines[1]), nPreviewGrp) - EgtOffsetCurve( vCrvs[4], b3ProfileStart:getMin():getX()) + local nPrevPart = FindAssociatedPart( abs( vPrevOutlines[1]), false) + local nPrevGeo = EgtGetFirstNameInGroup( nPrevPart, WIN_GEO) + local nPrevIn = EgtGetFirstNameInGroup( nPrevGeo, WIN_GEO_IN) + vCrvs[4] = EgtCopyGlob( nPrevIn, nPreviewGrp) + EgtInvertCurve( vCrvs[4]) -- creo la regione e ne estraggo il bordo local nAreaId = CalcIntersectionRegion( vCrvs, nPreviewGrp) @@ -6412,18 +6701,18 @@ local function CalcPartPreview( nPartId, nPreviewGrp) local nOutlineId = EgtGetInfo( nPartId, WIN_REF_OUTLINE, 'i') local nGeoGrp = EgtGetFirstNameInGroup( nPartId, WIN_GEO) - local nProfileGrp = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE) - - -- verifico se è sash active/inactive per gestione speciale - local nBaseOutlineId = EgtGetInfo( nOutlineId, WIN_COPY, 'i') - local bOnSplit = EgtGetInfo( nBaseOutlineId, WIN_CRV_ON_FRENCH_SPLIT, 'b') + + -- verifico se è anta con elemento su french split per evitare sovrapposizione tra i pezzi + local nParentAreaId = EgtGetParent( EgtGetParent( nOutlineId)) + local nSashType = EgtGetInfo( nParentAreaId, WIN_SASHTYPE, 'i') or WIN_SASHTYPES.NULL + local bSpecialSash = ( nSashType ~= WIN_SASHTYPES.NULL) -- recupero il tipo di giunzione local nStartJoint = EgtGetInfo( nOutlineId, WIN_STARTJOINT, 'i') local nEndJoint = EgtGetInfo( nOutlineId, WIN_ENDJOINT, 'i') -- se non ha giunzioni short e non è active/inactive come preview posso considerare direttamente la regione del geo - if nStartJoint ~= WIN_PART_JNT.SHORT and nEndJoint ~= WIN_PART_JNT.SHORT and not bOnSplit then + if nStartJoint ~= WIN_PART_JNT.SHORT and nEndJoint ~= WIN_PART_JNT.SHORT and not bSpecialSash then local nGeoSurf = EgtGetFirstNameInGroup( nGeoGrp, WIN_GEO_SURF) nAreaId = EgtCopyGlob( nGeoSurf, nPreviewGrp) EgtSetStatus( nAreaId, GDB_ST.ON) @@ -6434,6 +6723,8 @@ local function CalcPartPreview( nPartId, nPreviewGrp) local nGrpTmp = EgtGroup( nPreviewGrp) -- curva out è il geo out tranne nel caso di sash active/inactive per le quali considero l'outline per evitare sovrapposizioni + local nBaseOutlineId = EgtGetInfo( nOutlineId, WIN_COPY, 'i') + local bOnSplit = EgtGetInfo( nBaseOutlineId, WIN_CRV_ON_FRENCH_SPLIT, 'b') if bOnSplit then EgtCopyGlob( nOutlineId, nGrpTmp) else @@ -6443,25 +6734,28 @@ local function CalcPartPreview( nPartId, nPreviewGrp) -- curva right local vGeoRight = EgtGetNameInGroup( nGeoGrp, WIN_GEO_RIGHT) - if nEndJoint == WIN_PART_JNT.SHORT then - -- se giunzione short per evitare sovrapposizioni devo fermarla al box del pezzo adiacente - local vEndProfiles = EgtGetNameInGroup( nProfileGrp, WIN_PRF_END) - for i = 1, #vGeoRight do - local nNextOutline = EgtGetInfo( vGeoRight[i], WIN_REF_OUTLINE, 'i') - local nCrv = EgtCopyGlob( abs( nNextOutline), nGrpTmp) - local b3Profile = GetProfileLocalBox( vEndProfiles[i]) - local dRailDelta = EgtGetInfo( vEndProfiles[i], WIN_RAILDELTA, 'd') or 0 - local dOffs = b3Profile:getMin():getX() - dRailDelta - if nNextOutline < 0 then - EgtInvertCurve( nCrv) - dOffs = - ( b3Profile:getMax():getX() - dRailDelta) + for i = 1, #vGeoRight do + local nNextOutline = EgtGetInfo( vGeoRight[i], WIN_REF_OUTLINE, 'i') + if nEndJoint == WIN_PART_JNT.SHORT then + -- se giunzione short per evitare sovrapposizioni devo fermare al geo in del pezzo adiacente + local nNextPart = FindAssociatedPart( abs( nNextOutline), EgtGetName( nOutlineId) == WIN_SPLIT) + local nNextGeo = EgtGetFirstNameInGroup( nNextPart, WIN_GEO) + local nNextCrv = EgtGetFirstNameInGroup( nNextGeo, EgtIf( nNextOutline > 0, WIN_GEO_IN, WIN_GEO_OUT)) + local nCrv = EgtCopyGlob( nNextCrv, nGrpTmp) + EgtInvertCurve( nCrv) + -- per evitare casi problematici di assenza di intersezione forzo estensione in tangenza + EgtSetInfo( nCrv, WIN_TANG_START, true) + EgtSetInfo( nCrv, WIN_TANG_END, true) + + else + -- se guinzione full utilizzo la curva del geo o la curva di outline se si tratta di curva di french split ( la curva del geo si sovrapporrebbe a quella dell'anta adiacente) + local nBaseOutlineId = EgtGetInfo( abs( nNextOutline), WIN_COPY, 'i') + local bOnSplit = EgtGetInfo( nBaseOutlineId, WIN_CRV_ON_FRENCH_SPLIT, 'b') + if bOnSplit then + EgtCopyGlob( abs( nNextOutline), nGrpTmp) + else + EgtCopyGlob( vGeoRight[i], nGrpTmp) end - EgtOffsetCurve( nCrv, dOffs) - end - else - -- altrimenti posso utilizzare direttamente la curva del geo - for i = 1, #vGeoRight do - EgtCopyGlob( vGeoRight[i], nGrpTmp) end end @@ -6471,23 +6765,25 @@ local function CalcPartPreview( nPartId, nPreviewGrp) -- curva left local vGeoLeft = EgtGetNameInGroup( nGeoGrp, WIN_LEFT) - if nStartJoint == WIN_PART_JNT.SHORT then - local vStartProfiles = EgtGetNameInGroup( nProfileGrp, WIN_PRF_START) - for i = 1, #vGeoLeft do - local nPrevOutline = EgtGetInfo( vGeoLeft[i], WIN_REF_OUTLINE, 'i') - local nCrv = EgtCopyGlob( abs( nPrevOutline), nGrpTmp) - local b3Profile = GetProfileLocalBox( vStartProfiles[i]) - local dRailDelta = EgtGetInfo( vStartProfiles[i], WIN_RAILDELTA, 'd') or 0 - local dOffs = b3Profile:getMin():getX() - dRailDelta - if nPrevOutline < 0 then - EgtInvertCurve( nCrv) - dOffs = - ( b3Profile:getMax():getX() - dRailDelta) + for i = 1, #vGeoLeft do + local nPrevOutline = EgtGetInfo( vGeoLeft[i], WIN_REF_OUTLINE, 'i') + if nStartJoint == WIN_PART_JNT.SHORT then + local nPrevPart = FindAssociatedPart( abs( nPrevOutline), EgtGetName( nOutlineId) == WIN_SPLIT) + local nPrevGeo = EgtGetFirstNameInGroup( nPrevPart, WIN_GEO) + local nPrevCrv = EgtGetFirstNameInGroup( nPrevGeo, EgtIf( nPrevOutline > 0, WIN_GEO_IN, WIN_GEO_OUT)) + local nCrv = EgtCopyGlob( nPrevCrv, nGrpTmp) + EgtInvertCurve( nCrv) + EgtSetInfo( nCrv, WIN_TANG_START, true) + EgtSetInfo( nCrv, WIN_TANG_END, true) + + else + local nBaseOutlineId = EgtGetInfo( abs( nPrevOutline), WIN_COPY, 'i') + local bOnSplit = EgtGetInfo( nBaseOutlineId, WIN_CRV_ON_FRENCH_SPLIT, 'b') + if bOnSplit then + EgtCopyGlob( abs( nPrevOutline), nGrpTmp) + else + EgtCopyGlob( vGeoLeft[i], nGrpTmp) end - EgtOffsetCurve( nCrv, dOffs) - end - else - for i = 1, #vGeoLeft do - EgtCopyGlob( vGeoLeft[i], nGrpTmp) end end @@ -6508,7 +6804,7 @@ local function CalcPartPreview( nPartId, nPreviewGrp) if EgtGetName( nOutlineId) == WIN_BOTTOM then local nBottomRail = EgtGetInfo( nOutlineId, WIN_BOTTOMRAIL, 'i') or 0 if nBottomRail > 0 then - CalcBottomRailPreview( nPreviewGrp, nOutlineId, nBottomRail, nProfileGrp, nGeoGrp, color) + CalcBottomRailPreview( nPreviewGrp, nOutlineId, nBottomRail, nGeoGrp, color) end end end