From f8eab3581ce7e9dd4ef3a0c016ad7027d6e19878 Mon Sep 17 00:00:00 2001 From: SaraP Date: Wed, 1 Apr 2026 09:19:23 +0200 Subject: [PATCH] DataWindow : - gestione dei pezzi di ante troppo piccoli che scompaiono - correzione nel calcolo outline sash e fill nel caso di cambio profilo - migliorie nel calcolo solidi e lavorazioni. --- Designing/WinConst.lua | 3 +- Designing/WinLib/WinCalculate.lua | 2088 +++++++++++++++++------------ Designing/WinProject.lua | 6 - 3 files changed, 1250 insertions(+), 847 deletions(-) diff --git a/Designing/WinConst.lua b/Designing/WinConst.lua index 7182fa9..755c314 100644 --- a/Designing/WinConst.lua +++ b/Designing/WinConst.lua @@ -204,7 +204,8 @@ WIN_SPLIT_POSITION = 'SplitPosition' WIN_SPLIT_OFFS = 'SplitOffs' WIN_GRID_SPLIT = 'GridSplit' WIN_DAYLIGHT_MEASURE = 'DaylightMeasure' - +WIN_EXTRA_CRV = 'Extra' +WIN_SPECIAL_CRV = 'Special' -- PROFILI WIN_PROFILE = 'Profile' diff --git a/Designing/WinLib/WinCalculate.lua b/Designing/WinLib/WinCalculate.lua index 89ef839..67f5a4d 100644 --- a/Designing/WinLib/WinCalculate.lua +++ b/Designing/WinLib/WinCalculate.lua @@ -21,11 +21,11 @@ local JSON = require( 'JSON') local XML = require( 'xml2lua') local XMLHandler = require( 'xml2lua_tree') -local s_nRedisConnectionId = 0 -- 0 connessione non definita, > 0 connessione definita +local s_nRedisConnectionId = 0 -- 0 connessione non definita, > 0 connessione definita local s_dDowelTol = 1 local s_dSimplSolidApprox = 0.2 -- approssimazione lineare nel caso di solidi semplificati -local s_nSashNbr = 0 -- contatore delle ante per assegnare nomi -local s_dAngledCos = 0.995 -- coseno limite oltre il quale viene forzata giunzione angled +local s_nSashNbr = 0 -- contatore delle ante per assegnare nomi +local s_dAngledCos = 0.995 -- coseno limite oltre il quale viene forzata giunzione angled local s_bCalcSolid = false @@ -80,20 +80,15 @@ local function FindIntersectionPoint( nCrv1, nCrv2, ptRef) local nType1 = EgtGetType( nCrv1) local nType2 = EgtGetType( nCrv2) - -- se compo formata da una sola sottocurva viene gestita come curva semplice + -- se compo viene gestita estensione solo sulla sua prima/ultima curva if nType1 == GDB_TY.CRV_COMPO then local _, dE = EgtCurveDomain( nCrv1) - if abs( dE - 1) < GEO.EPS_SMALL then - nCrv1 = EgtCopyCompoSubCurve( nCrv1, 0, nGrp) - nType1 = EgtGetType( nCrv1) - end + nCrv1 = EgtCopyCompoSubCurve( nCrv1, dE - 1, nGrp) + nType1 = EgtGetType( nCrv1) end if nType2 == GDB_TY.CRV_COMPO then - local _, dE = EgtCurveDomain( nCrv2) - if abs( dE - 1) < GEO.EPS_SMALL then - nCrv2 = EgtCopyCompoSubCurve( nCrv2, 0, nGrp) - nType2 = EgtGetType( nCrv2) - end + nCrv2 = EgtCopyCompoSubCurve( nCrv2, 0, nGrp) + nType2 = EgtGetType( nCrv2) end if nType1 == GDB_TY.CRV_LINE and nType2 == GDB_TY.CRV_LINE then @@ -278,8 +273,7 @@ local function CalcIntersectionRegion( vCrvs, nGrp) local nGrpTmp = EgtGroup( nGrp) EgtSetStatus( nGrpTmp, GDB_ST.OFF) - -- costruisco le regioni definite dai semipiani delle linee che compongono il contorno e calcolo le estensioni per gli archi ( verificando di non avere circonferenze coincidenti) - -- e le composite ( che vanno gestite come gli archi) + -- costruisco le regioni definite dai semipiani delle linee che compongono il contorno e calcolo le estensioni per gli archi e le composite ( che vanno gestite come gli archi) local dExtraLen = 10000 local vSemiPlanes = {} local tArcs = {} @@ -294,29 +288,9 @@ local function CalcIntersectionRegion( vCrvs, nGrp) table.insert( vSemiPlanes, nSemiPlaneId) elseif EgtGetType( vCrvs[i]) == GDB_TY.CRV_ARC then - local dRad = EgtArcRadius( vCrvs[i]) - - -- se circonferenza verifico di non averla già considerata - local bTangentStart = EgtGetInfo( vCrvs[i], WIN_TANG_START, 'b') or false - local bTangentEnd = EgtGetInfo( vCrvs[i], WIN_TANG_END, 'b') or false - if not bTangentStart and not bTangentEnd then - local ptC = EgtCP( vCrvs[i]) - local bOverlap = false - for j = 1, #tArcs do - if tArcs[j].ptC and AreSamePointApprox( tArcs[j].ptC, ptC) and abs( tArcs[j].dRad - dRad) < GEO.EPS_SMALL then - bOverlap = true - table.insert( tArcs[j].vOrigId, vCrvs[i]) - break - end - end - if not bOverlap then - local nCrvId = CreateCurveExtension( vCrvs[i], nGrpTmp) - table.insert( tArcs, { nCrvId = nCrvId, vOrigId = { vCrvs[i]}, dRad = dRad, ptC = ptC}) - end - else - local nCrvId = CreateCurveExtension( vCrvs[i], nGrpTmp) - table.insert( tArcs, { nCrvId = nCrvId, vOrigId = { vCrvs[i]}, dRad = dRad}) - end + local nCrvId = CreateCurveExtension( vCrvs[i], nGrpTmp) + table.insert( tArcs, { nCrvId = nCrvId, nOrigId = vCrvs[i], dRad = EgtArcRadius( vCrvs[i])}) + else -- se composita deve contenere un arco, recupero il suo raggio local _, dEnd = EgtCurveDomain( vCrvs[i]) @@ -327,7 +301,7 @@ local function CalcIntersectionRegion( vCrvs, nGrp) end local nCrvId = CreateCurveExtension( vCrvs[i], nGrpTmp) - table.insert( tArcs, { nCrvId = nCrvId, vOrigId = { vCrvs[i]}, dRad = dRad}) + table.insert( tArcs, { nCrvId = nCrvId, nOrigId = vCrvs[i], dRad = dRad}) end end @@ -371,30 +345,30 @@ local function CalcIntersectionRegion( vCrvs, nGrp) local vArcs = EgtTableFill( nCrv, nCnt) for j = nCrv, nCrv + nCnt - 1 do local nInters, nPntCnt, nCrvCnt = EgtCurveCurveInters( j, nCrvBorder, nGrpTmp) - if nCnt == 1 then - EgtChangeClosedCurveStartPoint( j, EgtSP( nInters)) - end - 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 + if nInters then + if nCnt == 1 then + EgtChangeClosedCurveStartPoint( j, EgtSP( nInters)) + end + 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 -- modifico il bordo corrente considerando solo i tratti che poggiano sulle curve originali for j = 1, #vArcs do - for k = 1, #tArcs[i].vOrigId do - if CheckExtensionOverlap( vArcs[j], tArcs[i].vOrigId[k]) then - local dParS = EgtCurveParamAtPoint( nCrvBorder, EgtSP( vArcs[j]), 100 * GEO.EPS_SMALL) - local dParE = EgtCurveParamAtPoint( nCrvBorder, EgtEP( vArcs[j]), 100 * GEO.EPS_SMALL) - EgtTrimCurveStartEndAtParam( nCrvBorder, dParE, dParS) - EgtAddCurveCompoCurve( nCrvBorder, vArcs[j]) - break - end + if CheckExtensionOverlap( vArcs[j], tArcs[i].nOrigId) then + local dParS = EgtCurveParamAtPoint( nCrvBorder, EgtSP( vArcs[j]), 100 * GEO.EPS_SMALL) + local dParE = EgtCurveParamAtPoint( nCrvBorder, EgtEP( vArcs[j]), 100 * GEO.EPS_SMALL) + EgtTrimCurveStartEndAtParam( nCrvBorder, dParE, dParS) + EgtAddCurveCompoCurve( nCrvBorder, vArcs[j]) + break end end end @@ -457,7 +431,7 @@ local function TrimOrderedCurves( vCrvs, bDelete, nSurfId) local nC = nFirstIdxCrv local nB = nFirstIdxBorder repeat - -- cerco la curva originale associata + -- cerco la curva originale associata partendo dall'ultima trovata local dDist = EgtPointCurveDist( EgtMP( nCrvBorder + nB), vExtCrvs[nC+1]) local nSafeCnt = 0 while dDist > 2 * GEO.EPS_SMALL and nSafeCnt < #vExtCrvs do @@ -469,7 +443,18 @@ local function TrimOrderedCurves( vCrvs, bDelete, nSurfId) if nSafeCnt == #vExtCrvs then return end - + -- se la curva originale trovata è già associata ad una curva di bordo, verifico se posso associare alla curva di bordo corrente la curva originale consecutiva + -- ( per gestire estensioni che si sovrappongono a curve originali) + if tabAss[vCrvs[nC + 1]] then + local nNext = ( nC + 1) % #vCrvs + dDist = EgtPointCurveDist( EgtMP( nCrvBorder + nB), vExtCrvs[nNext+1]) + while dDist < GEO.EPS_SMALL do + nC = nNext + nNext = ( nNext + 1) % #vCrvs + dDist = EgtPointCurveDist( EgtMP( nCrvBorder + nB), vExtCrvs[nNext+1]) + end + end + -- aggiungo associazione local nOrigCrv = vCrvs[nC + 1] if tabAss[nOrigCrv] then @@ -478,14 +463,14 @@ local function TrimOrderedCurves( vCrvs, bDelete, nSurfId) tabAss[nOrigCrv] = { nCrvBorder + nB} end - -- passo alla curve successive - nC = ( nC + 1) % #vCrvs + -- passo alla curva di bordo successiva nB = ( nB + 1) % nCnt until nB == nFirstIdxBorder -- sostituisco le curve originali con quelle di bordo appena calcolate local vResultCurves = {} + local vExtraCurves = {} for i = 1, #vCrvs do if not tabAss[vCrvs[i]] then @@ -493,9 +478,9 @@ local function TrimOrderedCurves( vCrvs, bDelete, nSurfId) if bDelete then EgtErase( vCrvs[i]) else - -- se non va eliminata setto info che ricorda di gestirla in modo speciale - EgtSetInfo( vCrvs[i], WIN_GEO_EXTRA, true) + -- se non va eliminata la restituisco come curva extra EgtSetStatus( vCrvs[i], GDB_ST.OFF) + table.insert( vExtraCurves, vCrvs[i]) end else @@ -529,7 +514,7 @@ local function TrimOrderedCurves( vCrvs, bDelete, nSurfId) end EgtErase( nGrpTmp) - return vResultCurves + return vResultCurves, vExtraCurves end --------------------------------------------------------------------- @@ -1382,59 +1367,83 @@ local function CalcPartJoint( nJointType, bHorizontal) end --------------------------------------------------------------------- -local function GetOutlineJoints( vOutlineIds, vJoints) +local function CalcOutlineStartJoint( nOutlineId, nPrevOutlineId, vJoints) - for i = 1, #vOutlineIds do - - local nPrevIdx = EgtIf( i == 1, #vOutlineIds, i - 1) - local nNextIdx = EgtIf( i == #vOutlineIds, 1, i + 1) - - local nStartJoint, nEndJoint - if EgtGetName( vOutlineIds[i]) == WIN_BOTTOM then - nStartJoint = CalcPartJoint( vJoints[1], true) - nEndJoint = CalcPartJoint( vJoints[2], true) - elseif EgtGetName( vOutlineIds[i]) == WIN_RIGHT then + local nStartJoint + + if EgtGetName( nOutlineId) == WIN_BOTTOM then + nStartJoint = CalcPartJoint( vJoints[1], true) + elseif EgtGetName( nOutlineId) == WIN_RIGHT then + nStartJoint = CalcPartJoint( vJoints[2], false) + elseif EgtGetName( nOutlineId) == WIN_TOP then + nStartJoint = CalcPartJoint( vJoints[3], true) + -- correzione per caso a triangolo : se l'outline vicino è di tipo bottom, il corrente deve essere trattato come un pezzo verticale + if EgtGetName( nPrevOutlineId) == WIN_BOTTOM then nStartJoint = CalcPartJoint( vJoints[2], false) - nEndJoint = CalcPartJoint( vJoints[3], false) - elseif EgtGetName( vOutlineIds[i]) == WIN_TOP then - nStartJoint = CalcPartJoint( vJoints[3], true) - nEndJoint = CalcPartJoint( vJoints[4], true) - -- correzioni per caso a triangolo : se l'outline vicino è di tipo bottom, il corrente deve essere trattato come un pezzo verticale - if EgtGetName( vOutlineIds[nPrevIdx]) == WIN_BOTTOM then - nStartJoint = CalcPartJoint( vJoints[2], false) - nEndJoint = CalcPartJoint( vJoints[3], true) - end - if EgtGetName( vOutlineIds[nNextIdx]) == WIN_BOTTOM then - nStartJoint = CalcPartJoint( vJoints[3], true) - nEndJoint = CalcPartJoint( vJoints[1], false) - end - elseif EgtGetName( vOutlineIds[i]) == WIN_LEFT then - nStartJoint = CalcPartJoint( vJoints[4] or vJoints[3], false) -- ( vJoints[3] per gestire caso a triangolo) + end + elseif EgtGetName( nOutlineId) == WIN_LEFT then + nStartJoint = CalcPartJoint( vJoints[4] or vJoints[3], false) -- ( vJoints[3] per gestire caso a triangolo) + end + + -- eventuali correzioni : + -- a) forzatura a bisettrice se elementi in tangenza ( entro 6°) o dello stesso tipo + if nStartJoint ~= WIN_PART_JNT.ANGLED then + if EgtEV( nPrevOutlineId) * EgtSV( nOutlineId) > s_dAngledCos or EgtGetName( nOutlineId) == EgtGetName( nPrevOutlineId) then + nStartJoint = WIN_PART_JNT.ANGLED + end + end + -- b) forzatura a short se incontro con soglia + if EgtGetInfo( nPrevOutlineId, WIN_THRESHOLD, 'b') then + nStartJoint = WIN_PART_JNT.SHORT + end + + return nStartJoint +end + +--------------------------------------------------------------------- +local function CalcOutlineEndJoint( nOutlineId, nNextOutlineId, vJoints) + + local nEndJoint + + if EgtGetName( nOutlineId) == WIN_BOTTOM then + nEndJoint = CalcPartJoint( vJoints[2], true) + elseif EgtGetName( nOutlineId) == WIN_RIGHT then + nEndJoint = CalcPartJoint( vJoints[3], false) + elseif EgtGetName( nOutlineId) == WIN_TOP then + nEndJoint = CalcPartJoint( vJoints[4] or vJoints[3], true) -- ( vJoints[3] per gestire caso a triangolo) + -- correzione per caso a triangolo : se l'outline vicino è di tipo bottom, il corrente deve essere trattato come un pezzo verticale + if EgtGetName( nNextOutlineId) == WIN_BOTTOM then nEndJoint = CalcPartJoint( vJoints[1], false) end - - -- eventuali correzioni : - -- a) forzatura a bisettrice se elementi in tangenza ( entro 6°) o dello stesso tipo - if nStartJoint ~= WIN_PART_JNT.ANGLED then - if EgtEV( vOutlineIds[nPrevIdx]) * EgtSV( vOutlineIds[i]) > s_dAngledCos or EgtGetName( vOutlineIds[i]) == EgtGetName( vOutlineIds[nPrevIdx]) then - nStartJoint = WIN_PART_JNT.ANGLED - end - end - if nEndJoint ~= WIN_PART_JNT.ANGLED then - if EgtEV( vOutlineIds[i]) * EgtSV( vOutlineIds[nNextIdx]) > s_dAngledCos or EgtGetName( vOutlineIds[i]) == EgtGetName( vOutlineIds[nNextIdx]) then - nEndJoint = WIN_PART_JNT.ANGLED - end - end - - -- b) forzatura a short se incontro con soglia - if EgtGetInfo( vOutlineIds[nPrevIdx], WIN_THRESHOLD, 'b') then - nStartJoint = WIN_PART_JNT.SHORT - end - if EgtGetInfo( vOutlineIds[nNextIdx], WIN_THRESHOLD, 'b') then - nEndJoint = WIN_PART_JNT.SHORT + elseif EgtGetName( nOutlineId) == WIN_LEFT then + nEndJoint = CalcPartJoint( vJoints[1], false) + end + + -- eventuali correzioni : + -- a) forzatura a bisettrice se elementi in tangenza ( entro 6°) o dello stesso tipo + if nEndJoint ~= WIN_PART_JNT.ANGLED then + if EgtEV( nOutlineId) * EgtSV( nNextOutlineId) > s_dAngledCos or EgtGetName( nOutlineId) == EgtGetName( nNextOutlineId) then + nEndJoint = WIN_PART_JNT.ANGLED end + end + + -- b) forzatura a short se incontro con soglia + if EgtGetInfo( nNextOutlineId, WIN_THRESHOLD, 'b') then + nEndJoint = WIN_PART_JNT.SHORT + end + + return nEndJoint +end - -- salvo come info sulla curva +--------------------------------------------------------------------- +local function GetOutlineJoints( vOutlineIds, nAreaId) + + local vJoints = EgtGetInfo( nAreaId, WIN_JOINTS, 'vi') + for i = 1, #vOutlineIds do + local nPrevIdx = EgtIf( i == 1, #vOutlineIds, i - 1) + local nNextIdx = EgtIf( i == #vOutlineIds, 1, i + 1) + local nStartJoint = CalcOutlineStartJoint( vOutlineIds[i], vOutlineIds[nPrevIdx], vJoints) + local nEndJoint = CalcOutlineEndJoint( vOutlineIds[i], vOutlineIds[nNextIdx], vJoints) EgtSetInfo( vOutlineIds[i], WIN_STARTJOINT, nStartJoint) EgtSetInfo( vOutlineIds[i], WIN_ENDJOINT, nEndJoint) end @@ -1518,29 +1527,11 @@ local function CreatePartsFromOutlines( vOutlines, nAreaId, sName) local nBottomRail = EgtGetInfo( nAreaId, WIN_BOTTOMRAIL, 'i') -- calcolo le giunzioni - local vJoints = EgtGetInfo( nAreaId, WIN_JOINTS, 'vi') - GetOutlineJoints( vOutlines, vJoints) + GetOutlineJoints( vOutlines, nAreaId) - -- sistemo le dimensioni in modo che pezzi coinvolti da giunzione a bisettrice ( scelta o forzata) abbiano la stessa dimensione - -- TODO meglio correzione o segnalare errore? Nelle ante usi le dimensioni teoriche per posizionare gli split, se venissero cambiate i conti non tornano + -- TODO segnalare errore se pezzi con giunzione angled non hanno le stesse dimensioni local vPartsDim = EgtGetInfo( nAreaId, WIN_PART_DIM, 'vd') or {} - for i = 2, #vOutlines do - local nStartJoint = EgtGetInfo( vOutlines[i], WIN_STARTJOINT, 'i') - if nStartJoint == WIN_PART_JNT.ANGLED then - vPartsDim[i] = vPartsDim[i-1] - end - end - if vPartsDim[1] ~= vPartsDim[#vOutlines] and EgtGetInfo( vOutlines[1], WIN_STARTJOINT, 'i') == WIN_PART_JNT.ANGLED then - for i = #vOutlines, 2, -1 do - local nEndJoint = EgtGetInfo( vOutlines[i], WIN_ENDJOINT, 'i') - if nEndJoint == WIN_PART_JNT.ANGLED then - vPartsDim[i] = vPartsDim[1] - else - break - end - end - end - + -- creo i pezzi per ogni curva for i = 1, #vOutlines do EgtSetInfo( vOutlines[i], WIN_PART_DIM, vPartsDim[i]) @@ -1587,7 +1578,7 @@ end ---------------------------------------------------------------------------------- ------------------------------ CALCOLO OUTLINE --------------------------------- ---------------------------------------------------------------------------------- -local function GetPrevNextOutline( vOutlines, nOutlineLayerId) +local function GetFramePrevNextOutline( vOutlines, nOutlineLayerId) for i = 2, #vOutlines - 1 do EgtSetInfo( vOutlines[i], WIN_PREV_OUTLINES, { vOutlines[i-1]}) @@ -1819,7 +1810,7 @@ local function TestSplitTrimOutlines( nOutlineId, nTrimOutline, tabOutlines, nMa local dExtraLen = b3Profile:getDimX() local nMainSurf = CreateProfileSurf( nOutlineId, nMainProfile, WIN_SECTION, 4 * dExtraLen, nGrpTmp) EgtCutSurfTmPlane( nMainSurf, EgtMP( nOutlineId), EgtIf( bPrevOrNext, 1, -1) * EgtSV( nOutlineId)) - + -- recupero profili per i conti local vProfiles = {} local vsCtrIn = {} @@ -1878,19 +1869,32 @@ local function GetSplitsPrevNextOutline( vSplitIds, vOutlineIds) -- controllo la validità delle curve prev/next trovate dall'intersezione degli outlines e la validità di eventuali curve vicine verificando l'interferenza tra i profili local nPrevOutlineId = EgtGetInfo( vSplitIds[i], WIN_SPLIT_STARTINTERS, 'i') - local vPrevOutlineId = TestSplitTrimOutlines( vSplitIds[i], nPrevOutlineId, tabOutlines, nMainProfile, b3Profile, nGrpTmp, true) - EgtSetInfo( vSplitIds[i], WIN_PREV_OUTLINES, vPrevOutlineId) + local vPrevOutlineIds = TestSplitTrimOutlines( vSplitIds[i], nPrevOutlineId, tabOutlines, nMainProfile, b3Profile, nGrpTmp, true) + EgtSetInfo( vSplitIds[i], WIN_PREV_OUTLINES, vPrevOutlineIds) + -- setto tutte le giunzioni a short + local vStartJoints = {} + for i = 1, #vPrevOutlineIds do + vStartJoints[i] = WIN_PART_JNT.SHORT + end + EgtSetInfo( vSplitIds[i], WIN_STARTJOINT, vStartJoints) + local nNextOutlineId = EgtGetInfo( vSplitIds[i], WIN_SPLIT_ENDINTERS, 'i') - local vNextOutlineId = TestSplitTrimOutlines( vSplitIds[i], nNextOutlineId, tabOutlines, nMainProfile, b3Profile, nGrpTmp, false) - EgtSetInfo( vSplitIds[i], WIN_NEXT_OUTLINES, vNextOutlineId) - + local vNextOutlineIds = TestSplitTrimOutlines( vSplitIds[i], nNextOutlineId, tabOutlines, nMainProfile, b3Profile, nGrpTmp, false) + EgtSetInfo( vSplitIds[i], WIN_NEXT_OUTLINES, vNextOutlineIds) + local vEndJoints = {} + for i = 1, #vNextOutlineIds do + vEndJoints[i] = WIN_PART_JNT.SHORT + end + EgtSetInfo( vSplitIds[i], WIN_ENDJOINT, vEndJoints) + + -- se split di tipo mixed i pezzi che incontra deve essere di tipo mixed ( anche se avevo trovato una sola tipologia di figli), devono essere separati da giunzione -- a bisettrice e devono avere le stesse dimensioni. Impongo queste condizioni eventualmente ricalcolando i profili local bChangeProfile = EgtGetInfo( vSplitIds[i], WIN_PRF_CHANGE, 'b') or false if bChangeProfile then - AdjustMixedFrames( vPrevOutlineId) - AdjustMixedFrames( vNextOutlineId) + AdjustMixedFrames( vPrevOutlineIds) + AdjustMixedFrames( vNextOutlineIds) end end @@ -2512,27 +2516,49 @@ local function CalculateSashOutline( nAreaId, nAreaLayerId, nOutlineLayerId) -- calcolo l'outline corrispondente al telaio local nFrameArea = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_AREA .. '*') local nFrameOutlineLayer = EgtGetFirstNameInGroup( nFrameArea, WIN_OUTLINE) - local nFrameOutlineId = EgtGetFirstInGroup( nFrameOutlineLayer) - while nFrameOutlineId do - -- copio l'outline del telaio - local nOutlineId = EgtCopyGlob( nFrameOutlineId, nOutlineLayerId) - EgtSetInfo( nOutlineId, WIN_SOU_OUTLINE, nFrameOutlineId) + local vFrameOutlines = EgtGetAllInGroup( nFrameOutlineLayer) + local vFrameOffs = {} + -- calcolo gli offset da applicare ad ogni curva + for i = 1, #vFrameOutlines do + -- recupero il suo profilo per calcolare l'offset ( se pezzo contro vetro fisso non serve, sarà tagliato da uno split) + local nProfileId = GetOutlineProfileId( vFrameOutlines[i]) + local sKey = EgtIf( EgtGetName( vFrameOutlines[i]) == WIN_BOTTOM, WIN_SASH_BOTTOM_OVERLAP, WIN_SASH_TOP_OVERLAP) + local dOverlap = EgtGetInfo( nProfileId, sKey, 'd') + if dOverlap then + local b3Profile = GetProfileLocalBox( nProfileId) + vFrameOffs[i] = b3Profile:getMin():getX() + dOverlap + end + end + -- costruisco l'outline + for i = 1, #vFrameOutlines do + local nOutlineId = EgtCopyGlob( vFrameOutlines[i], nOutlineLayerId) + EgtSetInfo( nOutlineId, WIN_SOU_OUTLINE, vFrameOutlines[i]) -- rimuovo info che non voglio trasferire sull'anta EgtRemoveInfo( nOutlineId, WIN_PRF_CHANGE) EgtRemoveInfo( nOutlineId, WIN_THRESHOLD) EgtRemoveInfo( nOutlineId, WIN_PART_DIM) - - -- recupero il suo profilo per calcolare l'offset ( se pezzo contro vetro fisso non serve, sarà tagliato da uno split) - local nProfileId = GetOutlineProfileId( nFrameOutlineId) - local sKey = EgtIf( EgtGetName( nOutlineId) == WIN_BOTTOM, WIN_SASH_BOTTOM_OVERLAP, WIN_SASH_TOP_OVERLAP) - local dOverlap = EgtGetInfo( nProfileId, sKey, 'd') - if dOverlap then - local b3Profile = GetProfileLocalBox( nProfileId) - local dFillPerpOffset = b3Profile:getMin():getX() + dOverlap - EgtOffsetCurve( nOutlineId, dFillPerpOffset) + -- applico l'offset + if vFrameOffs[i] then + EgtOffsetCurve( nOutlineId, vFrameOffs[i]) + else + -- se non ha offset definito è un pezzo che verrà tagliato da uno split ma, affinchè la forma del telaio sia coerente, se è in tangenza con uno dei suoi vicini + -- devo applicare lo stesso offset + local nPrevIdx = EgtIf( i == 1, #vFrameOutlines, i-1) + local nNextIdx = EgtIf( i == #vFrameOutlines, 1, i+1) + if AreSameVectorApprox( EgtSV( vFrameOutlines[i]), EgtEV( vFrameOutlines[nPrevIdx])) then + while not vFrameOffs[nPrevIdx] do + nPrevIdx = EgtIf( nPrevIdx == 1, #vFrameOutlines, nPrevIdx-1) + end + EgtOffsetCurve( nOutlineId, vFrameOffs[nPrevIdx]) + vFrameOffs[i] = vFrameOffs[nPrevIdx] + elseif AreSameVectorApprox( EgtEV( vFrameOutlines[i]), EgtSV( vFrameOutlines[nNextIdx])) then + while not vFrameOffs[nNextIdx] do + nNextIdx = EgtIf( nNextIdx == #vFrameOutlines, 1, nNextIdx+1) + end + EgtOffsetCurve( nOutlineId, vFrameOffs[nNextIdx]) + vFrameOffs[i] = vFrameOffs[nNextIdx] + end end - - nFrameOutlineId = EgtGetNext( nFrameOutlineId) end -- accorcio gli offset local vCrvs = TrimOrderedCurves( EgtGetAllInGroup( nOutlineLayerId), true) @@ -2660,10 +2686,244 @@ local function CalculateSashOutline( nAreaId, nAreaLayerId, nOutlineLayerId) local nSashProfileId = EgtGetFirstNameInGroup( nSashProfileLayerId, sSashProfile) local dSashZOffset = EgtGetInfo( nSashProfileId, WIN_DELTA, 'd') EgtMove( vOutlineCrvs, Z_AX() * dSashZOffset) - + return vOutlineCrvs end +--------------------------------------------------------------------- +local function VerifySashParts( vOutlines, nAreaId) + + -- controlla se i pezzi di un'anta sono validi e se necessitano di gestione speciale nel calcolo dei prev e dei next. Vi sono due tipologie di pezzi che richiedono gestione speciale : + -- a) extra : il pezzo non serve, il suo contributo si limita al trim dei suoi pezzi vicini con il suo bordo out + -- b) special : il pezzo è necessario ma non sufficiente per il trim dei suoi pezzi vicini, che vanno tagliati non solo con il pezzo stesso ma anche tra di loro + -- per distinguere i pezzi extra da special controllo se i semiprofili interni dei pezzi vicini si incontrano in un punto sensato per cui il pezzo risulta superfluo oppure no + + local nGrpTmp1 = EgtGroup( nAreaId) + local nGrpTmp2 = EgtGroup( nAreaId) + + -- recupero i bordi interni ed esterni dei semiprofili in + local vInSemiProfile = {} + local vOutSemiProfile = {} + for i = 1, #vOutlines do + + -- recupero il semiprofilo in + local nProfileId = GetOutlineProfileId( vOutlines[i]) + local nSectionFrId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME) + local frSectionFrame = EgtFR( nSectionFrId, GDB_ID.ROOT) + local nInId = EgtGetFirstNameInGroup( nProfileId, WIN_IN) + local b3In = EgtGetBBoxRef( nInId, GDB_BB.STANDARD, frSectionFrame) + + vInSemiProfile[i] = EgtCopyGlob( vOutlines[i], nGrpTmp1) + EgtSetInfo( vInSemiProfile[i], 'SouIdx', i) + -- se non è possibile calcolare l'interno ( e.g. arco con raggio inferiore alla sua dimensione) il pezzo è sicuramente extra ma considero comunque le sue curve nel fare i conti + -- per non sfalsare gli indici + if not EgtOffsetCurve( vInSemiProfile[i], b3In:getMin():getX()) then + EgtSetInfo( vOutlines[i], WIN_EXTRA_CRV, true) + end + + vOutSemiProfile[i] = EgtCopyGlob( vOutlines[i], nGrpTmp2) + EgtOffsetCurve( vOutSemiProfile[i], b3In:getMax():getX()) + EgtSetInfo( vOutSemiProfile[i], 'SouIdx', i) + end + + local _, vExtraIn = TrimOrderedCurves( vInSemiProfile, false) + -- se nessun bordo più interno scompare allora tutti i pezzi sono standard + if #vExtraIn == 0 then + EgtErase( nGrpTmp1) + EgtErase( nGrpTmp2) + return + end + + local _, vExtraOut = TrimOrderedCurves( vOutSemiProfile, false) + -- se il bordo esterno del suo profilo in scompare i suoi vicini si incontrano in modo sensato quindi il pezzo è sicuramente superfluo + for i = 1, #vExtraOut do + local nIdx = EgtGetInfo( vExtraOut[i], 'SouIdx', 'i') + EgtSetInfo( vOutlines[nIdx], WIN_EXTRA_CRV, true) + end + + -- analizzo i tratti con gestione speciale consecutivi insieme + local nOldId + local vExtraInGrps = {} + for i = 1, #vExtraIn do + local nIdx = EgtGetInfo( vExtraIn[i], 'SouIdx', 'i') + if not EgtGetInfo( vOutlines[nIdx], WIN_EXTRA_CRV, 'b') then + if not nOldId or EgtGetNext( nOldId) ~= vExtraIn[i] then + table.insert( vExtraInGrps, { vExtraIn[i]}) + else + table.insert( vExtraInGrps[#vExtraInGrps], vExtraIn[i]) + end + nOldId = vExtraIn[i] + end + end + + for i = 1, #vExtraInGrps do + + -- calcolo il punto di incontro dei semiprofili interni dei due pezzi vicini validi + local nIdx1 = EgtGetInfo( vExtraInGrps[i][1], 'SouIdx', 'i') + local nPrevIdx = EgtIf( nIdx1 == 1, #vOutlines, nIdx1-1) + while EgtGetInfo( vOutlines[nPrevIdx], WIN_EXTRA_CRV, 'b') do + nPrevIdx = EgtIf( nPrevIdx == 1, #vOutlines, nPrevIdx-1) + end + local nIdx2 = EgtGetInfo( vExtraInGrps[i][#vExtraInGrps[i]], 'SouIdx', 'i') + local nNextIdx = EgtIf( nIdx2 == #vOutlines, 1, nIdx2+1) + while EgtGetInfo( vOutlines[nNextIdx], WIN_EXTRA_CRV, 'b') do + nNextIdx = EgtIf( nNextIdx == #vOutlines, 1, nNextIdx+1) + end + local nPrevOut = vOutSemiProfile[nPrevIdx] + local nNextOut = vOutSemiProfile[nNextIdx] + local ptInters = FindIntersectionPoint( nPrevOut, nNextOut, EgtEP( nPrevOut)) + + -- ricavo le curva che delimita la regione valida per l'intersezione dei semiprofili dei pezzi vicini + local vCurrOutlines = {} + for j = 1, #vExtraInGrps[i] do + local nIdx = EgtGetInfo( vExtraInGrps[i][j], 'SouIdx', 'i') + vCurrOutlines[j] = vOutlines[nIdx] + end + local nCompoOutline = EgtCurveCompo( nGrpTmp1, vCurrOutlines, false) + local nProfileId = GetOutlineProfileId( vCurrOutlines[1]) + local nSectionFrId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME) + local frSectionFrame = EgtFR( nSectionFrId, GDB_ID.ROOT) + local nCPId = EgtGetFirstNameInGroup( nProfileId, WIN_OUT) + local b3CP = EgtGetBBoxRef( nCPId, GDB_BB.STANDARD, frSectionFrame) + local nRefCrv = EgtOffsetCurveAdv( nCompoOutline, b3CP:getMin():getX()) + local _, _, nSide = EgtPointCurveDistSide( ptInters, nRefCrv, Z_AX()) + + for j = 1, #vCurrOutlines do + -- se il punto di intersezione cade nella regione valida il pezzo è extra altrimenti è special + if nSide == -1 then + EgtSetInfo( vCurrOutlines[j], WIN_EXTRA_CRV, true) + else + EgtSetInfo( vCurrOutlines[j], WIN_SPECIAL_CRV, true) + end + end + end + + EgtErase( nGrpTmp1) + EgtErase( nGrpTmp2) +end + +--------------------------------------------------------------------- +local function GetSashPrevNextOutlines( vOutlineIds, nOutlineLayerId, nAreaId) + + local vJoints = EgtGetInfo( nAreaId, WIN_JOINTS, 'vi') + + for i = 1, #vOutlineIds do + + if EgtGetInfo( vOutlineIds[i], WIN_EXTRA_CRV, 'b') then + -- non c'è bisogno di settare prev/next perchè il pezzo viene ignorato + else + + -- a) prev + local nPrevId = EgtGetPrev( vOutlineIds[i]) or EgtGetLastInGroup( nOutlineLayerId) + local bExtra = EgtGetInfo( nPrevId, WIN_EXTRA_CRV, 'b') or false + local bSpecial = EgtGetInfo( nPrevId, WIN_SPECIAL_CRV, 'b') or false + if not bExtra and not bSpecial then + -- se il precedente è un pezzo standard il prev è solamente lui e il joint calcolato è già corretto + EgtSetInfo( vOutlineIds[i], WIN_PREV_OUTLINES, nPrevId) + else + -- recupero tutti i precedenti fino a quando non trovo un elemento standard + local vPrevIds = {} + while bExtra or bSpecial do + table.insert( vPrevIds, 1, nPrevId) + nPrevId = EgtGetPrev( nPrevId) or EgtGetLastInGroup( nOutlineLayerId) + bExtra = EgtGetInfo( nPrevId, WIN_EXTRA_CRV, 'b') or false + bSpecial = EgtGetInfo( nPrevId, WIN_SPECIAL_CRV, 'b') or false + end + table.insert( vPrevIds, 1, nPrevId) + + -- calcolo i joints + local vStartJoints = {} + local nOldId = vOutlineIds[i] + local nOldTgId = vOutlineIds[i] + local bTangChain = true -- indica se l'outline e i primi vicini formano una catena di curve in tangenza + local nJoint -- il primo joint non è quello salvato nelle info della curva ma è da calcolare con la prima curva non extra + for j = #vPrevIds, 1, -1 do + if EgtGetInfo( vPrevIds[j], WIN_EXTRA_CRV, 'b') then + -- con i pezzi extra la giunzione è sempre full perchè il pezzo corrente va trimmato con il loro bordo esterno + vStartJoints[j] = WIN_PART_JNT.FULL + else + if not nJoint then + nJoint = CalcOutlineStartJoint( nOldId, vPrevIds[j], vJoints) + end + if AreSameVectorApprox( EgtEV( vPrevIds[j]), EgtSV( nOldTgId)) then + -- curve in tangenza devono avere la stessa giunzione + vStartJoints[j] = nJoint + else + -- se arrivo dalla catena di primi vicini tangenti devo ricalcolare il joint altrimenti va forzato ad angled + if bTangChain then + nJoint = CalcOutlineStartJoint( nOldId, vPrevIds[j], vJoints) + else + nJoint = WIN_PART_JNT.ANGLED + end + bTangChain = false + vStartJoints[j] = nJoint + end + nOldId = vPrevIds[j] + end + -- gli extra vanno ignorati nel calcolo delle giunzioni ma vanno considerati per il calcolo delle tangenze + nOldTgId = vPrevIds[j] + end + + EgtSetInfo( vOutlineIds[i], WIN_PREV_OUTLINES, vPrevIds) + EgtSetInfo( vOutlineIds[i], WIN_STARTJOINT, vStartJoints) + end + + + -- b) next + local nNextId = EgtGetNext( vOutlineIds[i]) or EgtGetFirstInGroup( nOutlineLayerId) + bExtra = EgtGetInfo( nNextId, WIN_EXTRA_CRV, 'b') or false + bSpecial = EgtGetInfo( nNextId, WIN_SPECIAL_CRV, 'b') or false + if not bExtra and not bSpecial then + -- caso standard + EgtSetInfo( vOutlineIds[i], WIN_NEXT_OUTLINES, nNextId) + else + + local vNextIds = {} + while bExtra or bSpecial do + table.insert( vNextIds, nNextId) + nNextId = EgtGetNext( nNextId) or EgtGetFirstInGroup( nOutlineLayerId) + bExtra = EgtGetInfo( nNextId, WIN_EXTRA_CRV, 'b') or false + bSpecial = EgtGetInfo( nNextId, WIN_SPECIAL_CRV, 'b') + end + table.insert( vNextIds, nNextId) + + -- calcolo i joints + local vEndJoints = {} + local nOldId = vOutlineIds[i] + local nOldTgId = vOutlineIds[i] + local bTangChain = true + local nJoint + for j = 1, #vNextIds do + -- se extra la giunzione deve essere full + if EgtGetInfo( vNextIds[j], WIN_EXTRA_CRV, 'b') then + vEndJoints[j] = WIN_PART_JNT.FULL + else + if not nJoint then + nJoint = CalcOutlineEndJoint( nOldId, vNextIds[j], vJoints) + end + if AreSameVectorApprox( EgtEV( nOldTgId), EgtSV( vNextIds[j])) then + vEndJoints[j] = nJoint + else + if bTangChain then + nJoint = CalcOutlineEndJoint( nOldId, vNextIds[j], vJoints) + else + nJoint = WIN_PART_JNT.ANGLED + end + bTangChain = false + vEndJoints[j] = nJoint + end + nOldId = vNextIds[j] + end + nOldTgId = vNextIds[j] + end + + EgtSetInfo( vOutlineIds[i], WIN_NEXT_OUTLINES, vNextIds) + EgtSetInfo( vOutlineIds[i], WIN_ENDJOINT, vEndJoints) + end + end + end +end + ------------------------------ FILL ------------------------------- --------------------------------------------------------------------- @@ -2680,29 +2940,52 @@ local function CalculateFillOutline( nAreaId, nOutlineLayerId) -- 1) calcolo l'area complessiva di fill definita dal suo parent local nParentOutlineLayer = EgtGetFirstNameInGroup( nParentArea, WIN_OUTLINE) local dDeltaZ = 0 - local nParentOutlineId = EgtGetFirstInGroup( nParentOutlineLayer) - while nParentOutlineId do - -- copio la curva di outline del parent - local nOutlineId = EgtCopy( nParentOutlineId, nOutlineLayerId) - EgtSetInfo( nOutlineId, WIN_SOU_OUTLINE, nParentOutlineId) - + local vParentOutlines = EgtGetAllInGroup( nParentOutlineLayer) + local vParentOffs = {} + -- calcolo gli offset + for i = 1, #vParentOutlines do -- recupero il suo profilo per calcolare l'offset perpendicolare - local nParentProfileId = GetOutlineProfileId( nParentOutlineId, true) - local b3FrameProfile = GetProfileLocalBox( nParentProfileId) + local nParentProfileId = GetOutlineProfileId( vParentOutlines[i], true) local dOverlap = EgtGetInfo( nParentProfileId, WIN_FILLOVERLAP, 'd') if dOverlap then + local b3FrameProfile = GetProfileLocalBox( nParentProfileId) local dDimRef = b3FrameProfile:getMin():getX() -- verifico se contributo per bottomrail local dRailOffs = EgtGetInfo( nParentProfileId, WIN_RAILOFFS, 'd') or 0 - local dFillPerpOffset = abs( dDimRef) - dOverlap + dRailOffs - EgtOffsetCurve( nOutlineId, - dFillPerpOffset) + vParentOffs[i] = abs( dDimRef) - dOverlap + dRailOffs -- movimento in z if dDeltaZ < GEO.EPS_SMALL then dDeltaZ = EgtGetInfo( nParentProfileId, WIN_FILLDELTA, 'd') end end - - nParentOutlineId = EgtGetNext( nParentOutlineId) + end + -- creo le curve di outlines + for i = 1, #vParentOutlines do + -- copio la curva di outline del parent + local nOutlineId = EgtCopy( vParentOutlines[i], nOutlineLayerId) + EgtSetInfo( nOutlineId, WIN_SOU_OUTLINE, vParentOutlines[i]) + -- applico offset + if vParentOffs[i] then + EgtOffsetCurve( nOutlineId, - vParentOffs[i]) + else + -- se non ha offset definito è un pezzo che verrà tagliato da uno split ma, affinchè la forma del telaio sia coerente, devo applicare lo stesso offset a curve + -- che sono in tangenza + local nPrevIdx = EgtIf( i == 1, #vParentOutlines, i-1) + local nNextIdx = EgtIf( i == #vParentOutlines, 1, i+1) + if AreSameVectorApprox( EgtSV( vParentOutlines[i]), EgtEV( vParentOutlines[nPrevIdx])) then + while not vParentOffs[nPrevIdx] do + nPrevIdx = EgtIf( nPrevIdx == 1, #vParentOutlines, nPrevIdx-1) + end + EgtOffsetCurve( nOutlineId, - vParentOffs[nPrevIdx]) + vParentOffs[i] = vParentOffs[nPrevIdx] + elseif AreSameVectorApprox( EgtEV( vParentOutlines[i]), EgtSV( vParentOutlines[nNextIdx])) then + while not vParentOffs[nNextIdx] do + nNextIdx = EgtIf( nNextIdx == #vParentOutlines, 1, nNextIdx+1) + end + EgtOffsetCurve( nOutlineId, - vParentOffs[nNextIdx]) + vParentOffs[i] = vParentOffs[nNextIdx] + end + end end -- accorcio gli offset local vCrvs = TrimOrderedCurves( EgtGetAllInGroup( nOutlineLayerId), true) @@ -2809,10 +3092,10 @@ local function CalculateOutlineFromAreaOutline( nAreaId) nBaseOutlineId = EgtGetNext( nBaseOutlineId) end local vOutlines = EgtGetAllInGroup( nOutlineLayerId) - GetPrevNextOutline( vOutlines, nOutlineLayerId) + GetFramePrevNextOutline( vOutlines, nOutlineLayerId) -- creo i pezzi CreatePartsFromOutlines( vOutlines, nAreaId, sName) - + -- SPLIT elseif nAreaType == WIN_AREATYPES.SPLIT then @@ -2875,15 +3158,17 @@ local function CalculateOutlineFromAreaOutline( nAreaId) elseif nAreaType == WIN_AREATYPES.SASH then local nBaseOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_AREAOUTLINE) local vOutlines = CalculateSashOutline( nAreaId, nBaseOutlineLayerId, nOutlineLayerId) - -- assegno prev e next - GetPrevNextOutline( vOutlines, nOutlineLayerId) -- creo i pezzi CreatePartsFromOutlines( vOutlines, nAreaId, sName) + -- ne verifico validità + VerifySashParts( vOutlines, nAreaId) + -- assegno i prev e i next + GetSashPrevNextOutlines( vOutlines, nOutlineLayerId, nAreaId) -- identifico la forma IdentifySashShape( nAreaId, nOutlineLayerId) -- disegno apertura DrawOpening( nAreaId) - + -- FILL elseif nAreaType == WIN_AREATYPES.FILL then @@ -2979,7 +3264,7 @@ end ---------------------------------------------------------------------------------- -- funzione che crea il bisettore parabolico tra linea e arco local function CalcParabolicBisector( nCrv1, nCrv2, dDim, nGrp, bArcExternal, bLineExternal) - + -- modifico le curve affinchè abbiano estremo in comune local ptInt = FindIntersectionPoint( nCrv1, nCrv2, EgtSP( nCrv2)) EgtModifyCurveStartPoint( nCrv2, ptInt) @@ -3033,7 +3318,7 @@ local function CalcParabolicBisector( nCrv1, nCrv2, dDim, nGrp, bArcExternal, bL end --------------------------------------------------------------------- --- funzione simile a CalcIntersectionRegion ma con considerazioni speciali per le curve del geo ( e.g. gestione bisettori) +-- funzione simile a CalcIntersectionRegion ma con considerazioni speciali per le curve del geo ( e.g. gestione bisettori, curve doppie) local function CalcGeoRegion( vCrvs, nGrp) local nSurfId @@ -3059,29 +3344,27 @@ local function CalcGeoRegion( vCrvs, nGrp) EgtTransform( nSemiPlaneId, frRect) table.insert( vSemiPlanes, nSemiPlaneId) - -- se arco calcolo estensione ( con verifica su circonferenze coincidenti) + -- se arco calcolo estensione verificando se la curva è doppia elseif EgtGetType( vCrvs[i]) == GDB_TY.CRV_ARC then - local dRad = EgtArcRadius( vCrvs[i]) - - local bTangentStart = EgtGetInfo( vCrvs[i], WIN_TANG_START, 'b') or false - local bTangentEnd = EgtGetInfo( vCrvs[i], WIN_TANG_END, 'b') or false - if not bTangentStart and not bTangentEnd then - local ptC = EgtCP( vCrvs[i]) - local bOverlap = false + local bFound = false + local nRefOutline = EgtGetInfo( vCrvs[i], WIN_REF_OUTLINE, 'i') + if nRefOutline then for j = 1, #tArcs do - if tArcs[j].ptC and AreSamePointApprox( tArcs[j].ptC, ptC) and abs( tArcs[j].dRad - dRad) < GEO.EPS_SMALL then - bOverlap = true + if tArcs[j].nRefOutline == nRefOutline then + local nCopy = EgtCopyGlob( vCrvs[i], nGrpTmp) + CopyInfo( nCopy, tArcs[j].vOrigId[1], WIN_TANG_START, false) + CopyInfo( nCopy, vCrvs[i], WIN_TANG_END, false) + local nCrvId = CreateCurveExtension( nCopy, nGrpTmp) + tArcs[j].nCrvId = nCrvId table.insert( tArcs[j].vOrigId, vCrvs[i]) + bFound = true break end end - if not bOverlap then - local nCrvId = CreateCurveExtension( vCrvs[i], nGrpTmp) - table.insert( tArcs, { nCrvId = nCrvId, vOrigId = { vCrvs[i]}, dRad = dRad, ptC = ptC}) - end - else + end + if not bFound then local nCrvId = CreateCurveExtension( vCrvs[i], nGrpTmp) - table.insert( tArcs, { nCrvId = nCrvId, vOrigId = { vCrvs[i]}, dRad = dRad}) + table.insert( tArcs, { nCrvId = nCrvId, vOrigId = { vCrvs[i]}, nRefOutline = nRefOutline, dRad = EgtArcRadius( vCrvs[i])}) end -- se composita è bisettore con gestione speciale @@ -3090,12 +3373,15 @@ local function CalcGeoRegion( vCrvs, nGrp) table.insert( vBisectors, nCrvId) end end - + -- b) calcolo la regione definita dai semipiani for i = 2, #vSemiPlanes do EgtSurfFrIntersect( vSemiPlanes[1], vSemiPlanes[i]) EgtErase( vSemiPlanes[i]) end + if EgtSurfFrChunkCount( vSemiPlanes[1]) == 0 then + return + end nSurfId = vSemiPlanes[1] -- c) se presenti archi, calcolo il loro contributo alla regione @@ -3110,6 +3396,7 @@ local function CalcGeoRegion( vCrvs, nGrp) -- limito la curva estesa alla regione local nSurfTrim = EgtSurfFlatRegion( nGrpTmp, nCrvBorder) local nCrv, nCnt = EgtTrimCurveWithRegion( tArcs[i].nCrvId, nSurfTrim, true, false) + -- se errore lo ignoro if not nCrv then nCnt = 0 @@ -3131,16 +3418,18 @@ local function CalcGeoRegion( vCrvs, nGrp) local vArcs = EgtTableFill( nCrv, nCnt) for j = nCrv, nCrv + nCnt - 1 do local nInters, nPntCnt, nCrvCnt = EgtCurveCurveInters( j, nCrvBorder, nGrpTmp) - if nCnt == 1 then - EgtChangeClosedCurveStartPoint( j, EgtSP( nInters)) - end - 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 + if nInters then + if nCnt == 1 then + EgtChangeClosedCurveStartPoint( j, EgtSP( nInters)) + end + 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 @@ -3234,25 +3523,25 @@ end --------------------------------------------------------------------- -- funzione che stabilisce il tipo di estensione ( standard seguendo la circonferenza o lineare in tangenza) per curve del geo ad arco in base a condizioni euristiche per evitare giunzioni -- problematiche -local function ComputeArcExtensions( nOutId, nInId, vLeftIds, vRightIds, nStartJoint, nEndJoint) +local function ComputeArcExtensions( nOutId, nInId, vLeftIds, vRightIds, vStartJoints, vEndJoints) -- controllo euristico : verifico se la parte più interna del semiprofilo associato alla curva del geo ( ovvero considero tra i due archi che limitano il semiprofilo quello -- con raggio minore perchè dovrebbe essere il più problematico) arriva alla curva di geo vicina con estensione standard oppure no - -- se giunzioni angled forzo estensioni in tangenza + -- se curve in tangenza forza estensione in tangenza -- se il pezzo corrente è arco devo verificare estensione per in e out if EgtGetType( nOutId) == GDB_TY.CRV_ARC then local bTangStart, bTangEnd = CheckSemiprofileIntersection( nOutId, vLeftIds[#vLeftIds], vRightIds[1]) + -- verifico se necessaria estensione in tangenza per giunzione angled o per la curva in if not bTangStart then - -- verifico se necessaria estensione in tangenza per giunzione angled o per la curva in - bTangStart = ( nStartJoint == WIN_PART_JNT.ANGLED or not FindIntersectionPoint( nInId, vLeftIds[1], ORIG())) + bTangStart = ( vStartJoints[#vStartJoints] == WIN_PART_JNT.ANGLED or not FindIntersectionPoint( nInId, vLeftIds[1], ORIG())) end EgtSetInfo( nOutId, WIN_TANG_START, bTangStart) EgtSetInfo( nInId, WIN_TANG_END, bTangStart) if not bTangEnd then - bTangEnd = ( nEndJoint == WIN_PART_JNT.ANGLED or not FindIntersectionPoint( nInId, vRightIds[#vRightIds], ORIG())) + bTangEnd = ( vEndJoints[1] == WIN_PART_JNT.ANGLED or not FindIntersectionPoint( nInId, vRightIds[#vRightIds], ORIG())) end EgtSetInfo( nOutId, WIN_TANG_END, bTangEnd) EgtSetInfo( nInId, WIN_TANG_START, bTangEnd) @@ -3262,6 +3551,27 @@ local function ComputeArcExtensions( nOutId, nInId, vLeftIds, vRightIds, nStartJ for i = 1, #vLeftIds do if EgtGetType( vLeftIds[i]) == GDB_TY.CRV_ARC then local bTangS, bTangE = CheckSemiprofileIntersection( vLeftIds[i], nInId, nOutId) + + -- se outline in tangenza con i vicini forzo estensione in tangenza + if not bTangS then + if vStartJoints[i] == WIN_PART_JNT.FULL or i == 1 or vStartJoints[i] == vStartJoints[i-1] then + local nOutlineId = EgtGetInfo( vLeftIds[i], WIN_REF_OUTLINE, 'i') + local nPrevOutlineId = EgtGetPrev( nOutlineId) or EgtGetLastInGroup( EgtGetParent( nOutlineId)) + if AreSameVectorApprox( EgtEV( nPrevOutlineId), EgtSV( nOutlineId)) then + bTangS = true + end + end + end + if not bTangE then + if vStartJoints[i] == WIN_PART_JNT.FULL or i == #vLeftIds or vStartJoints[i] == vStartJoints[i+1] then + local nOutlineId = EgtGetInfo( vLeftIds[i], WIN_REF_OUTLINE, 'i') + local nNextOutlineId = EgtGetNext( nOutlineId) or EgtGetFirstInGroup( EgtGetParent( nOutlineId)) + if AreSameVectorApprox( EgtEV( nOutlineId), EgtSV( nNextOutlineId)) then + bTangE = true + end + end + end + EgtSetInfo( vLeftIds[i], WIN_TANG_START, bTangS) EgtSetInfo( vLeftIds[i], WIN_TANG_END, bTangE) end @@ -3271,6 +3581,26 @@ local function ComputeArcExtensions( nOutId, nInId, vLeftIds, vRightIds, nStartJ for i = 1, #vRightIds do if EgtGetType( vRightIds[i]) == GDB_TY.CRV_ARC then local bTangS, bTangE = CheckSemiprofileIntersection( vRightIds[i], nOutId, nInId) + + if not bTangS then + if vEndJoints[i] == WIN_PART_JNT.FULL or i == 1 or vEndJoints[i] == vEndJoints[i-1] then + local nOutlineId = EgtGetInfo( vRightIds[i], WIN_REF_OUTLINE, 'i') + local nPrevOutlineId = EgtGetPrev( nOutlineId) or EgtGetLastInGroup( EgtGetParent( nOutlineId)) + if AreSameVectorApprox( EgtEV( nPrevOutlineId), EgtSV( nOutlineId)) then + bTangS = true + end + end + end + if not bTangE then + if vEndJoints[i] == WIN_PART_JNT.FULL or i == #vRightIds or vEndJoints[i] == vEndJoints[i+1] then + local nOutlineId = EgtGetInfo( vRightIds[i], WIN_REF_OUTLINE, 'i') + local nNextOutlineId = EgtGetNext( nOutlineId) or EgtGetFirstInGroup( EgtGetParent( nOutlineId)) + if AreSameVectorApprox( EgtEV( nOutlineId), EgtSV( nNextOutlineId)) then + bTangE = true + end + end + end + EgtSetInfo( vRightIds[i], WIN_TANG_START, bTangS) EgtSetInfo( vRightIds[i], WIN_TANG_END, bTangE) end @@ -3279,7 +3609,7 @@ end --------------------------------------------------------------------- -- funzione che crea le curve del geo -local function CreateGeoCurves( nOutlineId, vPrevOutlineId, vNextOutlineId, nStartJointType, nEndJointType, nGeoLayerId, nProfileLayerId) +local function CreateGeoCurves( nOutlineId, vPrevOutlineId, vNextOutlineId, vStartJoints, vEndJoints, nGeoLayerId, nProfileLayerId) local nCurrProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN) -- calcolo spostamento della curva iniziale dovuto a posizione riferimento @@ -3316,7 +3646,7 @@ local function CreateGeoCurves( nOutlineId, vPrevOutlineId, vNextOutlineId, nSta local vPrevProfileId = EgtGetNameInGroup( nProfileLayerId, WIN_PRF_START) for i = 1, #vPrevOutlineId do - if nStartJointType == WIN_PART_JNT.ANGLED then + if vStartJoints[i] == WIN_PART_JNT.ANGLED then -- recupero bordo out dell'altro pezzo ( non è detto coincida con l'outline) local b3Profile = GetProfileLocalBox( vPrevProfileId[i]) @@ -3340,6 +3670,7 @@ local function CreateGeoCurves( nOutlineId, vPrevOutlineId, vNextOutlineId, nSta EgtInvertCurve( nBisector) end EgtSetName( nBisector, WIN_GEO_LEFT) + EgtSetInfo( nBisector, WIN_REF_OUTLINE, vPrevOutlineId[i]) EgtRelocateGlob( nBisector, nGeoLayerId, GDB_IN.LAST_SON) -- b) se profili diversi per taglio corretto dei profili serve considerare anche il bordo out del pezzo adiacente @@ -3355,6 +3686,8 @@ local function CreateGeoCurves( nOutlineId, vPrevOutlineId, vNextOutlineId, nSta else -- considero la curva out come curva ausiliaria per il calcolo del geo EgtSetName( nOtherOut, WIN_AUX) + EgtSetInfo( nOtherOut, WIN_TANG_START, true) + EgtSetInfo( nOtherOut, WIN_TANG_END, true) end else @@ -3363,7 +3696,7 @@ local function CreateGeoCurves( nOutlineId, vPrevOutlineId, vNextOutlineId, nSta EgtInvertCurve( nPrevCurveId) end local dOffs, nPrevSemiProfile - if nStartJointType == WIN_PART_JNT.SHORT then + if vStartJoints[i] == WIN_PART_JNT.SHORT then -- la curva del geo corrisponde al bordo del controprofilo in del pezzo vicino local sCtrIn = GetProfileCtrIn( abs( vPrevOutlineId[i]), nOutlineId, vPrevProfileId[i]) local dCPDelta = GetDeltaProfile( vPrevProfileId[i], sCtrIn) @@ -3388,7 +3721,7 @@ local function CreateGeoCurves( nOutlineId, vPrevOutlineId, vNextOutlineId, nSta local vNextProfileId = EgtGetNameInGroup( nProfileLayerId, WIN_PRF_END) for i = 1, #vNextOutlineId do - if nEndJointType == WIN_PART_JNT.ANGLED then + if vEndJoints[i] == WIN_PART_JNT.ANGLED then local b3Profile = GetProfileLocalBox( vNextProfileId[i]) local nOtherOut = EgtCopyGlob( vNextOutlineId[i], nGeoLayerId) @@ -3410,6 +3743,7 @@ local function CreateGeoCurves( nOutlineId, vPrevOutlineId, vNextOutlineId, nSta nBisector = CalcParabolicBisector( nOutId, nOtherOut, b3Profile:getDimX(), nGeoLayerId) end EgtSetName( nBisector, WIN_GEO_RIGHT) + EgtSetInfo( nBisector, WIN_REF_OUTLINE, vNextOutlineId[i]) EgtRelocateGlob( nBisector, nInId, GDB_IN.BEFORE) -- gestione per profili diversi @@ -3424,6 +3758,8 @@ local function CreateGeoCurves( nOutlineId, vPrevOutlineId, vNextOutlineId, nSta EgtRelocateGlob( nOtherOut, nInId, GDB_IN.BEFORE) else EgtSetName( nOtherOut, WIN_AUX) + EgtSetInfo( nOtherOut, WIN_TANG_START, true) + EgtSetInfo( nOtherOut, WIN_TANG_END, true) end else @@ -3432,7 +3768,7 @@ local function CreateGeoCurves( nOutlineId, vPrevOutlineId, vNextOutlineId, nSta EgtInvertCurve( nNextCurveId) end local dOffs, nNextSemiProfile - if nEndJointType == WIN_PART_JNT.SHORT then + if vEndJoints[i] == WIN_PART_JNT.SHORT then local sCtrIn = GetProfileCtrIn( abs( vNextOutlineId[i]), nOutlineId, vNextProfileId[i]) local dCPDelta = GetDeltaProfile( vNextProfileId[i], sCtrIn) dOffs = - dCPDelta @@ -3454,13 +3790,17 @@ local function CreateGeoCurves( nOutlineId, vPrevOutlineId, vNextOutlineId, nSta -- verifico se necessaria estensione in tangenza per pezzi ad arco local vLeftIds = EgtGetNameInGroup( nGeoLayerId, WIN_LEFT) local vRightIds = EgtGetNameInGroup( nGeoLayerId, WIN_RIGHT) - ComputeArcExtensions( nOutId, nInId, vLeftIds, vRightIds, nStartJointType, nEndJointType) + ComputeArcExtensions( nOutId, nInId, vLeftIds, vRightIds, vStartJoints, vEndJoints) -- costruisco la superficie local vIds = EgtGetAllInGroup( nGeoLayerId) local nAreaId = CalcGeoRegion( vIds, nGeoLayerId) + if not nAreaId then + return false + end EgtSetName( nAreaId, WIN_GEO_SURF) EgtSetStatus( nAreaId, GDB_ST.OFF) + -- elimino curve aux local vCrvs = {} for i = 1, #vIds do @@ -3470,7 +3810,10 @@ local function CreateGeoCurves( nOutlineId, vPrevOutlineId, vNextOutlineId, nSta table.insert( vCrvs, vIds[i]) end end - TrimOrderedCurves( vCrvs, false, nAreaId) + local _, vExtraCrvs = TrimOrderedCurves( vCrvs, false, nAreaId) + for i = 1, #vExtraCrvs do + EgtSetInfo( vExtraCrvs[i], WIN_GEO_EXTRA, true) + end -- assegno spessore local dGeoH = b3CurrProfileFrame:getDimY() @@ -3488,6 +3831,8 @@ local function CreateGeoCurves( nOutlineId, vPrevOutlineId, vNextOutlineId, nSta local b3Ref = EgtGetBBoxRef( nAreaId, GDB_BB.STANDARD, frRef) EgtSetInfo( nGeoLayerId, WIN_GEOLEN, b3Ref:getDimX()) end + + return true end --------------------------------------------------------------------- @@ -3499,16 +3844,16 @@ local function CalcGeo( nPartId, nOutlineId) EgtSetName( nGeoLayerId, WIN_GEO) -- recupero il tipo di giunzioni - local nStartJoint - local nEndJoint + local vStartJoints + local vEndJoints local nBottomRail = EgtGetInfo( nPartId, WIN_BOTTOMRAIL, 'i') if nBottomRail then -- se bottomrail deve essere short ( l'info sulla curva di riferisce al pezzo bottom) - nStartJoint = WIN_PART_JNT.SHORT - nEndJoint = WIN_PART_JNT.SHORT + vStartJoints = { WIN_PART_JNT.SHORT} + vEndJoints = { WIN_PART_JNT.SHORT} else - nStartJoint = EgtGetInfo( nOutlineId, WIN_STARTJOINT, 'i') - nEndJoint = EgtGetInfo( nOutlineId, WIN_ENDJOINT, 'i') + vStartJoints = EgtGetInfo( nOutlineId, WIN_STARTJOINT, 'vi') + vEndJoints = EgtGetInfo( nOutlineId, WIN_ENDJOINT, 'vi') end -- aggiungo al gruppo profili quelli di trim @@ -3517,8 +3862,10 @@ local function CalcGeo( nPartId, nOutlineId) local nProfileLayerId = CalcStartEndProfiles( nPartId, nOutlineId, vPrevOutlineId, vNextOutlineId) -- creo lati dell'outline - CreateGeoCurves( nOutlineId, vPrevOutlineId, vNextOutlineId, nStartJoint, nEndJoint, nGeoLayerId, nProfileLayerId) - + local bOk = CreateGeoCurves( nOutlineId, vPrevOutlineId, vNextOutlineId, vStartJoints, vEndJoints, nGeoLayerId, nProfileLayerId) + + -- TODO verificare la validità del pezzo ( si è creata geo region, la curva out non è extra, ...) + end --------------------------------------------------------------------- @@ -3807,210 +4154,325 @@ local function GetProcessingInfoFromSemiProfile( nCrv, nSemiProfile) end --------------------------------------------------------------------- --- funzione che crea la lavorazione a partire dalla curva del geo -local function CreateProfilingProcessingCurve( vCrvs, nPrevCrv, nSurfGeo, nProcLayerId) +-- funzione che concatena, se possibile, lavorazioni con lo stesso semiprofilo +local function ChainProfilingProcessingCurves( vProcCrvsOrig, vRefCrvsOrig) - -- recupero il semiprofilo associato al gruppo di curve - local nSemiProfileId = EgtGetInfo( vCrvs[1], WIN_SEMI_PROFILE, 'i') - local nCrvId + if #vProcCrvsOrig == 1 then + return vProcCrvsOrig, vRefCrvsOrig + end + + local vProcCrvs = {} + local vRefCrvs = {} + + local nCurrCrv = vProcCrvsOrig[1] + local vCurrRef = { vRefCrvsOrig[1]} + local sIdCurr = EgtGetInfo( vProcCrvsOrig[1], WIN_PRC_ID) + for i = 2, #vProcCrvsOrig do + local bChain = false + local sId = EgtGetInfo( vProcCrvsOrig[i] or GDB_ID.NULL, WIN_PRC_ID) + if sIdCurr == sId then + -- verifico se le curve si tagliano tra di loro + local ptInt = EgtIP( nCurrCrv, vProcCrvsOrig[i], EgtEP( nCurrCrv)) + if ptInt then + bChain = true + local dPar1 = EgtCurveParamAtPoint( nCurrCrv, ptInt) + local dPar2 = EgtCurveParamAtPoint( vProcCrvsOrig[i], ptInt) + local vCompoCrvs = {} + -- se la curva non viene completamente trimmata la considero, altrimenti la cancello + if dPar1 > GEO.EPS_SMALL then + EgtTrimCurveEndAtParam( nCurrCrv, dPar1) + table.insert( vCompoCrvs, nCurrCrv) + else + EgtErase( nCurrCrv) + end + local _, dE = EgtCurveDomain( vProcCrvsOrig[i]) + if abs( dPar2 - dE) > GEO.EPS_SMALL then + EgtTrimCurveStartAtParam( vProcCrvsOrig[i], dPar2) + table.insert( vCompoCrvs, vProcCrvsOrig[i]) + else + EgtErase( vProcCrvsOrig[i]) + end + nCurrCrv = EgtCurveCompo( EgtGetParent( vProcCrvsOrig[1]), vCompoCrvs) + table.insert( vCurrRef, vRefCrvsOrig[i]) + end + end + if not bChain then + -- salvo la vecchia catena appena interrotta e inizializzo le variabili con la nuova + table.insert( vProcCrvs, nCurrCrv) + table.insert( vRefCrvs, vCurrRef) + nCurrCrv = vProcCrvsOrig[i] + vCurrRef = { vRefCrvsOrig[i]} + sIdCurr = sId + end + end + table.insert( vProcCrvs, nCurrCrv) + table.insert( vRefCrvs, vCurrRef) + + -- se è stata creata una catena ( quindi una lavorazione ha più curve di riferimento associate), vanno risettate le info di lavorazione + for i = 1, #vRefCrvs do + if #vRefCrvs[i] > 1 then + EgtSetName( vProcCrvs[i], EgtGetName( vRefCrvs[i][1])) + local nSemiProfileId = EgtGetInfo( vRefCrvs[i][1], WIN_SEMI_PROFILE, 'i') + GetProcessingInfoFromSemiProfile( vProcCrvs[i], nSemiProfileId) + for j = 1, #vRefCrvs[i] do + EgtSetInfo( vRefCrvs[i][j], WIN_REF_PRC, vProcCrvs[i]) + end + EgtSetInfo( vProcCrvs[i], WIN_REF_GEO, vRefCrvs[i]) + end + end + + return vProcCrvs, vRefCrvs +end + +--------------------------------------------------------------------- +-- funzione che verifica se la lavorazione è veramente necessaria considerando le interferenze tra i profili +local function TestProcessings( vProcCrvs, vRefCrvs, nGeoOut, nGeoIn) + + if #vProcCrvs == 1 then + return + end + + local nGrpTmp = EgtGroup( 0) + + -- creo le superifici delle lavorazioni e quelle estese da usare per i trim + local vSurfs = {} + for i = 1, #vProcCrvs do + local nSemiProfileId = EgtGetInfo( vRefCrvs[i][1], WIN_SEMI_PROFILE, 'i') + if nSemiProfileId then + local nGuideId = EgtCopyGlob( vProcCrvs[i], nGrpTmp) + local dOffs = EgtGetInfo( vRefCrvs[i][1], WIN_GEO_OFFS, 'd') + EgtOffsetCurve( nGuideId, - dOffs) + local nProfileId = EgtGetParent( nSemiProfileId) + local nSurf = CreateProfileSurfById( nGuideId, nProfileId, nSemiProfileId, 0, nGrpTmp) + local nSurfExt = CreateProfileSurf( nGuideId, nProfileId, WIN_OFST .. EgtGetName( nSemiProfileId), 1000, nGrpTmp) + vSurfs[i] = { nId = nSurf, nExtId = nSurfExt} + end + end + + -- superfici che delimitano il pezzo + local nOutlineId = EgtGetInfo( nGeoOut, WIN_REF_OUTLINE, 'i') + local nSemiProfileOut = EgtGetInfo( nGeoOut, WIN_SEMI_PROFILE, 'i') + local nProfileId = EgtGetParent( nSemiProfileOut) + local nSurfOut + local sName = EgtGetName( nSemiProfileOut) + if sName == WIN_OUT then + nSurfOut = CreateProfileSurf( nOutlineId, nProfileId, WIN_OFST .. sName, 1000, nGrpTmp) + else + nSurfOut = CreateProfileSurf( nOutlineId, nProfileId, WIN_OFST .. 'Ctr' .. sName, 1000, nGrpTmp) + EgtInvertSurf( nSurfOut) + end + local nSemiProfileIn = EgtGetInfo( nGeoIn, WIN_SEMI_PROFILE, 'i') + local sNameIn = EgtGetName( nSemiProfileIn) + if sNameIn == WIN_MIXED_COMMON .. WIN_IN then + sNameIn = WIN_FILL .. WIN_CTRIN + else + sNameIn = 'Ctr' .. sNameIn + end + local nSurfIn = CreateProfileSurf( nOutlineId, nProfileId, WIN_OFST .. sNameIn, 1000, nGrpTmp) + EgtInvertSurf( nSurfIn) + + for i = 1, #vSurfs do + -- taglio la superficie con le altre lavorazioni e con il bordo + for j = 1, #vSurfs do + if i ~= j then + EgtSurfTmCut( vSurfs[i].nId, vSurfs[j].nExtId, true, false) + end + end + EgtSurfTmCut( vSurfs[i].nId, nSurfOut, true, false) + EgtSurfTmCut( vSurfs[i].nId, nSurfIn, true, false) + -- se scompare la lavorazione non serve + if EgtSurfTmPartCount( vSurfs[i].nId) == 0 then + EgtErase( vProcCrvs[i]) + for j = 1, #vRefCrvs[i] do + EgtRemoveInfo( vRefCrvs[i][j], WIN_REF_PRC) + end + end + end + + EgtErase( nGrpTmp) +end + +--------------------------------------------------------------------- +local function CreateProfilingProcessingCurve( nGeoCrvId, nPrevCrv, nSurfGeo, nPrcLayerId) + + -- recupero il semiprofilo associato alla curva + local nSemiProfileId = EgtGetInfo( nGeoCrvId, WIN_SEMI_PROFILE, 'i') + local nPrcCrvId -- se bisettrice if not nSemiProfileId then - nCrvId = EgtCopyGlob( vCrvs[1], nProcLayerId) - - -- se lavorazioni di controprofilo + nPrcCrvId = EgtCopyGlob( nGeoCrvId, nPrcLayerId) + + -- se lavorazione di controprofilo else - local nGrpTmp = EgtGroup( nProcLayerId) + local nGrpTmp = EgtGroup( nPrcLayerId) 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) local dOffs = b3SemiProfile:getDimX() - - local vProcCrvs = {} - for i = 1, #vCrvs do - - -- la curva di lavorazione si basa sulla curva del geo - local nCrvId = EgtCopyGlob( vCrvs[i], nGrpTmp) - - -- calcolo la curva di lavorazione interna ( partendo dall'outline e non dal geo per essere coerente con la info di estensione) - local nRefOutlineId = EgtGetInfo( vCrvs[i], WIN_REF_OUTLINE, 'i') - local nOutlineId = EgtCopyGlob( abs( nRefOutlineId), nGrpTmp) - if nRefOutlineId < 0 then - EgtInvertCurve( nOutlineId) - end - local dGeoOffs = EgtGetInfo( vCrvs[i], WIN_GEO_OFFS, 'd') - local nOrigInnerProcId = EgtOffsetCurveAdv( nOutlineId, dGeoOffs - dOffs) - -- adatto la curva di lavorazione interna al pezzo - CopyInfo( nOrigInnerProcId, vCrvs[1], WIN_TANG_START, false) - CopyInfo( nOrigInnerProcId, vCrvs[#vCrvs], WIN_TANG_END, false) - local nInnerProcId = CreateCurveExtension( nOrigInnerProcId, nGrpTmp) - local nInId, nCnt = EgtTrimCurveWithRegion( nInnerProcId, nSurfGeo, true, false) + -- calcolo la curva di lavorazione interna ( partendo dall'outline e non dal geo per essere coerente con la info di estensione) + local nRefOutlineId = EgtGetInfo( nGeoCrvId, WIN_REF_OUTLINE, 'i') + local nOutlineId = EgtCopyGlob( abs( nRefOutlineId), nGrpTmp) + if nRefOutlineId < 0 then + EgtInvertCurve( nOutlineId) + end + local dGeoOffs = EgtGetInfo( nGeoCrvId, WIN_GEO_OFFS, 'd') + local nOrigInnerProcId = EgtOffsetCurveAdv( nOutlineId, dGeoOffs - dOffs) + + -- adatto la curva di lavorazione interna al pezzo + CopyInfo( nOrigInnerProcId, nGeoCrvId, WIN_TANG_START, false) + CopyInfo( nOrigInnerProcId, nGeoCrvId, WIN_TANG_END, false) - if not nInId then - nCnt = 0 - end - if nCnt > 0 then - if nCnt > 1 and AreSamePointApprox( EgtSP( nInId), EgtEP( nInId + nCnt - 1)) then - if EgtGetType( nInId) == GDB_TY.CRV_ARC then - EgtModifyCurveStartPoint( nInId, EgtSP( nInId + nCnt - 1)) - else - EgtAddCurveCompoCurve( nInId, nInId + nCnt - 1, true, false) - end - nCnt = nCnt - 1 + local nInnerProcId = CreateCurveExtension( nOrigInnerProcId, nGrpTmp) + local nInId, nCnt = EgtTrimCurveWithRegion( nInnerProcId, nSurfGeo, true, false) + + if not nInId then + nCnt = 0 + end + if nCnt > 0 then + if nCnt > 1 and AreSamePointApprox( EgtSP( nInId), EgtEP( nInId + nCnt - 1)) then + if EgtGetType( nInId) == GDB_TY.CRV_ARC then + EgtModifyCurveStartPoint( nInId, EgtSP( nInId + nCnt - 1)) + else + EgtAddCurveCompoCurve( nInId, nInId + nCnt - 1, true, false) end - -- se ottengo più tratti considero quello che ha porzione in comune con la curva originale - if nCnt > 1 then - local nTestCrv = EgtOffsetCurveAdv( vCrvs[i], - dOffs) - EgtRelocateGlob( nTestCrv, nGrpTmp) - local vOverlapCrvs = {} - for nId = nInId, nInId + nCnt - 1 do - if CheckExtensionOverlap( nId, nTestCrv) then - table.insert( vOverlapCrvs, nId) + nCnt = nCnt - 1 + end + -- se ottengo più tratti considero quello che ha porzione in comune con la curva originale + if nCnt > 1 then + local nTestCrv = EgtOffsetCurveAdv( nGeoCrvId, - dOffs) + EgtRelocateGlob( nTestCrv, nGrpTmp) + local vOverlapCrvs = {} + for nId = nInId, nInId + nCnt - 1 do + if CheckExtensionOverlap( nId, nTestCrv) then + table.insert( vOverlapCrvs, nId) + end + end + + if #vOverlapCrvs == 1 then + nInId = vOverlapCrvs[1] + elseif #vOverlapCrvs > 0 then + -- se ottengo più tratti di overlap con il geo considero il più vicino al geo precedente + local nIdx = 1 + local dMinDist = GEO.INFINITO + local ptRef = EgtEP( nPrevCrv) + for i = 1, #vOverlapCrvs do + local dDist = dist( EgtSP( vOverlapCrvs[i]), ptRef) + if dDist < dMinDist then + dMinDist = dDist + nIdx = i end end - - if #vOverlapCrvs == 1 then - nInId = vOverlapCrvs[1] - else - -- se ottengo più tratti di overlap con il geo considero il più vicino al geo precedente - local nIdx = 1 - local dMinDist = GEO.INFINITO - local ptRef = EgtEP( nPrevCrv) - for i = 1, #vOverlapCrvs do - local dDist = dist( EgtSP( vOverlapCrvs[i]), ptRef) - if dDist < dMinDist then - dMinDist = dDist - nIdx = i - end - end - nInId = vOverlapCrvs[nIdx] - end + nInId = vOverlapCrvs[nIdx] end end -- la allineo alla curva di lavoro EgtOffsetCurve( nInId, dOffs) - - local bExtra = EgtGetInfo( vCrvs[i], WIN_GEO_EXTRA, 'b') or false + + local bExtra = EgtGetInfo( nGeoCrvId, WIN_GEO_EXTRA, 'b') or false if bExtra then - -- se curva extra la curva di lavorazione è la corrispondente di quella interna - nCrvId = nInId + -- se la lavorazione fa overlap con la curva del geo allora considero direttamente la curva di lavorazione interna + if CheckExtensionOverlap( nInId, nGeoCrvId) then + nPrcCrvId = nInId + EgtRelocateGlob( nPrcCrvId, nPrcLayerId) + end else - -- la curva va modificata solo in allungamento - nCrvId = EgtCurveCompo( nProcLayerId, nCrvId) - AddExtension( nCrvId, nInId) + -- modifico la curva del geo in allungamento + nPrcCrvId = EgtCurveCompo( nPrcLayerId, nGeoCrvId, false) + AddExtension( nPrcCrvId, nInId) end - - -- se compo verifico se può diventare curva singola - if EgtGetType( nCrvId) == GDB_TY.CRV_COMPO then - EgtMergeCurvesInCurveCompo( nCrvId) - end - table.insert( vProcCrvs, nCrvId) end - - -- combino le curve - if #vProcCrvs == 1 then - nCrvId = vProcCrvs[1] - EgtRelocateGlob( nCrvId, nProcLayerId) - - else - for i = 1, #vProcCrvs - 1 do - local ptInt = FindIntersectionPoint( vProcCrvs[i], vProcCrvs[i+1], EgtEP( vProcCrvs[i])) - local dPar1 = EgtCurveParamAtPoint( vProcCrvs[i], ptInt) - local dPar2 = EgtCurveParamAtPoint( vProcCrvs[i+1], ptInt) - if dPar1 then - EgtTrimCurveEndAtParam( vProcCrvs[i], dPar1) - else - EgtModifyCurveEndPoint( vProcCrvs[i], ptInt) - end - if dPar2 then - EgtTrimCurveStartAtParam( vProcCrvs[i+1], dPar2) - else - EgtModifyCurveStartPoint( vProcCrvs[i+1], ptInt) - end - end - nCrvId = EgtCurveCompo( nProcLayerId, vProcCrvs, true) - end - EgtErase( nGrpTmp) end -- sistemo la curva e setto le info - EgtModifyCurveThickness( nCrvId, 0) - EgtSetStatus( nCrvId, GDB_ST.ON) - EgtSetName( nCrvId, EgtGetName( vCrvs[1])) - GetProcessingInfoFromSemiProfile( nCrvId, nSemiProfileId) - for i = 1, #vCrvs do - EgtSetInfo( vCrvs[i], WIN_REF_PRC, nCrvId) + if nPrcCrvId then + EgtModifyCurveThickness( nPrcCrvId, 0) + EgtSetStatus( nPrcCrvId, GDB_ST.ON) + EgtSetName( nPrcCrvId, EgtGetName( nGeoCrvId)) + GetProcessingInfoFromSemiProfile( nPrcCrvId, nSemiProfileId) + EgtSetInfo( nGeoCrvId, WIN_REF_PRC, nPrcCrvId) + EgtSetInfo( nPrcCrvId, WIN_REF_GEO, nGeoCrvId) + end + + return nPrcCrvId +end + +--------------------------------------------------------------------- +local function TrimTangentProcessings( nPrc1, nPrc2, ptRef) + -- se le due lavorazioni hanno lo stesso semiprofilo e sono in tangenza nel loro punto di intersezione, allora posso trimmarle per evitare di avere porzioni di lavorazioni superflue + local sId1 = EgtGetInfo( nPrc1, WIN_PRC_ID) + local sId2 = EgtGetInfo( nPrc2, WIN_PRC_ID) + if sId1 == sId2 then + local ptInt = EgtIP( nPrc1, nPrc2, ptRef) + if ptInt then + local dPar1 = EgtCurveParamAtPoint( nPrc1, ptInt) + local dPar2 = EgtCurveParamAtPoint( nPrc2, ptInt) + if AreSameVectorApprox( EgtUV( nPrc1, dPar1, -1), EgtUV( nPrc2, dPar2, -1)) then + EgtTrimCurveEndAtParam( nPrc1, dPar1) + EgtTrimCurveStartAtParam( nPrc2, dPar2) + end + end end - - return nCrvId end --------------------------------------------------------------------- -- funzione che calcola le lavorazioni di profilatura a partire dalle curve del geo local function CreateProfilingProcessingFromGeo( nGeoLayerId, nSurfGeo, nProcLayerId, nPartId) - -- out e in vengono gestite singolarmente, right e left vengono raggruppate in base al semiprofilo - -- out + -- a) out local nOut = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_OUT) - local nPrcOut = CreateProfilingProcessingCurve( { nOut}, nil, nSurfGeo, nProcLayerId) + local nPrcOut = CreateProfilingProcessingCurve( nOut, nil, nSurfGeo, nProcLayerId) local sOutId = EgtGetInfo( nPrcOut, WIN_PRC_ID) EgtSetInfo( nPartId, WIN_PRC_PROFILE_OUT, sOutId) - -- right - local vRight = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_RIGHT) - local vCurrRight = { vRight[1]} - local nSemiProfilePrev = EgtGetInfo( vRight[1], WIN_SEMI_PROFILE, 'i') - local sIdPrev = EgtGetInfo( nSemiProfilePrev or GDB_ID.NULL, WIN_PRC_ID) - local vsRightIds = { sIdPrev} - for i = 2, #vRight do - local nSemiProfileCurr = EgtGetInfo( vRight[i], WIN_SEMI_PROFILE, 'i') - local sIdCurr = EgtGetInfo( nSemiProfileCurr or GDB_ID.NULL, WIN_PRC_ID) - if nSemiProfilePrev and nSemiProfileCurr and sIdPrev == sIdCurr then - -- se hanno lo stesso semiprofilo vanno gestite insieme - table.insert( vCurrRight, vRight[i]) - else - -- se hanno un diverso semiprofilo calcolo la lavorazione del gruppo associato al semiprofilo precedente e inizio a creare il gruppo del semiprofilo della curva corrente - CreateProfilingProcessingCurve( vCurrRight, nOut, nSurfGeo, nProcLayerId) - vCurrRight = { vRight[i]} - table.insert( vsRightIds, sIdCurr) - sIdPrev = sIdCurr - end - end - CreateProfilingProcessingCurve( vCurrRight, nOut, nSurfGeo, nProcLayerId) - EgtSetInfo( nPartId, WIN_PRC_PROFILE_RIGHT, vsRightIds) - - -- in + -- b) in local nIn = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_IN) - local nPrcIn = CreateProfilingProcessingCurve( { nIn}, nil, nSurfGeo, nProcLayerId) + local nPrcIn = CreateProfilingProcessingCurve( nIn, nil, nSurfGeo, nProcLayerId) local sInId = EgtGetInfo( nPrcIn, WIN_PRC_ID) EgtSetInfo( nPartId, WIN_PRC_PROFILE_IN, sInId) - -- left - local vLeft = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_LEFT) - local vCurrLeft = { vLeft[1]} - nSemiProfilePrev = EgtGetInfo( vLeft[1], WIN_SEMI_PROFILE, 'i') - sIdPrev = EgtGetInfo( nSemiProfilePrev or GDB_ID.NULL, WIN_PRC_ID) - local vsLeftIds = { sIdPrev} - for i = 2, #vLeft do - local nSemiProfileCurr = EgtGetInfo( vLeft[i], WIN_SEMI_PROFILE, 'i') - local sIdCurr = EgtGetInfo( nSemiProfileCurr or GDB_ID.NULL, WIN_PRC_ID) - if nSemiProfilePrev and nSemiProfileCurr and sIdPrev == sIdCurr then - table.insert( vCurrLeft, vLeft[i]) - else - CreateProfilingProcessingCurve( vCurrLeft, nIn, nSurfGeo, nProcLayerId) - vCurrLeft = { vLeft[i]} - table.insert( vsLeftIds, sIdCurr) - sIdPrev = sIdCurr + -- c) right + -- costruisco le curve di lavorazione + local vRight = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_RIGHT) + local vProcRight = {} + local vRefRight = {} + for i = 1, #vRight do + local nCrvId = CreateProfilingProcessingCurve( vRight[i], nOut, nSurfGeo, nProcLayerId) + if nCrvId then + table.insert( vProcRight, nCrvId) + table.insert( vRefRight, vRight[i]) end end - CreateProfilingProcessingCurve( vCurrLeft, nIn, nSurfGeo, nProcLayerId) - EgtSetInfo( nPartId, WIN_PRC_PROFILE_LEFT, vsLeftIds) + -- concateno + vProcRight, vRefRight = ChainProfilingProcessingCurves( vProcRight, vRefRight) + -- verifico se ci sono lavorazioni superflue + TestProcessings( vProcRight, vRefRight, nOut, nIn) + -- eventuale trim con out e in + local vPrcRight = EgtGetNameInGroup( nProcLayerId, WIN_RIGHT) + TrimTangentProcessings( nPrcOut, vPrcRight[1], EgtEP( nPrcOut)) + TrimTangentProcessings( vPrcRight[#vPrcRight], nPrcIn, EgtSP( nPrcIn)) + -- d) left + local vLeft = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_LEFT) + local vProcLeft = {} + local vRefLeft = {} + for i = 1, #vLeft do + local nCrvId = CreateProfilingProcessingCurve( vLeft[i], nIn, nSurfGeo, nProcLayerId) + if nCrvId then + table.insert( vProcLeft, nCrvId) + table.insert( vRefLeft, vLeft[i]) + end + end + vProcLeft, vRefLeft = ChainProfilingProcessingCurves( vProcLeft, vRefLeft) + TestProcessings( vProcLeft, vRefLeft, nOut, nIn) + local vPrcLeft = EgtGetNameInGroup( nProcLayerId, WIN_LEFT) + TrimTangentProcessings( nPrcIn, vPrcLeft[1], EgtEP( nPrcIn)) + TrimTangentProcessings( vPrcLeft[#vPrcLeft], nPrcOut, EgtSP( nPrcOut)) end --------------------------------------------------------------------- @@ -4230,8 +4692,96 @@ end ---------------------------------------------------------------------------------- ---------------------------------- SOLIDO ---------------------------------------- ---------------------------------------------------------------------------------- +local function GetReferenceCurve( nCrv, nOrigCrv, dOffs, nSurfTrim) + + local nRes, nCnt = EgtTrimCurveWithRegion( nCrv, nSurfTrim, true, false) + if nCnt == 1 then + EgtOffsetCurve( nRes, dOffs) + return nRes + else + -- se più di un tratto interno alla regione considero solo quello che fa overlap con l'originale + for nId = nRes, nRes + nCnt - 1 do + EgtOffsetCurve( nId, dOffs) + if CheckExtensionOverlap( nId, nOrigCrv) then + return nId + end + end + end +end + +--------------------------------------------------------------------- +-- funzione che crea la guida per la superficie di trim, opportunamente estesa per avere booleane ben definite +local function CalcGuideExtension( nCrvId, nGeoId, nSurfTrimId, nLayerId) + + local nSemiProfile = EgtGetInfo( nGeoId, WIN_SEMI_PROFILE, 'i') + local nGrpTmp = EgtGroup( nLayerId) + + -- creo estensione della curva ( può essere fatta in tangenza perchè parto dalla curva di processing) + local nExtCrvId = EgtCurveCompo( nGrpTmp, nCrvId, false) + EgtAddCurveCompoLineTg( nExtCrvId, 10000, true) + EgtAddCurveCompoLineTg( nExtCrvId, 10000, false) + + local nGuideId + if not nSemiProfile then + -- se bisettore controllo solamente la curva stessa + nGuideId = GetReferenceCurve( nExtCrvId, nCrvId, 0, nSurfTrimId) + -- piccola estensione per essere oltre il minimo indispensabile + EgtExtendCurveStartByLen( nGuideId, 2) + EgtExtendCurveEndByLen( nGuideId, 2) + else + -- se semiprofilo controllo estensione richiesta per la sua parte interna ed esterna + local nProfileId = EgtGetParent( nSemiProfile) + local nFrameId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME) + local frFrame = EgtFR( nFrameId, GDB_ID.ROOT) + local b3SemiProfile = EgtGetBBoxRef( nSemiProfile, GDB_BB.STANDARD, frFrame) + + -- parametri di trim + local dParS = GEO.INFINITO + local dParE = -1 + + -- parte in + local nInExtCrvId = EgtOffsetCurveAdv( nExtCrvId, b3SemiProfile:getMin():getX()) + local nInId = GetReferenceCurve( nInExtCrvId, nCrvId, - b3SemiProfile:getMin():getX(), nSurfTrimId) + if nInId then + dParS = EgtCurveParamAtPoint( nExtCrvId, EgtSP( nInId)) + dParE = EgtCurveParamAtPoint( nExtCrvId, EgtEP( nInId)) + end + + -- parte out + local nOutExtCrvId = EgtOffsetCurveAdv( nExtCrvId, b3SemiProfile:getMax():getX()) + local nOutId = GetReferenceCurve( nOutExtCrvId, nCrvId, - b3SemiProfile:getMax():getX(), nSurfTrimId) + if nOutId then + dParS = min( dParS, EgtCurveParamAtPoint( nExtCrvId, EgtSP( nOutId))) + dParE = max( dParE, EgtCurveParamAtPoint( nExtCrvId, EgtEP( nOutId))) + end + + -- aggiusto la curva estesa tenendo conto di quanto realmente serve per il corretto trim del solido + EgtTrimCurveStartEndAtParam( nExtCrvId, dParS, dParE) + nGuideId = nExtCrvId + end + + EgtRelocateGlob( nGuideId, nLayerId) + EgtErase( nGrpTmp) + return nGuideId +end + +--------------------------------------------------------------------- -- funzione che crea le superfici di trim e taglia il solido -local function TrimSolid( vGeoIds, dGeoWidth, nLayerId, nMainExtrusionId) +local function TrimSolid( vGeoIds, nLayerId, nMainExtrusionId, nMainGuideId, nMainProfileId) + + -- creo la superficie di riferimento del solido originale per capire di quanto estendere le superfici di trim in modo da avere booleane ben definite tra le superfici + local b3Profile = GetProfileLocalBox( nMainProfileId) + local nOffsMax = EgtOffsetCurveAdv( nMainGuideId, b3Profile:getMax():getX()) + local nOffsMin = EgtOffsetCurveAdv( nMainGuideId, b3Profile:getMin():getX()) + EgtInvertCurve( nOffsMin) + local nCompo = EgtCurveCompo( nLayerId, nOffsMax) + EgtAddCurveCompoLine( nCompo, EgtSP( nOffsMin)) + EgtAddCurveCompoCurve( nCompo, nOffsMin) + EgtCloseCurveCompo( nCompo) + local nSurfTrim = EgtSurfFlatRegion( nLayerId, nCompo) + EgtSetStatus( nSurfTrim, GDB_ST.OFF) + EgtSetStatus( nCompo, GDB_ST.OFF) + local tabPrcCrv = {} for i = 1, #vGeoIds do @@ -4244,35 +4794,36 @@ local function TrimSolid( vGeoIds, dGeoWidth, nLayerId, nMainExtrusionId) -- 1) minizinken if not nSemiProfileId then - nGuideId = EgtCurveCompo( nLayerId, vGeoIds[i], false) - EgtExtendCurveStartByLen( nGuideId, 5) - EgtExtendCurveEndByLen( nGuideId, 5) + nGuideId = CalcGuideExtension( vGeoIds[i], vGeoIds[i], nSurfTrim, nLayerId) EgtMove( nGuideId, Z_AX()) - nTrimSurf = EgtSurfTmByExtrusion( nLayerId, nGuideId, - Z_AX() * 2 * dGeoWidth, WIN_SURF_APPROX) + nTrimSurf = EgtSurfTmByExtrusion( nLayerId, nGuideId, - Z_AX() * 2 * b3Profile:getDimY(), WIN_SURF_APPROX) EgtInvertSurf( nTrimSurf) -- 2) controprofilo else -- recupero la curva di lavorazione associata e verifico se la sua superficie di trim è già stata calcolata ( una curva di lavorazione può essere associata -- a più curve del geo) - local nPrcCrv = EgtGetInfo( vGeoIds[i], WIN_REF_PRC, 'i') or GDB_ID.NULL - if tabPrcCrv[nPrcCrv] then - -- se la superficie di trim è già stata creata salvo associazione nella curva geo - EgtSetInfo( vGeoIds[i], WIN_REF_SURF, tabPrcCrv[nPrcCrv]) - else - -- riposiziono la curva di lavorazione in corrispondenza dell'outline - local dOffs = EgtGetInfo( vGeoIds[i], WIN_GEO_OFFS, 'd') - nGuideId = EgtOffsetCurveAdv( nPrcCrv, - dOffs) - local nRefOutline = EgtGetInfo( vGeoIds[i], WIN_REF_OUTLINE, 'i') - if nRefOutline < 0 then - EgtInvertCurve( nGuideId) + local nPrcCrv = EgtGetInfo( vGeoIds[i], WIN_REF_PRC, 'i') + if nPrcCrv then + if tabPrcCrv[nPrcCrv] then + -- se la superficie di trim è già stata creata salvo associazione nella curva geo + EgtSetInfo( vGeoIds[i], WIN_REF_SURF, tabPrcCrv[nPrcCrv]) + else + -- riposiziono la curva di lavorazione in corrispondenza dell'outline + local dOffs = EgtGetInfo( vGeoIds[i], WIN_GEO_OFFS, 'd') + local nOffsCrv = EgtOffsetCurveAdv( nPrcCrv, - dOffs) + nGuideId = CalcGuideExtension( nOffsCrv, vGeoIds[i], nSurfTrim, nLayerId) + EgtErase( nOffsCrv) + local nRefOutline = EgtGetInfo( vGeoIds[i], WIN_REF_OUTLINE, 'i') + if nRefOutline < 0 then + EgtInvertCurve( nGuideId) + end + -- recupero il controprofilo da estrudere + local sTrimProfileName = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. WIN_OFST .. EgtGetName( nSemiProfileId) + -- calcolo la superficie di estrusione + nTrimSurf = CreateProfileSurf( nGuideId, EgtGetParent( nSemiProfileId), sTrimProfileName, b3Profile:getDimX(), nLayerId) + tabPrcCrv[nPrcCrv] = nTrimSurf end - -- recupero il controprofilo da estrudere - local sTrimProfileName = EgtGetName( nSemiProfileId) - sTrimProfileName = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. WIN_OFST .. sTrimProfileName - -- calcolo la superficie di estrusione - nTrimSurf = CreateProfileSurf( nGuideId, EgtGetParent( nSemiProfileId), sTrimProfileName, dGeoWidth, nLayerId) - tabPrcCrv[nPrcCrv] = nTrimSurf end end @@ -4284,52 +4835,50 @@ local function TrimSolid( vGeoIds, dGeoWidth, nLayerId, nMainExtrusionId) EgtSetInfo( vGeoIds[i], WIN_REF_SURF, nTrimSurf) end end + + EgtErase( nSurfTrim) + EgtErase( nCompo) + end --------------------------------------------------------------------- -- funzione che calcola la curva guida per il solido principale -local function CalcSolidGuide( nOutlineId, nSolidLayerId, nProfileId) +local function CalcSolidGuide( nOutlineId, nSolidLayerId, nProfileId, nGeoLayerId) local nGuideId + local dExtraLinearLen = 400 if EgtGetType( nOutlineId) == GDB_TY.CRV_LINE then - -- se tratto lineare non ci sono problemi di estensione + -- se tratto lineare non ci sono problemi per l'estensione nGuideId = EgtCopyGlob( nOutlineId, nSolidLayerId) - EgtExtendCurveStartByLen( nGuideId, 400) - EgtExtendCurveEndByLen( nGuideId, 400) + EgtExtendCurveStartByLen( nGuideId, dExtraLinearLen) + EgtExtendCurveEndByLen( nGuideId, dExtraLinearLen) else nGuideId = EgtCurveCompo( nSolidLayerId, nOutlineId, false) - - -- se tratto ad arco verifico l'allungamento minimo richiesto guardando le curve di lavorazione in e out - local nPartId = EgtGetParent( nSolidLayerId) - local nProcLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PRC) - local nGeoLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO) - - -- in - local nPrcIn = EgtGetFirstNameInGroup( nProcLayerId, WIN_GEO_IN) - local nInId = EgtCopyGlob( nPrcIn, nSolidLayerId) - EgtInvertCurve( nInId) - -- riporto la curva di lavorazione allineata all'outline - local nGeoIn = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_IN) - local dOffsIn = EgtGetInfo( nGeoIn, WIN_GEO_OFFS, 'd') or 0 - EgtOffsetCurve( nInId, dOffsIn) - -- aggiungo tratti di estensione se necessari - AddExtension( nGuideId, nInId) - - -- out - local nPrcOut = EgtGetFirstNameInGroup( nProcLayerId, WIN_GEO_OUT) - local nOutId = EgtCopyGlob( nPrcOut, nSolidLayerId) + + -- recupero il tipo di estensione local nGeoOut = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_OUT) - local dOffsOut = EgtGetInfo( nGeoOut, WIN_GEO_OFFS, 'd') or 0 - EgtOffsetCurve( nOutId, dOffsOut) - AddExtension( nGuideId, nOutId) - - -- piccola estensione per avere un po' di margine dal minimo indispensabile appena calcolato - EgtExtendCurveStartByLen( nGuideId, 5) - EgtExtendCurveEndByLen( nGuideId, 5) - - EgtErase( nInId) - EgtErase( nOutId) + local bTangS = EgtGetInfo( nGeoOut, WIN_TANG_START, 'b') + local bTangE = EgtGetInfo( nGeoOut, WIN_TANG_END, 'b') + + -- calcolo la lunghezza di estensione per l'arco in modo che la parte interna non si chiuda in una circonferenza + local dRad = EgtArcRadius( nOutlineId) + local dAng = EgtArcAngCenter( nOutlineId) * pi / 180 + local b3Profile = GetProfileLocalBox( nProfileId) + local dInnerRad = dRad - abs( b3Profile:getMin():getX()) + local dExtraLen = ( pi - 0.5 * dAng) * dInnerRad * dRad / dInnerRad - 2 + + if bTangS then + EgtAddCurveCompoLineTg( nGuideId, dExtraLinearLen, false) + else + EgtExtendCurveStartByLen( nGuideId, dExtraLen) + end + + if bTangE then + EgtAddCurveCompoLineTg( nGuideId, dExtraLinearLen, true) + else + EgtExtendCurveEndByLen( nGuideId, dExtraLen) + end end EgtSetName( nGuideId, WIN_MAINGUIDE) @@ -4374,7 +4923,7 @@ local function CalcMixedFrameSolid( nOutlineId, nSolidLayerId, nProfileLayerId, -- a) SOLIDO PRINCIPALE -- creo i solidi corrispondenti alla parte sash e alla parte fill local nMainProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN) - local nGuideId = CalcSolidGuide( nOutlineId, nSolidLayerId, nMainProfileId) + local nGuideId = CalcSolidGuide( nOutlineId, nSolidLayerId, nMainProfileId, nGeoLayerId) EgtSetName( nGuideId, WIN_MAINGUIDE) EgtSetStatus( nGuideId, GDB_ST.OFF) local sSectionSash = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. WIN_SASH .. WIN_SECTION @@ -4413,11 +4962,11 @@ local function CalcMixedFrameSolid( nOutlineId, nSolidLayerId, nProfileLayerId, -- b) TRIM START local vPrevGeoIds = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_LEFT) - TrimSolid( vPrevGeoIds, dGeoWidth, nSolidLayerId, nMainSolid) + TrimSolid( vPrevGeoIds, nSolidLayerId, nMainSolid, nGuideId, nMainProfileId) -- c) TRIM END local vNextGeoIds = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_RIGHT) - TrimSolid( vNextGeoIds, dGeoWidth, nSolidLayerId, nMainSolid) + TrimSolid( vNextGeoIds, nSolidLayerId, nMainSolid, nGuideId, nMainProfileId) return nMainSolid end @@ -4470,11 +5019,11 @@ end --------------------------------------------------------------------- -- funzione che crea il solido di un pezzo di split coinvolto da cambio profilo -local function CalcMixedSplitSolid( nOutlineId, nSolidLayerId, nProfileLayerId, dGeoWidth) +local function CalcMixedSplitSolid( nOutlineId, nSolidLayerId, nProfileLayerId, nGeoLayerId, dGeoWidth) -- a) creo il solido di estrusione principale local nMainProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN) - local nGuideId = CalcSolidGuide( nOutlineId, nSolidLayerId, nMainProfileId) + local nGuideId = CalcSolidGuide( nOutlineId, nSolidLayerId, nMainProfileId, nGeoLayerId) local sSection = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. WIN_SECTION local nMainExtrusionId = CreateMainSurf( nGuideId, nMainProfileId, sSection, nSolidLayerId) -- creo una copia @@ -4486,7 +5035,6 @@ local function CalcMixedSplitSolid( nOutlineId, nSolidLayerId, nProfileLayerId, -- booleane con superfici in parte sovrapposte local vPrevOutlines = EgtGetInfo( nOutlineId, WIN_PREV_OUTLINES, 'vi') local vNextOutlines = EgtGetInfo( nOutlineId, WIN_NEXT_OUTLINES, 'vi') - local nGeoLayerId = EgtGetFirstNameInGroup( EgtGetParent( nSolidLayerId), WIN_GEO) local vPrevGeo = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_LEFT) local vNextGeo = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_RIGHT) @@ -4548,7 +5096,7 @@ local function CalcSolid( nPartId, nOutlineId) local bChangeProfile = EgtGetInfo( nOutlineId, WIN_PRF_CHANGE, 'b') or false if bChangeProfile then if EgtGetName( nOutlineId) == WIN_SPLIT then - return CalcMixedSplitSolid( nOutlineId, nSolidLayerId, nProfileLayerId, dGeoWidth) + return CalcMixedSplitSolid( nOutlineId, nSolidLayerId, nProfileLayerId, nGeoLayerId, dGeoWidth) else return CalcMixedFrameSolid( nOutlineId, nSolidLayerId, nProfileLayerId, nGeoLayerId, dGeoWidth) end @@ -4556,7 +5104,7 @@ local function CalcSolid( nPartId, nOutlineId) -- a) creo il solido di estrusione principale local nMainProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN) - local nGuideId = CalcSolidGuide( nOutlineId, nSolidLayerId, nMainProfileId) + local nGuideId = CalcSolidGuide( nOutlineId, nSolidLayerId, nMainProfileId, nGeoLayerId) local sSection = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. WIN_SECTION local nMainExtrusionId = CreateMainSurf( nGuideId, nMainProfileId, sSection, nSolidLayerId) @@ -4567,9 +5115,9 @@ local function CalcSolid( nPartId, nOutlineId) -- b) trim con i controprofili su start e su end local nGeoRight = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_RIGHT) - TrimSolid( nGeoRight, dGeoWidth, nSolidLayerId, nMainExtrusionId) + TrimSolid( nGeoRight, nSolidLayerId, nMainExtrusionId, nGuideId, nMainProfileId) local nGeoLeft = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_LEFT) - TrimSolid( nGeoLeft, dGeoWidth, nSolidLayerId, nMainExtrusionId) + TrimSolid( nGeoLeft, nSolidLayerId, nMainExtrusionId, nGuideId, nMainProfileId) return nMainExtrusionId end @@ -4635,51 +5183,22 @@ end --------------------------------------------------------------------- -- funzione che calcola il riferimento dove posizionare i dowels -local function CreateDowelFrameDest( nPrevGeo, nGeo, nRefOutline, bCurrFullOrShort, bSashOrFrame) +local function CreateDowelFrameDest( nPrevRight, nCurrLeft, nRefOutline, bCurrFullOrShort) - -- 1) la direzione z è determinata dal pezzo short local vtZ + local ptOrig if EgtGetType( nRefOutline) == GDB_TY.CRV_LINE then vtZ = EgtEV( nRefOutline) + ptOrig = EgtIf( bCurrFullOrShort, EgtEP( nRefOutline), EgtSP( nRefOutline)) else -- se pezzo ad arco, recupero la direzione dalla curva nel punto estremo del geo - local nGeoRefCrv - if bCurrFullOrShort then - nGeoRefCrv = EgtGetFirstNameInGroup( nPrevGeo, WIN_RIGHT) - else - nGeoRefCrv = EgtGetFirstNameInGroup( nGeo, WIN_LEFT) - end - local ptInt = EgtIP( nGeoRefCrv, nRefOutline, ORIG()) - local dPar = EgtCurveParamAtPoint( nRefOutline, ptInt, 100 * GEO.EPS_SMALL) + local ptRef = EgtIf( bCurrFullOrShort, EgtSP( nPrevRight), EgtEP( nCurrLeft)) + local _, ptInt, dPar = EgtPointCurveDist( ptRef, nRefOutline) vtZ = EgtUV( nRefOutline, dPar, -1) + ptOrig = ptInt end - local frDest = Frame3d( ORIG(), - vtZ) - - -- 2) punto di origine - local nPrevRight = EgtGetFirstNameInGroup( nPrevGeo, WIN_GEO_RIGHT) - local ptRef1 = EgtIf( bCurrFullOrShort, EgtSP( nPrevRight), EgtEP( nPrevRight)) - local nLeft = EgtGetFirstNameInGroup( nGeo, WIN_GEO_LEFT) - local ptRef2 = EgtIf( bCurrFullOrShort, EgtSP( nLeft), EgtEP( nLeft)) - -- riporto i punti sulla curva di outline su cui va posizionato il profilo con le spine - local _, ptInt1 = EgtPointCurveDist( ptRef1, nRefOutline) - local _, ptInt2 = EgtPointCurveDist( ptRef2, nRefOutline) - - -- nel caso di telaio conviene tenere il punto più "interno" visto che la correzione sarà fatta verso l'esterno - -- nel caso di anta conviene tenere quello più "esterno" visto che la correzione sarà fatta verso l'interno - ptInt1:toLoc( frDest) - ptInt2:toLoc( frDest) - local ptInt - if ptInt1:getX() > ptInt2:getX() then - ptInt = EgtIf( bSashOrFrame, Point3d( ptInt1), Point3d( ptInt2)) - else - ptInt = EgtIf( bSashOrFrame, Point3d( ptInt2), Point3d( ptInt1)) - end - ptInt:toGlob( frDest) - - -- modifico il punto di origine del frame nel punto individuato - frDest:move( ptInt - ORIG()) - + local frDest = Frame3d( ptOrig, - vtZ) return frDest end @@ -4729,42 +5248,12 @@ local function CreateDowel( nOrigDowelId, nLayerId, frOrig, frDest, vtDir, nTest return nDowelId end ---------------------------------------------------------------------- --- funzione che calcola la correzione da applicare al frame dei dowels per evitare che fuoriescano dal pezzo da un lato visibile ( esterno per ante ed interno per telaio) -local function CalcDowelFrameCorrection( nOutlineId, nPrevOutlineId, nDowelRef, frOrig, frDest, nTestSurfPos, nTestSurfPosPrev, nTestSurf, vtMove, nLayerId, dLen, dPrevLen) - - local dMove = 0 - -- se le curve sono due linee non serve correzione - if EgtGetType( nOutlineId) == GDB_TY.CRV_LINE and EgtGetType( nPrevOutlineId) == GDB_TY.CRV_LINE then - return dMove - end - - -- 1) verifico posizione per il pezzo corrente - -- posiziono il dowel - local nDowel1 = EgtCopyGlob( nDowelRef, nLayerId) - PositionDowel( nDowel1, frOrig, frDest, - frDest:getVersZ(), nTestSurfPos) - -- verifico se la faccia di fondo fuoriesce dalla superficie di test - local dMove1 = EgtCAvToolPosStm( EgtCP( nDowel1) - frDest:getVersZ() * dLen, frDest:getVersZ(), nTestSurf, vtMove) - - -- 2) verifico posizione per il pezzo precedente - -- posiziono il dowel - local nDowel2 = EgtCopyGlob( nDowelRef, nLayerId) - PositionDowel( nDowel2, frOrig, frDest, frDest:getVersZ(), nTestSurfPosPrev) - -- verifico se la faccia di fondo fuoriesce dalla superficie di test - local dMove2 = EgtCAvToolPosStm( EgtCP( nDowel2) + frDest:getVersZ() * dPrevLen, - frDest:getVersZ(), nTestSurf, vtMove) - - EgtErase( nDowel1) - EgtErase( nDowel2) - - -- calcolo la correzione complessiva - dMove = max( dMove1, dMove2) + s_dDowelTol - return dMove -end - --------------------------------------------------------------------- -- funzione che calcola i dowels tra due pezzi local function CalcDowels( nOrigOutlineId, nOrigPrevOutlineId, bSashOrFrame, nBottomRail) - + + -- TODO correzione per non far uscire i dowels + -- se soglia non ci sono dowels if EgtGetInfo( nOrigOutlineId, WIN_THRESHOLD, 'b') or EgtGetInfo( nOrigPrevOutlineId, WIN_THRESHOLD, 'b') then return @@ -4810,10 +5299,28 @@ local function CalcDowels( nOrigOutlineId, nOrigPrevOutlineId, bSashOrFrame, nBo EgtOffsetCurve( nRefCrv, - dOffs) end - -- recupero i geo + -- recupero le curve di riferimento dei geo ( right per il prev e left per il corrente) local nGeo = EgtGetFirstNameInGroup( nPart, WIN_GEO) local nPrevGeo = EgtGetFirstNameInGroup( nPrevPart, WIN_GEO) - + local vPrevGeoCrvs = EgtGetNameInGroup( nPrevGeo, WIN_GEO_RIGHT) + local nPrevRight = vPrevGeoCrvs[1] + for i = 2, #vPrevGeoCrvs do + local nRefOutline = EgtGetInfo( vPrevGeoCrvs[i], WIN_REF_OUTLINE, 'i') + if nRefOutline == nOrigOutlineId then + nPrevRight = vPrevGeoCrvs[i] + break + end + end + local vCurrGeoCrvs = EgtGetNameInGroup( nGeo, WIN_GEO_LEFT) + local nCurrLeft = vCurrGeoCrvs[1] + for i = 2, #vCurrGeoCrvs do + local nRefOutline = EgtGetInfo( vCurrGeoCrvs[i], WIN_REF_OUTLINE, 'i') + if nRefOutline == nOrigPrevOutlineId then + nCurrLeft = vCurrGeoCrvs[i] + break + end + end + -- recupero i solidi local nPrevSolidId, nSolidId, nPrevSolidLay, nSolidLay if s_bCalcSolid then @@ -4824,13 +5331,22 @@ local function CalcDowels( nOrigOutlineId, nOrigPrevOutlineId, bSashOrFrame, nBo end -- recupero il tipo di giunzione - local nJointType = EgtGetInfo( nOutlineId, WIN_STARTJOINT, 'i') + local nJointType if nBottomRail then if EgtGetName( nOutlineId) == WIN_BOTTOM then nJointType = WIN_PART_JNT.SHORT else nJointType = WIN_PART_JNT.FULL end + else + local vJointTypes = EgtGetInfo( nOutlineId, WIN_STARTJOINT, 'vi') + local vPrevOutlines = EgtGetInfo( nOutlineId, WIN_PREV_OUTLINES, 'vi') + for i = 1, #vPrevOutlines do + if vPrevOutlines[i] == nOrigPrevOutlineId then + nJointType = vJointTypes[i] + break + end + end end if nJointType == WIN_PART_JNT.ANGLED then @@ -4844,7 +5360,7 @@ local function CalcDowels( nOrigOutlineId, nOrigPrevOutlineId, bSashOrFrame, nBo frOrig:invert() -- calcolo il riferimento su cui posizionare i dowels - local frDest = CreateDowelFrameDest( nPrevGeo, nGeo, nPrevOutlineId, true, bSashOrFrame) + local frDest = CreateDowelFrameDest( nPrevRight, nCurrLeft, nPrevOutlineId, true) -- recupero info con la lunghezza ( dipendono dal profilo del pezzo full quindi dal corrente) local sLenKey = WIN_DWL_TOP_PERP_LEN @@ -4865,63 +5381,30 @@ local function CalcDowels( nOrigOutlineId, nOrigPrevOutlineId, bSashOrFrame, nBo nTestSurf = CreateProfileSurf( nOrigOutlineId, nProfileId, sCtrIn, 100, nLayerId) else -- è la superficie che viene utilizzata per trimmare l'end del pezzo prev - local nGeoCrv = EgtGetFirstNameInGroup( nPrevGeo, WIN_GEO_RIGHT) - local nOrigSurf = EgtGetInfo( nGeoCrv, WIN_REF_SURF, 'i') + local nOrigSurf = EgtGetInfo( nPrevRight, WIN_REF_SURF, 'i') nTestSurf = EgtCopyGlob( nOrigSurf, nLayerId) end local nTestSurfInverted = EgtCopyGlob( nTestSurf, nLayerId) EgtInvertSurf( nTestSurfInverted) - - -- superficie test per la traslazione dei dowels - local nTestSurf2 - if bSashOrFrame then - -- se anta la superficie da cui non fuoriuscire è quella esterna del pezzo short, ovvero la superficie usata per trimmare lo start del pezzo corrente - if not s_bCalcSolid or s_bSimplSolid then - nTestSurf2 = CreateProfileSurf( nOrigPrevOutlineId, nPrevProfileId, WIN_OFST .. WIN_OUT, 100, nLayerId) - else - local nGeoCrv = EgtGetFirstNameInGroup( nGeo, WIN_GEO_LEFT) - local nOrigSurf = EgtGetInfo( nGeoCrv, WIN_REF_SURF, 'i') - nTestSurf2 = EgtCopyGlob( nOrigSurf, nLayerId) - end - EgtInvertSurf( nTestSurf2) - else - -- se telaio la superficie da cui non fuoriuscire è quella interna del pezzo short - local sCtrIn2 = WIN_OFST .. GetProfileCtrIn( nOrigPrevOutlineId, nOutlineId, nPrevProfileId) - nTestSurf2 = CreateProfileSurf( nOrigPrevOutlineId, nPrevProfileId, sCtrIn2, 100, nLayerId) - end - - -- direzione per la traslazione dei dowels - local vtMove = EgtIf( bSashOrFrame, - frDest:getVersX(), frDest:getVersX()) - + -- analizzo le singole file di dowels for k = 0, 3 do -- recupero i dowels della fila k-esima local vDowels = EgtGetNameInGroup( nPrevProfileId, WIN_DOWEL .. 'Row' .. tostring( k)) if #vDowels > 0 then - - -- recupero il dowel nella posizione più problematica ( per le ante è quello più esterno, per il telaio quello più interno) - local nDowelRef = EgtIf( bSashOrFrame, vDowels[1], vDowels[#vDowels]) - -- calcolo correzione da applicare al frame affinchè i dowels non fuoriescano da un lato visibile ( esterno per ante ed interno per telaio) - local dLenCurr = CalcDowelLen( nDowelRef, sLenKey, true) - local dLenPrev = CalcDowelLen( nDowelRef, sPrevLenKey, false) - local dMove = CalcDowelFrameCorrection( nOutlineId, nPrevOutlineId, nDowelRef, frOrig, frDest, nTestSurfInverted, nTestSurf, nTestSurf2, vtMove, nLayerId, dLenCurr, dLenPrev) - local frDestDowel = Frame3d( frDest) - frDestDowel:move( dMove * vtMove) - for i = 1, #vDowels do -- dowels per pezzo corrente ( full) local dLenFull = CalcDowelLen( vDowels[i], sLenKey, true) - CreateDowel( vDowels[i], nLayerId, frOrig, frDestDowel, - frDestDowel:getVersZ(), nTestSurfInverted, dLenFull, WIN_PRC_SIDETYPE.IN, nSolidId) + CreateDowel( vDowels[i], nLayerId, frOrig, frDest, - frDest:getVersZ(), nTestSurfInverted, dLenFull, WIN_PRC_SIDETYPE.IN, nSolidId) -- dowels per prezzo precedente ( short) local dLenShort = CalcDowelLen( vDowels[i], sPrevLenKey, false) - CreateDowel( vDowels[i], nPrevLayerId, frOrig, frDestDowel, frDestDowel:getVersZ(), nTestSurf, dLenShort, WIN_PRC_SIDETYPE.RIGHT, nPrevSolidId) + CreateDowel( vDowels[i], nPrevLayerId, frOrig, frDest, frDest:getVersZ(), nTestSurf, dLenShort, WIN_PRC_SIDETYPE.RIGHT, nPrevSolidId) end end end EgtErase( nTestSurf) EgtErase( nTestSurfInverted) - EgtErase( nTestSurf2) elseif nJointType == WIN_PART_JNT.SHORT then @@ -4932,7 +5415,7 @@ local function CalcDowels( nOrigOutlineId, nOrigPrevOutlineId, bSashOrFrame, nBo frOrig:invert() -- calcolo il riferimento su cui posizionare i dowels - local frDest = CreateDowelFrameDest( nPrevGeo, nGeo, nOutlineId, false, bSashOrFrame) + local frDest = CreateDowelFrameDest( nPrevRight, nCurrLeft, nOutlineId, false) -- recupero info con la lunghezza ( dipendono dal profilo del pezzo full, quindi da prezzo prev) local sLenKey = WIN_DWL_TOP_PARA_LEN @@ -4958,61 +5441,30 @@ local function CalcDowels( nOrigOutlineId, nOrigPrevOutlineId, bSashOrFrame, nBo local sCtrIn = WIN_OFST .. GetProfileCtrIn( nOrigPrevOutlineId, nOutlineId, nPrevProfileId) -- controprofilo del pezzo full nTestSurf = CreateProfileSurf( nOrigPrevOutlineId, nPrevProfileId, sCtrIn, 100, nLayerId) else - local nGeoCrv = EgtGetFirstNameInGroup( nGeo, WIN_GEO_LEFT) - local nOrigSurf = EgtGetInfo( nGeoCrv, WIN_REF_SURF, 'i') + local nOrigSurf = EgtGetInfo( nCurrLeft, WIN_REF_SURF, 'i') nTestSurf = EgtCopyGlob( nOrigSurf, nLayerId) end local nTestSurfInverted = EgtCopyGlob( nTestSurf, nLayerId) EgtInvertSurf( nTestSurfInverted) - -- superficie test per la traslazione dei dowels - local nTestSurf2 - if bSashOrFrame then - if not s_bCalcSolid or s_bSimplSolid then - nTestSurf2 = CreateProfileSurf( nOrigOutlineId, nProfileId, WIN_OFST .. WIN_OUT, 100, nLayerId) - else - local nGeoCrv = EgtGetFirstNameInGroup( nPrevGeo, WIN_GEO_RIGHT) - local nOrigSurf = EgtGetInfo( nGeoCrv, WIN_REF_SURF, 'i') - nTestSurf2 = EgtCopyGlob( nOrigSurf, nLayerId) - end - EgtInvertSurf( nTestSurf2) - else - local sCtrIn2 = WIN_OFST .. GetProfileCtrIn( nOutlineId, nPrevOutlineId, nProfileId) -- controprofilo del pezzo short - nTestSurf2 = CreateProfileSurf( nOrigOutlineId, nProfileId, sCtrIn2, 100, nLayerId) - end - - -- direzione per la traslazione dei dowels - local vtMove = EgtIf( bSashOrFrame, - frDest:getVersX(), frDest:getVersX()) - -- analizzo le singole file di dowels for k = 0, 3 do -- recupero i dowels sulla fila k-esima local vDowels = EgtGetNameInGroup( nProfileId, WIN_DOWEL .. 'Row' .. tostring(k)) if #vDowels > 0 then - - -- recupero il dowel nella posizione più problematica ( per le ante è quello più esterno, per il telaio quello più interno) - local nDowelRef = EgtIf( bSashOrFrame, vDowels[1], vDowels[#vDowels]) - -- calcolo correzione da applicare al frame affinchè i dowels non fuoriescano da un lato visibile ( esterno per ante ed interno per telaio) - local dLenCurr = CalcDowelLen( nDowelRef, sLenKey, false) - local dLenPrev = CalcDowelLen( nDowelRef, sPrevLenKey, true) - local dMove = CalcDowelFrameCorrection( nOutlineId, nPrevOutlineId, nDowelRef, frOrig, frDest, nTestSurf, nTestSurfInverted, nTestSurf2, vtMove, nLayerId, dLenCurr, dLenPrev) - local frDestDowel = Frame3d( frDest) - frDestDowel:move( dMove * vtMove) - for i = 1, #vDowels do -- dowels per pezzo corrente ( short) local dLenShort = CalcDowelLen( vDowels[i], sLenKey, false) - CreateDowel( vDowels[i], nLayerId, frOrig, frDestDowel, - frDestDowel:getVersZ(), nTestSurf, dLenShort, WIN_PRC_SIDETYPE.LEFT, nSolidId) + CreateDowel( vDowels[i], nLayerId, frOrig, frDest, - frDest:getVersZ(), nTestSurf, dLenShort, WIN_PRC_SIDETYPE.LEFT, nSolidId) -- dowels per prezzo precedente ( full) local dLenFull = CalcDowelLen( vDowels[i], sPrevLenKey, true) - CreateDowel( vDowels[i], nPrevLayerId, frOrig, frDestDowel, frDestDowel:getVersZ(), nTestSurfInverted, dLenFull, WIN_PRC_SIDETYPE.IN, nPrevSolidId) + CreateDowel( vDowels[i], nPrevLayerId, frOrig, frDest, frDest:getVersZ(), nTestSurfInverted, dLenFull, WIN_PRC_SIDETYPE.IN, nPrevSolidId) end end end EgtErase( nTestSurf) EgtErase( nTestSurfInverted) - EgtErase( nTestSurf2) end EgtErase( nOutlineId) @@ -5202,17 +5654,23 @@ local function CalculateAreaDowels( nAreaId) -- aggiungo le spine sui pezzi dell'area local nOutline = EgtGetFirstInGroup( nOutlineLayerId) local nPrevOutline = EgtGetLastInGroup( nOutlineLayerId) + while EgtGetInfo( nPrevOutline, WIN_EXTRA_CRV, 'b') do + nPrevOutline = EgtGetPrev( nPrevOutline) + end while nOutline do - -- aggiungo spine su nOutline e nPrevOutline nel loro punto di giunzione - CalcDowels( nOutline, nPrevOutline, nAreaType == WIN_AREATYPES.SASH) - -- bottomrail - if nBottomRails > 0 and ( EgtGetName( nOutline) == WIN_BOTTOM or EgtGetName( nPrevOutline) == WIN_BOTTOM) then - for j = 1, nBottomRails do - CalcDowels( nOutline, nPrevOutline, false, j) + local bExtra = EgtGetInfo( nOutline, WIN_EXTRA_CRV, 'b') or false + if not bExtra then + -- aggiungo spine su nOutline e nPrevOutline nel loro punto di giunzione + CalcDowels( nOutline, nPrevOutline, nAreaType == WIN_AREATYPES.SASH) + -- bottomrail + if nBottomRails > 0 and ( EgtGetName( nOutline) == WIN_BOTTOM or EgtGetName( nPrevOutline) == WIN_BOTTOM) then + for j = 1, nBottomRails do + CalcDowels( nOutline, nPrevOutline, false, j) + end end + -- aggiorno per iterazione successiva + nPrevOutline = nOutline end - -- aggiorno per iterazione successiva - nPrevOutline = nOutline nOutline = EgtGetNext( nOutline) end @@ -5341,7 +5799,7 @@ local function TrimStripSurfByCurve( nCrvId, nStripSurfId, nSolidLayerId, bPrev) end --------------------------------------------------------------------- -local function CalcAreaStrip( nGeoFillId) +local function CalcAreaStrip( nOutlineLayerId) if not s_bCalcSolid then return end @@ -5354,156 +5812,157 @@ local function CalcAreaStrip( nGeoFillId) EgtSetStatus( nGrp2, GDB_ST.OFF) -- 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 vOutlineCrvs = EgtGetAllInGroup( nOutlineLayerId) local tabStrip = {} - for i = 1, #vGeoCrvs do + for i = 1, #vOutlineCrvs do - local nFillOutlineId = EgtGetInfo( vGeoCrvs[i], WIN_REF_OUTLINE, 'i') - local nOutlineId = EgtGetInfo( nFillOutlineId, WIN_SOU_OUTLINE, 'i') + local nOutlineId = EgtGetInfo( vOutlineCrvs[i], WIN_SOU_OUTLINE, 'i') + -- verifico se pezzo ausiliario da ignorare + local bExtra = EgtGetInfo( nOutlineId, WIN_EXTRA_CRV, 'b') local nPartId = FindAssociatedPart( abs( nOutlineId), true) - + -- recupero profilo local nProfileLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE) local nProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN) local nStripId = GetStripNearestToOutline( nProfileId, nOutlineId) - + -- recupero layer per solido - local nSolidLayerId = EgtGetFirstNameInGroup( nPartId, WIN_SOLID) - - -- estrusione del fermavetro : - -- creazione della giuda - local nGuideId = EgtCurveCompo( nSolidLayerId, abs( nOutlineId), false) - local sProfileType = EgtGetInfo( nProfileId, WIN_PROFILETYPE) - if sProfileType == WIN_FILL_RAIL then - local dOffs = EgtGetInfo( nProfileId, WIN_RAILOFFS, 'd') - EgtOffsetCurve( nGuideId, - dOffs) + local nStripExtrusionId + if not bExtra then + local nSolidLayerId = EgtGetFirstNameInGroup( nPartId, WIN_SOLID) + + -- estrusione del fermavetro : + -- creazione della giuda + local nGuideId = EgtCurveCompo( nSolidLayerId, abs( nOutlineId), false) + local sProfileType = EgtGetInfo( nProfileId, WIN_PROFILETYPE) + if sProfileType == WIN_FILL_RAIL then + local dOffs = EgtGetInfo( nProfileId, WIN_RAILOFFS, 'd') + EgtOffsetCurve( nGuideId, - dOffs) + end + -- estensione : se in tangenza con le vicine estensione in tangenza altrimenti estensione standard + local nPrev = EgtGetPrev( vOutlineCrvs[i]) or EgtGetLastInGroup( nOutlineLayerId) + local nNext = EgtGetNext( vOutlineCrvs[i]) or EgtGetLastInGroup( nOutlineLayerId) + if AreSameVectorApprox( EgtEV( nPrev), EgtSV( nGuideId)) then + EgtAddCurveCompoLineTg( nGuideId, 100, false) + else + EgtExtendCurveStartByLen( nGuideId, 100) + end + if AreSameVectorApprox( EgtEV( nGuideId), EgtSV( nNext)) then + EgtAddCurveCompoLineTg( nGuideId, 100) + else + EgtExtendCurveEndByLen( nGuideId, 100) + end + -- sistemo il profilo da estrudere + 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) + nStripExtrusionId = EgtSurfTmSwept( nSolidLayerId, nSectionId, nGuideId, false, WIN_SURF_APPROX) + EgtSetName( nStripExtrusionId, WIN_SRF_STRIP) + EgtErase( nSectionId) + EgtErase( nGuideId) end - -- estensione : se in tangenza con le vicine estensione in tangenza altrimenti estensione standard - local nPrev = EgtGetPrev( vGeoCrvs[i]) or EgtGetLastInGroup( nGeoFillId) - local nNext = EgtGetNext( vGeoCrvs[i]) or EgtGetLastInGroup( nGeoFillId) - if AreSameVectorApprox( EgtEV( nPrev), EgtSV( nGuideId)) then - EgtAddCurveCompoLineTg( nGuideId, 100, false) - else - EgtExtendCurveStartByLen( nGuideId, 100) - end - if AreSameVectorApprox( EgtEV( nGuideId), EgtSV( nNext)) then - EgtAddCurveCompoLineTg( nGuideId, 100) - else - EgtExtendCurveEndByLen( nGuideId, 100) - end - -- sistemo il profilo da estrudere - 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) - EgtErase( nGuideId) -- curve limite del fermavetro local nOffs1, nOffs2 = CreateStripGuideLines( nOutlineId, 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) + EgtRelocateGlob( nOffs1, nGrp1) + EgtRelocateGlob( nOffs2, nGrp2) + EgtSetInfo( nOffs1, WIN_REF_OUTLINE, vOutlineCrvs[i]) + EgtSetInfo( nOffs2, WIN_REF_OUTLINE, vOutlineCrvs[i]) + + tabStrip[vOutlineCrvs[i]] = { Offs1 = GDB_ID.NULL, Offs2 = GDB_ID.NULL, StripId = nStripExtrusionId} end -- taglio le curve limite dei fermavetri per individuare correttamente i pezzi con cui verranno tagliati - TrimOrderedCurves( EgtGetAllInGroup( nGrp1), true) - TrimOrderedCurves( EgtGetAllInGroup( nGrp2), true) + local vCrv1 = TrimOrderedCurves( EgtGetAllInGroup( nGrp1), true) + local vCrv2 = TrimOrderedCurves( EgtGetAllInGroup( nGrp2), true) -- 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) + for i = 1, #vCrv1 do + local nOutlineRef = EgtGetInfo( vCrv1[i], WIN_REF_OUTLINE, 'i') + tabStrip[nOutlineRef].Offs1 = vCrv1[i] end - nCrvId = EgtGetFirstInGroup( nGrp2) - while nCrvId do - local nGeoRef = EgtGetInfo( nCrvId, WIN_REF_GEO, 'i') - tabStrip[nGeoRef].Offs2 = nCrvId - nCrvId = EgtGetNext( nCrvId) + for i = 1, #vCrv2 do + local nOutlineRef = EgtGetInfo( vCrv2[i], WIN_REF_OUTLINE, 'i') + tabStrip[nOutlineRef].Offs2 = vCrv2[i] 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 taglio basandomi solo sui riferimenti dello strip corrente - TrimStripSurfByPoints( EgtSP( nCrvOffs2), EgtSP( nCrvOffs1), nStripId, nSolidLayerId, true) - else - -- ci sono dei pezzi che scompaiono quindi vanno effettuati due tagli: uno per ricreare il bordo 2 dei pezzi che scompaiono e uno per - -- separare il pezzo corrente e il pezzo 1 - - -- a) recupero i pezzi che scompaiono - local nStartCrv = tabStrip[nPrevCrv1].Offs2 - nStartCrv = EgtGetNext( nStartCrv) or EgtGetFirstInGroup( EgtGetParent( nStartCrv)) - local vIds = {} - while nStartCrv ~= nCrvOffs2 do - table.insert( vIds, nStartCrv) - nStartCrv = EgtGetNext( nStartCrv) or EgtGetFirstInGroup( EgtGetParent( nStartCrv)) - end - local nCrvRef2 = EgtCurveCompo( nGrp, vIds, false) - -- taglio - TrimStripSurfByCurve( nCrvRef2, nStripId, nSolidLayerId) - - -- b) taglio che separa da pezzo 1 - TrimStripSurfByPoints( EgtCP( nCrvRef2), EgtSP( nCrvOffs1), nStripId, nSolidLayerId, true) - EgtErase( nCrvRef2) - 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') + for i = 1, #vOutlineCrvs do + if tabStrip[vOutlineCrvs[i]].StripId then + -- recupero solido del fermavetro + local nCrv = vOutlineCrvs[i] + local nStripId = tabStrip[nCrv].StripId + local nSolidLayerId = EgtGetParent( nStripId) - if nNextCrv1 == nNextCrv2 then - TrimStripSurfByPoints( EgtEP( nCrvOffs1), EgtEP( nCrvOffs2), nStripId, nSolidLayerId) - else - local nStartCrv = nCrvOffs2 - nStartCrv = EgtGetNext( nStartCrv) or EgtGetFirstInGroup( EgtGetParent( nStartCrv)) - local vIds = {} - while nStartCrv ~= tabStrip[nNextCrv1].Offs2 do - table.insert( vIds, nStartCrv) - nStartCrv = EgtGetNext( nStartCrv) or EgtGetFirstInGroup( EgtGetParent( nStartCrv)) - end - local nCrvRef2 = EgtCurveCompo( nGrp, vIds, false) - TrimStripSurfByCurve( nCrvRef2, nStripId, nSolidLayerId) - - TrimStripSurfByPoints( EgtEP( nCrvOffs1), EgtCP( nCrvRef2), nStripId, nSolidLayerId) - EgtErase( nCrvRef2) - end + -- recupero le corrispondenti curve limite trimmate + local nCrvOffs1 = tabStrip[nCrv].Offs1 + local nCrvOffs2 = tabStrip[nCrv].Offs2 - else - -- il pezzo scompare - EgtErase( nStripId) + -- 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_OUTLINE, 'i') + local nPrevCrv2 = EgtGetInfo( nPrev2, WIN_REF_OUTLINE, 'i') + + if nPrevCrv1 == nPrevCrv2 then + -- se le precedenti coincidono taglio basandomi solo sui riferimenti dello strip corrente + TrimStripSurfByPoints( EgtSP( nCrvOffs2), EgtSP( nCrvOffs1), nStripId, nSolidLayerId, true) + else + -- ci sono dei pezzi che scompaiono quindi vanno effettuati due tagli: uno per ricreare il bordo 2 dei pezzi che scompaiono e uno per + -- separare il pezzo corrente e il pezzo 1 + + -- a) recupero i pezzi che scompaiono + local nCurrCrv = tabStrip[nPrevCrv1].Offs2 + nCurrCrv = EgtGetNext( nCurrCrv) or EgtGetFirstInGroup( nGrp2) + local vIds = {} + while nCurrCrv ~= nCrvOffs2 do + table.insert( vIds, nCurrCrv) + nCurrCrv = EgtGetNext( nCurrCrv) or EgtGetFirstInGroup( nGrp2) + end + local nCrvBorder = EgtCurveCompo( nGrp, vIds, false) + -- taglio + TrimStripSurfByCurve( nCrvBorder, nStripId, nSolidLayerId) + + -- b) taglio che separa da pezzo 1 + TrimStripSurfByPoints( EgtCP( nCrvBorder), EgtSP( nCrvOffs1), nStripId, nSolidLayerId, true) + EgtErase( nCrvBorder) + 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_OUTLINE, 'i') + local nNextCrv2 = EgtGetInfo( nNext2, WIN_REF_OUTLINE, 'i') + + if nNextCrv1 == nNextCrv2 then + TrimStripSurfByPoints( EgtEP( nCrvOffs1), EgtEP( nCrvOffs2), nStripId, nSolidLayerId) + else + local nCurrCrv = nCrvOffs2 + nCurrCrv = EgtGetNext( nCurrCrv) or EgtGetFirstInGroup( nGrp2) + local vIds = {} + while nCurrCrv ~= tabStrip[nNextCrv1].Offs2 do + table.insert( vIds, nCurrCrv) + nCurrCrv = EgtGetNext( nCurrCrv) or EgtGetFirstInGroup( nGrp2) + end + local nCrvBorder = EgtCurveCompo( nGrp, vIds, false) + TrimStripSurfByCurve( nCrvBorder, nStripId, nSolidLayerId) + + TrimStripSurfByPoints( EgtEP( nCrvOffs1), EgtCP( nCrvBorder), nStripId, nSolidLayerId) + EgtErase( nCrvBorder) + end + + else + -- il pezzo scompare + EgtErase( nStripId) + end end end @@ -5522,6 +5981,7 @@ local function CalculateAreaParts( nFrameId) -- recupero i pezzi del serramento local vParts = {} local vFillParts = {} + local vAuxParts = {} -- sono pezzi non fisicamente realizzabili che servono solo per i conti local nPartId = EgtGetFirstPart( GDB_ID.ROOT) while nPartId do local nType = EgtGetInfo( nPartId, WIN_PART_TYPE, 'i') @@ -5529,7 +5989,12 @@ local function CalculateAreaParts( nFrameId) table.insert( vFillParts, nPartId) else local nOutlineId = EgtGetInfo( nPartId, WIN_REF_OUTLINE, 'i') - table.insert( vParts, { nId = nPartId, nOutlineId = nOutlineId}) + local bExtra = EgtGetInfo( nOutlineId, WIN_EXTRA_CRV, 'b') or false + if bExtra then + table.insert( vAuxParts, nPartId) + else + table.insert( vParts, { nId = nPartId, nOutlineId = nOutlineId}) + end end nPartId = EgtGetNextPart( nPartId) end @@ -5538,7 +6003,7 @@ local function CalculateAreaParts( nFrameId) for i = 1, #vParts do CalcGeo( vParts[i].nId, vParts[i].nOutlineId) end - + -- calcolo cambio profilo sugli split di tipo mixed for i = 1, #vParts do if EgtGetName( vParts[i].nOutlineId) == WIN_SPLIT then @@ -5565,7 +6030,7 @@ local function CalculateAreaParts( nFrameId) CalcSolid( vParts[i].nId, vParts[i].nOutlineId) end end - + -- pezzi fill for i = 1, #vFillParts do local nAreaId = EgtGetInfo( vFillParts[i], WIN_AREA, 'i') @@ -5576,8 +6041,11 @@ local function CalculateAreaParts( nFrameId) CalcFillSolid( vFillParts[i], nGeoLayerId) end -- calcolo fermavetro - CalcAreaStrip( nGeoLayerId) + CalcAreaStrip( nOutlineLayerId) end + + -- elimino i pezzi ausiliari + EgtErase( vAuxParts) end @@ -7674,13 +8142,13 @@ local function CalcPartPreview( nPartId, nPreviewGrp) local nGeoLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO) -- recupero il tipo di giunzioni - local nStartJoint = EgtGetInfo( nOutlineId, WIN_STARTJOINT, 'i') - local nEndJoint = EgtGetInfo( nOutlineId, WIN_ENDJOINT, 'i') + local vStartJoints = EgtGetInfo( nOutlineId, WIN_STARTJOINT, 'vi') + local vEndJoints = EgtGetInfo( nOutlineId, WIN_ENDJOINT, 'vi') local nAreaId - -- se non ha giunzioni short come preview posso considerare direttamente la regione del geo - if nStartJoint ~= WIN_PART_JNT.SHORT and nEndJoint ~= WIN_PART_JNT.SHORT then + -- se pezzo semplice senza giunzioni short come preview posso considerare direttamente la regione del geo + if #vStartJoints == 1 and #vEndJoints == 1 and vStartJoints[1] ~= WIN_PART_JNT.SHORT and vEndJoints[1] ~= WIN_PART_JNT.SHORT then local nGeoSurf = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_SURF) nAreaId = EgtCopyGlob( nGeoSurf, nPreviewGrp) EgtSetStatus( nAreaId, GDB_ST.ON) @@ -7713,25 +8181,27 @@ local function CalcPartPreview( nPartId, nPreviewGrp) local vGeoLeft = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_LEFT) local vPrevOutlineId = EgtGetInfo( nOutlineId, WIN_PREV_OUTLINES, 'vi') local vPrevProfileId = EgtGetNameInGroup( nProfileLayerId, WIN_PRF_START) - if nStartJoint == WIN_PART_JNT.ANGLED then + for i = 1, #vPrevOutlineId do - -- recupero la bisettrice dal geo - EgtCopyGlob( vGeoLeft[1], nGrpTmp) - - -- curva aux : considero l'out del pezzo precedente - local nCrvId = EgtCopyGlob( abs( vPrevOutlineId[1]), nGrpTmp) - local b3Profile = GetProfileLocalBox( vPrevProfileId[1]) - EgtOffsetCurve( nCrvId, b3Profile:getMax():getX()) - - else - for i = 1, #vPrevOutlineId do + if vStartJoints[i] == WIN_PART_JNT.ANGLED then + -- recupero la bisettrice dal geo + for k = 1, #vGeoLeft do + if EgtGetInfo( vGeoLeft[k], WIN_REF_OUTLINE, 'i') == vPrevOutlineId[i] and not EgtExistsInfo( vGeoLeft[k], WIN_SEMI_PROFILE) then + EgtCopyGlob( vGeoLeft[k], nGrpTmp) + end + end + -- curva aux : considero l'out del pezzo precedente + local nCrvId = EgtCopyGlob( abs( vPrevOutlineId[1]), nGrpTmp) + local b3Profile = GetProfileLocalBox( vPrevProfileId[1]) + EgtOffsetCurve( nCrvId, b3Profile:getMax():getX()) + else - -- se è pezzo del telaio contro soglia lo tratto come se fosse full + -- se è pezzo del telaio contro soglia lo tratto come se fosse full if EgtGetName( nOutlineId) ~= WIN_SPLIT and EgtGetInfo( abs( vPrevOutlineId[i]), WIN_THRESHOLD, 'b') then - nStartJoint = WIN_PART_JNT.FULL + vStartJoints[i] = WIN_PART_JNT.FULL end - if nStartJoint == WIN_PART_JNT.SHORT then + if vStartJoints[i] == WIN_PART_JNT.SHORT then local b3Profile = GetProfileLocalBox( vPrevProfileId[i]) local nCrvId = EgtCopy( abs( vPrevOutlineId[i]), nGrpTmp) local dRailDelta = EgtGetInfo( vPrevProfileId[i], WIN_RAILOFFS, 'd') or 0 @@ -7772,33 +8242,37 @@ local function CalcPartPreview( nPartId, nPreviewGrp) end end end - + -- d) curve right local vGeoRight = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_RIGHT) local vNextOutlineId = EgtGetInfo( nOutlineId, WIN_NEXT_OUTLINES, 'vi') local vNextProfileId = EgtGetNameInGroup( nProfileLayerId, WIN_PRF_END) - if nEndJoint == WIN_PART_JNT.ANGLED then + + for i = 1, #vNextOutlineId do - -- recupero la bisettrice dal geo - local nCrvId = EgtCopyGlob( vGeoRight[1], nGrpTmp) - EgtRelocateGlob( nCrvId, nInId, GDB_IN.BEFORE) - - -- curva aux - local nAuxCrv = EgtCopyGlob( abs( vNextOutlineId[1]), nGrpTmp) - local b3Profile = GetProfileLocalBox( vNextProfileId[1]) - EgtOffsetCurve( nAuxCrv, b3Profile:getMax():getX()) - EgtRelocateGlob( nAuxCrv, nInId, GDB_IN.BEFORE) - - else - for i = 1, #vNextOutlineId do + if vEndJoints[i] == WIN_PART_JNT.ANGLED then + -- recupero la bisettrice dal geo local nCrvId + for k = 1, #vGeoRight do + if EgtGetInfo( vGeoRight[k], WIN_REF_OUTLINE, 'i') == vNextOutlineId[i] and not EgtExistsInfo( vGeoRight[k], WIN_SEMI_PROFILE) then + nCrvId = EgtCopyGlob( vGeoRight[k], nGrpTmp) + EgtRelocateGlob( nCrvId, nInId, GDB_IN.BEFORE) + end + end + -- curva aux + local nAuxCrv = EgtCopyGlob( abs( vNextOutlineId[i]), nGrpTmp) + local b3Profile = GetProfileLocalBox( vNextProfileId[i]) + EgtOffsetCurve( nAuxCrv, b3Profile:getMax():getX()) + EgtRelocateGlob( nAuxCrv, nInId, GDB_IN.BEFORE) + else + local nCrvId -- se è pezzo del telaio contro soglia lo tratto come se fosse full if EgtGetName( nOutlineId) ~= WIN_SPLIT and EgtGetInfo( abs( vNextOutlineId[i]), WIN_THRESHOLD, 'b') then - nEndJoint = WIN_PART_JNT.FULL + vEndJoints[i] = WIN_PART_JNT.FULL end - if nEndJoint == WIN_PART_JNT.SHORT then + if vEndJoints[i] == WIN_PART_JNT.SHORT then nCrvId = EgtCopyGlob( abs( vNextOutlineId[i]), nGrpTmp) local b3Profile = GetProfileLocalBox( vNextProfileId[i]) local dRailDelta = EgtGetInfo( vNextProfileId[i], WIN_RAILOFFS, 'd') or 0 @@ -7821,12 +8295,12 @@ local function CalcPartPreview( nPartId, nPreviewGrp) else CopyInfo( nCrvId, vGeoRight[i], WIN_TANG_END, false) end - + else -- full local b3Profile = GetProfileLocalBox( vNextProfileId[i]) nCrvId = EgtCopyGlob( abs( vNextOutlineId[i]), nGrpTmp) local dOffs = b3Profile:getMax():getX() - if vNextOutlineId[i] < 0 then + if vNextOutlineId[i] < 0 then EgtInvertCurve( nCrvId) dOffs = - b3Profile:getMin():getX() end @@ -7843,6 +8317,11 @@ local function CalcPartPreview( nPartId, nPreviewGrp) EgtErase( nGrpTmp) end + -- se pezzo scompare + if not nAreaId then + return + end + -- sistemo la regione local nParentAreaId = EgtGetParent( EgtGetParent( nOutlineId)) local nAreaType = EgtGetInfo( nParentAreaId, WIN_AREATYPE, 'i') @@ -8010,7 +8489,7 @@ function WinCalculate.CreatePartFromArea( nFrameId) SetAreaProfiles( nFrameId) -- creo pezzi s_nSashNbr = 0 -- resetto il numero di ante del progetto - CalculateAreaParts( nFrameId) + CalculateAreaParts( nFrameId) -- calcolo le spine CalculateAreaDowels( nFrameId) @@ -8020,76 +8499,5 @@ function WinCalculate.CreatePartFromArea( nFrameId) end end ---------------------------------------------------------------------- --- funzione che ricalcola i solidi ( per cambio modalità visualizzazione) -function WinCalculate.RecalcSolids( nFrameId) - - -- scorro tutti i pezzi - local nPartId = EgtGetFirstPart() - while nPartId do - -- se solidi non vanno calcolati elimino semplicemente il gruppo dei solidi da ogni pezzo - if not s_bCalcSolid then - local nSolidLayId = EgtGetFirstNameInGroup( nPartId, WIN_SOLID) or GDB_ID.NULL - EgtErase( nSolidLayId) - - -- ricalcolo dei solidi - else - -- se fill, lo uso per ricalcolare strip - local nPartType = EgtGetInfo( nPartId, WIN_PART_TYPE, 'i') - if nPartType == WIN_PART_TYPES.FILL then - local nAreaId = EgtGetInfo( nPartId, WIN_AREA, 'i') - local nParentAreaId = EgtGetParent( nAreaId) - local nParentOutlineLayId = EgtGetFirstNameInGroup( nParentAreaId, WIN_OUTLINE) - local vParentOutlines = EgtGetAllInGroup( nParentOutlineLayId) - for i = 1, #vParentOutlines do - CreateStripFromOutline( nParentAreaId, vParentOutlines[i]) - end - - -- verifico se solido da calcolare - local nSolidLayId = EgtGetFirstNameInGroup( nPartId, WIN_SOLID) - if not nSolidLayId then - local nOutlineLayId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE) - local nGeoLayId = EgtGetFirstNameInGroup( nPartId, WIN_GEO) - CalcFillSolid( nPartId, nOutlineLayId, nGeoLayId) - end - - -- se pezzo, ricalcolo il suo solido - else - -- elimino gruppo dei solidi - local nSolidLayId = EgtGetFirstNameInGroup( nPartId, WIN_SOLID) or GDB_ID.NULL - EgtErase( nSolidLayId) - -- ricalcolo il solido principale - local nOutlineId = EgtGetInfo( nPartId, WIN_REF_OUTLINE, 'i') - local nSolidId = CalcSolid( nPartId, nOutlineId) - -- aggiungo lavorazioni - local nProcLayId = EgtGetFirstNameInGroup( nPartId, WIN_PRC) - local vProc = EgtGetAllInGroup( nProcLayId) - for i = 1, #vProc do - local nType = EgtGetInfo( vProc[i], WIN_PRC_FEATURE_TYPE) - local nProfilingType = EgtGetInfo( vProc[i], WIN_PRC_PROFILE_INFO) - if nType == WIN_PRC_TYPE.HOLE or ( nType == WIN_PRC_TYPE.PROFILING and nProfilingType == WIN_PRC_PROFILE_TYPE.GENERIC) then - UpdateSolidWithProcessingSurf( vProc[i], nSolidId, nProcLayId) - end - end - end - end - - nPartId = EgtGetNextPart( nPartId) - end - - -- accessori e ferramenta - local nAuxGrp = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_AUX) - if not s_bCalcSolid then - EgtErase( nAuxGrp or GDB_ID.NULL) - elseif not nAuxGrp then - nAuxGrp = GetAuxLayer() - -- ferramenta - DrawHardware( nFrameId, nAuxGrp) - -- accessori - WinCalculate.AddAccessories( nFrameId, true) - end - -end - --------------------------------------------------------------------- return WinCalculate diff --git a/Designing/WinProject.lua b/Designing/WinProject.lua index 758deef..1847331 100644 --- a/Designing/WinProject.lua +++ b/Designing/WinProject.lua @@ -356,12 +356,6 @@ local function WinCalculate_CreatePartFromArea() end _G.WinCalculate_CreatePartFromArea = WinCalculate_CreatePartFromArea ----------------------------------------------------------------------------------- -local function WinCalculate_RecalcSolids() - WinCalculate.RecalcSolids( WDG.FRAMEID) -end -_G.WinCalculate_RecalcSolids = WinCalculate_RecalcSolids - ---------------------------------------------------------------------------------- local function WinCalculate_AddHardware() WDG.HARDWAREKIT_LIST, WDG.HARDWAREPOSITION_LIST, WDG.HARDWAREOPTION_LIST = WinCalculate.AddHardware( WDG.FRAMEID, WDG.CALC_MACHINING, WDG.CALC_HARDWARELIST, WDG.CALC_POSITIONLIST, WDG.CALC_OPTIONLIST)