From f5fdb7d89e5e620a28bc5e64f3a6d951625447bc Mon Sep 17 00:00:00 2001 From: DarioS Date: Wed, 5 Jan 2022 20:47:31 +0100 Subject: [PATCH] DataWall : - migliorie per nesting - correzione scelta testa per fori orizzontali ciechi - posizionamento pezzi in Vista secondo angolo preferenziale di nesting. --- LuaLibs/WProcessDrill.lua | 2 +- LuaLibs/WallExec.lua | 15 +- NestFlipAndRotate.lua | 332 +++++++++++++++++++------------------- NestProcess.lua | 295 +++++++++++++++++++-------------- 4 files changed, 356 insertions(+), 288 deletions(-) diff --git a/LuaLibs/WProcessDrill.lua b/LuaLibs/WProcessDrill.lua index 053ba0d..f568ef2 100644 --- a/LuaLibs/WProcessDrill.lua +++ b/LuaLibs/WProcessDrill.lua @@ -257,7 +257,7 @@ function WPD.Make( Proc, nRawId, b3Raw) if dDiam < 200 then if WD.HOR_DRILL_Y_SPLIT and AreSameOrOppositeVectorApprox( vtExtr, Y_AX()) then local dExtrY = vtExtr:getY() - if abs( Proc.Flg) == 2 then + if not bOpen or abs( Proc.Flg) == 2 then sHead = EgtIf( dExtrY > 0, 'H5', 'H6') else if Proc.Box:getMax():getY() > WD.HOR_DRILL_Y_SPLIT + 10 then diff --git a/LuaLibs/WallExec.lua b/LuaLibs/WallExec.lua index d9ac9ca..e54e464 100644 --- a/LuaLibs/WallExec.lua +++ b/LuaLibs/WallExec.lua @@ -48,7 +48,7 @@ local Variant = require( 'WProcessVariant') ------------------------------------------------------------------------------------------------------------- -- *** Inserimento delle pareti nel pannello *** ------------------------------------------------------------------------------------------------------------- -function WallExec.ProcessWalls( dRawL, dRawW, dRawH, vWall, bMachGroupOk, bPartOriBL) +function WallExec.ProcessWalls( dRawL, dRawW, dRawH, vWall, bMachGroupOk, bNewProcess) -- Creazione nuovo gruppo di lavoro if not bMachGroupOk then @@ -117,8 +117,17 @@ function WallExec.ProcessWalls( dRawL, dRawW, dRawH, vWall, bMachGroupOk, bPartO -- inserisco il pezzo nel grezzo EgtDeselectPartObjs( Pz) local ptPos - if bPartOriBL then - ptPos = Point3d( vWall[i].PosX, vWall[i].PosZ, ( dRawH - PartHeight) / 2) + vtOffs + if bNewProcess then + local sNestingRef = ( WALL.NESTING_REF or WD.NESTING_CORNER) + if sNestingRef == 'TL' then + ptPos = Point3d( vWall[i].PosX, dRawW - PartWidth - vWall[i].PosZ, ( dRawH - PartHeight) / 2) + vtOffs + elseif sNestingRef == 'TR' then + ptPos = Point3d( dRawL - PartLen - vWall[i].PosX, dRawW - PartWidth - vWall[i].PosZ, ( dRawH - PartHeight) / 2) + vtOffs + elseif sNestingRef == 'BR' then + ptPos = Point3d( dRawL - PartLen - vWall[i].PosX, vWall[i].PosZ, ( dRawH - PartHeight) / 2) + vtOffs + else -- 'BL' + ptPos = Point3d( vWall[i].PosX, vWall[i].PosZ, ( dRawH - PartHeight) / 2) + vtOffs + end else local dPosH = EgtIf( vWall[i].PosY < 0.1, ( dRawH - PartHeight) / 2, vWall[i].PosY) ptPos = Point3d( dRawL - vWall[i].PosX - PartLen, vWall[i].PosZ, dPosH) + vtOffs diff --git a/NestFlipAndRotate.lua b/NestFlipAndRotate.lua index 5aa9b28..2532db8 100644 --- a/NestFlipAndRotate.lua +++ b/NestFlipAndRotate.lua @@ -152,193 +152,201 @@ end local vPartProc = WE.CollectFeatures( NFAR.PARTID) local b3Part = EgtGetBBoxGlob( NFAR.PARTID, GDB_BB.STANDARD) +local bManualFlip = EgtGetInfo( NFAR.PARTID, "MANUALFLIP", 'b') +local bManualRot = EgtGetInfo( NFAR.PARTID, "MANUALROT", 'b') -- FLIP - local FlipFeatureStates = ClassifyFlip( vPartProc, b3Part) -local bFlip --- analizzo stati flip delle feature -local nFlip0Min = 100 -local nFlip0Cnt = 0 -local nFlip1Min = 100 -local nFlip1Cnt = 0 --- calcolo punteggio minimo e sua molteplicita' per entrambi i lati -for nInd = 1, #FlipFeatureStates do - if FlipFeatureStates[nInd].Flip0 < nFlip0Min then - nFlip0Min = FlipFeatureStates[nInd].Flip0 - nFlip0Cnt = 1 - elseif FlipFeatureStates[nInd].Flip0 == nFlip0Min then - nFlip0Cnt = nFlip0Cnt + 1 + + if not bManualFlip then + local bFlip + -- analizzo stati flip delle feature + local nFlip0Min = 100 + local nFlip0Cnt = 0 + local nFlip1Min = 100 + local nFlip1Cnt = 0 + -- calcolo punteggio minimo e sua molteplicita' per entrambi i lati + for nInd = 1, #FlipFeatureStates do + if FlipFeatureStates[nInd].Flip0 < nFlip0Min then + nFlip0Min = FlipFeatureStates[nInd].Flip0 + nFlip0Cnt = 1 + elseif FlipFeatureStates[nInd].Flip0 == nFlip0Min then + nFlip0Cnt = nFlip0Cnt + 1 + end + if FlipFeatureStates[nInd].Flip1 < nFlip1Min then + nFlip1Min = FlipFeatureStates[nInd].Flip1 + nFlip1Cnt = 1 + elseif FlipFeatureStates[nInd].Flip1 == nFlip1Min then + nFlip1Cnt = nFlip1Cnt + 1 + end end - if FlipFeatureStates[nInd].Flip1 < nFlip1Min then - nFlip1Min = FlipFeatureStates[nInd].Flip1 - nFlip1Cnt = 1 - elseif FlipFeatureStates[nInd].Flip1 == nFlip1Min then - nFlip1Cnt = nFlip1Cnt + 1 - end -end --- calcolo lato con punteggio minore o molteplicita' piu' alta -if nFlip0Min == nFlip1Min then - if nFlip0Cnt > nFlip1Cnt then + -- calcolo lato con punteggio minore o molteplicita' piu' alta + if nFlip0Min == nFlip1Min then + if nFlip0Cnt > nFlip1Cnt then + bFlip = true + elseif nFlip0Cnt < nFlip1Cnt then + bFlip = false + end + elseif nFlip0Min < nFlip1Min then bFlip = true - elseif nFlip0Cnt < nFlip1Cnt then - bFlip = false + else + bFlip = false end -elseif nFlip0Min < nFlip1Min then - bFlip = true -else - bFlip = false + + if bFlip ~= nil then + -- se una posizione è più conveniente dell'altra setto info nel pezzo + EgtSetInfo( NFAR.PARTID, "NestAllowFlip", false) + EgtSetInfo( NFAR.PARTID, "NestFlip", bFlip) + else + EgtSetInfo( NFAR.PARTID, "NestAllowFlip", true) + end + + if bFlip then + -- flip pezzo + EgtRotate( NFAR.PARTID, b3Part:getCenter(), X_AX(), 180, GDB_RT.GLOB) + -- modifico le info del pezzo + local nPartFlip = EgtGetInfo( NFAR.PARTID, "INVERTED", 'i') or 0 + local nTotFlip = EgtIf( nPartFlip == 180, 0, 180) + EgtSetInfo( NFAR.PARTID, "INVERTED", nTotFlip) + EgtSetInfo( NFAR.PARTID, "FLIPROTMODIFIED", 1) + end end -if bFlip ~= nil then - -- se una posizione è più conveniente dell'altra setto info nel pezzo - EgtSetInfo( NFAR.PARTID, "NestAllowFlip", false) - EgtSetInfo( NFAR.PARTID, "NestFlip", bFlip) -else - EgtSetInfo( NFAR.PARTID, "NestAllowFlip", true) -end - -if bFlip then - -- flip pezzo - EgtRotate( NFAR.PARTID, b3Part:getCenter(), X_AX(), 180, GDB_RT.GLOB) - -- modifico le info del pezzo - local nPartFlip = EgtGetInfo( NFAR.PARTID, "INVERTED", 'i') or 0 - local nTotFlip = EgtIf( nPartFlip == 180, 0, 180) - EgtSetInfo( NFAR.PARTID, "INVERTED", nTotFlip) - EgtSetInfo( NFAR.PARTID, "FLIPROTMODIFIED", 1) -end -- ROTATION -local RotateFeatureStates = ClassifyRotation( vPartProc) - --- analizzo stati rotazione delle feature -local nRot0Min = 100 -local nRot0Cnt = 0 -local nRot90Min = 100 -local nRot90Cnt = 0 -local nRot180Min = 100 -local nRot180Cnt = 0 -local nRot270Min = 100 -local nRot270Cnt = 0 --- calcolo punteggio minimo e sua molteplicita' per tutte le rotazioni -for nInd = 1, #RotateFeatureStates do - if RotateFeatureStates[nInd].Rot0 < nRot0Min then - nRot0Min = RotateFeatureStates[nInd].Rot0 - nRot0Cnt = 1 - elseif RotateFeatureStates[nInd].Rot0 == nRot0Min then - nRot0Cnt = nRot0Cnt + 1 +if not bManualRot then + + local RotateFeatureStates = ClassifyRotation( vPartProc) + + -- analizzo stati rotazione delle feature + local nRot0Min = 100 + local nRot0Cnt = 0 + local nRot90Min = 100 + local nRot90Cnt = 0 + local nRot180Min = 100 + local nRot180Cnt = 0 + local nRot270Min = 100 + local nRot270Cnt = 0 + -- calcolo punteggio minimo e sua molteplicita' per tutte le rotazioni + for nInd = 1, #RotateFeatureStates do + if RotateFeatureStates[nInd].Rot0 < nRot0Min then + nRot0Min = RotateFeatureStates[nInd].Rot0 + nRot0Cnt = 1 + elseif RotateFeatureStates[nInd].Rot0 == nRot0Min then + nRot0Cnt = nRot0Cnt + 1 + end + if RotateFeatureStates[nInd].Rot90 < nRot90Min then + nRot90Min = RotateFeatureStates[nInd].Rot90 + nRot90Cnt = 1 + elseif RotateFeatureStates[nInd].Rot90 == nRot90Min then + nRot90Cnt = nRot90Cnt + 1 + end + if RotateFeatureStates[nInd].Rot180 < nRot180Min then + nRot180Min = RotateFeatureStates[nInd].Rot180 + nRot180Cnt = 1 + elseif RotateFeatureStates[nInd].Rot180 == nRot180Min then + nRot180Cnt = nRot180Cnt + 1 + end + if RotateFeatureStates[nInd].Rot270 < nRot270Min then + nRot270Min = RotateFeatureStates[nInd].Rot270 + nRot270Cnt = 1 + elseif RotateFeatureStates[nInd].Rot270 == nRot270Min then + nRot270Cnt = nRot270Cnt + 1 + end end - if RotateFeatureStates[nInd].Rot90 < nRot90Min then - nRot90Min = RotateFeatureStates[nInd].Rot90 - nRot90Cnt = 1 - elseif RotateFeatureStates[nInd].Rot90 == nRot90Min then - nRot90Cnt = nRot90Cnt + 1 - end - if RotateFeatureStates[nInd].Rot180 < nRot180Min then - nRot180Min = RotateFeatureStates[nInd].Rot180 - nRot180Cnt = 1 - elseif RotateFeatureStates[nInd].Rot180 == nRot180Min then - nRot180Cnt = nRot180Cnt + 1 - end - if RotateFeatureStates[nInd].Rot270 < nRot270Min then - nRot270Min = RotateFeatureStates[nInd].Rot270 - nRot270Cnt = 1 - elseif RotateFeatureStates[nInd].Rot270 == nRot270Min then - nRot270Cnt = nRot270Cnt + 1 - end -end - --- se c'e' qualche stato di rotazione -local MinList = { { Rot = 0, Score = nRot0Min, ScoreCnt = nRot0Cnt}, - { Rot = 90, Score = nRot90Min, ScoreCnt = nRot90Cnt}, - { Rot = 180, Score = nRot180Min, ScoreCnt = nRot180Cnt}, - { Rot = 270, Score = nRot270Min, ScoreCnt = nRot270Cnt}} -if #RotateFeatureStates > 0 then - -- calcolo lato con punteggio minore o molteplicita' piu' alta - local nRotMax = 0 - local nScoreMax = 0 - local nScoreCnt = 0 - for nInd = 1, #MinList do - if MinList[nInd].Score > nScoreMax then - nRotMax = MinList[nInd].Rot - nScoreMax = MinList[nInd].Score - nScoreCnt = MinList[nInd].ScoreCnt - elseif MinList[nInd].Score == nScoreMax then - if MinList[nInd].ScoreCnt > nScoreCnt then + + -- se c'e' qualche stato di rotazione + local MinList = { { Rot = 0, Score = nRot0Min, ScoreCnt = nRot0Cnt}, + { Rot = 90, Score = nRot90Min, ScoreCnt = nRot90Cnt}, + { Rot = 180, Score = nRot180Min, ScoreCnt = nRot180Cnt}, + { Rot = 270, Score = nRot270Min, ScoreCnt = nRot270Cnt}} + if #RotateFeatureStates > 0 then + -- calcolo lato con punteggio minore o molteplicita' piu' alta + local nRotMax = 0 + local nScoreMax = 0 + local nScoreCnt = 0 + for nInd = 1, #MinList do + if MinList[nInd].Score > nScoreMax then nRotMax = MinList[nInd].Rot nScoreMax = MinList[nInd].Score nScoreCnt = MinList[nInd].ScoreCnt + elseif MinList[nInd].Score == nScoreMax then + if MinList[nInd].ScoreCnt > nScoreCnt then + nRotMax = MinList[nInd].Rot + nScoreMax = MinList[nInd].Score + nScoreCnt = MinList[nInd].ScoreCnt + end end end + nRotate = nRotMax + else + nRotate = 0 end - nRotate = nRotMax -else - nRotate = 0 -end + - -local bRotNest = false -local nStepRotNest = 0 --- se calcolate limitazioni su rotazioni -if MinList and #MinList > 0 then - -- verifico condizioni da permettere al nesting - if MinList[1].Score >= 50 and MinList[2].Score >= 50 and MinList[3].Score >= 50 and MinList[4].Score >= 50 then + local bRotNest = false + local nStepRotNest = 0 + -- se calcolate limitazioni su rotazioni + if MinList and #MinList > 0 then + -- verifico condizioni da permettere al nesting + if MinList[1].Score >= 50 and MinList[2].Score >= 50 and MinList[3].Score >= 50 and MinList[4].Score >= 50 then + bRotNest = true + nStepRotNest = 90 + elseif (nRotate == 0 and MinList[3].Score >= 50) or ( nRotate == 90 and MinList[4].Score >= 50) then + bRotNest = true + nStepRotNest = 180 + end + else + -- altrimenti permetto tutto bRotNest = true nStepRotNest = 90 - elseif (nRotate == 0 and MinList[3].Score >= 50) or ( nRotate == 90 and MinList[4].Score >= 50) then - bRotNest = true - nStepRotNest = 180 - end -else - -- altrimenti permetto tutto - bRotNest = true - nStepRotNest = 90 -end - --- eseguo rotazione -EgtRotate( NFAR.PARTID, b3Part:getCenter(), Z_AX(), nRotate, GDB_RT.GLOB) --- verifico se ci sono fori lungo Y che bloccano la rotazione -local bDrillOnY = ( nStepRotNest == 180) - --- verifico se rotazione è valida ( pezzo contenuto nel grezzo) -b3Part = EgtGetBBoxGlob( NFAR.PARTID, GDB_BB.STANDARD) -local bValidRotationForRaw = b3Part:getDimX() < WD.MAX_LENGTH and b3Part:getDimY() < WD.MAX_WIDTH -if not bValidRotationForRaw then - EgtRotate( NFAR.PARTID, b3Part:getCenter(), Z_AX(), 90, GDB_RT.GLOB) - nRotate = nRotate + 90 - nStepRotNest = 180 -end - --- se non ci sono fori verifico se il pezzo cade -if not bDrillOnY then + end + + -- eseguo rotazione + EgtRotate( NFAR.PARTID, b3Part:getCenter(), Z_AX(), nRotate, GDB_RT.GLOB) + -- verifico se ci sono fori lungo Y che bloccano la rotazione + local bDrillOnY = ( nStepRotNest == 180) + + -- verifico se rotazione è valida ( pezzo contenuto nel grezzo) b3Part = EgtGetBBoxGlob( NFAR.PARTID, GDB_BB.STANDARD) - local bValidRotation = b3Part:getDimX() > ( WD.INTERAXIAL_DISTANCE or 1200) - -- verifico se ruotata resta valida - local bRotatedIsValid = b3Part:getDimY() > ( WD.INTERAXIAL_DISTANCE or 1200) - -- se non è valida e posso ruotare senza farlo fuoriuscire dal grezzo allora ruoto - if not bValidRotation and nStepRotNest ~= 180 then + local bValidRotationForRaw = b3Part:getDimX() < WD.MAX_LENGTH and b3Part:getDimY() < WD.MAX_WIDTH + local bRotatedIsValid = b3Part:getDimY() < WD.MAX_LENGTH and b3Part:getDimX() < WD.MAX_WIDTH + if not bValidRotationForRaw and bRotatedIsValid then EgtRotate( NFAR.PARTID, b3Part:getCenter(), Z_AX(), 90, GDB_RT.GLOB) nRotate = nRotate + 90 nStepRotNest = 180 - elseif bValidRotation and not bRotatedIsValid then - -- se fosse valida ma la sua ruotata no, allora blocco lo step nella rotazione del nesting - nStepRotNest = 180 - end -end - --- setto info -if nRotate > 0 then - local nPartRot = EgtGetInfo( NFAR.PARTID, "ROTATED", 'i') or 0 - local nTotRot = nPartRot + nRotate - nTotRot = EgtIf( nTotRot < 360, nTotRot, nTotRot - 360) - EgtSetInfo( NFAR.PARTID, "ROTATED", nTotRot) - EgtSetInfo( NFAR.PARTID, "FLIPROTMODIFIED", 1) + end + + -- se non ci sono fori verifico se il pezzo cade + if not bDrillOnY then + b3Part = EgtGetBBoxGlob( NFAR.PARTID, GDB_BB.STANDARD) + local bValidRotation = b3Part:getDimX() > ( WD.INTRULLI or 1200) + -- verifico se ruotata resta valida + local bRotatedIsValid = b3Part:getDimY() > ( WD.INTRULLI or 1200) + -- se non è valida e posso ruotare senza farlo fuoriuscire dal grezzo allora ruoto + if not bValidRotation and nStepRotNest ~= 180 then + EgtRotate( NFAR.PARTID, b3Part:getCenter(), Z_AX(), 90, GDB_RT.GLOB) + nRotate = nRotate + 90 + nStepRotNest = 180 + elseif bValidRotation and not bRotatedIsValid then + -- se fosse valida ma la sua ruotata no, allora blocco lo step nella rotazione del nesting + nStepRotNest = 180 + end + end + + -- setto info nel pezzo + if nRotate > 0 then + local nPartRot = EgtGetInfo( NFAR.PARTID, "ROTATED", 'i') or 0 + local nTotRot = nPartRot + nRotate + nTotRot = EgtIf( nTotRot < 360, nTotRot, nTotRot - 360) + EgtSetInfo( NFAR.PARTID, "ROTATED", nTotRot) + EgtSetInfo( NFAR.PARTID, "FLIPROTMODIFIED", 1) + end + + EgtSetInfo( NFAR.PARTID, "NestStepRot", nStepRotNest) + EgtSetInfo( NFAR.PARTID, "NestRot", nRotate) + EgtSetInfo( NFAR.PARTID, "NestAllowRot", bRotNest) end --- setto info nel pezzo -EgtSetInfo( NFAR.PARTID, "NestStepRot", nStepRotNest) -EgtSetInfo( NFAR.PARTID, "NestRot", nRotate) -EgtSetInfo( NFAR.PARTID, "NestAllowRot", bRotNest) - NFAR.ERR = 0 \ No newline at end of file diff --git a/NestProcess.lua b/NestProcess.lua index fc9bd16..195a4d8 100644 --- a/NestProcess.lua +++ b/NestProcess.lua @@ -11,8 +11,8 @@ EgtEnableDebug( false) --NEST.FILE = 'c:\\TechnoEssetre7\\EgtData\\Prods\\0010\\Bar_10_1.btl' --NEST.MACHINE = 'Essetre-90480019_MW' --NEST.FLAG = 3 ---NEST.MIN_ANGLE_PNT = 60 ---NEST.DRILL_MACH_AREA = 1 +--NEST.MIN_ANGLE_PNT = 60 +--NEST.DRILL_MACH_AREA = 0 local sLog = 'NestProcess : ' .. NEST.FILE .. ', ' .. NEST.MACHINE .. ', ' .. LEN["1"] .. ', ' .. WIDTH["1"] EgtOutLog( sLog) @@ -123,16 +123,16 @@ end -- Funzione che crea il rettangolo della lavorazione local function CreateToolRectangle( ptP1, ptP2, vtFace, nOutlineGrp) - local dExtra = 5 + local dExtra = 5 local vtX = ptP2 - ptP1 vtX:normalize() -- creo il rettangolo della lavorazione -- ptP1 = ptP1 - vtX * 9000 - ptP1 = ptP1 - vtX * ( WD.SIDEMILL_DIAM_DOWN / 2 + dExtra) - ptP2 = ptP2 + vtX * ( WD.SIDEMILL_DIAM_DOWN / 2 + dExtra) - ptP2 = ptP2 + vtFace * ( WD.SIDEMILL_DIAM_DOWN + dExtra) + ptP1 = ptP1 - vtX * ( WD.SIDEMILL_DIAM_DOWN / 2 + dExtra) + ptP2 = ptP2 + vtX * ( WD.SIDEMILL_DIAM_DOWN / 2 + dExtra) + ptP2 = ptP2 + vtFace * ( WD.SIDEMILL_DIAM_DOWN + dExtra) local nId = EgtRectangle2P( nOutlineGrp, Point3d(ptP2:getX(), ptP2:getY(), 0), Point3d( ptP1:getX(), ptP1:getY(), 0)) - EgtSetColor( nId, EgtStdColor("RED")) + EgtSetColor( nId, EgtStdColor("BLUE")) return nId end @@ -146,7 +146,7 @@ local function ComputeToolOutlines( nPartId) if not nOutlineGrp or nOutlineGrp == GDB_ID.NULL then nOutlineGrp = EgtGroup( GDB_ID.ROOT) EgtSetName( nOutlineGrp, "ToolOutlines") - EgtSetStatus( nOutlineGrp, GDB_ST.ON) + EgtSetStatus( nOutlineGrp, GDB_ST.OFF) end local vPartProc = WE.CollectFeatures( nPartId, b3Raw) @@ -212,7 +212,51 @@ local function ComputeToolOutlines( nPartId) end end end + end + + -- lap joint 4 facce + if Proc.Fct == 4 then + local nFacInd, dElev, nFacInd2, dElev2 = WL.GetFaceWithMostAdj( Proc.Id, Proc.PartId) + if nFacInd ~= -2 then + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT) + if not AreSameOrOppositeVectorApprox( vtN, Z_AX()) then + + local nOtherFace = -1 + for nIdx = 0, 3 do + local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, nIdx, GDB_ID.ROOT) + if AreSameOrOppositeVectorApprox( vtN2, Z_AX()) then + nOtherFace = nIdx + break + end + end + if nOtherFace ~= -1 and nOtherFace ~= nFacInd and nOtherFace ~= nFacInd2 then + local ptP1, ptP2 + local bAdj, ptP1tmp, ptP2tmp, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, nOtherFace, GDB_ID.ROOT) + local bAdj2, ptP3, ptP4 = EgtSurfTmFacetsContact( Proc.Id, nFacInd, nFacInd2, GDB_ID.ROOT) + if AreSamePointApprox( ptP1tmp, ptP3) or AreSamePointApprox( ptP1tmp, ptP4) then + ptP1 = Point3d( ptP1tmp:getX(), ptP1tmp:getY(), 0) + ptP2 = Point3d( ptP2tmp:getX(), ptP2tmp:getY(), 0) + else + ptP1 = Point3d( ptP2tmp:getX(), ptP2tmp:getY(), 0) + ptP2 = Point3d( ptP1tmp:getX(), ptP1tmp:getY(), 0) + end + + local dExtra = 5 + local vtX = ptP2 - ptP1 + vtX:normalize() + -- creo il rettangolo della lavorazione + ptP2 = ptP2 + vtX * ( WD.SIDEMILL_DIAM_DOWN / 2 + dExtra) + ptP2 = ptP2 + vtN * ( WD.SIDEMILL_DIAM_DOWN + dExtra) + local nId = EgtRectangle2P( nOutlineGrp, Point3d(ptP2:getX(), ptP2:getY(), 0), Point3d( ptP1:getX(), ptP1:getY(), 0)) + EgtSetColor( nId, EgtStdColor("BLUE")) + if nId ~= GDB_ID.NULL then table.insert(ToolOutlineId, nId) end + + end + end + end end + + end -- fori @@ -361,11 +405,23 @@ local function ClassifyDrillsOnLateralFaces( nPartId) end +local function AddNormalVector( vt, vCases) + + if AreSameVectorApprox( vt, X_AX()) then + vCases["R"] = 1 + elseif AreOppositeVectorApprox(vt, X_AX()) then + vCases["L"] = 1 + elseif AreSameVectorApprox( vt, Y_AX()) then + vCases["B"] = 1 + elseif AreOppositeVectorApprox(vt, Y_AX()) then + vCases["F"] = 1 + end +end local function ClassifyLapJointsFromBottom( nPartId) local res = { Nbr = 0, sCase = '', bParall = false} - + local b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD) local ptPartMin = b3Part:getMin() local ptPartMax = b3Part:getMax() @@ -384,7 +440,8 @@ local function ClassifyLapJointsFromBottom( nPartId) -- se rivolto verso il basso if ( vtN[1]:getZ() <= - 0.95 or vtN[2]:getZ() <= - 0.95) then local vtFace = EgtIf( vtN[1]:getZ() <= -0.95, vtN[2], vtN[1]) - table.insert( vtLapJoints, vtFace) + -- table.insert( vtLapJoints, vtFace) + AddNormalVector( vtFace, vtLapJoints) end elseif Proc.Fct == 3 then local nFacInd, dElev = WL.GetFaceWithMostAdj( Proc.Id, Proc.PartId) @@ -394,99 +451,79 @@ local function ClassifyLapJointsFromBottom( nPartId) local nOtherFace = EgtIf( nFacInd == 0, 1, 0) local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, nOtherFace, GDB_ID.ROOT) if abs( ptP1:getZ() - ptP2:getZ()) < GEO.EPS_SMALL then - table.insert( vtLapJoints, vtN) + -- table.insert( vtLapJoints, vtN) + AddNormalVector( vtN, vtLapJoints) end end - end + end + elseif Proc.Fct == 4 then + local nFacInd, dElev, nFacInd2, dElev2 = WL.GetFaceWithMostAdj( Proc.Id, Proc.PartId) + if nFacInd ~= -2 then + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT) + if not AreSameOrOppositeVectorApprox( vtN, Z_AX()) then + local nOtherFace = -1 + for nIdx = 0, 3 do + local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, nIdx, GDB_ID.ROOT) + if AreSameOrOppositeVectorApprox( vtN2, Z_AX()) then + nOtherFace = nIdx + break + end + end + if nOtherFace ~= -1 and nOtherFace ~= nFacInd and nOtherFace ~= nFacInd2 then + --table.insert( vtLapJoints, vtN) + AddNormalVector( vtN, vtLapJoints) + end + end + end end end end - if #vtLapJoints == 1 then + local nCnt = 0 + for _ in pairs(vtLapJoints) do nCnt = nCnt + 1 end + + if nCnt == 1 then res.Nbr = 1 - if AreOppositeVectorApprox( vtLapJoints[1], Y_AX()) then - res.sCase = 'F' - elseif AreSameVectorApprox( vtLapJoints[1], Y_AX()) then - res.sCase = 'B' - elseif AreSameVectorApprox( vtLapJoints[1], X_AX()) then - res.sCase = 'R' - elseif AreOppositeVectorApprox( vtLapJoints[1], X_AX()) then - res.sCase = 'L' + for k, _ in pairs( vtLapJoints) do + res.sCase = k end - - elseif #vtLapJoints == 2 then + + elseif nCnt == 2 then res.Nbr = 2 - if AreSameOrOppositeVectorApprox( vtLapJoints[1], vtLapJoints[2]) then - res.bParall = true - if AreSameOrOppositeVectorApprox( vtLapJoints[1], Y_AX()) then - res.sCase = 'F' - else - res.sCase = 'R' - end - + if vtLapJoints["F"] and vtLapJoints["B"] then + res.bParall = true + res.sCase = "F" + elseif vtLapJoints["R"] and vtLapJoints["L"] then + res.bParall = true + res.sCase = "R" else - idX = EgtIf(AreSameOrOppositeVectorApprox( vtLapJoints[1], X_AX()), 1, 2) - idY = EgtIf( idX == 1, 2, 1) - - if AreSameVectorApprox( vtLapJoints[idX], X_AX()) and AreSameVectorApprox( vtLapJoints[idY], Y_AX()) then + res.bParall = false + if vtLapJoints["B"] and vtLapJoints["R"] then res.sCase = 'BR' - elseif AreSameVectorApprox( vtLapJoints[idX], X_AX()) and AreOppositeVectorApprox( vtLapJoints[idY], Y_AX()) then - res.sCase = 'FR' - elseif AreOppositeVectorApprox( vtLapJoints[idX], X_AX()) and AreOppositeVectorApprox( vtLapJoints[idY], Y_AX()) then - res.sCase = 'FL' - elseif AreOppositeVectorApprox( vtLapJoints[idX], X_AX()) and AreSameVectorApprox( vtLapJoints[idY], Y_AX()) then + elseif vtLapJoints["B"] and vtLapJoints["L"] then res.sCase = 'BL' - end + elseif vtLapJoints["F"] and vtLapJoints["R"] then + res.sCase = 'FR' + elseif vtLapJoints["F"] and vtLapJoints["L"] then + res.sCase = 'FL' + end end - - elseif #vtLapJoints == 3 then - res.Nbr = 3 - - vt = {0, 0, 0, 0} - - if AreSameVectorApprox( vtLapJoints[1], X_AX()) then - vt[1] = 1 - elseif AreOppositeVectorApprox( vtLapJoints[1], X_AX()) then - vt[2] = 1 - elseif AreSameVectorApprox( vtLapJoints[1], Y_AX()) then - vt[3] = 1 - elseif AreOppositeVectorApprox( vtLapJoints[1], Y_AX()) then - vt[4] = 1 - end - - if AreSameVectorApprox( vtLapJoints[2], X_AX()) then - vt[1] = 1 - elseif AreOppositeVectorApprox( vtLapJoints[2], X_AX()) then - vt[2] = 1 - elseif AreSameVectorApprox( vtLapJoints[2], Y_AX()) then - vt[3] = 1 - elseif AreOppositeVectorApprox( vtLapJoints[2], Y_AX()) then - vt[4] = 1 - end - - if AreSameVectorApprox( vtLapJoints[3], X_AX()) then - vt[1] = 1 - elseif AreOppositeVectorApprox( vtLapJoints[3], X_AX()) then - vt[2] = 1 - elseif AreSameVectorApprox( vtLapJoints[3], Y_AX()) then - vt[3] = 1 - elseif AreOppositeVectorApprox( vtLapJoints[3], Y_AX()) then - vt[4] = 1 - end - - if vt[1] == 0 then - res.sCase = 'R' - elseif vt[2] == 0 then - res.sCase = 'L' - elseif vt[3] == 0 then - res.sCase = 'B' - elseif vt[4] == 0 then - res.sCase = 'F' + + elseif nCnt == 3 then + res.Nbr = 3 + if not vtLapJoints["F"] then + res.sCase = "F" + elseif not vtLapJoints["B"] then + res.sCase = "B" + elseif not vtLapJoints["R"] then + res.sCase = "R" + elseif not vtLapJoints["L"] then + res.sCase = "L" end - elseif #vtLapJoints == 4 then + elseif nCnt == 4 then res.Nbr = 4 - elseif #vtLapJoints ~= 0 then + elseif nCnt ~= 0 then return end @@ -503,7 +540,7 @@ local function CreateDefectOnAngle( nPartId, RawPart, bDrillLong, bOnOppositeAng if not nOutlineGrp or nOutlineGrp == GDB_ID.NULL then nOutlineGrp = EgtGroup( GDB_ID.ROOT) EgtSetName( nOutlineGrp, "SheetDefects") - EgtSetStatus( nOutlineGrp, GDB_ST.ON) + EgtSetStatus( nOutlineGrp, GDB_ST.OFF) end local dExtraMachArea = WD.SIDEMILL_DIAM_DOWN -- per tenere conto dell'area di lavorazione @@ -564,7 +601,10 @@ local function RotateOptimalCase( nPartId, nAngle, nAngleValidRot, RawPart, nPnt EgtRotate( nPartId, b3Part:getCenter(), Z_AX(), nAngle, GDB_RT.GLOB) local nRotate = nAngle local nAnglePnt - b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD) + local nBoxLayerId = EgtGetFirstNameInGroup( nPartId, "Box") + local nBoxId = EgtGetFirstNameInGroup( nBoxLayerId, "Box") + local b3Part = EgtGetBBoxGlob(nBoxId, GDB_BB.STANDARD) + -- b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD) local bIsValidRotation = b3Part:getDimX() < RawPart.Len and b3Part:getDimY() < RawPart.Width if bIsValidRotation then nAnglePnt = nPnt1 @@ -602,7 +642,7 @@ end -- Funzione che classifica i pezzi in base alla loro necessità di stare negli angoli -local function ClassifyAngles( nPartId, RawPart, sRefOrig) +local function ClassifyAngles( nPartId, RawPart, sRefOrig, bLockedRot) local nAngle local nRotate = 0 @@ -621,7 +661,7 @@ local function ClassifyAngles( nPartId, RawPart, sRefOrig) end -- oriento il pezzo in base al foro - if bDrill then + if bDrill and not bLockedRot then local RotationAngles if sRefOrig == 'TL' or sRefOrig == 'TR' then RotationAngles = { F = 180, B = 0, L = 270, R = 90} @@ -632,7 +672,10 @@ local function ClassifyAngles( nPartId, RawPart, sRefOrig) nRotate = nRotate + RotationAngles[DrillClassif.sCase] -- verifico se la rotazione è valida - b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD) + local nBoxLayerId = EgtGetFirstNameInGroup( nPartId, "Box") + local nBoxId = EgtGetFirstNameInGroup( nBoxLayerId, "Box") + local b3Part = EgtGetBBoxGlob(nBoxId, GDB_BB.STANDARD) + -- b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD) local bIsValidRotation = b3Part:getDimX() < RawPart.Len and b3Part:getDimY() < RawPart.Width if not bIsValidRotation then -- ritorno nella posizione originaria @@ -646,10 +689,10 @@ local function ClassifyAngles( nPartId, RawPart, sRefOrig) -- se non ho fori scelgo una posizione che non faccia cadere il pezzo local bOnly180Rot = false - if not bDrill then + if not bDrill and not bLockedRot then b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD) - local bIsValid = b3Part:getDimX() > ( WD.INTERAXIAL_DISTANCE or 1200) - local bRotatedIsValid = b3Part:getDimY() > ( WD.INTERAXIAL_DISTANCE or 1200) + local bIsValid = b3Part:getDimX() > ( WD.INTRULLI or 1200) + local bRotatedIsValid = b3Part:getDimY() > ( WD.INTRULLI or 1200) if not bIsValid and not bRotatedIsValid then EgtSetInfo( nPartId, "REDUCECUT", 1) elseif not bIsValid or not bRotatedIsValid then @@ -668,6 +711,15 @@ local function ClassifyAngles( nPartId, RawPart, sRefOrig) b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD) local bAdd = true + if ResLapJoints.Nbr > 0 and bLockedRot then + b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD) + if b3Part:getDimX() > ( WD.INTRULLI or 1200) then + EgtSetInfo( nPartId, "REDUCECUT", 1) + end + local PartAngleClassification = { PartId = tostring( nPartId), Angle = 100, nRotate = 0, bDrill = true, bLongDrill = true} + return PartAngleClassification + end + -- se anche fori oppure possibile solo rotazione di 180° per non far cadere il pezzo if bDrill or bOnly180Rot then if ResLapJoints.Nbr == 0 then @@ -814,7 +866,7 @@ local function ClassifyAngles( nPartId, RawPart, sRefOrig) local PartAngleClassification = { PartId = tostring( nPartId), Angle = nAngle, nRotate = nRotate, bDrill = bDrill, bLongDrill = bLongDrill} - local bCanBeOnOtherEdge = not bDrill or ( bDrill and RawPart.Width >= ( WD.MINRAWY_HOR_DRILL or 2800)) + local bCanBeOnOtherEdge = not bDrill or ( bDrill and RawPart.Width >= WD.MINRAWY_HOR_DRILL) if bCanBeOnOtherEdge or bOnly180Rot then EgtSetInfo( nPartId, "NestAllowRot", 1) EgtSetInfo( nPartId, "NestStepRot", 180) @@ -826,7 +878,7 @@ local function ClassifyAngles( nPartId, RawPart, sRefOrig) -- verifico se il pezzo cade (caso di foro) b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD) - if b3Part:getDimX() > ( WD.INTERAXIAL_DISTANCE or 1200) then + if b3Part:getDimX() > ( WD.INTRULLI or 1200) then EgtSetInfo( nPartId, "REDUCECUT", 1) end @@ -859,7 +911,7 @@ local function ComputeRestrictedZones( RawParts) vRawDistrib = {0.7, 0.3} else for nInd = 1, #RawParts do - table.insert(vRawDistrib, 1 / #RawParts) + table.insert( vRawDistrib, 1 / #RawParts) end end @@ -889,8 +941,9 @@ local function ComputeRestrictedZones( RawParts) local nPartIndex = 0 local AngleClassification = {} for nPartId, nCount in pairs( PART) do - nPartIndex = nPartIndex + 1 - local PartClassif = ClassifyAngles(tonumber(nPartId), RawParts[nMaxSheet], WD.ORIG_CORNER) + nPartIndex = nPartIndex + 1 + local bManualRot = EgtGetInfo( nPartId, "MANUALROT", 'b') + local PartClassif = ClassifyAngles(tonumber(nPartId), RawParts[nMaxSheet], WD.ORIG_CORNER, bManualRot) if PartClassif then for nI = 1, nCount do local newTab = {PartId = PartClassif.PartId, Angle = PartClassif.Angle, nRotate = PartClassif.nRotate, bDrill = PartClassif.bDrill, bLongDrill = PartClassif.bLongDrill} @@ -900,13 +953,12 @@ local function ComputeRestrictedZones( RawParts) if EgtProcessEvents( nPartIndex / nTotParts * 100, 0) == 1 then return false - end - + end end table.sort( AngleClassification, function(a, b) return a.Angle > b.Angle end) - + local vManuallyDone = {} local vPartsManuallyDone = {} @@ -928,8 +980,7 @@ local function ComputeRestrictedZones( RawParts) for nInd2 = 1, #vManuallyDone do -- verifico se il pezzo può stare sull'altro angolo local bCanBeOnOtherAngle = not AngleClassification[nInd].bDrill or - ( AngleClassification[nInd].bDrill and not AngleClassification[nInd].bLongDrill and - RawParts[vManuallyDone[nInd2].RawPartId].Width >= ( WD.MINRAWY_HOR_DRILL or 2800)) + ( AngleClassification[nInd].bDrill and not AngleClassification[nInd].bLongDrill and RawParts[vManuallyDone[nInd2].RawPartId].Width >= WD.MINRAWY_HOR_DRILL) if #(vManuallyDone[nInd2].Parts) == 0 then -- verifico che il pezzo stia in questo grezzo @@ -1001,8 +1052,7 @@ local function ComputeRestrictedZones( RawParts) else -- aggiungo info per il nesting per ricordare che andrà sul lato EgtSetInfo( AngleClassification[nInd].PartId, "NestOnEdge", 1) - end - + end end @@ -1128,7 +1178,7 @@ local function AddParts(RawParts, vPartsDoneManually) -- rotation local bManualRot = EgtGetInfo( nPartId, "MANUALROT", 'b') - if bManualRot then + if bManualRot then bRotNest = false elseif EgtExistsInfo( nPartId, "NestRot") then nStepRotNest = EgtGetInfo( nPartId, "NestStepRot", 'i') @@ -1432,20 +1482,17 @@ local function AddParts(RawParts, vPartsDoneManually) local nBoxId = EgtGetFirstNameInGroup( nBoxLayerId, "Box") local b3Part = EgtGetBBoxGlob(nBoxId, GDB_BB.STANDARD) -- local b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD) - local ptRef - local dval = 0.1 - if ( WD.ORIG_CORNER == 'TL' or WD.ORIG_CORNER == 'TR') then - --ptRef = b3Part:getMax() - ptRef = Point3d( b3Part:getMax():getX() - dval, b3Part:getMax():getY() - dval, 0) - - else - --ptRef = b3Part:getMin() - ptRef = Point3d( b3Part:getMin():getX() + dval, b3Part:getMin():getY() + dval, 0) + if abs( b3Part:getDimY() + 2 * NEST.KERF - RawParts[1].Width) > 2 then + local ptRef + local dval = 10 + if ( WD.ORIG_CORNER == 'TL' or WD.ORIG_CORNER == 'TR') then + ptRef = Point3d( b3Part:getMax():getX() - b3Part:getDimX()/2, b3Part:getMax():getY() - dval, 0) + else + ptRef = Point3d( b3Part:getMin():getX() + b3Part:getDimX()/2, b3Part:getMin():getY() + dval, 0) + end + EgtAutoNestSetStripYconstraintToPart( nPartId, ptRef, NEST.KERF + dval, RawParts[1].Width - 2 * ( NEST.KERF + dval)) end - --EgtAutoNestSetStripYconstraintToPart( nPartId, ptRef, NEST.KERF + GEO.EPS_SMALL, RawParts[1].Width - 2 * ( NEST.KERF + GEO.EPS_SMALL)) - EgtAutoNestSetStripYconstraintToPart( nPartId, ptRef, NEST.KERF + dval + GEO.EPS_SMALL, RawParts[1].Width - 2 * ( NEST.KERF + dval)) - - end + end -- verifico se anullato nesting if EgtProcessEvents( 100 + ( nPartIndex / nTotParts * 100), 0) == 1 then @@ -1512,6 +1559,9 @@ if bOk then -- Impostazione corner di inizio del nesting (NST_CORNER.BL, TL, BR, TR) EgtAutoNestSetStartCorner( NEST.CORNER) + + -- Report dei dati di nesting per debug + EgtAutoNestSetReportFile( EgtGetTempDir() .. '\\LastNest.json') -- imposto tempo di nesting e lo avvio EgtAutoNestCompute( true, NEST.TIME) @@ -1729,7 +1779,7 @@ if bNestingOk then -- applico flip, rotazione e traslazione pezzo e box da nesting EgtSetInfo( nMachGroup, "PART" .. nPartCount, nPartDuploId .. "," .. EgtNumToString( vDoneManually[nInd].Parts[nInd2].posX, 3) .. "," .. EgtNumToString( vDoneManually[nInd].Parts[nInd2].posY, 3) .. "," .. 0 .."," .. 0) EgtSetInfo( nPartDuploId, "POSX", vDoneManually[nInd].Parts[nInd2].posX) - EgtSetInfo( nPartDuploId, "POSY", vDoneManually[nInd].Parts[nInd2].posY) + EgtSetInfo( nPartDuploId, "POSY", vDoneManually[nInd].Parts[nInd2].posY) end end end @@ -1742,6 +1792,7 @@ if bNestingOk then WALL.FILE = NEST.FILE WALL.MACHINE = NEST.MACHINE WALL.FLAG = 6 -- CREATE_PANEL + WALL.NESTING_REF = 'BL' nMachGroup = EgtGetFirstMachGroup() while nMachGroup do EgtSetCurrMachGroup( nMachGroup)