From 6c075e90532ba3f54d88b62c8f294146b6cdc11b Mon Sep 17 00:00:00 2001 From: SaraP Date: Mon, 6 Oct 2025 15:25:27 +0200 Subject: [PATCH] DataWindow : - correzioni varie per casi di split contro 2 pezzi o che comportano cambio di forma - nuova gestione calcolo fermavetri. --- Designing/WinConst.lua | 4 + Designing/WinLib/WinCalculate.lua | 2134 +++++++++++++++++------------ 2 files changed, 1287 insertions(+), 851 deletions(-) diff --git a/Designing/WinConst.lua b/Designing/WinConst.lua index fac0f32..a82b0e5 100644 --- a/Designing/WinConst.lua +++ b/Designing/WinConst.lua @@ -166,6 +166,7 @@ WIN_REF_BOTTOMRAIL_PART = 'BottomRailPartRef' WIN_PREV_OUTLINES = 'PrevOutlines' WIN_NEXT_OUTLINES = 'NextOutlines' WIN_REF_SPLIT = 'RefSplit' +WIN_INV_SPLIT = 'InvSplit' WIN_PRJ_ORIGSPLIT = 'OrigSplit' WIN_CRV_ON_FRENCH_SPLIT = 'OutlineOnFrenchSplit' WIN_SPLIT_STARTINTERS = 'SplitStartInters' @@ -349,6 +350,9 @@ WIN_GEOHEIGHT = 'GeoHeight' WIN_GEOLEN = 'GeoLen' WIN_SEMI_PROFILE = 'SemiProfileId' WIN_GLASS_RECT = 'GlassRectangle' +WIN_GEO_SURF = 'GeoRegion' +WIN_GEO_EXTRA = 'GeoExtra' +WIN_REF_GEO = 'GeoRef' -- CAMBIO PROFILO diff --git a/Designing/WinLib/WinCalculate.lua b/Designing/WinLib/WinCalculate.lua index 8aa9ad6..cc4d8de 100644 --- a/Designing/WinLib/WinCalculate.lua +++ b/Designing/WinLib/WinCalculate.lua @@ -75,126 +75,290 @@ local function GetAuxLayer() end --------------------------------------------------------------------- --- funzione che trova punto di intersezione fra due curve eventualmente estendendole +-- funzione che trova il punto di intersezione fra due curve considerandole estese local function FindIntersectionPoint( nCrv1, nCrv2, ptRef) - local ptInt - -- se archi, cerco intersezioni tra le circonferenze - if EgtGetType( nCrv1) == GDB_TY.CRV_ARC and EgtGetType( nCrv2) == GDB_TY.CRV_ARC then - -- trovo intersezione tra le due circonferenze - local nCircle1 = EgtCircle( GDB_ID.ROOT, EgtCP( nCrv1), EgtArcRadius( nCrv1)) - local nCircle2 = EgtCircle( GDB_ID.ROOT, EgtCP( nCrv2), EgtArcRadius( nCrv2)) - ptInt = EgtIP( nCircle1, nCircle2, ptRef) - EgtModifyCurveStartPoint( nCrv1, ptInt) - EgtModifyCurveEndPoint( nCrv2, ptInt) - EgtErase( nCircle1) - EgtErase( nCircle2) - - elseif EgtGetType( nCrv1) == GDB_TY.CRV_ARC or EgtGetType( nCrv2) == GDB_TY.CRV_ARC then - local nLine = EgtIf( EgtGetType( nCrv1) == GDB_TY.CRV_LINE, nCrv1, nCrv2) - local nArc = EgtIf( nLine == nCrv1, nCrv2, nCrv1) - -- creo circonferenza corrispondente all'arco - local nCircle = EgtCircle( GDB_ID.ROOT, EgtCP( nArc), EgtArcRadius( nArc)) - -- prolungo la linea dal lato opportuno - local dDist1 = dist( EgtSP( nLine), ptRef) - local dDist2 = dist( EgtEP( nLine), ptRef) - if dDist1 < dDist2 then - EgtExtendCurveStartByLen( nLine, 10000) - else - EgtExtendCurveEndByLen( nLine, 10000) - end - -- trovo le intersezioni tra retta e circonferenza - local nId1, nPoints = EgtCurveCurveInters( nCircle, nLine, GDB_ID.ROOT) - if nPoints == 1 then - ptInt = EgtSP( nId1) - EgtErase( nId1) - else - -- conservo quello più vicino al punto di riferimento - local ptInt1 = EgtSP( nId1) - local ptInt2 = EgtSP( nId1 + 1) - local ptNewRef = EgtIf( nArc == nCrv2, EgtEP( nArc), EgtSP( nArc)) - local dDist1 = dist( ptNewRef, ptInt1) - local dDist2 = dist( ptNewRef, ptInt2) - if dDist1 < dDist2 + GEO.EPS_SMALL then - ptInt = ptInt1 - else - ptInt = ptInt2 - end - EgtErase( nId1) - EgtErase( nId1 + 1) - end - EgtErase( nCircle) - -- allungo l'arco per arrivare al punto di intersezione - if nArc == nCrv2 then - EgtModifyCurveEndPoint( nArc, ptInt) + local ptInt = EgtIP( nCrv1, nCrv2, ptRef) + + -- se il punto di intersezione non esiste ritento estendendo le curve + if not ptInt then + local nGrp = EgtGetParent( nCrv1) + local dExtraLen = 10000 + local nCrvA, nCrvB + if EgtGetType( nCrv1) == GDB_TY.CRV_LINE and EgtGetType( nCrv2) == GDB_TY.CRV_LINE then + -- caso linea-linea : estendo le due linee + nCrvA = EgtCopyGlob( nCrv1, nGrp) + nCrvB = EgtCopyGlob( nCrv2, nGrp) + EgtExtendCurveStartByLen( nCrvA, dExtraLen) + EgtExtendCurveEndByLen( nCrvA, dExtraLen) + EgtExtendCurveStartByLen( nCrvB, dExtraLen) + EgtExtendCurveEndByLen( nCrvB, dExtraLen) + + elseif EgtGetType( nCrv1) == GDB_TY.CRV_ARC and EgtGetType( nCrv2) == 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 - EgtModifyCurveStartPoint( nArc, ptInt) - end - - else - ptInt = EgtIP( nCrv1, nCrv2, ORIG()) - if not ptInt then - -- tento estendendo le curve - EgtExtendCurveStartByLen( nCrv1, 10000) - EgtExtendCurveEndByLen( nCrv1, 10000) - EgtExtendCurveStartByLen( nCrv2, 10000) - EgtExtendCurveEndByLen( nCrv2, 10000) - ptInt = EgtIP( nCrv1, nCrv2, ORIG()) + -- 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) + nCrvA = EgtCircle( nGrp, EgtCP( nArc), EgtArcRadius( nArc)) + nCrvB = EgtCopyGlob( nLine, nGrp) + EgtExtendCurveStartByLen( nCrvB, dExtraLen) + EgtExtendCurveEndByLen( nCrvB, dExtraLen) end + + ptInt = EgtIP( nCrvA, nCrvB, ptRef) + EgtErase( { nCrvA, nCrvB}) end return ptInt end --------------------------------------------------------------------- --- funzione che data una lista di curve ordinate che creano una curva chiusa, --- ne estende/taglia i contorni per ottenere una curva chiusa continua -local function TrimAndOrientOrderedCurves( vCrvs, bOrient) - local IntersCurveList = {} - local LastCurveInters - -- ciclo sulle curve per ottenere lista intersezioni - for i = 1, #vCrvs do - -- recupero la precedente - local nPrevIndex = EgtIf( i == 1, #vCrvs, i - 1) - -- calcolo intersezione - local ptInters = FindIntersectionPoint( vCrvs[i], vCrvs[ nPrevIndex], EgtSP( vCrvs[i])) - if LastCurveInters then - LastCurveInters.EndInters = Point3d( ptInters) - end - local NewCurveInters = { CurveId = vCrvs[i], StartInters = Point3d( ptInters)} - table.insert( IntersCurveList, NewCurveInters) - LastCurveInters = NewCurveInters - end - IntersCurveList[#IntersCurveList].EndInters = IntersCurveList[1].StartInters +-- 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 - -- ciclo per tagliare ed orientare - for nIntersCurveIndex = 1, #IntersCurveList do - local CurveInters = IntersCurveList[nIntersCurveIndex] - local dStartParam = EgtCurveParamAtPoint( CurveInters.CurveId, CurveInters.StartInters, 100 * GEO.EPS_SMALL) - local dEndParam = EgtCurveParamAtPoint( CurveInters.CurveId, CurveInters.EndInters, 100 * GEO.EPS_SMALL) - EgtTrimCurveStartEndAtParam( CurveInters.CurveId, min( dStartParam, dEndParam), max( dStartParam, dEndParam)) - if bOrient and dStartParam > dEndParam then - EgtInvertCurve( CurveInters.CurveId) + -- gruppo temporaneo per i conti + local nGrpTmp = EgtGroup( nGrp) + EgtSetStatus( nGrpTmp, GDB_ST.OFF) + + -- costruisco la regione definita da tutti i semipiani delle linee che compongono il contorno + local bArcs = false + local dExtraLen = 10000 + local vSemiPlaneSurfs = {} + for i = 1, #vCrvs do + if EgtGetType( vCrvs[i]) == GDB_TY.CRV_LINE then + local vtDir = EgtSV( vCrvs[i]) + local vtOrtho = Vector3d( vtDir) + vtOrtho:rotate( Z_AX(), 90) + local nSemiPlaneId = EgtSurfFrRectangle( nGrpTmp, ORIG(), Point3d( EgtCurveLength( vCrvs[i]) + 2 * dExtraLen, dExtraLen, 0)) + local frRect = Frame3d( EgtSP( vCrvs[i]) - vtDir * dExtraLen, vtDir, vtOrtho, Z_AX()) + EgtTransform( nSemiPlaneId, frRect) + table.insert( vSemiPlaneSurfs, nSemiPlaneId) + else + bArcs = true + end + end + for i = 2, #vSemiPlaneSurfs do + EgtSurfFrIntersect( vSemiPlaneSurfs[1], vSemiPlaneSurfs[i]) + EgtErase( vSemiPlaneSurfs[i]) + end + nSurfId = vSemiPlaneSurfs[1] + + -- se presenti archi, calcolo le regioni associate limitandole con i semipiani + if bArcs then + local vArcSurfs = {} + local nCrvBorder = EgtExtractSurfFrChunkLoops( nSurfId, 0, nGrpTmp) + + for i = 1, #vCrvs do + if EgtGetType( vCrvs[i]) == GDB_TY.CRV_ARC then + + -- creo circonferenza corrispondente + local nCircleId = EgtCopyGlob( vCrvs[i], nGrpTmp) + local dAngOld = EgtArcAngCenter( vCrvs[i]) + EgtModifyArcAngCenter( nCircleId, EgtIf( dAngOld > 0, 360, -360)) + + -- limito la circonferenza alla regione definita dei semipiani + local nCrv, nCnt = EgtTrimCurveWithRegion( nCircleId, nSurfId, true, false) + + 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) + nCnt = nCnt - 1 + end + + -- spezzo in corrispondenza di eventuali punti tangenti alla regione dei semipiani + local vArcs = EgtTableFill( nCrv, nCnt) + for j = nCrv, nCrv + nCnt - 1 do + local nInters, nPntCnt, nCrvCnt = EgtCurveCurveInters( j, nCrvBorder, nGrpTmp) + if nPntCnt > 2 then + local nCurrCrv = j + for nPntId = nInters, nInters + nPntCnt - 1 do + local dPar = EgtCurveParamAtPoint( nCurrCrv, EgtSP( nPntId)) + local nNewCrv = EgtSplitCurveAtParam( nCurrCrv, dPar) + if nNewCrv then + table.insert( vArcs, nNewCrv) + nCurrCrv = nNewCrv + end + end + end + end + + -- considero solo i tratti che poggiano sulla curva orginale + for j = 1, #vArcs do + local dParS = EgtCurveParamAtPoint( vCrvs[i], EgtSP( vArcs[j])) + local dParE = EgtCurveParamAtPoint( vCrvs[i], EgtEP( vArcs[j])) + + local bOk = false + 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( vCrvs[i])) + local dPar2 = EgtCurveParamAtPoint( vArcs[j], EgtEP( vCrvs[i])) + if dPar1 or dPar2 then + bOk = true + end + elseif dParS and abs( dParS - 1) > GEO.EPS_SMALL then + bOk = true + elseif dParE and dParE > GEO.EPS_SMALL then + bOk = true + end + + if not bOk then + EgtErase( vArcs[j]) + else + local dParS = EgtCurveParamAtPoint( nCrvBorder, EgtSP( vArcs[j]), 100 * GEO.EPS_SMALL) + local dParE = EgtCurveParamAtPoint( nCrvBorder, EgtEP( vArcs[j]), 100 * GEO.EPS_SMALL) + local nBorderCopy = EgtCopyGlob( nCrvBorder, nGrpTmp) + EgtTrimCurveStartEndAtParam( nBorderCopy, dParE, dParS) + local nCompo = EgtCurveCompo( nGrpTmp, { nBorderCopy, vArcs[j]}) + local nTrimSurf = EgtSurfFlatRegion( nGrpTmp, nCompo) + table.insert( vArcSurfs, nTrimSurf) + end + end + end + end + end + + for i = 1, #vArcSurfs do + EgtSurfFrIntersect( nSurfId, vArcSurfs[i]) + EgtErase( vArcSurfs[i]) + end + end + + EgtRelocateGlob( nSurfId, nGrp) + EgtErase( nGrpTmp) + return nSurfId +end + +--------------------------------------------------------------------- +-- 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) +local function AdjustExtraCurvesForTrim( nCrvId, nSurfId, nMode) + + if not nMode or nMode == 0 then + EgtErase( nCrvId) + + elseif nMode == 1 then + -- rimuovo la info che riconduce alla curva che sto per eliminare dalla curva corrispondente del base outline + local nBaseOutline = EgtGetInfo( nCrvId, WIN_COPY, 'i') + EgtRemoveInfo( nBaseOutline, WIN_COPY) + -- elimino la curva + EgtErase( nCrvId) + + elseif nMode == 2 then + -- se la curva è fuori dalla regione allora non va eliminata ma viene settata info che indica di ignorarla + local nTestCrv = EgtCopyGlob( nCrvId, EgtGetParent( nSurfId)) + local nTmp, nCnt = EgtTrimCurveWithRegion( nTestCrv, nSurfId, true, true) + if nCnt > 0 then + EgtErase( nCrvId) + else + EgtSetInfo( nCrvId, WIN_GEO_EXTRA, true) + EgtSetStatus( nCrvId, GDB_ST.OFF) end end end --------------------------------------------------------------------- -local function TrimSplitWithOutline( nSplitId) - -- estendo agli estremi ( TO DO : gestire caso di split non lineare) - EgtExtendCurveStartByLen( nSplitId, 50) - EgtExtendCurveEndByLen( nSplitId, 50) - -- lo taglio con outline - local nStartIntersId = EgtGetInfo( nSplitId, WIN_SPLIT_STARTINTERS, 'i') - local nOutlineId = EgtGetInfo( nStartIntersId, WIN_COPY, 'i') - local ptStartInters = EgtIP( nSplitId, nOutlineId, EgtSP( nSplitId)) - local dStartInters = EgtCurveParamAtPoint( nSplitId, ptStartInters) - EgtTrimCurveStartAtParam( nSplitId, dStartInters) - local nEndIntersId = EgtGetInfo( nSplitId, WIN_SPLIT_ENDINTERS, 'i') - nOutlineId = EgtGetInfo( nEndIntersId, WIN_COPY, 'i') - local ptEndInters = EgtIP( nSplitId, nOutlineId, EgtSP( nSplitId)) - local dEndInters = EgtCurveParamAtPoint( nSplitId, ptEndInters) - EgtTrimCurveEndAtParam( nSplitId, dEndInters) +-- 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) + + -- 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 + + -- 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 + + 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 + + EgtErase( nGrpTmp) + return vResultCurves end --------------------------------------------------------------------- @@ -772,6 +936,24 @@ end ---------------------------------------------------------------------------------- ------------------------------ CALCOLO OUTLINE --------------------------------- ---------------------------------------------------------------------------------- +local function TrimSplitWithOutline( nSplitId) + -- estendo agli estremi ( TO DO : gestire caso di split non lineare) + EgtExtendCurveStartByLen( nSplitId, 50) + EgtExtendCurveEndByLen( nSplitId, 50) + -- lo taglio con outline + local nStartIntersId = EgtGetInfo( nSplitId, WIN_SPLIT_STARTINTERS, 'i') + local nOutlineId = EgtGetInfo( nStartIntersId, WIN_COPY, 'i') + local ptStartInters = EgtIP( nSplitId, nOutlineId, EgtSP( nSplitId)) + local dStartInters = EgtCurveParamAtPoint( nSplitId, ptStartInters) + EgtTrimCurveStartAtParam( nSplitId, dStartInters) + local nEndIntersId = EgtGetInfo( nSplitId, WIN_SPLIT_ENDINTERS, 'i') + nOutlineId = EgtGetInfo( nEndIntersId, WIN_COPY, 'i') + local ptEndInters = EgtIP( nSplitId, nOutlineId, EgtEP( nSplitId)) + local dEndInters = EgtCurveParamAtPoint( nSplitId, ptEndInters) + EgtTrimCurveEndAtParam( nSplitId, dEndInters) +end + +--------------------------------------------------------------------- -- funzione che calcola l'outline dall'area outline ( base outline) local function CalculateOutlineFromAreaOutline( nAreaId) @@ -819,26 +1001,35 @@ local function CalculateOutlineFromAreaOutline( nAreaId) while nBaseOutlineId do -- recupero la curva di outline corrispondente alla curva del base outline da cui deriva e la copio local nSouId = EgtGetInfo( nBaseOutlineId, WIN_SOU, 'i') - local nCopyId = EgtGetInfo( nSouId, WIN_COPY, 'i') + local nCopyId = EgtGetInfo( nSouId, WIN_COPY, 'i') or GDB_ID.NULL local nOutlineId = EgtCopy( nCopyId, nOutlineLayerId) - -- se deriva da split devo aggiornare il nome e setto il riferimento - local sSouName = EgtGetName( nSouId) - if sSouName == WIN_SPLIT then - local sBaseName = EgtGetName( nBaseOutlineId) - EgtSetName( nOutlineId, sBaseName) - EgtSetInfo( nOutlineId, WIN_REF_SPLIT, nSouId) + if nOutlineId then + -- se deriva da split devo aggiornare il nome, controllare l'orientamento e settare il riferimento + local sSouName = EgtGetName( nSouId) + if sSouName == WIN_SPLIT then + local sBaseName = EgtGetName( nBaseOutlineId) + EgtSetName( nOutlineId, sBaseName) + EgtSetInfo( nOutlineId, WIN_REF_SPLIT, nSouId) + -- verifico orientamento + local nCrvRef = EgtGetPrev( nBaseOutlineId) or EgtGetNext( nBaseOutlineId) + local _, _, nSide = EgtPointCurveDistSide( EgtMP( nCrvRef), nOutlineId, Z_AX()) + if nSide == 1 then + EgtInvertCurve( nOutlineId) + EgtSetInfo( nOutlineId, WIN_INV_SPLIT, true) + end + end + + -- sistemo le info + EgtSetInfo( nOutlineId, WIN_COPY, nBaseOutlineId) + EgtSetInfo( nBaseOutlineId, WIN_COPY, nOutlineId) + EgtRemoveInfo( nOutlineId, WIN_CHILD) end - -- sistemo le info - EgtSetInfo( nOutlineId, WIN_COPY, nBaseOutlineId) - EgtSetInfo( nBaseOutlineId, WIN_COPY, nOutlineId) - EgtRemoveInfo( nOutlineId, WIN_CHILD) - nBaseOutlineId = EgtGetNext( nBaseOutlineId) end -- taglio tutti i contorni - TrimAndOrientOrderedCurves( EgtGetAllInGroup( nOutlineLayerId), true) + TrimOrderedCurves( EgtGetAllInGroup( nOutlineLayerId), 1) -- se presente, copio split local nBaseSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_BASESPLIT) @@ -894,60 +1085,63 @@ local function CalculateOutlineFromAreaOutline( nAreaId) while nBaseOutlineId do -- recupero la curva di outline del base outline da cui deriva e la copio local nSouId = EgtGetInfo( nBaseOutlineId, WIN_SOU, 'i') - local nCopyId = EgtGetInfo( nSouId, WIN_COPY, 'i') + local nCopyId = EgtGetInfo( nSouId, WIN_COPY, 'i') or GDB_ID.NULL local nOutlineId = EgtCopy( nCopyId, nOutlineLayerId) - -- recupero profilo - local sSashProfile = EgtGetInfo( nBaseOutlineId, WIN_PROFILETYPE) - local nSashProfileId = EgtGetFirstNameInGroup( nSashProfileLayerId, sSashProfile) - - -- calcolo offset sulla z dell'anta - local dSashZOffset = EgtGetInfo( nSashProfileId, WIN_DELTA, 'd') - - -- sposto anta in Z - EgtMove( nOutlineId, Z_AX() * dSashZOffset) - - -- sistemo le info - EgtSetInfo( nBaseOutlineId, WIN_COPY, nOutlineId) - EgtSetInfo( nOutlineId, WIN_COPY, nBaseOutlineId) - EgtSetInfo( nOutlineId, WIN_PROFILETYPE, sSashProfile) - if EgtGetName( nOutlineId) == WIN_BOTTOM then - CopyInfo( nOutlineId, nAreaId, WIN_BOTTOMRAIL) - end - EgtRemoveInfo( nOutlineId, WIN_PRF_CHANGE) - EgtRemoveInfo( nOutlineId, WIN_REF_SPLIT) - EgtRemoveInfo( nOutlineId, WIN_THRESHOLD) - - -- verifico se outline e' segmento battente o ricevente ( che quindi deriva da split di tipo french) - local bOnFrenchSplit = EgtGetInfo( nBaseOutlineId, WIN_CRV_ON_FRENCH_SPLIT, 'b') or false - - -- se outline non è segmento battente o ricevente necessita di offset - if not bOnFrenchSplit then + if nOutlineId then + -- recupero profilo + local sSashProfile = EgtGetInfo( nBaseOutlineId, WIN_PROFILETYPE) + local nSashProfileId = EgtGetFirstNameInGroup( nSashProfileLayerId, sSashProfile) - -- recupero a ritroso il profilo dell'elemento del frame su cui poggia - local nFrameBaseOutlineId = nSouId - local sFrameProfile = EgtGetInfo( nFrameBaseOutlineId, WIN_PROFILETYPE) - while not sFrameProfile and nFrameBaseOutlineId do - nFrameBaseOutlineId = EgtGetInfo( nFrameBaseOutlineId, WIN_SOU , 'i') - sFrameProfile = EgtGetInfo( nFrameBaseOutlineId or GDB_ID.NULL, WIN_PROFILETYPE) + -- calcolo offset sulla z dell'anta + local dSashZOffset = EgtGetInfo( nSashProfileId, WIN_DELTA, 'd') + + -- sposto anta in Z + EgtMove( nOutlineId, Z_AX() * dSashZOffset) + + -- sistemo le info + EgtSetInfo( nBaseOutlineId, WIN_COPY, nOutlineId) + EgtSetInfo( nOutlineId, WIN_COPY, nBaseOutlineId) + EgtSetInfo( nOutlineId, WIN_PROFILETYPE, sSashProfile) + if EgtGetName( nOutlineId) == WIN_BOTTOM then + CopyInfo( nOutlineId, nAreaId, WIN_BOTTOMRAIL) end - local nFrameProfileId = EgtGetFirstNameInGroup( nFrameProfileLayerId, sFrameProfile) + EgtRemoveInfo( nOutlineId, WIN_PRF_CHANGE) + EgtRemoveInfo( nOutlineId, WIN_REF_SPLIT) + EgtRemoveInfo( nOutlineId, WIN_INV_SPLIT) + EgtRemoveInfo( nOutlineId, WIN_THRESHOLD) - -- calcolo il box del riferimento del profilo del frame - local b3FrameProfile = GetProfileLocalBox( nFrameProfileId) - -- calcolo offset perpendicolare - local sOverlapInfo = EgtIf( EgtGetName( nOutlineId) == WIN_BOTTOM, WIN_SASH_BOTTOM_OVERLAP, WIN_SASH_TOP_OVERLAP) - local dOverlap = EgtGetInfo( nFrameProfileId, sOverlapInfo, 'd') - local dSashPerpOffset = abs( b3FrameProfile:getMin():getX()) - dOverlap - - -- faccio offset - EgtOffsetCurve( nOutlineId, - dSashPerpOffset) + -- verifico se outline e' segmento battente o ricevente ( che quindi deriva da split di tipo french) + local bOnFrenchSplit = EgtGetInfo( nBaseOutlineId, WIN_CRV_ON_FRENCH_SPLIT, 'b') or false + + -- se outline non è segmento battente o ricevente necessita di offset + if not bOnFrenchSplit then + + -- recupero a ritroso il profilo dell'elemento del frame su cui poggia + local nFrameBaseOutlineId = nSouId + local sFrameProfile = EgtGetInfo( nFrameBaseOutlineId, WIN_PROFILETYPE) + while not sFrameProfile and nFrameBaseOutlineId do + nFrameBaseOutlineId = EgtGetInfo( nFrameBaseOutlineId, WIN_SOU , 'i') + sFrameProfile = EgtGetInfo( nFrameBaseOutlineId or GDB_ID.NULL, WIN_PROFILETYPE) + end + local nFrameProfileId = EgtGetFirstNameInGroup( nFrameProfileLayerId, sFrameProfile) + + -- calcolo il box del riferimento del profilo del frame + local b3FrameProfile = GetProfileLocalBox( nFrameProfileId) + -- calcolo offset perpendicolare + local sOverlapInfo = EgtIf( EgtGetName( nOutlineId) == WIN_BOTTOM, WIN_SASH_BOTTOM_OVERLAP, WIN_SASH_TOP_OVERLAP) + local dOverlap = EgtGetInfo( nFrameProfileId, sOverlapInfo, 'd') + local dSashPerpOffset = abs( b3FrameProfile:getMin():getX()) - dOverlap + + -- faccio offset + EgtOffsetCurve( nOutlineId, - dSashPerpOffset) + end end nBaseOutlineId = EgtGetNext( nBaseOutlineId) end -- accorcio gli offset - TrimAndOrientOrderedCurves( EgtGetAllInGroup( nOutlineLayerId), true) + TrimOrderedCurves( EgtGetAllInGroup( nOutlineLayerId), 1) -- se presente, copio split local nBaseSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_BASESPLIT) @@ -982,48 +1176,51 @@ local function CalculateOutlineFromAreaOutline( nAreaId) while nBaseOutlineId do -- recupero la curva di outline del base outline da cui deriva e la copio local nSouId = EgtGetInfo( nBaseOutlineId, WIN_SOU, 'i') - local nCopyId = EgtGetInfo( nSouId, WIN_COPY, 'i') + local nCopyId = EgtGetInfo( nSouId, WIN_COPY, 'i') or GDB_ID.NULL local nOutlineId = EgtCopy( nCopyId, nOutlineLayerId) - -- sistemo le info - EgtSetInfo( nBaseOutlineId, WIN_COPY, nOutlineId) - EgtSetInfo( nOutlineId, WIN_COPY, nBaseOutlineId) - -- recupero a ritroso il profilo dell'elemento su cui poggia ( anta, split o frame) - local nParentBaseOutlineId = nSouId - local sParentProfile = EgtGetInfo( nParentBaseOutlineId, WIN_PROFILETYPE) - while not sParentProfile and nParentBaseOutlineId do - nParentBaseOutlineId = EgtGetInfo( nParentBaseOutlineId, WIN_SOU , 'i') - sParentProfile = EgtGetInfo( nParentBaseOutlineId or GDB_ID.NULL, WIN_PROFILETYPE) + if nOutlineId then + -- sistemo le info + EgtSetInfo( nBaseOutlineId, WIN_COPY, nOutlineId) + EgtSetInfo( nOutlineId, WIN_COPY, nBaseOutlineId) + + -- recupero a ritroso il profilo dell'elemento su cui poggia ( anta, split o frame) + local nParentBaseOutlineId = nSouId + local sParentProfile = EgtGetInfo( nParentBaseOutlineId, WIN_PROFILETYPE) + while not sParentProfile and nParentBaseOutlineId do + nParentBaseOutlineId = EgtGetInfo( nParentBaseOutlineId, WIN_SOU , 'i') + sParentProfile = EgtGetInfo( nParentBaseOutlineId or GDB_ID.NULL, WIN_PROFILETYPE) + end + local nParentOutlineId = EgtGetInfo( nParentBaseOutlineId, WIN_COPY, 'i') + local nParentProfileId = GetOutlineProfileId( nParentOutlineId, true) + sParentProfile = EgtGetName( nParentProfileId) + + -- calcolo il box del riferimento del profilo del frame + local b3FrameProfile = GetProfileLocalBox( nParentProfileId) + -- calcolo offset perpendicolare e sulla z dell'anta + local dOverlap = EgtGetInfo( nParentProfileId, WIN_FILLOVERLAP, 'd') + local bMixedSplit = ( EgtGetInfo( nParentOutlineId, WIN_PRF_CHANGE, 'b') or false) and EgtGetName( nParentOutlineId) == WIN_SPLIT + local dDimRef = EgtIf( bMixedSplit, b3FrameProfile:getMax():getX(), b3FrameProfile:getMin():getX()) + local dFillPerpOffset = abs( dDimRef) - dOverlap + if sParentProfile == WIN_FILL_RAIL then + -- se bottom rail considero la distanza necessaria per il numero di bottomrail richiesti + local nBottomRails = EgtGetInfo( nParentOutlineId, WIN_BOTTOMRAIL, 'i') + local dRailDelta1 = EgtGetInfo( nParentProfileId, WIN_RAILDELTA .. '1', 'd') + local dRailDelta2 = EgtGetInfo( nParentProfileId, WIN_RAILDELTA .. '2', 'd') + dFillPerpOffset = dFillPerpOffset + dRailDelta1 + ( nBottomRails - 1) * dRailDelta2 + end + -- faccio offset + EgtOffsetCurve( nOutlineId, - dFillPerpOffset) + + -- movimento in z + local dFillZOffset = EgtGetInfo( nParentProfileId, WIN_FILLDELTA, 'd') + EgtMove( nOutlineId, Z_AX() * dFillZOffset) end - local nParentOutlineId = EgtGetInfo( nParentBaseOutlineId, WIN_COPY, 'i') - local nParentProfileId = GetOutlineProfileId( nParentOutlineId, true) - sParentProfile = EgtGetName( nParentProfileId) - - -- calcolo il box del riferimento del profilo del frame - local b3FrameProfile = GetProfileLocalBox( nParentProfileId) - -- calcolo offset perpendicolare e sulla z dell'anta - local dOverlap = EgtGetInfo( nParentProfileId, WIN_FILLOVERLAP, 'd') - local bMixedSplit = ( EgtGetInfo( nParentOutlineId, WIN_PRF_CHANGE, 'b') or false) and EgtGetName( nParentOutlineId) == WIN_SPLIT - local dDimRef = EgtIf( bMixedSplit, b3FrameProfile:getMax():getX(), b3FrameProfile:getMin():getX()) - local dFillPerpOffset = abs( dDimRef) - dOverlap - if sParentProfile == WIN_FILL_RAIL then - -- se bottom rail considero la distanza necessaria per il numero di bottomrail richiesti - local nBottomRails = EgtGetInfo( nParentOutlineId, WIN_BOTTOMRAIL, 'i') - local dRailDelta1 = EgtGetInfo( nParentProfileId, WIN_RAILDELTA .. '1', 'd') - local dRailDelta2 = EgtGetInfo( nParentProfileId, WIN_RAILDELTA .. '2', 'd') - dFillPerpOffset = dFillPerpOffset + dRailDelta1 + ( nBottomRails - 1) * dRailDelta2 - end - -- faccio offset - EgtOffsetCurve( nOutlineId, - dFillPerpOffset) - - -- movimento in z - local dFillZOffset = EgtGetInfo( nParentProfileId, WIN_FILLDELTA, 'd') - EgtMove( nOutlineId, Z_AX() * dFillZOffset) nBaseOutlineId = EgtGetNext( nBaseOutlineId) end -- accorcio gli offset - TrimAndOrientOrderedCurves( EgtGetAllInGroup( nOutlineLayerId), true) + TrimOrderedCurves( EgtGetAllInGroup( nOutlineLayerId), 1) end end @@ -1077,126 +1274,6 @@ local function GetOutlineProfileType( nOutlineId, bForceBottomRail, nBottomRail) return nProfileType end ---------------------------------------------------------------------- --- funzione che calcola gli outline precedenti e successivi nel caso di split -local function GetSplitOtherOutline( nSplitId, nSurfSplit, nOutlineId, bPrevOrNext) - - local vOutlineIds = {} - - -- verifico se devo controllare la curva precedente o successiva dell'outline corrente - local nCrv - local bPrevOutline = false - local ptRef = EgtIf( bPrevOrNext, EgtSP( nSplitId), EgtEP( nSplitId)) - local dPar = EgtCurveParamAtPoint( nOutlineId, ptRef) - local dLenInt = EgtCurveLengthAtParam( nOutlineId, dPar) - local dLenTot = EgtCurveLength( nOutlineId) - -- se l'intersezione è più vicina alla fine dell'outline devo controllare il suo next, altrimenti il suo prev - if abs( dLenTot - dLenInt) < dLenInt then - nCrv = EgtGetNext( nOutlineId) or EgtGetFirstInGroup( EgtGetParent( nOutlineId)) - else - bPrevOutline = true - nCrv = EgtGetPrev( nOutlineId) or EgtGetLastInGroup( EgtGetParent( nOutlineId)) - end - - -- recupero il geo associato e costruisco superficie test - local nPartId = FindAssociatedPart( nCrv, true) - local nGeoId = EgtGetFirstNameInGroup( nPartId, WIN_GEO) - local nGeoOut = EgtGetFirstNameInGroup( nGeoId, WIN_GEO_OUT) - local nGeoIn = EgtGetFirstNameInGroup( nGeoId, WIN_GEO_IN) - local nCrv1 = EgtCopyGlob( nGeoOut, nGeoId) - local nCrv2 = EgtCopyGlob( nGeoIn, nGeoId) - local nCompoTest = EgtCurveCompo( nGeoId, nCrv1) - local dParTest = 0.2 - if bPrevOutline then - -- considero solo la parte finale del pezzo - EgtTrimCurveStartAtParam( nCompoTest, 1 - dParTest) - EgtAddCurveCompoLine( nCompoTest, EgtSP( nCrv2)) - EgtTrimCurveEndAtParam( nCrv2, dParTest) - else - -- considero solo la parte iniziale del pezzo - EgtTrimCurveEndAtParam( nCompoTest, dParTest) - EgtTrimCurveStartAtParam( nCrv2, 1 - dParTest) - EgtAddCurveCompoLine( nCompoTest, EgtSP( nCrv2)) - end - EgtAddCurveCompoCurve( nCompoTest, nCrv2) - EgtCloseCurveCompo( nCompoTest) - local nSurfTest = EgtSurfFlatRegion( nGeoId, { nCompoTest}) - - -- verifico se le due regioni interferiscono - if EgtSurfFrTestExternal( nSurfSplit, nSurfTest) then - vOutlineIds = { nOutlineId} - else - -- aggiungo la curva trovata tra le curve di outline da considerare rispettando l'ordinamento - if bPrevOutline then - vOutlineIds = { nCrv, nOutlineId} - else - vOutlineIds = { nOutlineId, nCrv} - end - end - - EgtErase( nCompoTest) - EgtErase( nSurfTest) - - return vOutlineIds -end - ---------------------------------------------------------------------- --- funzione che recupera gli outline precedenti e successivi -local function GetPrevNextOutline( nProfileType, nOutlineId, nOutlineLayerId) - - local vPrevOutlineId = {} - local vNextOutlineId = {} - - if nProfileType ~= WIN_PRF.SPLIT then - vPrevOutlineId = { EgtGetPrev( nOutlineId) or EgtGetLastInGroup( nOutlineLayerId)} - vNextOutlineId = { EgtGetNext( nOutlineId) or EgtGetFirstInGroup( nOutlineLayerId)} - else - -- se split recupero tutte le curve di base outline che lo tagliano - local vPrevBaseOutlineId = EgtGetInfo( nOutlineId, WIN_SPLIT_STARTINTERS, 'vi') - for i = 1, #vPrevBaseOutlineId do - -- recupero l'outline associato al base outline che lo taglia - table.insert( vPrevOutlineId, EgtGetInfo( vPrevBaseOutlineId[i], WIN_COPY, 'i')) - end - local vNextBaseOutlineId = EgtGetInfo( nOutlineId, WIN_SPLIT_ENDINTERS, 'vi') - for i = 1, #vNextBaseOutlineId do - table.insert( vNextOutlineId, EgtGetInfo( vNextBaseOutlineId[i], WIN_COPY, 'i')) - end - - -- se lo split è tagliato da una sola curva di base outline, verifico se coinvolge altre curve - if #vPrevBaseOutlineId == 1 or #vNextBaseOutlineId == 1 then - - -- costruisco una regione approssimata per il pezzo dello split - local nGrp = EgtGetParent( nOutlineId) - local nSplitProfileId = GetOutlineProfileId( nOutlineId, false) - local b3Profile = GetProfileLocalBox( nSplitProfileId) - local nCrvOut = EgtCopyGlob( nOutlineId, nGrp) - local nCrvIn = EgtCopyGlob( nOutlineId, nGrp) - EgtOffsetCurve( nCrvOut, b3Profile:getMax():getX()) - EgtOffsetCurve( nCrvIn, b3Profile:getMin():getX()) - EgtInvertCurve( nCrvIn) - local nCompoTest = EgtCurveCompo( nGrp, nCrvOut) - EgtAddCurveCompoLine( nCompoTest, EgtSP( nCrvIn)) - EgtAddCurveCompoCurve( nCompoTest, nCrvIn) - EgtCloseCurveCompo( nCompoTest) - local nSurfTest = EgtSurfFlatRegion( nGrp, nCompoTest) - - -- se necessario aggiorno il prev - if #vPrevBaseOutlineId == 1 and EgtGetName( vPrevBaseOutlineId[1]) ~= WIN_SPLIT then - vPrevOutlineId = GetSplitOtherOutline( nOutlineId, nSurfTest, vPrevOutlineId[1], true) - end - -- se necessario aggiorno il next - if #vNextOutlineId == 1 and EgtGetName( vNextBaseOutlineId[1]) ~= WIN_SPLIT then - vNextOutlineId = GetSplitOtherOutline( nOutlineId, nSurfTest, vNextOutlineId[1], false) - end - - EgtErase( nSurfTest) - EgtErase( nCompoTest) - end - end - - return vPrevOutlineId, vNextOutlineId -end - --------------------------------------------------------------------- -- funzione che restituisce il tipo di controprofilo dell'outline adiacente local function GetProfileCtrIn( nPrevOutlineId, nOutlineId, nPrevProfileId) @@ -1231,58 +1308,195 @@ local function GetProfileCtrIn( nPrevOutlineId, nOutlineId, nPrevProfileId) end --------------------------------------------------------------------- --- funzione che crea la superficie corrispondente al Geo di un pezzo gestendo i casi di autointersezione -local function CreateGeoArea( nGeoLayId, nDestLayId, bKeepBorder) +-- funzione che costruisce una superficie estrudendo il nSectionId lungo l'outline +local function CreateProfileSurfById( nOutlineId, nProfileId, nSectionId, dExtraLen, nLayerId) - -- recupero le curve left e right e verifico se hanno orientamento coerente ( quindi non generano autointersezioni) - local bAutointers = false - local vLeft = EgtGetNameInGroup( nGeoLayId, WIN_LEFT) - local vRight = EgtGetNameInGroup( nGeoLayId, WIN_RIGHT) - if #vLeft == 2 and not AreSamePointApprox( EgtEP( vLeft[1]), EgtSP( vLeft[2])) then - bAutointers = true - -- se orientamento non coerente devo ignorare la prima curva - vLeft[1] = GDB_ID.NULL - end - if #vRight == 2 and not AreSamePointApprox( EgtEP( vRight[1]), EgtSP( vRight[2])) then - bAutointers = true - -- se orientamento non coerente devo ignorare la seconda curva - vRight[2] = GDB_ID.NULL - end - - local nCompoId - if not bAutointers then - -- se no autointersezioni costruisco il bordo del geo usando direttamente le sue curve - local vCrvs = EgtGetAllInGroup( nGeoLayId) - nCompoId = EgtCurveCompo( nDestLayId, vCrvs, false) + -- creo guida con estensione in tangenza + local nGuideId = EgtCopy( nOutlineId, nLayerId) + if EgtGetType( nGuideId) == GDB_TY.CRV_LINE then + EgtExtendCurveStartByLen( nGuideId, dExtraLen) + EgtExtendCurveEndByLen( nGuideId, dExtraLen) else - -- nel caso di autointersezione devo ignorare le curve left e right con orientamento non coerente - local vGeoCrvs = {} - local nOutId = EgtGetFirstNameInGroup( nGeoLayId, WIN_GEO_OUT) - vGeoCrvs[1] = EgtCopyGlob( nOutId, nDestLayId) - for i = 1, #vRight do - if vRight[i] ~= GDB_ID.NULL then - table.insert( vGeoCrvs, EgtCopyGlob( vRight[i], nDestLayId)) - end - end - local nInId = EgtGetFirstNameInGroup( nGeoLayId, WIN_GEO_IN) - table.insert( vGeoCrvs, EgtCopyGlob( nInId, nDestLayId)) - for i = 1, #vLeft do - if vLeft[i] ~= GDB_ID.NULL then - table.insert( vGeoCrvs, EgtCopyGlob( vLeft[i], nDestLayId)) - end - end - -- taglio le curve - TrimAndOrientOrderedCurves( vGeoCrvs, false) - -- creo compo - nCompoId = EgtCurveCompo( nDestLayId, vGeoCrvs) + nGuideId = EgtCurveCompo( nLayerId, nGuideId) + EgtAddCurveCompoLineTg( nGuideId, dExtraLen) + EgtAddCurveCompoLineTg( nGuideId, dExtraLen, false) + end + -- correzione nel caso di bottomrail + local sProfileType = EgtGetInfo( nProfileId, WIN_PRF_TYPE) + if sProfileType == WIN_RAIL or sProfileType == WIN_FILL_RAIL then + local dOffs = EgtGetInfo( nProfileId, WIN_RAILDELTA, 'd') + EgtOffsetCurve( nGuideId, - dOffs) + end + + -- verifico se necessaria inversione della guida nel caso sia curva "virtuale" ( ovvero in area null o split) che deriva da pezzo di split + if EgtExistsInfo( nOutlineId, WIN_INV_SPLIT) then + EgtInvertCurve( nGuideId) end - local nArea = EgtSurfFlatRegion( nDestLayId, nCompoId) - if not bKeepBorder then - EgtErase( nCompoId) + -- recupero il profilo da estrudere + local nSectionRefId = EgtCopyGlob( nSectionId, nLayerId) + + -- posiziono la sezione di estrusione sulla guida : + -- recupero frame del profilo + local nProfileFrameId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME) + local frProfile = EgtFR( nProfileFrameId, GDB_ID.ROOT) + frProfile:invert() + -- calcolo il frame di destinazione sulla guida + local frDest = Frame3d( EgtSP( nGuideId), - EgtSV( nGuideId), GDB_RT.GLOB) + -- posiziono con i riferimenti + EgtTransform( nSectionRefId, frProfile, GDB_RT.GLOB) + EgtTransform( nSectionRefId, frDest, GDB_RT.GLOB) + + -- creo la superfice di estrusione + local nStmId = EgtSurfTmSwept( nLayerId, nSectionRefId, nGuideId, false, WIN_SURF_APPROX) + EgtErase( nGuideId) + EgtErase( nSectionRefId) + + return nStmId +end + +--------------------------------------------------------------------- +-- come CreateProfileSurfById ma riceve il nome della sezione da estrudere +local function CreateProfileSurf( nOutlineId, nProfileId, sSectionName, dExtraLen, nLayerId) + -- recupero l'id della sezione da estrudere + local nSectionId = EgtGetFirstNameInGroup( nProfileId, sSectionName) + if not nSectionId then return end + return CreateProfileSurfById( nOutlineId, nProfileId, nSectionId, dExtraLen, nLayerId) +end + +--------------------------------------------------------------------- +-- funzione che verifica gli outlines prev/next per lo split controllando l'interferenza tra i profili +local function TestSplitTrimOutlines( nOutlineId, vTrimOutlines, nMainProfile, b3Profile, nGrpTmp, bPrevOrNext) + + if #vTrimOutlines == 1 then + -- verifico se conviene testare la curva precedente o successiva + local bBefore = false + local nRefCurve + local ptRef = EgtIf( bPrevOrNext, EgtSP( nOutlineId), EgtEP( nOutlineId)) + local dPar = EgtCurveParamAtPoint( vTrimOutlines[1], ptRef) + if dPar > 0.5 then + nRefCurve = EgtGetNext( vTrimOutlines[1]) or EgtGetFirstInGroup( EgtGetParent( vTrimOutlines[1])) + else + bBefore = true + nRefCurve = EgtGetPrev( vTrimOutlines[1]) or EgtGetLastInGroup( EgtGetParent( vTrimOutlines[1])) + end + + -- primo test : controllo interferenza tra i box dei pezzi + local nRefPart = FindAssociatedPart( nRefCurve, true) + local nRefGeo = EgtGetFirstNameInGroup( nRefPart, WIN_GEO) + local nRefSurf = EgtGetFirstNameInGroup( nRefGeo, WIN_GEO_SURF) + local nOutId = EgtOffsetCurveAdv( nOutlineId, b3Profile:getMax():getX()) + local nInId = EgtOffsetCurveAdv( nOutlineId, b3Profile:getMin():getX()) + EgtRelocateGlob( nOutId, nGrpTmp) + EgtRelocateGlob( nInId, nGrpTmp) + + local _, nCnt1 = EgtTrimCurveWithRegion( nOutId, nRefSurf, true, false) + local _, nCnt2 = EgtTrimCurveWithRegion( nInId, nRefSurf, true, false) + if nCnt1 == 0 and nCnt2 == 0 then + return vTrimOutlines + end + + if bBefore then + vTrimOutlines = { nRefCurve, vTrimOutlines[1]} + else + vTrimOutlines = { vTrimOutlines[1], nRefCurve} + end end - return nArea + local vRealTrimOutlines = {} + + -- recupero i profili e i controprofili con cui tagliare + local nProfile1 = GetOutlineProfileId( vTrimOutlines[1], true) + local nProfile2 = GetOutlineProfileId( vTrimOutlines[2], true) + local sCtrIn1 = GetProfileCtrIn( vTrimOutlines[1], nOutlineId, nProfile1) + local sCtrIn2 = GetProfileCtrIn( vTrimOutlines[2], nOutlineId, nProfile2) + + -- creo il solido + local dExtraLen = b3Profile:getDimX() + local nMainSurf = CreateProfileSurf( nOutlineId, nMainProfile, WIN_SECTION, 4 * dExtraLen, nGrpTmp) + EgtCutSurfTmPlane( nMainSurf, EgtMP( nOutlineId), EgtIf( bPrevOrNext, 1, -1) * EgtSV( nOutlineId)) + + -- testo la curva 1 + local nTestSurf1 = CreateProfileSurf( vTrimOutlines[1], nProfile1, sCtrIn1, 4 * dExtraLen, nGrpTmp) + if AreSameVectorApprox( EgtEV( vTrimOutlines[1]), EgtSV( vTrimOutlines[2])) then + EgtCutSurfTmPlane( nTestSurf1, EgtEP( vTrimOutlines[1]), EgtEV( vTrimOutlines[1]), false) + else + local nTrimSurf2 = CreateProfileSurf( vTrimOutlines[2], nProfile2, WIN_OFST .. sCtrIn2, 4 * dExtraLen, nGrpTmp) + EgtSurfTmCut( nTestSurf1, nTrimSurf2, true, false) + end + local nId, _, nCrvCnt = EgtSurfTmSurfTmInters( nMainSurf, nTestSurf1, nGrpTmp) + if nId and nCrvCnt > 0 then + vRealTrimOutlines[1] = vTrimOutlines[1] + end + + -- testo la curva 2 + local nTestSurf2 = CreateProfileSurf( vTrimOutlines[2], nProfile2, sCtrIn2, 4 * dExtraLen, nGrpTmp) + if AreSameVectorApprox( EgtEV( vTrimOutlines[1]), EgtSV( vTrimOutlines[2])) then + EgtCutSurfTmPlane( nTestSurf2, EgtEP( vTrimOutlines[1]), - EgtEV( vTrimOutlines[1]), false) + else + local nTrimSurf1 = CreateProfileSurf( vTrimOutlines[1], nProfile1, WIN_OFST .. sCtrIn1, 4 * dExtraLen, nGrpTmp) + EgtSurfTmCut( nTestSurf2, nTrimSurf1, true, false) + end + local nId2, _, nCrvCnt2 = EgtSurfTmSurfTmInters( nMainSurf, nTestSurf2, nGrpTmp) + if nId2 and nCrvCnt2 > 0 then + table.insert( vRealTrimOutlines, vTrimOutlines[2]) + end + + return vRealTrimOutlines +end + +--------------------------------------------------------------------- +-- funzione che recupera gli outline precedenti e successivi +local function GetPrevNextOutline( nProfileType, nOutlineId, nOutlineLayerId) + + local vPrevOutlineId = {} + local vNextOutlineId = {} + + if nProfileType ~= WIN_PRF.SPLIT then + vPrevOutlineId = { EgtGetPrev( nOutlineId) or EgtGetLastInGroup( nOutlineLayerId)} + vNextOutlineId = { EgtGetNext( nOutlineId) or EgtGetFirstInGroup( nOutlineLayerId)} + + else + -- se split recupero tutte le curve di base outline che lo tagliano dalle info + local vPrevBaseOutlineId = EgtGetInfo( nOutlineId, WIN_SPLIT_STARTINTERS, 'vi') + local vNextBaseOutlineId = EgtGetInfo( nOutlineId, WIN_SPLIT_ENDINTERS, 'vi') + -- recupero gli outlines associati + for i = 1, #vPrevBaseOutlineId do + vPrevOutlineId[i] = EgtGetInfo( vPrevBaseOutlineId[i], WIN_COPY, 'i') + end + for i = 1, #vNextBaseOutlineId do + vNextOutlineId[i] = EgtGetInfo( vNextBaseOutlineId[i], WIN_COPY, 'i') + end + + -- controllo validità delle curve trovate verificando l'interferenza tra i profili + local nGrpTmp = EgtGroup( GDB_ID.ROOT) + local nMainProfile = GetOutlineProfileId( nOutlineId) + local b3Profile = GetProfileLocalBox( nMainProfile) + vPrevOutlineId = TestSplitTrimOutlines( nOutlineId, vPrevOutlineId, nMainProfile, b3Profile, nGrpTmp, true) + vNextOutlineId = TestSplitTrimOutlines( nOutlineId, vNextOutlineId, nMainProfile, b3Profile, nGrpTmp, false) + EgtErase( nGrpTmp) + + -- considero come curve prev e next quelle associate ad un pezzo e non curve virtuali per rendere più solidi i conti successivi + -- verifico la coerenza dell'orientamento e la indico con il segno ( > 0 concorde, < 0 discorde e va invertita) + for i = 1, #vPrevOutlineId do + local nPart = FindAssociatedPart( vPrevOutlineId[i], true) + local bInvert = EgtGetInfo( vPrevOutlineId[i], WIN_INV_SPLIT, 'b') or false + vPrevOutlineId[i] = EgtGetInfo( nPart, WIN_REF_OUTLINE, 'i') + if bInvert then + vPrevOutlineId[i] = - vPrevOutlineId[i] + end + end + for i = 1, #vNextOutlineId do + local nPart = FindAssociatedPart( vNextOutlineId[i], true) + local bInvert = EgtGetInfo( vNextOutlineId[i], WIN_INV_SPLIT, 'b') or false + vNextOutlineId[i] = EgtGetInfo( nPart, WIN_REF_OUTLINE, 'i') + if bInvert then + vNextOutlineId[i] = - vNextOutlineId[i] + end + end + end + + return vPrevOutlineId, vNextOutlineId end @@ -1345,26 +1559,26 @@ local function CalcProfiles( nPartId, nOutlineId, vPrevOutlineId, vNextOutlineId -- recupero profili start e ne creo copia -- se il tipo corrente è split il pezzo va tagliato con il bottomrail, altrimenti con il bottom for i = 1, #vPrevOutlineId do - local nOrigStartProfileId = GetOutlineProfileId( vPrevOutlineId[i], nProfileType == WIN_PRF.SPLIT) + local nOrigStartProfileId = GetOutlineProfileId( abs( vPrevOutlineId[i]), nProfileType == WIN_PRF.SPLIT) local nStartProfileId = EgtCopy( nOrigStartProfileId, nProfileLayerId) local sStartProfileType = EgtGetName( nStartProfileId) EgtSetInfo( nStartProfileId, WIN_PRF_TYPE, sStartProfileType) EgtSetName( nStartProfileId, WIN_PRF_START) if sStartProfileType == WIN_FILL_RAIL then - local nBottomRailTot = EgtGetInfo( vPrevOutlineId[i], WIN_BOTTOMRAIL, 'i') + local nBottomRailTot = EgtGetInfo( abs( vPrevOutlineId[i]), WIN_BOTTOMRAIL, 'i') SaveRailDelta( nStartProfileId, nBottomRailTot) end end -- recupero profili end e ne creo copia for i = 1, #vNextOutlineId do - local nOrigEndProfileId = GetOutlineProfileId( vNextOutlineId[i], nProfileType == WIN_PRF.SPLIT) + local nOrigEndProfileId = GetOutlineProfileId( abs( vNextOutlineId[i]), nProfileType == WIN_PRF.SPLIT) local nEndProfileId = EgtCopy( nOrigEndProfileId, nProfileLayerId) local sEndProfileType = EgtGetName( nEndProfileId) EgtSetInfo( nEndProfileId, WIN_PRF_TYPE, sEndProfileType) EgtSetName( nEndProfileId, WIN_PRF_END) if sEndProfileType == WIN_FILL_RAIL then - local nBottomRailTot = EgtGetInfo( vPrevOutlineId[i], WIN_BOTTOMRAIL, 'i') + local nBottomRailTot = EgtGetInfo( abs( vNextOutlineId[i]), WIN_BOTTOMRAIL, 'i') SaveRailDelta( nEndProfileId, nBottomRailTot) end end @@ -1424,14 +1638,16 @@ local function CreateFrameGeo( nOutlineId, vPrevOutlineId, vNextOutlineId, nStar EgtSetName( nOutId, WIN_GEO_OUT) local nSemiProfileOut = EgtGetFirstNameInGroup( nCurrProfileId, WIN_OUT) or EgtGetFirstNameInGroup( nCurrProfileId, WIN_IN .. '1') EgtSetInfo( nOutId, WIN_SEMI_PROFILE, nSemiProfileOut) + EgtSetInfo( nOutId, WIN_REF_OUTLINE, nOutlineId) - -- cruva in + -- curva in local nInId = EgtCopy( nOutlineId, nGeoLayerId) EgtOffsetCurve( nInId, dCurrOffset - b3CurrProfileFrame:getDimX()) EgtInvertCurve( nInId) EgtSetName( nInId, WIN_GEO_IN) local nSemiProfileIn = EgtGetFirstNameInGroup( nCurrProfileId, WIN_IN) or EgtGetFirstNameInGroup( nCurrProfileId, WIN_IN .. '2') or EgtGetFirstNameInGroup( nCurrProfileId, WIN_MIXED_COMMON .. WIN_IN) EgtSetInfo( nInId, WIN_SEMI_PROFILE, nSemiProfileIn) + EgtSetInfo( nInId, WIN_REF_OUTLINE, nOutlineId) -- curve left local vPrevProfileId = EgtGetNameInGroup( nProfileLayerId, WIN_PRF_START) @@ -1440,7 +1656,7 @@ local function CreateFrameGeo( nOutlineId, vPrevOutlineId, vNextOutlineId, nStar local nPrevSemiProfile if nStartPartJointType == WIN_PART_JNT.ANGLED then -- calcolo la bisettrice - local vtMedia = ( ( EgtSV( nOutlineId) - EgtEV( vPrevOutlineId[i])) / 2) + local vtMedia = ( ( EgtSV( nOutlineId) - EgtEV( abs( vPrevOutlineId[i]))) / 2) if not vtMedia:normalize() then vtMedia = EgtSV( nOutlineId) vtMedia:rotate( Z_AX(), 90) @@ -1448,9 +1664,12 @@ local function CreateFrameGeo( nOutlineId, vPrevOutlineId, vNextOutlineId, nStar nPrevCurveId = EgtLinePVL( nGeoLayerId, EgtSP( nOutlineId), vtMedia, 3 * b3CurrProfileFrame:getDimX()) EgtInvertCurve( nPrevCurveId) else - nPrevCurveId = EgtCopy( vPrevOutlineId[i], nGeoLayerId) + nPrevCurveId = EgtCopy( abs( vPrevOutlineId[i]), nGeoLayerId) + if vPrevOutlineId[i] < 0 then + EgtInvertCurve( nPrevCurveId) + end if nStartPartJointType == WIN_PART_JNT.SHORT then - local sCtrIn = GetProfileCtrIn( vPrevOutlineId[i], nOutlineId, vPrevProfileId[i]) + local sCtrIn = GetProfileCtrIn( abs( vPrevOutlineId[i]), nOutlineId, vPrevProfileId[i]) local dCPDelta = GetDeltaProfile( vPrevProfileId[i], sCtrIn) EgtOffsetCurve( nPrevCurveId, - dCPDelta) -- ricavo il semiprofilo associato @@ -1461,8 +1680,8 @@ local function CreateFrameGeo( nOutlineId, vPrevOutlineId, vNextOutlineId, nStar end EgtSetName( nPrevCurveId, WIN_GEO_LEFT) EgtSetInfo( nPrevCurveId, WIN_SEMI_PROFILE, nPrevSemiProfile) - EgtSetInfo( nPrevCurveId, WIN_REF_OUTLINE, vPrevOutlineId[i]) - EgtRelocateGlob( nPrevCurveId, nGeoLayerId, GDB_IN.LAST_SON) + EgtSetInfo( nPrevCurveId, WIN_REF_OUTLINE, abs( vPrevOutlineId[i])) + EgtRelocateGlob( nPrevCurveId, nGeoLayerId, GDB_IN.LAST_SON) end -- curve right @@ -1472,16 +1691,19 @@ local function CreateFrameGeo( nOutlineId, vPrevOutlineId, vNextOutlineId, nStar local nNextSemiProfile if nEndPartJointType == WIN_PART_JNT.ANGLED then -- calcolo la bisettrice - local vtMedia = ( ( EgtSV( vNextOutlineId[i]) - EgtEV( nOutlineId)) / 2) + local vtMedia = ( ( EgtSV( abs( vNextOutlineId[i])) - EgtEV( nOutlineId)) / 2) if not vtMedia:normalize() then vtMedia = EgtEV( nOutlineId) vtMedia:rotate( Z_AX(), 90) end nNextCurveId = EgtLinePVL( nGeoLayerId, EgtEP( nOutlineId), vtMedia, 3 * b3CurrProfileFrame:getDimX()) else - nNextCurveId = EgtCopy( vNextOutlineId[i], nGeoLayerId) + nNextCurveId = EgtCopy( abs( vNextOutlineId[i]), nGeoLayerId) + if vNextOutlineId[i] < 0 then + EgtInvertCurve( nNextCurveId) + end if nEndPartJointType == WIN_PART_JNT.SHORT then - local sCtrIn = GetProfileCtrIn( vNextOutlineId[i], nOutlineId, vNextProfileId[i]) + local sCtrIn = GetProfileCtrIn( abs( vNextOutlineId[i]), nOutlineId, vNextProfileId[i]) local dCPDelta = GetDeltaProfile( vNextProfileId[i], sCtrIn) EgtOffsetCurve( nNextCurveId, - dCPDelta) -- ricavo il semiprofilo associato @@ -1492,14 +1714,20 @@ local function CreateFrameGeo( nOutlineId, vPrevOutlineId, vNextOutlineId, nStar end EgtSetName( nNextCurveId, WIN_GEO_RIGHT) EgtSetInfo( nNextCurveId, WIN_SEMI_PROFILE, nNextSemiProfile) - EgtSetInfo( nNextCurveId, WIN_REF_OUTLINE, vNextOutlineId[i]) + EgtSetInfo( nNextCurveId, WIN_REF_OUTLINE, abs( vNextOutlineId[i])) EgtRelocateGlob( nNextCurveId, nInId, GDB_IN.BEFORE) end - - local vIds = EgtGetAllInGroup( nGeoLayerId) - + -- trim delle curve - TrimAndOrientOrderedCurves( vIds, false) + local vIds = EgtGetAllInGroup( nGeoLayerId) + local vMainCrvs = TrimOrderedCurves( vIds, 2) + + -- costruisco la regione + local nCompoId = EgtCurveCompo( nGeoLayerId, vMainCrvs, false) + local nAreaId = EgtSurfFlatRegion( nGeoLayerId, nCompoId) + EgtSetName( nAreaId, WIN_GEO_SURF) + EgtSetStatus( nAreaId, GDB_ST.OFF) + EgtErase( nCompoId) -- assegno spessore local dGeoH = b3CurrProfileFrame:getDimY() @@ -1514,7 +1742,7 @@ local function CreateFrameGeo( nOutlineId, vPrevOutlineId, vNextOutlineId, nStar if EgtGetType( nOutlineId) == GDB_TY.CRV_LINE then local vtS = EgtSV( nOutlineId) local frRef = Frame3d( ORIG(), vtS, Z_AX() ^ vtS, Z_AX()) - local b3Ref = EgtGetBBoxRef( nGeoLayerId, GDB_BB.STANDARD, frRef) + local b3Ref = EgtGetBBoxRef( nAreaId, GDB_BB.STANDARD, frRef) EgtSetInfo( nGeoLayerId, WIN_GEOLEN, b3Ref:getDimX()) end end @@ -1552,13 +1780,13 @@ local function CalcFrameGeo( nPartId, nOutlineId, nOutlineCrvNbr, nOutlineLayerI nStartJointType = vJoints[3] nEndJointType = vJoints[4] -- correzioni per caso a triangolo - if EgtGetName( vPrevOutlineId[1]) == WIN_BOTTOM then + if EgtGetName( abs( vPrevOutlineId[#vPrevOutlineId])) == WIN_BOTTOM then nStartJointType = vJoints[2] nEndJointType = vJoints[3] -- il lato top deve essere trattato come un left/right nel calcolo della giunzione nProfileTypeS = WIN_PRF.LEFT end - if EgtGetName( vNextOutlineId[1]) == WIN_BOTTOM then + if EgtGetName( abs( vNextOutlineId[1])) == WIN_BOTTOM then nStartJointType = vJoints[3] nEndJointType = vJoints[1] nProfileTypeE = WIN_PRF.LEFT @@ -1569,10 +1797,10 @@ local function CalcFrameGeo( nPartId, nOutlineId, nOutlineCrvNbr, nOutlineLayerI 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( vPrevOutlineId[1]), EgtSV( nOutlineId)) or EgtGetName( nOutlineId) == EgtGetName( vPrevOutlineId[1])) then + if nStartJointType ~= WIN_JNT.ANGLED and ( AreSameVectorApprox( EgtEV( abs( vPrevOutlineId[1])), EgtSV( nOutlineId)) or EgtGetName( nOutlineId) == EgtGetName( abs( vPrevOutlineId[1]))) then nStartJointType = WIN_JNT.ANGLED end - if nEndJointType ~= WIN_JNT.ANGLED and ( AreSameVectorApprox( EgtEV( nOutlineId), EgtSV( vNextOutlineId[1])) or EgtGetName( nOutlineId) == EgtGetName( vNextOutlineId[1])) then + if nEndJointType ~= WIN_JNT.ANGLED and ( AreSameVectorApprox( EgtEV( nOutlineId), EgtSV( abs( vNextOutlineId[1]))) or EgtGetName( nOutlineId) == EgtGetName( abs( vNextOutlineId[1]))) then nEndJointType = WIN_JNT.ANGLED end end @@ -1581,10 +1809,10 @@ local function CalcFrameGeo( nPartId, nOutlineId, nOutlineCrvNbr, nOutlineLayerI local nStartPartJointType = CalcPartJointType( nProfileTypeS, nStartJointType) local nEndPartJointType = CalcPartJointType( nProfileTypeE, nEndJointType) -- nel caso di incontro con soglia la giunzione deve essere full - if EgtGetInfo( vPrevOutlineId[1], WIN_THRESHOLD, 'b') then + if EgtGetInfo( abs( vPrevOutlineId[1]), WIN_THRESHOLD, 'b') then nStartPartJointType = WIN_JNT.FULL end - if EgtGetInfo( vNextOutlineId[1], WIN_THRESHOLD, 'b') then + if EgtGetInfo( abs( vNextOutlineId[1]), WIN_THRESHOLD, 'b') then nEndPartJointType = WIN_JNT.FULL end @@ -1603,18 +1831,120 @@ local function CalcFrameGeo( nPartId, nOutlineId, nOutlineCrvNbr, nOutlineLayerI end +--------------------------------------------------------------------- +local function AddFillGeoCurve( nTestOutlineId, nOtherGeoId, nGeoLayerId) + + -- verifico se la curva da testare è quella già presente nell'outline + local bAdd = true + local nRef = EgtGetInfo( abs( nTestOutlineId), WIN_COPY, 'i') + local nOtherOutlineId = EgtGetInfo( nOtherGeoId, WIN_REF_OUTLINE, 'i') + local nOtherBaseOutlineId = EgtGetInfo( nOtherOutlineId, WIN_COPY, 'i') + local nOtherSouId = EgtGetInfo( nOtherBaseOutlineId, WIN_SOU, 'i') + while nOtherSouId and bAdd do + bAdd = ( nOtherSouId ~= nRef) + nOtherSouId = EgtGetInfo( nOtherSouId, WIN_SOU, 'i') + end + + if not bAdd then + return + end + + -- aggiungo al geo + local nNewCrv = EgtCopyGlob( abs( nTestOutlineId), nGeoLayerId) + + -- setto info per recuperare outline che lo ha generato + EgtSetInfo( nNewCrv, WIN_REF_OUTLINE, abs( nTestOutlineId)) + + -- recupero offset dal profilo + local nRefPart = FindAssociatedPart( abs( nTestOutlineId)) + local nProfileLayId = EgtGetFirstNameInGroup( nRefPart, WIN_PROFILE) + local nProfileId = EgtGetFirstNameInGroup( nProfileLayId, WIN_PRF_MAIN) + local b3Profile = GetProfileLocalBox( nProfileId) + local dOverlap = EgtGetInfo( nProfileId, WIN_FILLOVERLAP, 'd') + local dDimRef = b3Profile:getMin():getX() + local dFillPerpOffset = abs( dDimRef) - dOverlap + + EgtOffsetCurve( nNewCrv, - dFillPerpOffset) + + -- applico movimento in z + local dFillZOffset = EgtGetInfo( nProfileId, WIN_FILLDELTA, 'd') + EgtMove( nNewCrv, Z_AX() * dFillZOffset) + + if nTestOutlineId < 0 then + EgtInvertCurve( nNewCrv) + end + + return nNewCrv +end + --------------------------------------------------------------------- -- funzione che calcola l'ingombro del fill local function CalcFillGeo( nPartId, nOutlineLayerId) + -- creo layer per ingombro local nGeoLayerId = EgtGroup( nPartId) EgtSetName( nGeoLayerId, WIN_GEO) -- copio lati da Outline - local nOutlineId = EgtGetFirstInGroup( nOutlineLayerId) - while nOutlineId do - EgtCopy( nOutlineId, nGeoLayerId) - nOutlineId = EgtGetNext( nOutlineId) + local vOutlineIds = EgtGetAllInGroup( nOutlineLayerId) + for i = 1, #vOutlineIds do + local nCrv = EgtCopy( vOutlineIds[i], nGeoLayerId) + EgtSetInfo( nCrv, WIN_REF_OUTLINE, vOutlineIds[i]) end + + -- verifico che nel caso di split i suoi prev e next siano stati considerati correttamente dall'outline, altrimenti li aggiungo + local bExtraCrvs = false + local vGeoIds = EgtGetAllInGroup( nGeoLayerId) + for i = 1, #vGeoIds do + local nRefBaseSplit = EgtGetInfo( vOutlineIds[i], WIN_REF_SPLIT, 'i') + if nRefBaseSplit then + + local nRefSplit = EgtGetInfo( nRefBaseSplit, WIN_COPY, 'i') + local vPrevOutlines = EgtGetInfo( nRefSplit, WIN_PREV_OUTLINES, 'vi') + local vNextOutlines = EgtGetInfo( nRefSplit, WIN_NEXT_OUTLINES, 'vi') + -- se la curva è invertita devo scambiare prev e next + local bInverted = EgtGetInfo( vOutlineIds[i], WIN_INV_SPLIT, 'b') or false + if bInverted then + vPrevOutlines, vNextOutlines = vNextOutlines, vPrevOutlines + end + + -- sistemo i precedenti + local nPrevIdx = EgtIf( i == 1, #vOutlineIds, i-1) + local nOldCrv = vGeoIds[i] + for j = #vPrevOutlines, 1, -1 do + local nPrevCrv = AddFillGeoCurve( vPrevOutlines[j], vGeoIds[nPrevIdx], nGeoLayerId) + if nPrevCrv then + bExtraCrvs = true + else + -- se non è stata aggiunta era già la curva presente nel geo + nPrevCrv = vGeoIds[nPrevIdx] + nPrevIdx = EgtIf( nPrevIdx == 1, #vOutlineIds, nPrevIdx-1) + end + EgtRelocateGlob( nPrevCrv, nOldCrv, GDB_IN.BEFORE) + nOldCrv = nPrevCrv + end + + -- sistemo i successivi + local nNextIdx = EgtIf( i == #vOutlineIds, 1, i+1) + nOldCrv = vGeoIds[i] + for j = 1, #vNextOutlines do + local nNextCrv = AddFillGeoCurve( vNextOutlines[j], vGeoIds[nNextIdx], nGeoLayerId) + if nNextCrv then + bExtraCrvs = true + else + nNextCrv = vGeoIds[nNextIdx] + nNextIdx = EgtIf( nNextIdx == #vOutlineIds, 1, nNextIdx+1) + end + EgtRelocateGlob( nNextCrv, nOldCrv, GDB_IN.AFTER) + nOldCrv = nNextCrv + end + end + end + + -- se sono state aggiunte delle curve è necessario trimmarle + if bExtraCrvs then + TrimOrderedCurves( EgtGetAllInGroup( nGeoLayerId)) + end + -- recupero e salvo spessore vetro local nProfileLayerId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_PROFILE) local nSashProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_SASH) @@ -1963,7 +2293,7 @@ local function CalcMixedFrameProfilingProcessings( nPartId, nProcLayerId, nGeoLa -- a) lavorazioni profili -- per le lavorazioni dei profili out, left, right e in comune si usano le corrispondenti curve del geo local vGeoCrvs = EgtGetAllInGroup( nGeoLayerId) - for i = 1, #vGeoCrvs do + for i = 1, #vGeoCrvs - 1 do -- copio curva local nCrv = EgtCopyGlob( vGeoCrvs[i], nProcLayerId) EgtModifyCurveThickness( nCrv, 0) @@ -2021,7 +2351,7 @@ local function CalcMixedSplitProfilingProcessings( nSplitId, nProcLayerId, nGeoL -- a) lavorazione dei profili local vGeoCrvs = EgtGetAllInGroup( nGeoLayerId) - for i = 1, #vGeoCrvs do + for i = 1, #vGeoCrvs - 1 do -- copio la curva local nCrvId = EgtCopyGlob( vGeoCrvs[i], nProcLayerId) EgtModifyCurveThickness( nCrvId, 0) @@ -2038,7 +2368,7 @@ local function CalcMixedSplitProfilingProcessings( nSplitId, nProcLayerId, nGeoL local nMillingLeft = EgtCopyGlob( nIntersLeft, nProcLayerId) -- recupero profondità local vOutlineLeft = EgtGetInfo( nSplitId, WIN_PREV_OUTLINES, 'vi') - local nProfileLeft = GetOutlineProfileId( vOutlineLeft[1], false) + local nProfileLeft = GetOutlineProfileId( abs( vOutlineLeft[1]), false) local dDepthLeft = EgtGetInfo( nProfileLeft, WIN_SASH_DEPTH .. '2', 'd') EgtModifyCurveThickness( nMillingLeft, - dDepthLeft) -- setto info di lavorazione @@ -2052,7 +2382,7 @@ local function CalcMixedSplitProfilingProcessings( nSplitId, nProcLayerId, nGeoL local nMillingRight = EgtCopyGlob( nIntersRight, nProcLayerId) -- recupero profondità local vOutlineRight = EgtGetInfo( nSplitId, WIN_NEXT_OUTLINES, 'vi') - local nProfileRight = GetOutlineProfileId( vOutlineRight[1], false) + local nProfileRight = GetOutlineProfileId( abs( vOutlineRight[1]), false) local dDepthRight = EgtGetInfo( nProfileRight, WIN_SASH_DEPTH .. '2', 'd') EgtModifyCurveThickness( nMillingRight, - dDepthRight) EgtInvertCurve( nMillingRight) @@ -2063,6 +2393,93 @@ 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 + + -- 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) + + -- 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) + + if nCnt == 0 then + return + end + + 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( nCrvId), 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 + + for nId = nNewId, nNewId + nCnt - 1 do + if nId ~= nIdRef then + EgtErase( nId) + end + end + nNewId = nIdRef + 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) +end + --------------------------------------------------------------------- -- funzione che calcola le lavorazioni di profiling local function CalcProfilingProcessings( nPartId, nOutlineId) @@ -2074,8 +2491,7 @@ local function CalcProfilingProcessings( nPartId, nOutlineId) -- recupero il geo e creo la superficie associata per limitare le lavorazioni local nGeoLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO) - local nSurfGeo = CreateGeoArea( nGeoLayerId, nProcLayerId, false) - EgtSurfFrOffset( nSurfGeo, 50 * GEO.EPS_SMALL) + local nSurfGeo = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_SURF) -- recupero il gruppo dei profili local nProfileLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE) @@ -2098,14 +2514,18 @@ local function CalcProfilingProcessings( nPartId, nOutlineId) end else -- 2) caso standard - -- recupero tutte le curve del geo + -- recupero tutte le curve del geo e le copio nel gruppo processings local vGeoCrvs = EgtGetAllInGroup( nGeoLayerId) - for i = 1, #vGeoCrvs do + 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) end @@ -2128,7 +2548,6 @@ local function CalcProfilingProcessings( nPartId, nOutlineId) EgtSetName( nStripCut, WIN_PRC_TYPE.STRIP_CUT) EgtSetInfo( nStripCut, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.STRIP_CUT) end - EgtErase( nSurfGeo) -- verifico se anta ricevente ( info necessaria per ottimizzazione lavorazioni) local nAreaId = EgtGetParent( EgtGetParent( nOutlineId)) @@ -2152,50 +2571,48 @@ local function CalcGeoRaw( nPartId) local nGeoLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO) local nGeoRawLayerId = EgtCopyGlob( nGeoLayerId, nPartId) + EgtErase( EgtGetLastInGroup( nGeoRawLayerId)) -- elimino la regione EgtSetName( nGeoRawLayerId, WIN_GEO_RAW) EgtSetStatus( nGeoRawLayerId, GDB_ST.OFF) - - -- recupero le curve del geo - local nOut = EgtGetFirstNameInGroup( nGeoRawLayerId, WIN_GEO_OUT) - local nIn = EgtGetFirstNameInGroup( nGeoRawLayerId, WIN_GEO_IN) - local vRight = EgtGetNameInGroup( nGeoRawLayerId, WIN_GEO_RIGHT) - local vLeft = EgtGetNameInGroup( nGeoRawLayerId, WIN_GEO_LEFT) - -- verifico se le curve right e left hanno direzioni coerenti - if #vRight == 2 and not AreSamePointApprox( EgtEP( vRight[1]), EgtSP( vRight[2])) then - -- la seconda curva va ignorata - EgtErase( vRight[2]) - vRight = { vRight[1]} - end - if #vLeft == 2 and not AreSamePointApprox( EgtEP( vLeft[1]), EgtSP( vLeft[2])) then - -- la prima curva va ignorata - EgtErase( vLeft[1]) - vLeft = { vLeft[2]} - end - + -- recupero i sovramateriali da applicare alle curve local dOvermatOut = EgtGetInfo( nPartId, WIN_PRC_OVERMAT_OUT, 'd') local dOvermatRight = EgtGetInfo( nPartId, WIN_PRC_OVERMAT_RIGHT, 'd') local dOvermatIn = EgtGetInfo( nPartId, WIN_PRC_OVERMAT_IN, 'd') local dOvermatLeft = EgtGetInfo( nPartId, WIN_PRC_OVERMAT_LEFT, 'd') - -- applico i sovramateriali + -- recupero le curve del raw e applico i sovramateriali + local nOut = EgtGetFirstNameInGroup( nGeoRawLayerId, WIN_GEO_OUT) EgtOffsetCurve( nOut, dOvermatOut) - for i = 1, #vRight do - EgtOffsetCurve( vRight[i], dOvermatRight) - end + local nIn = EgtGetFirstNameInGroup( nGeoRawLayerId, WIN_GEO_IN) EgtOffsetCurve( nIn, dOvermatIn) + 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 + EgtErase( vRight[i]) + else + EgtOffsetCurve( vRight[i], dOvermatRight) + end + end + local vLeft = EgtGetNameInGroup( nGeoRawLayerId, WIN_GEO_LEFT) for i = 1, #vLeft do - EgtOffsetCurve( vLeft[i], dOvermatLeft) + local bExtra = EgtGetInfo( vLeft[i], WIN_GEO_EXTRA, 'b') or false + if bExtra then + EgtErase( vLeft[i]) + else + EgtOffsetCurve( vLeft[i], dOvermatLeft) + end end -- creo la composita del grezzo a partire dalle curve local vCrvs = EgtGetAllInGroup( nGeoRawLayerId) - TrimAndOrientOrderedCurves( vCrvs, false) + vCrvs = TrimOrderedCurves( vCrvs) local nCompo = EgtCurveCompo( nGeoRawLayerId, vCrvs) -- 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()) @@ -2208,75 +2625,6 @@ end ---------------------------------------------------------------------------------- ---------------------------------- SOLIDO ---------------------------------------- ---------------------------------------------------------------------------------- --- funzione che costruisce una superficie estrudendo il nSectionId lungo l'outline -local function CreateProfileSurfById( nOutlineId, nProfileId, nSectionId, dExtraLen, nLayerId) - - -- creo guida con estensione in tangenza - local nGuideId = EgtCopy( nOutlineId, nLayerId) - if EgtGetType( nGuideId) == GDB_TY.CRV_LINE then - EgtExtendCurveStartByLen( nGuideId, dExtraLen) - EgtExtendCurveEndByLen( nGuideId, dExtraLen) - else - nGuideId = EgtCurveCompo( nLayerId, nGuideId) - EgtAddCurveCompoLineTg( nGuideId, dExtraLen) - EgtAddCurveCompoLineTg( nGuideId, dExtraLen, false) - end - -- correzione nel caso di bottomrail - local sProfileType = EgtGetInfo( nProfileId, WIN_PRF_TYPE) - if sProfileType == WIN_RAIL or sProfileType == WIN_FILL_RAIL then - local dOffs = EgtGetInfo( nProfileId, WIN_RAILDELTA, 'd') - EgtOffsetCurve( nGuideId, - dOffs) - end - - -- verifico se necessaria inversione della guida nel caso sia curva "virtuale" ( ovvero in area null o split) che deriva da pezzo di split - local nRefSplitId = EgtGetInfo( nOutlineId, WIN_REF_SPLIT, 'i') - if nRefSplitId then - -- recupero base outline per confrontarlo con lo split da cui deriva - local nBaseOutlineId = EgtGetInfo( nOutlineId, WIN_COPY, 'i') - -- recupero vettore tangente nel punto medio del base outline - local ptM = EgtMP( nBaseOutlineId) - local vtM = EgtMV( nBaseOutlineId) - -- recupero vettore tangente nello stesso punto della curva di split da cui deriva - local dRefSplitPar = EgtCurveParamAtPoint( nRefSplitId, ptM) - local vtMRefSplit = EgtUV( nRefSplitId, dRefSplitPar, -1) - -- se i due vettori non sono orientati nella stessa direzione inverto la guida - if not AreSameVectorApprox( vtM, vtMRefSplit) then - EgtInvertCurve( nGuideId) - end - end - - -- recupero il profilo da estrudere - local nSectionRefId = EgtCopyGlob( nSectionId, nLayerId) - - -- posiziono la sezione di estrusione sulla guida : - -- recupero frame del profilo - local nProfileFrameId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME) - local frProfile = EgtFR( nProfileFrameId, GDB_ID.ROOT) - frProfile:invert() - -- calcolo il frame di destinazione sulla guida - local frDest = Frame3d( EgtSP( nGuideId), - EgtSV( nGuideId), GDB_RT.GLOB) - -- posiziono con i riferimenti - EgtTransform( nSectionRefId, frProfile, GDB_RT.GLOB) - EgtTransform( nSectionRefId, frDest, GDB_RT.GLOB) - - -- creo la superfice di estrusione - local nStmId = EgtSurfTmSwept( nLayerId, nSectionRefId, nGuideId, false, WIN_SURF_APPROX) - EgtErase( nGuideId) - EgtErase( nSectionRefId) - - return nStmId -end - ---------------------------------------------------------------------- --- come CreateProfileSurfById ma riceve il nome della sezione da estrudere -local function CreateProfileSurf( nOutlineId, nProfileId, sSectionName, dExtraLen, nLayerId) - -- recupero l'id della sezione da estrudere - local nSectionId = EgtGetFirstNameInGroup( nProfileId, sSectionName) - if not nSectionId then return end - return CreateProfileSurfById( nOutlineId, nProfileId, nSectionId, dExtraLen, nLayerId) -end - ---------------------------------------------------------------------- -- funzione che crea la superficie di trim per il solido local function CreateTrimSurf( nGeoId, nProfileId, dGeoWidth, nLayerId) @@ -2306,7 +2654,6 @@ local function CreateTrimSurf( nGeoId, nProfileId, dGeoWidth, nLayerId) -- calcolo la superficie di estrusione return CreateProfileSurf( nRefOutline, nProfileId, sTrimProfileName, 4 * dGeoWidth, nLayerId) end - end --------------------------------------------------------------------- @@ -2520,7 +2867,7 @@ local function CalcSolid( nPartId, nOutlineId) -- a) creo il solido di estrusione principale local nMainProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN) local sSection = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. WIN_SECTION - local nMainExtrusionId = CreateMainSurf( nOutlineId, 2 * dGeoWidth, nMainProfileId, sSection, nSolidLayerId) + local nMainExtrusionId = CreateMainSurf( nOutlineId, 4 * dGeoWidth, nMainProfileId, sSection, nSolidLayerId) -- creo una copia ( usata per calcolo ferramenta) local nOrigMainExtrusionId = EgtCopy( nMainExtrusionId, nSolidLayerId) EgtSetName( nOrigMainExtrusionId, WIN_SRF_ORIGMAIN) @@ -2555,13 +2902,13 @@ end --------------------------------------------------------------------- -- funzione che crea il solido del Fill -local function CalcFillSolid( nPartId, nOutlineLayerId, nGeoLayerId) - -- creo layer per solido +local function CalcFillSolid( nPartId, nGeoLayerId) + -- creo layer per solido local nSolidLayerId = EgtGroup( nPartId) EgtSetName( nSolidLayerId, WIN_SOLID) - -- creo compo di outline - local vOutlineList = EgtGetAllInGroup( nOutlineLayerId) - local nCompoOutlineId = EgtCurveCompoByChain( nSolidLayerId, vOutlineList, EgtSP( vOutlineList[1]), false) + -- creo compo dalle curve del geo + local vGeoList = EgtGetAllInGroup( nGeoLayerId) + local nCompoOutlineId = EgtCurveCompo( nSolidLayerId, vGeoList, false) -- recupero spessore vetro local dGlassThickness = EgtGetInfo( nGeoLayerId, WIN_GLASSTHICKNESS, 'd') local nSurfId = EgtSurfTmByRegionExtrusion( nSolidLayerId, nCompoOutlineId, Z_AX() * dGlassThickness) @@ -3003,7 +3350,7 @@ end --------------------------------------------------------------------- -- funzione che calcola i dowels tra uno split e i pezzi sui cui poggia -local function CalcSplitDowels( nSplitId, vOutlines, bStartOrEnd) +local function CalcSplitDowels( nSplitId, bStartOrEnd) -- TO DO : da gestire incrocio dowels di tre pezzi @@ -3033,137 +3380,140 @@ local function CalcSplitDowels( nSplitId, vOutlines, bStartOrEnd) sSplitDowelSide = WIN_PRC_SIDETYPE.LEFT end - -- creo la superficie di test per verificare se dowel interno al pezzo + -- recupero la superficie del pezzo per verificare se dowel interno local nSplitGeo = EgtGetFirstNameInGroup( nSplitPart, WIN_GEO) - local nSplitSurf = CreateGeoArea( nSplitGeo, nSplitLayerId, false) - + local nSplitSurf = EgtGetFirstNameInGroup( nSplitGeo, WIN_GEO_SURF) + + local vGeoCrvs = EgtGetNameInGroup( nSplitGeo, EgtIf( bStartOrEnd, WIN_LEFT, WIN_RIGHT)) local ptRef = EgtIf( bStartOrEnd, EgtSP( nSplitId), EgtEP( nSplitId)) - -- se il bottom è soglia va ignorato - local nStartIdx = EgtIf( EgtGetInfo( vOutlines[1], WIN_THRESHOLD, 'b'), 2, 1) - for i = nStartIdx, #vOutlines do - - -- recupero il pezzo associato e il suo outline di riferimento - local nPartId = FindAssociatedPart( vOutlines[i], true) - local nOutlineId = EgtGetInfo( nPartId, WIN_REF_OUTLINE, 'i') - local nProfileType = GetOutlineProfileType( nOutlineId, true) - - -- calcolo il frame di destinazione - -- trovo intersezione dello split con lato In o Out del geo - local nGeoLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO) - local nGeoCrvId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_IN) - local ptInters = EgtIP( nGeoCrvId, nSplitId, ptRef) - local sDowelSide = WIN_PRC_SIDETYPE.IN - if not ptInters and nProfileType == WIN_PRF.SPLIT then - nGeoCrvId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_OUT) - ptInters = EgtIP( nGeoCrvId, nSplitId, ptRef) - sDowelSide = WIN_PRC_SIDETYPE.OUT - end - -- se non trovo intersezione passo al successivo - if ptInters then - - -- TO DO : gestione split non lineare - local frDest = Frame3d( ptInters, - EgtSV( nSplitId)) - - -- recupero il layer con le lavorazioni - local nLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PRC) - - -- nel layer dei profili del pezzo aggiungo il profilo dello split posizionato correttamente - local nProfileLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE) - local nSplitProfileCopyId = EgtCopy( nSplitProfile, nProfileLayerId) - local sSplitProfileType = EgtGetName( nSplitProfile) - EgtSetInfo( nSplitProfileCopyId, WIN_PRF_TYPE, sSplitProfileType) - EgtSetName( nSplitProfileCopyId, WIN_PRF_SPLIT) - -- posiziono il profilo sulla curva di split - EgtTransform( EgtGetAllInGroup( nSplitProfileCopyId), frOrig, GDB_RT.GLOB) - EgtChangeGroupFrame( nSplitProfileCopyId, frDest, GDB_RT.GLOB) - - -- recupero eventuale solido - local nSolidId - if s_bCalcSolid then - local nSolidLayerId = EgtGetFirstNameInGroup( nPartId, WIN_SOLID) - nSolidId = EgtGetFirstNameInGroup( nSolidLayerId, WIN_SRF_MAIN) - end - - -- recupero le chiavi delle lunghezze ( dipendono dal profilo del pezzo su cui poggia lo split) - local sSplitLenKey = WIN_DWL_TOP_PARA_LEN - local sLenKey = WIN_DWL_TOP_PERP_LEN - if nProfileType == WIN_PRF.BOTTOM then - sSplitLenKey = WIN_DWL_BOTTOM_PARA_LEN - sLenKey = WIN_DWL_BOTTOM_PERP_LEN - elseif nProfileType == WIN_PRF.BOTTOMRAIL_FINAL then - sSplitLenKey = WIN_DWL_RAILBOTTOM_PARA_LEN - sLenKey = WIN_DWL_RAILBOTTOM_PERP_LEN - elseif nProfileType == WIN_PRF.SPLIT then - sSplitLenKey = WIN_DWL_SPLIT_PARA_LEN - sLenKey = WIN_DWL_SPLIT_PERP_LEN - end - - -- creo la superficie di test per il posizionamento dei dowels - local nProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN) - local nTestSurf - if not s_bCalcSolid or s_bSimplSolid then - local bChangeProfile = EgtGetInfo( nSplitId, WIN_PRF_CHANGE, 'b') or false - if bChangeProfile then - local nMixedOutline = EgtGetInfo( nSplitId, EgtIf( bStartOrEnd, WIN_MIXED_REF_START, WIN_MIXED_REF_END), 'i') - nTestSurf = CreateMixedSplitTrimSurf( nMixedOutline, nProfileId, 100, nLayerId) - else - local sCtr = WIN_OFST .. GetProfileCtrIn( nOutlineId, nSplitId, nProfileId) - nTestSurf = CreateProfileSurf( nOutlineId, nProfileId, sCtr, 100, nLayerId) - end - else - -- è la stessa superficie utilizzata per il trim del solido - nTestSurf = EgtCopyGlob( vTestSurf[i], nSplitLayerId) - end - local nTestSurfInverted = EgtCopyGlob( nTestSurf, nSplitLayerId) - EgtInvertSurf( nTestSurfInverted) + for i = 1, #vGeoCrvs do - -- calcolo le direzioni entranti nei pezzi - local vtSplitDir = EgtIf( bStartOrEnd, - frDest:getVersZ(), frDest:getVersZ()) - local vtDir = frDest:getVersZ() - local _, _, nSide = EgtPointCurveDistSide( ptInters + vtDir, nGeoCrvId, Z_AX()) - if nSide == 1 then - -- se a destra della curva significa che la direzione è uscente dal pezzo e va invertita - vtDir = - vtDir + local nOrigOutline = EgtGetInfo( vGeoCrvs[i], WIN_REF_OUTLINE, 'i') + -- verifico se soglia ( in quel caso non ci sono dowels quindi va ignorato) + local bThreshold = EgtGetInfo( nOrigOutline, WIN_THRESHOLD, 'b') or false + + if not bThreshold then + + -- recupero il pezzo associato e il suo outline di riferimento + local nPartId = FindAssociatedPart( nOrigOutline, true) + local nOutlineId = EgtGetInfo( nPartId, WIN_REF_OUTLINE, 'i') + local nProfileType = GetOutlineProfileType( nOutlineId, true) + + -- calcolo il frame di destinazione + -- trovo intersezione dello split con lato In o Out del geo + local nGeoLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO) + local nGeoCrvId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_IN) + local ptInters = EgtIP( nGeoCrvId, nSplitId, ptRef) + local sDowelSide = WIN_PRC_SIDETYPE.IN + if not ptInters and nProfileType == WIN_PRF.SPLIT then + nGeoCrvId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_OUT) + ptInters = EgtIP( nGeoCrvId, nSplitId, ptRef) + sDowelSide = WIN_PRC_SIDETYPE.OUT end - - -- creo la superficie di test per verificare se dowel interno al pezzo - local nGeo = EgtGetFirstNameInGroup( nPartId, WIN_GEO) - local nSurf = CreateGeoArea( nGeo, nLayerId, false) - - -- aggiungo i dowels - local vDowels = EgtGetNameInGroup( nSplitProfile, WIN_DOWEL .. '*') or {} - for i = 1, #vDowels do - -- split - local dLen1 = CalcDowelLen( vDowels[i], sSplitLenKey, false) - local nDowel1 = CreateDowel( vDowels[i], nSplitLayerId, frOrig, frDest, vtSplitDir, nTestSurf, dLen1, sSplitDowelSide, nSplitSolidId) - -- verifico se dowel è interno al pezzo ( TO DO : da migliorare!) - local ptTest = EgtCP( nDowel1) - vtSplitDir * EgtCurveThickness( nDowel1) - local nTestPoint = EgtPoint( nSplitLayerId, ptTest) - if EgtSurfFrTestExternal( nSplitSurf, nTestPoint) then - EgtErase( nDowel1) - end - EgtErase( nTestPoint) + -- se non trovo intersezione passo al successivo + if ptInters then + + -- TO DO : gestione split non lineare + local frDest = Frame3d( ptInters, - EgtSV( nSplitId)) - -- pezzo - local dLen2 = CalcDowelLen( vDowels[i], sLenKey, true) - local nDowel2 = CreateDowel( vDowels[i], nLayerId, frOrig, frDest, vtDir, nTestSurfInverted, dLen2, sDowelSide, nSolidId) - ptTest = EgtCP( nDowel2) - vtDir * EgtCurveThickness( nDowel2) - nTestPoint = EgtPoint( nLayerId, ptTest) - if EgtSurfFrTestExternal( nSurf, nTestPoint) then - EgtErase( nDowel2) - end - EgtErase( nTestPoint) + -- recupero il layer con le lavorazioni + local nLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PRC) + -- nel layer dei profili del pezzo aggiungo il profilo dello split posizionato correttamente + local nProfileLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE) + local nSplitProfileCopyId = EgtCopy( nSplitProfile, nProfileLayerId) + local sSplitProfileType = EgtGetName( nSplitProfile) + EgtSetInfo( nSplitProfileCopyId, WIN_PRF_TYPE, sSplitProfileType) + EgtSetName( nSplitProfileCopyId, WIN_PRF_SPLIT) + -- posiziono il profilo sulla curva di split + EgtTransform( EgtGetAllInGroup( nSplitProfileCopyId), frOrig, GDB_RT.GLOB) + EgtChangeGroupFrame( nSplitProfileCopyId, frDest, GDB_RT.GLOB) + + -- recupero eventuale solido + local nSolidId + if s_bCalcSolid then + local nSolidLayerId = EgtGetFirstNameInGroup( nPartId, WIN_SOLID) + nSolidId = EgtGetFirstNameInGroup( nSolidLayerId, WIN_SRF_MAIN) + end + + -- recupero le chiavi delle lunghezze ( dipendono dal profilo del pezzo su cui poggia lo split) + local sSplitLenKey = WIN_DWL_TOP_PARA_LEN + local sLenKey = WIN_DWL_TOP_PERP_LEN + if nProfileType == WIN_PRF.BOTTOM then + sSplitLenKey = WIN_DWL_BOTTOM_PARA_LEN + sLenKey = WIN_DWL_BOTTOM_PERP_LEN + elseif nProfileType == WIN_PRF.BOTTOMRAIL_FINAL then + sSplitLenKey = WIN_DWL_RAILBOTTOM_PARA_LEN + sLenKey = WIN_DWL_RAILBOTTOM_PERP_LEN + elseif nProfileType == WIN_PRF.SPLIT then + sSplitLenKey = WIN_DWL_SPLIT_PARA_LEN + sLenKey = WIN_DWL_SPLIT_PERP_LEN + end + + -- creo la superficie di test per il posizionamento dei dowels + local nProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN) + local nTestSurf + if not s_bCalcSolid or s_bSimplSolid then + local bChangeProfile = EgtGetInfo( nSplitId, WIN_PRF_CHANGE, 'b') or false + if bChangeProfile then + local nMixedOutline = EgtGetInfo( nSplitId, EgtIf( bStartOrEnd, WIN_MIXED_REF_START, WIN_MIXED_REF_END), 'i') + nTestSurf = CreateMixedSplitTrimSurf( nMixedOutline, nProfileId, 100, nLayerId) + else + local sCtr = WIN_OFST .. GetProfileCtrIn( nOutlineId, nSplitId, nProfileId) + nTestSurf = CreateProfileSurf( nOutlineId, nProfileId, sCtr, 100, nLayerId) + end + else + -- è la stessa superficie utilizzata per il trim del solido + nTestSurf = EgtCopyGlob( vTestSurf[i], nSplitLayerId) + end + local nTestSurfInverted = EgtCopyGlob( nTestSurf, nSplitLayerId) + EgtInvertSurf( nTestSurfInverted) + + -- calcolo le direzioni entranti nei pezzi + local vtSplitDir = EgtIf( bStartOrEnd, - frDest:getVersZ(), frDest:getVersZ()) + local vtDir = frDest:getVersZ() + local _, _, nSide = EgtPointCurveDistSide( ptInters + vtDir, nGeoCrvId, Z_AX()) + if nSide == 1 then + -- se a destra della curva significa che la direzione è uscente dal pezzo e va invertita + vtDir = - vtDir + end + + -- recupero la superficie del pezzo per verificare se dowel interno + local nGeo = EgtGetFirstNameInGroup( nPartId, WIN_GEO) + local nSurf = EgtGetFirstNameInGroup( nGeo, WIN_GEO_SURF) + + -- aggiungo i dowels + local vDowels = EgtGetNameInGroup( nSplitProfile, WIN_DOWEL .. '*') or {} + for i = 1, #vDowels do + -- split + local dLen1 = CalcDowelLen( vDowels[i], sSplitLenKey, false) + local nDowel1 = CreateDowel( vDowels[i], nSplitLayerId, frOrig, frDest, vtSplitDir, nTestSurf, dLen1, sSplitDowelSide, nSplitSolidId) + -- verifico se dowel è interno al pezzo ( TO DO : da migliorare!) + local ptTest = EgtCP( nDowel1) - vtSplitDir * EgtCurveThickness( nDowel1) + local nTestPoint = EgtPoint( nSplitLayerId, ptTest) + if EgtSurfFrTestExternal( nSplitSurf, nTestPoint) then + EgtErase( nDowel1) + end + EgtErase( nTestPoint) + + -- pezzo + local dLen2 = CalcDowelLen( vDowels[i], sLenKey, true) + local nDowel2 = CreateDowel( vDowels[i], nLayerId, frOrig, frDest, vtDir, nTestSurfInverted, dLen2, sDowelSide, nSolidId) + ptTest = EgtCP( nDowel2) - vtDir * EgtCurveThickness( nDowel2) + nTestPoint = EgtPoint( nLayerId, ptTest) + if EgtSurfFrTestExternal( nSurf, nTestPoint) then + EgtErase( nDowel2) + end + EgtErase( nTestPoint) + + end + + EgtErase( nTestSurf) + EgtErase( nTestSurfInverted) end - - EgtErase( nTestSurf) - EgtErase( nTestSurfInverted) - EgtErase( nSurf) end end - - EgtErase( nSplitSurf) end --------------------------------------------------------------------- @@ -3201,11 +3551,9 @@ local function CalculateAreaDowels( nAreaId) if nSplitType ~= WIN_SPLITTYPES.FRENCH then local nSplitId = EgtGetFirstInGroup( nSplitLayerId) -- start - local vPrevOutlineId = EgtGetInfo( nSplitId, WIN_PREV_OUTLINES, 'vi') - CalcSplitDowels( nSplitId, vPrevOutlineId, true) + CalcSplitDowels( nSplitId, true) -- end - local vNextOutlineId = EgtGetInfo( nSplitId, WIN_NEXT_OUTLINES, 'vi') - CalcSplitDowels( nSplitId, vNextOutlineId, false) + CalcSplitDowels( nSplitId, false) end end @@ -3223,155 +3571,223 @@ end --------------------------------- STRIP ---------------------------------------- ---------------------------------------------------------------------------------- -- funzione che restitutisce lo Strip piu' vicino --- ( analoga a GetProfileCtrIn) -local function GetStripNearestToOutline( nPrevProfileId, nPrevOutlineId, nOutlineId) - local sStripName = WIN_STRIP +local function GetStripNearestToOutline( nProfileId, nOutlineId) - -- gestione particolare del caso di profilo di split - if not EgtGetFirstNameInGroup( nPrevProfileId, sStripName) then - -- recupero la curva di base outline da cui deriva il precedente - local nPrevSouId = EgtGetInfo( nPrevOutlineId, WIN_COPY, 'i') - local sPrevSouName - repeat - nPrevSouId = EgtGetInfo( nPrevSouId, WIN_SOU, 'i') - sPrevSouName = EgtGetName( nPrevSouId or GDB_ID.NULL) - until not nPrevSouId or sPrevSouName == WIN_SPLIT - - -- verifico da quale lato si trova la curva per decidere quale controprofilo considerare - local _, _, nSide = EgtPointCurveDistSide( EgtMP( nOutlineId), nPrevSouId, Z_AX()) - if nSide == 1 then - sStripName = WIN_STRIP .. '1' -- dx + local sStripName = WIN_STRIP + -- gestione particolare del caso di profilo di split ( devo capire il lato corretto) + if not EgtGetFirstNameInGroup( nProfileId, sStripName) then + local bInverted = EgtGetInfo( nOutlineId, WIN_INV_SPLIT, 'b') or false + if bInverted then + sStripName = WIN_STRIP .. '1' else - sStripName = WIN_STRIP .. '2' -- sx + sStripName = WIN_STRIP .. '2' end end if s_bSimplSolid then sStripName = WIN_SIMPLIFIED .. sStripName end - local nStripId = EgtGetFirstNameInGroup( nPrevProfileId, sStripName) + + local nStripId = EgtGetFirstNameInGroup( nProfileId, sStripName) return nStripId end --------------------------------------------------------------------- --- funzione che crea le linee di contorno massima e minima degli strip -local function CreateStripGuideLines( nOutlineId, nStripId, nProfileId, nSolidLayerId) +local function CreateStripGuideLines( nOutlineId, nRefOutlineId, nStripId, nProfileId, nSolidLayerId) + -- restutuisco le curve ordinate in modo che la prima sia quella più esterna e la seconda quella più interna - -- recupero il frame del profilo + -- recupero il box dello strip nel frame del profilo local nProfileFrameId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME) local frProfile = EgtFR( nProfileFrameId, GDB_ID.ROOT) - -- se profilo e direzione prev uguali ( Prev e' Split), cambio segno all'offset di modo che rimanga sempre dalla stessa parte - local vtE = EgtEV( nOutlineId) - local bMainInvertOffset = AreSameVectorApprox( frProfile:getVersZ(), vtE) - -- calcolo BBox local b3MainStrip = EgtGetBBoxRef( nStripId, GDB_BB.STANDARD, frProfile, GDB_RT.GLOB) - -- calcolo offset per Strip + + -- calcolo offset per strip local dDelta = EgtGetInfo( nProfileId, WIN_RAILDELTA, 'd') or 0 - local dMainStripMinDelta = EgtIf( bMainInvertOffset, - b3MainStrip:getMax():getX() + dDelta, b3MainStrip:getMin():getX() - dDelta) - local dMainStripMaxDelta = EgtIf( bMainInvertOffset, - b3MainStrip:getMin():getX() + dDelta, b3MainStrip:getMax():getX() - dDelta) + local dMinOffs = b3MainStrip:getMin():getX() - dDelta + local dMaxOffs = b3MainStrip:getMax():getX() - dDelta - local nStripMinOffsetId = EgtCopy( nOutlineId, nSolidLayerId) - EgtOffsetCurve( nStripMinOffsetId, dMainStripMinDelta) - local nStripMaxOffsetId = EgtCopy( nOutlineId, nSolidLayerId) - EgtOffsetCurve( nStripMaxOffsetId, dMainStripMaxDelta) + local nMinOffsetId = EgtCopy( nOutlineId, nSolidLayerId) + EgtOffsetCurve( nMinOffsetId, dMinOffs) + local nMaxOffsetId = EgtCopy( nOutlineId, nSolidLayerId) + EgtOffsetCurve( nMaxOffsetId, dMaxOffs) - return nStripMinOffsetId, nStripMaxOffsetId + -- verifico se le curve vanno invertite nel caso di split + local bInverted = EgtGetInfo( nRefOutlineId, WIN_INV_SPLIT, 'b') or false + if bInverted then + EgtInvertCurve( nMinOffsetId) + EgtInvertCurve( nMaxOffsetId) + return nMaxOffsetId, nMinOffsetId + end + + return nMinOffsetId, nMaxOffsetId +end + +--------------------------------------------------------------------- +local function TrimStripSurf( pt1, pt2, nStripSurfId, nSolidLayerId) + -- creo la superficie di trim + local nTrimGuideId = EgtLine( nSolidLayerId, pt1, pt2) + EgtExtendCurveStartByLen( nTrimGuideId, 10) + EgtExtendCurveEndByLen( nTrimGuideId, 10) + EgtMove( nTrimGuideId, Z_AX()) + local dDim = 100 + local nTrimSurfId = EgtSurfTmByExtrusion( nSolidLayerId, nTrimGuideId, - Z_AX() * dDim, WIN_SURF_APPROX) + + -- intersezione con strip + EgtSurfTmIntersect( nStripSurfId, nTrimSurfId) + + EgtErase( nTrimGuideId) + EgtErase( nTrimSurfId) end --------------------------------------------------------------------- --- funzione che crea gli Strip -local function CreateStripFromOutline( nAreaId, nOutlineId) +-- funzione che calcola i fermavetro a partire dal Geo di un'area fill +local function CalcAreaStrip( nGeoFillId) - -- recupero il pezzo associato ( prendendo quello di bottomrail se esiste) - local nPartId = FindAssociatedPart( nOutlineId, true) - -- recupero layer per solido e per profili di estrusione - local nSolidLayerId = EgtGetFirstNameInGroup( nPartId, WIN_SOLID) - - -- recupero gli outline precedente e successivo ( non serve utilizzare un WIN_PRF accurato perchè conta solo sia diverso da split) - local nOutlineLayerId = EgtGetParent( nOutlineId) - local vPrevOutlineId, vNextOutlineId = GetPrevNextOutline( WIN_PRF.NULL, nOutlineId, nOutlineLayerId) - - -- recupero i pezzi precedente e successivo, prendendo eventualmente quelli di bottomrail - local nPrevPartId = FindAssociatedPart( vPrevOutlineId[1], true) - local nNextPartId = FindAssociatedPart( vNextOutlineId[1], true) - - -- recupero profilo e controprofili - local nMainProfileLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE) - local nMainProfileId = EgtGetFirstNameInGroup( nMainProfileLayerId, WIN_PRF_MAIN) - local nPrevProfileLayerId = EgtGetFirstNameInGroup( nPrevPartId, WIN_PROFILE) - local nStartProfileId = EgtGetFirstNameInGroup( nPrevProfileLayerId, WIN_PRF_MAIN) - local nNextProfileLayerId = EgtGetFirstNameInGroup( nNextPartId, WIN_PROFILE) - local nEndProfileId = EgtGetFirstNameInGroup( nNextProfileLayerId, WIN_PRF_MAIN) + if not s_bCalcSolid then return end - -- a) estrudo il fermavetro - -- recupero guida Main - local nGuideId = EgtGetFirstNameInGroup( nSolidLayerId, WIN_MAINGUIDE) - -- recupero strip piu' vicino a prev outline e lo posiziono sulla guida - local nMainStripId = GetStripNearestToOutline( nMainProfileId, nOutlineId, vPrevOutlineId[1]) - local nSectionId = EgtCopyGlob( nMainStripId, nSolidLayerId) - local nFrameProfileId = EgtGetFirstNameInGroup( nMainProfileId, WIN_SECTIONFRAME) - local frOrig = EgtFR( nFrameProfileId, GDB_ID.ROOT) - frOrig:invert() - local frDest = Frame3d( EgtSP( nGuideId), - EgtSV( nGuideId)) - EgtTransform( nSectionId, frOrig) - EgtTransform( nSectionId, frDest) - -- creo estrusione - local nMainStripExtrusionId = EgtSurfTmSwept( nSolidLayerId, nSectionId, nGuideId, false, WIN_SURF_APPROX) - EgtSetName( nMainStripExtrusionId, WIN_SRF_STRIP) + -- gruppi temporanei per i conti + local nGrp = EgtGroup( GDB_ID.ROOT) + local nGrp1 = EgtGroup( GDB_ID.ROOT) + local nGrp2 = EgtGroup( GDB_ID.ROOT) + EgtSetStatus( nGrp, GDB_ST.OFF) + EgtSetStatus( nGrp1, GDB_ST.OFF) + EgtSetStatus( nGrp2, GDB_ST.OFF) - -- b) taglio con start - -- recupero strip dello start piu' vicino ad outline - local nStartStripId = GetStripNearestToOutline( nStartProfileId, vPrevOutlineId[1], nOutlineId) + -- estrudo i fermavetri e calcolo le curve che li limitano ( Offs1 sono quelli più lontani dal pezzo, Offs2 quelli più vicini) + local vGeoCrvs = EgtGetAllInGroup( nGeoFillId) + local tabStrip = {} + for i = 1, #vGeoCrvs do - -- disegno guida start per lo strip trovando le intersezioni degli outline minimi e massimi tra MainStrip e StartStrip - local nMainStripMinOffsetId, nMainStripMaxOffsetId = CreateStripGuideLines( nOutlineId, nMainStripId, nMainProfileId, nSolidLayerId) - local nStartStripMinOffsetId, nStartStripMaxOffsetId = CreateStripGuideLines( vPrevOutlineId[1], nStartStripId, nStartProfileId, nSolidLayerId) - local ptStripMinStart = FindIntersectionPoint( nMainStripMinOffsetId, nStartStripMinOffsetId, EgtSP( nMainStripMinOffsetId)) - local ptStripMaxStart = FindIntersectionPoint( nMainStripMaxOffsetId, nStartStripMaxOffsetId, EgtSP( nMainStripMinOffsetId)) - local nStartStripGuideId = EgtLine( nSolidLayerId, ptStripMinStart, ptStripMaxStart) - EgtExtendCurveStartByLen( nStartStripGuideId, 10) - EgtExtendCurveEndByLen( nStartStripGuideId, 10) - EgtMove( nStartStripGuideId, Z_AX()) - - -- estrudo Strip start - local b3RefStartProfile = GetProfileLocalBox( nStartProfileId) - local nStartStripExtrusionId = EgtSurfTmByExtrusion( nSolidLayerId, nStartStripGuideId, - Z_AX() * ( b3RefStartProfile:getDimY() + 2), WIN_SURF_APPROX) - EgtInvertSurf( nStartStripExtrusionId) - - -- intersezione con main - EgtSurfTmIntersect( nMainStripExtrusionId, nStartStripExtrusionId) - - -- c) taglio con end - -- recupero strip piu' vicino ad outline - local nEndStripId = GetStripNearestToOutline( nEndProfileId, vNextOutlineId[1], nOutlineId) - - -- disegno guida end per lo strip trovando le intersezioni degli outline minimi e massimi tra MainStrip ed EndStrip - local nEndStripMinOffsetId, nEndStripMaxOffsetId = CreateStripGuideLines( vNextOutlineId[1], nEndStripId, nEndProfileId, nSolidLayerId) - local ptStripMinEnd = FindIntersectionPoint( nMainStripMinOffsetId, nEndStripMinOffsetId, EgtEP( nMainStripMinOffsetId)) - local ptStripMaxEnd = FindIntersectionPoint( nMainStripMaxOffsetId, nEndStripMaxOffsetId, EgtEP( nMainStripMaxOffsetId)) - local nEndStripGuideId = EgtLine( nSolidLayerId, ptStripMinEnd, ptStripMaxEnd) - EgtExtendCurveStartByLen( nEndStripGuideId, 10) - EgtExtendCurveEndByLen( nEndStripGuideId, 10) - EgtMove( nEndStripGuideId, Z_AX()) - - -- estrudo Strip end - local b3RefEndProfile = GetProfileLocalBox( nEndProfileId) - local nEndStripExtrusionId = EgtSurfTmByExtrusion( nSolidLayerId, nEndStripGuideId, - Z_AX() * ( b3RefEndProfile:getDimY() + 2), WIN_SURF_APPROX) + local nCrvId = EgtGetInfo( vGeoCrvs[i], WIN_REF_OUTLINE, 'i') + local nPartId = FindAssociatedPart( nCrvId, true) + local nOutlineId = EgtGetInfo( nPartId, WIN_REF_OUTLINE, 'i') + + -- recupero profilo + local nProfileLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE) + local nProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN) + local nStripId = GetStripNearestToOutline( nProfileId, nCrvId) - -- intersezione con main - EgtSurfTmIntersect( nMainStripExtrusionId, nEndStripExtrusionId) - - -- cancello curve e superfici di costruzione - EgtErase( nSectionId) - EgtErase( { nMainStripMinOffsetId, nMainStripMaxOffsetId}) - EgtErase( { nStartStripMinOffsetId, nStartStripMaxOffsetId, nStartStripGuideId, nStartStripExtrusionId}) - EgtErase( { nEndStripMinOffsetId, nEndStripMaxOffsetId, nEndStripGuideId, nEndStripExtrusionId}) - + -- recupero layer per solido + local nSolidLayerId = EgtGetFirstNameInGroup( nPartId, WIN_SOLID) + + -- estrusione del fermavetro + local nGuideId = EgtGetFirstNameInGroup( nSolidLayerId, WIN_MAINGUIDE) + local nSectionId = EgtCopyGlob( nStripId, nSolidLayerId) + local nFrameProfileId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME) + local frOrig = EgtFR( nFrameProfileId, GDB_ID.ROOT) + frOrig:invert() + local frDest = Frame3d( EgtSP( nGuideId), - EgtSV( nGuideId)) + EgtTransform( nSectionId, frOrig) + EgtTransform( nSectionId, frDest) + local nStripExtrusionId = EgtSurfTmSwept( nSolidLayerId, nSectionId, nGuideId, false, WIN_SURF_APPROX) + EgtSetName( nStripExtrusionId, WIN_SRF_STRIP) + EgtErase( nSectionId) + + -- curve limite del fermavetro + local nOffs1, nOffs2 = CreateStripGuideLines( nOutlineId, nCrvId, nStripId, nProfileId, nGrp) + EgtSetInfo( nOffs1, WIN_REF_GEO, vGeoCrvs[i]) + EgtSetInfo( nOffs2, WIN_REF_GEO, vGeoCrvs[i]) + + tabStrip[vGeoCrvs[i]] = { OrigOffs1 = nOffs1, OrigOffs2 = nOffs2, Offs1 = GDB_ID.NULL, Offs2 = GDB_ID.NULL, StripId = nStripExtrusionId} + EgtCopyGlob( nOffs1, nGrp1) + EgtCopyGlob( nOffs2, nGrp2) + end + + -- taglio le curve limite dei fermavetri per individuare correttamente i pezzi con cui verranno tagliati + TrimOrderedCurves( EgtGetAllInGroup( nGrp1)) + TrimOrderedCurves( EgtGetAllInGroup( nGrp2)) + + -- associo le curve trimmate alle curve geo corrispondenti + local nCrvId = EgtGetFirstInGroup( nGrp1) + while nCrvId do + local nGeoRef = EgtGetInfo( nCrvId, WIN_REF_GEO, 'i') + tabStrip[nGeoRef].Offs1 = nCrvId + nCrvId = EgtGetNext( nCrvId) + end + nCrvId = EgtGetFirstInGroup( nGrp2) + while nCrvId do + local nGeoRef = EgtGetInfo( nCrvId, WIN_REF_GEO, 'i') + tabStrip[nGeoRef].Offs2 = nCrvId + nCrvId = EgtGetNext( nCrvId) + end + + -- trim dei solidi fermavetro + for i = 1, #vGeoCrvs do + + -- recupero solido del fermavetro + local nGeoCrv = vGeoCrvs[i] + local nStripId = tabStrip[nGeoCrv].StripId + local nSolidLayerId = EgtGetParent( nStripId) + + -- recupero le corrispondenti curve limite trimmate + local nCrvOffs1 = tabStrip[nGeoCrv].Offs1 + local nCrvOffs2 = tabStrip[nGeoCrv].Offs2 + + -- se entrambe le curve valide + if nCrvOffs1 ~= GDB_ID.NULL and nCrvOffs2 ~= GDB_ID.NULL then + -- a) trim start + -- recupero le precedenti della curva 1 e 2 + local nPrev1 = EgtGetPrev( nCrvOffs1) or EgtGetLastInGroup( nGrp1) + local nPrev2 = EgtGetPrev( nCrvOffs2) or EgtGetLastInGroup( nGrp2) + local nPrevCrv1 = EgtGetInfo( nPrev1, WIN_REF_GEO, 'i') + local nPrevCrv2 = EgtGetInfo( nPrev2, WIN_REF_GEO, 'i') + + if nPrevCrv1 == nPrevCrv2 then + -- se le precedenti coincidono devo tagliare con un solo pezzo + TrimStripSurf( EgtSP( nCrvOffs2), EgtSP( nCrvOffs1), nStripId, nSolidLayerId, true) + else + -- se ho due precedenti distinte, devo tagliare con due pezzi : + -- nPrev1 : essendo la precedente per le curve 1, devo ricavare l'intersezione sulle curve 2 + local ptInt = FindIntersectionPoint( tabStrip[nPrevCrv1].OrigOffs2, tabStrip[nGeoCrv].OrigOffs2, EgtSP( nGeoCrv), true) + TrimStripSurf( ptInt, EgtSP( nCrvOffs1), nStripId, nSolidLayerId, true) + -- nPrev2 : essendo la precedente per le curve 2, devo ricavare l'intersezione sulle curve 1 + ptInt = FindIntersectionPoint( tabStrip[nPrevCrv2].OrigOffs1, tabStrip[nGeoCrv].OrigOffs1, EgtSP( nGeoCrv), true) + TrimStripSurf( EgtSP( nCrvOffs2), ptInt, nStripId, nSolidLayerId, true) + end + + -- b) trim end + -- recupero le successive per le curve 1 e 2 + local nNext1 = EgtGetNext( nCrvOffs1) or EgtGetFirstInGroup( nGrp1) + local nNext2 = EgtGetNext( nCrvOffs2) or EgtGetFirstInGroup( nGrp2) + local nNextCrv1 = EgtGetInfo( nNext1, WIN_REF_GEO, 'i') + local nNextCrv2 = EgtGetInfo( nNext2, WIN_REF_GEO, 'i') + + if nNextCrv1 == nNextCrv2 then + -- devo tagliare con un solo pezzo + TrimStripSurf( EgtEP( nCrvOffs1), EgtEP( nCrvOffs2), nStripId, nSolidLayerId) + else + -- devo tagliare con due pezzi + -- nNext1 + local ptInt = FindIntersectionPoint( tabStrip[nGeoCrv].OrigOffs2, tabStrip[nNextCrv1].OrigOffs2, EgtEP( nGeoCrv), true) + TrimStripSurf( EgtEP( nCrvOffs1), ptInt, nStripId, nSolidLayerId) + -- nNext2 + ptInt = FindIntersectionPoint( tabStrip[nGeoCrv].OrigOffs1, tabStrip[nNextCrv2].OrigOffs1, EgtEP( nGeoCrv), true) + TrimStripSurf( ptInt, EgtEP( nCrvOffs2), nStripId, nSolidLayerId) + end + + else + if nCrvOffs1 == -1 and nCrvOffs2 ~= -1 then + -- se la curva 1 scompare devo ricavare le intersezioni prev e next su di essa + local nPrevId = EgtGetPrev( nGeoCrv) or EgtGetLastInGroup( nGeoFillId) + local nNextId = EgtGetNext( nGeoCrv) or EgtGetFirstInGroup( nGeoFillId) + local ptIntPrev = FindIntersectionPoint( tabStrip[nPrevId].OrigOffs1, tabStrip[nGeoCrv].OrigOffs1, EgtSP( nGeoCrv), true) + local ptIntNext = FindIntersectionPoint( tabStrip[nGeoCrv].OrigOffs1, tabStrip[nNextId].OrigOffs1, EgtEP( nGeoCrv), true) + -- trim start ed end + TrimStripSurf( EgtSP( nCrvOffs2), ptIntPrev, nStripId, nSolidLayerId) + TrimStripSurf( ptIntNext, EgtEP( nCrvOffs2), nStripId, nSolidLayerId) + else + -- il fermavetro non serve + EgtErase( nStripId) + end + end + end + + EgtErase( nGrp) + EgtErase( nGrp1) + EgtErase( nGrp2) end - - ---------------------------------------------------------------------------------- ----------------------------- CALCOLO PEZZI ------------------------------------ ---------------------------------------------------------------------------------- @@ -3442,7 +3858,7 @@ local function DrawOpening( nAreaId) end EgtOffsetCurve( nCrv, dOffs) end - TrimAndOrientOrderedCurves( vCrvs, false) + vCrvs = TrimOrderedCurves( vCrvs) local nGuideId = EgtCurveCompo( nOpeningLayId, vCrvs) local _, dParE = EgtCurveDomain( nGuideId) @@ -3615,8 +4031,10 @@ local function CreatePartFromOutline( nAreaLayerId, sName, nOutlineId, nOutlineC local nGeoLayerId = CalcFillGeo( nPartId, nOutlineLayerId) -- disegno solido if s_bCalcSolid then - CalcFillSolid( nPartId, nOutlineLayerId, nGeoLayerId) + CalcFillSolid( nPartId, nGeoLayerId) end + -- calcolo fermavetro + CalcAreaStrip( nGeoLayerId) end return nPartId end @@ -3663,27 +4081,14 @@ local function CalculateAreaParts( nAreaId) EgtSetName( nSelectionLayerId, WIN_SPLITSELECTION) EgtSetStatus( nSelectionLayerId, GDB_ST.OFF) local nSplitPartGeoId = EgtGetFirstNameInGroup( nSplitPartId, WIN_GEO) - local nSelectionArea = CreateGeoArea( nSplitPartGeoId, nSelectionLayerId, false) + local nSplitArea = EgtGetFirstNameInGroup( nSplitPartGeoId, WIN_GEO_SURF) + local nSelectionArea = EgtCopyGlob( nSplitArea, nSelectionLayerId) + EgtSetStatus( nSelectionArea, GDB_ST.ON) EgtSetColor( nSelectionArea, 'YELLOW') EgtSetAlpha( nSelectionArea, 10) EgtMove( nSelectionArea, 10 * Z_AX()) end end - elseif nAreaType ~= WIN_AREATYPES.FILL then - if s_bCalcSolid then - --- verifico se area successiva e' un fill - local nChildAreaId = EgtGetFirstNameInGroup( nAreaId, WIN_AREA .. '*') - local nChildAreaType = EgtGetInfo( nChildAreaId or GDB_ID.NULL, WIN_AREATYPE, "i") - if nChildAreaType == WIN_AREATYPES.FILL then - -- se lo e', vuol dire che e' un vetro fisso, quindi calcolo strip dell'outline - local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE) - local nOutlineId = EgtGetFirstInGroup( nOutlineLayerId) - while nOutlineId do - CreateStripFromOutline( nAreaId, nOutlineId) - nOutlineId = EgtGetNext( nOutlineId) - end - end - end end -- se anta disegno apertura @@ -3937,8 +4342,8 @@ local function CalcLogs( nGrp, nGeoOut, dOverMatIn, dOverMatOut, dOverMatExt, dO -- taglio le curve nei loro punti di intersezione local vCrvs = { nLineTop, nLineRight, nLineBottom, nLineLeft} - TrimAndOrientOrderedCurves( vCrvs, false) - + vCrvs = TrimOrderedCurves( vCrvs) + -- TO DO : controllo lunghezza minima -- local dLenTop = EgtCurveLength( nLineTop) @@ -4261,7 +4666,18 @@ local function CalcGeoRawFromLogs( nPartId) table.insert( vCrvs, nLineL) -- taglio le curve nelle intersezioni ( va eliminato il sovramateriale per minizinken) - TrimAndOrientOrderedCurves( vCrvs, false) + local nPrevId = vCrvs[#vCrvs] + local vPtInters = {} + for i = 1, #vCrvs do + vPtInters[i] = FindIntersectionPoint( nPrevId, vCrvs[i], EgtSP( vCrvs[i])) + nPrevId = vCrvs[i] + end + vPtInters[#vPtInters + 1] = vPtInters[1] + for i = 1, #vCrvs do + local dParS = EgtCurveParamAtPoint( vCrvs[i], vPtInters[i]) + local dParE = EgtCurveParamAtPoint( vCrvs[i], vPtInters[i+1]) + EgtTrimCurveStartEndAtParam( vCrvs[i], dParS, dParE) + end -- costruisco la compo del grezzo local nCompo = EgtCurveCompo( nGeoRawLayerId, vCrvs) @@ -4732,7 +5148,7 @@ local function SearchSash( nAreaId, SashList) EgtSetInfo( nOutlineCopyId, WIN_GAPDELTAZ .. 2, b3Profile:getDimY()) nOutlineId = EgtGetNext( nOutlineId) end - TrimAndOrientOrderedCurves( vOutlineCopy, false) + vOutlineCopy = TrimOrderedCurves( vOutlineCopy) -- costruisco i riferimenti local tFrame = {} @@ -5497,8 +5913,8 @@ local function GetTrimParamsByPrevAndNext( nCrvId, nAuxCrvId, sGeoRef) local nAuxGrp = EgtGetParent( nCrvId) -- recupero curve prev e next di riferimento - local nPrevCrv = EgtGetInfo( nAuxCrvId, WIN_PREV_OUTLINES, 'i') - local nNextCrv = EgtGetInfo( nAuxCrvId, WIN_NEXT_OUTLINES, 'i') + local nPrevCrv = abs( EgtGetInfo( nAuxCrvId, WIN_PREV_OUTLINES, 'i')) + local nNextCrv = abs( EgtGetInfo( nAuxCrvId, WIN_NEXT_OUTLINES, 'i')) if not nPrevCrv or not nNextCrv then -- gestione speciale per soglia dove prev e next non sono settati local nRefGrp = EgtGetParent( nAuxCrvId) @@ -5780,7 +6196,7 @@ local function CalcGaskets( nAreaId, bDraw) if #vCrvs > 0 then -- taglio le curve - TrimAndOrientOrderedCurves( vCrvs, true) + TrimOrderedCurves( vCrvs) -- aggiorno lunghezza for i = 1, #vCrvs do @@ -5929,11 +6345,12 @@ local function CalcBottomRailPreview( nPreviewGrp, nOutlineId, nBottomRail, nPro -- la curva out corrisponde al geo in del pezzo bottom local nPartGeoIn = EgtGetFirstNameInGroup( nGeoGrp, WIN_GEO_IN) vCrvs[1] = EgtCopyGlob( nPartGeoIn, nPreviewGrp) - + EgtInvertCurve( vCrvs[1]) + local vNextOutlines = EgtGetInfo( nOutlineId, WIN_NEXT_OUTLINES, 'vi') local vEndProfiles = EgtGetNameInGroup( nProfileGrp, WIN_PRF_END) local b3ProfileEnd = GetProfileLocalBox( vEndProfiles[1]) - vCrvs[2] = EgtCopyGlob( vNextOutlines[1], nPreviewGrp) + vCrvs[2] = EgtCopyGlob( abs( vNextOutlines[1]), nPreviewGrp) EgtOffsetCurve( vCrvs[2], b3ProfileEnd:getMin():getX()) -- la curva in corrisponde al geo in dell'ultimo bottomrail @@ -5946,25 +6363,23 @@ local function CalcBottomRailPreview( nPreviewGrp, nOutlineId, nBottomRail, nPro local vPrevOutlines = EgtGetInfo( nOutlineId, WIN_PREV_OUTLINES, 'vi') local vStartProfiles = EgtGetNameInGroup( nProfileGrp, WIN_PRF_START) local b3ProfileStart = GetProfileLocalBox( vStartProfiles[1]) - vCrvs[4] = EgtCopyGlob( vPrevOutlines[1], nPreviewGrp) + vCrvs[4] = EgtCopyGlob( abs( vPrevOutlines[1]), nPreviewGrp) EgtOffsetCurve( vCrvs[4], b3ProfileStart:getMin():getX()) - -- creo il bordo - TrimAndOrientOrderedCurves( vCrvs, true) - local nCrvId = EgtCurveCompo( nPreviewGrp, vCrvs, false) + -- creo la regione e ne estraggo il bordo + local nAreaId = CalcIntersectionRegion( vCrvs, nPreviewGrp) + EgtSetColor( nAreaId, color) + local nCrvId = EgtExtractSurfFrChunkLoops( nAreaId, 0, nPreviewGrp) EgtSetColor( nCrvId, EgtStdColor( 'BLACK')) EgtModifyCurveThickness( nCrvId, 0) - -- creo la regione - local nAreaId = EgtSurfFlatRegion( nPreviewGrp, {nCrvId}) - EgtSetColor( nAreaId, color) - EgtRelocateGlob( nCrvId, nAreaId, GDB_IN.AFTER) - + -- creo linee di divisione tra gli zoccoli if nBottomRail > 1 then - local dLen = EgtCurveLength( vCrvs[1]) - local dStep = 1 / nBottomRail + local b3Surf = EgtGetBBoxGlob( nAreaId, GDB_BB.STANDARD) + local dLen = b3Surf:getDimX() + local dStep = b3Surf:getDimY() / nBottomRail for i = 1, nBottomRail - 1 do - local pt = EgtUP( vCrvs[4], i * dStep) + local pt = b3Surf:getMin() + i * dStep * Y_AX() local nCrvId = EgtLinePVL( nPreviewGrp, pt, X_AX(), dLen) EgtSetColor( nCrvId, EgtStdColor( 'BLACK')) end @@ -5976,85 +6391,102 @@ end ---------------------------------------------------------------------------------- local function CalcPartPreview( nPartId, nPreviewGrp) + local nAreaId + local nOutlineId = EgtGetInfo( nPartId, WIN_REF_OUTLINE, 'i') local nGeoGrp = EgtGetFirstNameInGroup( nPartId, WIN_GEO) local nProfileGrp = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE) - - -- gruppo temporaneo per i conti - 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 + + -- 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') - if bOnSplit then - local nCrv = EgtCopyGlob( nOutlineId, nGrpTmp) - EgtSetName( nCrv, WIN_GEO_OUT) -- setto il nome per la funzione CreateGeoArea - else - local nGeoOut = EgtGetFirstNameInGroup( nGeoGrp, WIN_GEO_OUT) - EgtCopyGlob( nGeoOut, nGrpTmp) - end - -- curva right - local nEndJoint = EgtGetInfo( nOutlineId, WIN_ENDJOINT, 'i') - if nEndJoint == WIN_PART_JNT.SHORT then - -- se giunzione short per evitare sovrapposizioni devo fermarla al box del pezzo adiacente - local vNextOutlines = EgtGetInfo( nOutlineId, WIN_NEXT_OUTLINES, 'vi') - local vEndProfiles = EgtGetNameInGroup( nProfileGrp, WIN_PRF_END) - for i = 1, #vNextOutlines do - local nCrv = EgtCopyGlob( vNextOutlines[i], nGrpTmp) - local b3Profile = GetProfileLocalBox( vEndProfiles[i]) - local dRailDelta = EgtGetInfo( vEndProfiles[i], WIN_RAILDELTA, 'd') or 0 - local dOffs = b3Profile:getMin():getX() - dRailDelta - EgtOffsetCurve( nCrv, dOffs) - EgtSetName( nCrv, WIN_RIGHT) - end - else - -- altrimenti posso utilizzare la curva del geo - local vGeoRight = EgtGetNameInGroup( nGeoGrp, WIN_RIGHT) - for i = 1, #vGeoRight do - EgtCopyGlob( vGeoRight[i], nGrpTmp) - end - end - - -- curva in - local nGeoIn = EgtGetFirstNameInGroup( nGeoGrp, WIN_GEO_IN) - EgtCopyGlob( nGeoIn, nGrpTmp) - - -- curva left + -- recupero il tipo di giunzione local nStartJoint = EgtGetInfo( nOutlineId, WIN_STARTJOINT, 'i') - if nStartJoint == WIN_PART_JNT.SHORT then - local vPrevOutlines = EgtGetInfo( nOutlineId, WIN_PREV_OUTLINES, 'vi') - local vStartProfiles = EgtGetNameInGroup( nProfileGrp, WIN_PRF_START) - for i = 1, #vPrevOutlines do - local nCrv = EgtCopyGlob( vPrevOutlines[i], nGrpTmp) - local b3Profile = GetProfileLocalBox( vStartProfiles[i]) - local dRailDelta = EgtGetInfo( vStartProfiles[i], WIN_RAILDELTA, 'd') or 0 - local dOffs = b3Profile:getMin():getX() - dRailDelta - EgtOffsetCurve( nCrv, dOffs) - EgtSetName( nCrv, WIN_LEFT) - end + 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 + local nGeoSurf = EgtGetFirstNameInGroup( nGeoGrp, WIN_GEO_SURF) + nAreaId = EgtCopyGlob( nGeoSurf, nPreviewGrp) + EgtSetStatus( nAreaId, GDB_ST.ON) + + -- altrimenti devi calcolare le curve che delimitano la regione else - local vGeoLeft = EgtGetNameInGroup( nGeoGrp, WIN_LEFT) - for i = 1, #vGeoLeft do - EgtCopyGlob( vGeoLeft[i], nGrpTmp) + -- gruppo temporaneo per i conti + 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 + if bOnSplit then + EgtCopyGlob( nOutlineId, nGrpTmp) + else + local nGeoOut = EgtGetFirstNameInGroup( nGeoGrp, WIN_GEO_OUT) + EgtCopyGlob( nGeoOut, nGrpTmp) end + + -- curva right + if nEndJoint == WIN_PART_JNT.SHORT then + -- se giunzione short per evitare sovrapposizioni devo fermarla al box del pezzo adiacente + local vNextOutlines = EgtGetInfo( nOutlineId, WIN_NEXT_OUTLINES, 'vi') + local vEndProfiles = EgtGetNameInGroup( nProfileGrp, WIN_PRF_END) + for i = 1, #vNextOutlines do + local nCrv = EgtCopyGlob( abs( vNextOutlines[i]), nGrpTmp) + local b3Profile = GetProfileLocalBox( vEndProfiles[i]) + local dRailDelta = EgtGetInfo( vEndProfiles[i], WIN_RAILDELTA, 'd') or 0 + local dOffs = b3Profile:getMin():getX() - dRailDelta + if vNextOutlines[i] < 0 then + EgtInvertCurve( nCrv) + dOffs = - ( b3Profile:getMax():getX() - dRailDelta) + end + EgtOffsetCurve( nCrv, dOffs) + end + else + -- altrimenti posso utilizzare la curva del geo + local vGeoRight = EgtGetNameInGroup( nGeoGrp, WIN_RIGHT) + for i = 1, #vGeoRight do + EgtCopyGlob( vGeoRight[i], nGrpTmp) + end + end + + -- curva in + local nGeoIn = EgtGetFirstNameInGroup( nGeoGrp, WIN_GEO_IN) + EgtCopyGlob( nGeoIn, nGrpTmp) + + -- curva left + if nStartJoint == WIN_PART_JNT.SHORT then + local vPrevOutlines = EgtGetInfo( nOutlineId, WIN_PREV_OUTLINES, 'vi') + local vStartProfiles = EgtGetNameInGroup( nProfileGrp, WIN_PRF_START) + for i = 1, #vPrevOutlines do + local nCrv = EgtCopyGlob( abs( vPrevOutlines[i]), nGrpTmp) + local b3Profile = GetProfileLocalBox( vStartProfiles[i]) + local dRailDelta = EgtGetInfo( vStartProfiles[i], WIN_RAILDELTA, 'd') or 0 + local dOffs = b3Profile:getMin():getX() - dRailDelta + if vPrevOutlines[i] < 0 then + EgtInvert( nCrv) + dOffs = - ( b3Profile:getMax():getX() - dRailDelta) + end + EgtOffsetCurve( nCrv, dOffs) + end + else + local vGeoLeft = EgtGetNameInGroup( nGeoGrp, WIN_LEFT) + for i = 1, #vGeoLeft do + EgtCopyGlob( vGeoLeft[i], nGrpTmp) + end + end + + -- creo la regione + nAreaId = CalcIntersectionRegion( EgtGetAllInGroup( nGrpTmp), nPreviewGrp) + EgtErase( nGrpTmp) end - -- eventuale trim delle curve se non ho considerato tutte le curve del geo - if nStartJoint == WIN_PART_JNT.SHORT or nEndJoint == WIN_PART_JNT.SHORT or bOnSplit then - TrimAndOrientOrderedCurves( EgtGetAllInGroup( nGrpTmp), true) - end - - -- creo il bordo e la regione - local nAreaId = CreateGeoArea( nGrpTmp, nPreviewGrp, true) + -- sistemo la regione local color = EgtGetColor( nPartId) EgtSetColor( nAreaId, color) - local nCrvId = EgtGetPrev( nAreaId or GDB_ID.NULL) or GDB_ID.NULL - EgtRelocateGlob( nCrvId, nAreaId, GDB_IN.AFTER) - EgtSetColor( nCrvId, EgtStdColor( 'BLACK')) - EgtModifyCurveThickness( nCrvId, 0) - EgtErase( nGrpTmp) - + -- estraggo il contorno + local nCompoId = EgtExtractSurfFrChunkLoops( nAreaId, 0, nPreviewGrp) + EgtSetColor( nCompoId, EgtStdColor( 'BLACK')) + EgtModifyCurveThickness( nCompoId, 0) + -- se bottom aggiungo anche eventuale preview del bottomrail if EgtGetName( nOutlineId) == WIN_BOTTOM then local nBottomRail = EgtGetInfo( nOutlineId, WIN_BOTTOMRAIL, 'i') or 0