diff --git a/LuaLibs/AddManData.lua b/LuaLibs/AddManData.lua index 63d780b..8179165 100644 --- a/LuaLibs/AddManData.lua +++ b/LuaLibs/AddManData.lua @@ -196,7 +196,6 @@ KEY_MAX_SLICES_NBR = 'MaxSlicesNumber' KEY_SLICE_NBR = 'SliceNbr' KEY_SLICE_DIR = 'SliceDir' KEY_SLICE_POS = 'SlicePos' -KEY_SLICE_DELTAZ = 'DeltaZ' KEY_ZIG_ZAG_INFILL = 'ZigZagInfill' KEY_ZIG_ZAG_DIR = 'ZigZagDir' KEY_INVERTED_CRV = 'InvertedCrv' @@ -204,6 +203,7 @@ KEY_CLOSED_CRV = 'ClosedCrv' KEY_ASSOCIATED_SURF = 'AssociatedSurf' KEY_ASSOCIATED_CRVS = 'AssociatedCrvs' KEY_ORIGINAL_SURF = 'OriginalSurf' +KEY_ORIGINAL_SOLID = 'OriginalSolid' KEY_HAS_SOLIDS = 'Solids' KEY_BOX_MIN_Z = 'PartBoxMinZ' KEY_ORIGINAL_START_POINT = 'OriginalStartPoint' @@ -307,7 +307,6 @@ RIB_TYPE = { --------------------------------------------------------------------- TABLE = 'Table' PART = 'Part' -ORIGINAL_SOLID = 'OriginalSolid' PRINT_SOLID = 'PrintSolid' LAY_MACH_START = 'MachStart' LAY_RIBS = 'Ribs' diff --git a/LuaLibs/CalcPaths.lua b/LuaLibs/CalcPaths.lua index 49ea9f3..0a76a15 100644 --- a/LuaLibs/CalcPaths.lua +++ b/LuaLibs/CalcPaths.lua @@ -358,26 +358,23 @@ end -------------------------------------------------------------------- ------------------------- INFILL ----------------------------------- -------------------------------------------------------------------- -local function CalcInfillPaths( nLayId, nInfillGrp, LayerParams) +local function CalcInfillPaths( nCrvGrp, nInfillGrp, LayerParams) if not nInfillGrp then return end - - -- recupero le curve di infill - local vIds = EgtGetAllInGroup( nInfillGrp) - if not vIds or #vIds == 0 then return end - - -- scorro i gruppi di curve - local vCrvGrps = EgtGetNameInGroup( nLayId, CONTOUR_GRP .. '*') - for i = 1, #vCrvGrps do + + -- recupero le curve di infill legate al solido del CrvGrp corrente + local nOrigStm = EgtGetInfo( nCrvGrp, KEY_ORIGINAL_SOLID, 'i') + local vIds = EgtGetNameInGroup( nInfillGrp, INFILL_CRV .. tostring( nOrigStm) .. '*') or {} + if #vIds > 0 then -- creo il gruppo per infill - local nInfillPathGrp = EgtGroup( vCrvGrps[i]) + local nInfillPathGrp = EgtGroup( nCrvGrp) EgtSetName( nInfillPathGrp, INFILL_GRP) EgtSetStatus( nInfillPathGrp, GDB_ST.OFF) EgtSetInfo( nInfillPathGrp, KEY_FILL_TYPE, LayerParams.nInfillType) -- recupero la superficie occupata dalle shell - local nSrfBase = EgtGetFirstNameInGroup( vCrvGrps[i], TOT_SHELL_TRIM_SURF) + local nSrfBase = EgtGetFirstNameInGroup( nCrvGrp, TOT_SHELL_TRIM_SURF) if not nSrfBase then -- se non esiste non c'è spazio per infill EgtOutLog( 'Warning : Infill not possibile (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths') @@ -395,10 +392,10 @@ local function CalcInfillPaths( nLayId, nInfillGrp, LayerParams) EgtOutLog( 'Warning : Infill without correct overlap (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths') end - for i = 1, #vIds do - local nNewId = EgtCopyGlob( vIds[i], nInfillPathGrp) + for j = 1, #vIds do + local nNewId = EgtCopyGlob( vIds[j], nInfillPathGrp) -- eventuale inversione della curva per link - if LayerParams.bInfillLink and i % 2 == 0 then + if LayerParams.bInfillLink and j % 2 == 0 then EgtInvertCurve( nNewId) UpdateInvertInfo( nNewId) end @@ -641,13 +638,17 @@ local function GetZigZagDirection( nSrfId, nBorderSurf, dStrand, nGrp, frLoc, nT local vtDir local sInfoKey = KEY_ZIG_ZAG_DIR + -- l'info è legata all'id del solido if nType == TYPE.AUX_SOLID then - -- l'info è legata all'id del solido local vsSolidName = EgtSplitString( sName, '_') local nAuxSolidGrp = EgtGetFirstNameInGroup( nSliceLayId, AUX_SOLIDS_GRP) local nOrigCrvId = EgtGetFirstNameInGroup( nAuxSolidGrp, vsSolidName[1]) local sOrigSolidId = EgtGetInfo( nOrigCrvId, KEY_ORIGINAL_SURF) sInfoKey = sInfoKey .. '_' .. sOrigSolidId + else + local nCrvGrp = EgtGetParent( nGrp) + local sOrigSolidId = EgtGetInfo( nCrvGrp, KEY_ORIGINAL_SOLID) + sInfoKey = sInfoKey .. '_' .. sOrigSolidId end -- controllo se info già presente sul layer per altri chunk @@ -703,62 +704,57 @@ local function ComputeZigZagSolidFill( nSrf, dStrand, sName, nType, nGrp, nBorde end ------------------------------------------------------------------ -local function CalcSolidFillPath( nLayId, LayerParams, nStartLay, nFillType) +local function CalcSolidFillPath( nCrvGrp, nLayId, LayerParams, nStartLay, nFillType) - -- scorro i gruppi di curve - local vCrvGrps = EgtGetNameInGroup( nLayId, CONTOUR_GRP .. '*') - for i = 1, #vCrvGrps do - - -- creo il gruppo per infill - local nInfillPathGrp = EgtGroup( vCrvGrps[i]) - EgtSetName( nInfillPathGrp, INFILL_GRP) - EgtSetStatus( nInfillPathGrp, GDB_ST.OFF) - EgtSetInfo( nInfillPathGrp, KEY_FILL_TYPE, nFillType) - - -- recupero la superficie occupata dalle shell - local nSrfBase = EgtGetFirstNameInGroup( vCrvGrps[i], TOT_SHELL_TRIM_SURF) - if not nSrfBase then - -- se non esiste non c'è spazio per solid fill + -- creo il gruppo per infill + local nInfillPathGrp = EgtGroup( nCrvGrp) + EgtSetName( nInfillPathGrp, INFILL_GRP) + EgtSetStatus( nInfillPathGrp, GDB_ST.OFF) + EgtSetInfo( nInfillPathGrp, KEY_FILL_TYPE, nFillType) + + -- recupero la superficie occupata dalle shell + local nSrfBase = EgtGetFirstNameInGroup( nCrvGrp, TOT_SHELL_TRIM_SURF) + if not nSrfBase then + -- se non esiste non c'è spazio per solid fill + EgtOutLog( 'Warning : SolidFill not possibile (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths') + else + -- calcolo la superficie da riempire + local nSrfToFill, bNoOverlap = ComputeTrimSurf( nSrfBase, nInfillPathGrp, LayerParams.dInfillStrand, LayerParams.dInfillOverlap) + if not nSrfToFill then + -- errore + EgtOutLog( 'Error : creation of SolidFill region failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths') + table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : creation of SolidFill region failed') + elseif nSrfToFill == GDB_ID.NULL then EgtOutLog( 'Warning : SolidFill not possibile (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths') else - -- calcolo la superficie da riempire - local nSrfToFill, bNoOverlap = ComputeTrimSurf( nSrfBase, nInfillPathGrp, LayerParams.dInfillStrand, LayerParams.dInfillOverlap) - if not nSrfToFill then - -- errore - EgtOutLog( 'Error : creation of SolidFill region failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths') - table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : creation of SolidFill region failed') - elseif nSrfToFill == GDB_ID.NULL then - EgtOutLog( 'Warning : SolidFill not possibile (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths') - else - if bNoOverlap then - EgtOutLog( 'Warning : SolidFill without correct overlap (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths') - end - - -- distanza tra passate tenendo conto dell'overlap indicato - local dDist = ( 1 - LayerParams.dInfillStrandOverlap / 100) * LayerParams.dInfillStrand - -- inserisco il riempimento - if nFillType == FILL_TYPE.OFFSET then - -- recupero le shell precedenti dal PathGrp - local nPathGrp = EgtGetFirstNameInGroup( vCrvGrps[i], PATH_GRP) - local nLast = EgtGetLastNameInGroup( nPathGrp, SHELL_CRV .. '*') or EgtGetLastNameInGroup( nPathGrp, EXTRA_SHELL_CRV .. '*') - local vOldIds = EgtGetNameInGroup( nPathGrp, EgtGetName( nLast)) - if not ComputeOffsetShells( nSrfToFill, dDist, INFILL_CRV, TYPE.INFILL, nInfillPathGrp, nStartLay, vOldIds) then - EgtOutLog( 'Error : creation of SolidFill failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths') - table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : creation of SolidFill failed') - end - elseif nFillType == FILL_TYPE.ZIGZAG then - ComputeZigZagSolidFill( nSrfToFill, dDist, INFILL_CRV, TYPE.INFILL, nInfillPathGrp, nil, nLayId) - end - - -- avendo riempito la regione, la TotShellTrimSurf non deve esistere - EgtErase( nSrfBase) + if bNoOverlap then + EgtOutLog( 'Warning : SolidFill without correct overlap (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths') end + + -- distanza tra passate tenendo conto dell'overlap indicato + local dDist = ( 1 - LayerParams.dInfillStrandOverlap / 100) * LayerParams.dInfillStrand + -- inserisco il riempimento + if nFillType == FILL_TYPE.OFFSET then + -- recupero le shell precedenti dal PathGrp + local nPathGrp = EgtGetFirstNameInGroup( nCrvGrp, PATH_GRP) + local nLast = EgtGetLastNameInGroup( nPathGrp, SHELL_CRV .. '*') or EgtGetLastNameInGroup( nPathGrp, EXTRA_SHELL_CRV .. '*') + local vOldIds = EgtGetNameInGroup( nPathGrp, EgtGetName( nLast)) + if not ComputeOffsetShells( nSrfToFill, dDist, INFILL_CRV, TYPE.INFILL, nInfillPathGrp, nStartLay, vOldIds) then + EgtOutLog( 'Error : creation of SolidFill failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths') + table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : creation of SolidFill failed') + end + elseif nFillType == FILL_TYPE.ZIGZAG then + ComputeZigZagSolidFill( nSrfToFill, dDist, INFILL_CRV, TYPE.INFILL, nInfillPathGrp, nil, nLayId) + end + + -- avendo riempito la regione, la TotShellTrimSurf non deve esistere + EgtErase( nSrfBase) end - - -- se gruppo vuoto lo cancello - if not EgtGetFirstInGroup( nInfillPathGrp) then - EgtErase( nInfillPathGrp) - end + end + + -- se gruppo vuoto lo cancello + if not EgtGetFirstInGroup( nInfillPathGrp) then + EgtErase( nInfillPathGrp) end end @@ -4261,7 +4257,7 @@ local function ComputeAuxSolidsGenericInfill( nSrf, dStrand, sName, nPathGrp, nS end -------------------------------------------------------------------- -local function CalcAuxSolidsPaths( nSliceGrp, nSolidGrp, LayerParams, nStartLay) +local function CalcAuxSolidsPaths( nCrvGrp, nSliceGrp, nSolidGrp, LayerParams, nStartLay) -- recupero i solidi ausiliari dividendoli per nome local vSolidIds = {} @@ -4273,125 +4269,117 @@ local function CalcAuxSolidsPaths( nSliceGrp, nSolidGrp, LayerParams, nStartLay) nFirst = EgtGetNextName( vIds[#vIds], AUX_SOLIDS_CRV .. '*') end - -- scorro i gruppi di curve - local nCrvGrp = EgtGetFirstNameInGroup( nSliceGrp, CONTOUR_GRP .. '*') - while nCrvGrp do - - -- creo o svuoto il gruppo per i solidi ausiliari - local nSolidPathGrp = EgtGetFirstNameInGroup( nCrvGrp, AUX_SOLIDS_GRP) - if not nSolidPathGrp then - nSolidPathGrp = EgtGroup( nCrvGrp) - EgtSetName( nSolidPathGrp, AUX_SOLIDS_GRP) - EgtSetStatus( nSolidPathGrp, GDB_ST.OFF) - else - EgtEmptyGroup( nSolidPathGrp) - end + -- creo o svuoto il gruppo per i solidi ausiliari + local nSolidPathGrp = EgtGetFirstNameInGroup( nCrvGrp, AUX_SOLIDS_GRP) + if not nSolidPathGrp then + nSolidPathGrp = EgtGroup( nCrvGrp) + EgtSetName( nSolidPathGrp, AUX_SOLIDS_GRP) + EgtSetStatus( nSolidPathGrp, GDB_ST.OFF) + else + EgtEmptyGroup( nSolidPathGrp) + end - -- creo le superfici con cui fare i trim - local nSrfBase = EgtGetFirstNameInGroup( nCrvGrp, TOT_SHELL_TRIM_SURF) - if not nSrfBase then - EgtOutLog( 'Warning : AuxSolids not possible (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths') - else + -- creo le superfici con cui fare i trim + local nSrfBase = EgtGetFirstNameInGroup( nCrvGrp, TOT_SHELL_TRIM_SURF) + if not nSrfBase then + EgtOutLog( 'Warning : AuxSolids not possible (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths') + else - for i = 1, #vSolidIds do - -- creo la flat region corrispondente al solido ausiliario - local sName = EgtGetName( vSolidIds[i][1]) - local dStrand = EgtGetInfo( vSolidIds[i][1], KEY_AUX_SOLIDS_STRAND, 'd') - local dOverlap = EgtGetInfo( vSolidIds[i][1], KEY_AUX_SOLIDS_OVERLAP, 'd') - local nOrigSurf = EgtGetInfo( vSolidIds[i][1], KEY_ORIGINAL_SURF, 'i') - local nInfillType = EgtGetInfo( vSolidIds[i][1], KEY_AUX_SOLIDS_INFILL, 'i') - local bInfillLink = EgtGetInfo( vSolidIds[i][1], KEY_AUX_SOLIDS_INFILL_LINK, 'b') - local nShells = EgtGetInfo( vSolidIds[i][1], KEY_AUX_SOLIDS_SHELLS_NBR, 'i') - if nInfillType == FILL_TYPE.OFFSET then - -- realizzo le shells insieme al riempimento - nShells = 0 - end - - local nSrfId = EgtSurfFlatRegion( nSolidPathGrp, vSolidIds[i]) - if nSrfId then - EgtSetName( nSrfId, AUX_SOLIDS_SRF) - -- calcolo superficie con cui fare trim - local nTrimSurf, bNoOverlap = ComputeTrimSurf( nSrfBase, nSolidPathGrp, dStrand, dOverlap) - if not nTrimSurf then - EgtOutLog( 'Error : creation of AuxSolid region failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths') - table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : creation of AuxSolid region failed') - elseif nTrimSurf == GDB_ID.NULL then - EgtOutLog( 'Warning : AuxSolids not possible (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths') - else - if bNoOverlap then - EgtOutLog( 'Warning : AuxSolids without correct overlap (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths') - end - - -- trim con la superficie di offset - EgtSurfFrIntersect( nSrfId, nTrimSurf) - - local nFirst, nCnt = EgtExplodeSurf( nSrfId) - for j = 0, nCnt - 1 do - local sNewName = sName .. EgtIf( j == 0, '', '_' .. tostring( j)) - - -- calcolo shells - if not ComputeOffsetShells( nFirst + j, dStrand, sNewName, TYPE.AUX_SOLID, nSolidPathGrp, nStartLay, nil, nShells) then - EgtOutLog( 'Error : creation of AuxSolid shells failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths') - table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : creation of AuxSolid shells failed') - end - - -- calcolo la superficie per il riempimento - local nSrfFill - if nShells > 0 then - local dOffs = ( nShells - dOverlap / 100) * dStrand - nSrfFill = ComputeSurfOffset( nFirst + j, nSolidPathGrp, - dOffs) - if not nSrfFill then - EgtOutLog( 'Error : creation of AuxSolid infill region failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths') - table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : creation of AuxSolid infill region failed') - elseif nSrfFill == GDB_ID.NULL then - EgtOutLog( 'Warning : AuxSolids infill not possible (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths') - end - else - -- la superficie per il riempimento è la surf del solido - nSrfFill = nFirst + j - end - - -- riempimento - if nInfillType == FILL_TYPE.OFFSET then - -- recupero le shells - if not ComputeOffsetShells( nSrfFill, dStrand, sNewName, TYPE.AUX_SOLID, nSolidPathGrp, nStartLay) then - EgtOutLog( 'Error : creation of AuxSolid offset infill failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths') - table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : creation of AuxSolid offset infill failed') - end - elseif nInfillType == FILL_TYPE.ZIGZAG then - ComputeZigZagSolidFill( nSrfFill, dStrand, sNewName, TYPE.AUX_SOLID, nSolidPathGrp, EgtIf( nShells == 0, nTrimSurf, nil), nSliceGrp) - if nShells == 0 then - -- aggiungo eventuale passata extra - AddExtraZigZag( nSrfFill, sNewName, dStrand, nSolidPathGrp, nTrimSurf) - end - elseif nInfillType ~= FILL_TYPE.NONE then - ComputeAuxSolidsGenericInfill( nSrfFill, dStrand, sNewName, nSolidPathGrp, nStartLay, nOrigSurf, dOverlap, nSolidGrp, bInfillLink) - end - - -- aggiorno la superficie di trim con il solido ausiliario - if nShells == 0 and nInfillType == FILL_TYPE.ZIGZAG then - -- gestione speciale perchè non è detto che le passate corrispondano esattamente al solido - UpdateTrimSurfWithAuxSolidsZigZag( nSolidPathGrp, sNewName, nSrfBase, dStrand, nFirst + j) - else - UpdateTrimSurfWithAuxSolidsOffset( nFirst + j, nSrfBase, dStrand, nSolidPathGrp) - end - - end - end - else + for i = 1, #vSolidIds do + -- creo la flat region corrispondente al solido ausiliario + local sName = EgtGetName( vSolidIds[i][1]) + local dStrand = EgtGetInfo( vSolidIds[i][1], KEY_AUX_SOLIDS_STRAND, 'd') + local dOverlap = EgtGetInfo( vSolidIds[i][1], KEY_AUX_SOLIDS_OVERLAP, 'd') + local nOrigSurf = EgtGetInfo( vSolidIds[i][1], KEY_ORIGINAL_SURF, 'i') + local nInfillType = EgtGetInfo( vSolidIds[i][1], KEY_AUX_SOLIDS_INFILL, 'i') + local bInfillLink = EgtGetInfo( vSolidIds[i][1], KEY_AUX_SOLIDS_INFILL_LINK, 'b') + local nShells = EgtGetInfo( vSolidIds[i][1], KEY_AUX_SOLIDS_SHELLS_NBR, 'i') + if nInfillType == FILL_TYPE.OFFSET then + -- realizzo le shells insieme al riempimento + nShells = 0 + end + + local nSrfId = EgtSurfFlatRegion( nSolidPathGrp, vSolidIds[i]) + if nSrfId then + EgtSetName( nSrfId, AUX_SOLIDS_SRF) + -- calcolo superficie con cui fare trim + local nTrimSurf, bNoOverlap = ComputeTrimSurf( nSrfBase, nSolidPathGrp, dStrand, dOverlap) + if not nTrimSurf then EgtOutLog( 'Error : creation of AuxSolid region failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths') table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : creation of AuxSolid region failed') + elseif nTrimSurf == GDB_ID.NULL then + EgtOutLog( 'Warning : AuxSolids not possible (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths') + else + if bNoOverlap then + EgtOutLog( 'Warning : AuxSolids without correct overlap (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths') + end + + -- trim con la superficie di offset + EgtSurfFrIntersect( nSrfId, nTrimSurf) + + local nFirst, nCnt = EgtExplodeSurf( nSrfId) + for j = 0, nCnt - 1 do + local sNewName = sName .. EgtIf( j == 0, '', '_' .. tostring( j)) + + -- calcolo shells + if not ComputeOffsetShells( nFirst + j, dStrand, sNewName, TYPE.AUX_SOLID, nSolidPathGrp, nStartLay, nil, nShells) then + EgtOutLog( 'Error : creation of AuxSolid shells failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths') + table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : creation of AuxSolid shells failed') + end + + -- calcolo la superficie per il riempimento + local nSrfFill + if nShells > 0 then + local dOffs = ( nShells - dOverlap / 100) * dStrand + nSrfFill = ComputeSurfOffset( nFirst + j, nSolidPathGrp, - dOffs) + if not nSrfFill then + EgtOutLog( 'Error : creation of AuxSolid infill region failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths') + table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : creation of AuxSolid infill region failed') + elseif nSrfFill == GDB_ID.NULL then + EgtOutLog( 'Warning : AuxSolids infill not possible (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths') + end + else + -- la superficie per il riempimento è la surf del solido + nSrfFill = nFirst + j + end + + -- riempimento + if nInfillType == FILL_TYPE.OFFSET then + -- recupero le shells + if not ComputeOffsetShells( nSrfFill, dStrand, sNewName, TYPE.AUX_SOLID, nSolidPathGrp, nStartLay) then + EgtOutLog( 'Error : creation of AuxSolid offset infill failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths') + table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : creation of AuxSolid offset infill failed') + end + elseif nInfillType == FILL_TYPE.ZIGZAG then + ComputeZigZagSolidFill( nSrfFill, dStrand, sNewName, TYPE.AUX_SOLID, nSolidPathGrp, EgtIf( nShells == 0, nTrimSurf, nil), nSliceGrp) + if nShells == 0 then + -- aggiungo eventuale passata extra + AddExtraZigZag( nSrfFill, sNewName, dStrand, nSolidPathGrp, nTrimSurf) + end + elseif nInfillType ~= FILL_TYPE.NONE then + ComputeAuxSolidsGenericInfill( nSrfFill, dStrand, sNewName, nSolidPathGrp, nStartLay, nOrigSurf, dOverlap, nSolidGrp, bInfillLink) + end + + -- aggiorno la superficie di trim con il solido ausiliario + if nShells == 0 and nInfillType == FILL_TYPE.ZIGZAG then + -- gestione speciale perchè non è detto che le passate corrispondano esattamente al solido + UpdateTrimSurfWithAuxSolidsZigZag( nSolidPathGrp, sNewName, nSrfBase, dStrand, nFirst + j) + else + UpdateTrimSurfWithAuxSolidsOffset( nFirst + j, nSrfBase, dStrand, nSolidPathGrp) + end + + end end + else + EgtOutLog( 'Error : creation of AuxSolid region failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths') + table.insert( s_vErr, ' - layer ' .. EgtNumToString( s_nCurrIdx) .. ' : creation of AuxSolid region failed') end end - - -- verifico se il gruppo contine qualcosa - if not EgtGetFirstNameInGroup( nSolidPathGrp, AUX_SOLIDS_CRV .. '*') then - EgtErase( nSolidPathGrp) - end - - -- passo al gruppo di contorni successivo - nCrvGrp = EgtGetNextName( nCrvGrp, CONTOUR_GRP .. '*') + end + + -- verifico se il gruppo contine qualcosa + if not EgtGetFirstNameInGroup( nSolidPathGrp, AUX_SOLIDS_CRV .. '*') then + EgtErase( nSolidPathGrp) end end @@ -4410,8 +4398,6 @@ function CalcPaths.Exec( nPartId) -- recupero i parametri per calcolo dei path local LayerParams = GetLayerParamsForPathCalc() - local nFirstSolidLay = EgtGetInfo( s_nPartId, KEY_FIRST_SOLID_LAY, 'i') or -1 - local nLastSolidLay = EgtGetInfo( s_nPartId, KEY_LAST_SOLID_LAY, 'i') or -1 local nSlicingType = EgtGetInfo( s_nPartId, KEY_SLICING_TYPE, 'i') -- scorro tutti i suoi layer @@ -4439,6 +4425,11 @@ function CalcPaths.Exec( nPartId) local nCrvGrpId = EgtGetFirstNameInGroup( vLayIds[nIdx], CONTOUR_GRP.."*") or GDB_ID.NULL while nCrvGrpId ~= GDB_ID.NULL do + -- recupero i layer estremi con il solido + local nOrigStm = EgtGetInfo( nCrvGrpId, KEY_ORIGINAL_SOLID, 'i') + local nFirstLay = EgtGetInfo( s_nPartId, KEY_FIRST_SOLID_LAY .. tostring( nOrigStm), 'i') or -1 + local nLastLay = EgtGetInfo( s_nPartId, KEY_LAST_SOLID_LAY .. tostring( nOrigStm), 'i') or -1 + -- verifico se il path è già stato calcolato local nGrpId = EgtGetFirstNameInGroup( nCrvGrpId, PATH_GRP) or GDB_ID.NULL if nGrpId == GDB_ID.NULL then @@ -4546,29 +4537,29 @@ function CalcPaths.Exec( nPartId) ReorderExtraShells( nGrpId, nStartLay, LayerParams) end + -- gestione solidi ausiliari ( se no floor o ceil) + if nAuxSolidsGrp and nFirstLay + LayerParams.nFloorNbr <= nIdx and nIdx <= nLastLay - LayerParams.nCeilNbr then + CalcAuxSolidsPaths( nCrvGrpId, vLayIds[nIdx], nAuxSolidsGrp, LayerParams, nStartLay) + end + + -- gestione riempimenti + if LayerParams.nShellsNbr > 0 then + -- floor + if nIdx < nFirstLay + LayerParams.nFloorNbr then + CalcSolidFillPath( nCrvGrpId, vLayIds[nIdx], LayerParams, nStartLay, LayerParams.nFloorType) + -- infill + elseif nIdx <= nLastLay - LayerParams.nCeilNbr then + CalcInfillPaths( nCrvGrpId, nInfillGrp, LayerParams) + -- ceil + else + CalcSolidFillPath( nCrvGrpId, vLayIds[nIdx], LayerParams, nStartLay, LayerParams.nCeilType) + end + end + -- passo al gruppo di contorni successivo nCrvGrpId = EgtGetNextName( nCrvGrpId, CONTOUR_GRP.."*") or GDB_ID.NULL end - - -- gestione solidi ausiliari ( se no floor o ceil) - if nAuxSolidsGrp and LayerParams.nFloorNbr < nIdx and nIdx <= nLastSolidLay - LayerParams.nCeilNbr then - CalcAuxSolidsPaths( vLayIds[nIdx], nAuxSolidsGrp, LayerParams, nStartLay) - end - - -- gestione riempimenti - if LayerParams.nShellsNbr > 0 then - -- floor - if nIdx <= LayerParams.nFloorNbr then - CalcSolidFillPath( vLayIds[nIdx], LayerParams, nStartLay, LayerParams.nFloorType) - -- infill - elseif nIdx <= nLastSolidLay - LayerParams.nCeilNbr then - CalcInfillPaths( vLayIds[nIdx], nInfillGrp, LayerParams) - -- ceil - else - CalcSolidFillPath( vLayIds[nIdx], LayerParams, nStartLay, LayerParams.nCeilType) - end - end - + -- gestione costolature if nRibsGrp then CalcRibsPaths( vLayIds[nIdx], nRibsGrp, LayerParams, nStartLay, bIgnoreMergedRibs) diff --git a/LuaLibs/CalcSlices.lua b/LuaLibs/CalcSlices.lua index 15e5a5f..8b1a714 100644 --- a/LuaLibs/CalcSlices.lua +++ b/LuaLibs/CalcSlices.lua @@ -350,7 +350,7 @@ local function GetAuxSolidsParams( nId) end -------------------------------------------------------------------- -local function SlicingExtraObjects( nLay, vSlicingDir, vSlicingVal, nSlicingType, nType, sName, sNameGrp, nStmId) +local function SlicingExtraObjects( nLay, vSlicingDir, vSlicingVal, nSlicingType, nType, sName, sNameGrp, vStmIds) if not nLay then return end @@ -386,17 +386,20 @@ local function SlicingExtraObjects( nLay, vSlicingDir, vSlicingVal, nSlicingType -- taglio i setti unbounded e limitati con il solido local vEraseIds = {} - if nStmId then + if vStmIds and #vStmIds > 0 then local bLimitUnbddRibs = EgtGetInfo( s_nPartId, KEY_LIMIT_UNBDD_RIBS, 'b') or false if nType == TYPE.RIB and bLimitUnbddRibs then for i = 1, #vSliceIds do if tabParams[i][KEY_RIBS_TYPE] == RIB_TYPE.UNBOUNDED then - -- creo copia e la taglio con solido - local nCopy = EgtCopyGlob( vSliceIds[i], EgtGetParent( vSliceIds[i])) - EgtSurfTmCut( nCopy, nStmId, true, true) + -- creo copia tagliata con i solidi + local vParts = {} + for j = 1, #vStmIds do + vParts[j] = EgtCopyGlob( vSliceIds[i], EgtGetParent( vSliceIds[i])) + EgtSurfTmCut( vParts[j], vStmIds[j], true, true) + end -- lo slicing va fatto sulla copia - vSliceIds[i] = nCopy - table.insert( vEraseIds, nCopy) + vSliceIds[i] = EgtSurfTmByTriangles( EgtGetParent( vSliceIds[i]), vParts) + table.insert( vEraseIds, vSliceIds[i]) end end end @@ -548,31 +551,36 @@ local function SlicingInfill( nLay, sName, sNameGrp) -- verifico che oggetto sia trimesh local nTypeObj = EgtGetType( vInfillIds[j]) if nTypeObj == GDB_TY.SRF_MESH then + local nOrigSolid = EgtGetInfo( vInfillIds[j], KEY_ORIGINAL_SOLID, 'i') + -- slicing local nNewId, nPntCnt, nCrvCnt, nSrfCnt = EgtPlaneSurfTmInters( ptSlicing, vtSlicing, vInfillIds[j], nGrp, GDB_RT.GLOB, TOLER) - - -- rimuovo punti - for nId = nNewId, nNewId + nPntCnt -1 do - EgtErase( nId) - end - - -- concateno le curve - local vChain = {} - for nId = nNewId + nPntCnt, nNewId + nPntCnt + nCrvCnt - 1 do - table.insert( vChain, nId) - end - local nChainId, nCnt = EgtCurveCompoByChain( nGrp, vChain, ORIG(), true, GDB_RT.LOC, TOLER) - -- sistemo le curve - for nId = nChainId, nChainId + nCnt - 1 do - EgtSetName( nId, sName .. EgtNumToString(j)) - EgtSetInfo( nId, KEY_ORIGINAL_SURF, vInfillIds[j]) - EgtModifyCurveExtrusion( nId, vtSlicing, GDB_RT.GLOB) - EgtApproxCurve( nId, GDB_CA.ARCS, MID_TOLER) - end - - -- rimuovo superfici - for nId = nNewId + nPntCnt + nCrvCnt, nNewId + nPntCnt + nCrvCnt + nSrfCnt - 1 do - EgtErase( nId) + if nNewId then + + -- rimuovo punti + for nId = nNewId, nNewId + nPntCnt -1 do + EgtErase( nId) + end + + -- concateno le curve + local vChain = {} + for nId = nNewId + nPntCnt, nNewId + nPntCnt + nCrvCnt - 1 do + table.insert( vChain, nId) + end + local nChainId, nCnt = EgtCurveCompoByChain( nGrp, vChain, ORIG(), true, GDB_RT.LOC, TOLER) + -- sistemo le curve + for nId = nChainId, nChainId + nCnt - 1 do + local sFullName = sName .. tostring( nOrigSolid) .. '_' .. EgtNumToString( j) + EgtSetName( nId, sFullName) + EgtSetInfo( nId, KEY_ORIGINAL_SURF, vInfillIds[j]) + EgtModifyCurveExtrusion( nId, vtSlicing, GDB_RT.GLOB) + EgtApproxCurve( nId, GDB_CA.ARCS, MID_TOLER) + end + + -- rimuovo superfici + for nId = nNewId + nPntCnt + nCrvCnt, nNewId + nPntCnt + nCrvCnt + nSrfCnt - 1 do + EgtErase( nId) + end end end end @@ -594,7 +602,11 @@ local function CalcLinesInfill( nInfillGrp, nStmId, dOffsStm, frLoc, vtOffs, dDi local ptMax = b3Loc:getMax() local dZ = ptMin:getZ() - local nGrp = EgtGroup( nInfillGrp, frLoc, GDB_RT.GLOB) + -- recupero o creo il gruppo per gli infill + local nGrp = EgtGetFirstInGroup( nInfillGrp) + if not nGrp then + nGrp = EgtGroup( nInfillGrp, frLoc, GDB_RT.GLOB) + end -- calcolo la prima quota a cui tracciare la linea local dY = ptMin:getY() + vtOffs:getY() % dDist @@ -603,7 +615,8 @@ local function CalcLinesInfill( nInfillGrp, nStmId, dOffsStm, frLoc, vtOffs, dDi while dY < ptMax:getY() + GEO.EPS_SMALL do local ptS = Point3d( ptMin:getX(), dY, dZ) local ptE = Point3d( ptMax:getX(), dY, dZ) - EgtCurveCompoFromPoints( nGrp, {ptS, ptE}) + local nCrv = EgtCurveCompoFromPoints( nGrp, {ptS, ptE}) + EgtSetInfo( nCrv, KEY_ORIGINAL_SOLID, nStmId) dY = dY + dDist end end @@ -618,29 +631,37 @@ local function CalcSimpleGridInfill( nInfillGrp, nStmId, dOffsStm, frLoc, vtOffs local ptMax = b3Loc:getMax() local dZ = ptMin:getZ() + -- recupero i gruppi per le due direzioni della griglia + local nMainGrp = EgtGetFirstInGroup( nInfillGrp) + local nOtherGrp = EgtGetLastInGroup( nInfillGrp) + if not nMainGrp then + nMainGrp = EgtGroup( nInfillGrp, frLoc, GDB_RT.GLOB) + nOtherGrp = EgtGroup( nInfillGrp, frLoc, GDB_RT.GLOB) + end + -- direzione principale - local nMainGrp = EgtGroup( nInfillGrp, frLoc, GDB_RT.GLOB) local dY = ptMin:getY() + vtOffs:getY() % dDist while dY < ptMax:getY() + GEO.EPS_SMALL do local ptS = Point3d( ptMin:getX(), dY, dZ) local ptE = Point3d( ptMax:getX(), dY, dZ) - EgtCurveCompoFromPoints( nMainGrp, {ptS, ptE}) + local nCrv = EgtCurveCompoFromPoints( nMainGrp, {ptS, ptE}) + EgtSetInfo( nCrv, KEY_ORIGINAL_SOLID, nStmId) dY = dY + dDist end -- direzione secondaria ( ortogonale alla principale) - local nOtherGrp = EgtGroup( nInfillGrp, frLoc, GDB_RT.GLOB) local dX = ptMin:getX() + vtOffs:getX() % dDist while dX < ptMax:getX() + GEO.EPS_SMALL do local ptS = Point3d( dX, ptMin:getY(), dZ) local ptE = Point3d( dX, ptMax:getY(), dZ) - EgtCurveCompoFromPoints( nOtherGrp, {ptS, ptE}) + local nCrv = EgtCurveCompoFromPoints( nOtherGrp, {ptS, ptE}) + EgtSetInfo( nCrv, KEY_ORIGINAL_SOLID, nStmId) dX = dX + dDist end end -------------------------------------------------------------------- -local function CompletePatternBaseCrv( nCrvBase, dAng, dDim1, dDim2, dMinY, dMaxY) +local function CompletePatternBaseCrv( nCrvBase, dAng, dDim1, dDim2, dMinY, dMaxY, nStmId) local vtDir1 = VectorFromPolar( 1, dAng) local vtDir2 = VectorFromPolar( 1, 180 - dAng) @@ -671,11 +692,12 @@ local function CompletePatternBaseCrv( nCrvBase, dAng, dDim1, dDim2, dMinY, dMax EgtAddCurveCompoLine( nCrvBase, ptNext, false) end + EgtSetInfo( nCrvBase, KEY_ORIGINAL_SOLID, nStmId) return nCrvBase end -------------------------------------------------------------------- -local function CalcPatternCrvs( nGrp, nCrvBase, dMinX, dMaxX, dAng, dDim1, dStrand) +local function CalcPatternCrvs( nGrp, nCrvBase, dMinX, dMaxX, dAng, dDim1, dStrand, nStmId) local ptRef = EgtSP( nCrvBase) local dReflDist = dDim1 * cos( dAng) + dStrand * 0.5 @@ -685,6 +707,7 @@ local function CalcPatternCrvs( nGrp, nCrvBase, dMinX, dMaxX, dAng, dDim1, dStra local dXRefl = ptRef:getX() + dReflDist while dXRefl < dMaxX do local nCurrCrv = EgtCopyGlob( nPrevCrv, nGrp, GDB_IN.LAST_SON) + EgtSetInfo( nCurrCrv, KEY_ORIGINAL_SOLID, nStmId) -- riflessione local ptRefl = Point3d( dXRefl, ptRef:getY(), ptRef:getZ()) EgtMirror( nCurrCrv, ptRefl, X_AX()) @@ -698,6 +721,7 @@ local function CalcPatternCrvs( nGrp, nCrvBase, dMinX, dMaxX, dAng, dDim1, dStra dXRefl = ptRef:getX() - dStrand / 2 while dXRefl > dMinX do local nCurrCrv = EgtCopyGlob( nPrevCrv, nGrp, GDB_IN.FIRST_SON) + EgtSetInfo( nCurrCrv, KEY_ORIGINAL_SOLID, nStmId) -- riflessione local ptRefl = Point3d( dXRefl, ptRef:getY(), ptRef:getZ()) EgtMirror( nCurrCrv, ptRefl, X_AX()) @@ -713,7 +737,8 @@ local function CalcGridFromPattern( nInfillGrp, nStmId, dOffsStm, frRef, vtOffs, -- direzione principale local frLoc = Frame3d( frRef) frLoc:rotate( ORIG(), vtSlicing, vSlicesAng[1]) - local nMainGrp = EgtGroup( nInfillGrp, frLoc, GDB_RT.GLOB) + local vGrps = EgtGetAllInGroup( nInfillGrp) or {} + local nMainGrp = vGrps[1] or EgtGroup( nInfillGrp, frLoc, GDB_RT.GLOB) -- recupero il box del pezzo nel frame della direzione principale local b3Loc = EgtGetBBoxRef( nStmId, GDB_BB.STANDARD, frLoc) @@ -735,10 +760,10 @@ local function CalcGridFromPattern( nInfillGrp, nStmId, dOffsStm, frRef, vtOffs, pt2 = pt2 + vtDir2 * dDim1 EgtAddCurveCompoLine( nCrvBase, pt2) end - CompletePatternBaseCrv( nCrvBase, dAng, dDim1, dDim2, ptMin:getY(), ptMax:getY()) + CompletePatternBaseCrv( nCrvBase, dAng, dDim1, dDim2, ptMin:getY(), ptMax:getY(), nStmId) -- preparo le altre curve - CalcPatternCrvs( nMainGrp, nCrvBase, ptMin:getX(), ptMax:getX(), dAng, dDim1, dStrand) + CalcPatternCrvs( nMainGrp, nCrvBase, ptMin:getX(), ptMax:getX(), dAng, dDim1, dStrand, nStmId) -- calcolo centro di rotazione local dDimPattern = 2 * dDim2 + 2 * dDim1 * sin( dAng) @@ -751,7 +776,7 @@ local function CalcGridFromPattern( nInfillGrp, nStmId, dOffsStm, frRef, vtOffs, -- calcolo il nuovo riferimento local frLoc2 = Frame3d( frRef) frLoc2:rotate( ORIG(), vtSlicing, vSlicesAng[i]) - local nGrp = EgtGroup( nInfillGrp, frLoc2, GDB_RT.GLOB) + local nGrp = vGrps[i] or EgtGroup( nInfillGrp, frLoc2, GDB_RT.GLOB) -- calcolo il box del pezzo nel nuovo riferimento local b3Loc2 = EgtGetBBoxRef( nStmId, GDB_BB.STANDARD, frLoc2) @@ -763,16 +788,16 @@ local function CalcGridFromPattern( nInfillGrp, nStmId, dOffsStm, frRef, vtOffs, local nCrvBase2 = EgtCopyGlob( nCrvBase, nMainGrp) EgtRotate( nCrvBase2, ptCen, Z_AX(), vSlicesAng[i] - vSlicesAng[1]) EgtRelocateGlob( nCrvBase2, nGrp) - CompletePatternBaseCrv( nCrvBase2, dAng, dDim1, dDim2, ptMin2:getY(), ptMax2:getY()) + CompletePatternBaseCrv( nCrvBase2, dAng, dDim1, dDim2, ptMin2:getY(), ptMax2:getY(), nStmId) -- preparo le altre curve - CalcPatternCrvs( nGrp, nCrvBase2, ptMin2:getX(), ptMax2:getX(), dAng, dDim1, dStrand) + CalcPatternCrvs( nGrp, nCrvBase2, ptMin2:getX(), ptMax2:getX(), dAng, dDim1, dStrand, nStmId) end end -------------------------------------------------------------------- -local function CalcInfill( nInfillGrp, nType, dDensity, dDir, dOffsX, dOffsY, dGridOverlap, nStmId, dOffsStm, dStrand, vtSlicing) +local function CalcInfill( nInfillGrp, nType, dDensity, dDir, dOffsX, dOffsY, dGridOverlap, vStmIds, dOffsStm, dStrand, vtSlicing) -- frame locale alla direzione dell'infill local frLoc = Frame3d( ORIG(), vtSlicing) @@ -791,31 +816,33 @@ local function CalcInfill( nInfillGrp, nType, dDensity, dDir, dOffsX, dOffsY, dG dGridOverlap = 0 end - -- creo le curve di infill - if nType == FILL_TYPE.LINES then - CalcLinesInfill( nInfillGrp, nStmId, dOffsStm, frLoc, vtOffs, dDist) - - elseif nType == FILL_TYPE.GRID then - CalcSimpleGridInfill( nInfillGrp, nStmId, dOffsStm, frLoc, vtOffs, dDist) - - elseif nType == FILL_TYPE.ZIG_ZAG_GRID then - local dRealStrand = ( 1 - dGridOverlap / 100) * dStrand - local dAng = 45 - local dDim1 = ( dDist - dStrand) * sqrt(2) - local dDim2 = dRealStrand - local vSlicesAng = {-45, 45} - CalcGridFromPattern( nInfillGrp, nStmId, dOffsStm, frLoc, vtOffs, dDim1, dDim2, dAng, vSlicesAng, dRealStrand, vtSlicing) - - elseif nType == FILL_TYPE.HONEYCOMB or nType == FILL_TYPE.HONEYCOMB_GRID then - local dRealStrand = ( 1 - dGridOverlap / 100) * dStrand - local dAng = 30 - local dDim1 = ( dDist - dStrand) / cos(30) - local dDim2 = dDim1 + sqrt(3) * dRealStrand - local vSlicesAng = EgtIf( nType == FILL_TYPE.HONEYCOMB, {0}, {0, 60, 120}) - CalcGridFromPattern( nInfillGrp, nStmId, dOffsStm, frLoc, vtOffs, dDim1, dDim2, dAng, vSlicesAng, dRealStrand, vtSlicing) + -- creo le curve di infill per ogni solido + for i = 1, #vStmIds do + if nType == FILL_TYPE.LINES then + CalcLinesInfill( nInfillGrp, vStmIds[i], dOffsStm, frLoc, vtOffs, dDist) + + elseif nType == FILL_TYPE.GRID then + CalcSimpleGridInfill( nInfillGrp, vStmIds[i], dOffsStm, frLoc, vtOffs, dDist) + + elseif nType == FILL_TYPE.ZIG_ZAG_GRID then + local dRealStrand = ( 1 - dGridOverlap / 100) * dStrand + local dAng = 45 + local dDim1 = ( dDist - dStrand) * sqrt(2) + local dDim2 = dRealStrand + local vSlicesAng = {-45, 45} + CalcGridFromPattern( nInfillGrp, vStmIds[i], dOffsStm, frLoc, vtOffs, dDim1, dDim2, dAng, vSlicesAng, dRealStrand, vtSlicing) + + elseif nType == FILL_TYPE.HONEYCOMB or nType == FILL_TYPE.HONEYCOMB_GRID then + local dRealStrand = ( 1 - dGridOverlap / 100) * dStrand + local dAng = 30 + local dDim1 = ( dDist - dStrand) / cos(30) + local dDim2 = dDim1 + sqrt(3) * dRealStrand + local vSlicesAng = EgtIf( nType == FILL_TYPE.HONEYCOMB, {0}, {0, 60, 120}) + CalcGridFromPattern( nInfillGrp, vStmIds[i], dOffsStm, frLoc, vtOffs, dDim1, dDim2, dAng, vSlicesAng, dRealStrand, vtSlicing) + end end - -- calcolo le superifici a partire dalle curve ( nei casi standard è semplice estrusione) + -- calcolo le superfici a partire dalle curve ( nei casi standard è semplice estrusione) local vGrps = EgtGetAllInGroup( nInfillGrp) local vCrvs = {} for i = 1, #vGrps do @@ -825,14 +852,16 @@ local function CalcInfill( nInfillGrp, nType, dDensity, dDir, dOffsX, dOffsY, dG local ptLast = EgtGetInfo( nLastLay, KEY_SLICE_POS, 'p') local dZ = ( ptLast - ORIG()) * vtSlicing for i = 1, #vCrvs do - EgtSurfTmByExtrusion( EgtGetParent( vCrvs[i]), vCrvs[i], ( dZ + 100) * vtSlicing, 0.05, GDB_RT.GLOB) + local nStmId = EgtSurfTmByExtrusion( EgtGetParent( vCrvs[i]), vCrvs[i], ( dZ + 100) * vtSlicing, 0.05, GDB_RT.GLOB) + local nOrigSolid = EgtGetInfo( vCrvs[i], KEY_ORIGINAL_SOLID, 'i') + EgtSetInfo( nStmId, KEY_ORIGINAL_SOLID, nOrigSolid) end EgtErase( vCrvs) end -------------------------------------------------------------------- -local function PrepareInfill( nStmId, vtSlicing) +local function PrepareInfill( vStmIds, vtSlicing) -- verifco se richiesto infill local nShells = EgtGetInfo( s_nPartId, KEY_SHELLS_NBR, 'i') @@ -860,7 +889,7 @@ local function PrepareInfill( nStmId, vtSlicing) EgtSetStatus( nInfillGrp, GDB_ST.OFF) -- calcolo infill - CalcInfill( nInfillGrp, nType, dDensity, dDir, dOffsX, dOffsY, dGridOverlap, nStmId, dOffsStm, dStrand, vtSlicing) + CalcInfill( nInfillGrp, nType, dDensity, dDir, dOffsX, dOffsY, dGridOverlap, vStmIds, dOffsStm, dStrand, vtSlicing) -- aggiungo allo slicing SlicingInfill( nInfillGrp, INFILL_CRV, INFILL_GRP) @@ -896,11 +925,10 @@ local function PrepareAuxSolidsInfill( nSolidsLay, vtSlicing) EgtSetStatus( nInfillGrp, GDB_ST.OFF) -- calcolo infill - CalcInfill( nInfillGrp, nType, dDensity, dDir, dOffsX, dOffsY, dGridOverlap, vIds[i], 0, dStrand, vtSlicing) + CalcInfill( nInfillGrp, nType, dDensity, dDir, dOffsX, dOffsY, dGridOverlap, {vIds[i]}, 0, dStrand, vtSlicing) -- aggiungo allo slicing - local sName = AUX_SOLIDS_INFILL_CRV .. EgtNumToString( vIds[i]) .. '_' - SlicingInfill( nInfillGrp, sName, AUX_SOLIDS_GRP) + SlicingInfill( nInfillGrp, AUX_SOLIDS_INFILL_CRV, AUX_SOLIDS_GRP) end end end @@ -908,7 +936,7 @@ local function PrepareAuxSolidsInfill( nSolidsLay, vtSlicing) end -------------------------------------------------------------------- -local function ExtractRibsLoops( nRibsGrp, nStmId) +local function ExtractRibsLoops( nRibsGrp) local nLoopGrp = EgtGroup( s_nPartId) EgtSetName( nLoopGrp, RIBS_LOOP_GRP) @@ -919,7 +947,7 @@ local function ExtractRibsLoops( nRibsGrp, nStmId) for i = 1, #vIds do -- se trimesh estraggo i contorni if EgtGetType( vIds[i]) == GDB_TY.SRF_MESH then - local nCrv, nCnt = EgtExtractSurfTmLoops( vIds[i], nLoopGrp) + local nCrv, nCnt = EgtExtractSurfTmLoops( vIds[i], nLoopGrp) if nCrv then -- assegno nome che permetta di ricondurli alla superficie da cui derivano for nId = nCrv, nCrv + nCnt - 1 do @@ -1069,7 +1097,6 @@ local function SlicingNoSolid( nRibsLay, nSlicingType, dMaxH, dSliceStep, vSlici end EgtSetInfo( nLayId, KEY_SLICE_POS, ptSlicing) EgtSetInfo( nLayId, KEY_SLICE_DIR, vtSlicing) - EgtSetInfo( nLayId, KEY_SLICE_DELTAZ, dDeltaZ) if EgtProcessEvents( EgtIf( PRINT, 100, 0) + i / #vSlicingVal * 100, 0) == 1 then return false end end @@ -1101,355 +1128,382 @@ local function SlicingNoSolid( nRibsLay, nSlicingType, dMaxH, dSliceStep, vSlici end --------------------------------------------------------------------- -local function MultiPlanarSlicing( nStmId, dMaxH, vSlicingDir, vSlicingPnt) +local function MultiPlanarSlicing( vStmIds, dMaxH, vSlicingDir, vSlicingPnt) local dSliceStep = EgtGetInfo( s_nPartId, KEY_SLICE_STEP, 'd') - -- ciclo sui piani di slicing calcolati - local nFirstGrpId - local nCnt = 0 - for i = 1, #vSlicingPnt do - local vtN = vSlicingDir[i] - local ptOn = vSlicingPnt[i] - -- correzione per layer iniziale - if i == 1 then - ptOn = ptOn + DELTAZ * vtN - end - - local nGrpId = EgtGroup( s_nPartId) - if not nFirstGrpId then - nFirstGrpId = nGrpId - end - local nEntId = EgtPlaneSurfTmInters( ptOn, vtN, nStmId, nGrpId, GDB_RT.GLOB, TOLER) - -- eventuale verifica con altezza massima - if dMaxH < GEO.INFINITO then - local b3Box = EgtGetBBoxGlob( nGrpId, GDB_BB.STANDARD) - local ptMax = b3Box:getMax() + dSliceStep * vtN - if ptMax:getZ() > dMaxH + GEO.EPS_SMALL then - EgtErase( nGrpId) - break + local vLayers = {} + + -- ciclo sui solidi + for j = 1, #vStmIds do + -- ciclo sui piani di slicing calcolati + for i = 1, #vSlicingPnt do + local vtN = vSlicingDir[i] + local ptOn = vSlicingPnt[i] + -- correzione per layer iniziale + if i == 1 then + ptOn = ptOn + DELTAZ * vtN + end + + local nGrpId = EgtGroup( s_nPartId) + local nEntId = EgtPlaneSurfTmInters( ptOn, vtN, vStmIds[j], nGrpId, GDB_RT.GLOB, TOLER) + -- eventuale verifica con altezza massima + if dMaxH < GEO.INFINITO then + local b3Box = EgtGetBBoxGlob( nGrpId, GDB_BB.STANDARD) + local ptMax = b3Box:getMax() + dSliceStep * vtN + if ptMax:getZ() > dMaxH + GEO.EPS_SMALL then + EgtErase( nGrpId) + break + end + end + + if vLayers[i] then + table.insert( vLayers[i], { nId = nGrpId, nStmId = vStmIds[j]}) + else + vLayers[i] = { { nId = nGrpId, nStmId = vStmIds[j]}} + end + + -- aggiornamento progress ( per riconoscimento corretto della fase dal programma deve partire da 1) + if EgtProcessEvents( max( 1, 100 * ( ( j-1) * #vSlicingPnt + i) / #vSlicingPnt / #vStmIds), 0) == 1 then + return {} end end - nCnt = i + 1 - -- aggiornamento progress ( per riconoscimento corretto della fase dal programma deve partire da 1) - if EgtProcessEvents( max( 1, 100 * i / #vSlicingPnt), 0) == 1 then - return nFirstGrpId, -1 - end end - return nFirstGrpId, nCnt + + return vLayers end --------------------------------------------------------------------- -local function SlicingWithSolid( nStmId, nSlicingType, dMaxH, vSlicingVal, vSlicingDir) +local function SlicingWithSolid( vStmIds, nSlicingType, dMaxH, vSlicingVal, vSlicingDir) -- calcolo delle intersezioni - local nLayId, nCnt + local vLayers = {} if nSlicingType ~= SLICING_TYPE.MULTIPLANAR and nSlicingType ~= SLICING_TYPE.MULTIPLANAR_DEG45 and nSlicingType ~= SLICING_TYPE.MULTIPLANAR_HOR then if EgtProcessEvents( 1, 0) == 1 then return false end - nLayId, nCnt = EgtParPlanesSurfTmInters( ORIG(), vSlicingDir[1], vSlicingVal, nStmId, s_nPartId, GDB_RT.GLOB, TOLER) - if EgtProcessEvents( 100, 0) == 1 then return false end + for i = 1, #vStmIds do + local nLayId = EgtParPlanesSurfTmInters( ORIG(), vSlicingDir[1], vSlicingVal, vStmIds[i], s_nPartId, GDB_RT.GLOB, TOLER) + local j = 1 + while nLayId do + if vLayers[j] then + table.insert( vLayers[j], { nId = nLayId, nStmId = vStmIds[i]}) + else + vLayers[j] = { { nId = nLayId, nStmId = vStmIds[i]}} + end + j = j + 1 + nLayId = EgtGetNext( nLayId) + end + if EgtProcessEvents( i / #vStmIds * 100, 0) == 1 then return false end + end else - nLayId, nCnt = MultiPlanarSlicing( nStmId, dMaxH, vSlicingDir, vSlicingVal) - if nCnt == -1 then return false end + vLayers = MultiPlanarSlicing( vStmIds, dMaxH, vSlicingDir, vSlicingVal) + if #vLayers == 0 then return false end end - + local vPrevCen = {} - local nLayCnt = 1 - local nCounterTot = nCnt + 12 + local nCounterTot = #vLayers + 12 - local nFirstSolidLay -- primo layer che contiene il solido - local nLastSolidLay -- ultimo layer che contiene il solido + local tFirstSolidLay = {} -- primi layers che contengono i solid + local tLastSolidLay = {} -- ultimi layers che contengono i solidi -- scorro i risultati dello slicing - while nLayId do + for i = 1, #vLayers do - EgtSetInfo( nLayId, KEY_SLICE_NBR, nLayCnt) + local nLayId = vLayers[i][1].nId -- conservo il layer del primo solido + EgtSetInfo( nLayId, KEY_SLICE_NBR, i) -- ricavo punto e direzione del piano di slicing - local dDeltaZ = EgtIf( nLayCnt == 1, DELTAZ, 0) + local dDeltaZ = EgtIf( i == 1, DELTAZ, 0) local ptSlicing local vtSlicing if nSlicingType == SLICING_TYPE.MULTIPLANAR or nSlicingType == SLICING_TYPE.MULTIPLANAR_DEG45 or nSlicingType == SLICING_TYPE.MULTIPLANAR_HOR then -- nel caso multiplanare sono i dati di slicing - vtSlicing = vSlicingDir[nLayCnt] - ptSlicing = vSlicingVal[nLayCnt] + vtSlicing = vSlicingDir[i] + ptSlicing = vSlicingVal[i] else - -- nel caso standard la direzione è è l'unico elemento del vettore direzioni ( visto che è comune a tutti i piani) mentre i valori sono le distanze dai piani da quello + -- nel caso standard la direzione è l'unico elemento del vettore direzioni ( visto che è comune a tutti i piani) mentre i valori sono le distanze dai piani da quello -- posto nell'origine vtSlicing = vSlicingDir[1] - ptSlicing = ORIG() + ( vSlicingVal[nLayCnt] - dDeltaZ) * vtSlicing + ptSlicing = ORIG() + ( vSlicingVal[i] - dDeltaZ) * vtSlicing end EgtSetInfo( nLayId, KEY_SLICE_POS, ptSlicing) EgtSetInfo( nLayId, KEY_SLICE_DIR, vtSlicing) - -- verifico se necessario ricalcolo - local nId = EgtGetLastInGroup( nLayId) - local bRecalc = not nId - local vtRecalc - local nRecalc = 0 - while nId and not bRecalc do - local nType = EgtGetType( nId) - if nType == GDB_TY.SRF_MESH then - bRecalc = true - vtRecalc = EgtSurfTmFacetNormVersor( nId, 0) - elseif nType == GDB_TY.GEO_POINT then - bRecalc = true - end - nId = EgtGetPrev( nId) - end - -- eseguo eventuale ricalcolo - ::RECALC:: - if bRecalc then - nRecalc = nRecalc + 1 - EgtEmptyGroup( nLayId) - dDeltaZ = dDeltaZ + EgtIf( vtRecalc and vtRecalc:getZ() > 0, - DELTAZ, DELTAZ) - -- eseguo il ricalcolo solo a quella quota - local ptOn = ptSlicing + dDeltaZ * vtSlicing - EgtPlaneSurfTmInters( ptOn, vtSlicing, nStmId, nLayId, GDB_RT.GLOB, TOLER) - EgtOutLog( 'Warning : recalc at layer '.. EgtNumToString( nLayCnt)) - end - EgtSetInfo( nLayId, KEY_SLICE_DELTAZ, dDeltaZ) - - -- salvo i risultati nel layer - local vClosedId = {} - local vOpenId = {} - nId = EgtGetFirstInGroup( nLayId) - - while nId do - if EgtGetType( nId) == GDB_TY.GEO_POINT or EgtGetType( nId) == GDB_TY.SRF_MESH then - -- se punto o superficie lo elimino - EgtErase( nId) - else - -- correggo eventuali spostamenti in Z - if abs( dDeltaZ) > GEO.EPS_SMALL then - EgtMove( nId, - dDeltaZ * vtSlicing) - end - -- verifico presenza contorni aperti - if EgtCurveIsClosed( nId) then - table.insert( vClosedId, nId) - else - table.insert( vOpenId, nId) - end - end + -- recupero le curve di slicing dei diversi solidi e verifico se necessario ricalcolo + local vSrfId = {} + local bErr = false + local bOpen = false + local nTotCrvs = 0 + for j = 1, #vLayers[i] do - nId = EgtGetNext( nId) - end + -- recupero la superficie in analisi + local nStmId = vLayers[i][j].nStmId + + local dCurrDeltaZ = dDeltaZ + local nId = EgtGetLastInGroup( vLayers[i][j].nId) + local bRecalc = not nId + local vtRecalc + local nRecalc = 0 + while nId and not bRecalc do + local nType = EgtGetType( nId) + if nType == GDB_TY.SRF_MESH then + bRecalc = true + vtRecalc = EgtSurfTmFacetNormVersor( nId, 0) + elseif nType == GDB_TY.GEO_POINT then + bRecalc = true + end + nId = EgtGetPrev( nId) + end + -- eseguo eventuale ricalcolo + ::RECALC:: + if bRecalc then + nRecalc = nRecalc + 1 + EgtEmptyGroup( vLayers[i][j].nId) + dCurrDeltaZ = dCurrDeltaZ + EgtIf( vtRecalc and vtRecalc:getZ() > 0, - DELTAZ, DELTAZ) + -- eseguo il ricalcolo solo a quella quota + local ptOn = ptSlicing + dCurrDeltaZ * vtSlicing + EgtPlaneSurfTmInters( ptOn, vtSlicing, nStmId, vLayers[i][j].nId, GDB_RT.GLOB, TOLER) + EgtOutLog( 'Warning : recalc at layer '.. EgtNumToString( i)) + end - -- se presenti percorsi aperti, provo a concatenarli - if #vOpenId > 0 then - local nRordId, nRordCnt = EgtCurveCompoByReorder( nLayId, vOpenId, ORIG(), true, GDB_RT.LOC, BIG_TOLER) - if nRordId then - vOpenId = {} - for nId = nRordId, nRordId + nRordCnt - 1 do + -- analizzo i risultati nel layer + local vClosedId = {} + local vOpenId = {} + + nId = EgtGetFirstInGroup( vLayers[i][j].nId) + while nId do + if EgtGetType( nId) == GDB_TY.GEO_POINT or EgtGetType( nId) == GDB_TY.SRF_MESH then + -- se punto o superficie lo elimino + EgtErase( nId) + else + -- correggo eventuali spostamenti in Z + if abs( dCurrDeltaZ) > GEO.EPS_SMALL then + EgtMove( nId, - dCurrDeltaZ * vtSlicing) + end + -- verifico presenza contorni aperti if EgtCurveIsClosed( nId) then table.insert( vClosedId, nId) else table.insert( vOpenId, nId) end end + nId = EgtGetNext( nId) + end + + -- se presenti percorsi aperti, provo a concatenarli + if #vOpenId > 0 then + local nRordId, nRordCnt = EgtCurveCompoByReorder( vLayers[i][j].nId, vOpenId, ORIG(), true, GDB_RT.LOC, BIG_TOLER) + if nRordId then + vOpenId = {} + for nId = nRordId, nRordId + nRordCnt - 1 do + if EgtCurveIsClosed( nId) then + table.insert( vClosedId, nId) + else + table.insert( vOpenId, nId) + end + end + end + end + -- chiudo percorsi aperti praticamente chiusi ed elimino quelli troppo corti + for i = #vOpenId, 1, -1 do + local ptStart = EgtSP( vOpenId[i]) + local ptEnd = EgtEP( vOpenId[i]) + if EgtCurveLength( vOpenId[i]) < MIN_LEN then + EgtErase( vOpenId[i]) + table.remove( vOpenId, i) + elseif AreSamePointEpsilon( ptStart, ptEnd, BIG_TOLER) then + local ptMid = ( ptStart + ptEnd) / 2 + EgtModifyCurveStartPoint( vOpenId[i], ptMid) + EgtModifyCurveEndPoint( vOpenId[i], ptMid) + table.insert( vClosedId, vOpenId[i]) + table.remove( vOpenId, i) + end + end + + -- se necessario e possibile, torno a ricalcolo + if #vOpenId > 0 and nRecalc < 2 then + bRecalc = true + goto RECALC + end + + nTotCrvs = nTotCrvs + #vOpenId + #vClosedId + EgtSetColor( vClosedId, 'TEAL') + EgtSetColor( vOpenId, 'RED') + for j = 1, #vOpenId do + EgtRelocateGlob( vOpenId[j], nLayId) + end + if #vOpenId > 0 then + bOpen = true + end + + -- elimino percorsi chiusi di area troppo piccola e approssimo i percorsi + for j = #vClosedId, 1, -1 do + local _, _, dArea = EgtCurveArea( vClosedId[j]) + if dArea and dArea < MIN_AREA then + EgtErase( vClosedId[j]) + table.remove( vClosedId, j) + else + EgtModifyCurveExtrusion( vClosedId[j], vtSlicing, GDB_RT.GLOB) + EgtApproxCurve( vClosedId[j], GDB_CA.ARCS, MID_TOLER) + end + end + + -- costruisco le superfici a partire dai percorsi chiusi + local nSurfFR, nSrfNbr = EgtSurfFlatRegion( nLayId, vClosedId) + if nSurfFR then + + -- se slicing del solido valido aggiorno i valori dei layer estremi che lo contengono + if not tFirstSolidLay[nStmId] then tFirstSolidLay[nStmId] = i end + tLastSolidLay[nStmId] = i + + -- verifico orientamento della normale + local vtN = EgtSurfFrNormVersor( nSurfFR, GDB_ID.ROOT) + if AreOppositeVectorApprox( vtN, vtSlicing) then + EgtInvertSurf( nSurfFR) + end + -- elimino le curve originali + EgtErase( vClosedId) + -- esplodo in superfici elementari + for j = 1, nSrfNbr do + local nCurrSfrId = nSurfFR + j - 1 + EgtSetInfo( nCurrSfrId, KEY_ORIGINAL_SOLID, nStmId) + local nSfrId, nSfrCnt = EgtExplodeSurf( nCurrSfrId) + for nId = nSfrId, nSfrId + nSfrCnt - 1 do + table.insert( vSrfId, nId) + end + end + + -- se non c'è superficie verifico se vero errore + elseif not bErr then + bErr = true + -- se nessuna curva + if #vClosedId == 0 and #vOpenId == 0 then + bErr = false + -- se una sola curva, ne verifico larghezza media + elseif #vClosedId == 1 then + local dLen = EgtCurveLength( vClosedId[1]) + local _, _, dArea = EgtCurveArea( vClosedId[1]) + if not dArea or dArea / dLen < MID_TOLER then bErr = false end + end end end - -- chiudo percorsi aperti praticamente chiusi ed elimino quelli troppo corti - for i = #vOpenId, 1, -1 do - local ptStart = EgtSP( vOpenId[i]) - local ptEnd = EgtEP( vOpenId[i]) - if EgtCurveLength( vOpenId[i]) < MIN_LEN then - EgtErase( vOpenId[i]) - table.remove( vOpenId, i) - elseif AreSamePointEpsilon( ptStart, ptEnd, BIG_TOLER) then - local ptMid = ( ptStart + ptEnd) / 2 - EgtModifyCurveStartPoint( vOpenId[i], ptMid) - EgtModifyCurveEndPoint( vOpenId[i], ptMid) - table.insert( vClosedId, vOpenId[i]) - table.remove( vOpenId, i) - end - end - local bAllClosed = ( #vOpenId == 0) - -- elimino percorsi chiusi di area troppo piccola - for i = #vClosedId, 1, -1 do - local _, _, dArea = EgtCurveArea( vClosedId[i]) - if dArea and dArea < MIN_AREA then - EgtErase( vClosedId[i]) - table.remove( vClosedId, i) - end - end - - -- se necessario e possibile, torno a ricalcolo - if not bAllClosed and nRecalc < 2 then - bRecalc = true - goto RECALC - end - + -- imposto dati ausiliari - EgtSetName( nLayId, EgtIf( bAllClosed, '', '__') .. SLICE_LAYER .. EgtNumToString( nLayCnt)) - EgtSetInfo( nLayId, 'CrvCnt', #vClosedId + #vOpenId) - EgtSetColor( vClosedId or {}, 'TEAL') - EgtSetColor( vOpenId or {}, 'RED') - - -- creo flat region a partire dalle curve chiuse ottenute con lo slicing - for i = 1, #vClosedId do - EgtModifyCurveExtrusion( vClosedId[i], vtSlicing, GDB_RT.GLOB) - EgtApproxCurve( vClosedId[i], GDB_CA.ARCS, MID_TOLER) + EgtSetName( nLayId, EgtIf( bOpen or bErr, '__', '') .. SLICE_LAYER .. EgtNumToString( i)) + if bOpen or bErr then + EgtOutLog( 'Error : hole in solid (layer '.. EgtNumToString( i) ..') - CalcSlices') + table.insert( s_vErr, i) end - local nSurfFR, nSrfNbr = EgtSurfFlatRegion( nLayId, vClosedId) - - if nSurfFR then - - -- se slicing del solido valido aggiorno i valori dei layer estremi che lo contengono - if not nFirstSolidLay then nFirstSolidLay = nLayCnt end - nLastSolidLay = nLayCnt - - -- verifico orientamento della normale - local vtN = EgtSurfFrNormVersor( nSurfFR, GDB_ID.ROOT) - if AreOppositeVectorApprox( vtN, vtSlicing) then - EgtInvertSurf( nSurfFR) - end - -- elimino le curve originali - for i = 1, #vClosedId do - EgtErase( vClosedId[i]) - end - -- esplodo in superfici elementari - local vSrfId = {} - for j = 1, nSrfNbr do - local nCurrSfrId = nSurfFR + j - 1 - local nSfrId, nSfrCnt = EgtExplodeSurf( nCurrSfrId) - for nId = nSfrId, nSfrId + nSfrCnt - 1 do - table.insert( vSrfId, nId) - end - end - -- calcolo i centri delle superfici - local vCen = {} - for j = 1, #vSrfId do - local nId = vSrfId[j] - local ptCen = EgtCP( nId, GDB_ID.ROOT) - table.insert( vCen, ptCen) - end - -- ordino le superfici rispetto ai centri del layer precedente - local vOrd = {} - if #vPrevCen > 1 then - for j = 1, #vPrevCen do - local nMin = 0 - local dMinDist = GEO.INFINITO - for k = 1, #vCen do - if not ValueInArray( vOrd, k) then - local dDist = dist( vPrevCen[j], vCen[k]) - if dDist < dMinDist then - dMinDist = dDist - nMin = k - end - end - end - if nMin ~= 0 then - vOrd[j] = nMin - end - end - -- se necessario, completo il vettore di ordine - if #vOrd < #vSrfId then - for j = 1, #vSrfId do - if not ValueInArray( vOrd, j) then - table.insert( vOrd, j) + + -- costruisco i CrvGrps con le superfici di slicing + if not bOpen and not bErr and #vSrfId == 0 then + local nGrpCrv = EgtGroup( nLayId) + EgtSetName( nGrpCrv, CONTOUR_GRP .. EgtNumToString( 1)) + end + + -- calcolo i centri delle superfici + local vCen = {} + for j = 1, #vSrfId do + local ptCen = EgtCP( vSrfId[j], GDB_ID.ROOT) + table.insert( vCen, ptCen) + end + -- ordino le superfici rispetto ai centri del layer precedente + local vOrd = {} + if #vPrevCen > 1 then + for j = 1, #vPrevCen do + local nMin = 0 + local dMinDist = GEO.INFINITO + for k = 1, #vCen do + if not ValueInArray( vOrd, k) then + local dDist = dist( vPrevCen[j], vCen[k]) + if dDist < dMinDist then + dMinDist = dDist + nMin = k end end end - else - EgtSpInit() + if nMin ~= 0 then + vOrd[j] = nMin + end + end + -- se necessario, completo il vettore di ordine + if #vOrd < #vSrfId then for j = 1, #vSrfId do - EgtSpAddPoint( vCen[j]:getX(), vCen[j]:getY()) - end - vOrd = EgtSpCalculate( SHP_TY.OPEN) - EgtSpTerminate() - if not vOrd then - for j = 1, #vSrfId do - vOrd[j] = j + if not ValueInArray( vOrd, j) then + table.insert( vOrd, j) end end end - -- salvo i nuovi centri + else + EgtSpInit() for j = 1, #vSrfId do - vPrevCen[j] = vCen[vOrd[j]] + EgtSpAddPoint( vCen[j]:getX(), vCen[j]:getY()) end - -- creo i gruppi di percorsi - for j = 1, #vSrfId do - local nId = vSrfId[vOrd[j]] - -- per ogni chunk creo un gruppo di percorsi - local nGrpCrv = EgtGroup( nLayId) - EgtSetName( nGrpCrv, CONTOUR_GRP .. EgtNumToString( j, 1)) - EgtRelocateGlob( nId, nGrpCrv) - EgtSetName( nId, LAYER_SRF) - EgtSetStatus( nId, GDB_ST.OFF) - -- estraggo i contorni della superficie - local nCsId, nCsCnt = EgtExtractSurfFrChunkLoops( nId, 0, nGrpCrv) - for nId2 = nCsId, nCsId + nCsCnt - 1 do - EgtSetName( nId2, OUTER_CRV) - EgtSetStatus( nId2, GDB_ST.OFF) - EgtSetColor( nId2, 'BLACK') + vOrd = EgtSpCalculate( SHP_TY.OPEN) + EgtSpTerminate() + if not vOrd then + for j = 1, #vSrfId do + vOrd[j] = j end end - - if #vOpenId > 1 then - EgtOutLog( 'Error : hole in solid (layer '.. EgtNumToString( nLayCnt) ..') - CalcSlices') - table.insert( s_vErr, nLayCnt) - end - - else - - local bErr = true - -- se nessuna curva - if #vClosedId == 0 and #vOpenId == 0 then - bErr = false - -- se una sola curva, ne verifico larghezza media - elseif #vClosedId == 1 then - local dLen = EgtCurveLength( vClosedId[1]) - local _, _, dArea = EgtCurveArea( vClosedId[1]) - if not dArea or dArea / dLen < MID_TOLER then bErr = false end - end - - -- se vero errore lo segnalo - if bErr then - EgtOutLog( 'Error : hole in solid (layer '.. EgtNumToString( nLayCnt) ..') - CalcSlices') - table.insert( s_vErr, nLayCnt) - -- cambio nome al layer - EgtSetName( nLayId, '__' .. SLICE_LAYER .. EgtNumToString( nLayCnt)) - else - -- altrimenti creo il CrvGrp da utilizzare nel CalcPath - local nGrpCrv = EgtGroup( nLayId) - EgtSetName( nGrpCrv, CONTOUR_GRP .. EgtNumToString( 1)) + end + -- salvo i nuovi centri + for j = 1, #vSrfId do + vPrevCen[j] = vCen[vOrd[j]] + end + -- creo i gruppi di percorsi + for j = 1, #vSrfId do + local nId = vSrfId[vOrd[j]] + -- per ogni chunk creo un gruppo di percorsi + local nGrpCrv = EgtGroup( nLayId) + EgtSetName( nGrpCrv, CONTOUR_GRP .. EgtNumToString( j, 1)) + EgtRelocateGlob( nId, nGrpCrv) + EgtSetName( nId, LAYER_SRF) + EgtSetStatus( nId, GDB_ST.OFF) + local nOrigStm = EgtGetInfo( nId, KEY_ORIGINAL_SOLID, 'i') + EgtSetInfo( nGrpCrv, KEY_ORIGINAL_SOLID, nOrigStm) + -- estraggo i contorni della superficie + local nCsId, nCsCnt = EgtExtractSurfFrChunkLoops( nId, 0, nGrpCrv) + for nId2 = nCsId, nCsId + nCsCnt - 1 do + EgtSetName( nId2, OUTER_CRV) + EgtSetStatus( nId2, GDB_ST.OFF) + EgtSetColor( nId2, 'BLACK') end end + -- cancello layers di slicing inutili + for j = 2, #vLayers[i] do + EgtErase( vLayers[i][j].nId) + end + -- passo al layer successivo - if EgtProcessEvents( EgtIf( PRINT, 100, 0) + nLayCnt / nCounterTot * 100, 0) == 1 then + if EgtProcessEvents( EgtIf( PRINT, 100, 0) + i / nCounterTot * 100, 0) == 1 then -- elimino i layer non ancora analizzati - local nNext = EgtGetNext( nLayId) - while nNext do - local nCurr = nNext - nNext = EgtGetNext( nCurr) - EgtErase( nCurr) + for j = i + 1, #vLayers do + for k = 1, #vLayers[j] do + EgtErase( vLayers[j][k].nId) + end end return false end - - nLayCnt = nLayCnt + 1 - nLayId = EgtGetNext( nLayId) end -- costolature local nRibsLay = EgtGetFirstNameInGroup( s_nPartId, LAY_RIBS) - ExtractRibsLoops( nRibsLay, nStmId) - SlicingExtraObjects( nRibsLay, vSlicingDir, vSlicingVal, nSlicingType, TYPE.RIB, RIBS_CRV, RIBS_GRP, nStmId) - if EgtProcessEvents( EgtIf( PRINT, 100, 0) + ( nCnt + 3) / nCounterTot * 100, 0) == 1 then return false end + ExtractRibsLoops( nRibsLay) + SlicingExtraObjects( nRibsLay, vSlicingDir, vSlicingVal, nSlicingType, TYPE.RIB, RIBS_CRV, RIBS_GRP, vStmIds) + if EgtProcessEvents( EgtIf( PRINT, 100, 0) + ( #vLayers + 3) / nCounterTot * 100, 0) == 1 then return false end local bSpiralVase = EgtGetInfo( s_nPartId, KEY_SPIRAL_VASE, 'b') or false if not bSpiralVase then -- infill if nSlicingType ~= SLICING_TYPE.MULTIPLANAR and nSlicingType ~= SLICING_TYPE.MULTIPLANAR_DEG45 and nSlicingType ~= SLICING_TYPE.MULTIPLANAR_HOR then - PrepareInfill( nStmId, vSlicingDir[1]) + PrepareInfill( vStmIds, vSlicingDir[1]) end - if EgtProcessEvents( EgtIf( PRINT, 100, 0) + ( nCnt + 6) / nCounterTot * 100, 0) == 1 then return false end + if EgtProcessEvents( EgtIf( PRINT, 100, 0) + ( #vLayers + 6) / nCounterTot * 100, 0) == 1 then return false end -- solidi per regioni con diverso numero di passate local nShellNbrLay = EgtGetFirstNameInGroup( s_nPartId, LAY_SHELL_NBR) SlicingExtraObjects( nShellNbrLay, vSlicingDir, vSlicingVal, nSlicingType, TYPE.EXTRA_SHELL, SHELL_NBR_CRV, SHELL_NBR_GRP) - if EgtProcessEvents( EgtIf( PRINT, 100, 0) + ( nCnt + 9) / nCounterTot * 100, 0) == 1 then return false end + if EgtProcessEvents( EgtIf( PRINT, 100, 0) + ( #vLayers + 9) / nCounterTot * 100, 0) == 1 then return false end -- solidi ausiliari local nAuxSolidsLay = EgtGetFirstNameInGroup( s_nPartId, LAY_AUX_SOLIDS) @@ -1457,20 +1511,33 @@ local function SlicingWithSolid( nStmId, nSlicingType, dMaxH, vSlicingVal, vSlic if nSlicingType ~= SLICING_TYPE.MULTIPLANAR and nSlicingType ~= SLICING_TYPE.MULTIPLANAR_DEG45 and nSlicingType ~= SLICING_TYPE.MULTIPLANAR_HOR then PrepareAuxSolidsInfill( nAuxSolidsLay, vSlicingDir[1]) end - if EgtProcessEvents( EgtIf( PRINT, 100, 0) + ( nCnt + 12) / nCounterTot * 100, 0) == 1 then return false end + if EgtProcessEvents( EgtIf( PRINT, 100, 0) + ( #vLayers + 12) / nCounterTot * 100, 0) == 1 then return false end end + -- salvo info sui layers che contengono i solidi + local nFirstSolidLay = #vLayers + local nLastSolidLay = 0 + for i = 1, #vStmIds do + if tFirstSolidLay[vStmIds[i]] then + EgtSetInfo( s_nPartId, KEY_FIRST_SOLID_LAY .. tostring( vStmIds[i]), tFirstSolidLay[vStmIds[i]]) + nFirstSolidLay = min( nFirstSolidLay, tFirstSolidLay[vStmIds[i]]) + end + if tLastSolidLay[vStmIds[i]] then + EgtSetInfo( s_nPartId, KEY_LAST_SOLID_LAY .. tostring( vStmIds[i]), tLastSolidLay[vStmIds[i]]) + nLastSolidLay = max( nLastSolidLay, tLastSolidLay[vStmIds[i]]) + end + end EgtSetInfo( s_nPartId, KEY_FIRST_SOLID_LAY, nFirstSolidLay) EgtSetInfo( s_nPartId, KEY_LAST_SOLID_LAY, nLastSolidLay) -- verifico se posso eliminare gli ultimi layer senza solido. Per poterlo fare non devono contenere setti esterni o unbounded - local vLayers = EgtGetNameInGroup( s_nPartId, SLICE_LAYER .. '*') - if #vLayers ~= nLastSolidLay then + local vFinalLayers = EgtGetNameInGroup( s_nPartId, SLICE_LAYER .. '*') + if #vFinalLayers ~= nLastSolidLay then -- recupero l'ultimo layer con setti esterni local nLastLayerIdx - for i = #vLayers, nLastSolidLay + 1, - 1 do + for i = #vFinalLayers, nLastSolidLay + 1, - 1 do if nLastLayerIdx then break end - local nRibsGrp = EgtGetFirstNameInGroup( vLayers[i], RIBS_GRP) + local nRibsGrp = EgtGetFirstNameInGroup( vFinalLayers[i], RIBS_GRP) if nRibsGrp then local vRibs = EgtGetNameInGroup( nRibsGrp, RIBS_CRV .. '*') for j = 1, #vRibs do @@ -1486,8 +1553,8 @@ local function SlicingWithSolid( nStmId, nSlicingType, dMaxH, vSlicingVal, vSlic nLastLayerIdx = nLastSolidLay end -- cancello eventuali layers inutile - for i = #vLayers, nLastLayerIdx + 1, -1 do - EgtErase( vLayers[i]) + for i = #vFinalLayers, nLastLayerIdx + 1, -1 do + EgtErase( vFinalLayers[i]) end end @@ -1502,7 +1569,7 @@ local function SlicingWithSolid( nStmId, nSlicingType, dMaxH, vSlicingVal, vSlic end --------------------------------------------------------------------- -function CalcSlices.Exec( nPartId, nStmId) +function CalcSlices.Exec( nPartId, nSolidLayId) s_nPartId = nPartId @@ -1544,13 +1611,26 @@ function CalcSlices.Exec( nPartId, nStmId) nMaxSlicesNbr = GEO.INFINITO -- da gestire come caso illimitato end - -- recupero la superficie ed eventuali setti esterni/unbounded da usare come riferimenti per quote slicing + -- recupero i solidi ed eventuali setti esterni/unbounded da usare come riferimenti per quote slicing local vRefIds = {} - if nStmId then table.insert( vRefIds, nStmId) end + local vStmIds = {} + local vIds = EgtGetAllInGroup( nSolidLayId) + for i = 1, #vIds do + if EgtGetType( vIds[i]) == GDB_TY.SRF_MESH then + table.insert( vStmIds, vIds[i]) + table.insert( vRefIds, vIds[i]) + end + end + -- se spiral vase deve esserci un solo solido + local bSpiralVase = EgtGetInfo( s_nPartId, KEY_SPIRAL_VASE, 'b') or false + if bSpiralVase and #vStmIds > 1 then + EgtOutBox( "More than one solid in spiral vase mode", 'Error', 'ERROR') + return + end local nRibsLay = EgtGetFirstNameInGroup( s_nPartId, LAY_RIBS) local vRibsIds = EgtGetAllInGroup( nRibsLay) local bLimitUnbddRibs = EgtGetInfo( s_nPartId, KEY_LIMIT_UNBDD_RIBS, 'b') or false - if bLimitUnbddRibs and not nStmId then + if bLimitUnbddRibs and #vStmIds == 0 then EgtOutBox( "No solid to limit unbounded ribs!", 'Error', 'ERROR') return end @@ -1572,7 +1652,7 @@ function CalcSlices.Exec( nPartId, nStmId) local vSlicingVal = {} local vSlicingDir = {} if nSlicingType == SLICING_TYPE.MULTIPLANAR or nSlicingType == SLICING_TYPE.MULTIPLANAR_DEG45 or nSlicingType == SLICING_TYPE.MULTIPLANAR_HOR then - vSlicingVal, vSlicingDir = ComputeMultiplanarSlicingData( dSliceStep, nMaxSlicesNbr, nSlicingType, nStmId) + vSlicingVal, vSlicingDir = ComputeMultiplanarSlicingData( dSliceStep, nMaxSlicesNbr, nSlicingType, vStmIds[1]) else vSlicingVal, vSlicingDir = ComputeSlicingData( vRefIds, vtSlicing, dSliceStep, dMaxH, nMaxSlicesNbr) end @@ -1582,14 +1662,14 @@ function CalcSlices.Exec( nPartId, nStmId) -- Eseguo slicing local bOk = true - if not nStmId then + if #vStmIds == 0 then -- caso senza solido e solo setti bOk = SlicingNoSolid( nRibsLay, nSlicingType, dMaxH, dSliceStep, vSlicingVal, vSlicingDir) else -- caso con solido - bOk = SlicingWithSolid( nStmId, nSlicingType, dMaxH, vSlicingVal, vSlicingDir) + bOk = SlicingWithSolid( vStmIds, nSlicingType, dMaxH, vSlicingVal, vSlicingDir) end - + -- eventuale segnalazione errori if bOk and #s_vErr > 0 then EgtOutBox( 'Slicing Error on layers :\n' .. table.concat( s_vErr, ','), 'SlicingCalc') diff --git a/LuaLibs/CalcToolPath.lua b/LuaLibs/CalcToolPath.lua index f18576f..044f650 100644 --- a/LuaLibs/CalcToolPath.lua +++ b/LuaLibs/CalcToolPath.lua @@ -3088,7 +3088,8 @@ function CalcToolPath.Exec( nPartId) local vSpiralVaseIds = {} if LayerParams.bSpiralVase then if LayerParams.nFloorNbr > 0 then - for i = LayerParams.nFloorNbr + 1, #vLayIds do + local nFirstLay = EgtGetInfo( s_nPartId, KEY_FIRST_SOLID_LAY, 'i') + for i = LayerParams.nFloorNbr + nFirstLay, #vLayIds do table.insert( vSpiralVaseIds, vLayIds[i]) vLayIds[i] = nil end diff --git a/LuaLibs/RunCalcSolids.lua b/LuaLibs/RunCalcSolids.lua index c54ab5a..026ff51 100644 --- a/LuaLibs/RunCalcSolids.lua +++ b/LuaLibs/RunCalcSolids.lua @@ -27,7 +27,9 @@ local function GetLayerParamsForSolidCalc( nPartId) LayerParams.vtSlicing = EgtGetInfo( nPartId, KEY_SLICE_DIR, 'v') or EgtGetInfo( nPartId, 'SlicingDir', 'v') LayerParams.dStrand = EgtGetInfo( nPartId, KEY_STRAND, 'd') LayerParams.vtCorr = EgtGetInfo( nPartId, KEY_MOVED_PART2, 'v') or V_NULL() - LayerParams.nFloorNbr = EgtGetInfo( s_nPartId, KEY_FLOOR_NBR, 'i') or 0 + local nFloorNbr = EgtGetInfo( s_nPartId, KEY_FLOOR_NBR, 'i') or 0 + local nFirstSolidLay = EgtGetInfo( s_nPartId, KEY_FIRST_SOLID_LAY, 'i') or 1 + LayerParams.nFirstSpiralLay = nFloorNbr + nFirstSolidLay return LayerParams end @@ -643,7 +645,7 @@ local function CreateFullSpiralVaseMultiPlanarSolids( vIds, nSolidGrpId, LayerPa local ptProj = ptVertex + dDistCrv * LayerParams.vtSlicing local dDistPlanePrev = ( ptProj - ptSlicingPrev) * vtSlicingPrev / dCosAng local dDeltaPos - if nSliceNbr == 2 + LayerParams.nFloorNbr and dCurrLen < 0.5 * dLen then + if nSliceNbr == LayerParams.nFirstSpiralLay + 1 and dCurrLen < 0.5 * dLen then dDeltaPos = 0.5 * dDistPlanePrev else dDeltaPos = dDistPlanePrev * ( dLen - dCurrLen) / dLen @@ -651,7 +653,7 @@ local function CreateFullSpiralVaseMultiPlanarSolids( vIds, nSolidGrpId, LayerPa -- 2) per calcolare la vera altezza del solido calcolo la distanza dal toolpath precedente guardando il punto di riferimento sul percorso corrente local dNewH - if nSliceNbr == 2 + LayerParams.nFloorNbr then + if nSliceNbr == LayerParams.nFirstSpiralLay + 1 then -- il primo layer è ad altezza costante quindi è semplice distanza dal piano precedente lungo vtSlicing dNewH = ( ptProj - ptSlicingPrev) * vtSlicingPrev / dCosAng - dDeltaPos else @@ -812,7 +814,6 @@ function RunCalcSolids.Exec() s_dMultiPlanarH = min( dMaxFactor, 5) * LayerParams.dLayHeight end - local bFirst = true for nIdx = 1, #vLayIds do -- flag di interruzione perchè trovati solidi già ok local bSolidsOk = false @@ -843,13 +844,13 @@ function RunCalcSolids.Exec() if nSlicingType == SLICING_TYPE.MULTIPLANAR or nSlicingType == SLICING_TYPE.MULTIPLANAR_DEG45 or nSlicingType == SLICING_TYPE.MULTIPLANAR_HOR then LayerParams.vtSlicing = EgtGetInfo( vLayIds[nIdx], KEY_SLICE_DIR, 'v') - if LayerParams.bSpiralVase and nIdx > LayerParams.nFloorNbr then + if LayerParams.bSpiralVase and nIdx >= LayerParams.nFirstSpiralLay then local dTransitionLen = EgtGetInfo( nPartId, KEY_SPIRAL_VASE_LEN, 'd') or 0 -- a) spiral vase completo ( con transizione in altezza su tutto il layer) if dTransitionLen < GEO.EPS_SMALL then - if nIdx == LayerParams.nFloorNbr + 1 then + if nIdx == LayerParams.nFirstSpiralLay then -- il primo layer va gestito come uno spiral vase con transizione parziale ( curva a quota costante e ultimo tratto che si alza) - CreatePartialSpiralVaseMultiPlanarSolids( vIds, nSolidGrpId, LayerParams, vLayIds[nIdx], bFirst) + CreatePartialSpiralVaseMultiPlanarSolids( vIds, nSolidGrpId, LayerParams, vLayIds[nIdx], nIdx == 1) elseif nIdx == #vLayIds then -- gestione speciale per lead out e coasting CreateFullSpiralVaseMultiPlanarSolidsLastLayer( vIds, nSolidGrpId, LayerParams, vLayIds[nIdx]) @@ -863,13 +864,13 @@ function RunCalcSolids.Exec() -- ultimo layer è un multiplanare standard perchè non ha tratto finale che si alza CreateMultiPlanarSolids( vIds, nSolidGrpId, LayerParams, vLayIds[nIdx], false) else - CreatePartialSpiralVaseMultiPlanarSolids( vIds, nSolidGrpId, LayerParams, vLayIds[nIdx], bFirst) + CreatePartialSpiralVaseMultiPlanarSolids( vIds, nSolidGrpId, LayerParams, vLayIds[nIdx], nIdx == 1) end end -- c) multiplanare standard else - CreateMultiPlanarSolids( vIds, nSolidGrpId, LayerParams, vLayIds[nIdx], bFirst) + CreateMultiPlanarSolids( vIds, nSolidGrpId, LayerParams, vLayIds[nIdx], nIdx == 1) end -- slicing standard spiral vase @@ -916,14 +917,12 @@ function RunCalcSolids.Exec() CreateSolidFromCurve( vIds[i], nSolidGrpId, LayerParams, nSliceNbr) end end - bFirst = false end else bSolidsOk = true break end - - --passo al gruppo di contorni successivo + -- passo al gruppo di contorni successivo nCrvGrpId = EgtGetNextName( nCrvGrpId, CONTOUR_GRP.."*") or GDB_ID.NULL end if bSolidsOk then diff --git a/LuaLibs/RunSlicing.lua b/LuaLibs/RunSlicing.lua index bd83b45..a307d90 100644 --- a/LuaLibs/RunSlicing.lua +++ b/LuaLibs/RunSlicing.lua @@ -156,11 +156,6 @@ function RunSlicing.Exec() return end local nSolidLayId = EgtGetFirstNameInGroup( nPartId, PRINT_SOLID) - local nStmId = EgtGetFirstInGroup( nSolidLayId or GDB_ID.NULL) - if nStmId and EgtGetType( nStmId) ~= GDB_TY.SRF_MESH then - EgtOutBox( "Part without surface!", 'Warning', 'WARNING') - return - end local nRibsLayId = EgtGetFirstNameInGroup( nPartId, LAY_RIBS) local nShellNbrLay = EgtGetFirstNameInGroup( nPartId, LAY_SHELL_NBR) local nAuxSolidsLay = EgtGetFirstNameInGroup( nPartId, LAY_AUX_SOLIDS) @@ -181,7 +176,7 @@ function RunSlicing.Exec() RemoveOldTFS() -- Calcolo delle fette - local bOk = CSLICES.Exec( nPartId, nStmId) + local bOk = CSLICES.Exec( nPartId, nSolidLayId) EgtDraw() -- Calcolo dei percorsi sul centro strand in basso diff --git a/Version.lua b/Version.lua index 1d95775..4add404 100644 --- a/Version.lua +++ b/Version.lua @@ -1,4 +1,4 @@ --- Version.lua by Egaltech s.r.l. 2026/06/24 +-- Version.lua by Egaltech s.r.l. 2026/07/01 -- Gestione della versione di 3dPrinting -VERSION = '3.1f4' \ No newline at end of file +VERSION = '3.1g1' \ No newline at end of file