DataWall :

- migliorie per nesting
- correzione scelta testa per fori orizzontali ciechi
- posizionamento pezzi in Vista secondo angolo preferenziale di nesting.
This commit is contained in:
DarioS
2022-01-05 20:47:31 +01:00
parent a471125fda
commit f5fdb7d89e
4 changed files with 356 additions and 288 deletions
+1 -1
View File
@@ -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
+12 -3
View File
@@ -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
+170 -162
View File
@@ -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
+173 -122
View File
@@ -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)