b1d113b63f
- aggiunta lettura thickness dalle info del part.
967 lines
33 KiB
Lua
967 lines
33 KiB
Lua
-- 2023/05/__
|
|
-- |ultima modifica:|
|
|
-- |aggiunta gestione di più loop interni|
|
|
--ERR == -1 valore di default
|
|
--ERR == 1 SLD.CurrId non è valido ( == -1)
|
|
--ERR == 0 eseguito senza problemi
|
|
|
|
-- Intestazioni
|
|
require( 'EgtBase')
|
|
_ENV = EgtProtectGlobal()
|
|
EgtEnableDebug( false)
|
|
|
|
|
|
-- Dati raccolti direttamente dal programma
|
|
local SLD = {}
|
|
--input
|
|
SLD.THICK = 40
|
|
SLD.CurrId = -1
|
|
-- output
|
|
SLD.CurrPartSolid = -1
|
|
SLD.CurrSrfTmId = -1
|
|
SLD.ERR = -1
|
|
|
|
----- mi preparo a ricevere argomenti
|
|
local arg = ...
|
|
local bAutoRun = false
|
|
if arg then
|
|
bAutoRun = arg.AutoRun
|
|
end
|
|
|
|
_G.SLD = SLD
|
|
|
|
local ColorSTD = 'AQUA'
|
|
local ColocERR = 'ORANGE'
|
|
|
|
-- Id del primo Part del progetto
|
|
local IdP_FirstPart = -1
|
|
-- Id del layer "OutLoop"
|
|
local IdL_OutLoop = -1
|
|
-- Id del layer "InLoop"
|
|
local IdL_InLoop = -1
|
|
-- Id del layer "OnPath"
|
|
local IdL_OnPath = -1
|
|
-- Id del layer "Pocket"
|
|
local IdL_Pocket = -1
|
|
-- Id del layer "FiloTop"
|
|
local IdL_FiloTop = -1
|
|
-- Id del Part "SOLID"
|
|
local IdP_SOLID = -1
|
|
-- Id dei layer apprtenenti a "SOLID"
|
|
local IdL_Temp = -1
|
|
local IdL_Solid = -1
|
|
local IdL_Bound = -1
|
|
local IdL_Faces = -1
|
|
|
|
--[[
|
|
tabella contenente: IdSurf → superificie di taglio,
|
|
ptS → punto in basso a sinistra dalla superificie
|
|
vtS → direzioned del lato basso della superficie
|
|
Ang → inclinazione rispetto alla verticale
|
|
Hill → tallone
|
|
NAng → direzione agolo orizzontale lato successivo
|
|
]]--
|
|
local tbId_RectSurf = {}
|
|
-- tabella contenente i lati del layer OutLoop: IdS → lato del contorno
|
|
local tbId_OutLoop = {}
|
|
-- tabella contenente le tabelle dei layer degli InLoop: IdI → lato del contorno
|
|
local tbId_InLoop = {}
|
|
-- tabella contenente le tabelle delle curve composte del layer OnPath: IdI →
|
|
local tbId_OnPath = {}
|
|
-- tabella contenente le tabelle dei lati del layer Pocket: IdI →
|
|
local tbId_Pocket = {}
|
|
-- tabella contenente la tabella delle curve composte del layer FiloTop: IdI →
|
|
local tbId_FiloTop = {}
|
|
-- Id del solido generato
|
|
local IdEnt_Part = -1
|
|
-- Id del solido da sottrarre
|
|
local IdEnt_SubPart = -1
|
|
-- Id della facce come Flat Region
|
|
local tbId_Faces = {}
|
|
|
|
-- Spessore grezzo (Ddefault)
|
|
local RTh = 30
|
|
local bAlwaysOnTop = true
|
|
--local nIdTrimOut = -1
|
|
--local nIdTrimIn = -1
|
|
local tbTrimTot = {}
|
|
-- Estensioni delle regioni di taglio per SideAngle
|
|
--NB: lo spessore dei pezzi è limitato a 100(o meno, se ci sono dei sideAng), quindi per spessori importanti bisognerebbe modificare il valore di questa dimensione
|
|
local DefaultDim = 100
|
|
-- valore di tolleranza minimo per estrarre i contorni da una regione
|
|
local TollY = 1
|
|
local m_bArc = false
|
|
|
|
----------------------------------------------------------------------------
|
|
-- **Preparo ambiente** Part+Layer
|
|
----------------------------------------------------------------------------
|
|
-- Reimposto a vuoto il valore delle tabelle, resetto gli Id
|
|
local function ResetAllTabAndVar()
|
|
tbId_RectSurf = {}
|
|
-- tabella contenente i lati del layer OutLoop: IdS → lato del contorno
|
|
tbId_OutLoop = {}
|
|
-- tabella contenente i lati del layer InLoop: IdI → lato del contorno
|
|
tbId_InLoop = {}
|
|
-- tabella delle superfici laterali ( facce adiacenti già mergiate in un'unica superficie), la prima è quella out, le successive sono quelle in
|
|
tbId_SurfLat = {}
|
|
-- tabella contenente le curve composte del layer OnPath: IdI →
|
|
tbId_OnPath = {}
|
|
-- tabella contenente i lati del layer Pocket: IdI →
|
|
tbId_Pocket = {}
|
|
-- tabella contenente le curve composte del layer FiloTop: IdI →
|
|
tbId_FiloTop = {}
|
|
-- Id del solido generato
|
|
IdEnt_Part = -1
|
|
-- Id del solido da sottrarre
|
|
IdEnt_SubPart = -1
|
|
-- -- Id della superficie interna del solido
|
|
-- nIdTrimIn = -1
|
|
-- -- Id dalla superficie esterna del solido
|
|
-- nIdTrimOut = -1
|
|
-- tabella delle superfici per costruire il solido
|
|
tbTrimTot = {}
|
|
-- tabella delle superfici laterali
|
|
tbId_SurfLat = {}
|
|
-- Id della facce come Flat Region
|
|
tbId_Faces = {}
|
|
m_bArc = false
|
|
end
|
|
|
|
-- Elimino il layer solid del Part selezionato
|
|
local function ClearCurrIdSOLID()
|
|
IdP_SOLID = EgtGetFirstPart()
|
|
while IdP_SOLID do
|
|
local IdP_SOLID_Next = EgtGetNext( IdP_SOLID)
|
|
local nIdParent = EgtGetInfo(IdP_SOLID, "Parent", 'i')
|
|
if EgtGetName( IdP_SOLID) == "SOLID" and nIdParent ~= nil and IdFP == nIdParent then
|
|
EgtErase( IdP_SOLID)
|
|
break
|
|
end
|
|
IdP_SOLID = IdP_SOLID_Next
|
|
end
|
|
end
|
|
--
|
|
|
|
--[[
|
|
Creazione di un nuovo Part: IdP_SOLID → part "SOLID"
|
|
IdL_Temp → Layer di destinazione delle superfici di taglio
|
|
IdL_Solid → Layer di destinazione del solido
|
|
IdL_Bound → Layer di destinazione delle linee di contorno del solido
|
|
|
|
]]--
|
|
local function CreatePartSOLID()
|
|
ResetAllTabAndVar()
|
|
IdP_SOLID = EgtGroup(GDB_ID.ROOT,GDB_RT.LOC)
|
|
EgtSetName( IdP_SOLID, "SOLID")
|
|
EgtSetInfo(IdP_SOLID, "Parent", IdFP)
|
|
EgtSetInfo(IdFP, "Child", IdP_SOLID)
|
|
EgtSetInfo( IdP_SOLID, "Th", RTh)
|
|
IdL_Temp = EgtGroup(IdP_SOLID,GDB_RT.LOC)
|
|
EgtSetName( IdL_Temp, "Temp")
|
|
IdL_Solid = EgtGroup(IdP_SOLID,GDB_RT.LOC)
|
|
EgtSetName( IdL_Solid, "Surface")
|
|
IdL_Bound = EgtGroup(IdP_SOLID,GDB_RT.LOC)
|
|
EgtSetName( IdL_Bound, "Boundary")
|
|
IdL_Faces = EgtGroup(IdP_SOLID,GDB_RT.LOC)
|
|
EgtSetName( IdL_Faces, "Faces")
|
|
end
|
|
--
|
|
|
|
----------------------------------------------------------------------------
|
|
-- **Recupero info dei pezzi** SideAng:Ang, Heel; FiloTop:Depth
|
|
----------------------------------------------------------------------------
|
|
-- restituisce le info sui lati inclinati
|
|
local function GetAngHill( nInd)
|
|
if nInd then
|
|
local A = EgtGetInfo( nInd, 'OrigSideAng', 'd')
|
|
local H = EgtGetInfo( nInd, 'Heel', 'd')
|
|
if A and H then
|
|
return A, H
|
|
elseif A and not H then
|
|
return A, 0
|
|
end
|
|
end
|
|
return 0,0
|
|
end
|
|
--
|
|
|
|
-- restituisce l'affondamento del profilo FiloTop
|
|
local function GetDepth( nInd)
|
|
if nInd then
|
|
local D = EgtGetInfo( nInd, 'Depth', 'd')
|
|
if D then
|
|
return D
|
|
end
|
|
end
|
|
return 0
|
|
end
|
|
--
|
|
|
|
-- restituisce l'affondamento del profilo FiloTop
|
|
local function GetDepthOnPath( nInd)
|
|
if nInd then
|
|
D = EgtGetInfo( nInd, 'Depth', 'd')
|
|
if not D then
|
|
D = EgtGetInfo( nInd, 'Th', 'd')
|
|
end
|
|
if D then
|
|
return D
|
|
end
|
|
end
|
|
return 5
|
|
end
|
|
--
|
|
|
|
-- restituisce il valore dell'angolo successivo (se <0 angolo concavo)
|
|
local function GetnNextAng( nInd)
|
|
local A = EgtGetInfo( nInd, 'NextAng', 'd')
|
|
return A
|
|
end
|
|
--
|
|
|
|
-- restituisce il valore dell'angolo precedente (se <0 angolo concavo)
|
|
local function GetnPrevAng( nInd)
|
|
local A = EgtGetInfo( nInd, 'PrevAng', 'd')
|
|
return A
|
|
end
|
|
--
|
|
|
|
----------------------------------------------------------------------------
|
|
-- **Carico tabelle** IdL_OutLoop, IdL_InLoop, tbId_OnPath, tbId_Pocket, tbId_FiloTop
|
|
----------------------------------------------------------------------------
|
|
-- riceve la tablella e il nome del Layer, riempie la tabella e restituisce l'ID del layer
|
|
local function GetIdFromLay( myTab, sLay)
|
|
RTh = SLD.THICK
|
|
--IdFP = EgtGetFirstPart()
|
|
local IdLay = EgtGetFirstNameInGroup( IdFP, sLay)
|
|
local tbIdLayTemp = {}
|
|
-- salvo l'id solo del primo layer con nome sLay
|
|
local IdFirstLay = IdLay
|
|
-- questo while su IdLay serve se ho più gruppi con questo nome
|
|
while IdLay do
|
|
local IdS = EgtGetFirstInGroup( IdLay)
|
|
while IdS do
|
|
if EgtGetType( IdS) == GDB_TY.CRV_LINE or EgtGetType( IdS) == GDB_TY.CRV_ARC or EgtGetType( IdS) == GDB_TY.CRV_COMPO then
|
|
if sLay == 'OutLoop' then
|
|
table.insert( myTab, IdS)
|
|
elseif sLay == 'InLoop' or sLay == 'Pocket' or sLay == 'FiloTop' or sLay == 'OnPath' then
|
|
table.insert( tbIdLayTemp, IdS)
|
|
end
|
|
end
|
|
IdS = EgtGetNext( IdS)
|
|
end
|
|
if sLay == 'InLoop' or sLay == 'Pocket' or sLay == 'FiloTop' or sLay == 'OnPath' then
|
|
table.insert( myTab, tbIdLayTemp)
|
|
tbIdLayTemp = {}
|
|
end
|
|
|
|
IdLay = EgtGetNextName( IdLay, sLay)
|
|
end
|
|
return IdFirstLay
|
|
end
|
|
--
|
|
|
|
----------------------------------------------------------------------------
|
|
-- **Solido di riferimento** IdEnt_Part
|
|
----------------------------------------------------------------------------
|
|
-- dato il contorno del pezzo
|
|
local function CreateSolid()
|
|
|
|
local nLoopOut, nCountOut = EgtExtractSurfTmLoops( tbId_SurfLat[1], IdL_Bound)
|
|
local tbLoop1 ={nLoopOut}
|
|
local tbLoop2 ={nLoopOut + 1}
|
|
--local ptSBottom = EgtSP( nLoopOut + 1)
|
|
|
|
local nLoopIn = -1
|
|
local nCountIn = 0
|
|
if #tbId_SurfLat > 1 then
|
|
for k = 2, #tbId_SurfLat, 1 do
|
|
nLoopIn, nCountIn = EgtExtractSurfTmLoops( tbId_SurfLat[k], IdL_Bound)
|
|
for p=0, nCountIn - 1, 1 do
|
|
if math.abs(EgtSP( nLoopIn + p):getZ() - EgtSP( nLoopOut):getZ()) < 0.01 then
|
|
table.insert(tbLoop1, nLoopIn + p)
|
|
else --math.abs(EgtSP( nLoopIn + p):getZ() - EgtSP( nLoopOut + 1):getZ()) < EPS_SMALL then
|
|
table.insert(tbLoop2, nLoopIn + p)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- creo le SurfTm delle facce sopra e sotto
|
|
local nIdSurf1 = EgtSurfTmByRegion( IdL_Solid, tbLoop1)
|
|
local nIdSurf2 = EgtSurfTmByRegion( IdL_Solid, tbLoop2)
|
|
for i = 1, #tbLoop1, 1 do
|
|
EgtErase( tbLoop1[i])
|
|
end
|
|
for i = 1, #tbLoop2, 1 do
|
|
EgtErase( tbLoop2[i])
|
|
end
|
|
EgtInvertSurf( {nIdSurf1, nIdSurf2})
|
|
|
|
tbTrimTot = {nIdSurf1, nIdSurf2}
|
|
for k = 1, #tbId_SurfLat, 1 do
|
|
table.insert( tbTrimTot, tbId_SurfLat[k])
|
|
end
|
|
|
|
local nIdTrimTot = EgtSurfTmByTriangles( IdL_Solid, tbTrimTot, false)
|
|
EgtSetColor( nIdTrimTot, ColorSTD)
|
|
EgtErase( tbTrimTot)
|
|
tbTrimTot = {nIdTrimTot}
|
|
IdEnt_Part = nIdTrimTot
|
|
SLD.CurrPartSolid = IdP_SOLID
|
|
SLD.CurrSrfTmId = nIdTrimTot
|
|
end
|
|
--
|
|
|
|
----------------------------------------------------------------------------
|
|
-- **Pocket**
|
|
----------------------------------------------------------------------------
|
|
local function PocketSolid()
|
|
-- se sono presenti dei ribassi provvedo a disegnarli
|
|
if #tbId_Pocket > 0 then
|
|
for i = 1, #tbId_Pocket do
|
|
local IdCompo_Pocket, nCrv = EgtCurveCompoByChain( IdL_Solid, tbId_Pocket[i], EgtSP( tbId_Pocket[i][1]), false)
|
|
local IdEnt_Pocket = EgtSurfTmByRegionExtrusion( IdL_Solid, {IdCompo_Pocket}, Z_AX()*(2* RTh))
|
|
EgtSurfTmSubtract( IdEnt_Part, IdEnt_Pocket)
|
|
EgtErase( {IdEnt_Pocket})
|
|
EgtErase( {IdCompo_Pocket})
|
|
local a = 0
|
|
end
|
|
end
|
|
end
|
|
|
|
----------------------------------------------------------------------------
|
|
-- **OnPath**
|
|
----------------------------------------------------------------------------
|
|
local function Engraves( nId)
|
|
-- se non restituisce nulla allora utlizzo direttamente la copia
|
|
local vtExtr
|
|
local vtO
|
|
|
|
nNbr = 1
|
|
vtO = EgtSV( nId)
|
|
vtExtr = Vector3d( vtO[3]/vtO[1], 0, 1)
|
|
vtExtr:normalize()
|
|
local D = 10
|
|
EgtMove( {nId}, vtExtr*(D))
|
|
|
|
if D > 0 or not vt then
|
|
local nEntCopy_1 = EgtCopy( nId, IdL_Temp)
|
|
local nEntCopy_2 = EgtCopy( nId, IdL_Temp)
|
|
EgtMove( {nEntCopy_2}, vtExtr*(- D))
|
|
local nLine_1 = EgtLine( IdL_Temp, EgtSP( nEntCopy_1, GDB_ID.ROOT ), EgtSP( nEntCopy_2, GDB_ID.ROOT ))
|
|
local nLine_2 = EgtLine( IdL_Temp, EgtEP( nEntCopy_1, GDB_ID.ROOT ), EgtEP( nEntCopy_2, GDB_ID.ROOT ))
|
|
local nCompo = EgtCurveCompoByChain( IdL_Solid, {nEntCopy_1,nLine_1,nEntCopy_2,nLine_2}, EgtSP( nLine_1), false)
|
|
vtExtr:rotate( vtO, 90)
|
|
local IdSubSolid = EgtSurfTmByRegionExtrusion( IdL_Solid, {nCompo}, vtExtr*(2))
|
|
EgtSurfTmSubtract( IdEnt_Part, IdSubSolid)
|
|
EgtErase( {nEntCopy_1,nLine_1,nEntCopy_2,nLine_2, nCompo, IdSubSolid, nId})
|
|
end
|
|
end
|
|
--
|
|
|
|
-- genero i tagli singoli
|
|
local function OnPathSolid()
|
|
for i=1, #tbId_OnPath, 1 do
|
|
for j=1, #tbId_OnPath[i], 1 do
|
|
local nInd = tbId_OnPath[i][j]
|
|
local D = GetDepthOnPath( nInd)
|
|
if D > RTh then
|
|
SLD.ERR = 1
|
|
EgtSetColor( {IdEnt_Part}, ColocERR)
|
|
end
|
|
-- creo una copia nel Layer "Temp"
|
|
local nEntCopy = EgtCopy( nInd, IdL_Temp)
|
|
local nId, nNbr = EgtExplodeCurveCompo( nEntCopy)
|
|
-- definisco il vettore di spostamento verticale del solido da sottrarre
|
|
local vtV = Z_AX()
|
|
if nId ~= nil then
|
|
for j=0 , nNbr-1, 1 do
|
|
local nTempId = nId + j
|
|
local vt = EgtSV( nTempId)
|
|
vt:rotate(vtV, 90)
|
|
if D > 0 or not vt then
|
|
local nEntCopy_1 = EgtCopy( nTempId, IdL_Temp)
|
|
local nEntCopy_2 = EgtCopy( nTempId, IdL_Temp)
|
|
EgtMove( {nEntCopy_2}, vtV*(- D))
|
|
local nLine_1 = EgtLine( IdL_Temp, EgtSP( nEntCopy_1, GDB_ID.ROOT ), EgtSP( nEntCopy_2, GDB_ID.ROOT ))
|
|
local nLine_2 = EgtLine( IdL_Temp, EgtEP( nEntCopy_1, GDB_ID.ROOT ), EgtEP( nEntCopy_2, GDB_ID.ROOT ))
|
|
local nCompo = EgtCurveCompoByChain( IdL_Solid, {nEntCopy_1,nLine_1,nEntCopy_2,nLine_2}, EgtSP( nLine_1), false)
|
|
local IdSubSolid = EgtSurfTmByRegionExtrusion( IdL_Solid, {nCompo}, vt*(2))
|
|
EgtSurfTmSubtract( IdEnt_Part, IdSubSolid)
|
|
EgtErase( {nEntCopy_1,nLine_1,nEntCopy_2,nLine_2, nCompo, IdSubSolid, nTempId})
|
|
end
|
|
end
|
|
else
|
|
Engraves( nEntCopy)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
--
|
|
|
|
|
|
----------------------------------------------------------------------------
|
|
-- **Filo Top**
|
|
----------------------------------------------------------------------------
|
|
-- sottraggo al solido il contorno FiloTop
|
|
local function FiloTopSolid()
|
|
local nLay = EgtGetFirstNameInGroup( IdFP, "FiloTop")
|
|
for i = 1, #tbId_FiloTop do
|
|
local D = GetDepth( nLay)
|
|
if D < 0.1 then
|
|
return
|
|
end
|
|
local IdEnt_SurfFiloTop = EgtSurfTmByRegionExtrusion( IdL_Solid, tbId_FiloTop[i], Z_AX()*(- D -1))
|
|
EgtMove( {IdEnt_SurfFiloTop}, Z_AX()*1)
|
|
EgtSurfTmSubtract( IdEnt_Part, IdEnt_SurfFiloTop)
|
|
EgtErase( {IdEnt_SurfFiloTop})
|
|
nLay = EgtGetNextName( nLay, "FiloTop")
|
|
end
|
|
end
|
|
--
|
|
|
|
----------------------------------------------------------------------------
|
|
-- HillPlane D
|
|
----------------------------------------------------------------------------
|
|
local function PlaneShift( nId, Hill)
|
|
if bAlwaysOnTop then
|
|
Hill = Hill * (-1)
|
|
end
|
|
local vtTrasl = Z_AX() * Hill
|
|
EgtMove( nId, vtTrasl)
|
|
end
|
|
--
|
|
|
|
----------------------------------------------------------------------------
|
|
-- HillPlane C
|
|
----------------------------------------------------------------------------
|
|
local function PlaneNoShift( nId)
|
|
PlaneShift( nId, 0)
|
|
end
|
|
--
|
|
|
|
----------------------------------------------------------------------------
|
|
-- HillPlane A
|
|
----------------------------------------------------------------------------
|
|
local function HillPlaneAng( nId, ptS, vtS, Ang, Hill)
|
|
local nIdHill = EgtCopy( nId, IdL_Solid)
|
|
EgtRotate( nIdHill, ptS, vtS, Ang, GDB_ID.ROOT)
|
|
local dTrasl
|
|
if bAlwaysOnTop then
|
|
if Ang > 0 then
|
|
dTrasl = ( RTh - Hill) * math.tan( Ang * math.pi / 180)
|
|
else
|
|
dTrasl = 0
|
|
end
|
|
else
|
|
if Ang > 0 then
|
|
dTrasl = 0
|
|
else
|
|
dTrasl = ( RTh - Hill) * math.tan( -Ang * math.pi / 180)
|
|
end
|
|
end
|
|
local vtTrasl = ( vtS ^ Z_AX()) * dTrasl
|
|
EgtMove( nIdHill, vtTrasl)
|
|
if bAlwaysOnTop then
|
|
if Ang < 0 then
|
|
PlaneShift( nId, Hill)
|
|
end
|
|
else
|
|
if Ang > 0 then
|
|
PlaneShift( nId, Hill)
|
|
end
|
|
end
|
|
local pt_a, vn_a = EgtSurfTmFacetCenter( nId, 0)
|
|
local pt_h, vn_h = EgtSurfTmFacetCenter( nIdHill, 0)
|
|
EgtCutSurfTmPlane( nIdHill, pt_a, vn_a, false)
|
|
EgtCutSurfTmPlane( nId, pt_h, vn_h, false)
|
|
PlaneNoShift( nId)
|
|
return nIdHill, vtTrasl
|
|
end
|
|
--
|
|
|
|
------------------------------------------------------------------------------
|
|
---- HillPlane B
|
|
------------------------------------------------------------------------------
|
|
--local function HillPlaneNegAng( nId, ptS, vtS, Ang, Hill)
|
|
-- local nIdHill, vtTrasl = HillPlanePosAng( nId, ptS, vtS, Ang, Hill, true)
|
|
-- return nIdHill, vtTrasl
|
|
--end
|
|
----
|
|
|
|
----------------------------------------------------------------------------
|
|
-- **Side Ang**
|
|
----------------------------------------------------------------------------
|
|
local function SideAngSolid( tbLoop, bInLoop)
|
|
|
|
local tbIdR = {}
|
|
local IdS
|
|
local Ang = 0
|
|
local Hill = 0
|
|
local NAng = 0
|
|
m_bArc = false
|
|
|
|
local tbArc = {}
|
|
local tbLimited = {}
|
|
for i=1, #tbLoop, 1 do
|
|
IdS = tbLoop[i]
|
|
-- recupero i dati SideAng per ogni lato
|
|
Ang, Hill = GetAngHill( IdS)
|
|
NAng = GetnNextAng( IdS)
|
|
if math.abs(NAng) <= 2 then NAng = 0 end
|
|
|
|
-- verifico che il lato presenti un angolo inclinato
|
|
if EgtGetType( IdS) == GDB_TY.CRV_ARC then
|
|
m_bArc = true
|
|
table.insert(tbArc, true)
|
|
local ptStart = EgtSP(IdS, GDB_ID.ROOT)
|
|
local vtStart = EgtSV( IdS, GDB_ID.ROOT)
|
|
local vtEnd = EgtEV( IdS, GDB_ID.ROOT)
|
|
if Ang == 0 then
|
|
local vtExtr = Z_AX() * RTh
|
|
if bAlwaysOnTop then
|
|
vtExtr = vtExtr * (-1)
|
|
end
|
|
local nSurfId = EgtSurfTmByExtrusion(IdL_Solid, IdS, vtExtr)
|
|
if bAlwaysOnTop then
|
|
EgtInvertSurf( nSurfId)
|
|
end
|
|
local tbInfoRot = { nSurfId, ptStart, vtStart, Ang, Hill, NAng, vtEnd}
|
|
table.insert(tbIdR,tbInfoRot)
|
|
table.insert(tbLimited, false)
|
|
else
|
|
-- costruisco la superficie laterale generata dall'arco con una swept lungo l'arco stesso
|
|
-- la sezione di cui effetturare lo sweep viene creata trovando il punto di partenza del secondo arco che delimita questa superficie
|
|
local dLatMove = RTh * math.tan( math.abs(Ang) * pi / 180)
|
|
local vtLatMove = (Z_AX() ^ vtStart)
|
|
local vtVertMove = Z_AX() * RTh
|
|
if not bInLoop then vtLatMove = vtLatMove * (-1) end
|
|
-- devo controllare se il side ang e lo spessore della lastra sono abbastanza da far collassare l'arco in un punto ed eventualmente andare oltre
|
|
-- verifico quindi se devo limitare la superficie della sezione di cono
|
|
local dRad = EgtArcRadius( IdS)
|
|
local bLimited = false
|
|
local dArcAng = EgtArcAngCenter( IdS)
|
|
local bCheckLimit = (dArcAng > 0 and Ang < 0 ) or ( dArcAng < 0 and Ang > 0)
|
|
if bCheckLimit then
|
|
if dRad < math.abs(dLatMove) + 0.01 then
|
|
vtLatMove = vtLatMove * dRad
|
|
vtVertMove = Z_AX() * dRad / math.tan( math.abs(Ang) * pi / 180)
|
|
bLimited = true
|
|
end
|
|
else
|
|
vtLatMove = vtLatMove * dLatMove
|
|
end
|
|
table.insert(tbLimited, bLimited)
|
|
|
|
if (Ang > 0 and bAlwaysOnTop) or ( Ang < 0 and not bAlwaysOnTop) then
|
|
vtLatMove = vtLatMove * ( -1)
|
|
end
|
|
if bAlwaysOnTop then
|
|
vtVertMove = vtVertMove * (-1)
|
|
end
|
|
local ptSecondArcStart = ptStart + ( vtVertMove + vtLatMove)
|
|
local nIdLine = EgtLine(IdL_Temp,ptStart,ptSecondArcStart,GDB_ID.ROOT)
|
|
local nPointId = EgtPoint( IdL_Temp, ptSecondArcStart)
|
|
local nSurfId = 0
|
|
if not bLimited then
|
|
nSurfId = EgtSurfTmSwept(IdL_Solid,nIdLine,IdS,Z_AX(),false,0.01,GDB_ID.ROOT)
|
|
EgtInvertSurf( nSurfId)
|
|
else
|
|
local vtAx = Z_AX()
|
|
if not bAlwaysOnTop then
|
|
vtAx = vtAx * (-1)
|
|
end
|
|
nSurfId = EgtSurfTmRuled( IdL_Solid, nPointId, IdS)
|
|
EgtInvertSurf( nSurfId)
|
|
-- nSurfId = EgtSurfTmCone(IdL_Solid,ptSecondArcStart, vtAx, dRad, RTh)
|
|
end
|
|
EgtErase( nIdLine)
|
|
EgtErase( nPointId)
|
|
local tbInfoRot = { nSurfId, ptStart, vtStart, Ang, Hill, NAng, vtEnd}
|
|
table.insert(tbIdR,tbInfoRot)
|
|
end
|
|
elseif EgtGetType( IdS) ~= GDB_TY.CRV_COMPO then
|
|
table.insert(tbArc, false)
|
|
local ptS = EgtSP( IdS, GDB_ID.ROOT)
|
|
local vtS = EgtSV( IdS, GDB_ID.ROOT)
|
|
local vtE = EgtEV( IdS, GDB_ID.ROOT)
|
|
local IdRect = EgtCurveGetFatCurve( IdS, IdL_Temp, DefaultDim, true)
|
|
local IdSurf = EgtSurfTmByRegion( IdL_Solid, IdRect)
|
|
EgtErase( IdRect)
|
|
|
|
local tbInfoRot = { IdSurf, ptS, vtS, Ang, Hill, NAng, vtE}
|
|
table.insert( tbIdR, tbInfoRot)
|
|
table.insert(tbLimited, false)
|
|
end
|
|
end
|
|
|
|
-- posiziono i piani calcolati in precedenza e creo i piani di Hill
|
|
for i=1, #tbIdR, 1 do
|
|
local dTempAng = 90
|
|
if not tbArc[i] then
|
|
EgtRotate( tbIdR[i][1], tbIdR[i][2], tbIdR[i][3], -tbIdR[i][4] + dTempAng, GDB_ID.ROOT)
|
|
end
|
|
-- se ho l'hill lo creo e lo aggiungo alle caratteristiche della faccia
|
|
if tbIdR[i][4] ~= 0 and tbIdR[i][5] > 0 then
|
|
if not tbArc[i] then
|
|
local nIdHill
|
|
nIdHill, tbIdR[i][8] = HillPlaneAng( tbIdR[i][1], tbIdR[i][2], tbIdR[i][3], tbIdR[i][4], tbIdR[i][5])
|
|
-- aggiungo l'hill come elemento separato della faccia di taglio
|
|
tbIdR[i][9] = { nIdHill, tbIdR[i][2] + tbIdR[i][8], tbIdR[i][3], tbIdR[i][4], tbIdR[i][5], tbIdR[i][6], tbIdR[i][8]}
|
|
else
|
|
--- hill da gestire per il caso del lato che è un arco
|
|
end
|
|
else
|
|
tbIdR[i][8] = Vector3d({0,0,0})
|
|
end
|
|
end
|
|
|
|
-- **NANG** corrego la dimenione dei piani in funzione dell'angolo che descrivono con il pezzo successivo
|
|
for i=1, #tbIdR, 1 do
|
|
local Ind_Curr = i
|
|
local Ind_Nex = i + 1
|
|
if i == #tbIdR then
|
|
Ind_Nex = 1
|
|
end
|
|
-- se ho solo una faccia laterale termino ( è un foro descritto da un unico loop circolare)
|
|
if Ind_Curr == Ind_Nex then break end
|
|
|
|
local pt_n, vn_n = EgtSurfTmFacetCenter( tbIdR[Ind_Nex][1], 0)
|
|
local pt_c, vn_c = EgtSurfTmFacetCenter( tbIdR[Ind_Curr][1], 0)
|
|
if tbArc[Ind_Nex] then
|
|
pt_n = tbIdR[Ind_Nex][2] -- prendo startPoint
|
|
vn_n = tbIdR[Ind_Nex][3] -- prendo vtStart
|
|
if math.abs( tbIdR[Ind_Curr][6]) > 90 then
|
|
vn_n = vn_n * (-1)
|
|
elseif math.abs( tbIdR[Ind_Curr][6]) > 90 then
|
|
vn_n = EgtEV( tbLoop[Ind_Curr], GDB_ID.ROOT) -- prendo l'end del segmento precedente all'arco
|
|
end
|
|
end
|
|
if tbArc[Ind_Curr] then
|
|
pt_c = EgtEP( tbLoop[Ind_Curr], GDB_ID.ROOT) -- prendo endPoint
|
|
vn_c = tbIdR[Ind_Curr][7] -- prendo vtEnd
|
|
if math.abs( tbIdR[Ind_Curr][6]) < 90 then
|
|
vn_c = vn_c * (-1)
|
|
elseif math.abs( tbIdR[Ind_Curr][6]) > 90 then
|
|
vn_c = tbIdR[Ind_Nex][3] -- prendo lo start del segmento successivo all'arco
|
|
end
|
|
end
|
|
|
|
if (not tbArc[Ind_Nex]) and (not tbArc[Ind_Curr]) then
|
|
if ( tbIdR[Ind_Curr][6] < 0) then
|
|
vn_n = vn_n * (-1)
|
|
vn_c = vn_c * (-1)
|
|
end
|
|
end
|
|
-- devo tagliare le superfici di taglio con le superfici di taglio
|
|
-- gli archi li taglio usando i suoi vettori a inizio e fine curva
|
|
if tbArc[Ind_Curr] then
|
|
EgtCutSurfTmPlane( tbIdR[Ind_Curr][1], tbIdR[Ind_Curr][2], - tbIdR[Ind_Curr][3], false)
|
|
EgtCutSurfTmPlane( tbIdR[Ind_Curr][1], EgtEP(tbLoop[Ind_Curr], GDB_ID.ROOT), tbIdR[Ind_Curr][7], false)
|
|
else
|
|
EgtCutSurfTmPlane( tbIdR[Ind_Curr][1], pt_n, vn_n, false)
|
|
end
|
|
if not tbArc[Ind_Nex] then
|
|
EgtCutSurfTmPlane( tbIdR[Ind_Nex][1], pt_c, vn_c, false)
|
|
end
|
|
|
|
-- nel caso in cui la superficie generata dall'arco è limitata devo tagliare tra loro anche le superfici precedente e successiva all'arco--------------------------------------------------
|
|
if tbLimited[Ind_Curr] then
|
|
local Ind_Pre = Ind_Curr > 1 and (Ind_Curr - 1) or #tbLoop
|
|
local pt_p, vn_p = EgtSurfTmFacetCenter( tbIdR[Ind_Pre][1], 0)
|
|
pt_n, vn_n = EgtSurfTmFacetCenter( tbIdR[Ind_Nex][1], 0)
|
|
-- calcolo l'angolo tra le due facce
|
|
local dArcAng = EgtArcAngCenter( tbLoop[Ind_Curr])
|
|
local dAngSkip = tbIdR[Ind_Pre][6] + tbIdR[Ind_Nex][6] + dArcAng
|
|
if dAngSkip < 0 then
|
|
vn_p = vn_p * (-1)
|
|
vn_n = vn_n * (-1)
|
|
end
|
|
EgtCutSurfTmPlane( tbIdR[Ind_Pre][1], pt_n, vn_n, false)
|
|
EgtCutSurfTmPlane( tbIdR[Ind_Nex][1], pt_p, vn_p, false)
|
|
end
|
|
|
|
--taglio i piani dei talloni con i piani dei talloni ( se non ho un altro tallone allora taglio con la sup di taglio)
|
|
local pt_nH, vn_nH
|
|
local pt_cH, vn_cH
|
|
if tbIdR[Ind_Curr][5] > 0 then
|
|
pt_cH, vn_cH = EgtSurfTmFacetCenter( tbIdR[Ind_Curr][9][1], 0)
|
|
if ( tbIdR[Ind_Curr][6] < 0) then
|
|
vn_cH = vn_cH * (-1)
|
|
end
|
|
end
|
|
if tbIdR[Ind_Nex][5] > 0 then
|
|
pt_nH, vn_nH = EgtSurfTmFacetCenter( tbIdR[Ind_Nex][9][1], 0)
|
|
if ( tbIdR[Ind_Curr][6] < 0) then
|
|
vn_nH = vn_nH * (-1)
|
|
end
|
|
if tbIdR[Ind_Curr][5] > 0 then
|
|
EgtCutSurfTmPlane( tbIdR[Ind_Curr][9][1], tbIdR[Ind_Nex][9][2], vn_nH, false)
|
|
EgtCutSurfTmPlane( tbIdR[Ind_Nex][9][1], tbIdR[Ind_Curr][9][2], vn_cH, false)
|
|
-- se l'angolo con il prossimo lato è positivo, entrambi hanno un hill e gli Ang sono discordi, allora devo anche tagliare gli hill con i piani di taglio e viceversa
|
|
--if tbIdR[Ind_Curr][6] > 0 and tbIdR[Ind_Curr][4] * tbIdR[Ind_Nex][4] < 0 then
|
|
if tbIdR[Ind_Curr][6] > 0 then -- ho tolto la condizione che gli angoli debbano essere discordi!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
EgtCutSurfTmPlane( tbIdR[Ind_Nex][9][1], pt_c, vn_c, false)
|
|
EgtCutSurfTmPlane( tbIdR[Ind_Curr][9][1], pt_n, vn_n, false)
|
|
EgtCutSurfTmPlane( tbIdR[Ind_Curr][1], tbIdR[Ind_Nex][9][2], vn_nH, false)
|
|
EgtCutSurfTmPlane( tbIdR[Ind_Nex][1], tbIdR[Ind_Curr][9][2], vn_cH, false)
|
|
end
|
|
else
|
|
EgtCutSurfTmPlane( tbIdR[Ind_Nex][9][1], pt_c, vn_c, false)
|
|
EgtCutSurfTmPlane( tbIdR[Ind_Curr][1], tbIdR[Ind_Nex][9][2], vn_nH, false)
|
|
end
|
|
else
|
|
if tbIdR[Ind_Curr][5] > 0 then
|
|
EgtCutSurfTmPlane( tbIdR[Ind_Curr][9][1], pt_n, vn_n, false)
|
|
EgtCutSurfTmPlane( tbIdR[Ind_Nex][1], tbIdR[Ind_Curr][9][2], vn_cH, false)
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
-- unisco tutte le superfici laterali
|
|
local tbIdTrim = {}
|
|
for i=1, #tbIdR, 1 do
|
|
if tbIdR[i][1] > -1 then
|
|
table.insert( tbIdTrim, tbIdR[i][1])
|
|
if tbIdR[i][5] > 0 then
|
|
table.insert( tbIdTrim, tbIdR[i][9][1])
|
|
end
|
|
end
|
|
end
|
|
|
|
if #tbIdR > 0 then
|
|
local nIdTrim = EgtSurfTmByTriangles( IdL_Solid, tbIdTrim, true)
|
|
table.insert( tbId_SurfLat, nIdTrim)
|
|
|
|
-- le trimmo con la superficie superiore e con quella inferiore
|
|
local ptOrig_t
|
|
local ptOrig_b
|
|
if bAlwaysOnTop then
|
|
ptOrig_t = tbIdR[1][2]
|
|
ptOrig_b = ptOrig_t + Point3d({0,0,-RTh})
|
|
else
|
|
ptOrig_b = tbIdR[1][2]
|
|
ptOrig_t = ptOrig_b + Point3d({0,0,RTh})
|
|
end
|
|
|
|
EgtCutSurfTmPlane( nIdTrim, ptOrig_b, {0,0,-1}, false, GDB_RT.GLOB)
|
|
EgtCutSurfTmPlane( nIdTrim, ptOrig_t, {0,0,1}, false, GDB_RT.GLOB)
|
|
|
|
end
|
|
|
|
end
|
|
--
|
|
|
|
local function CorrectReference()
|
|
local sName = EgtGetName( IdFP)
|
|
if sName ~= "SOLID" then
|
|
local nLayRef = EgtGetFirstNameInGroup( IdFP, "Ref")
|
|
local nRef = EgtGetFirstInGroup(nLayRef)
|
|
while nRef do
|
|
local var = EgtGetInfo(nRef, "Var")
|
|
if var == "Th" then
|
|
var = RTh
|
|
else
|
|
var = EgtGetInfo(nRef, "Var", "i")
|
|
end
|
|
local dir = EgtGetInfo(nRef, "Dir")
|
|
if dir then
|
|
local tbDir = EgtSplitString(dir,",")
|
|
local vtDir = {}
|
|
for _,sDir in pairs(tbDir) do
|
|
sDir = sDir:gsub("x", EgtNumToString(var))
|
|
table.insert(vtDir, EgtEvalNumExpr(sDir))
|
|
end
|
|
vtDir = Vector3d(vtDir)
|
|
EgtMove(nRef,vtDir, GDB_RT.GLOB)
|
|
end
|
|
nRef = EgtGetNext(nRef)
|
|
end
|
|
end
|
|
end
|
|
|
|
local function GetThickness()
|
|
local val = EgtGetInfo( IdFP,"Th","d")
|
|
if val then
|
|
SLD.THICK = val
|
|
end
|
|
end
|
|
|
|
----------------------------------------------------------------------------
|
|
-- **Wire Frame**
|
|
----------------------------------------------------------------------------
|
|
local function ExplodSurf( nId)
|
|
local IdFac, Nbr = EgtExplodeSurf(nId)
|
|
local i = 0
|
|
while IdFac and Nbr > 1 and i < Nbr do
|
|
ExplodSurf( IdFac)
|
|
IdFac = IdFac + 1
|
|
i = i+1
|
|
end
|
|
return IdFac, Nbr
|
|
end
|
|
--
|
|
|
|
-- estraggo il contorno delle superfici del solido
|
|
local function ExtractBoundaryAndFaces()
|
|
local nSurfCopy = EgtCopy( tbTrimTot[1], IdL_Temp)
|
|
local IdFac, Nbr = ExplodSurf( nSurfCopy)
|
|
|
|
local IdS = EgtGetFirstInGroup( IdL_Temp)
|
|
local nCount = 0
|
|
while IdS ~= nil do
|
|
------------------------ gestione archi
|
|
-- local tabMergSurf = {}
|
|
-- local _, dX, dY = EgtSurfTmFacetMinAreaRectangle( IdS, 0)
|
|
-- if dY~=nil and dY > TollY then
|
|
-- local TempIdSmall = EgtExtractSurfTmFacetLoops( IdS, 0, IdL_Bound)
|
|
-- else
|
|
-- table.insert( tabMergSurf, IdS)
|
|
-- end
|
|
-- EgtSurfTmByTriangles( IdL_Temp, tabMergSurf)
|
|
-- EgtErase( tabMergSurf)
|
|
-- IdS = EgtGetNext( IdS)
|
|
|
|
------------------------ gestione archi
|
|
----------- gestione archi che non vengono esplosi----------------
|
|
nCount = nCount + 1
|
|
local bExplode = false
|
|
|
|
----------- gestione archi che non vengono esplosi----------------
|
|
---
|
|
local nLoop, nLoopCount = EgtExtractSurfTmFacetLoops( IdS, 0, IdL_Bound)
|
|
local ColorApply = 'BLACK'
|
|
local tbLoopFlatRegion = {}
|
|
for l=nLoop, nLoop + (nLoopCount-1), 1 do
|
|
-- coloro il loop e lo aggiungo alla tabella per ricreare la flat region
|
|
EgtSetColor( l, ColorApply)
|
|
table.insert(tbLoopFlatRegion, l)
|
|
end
|
|
-- ricreo la faccia laterale come flat region e la metto con trasparenza massima
|
|
local nIdFace = EgtSurfFlatRegion( IdL_Faces, tbLoopFlatRegion)
|
|
EgtSetAlpha(nIdFace,1)
|
|
table.insert( tbId_Faces, nIdFace)
|
|
for l=nLoop, nLoop + (nLoopCount-1), 1 do
|
|
-- esplodo i loop
|
|
EgtExplodeCurveCompo( l)
|
|
end
|
|
local nIdCurr = IdS
|
|
IdS = EgtGetNext( IdS)
|
|
-- cancello la superficie
|
|
EgtErase( nIdCurr)
|
|
end
|
|
|
|
-- cancello le linee doppie sugli edge
|
|
local IdL = EgtGetFirstInGroup(IdL_Bound)
|
|
|
|
while IdL ~= nil do
|
|
local ptStart = EgtSP( IdL)
|
|
local ptEnd = EgtEP( IdL)
|
|
IdL_b = EgtGetFirstInGroup(IdL_Bound)
|
|
while IdL_b ~= nil do
|
|
local ptStart_b = EgtSP( IdL_b)
|
|
local ptEnd_b = EgtEP( IdL_b)
|
|
if IdL_b ~= IdL and
|
|
(AreSamePointApprox(ptStart, ptStart_b) and AreSamePointApprox(ptEnd, ptEnd_b)) or
|
|
(AreSamePointApprox(ptStart, ptEnd_b) and AreSamePointApprox(ptEnd, ptStart_b)) then
|
|
local IdL_bNext = IdL_b
|
|
EgtErase( IdL_b)
|
|
IdL_b = EgtGetNext( IdL_bNext)
|
|
else
|
|
IdL_b = EgtGetNext( IdL_b)
|
|
end
|
|
end
|
|
IdL = EgtGetNext( IdL)
|
|
end
|
|
end
|
|
--
|
|
|
|
----------------------------------------------------------------------------
|
|
-- |ESEGUO FUNZIONI|
|
|
----------------------------------------------------------------------------
|
|
-- funzione che si occupa di creare il solido finale
|
|
local function Draw(bPreview)
|
|
CreatePartSOLID()
|
|
-- SOLID
|
|
IdL_OutLoop = GetIdFromLay( tbId_OutLoop, 'OutLoop')
|
|
IdL_InLoop = GetIdFromLay( tbId_InLoop, 'InLoop')
|
|
IdL_OnPath = GetIdFromLay( tbId_OnPath, 'OnPath')
|
|
IdL_Pocket = GetIdFromLay( tbId_Pocket, 'Pocket')
|
|
IdL_FiloTop = GetIdFromLay( tbId_FiloTop, 'FiloTop')
|
|
|
|
-- SIDEANG
|
|
SideAngSolid( tbId_OutLoop, false)
|
|
for i = 1, #tbId_InLoop, 1 do
|
|
SideAngSolid( tbId_InLoop[i], true)
|
|
end
|
|
|
|
CreateSolid()
|
|
|
|
|
|
---- POCKET
|
|
PocketSolid()
|
|
---- FILO TOP
|
|
FiloTopSolid()
|
|
-- -- ONPATH
|
|
OnPathSolid()
|
|
-- WIREFRAME
|
|
---- Correzione dei riferimenti
|
|
CorrectReference()
|
|
|
|
|
|
ExtractBoundaryAndFaces()
|
|
end
|
|
--
|
|
|
|
|
|
--per uso nell' |omagOFFICE|
|
|
function SLD.Main()
|
|
IdFP = SLD.CurrId
|
|
ClearCurrIdSOLID()
|
|
if IdFP == -1 then
|
|
SLD.ERR = 1
|
|
return
|
|
end
|
|
RTh = SLD.THICK
|
|
if RTh == 0 then
|
|
return
|
|
end
|
|
GetThickness()
|
|
Draw( true)
|
|
EgtSetStatus( IdFP, GDB_ST.OFF)
|
|
EgtDraw()
|
|
SLD.ERR = 0
|
|
end
|
|
|
|
--per uso nell' |omagOFFICE|
|
|
|
|
--per uso nel |CAM5| (bAutoRun da settare a true)
|
|
bAutoRun = true -- debug
|
|
if bAutoRun then
|
|
ClearCurrIdSOLID()
|
|
RTh = SLD.THICK
|
|
IdFP = EgtGetFirstPart()
|
|
local sName = ""
|
|
--IdFP = 49389
|
|
while IdFP ~= nil and sName ~= "SOLID" do
|
|
-- procedo a costruire il solido solo se sono in un part con un OutLoop
|
|
local nLay = EgtGetFirstNameInGroup(IdFP, "OutLoop")
|
|
if nLay then
|
|
GetThickness()
|
|
Draw( true)
|
|
EgtSetStatus( IdFP, GDB_ST.OFF)
|
|
end
|
|
IdFP = EgtGetNextPart(IdFP)
|
|
sName = EgtGetName(IdFP)
|
|
--break
|
|
end
|
|
--EgtSaveFile('c:\\EgtData\\OmagOFFICE\\Temp\\buche_sottili_SOLID.nge')
|
|
EgtDraw()
|
|
--SLD.ERR = 0
|
|
end
|
|
-----per uso nel |CAM5|
|
|
|
|
--_G.SLD_Main = SLD_Main
|