From c831af68998046ec426a4fe636eb5fedd3390c75 Mon Sep 17 00:00:00 2001 From: SaraP Date: Mon, 27 May 2024 14:37:25 +0200 Subject: [PATCH 1/2] EgwWindowLua : - integrato il calcolo degli split dowels nel calcolo del solido - modifica alla struttura della ricorsione nel calcolo dei pezzi dal telaio. --- Profiles/Main.lua | 1 - Profiles/WinLib/WinCalculate.lua | 475 +++++++++++++++---------------- Profiles/WinOpenProjectFile.lua | 1 - 3 files changed, 234 insertions(+), 243 deletions(-) diff --git a/Profiles/Main.lua b/Profiles/Main.lua index 49af335..248371b 100644 --- a/Profiles/Main.lua +++ b/Profiles/Main.lua @@ -656,7 +656,6 @@ WinCalculate.SetCalcSolid( true) -- -- creo i pezzi WinCalculate.CreatePartFromArea( nFrameId) -WinCalculate.AddSplitDowelToParts( nFrameId) WinCalculate.AddHardware( nFrameId) -- -- creo tabella per salvataggio diff --git a/Profiles/WinLib/WinCalculate.lua b/Profiles/WinLib/WinCalculate.lua index a3470bf..94e4c8f 100644 --- a/Profiles/WinLib/WinCalculate.lua +++ b/Profiles/WinLib/WinCalculate.lua @@ -333,6 +333,19 @@ local function CalcProfileType( nAreaId) end end +--------------------------------------------------------------------- +-- funzione che cicla ricorsivamente su aree e sottoaree per impostare i tipi di profilo +local function CalculateAreaProfileType( nAreaId) + -- calcolo i profili per l'area corrente + CalcProfileType( nAreaId) + -- calcolo i profili per le eventuali sottoaree + local nChildAreaId = EgtGetFirstNameInGroup( nAreaId, WIN_AREA .. '*') + while nChildAreaId do + CalculateAreaProfileType( nChildAreaId) + nChildAreaId = EgtGetNextName( nChildAreaId, WIN_AREA .. '*') + end +end + --------------------------------------------------------------------- --------------------- CALCOLO OUTLINE ------------------------------- @@ -601,6 +614,20 @@ local function CalculateOutlineFromAreaOutline( nAreaId) EgtErase( nCompoId) end +--------------------------------------------------------------------- +-- funzione che cicla ricorsivamente su aree e sottaree per calcolare gli outlines +local function CalculateAreaOutline( nAreaId) + -- calcolo outlines per l'area corrente + CalculateOutlineFromAreaOutline( nAreaId) + -- calcolo outlines per le eventuali sottoaree + local nChildAreaId = EgtGetFirstNameInGroup( nAreaId, WIN_AREA .. '*') + while nChildAreaId do + CalculateAreaOutline( nChildAreaId) + nChildAreaId = EgtGetNextName( nChildAreaId, WIN_AREA .. '*') + end +end + + --------------------------------------------------------------------- ---------------------- CALCOLO PEZZI ------------------------------ @@ -958,7 +985,7 @@ local function CalcStartEndProfileType( nProfileType, nOutlineId, nStartProfileI end --------------------------------------------------------------------- -local function AddDowelStart( nOutlineId, nPrevOutlineId, StartJointType, nMainProfileId, nStartProfileId, nDowelLayerId, nGeoInId, nSolidLayerId, +local function AddStartDowels( nOutlineId, nPrevOutlineId, StartJointType, nMainProfileId, nStartProfileId, nDowelLayerId, nGeoInId, nSolidLayerId, nMainExtrusionId, nStartExtrusionId, nExtrCopyId) local sOutlineName = EgtGetName( nOutlineId) @@ -1085,8 +1112,8 @@ local function AddDowelStart( nOutlineId, nPrevOutlineId, StartJointType, nMainP end --------------------------------------------------------------------- -local function AddDowelEnd( nOutlineId, nEndOutlineId, EndJointType, nMainProfileId, nEndProfileId, nDowelLayerId, nGeoInId, nSolidLayerId, - nMainExtrusionId, nEndExtrusionId, nExtrCopyId) +local function AddEndDowels( nOutlineId, nEndOutlineId, EndJointType, nMainProfileId, nEndProfileId, nDowelLayerId, nGeoInId, nSolidLayerId, + nMainExtrusionId, nEndExtrusionId, nExtrCopyId) local sOutlineName = EgtGetName( nOutlineId) local sEndOutlineName = EgtGetName( nEndOutlineId) @@ -1329,7 +1356,7 @@ local function MakeSolidByExtrusion( nGeoId, nOutlineId, nMainProfileId, nStartP EgtSurfTmCut( nStartExtrusionId, nExtrCopyId, true, false) -- creo fori per spine su Start - AddDowelStart( nOutlineId, nPrevOutlineId, StartJointType, nMainProfileId, nStartProfileId, nDowelLayerId, nGeoInId, nSolidLayerId, nMainExtrusionId, nStartExtrusionId, nExtrCopyId) + AddStartDowels( nOutlineId, nPrevOutlineId, StartJointType, nMainProfileId, nStartProfileId, nDowelLayerId, nGeoInId, nSolidLayerId, nMainExtrusionId, nStartExtrusionId, nExtrCopyId) -- c) END PROFILE @@ -1403,12 +1430,165 @@ local function MakeSolidByExtrusion( nGeoId, nOutlineId, nMainProfileId, nStartP EgtSurfTmCut( nEndExtrusionId, nExtrCopyId, true, false) -- creo fori per spine su End - AddDowelEnd( nOutlineId, nEndOutlineId, EndJointType, nMainProfileId, nEndProfileId, nDowelLayerId, nGeoInId, nSolidLayerId, nMainExtrusionId, nEndExtrusionId, nExtrCopyId) + AddEndDowels( nOutlineId, nEndOutlineId, EndJointType, nMainProfileId, nEndProfileId, nDowelLayerId, nGeoInId, nSolidLayerId, nMainExtrusionId, nEndExtrusionId, nExtrCopyId) -- elimino copia dell'estrusione principale EgtErase( { nExtrCopyId}) end +---------------------------------------------------------------------------------- +------------------------------- SPLIT DOWELS ------------------------------------- +---------------------------------------------------------------------------------- +-- funzione che calcola intersezione, geometrie e superfici dei dowel degli split +local function CalSplitDowel( nSplitLayerId, nOutlineId, nProfileType, nPartId) + + -- verifico se interseca l'outline che sto analizzando + local nSplitId = EgtGetFirstInGroup( nSplitLayerId) + local ptInt = EgtIP( nOutlineId, nSplitId, EgtSP( nSplitId)) + if not ptInt then + return + end + + -- se interseca, recupero il profilo dello split + local nOrigSplitProfileId = GetOutlineProfileId( nSplitId, false) + + -- creo copia del profilo + local nFrameProfileLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE) + local nSplitProfileId = EgtCopy( nOrigSplitProfileId, nFrameProfileLayerId) + local sSplitProfileType = EgtGetName( nOrigSplitProfileId) + EgtSetInfo( nSplitProfileId, WIN_PRF_TYPE, sSplitProfileType) + EgtSetName( nSplitProfileId, WIN_PRF_SPLIT) + + -- recupero intersezione con lato In o Out del geo + local nGeoLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO) + local nGeoCrvId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_IN) + local ptInters = EgtIP( nGeoCrvId, nSplitId, EgtSP( nSplitId)) + if not ptInters and nProfileType == WIN_PRF.SPLIT then + nGeoCrvId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_OUT) + ptInters = EgtIP( nGeoCrvId, nSplitId, EgtSP( nSplitId)) + end + + -- recupero frame del profilo e lo applico a tutte le sue geometrie + local nSplitProfileFrameId = EgtGetFirstNameInGroup( nSplitProfileId, WIN_SECTIONFRAME) + local frInvertSplitProfile = EgtFR( nSplitProfileFrameId) + frInvertSplitProfile:invert() + EgtTransform( EgtGetAllInGroup( nSplitProfileId), frInvertSplitProfile) + -- assegno come riferimento del profilo il punto di intersezione e la direzione dello split + local vtDir = - EgtSV( nSplitId) -- se non fosse lineare potrebbe essere end vector ? + EgtChangeGroupFrame( nSplitProfileId, Frame3d( ptInters, vtDir)) + + -- calcolo la direzione del dowel sempre verso l'interno del pezzo + local vtDowelDir = Vector3d( vtDir) + local _, _, nSide = EgtPointCurveDistSide( ptInters + vtDowelDir, nGeoCrvId, Z_AX()) + if nSide == 1 then + -- se a destra della curva significa che la direzione è uscente dal pezzo e va invertita + vtDowelDir = - vtDowelDir + end + + -- recupero solido del pezzo + local nSolidLayerId = EgtGetFirstNameInGroup( nPartId, WIN_SOLID) + local nMainExtrusionId = EgtGetFirstNameInGroup( nSolidLayerId, WIN_SRF_MAIN) + local nOrigMainExtrusionId = EgtGetFirstNameInGroup( nSolidLayerId, WIN_SRF_ORIGMAIN) + + -- creo fori per spine su Split + local nDowelLayerId = EgtGetFirstNameInGroup( nPartId, WIN_DOWEL) + + -- recupero profondita' d'inizio e fine + local sStart = WIN_DWL_TOPPERPSTART + local sEnd = WIN_DWL_TOPPERPEND + if nProfileType == WIN_PRF.BOTTOM then + sStart = WIN_DWL_BOTTOMPERPSTART + sEnd = WIN_DWL_BOTTOMPERPEND + elseif nProfileType == WIN_PRF.BOTTOMRAIL then + sStart = WIN_DWL_RAILBOTTOMPERPSTART + sEnd = WIN_DWL_RAILBOTTOMPERPEND + elseif nProfileType == WIN_PRF.SPLIT then + local sProfileType = EgtGetInfo( nOutlineId, WIN_PROFILETYPE) + if sProfileType == WIN_SASH_HORIZONTAL then + sStart = WIN_DWL_HORIZONTALSPLITPERPSTART + sEnd = WIN_DWL_HORIZONTALSPLITPERPEND + -- sta sempre leggendo l'informazione corretta? ( cfr dowel per start ed end nella crezione del solido) + elseif sProfileType == WIN_SASH_VERTICAL then + sStart = WIN_DWL_VERTICALSPLITPERPSTART + sEnd = WIN_DWL_VERTICALSPLITPERPEND + else -- sProfileType == WIN_FRAME_SPLIT + sStart = WIN_DWL_SPLITPERPSTART + sEnd = WIN_DWL_SPLITPERPEND + end + end + + -- ciclo sui fori trovati + local nOrigDowelId = EgtGetFirstNameInGroup( nSplitProfileId, WIN_DOWEL .. '*') + while nOrigDowelId do + local dStart = EgtGetInfo( nOrigDowelId, sStart, 'd') + if not dStart then + dStart = EgtGetInfo( nOrigDowelId, WIN_DWL_TOPPERPSTART, 'd') + end + local dEnd = EgtGetInfo( nOrigDowelId, sEnd, 'd') + if not dEnd then + dEnd = EgtGetInfo( nOrigDowelId, WIN_DWL_TOPPERPEND, 'd') + end + local nDowelId = EgtCopyGlob( nOrigDowelId, nDowelLayerId) + EgtSetColor( nDowelId, Color3d( 128, 128, 128)) + + -- posiziono il dowel e gli assegno estrusione e spessore + EgtMove( nDowelId, vtDowelDir * dStart) + EgtModifyCurveExtrusion( nDowelId, vtDowelDir) + EgtModifyCurveThickness( nDowelId, dEnd - dStart) + -- creo solido di estrusione + local nDowelExtrusionId = EgtSurfTmByRegionExtrusion( nSolidLayerId, nDowelId, vtDowelDir * ( dEnd - dStart + 1)) + EgtMove( nDowelExtrusionId, - vtDowelDir) + EgtInvertSurf( nDowelExtrusionId) + -- taglio estrusi per ottenere solido + EgtSurfTmCut( nMainExtrusionId, nDowelExtrusionId, true, false) + EgtSurfTmCut( nDowelExtrusionId, nOrigMainExtrusionId, true, false) + + nOrigDowelId = EgtGetNextName( nOrigDowelId, WIN_DOWEL .. '*') + end +end + +---------------------------------------------------------------------------------- +-- funzione che cicla ricorsivamente sulle aree e sottoaree relative al pezzo per aggiungere gli split dowels +local function AddAreaSplitDowels( nOutlineId, nPartId, nProfileType, nAreaLayerId) + + -- verifico la presenza di eventuali split nell'area corrente + local nSplitLayerId = EgtGetFirstNameInGroup( nAreaLayerId, WIN_SPLIT) + if nSplitLayerId then + local nSplitType = EgtGetInfo( nSplitLayerId, WIN_SPLITTYPE, 'i') or WIN_SPLITTYPES.NULL + if nSplitType ~= WIN_SPLITTYPES.FRENCH then + CalSplitDowel( nSplitLayerId, nOutlineId, nProfileType, nPartId) + end + end + + -- verifico la presenza di split nelle sottoaree + local nChildAreaId = EgtGetFirstNameInGroup( nAreaLayerId, WIN_AREA .. '*') + while nChildAreaId do + local nAreaType = EgtGetInfo( nChildAreaId, WIN_AREATYPE, 'i') + if nAreaType == WIN_AREATYPES.SPLIT then + AddAreaSplitDowels( nOutlineId, nPartId, nProfileType, nChildAreaId) + end + nChildAreaId = EgtGetNextName( nChildAreaId, WIN_AREA .. '*') + end +end + +---------------------------------------------------------------------------------- +-- funzione che aggiunge al solido i dowels degli split che lo intersecano +local function AddSplitDowels( nOutlineId, nOutlineLayerId, nPartId, nProfileType) + + -- se profilo bottom con BottomRail esco ( gli split dowels saranno aggiuti sul BottomRail associato) + if nProfileType == WIN_PRF.BOTTOM then + local bBottomRail = EgtGetInfo( nOutlineLayerId, WIN_BOTTOMRAIL, 'b') or false + if bBottomRail then + return + end + end + + -- recupero area del pezzo + local nAreaLayerId = EgtGetParent( nOutlineLayerId) + -- aggiungo gli split dowels a partire dall'area corrente + AddAreaSplitDowels( nOutlineId, nPartId, nProfileType, nAreaLayerId) +end + --------------------------------------------------------------------- -- funzione che crea il solido del pezzo del telaio local function CalcFrameSolid( nPartId, nOutlineId, nGeoId, nOutlineLayerId, bBottomRail) @@ -1449,6 +1629,10 @@ local function CalcFrameSolid( nPartId, nOutlineId, nGeoId, nOutlineLayerId, bBo -- creo solido dai profili MakeSolidByExtrusion( nGeoId, nOutlineId, nMainProfileId, nStartProfileId, nEndProfileId, nProfileType, nSolidLayerId, nDowelLayerId) + + -- aggiungo dowels degli split + AddSplitDowels( nOutlineId, nOutlineLayerId, nPartId, nProfileType) + end --------------------------------------------------------------------- @@ -1583,12 +1767,36 @@ local function CreateStripGuideLines( nOutlineId, nStripId, nProfileId, nSolidLa end +--------------------------------------------------------------------- +-- funzione che recupera il pezzo associato ad un outline +local function FindAssociatedPart( nOutlineId) + + local nPartId = EgtGetInfo( nOutlineId, WIN_REF_BOTTOMRAIL_PART, 'i') or EgtGetInfo( nOutlineId, WIN_REF_PART, 'i') + if not nPartId then + -- cerco la prima curva da cui deriva che ha un pezzo associato + local nBaseOutline = EgtGetInfo( nOutlineId, WIN_COPY, 'i') + while not nPartId do + -- recupero il base outline da cui deriva + nBaseOutline = EgtGetInfo( nBaseOutline, WIN_SOU, 'i') + -- verifico se ha un profilo associato ( e quindi un pezzo) + local sProfileType = EgtGetInfo( nBaseOutline, WIN_PROFILETYPE) + if sProfileType then + -- recupero l'outline associato + local nCrvId = EgtGetInfo( nBaseOutline, WIN_COPY, 'i') + nPartId = EgtGetInfo( nCrvId, WIN_REF_BOTTOMRAIL_PART, 'i') or EgtGetInfo( nCrvId, WIN_REF_PART, 'i') + end + end + end + + return nPartId +end + --------------------------------------------------------------------- -- funzione che crea gli Strip local function CreateStripFromOutline( nAreaId, nOutlineId) -- recupero il pezzo associato ( prendendo quello di bottomrail se esiste) - local nPartId = EgtGetInfo( nOutlineId, WIN_REF_BOTTOMRAIL_PART, 'i') or EgtGetInfo( nOutlineId, WIN_REF_PART, 'i') + local nPartId = FindAssociatedPart( nOutlineId) -- recupero layer per solido e per profili di estrusione local nSolidLayerId = EgtGetFirstNameInGroup( nPartId, WIN_SOLID) local nMainProfileLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE) @@ -1597,8 +1805,8 @@ local function CreateStripFromOutline( nAreaId, nOutlineId) local nOutlineLayerId = EgtGetParent( nOutlineId) local nPrevOutlineId, nNextOutlineId = GetPrevNextOutline( WIN_PRF.NULL, nOutlineId, nOutlineLayerId) -- recupero i pezzi precedente e successivo, prendendo eventualmente quelli di bottomrail - local nPrevPartId = EgtGetInfo( nPrevOutlineId, WIN_REF_BOTTOMRAIL_PART, 'i') or EgtGetInfo( nPrevOutlineId, WIN_REF_PART) - local nNextPartId = EgtGetInfo( nNextOutlineId, WIN_REF_BOTTOMRAIL_PART, 'i') or EgtGetInfo( nNextOutlineId, WIN_REF_PART) + local nPrevPartId = FindAssociatedPart( nPrevOutlineId) + local nNextPartId = FindAssociatedPart( nNextOutlineId) -- recupero profilo e controprofili local nMainProfileId = EgtGetFirstNameInGroup( nMainProfileLayerId, WIN_PRF_MAIN) @@ -1671,238 +1879,10 @@ local function CreateStripFromOutline( nAreaId, nOutlineId) EgtErase( nStripExtrCopyId) end ----------------------------------------------------------------------------------- -------------------------------- SPLIT DOWELS ------------------------------------- ----------------------------------------------------------------------------------- --- funzione che calcola intersezione, geometrie e superfici dei dowel degli split -local function CalSplitDowel( nSplitLayerId, nOutlineId, nProfileType, nPartId) - - -- verifico se interseca l'outline che sto analizzando - local nSplitId = EgtGetFirstInGroup( nSplitLayerId) - local ptInt = EgtIP( nOutlineId, nSplitId, EgtSP( nSplitId)) - if not ptInt then - return - end - - -- se interseca, recupero il profilo dello split - local nOrigSplitProfileId = GetOutlineProfileId( nSplitId, false) - - -- creo copia del profilo - local nFrameProfileLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE) - local nSplitProfileId = EgtCopy( nOrigSplitProfileId, nFrameProfileLayerId) - local sSplitProfileType = EgtGetName( nOrigSplitProfileId) - EgtSetInfo( nSplitProfileId, WIN_PRF_TYPE, sSplitProfileType) - EgtSetName( nSplitProfileId, WIN_PRF_SPLIT) - - -- recupero intersezione con lato In o Out del geo - local nGeoLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO) - local nGeoCrvId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_IN) - local ptInters = EgtIP( nGeoCrvId, nSplitId, EgtSP( nSplitId)) - if not ptInters and nProfileType == WIN_PRF.SPLIT then - nGeoCrvId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_OUT) - ptInters = EgtIP( nGeoCrvId, nSplitId, EgtSP( nSplitId)) - end - - -- recupero frame del profilo e lo applico a tutte le sue geometrie - local nSplitProfileFrameId = EgtGetFirstNameInGroup( nSplitProfileId, WIN_SECTIONFRAME) - local frInvertSplitProfile = EgtFR( nSplitProfileFrameId) - frInvertSplitProfile:invert() - EgtTransform( EgtGetAllInGroup( nSplitProfileId), frInvertSplitProfile) - -- assegno come riferimento del profilo il punto di intersezione e la direzione dello split - local vtDir = - EgtSV( nSplitId) -- se non fosse lineare potrebbe essere end vector ? - EgtChangeGroupFrame( nSplitProfileId, Frame3d( ptInters, vtDir)) - - -- calcolo la direzione del dowel sempre verso l'interno del pezzo - local vtDowelDir = Vector3d( vtDir) - local _, _, nSide = EgtPointCurveDistSide( ptInters + vtDowelDir, nGeoCrvId, Z_AX()) - if nSide == 1 then - -- se a destra della curva significa che la direzione è uscente dal pezzo e va invertita - vtDowelDir = - vtDowelDir - end - - -- recupero solido del pezzo - local nSolidLayerId = EgtGetFirstNameInGroup( nPartId, WIN_SOLID) - local nMainExtrusionId = EgtGetFirstNameInGroup( nSolidLayerId, WIN_SRF_MAIN) - local nOrigMainExtrusionId = EgtGetFirstNameInGroup( nSolidLayerId, WIN_SRF_ORIGMAIN) - - -- creo fori per spine su Split - local nDowelLayerId = EgtGetFirstNameInGroup( nPartId, WIN_DOWEL) - - -- recupero profondita' d'inizio e fine - local sStart = WIN_DWL_TOPPERPSTART - local sEnd = WIN_DWL_TOPPERPEND - if nProfileType == WIN_PRF.BOTTOM then - sStart = WIN_DWL_BOTTOMPERPSTART - sEnd = WIN_DWL_BOTTOMPERPEND - elseif nProfileType == WIN_PRF.BOTTOMRAIL then - sStart = WIN_DWL_RAILBOTTOMPERPSTART - sEnd = WIN_DWL_RAILBOTTOMPERPEND - elseif nProfileType == WIN_PRF.SPLIT then - local sProfileType = EgtGetInfo( nOutlineId, WIN_PROFILETYPE) - if sProfileType == WIN_SASH_HORIZONTAL then - sStart = WIN_DWL_HORIZONTALSPLITPERPSTART - sEnd = WIN_DWL_HORIZONTALSPLITPERPEND - -- sta sempre leggendo l'informazione corretta? ( cfr dowel per start ed end nella crezione del solido) - elseif sProfileType == WIN_SASH_VERTICAL then - sStart = WIN_DWL_VERTICALSPLITPERPSTART - sEnd = WIN_DWL_VERTICALSPLITPERPEND - else -- sProfileType == WIN_FRAME_SPLIT - sStart = WIN_DWL_SPLITPERPSTART - sEnd = WIN_DWL_SPLITPERPEND - end - end - - -- ciclo sui fori trovati - local nOrigDowelId = EgtGetFirstNameInGroup( nSplitProfileId, WIN_DOWEL .. '*') - while nOrigDowelId do - local dStart = EgtGetInfo( nOrigDowelId, sStart, 'd') - if not dStart then - dStart = EgtGetInfo( nOrigDowelId, WIN_DWL_TOPPERPSTART, 'd') - end - local dEnd = EgtGetInfo( nOrigDowelId, sEnd, 'd') - if not dEnd then - dEnd = EgtGetInfo( nOrigDowelId, WIN_DWL_TOPPERPEND, 'd') - end - local nDowelId = EgtCopyGlob( nOrigDowelId, nDowelLayerId) - EgtSetColor( nDowelId, Color3d( 128, 128, 128)) - - -- posiziono il dowel e gli assegno estrusione e spessore - EgtMove( nDowelId, vtDowelDir * dStart) - EgtModifyCurveExtrusion( nDowelId, vtDowelDir) - EgtModifyCurveThickness( nDowelId, dEnd - dStart) - -- creo solido di estrusione - local nDowelExtrusionId = EgtSurfTmByRegionExtrusion( nSolidLayerId, nDowelId, vtDowelDir * ( dEnd - dStart + 1)) - EgtMove( nDowelExtrusionId, - vtDowelDir) - EgtInvertSurf( nDowelExtrusionId) - -- taglio estrusi per ottenere solido - EgtSurfTmCut( nMainExtrusionId, nDowelExtrusionId, true, false) - EgtSurfTmCut( nDowelExtrusionId, nOrigMainExtrusionId, true, false) - - nOrigDowelId = EgtGetNextName( nOrigDowelId, WIN_DOWEL .. '*') - end -end - ----------------------------------------------------------------------------------- --- funzione ricorsiva che cerca gli split che possono dare origine a dei dowel -local function VerifyDowelArea( nAreaLayerId, nOutlineId, nProfileType, nPartId) - - -- verifico la presenza di eventuali Split - local nSplitLayerId = EgtGetFirstNameInGroup( nAreaLayerId, WIN_SPLIT) - if nSplitLayerId then - local nSplitType = EgtGetInfo( nSplitLayerId, WIN_SPLITTYPE, 'i') or WIN_SPLITTYPES.NULL - if nSplitType ~= WIN_SPLITTYPES.FRENCH then - CalSplitDowel( nSplitLayerId, nOutlineId, nProfileType, nPartId) - end - end - - -- verifico la presenza di split in sotto aree - local nArea1LayerId = EgtGetFirstNameInGroup( nAreaLayerId, WIN_AREA1) - if nArea1LayerId then - local nAreaType = EgtGetInfo( nArea1LayerId, WIN_AREATYPE, 'i') - if nAreaType == WIN_AREATYPES.SPLIT then - VerifyDowelArea( nArea1LayerId, nOutlineId, nProfileType, nPartId) - end - end - local nArea2LayerId = EgtGetFirstNameInGroup( nAreaLayerId, WIN_AREA2) - if nArea2LayerId then - local nAreaType = EgtGetInfo( nArea2LayerId, WIN_AREATYPE, 'i') - if nAreaType == WIN_AREATYPES.SPLIT then - VerifyDowelArea( nArea2LayerId, nOutlineId, nProfileType, nPartId) - end - end -end - ----------------------------------------------------------------------------------- --- funzione che posiziona i fori delle spine degli split, li estrude e crea il solido -local function AddSplitDowelToExtrusion( nOutlineId, bIsBottomRail) - - -- ricavo pezzo associato - local sPartRef = WIN_REF_PART - if bIsBottomRail then - sPartRef = WIN_REF_BOTTOMRAIL_PART - end - local nPartId = EgtGetInfo( nOutlineId, sPartRef, 'i') - - -- ricavo tipo di profilo - local nProfileType = GetOutlineProfileType( nOutlineId, bIsBottomRail) - - -- se profilo Bottom con BottomRail, esco ( gli split dowels saranno fatti sul BottomRail) - local nOutlineLayerId = EgtGetParent( nOutlineId) - if nProfileType == WIN_PRF.BOTTOM then - local bBottomRail = EgtGetInfo( nOutlineLayerId, WIN_BOTTOMRAIL, 'b') or false - if bBottomRail then - return - end - end - - -- recupero l'area di cui fa parte il pezzo - local nAreaLayerId = EgtGetParent( nOutlineLayerId) - - -- verifico la presenza di eventuali Split - VerifyDowelArea( nAreaLayerId, nOutlineId, nProfileType, nPartId) -end - ----------------------------------------------------------------------------------- -function WinCalculate.AddSplitDowelToParts( nAreaId) - -- se non ho calcolato i solidi, esco - if not bCalcSolid then - return - end - -- recupero tipo di area - local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i') - if nAreaType == WIN_AREATYPES.FRAME or nAreaType == WIN_AREATYPES.SASH then - -- recupero pezzi outline - local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE) - local nOutlineId = EgtGetFirstInGroup( nOutlineLayerId) - while nOutlineId do - AddSplitDowelToExtrusion( nOutlineId, false) - -- se di tipo bottom - local sName = EgtGetName( nOutlineId) - if sName == WIN_BOTTOM then - -- se ha BottomRail - local bBottomRail = EgtGetInfo( nOutlineLayerId, WIN_BOTTOMRAIL, 'b') or false - if bBottomRail then - AddSplitDowelToExtrusion( nOutlineId, true) - end - end - nOutlineId = EgtGetNext( nOutlineId) - end - end - -- verifico se c'e' uno split - local nSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_SPLIT) - if nSplitLayerId then - local nSplitType = EgtGetInfo( nSplitLayerId, WIN_SPLITTYPE, 'i') or WIN_SPLITTYPES.NULL - -- se split ha pezzo associato - if nSplitType ~= WIN_SPLITTYPES.FRENCH then - local nSplitId = EgtGetFirstInGroup( nSplitLayerId) - if nSplitId then - AddSplitDowelToExtrusion( nSplitId, false) - end - end - end - - -- verifico se ci sono aree - local nChildAreaId = EgtGetFirstNameInGroup( nAreaId, WIN_AREA .. '*') - while nChildAreaId do - -- lancio costruzione pezzi di quell'area - WinCalculate.AddSplitDowelToParts( nChildAreaId) - nChildAreaId = EgtGetNextName( nChildAreaId, WIN_AREA .. '*') - end -end - --------------------------------------------------------------------- -------------------------- FUNZIONI ---------------------------------- ---------------------------------------------------------------------- --- funzione che cicla ricorsivamente sulla struttura per creare tutti i pezzi della finestra -function WinCalculate.CreatePartFromArea( nAreaId) +-- funzione che cicla ricorsivamente su aree e sottaree per calcolare i pezzi +local function CalculateAreaParts( nAreaId) - -- assengo il tipo di profilo alle curve del base outline - CalcProfileType( nAreaId) - - -- calcolo outline a partire dal base outline - CalculateOutlineFromAreaOutline( nAreaId) - - -- creo pezzo local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i') if nAreaType == WIN_AREATYPES.FRAME or nAreaType == WIN_AREATYPES.SASH then -- creo pezzi per ogni outline @@ -1955,15 +1935,28 @@ function WinCalculate.CreatePartFromArea( nAreaId) end end - -- verifico se ci sono sotto-aree da realizzare + -- calcolo i pezzi delle sottoaree local nChildAreaId = EgtGetFirstNameInGroup( nAreaId, WIN_AREA .. '*') while nChildAreaId do - -- lancio costruzione pezzi di quell'area - WinCalculate.CreatePartFromArea( nChildAreaId) + CalculateAreaParts( nChildAreaId) nChildAreaId = EgtGetNextName( nChildAreaId, WIN_AREA .. '*') end end + +--------------------------------------------------------------------- +------------------------- FUNZIONI ---------------------------------- +--------------------------------------------------------------------- +-- funzione che crea tutti i pezzi della finestra partendo dal telaio +function WinCalculate.CreatePartFromArea( nFrameId) + -- assengo il tipo di profilo alle curve del base outline + CalculateAreaProfileType( nFrameId) + -- calcolo outline a partire dal base outline + CalculateAreaOutline( nFrameId) + -- creo pezzi + CalculateAreaParts( nFrameId) +end + --------------------------------------------------------------------- -- funzione che posiziona un pezzo function WinCalculate.PositionPart(nPartId) diff --git a/Profiles/WinOpenProjectFile.lua b/Profiles/WinOpenProjectFile.lua index 9519825..6fdf051 100644 --- a/Profiles/WinOpenProjectFile.lua +++ b/Profiles/WinOpenProjectFile.lua @@ -69,7 +69,6 @@ WinCalculate.SetCalcSolid( true) -- creo i pezzi local nFrameId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_AREAASTERISK) WinCalculate.CreatePartFromArea( nFrameId) -WinCalculate.AddSplitDowelToParts( nFrameId) -- elimino profilo se in batch per test if WINDOW and WINDOW.TEST and WINDOW.TEST == 1 then From 536c969471bb7b01106aae151d1222d3d32aa32e Mon Sep 17 00:00:00 2001 From: SaraP Date: Wed, 29 May 2024 08:59:49 +0200 Subject: [PATCH 2/2] EgwWindowLua : - correzioni e migliorie varie. --- Profiles/WinLib/WinCalculate.lua | 128 ++++++++++++------------------- 1 file changed, 51 insertions(+), 77 deletions(-) diff --git a/Profiles/WinLib/WinCalculate.lua b/Profiles/WinLib/WinCalculate.lua index 94e4c8f..edc83c6 100644 --- a/Profiles/WinLib/WinCalculate.lua +++ b/Profiles/WinLib/WinCalculate.lua @@ -76,12 +76,12 @@ end local function TrimSplitWithOutline( nSplitId) -- lo taglio con outline local nStartIntersId = EgtGetInfo( nSplitId, WIN_SPLIT_STARTINTERS, 'i') - local nOutlineId = EgtGetInfo( nStartIntersId, WIN_CHILD, 'i') + local nOutlineId = EgtGetInfo( nStartIntersId, WIN_COPY, 'i') local ptStartInters = EgtIP( nSplitId, nOutlineId, EgtSP( nSplitId)) local dStartInters = EgtCurveParamAtPoint( nSplitId, ptStartInters) - EgtTrimCurveStartAtParam( nSplitId, dStartInters) + EgtTrimCurveStartAtParam( nSplitId, dStartInters) local nEndIntersId = EgtGetInfo( nSplitId, WIN_SPLIT_ENDINTERS, 'i') - nOutlineId = EgtGetInfo( nEndIntersId, WIN_CHILD, 'i') + nOutlineId = EgtGetInfo( nEndIntersId, WIN_COPY, 'i') local ptEndInters = EgtIP( nSplitId, nOutlineId, EgtSP( nSplitId)) local dEndInters = EgtCurveParamAtPoint( nSplitId, ptEndInters) EgtTrimCurveEndAtParam( nSplitId, dEndInters) @@ -428,16 +428,10 @@ local function CalculateOutlineFromAreaOutline( nAreaId) EgtRemoveInfo( nSplitId, WIN_SOU) -- lo taglio con outline TrimSplitWithOutline( nSplitId) + -- recupero tipo di profilo + local sSplitProfile = EgtGetInfo( nSplitId, WIN_PROFILETYPE) -- se split interno ad anta - local nParentAreaId = EgtGetParent( nAreaId) - local nParentAreaType = EgtGetInfo( nParentAreaId, WIN_AREATYPE, 'i') - while nParentAreaType ~= WIN_AREATYPES.FRAME and nParentAreaType ~= WIN_AREATYPES.SASH do - nParentAreaId = EgtGetParent( nParentAreaId) - nParentAreaType = EgtGetInfo( nParentAreaId, WIN_AREATYPE, 'i') - end - if nParentAreaType == WIN_AREATYPES.SASH then - -- recupero tipo di profilo - local sSplitProfile = EgtGetInfo( nSplitId, WIN_PROFILETYPE) + if sSplitProfile == WIN_SASH_SPLIT then -- recupero profilo usato per anta local nProfileLayerId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_PROFILE) local nSashProfileLayerId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_SASH) @@ -448,7 +442,7 @@ local function CalculateOutlineFromAreaOutline( nAreaId) EgtMove( nSplitId, Z_AX() * dSashZOffset) end end - + -- SASH elseif nAreaType == WIN_AREATYPES.SASH then @@ -745,19 +739,14 @@ local function GetProfileCtrIn( nProfileType, nPrevOutlineId, nOutlineId, nPrevP local sPrevCtrIn = WIN_CTRIN -- gestione particolare nel caso di split su split if nProfileType == WIN_PRF.SPLIT then - -- verifico se il prev e' uno split - -- recupero il base outline corrispondente e verifico se un suo sou è split + -- recupero il base outline del prev e verifico se deriva da uno split local nPrevSouId = EgtGetInfo( nPrevOutlineId, WIN_COPY, 'i') - local nPrevSouParentId - local sPrevSouParentId + local sPrevSouName repeat nPrevSouId = EgtGetInfo( nPrevSouId, WIN_SOU, 'i') - if nPrevSouId then - nPrevSouParentId = EgtGetParent( nPrevSouId) - sPrevSouParentId = EgtGetName( nPrevSouParentId) - end - until not nPrevSouId or sPrevSouParentId == WIN_BASESPLIT - if nPrevSouId and sPrevSouParentId == WIN_BASESPLIT then + sPrevSouName = EgtGetName( nPrevSouId or GDB_ID.NULL) + until not nPrevSouId or sPrevSouName == WIN_SPLIT + if sPrevSouName == WIN_SPLIT then -- verifico da che lato sono dello split local dOutlineDist, _, dSide = EgtPointCurveDistSide( EgtMP( nOutlineId), nPrevSouId, Z_AX()) -- recupero box dei controprofili rispetto al loro sistema di riferimento @@ -930,10 +919,8 @@ local function CalcFrameGeo( nPartId, nOutlineId, nOutlineLayerId, bBottomRail) local nEndPartJointType = CalcPartJointType( nProfileType, nEndJointType) -- salvo i valori joint su outline per disegno solido - if nProfileType ~= WIN_PRF.BOTTOMRAIL then - EgtSetInfo( nOutlineId, WIN_STARTJOINT, nStartPartJointType) - EgtSetInfo( nOutlineId, WIN_ENDJOINT, nEndPartJointType) - end + EgtSetInfo( nOutlineId, WIN_STARTJOINT, nStartPartJointType) + EgtSetInfo( nOutlineId, WIN_ENDJOINT, nEndPartJointType) -- creo lati dell'outline local nGeoOutId = CreateFrameGeo( nOutlineId, nPrevOutlineId, nNextOutlineId, nStartPartJointType, nEndPartJointType, nProfileType, nGeoLayerId, bBottomRail) @@ -974,11 +961,6 @@ local function CalcStartEndProfileType( nProfileType, nOutlineId, nStartProfileI sEndProfileType = GetProfileCtrIn( nProfileType, nEndId, nOutlineId, nEndProfileId) sStartProfileType = WIN_OFST .. sStartProfileType sEndProfileType = WIN_OFST .. sEndProfileType - elseif nProfileType == WIN_PRF.BOTTOMRAIL then - StartJointType = WIN_JNT.FULL_V - EndJointType = WIN_JNT.FULL_V - sStartProfileType = WIN_CTRINOFST - sEndProfileType = WIN_CTRINOFST end return sStartProfileType, sEndProfileType, StartJointType, EndJointType @@ -986,7 +968,7 @@ end --------------------------------------------------------------------- local function AddStartDowels( nOutlineId, nPrevOutlineId, StartJointType, nMainProfileId, nStartProfileId, nDowelLayerId, nGeoInId, nSolidLayerId, - nMainExtrusionId, nStartExtrusionId, nExtrCopyId) + nMainExtrusionId, nStartExtrusionId, nExtrCopyId) local sOutlineName = EgtGetName( nOutlineId) local sPrevOutlineName = EgtGetName( nPrevOutlineId) @@ -1256,7 +1238,7 @@ local function MakeSolidByExtrusion( nGeoId, nOutlineId, nMainProfileId, nStartP -- recupero outline precedente e successivo local nPrevOutlineId, nEndOutlineId = GetPrevNextOutline( nProfileType, nOutlineId, nOutlineLayerId) - + -- a) MAIN EXTRUSION -- creo guida Main local nGuideId = EgtCopy( nOutlineId, nSolidLayerId) @@ -1302,27 +1284,24 @@ local function MakeSolidByExtrusion( nGeoId, nOutlineId, nMainProfileId, nStartP -- assegno come riferimento del profilo il punto start dell'outline EgtChangeGroupFrame( nStartProfileId, Frame3d( EgtSP( nStartGuideId), - EgtSV( nStartGuideId))) - -- se Start e' split verifico se è necessaria inversione del profilo - local nStartId = EgtGetInfo( nOutlineId, WIN_SPLIT_STARTINTERS, 'i') - local nStartProfileType - if nStartId then - local nStartAreaId = EgtGetParent( EgtGetParent( nStartId)) - if nStartAreaId then - nStartProfileType = EgtGetInfo( nStartAreaId, WIN_AREATYPE, 'i') - end + -- verifico se outline è split interno ad area di split per controlli su inversione del profilo + local bSplitInsideSplitArea = false + if nProfileType == WIN_PRF.SPLIT then + local nAreaId = EgtGetParent( EgtGetParent( nOutlineId)) + local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i') + bSplitInsideSplitArea = ( nAreaType == WIN_AREATYPES.SPLIT) end - if nProfileType == WIN_PRF.SPLIT and nStartProfileType and nStartProfileType == WIN_AREATYPES.SPLIT then + + if bSplitInsideSplitArea then + -- verifico se il suo start deriva da uno split + local nStartId = EgtGetInfo( nOutlineId, WIN_SPLIT_STARTINTERS, 'i') local nStartSouId = nStartId - local nStartSouLayerId - local sStartSouLayer + local sStartSouName repeat - nStartSouId = EgtGetInfo( nStartSouId, WIN_SOU) - nStartSouLayerId = EgtGetParent( nStartSouId) - if nStartSouLayerId then - sStartSouLayer = EgtGetName( nStartSouLayerId) - end - until not nStartSouId or not nStartSouLayerId or sStartSouLayer == WIN_BASESPLIT - if nStartSouId and nStartSouLayerId and sStartSouLayer == WIN_BASESPLIT then + nStartSouId = EgtGetInfo( nStartSouId, WIN_SOU, 'i') + sStartSouName = EgtGetName( nStartSouId or GDB_ID.NULL) + until not nStartSouId or sStartSouName == WIN_SPLIT + if sStartSouName == WIN_SPLIT then -- recupero vettore tangente nel punto medio della curva di contorno local ptMidStart = EgtMP( nStartId) local vtMidStart = EgtMV( nStartId) @@ -1330,7 +1309,7 @@ local function MakeSolidByExtrusion( nGeoId, nOutlineId, nMainProfileId, nStartP local dMidStartOnStartSou = EgtCurveParamAtPoint( nStartSouId, ptMidStart) local vtMidStartSou = EgtUV( nStartSouId, dMidStartOnStartSou, -1) -- se i due vettori non sono orientati nella stessa direzione - if not AreSameVectorExact( vtMidStart, vtMidStartSou) then + if not AreSameVectorApprox( vtMidStart, vtMidStartSou) then -- ruoto di 180 gradi il profilo local frStartProfileS = EgtFR( nStartProfileFrameId, GDB_ID.ROOT) EgtRotate( nStartProfileId, frStartProfileS:getOrigin(), frStartProfileS:getVersY(), 180, GDB_RT.GLOB) @@ -1339,6 +1318,7 @@ local function MakeSolidByExtrusion( nGeoId, nOutlineId, nMainProfileId, nStartP end end end + -- recupero outline del profilo Start e lo estrudo local nOutStartProfileId if sStartProfileType == WIN_MINIZINKEN then @@ -1378,27 +1358,18 @@ local function MakeSolidByExtrusion( nGeoId, nOutlineId, nMainProfileId, nStartP EgtTransform( EgtGetAllInGroup( nEndProfileId), frEndProfile) -- assegno come riferimento del profilo il punto start dell'outline EgtChangeGroupFrame( nEndProfileId, Frame3d( EgtSP( nEndGuideId), - EgtSV( nEndGuideId))) - -- se End e' split, ruoto di 180 gradi il profilo - local nEndId = EgtGetInfo( nOutlineId, WIN_SPLIT_ENDINTERS, 'i') - local nEndProfileType - if nEndId then - local nEndAreaId = EgtGetParent( EgtGetParent( nEndId)) - if nEndAreaId then - nEndProfileType = EgtGetInfo( nEndAreaId, WIN_AREATYPE, 'i') - end - end - if nProfileType == WIN_PRF.SPLIT and nEndProfileType and nEndProfileType == WIN_AREATYPES.SPLIT then + + -- verifico se necessario ruotare di 180 gradi il profilo + if bSplitInsideSplitArea then + -- verifico se end deriva da split + local nEndId = EgtGetInfo( nOutlineId, WIN_SPLIT_ENDINTERS, 'i') local nEndSouId = nEndId - local nEndSouLayerId - local sEndSouLayer + local sEndSouName repeat nEndSouId = EgtGetInfo( nEndSouId, WIN_SOU) - nEndSouLayerId = EgtGetParent( nEndSouId) - if nEndSouLayerId then - sEndSouLayer = EgtGetName( nEndSouLayerId) - end - until not nEndSouId or not nEndSouLayerId or sEndSouLayer == WIN_BASESPLIT - if nEndSouId and nEndSouLayerId and sEndSouLayer == WIN_BASESPLIT then + sEndSouName = EgtGetName( nEndSouId or GDB_ID.NULL) + until not nEndSouId or sEndSouName == WIN_SPLIT + if sEndSouName == WIN_SPLIT then -- recupero vettore tangente nel punto medio della curva di contorno local ptMidEnd = EgtMP( nEndId) local vtMidEnd = EgtMV( nEndId) @@ -1406,7 +1377,7 @@ local function MakeSolidByExtrusion( nGeoId, nOutlineId, nMainProfileId, nStartP local dMidStartOnEndSou = EgtCurveParamAtPoint( nEndSouId, ptMidEnd) local vtMidEndSou = EgtUV( nEndSouId, dMidStartOnEndSou, -1) -- se i due vettori non sono orientati nella stessa direzione - if not AreSameVectorExact( vtMidEnd, vtMidEndSou) then + if not AreSameVectorApprox( vtMidEnd, vtMidEndSou) then -- ruoto di 180 gradi il profilo local frEndProfileS = EgtFR( nEndProfileFrameId, GDB_ID.ROOT) EgtRotate( nEndProfileId, frEndProfileS:getOrigin(), frEndProfileS:getVersY(), 180, GDB_RT.GLOB) @@ -1448,7 +1419,7 @@ local function CalSplitDowel( nSplitLayerId, nOutlineId, nProfileType, nPartId) if not ptInt then return end - + -- se interseca, recupero il profilo dello split local nOrigSplitProfileId = GetOutlineProfileId( nSplitId, false) @@ -1505,9 +1476,12 @@ local function CalSplitDowel( nSplitLayerId, nOutlineId, nProfileType, nPartId) elseif nProfileType == WIN_PRF.SPLIT then local sProfileType = EgtGetInfo( nOutlineId, WIN_PROFILETYPE) if sProfileType == WIN_SASH_HORIZONTAL then - sStart = WIN_DWL_HORIZONTALSPLITPERPSTART - sEnd = WIN_DWL_HORIZONTALSPLITPERPEND - -- sta sempre leggendo l'informazione corretta? ( cfr dowel per start ed end nella crezione del solido) + -- se poggia sul controprofilo CntrIn2 leggo le info dello split orizzontale, altrimenti vanno bene quelle del top + -- ( cfr AddStartDowels e AddEndDowels) + if AreSamePointApprox( ptInt, EgtSP( nSplitId)) then + sStart = WIN_DWL_HORIZONTALSPLITPERPSTART + sEnd = WIN_DWL_HORIZONTALSPLITPERPEND + end elseif sProfileType == WIN_SASH_VERTICAL then sStart = WIN_DWL_VERTICALSPLITPERPSTART sEnd = WIN_DWL_VERTICALSPLITPERPEND @@ -1880,7 +1854,7 @@ local function CreateStripFromOutline( nAreaId, nOutlineId) end --------------------------------------------------------------------- --- funzione che cicla ricorsivamente su aree e sottaree per calcolare i pezzi +-- funzione che cicla ricorsivamente su aree e sottoaree per calcolare i pezzi local function CalculateAreaParts( nAreaId) local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i')