diff --git a/NestProcess.lua b/NestProcess.lua index cc70b40..e7c4a31 100644 --- a/NestProcess.lua +++ b/NestProcess.lua @@ -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