diff --git a/Operation.cpp b/Operation.cpp index fd5024e..5155869 100644 --- a/Operation.cpp +++ b/Operation.cpp @@ -30,6 +30,7 @@ #include "/EgtDev/Include/EGkIntersLineSurfTm.h" #include "/EgtDev/Include/EGkGeomDB.h" #include "/EgtDev/Include/EGkCDeBoxClosedSurfTm.h" +#include "/EgtDev/Include/EGkCDeCylClosedSurfTm.h" #include "/EgtDev/Include/EXeConst.h" #include "/EgtDev/Include/EgtPointerOwner.h" @@ -2259,24 +2260,49 @@ Operation::TestCollisionAvoid( const DBLVECTOR& vAxStart, const DBLVECTOR& vAxEn BBox3d b3Raw ; int nRawSolidId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_SOLID) ; if ( m_pGeomDB->GetGlobalBBox( nRawSolidId, b3Raw) && b3Head.Overlaps( b3Raw)) { + // solido del grezzo + const ISurfTriMesh* pStm = GetSurfTriMesh( m_pGeomDB->GetGeoObj( nRawSolidId)) ; // riferimento del grezzo Frame3d frSolid ; m_pGeomDB->GetGlobFrame( nRawSolidId, frSolid) ; // verifico i sottobox for ( const auto& biSH : vbiSH) { if ( biSH.first.Overlaps( b3Raw)) { - // sottobox testa nel riferimento del solido + // box del solido parte della testa BBox3d b3Hsol ; - m_pGeomDB->GetRefBBox( biSH.second, frSolid, b3Hsol) ; + m_pGeomDB->GetLocalBBox( biSH.second, b3Hsol, BBF_ONLY_VISIBLE) ; Point3d ptMin ; Vector3d vtDiag ; b3Hsol.GetMinDim( ptMin, vtDiag.x, vtDiag.y, vtDiag.z) ; - // solido - const ISurfTriMesh* pStm = GetSurfTriMesh( m_pGeomDB->GetGeoObj( nRawSolidId)) ; - // verifica di collisione tra sottobox e solido - if ( pStm == nullptr || CDeBoxClosedSurfTm( Frame3d( ptMin), vtDiag, dSafeDist, *pStm)) { - bCollide = true ; - break ; + // riferimento della parte di testa + Frame3d frHsol ; + if ( m_pGeomDB->GetGdbType( biSH.second) == GDB_TY_GEO) + m_pGeomDB->GetGlobFrame( biSH.second, frHsol) ; + else + m_pGeomDB->GetGroupGlobFrame( biSH.second, frHsol) ; + // lo porto nel riferimento del grezzo + frHsol.ToLoc( frSolid) ; + // se utensile cilindrico (faccia XY quadra e origine del riferimento nel suo centro) + if ( abs( vtDiag.x - vtDiag.y) < 100 * EPS_SMALL && + abs( vtDiag.x / 2 + ptMin.x) < 100 * EPS_SMALL && + abs( vtDiag.y / 2 + ptMin.y) < 100 * EPS_SMALL) { + // traslo il riferimento per avere il cilindro centrato sull'asse Y in positivo + frHsol.Translate( frHsol.VersZ() * ptMin.z) ; + // verifica di collisione tra cilindro e solido + if ( pStm == nullptr || CDeCylClosedSurfTm( frHsol, vtDiag.z, max( vtDiag.x, vtDiag.y) / 2, dSafeDist, *pStm)) { + bCollide = true ; + break ; + } + } + // altrimenti + else { + // traslo il riferimento per avere il box nel primo ottante + frHsol.Translate( frHsol.VersX() * ptMin.x + frHsol.VersY() * ptMin.y + frHsol.VersZ() * ptMin.z) ; + // verifica di collisione tra box e solido + if ( pStm == nullptr || CDeBoxClosedSurfTm( frHsol, vtDiag, dSafeDist, *pStm)) { + bCollide = true ; + break ; + } } } }