From 59a2cfbfedd65da92afe5e84f8565c90a6e77ab5 Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Mon, 8 Apr 2019 09:58:57 +0000 Subject: [PATCH] EgtGeomKernel : - altra correzione a MC_Table per Zmap - in Zmap ad AvoidBox, AvoidCylinder e AvoidSphere aggiunto parametro dSafeDist e migliorate queste funzioni. --- CAvToolSurfTm.cpp | 9 +-- MC_Tables.h | 2 +- VolZmap.h | 14 ++--- VolZmapCalculus.cpp | 131 +++++++++++++++++++++++++++++++++++++------- 4 files changed, 123 insertions(+), 33 deletions(-) diff --git a/CAvToolSurfTm.cpp b/CAvToolSurfTm.cpp index f04021e..bdd9dd8 100644 --- a/CAvToolSurfTm.cpp +++ b/CAvToolSurfTm.cpp @@ -280,15 +280,12 @@ CAvToolSurfTm::MyTestPositionHG( Point3d& ptT, const Vector3d& vtDir) Vector3d vtDirL = vtDir ; vtDirL.ToLoc( m_frMove) ; b3Tool.Add( ptTL) ; b3Tool.Add( ptTL - vtDirL * m_Tool.GetHeigth()) ; - if ( AreSameOrOppositeVectorApprox( vtDir, m_frMove.VersX())) { + if ( vtDirL.IsXplus() || vtDirL.IsXminus()) b3Tool.Expand( 0, m_Tool.GetRadius(), m_Tool.GetRadius()) ; - } - else if ( AreSameOrOppositeVectorApprox( vtDir, m_frMove.VersY())) { + else if ( vtDirL.IsYplus() || vtDirL.IsYminus()) b3Tool.Expand( m_Tool.GetRadius(), 0, m_Tool.GetRadius()) ; - } - else if ( AreSameOrOppositeVectorApprox( vtDir, m_frMove.VersZ())) { + else if ( vtDirL.IsZplus() || vtDirL.IsZminus()) b3Tool.Expand( m_Tool.GetRadius(), m_Tool.GetRadius(), 0) ; - } else { double dExpandX = m_Tool.GetRadius() * sqrt( 1 - vtDirL.x * vtDirL.x) ; double dExpandY = m_Tool.GetRadius() * sqrt( 1 - vtDirL.y * vtDirL.y) ; diff --git a/MC_Tables.h b/MC_Tables.h index 90ddc85..0b0420f 100644 --- a/MC_Tables.h +++ b/MC_Tables.h @@ -781,7 +781,7 @@ static int TriangleTableEn[256][2][17] = { {{2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1, -1}, // 1 1 1 0 1 0 0 0 Config 11 {1, 6, 2, 3, 7, 4, 9, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, - {{7, 4, 8, 2, 0, 10, 9, 10, 0, -1, -1, -1, -1, -1, -1, -1, -1}, // 1 1 1 0 1 0 0 1 Config 6 + {{2, 0, 10, 9, 10, 0, 7, 4, 8, -1, -1, -1, -1, -1, -1, -1, -1}, // 1 1 1 0 1 0 0 1 Config 6 {2, 4, 3, 9, 10, 2, 0, 7, 4, 8, -1, -1, -1, -1, -1, -1, -1}}, {{10, 2, 1, 4, 0, 7, 3, 7, 0, -1, -1, -1, -1, -1, -1, -1, -1}, // 1 1 1 0 1 0 1 0 Config 6 diff --git a/VolZmap.h b/VolZmap.h index ac7ee67..ae51260 100644 --- a/VolZmap.h +++ b/VolZmap.h @@ -100,9 +100,9 @@ class VolZmap : public IVolZmap, public IGeoObjRW bool GetDepthWithDexel( const Point3d& ptP, const Vector3d& vtDir, double& dInLength, double& dOutLength) const ; bool GetDepthWithVoxel( const Point3d& ptP, const Vector3d& vtDir, double& dInLength, double& dOutLength, bool bEnh) const ; bool GetPlaneIntersection( const Plane3d& plPlane, ICURVEPOVECTOR& vpLoop) const override ; - bool AvoidBox( const Frame3d& frBox, const Vector3d& vtDiag) const override ; - bool AvoidSphere( const Point3d& ptCenter, double dRad) const override ; - bool AvoidCylinder( const Frame3d& frCyl, double dL, double dR) const override ; + bool AvoidBox( const Frame3d& frBox, const Vector3d& vtDiag, double dSafeDist) const override ; + bool AvoidSphere( const Point3d& ptCenter, double dRad, double dSafeDist) const override ; + bool AvoidCylinder( const Frame3d& frCyl, double dH, double dR, double dSafeDist) const override ; VolZmap* ClonePart( int nPart) const override ; bool RemovePart( int nPart) override ; bool Cut( const Plane3d& plPlane) override ; @@ -301,17 +301,17 @@ class VolZmap : public IVolZmap, public IGeoObjRW double& dU1, double& dU2) const ; bool IntersLineCylinder( const Point3d& ptLineSt, const Vector3d& vtLineDir, const Frame3d& CylFrame, double dH, double dRad, bool bTapLow, bool bTapUp, - Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) ; + Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const ; bool IntersLineEllipticalCylinder( const Point3d& ptLineSt, const Vector3d& vtLineDir, const Frame3d& CircFrame, double dRad, double dLongMvLen, double dOrtMvLen, bool bTapLow, bool bTapUp, - Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) ; + Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const ; bool IntersLineConus( const Point3d& ptLineSt, const Vector3d& vtLineDir, const Frame3d& ConusFrame, double dTan, double dMinH, double dMaxH, bool bTapLow, bool bTapUp, - Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) ; + Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const ; bool IntersLineMyPolyhedron( const Point3d& ptLineSt, const Vector3d& vtLineDir, const Frame3d& PolyFrame, double dLenX, double dLenY, double dLenZ, double dDeltaX, - Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) ; + Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const ; bool TestIntersPlaneZmapBBox( const Plane3d& plPlane) const ; // Voxel: esistenza e passaggio da N a ijk per i voxel bool IsValidVoxel( int nN) const ; diff --git a/VolZmapCalculus.cpp b/VolZmapCalculus.cpp index efd2384..56ecf1f 100644 --- a/VolZmapCalculus.cpp +++ b/VolZmapCalculus.cpp @@ -672,13 +672,23 @@ VolZmap::GetDepthWithVoxel( const Point3d& ptP, const Vector3d& vtD, double& dIn //---------------------------------------------------------------------------- bool -VolZmap::AvoidBox( const Frame3d& frBox, const Vector3d& vtDiag) const +VolZmap::AvoidBox( const Frame3d& frBox, const Vector3d& vtDiag, double dSafeDist) const { // BBox BBox3d b3Box( ORIG, ORIG + vtDiag) ; - // lo porto nel riferimento intrinseco dello Zmap - b3Box.LocToLoc( frBox, m_MapFrame) ; + // Sistemazioni per distanza di sicurezza + if ( dSafeDist > EPS_SMALL) + b3Box.Expand( dSafeDist) ; + + // Riferimento nell'angolo con coordinate minime + Point3d ptMin = b3Box.GetMin() ; ptMin.ToGlob( frBox) ; + Frame3d frB = frBox ; frB.ChangeOrig( ptMin) ; + Vector3d vtDg = b3Box.GetMax() - b3Box.GetMin() ; + b3Box.Set( ORIG, ORIG + vtDg) ; + + // Lo porto nel riferimento intrinseco dello Zmap + b3Box.LocToLoc( frB, m_MapFrame) ; // BBox dello Zmap nel suo riferimento intrinseco BBox3d b3Zmap( ORIG, Point3d( m_nNx[0] * m_dStep, m_nNy[0] * m_dStep, m_dMaxZ[0])) ; @@ -695,12 +705,12 @@ VolZmap::AvoidBox( const Frame3d& frBox, const Vector3d& vtDiag) const int nEnJ = Clamp( int( b3Int.GetMax().y / m_dStep), 0, m_nNy[0] -1) ; // Vettore direzione dei dexel nel riferimento del Box - Vector3d vtK = Z_AX ; vtK.LocToLoc( m_MapFrame, frBox) ; + Vector3d vtK = Z_AX ; vtK.LocToLoc( m_MapFrame, frB) ; // Riferimento intrinseco dei dexel nel riferimento del box - Point3d ptO = ORIG ; ptO.LocToLoc( m_MapFrame, frBox) ; - Vector3d vtX = X_AX ; vtX.LocToLoc( m_MapFrame, frBox) ; - Vector3d vtY = Y_AX ; vtY.LocToLoc( m_MapFrame, frBox) ; + Point3d ptO = ORIG ; ptO.LocToLoc( m_MapFrame, frB) ; + Vector3d vtX = X_AX ; vtX.LocToLoc( m_MapFrame, frB) ; + Vector3d vtY = Y_AX ; vtY.LocToLoc( m_MapFrame, frB) ; // Ciclo di intersezione dei dexel con il BBox for ( int i = nStI ; i <= nEnI ; ++ i) { @@ -722,7 +732,7 @@ VolZmap::AvoidBox( const Frame3d& frBox, const Vector3d& vtDiag) const else if ( k == 4) ptT += - 0.4 * m_dStep * vtX + 0.4 * m_dStep * vtY ; double dZmin, dZmax ; - if ( IntersLineBox( ptT, vtK, ORIG, ORIG + vtDiag, dZmin, dZmax)) { + if ( IntersLineBox( ptT, vtK, ORIG, ORIG + vtDg, dZmin, dZmax)) { for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 1) { if ( ! ( dZmax < m_Values[0][nPos][nIndex].dMin - EPS_SMALL || dZmin > m_Values[0][nPos][nIndex].dMax + EPS_SMALL)) @@ -738,12 +748,16 @@ VolZmap::AvoidBox( const Frame3d& frBox, const Vector3d& vtDiag) const //---------------------------------------------------------------------------- bool -VolZmap::AvoidSphere( const Point3d& ptCenter, double dRad) const +VolZmap::AvoidSphere( const Point3d& ptCenter, double dRad, double dSafeDist) const { // Porto la sfera nel riferimento intrinseco dello Zmap Point3d ptC = ptCenter ; ptC.ToLoc( m_MapFrame) ; + // Aumento il raggio della distanza di sicurezza + if ( dSafeDist > EPS_SMALL) + dRad += dSafeDist ; + // BBox della sfera BBox3d b3Box( ptC) ; b3Box.Expand( dRad) ; @@ -782,9 +796,9 @@ VolZmap::AvoidSphere( const Point3d& ptCenter, double dRad) const else if ( k == 4) ptT += - 0.4 * m_dStep * X_AX + 0.4 * m_dStep * Y_AX ; Point3d ptI1, ptI2 ; - if ( IntersLineSphere( ptT, Z_AX, ptC, dRad, ptI1, ptI2) != ILST_NO) { - double dZmin = ptI1.z ; - double dZmax = ptI2.z ; + if ( ::IntersLineSphere( ptT, Z_AX, ptC, dRad, ptI1, ptI2) != ILST_NO) { + double dZmin = min( ptI1.z, ptI2.z) ; + double dZmax = max( ptI1.z, ptI2.z) ; for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 1) { if ( ! ( dZmax < m_Values[0][nPos][nIndex].dMin - EPS_SMALL || dZmin > m_Values[0][nPos][nIndex].dMax + EPS_SMALL)) @@ -800,8 +814,89 @@ VolZmap::AvoidSphere( const Point3d& ptCenter, double dRad) const //---------------------------------------------------------------------------- bool -VolZmap::AvoidCylinder( const Frame3d& frCyl, double dL, double dR) const +VolZmap::AvoidCylinder( const Frame3d& frCyl, double dH, double dR, double dSafeDist) const { + // Porto il cilindro nel riferimento intrinseco dello Zmap + Frame3d frC = frCyl ; + frC.ToLoc( m_MapFrame) ; + + // Se altezza negativa, sposto riferimento da faccia sopra a quella sotto + if ( dH < 0) { + frC.Translate( dH * frC.VersZ()) ; + dH = - dH ; + } + + // Sistemazioni per distanza di sicurezza + if ( dSafeDist > EPS_SMALL) { + frC.Translate( - dSafeDist * frC.VersZ()) ; + dH += 2 * dSafeDist ; + dR += dSafeDist ; + } + + // BBox del cilindro + Vector3d vtDirL = frC.VersZ() ; + BBox3d b3Box( frC.Orig()) ; + b3Box.Add( frC.Orig() + frC.VersZ() * dH) ; + if ( vtDirL.IsXplus() || vtDirL.IsXminus()) + b3Box.Expand( 0, dR, dR) ; + else if ( vtDirL.IsYplus() || vtDirL.IsYminus()) + b3Box.Expand( dR, 0, dR) ; + else if ( vtDirL.IsZplus() || vtDirL.IsZminus()) + b3Box.Expand( dR, dR, 0) ; + else { + double dExpandX = dR * sqrt( 1 - vtDirL.x * vtDirL.x) ; + double dExpandY = dR * sqrt( 1 - vtDirL.y * vtDirL.y) ; + double dExpandZ = dR * sqrt( 1 - vtDirL.z * vtDirL.z) ; + b3Box.Expand( dExpandX, dExpandY, dExpandZ) ; + } + + // BBox dello Zmap nel suo riferimento intrinseco + BBox3d b3Zmap( ORIG, Point3d( m_nNx[0] * m_dStep, m_nNy[0] * m_dStep, m_dMaxZ[0])) ; + + // Se non interferiscono, posso uscire + BBox3d b3Int ; + if ( ! b3Zmap.FindIntersection( b3Box, b3Int)) + return true ; + + // Limiti su indici + int nStI = Clamp( int( b3Int.GetMin().x / m_dStep), 0, m_nNx[0] -1) ; + int nEnI = Clamp( int( b3Int.GetMax().x / m_dStep), 0, m_nNx[0] -1) ; + int nStJ = Clamp( int( b3Int.GetMin().y / m_dStep), 0, m_nNy[0] -1) ; + int nEnJ = Clamp( int( b3Int.GetMax().y / m_dStep), 0, m_nNy[0] -1) ; + + // Ciclo di intersezione dei dexel con il cilindro (nel riferimento intrinseco) + for ( int i = nStI ; i <= nEnI ; ++ i) { + for ( int j = nStJ ; j <= nEnJ ; ++ j) { + int nPos = j * m_nNx[0] + i ; + int nSize = int( m_Values[0][nPos].size()) ; + if ( nSize == 0) + continue ; + for ( int k = 0 ; k < 5 ; ++ k) { + Point3d ptT = ORIG + ( i + 0.5) * m_dStep * X_AX + ( j + 0.5) * m_dStep * Y_AX ; + if ( k == 0) + ; + else if ( k == 1) + ptT += - 0.4 * m_dStep * X_AX - 0.4 * m_dStep * Y_AX ; + else if ( k == 2) + ptT += + 0.4 * m_dStep * X_AX - 0.4 * m_dStep * Y_AX ; + else if ( k == 3) + ptT += + 0.4 * m_dStep * X_AX + 0.4 * m_dStep * Y_AX ; + else if ( k == 4) + ptT += - 0.4 * m_dStep * X_AX + 0.4 * m_dStep * Y_AX ; + Point3d ptI1, ptI2 ; + Vector3d vtN1, vtN2 ; + if ( IntersLineCylinder( ptT, Z_AX, frC, dH, dR, true, true, ptI1, vtN1, ptI2, vtN2)) { + double dZmin = min( ptI1.z, ptI2.z) ; + double dZmax = max( ptI1.z, ptI2.z) ; + for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 1) { + if ( ! ( dZmax < m_Values[0][nPos][nIndex].dMin - EPS_SMALL || + dZmin > m_Values[0][nPos][nIndex].dMax + EPS_SMALL)) + return false ; + } + } + } + } + } return true ; } @@ -813,7 +908,7 @@ VolZmap::AvoidCylinder( const Frame3d& frCyl, double dL, double dR) const bool VolZmap::IntersLineCylinder( const Point3d& ptLineSt, const Vector3d& vtLineDir, const Frame3d& CylFrame, double dH, double dRad, bool bTapLow, bool bTapUp, - Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) + Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const { // Porto la linea nel riferimento del cilindro Point3d ptP = ptLineSt ; ptP.ToLoc( CylFrame) ; @@ -880,8 +975,6 @@ VolZmap::IntersLineCylinder( const Point3d& ptLineSt, const Vector3d& vtLineDir, // Punti di intersezione con la superficie del cilindro ptInt1 = ptP + vdRoots[0] * vtV ; ptInt2 = ptP + vdRoots[1] * vtV ; - if ( ptInt1.z > ptInt2.z) - swap( ptInt1, ptInt2) ; // Determino le normali vtN1.Set( -ptInt1.x, -ptInt1.y, 0) ; vtN1.Normalize() ; @@ -938,7 +1031,7 @@ VolZmap::IntersLineCylinder( const Point3d& ptLineSt, const Vector3d& vtLineDir, bool VolZmap::IntersLineConus( const Point3d& ptLineSt, const Vector3d& vtLineDir, const Frame3d& ConusFrame, double dTan, double dMinH, double dMaxH, bool bTapLow, bool bTapUp, - Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) + Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const { // Porto la linea nel riferimento del cono Point3d ptP = ptLineSt ; ptP.ToLoc( ConusFrame) ; @@ -1072,7 +1165,7 @@ bool VolZmap::IntersLineEllipticalCylinder( const Point3d& ptLineSt, const Vector3d& vtLineDir, const Frame3d& CircFrame, double dRad, double dLongMvLen, double dOrtMvLen, bool bTapLow, bool bTapUp, - Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) + Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const { // Se il cilindrico ellittico degenera in un piano, non bisogna tagliare if ( abs( dLongMvLen) < EPS_SMALL) @@ -1210,7 +1303,7 @@ VolZmap::IntersLineEllipticalCylinder( const Point3d& ptLineSt, const Vector3d& bool VolZmap::IntersLineMyPolyhedron( const Point3d& ptLineSt, const Vector3d& vtLineDir, const Frame3d& PolyFrame, double dLenX, double dLenY, double dLenZ, double dDeltaZ, - Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) + Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const { // Controllo sulle dimensioni lineari affinché sia valido il poliedro if ( dLenX <= EPS_SMALL || dLenY <= EPS_SMALL || dLenZ <= EPS_SMALL)