Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0d3b3d1f04 | |||
| c490d5d388 | |||
| bc401eef07 | |||
| a93326e3cd | |||
| 6b5d7525a1 | |||
| 111a733365 | |||
| 7ce6ca9f13 | |||
| 6902620f5d | |||
| 7c6b5cf12c | |||
| 9c0d2111f5 |
+30
-2
@@ -46,6 +46,7 @@
|
||||
-- 2023/02/20 Ora le mortase a coda di rondine laterali sono sempre fatte prima dei tagli longitudinali.
|
||||
-- 2023/03/31 Corretto ordinamento per fori di coda da lasciare in coda.
|
||||
-- 2023/07/31 Corretto errore nelle mortase in doppio.
|
||||
-- 2023/09/13 Aggiunta ClassifyTopology per la classificazione topologica delle feature. In CollectFeatures aggiunta la raccolta preliminare di alcune informazioni.
|
||||
|
||||
-- Tabella per definizione modulo
|
||||
local BeamExec = {}
|
||||
@@ -102,6 +103,7 @@ _G.package.loaded.ProcessFreeContour = nil
|
||||
_G.package.loaded.ProcessDecor = nil
|
||||
local ML = require( 'MachiningLib')
|
||||
local BL = require( 'BeamLib')
|
||||
local Topology = require( 'FeatureTopology')
|
||||
local DC = require( 'DiceCut')
|
||||
local Fbs = require( 'FacesBySaw')
|
||||
local Hcut= require( 'ProcessHeadCut')
|
||||
@@ -280,6 +282,7 @@ local function CollectFeatures( PartId, b3Raw, dCurrOvmH, dCurrOvmT)
|
||||
local nAddMainId = EgtGetInfo( ProcId, 'MAINID', 'i')
|
||||
if nGrp and nPrc and nDo == 1 then
|
||||
local Proc = {}
|
||||
Proc.PartId = PartId
|
||||
Proc.Id = ProcId
|
||||
Proc.Grp = nGrp
|
||||
Proc.Prc = nPrc
|
||||
@@ -297,6 +300,15 @@ local function CollectFeatures( PartId, b3Raw, dCurrOvmH, dCurrOvmT)
|
||||
Proc.MainId = Proc.Id + nAddMainId
|
||||
end
|
||||
Proc.Box = EgtGetBBoxGlob( ProcId, GDB_BB.STANDARD)
|
||||
if b3Raw then
|
||||
-- recupero l'elenco delle facce della parte interessate dalla feature
|
||||
Proc.AffectedFaces = BL.GetProcessAffectedFaces( Proc)
|
||||
-- recupero informazioni sulle facce della feature
|
||||
Proc.Face = {}
|
||||
for i = 1, Proc.Fct do
|
||||
Proc.Face[i] = { Id = i - 1, VtN = EgtSurfTmFacetNormVersor( Proc.Id, i - 1, GDB_ID.ROOT ), Elevation = BL.GetFaceElevation( Proc.Id, i - 1, PartId)}
|
||||
end
|
||||
end
|
||||
if Proc.Box and not Proc.Box:isEmpty() then
|
||||
Proc.Head = IsHeadFeature( Proc, b3Raw, dCurrOvmH)
|
||||
Proc.Tail, Proc.AdvTail = IsTailFeature( Proc, b3Raw, dCurrOvmH, dCurrOvmT)
|
||||
@@ -324,6 +336,7 @@ local function CollectFeatures( PartId, b3Raw, dCurrOvmH, dCurrOvmT)
|
||||
Proc.Tail = Drill.IsTailFeature( Proc, b3Raw, dCurrOvmH, dCurrOvmT)
|
||||
-- definisco dati seconda parte
|
||||
local Proc2 = {}
|
||||
Proc2.PartId = PartId
|
||||
Proc2.Id = ProcId
|
||||
Proc2.Grp = nGrp
|
||||
Proc2.Prc = nPrc
|
||||
@@ -651,11 +664,11 @@ local function PrintFeatures( vProc, b3Raw)
|
||||
EgtOutLog( ' RawBox=' .. tostring( b3Raw))
|
||||
for i = 1, #vProc do
|
||||
local Proc = vProc[i]
|
||||
local sOut = string.format( ' Id=%3d Grp=%1d Prc=%3d TC=%2d/%d Flg=%2d Down=%s Side=%s Head=%s Tail=%s Fcse=%1d,%1d Diam=%.2f Fct=%2d Box=%s',
|
||||
local sOut = string.format( ' Id=%3d Grp=%1d Prc=%3d TC=%2d/%d Flg=%2d Down=%s Side=%s Head=%s Tail=%s Fcse=%1d,%1d Diam=%.2f Fct=%2d Box=%s TopoName=%s',
|
||||
Proc.Id, Proc.Grp, Proc.Prc, Proc.TaskId, Proc.CutId,
|
||||
Proc.Flg, EgtIf( Proc.Down, 'T', 'F'), EgtIf( Proc.Side, 'T', 'F'),
|
||||
EgtIf( Proc.Head, 'T', 'F'), EgtIf( Proc.Tail, 'T', EgtIf( Proc.AdvTail, 'A', 'F')),
|
||||
Proc.Fcs, Proc.Fce, Proc.Diam, Proc.Fct, tostring( Proc.Box))
|
||||
Proc.Fcs, Proc.Fce, Proc.Diam, Proc.Fct, tostring( Proc.Box), Proc.TopologyLongName or '')
|
||||
-- info speciali per Block Haus Half Lap
|
||||
if Proc.Prc == 37 then
|
||||
local sSpec = string.format( ' N=%s Hd=%s', tostring( Proc.vtN or V_NULL()), EgtIf( Proc.HeadDir, 'T', 'F'))
|
||||
@@ -1137,6 +1150,19 @@ local function ClassifyFeatures( vProc, b3Raw, Stats)
|
||||
return bAllOk, bSomeDown, bSomeSide, bSplitRot
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function ClassifyTopology( vProc)
|
||||
local nRecognized = 0
|
||||
for i = 1, #vProc do
|
||||
local Proc = vProc[i]
|
||||
if Topology.Classify( Proc) then
|
||||
nRecognized = nRecognized + 1
|
||||
end
|
||||
end
|
||||
|
||||
return nRecognized
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function AddFeatureMachining( Proc, nPhase, nRawId, nPartId, dCurrOvmH, bNeedHCut, b3Raw, nOrd, sDownOrSideOrStd, bPreMove, vtMove, dCurrOvmT)
|
||||
local bOk = true
|
||||
@@ -1816,6 +1842,8 @@ function BeamExec.ProcessFeatures()
|
||||
if BD.TWO_EQUAL_HEADS or BD.DOWN_HEAD then
|
||||
SetMirroredFeatures( vProc, b3Raw)
|
||||
end
|
||||
-- classifico topologicamente le feature
|
||||
ClassifyTopology( vProc)
|
||||
-- le ordino lungo X
|
||||
OrderFeatures( vProc, b3Raw)
|
||||
-- le classifico
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
-- 2023/01/31 Aggiunta funzione ConvertToClosedCurve, precedentemente parte di ProcessMortise.Make
|
||||
-- 2023/02/22 Modifiche a SetOpenSide, aggiunte ChangeOrOpenStart e CurveWithOnlyStraightLines.
|
||||
-- 2023/06/12 In ChangeOrOpenStart corretta ricerca segmento più lungo.
|
||||
-- 2023/09/13 Aggiunte funzioni Is3EdgesApprox e GetProcessAffectedFaces.
|
||||
|
||||
-- Tabella per definizione modulo
|
||||
local BeamLib = {}
|
||||
@@ -1058,5 +1059,60 @@ function BeamLib.CurveWithOnlyStraightLines( nPathInt)
|
||||
return true
|
||||
end
|
||||
|
||||
---------------------------------------------------------------------
|
||||
-- Funzione per determinare se la faccia ha lati molto corti (trascurabili) ed è quindi approssimabile ad una 3 facce
|
||||
function BeamLib.Is3EdgesApprox( Proc, nFacet, nAddGrpId)
|
||||
nAddGrpId = nAddGrpId or BeamLib.GetAddGroup( Proc.PartId)
|
||||
local bResult = false
|
||||
local nContourId = EgtExtractSurfTmFacetLoops( Proc.Id, nFacet, nAddGrpId)
|
||||
EgtMergeCurvesInCurveCompo( nContourId)
|
||||
-- recupero il numero effettivo di lati
|
||||
local _, nEntityCount = EgtCurveDomain( nContourId)
|
||||
local nEdges = nEntityCount
|
||||
if nContourId then
|
||||
if nEntityCount and nEntityCount == 3 then
|
||||
bResult = true
|
||||
-- rimuovo i lati molto corti dal conteggio totale
|
||||
elseif nEntityCount then
|
||||
for i = 1, nEntityCount do
|
||||
local dLength = EgtCurveCompoLength( nContourId, i - 1)
|
||||
if dLength < 15 then nEdges = nEdges - 1 end
|
||||
end
|
||||
end
|
||||
if nEdges == 3 then bResult = true end
|
||||
end
|
||||
return bResult
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- restituisce le facce della parte interessate dalla feature Proc
|
||||
function BeamLib.GetProcessAffectedFaces( Proc)
|
||||
local nBoxSolidId = EgtGetFirstNameInGroup( Proc.PartId or GDB_ID.NULL, 'Box')
|
||||
local b3Part = EgtGetBBoxGlob( nBoxSolidId, GDB_BB.STANDARD)
|
||||
local vtFacesAffected = { Top = false, Bottom = false, Front = false, Back = false, Left = false, Right = false}
|
||||
if Proc.Box and not Proc.Box:isEmpty() then
|
||||
if Proc.Box:getMax():getZ() > b3Part:getMax():getZ() - 500 * GEO.EPS_SMALL then
|
||||
vtFacesAffected.Top = true
|
||||
end
|
||||
if Proc.Box:getMin():getZ() < b3Part:getMin():getZ() + 500 * GEO.EPS_SMALL then
|
||||
vtFacesAffected.Bottom = true
|
||||
end
|
||||
if Proc.Box:getMin():getY() < b3Part:getMin():getY() + 500 * GEO.EPS_SMALL then
|
||||
vtFacesAffected.Front = true
|
||||
end
|
||||
if Proc.Box:getMax():getY() > b3Part:getMax():getY() - 500 * GEO.EPS_SMALL then
|
||||
vtFacesAffected.Back = true
|
||||
end
|
||||
if Proc.Box:getMin():getX() < b3Part:getMin():getX() + 500 * GEO.EPS_SMALL then
|
||||
vtFacesAffected.Left = true
|
||||
end
|
||||
if Proc.Box:getMax():getX() > b3Part:getMax():getX() - 500 * GEO.EPS_SMALL then
|
||||
vtFacesAffected.Right = true
|
||||
end
|
||||
end
|
||||
|
||||
return vtFacesAffected
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
return BeamLib
|
||||
|
||||
@@ -0,0 +1,234 @@
|
||||
-- FeatureTopology.lua by Egaltech s.r.l. 2023/09/12
|
||||
-- Libreria per classificazione topologica feature travi
|
||||
|
||||
-- Tabella per definizione modulo
|
||||
local FeatureTopology = {}
|
||||
|
||||
-- Include
|
||||
require( 'EgtBase')
|
||||
|
||||
-- Carico le librerie
|
||||
local BL = require( 'BeamLib')
|
||||
|
||||
EgtOutLog( ' FeatureTopology started', 1)
|
||||
|
||||
---------------------------------------------------------------------
|
||||
-- restituisce la matrice delle adiacenze di Proc dove i e j sono le facce e a(ij) è l'angolo tra di esse; 0 se nessuna adiacenza
|
||||
local function GetAdjacencyMatrix( Proc)
|
||||
local vAdj = {}
|
||||
for i = 1, Proc.Fct do
|
||||
vAdj[i] = {}
|
||||
for j = 1, Proc.Fct do
|
||||
if i == j then
|
||||
vAdj[i][j] = 0
|
||||
else
|
||||
_, _, _, vAdj[i][j] = EgtSurfTmFacetsContact( Proc.Id, i - 1, j - 1, GDB_ID.ROOT)
|
||||
if not vAdj[i][j] then vAdj[i][j] = 0 end
|
||||
end
|
||||
j = j + 1
|
||||
end
|
||||
i = i + 1
|
||||
end
|
||||
return vAdj
|
||||
end
|
||||
|
||||
---------------------------------------------------------------------
|
||||
-- restituisce gli id delle facce di Proc che hanno il numero di adiacenze nAdj
|
||||
function FeatureTopology.GetFacesWithGivenAdjacencyNumber( Proc, nAdj)
|
||||
local vAdj = GetAdjacencyMatrix( Proc)
|
||||
local vFacesWithGivenAdj = {}
|
||||
for i = 1, Proc.Fct do
|
||||
local nAdjCount = 0
|
||||
for j = 1, Proc.Fct do
|
||||
if vAdj[i][j] and vAdj[i][j] ~= 0 then
|
||||
nAdjCount = nAdjCount + 1
|
||||
end
|
||||
end
|
||||
if nAdjCount == nAdj then
|
||||
table.insert( vFacesWithGivenAdj, i - 1)
|
||||
end
|
||||
end
|
||||
return vFacesWithGivenAdj
|
||||
end
|
||||
|
||||
---------------------------------------------------------------------
|
||||
-- restituisce true se Proc ha tutti gli angoli concavi (bAllConcave) e, nei casi in cui ha senso, se questi sono esattamente 90 deg (bAllRight)
|
||||
local function AreAllAnglesConcaveOrRight( Proc)
|
||||
local vAdj = GetAdjacencyMatrix( Proc)
|
||||
local bAllConcave, bAllRight = true, true
|
||||
for i = 1, Proc.Fct do
|
||||
for j = 1, Proc.Fct do
|
||||
-- se trovo un angolo convesso restituisco falso e esco subito
|
||||
if vAdj[i][j] and vAdj[i][j] > 0 then
|
||||
bAllConcave = false
|
||||
bAllRight = false
|
||||
break
|
||||
elseif vAdj[i][j] and vAdj[i][j] ~= 0 and vAdj[i][j] + 90 > 500 * GEO.EPS_ANG_SMALL then
|
||||
bAllRight = false
|
||||
end
|
||||
end
|
||||
end
|
||||
-- se 1 faccia oppure 2 facce con angolo convesso non ha senso ritornare valori per bAllRight
|
||||
if Proc.Fct < 2 or ( Proc.Fct == 2 and vAdj[1][2] > 0) then
|
||||
return bAllConcave
|
||||
else
|
||||
return bAllConcave, bAllRight
|
||||
end
|
||||
end
|
||||
|
||||
---------------------------------------------------------------------
|
||||
-- restituisce true se almeno una delle dimensioni della feature è maggiore o uguale ad una delle dimensioni principali del pezzo (tolleranza 1 mm)
|
||||
local function IsAnyDimensionLongAsPart( Proc)
|
||||
local bResult = false
|
||||
local nBoxSolidId = EgtGetFirstNameInGroup( Proc.PartId or GDB_ID.NULL, 'Box')
|
||||
local b3Solid = EgtGetBBoxGlob( nBoxSolidId, GDB_BB.STANDARD)
|
||||
if Proc.Box:getDimX() > b3Solid:getDimX() - 1000 * GEO.EPS_SMALL or
|
||||
Proc.Box:getDimY() > b3Solid:getDimY() - 1000 * GEO.EPS_SMALL or
|
||||
Proc.Box:getDimZ() > b3Solid:getDimZ() - 1000 * GEO.EPS_SMALL then
|
||||
bResult = true
|
||||
end
|
||||
return bResult
|
||||
end
|
||||
|
||||
---------------------------------------------------------------------
|
||||
-- retituisce un vettore con gli indici (0 based) delle facce triangolari (o quasi) di Proc
|
||||
local function GetTriangularFaces( Proc)
|
||||
local vTriangularFaces = {}
|
||||
for i = 1, Proc.Fct do
|
||||
if BL.Is3EdgesApprox( Proc, i - 1) then
|
||||
table.insert( vTriangularFaces, i - 1)
|
||||
end
|
||||
end
|
||||
return vTriangularFaces
|
||||
end
|
||||
|
||||
---------------------------------------------------------------------
|
||||
-- restituisce un vettore contenente gli indici delle facce di Proc parallele ad una delle direzioni principali; il check varia in base alla famiglia topologica
|
||||
local function GetFacesParallelToPart( Proc, sFamily)
|
||||
local vFacesParallelToPart = {}
|
||||
for i = 0, Proc.Fct - 1 do
|
||||
local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i, GDB_ID.ROOT)
|
||||
if sFamily == 'Bevel' or sFamily == 'DoubleBevel' then
|
||||
local vTriangularFaces = GetTriangularFaces( Proc)
|
||||
local bIsTriangularFace = false
|
||||
-- verifico se la faccia è triangolare
|
||||
for j = 1, #vTriangularFaces do
|
||||
if i == vTriangularFaces[j] then
|
||||
bIsTriangularFace = true
|
||||
end
|
||||
end
|
||||
-- se faccia triangolare deve avere la normale parallela ad una direzione principale
|
||||
if bIsTriangularFace then
|
||||
if AreSameOrOppositeVectorApprox( vtN, X_AX()) or AreSameOrOppositeVectorApprox( vtN, Y_AX()) or AreSameOrOppositeVectorApprox( vtN, Z_AX()) then
|
||||
table.insert( vFacesParallelToPart, i)
|
||||
end
|
||||
-- altrimenti deve avere una componente della normale nulla
|
||||
else
|
||||
if abs( vtN:getX()) < 10 * GEO.EPS_SMALL or abs( vtN:getY()) < 10 * GEO.EPS_SMALL or abs( vtN:getZ()) < 10 * GEO.EPS_SMALL then
|
||||
table.insert( vFacesParallelToPart, i)
|
||||
end
|
||||
end
|
||||
else
|
||||
-- la normale deve essere parallela ad una direzione principale
|
||||
if AreSameOrOppositeVectorApprox( vtN, X_AX()) or AreSameOrOppositeVectorApprox( vtN, Y_AX()) or AreSameOrOppositeVectorApprox( vtN, Z_AX()) then
|
||||
table.insert( vFacesParallelToPart, i)
|
||||
end
|
||||
end
|
||||
end
|
||||
return vFacesParallelToPart
|
||||
end
|
||||
|
||||
---------------------------------------------------------------------
|
||||
-- restituisce una stringa con il nome esteso della topologia della feature
|
||||
-- *famiglia-passante-angoli tutti concavi a 90deg-facce tutte parallele alle dimensioni principali-numero di facce*
|
||||
local function GetTopologyLongName( sFamily, bIsThrough, bAllRightAngles, bIsParallel, nNumberOfFaces)
|
||||
-- feature passante o cieca
|
||||
local sThrough = '_'
|
||||
if bIsThrough ~= nil then sThrough = EgtIf( bIsThrough, 'Through', 'Blind') end
|
||||
-- tutti gli angoli della feature sono retti oppure no
|
||||
local sAllRightAngles = '_'
|
||||
if bAllRightAngles ~= nil then sAllRightAngles = EgtIf( bAllRightAngles, 'RightAngles', 'NotRightAngles') end
|
||||
-- tutte le dimensioni della feature sono parallele agli assi principali del pezzo oppure no
|
||||
local sParallel = '_'
|
||||
if bIsParallel ~= nil then sParallel = EgtIf( bIsParallel, 'Parallel', 'NotParallel') end
|
||||
|
||||
local sLongName = sFamily .. '-' .. sThrough .. '-' .. sAllRightAngles .. '-' .. sParallel .. '-' .. nNumberOfFaces
|
||||
return sLongName
|
||||
end
|
||||
|
||||
---------------------------------------------------------------------
|
||||
-- riconosce se Proc è una delle topologie standard e, in caso positivo, ne scrive le caratteristiche in campi specifici della Proc stessa restituendo true
|
||||
function FeatureTopology.Classify( Proc)
|
||||
local bRecognized = false
|
||||
local sFamily
|
||||
local bIsThrough
|
||||
local bAllRightAngles
|
||||
local bIsParallel
|
||||
local sLongName = ''
|
||||
|
||||
-- SE NON HA TUTTE LE FACCE PIANE RITORNARE NIL!!
|
||||
|
||||
local bAllAnglesConcave
|
||||
bAllAnglesConcave, bAllRightAngles = AreAllAnglesConcaveOrRight( Proc)
|
||||
local vTriangularFaces = GetTriangularFaces( Proc)
|
||||
local bIsAnyDimensionLongAsPart = IsAnyDimensionLongAsPart( Proc)
|
||||
local vFacesWithTwoAdj = FeatureTopology.GetFacesWithGivenAdjacencyNumber( Proc, 2)
|
||||
local vFacesWithThreeAdj = FeatureTopology.GetFacesWithGivenAdjacencyNumber( Proc, 3)
|
||||
local vFacesWithFourAdj = FeatureTopology.GetFacesWithGivenAdjacencyNumber( Proc, 4)
|
||||
|
||||
if Proc.IsOutline then
|
||||
sFamily = 'OUTLINE'
|
||||
elseif Proc.Prc == 40 then
|
||||
sFamily = 'DRILLING'
|
||||
elseif Proc.Fct == 1 and bIsAnyDimensionLongAsPart then
|
||||
sFamily = 'Bevel'
|
||||
bIsThrough = true
|
||||
elseif Proc.Fct == 2 and bAllAnglesConcave and #vTriangularFaces == 1 then
|
||||
sFamily = 'Bevel'
|
||||
bIsThrough = false
|
||||
elseif Proc.Fct == 2 and bAllAnglesConcave then
|
||||
sFamily = 'Rabbet'
|
||||
bIsThrough = true
|
||||
elseif Proc.Fct == 2 and not bAllAnglesConcave and bIsAnyDimensionLongAsPart then
|
||||
sFamily = 'DoubleBevel'
|
||||
bIsThrough = true
|
||||
elseif Proc.Fct == 3 and bAllAnglesConcave and #vFacesWithTwoAdj == 1 and #vTriangularFaces == 2 then
|
||||
sFamily = 'Bevel'
|
||||
bIsThrough = false
|
||||
elseif Proc.Fct == 3 and bAllAnglesConcave and #vFacesWithTwoAdj == 1 and bIsAnyDimensionLongAsPart then
|
||||
sFamily = 'Groove'
|
||||
bIsThrough = true
|
||||
elseif Proc.Fct == 3 and bAllAnglesConcave and #vFacesWithTwoAdj == 3 then
|
||||
sFamily = 'Groove'
|
||||
bIsThrough = false
|
||||
elseif Proc.Fct == 4 and bAllAnglesConcave and #vFacesWithThreeAdj == 2 then
|
||||
sFamily = 'Groove'
|
||||
bIsThrough = false
|
||||
elseif Proc.Fct == 4 and bAllAnglesConcave and #vFacesWithTwoAdj == 4 and bIsAnyDimensionLongAsPart then
|
||||
sFamily = 'Tunnel'
|
||||
bIsThrough = true
|
||||
elseif Proc.Fct == 5 and bAllAnglesConcave and #vFacesWithFourAdj == 1 then
|
||||
sFamily = 'Pocket'
|
||||
bIsThrough = false
|
||||
end
|
||||
local vFacesParallelToPart = GetFacesParallelToPart( Proc, sFamily)
|
||||
bIsParallel = ( #vFacesParallelToPart == Proc.Fct)
|
||||
|
||||
if sFamily == 'OUTLINE' or sFamily == 'DRILLING' then
|
||||
Proc.Topology = sFamily
|
||||
Proc.TopologyLongName = sFamily
|
||||
bRecognized = true
|
||||
elseif sFamily then
|
||||
sLongName = GetTopologyLongName( sFamily, bIsThrough, bAllRightAngles, bIsParallel, Proc.Fct)
|
||||
Proc.Topology, Proc.IsThrough, Proc.AllRightAngles, Proc.IsParallel, Proc.TopologyLongName = sFamily, bIsThrough, bAllRightAngles, bIsParallel, sLongName
|
||||
bRecognized = true
|
||||
else
|
||||
Proc.Topology = 'OTHER'
|
||||
Proc.TopologyLongName = 'OTHER'
|
||||
end
|
||||
|
||||
return bRecognized
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
return FeatureTopology
|
||||
+85
-25
@@ -5189,7 +5189,7 @@ local function MakeMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, bSinglePa
|
||||
-- 3 facce non a L ma con una faccia favorevole a Y, oppure
|
||||
-- 4 facce
|
||||
-- lancio la MakePocket ( lavorazione solo da un lato, fondo della tasca la faccia più favorevole a Y)
|
||||
if bForceSideMill and (( Proc.Fct == 3 and bIsL) or ( ( Proc.Fct == 3 or Proc.Fct == 2) and abs( vtNFacApproxY:getY()) >= 0.707 ) or Proc.Fct == 4) then
|
||||
if bForceSideMill and (( Proc.Fct == 3 and bIsL) or ( ( Proc.Fct == 3 or Proc.Fct == 2) and abs( vtNFacApproxY:getY()) >= 0.707 ) or ( Proc.Fct == 4 and Proc.Topology == 'Groove')) then
|
||||
nFacInd, vtN, ptC = nFacApproxY, vtNFacApproxY, ptCFacApproxY
|
||||
local tvtNx = {}
|
||||
tvtNx[2] = vtN
|
||||
@@ -5544,62 +5544,101 @@ local function MakeLongMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead)
|
||||
-- ottengo la distanza tra la fine del pezzo e il pezzo successivo
|
||||
local dDistToNextPiece = BL.GetDistanceToNextPart( nRawId, nPhase)
|
||||
-- verifico se applicare gestione speciale delle giunzioni (U diretta come asse X)
|
||||
local bAddEndCap = false
|
||||
local bAddEndCapLeftSide, bAddEndCapRightSide = false, false
|
||||
local dAddLen = 0
|
||||
local bIsOpenU = ( Proc.Fct == 3 and not TestElleShape3( Proc))
|
||||
if bIsOpenU then
|
||||
local ptC0, vtN0 = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT)
|
||||
local ptC1, vtN1 = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT)
|
||||
local ptC2, vtN2 = EgtSurfTmFacetCenter( Proc.Id, 2, GDB_ID.ROOT)
|
||||
if vtN0:getX() < 0.0175 and vtN1:getX() < 0.0175 and vtN2:getX() < 0.0175 then
|
||||
if abs( vtN0:getX()) < 0.0175 and abs( vtN1:getX()) < 0.0175 and abs( vtN2:getX()) < 0.0175 then
|
||||
local dWidth = 0
|
||||
if vtN0 * vtN1 < -0.9998 then
|
||||
bAddEndCap = true
|
||||
bAddEndCapLeftSide = true
|
||||
dWidth = ( ptC1 - ptC0) * vtN0
|
||||
elseif vtN0 * vtN2 < -0.9998 then
|
||||
bAddEndCap = true
|
||||
bAddEndCapLeftSide = true
|
||||
dWidth = ( ptC2 - ptC0) * vtN0
|
||||
elseif vtN1 * vtN2 < -0.9998 then
|
||||
bAddEndCap = true
|
||||
bAddEndCapLeftSide = true
|
||||
dWidth = ( ptC2 - ptC1) * vtN1
|
||||
end
|
||||
dAddLen = min( dWidth, 100) / 2
|
||||
end
|
||||
end
|
||||
-- verifico se applicare gestione speciale per tunnel
|
||||
local nSurfBottomId
|
||||
if Proc.Topology == 'Tunnel' and Proc.AffectedFaces.Front then
|
||||
bAddEndCapLeftSide = true
|
||||
bAddEndCapRightSide = true
|
||||
-- recupero centro e normale delle facce
|
||||
local vtN = {}
|
||||
for i = 1, Proc.Fct do
|
||||
vtN[i] = EgtSurfTmFacetNormVersor( Proc.Id, i - 1, GDB_ID.ROOT)
|
||||
end
|
||||
-- calcolo l'orientamento del tunnel
|
||||
local vtOrtho
|
||||
local bAdj = EgtSurfTmFacetsContact( Proc.Id, 0, 1)
|
||||
if bAdj then
|
||||
vtOrtho = vtN[1] ^ vtN[2]
|
||||
else
|
||||
if Proc.Fct >= 3 then
|
||||
vtOrtho = vtN[1] ^ vtN[3]
|
||||
else
|
||||
return 0, 0, 0
|
||||
end
|
||||
end
|
||||
local ptMaxBox = Proc.Box:getMax()
|
||||
-- per creare le superfici di cap nei tunnel serve aggiungere una faccia di fondo
|
||||
-- recupero il box della trave e lo ingrandisco di poco per essere sicuro di avere intersezione con il piano di fondo
|
||||
local b3SolidExtended = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
|
||||
b3SolidExtended:expand( 100 * GEO.EPS_SMALL)
|
||||
-- superficie di fondo
|
||||
nSurfBottomId = EgtSurfTmPlaneInBBox( nAddGrpId, ptMaxBox, vtOrtho, b3SolidExtended, GDB_ID.ROOT)
|
||||
-- calcolo di quanto allargare le superfici
|
||||
local dWidth = b3Raw:getDimY()
|
||||
dAddLen = min( dWidth, 100) / 2
|
||||
end
|
||||
-- la divido in parti lungo X
|
||||
local vAddId = {}
|
||||
local bAllWithEndCap = bAddEndCap
|
||||
local bAllWithEndCap = bAddEndCapLeftSide or bAddEndCapRightSide
|
||||
local nPart = max( ceil( Proc.Box:getDimX() / BD.LONGCUT_MAXLEN), 2)
|
||||
local dPartLen = Proc.Box:getDimX() / nPart
|
||||
local Xmin = Proc.Box:getMin():getX()
|
||||
-- trimesh per la creazione degli EndCap
|
||||
local AddIdCopy = EgtCopyGlob( Proc.Id, nAddGrpId) or GDB_ID.NULL
|
||||
-- aggiunta di eventuale fondo alla trimesh per creare correttamente le superfici EndCap
|
||||
if nSurfBottomId then EgtSurfTmAdd( AddIdCopy, nSurfBottomId) end
|
||||
for i = 1, nPart do
|
||||
local nCapIdLeftSide, nCapIdRightSide
|
||||
-- eseguo divisione
|
||||
local AddId = EgtCopyGlob( Proc.Id, nAddGrpId) or GDB_ID.NULL
|
||||
if i > 1 or bAddEndCap then
|
||||
-- definizione del piano
|
||||
if i > 1 or bAddEndCapLeftSide then
|
||||
-- definizione del piano sinsitro
|
||||
local dAdd = EgtIf( i > 1, dAddLen, 0)
|
||||
local ptOn = Point3d( Xmin - dAdd + ( i - 1) * dPartLen, 0, 0)
|
||||
local vtN = -X_AX()
|
||||
-- se richiesto, creazione tappo
|
||||
local CapId
|
||||
if bAddEndCap then
|
||||
local nFirstId, nPnt, nCrv, nSrf = EgtPlaneSurfTmInters( ptOn, vtN, AddId, nAddGrpId, GDB_RT.GLOB)
|
||||
-- se richiesto, creazione tappo sinistro
|
||||
if bAddEndCapLeftSide then
|
||||
local nFirstId, nPnt, nCrv, nSrf = EgtPlaneSurfTmInters( ptOn, vtN, AddIdCopy, nAddGrpId, GDB_RT.GLOB)
|
||||
if nPnt == 0 and nCrv == 1 and nSrf == 0 then
|
||||
EgtCloseCurveCompo( nFirstId)
|
||||
CapId = EgtSurfTmByFlatContour( nAddGrpId, nFirstId)
|
||||
if not CapId then bAllWithEndCap = false end
|
||||
end
|
||||
if nFirstId then
|
||||
for nId = nFirstId, nFirstId + nPnt + nCrv + nSrf - 1 do
|
||||
EgtErase( nId)
|
||||
end
|
||||
nCapIdLeftSide = EgtSurfTmByFlatContour( nAddGrpId, nFirstId)
|
||||
if not nCapIdLeftSide then bAllWithEndCap = false end
|
||||
end
|
||||
if nFirstId then
|
||||
for nId = nFirstId, nFirstId + nPnt + nCrv + nSrf - 1 do
|
||||
EgtErase( nId)
|
||||
end
|
||||
end
|
||||
end
|
||||
-- taglio della superficie
|
||||
EgtCutSurfTmPlane( AddId, ptOn, vtN, true, GDB_RT.GLOB)
|
||||
-- se esiste, aggiunta del tappo
|
||||
if CapId then
|
||||
AddId = EgtSurfTmBySewing( nAddGrpId, { AddId, CapId})
|
||||
if i > 1 then
|
||||
-- taglio della superficie lato sinistro
|
||||
EgtCutSurfTmPlane( AddId, ptOn, vtN, true, GDB_RT.GLOB)
|
||||
end
|
||||
-- se esiste, aggiunta del tappo sinistro
|
||||
if nCapIdLeftSide then
|
||||
AddId = EgtSurfTmBySewing( nAddGrpId, { AddId, nCapIdLeftSide})
|
||||
-- se prima spezzatura, allungamento per non lasciare archi
|
||||
if i == 1 then
|
||||
local b3Box = EgtGetBBoxGlob( AddId, GDB_BB.STANDARD)
|
||||
@@ -5609,14 +5648,35 @@ local function MakeLongMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead)
|
||||
end
|
||||
end
|
||||
if i < nPart then
|
||||
-- definizione del piano destro
|
||||
local ptOn = Point3d( Xmin + i * dPartLen, 0, 0)
|
||||
local vtN = X_AX()
|
||||
-- taglio della superficie lato destro
|
||||
EgtCutSurfTmPlane( AddId, ptOn, vtN, true, GDB_RT.GLOB)
|
||||
-- se richiesto, creazione tappo destro
|
||||
if bAddEndCapRightSide then
|
||||
local nFirstId, nPnt, nCrv, nSrf = EgtPlaneSurfTmInters( ptOn, vtN, AddIdCopy, nAddGrpId, GDB_RT.GLOB)
|
||||
if nPnt == 0 and nCrv == 1 and nSrf == 0 then
|
||||
EgtCloseCurveCompo( nFirstId)
|
||||
nCapIdRightSide = EgtSurfTmByFlatContour( nAddGrpId, nFirstId)
|
||||
if not nCapIdRightSide then bAllWithEndCap = false end
|
||||
end
|
||||
if nFirstId then
|
||||
for nId = nFirstId, nFirstId + nPnt + nCrv + nSrf - 1 do
|
||||
EgtErase( nId)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
-- se esiste, aggiunta del tappo destro
|
||||
if nCapIdRightSide then
|
||||
AddId = EgtSurfTmBySewing( nAddGrpId, { AddId, nCapIdRightSide})
|
||||
end
|
||||
EgtSetName( AddId, 'AddPart_' .. tostring( Proc.Id) .. '_' .. tostring( i))
|
||||
-- eseguo inserimento in modo da ordinare da X+ a X-
|
||||
table.insert( vAddId, 1, AddId)
|
||||
end
|
||||
EgtErase( AddIdCopy)
|
||||
-- applico le lavorazioni sulle diverse parti
|
||||
local sWarn
|
||||
local bPrevBhSideMill
|
||||
|
||||
+7
-1
@@ -1,7 +1,13 @@
|
||||
==== Beam Update Log ====
|
||||
|
||||
Versione 2.5i1 (12/09/2023)
|
||||
- Fixed : in LapJoint gestito correttamente il ritorno nil di GetUShapeWidth [Ticket #1354].
|
||||
- Fixed : in LapJoint gestito correttamente il ritorno nil di GetUShapeWidth [Ticket #1354]
|
||||
- Modif : in Cut abbassato a 590 mm il limite per convertire in LongCut [Ticket #1448].
|
||||
|
||||
Versione 2.5h2 (11/08/2023)
|
||||
- Fixed : corrette forature con aggregato quando lato aperto
|
||||
- Fixed : in RidgeLap corretto ingombro lavorazione in testa e coda quando rivolta verso il basso
|
||||
- Modif : in LapJoint e Mortise modificata posizione braccio per FAST quando vicino alla coda della trave.
|
||||
|
||||
Versione 2.5h1 (07/08/2023)
|
||||
- Fixed : tagli doppi di lato non effettuati se macchina tipo PF e pezzo alto [Ticket #1400]
|
||||
|
||||
Reference in New Issue
Block a user