DataWall :
- migliorie Nesting.
This commit is contained in:
+410
-311
@@ -122,24 +122,167 @@ local function NewMachGroupName()
|
||||
end
|
||||
|
||||
-- Funzione che crea il rettangolo della lavorazione
|
||||
local function CreateToolRectangle( ptP1, ptP2, vtFace, nOutlineGrp)
|
||||
local function CreateToolRectangle( ptP1, dValP1, ptP2, dValP2, vtFace, dValFace, nOutlineGrp)
|
||||
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 * ( dValP1 + dExtra)
|
||||
ptP2 = ptP2 + vtX * ( dValP2 + dExtra)
|
||||
ptP2 = ptP2 + vtFace * ( dValFace + dExtra)
|
||||
local nId = EgtRectangle2P( nOutlineGrp, Point3d(ptP2:getX(), ptP2:getY(), 0), Point3d( ptP1:getX(), ptP1:getY(), 0))
|
||||
EgtSetColor( nId, EgtStdColor("BLUE"))
|
||||
return nId
|
||||
end
|
||||
|
||||
-- Funzione che verifica se la lavorazione è lap joint dal basso ed eventualmente ne calcola l'area di lavorazione
|
||||
local function IdentifyLJFromBottom( Proc, bCompute, nOutlineGrp)
|
||||
|
||||
local bLJFromBottom = false
|
||||
local nRectId
|
||||
local vtFace = {}
|
||||
|
||||
if Proc.Fct == 2 then
|
||||
local vtN = {}
|
||||
vtN[1] = EgtSurfTmFacetNormVersor( Proc.Id, 0, GDB_ID.ROOT)
|
||||
vtN[2] = EgtSurfTmFacetNormVersor( Proc.Id, 1, GDB_ID.ROOT)
|
||||
|
||||
-- se rivolto verso il basso
|
||||
if ( vtN[1]:getZ() <= - 0.95 or vtN[2]:getZ() <= - 0.95) then
|
||||
vtFace[1] = EgtIf( vtN[1]:getZ() <= -0.95, vtN[2], vtN[1])
|
||||
if not AreSameOrOppositeVectorApprox( vtFace[1], Z_AX()) then
|
||||
bLJFromBottom = true
|
||||
if bCompute then
|
||||
local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT)
|
||||
-- creo il rettangolo della lavorazione
|
||||
nRectId = CreateToolRectangle( ptP1, WD.SIDEMILL_DIAM_DOWN / 2, ptP2, WD.SIDEMILL_DIAM_DOWN / 2, vtFace[1], WD.SIDEMILL_DIAM_DOWN, nOutlineGrp)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
elseif Proc.Fct == 3 then
|
||||
local nFacInd, dElev, nFacInd2 = WL.GetFaceWithMostAdj( Proc.Id, Proc.PartId)
|
||||
|
||||
-- se nel mezzo di una faccia
|
||||
if not nFacInd2 then
|
||||
if nFacInd ~= -2 then
|
||||
vtFace[1] = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT)
|
||||
if not AreSameOrOppositeVectorApprox( vtFace[1], Z_AX()) then
|
||||
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
|
||||
bLJFromBottom = true
|
||||
if bCompute then
|
||||
nRectId = CreateToolRectangle( ptP1, WD.SIDEMILL_DIAM_DOWN / 2, ptP2, WD.SIDEMILL_DIAM_DOWN / 2, vtFace[1], WD.SIDEMILL_DIAM_DOWN, nOutlineGrp)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- se dal basso
|
||||
else
|
||||
local nFaceZ = -1
|
||||
for nIdx = 0, 2 do
|
||||
local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, nIdx, GDB_ID.ROOT)
|
||||
if AreOppositeVectorApprox( vtN2, Z_AX()) then
|
||||
nFaceZ = nIdx
|
||||
break
|
||||
end
|
||||
end
|
||||
if nFaceZ ~= -1 then
|
||||
local nFace = EgtIf( nFaceZ == nFacInd, nFacInd2, nFacInd)
|
||||
local nOtherFace = EgtIf( nFaceZ + nFace == 3, 0, EgtIf( nFaceZ + nFace == 2, 1, 2))
|
||||
vtFace[1] = EgtSurfTmFacetNormVersor( Proc.Id, nFace, GDB_ID.ROOT)
|
||||
vtFace[2] = EgtSurfTmFacetNormVersor( Proc.Id, nOtherFace, GDB_ID.ROOT)
|
||||
bLJFromBottom = true
|
||||
if bCompute then
|
||||
local bAdj, ptP1, ptP2 = EgtSurfTmFacetsContact( Proc.Id, nFace, nFaceZ, GDB_ID.ROOT)
|
||||
local bAdj2, ptP3, ptP4 = EgtSurfTmFacetsContact( Proc.Id, nFace, nOtherFace, GDB_ID.ROOT)
|
||||
if AreSamePointApprox( ptP2, ptP3) or AreSamePointApprox( ptP2, ptP4) then
|
||||
ptP1, ptP2 = ptP2, ptP1
|
||||
end
|
||||
nRectId = CreateToolRectangle( ptP1, 0, ptP2, WD.SIDEMILL_DIAM_DOWN / 2, vtFace[1], WD.SIDEMILL_DIAM_DOWN, nOutlineGrp)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
elseif Proc.Fct == 4 then
|
||||
local nFacInd, dElev, nFacInd2, dElev2 = WL.GetFaceWithMostAdj( Proc.Id, Proc.PartId)
|
||||
if nFacInd ~= -2 then
|
||||
vtFace[1] = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT)
|
||||
if not AreSameOrOppositeVectorApprox( vtFace[1], 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
|
||||
bLJFromBottom = true
|
||||
if bCompute then
|
||||
local bAdj, ptP1, ptP2 = EgtSurfTmFacetsContact( Proc.Id, nFacInd, nOtherFace, GDB_ID.ROOT)
|
||||
local bAdj2, ptP3, ptP4 = EgtSurfTmFacetsContact( Proc.Id, nFacInd, nFacInd2, GDB_ID.ROOT)
|
||||
if AreSamePointApprox( ptP2, ptP3) or AreSamePointApprox( ptP2, ptP4) then
|
||||
ptP1, ptP2 = ptP2, ptP1
|
||||
end
|
||||
nRectId = CreateToolRectangle( ptP1, 0, ptP2, WD.SIDEMILL_DIAM_DOWN / 2, vtFace[1], WD.SIDEMILL_DIAM_DOWN, nOutlineGrp)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if bLJFromBottom then
|
||||
return vtFace, nRectId
|
||||
else
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
-- Funzione che verifica se la lavorazione è lap joint da sopra ed eventualmente ne calcola l'area di lavorazione
|
||||
local function IdentifyLJFromTop( Proc, bCompute, nOutlineGrp)
|
||||
|
||||
local bLJFromTop = false
|
||||
local vtFace, nRectId
|
||||
|
||||
if Proc.Fct == 2 then
|
||||
local vtN = {}
|
||||
vtN[1] = EgtSurfTmFacetNormVersor( Proc.Id, 0, GDB_ID.ROOT)
|
||||
vtN[2] = EgtSurfTmFacetNormVersor( Proc.Id, 1, GDB_ID.ROOT)
|
||||
|
||||
-- se rivolto verso l'alto
|
||||
if ( vtN[1]:getZ() >= 0.95 or vtN[2]:getZ() >= 0.95 and WD.SIDEMILL_DIAM_UP > 0) then
|
||||
bLJFromTop = true
|
||||
vtFace = EgtIf( vtN[1]:getZ() >= 0.95, vtN[2], vtN[1])
|
||||
if bCompute then
|
||||
local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT)
|
||||
local b3Face = EgtSurfTmGetFacetBBoxGlob( Proc.Id, EgtIf( vtN[1]:getZ() >= 0.95, 0, 1), GDB_BB.STANDARD)
|
||||
local dDim = 0
|
||||
if AreSameOrOppositeVectorApprox( vtFace, X_AX()) then
|
||||
dDim = b3Face:getDimX()
|
||||
elseif AreSameOrOppositeVectorApprox( vtFace, Y_AX()) then
|
||||
dDim = b3Face:getDimY()
|
||||
end
|
||||
local dVal = max( dDim + WD.SIDEMILL_DIAM_UP / 2, WD.SIDEMILL_DIAM_UP)
|
||||
nRectId = CreateToolRectangle( ptP1, WD.SIDEMILL_DIAM_UP / 2, ptP2, WD.SIDEMILL_DIAM_UP / 2, vtFace, dVal, nOutlineGrp)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if bLJFromTop then
|
||||
return vtFace, nRectId
|
||||
else
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
-- Funzione che crea le regioni occupate dalle lavorazioni
|
||||
local function ComputeToolOutlines( nPartId)
|
||||
|
||||
local ToolOutlineId = {}
|
||||
EgtRemoveInfo( nPartId, "ToolOutlines")
|
||||
|
||||
-- recupero il gruppo con gli outlines degli utensili
|
||||
local nOutlineGrp = EgtGetFirstNameInGroup(GDB_ID.ROOT, "ToolOutlines")
|
||||
@@ -151,112 +294,26 @@ local function ComputeToolOutlines( nPartId)
|
||||
|
||||
local vPartProc = WE.CollectFeatures( nPartId, b3Raw)
|
||||
for nInd = 1, #vPartProc do
|
||||
Proc = vPartProc[nInd]
|
||||
|
||||
local Proc = vPartProc[nInd]
|
||||
|
||||
-- lap joint
|
||||
if LapJoint.Identify( vPartProc[nInd]) then
|
||||
|
||||
if Proc.Fct == 2 then
|
||||
local vtN = {}
|
||||
vtN[1] = EgtSurfTmFacetNormVersor( Proc.Id, 0, GDB_ID.ROOT)
|
||||
vtN[2] = EgtSurfTmFacetNormVersor( Proc.Id, 1, GDB_ID.ROOT)
|
||||
|
||||
-- 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])
|
||||
local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT)
|
||||
-- creo il rettangolo della lavorazione
|
||||
local nId = CreateToolRectangle( ptP1, ptP2, vtFace, nOutlineGrp)
|
||||
if nId ~= GDB_ID.NULL then table.insert(ToolOutlineId, nId) end
|
||||
|
||||
-- se rivolto verso l'alto
|
||||
elseif ( vtN[1]:getZ() >= 0.95 or vtN[2]:getZ() >= 0.95 and WD.SIDEMILL_DIAM_UP > 0) then
|
||||
local vtFace = EgtIf( vtN[1]:getZ() >= 0.95, vtN[2], vtN[1])
|
||||
local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT)
|
||||
local b3Face = EgtSurfTmGetFacetBBoxGlob( Proc.Id, EgtIf( vtN[1]:getZ() >= 0.95, 0, 1), GDB_BB.STANDARD)
|
||||
local dDim = 0
|
||||
if AreSameOrOppositeVectorApprox( vtFace, X_AX()) then
|
||||
dDim = b3Face:getDimX()
|
||||
elseif AreSameOrOppositeVectorApprox( vtFace, Y_AX()) then
|
||||
dDim = b3Face:getDimY()
|
||||
end
|
||||
|
||||
-- creo il rettangolo della lavorazione
|
||||
local dExtra = 5
|
||||
local vtX = ptP2 - ptP1
|
||||
vtX:normalize()
|
||||
-- creo il rettangolo della lavorazione
|
||||
ptP1 = ptP1 - vtX * ( WD.SIDEMILL_DIAM_UP / 2 + dExtra)
|
||||
ptP2 = ptP2 + vtX * ( WD.SIDEMILL_DIAM_UP / 2 + dExtra)
|
||||
local dVal = max( dDim + WD.SIDEMILL_DIAM_UP / 2, WD.SIDEMILL_DIAM_UP)
|
||||
ptP2 = ptP2 + vtFace * ( dVal + dExtra)
|
||||
local nId = EgtRectangle2P( nOutlineGrp, Point3d(ptP2:getX(), ptP2:getY(), 0), Point3d( ptP1:getX(), ptP1:getY(), 0))
|
||||
EgtSetColor( nId, EgtStdColor("RED"))
|
||||
if LapJoint.Identify( Proc) then
|
||||
-- verifico se dal basso
|
||||
local _ , nRectId = IdentifyLJFromBottom( Proc, true, nOutlineGrp)
|
||||
if nRectId then
|
||||
EgtSetColor( nRectId, EgtStdColor("BLUE"))
|
||||
table.insert( ToolOutlineId, nRectId)
|
||||
else
|
||||
-- verifico se dall'alto
|
||||
local _ , nRectId = IdentifyLJFromTop( Proc, true, nOutlineGrp)
|
||||
if nRectId then
|
||||
EgtSetColor( nRectId, EgtStdColor("AQUA"))
|
||||
local nPrId = EgtGetInfo( Proc.Id, "PRID", 'i')
|
||||
EgtSetInfo( nId, "PRID", nPrId)
|
||||
if nId ~= GDB_ID.NULL then table.insert(ToolOutlineId, nId) end
|
||||
end
|
||||
end
|
||||
|
||||
-- lap joint 3 facce nel mezzo di una faccia
|
||||
if Proc.Fct == 3 then
|
||||
local nFacInd, dElev = 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 = 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
|
||||
local nId = CreateToolRectangle( ptP1, ptP2, vtN, nOutlineGrp)
|
||||
if nId ~= GDB_ID.NULL then table.insert(ToolOutlineId, nId) end
|
||||
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
|
||||
|
||||
|
||||
EgtSetInfo( nRectId, "PRID", nPrId)
|
||||
table.insert( ToolOutlineId, nRectId)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- fori
|
||||
@@ -268,41 +325,26 @@ local function ComputeToolOutlines( nPartId)
|
||||
local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB)
|
||||
local bOpen = ( Proc.Fcs ~= 0 and Proc.Fce ~= 0)
|
||||
local dDiam = 2 * EgtArcRadius( AuxId)
|
||||
|
||||
-- verifico se la lunghezza del foro è maggiore della lunghezza della punta
|
||||
if bOpen and AreSameOrOppositeVectorApprox( vtExtr, Y_AX()) and dLen > WD.HOR_DRILL_LEN - 1 then
|
||||
local ptP1 = Proc.Box:getMin()
|
||||
local ptP2 = Proc.Box:getMax()
|
||||
local b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD)
|
||||
|
||||
local ptP2 = Proc.Box:getMax()
|
||||
local dExtra = 10
|
||||
ptP1 = ptP1 - ( WD.MAX_WIDTH - dLen + dExtra) * Y_AX()
|
||||
ptP2 = ptP2 + ( WD.MAX_WIDTH - dLen + dExtra) * Y_AX()
|
||||
-- if abs( ptP1:getY() - b3Part:getMin():getY()) < GEO.EPS_SMALL then
|
||||
-- -- se foro è sulla faccia front
|
||||
-- ptP1 = ptP1 - dExtra * Y_AX()
|
||||
-- ptP2 = ptP1 + ( WD.MAX_WIDTH + dExtra) * Y_AX()
|
||||
-- ptP2 = ptP2 + dDiam * X_AX()
|
||||
-- else
|
||||
-- -- se foro è sulla faccia back
|
||||
-- ptP1 = ptP1 - ( WD.MAX_WIDTH - dLen + dExtra) * Y_AX()
|
||||
-- ptP2 = ptP2 + dExtra * Y_AX()
|
||||
-- end
|
||||
|
||||
|
||||
|
||||
local nId = EgtRectangle2P( nOutlineGrp, Point3d(ptP2:getX(), ptP2:getY(), 0), Point3d( ptP1:getX(), ptP1:getY(), 0))
|
||||
EgtSetColor( nId, EgtStdColor("RED"))
|
||||
if nId ~= GDB_ID.NULL then table.insert(ToolOutlineId, nId) end
|
||||
|
||||
EgtSetColor( nId, EgtStdColor("AQUA"))
|
||||
if nId ~= GDB_ID.NULL then table.insert(ToolOutlineId, nId) end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return ToolOutlineId
|
||||
end
|
||||
|
||||
|
||||
|
||||
local function ClassifyDrillsOnLateralFaces( nPartId)
|
||||
|
||||
local DrillClassif
|
||||
@@ -310,7 +352,6 @@ local function ClassifyDrillsOnLateralFaces( nPartId)
|
||||
local nBoxLayerId = EgtGetFirstNameInGroup( nPartId, "Box")
|
||||
local nBoxId = EgtGetFirstNameInGroup( nBoxLayerId, "Box")
|
||||
local b3Part = EgtGetBBoxGlob(nBoxId, GDB_BB.STANDARD)
|
||||
--local b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD)
|
||||
local ptPartMin = b3Part:getMin()
|
||||
local ptPartMax = b3Part:getMax()
|
||||
|
||||
@@ -327,6 +368,7 @@ local function ClassifyDrillsOnLateralFaces( nPartId)
|
||||
local ptDrill = EgtCP( AuxId, GDB_RT.GLOB)
|
||||
local dLen = abs( EgtCurveThickness( AuxId))
|
||||
local bLong = dLen > WD.HOR_DRILL_LEN - 1
|
||||
|
||||
-- faccia Front
|
||||
local dTol = GEO.EPS_SMALL
|
||||
if ( abs( ptDrill:getY() - ptPartMin:getY()) < dTol) then
|
||||
@@ -401,21 +443,7 @@ local function ClassifyDrillsOnLateralFaces( nPartId)
|
||||
DrillClassif = { sCase = sDrillFace, bClosed = DrillOnFaces[sDrillFace].closed, bLong = DrillOnFaces[sDrillFace].long}
|
||||
end
|
||||
|
||||
return DrillClassif
|
||||
|
||||
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
|
||||
return DrillClassif
|
||||
end
|
||||
|
||||
local function ClassifyLapJointsFromBottom( nPartId)
|
||||
@@ -426,56 +454,27 @@ local function ClassifyLapJointsFromBottom( nPartId)
|
||||
local ptPartMin = b3Part:getMin()
|
||||
local ptPartMax = b3Part:getMax()
|
||||
|
||||
local vtLapJoints = {}
|
||||
local vtLapJoints = {}
|
||||
local dMinComponentVal = 0.95
|
||||
local vPartProc = WE.CollectFeatures( nPartId)
|
||||
for nInd = 1, #vPartProc do
|
||||
|
||||
if LapJoint.Identify( vPartProc[nInd]) then
|
||||
local Proc = vPartProc[nInd]
|
||||
if Proc.Fct == 2 then
|
||||
local vtN = {}
|
||||
vtN[1] = EgtSurfTmFacetNormVersor( Proc.Id, 0, GDB_ID.ROOT)
|
||||
vtN[2] = EgtSurfTmFacetNormVersor( Proc.Id, 1, GDB_ID.ROOT)
|
||||
|
||||
-- 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)
|
||||
AddNormalVector( vtFace, vtLapJoints)
|
||||
end
|
||||
elseif Proc.Fct == 3 then
|
||||
local nFacInd, dElev = 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 = 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)
|
||||
AddNormalVector( vtN, vtLapJoints)
|
||||
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
|
||||
-- verifico se LJ da sotto
|
||||
local vtFace = IdentifyLJFromBottom( vPartProc[nInd], false)
|
||||
if vtFace then
|
||||
for nInd2 = 1, #vtFace do
|
||||
if vtFace[nInd2]:getX() > dMinComponentVal then
|
||||
vtLapJoints["R"] = 1
|
||||
elseif vtFace[nInd2]:getX() < - dMinComponentVal then
|
||||
vtLapJoints["L"] = 1
|
||||
elseif vtFace[nInd2]:getY() > dMinComponentVal then
|
||||
vtLapJoints["B"] = 1
|
||||
elseif vtFace[nInd2]:getY() < - dMinComponentVal then
|
||||
vtLapJoints["F"] = 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -584,7 +583,6 @@ local function CreateDefectOnAngle( nPartId, RawPart, bDrillLong, bOnOppositeAng
|
||||
PartTab.posX = RawPart.Len - b3Part:getDimX() - NEST.KERF
|
||||
PartTab.posY = NEST.KERF
|
||||
end
|
||||
|
||||
|
||||
PartTab.Id = tonumber(nPartId)
|
||||
PartTab.DefectId = EgtRectangle2P( nOutlineGrp, Point3d(ptP2:getX() + dExtraMachArea, ptP2:getY() + dExtraMachArea , 0), Point3d( ptP1:getX() - dExtraMachArea , ptP1:getY() - dExtraMachArea, 0))
|
||||
@@ -597,18 +595,21 @@ end
|
||||
|
||||
local function RotateOptimalCase( nPartId, nAngle, nAngleValidRot, RawPart, nPnt1, nPnt2)
|
||||
|
||||
local bOptimal = false
|
||||
local b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD)
|
||||
EgtRotate( nPartId, b3Part:getCenter(), Z_AX(), nAngle, GDB_RT.GLOB)
|
||||
local nRotate = nAngle
|
||||
local nAnglePnt
|
||||
local nBoxLayerId = EgtGetFirstNameInGroup( nPartId, "Box")
|
||||
local nBoxId = EgtGetFirstNameInGroup( nBoxLayerId, "Box")
|
||||
local b3Part = EgtGetBBoxGlob(nBoxId, GDB_BB.STANDARD)
|
||||
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
|
||||
local bIsValidRotation = b3Part:getDimX() < RawPart.Len - 2 * NEST.KERF + GEO.EPS_SMALL and b3Part:getDimY() < RawPart.Width - 2 * NEST.KERF + GEO.EPS_SMALL
|
||||
if bIsValidRotation then
|
||||
bOptimal = true
|
||||
nAnglePnt = nPnt1
|
||||
else
|
||||
bOptimal = false
|
||||
-- ruoto nella migliore posizione ammissibile
|
||||
EgtRotate( nPartId, b3Part:getCenter(), Z_AX(), nAngleValidRot, GDB_RT.GLOB)
|
||||
nRotate = nRotate + nAngleValidRot
|
||||
@@ -619,7 +620,7 @@ local function RotateOptimalCase( nPartId, nAngle, nAngleValidRot, RawPart, nPnt
|
||||
nRotate = nRotate - 360
|
||||
end
|
||||
|
||||
return nAnglePnt, nRotate
|
||||
return nAnglePnt, nRotate, bOptimal
|
||||
|
||||
end
|
||||
|
||||
@@ -637,22 +638,28 @@ local function RotateOptimalCaseDrill( nPartId, bCanRotate, nPnt1, nPnt2)
|
||||
nAnglePnt = nPnt2
|
||||
end
|
||||
|
||||
return nAnglePnt, nRotate
|
||||
return nAnglePnt, nRotate
|
||||
end
|
||||
|
||||
|
||||
-- Funzione che classifica i pezzi in base alla loro necessità di stare negli angoli
|
||||
local function ClassifyAngles( nPartId, RawPart, sRefOrig, bLockedRot)
|
||||
|
||||
-- elimino eventuali info
|
||||
EgtSetInfo( nPartId, "NestOnEdge", 0)
|
||||
EgtSetInfo( nPartId, "NestOnAngle", 0)
|
||||
|
||||
local nAngle
|
||||
local nRotate = 0
|
||||
local bOptimal
|
||||
local bManual = false
|
||||
local b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD)
|
||||
|
||||
-- fori
|
||||
local DrillClassif = ClassifyDrillsOnLateralFaces( nPartId)
|
||||
local bDrill = false
|
||||
local bDrillOpen = false
|
||||
local bLongDrill = false
|
||||
local bLongDrill = false
|
||||
|
||||
if DrillClassif then
|
||||
bDrill = true
|
||||
@@ -676,7 +683,7 @@ local function ClassifyAngles( nPartId, RawPart, sRefOrig, bLockedRot)
|
||||
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
|
||||
local bIsValidRotation = b3Part:getDimX() < RawPart.Len - 2 * NEST.KERF + GEO.EPS_SMALL and b3Part:getDimY() < RawPart.Width - 2 * NEST.KERF + GEO.EPS_SMALL
|
||||
if not bIsValidRotation then
|
||||
-- ritorno nella posizione originaria
|
||||
EgtRotate( nPartId, b3Part:getCenter(), Z_AX(), - RotationAngles[DrillClassif.sCase], GDB_RT.GLOB)
|
||||
@@ -735,18 +742,20 @@ local function ClassifyAngles( nPartId, RawPart, sRefOrig, bLockedRot)
|
||||
nAngle, nRotate2 = RotateOptimalCaseDrill( nPartId, bDrillOpen or bOnly180Rot, 20, 100)
|
||||
nRotate = nRotate + nRotate2
|
||||
elseif ResLapJoints.sCase == 'R' then
|
||||
if bDrillOpen or bOnly180Rot then bManual = true end
|
||||
if sRefOrig == 'TL' or sRefOrig == 'BL'then
|
||||
nAngle, nRotate2 = RotateOptimalCaseDrill( nPartId, bDrillOpen or bOnly180Rot, 50, 0)
|
||||
nAngle, nRotate2 = RotateOptimalCaseDrill( nPartId, bDrillOpen or bOnly180Rot, 40, 0)
|
||||
nRotate = nRotate + nRotate2
|
||||
else
|
||||
nAngle = 50
|
||||
nAngle = 40
|
||||
end
|
||||
elseif ResLapJoints.sCase == 'L' then
|
||||
if bDrillOpen or bOnly180Rot then bManual = true end
|
||||
if sRefOrig == 'TR' or sRefOrig == 'BR' then
|
||||
nAngle, nRotate2 = RotateOptimalCaseDrill( nPartId, bDrillOpen or bOnly180Rot, 50, 0)
|
||||
nAngle, nRotate2 = RotateOptimalCaseDrill( nPartId, bDrillOpen or bOnly180Rot, 40, 0)
|
||||
nRotate = nRotate + nRotate2
|
||||
else
|
||||
nAngle = 50
|
||||
nAngle = 40
|
||||
end
|
||||
end
|
||||
|
||||
@@ -760,9 +769,9 @@ local function ClassifyAngles( nPartId, RawPart, sRefOrig, bLockedRot)
|
||||
else
|
||||
if (( sRefOrig == 'TL' or sRefOrig == 'TR') and (ResLapJoints.sCase == 'BL' or ResLapJoints.sCase == 'BR')) or
|
||||
(( sRefOrig == 'BL' or sRefOrig == 'BR') and (ResLapJoints.sCase == 'FL' or ResLapJoints.sCase == 'FR')) then
|
||||
nAngle = 50
|
||||
nAngle = 40
|
||||
else
|
||||
nAngle, nRotate2 = RotateOptimalCaseDrill( nPartId, bDrillOpen or bOnly180Rot, 50, 100)
|
||||
nAngle, nRotate2 = RotateOptimalCaseDrill( nPartId, bDrillOpen or bOnly180Rot, 40, 100)
|
||||
nRotate = nRotate + nRotate2
|
||||
end
|
||||
end
|
||||
@@ -776,12 +785,14 @@ local function ClassifyAngles( nPartId, RawPart, sRefOrig, bLockedRot)
|
||||
nAngle, nRotate2 = RotateOptimalCaseDrill( nPartId, bDrillOpen or bOnly180Rot, 80, 100)
|
||||
nRotate = nRotate + nRotate2
|
||||
elseif ResLapJoints.sCase == 'R' then
|
||||
if bDrillOpen or bOnly180Rot then bManual = true end
|
||||
if sRefOrig == 'TR' or sRefOrig == 'BR' then
|
||||
nAngle, nRotate2 = RotateOptimalCaseDrill( nPartId, bDrillOpen or bOnly180Rot, 100, 100)
|
||||
nRotate = nRotate + nRotate2
|
||||
end
|
||||
nAngle = 100
|
||||
elseif ResLapJoints.sCase == 'L' then
|
||||
if bDrillOpen or bOnly180Rot then bManual = true end
|
||||
if sRefOrig == 'TL' or sRefOrig == 'BL' then
|
||||
nAngle, nRotate2 = RotateOptimalCaseDrill( nPartId, bDrillOpen or bOnly180Rot, 100, 100)
|
||||
nRotate = nRotate + nRotate2
|
||||
@@ -806,8 +817,9 @@ local function ClassifyAngles( nPartId, RawPart, sRefOrig, bLockedRot)
|
||||
RotationAngles = { F = 0, B = 180, R = 270, L = 90}
|
||||
end
|
||||
local nAngleValidRot = EgtIf( sRefOrig == 'TL' or sRefOrig == 'BR', 90, 270)
|
||||
nAngle, nRotate2 = RotateOptimalCase( nPartId, RotationAngles[ResLapJoints.sCase], nAngleValidRot, RawPart, 20, 50)
|
||||
nAngle, nRotate2, bOptimal = RotateOptimalCase( nPartId, RotationAngles[ResLapJoints.sCase], nAngleValidRot, RawPart, 20, 40)
|
||||
nRotate = nRotate + nRotate2
|
||||
if not bOptimal then bManual = true end
|
||||
|
||||
elseif ResLapJoints.Nbr == 2 then
|
||||
if ResLapJoints.bParall then
|
||||
@@ -827,8 +839,12 @@ local function ClassifyAngles( nPartId, RawPart, sRefOrig, bLockedRot)
|
||||
RotationAngles = { FR = 270, BR = 180, BL = 90, FL = 0}
|
||||
end
|
||||
local nAngleValidRot = EgtIf( sRefOrig == 'TL' or sRefOrig == 'BR', 270, 90)
|
||||
nAngle, nRotate2 = RotateOptimalCase( nPartId, RotationAngles[ResLapJoints.sCase], nAngleValidRot, RawPart, 50, 50)
|
||||
nAngle, nRotate2, bOptimal = RotateOptimalCase( nPartId, RotationAngles[ResLapJoints.sCase], nAngleValidRot, RawPart, 40, 40)
|
||||
nRotate = nRotate + nRotate2
|
||||
|
||||
local b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD)
|
||||
local bCanRotate = b3Part:getDimX() < RawPart.Width
|
||||
if bOptimal and bCanRotate then bManual = true end
|
||||
end
|
||||
|
||||
elseif ResLapJoints.Nbr == 3 then
|
||||
@@ -838,8 +854,9 @@ local function ClassifyAngles( nPartId, RawPart, sRefOrig, bLockedRot)
|
||||
RotationAngles = { F = 180, B = 0, R = 90, L = 270}
|
||||
end
|
||||
local nAngleValidRot = EgtIf( sRefOrig == 'TL' or sRefOrig == 'BR', 90, 270)
|
||||
nAngle, nRotate2 = RotateOptimalCase( nPartId, RotationAngles[ResLapJoints.sCase], nAngleValidRot, RawPart, 80, 100)
|
||||
nAngle, nRotate2, bOptimal = RotateOptimalCase( nPartId, RotationAngles[ResLapJoints.sCase], nAngleValidRot, RawPart, 80, 100)
|
||||
nRotate = nRotate + nRotate2
|
||||
if not bOptimal then bManual = true end
|
||||
|
||||
elseif ResLapJoints.Nbr == 4 then
|
||||
nAngle = 100
|
||||
@@ -864,7 +881,7 @@ local function ClassifyAngles( nPartId, RawPart, sRefOrig, bLockedRot)
|
||||
return
|
||||
end
|
||||
|
||||
local PartAngleClassification = { PartId = tostring( nPartId), Angle = nAngle, nRotate = nRotate, bDrill = bDrill, bLongDrill = bLongDrill}
|
||||
local PartAngleClassification = { PartId = tostring( nPartId), Angle = nAngle, nRotate = nRotate, bDrill = bDrill, bLongDrill = bLongDrill, bManual = bManual}
|
||||
|
||||
local bCanBeOnOtherEdge = not bDrill or ( bDrill and RawPart.Width >= WD.MINRAWY_HOR_DRILL)
|
||||
if bCanBeOnOtherEdge or bOnly180Rot then
|
||||
@@ -900,9 +917,9 @@ local function ComputeRestrictedZones( RawParts)
|
||||
-- stimo il numero di angoli disponibili
|
||||
local vSheetNbrEstimate = {}
|
||||
local nSheetNbrEstimate = 0
|
||||
local nSheetNbrCorrection = 0
|
||||
local nSheetNbrCorrection = - 2
|
||||
local nAnglesNbrEstimate = 0
|
||||
local nAngelsNbrCorrection = -1
|
||||
local nAngelsNbrCorrection = 0
|
||||
|
||||
local vRawDistrib = {}
|
||||
if #RawParts == 1 then
|
||||
@@ -928,7 +945,11 @@ local function ComputeRestrictedZones( RawParts)
|
||||
end
|
||||
end
|
||||
|
||||
vSheetNbrEstimate[nInd] = ceil( dTotArea * vRawDistrib[nInd] / dSheetArea) + nSheetNbrCorrection
|
||||
vSheetNbrEstimate[nInd] = min( ceil( dTotArea * vRawDistrib[nInd] / dSheetArea) + nSheetNbrCorrection, RawParts[nInd].Qty)
|
||||
if vSheetNbrEstimate[nInd] <= 0 then
|
||||
vSheetNbrEstimate[nInd] = min( RawParts[nInd].Qty, 1)
|
||||
end
|
||||
|
||||
nSheetNbrEstimate = nSheetNbrEstimate + vSheetNbrEstimate[nInd]
|
||||
nAnglesNbrEstimate = nAnglesNbrEstimate + vSheetNbrEstimate[nInd] * 2
|
||||
end
|
||||
@@ -946,7 +967,7 @@ local function ComputeRestrictedZones( RawParts)
|
||||
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}
|
||||
local newTab = {PartId = PartClassif.PartId, Angle = PartClassif.Angle, nRotate = PartClassif.nRotate, bDrill = PartClassif.bDrill, bLongDrill = PartClassif.bLongDrill, bManual = PartClassif.bManual}
|
||||
table.insert( AngleClassification, newTab)
|
||||
end
|
||||
end
|
||||
@@ -958,8 +979,7 @@ local function ComputeRestrictedZones( RawParts)
|
||||
|
||||
table.sort( AngleClassification, function(a, b) return a.Angle > b.Angle end)
|
||||
|
||||
|
||||
|
||||
|
||||
local vManuallyDone = {}
|
||||
local vPartsManuallyDone = {}
|
||||
for nInd = 1, #vSheetNbrEstimate do
|
||||
@@ -967,93 +987,130 @@ local function ComputeRestrictedZones( RawParts)
|
||||
table.insert( vManuallyDone, { RawPartId = nInd, Done = 0, Parts = {}})
|
||||
end
|
||||
end
|
||||
local nSheetNbr = #vManuallyDone
|
||||
local nFilledSheets = 0
|
||||
local nSheetNbr = #vManuallyDone
|
||||
local vFilledSheets = {}
|
||||
for nInd = 1, #vSheetNbrEstimate do
|
||||
for nInd2 = 1, vSheetNbrEstimate[nInd] do
|
||||
table.insert( vFilledSheets, { Width = RawParts[nInd].Width, OrigWidth = RawParts[nInd].Width})
|
||||
end
|
||||
end
|
||||
|
||||
for nInd = 1, #AngleClassification do
|
||||
|
||||
if AngleClassification[nInd].Angle >= NEST.MIN_ANGLE_PNT then
|
||||
|
||||
-- trovo il punto della lista dove inserirlo
|
||||
local nIdx = -1
|
||||
local bOnOppositeSide = false
|
||||
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)
|
||||
|
||||
if #(vManuallyDone[nInd2].Parts) == 0 then
|
||||
-- verifico che il pezzo stia in questo grezzo
|
||||
local b3Part = EgtGetBBoxGlob( AngleClassification[nInd].PartId, GDB_BB.STANDARD)
|
||||
if b3Part:getDimX() < RawParts[vManuallyDone[nInd2].RawPartId].Len and b3Part:getDimY() < RawParts[vManuallyDone[nInd2].RawPartId].Width then
|
||||
nIdx = nInd2
|
||||
nFilledSheets = nFilledSheets + 1
|
||||
break
|
||||
if AngleClassification[nInd].Angle >= NEST.MIN_ANGLE_PNT and AngleClassification[nInd].Angle > 0 then
|
||||
|
||||
-- verifico di avere ancora angoli a disposizione secondo la stima dei grezzi
|
||||
local bFound = false
|
||||
local nBoxLayerId = EgtGetFirstNameInGroup( AngleClassification[nInd].PartId, "Box")
|
||||
local nBoxId = EgtGetFirstNameInGroup( nBoxLayerId, "Box")
|
||||
local b3Part = EgtGetBBoxGlob(nBoxId, GDB_BB.STANDARD)
|
||||
local dPartWidth = b3Part:getDimY() + NEST.KERF
|
||||
for nInd2 = 1, #vFilledSheets do
|
||||
if dPartWidth < vFilledSheets[nInd2].Width then
|
||||
-- verifico se il grezzo aveva già un pezzo in un angolo
|
||||
if abs( vFilledSheets[nInd2].Width - vFilledSheets[nInd2].OrigWidth) < GEO.EPS_SMALL then
|
||||
vFilledSheets[nInd2].Width = vFilledSheets[nInd2].Width - dPartWidth - WD.SIDEMILL_DIAM_DOWN
|
||||
else
|
||||
-- se il grezzo aveva già un pezzo nell'angolo, dopo il pezzo corrente non ne posso mettere altri
|
||||
vFilledSheets[nInd2].Width = 0
|
||||
end
|
||||
bFound = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
-- se ho ancora angoli a disposizione oppure il pezzo deve stare necessariamente sull'angolo per essere lavorato
|
||||
if bFound or AngleClassification[nInd].Angle == 100 then
|
||||
-- verifico se va nestato manualmente
|
||||
if AngleClassification[nInd].bManual then
|
||||
|
||||
-- trovo il punto della lista dove inserirlo
|
||||
local nIdx = -1
|
||||
local bOnOppositeSide = false
|
||||
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)
|
||||
|
||||
if #(vManuallyDone[nInd2].Parts) == 0 then
|
||||
-- verifico che il pezzo stia in questo grezzo
|
||||
local b3Part = EgtGetBBoxGlob( AngleClassification[nInd].PartId, GDB_BB.STANDARD)
|
||||
if b3Part:getDimX() < RawParts[vManuallyDone[nInd2].RawPartId].Len and b3Part:getDimY() < RawParts[vManuallyDone[nInd2].RawPartId].Width then
|
||||
nIdx = nInd2
|
||||
break
|
||||
end
|
||||
|
||||
elseif #(vManuallyDone[nInd2].Parts) == 1 and bCanBeOnOtherAngle then
|
||||
-- verifico se il pezzo già posizionato nell'angolo non ha fori lunghi
|
||||
if not vManuallyDone[nInd2].Parts[1].bLongDrill then
|
||||
-- oriento il pezzo in modo ottimale per andare su quell'angolo
|
||||
local sRefOrig
|
||||
if WD.ORIG_CORNER == 'TL' then sRefOrig = 'BL' end
|
||||
if WD.ORIG_CORNER == 'BL' then sRefOrig = 'TL' end
|
||||
if WD.ORIG_CORNER == 'TR' then sRefOrig = 'BR' end
|
||||
if WD.ORIG_CORNER == 'BR' then sRefOrig = 'TR' end
|
||||
local res = ClassifyAngles( AngleClassification[nInd].PartId, RawParts[vManuallyDone[nInd2].RawPartId], sRefOrig)
|
||||
-- verifico sia compatibile con pezzo già inserito
|
||||
local b3OtherPart = EgtGetBBoxGlob( vManuallyDone[nInd2].Parts[1].Id, GDB_BB.STANDARD)
|
||||
local b3Part = EgtGetBBoxGlob( AngleClassification[nInd].PartId, GDB_BB.STANDARD)
|
||||
local dExtra = 2 * NEST.KERF + WD.SIDEMILL_DIAM_DOWN + 1
|
||||
-- se è compatibile assegno questa rotazione al pezzo
|
||||
if b3Part:getDimY() + b3OtherPart:getDimY() + dExtra < RawParts[vManuallyDone[nInd2].RawPartId].Width then
|
||||
nIdx = nInd2
|
||||
bOnOppositeSide = true
|
||||
-- aggiorno le info di rotazione
|
||||
if res.nRotate > 0 then
|
||||
local nPartRot = EgtGetInfo( AngleClassification[nInd].PartId, "ROTATED", 'i') or 0
|
||||
local nTotRot = nPartRot + res.nRotate
|
||||
nTotRot = EgtIf( nTotRot < 360, nTotRot, nTotRot - 360)
|
||||
EgtSetInfo( AngleClassification[nInd].PartId, "ROTATED", nTotRot)
|
||||
EgtSetInfo( AngleClassification[nInd].PartId, "MODIFIEDFORNEST", 1)
|
||||
end
|
||||
break
|
||||
end
|
||||
-- altrimenti lo riporto nella sua posizione originaria
|
||||
EgtRotate( AngleClassification[nInd].PartId, b3Part:getCenter(), Z_AX(), - res.nRotate, GDB_RT.GLOB)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
elseif #(vManuallyDone[nInd2].Parts) == 1 and bCanBeOnOtherAngle and nFilledSheets == nSheetNbr then
|
||||
-- verifico se il pezzo già posizionato nell'angolo non ha fori lunghi
|
||||
if not vManuallyDone[nInd2].Parts[1].bLongDrill then
|
||||
-- oriento il pezzo in modo ottimale per andare su quell'angolo
|
||||
local sRefOrig
|
||||
if WD.ORIG_CORNER == 'TL' then sRefOrig = 'BL' end
|
||||
if WD.ORIG_CORNER == 'BL' then sRefOrig = 'TL' end
|
||||
if WD.ORIG_CORNER == 'TR' then sRefOrig = 'BR' end
|
||||
if WD.ORIG_CORNER == 'BR' then sRefOrig = 'TR' end
|
||||
local res = ClassifyAngles( AngleClassification[nInd].PartId, RawParts[vManuallyDone[nInd2].RawPartId], sRefOrig)
|
||||
-- verifico sia compatibile con pezzo già inserito
|
||||
local b3OtherPart = EgtGetBBoxGlob( vManuallyDone[nInd2].Parts[1].Id, GDB_BB.STANDARD)
|
||||
local b3Part = EgtGetBBoxGlob( AngleClassification[nInd].PartId, GDB_BB.STANDARD)
|
||||
local dExtra = 2 * NEST.KERF + WD.SIDEMILL_DIAM_DOWN + 1
|
||||
-- se è compatibile assegno questa rotazione al pezzo
|
||||
if b3Part:getDimY() + b3OtherPart:getDimY() + dExtra < RawParts[vManuallyDone[nInd2].RawPartId].Width then
|
||||
nIdx = nInd2
|
||||
bOnOppositeSide = true
|
||||
-- aggiorno le info di rotazione
|
||||
if res.nRotate > 0 then
|
||||
local nPartRot = EgtGetInfo( AngleClassification[nInd].PartId, "ROTATED", 'i') or 0
|
||||
local nTotRot = nPartRot + res.nRotate
|
||||
nTotRot = EgtIf( nTotRot < 360, nTotRot, nTotRot - 360)
|
||||
EgtSetInfo( AngleClassification[nInd].PartId, "ROTATED", nTotRot)
|
||||
EgtSetInfo( AngleClassification[nInd].PartId, "MODIFIEDFORNEST", 1)
|
||||
end
|
||||
break
|
||||
end
|
||||
-- altrimenti lo riporto nella sua posizione originaria
|
||||
EgtRotate( AngleClassification[nInd].PartId, b3Part:getCenter(), Z_AX(), - res.nRotate, GDB_RT.GLOB)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if nIdx ~= -1 then
|
||||
-- nesto il pezzo a mano
|
||||
-- aree di lavorazione
|
||||
local nToolOutlineIds = ComputeToolOutlines( AngleClassification[nInd].PartId)
|
||||
local sInfo = ""
|
||||
for nInd = 1, #nToolOutlineIds do
|
||||
sInfo = sInfo .. tostring(nToolOutlineIds[nInd]) .. ","
|
||||
end
|
||||
-- salvo tra le info del pezzo gli id delle sue aree di lavorazione
|
||||
if sInfo ~= "" then
|
||||
EgtSetInfo( AngleClassification[nInd].PartId, "ToolOutlines", sInfo)
|
||||
end
|
||||
|
||||
-- calcolo defect corrispondente al pezzo
|
||||
local PartTab = CreateDefectOnAngle( AngleClassification[nInd].PartId, RawParts[vManuallyDone[nIdx].RawPartId], AngleClassification[nInd].bLongDrill, bOnOppositeSide)
|
||||
PartTab.bLongDrill = AngleClassification[nInd].bLongDrill
|
||||
table.insert( vManuallyDone[nIdx].Parts, PartTab)
|
||||
table.insert( vPartsManuallyDone, tonumber( AngleClassification[nInd].PartId))
|
||||
-- nesto il pezzo a mano
|
||||
if nIdx ~= -1 then
|
||||
-- aree di lavorazione
|
||||
local nToolOutlineIds = ComputeToolOutlines( AngleClassification[nInd].PartId)
|
||||
local sInfo = ""
|
||||
for nInd = 1, #nToolOutlineIds do
|
||||
sInfo = sInfo .. tostring(nToolOutlineIds[nInd]) .. ","
|
||||
end
|
||||
-- salvo tra le info del pezzo gli id delle sue aree di lavorazione
|
||||
if sInfo ~= "" then
|
||||
EgtSetInfo( AngleClassification[nInd].PartId, "ToolOutlines", sInfo)
|
||||
end
|
||||
|
||||
-- calcolo defect corrispondente al pezzo
|
||||
local PartTab = CreateDefectOnAngle( AngleClassification[nInd].PartId, RawParts[vManuallyDone[nIdx].RawPartId], AngleClassification[nInd].bLongDrill, bOnOppositeSide)
|
||||
PartTab.bLongDrill = AngleClassification[nInd].bLongDrill
|
||||
table.insert( vManuallyDone[nIdx].Parts, PartTab)
|
||||
table.insert( vPartsManuallyDone, tonumber( AngleClassification[nInd].PartId))
|
||||
|
||||
else
|
||||
-- aggiungo info per il nesting per ricordare che andrà su angolo
|
||||
EgtSetInfo( AngleClassification[nInd].PartId, "NestOnAngle", 1)
|
||||
end
|
||||
else
|
||||
-- se non va nestato manualmente segno info per nesting
|
||||
EgtSetInfo( AngleClassification[nInd].PartId, "NestOnAngle", 1)
|
||||
end
|
||||
|
||||
else
|
||||
-- aggiungo info per il nesting per ricordare che andrà sul lato
|
||||
EgtSetInfo( AngleClassification[nInd].PartId, "NestOnEdge", 1)
|
||||
|
||||
end
|
||||
-- se non ho più angoli a disposizione lo metto sul lato
|
||||
EgtSetInfo(AngleClassification[nInd].PartId, "NestOnEdge", 1)
|
||||
end
|
||||
|
||||
else
|
||||
-- aggiungo info per il nesting per ricordare che andrà sul lato
|
||||
EgtSetInfo( AngleClassification[nInd].PartId, "NestOnEdge", 1)
|
||||
EgtSetInfo(AngleClassification[nInd].PartId, "NestOnEdge", 1)
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
local nInd = 1
|
||||
@@ -1132,6 +1189,24 @@ end
|
||||
|
||||
local function AddParts(RawParts, vPartsDoneManually)
|
||||
|
||||
-- cerco la width massima dei grezzi
|
||||
local dRawMaxWidth = - 100
|
||||
for nIndex = 1, #RawParts do
|
||||
if RawParts[nIndex].Width > dRawMaxWidth then
|
||||
dRawMaxWidth = RawParts[nIndex].Width
|
||||
end
|
||||
end
|
||||
|
||||
-- valori correttivi per vincoli StripX e StripY
|
||||
local dStripYCorr = GEO.EPS_SMALL
|
||||
local dStripXCorr = GEO.EPS_SMALL
|
||||
if NEST.CORNER == NST_CORNER.TL or NEST.CORNER == NST_CORNER.TR then
|
||||
dStripYCorr = 0.1 - GEO.EPS_SMALL
|
||||
end
|
||||
if NEST.CORNER == NST_CORNER.BR or NEST.CORNER == NST_CORNER.TR then
|
||||
dStripXCorr = 0.1 - GEO.EPS_SMALL
|
||||
end
|
||||
|
||||
local nTotParts = 0
|
||||
for _ in pairs( PART) do nTotParts = nTotParts + 1 end
|
||||
local nPartIndex = 0
|
||||
@@ -1185,7 +1260,7 @@ local function AddParts(RawParts, vPartsDoneManually)
|
||||
nRotate = EgtGetInfo( nPartId, "NestRot", 'i')
|
||||
bRotNest = EgtGetInfo( nPartId, "NestAllowRot", 'b')
|
||||
-- verifico se rotazione è valida (pezzo è contenuto nel grezzo)
|
||||
local bValidRotationInRaw = b3Part:getDimX() < RawParts[1].Len and b3Part:getDimY() < RawParts[1].Width
|
||||
local bValidRotationInRaw = b3Part:getDimX() < RawParts[1].Len - 2 * NEST.KERF + GEO.EPS_SMALL and b3Part:getDimY() < dRawMaxWidth - 2 * NEST.KERF + GEO.EPS_SMALL
|
||||
if not bValidRotationInRaw then
|
||||
bRotNest = true
|
||||
nStepRotNest = 90
|
||||
@@ -1249,7 +1324,7 @@ local function AddParts(RawParts, vPartsDoneManually)
|
||||
local bPartIsModified = EgtGetInfo( nPartId, "MODIFIEDFORNEST", 'b')
|
||||
if not nOldOutline or bPartIsModified then
|
||||
|
||||
-- elimino il vecchio contorno se presente
|
||||
-- elimino il vecchio contorno se pesente
|
||||
while ( nOldOutline) do
|
||||
EgtErase(nOldOutline or GDB_ID.NULL)
|
||||
nOldOutline = EgtGetFirstNameInGroup( nOutlineLayer, 'ON_TMP')
|
||||
@@ -1475,25 +1550,36 @@ local function AddParts(RawParts, vPartsDoneManually)
|
||||
EgtSetInfo( nPartId, "ToolOutlines", sInfo)
|
||||
end
|
||||
|
||||
-- se necessario forzo il pezzo sul lato
|
||||
-- Eventuali vincoli StripX e StripY
|
||||
local bOnEdge = EgtGetInfo(nPartId, "NestOnEdge", 'b')
|
||||
if bOnEdge then
|
||||
local bOnAngle = EgtGetInfo(nPartId, "NestOnAngle", 'b')
|
||||
if bOnEdge or bOnAngle then
|
||||
local nBoxLayerId = EgtGetFirstNameInGroup( nPartId, "Box")
|
||||
local nBoxId = EgtGetFirstNameInGroup( nBoxLayerId, "Box")
|
||||
local b3Part = EgtGetBBoxGlob(nBoxId, GDB_BB.STANDARD)
|
||||
-- local b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD)
|
||||
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))
|
||||
|
||||
-- punto di riferimento sul pezzo
|
||||
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
|
||||
|
||||
-- vincolo StripY
|
||||
EgtAutoNestSetStripYconstraintToPart( nPartId, ptRef, NEST.KERF + dval + dStripYCorr, dRawMaxWidth - 2 * ( NEST.KERF + dval))
|
||||
|
||||
-- se sull'angolo aggiungo anche vincolo StripX
|
||||
if bOnAngle then
|
||||
if WD.ORIG_CORNER == 'TL' or WD.ORIG_CORNER == 'BL' then
|
||||
EgtAutoNestSetStripXconstraintToPart( nPartId, ptRef, NEST.KERF + b3Part:getDimX() / 2 + dStripXCorr, 100000)
|
||||
else
|
||||
EgtAutoNestSetStripXconstraintToPart( nPartId, ptRef, -100, RawParts[1].Len + 100 - NEST.KERF - b3Part:getDimX() / 2 + dStripXCorr)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- verifico se anullato nesting
|
||||
if EgtProcessEvents( 100 + ( nPartIndex / nTotParts * 100), 0) == 1 then
|
||||
return false
|
||||
@@ -1589,6 +1675,19 @@ while bNestingOk do
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local dXCorr = 0
|
||||
local dYCorr = 0
|
||||
if NEST.CORNER == NST_CORNER.TL then
|
||||
dYCorr = - 0.1
|
||||
elseif NEST.CORNER == NST_CORNER.TR then
|
||||
dYCorr = - 0.1
|
||||
dXCorr = - 0.1
|
||||
elseif NEST.CORNER == NST_CORNER.BR then
|
||||
dXCorr = - 0.1
|
||||
end
|
||||
|
||||
|
||||
-- se nesting andato bene
|
||||
if bNestingOk then
|
||||
|
||||
@@ -1714,9 +1813,9 @@ if bNestingOk then
|
||||
local nBoxId = EgtGetFirstNameInGroup( nBoxLayerId, "Box")
|
||||
local PartBBox = EgtGetBBoxGlob(nBoxId, GDB_BB.STANDARD)
|
||||
local ptPos = Point3d( PartBBox:getMin():getX(), PartBBox:getMin():getY(), 0)
|
||||
EgtSetInfo( nMachGroup, "PART" .. nPartCount, nPartDuploId .. "," .. EgtNumToString( ptPos:getX(), 3) .. "," .. EgtNumToString( ptPos:getY(), 3) .. "," .. 0 .."," .. 0)
|
||||
EgtSetInfo( nPartDuploId, "POSX", ptPos:getX())
|
||||
EgtSetInfo( nPartDuploId, "POSY", ptPos:getY())
|
||||
EgtSetInfo( nMachGroup, "PART" .. nPartCount, nPartDuploId .. "," .. EgtNumToString( ptPos:getX() + dXCorr, 3) .. "," .. EgtNumToString( ptPos:getY() + dYCorr, 3) .. "," .. 0 .."," .. 0)
|
||||
EgtSetInfo( nPartDuploId, "POSX", ptPos:getX() + dXCorr)
|
||||
EgtSetInfo( nPartDuploId, "POSY", ptPos:getY() + dYCorr)
|
||||
|
||||
local nPartRot = EgtGetInfo( nId, "ROTATED", 'i') or 0
|
||||
local nTotRot = dAngRot + nPartRot
|
||||
|
||||
Reference in New Issue
Block a user