diff --git a/Designing/WinLib/WinCalculate.lua b/Designing/WinLib/WinCalculate.lua index 1436ceb..28256b7 100644 --- a/Designing/WinLib/WinCalculate.lua +++ b/Designing/WinLib/WinCalculate.lua @@ -239,7 +239,7 @@ local function CalcIntersectionRegion( vCrvs, nGrp) -- costruisco le regioni definite dai semipiani delle linee che compongono il contorno e calcolo le estensioni per gli archi ( verificando di non avere circonferenze coincidenti) -- e le composite ( che vanno gestite come gli archi) local dExtraLen = 10000 - local vSemiPlaneSurfs = {} + local vSemiPlanes = {} local tArcs = {} for i = 1, #vCrvs do if EgtGetType( vCrvs[i]) == GDB_TY.CRV_LINE then @@ -249,7 +249,7 @@ local function CalcIntersectionRegion( vCrvs, nGrp) local nSemiPlaneId = EgtSurfFrRectangle( nGrpTmp, ORIG(), Point3d( EgtCurveLength( vCrvs[i]) + 2 * dExtraLen, dExtraLen, 0)) local frRect = Frame3d( EgtSP( vCrvs[i]) - vtDir * dExtraLen, vtDir, vtOrtho, Z_AX()) EgtTransform( nSemiPlaneId, frRect) - table.insert( vSemiPlaneSurfs, nSemiPlaneId) + table.insert( vSemiPlanes, nSemiPlaneId) elseif EgtGetType( vCrvs[i]) == GDB_TY.CRV_ARC then local dRad = EgtArcRadius( vCrvs[i]) @@ -278,22 +278,23 @@ local function CalcIntersectionRegion( vCrvs, nGrp) else -- se composita deve contenere un arco, recupero il suo raggio local _, dEnd = EgtCurveDomain( vCrvs[i]) - local dRad + local dRad = 0 for j = 0, dEnd - 1 do dRad = EgtCurveCompoRadius( vCrvs[i], j) if dRad > 0 then break end end + local nCrvId = CreateCurveExtension( vCrvs[i], nGrpTmp) table.insert( tArcs, { nCrvId = nCrvId, vOrigId = { vCrvs[i]}, dRad = dRad}) end end -- calcolo la regione definita dai semipiani - for i = 2, #vSemiPlaneSurfs do - EgtSurfFrIntersect( vSemiPlaneSurfs[1], vSemiPlaneSurfs[i]) - EgtErase( vSemiPlaneSurfs[i]) + for i = 2, #vSemiPlanes do + EgtSurfFrIntersect( vSemiPlanes[1], vSemiPlanes[i]) + EgtErase( vSemiPlanes[i]) end - nSurfId = vSemiPlaneSurfs[1] + nSurfId = vSemiPlanes[1] -- se presenti archi, calcolo il loro contributo alla regione if #tArcs > 0 then @@ -396,12 +397,15 @@ end --------------------------------------------------------------------- -- funzione che data una lista di curve ordinate e orientate le estende o le taglia per creare una curva chiusa -local function TrimOrderedCurves( vCrvs, nExtraCurvesMode) - - -- costruisco la regione definita dalle curve +local function TrimOrderedCurves( vCrvs, nExtraCurvesMode, nSurfId) + local nGrpTmp = EgtGroup( GDB_ID.ROOT) EgtSetStatus( nGrpTmp, GDB_ST.OFF) - local nSurfId = CalcIntersectionRegion( vCrvs, nGrpTmp) + + -- se non calcolata, costruisco la regione definita dalle curve + if not nSurfId then + nSurfId = CalcIntersectionRegion( vCrvs, nGrpTmp) + end -- copia estesa delle curve per verificare gli overlaps local vExtCrvs = {} @@ -1784,6 +1788,218 @@ end ---------------------------------------------------------------------------------- -------------------------------- GEO ------------------------------------------- ---------------------------------------------------------------------------------- +-- funzione che crea il bisettore parabolico tra linea e arco +local function CalcParabolicBisector( nCrv1, nCrv2, dDim, nGrp) + + -- modifico le curve affinchè abbiano estremo in comune + local ptInt = FindIntersectionPoint( nCrv1, nCrv2, EgtSP( nCrv2)) + EgtModifyCurveStartPoint( nCrv2, ptInt) + EgtModifyCurveEndPoint( nCrv1, ptInt) + + -- calcolo coefficienti dell'equazione del bisettore ( equazione presa da Vroni) + local nArc, nLine, nSign + if EgtGetType( nCrv1) == GDB_TY.CRV_ARC and EgtGetType( nCrv2) == GDB_TY.CRV_LINE then + nArc = nCrv1 + nLine = nCrv2 + nSign = -1 + else + nArc = nCrv2 + nLine = nCrv1 + nSign = 1 + end + local ptC = EgtCP( nArc) + local dRad = EgtArcRadius( nArc) + -- equazione della retta + local dCoeffA = - EgtSV( nLine):getY() + local dCoeffB = EgtSV( nLine):getX() + local dCoeffC = - dCoeffA * ptInt:getX() - dCoeffB * ptInt:getY() + + local dDist = dCoeffA * ptC:getX() + dCoeffB * ptC:getY() + dCoeffC + local dA = ptC:getX() - dCoeffA * dDist + local dB = ptC:getY() - dCoeffB * dDist + local dZ = ptC:getZ() + -- k1 = -1 deve essere dentro la circonferenza + -- k2 = -1 deve essere a sinistra della linea + + -- campiono il bisettore ( è parametrizzato sul valore di offset t) + local vPoints = {} + local nTot = 10 + for i = 1, nTot do + local t = dDim / ( nTot - 1) * ( i - 1) + local dDiscriminant = dRad * dRad + 2 * t * ( - dRad + dDist) - dDist * dDist + local dX, dY + if dDiscriminant < GEO.EPS_ZERO then + dX = dA + dCoeffA * t + dY = dB + dCoeffB * t + else + dX = dA + dCoeffA * t + nSign * dCoeffB * sqrt( dDiscriminant) + dY = dB + dCoeffB * t - nSign * dCoeffA * sqrt( dDiscriminant) + end + vPoints[i] = Point3d( dX, dY, dZ) + end + + local nCompo = EgtCurveCompoFromPoints( nGrp, vPoints) + return nCompo +end + +--------------------------------------------------------------------- +-- funzione simile a CalcIntersectionRegion ma con considerazioni speciali per le curve del geo ( e.g. gestione bisettori) +local function CalcGeoRegion( vCrvs, nGrp) + + local nSurfId + local dExtraLen = 10000 + + -- gruppo temporaneo per i conti + local nGrpTmp = EgtGroup( nGrp) + EgtSetStatus( nGrpTmp, GDB_ST.OFF) + + -- a) costruisco i semipiani e identifico le curve con gestione speciale + local vSemiPlanes = {} + local tArcs = {} + local vBisectors = {} + for i = 1, #vCrvs do + + -- se linea costruisco il semipiano corrispondente + if EgtGetType( vCrvs[i]) == GDB_TY.CRV_LINE then + local vtDir = EgtSV( vCrvs[i]) + local vtOrtho = Vector3d( vtDir) + vtOrtho:rotate( Z_AX(), 90) + local nSemiPlaneId = EgtSurfFrRectangle( nGrpTmp, ORIG(), Point3d( EgtCurveLength( vCrvs[i]) + 2 * dExtraLen, dExtraLen, 0)) + local frRect = Frame3d( EgtSP( vCrvs[i]) - vtDir * dExtraLen, vtDir, vtOrtho, Z_AX()) + EgtTransform( nSemiPlaneId, frRect) + table.insert( vSemiPlanes, nSemiPlaneId) + + -- se arco calcolo estensione ( con verifica su circonferenze coincidenti) + 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 + 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 + + -- se composita è bisettore con gestione speciale + else + local nCrvId = EgtCopyGlob( vCrvs[i], nGrpTmp) + 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 + nSurfId = vSemiPlanes[1] + + -- c) se presenti archi, calcolo il loro contributo alla regione + if #tArcs > 0 then + + local nCrvBorder = EgtExtractSurfFrChunkLoops( nSurfId, 0, nGrpTmp) + + -- riordino per raggio decrescente ( per gestire prima quelle più grandi che potrebbero contenere le altre) + table.sort( tArcs, function ( a, b) return a.dRad > b.dRad end) + + for i = 1, #tArcs do + -- 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 + end + + if nCnt > 0 then + -- unisco tratto iniziale e finale se consecutivi + if nCnt > 1 and AreSamePointApprox( EgtSP( nCrv), EgtEP( nCrv + nCnt - 1)) then + if EgtGetType( nCrv) == GDB_TY.CRV_ARC then + EgtModifyCurveStartPoint( nCrv, EgtSP( nCrv + nCnt - 1)) + EgtErase( nCrv + nCnt - 1) + else + local vNewProps = EgtCurveCompoGetTempProp( nCrv + nCnt - 1) or {} + EgtAddCurveCompoCurve( nCrv, nCrv + nCnt - 1, true, false) + for i = 1, #vNewProps do + EgtCurveCompoSetTempProp( nCrv, i-1, vNewProps[i]) + end + end + nCnt = nCnt - 1 + end + + -- spezzo in corrispondenza di eventuali punti tangenti alla regione + 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 + end + end + end + + -- modifico il bordo corrente considerando solo i tratti che poggiano sulle curve orginali + 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 + end + end + end + end + + -- ricostruisco la superficie + nSurfId = EgtSurfFlatRegion( nGrpTmp, nCrvBorder) + end + + -- d) gestione di eventuali bisettori + if #vBisectors > 0 then + local nCrvBorder = EgtExtractSurfFrChunkLoops( nSurfId, 0, nGrpTmp) + for i = 1, #vBisectors do + local nCrv, nCnt = EgtTrimCurveWithRegion( vBisectors[i], nSurfId, true, false) + if nCrv and nCnt == 1 then + local dParS = EgtCurveParamAtPoint( nCrvBorder, EgtSP( nCrv), 100 * GEO.EPS_SMALL) + local dParE = EgtCurveParamAtPoint( nCrvBorder, EgtEP( nCrv), 100 * GEO.EPS_SMALL) + EgtTrimCurveStartEndAtParam( nCrvBorder, dParE, dParS) + EgtAddCurveCompoCurve( nCrvBorder, nCrv) + end + + end + nSurfId = EgtSurfFlatRegion( nGrpTmp, nCrvBorder) + end + + EgtRelocateGlob( nSurfId, nGrp) + EgtErase( nGrpTmp) + return nSurfId +end + +--------------------------------------------------------------------- -- funzione che dato il tipo di pezzo e di giunzione, restituisce se e' corto, lungo o angolato local function CalcPartJointType( nProfileType, JointType) @@ -1897,12 +2113,13 @@ local function GetDeltaProfile( nProfileId, sCtrIn) end --------------------------------------------------------------------- -local function CheckSemiprofileIntersection( nGeoId, nProfileId, nPrevGeoId, nNextGeoId) +local function CheckSemiprofileIntersection( nGeoId, nPrevGeoId, nNextGeoId) local nOutlineId = EgtGetInfo( nGeoId, WIN_REF_OUTLINE, 'i') -- recupero la curva più interna del semiprofilo local nSemiProfileId = EgtGetInfo( nGeoId, WIN_SEMI_PROFILE, 'i') + local nProfileId = EgtGetParent( nSemiProfileId) local nFrameId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME) local frFrame = EgtFR( nFrameId) local b3Box = EgtGetBBoxRef( nSemiProfileId, GDB_BB.STANDARD, frFrame) @@ -1930,48 +2147,56 @@ end --------------------------------------------------------------------- -- funzione che stabilisce il tipo di estensione ( standard seguendo la circonferenza o lineare in tangenza) per curve del geo ad arco in base a condizioni euristiche per evitare giunzioni -- problematiche -local function ComputeArcExtensions( nOutId, nInId, nCurrProfileId, vLeftIds, vLeftProfileIds, vRightIds, vRightProfileIds) +local function ComputeArcExtensions( nOutId, nInId, vLeftIds, vRightIds, nStartJoint, nEndJoint) -- 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 il pezzo corrente è arco devo verificare estensione per in e out if EgtGetType( nOutId) == GDB_TY.CRV_ARC then - + -- in : la curva più interna del semiprofilo associato è la curva in stessa - if FindIntersectionPoint( nInId, vRightIds[#vRightIds], ORIG()) then - EgtSetInfo( nInId, WIN_TANG_START, false) - else + if nEndJoint == WIN_PART_JNT.ANGLED or not FindIntersectionPoint( nInId, vRightIds[#vRightIds], ORIG()) then EgtSetInfo( nInId, WIN_TANG_START, true) - end - if FindIntersectionPoint( nInId, vLeftIds[1], ORIG()) then - EgtSetInfo( nInId, WIN_TANG_END, false) else + EgtSetInfo( nInId, WIN_TANG_START, false) + end + if nStartJoint == WIN_PART_JNT.ANGLED or not FindIntersectionPoint( nInId, vLeftIds[1], ORIG()) then EgtSetInfo( nInId, WIN_TANG_END, true) + else + EgtSetInfo( nInId, WIN_TANG_END, false) end -- out - CheckSemiprofileIntersection( nOutId, nCurrProfileId, vLeftIds[#vLeftIds], vRightIds[1]) + CheckSemiprofileIntersection( nOutId, vLeftIds[#vLeftIds], vRightIds[1]) + if nStartJoint == WIN_PART_JNT.ANGLED then + EgtSetInfo( nOutId, WIN_TANG_START, true) + end + if nEndJoint == WIN_PART_JNT.ANGLED then + EgtSetInfo( nOutId, WIN_TANG_END, true) + end + end -- verifico estensione left for i = 1, #vLeftIds do if EgtGetType( vLeftIds[i]) == GDB_TY.CRV_ARC then - CheckSemiprofileIntersection( vLeftIds[i], vLeftProfileIds[i], nInId, nOutId) + CheckSemiprofileIntersection( vLeftIds[i], nInId, nOutId) end end -- verifico estensione right for i = 1, #vRightIds do if EgtGetType( vRightIds[i]) == GDB_TY.CRV_ARC then - CheckSemiprofileIntersection( vRightIds[i], vRightProfileIds[i], nOutId, nInId) + CheckSemiprofileIntersection( vRightIds[i], nOutId, nInId) end end end --------------------------------------------------------------------- -- funzione che crea le curve del geo -local function CreateFrameGeo( nOutlineId, vPrevOutlineId, vNextOutlineId, nStartPartJointType, nEndPartJointType, nGeoLayerId, nProfileLayerId) +local function CreateGeoCurves( nOutlineId, vPrevOutlineId, vNextOutlineId, nStartPartJointType, nEndPartJointType, nGeoLayerId, nProfileLayerId) local nCurrProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN) -- calcolo spostamento della curva iniziale dovuto a posizione riferimento @@ -2001,72 +2226,134 @@ local function CreateFrameGeo( nOutlineId, vPrevOutlineId, vNextOutlineId, nStar EgtSetName( nInId, WIN_GEO_IN) local nSemiProfileIn = EgtGetFirstNameInGroup( nCurrProfileId, WIN_IN) or EgtGetFirstNameInGroup( nCurrProfileId, WIN_IN .. '2') or EgtGetFirstNameInGroup( nCurrProfileId, WIN_MIXED_COMMON .. WIN_IN) EgtSetInfo( nInId, WIN_SEMI_PROFILE, nSemiProfileIn) - EgtSetInfo( nInId, WIN_REF_OUTLINE, nOutlineId) - EgtSetInfo( nInId, WIN_GEO_OFFS, dCurrOffset - b3CurrProfileFrame:getDimX()) + EgtSetInfo( nInId, WIN_REF_OUTLINE, - nOutlineId) + EgtSetInfo( nInId, WIN_GEO_OFFS, - dCurrOffset + b3CurrProfileFrame:getDimX()) + -- curve left local vPrevProfileId = EgtGetNameInGroup( nProfileLayerId, WIN_PRF_START) for i = 1, #vPrevOutlineId do - local nPrevCurveId - local nPrevSemiProfile + if nStartPartJointType == WIN_PART_JNT.ANGLED then - -- calcolo la bisettrice - local vtMedia = ( ( EgtSV( nOutlineId) - EgtEV( abs( vPrevOutlineId[i]))) / 2) - if not vtMedia:normalize() then - vtMedia = EgtSV( nOutlineId) - vtMedia:rotate( Z_AX(), 90) + + -- recupero bordo out dell'altro pezzo ( non è detto coincida con l'outline) + local b3Profile = GetProfileLocalBox( vPrevProfileId[i]) + local nOtherOut = EgtCopyGlob( vPrevOutlineId[i], nGeoLayerId) + EgtOffsetCurve( nOtherOut, b3Profile:getMax():getX()) + + -- a) calcolo bisettore: se pezzi lineari o in tangenza è segmento, altrimenti è tratto di parabola + local nBisector + if ( EgtGetType( nOutlineId) == GDB_TY.CRV_LINE and EgtGetType( vPrevOutlineId[i]) == GDB_TY.CRV_LINE) or + EgtEV( vPrevOutlineId[i]) * EgtSV( nOutlineId) > 0.95 or + EgtGetName( nOutlineId) == EgtGetName( vPrevOutlineId[i]) then + + local nOtherIn = EgtCopyGlob( vPrevOutlineId[i], nGeoLayerId) + EgtOffsetCurve( nOtherIn, b3Profile:getMin():getX()) + local ptInt1 = FindIntersectionPoint( nOutId, nOtherOut, EgtSP( nOutId)) + local ptInt2 = FindIntersectionPoint( nInId, nOtherIn, EgtSP( nInId)) + EgtErase( nOtherIn) + nBisector = EgtLine( nGeoLayerId, ptInt2, ptInt1) + else + nBisector = CalcParabolicBisector( nOtherOut, nOutId, b3Profile:getDimX(), nGeoLayerId) + EgtInvertCurve( nBisector) end - nPrevCurveId = EgtLinePVL( nGeoLayerId, EgtSP( nOutlineId), vtMedia, 3 * b3CurrProfileFrame:getDimX()) - EgtInvertCurve( nPrevCurveId) + EgtSetName( nBisector, WIN_GEO_LEFT) + EgtRelocateGlob( nBisector, nGeoLayerId, GDB_IN.LAST_SON) + + -- b) se profili diversi per taglio corretto dei profili serve considerare anche il bordo out del pezzo adiacente + local sCurrProfile = EgtGetInfo( nCurrProfileId, WIN_PRF_TYPE) + local sPrevProfile = EgtGetInfo( vPrevProfileId[i], WIN_PRF_TYPE) + if sCurrProfile ~= sPrevProfile then + EgtSetName( nOtherOut, WIN_GEO_LEFT) + EgtRelocateGlob( nOtherOut, nGeoLayerId, GDB_IN.LAST_SON) + local nSemiProfileId = EgtGetFirstNameInGroup( vPrevProfileId[i], WIN_OUT) + EgtSetInfo( nOtherOut, WIN_SEMI_PROFILE, nSemiProfileId) + EgtSetInfo( nOtherOut, WIN_REF_OUTLINE, vPrevOutlineId[i]) + EgtSetInfo( nOtherOut, WIN_GEO_OFFS, b3Profile:getMax():getX()) + else + -- considero la curva out come curva ausiliaria per il calcolo del geo + EgtSetName( nOtherOut, WIN_AUX) + end + else - nPrevCurveId = EgtCopy( abs( vPrevOutlineId[i]), nGeoLayerId) + local nPrevCurveId = EgtCopy( abs( vPrevOutlineId[i]), nGeoLayerId) if vPrevOutlineId[i] < 0 then EgtInvertCurve( nPrevCurveId) end - local dOffs + local dOffs, nPrevSemiProfile if nStartPartJointType == 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) dOffs = - dCPDelta nPrevSemiProfile = EgtGetFirstNameInGroup( vPrevProfileId[i], sCtrIn) else + -- la curva del geo corrisponde all'out del pezzo vicino local b3Profile = GetProfileLocalBox( vPrevProfileId[i]) dOffs = b3Profile:getMax():getX() nPrevSemiProfile = EgtGetFirstNameInGroup( vPrevProfileId[i], WIN_OUT) end EgtOffsetCurve( nPrevCurveId, dOffs) EgtSetInfo( nPrevCurveId, WIN_GEO_OFFS, dOffs) + EgtSetInfo( nPrevCurveId, WIN_SEMI_PROFILE, nPrevSemiProfile) + EgtSetInfo( nPrevCurveId, WIN_REF_OUTLINE, vPrevOutlineId[i]) + EgtSetName( nPrevCurveId, WIN_GEO_LEFT) + EgtRelocateGlob( nPrevCurveId, nGeoLayerId, GDB_IN.LAST_SON) end - EgtSetName( nPrevCurveId, WIN_GEO_LEFT) - EgtSetInfo( nPrevCurveId, WIN_SEMI_PROFILE, nPrevSemiProfile) - EgtSetInfo( nPrevCurveId, WIN_REF_OUTLINE, vPrevOutlineId[i]) - EgtRelocateGlob( nPrevCurveId, nGeoLayerId, GDB_IN.LAST_SON) end -- curve right local vNextProfileId = EgtGetNameInGroup( nProfileLayerId, WIN_PRF_END) for i = 1, #vNextOutlineId do - local nNextCurveId - local nNextSemiProfile + if nEndPartJointType == WIN_PART_JNT.ANGLED then - -- calcolo la bisettrice - local vtMedia = ( ( EgtSV( abs( vNextOutlineId[i])) - EgtEV( nOutlineId)) / 2) - if not vtMedia:normalize() then - vtMedia = EgtEV( nOutlineId) - vtMedia:rotate( Z_AX(), 90) + + local b3Profile = GetProfileLocalBox( vNextProfileId[i]) + local nOtherOut = EgtCopyGlob( vNextOutlineId[i], nGeoLayerId) + EgtOffsetCurve( nOtherOut, b3Profile:getMax():getX()) + + -- calcolo bisettore + local nBisector + if ( EgtGetType( nOutlineId) == GDB_TY.CRV_LINE and EgtGetType( vNextOutlineId[i]) == GDB_TY.CRV_LINE) or + EgtEV( nOutlineId) * EgtSV( vNextOutlineId[i]) > 0.95 or + EgtGetName( nOutlineId) == EgtGetName( vNextOutlineId[i]) then + + local nOtherIn = EgtCopyGlob( vNextOutlineId[i], nGeoLayerId) + EgtOffsetCurve( nOtherIn, b3Profile:getMin():getX()) + local ptInt1 = FindIntersectionPoint( nOutId, nOtherOut, EgtEP( nOutId)) + local ptInt2 = FindIntersectionPoint( nInId, nOtherIn, EgtEP( nInId)) + EgtErase( nOtherIn) + nBisector = EgtLine( nGeoLayerId, ptInt1, ptInt2) + else + nBisector = CalcParabolicBisector( nOutId, nOtherOut, b3Profile:getDimX(), nGeoLayerId) end - nNextCurveId = EgtLinePVL( nGeoLayerId, EgtEP( nOutlineId), vtMedia, 3 * b3CurrProfileFrame:getDimX()) + EgtSetName( nBisector, WIN_GEO_RIGHT) + EgtRelocateGlob( nBisector, nInId, GDB_IN.BEFORE) + + -- gestione per profili diversi + local sCurrProfile = EgtGetInfo( nCurrProfileId, WIN_PRF_TYPE) + local sNextProfile = EgtGetInfo( vNextProfileId[i], WIN_PRF_TYPE) + if sCurrProfile ~= sNextProfile then + EgtSetName( nOtherOut, WIN_GEO_RIGHT) + local nSemiProfileId = EgtGetFirstNameInGroup( vNextProfileId[i], WIN_OUT) + EgtSetInfo( nOtherOut, WIN_SEMI_PROFILE, nSemiProfileId) + EgtSetInfo( nOtherOut, WIN_REF_OUTLINE, vNextOutlineId[i]) + EgtSetInfo( nOtherOut, WIN_GEO_OFFS, b3Profile:getMax():getX()) + EgtRelocateGlob( nOtherOut, nInId, GDB_IN.BEFORE) + else + EgtSetName( nOtherOut, WIN_AUX) + end + else - nNextCurveId = EgtCopy( abs( vNextOutlineId[i]), nGeoLayerId) + local nNextCurveId = EgtCopy( abs( vNextOutlineId[i]), nGeoLayerId) if vNextOutlineId[i] < 0 then EgtInvertCurve( nNextCurveId) end - local dOffs + local dOffs, nNextSemiProfile if nEndPartJointType == WIN_PART_JNT.SHORT then local sCtrIn = GetProfileCtrIn( abs( vNextOutlineId[i]), nOutlineId, vNextProfileId[i]) local dCPDelta = GetDeltaProfile( vNextProfileId[i], sCtrIn) dOffs = - dCPDelta - -- ricavo il semiprofilo associato nNextSemiProfile = EgtGetFirstNameInGroup( vNextProfileId[i], sCtrIn) else local b3Profile = GetProfileLocalBox( vNextProfileId[i]) @@ -2075,29 +2362,34 @@ local function CreateFrameGeo( nOutlineId, vPrevOutlineId, vNextOutlineId, nStar end EgtOffsetCurve( nNextCurveId, dOffs) EgtSetInfo( nNextCurveId, WIN_GEO_OFFS, dOffs) + EgtSetInfo( nNextCurveId, WIN_SEMI_PROFILE, nNextSemiProfile) + EgtSetInfo( nNextCurveId, WIN_REF_OUTLINE, vNextOutlineId[i]) + EgtSetName( nNextCurveId, WIN_GEO_RIGHT) + EgtRelocateGlob( nNextCurveId, nInId, GDB_IN.BEFORE) end - EgtSetName( nNextCurveId, WIN_GEO_RIGHT) - EgtSetInfo( nNextCurveId, WIN_SEMI_PROFILE, nNextSemiProfile) - EgtSetInfo( nNextCurveId, WIN_REF_OUTLINE, vNextOutlineId[i]) - EgtRelocateGlob( nNextCurveId, nInId, GDB_IN.BEFORE) end -- verifico se necessaria estensione in tangenza per pezzi ad arco local vLeftIds = EgtGetNameInGroup( nGeoLayerId, WIN_LEFT) local vRightIds = EgtGetNameInGroup( nGeoLayerId, WIN_RIGHT) - ComputeArcExtensions( nOutId, nInId, nCurrProfileId, vLeftIds, vPrevProfileId, vRightIds, vNextProfileId) - - -- trim delle curve + ComputeArcExtensions( nOutId, nInId, vLeftIds, vRightIds, nStartPartJointType, nEndPartJointType) + + -- costruisco la superficie local vIds = EgtGetAllInGroup( nGeoLayerId) - local vMainCrvs = TrimOrderedCurves( vIds, 2) - - -- costruisco la regione - local nCompoId = EgtCurveCompo( nGeoLayerId, vMainCrvs, false) - local nAreaId = EgtSurfFlatRegion( nGeoLayerId, nCompoId) + local nAreaId = CalcGeoRegion( vIds, nGeoLayerId) EgtSetName( nAreaId, WIN_GEO_SURF) EgtSetStatus( nAreaId, GDB_ST.OFF) - EgtErase( nCompoId) - + -- elimino curve aux + local vCrvs = {} + for i = 1, #vIds do + if EgtGetName( vIds[i]) == WIN_AUX then + EgtErase( vIds[i]) + else + table.insert( vCrvs, vIds[i]) + end + end + TrimOrderedCurves( vCrvs, 2, nAreaId) + -- assegno spessore local dGeoH = b3CurrProfileFrame:getDimY() EgtModifyCurveThickness( vIds, - dGeoH) @@ -2118,7 +2410,7 @@ end --------------------------------------------------------------------- -- funzione che calcola l'ingombro dei pezzi del telaio -local function CalcFrameGeo( nPartId, nOutlineId, nOutlineCrvNbr, nOutlineLayerId, nProfileType, nBottomRail) +local function CalcGeo( nPartId, nOutlineId, nOutlineCrvNbr, nOutlineLayerId, nProfileType, nBottomRail) -- creo layer per ingombro local nGeoLayerId = EgtGroup( nPartId) @@ -2196,7 +2488,7 @@ local function CalcFrameGeo( nPartId, nOutlineId, nOutlineCrvNbr, nOutlineLayerI local nProfileLayerId = CalcProfiles( nPartId, nOutlineId, vPrevOutlineId, vNextOutlineId, nProfileType, nBottomRail) -- creo lati dell'outline - CreateFrameGeo( nOutlineId, vPrevOutlineId, vNextOutlineId, nStartPartJointType, nEndPartJointType, nGeoLayerId, nProfileLayerId) + CreateGeoCurves( nOutlineId, vPrevOutlineId, vNextOutlineId, nStartPartJointType, nEndPartJointType, nGeoLayerId, nProfileLayerId) end @@ -2686,16 +2978,26 @@ local function CreateProfilingProcessingCurve( nGeoCrvId, nPrevGeo, nNextGeo, nS -- aggiusto la lunghezza per assicurarmi che la lavorazione sia completa if nSemiProfileId and not ( AreSameVectorApprox( EgtSV( nCrvId), EgtEV( nPrevGeo)) and AreSameVectorApprox( EgtEV( nCrvId), EgtSV( nNextGeo))) then - -- calcolo la curva di lavorazione interna + -- calcolo la curva di lavorazione interna : + -- dall'outline ricalcolo la curva del geo ( per essere allineati con l'info di estensione) + local nOutlineId = EgtGetInfo( nGeoCrvId, WIN_REF_OUTLINE, 'i') + local nOrigInnerProcId = EgtCopyGlob( abs( nOutlineId), nProcLayerId) + if nOutlineId < 0 then + EgtInvertCurve( nOrigInnerProcId) + end + local dGeoOffs = EgtGetInfo( nGeoCrvId, WIN_GEO_OFFS, 'd') + EgtOffsetCurve( nOrigInnerProcId, dGeoOffs) + -- ricavo l'offset per trovare la curva interna local nProfileId = EgtGetParent( nSemiProfileId) local nFrameId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME) local frFrame = EgtFR( nFrameId, GDB_ID.ROOT) local b3SemiProfile = EgtGetBBoxRef( nSemiProfileId, GDB_BB.STANDARD, frFrame, GDB_RT.GLOB) local dOffs = b3SemiProfile:getDimX() - local nOrigInnerProcId = EgtCopyGlob( nCrvId, nProcLayerId) EgtOffsetCurve( nOrigInnerProcId, - dOffs) -- adatto la curva di lavorazione interna al pezzo + CopyInfo( nOrigInnerProcId, nGeoCrvId, WIN_TANG_START, false) + CopyInfo( nOrigInnerProcId, nGeoCrvId, WIN_TANG_END, false) local nInnerProcId = CreateCurveExtension( nOrigInnerProcId, nProcLayerId) local nNewId, nCnt = EgtTrimCurveWithRegion( nInnerProcId, nSurfGeo, true, false) @@ -2703,7 +3005,6 @@ local function CreateProfilingProcessingCurve( nGeoCrvId, nPrevGeo, nNextGeo, nS nCnt = 0 end if nCnt > 0 then - -- se ottengo più tratti considero quello che ha porzione in comune con la curva non estesa if nCnt > 1 and AreSamePointApprox( EgtSP( nNewId), EgtEP( nNewId + nCnt - 1)) then if EgtGetType( nNewId) == GDB_TY.CRV_ARC then EgtModifyCurveStartPoint( nNewId, EgtSP( nNewId + nCnt - 1)) @@ -2713,18 +3014,22 @@ local function CreateProfilingProcessingCurve( nGeoCrvId, nPrevGeo, nNextGeo, nS end nCnt = nCnt - 1 end + -- se ottengo più tratti considero quello che ha porzione in comune con la curva del geo ( garantisce risultati migliori dell'outline perchè più limitata) if nCnt > 1 then + local nTestOverlap = EgtCopyGlob( nGeoCrvId, nProcLayerId) + EgtOffsetCurve( nTestOverlap, - dOffs) local bFound = false for nId = nNewId, nNewId + nCnt - 1 do if bFound then EgtErase( nId) - elseif CheckExtensionOverlap( nId, nOrigInnerProcId) then + elseif CheckExtensionOverlap( nId, nTestOverlap) then nNewId = nId bFound = true else EgtErase( nId) end end + EgtErase( nTestOverlap) end -- la allineo alla curva di lavoro @@ -2773,7 +3078,7 @@ local function CalcProfilingProcessings( nPartId, nOutlineId) local nProcLayerId = EgtGroup( nPartId) EgtSetName( nProcLayerId, WIN_PRC) EgtSetStatus( nProcLayerId, GDB_ST.OFF) - + -- recupero il geo e la superficie associata per limitare le lavorazioni local nGeoLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO) local vGeoCrvs = EgtGetAllInGroup( nGeoLayerId) @@ -3018,24 +3323,25 @@ local function CalcSolidGuide( nOutlineId, nSolidLayerId, nProfileId) local nProcLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PRC) local nPrcIn = EgtGetFirstNameInGroup( nProcLayerId, WIN_GEO_IN) local nInId = EgtCopyGlob( nPrcIn, nSolidLayerId) + EgtInvertCurve( nInId) -- riporto la curva di lavorazione allineata all'outline local nGeoLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO) local nGeoIn = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_IN) local dOffsIn = EgtGetInfo( nGeoIn, WIN_GEO_OFFS, 'd') or 0 EgtOffsetCurve( nInId, dOffsIn) - EgtInvertCurve( nInId) + -- aggiungo tratti di estensione se necessari - local dParS = EgtCurveParamAtPoint( nGuideId, EgtSP( nInId)) + local dParS = EgtCurveParamAtPoint( nGuideId, EgtSP( nInId), 100 * GEO.EPS_SMALL) if not dParS then - local dParTrim = EgtCurveParamAtPoint( nInId, EgtSP( nGuideId)) + local dParTrim = EgtCurveParamAtPoint( nInId, EgtSP( nGuideId), 100 * GEO.EPS_SMALL) local nNewCrv = EgtCopyGlob( nInId, nSolidLayerId) EgtTrimCurveEndAtParam( nNewCrv, dParTrim) EgtAddCurveCompoCurve( nGuideId, nNewCrv, true, false) end - local dParE = EgtCurveParamAtPoint( nGuideId, EgtEP( nInId)) + local dParE = EgtCurveParamAtPoint( nGuideId, EgtEP( nInId), 100 * GEO.EPS_SMALL) if not dParE then - local dParTrim = EgtCurveParamAtPoint( nInId, EgtEP( nGuideId)) + local dParTrim = EgtCurveParamAtPoint( nInId, EgtEP( nGuideId), 100 * GEO.EPS_SMALL) local nNewCrv = EgtCopyGlob( nInId, nSolidLayerId) EgtTrimCurveStartAtParam( nNewCrv, dParTrim) EgtAddCurveCompoCurve( nGuideId, nNewCrv) @@ -3044,7 +3350,7 @@ local function CalcSolidGuide( nOutlineId, nSolidLayerId, nProfileId) -- piccola estensione per avere un po' di margine dal minimo indispensabile appena calcolato EgtExtendCurveStartByLen( nGuideId, 5) EgtExtendCurveEndByLen( nGuideId, 5) - + EgtErase( nInId) end @@ -3248,6 +3554,7 @@ local function CalcSolid( nPartId, nOutlineId) local nGuideId = CalcSolidGuide( nOutlineId, nSolidLayerId, nMainProfileId) local sSection = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. WIN_SECTION local nMainExtrusionId = CreateMainSurf( nGuideId, nMainProfileId, sSection, nSolidLayerId) + -- creo una copia ( usata per calcolo ferramenta) local nOrigMainExtrusionId = EgtCopy( nMainExtrusionId, nSolidLayerId) EgtSetName( nOrigMainExtrusionId, WIN_SRF_ORIGMAIN) @@ -3273,7 +3580,7 @@ local function CalcSolid( nPartId, nOutlineId) for i = 1, #vChains do local nTrimSurf if #vChains[i] == 1 then - local nRefOutlineId = EgtGetInfo( vChains[i][1], WIN_REF_OUTLINE, 'i') + local nRefOutlineId = EgtGetInfo( vChains[i][1], WIN_REF_OUTLINE, 'i') or GDB_ID.NULL nTrimSurf = CreateTrimSurf( vChains[i][1], abs( nRefOutlineId), dGeoWidth, nSolidLayerId) -- assegno alla curva del geo la superficie di trim creata EgtSetInfo( vChains[i][1], WIN_REF_SURF, nTrimSurf) @@ -3281,7 +3588,7 @@ local function CalcSolid( nPartId, nOutlineId) -- costruisco la guida a partire dagli outlines local vRefOutlineIds = {} for j = 1, #vChains[i] do - local nCurrOutline = EgtGetInfo( vChains[i][j], WIN_REF_OUTLINE, 'i') + local nCurrOutline = EgtGetInfo( vChains[i][j], WIN_REF_OUTLINE, 'i') or GDB_ID.NULL -- verifico di non inserire un outline doppio if j == 1 or nCurrOutline ~= vRefOutlineIds[#vRefOutlineIds] then table.insert( vRefOutlineIds, abs( nCurrOutline)) @@ -4455,7 +4762,7 @@ local function CreatePartFromOutline( nAreaLayerId, sName, nOutlineId, nOutlineC -- ricavo il tipo di profilo local nProfileType = GetOutlineProfileType( nOutlineId, false, nBottomRail) -- disegno ingombro - CalcFrameGeo( nPartId, nOutlineId, nOutlineCrvNbr, nOutlineLayerId, nProfileType, nBottomRail) + CalcGeo( nPartId, nOutlineId, nOutlineCrvNbr, nOutlineLayerId, nProfileType, nBottomRail) -- calcolo eventuali curve ausiliarie per cambio profilo local bChangeProfile = EgtGetInfo( nOutlineId, WIN_PRF_CHANGE, 'b') or false if bChangeProfile and nProfileType ~= WIN_PRF.SPLIT then @@ -4467,8 +4774,8 @@ local function CreatePartFromOutline( nAreaLayerId, sName, nOutlineId, nOutlineC CalcGeoRaw( nPartId, nOutlineId) -- disegno solido if s_bCalcSolid then - CalcSolid( nPartId, nOutlineId) - end + CalcSolid( nPartId, nOutlineId) + end -- b) Fill elseif nAreaType == WIN_AREATYPES.FILL then @@ -5431,7 +5738,7 @@ local function DrawHandlePreview( nOutlineId, sHandleSide, dHandleH, nLayerId, b local nProfileLayId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE) local nMainProfileId = EgtGetFirstNameInGroup( nProfileLayId, WIN_PRF_MAIN) local b3Profile = GetProfileLocalBox( nMainProfileId) - local dSide = 0.5 * b3Profile:getDimX() + local dSide = 0.33 * b3Profile:getDimX() -- punto su cui centrare la maniglia local ptC = ptRef - dHandleH * vtDir + dSide * vtDirIn + Z_AX() @@ -6694,117 +7001,233 @@ local function CalcBottomRailPreview( nPreviewGrp, nOutlineId, nBottomRail, nGeo EgtErase( vCrvs) end +---------------------------------------------------------------------------------- +local function GetBorderFromAdjacentSash( nOutlineId, nGrpId) + -- recupero l'anta active adiacente + local nBaseOutlineId = EgtGetInfo( nOutlineId, WIN_COPY, 'i') + local nSouId = EgtGetInfo( nBaseOutlineId, WIN_SOU, 'i') + local vChildrenIds = EgtGetInfo( nSouId, WIN_CHILD, 'vi') + local nActiveChildId = EgtIf( vChildrenIds[1] == nBaseOutlineId, vChildrenIds[2], vChildrenIds[1]) + -- recupero il suo geo out + local nActiveOutlineId = EgtGetInfo( nActiveChildId, WIN_COPY, 'i') + local nActivePartId = EgtGetInfo( nActiveOutlineId, WIN_REF_PART, 'i') + local nActiveGeoId = EgtGetFirstNameInGroup( nActivePartId, WIN_GEO) + local nActiveOutId = EgtGetFirstNameInGroup( nActiveGeoId, WIN_GEO_OUT) + + local nCrvId = EgtCopyGlob( nActiveOutId, nGrpId) + EgtInvertCurve( nCrvId) + return nCrvId +end + ---------------------------------------------------------------------------------- local function CalcPartPreview( nPartId, nPreviewGrp) - local nAreaId - local nOutlineId = EgtGetInfo( nPartId, WIN_REF_OUTLINE, 'i') - local nGeoGrp = EgtGetFirstNameInGroup( nPartId, WIN_GEO) + local nGeoLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO) - -- verifico se è anta con elemento su french split per evitare sovrapposizione tra i pezzi + -- verifico se è anta con parti contro anta active local nParentAreaId = EgtGetParent( EgtGetParent( nOutlineId)) - local nSashType = EgtGetInfo( nParentAreaId, WIN_SASHTYPE, 'i') or WIN_SASHTYPES.NULL - local bSpecialSash = ( nSashType ~= WIN_SASHTYPES.NULL) + local nSashType = EgtGetInfo( nParentAreaId, WIN_SASHTYPE, 'i') + local bInactiveSash = ( nSashType == WIN_SASHTYPES.INACTIVE or nSashType == WIN_SASHTYPES.INACTIVE_IN or nSashType == WIN_SASHTYPES.INACTIVE_OUT or nSashType == WIN_SASHTYPES.ACTIVE_OUT) - -- recupero il tipo di giunzione + -- recupero il tipo di giunzioni local nStartJoint = EgtGetInfo( nOutlineId, WIN_STARTJOINT, 'i') local nEndJoint = EgtGetInfo( nOutlineId, WIN_ENDJOINT, 'i') - -- se non ha giunzioni short e non è active/inactive come preview posso considerare direttamente la regione del geo - if nStartJoint ~= WIN_PART_JNT.SHORT and nEndJoint ~= WIN_PART_JNT.SHORT and not bSpecialSash then - local nGeoSurf = EgtGetFirstNameInGroup( nGeoGrp, WIN_GEO_SURF) + local nAreaId + + -- se non ha giunzioni short e non è inactive come preview posso considerare direttamente la regione del geo + if nStartJoint ~= WIN_PART_JNT.SHORT and nEndJoint ~= WIN_PART_JNT.SHORT and not bInactiveSash then + local nGeoSurf = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_SURF) nAreaId = EgtCopyGlob( nGeoSurf, nPreviewGrp) EgtSetStatus( nAreaId, GDB_ST.ON) - -- altrimenti devi calcolare le curve che delimitano la regione + -- altrimenti devo calcolare le curve che delimitano la regione ( in modo simile a quanto fatto in CreateGeoCurves) else - -- gruppo temporaneo per i conti + local nGrpTmp = EgtGroup( nPreviewGrp) - -- curva out è il geo out tranne nel caso di sash active/inactive per le quali considero l'outline per evitare sovrapposizioni - local nBaseOutlineId = EgtGetInfo( nOutlineId, WIN_COPY, 'i') - local bOnSplit = EgtGetInfo( nBaseOutlineId, WIN_CRV_ON_FRENCH_SPLIT, 'b') - if bOnSplit then - EgtCopyGlob( nOutlineId, nGrpTmp) + local nProfileLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE) + local nProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN) + local b3Profile = GetProfileLocalBox( nProfileId) + + -- a) curva out : se outline è split di anta inactive considero il bordo del pezzo active, altrimenti ricalcolo curva del geo ( non posso utilizzare direttamente quella + -- del geo perchè non deve avere estensioni) + local sProfileType = EgtGetInfo( nProfileId, WIN_PRF_TYPE) + if sProfileType == WIN_SASH_INACTIVE or sProfileType == WIN_FRENCH_OUT then + GetBorderFromAdjacentSash( nOutlineId, nGrpTmp) else - local nGeoOut = EgtGetFirstNameInGroup( nGeoGrp, WIN_GEO_OUT) - EgtCopyGlob( nGeoOut, nGrpTmp) + local nOutId = EgtCopy( nOutlineId, nGrpTmp) + EgtOffsetCurve( nOutId, b3Profile:getMax():getX()) + local nGeoOut = EgtGetFirstNameInGroup( nGeoLayerId, WIN_OUT) + CopyInfo( nOutId, nGeoOut, WIN_TANG_START, false) + CopyInfo( nOutId, nGeoOut, WIN_TANG_END, false) end - - -- curva right - local vGeoRight = EgtGetNameInGroup( nGeoGrp, WIN_GEO_RIGHT) - for i = 1, #vGeoRight do - local nNextOutline = EgtGetInfo( vGeoRight[i], WIN_REF_OUTLINE, 'i') - if nEndJoint == WIN_PART_JNT.SHORT then - -- se giunzione short per evitare sovrapposizioni devo fermare al geo in del pezzo adiacente - local nNextPart = FindAssociatedPart( abs( nNextOutline), EgtGetName( nOutlineId) == WIN_SPLIT) - local nNextGeo = EgtGetFirstNameInGroup( nNextPart, WIN_GEO) - local nNextCrv = EgtGetFirstNameInGroup( nNextGeo, EgtIf( nNextOutline > 0, WIN_GEO_IN, WIN_GEO_OUT)) - local nCrv = EgtCopyGlob( nNextCrv, nGrpTmp) - EgtInvertCurve( nCrv) - -- per evitare casi problematici di assenza di intersezione forzo estensione in tangenza - EgtSetInfo( nCrv, WIN_TANG_START, true) - EgtSetInfo( nCrv, WIN_TANG_END, true) - - else - -- se guinzione full utilizzo la curva del geo o la curva di outline se si tratta di curva di french split ( la curva del geo si sovrapporrebbe a quella dell'anta adiacente) - local nBaseOutlineId = EgtGetInfo( abs( nNextOutline), WIN_COPY, 'i') - local bOnSplit = EgtGetInfo( nBaseOutlineId, WIN_CRV_ON_FRENCH_SPLIT, 'b') - if bOnSplit then - EgtCopyGlob( abs( nNextOutline), nGrpTmp) - else - EgtCopyGlob( vGeoRight[i], nGrpTmp) - end - end - end - - -- curva in - local nGeoIn = EgtGetFirstNameInGroup( nGeoGrp, WIN_GEO_IN) - EgtCopyGlob( nGeoIn, nGrpTmp) - - -- curva left - local vGeoLeft = EgtGetNameInGroup( nGeoGrp, WIN_LEFT) - for i = 1, #vGeoLeft do - local nPrevOutline = EgtGetInfo( vGeoLeft[i], WIN_REF_OUTLINE, 'i') - if nStartJoint == WIN_PART_JNT.SHORT then - local nPrevPart = FindAssociatedPart( abs( nPrevOutline), EgtGetName( nOutlineId) == WIN_SPLIT) - local nPrevGeo = EgtGetFirstNameInGroup( nPrevPart, WIN_GEO) - local nPrevCrv = EgtGetFirstNameInGroup( nPrevGeo, EgtIf( nPrevOutline > 0, WIN_GEO_IN, WIN_GEO_OUT)) - local nCrv = EgtCopyGlob( nPrevCrv, nGrpTmp) - EgtInvertCurve( nCrv) - EgtSetInfo( nCrv, WIN_TANG_START, true) - EgtSetInfo( nCrv, WIN_TANG_END, true) + + -- b) curva in + local nInId = EgtCopy( nOutlineId, nGrpTmp) + EgtOffsetCurve( nInId, b3Profile:getMin():getX()) + EgtInvertCurve( nInId) + local nGeoIn = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_IN) + CopyInfo( nInId, nGeoIn, WIN_TANG_START, false) + CopyInfo( nInId, nGeoIn, WIN_TANG_END, false) + -- c) curve left + 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 + + -- recupero la bisettrice dal geo + EgtCopyGlob( vGeoLeft[1], nGrpTmp) + + -- curva aux : nel caso di curva su split french con anta inactive considero il bordo del pezzo active, altrimenti considero l'out del pezzo precedente + local sProfileType = EgtGetInfo( vPrevProfileId[1], WIN_PRF_TYPE) + if sProfileType == WIN_SASH_INACTIVE or sProfileType == WIN_FRENCH_OUT then + GetBorderFromAdjacentSash( abs( vPrevOutlineId[1]), nGrpTmp) else - local nBaseOutlineId = EgtGetInfo( abs( nPrevOutline), WIN_COPY, 'i') - local bOnSplit = EgtGetInfo( nBaseOutlineId, WIN_CRV_ON_FRENCH_SPLIT, 'b') - if bOnSplit then - EgtCopyGlob( abs( nPrevOutline), nGrpTmp) - else - EgtCopyGlob( vGeoLeft[i], nGrpTmp) + local nCrvId = EgtCopyGlob( abs( vPrevOutlineId[1]), nGrpTmp) + local b3Profile = GetProfileLocalBox( vPrevProfileId[1]) + EgtOffsetCurve( nCrvId, b3Profile:getMax():getX()) + end + + else + for i = 1, #vPrevOutlineId do + if nStartJoint == WIN_PART_JNT.SHORT then + local b3Profile = GetProfileLocalBox( vPrevProfileId[i]) + local nCrvId = EgtCopy( abs( vPrevOutlineId[i]), nGrpTmp) + local dRailDelta = EgtGetInfo( vPrevProfileId[i], WIN_RAILDELTA, 'd') or 0 + local dOffs = b3Profile:getMin():getX() - dRailDelta + if vPrevOutlineId[i] < 0 then + EgtInvertCurve( nCrvId) + dOffs = - b3Profile:getMax():getX() + end + EgtOffsetCurve( nCrvId, dOffs) + + -- per un risultato graficamente migliore se il pezzo precedente è in tangenza con il vicino, impongo estensione in tangenza, altrimenti considero quella + -- calcolata dal geo + local nStartType = EgtGetInfo( abs( vPrevOutlineId[i]), WIN_STARTJOINT, 'i') + if nStartType == WIN_PART_JNT.ANGLED then + EgtSetInfo( nCrvId, WIN_TANG_START, true) + else + CopyInfo( nCrvId, vGeoLeft[i], WIN_TANG_START, false) + end + local nEndType = EgtGetInfo( abs( vPrevOutlineId[i]), WIN_ENDJOINT, 'i') + if nEndType == WIN_PART_JNT.ANGLED then + EgtSetInfo( nCrvId, WIN_TANG_END, true) + else + CopyInfo( nCrvId, vGeoLeft[i], WIN_TANG_END, false) + end + + elseif nStartJoint == WIN_PART_JNT.FULL then + -- nel caso di curva su split french con anta inactive bisogna considerare il bordo del pezzo active, altrimenti considero l'out del pezzo precedente + local sProfileType = EgtGetInfo( vPrevProfileId[i], WIN_PRF_TYPE) + if sProfileType == WIN_SASH_INACTIVE or sProfileType == WIN_FRENCH_OUT then + GetBorderFromAdjacentSash( abs( vPrevOutlineId[i]), nGrpTmp) + else + local nCrvId = EgtCopy( abs( vPrevOutlineId[i]), nGrpTmp) + local b3Profile = GetProfileLocalBox( vPrevProfileId[i]) + local dOffs = b3Profile:getMax():getX() + if vPrevOutlineId[i] < 0 then + EgtInvertCurve( nCrvId) + dOffs = - b3Profile:getMin():getX() + end + EgtOffsetCurve( nCrvId, dOffs) + CopyInfo( nCrvId, vGeoLeft[i], WIN_TANG_START, false) + CopyInfo( nCrvId, vGeoLeft[i], WIN_TANG_END, false) + end 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 + + -- recupero la bisettrice dal geo + local nCrvId = EgtCopyGlob( vGeoRight[1], nGrpTmp) + EgtRelocateGlob( nCrvId, nInId, GDB_IN.BEFORE) + + -- curva aux + local nAuxCrv + local sProfileType = EgtGetInfo( vNextProfileId[1], WIN_PRF_TYPE) + if sProfileType == WIN_SASH_INACTIVE or sProfileType == WIN_FRENCH_OUT then + nAuxCrv = GetBorderFromAdjacentSash( abs( vNextOutlineId[1]), nGrpTmp) + else + nAuxCrv = EgtCopyGlob( abs( vNextOutlineId[1]), nGrpTmp) + local b3Profile = GetProfileLocalBox( vNextProfileId[1]) + EgtOffsetCurve( nAuxCrv, b3Profile:getMax():getX()) + end + EgtRelocateGlob( nAuxCrv, nInId, GDB_IN.BEFORE) - -- creo la regione - nAreaId = CalcIntersectionRegion( EgtGetAllInGroup( nGrpTmp), nPreviewGrp) + else + for i = 1, #vNextOutlineId do + local nCrvId + if nEndJoint == WIN_PART_JNT.SHORT then + nCrvId = EgtCopyGlob( abs( vNextOutlineId[i]), nGrpTmp) + local b3Profile = GetProfileLocalBox( vNextProfileId[i]) + local dRailDelta = EgtGetInfo( vNextProfileId[i], WIN_RAILDELTA, 'd') or 0 + local dOffs = b3Profile:getMin():getX() - dRailDelta + if vNextOutlineId[i] < 0 then + EgtInvertCurve( nCrvId) + dOffs = - b3Profile:getMax():getX() + end + EgtOffsetCurve( nCrvId, dOffs) + + local nStartType = EgtGetInfo( abs( vNextOutlineId[i]), WIN_STARTJOINT, 'i') + if nStartType == WIN_PART_JNT.ANGLED then + EgtSetInfo( nCrvId, WIN_TANG_START, true) + else + CopyInfo( nCrvId, vGeoRight[i], WIN_TANG_START, false) + end + local nEndType = EgtGetInfo( abs( vNextOutlineId[i]), WIN_ENDJOINT, 'i') + if nEndType == WIN_PART_JNT.ANGLED then + EgtSetInfo( nCrvId, WIN_TANG_END, true) + else + CopyInfo( nCrvId, vGeoRight[i], WIN_TANG_END, false) + end + + elseif nEndJoint == WIN_PART_JNT.FULL then + + local sProfileType = EgtGetInfo( vNextProfileId[i], WIN_PRF_TYPE) + if sProfileType == WIN_SASH_INACTIVE or sProfileType == WIN_FRENCH_OUT then + nCrvId = GetBorderFromAdjacentSash( abs( vNextOutlineId[i]), nGrpTmp) + else + local b3Profile = GetProfileLocalBox( vNextProfileId[i]) + nCrvId = EgtCopyGlob( abs( vNextOutlineId[i]), nGrpTmp) + local dOffs = b3Profile:getMax():getX() + if vNextOutlineId[i] < 0 then + EgtInvertCurve( nCrvId) + dOffs = - b3Profile:getMin():getX() + end + EgtOffsetCurve( nCrvId, dOffs) + CopyInfo( nCrvId, vGeoRight[i], WIN_TANG_START, false) + CopyInfo( nCrvId, vGeoRight[i], WIN_TANG_END, false) + end + end + EgtRelocateGlob( nCrvId, nInId, GDB_IN.BEFORE) + end + end + + local vIds = EgtGetAllInGroup( nGrpTmp) + nAreaId = CalcGeoRegion( vIds, nPreviewGrp) EgtErase( nGrpTmp) end - + -- sistemo la regione local color = EgtGetColor( nPartId) EgtSetColor( nAreaId, color) -- estraggo il contorno local nCompoId = EgtExtractSurfFrChunkLoops( nAreaId, 0, nPreviewGrp) EgtSetColor( nCompoId, EgtStdColor( 'BLACK')) - EgtModifyCurveThickness( nCompoId, 0) - + -- se bottom aggiungo anche eventuale preview del bottomrail if EgtGetName( nOutlineId) == WIN_BOTTOM then local nBottomRail = EgtGetInfo( nOutlineId, WIN_BOTTOMRAIL, 'i') or 0 if nBottomRail > 0 then - CalcBottomRailPreview( nPreviewGrp, nOutlineId, nBottomRail, nGeoGrp, color) + CalcBottomRailPreview( nPreviewGrp, nOutlineId, nBottomRail, nGeoLayerId, color) end end end