diff --git a/LuaLibs/AddManData.lua b/LuaLibs/AddManData.lua index 2aefe40..63d780b 100644 --- a/LuaLibs/AddManData.lua +++ b/LuaLibs/AddManData.lua @@ -315,6 +315,8 @@ LAY_AUX_SOLIDS = 'AuxSolids' LAY_SHELL_NBR = 'ShellNumber' LAY_AUX = 'Aux' SPINE_CURVE = 'Spine' +SPINE_PLANE = 'Plane' +SPINE_FROM_PLANES = 'SpineComputedFromPlanes' LAY_FRAME = 'Frame' VIEWPARAMS = 'ViewParams' IMPORTED_SOLID = 'ImportedSolid' diff --git a/LuaLibs/CalcSlices.lua b/LuaLibs/CalcSlices.lua index fed4fe3..15e5a5f 100644 --- a/LuaLibs/CalcSlices.lua +++ b/LuaLibs/CalcSlices.lua @@ -56,13 +56,13 @@ local function ComputeSlicingData( vIds, vtSlicing, dSliceStep, dMaxH, nMaxSlice end --------------------------------------------------------------------- -local function ComputeMultiplanarSlicingData( dSliceStep, nMaxSlicesNbr, nSlicingType) - -- le direzioni e i valori di slicing sono le normali e i punti che definiscono i piani di slicing e vengono calcolati sulla curva "Spine" - - -- recupero la curva guida ( è la prima nel gruppo aux con info NameEntity = Spine oppure quella con nome Spine) +local function GetMultiplanarGuide( nStmId, nSlicingType) + local nAuxLayId = EgtGetFirstNameInGroup( s_nPartId, LAY_AUX) local vIds = EgtGetAllInGroup( nAuxLayId) local nSpineId + + -- verfico se definita curva guida ( è la prima nel gruppo aux con info NameEntity = Spine oppure quella con nome Spine) for i = 1, #vIds do local sNameEntity = EgtGetInfo( vIds[i], KEY_ENTITY_NAME) if sNameEntity == SPINE_CURVE then @@ -72,6 +72,99 @@ local function ComputeMultiplanarSlicingData( dSliceStep, nMaxSlicesNbr, nSlicin nSpineId = vIds[i] end end + + if nSpineId then + return nSpineId + end + + -- se curva non definita deve essere calcolata a partire dai piani + local vPoints = {} + local vNormals = {} + local nGrpTmp = EgtGroup( nAuxLayId) + for i = 1, #vIds do + -- cerco il piano i-esimo tramite nome o info EntityName + local nPlaneId = EgtGetFirstNameInGroup( nAuxLayId, SPINE_PLANE .. tostring( i)) + if not nPlaneId then + for j = 1, #vIds do + if EgtGetInfo( vIds[j], KEY_ENTITY_NAME) == SPINE_PLANE .. tostring( i) then + nPlaneId = vIds[j] + break + end + end + end + if not nPlaneId or EgtGetType( nPlaneId) ~= GDB_TY.SRF_MESH then + break + end + + local ptOn, vtN = EgtSurfTmFacetCenter( nPlaneId, 0, GDB_ID.ROOT) + -- come origine del piano considero il centroide dell'intersezione fra il solido e il piano + if nStmId then + local dDelta = 0 + local nRes, nPntCnt, nCrvCnt, nSrfCnt = EgtPlaneSurfTmInters( ptOn, vtN, nStmId, nGrpTmp, GDB_RT.GLOB) + -- se fallisce ritento spostando leggermente il piano + if not nRes then + dDelta = EgtIf( i == 1, DELTAZ, - DELTAZ) + nRes, nPntCnt, nCrvCnt, nSrfCnt = EgtPlaneSurfTmInters( ptOn + dDelta * vtN, vtN, nStmId, nGrpTmp, GDB_RT.GLOB) + end + if nSrfCnt > 0 then + ptOn = EgtGP( nRes + nPntCnt + nCrvCnt, GDB_ID.ROOT) - dDelta * vtN + else + for nCrvId = nRes + nPntCnt, nRes + nPntCnt + nCrvCnt - 1 do + if EgtCurveIsClosed( nCrvId) then + ptOn = EgtGP( nCrvId, GDB_ID.ROOT) - dDelta * vtN + break + end + end + end + end + table.insert( vPoints, ptOn) + table.insert( vNormals, vtN) + end + + -- costruisco la guida a partire dai punti e dalle tangenti + if #vPoints > 0 then + + if nSlicingType == SLICING_TYPE.MULTIPLANAR then + -- verifico che il primo piano sia sulla tavola, altrimenti lo aggiungo + if abs( vPoints[1]:getZ()) > GEO.EPS_SMALL or not AreSameVectorApprox( vNormals[1], Z_AX()) then + local ptP + local nRes, nPntCnt, nCrvCnt, nSrfCnt = EgtPlaneSurfTmInters( ORIG() + DELTAZ * Z_AX(), Z_AX(), nStmId, nGrpTmp, GDB_RT.GLOB) + if nSrfCnt > 0 then + ptP = EgtGP( nRes + nPntCnt + nCrvCnt, GDB_ID.ROOT) - DELTAZ * Z_AX() + else + for nCrvId = nRes + nPntCnt, nRes + nPntCnt + nCrvCnt - 1 do + if EgtCurveIsClosed( nCrvId) then + ptP = EgtGP( nCrvId, GDB_ID.ROOT) - DELTAZ * Z_AX() + break + end + end + end + table.insert( vPoints, 1, ptP) + table.insert( vNormals, 1, Z_AX()) + end + end + + local vCubicBezier = {} + for i = 1, #vPoints - 1 do + local dDist = 1/3 * dist( vPoints[i], vPoints[i+1]) + local pt1 = vPoints[i] + dDist * vNormals[i] + local pt2 = vPoints[i+1] - dDist * vNormals[i+1] + vCubicBezier[i] = EgtCurveBezier( nGrpTmp, 3, { vPoints[i], pt1, pt2, vPoints[i+1]}, GDB_RT.GLOB) + end + nSpineId = EgtCurveCompo( nAuxLayId, vCubicBezier) + EgtSetName( nSpineId or GDB_ID.NULL, SPINE_FROM_PLANES) + end + + EgtErase( nGrpTmp) + return nSpineId +end + +--------------------------------------------------------------------- +local function ComputeMultiplanarSlicingData( dSliceStep, nMaxSlicesNbr, nSlicingType, nStmId) + -- le direzioni e i valori di slicing sono le normali e i punti che definiscono i piani di slicing e vengono calcolati sulla curva guida ( spine) + + -- recupero o calcolo la curva guida + local nSpineId = GetMultiplanarGuide( nStmId, nSlicingType) if not nSpineId or ( EgtGetType( nSpineId) & GDB_FY.GEO_CURVE) == 0 then EgtOutBox( "No spine for multiplanar slicing", 'Error', 'ERROR') return nil @@ -1479,7 +1572,7 @@ function CalcSlices.Exec( nPartId, nStmId) local vSlicingVal = {} local vSlicingDir = {} if nSlicingType == SLICING_TYPE.MULTIPLANAR or nSlicingType == SLICING_TYPE.MULTIPLANAR_DEG45 or nSlicingType == SLICING_TYPE.MULTIPLANAR_HOR then - vSlicingVal, vSlicingDir = ComputeMultiplanarSlicingData( dSliceStep, nMaxSlicesNbr, nSlicingType) + vSlicingVal, vSlicingDir = ComputeMultiplanarSlicingData( dSliceStep, nMaxSlicesNbr, nSlicingType, nStmId) else vSlicingVal, vSlicingDir = ComputeSlicingData( vRefIds, vtSlicing, dSliceStep, dMaxH, nMaxSlicesNbr) end diff --git a/LuaLibs/RunSlicing.lua b/LuaLibs/RunSlicing.lua index 1a4ee24..bd83b45 100644 --- a/LuaLibs/RunSlicing.lua +++ b/LuaLibs/RunSlicing.lua @@ -86,6 +86,13 @@ local function RemoveOldSlices( nPartId) EgtErase( nExportGrpId) end + -- rimuovo spina per multiplanare calcolata dai piani + local nAuxGrpId = EgtGetFirstNameInGroup( nPartId, LAY_AUX) + local nSpineId = EgtGetFirstNameInGroup( nAuxGrpId, SPINE_FROM_PLANES) + if nSpineId then + EgtErase( nSpineId) + end + end ---------------------------------------------------------------------