diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc index b65c565..e21fe9e 100644 Binary files a/EgtGeomKernel.rc and b/EgtGeomKernel.rc differ diff --git a/MC_Tables.h b/MC_Tables.h index 9b63a80..d9d6d68 100644 --- a/MC_Tables.h +++ b/MC_Tables.h @@ -721,120 +721,117 @@ static int TriangleTableEn[256][2][17] = { {{5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1, -1}, {1, 6, 10, 2, 1, 9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, - /* 220 */ - {{8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 5, 8, 4, 5, 1, 3,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, + // 220 ---------------------------------------------------------- + {{8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 5, 8, 4, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, - {{0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 4, 0, 4, 5, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, + {{0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 4, 0, 4, 5, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, - {{8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1, -1}, - {2, 4, 4, 0, 3, 5, 9, 8, 4, 5, 3, -1, -1, -1, -1, -1, -1}}, + {{8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1, -1}, + {2, 4, 4, 0, 3, 5, 9, 8, 4, 5, 3, -1, -1, -1, -1, -1, -1}}, - {{9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 3, 9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, + {{9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 3, 9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, - {{4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 5, 9,10, 11, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, + {{4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 5, 9, 10, 11, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, - /* 225 */ - {{0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1, -1}, - {2, 3, 5, 0, 8, 3, 7, 4, 9, 10, 11, -1, -1, -1, -1, -1, -1}}, + {{0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1, -1}, + {2, 3, 5, 0, 8, 3, 7, 4, 9, 10, 11, -1, -1, -1, -1, -1, -1}}, - {{1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1, -1}, - {1, 6, 1, 10,11, 7, 4, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, + {{1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1, -1}, + {1, 6, 1, 10, 11, 7, 4, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, - {{3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1, -1}, - {1, 7, 3, 1,10,11, 7, 4, 8, -1, -1, -1, -1, -1, -1, -1, -1}}, + {{3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1, -1}, + {1, 7, 3, 1, 10, 11, 7, 4, 8, -1, -1, -1, -1, -1, -1, -1, -1}}, - {{4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1, -1}, - {2, 4, 4, 2, 11, 9, 1, 4, 9, 11, 7, -1, -1, -1, -1, -1, -1}}, + {{4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1, -1}, + {2, 4, 4, 2, 11, 9, 1, 4, 9, 11, 7, -1, -1, -1, -1, -1, -1}}, - {{9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1, -1}, - {3, 4, 4, 3, 1, 2, 11, 9, 7, 4, 9,11, 8, 3, 0, 8, 3}}, + {{9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1, -1}, + {3, 4, 4, 3, 1, 2, 11, 9, 7, 4, 9, 11, 8, 3, 0, 8, 3}}, - /* 230 */ - {{11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1, -1}, - { 1, 5, 11, 7, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, + // 230 ---------------------------------------------------------- + {{11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 5, 11, 7, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, - {{11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1, -1}, - { 2, 4, 4, 11, 7, 4, 2, 3, 2, 4, 8,-1, -1, -1, -1, -1, -1}}, + {{11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1, -1}, + {2, 4, 4, 11, 7, 4, 2, 3, 2, 4, 8, -1, -1, -1, -1, -1, -1}}, - {{2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1, -1}, - {1, 6, 2, 3, 7, 4, 9,10, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, + {{2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1, -1}, + {1, 6, 2, 3, 7, 4, 9, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, - {{9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1, -1}, - {1, 7, 9,10, 2, 0, 8, 7, 4,-1, -1, -1, -1, -1, -1, -1, -1}}, + {{9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1, -1}, + {1, 7, 9, 10, 2, 0, 8, 7, 4,-1, -1, -1, -1, -1, -1, -1, -1}}, - {{3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1, -1}, - {1, 7, 3, 7, 4, 0, 1,10, 2, -1, -1, -1, -1, -1, -1, -1, -1}}, + {{3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1, -1}, + {1, 7, 3, 7, 4, 0, 1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1}}, - /* 235 */ - {{1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {2, 3, 3, 1,10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1}}, + {{1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {2, 3, 3, 1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1}}, - {{4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 5, 4, 9, 1, 3, 7,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, + {{4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 5, 4, 9, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, - {{4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1, -1}, - {2, 4, 4, 8, 7, 1, 0, 4, 9, 1, 7, -1, -1, -1, -1, -1, -1}}, + {{4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1, -1}, + {2, 4, 4, 8, 7, 1, 0, 4, 9, 1, 7, -1, -1, -1, -1, -1, -1}}, - {{4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 4, 3, 7, 4, 0,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, + {{4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 4, 3, 7, 4, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, - {{4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 3, 4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, + {{4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 3, 4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, - /* 240 */ - {{9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 4, 8, 9, 10,11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, + // 240 ------------------------------------------------------------ + {{9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 4, 8, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, - {{3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 5, 3, 0, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, + {{3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 5, 3, 0, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, - {{0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 5, 0, 1, 10,11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, + {{0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 5, 0, 1, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, - {{3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 4, 3, 1,10, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, + {{3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 4, 3, 1, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, - {{1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 5, 1, 2, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, + {{1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 5, 1, 2, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, - /* 245 */ - {{3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1, -1}, - {2, 4, 4, 2,11, 9, 1, 3, 0, 9, 11, -1, -1, -1, -1, -1,-1}}, + {{3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1, -1}, + {2, 4, 4, 2, 11, 9, 1, 3, 0, 9, 11, -1, -1, -1, -1, -1,-1}}, - {{0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 4, 0, 2,11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, + {{0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 4, 0, 2, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, - {{3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 3, 3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, + {{3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 3, 3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, - {{2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 5, 2, 3, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, + {{2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 5, 2, 3, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, - {{9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 4, 2, 0, 9,10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, + {{9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 4, 2, 0, 9, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, - /* 250 */ - {{2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1, -1}, - {2, 4, 4, 2, 3, 8, 10, 1, 10, 8, 0, -1, -1, -1, -1, -1, -1}}, + // 250 ------------------------------------------------------- + {{2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1, -1}, + {2, 4, 4, 2, 3, 8, 10, 1, 10, 8, 0, -1, -1, -1, -1, -1, -1}}, - {{1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 3, 1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, + {{1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 3, 1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, - {{1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 4, 1, 3, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, + {{1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 4, 1, 3, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, - {{0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 3, 0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, + {{0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 3, 0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, - {{0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 3, 0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, + {{0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 3, 0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, - {{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - { 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}} + {{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}} } ; #if 0 diff --git a/VolTriZmapCalculus.cpp b/VolTriZmapCalculus.cpp index 2389193..7ef952f 100644 --- a/VolTriZmapCalculus.cpp +++ b/VolTriZmapCalculus.cpp @@ -26,7 +26,7 @@ using namespace std ; //---------------------------------------------------------------------------- bool VolZmap::IntersLineBox( const Point3d& ptP, const Vector3d& vtV, - const Point3d& ptMin, const Point3d& ptMax, double& dU1, double& dU2) + const Point3d& ptMin, const Point3d& ptMax, double& dU1, double& dU2) const { // Il box è allineato agli assi @@ -312,7 +312,8 @@ VolZmap::AvoidBox( const Frame3d& frBox, const Vector3d& vtDiag) bool VolZmap::IntersLineCylinder( const Point3d& ptLineSt, const Vector3d& vtLineDir, const Frame3d& CylFrame, double dL, double dR, - Point3d& ptInt1, Point3d& ptInt2) + Point3d& ptInt1, Point3d& ptInt2, Vector3d& vtN1, Vector3d& vtN2, + bool bTapO, bool bTapL) { // NB: L'origine del sistema di riferimento deve essere // nel centro della circonferenza di base e l'asse di simmetria @@ -323,14 +324,16 @@ VolZmap::IntersLineCylinder( const Point3d& ptLineSt, const Vector3d& vtLineDir, Point3d ptP = ptLineSt ; Vector3d vtV = vtLineDir ; - // Trasformazione delle coordinate + // Trasformazione delle coordinate: + // l'asse del cilindro corrisponde con + // l'asse x del sistema di riferimento ptP.ToLoc( CylFrame) ; vtV.ToLoc( CylFrame) ; DBLVECTOR vdCoef(3) ; DBLVECTOR vdRoots ; - double dSqRad = dR * dR ; + double dSqRad = dR * dR - 2 * dR * EPS_SMALL ; vdCoef[0] = ptP.y * ptP.y + ptP.z * ptP.z - dSqRad ; vdCoef[1] = 2 * ( ptP.y * vtV.y + ptP.z * vtV.z) ; @@ -347,12 +350,18 @@ VolZmap::IntersLineCylinder( const Point3d& ptLineSt, const Vector3d& vtLineDir, ptInt1 = ptP - ( ptP.x / vtV.x) * vtV ; ptInt2 = ptP + ( ( dL - ptP.x) / vtV.x) * vtV ; + vtN1 = X_AX ; + vtN2 = - X_AX ; + if ( ptInt1.y * ptInt1.y + ptInt1.z * ptInt1.z <= dSqRad && ptInt2.y * ptInt2.y + ptInt2.z * ptInt2.z <= dSqRad) { ptInt1.ToGlob( CylFrame) ; ptInt2.ToGlob( CylFrame) ; + vtN1.ToGlob( CylFrame) ; + vtN2.ToGlob( CylFrame) ; + return true ; } // Nessuna intersezione @@ -370,31 +379,43 @@ VolZmap::IntersLineCylinder( const Point3d& ptLineSt, const Vector3d& vtLineDir, if ( nRoot == 2) { + double dEpsO = ( bTapO ? - EPS_SMALL : EPS_SMALL) ; + double dEpsL = ( bTapL ? EPS_SMALL : - EPS_SMALL) ; + ptInt1 = ptP + vdRoots[0] * vtV ; ptInt2 = ptP + vdRoots[1] * vtV ; if ( ptInt1.x > ptInt2.x) - swap( ptInt1, ptInt2) ; + swap( ptInt1, ptInt2) ; + + vtN1.Set( 0, ( ORIG - ptInt1).y, ( ORIG - ptInt1).z) ; + vtN2.Set( 0, ( ORIG - ptInt2).y, ( ORIG - ptInt2).z) ; - if ( ptInt1.x < dL + EPS_SMALL) { + if ( ptInt1.x < dL + dEpsL) { - if ( ptInt1.x > - EPS_SMALL) { + if ( ptInt1.x > dEpsO) { - if ( ptInt2.x > dL) + if ( ptInt2.x > dL + dEpsL) { ptInt2 = ptP + ( ( dL - ptP.x) / vtV.x) * vtV ; + vtN2.Set( -1, 0, 0) ; + } } else { - if ( ptInt2.x > dL) { + if ( ptInt2.x > dL + dEpsL) { ptInt1 = ptP - ( ptP.x / vtV.x) * vtV ; ptInt2 = ptP + ( ( dL - ptP.x) / vtV.x) * vtV ; + vtN1.Set( 1, 0, 0) ; + vtN2.Set( -1, 0, 0) ; } - else if ( ptInt2.x > 0) + else if ( ptInt2.x > dEpsO) { - ptInt1 = ptP - ( ptP.x / vtV.x) * vtV ; + ptInt1 = ptP - ( ptP.x / vtV.x) * vtV ; + vtN1.Set( 1, 0, 0) ; + } else return false ; } @@ -405,7 +426,12 @@ VolZmap::IntersLineCylinder( const Point3d& ptLineSt, const Vector3d& vtLineDir, // Riporto le coordinate nel sistema di riferimento griglia ptInt1.ToGlob( CylFrame) ; ptInt2.ToGlob( CylFrame) ; - } + vtN1.ToGlob( CylFrame) ; + vtN2.ToGlob( CylFrame) ; + + vtN1.Normalize() ; + vtN2.Normalize() ; + } return true ; } @@ -516,11 +542,12 @@ VolZmap::IntersZLineCylinder( const Point3d& ptLine, } } +/* //---------------------------------------------------------------------------- bool VolZmap::IntersLineConus( const Point3d& ptLineSt, const Vector3d& vtLineDir, const Frame3d& ConusFrame, double dTan, double dl, double dL, - Point3d& ptInt1, Point3d& ptInt2) + Point3d& ptInt1, Point3d& ptInt2, Vector3d& vtN1, Vector3d& vtN2) { // NB: L'origine del sistema di riferimento deve essere // nel vertice del cono e l'asse di simmetria deve coincidere @@ -541,6 +568,8 @@ VolZmap::IntersLineConus( const Point3d& ptLineSt, const Vector3d& vtLineDir, double dSqTan = dTan * dTan ; double dMinRad = dTan * dl ; double dMaxRad = dTan * dL ; + double dDeltaR = dMaxRad - dMinRad ; + double dHei = dL - dl ; vdCoef[0] = dSqTan * ptP.x * ptP.x - ptP.y * ptP.y - ptP.z * ptP.z ; vdCoef[1] = 2 * ( dSqTan * ptP.x * vtV.x - ptP.y * vtV.y - ptP.z * vtV.z) ; @@ -558,18 +587,32 @@ VolZmap::IntersLineConus( const Point3d& ptLineSt, const Vector3d& vtLineDir, if ( nRoot == 1) { ptInt1 = ptP + vdRoots[0] * vtV ; + + Vector3d vtU = ( ptInt1 - ORIG) - ( ptInt1 - ORIG).x * X_AX ; + + vtU.Normalize() ; + + vtN1 = dDeltaR * X_AX - dHei * vtU ; + + vtN1.Normalize() ; if ( ptInt1.x < dL + EPS_SMALL) { - if ( ptInt1.x > dl) + if ( ptInt1.x > dl) { - ptInt2 = ptP + ( ( dL - ptP.x) / vtV.x) * vtV ; + ptInt2 = ptP + ( ( dL - ptP.x) / vtV.x) * vtV ; + vtN2 = - X_AX ; + + } else if ( ptInt1.x > - EPS_SMALL) { ptInt1 = ptP + ( ( dl - ptP.x) / vtV.x) * vtV ; ptInt2 = ptP + ( ( dL - ptP.x) / vtV.x) * vtV ; + vtN1 = X_AX ; + vtN2 = - X_AX ; + if ( ptInt2.y * ptInt2.y + ptInt2.z * ptInt2.z > dMaxRad * dMaxRad) return false ; @@ -580,6 +623,9 @@ VolZmap::IntersLineConus( const Point3d& ptLineSt, const Vector3d& vtLineDir, ptInt1.ToGlob( ConusFrame) ; ptInt2.ToGlob( ConusFrame) ; + vtN1.ToGlob( ConusFrame) ; + vtN2.ToGlob( ConusFrame) ; + return true ; } else @@ -595,27 +641,46 @@ VolZmap::IntersLineConus( const Point3d& ptLineSt, const Vector3d& vtLineDir, if ( ptInt1.x > ptInt2.x) swap( ptInt1, ptInt2) ; + + Vector3d vtU1 = ( ptInt1 - ORIG) - ( ptInt1 - ORIG).x * X_AX ; + Vector3d vtU2 = ( ptInt2 - ORIG) - ( ptInt2 - ORIG).x * X_AX ; + + vtU1.Normalize() ; + vtU2.Normalize() ; + + vtN1 = dDeltaR * X_AX - dHei * vtU1 ; + vtN2 = dDeltaR * X_AX - dHei * vtU2 ; + + vtN1.Normalize() ; + vtN2.Normalize() ; if ( ptInt1.x < dL + EPS_SMALL) { if ( ptInt1.x > dl - EPS_SMALL) { - if ( ptInt2.x > dL) + if ( ptInt2.x > dL) { ptInt2 = ptP + ( ( dL - ptP.x) / vtV.x) * vtV ; + + vtN2 = - X_AX ; + } } else if ( ptInt1.x > - EPS_SMALL) { if ( ptInt2.x > dL) { ptInt1 = ptP + ( ( dl - ptP.x) / vtV.x) * vtV ; - ptInt2 = ptP + ( ( dL - ptP.x) / vtV.x) * vtV ; + ptInt2 = ptP + ( ( dL - ptP.x) / vtV.x) * vtV ; + + vtN1 = X_AX ; + vtN2 = - X_AX ; } - else if ( ptInt2.x > dl - EPS_SMALL) + else if ( ptInt2.x > dl - EPS_SMALL) { ptInt1 = ptP + ( ( dl - ptP.x) / vtV.x) * vtV ; - + vtN1 = X_AX ; + } else return false ; } @@ -628,12 +693,16 @@ VolZmap::IntersLineConus( const Point3d& ptLineSt, const Vector3d& vtLineDir, else if ( ptInt2.x < dl) { ptInt1 = ptP + ( ( dl - ptP.x) / vtV.x) * vtV ; - ptInt2 = ptP + ( ( dL - ptP.x) / vtV.x) * vtV ; + ptInt2 = ptP + ( ( dL - ptP.x) / vtV.x) * vtV ; + + vtN1 = X_AX ; + vtN2 = - X_AX ; } - else if ( ptInt2.x < dL) + else if ( ptInt2.x < dL) { ptInt1 = ptP + ( ( dL - ptP.x) / vtV.x) * vtV ; - + vtN1 = - X_AX ; + } else return false ; } @@ -641,19 +710,230 @@ VolZmap::IntersLineConus( const Point3d& ptLineSt, const Vector3d& vtLineDir, ptInt1.ToGlob( ConusFrame) ; ptInt2.ToGlob( ConusFrame) ; + vtN1.ToGlob( ConusFrame) ; + vtN2.ToGlob( ConusFrame) ; + + vtN1.Normalize() ; + vtN2.Normalize() ; + return true ; } else return false ; } return false ; +}*/ + +//---------------------------------------------------------------------------- +bool +VolZmap::IntersLineConus( const Point3d& ptLineSt, const Vector3d& vtLineDir, + const Frame3d& ConusFrame, double dTan, double dl, double dL, + Point3d& ptInt1, Point3d& ptInt2, Vector3d& vtN1, Vector3d& vtN2, + bool bTapLow, bool bTapUp) +{ + // NB: L'origine del sistema di riferimento deve essere + // nel vertice del cono e l'asse di simmetria deve coincidere + // con l'asse x. + // La funzione restituisce true in caso di intersezione, + // false altrimenti. + + Point3d ptP = ptLineSt ; + Vector3d vtV = vtLineDir ; + + // Trasformazione delle coordinate + ptP.ToLoc( ConusFrame) ; + vtV.ToLoc( ConusFrame) ; + + DBLVECTOR vdCoef(3) ; + DBLVECTOR vdRoots ; + + double dSqTan = dTan * dTan ; + double dMinRad = dTan * dl ; + double dMaxRad = dTan * dL ; + double dDeltaR = dMaxRad - dMinRad ; + double dHei = dL - dl ; + + vdCoef[0] = dSqTan * ptP.x * ptP.x - ptP.y * ptP.y - ptP.z * ptP.z ; + vdCoef[1] = 2 * ( dSqTan * ptP.x * vtV.x - ptP.y * vtV.y - ptP.z * vtV.z) ; + vdCoef[2] = dSqTan * vtV.x * vtV.x - vtV.y * vtV.y - vtV.z * vtV.z ; + + // Computo radici + int nRoot = PolynomialRoots( 2, vdCoef, vdRoots) ; + + // Nessuna soluzione + if ( nRoot == 0) + return false ; + + double dEpsLow = ( bTapLow ? - EPS_SMALL : EPS_SMALL) ; + double dEpsUp = ( bTapUp ? EPS_SMALL : - EPS_SMALL) ; + + // Una soluzione: la retta iterseca superficie + // laterale e un piano + if ( nRoot == 1) { + + ptInt1 = ptP + vdRoots[0] * vtV ; + + Vector3d vtU = ( ptInt1 - ORIG) - ( ptInt1 - ORIG).x * X_AX ; + + vtU.Normalize() ; + + vtN1 = dDeltaR * X_AX - dHei * vtU ; + + vtN1.Normalize() ; + + if ( ptInt1.x < dL + dEpsUp) { + + if ( ptInt1.x > dl + dEpsLow) { + + ptInt2 = ptP + ( ( dL - ptP.x) / vtV.x) * vtV ; + + vtN2 = - X_AX ; + + } + else if ( ptInt1.x > - EPS_SMALL) { + + ptInt1 = ptP + ( ( dl - ptP.x) / vtV.x) * vtV ; + ptInt2 = ptP + ( ( dL - ptP.x) / vtV.x) * vtV ; + + vtN1 = X_AX ; + vtN2 = - X_AX ; + + if ( ptInt2.y * ptInt2.y + ptInt2.z * ptInt2.z > dMaxRad * dMaxRad) + + return false ; + } + else + return false ; + + ptInt1.ToGlob( ConusFrame) ; + ptInt2.ToGlob( ConusFrame) ; + + vtN1.ToGlob( ConusFrame) ; + vtN2.ToGlob( ConusFrame) ; + + return true ; + } + else + return false ; + + } + // Due soluzioni: la retta interseca due volte la + // superficie laterale + else if ( nRoot == 2) { + + ptInt1 = ptP + vdRoots[0] * vtV ; + ptInt2 = ptP + vdRoots[1] * vtV ; + + if ( ptInt1.x > ptInt2.x) + swap( ptInt1, ptInt2) ; + + Vector3d vtU1 = ( ptInt1 - ORIG) - ( ptInt1 - ORIG).x * X_AX ; + Vector3d vtU2 = ( ptInt2 - ORIG) - ( ptInt2 - ORIG).x * X_AX ; + + vtU1.Normalize() ; + vtU2.Normalize() ; + + vtN1 = dDeltaR * X_AX - dHei * vtU1 ; + vtN2 = dDeltaR * X_AX - dHei * vtU2 ; + + vtN1.Normalize() ; + vtN2.Normalize() ; + + if ( abs( vtV.x) < EPS_ZERO) { + + if ( ptInt1.x > dl + dEpsLow && ptInt1.x < dL + dEpsUp) { + + ptInt1.ToGlob( ConusFrame) ; + ptInt2.ToGlob( ConusFrame) ; + + vtN1.ToGlob( ConusFrame) ; + vtN2.ToGlob( ConusFrame) ; + + vtN1.Normalize() ; + vtN2.Normalize() ; + + return true ; + } + else + return false ; + } + + + if ( ptInt1.x < dL + dEpsUp) { + + if ( ptInt1.x > dl + dEpsLow) { + + if ( ptInt2.x > dL + dEpsUp) { + + ptInt2 = ptP + ( ( dL - ptP.x) / vtV.x) * vtV ; + + vtN2 = - X_AX ; + } + } + else if ( ptInt1.x > - EPS_SMALL) { + + if ( ptInt2.x > dL + dEpsUp) { + + ptInt1 = ptP + ( ( dl - ptP.x) / vtV.x) * vtV ; + ptInt2 = ptP + ( ( dL - ptP.x) / vtV.x) * vtV ; + + vtN1 = X_AX ; + vtN2 = - X_AX ; + } + else if ( ptInt2.x > dl + dEpsLow) { + + ptInt1 = ptP + ( ( dl - ptP.x) / vtV.x) * vtV ; + vtN1 = X_AX ; + } + else + return false ; + } + else { + + if ( ptInt2.x < 0) + + return false ; + + else if ( ptInt2.x < dl + dEpsLow) { + + ptInt1 = ptP + ( ( dl - ptP.x) / vtV.x) * vtV ; + ptInt2 = ptP + ( ( dL - ptP.x) / vtV.x) * vtV ; + + vtN1 = X_AX ; + vtN2 = - X_AX ; + } + else if ( ptInt2.x < dL + dEpsUp) { + + ptInt1 = ptP + ( ( dL - ptP.x) / vtV.x) * vtV ; + vtN1 = - X_AX ; + } + else + return false ; + } + + ptInt1.ToGlob( ConusFrame) ; + ptInt2.ToGlob( ConusFrame) ; + + vtN1.ToGlob( ConusFrame) ; + vtN2.ToGlob( ConusFrame) ; + + vtN1.Normalize() ; + vtN2.Normalize() ; + + return true ; + } + else + return false ; + } + return false ; } //---------------------------------------------------------------------------- bool VolZmap::IntersLineEllipticalCylinder( const Vector3d& vtLineDir, const Point3d& ptLineSt, const Frame3d& CircFrame, double dSqRad, double dLongMvLen, double dOrtMvLen, - Point3d& ptInt1, Point3d& ptInt2) + Point3d& ptInt1, Point3d& ptInt2, Vector3d& vtN1, Vector3d& vtN2, + bool bTapLow, bool bTapUp) { // NB: L'origine del sistema di riferimento deve essere // nel centro della circonferenza di base, la cui tralsazione obliqua @@ -672,6 +952,10 @@ VolZmap::IntersLineEllipticalCylinder( const Vector3d& vtLineDir, const Point3d& Point3d ptP = ptLineSt ; Vector3d vtV = vtLineDir ; + // Asse cilindro ellittico + Vector3d vtAx( dLongMvLen, dOrtMvLen, 0) ; + vtAx.Normalize() ; + // Trasformazione delle coordinate ptP.ToLoc( CircFrame) ; vtV.ToLoc( CircFrame) ; @@ -700,6 +984,12 @@ VolZmap::IntersLineEllipticalCylinder( const Vector3d& vtLineDir, const Point3d& ptInt1.ToGlob( CircFrame) ; ptInt2.ToGlob( CircFrame) ; + vtN1 = X_AX ; + vtN2 = - X_AX ; + + vtN1.ToGlob( CircFrame) ; + vtN2.ToGlob( CircFrame) ; + return true ; } // Nessuna intersezione @@ -711,10 +1001,15 @@ VolZmap::IntersLineEllipticalCylinder( const Vector3d& vtLineDir, const Point3d& return false ; } + double dEpsLow = ( bTapLow ? - EPS_SMALL : EPS_SMALL) ; + double dEpsUp = ( bTapUp ? EPS_SMALL : - EPS_SMALL) ; + // L'equazione ammette o due soluzioni (eventualmente // coincidenti) oppure nessuna o infinite se la la retta // appartiene alla superficie + Vector3d vtMv( dLongMvLen, dOrtMvLen, 0) ; + if ( nRoot == 2) { ptInt1 = ptP + vdRoots[0] * vtV ; @@ -725,30 +1020,73 @@ VolZmap::IntersLineEllipticalCylinder( const Vector3d& vtLineDir, const Point3d& swap( ptInt1, ptInt2) ; + Vector3d vtTest1 = ( ptInt1 - ORIG) - ( ptInt1 - ORIG) * vtAx * vtAx ; + Vector3d vtTest2 = ( ptInt2 - ORIG) - ( ptInt2 - ORIG) * vtAx * vtAx ; - if ( ptInt1.x < dLongMvLen + EPS_SMALL) { + double dY0_1, dY0_2 ; - if ( ptInt1.x > - EPS_SMALL) { + if ( vtTest1.y > 0) { - if ( ptInt2.x > dLongMvLen) + dY0_1 = ( dSqRad - ptInt1.z * ptInt1.z > 0 ? sqrt( dSqRad - ptInt1.z * ptInt1.z) : 0) ; + } + else { + + dY0_1 = ( dSqRad - ptInt1.z * ptInt1.z > 0 ? - sqrt( dSqRad - ptInt1.z * ptInt1.z) : 0) ; + } + + Vector3d vtCirc1( 0, - dY0_1, - ptInt1.z) ; + Vector3d vtTan1( 0, - vtCirc1.z, vtCirc1.y) ; + Vector3d vtCross1 = vtTan1 ^ vtMv ; + + vtN1 = ( vtCross1 * vtCirc1 > 0 ? vtCross1 : - vtCross1) ; + + if ( vtTest2.y > 0) { + + dY0_2 = ( dSqRad - ptInt2.z * ptInt2.z > 0 ? sqrt( dSqRad - ptInt2.z * ptInt2.z) : 0) ; + } + else { + + dY0_2 = ( dSqRad - ptInt2.z * ptInt2.z > 0 ? - sqrt( dSqRad - ptInt2.z * ptInt2.z) : 0) ; + } + + Vector3d vtCirc2( 0, - dY0_2, - ptInt2.z) ; + Vector3d vtTan2( 0, - vtCirc2.z, vtCirc2.y) ; + Vector3d vtCross2 = vtTan2 ^ vtMv ; + + vtN2 = ( vtCross2 * vtCirc2 > 0 ? vtCross2 : - vtCross2) ; + + + + if ( ptInt1.x < dLongMvLen + dEpsUp) { + + if ( ptInt1.x > + dEpsLow) { + + if ( ptInt2.x > dLongMvLen + dEpsUp) { ptInt2 = ptP + ( ( dLongMvLen - ptP.x) / vtV.x) * vtV ; + vtN2 = - X_AX ; + } } else { - if ( ptInt2.x > dLongMvLen) { + if ( ptInt2.x > dLongMvLen + dEpsUp) { ptInt1 = ptP - ( ptP.x / vtV.x) * vtV ; ptInt2 = ptP + ( ( dLongMvLen - ptP.x) / vtV.x) * vtV ; + vtN1.Set( 1, 0, 0) ; + vtN2.Set( -1, 0, 0) ; + if ( ptInt1.y * ptInt1.y + ptInt1.z * ptInt1.z > dSqRad && ptInt2.y * ptInt2.y + ptInt2.z * ptInt2.z > dSqRad) return false ; } - else if ( ptInt2.x > 0) + else if ( ptInt2.x > dEpsLow) { - ptInt1 = ptP - ( ptP.x / vtV.x) * vtV ; + ptInt1 = ptP - ( ptP.x / vtV.x) * vtV ; + vtN1.Set( 1, 0, 0) ; + } else return false ; } @@ -760,6 +1098,12 @@ VolZmap::IntersLineEllipticalCylinder( const Vector3d& vtLineDir, const Point3d& // griglia ptInt1.ToGlob( CircFrame) ; ptInt2.ToGlob( CircFrame) ; + + vtN1.ToGlob( CircFrame) ; + vtN2.ToGlob( CircFrame) ; + + vtN1.Normalize() ; + vtN2.Normalize() ; } return true ; @@ -769,7 +1113,7 @@ VolZmap::IntersLineEllipticalCylinder( const Vector3d& vtLineDir, const Point3d& bool VolZmap::IntersLineMyPolyhedron( const Point3d& ptLineSt, const Vector3d& vtLineDir, const Frame3d& PolyFrame, double dLenX, double dLenY, double dLenZ, double dDeltaX, - Point3d& ptInt1, Point3d& ptInt2) + Point3d& ptInt1, Point3d& ptInt2, Vector3d& vtN1, Vector3d& vtN2) { double SqIndet = EPS_SMALL * EPS_SMALL ; @@ -793,6 +1137,8 @@ VolZmap::IntersLineMyPolyhedron( const Point3d& ptLineSt, const Vector3d& vtLine Vector3d vtOb( dLenY, - dDeltaX, 0) ; + vtOb.Normalize() ; + Point3d ptI1 = ptP + ( ( ptFacet135.z - ptP.z) / vtV.z) * vtV ; Point3d ptI2 = ptP + ( ( ptFacet246.z - ptP.z) / vtV.z) * vtV ; Point3d ptI3 = ptP + ( ( ptFacet135.y - ptP.y) / vtV.y) * vtV ; @@ -800,6 +1146,11 @@ VolZmap::IntersLineMyPolyhedron( const Point3d& ptLineSt, const Vector3d& vtLine Point3d ptI5 = ptP + ( ( vtFacet5 * vtOb) / ( vtV * vtOb)) * vtV ; Point3d ptI6 = ptP + ( ( vtFacet6 * vtOb) / ( vtV * vtOb)) * vtV ; + if ( abs( vtV.z) < EPS_ZERO && + abs( ptP.z) > dLenZ / 2 - EPS_SMALL) + + return false ; + int nIntNum = 0 ; // Intersezione con la prima faccia @@ -807,6 +1158,7 @@ VolZmap::IntersLineMyPolyhedron( const Point3d& ptLineSt, const Vector3d& vtLine ptI1.x * dLenY >= dDeltaX * ptI1.y && ( ptI1.x - dLenX) * dLenY <= dDeltaX * ptI1.y) { ptInt1 = ptI1 ; + vtN1 = - Z_AX ; ++ nIntNum ; } @@ -817,11 +1169,13 @@ VolZmap::IntersLineMyPolyhedron( const Point3d& ptLineSt, const Vector3d& vtLine if ( nIntNum == 0) { ptInt1 = ptI2 ; + vtN1 = Z_AX ; ++ nIntNum ; } else if ( ( ptInt1 - ptI2).SqLen() > SqIndet) { ptInt2 = ptI2 ; + vtN2 = Z_AX ; ++ nIntNum ; } } @@ -834,11 +1188,13 @@ VolZmap::IntersLineMyPolyhedron( const Point3d& ptLineSt, const Vector3d& vtLine if ( nIntNum == 0) { ptInt1 = ptI3 ; + vtN1 = Y_AX ; ++ nIntNum ; } else if ( ( ptInt1 - ptI3).SqLen() > SqIndet) { ptInt2 = ptI3 ; + vtN2 = Y_AX ; ++ nIntNum ; } } @@ -851,11 +1207,13 @@ VolZmap::IntersLineMyPolyhedron( const Point3d& ptLineSt, const Vector3d& vtLine if ( nIntNum == 0) { ptInt1 = ptI4 ; + vtN1 = - Y_AX ; ++ nIntNum ; } else if ( ( ptInt1 - ptI4).SqLen() > SqIndet) { ptInt2 = ptI4 ; + vtN2 = - Y_AX ; ++ nIntNum ; } } @@ -868,11 +1226,13 @@ VolZmap::IntersLineMyPolyhedron( const Point3d& ptLineSt, const Vector3d& vtLine if ( nIntNum == 0) { ptInt1 = ptI5 ; + vtN1 = vtOb ; ++ nIntNum ; } else if ( ( ptInt1 - ptI5).SqLen() > SqIndet) { ptInt2 = ptI5 ; + vtN2 = vtOb ; ++ nIntNum ; } } @@ -885,11 +1245,13 @@ VolZmap::IntersLineMyPolyhedron( const Point3d& ptLineSt, const Vector3d& vtLine if ( nIntNum == 0) { ptInt1 = ptI6; + vtN1 = - vtOb ; ++ nIntNum ; } else if ( ( ptInt1 - ptI6).SqLen() > SqIndet) { ptInt2 = ptI6; + vtN2 = - vtOb ; ++ nIntNum ; } } @@ -900,6 +1262,9 @@ VolZmap::IntersLineMyPolyhedron( const Point3d& ptLineSt, const Vector3d& vtLine ptInt1.ToGlob( PolyFrame) ; ptInt2.ToGlob( PolyFrame) ; + vtN1.ToGlob( PolyFrame) ; + vtN2.ToGlob( PolyFrame) ; + return true ; } else diff --git a/VolTriZmapCreation.cpp b/VolTriZmapCreation.cpp index dca72ea..970e75b 100644 --- a/VolTriZmapCreation.cpp +++ b/VolTriZmapCreation.cpp @@ -286,8 +286,8 @@ VolZmap::CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double if ( nType == CRVC_IN || nType == CRVC_ON_P || nType == CRVC_ON_M) { // Indici corrispondenti alle coordinate dei punti - int nStartJ = Clamp( int( floor( dt1 * dLengthY / m_dStep + 0.5)), 0, m_nNy[0] - 1) ; // CAMBIATO CON EPS - int nEndJ = Clamp( int( floor( dt2 * dLengthY / m_dStep - 0.5)), 0, m_nNy[0] - 1) ; // CAMBIATO CON EPS + int nStartJ = Clamp( int( floor( dt1 * dLengthY / m_dStep - EPS_SMALL + 0.5)), 0, m_nNy[0] - 1) ; // CAMBIATO CON EPS + int nEndJ = Clamp( int( floor( dt2 * dLengthY / m_dStep + EPS_SMALL - 0.5)), 0, m_nNy[0] - 1) ; // CAMBIATO CON EPS // Ridimensiono e riempio i dexel for ( int j = nStartJ ; j <= nEndJ ; ++ j) { diff --git a/VolTriZmapGraphics.cpp b/VolTriZmapGraphics.cpp index e8b10a7..59182bf 100644 --- a/VolTriZmapGraphics.cpp +++ b/VolTriZmapGraphics.cpp @@ -21,6 +21,7 @@ #include "MC_Tables.h" #include "\EgtDev\Include\EGkIntervals.h" #include "\EgtDev\Include\EgtNumUtils.h" +#include "\EgtDev\Include\EGkStringUtils3d.h" #include "\EgtDev\Extern\Eigen\Core" #include "\EgtDev\Extern\Eigen\SVD" @@ -59,9 +60,8 @@ TestOnNormal( const VectorField CompoVert[], int nCompoElem, int& FeatureType) { int nI, nJ ; double dMinCosTheta = 1.001 ; - double dCosThetaSharp = 0.9 ; + const double dCosThetaSharp = 0.9 ; - // Nota 0-esimo indice è vuoto for ( int i = 0 ; i < nCompoElem ; ++ i) { for ( int j = i + 1 ; j < nCompoElem ; ++ j) { @@ -83,12 +83,9 @@ TestOnNormal( const VectorField CompoVert[], int nCompoElem, int& FeatureType) return false ; } - Vector3d vtI = CompoVert[nI].vtNorm ; - Vector3d vtJ = CompoVert[nJ].vtNorm ; - Vector3d vtK = vtI ^ vtJ ; + Vector3d vtK = CompoVert[nI].vtNorm ^ CompoVert[nJ].vtNorm ; - double dMaxAbsCosPhi = 0 ; - double dCosPhiCorner = 0.7 ; + const double dCosPhiCorner = 0.5 ; for ( int i = 0 ; i < nCompoElem ; ++ i) { @@ -96,54 +93,201 @@ TestOnNormal( const VectorField CompoVert[], int nCompoElem, int& FeatureType) if ( dAbsCurrentCos > dCosPhiCorner) { - // nI = i ; - dMaxAbsCosPhi = dAbsCurrentCos ; + FeatureType = Corner ; + return true ; } } - if ( dMaxAbsCosPhi <= dCosPhiCorner) - FeatureType = Edge ; - else - FeatureType = Corner ; - + FeatureType = Edge ; + return true ; } +//---------------------------------------------------------------------------- +bool +TestOnSlice( const VectorField CompoVert[], int nLimArrey, + int i, + int j, + int k, double dStep) +{ + // Coordinate dei piani + double dX0 = ( i + 0.5) * dStep ; + double dX1 = ( i + 1.5) * dStep ; + double dY0 = ( j + 0.5) * dStep ; + double dY1 = ( j + 1.5) * dStep ; + double dZ0 = ( k + 0.5) * dStep ; + double dZ1 = ( k + 1.5) * dStep ; + + + // Analisi faccia 1 + int nCount = 0 ; + double dDelta = abs( CompoVert[0].ptInt.x - dX0) ; + + while ( dDelta < EPS_SMALL && nCount < nLimArrey) { + + ++ nCount ; + dDelta = abs( CompoVert[nCount].ptInt.x - dX0) ; + } + + if ( nCount == nLimArrey) + return false ; + + // Analisi faccia 2 + nCount = 0 ; + dDelta = abs( CompoVert[0].ptInt.x - dX1) ; + + while ( dDelta < EPS_SMALL && nCount < nLimArrey) { + + ++ nCount ; + dDelta = abs( CompoVert[nCount].ptInt.x - dX1) ; + } + + if ( nCount == nLimArrey) + return false ; + + // Analisi faccia 3 + nCount = 0 ; + dDelta = abs( CompoVert[0].ptInt.y - dY0) ; + + while ( dDelta < EPS_SMALL && nCount < nLimArrey) { + + ++ nCount ; + dDelta = abs( CompoVert[nCount].ptInt.y - dY0) ; + } + + if ( nCount == nLimArrey) + return false ; + + // Analisi faccia 4 + nCount = 0 ; + dDelta = abs( CompoVert[0].ptInt.y - dY1) ; + + while ( dDelta < EPS_SMALL && nCount < nLimArrey) { + + ++ nCount ; + dDelta = abs( CompoVert[nCount].ptInt.y - dY1) ; + } + + if ( nCount == nLimArrey) + return false ; + + // Analisi faccia 5 + nCount = 0 ; + dDelta = abs( CompoVert[0].ptInt.z - dZ0) ; + + while ( dDelta < EPS_SMALL && nCount < nLimArrey) { + + ++ nCount ; + dDelta = abs( CompoVert[nCount].ptInt.z - dZ0) ; + } + + if ( nCount == nLimArrey) + return false ; + + // Analisi faccia 6 + nCount = 0 ; + dDelta = abs( CompoVert[0].ptInt.z - dZ1) ; + + while ( dDelta < EPS_SMALL && nCount < nLimArrey) { + + ++ nCount ; + dDelta = abs( CompoVert[nCount].ptInt.z - dZ1) ; + } + + if ( nCount == nLimArrey) + return false ; + + return true ; +} + // ------------------------- VISUALIZZAZIONE -------------------------------------------------------------------------------------- //---------------------------------------------------------------------------- bool VolZmap::GetDexelLines( int nDir, int nPos1, int nPos2, POLYLINELIST& lstPL) const { - // Controllo l'ammissibilità della griglia - if ( nDir < 0 || nDir > 2) - return false ; + // Se richiesti spilloni ( 0 <= nDir < 3) + if ( nDir < 3) { - // Verifiche sugli indici - if ( nPos1 < 0 || nPos1 >= int( m_nNx[nDir]) || nPos2 < 0 || nPos2 >= int( m_nNy[nDir])) - return false ; + // Controllo l'ammissibilità della griglia + if ( nDir < 0 || nDir > 2) + return false ; - int nPos = nPos1 + nPos2 * m_nNx[nDir] ; + // Verifiche sugli indici + if ( nPos1 < 0 || nPos1 >= int( m_nNx[nDir]) || nPos2 < 0 || nPos2 >= int( m_nNy[nDir])) + return false ; - if ( nPos < 0 || nPos >= int( m_Values[nDir].size())) - return false ; + int nPos = nPos1 + nPos2 * m_nNx[nDir] ; - // Calcolo coordinate punto - double dX = m_dStep * ( 0.5 + nPos1) ; - double dY = m_dStep * ( 0.5 + nPos2) ; + if ( nPos < 0 || nPos >= int( m_Values[nDir].size())) + return false ; - // Determino il punto di partensa sulla griglia - Point3d ptP = m_MapFrame[nDir].Orig() + dX * m_MapFrame[nDir].VersX() + dY * m_MapFrame[nDir].VersY() ; + // Calcolo coordinate punto + double dX = m_dStep * ( 0.5 + nPos1) ; + double dY = m_dStep * ( 0.5 + nPos2) ; - // Creo le polilinee - for ( int j = 1 ; j < int( m_Values[nDir][nPos].size()) ; j += 2) { - // aggiungo polilinea a lista - lstPL.emplace_back() ; - // inserisco punti estremi - lstPL.back().AddUPoint( 0, ptP + m_Values[nDir][nPos][j-1].dZVal * m_MapFrame[nDir].VersZ()) ; - lstPL.back().AddUPoint( 1, ptP + m_Values[nDir][nPos][j].dZVal * m_MapFrame[nDir].VersZ()) ; + // Determino il punto di partenza sulla griglia + Point3d ptP = m_MapFrame[nDir].Orig() + dX * m_MapFrame[nDir].VersX() + dY * m_MapFrame[nDir].VersY() ; + + // Creo le polilinee + for ( int j = 1 ; j < int( m_Values[nDir][nPos].size()) ; j += 2) { + // aggiungo polilinea a lista + lstPL.emplace_back() ; + // inserisco punti estremi + lstPL.back().AddUPoint( 0, ptP + m_Values[nDir][nPos][j-1].dZVal * m_MapFrame[nDir].VersZ()) ; + lstPL.back().AddUPoint( 1, ptP + m_Values[nDir][nPos][j].dZVal * m_MapFrame[nDir].VersZ()) ; + } + return true ; + } + // altrimenti richieste normali ( 3 <= nDir < 6) + else { + + // riporto a indice griglia + nDir -= 3 ; + + // Controllo l'ammissibilità della griglia + if ( nDir < 0 || nDir > 2) + return false ; + + // Verifiche sugli indici + if ( nPos1 < 0 || nPos1 >= int( m_nNx[nDir]) || nPos2 < 0 || nPos2 >= int( m_nNy[nDir])) + return false ; + + int nPos = nPos1 + nPos2 * m_nNx[nDir] ; + + if ( nPos < 0 || nPos >= int( m_Values[nDir].size())) + return false ; + + // Calcolo coordinate punto + double dX = m_dStep * ( 0.5 + nPos1) ; + double dY = m_dStep * ( 0.5 + nPos2) ; + + // Determino il punto di partenza sulla griglia + Point3d ptP = m_MapFrame[nDir].Orig() + dX * m_MapFrame[nDir].VersX() + dY * m_MapFrame[nDir].VersY() ; + + // Creo le polilinee + for ( int j = 1 ; j < int( m_Values[nDir][nPos].size()) ; j += 2) { + // aggiungo polilinea a lista + lstPL.emplace_back() ; + // calcolo e inserisco punto inizio spillone + Point3d ptQ = ptP + m_Values[nDir][nPos][j-1].dZVal * m_MapFrame[nDir].VersZ() ; + lstPL.back().AddUPoint( 0, ptQ) ; + // calcolo e inserisco punto su termine sua normale + Vector3d vtV = m_Values[nDir][nPos][j-1].vtN ; + vtV.ToGlob( m_MapFrame[0]) ; + lstPL.back().AddUPoint( 1, ptQ + vtV * m_dStep / 4) ; + // aggiungo polilinea a lista + lstPL.emplace_back() ; + // calcolo e inserisco punto fine spillone + Point3d ptR = ptP + m_Values[nDir][nPos][j].dZVal * m_MapFrame[nDir].VersZ() ; + lstPL.back().AddUPoint( 0, ptR) ; + // calcolo e inserisco punto su termine sua normale + Vector3d vtW = m_Values[nDir][nPos][j].vtN ; + vtW.ToGlob( m_MapFrame[0]) ; + lstPL.back().AddUPoint( 1, ptR + vtW * m_dStep / 4) ; + } + return true ; } - return true ; } //---------------------------------------------------------------------------- @@ -179,8 +323,7 @@ VolZmap::GetAllTriangles( TRIA3DLIST& lstTria) const // for ( int j = 0 ; j < int( triHold[i].vecTria.size()) ; ++ j) // lstTria.emplace_back( triHold[i].vecTria[j]) ; - //} - + //} else MarchingCubes( lstTria) ; @@ -190,7 +333,12 @@ VolZmap::GetAllTriangles( TRIA3DLIST& lstTria) const //---------------------------------------------------------------------------- bool VolZmap::GetBlockTriangles( int nBlock, TRIA3DLIST& lstTria) const -{ +{ + // Controllo sulla validità del blocco + if ( nBlock < 0 || nBlock >= int( m_BlockToUpdate.size())) + return false ; + + // Caso di singola mappa if ( m_nMapNum == 1) { const int MAX_DIM_CHUNK = 128 ; @@ -218,12 +366,81 @@ VolZmap::GetBlockTriangles( int nBlock, TRIA3DLIST& lstTria) const } } } - else - - //ExtMarchingCubes( nBlock, lstTria, triHold) ; + // Caso con tre mappe + else { - MarchingCubes( nBlock, lstTria) ; - + // Calcolo i limiti sugli indici dei voxel del blocco + // Vettore indici i,j,k del blocco + int nIJK[3] ; + GetBlockIJK( nIJK, nBlock) ; + // Vettore limiti sugli indici dei voxel del blocco + int LimitIndexes[6] ; + GetBlockLimitsIJK( nIJK, LimitIndexes) ; + + TriHolder triHold ; + + ExtMarchingCubes( LimitIndexes, lstTria, triHold) ; + FlipEdges( triHold) ; + + // Valuto se esistono voxel contenenti sharp feature + if ( ! triHold.size()) + + ; + + else { + + // Cerco fra i voxel con sharp feature quelli + // di frontiera e quelli ad essi adiacenti. + + // Ciclo sui voxel con sharp feature + for ( size_t t = 0 ; t < triHold.size() ; ++ t) { + + // Voxel di frontiera + if ( triHold[t].i == LimitIndexes[0] || triHold[t].i == LimitIndexes[1] - 1 || + triHold[t].j == LimitIndexes[2] || triHold[t].j == LimitIndexes[3] - 1 || + triHold[t].k == LimitIndexes[4] || triHold[t].k == LimitIndexes[5] - 1) { + + // Ciclo sui voxel adiacenti + for ( int nI = triHold[t].i - 1 ; nI <= triHold[t].i + 1 ; ++ nI) { + for ( int nJ = triHold[t].j - 1 ; nJ <= triHold[t].j + 1 ; ++ nJ) { + for ( int nK = triHold[t].k - 1 ; nK <= triHold[t].k + 1 ; ++ nK) { + + // Voxel adiacente appartenente allo + // Zmap e non appartenente al blocco + if ( ( nI >= -1 && nI <= int( m_nNx[0]) - 1 && + nJ >= -1 && nJ <= int( m_nNy[0]) - 1 && + nK >= -1 && nK <= int( m_nNy[1]) - 1) && + ! ( nI >= LimitIndexes[0] && nI < LimitIndexes[1] && + nJ >= LimitIndexes[2] && nJ < LimitIndexes[3] && + nK >= LimitIndexes[4] && nK < LimitIndexes[5])) { + + std::vector AdjVoxel ; + + AdjVoxel.emplace_back( nI) ; + AdjVoxel.emplace_back( nJ) ; + AdjVoxel.emplace_back( nK) ; + + TriHolder NewTriHold ; + + ExtMarchingCubes( AdjVoxel, NewTriHold) ; + + if ( NewTriHold.size()) + FlipEdgesLocalFlipEdges( triHold[t], NewTriHold[0]) ; + } + } + } + } + } + } + } + + for ( size_t t1 = 0 ; t1 < triHold.size() ; ++ t1) + for ( size_t t2 = 0 ; t2 < triHold[t1].vCompoTria.size() ; ++ t2) + for ( size_t t3 = 0 ; t3 < triHold[t1].vCompoTria[t2].size() ; ++ t3) + lstTria.emplace_back( triHold[t1].vCompoTria[t2][t3]) ; + + } + m_BlockToUpdate[nBlock] = false ; return true ; @@ -541,30 +758,27 @@ VolZmap::MarchingCubes( int nBlock, TRIA3DLIST& lstTria) const int nKBlock = ( nBlock / int( m_nFracLin[0] * m_nFracLin[1])) ; // Calcolo limiti per l'indice i - int nStartI = nIBlock * int( m_nDexNumPBlock) - 1 ; //( nIBlock > 0 ? nIBlock * int( m_nDexNumPBlock) : - 1) ; + int nStartI = nIBlock * int( m_nDexNumPBlock) - 1 ; int nEndI = ( nIBlock + 1 == int( m_nFracLin[0]) ? int( m_nNx[0]) : ( nIBlock + 1) * int( m_nDexNumPBlock)) ; // Calcolo limiti per l'indice j - int nStartJ = nJBlock * int( m_nDexNumPBlock) - 1 ; //( nJBlock > 0 ? nJBlock * int( m_nDexNumPBlock) : - 1) ; + int nStartJ = nJBlock * int( m_nDexNumPBlock) - 1 ; int nEndJ = ( nJBlock + 1 == int( m_nFracLin[1]) ? int( m_nNy[0]) : ( nJBlock + 1) * int( m_nDexNumPBlock)) ; // Calcolo limiti per l'indice k - int nStartK = nKBlock * int( m_nDexNumPBlock) - 1 ; //( nKBlock > 0 ? nKBlock * int( m_nDexNumPBlock) : - 1) ; + int nStartK = nKBlock * int( m_nDexNumPBlock) - 1 ; int nEndK = ( nKBlock + 1 == int( m_nFracLin[2]) ? int( m_nNy[1]) : ( nKBlock + 1) * int( m_nDexNumPBlock)) ; - // Ciclo su tutti i voxel dello Zmap for ( int i = nStartI ; i < nEndI ; ++ i) { for ( int j = nStartJ ; j < nEndJ ; ++ j) { for ( int k = nStartK ; k < nEndK ; ++ k) { - // Indici i,j,k dei vertici int IndexCorner[8][3] = { - { i, j, k}, { i + 1, j, k}, { i + 1, j + 1, k}, @@ -575,34 +789,24 @@ VolZmap::MarchingCubes( int nBlock, TRIA3DLIST& lstTria) const { i, j + 1, k + 1} } ; - - int nIndex = 0 ; - // Classificazione dei vertici: interni o esterni al materiale + int nIndex = 0 ; if ( IsThereMat( i, j, k)) nIndex |= ( 1 << 0) ; - if ( IsThereMat( i + 1, j, k)) nIndex |= ( 1 << 1) ; - if ( IsThereMat( i + 1, j + 1, k)) nIndex |= ( 1 << 2) ; - if ( IsThereMat( i, j + 1, k)) nIndex |= ( 1 << 3) ; - if ( IsThereMat( i, j, k + 1)) nIndex |= ( 1 << 4) ; - if ( IsThereMat( i + 1, j, k + 1)) nIndex |= ( 1 << 5) ; - if ( IsThereMat( i + 1, j + 1, k + 1)) nIndex |= ( 1 << 6) ; - if ( IsThereMat( i, j + 1, k + 1)) nIndex |= ( 1 << 7) ; - // Se vi è qualche intersezione fra segmenti e superficie // continuo altrimenti passo al prossimo voxel @@ -610,17 +814,14 @@ VolZmap::MarchingCubes( int nBlock, TRIA3DLIST& lstTria) const continue ; static int intersections[12][2] = { - { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 0 }, { 4, 5 }, { 5, 6 }, { 6, 7 }, { 7, 4 }, { 0, 4 }, { 1, 5 }, { 2, 6 }, { 3, 7 } } ; - Point3d ptIntPoint[12] ; - // Ciclo sui segmenti + Point3d ptIntPoint[12] ; for ( int EdgeIndex = 0 ; EdgeIndex < 12 ; ++ EdgeIndex) { - // Se il segmento non attraversa la superficie - // passo al successivo + // Se il segmento non attraversa la superficie passo al successivo if ( ! ( EdgeTable[nIndex] & ( 1 << EdgeIndex))) continue ; @@ -664,44 +865,17 @@ VolZmap::MarchingCubes( int nBlock, TRIA3DLIST& lstTria) const //---------------------------------------------------------------------------- bool -VolZmap::ExtMarchingCubes( int nBlock, TRIA3DLIST& lstTria, TriHolder& triHold) const +VolZmap::ExtMarchingCubes( const int nLimits[], TRIA3DLIST& lstTria, TriHolder& triHold) const { - - if ( nBlock < 0 || nBlock >= int( m_BlockToUpdate.size())) - return false ; - Point3d ptMapOrig = m_MapFrame[0].Orig() ; - // Calcolo posizione del blocco nel reticolo - int nIBlock = ( nBlock % int( m_nFracLin[0] * m_nFracLin[1])) % int( m_nFracLin[0]) ; - int nJBlock = ( nBlock % int( m_nFracLin[0] * m_nFracLin[1])) / int( m_nFracLin[0]) ; - int nKBlock = ( nBlock / int( m_nFracLin[0] * m_nFracLin[1])) ; - - // Calcolo limiti per l'indice i - int nStartI = nIBlock * int( m_nDexNumPBlock) - 1 ; - int nEndI = ( nIBlock + 1 == int( m_nFracLin[0]) ? - int( m_nNx[0]) : ( nIBlock + 1) * int( m_nDexNumPBlock)) ; - - // Calcolo limiti per l'indice j - int nStartJ = nJBlock * int( m_nDexNumPBlock) - 1 ; - int nEndJ = ( nJBlock + 1 == int( m_nFracLin[1]) ? - int( m_nNy[0]) : ( nJBlock + 1) * int( m_nDexNumPBlock)) ; - - // Calcolo limiti per l'indice k - int nStartK = nKBlock * int( m_nDexNumPBlock) - 1 ; - int nEndK = ( nKBlock + 1 == int( m_nFracLin[2]) ? - int( m_nNy[1]) : ( nKBlock + 1) * int( m_nDexNumPBlock)) ; - - // Ciclo su tutti i voxel dello Zmap - for ( int i = nStartI ; i < nEndI ; ++ i) { - for ( int j = nStartJ ; j < nEndJ ; ++ j) { - for ( int k = nStartK ; k < nEndK ; ++ k) { + for ( int i = nLimits[0] ; i < nLimits[1] ; ++ i) { + for ( int j = nLimits[2] ; j < nLimits[3] ; ++ j) { + for ( int k = nLimits[4] ; k < nLimits[5] ; ++ k) { - // Indici i,j,k dei vertici int IndexCorner[8][3] = { - { i, j, k}, { i + 1, j, k}, { i + 1, j + 1, k}, @@ -711,29 +885,35 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DLIST& lstTria, TriHolder& triHold) { i + 1, j + 1, k + 1}, { i, j + 1, k + 1} } ; - - + int nIndex = 0 ; // Classificazione dei vertici: interni o esterni al materiale - if ( IsThereMat( i, j, k)) nIndex |= ( 1 << 0) ; - if ( IsThereMat( i + 1, j, k)) nIndex |= ( 1 << 1) ; - if ( IsThereMat( i + 1, j + 1, k)) nIndex |= ( 1 << 2) ; - if ( IsThereMat( i, j + 1, k)) nIndex |= ( 1 << 3) ; - if ( IsThereMat( i, j, k + 1)) nIndex |= ( 1 << 4) ; - if ( IsThereMat( i + 1, j, k + 1)) nIndex |= ( 1 << 5) ; - if ( IsThereMat( i + 1, j + 1, k + 1)) nIndex |= ( 1 << 6) ; - if ( IsThereMat( i, j + 1, k + 1)) nIndex |= ( 1 << 7) ; + if ( IsThereMat( i, j, k)) + nIndex |= ( 1 << 0) ; + if ( IsThereMat( i + 1, j, k)) + nIndex |= ( 1 << 1) ; + if ( IsThereMat( i + 1, j + 1, k)) + nIndex |= ( 1 << 2) ; + if ( IsThereMat( i, j + 1, k)) + nIndex |= ( 1 << 3) ; + if ( IsThereMat( i, j, k + 1)) + nIndex |= ( 1 << 4) ; + if ( IsThereMat( i + 1, j, k + 1)) + nIndex |= ( 1 << 5) ; + if ( IsThereMat( i + 1, j + 1, k + 1)) + nIndex |= ( 1 << 6) ; + if ( IsThereMat( i, j + 1, k + 1)) + nIndex |= ( 1 << 7) ; // Se vi è qualche intersezione fra segmenti e superficie - // continuo altrimenti passo al prossimo voxel + // continuo altrimenti passo al prossimo voxel. if ( EdgeTable[nIndex] == 0) continue ; static int intersections[12][2] = { - - { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 0 }, { 4, 5 }, { 5, 6 }, - { 6, 7 }, { 7, 4 }, { 0, 4 }, { 1, 5 }, { 2, 6 }, { 3, 7 } + { 0, 1 }, { 1, 2 }, { 3, 2 }, { 0, 3 }, { 4, 5 }, { 5, 6 }, + { 7, 6 }, { 4, 7 }, { 0, 4 }, { 1, 5 }, { 2, 6 }, { 3, 7 } } ; // Arrey di strutture punto di intersezione @@ -742,18 +922,19 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DLIST& lstTria, TriHolder& triHold) // Ciclo sui segmenti for ( int EdgeIndex = 0 ; EdgeIndex < 12 ; ++ EdgeIndex) { - // Se il segmento non attraversa la superficie - // passo al successivo + // Se il segmento non attraversa la superficie passo al successivo if ( ! ( EdgeTable[nIndex] & ( 1 << EdgeIndex))) continue ; int n1 = intersections[EdgeIndex][0] ; - int n2 = intersections[EdgeIndex][1] ; + int n2 = intersections[EdgeIndex][1] ; - // Determino con precisione il punto di intersezione sullo spigolo - IntersPos( IndexCorner[n1], IndexCorner[n2], - VecField[EdgeIndex].ptInt, - VecField[EdgeIndex].vtNorm) ; + bool bN1 = ( ( nIndex & ( 1 << n1)) != 0) ; + + // Determino con precisione il punto di intersezione sullo spigolo. + NewIntersPos( IndexCorner[n1], IndexCorner[n2], bN1, + VecField[EdgeIndex].ptInt, + VecField[EdgeIndex].vtNorm) ; VecField[EdgeIndex].ptInt.ToGlob( m_MapFrame[0]) ; VecField[EdgeIndex].vtNorm.ToGlob( m_MapFrame[0]) ; @@ -770,6 +951,9 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DLIST& lstTria, TriHolder& triHold) // della seconda e così via. int nTableOffset = nComponents ; + // Numero di feature nel voxel: al più vi è una feature per componente connessa + int nFeatureInVoxel = 0 ; + // Ciclo sulle componenti for ( int nCompCount = 1 ; nCompCount <= nComponents ; ++ nCompCount) { @@ -781,122 +965,309 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DLIST& lstTria, TriHolder& triHold) // Riempio il vettore for ( int nVertCount = 0 ; nVertCount < nVertComp ; ++ nVertCount) - // Nota che il primo elemento dell'arrey - // (0-esimo) non viene iniziallizzato + // Nota che il primo elemento dell'array (0-esimo) non viene inizializzato CompoVert[nVertCount] = VecField[TriangleTableEn[nIndex][1][nVertCount + nTableOffset + 1]] ; int nFeatureType ; - // Valuto le relazioni reciproche fra le normali - bool bExt = TestOnNormal( CompoVert, nVertComp, nFeatureType) ; + // Valuto le relazioni reciproche fra le normali e + // se i punti sono su un piano di griglia. + bool bNormal = TestOnNormal( CompoVert, nVertComp, nFeatureType) ; + bool bExt = bNormal ; // Extended MC if ( bExt) { - - // Ridimensiono il vettore che contiene i - triHold.resize( triHold.size() + 1) ; - - int nCurrent = int( triHold.size()) - 1 ; - - triHold[nCurrent].i = i ; - triHold[nCurrent].j = j ; - triHold[nCurrent].k = k ; - + + // Passo al sistema di riferimento del baricentro Point3d ptGravityCenter( 0, 0, 0) ; - for ( int i = 0 ; i < nVertComp ; ++ i) - - ptGravityCenter += CompoVert[i].ptInt ; + for ( int ni = 0 ; ni < nVertComp ; ++ ni) + ptGravityCenter += CompoVert[ni].ptInt ; ptGravityCenter /= nVertComp ; - Vector3d vtO = ptGravityCenter - ORIG ; - + Vector3d vtO = ptGravityCenter - ORIG ; + Point3d ptTrasf[12] ; - for ( int i = 0 ; i < nVertComp ; ++ i) - - ptTrasf[i] = CompoVert[i].ptInt - vtO ; - + for ( int ni = 0 ; ni < nVertComp ; ++ ni) + ptTrasf[ni] = CompoVert[ni].ptInt - vtO ; + + // Preparo le matrici per il sistema typedef Eigen::Matrix dSystemMatrix ; typedef Eigen::Matrix dSystemVector ; - - dSystemMatrix dMatrixN ; - dSystemVector dKnownVector ; - dSystemVector dUnknownVector ; - - dMatrixN.resize( nVertComp, 3) ; - dKnownVector.resize( nVertComp, 1) ; - - for ( int i = 0 ; i < nVertComp ; ++ i) { - - dMatrixN( i, 0) = CompoVert[i].vtNorm.x ; - dMatrixN( i, 1) = CompoVert[i].vtNorm.y ; - dMatrixN( i, 2) = CompoVert[i].vtNorm.z ; - - dKnownVector( i) = CompoVert[i].vtNorm * ( ptTrasf[i] - ORIG) ; - } - typedef Eigen::JacobiSVD DecomposerSVD ; -#define ComputeU Eigen::ComputeThinU -#define ComputeV Eigen::ComputeThinV + dSystemMatrix dMatrixN, dMatrixU, dMatrixV ; + dSystemVector dKnownVector, dUnknownVector, dSingularValue ; + + dMatrixN.resize( nVertComp, 3) ; + dKnownVector.resize( nVertComp, 1) ; + dUnknownVector.resize( 3, 1) ; + + // Studio del caso 4 punti su un piano + int nEqual = 0 ; + int nPosD ; + Vector3d vtD, vtE ; - DecomposerSVD svd( dMatrixN, ComputeU | ComputeV) ; + if ( nVertComp == 4 && nFeatureType == 2) { + int nPosEq ; + for ( int ni = 0 ; ni < 2 ; ++ ni) { + for ( int nj = ni + 1 ; nj < nVertComp ; ++ nj) { -#undef ComputeU -#undef ComputeV - - dSystemVector dSingularValue = svd.singularValues( ) ; - - if ( nFeatureType == 2) { - - int nIMin = 0 ; - int nRank = min( nVertComp, 3) ; - double dMinVal = DBL_MAX ; - - for ( int i = 0 ; i < nRank ; ++ i) { + if ( AreSameVectorApprox( CompoVert[ni].vtNorm, + CompoVert[nj].vtNorm)) { + nEqual ++ ; + nPosEq = ni ; + } + } + if ( nEqual == 2) + break ; + else + nEqual = 0 ; + } + if ( nEqual == 2) { - if ( dSingularValue( i) < dMinVal) { - - nIMin = i ; - dMinVal = dSingularValue( i) ; + for ( int ni = 0 ; ni < nVertComp ; ++ ni) + + if ( ! AreSameVectorApprox( CompoVert[ni].vtNorm, + CompoVert[nPosEq].vtNorm)) { + nPosD = ni ; + vtD = CompoVert[ni].vtNorm ; + vtE = CompoVert[nPosEq].vtNorm ; + } + } + } + + double dDot = abs( ( CompoVert[1].ptInt - CompoVert[0].ptInt) * + ( ( CompoVert[2].ptInt - CompoVert[1].ptInt) ^ + ( CompoVert[3].ptInt - CompoVert[2].ptInt))) ; + + // Caso quattro punti su un piano + if ( nVertComp == 4 && nEqual == 2 && dDot < EPS_SMALL) { + + for ( int ni = 0 ; ni < nVertComp ; ++ ni) { + if ( ni != nPosD) { + dMatrixN( ni, 0) = CompoVert[ni].vtNorm.x ; + dMatrixN( ni, 1) = CompoVert[ni].vtNorm.y ; + dMatrixN( ni, 2) = CompoVert[ni].vtNorm.z ; + dKnownVector( ni) = CompoVert[ni].vtNorm * ( ptTrasf[ni] - ORIG) ; + } + else { + dMatrixN( ni, 0) = vtE.x ; + dMatrixN( ni, 1) = vtE.y ; + dMatrixN( ni, 2) = vtE.z ; + dKnownVector( ni) = vtE * ( ptTrasf[ni] - ORIG) ; } } + } + // caso generale + else { + for ( int ni = 0 ; ni < nVertComp ; ++ ni) { + dMatrixN( ni, 0) = CompoVert[ni].vtNorm.x ; + dMatrixN( ni, 1) = CompoVert[ni].vtNorm.y ; + dMatrixN( ni, 2) = CompoVert[ni].vtNorm.z ; + dKnownVector( ni) = CompoVert[ni].vtNorm * ( ptTrasf[ni] - ORIG) ; + } + } + + DecomposerSVD svd( dMatrixN, Eigen::ComputeThinU | Eigen::ComputeThinV) ; - dSingularValue( nIMin) = 0 ; + dMatrixU = svd.matrixU() ; + dMatrixV = svd.matrixV() ; + dSingularValue = svd.singularValues() ; + + double s0 = dSingularValue( 0) ; + double s1 = dSingularValue( 1) ; + double s2 = dSingularValue( 2) ; + + if ( nFeatureType == 2 ) + dSingularValue( 2) = 0 ; + + // Back substitution: risolvo il sistema USV*x = b + // Calcolo U^T b + double vTemp[3] ; + + for ( int ni = 0 ; ni < 3 ; ++ ni) { + + double s = 0 ; + + if ( abs( dSingularValue( ni)) > EPS_SMALL) { + + for ( int nj = 0 ; nj < nVertComp ; ++ nj) + s += dMatrixU( nj, ni) * dKnownVector( nj) ; + + s /= dSingularValue( ni) ; + } + vTemp[ni] = s ; } - - dUnknownVector = svd.solve( dKnownVector) ; + // Moltiplico per V + for ( int ni = 0 ; ni < 3 ; ++ ni) { + + double s = 0 ; + + for ( int nj = 0 ; nj < 3 ; ++ nj) + s += dMatrixV( ni, nj) * vTemp[nj] ; + + dUnknownVector( ni) = s ; + } + + // Limito la feature entro una distanza di 3 + // volte la diagonale del voxel dal baricentro. + Vector3d vtFeature( dUnknownVector( 0), + dUnknownVector( 1), + dUnknownVector( 2)) ; + + double dDistFeature = vtFeature.Len() ; + + const double dMaxDist = sqrt( 3) * m_dStep ; + + if ( dDistFeature > dMaxDist) { + + // Costruzione dei triangoli + for ( int TriIndex = 0 ; TriangleTableEn[nIndex][0][TriIndex] != - 1 ; TriIndex += 3) { + + // Costruzione triangolo + int i0 = TriangleTableEn[nIndex][0][TriIndex + 2] ; + int i1 = TriangleTableEn[nIndex][0][TriIndex + 1] ; + int i2 = TriangleTableEn[nIndex][0][TriIndex] ; + + Triangle3d CurrentTriangle ; + + // Il triangolo è pronto + CurrentTriangle.Set( VecField[i0].ptInt, VecField[i1].ptInt, VecField[i2].ptInt) ; + CurrentTriangle.Validate( true) ; + + // Se il triangolo non è degenere lo aggiungo alla lista + if ( ! ( AreSamePointApprox( CurrentTriangle.GetP( 0), CurrentTriangle.GetP( 1)) || + AreSamePointApprox( CurrentTriangle.GetP( 1), CurrentTriangle.GetP( 2)) || + AreSamePointApprox( CurrentTriangle.GetP( 2), CurrentTriangle.GetP( 0)))) + lstTria.emplace_back( CurrentTriangle) ; + } + + continue ; + } + + // Esprimo la soluzione nel sistema di riferimento dello z-map. Point3d ptSol( dUnknownVector( 0) + vtO.x, dUnknownVector( 1) + vtO.y, dUnknownVector( 2) + vtO.z) ; - for ( int i = 0 ; i < nVertComp ; ++ i) - - ptTrasf[i] = ptTrasf[i] + vtO ; - //ptSol += vtO ; - Triangle3d CurrentTriangle ; + TRIA3DVECTOR triContainer ; - for ( int i = 0 ; i < nVertComp - 1 ; ++ i) { + bool bInvNormal = false ; - // Il triangolo è pronto - CurrentTriangle.Set( ptSol, CompoVert[i+1].ptInt, CompoVert[i].ptInt) ; + for ( int ni = 0 ; ni < nVertComp ; ++ ni) { + + // Il triangolo è pronto + int nj = ( ni + 1 < nVertComp) ? ni + 1 : 0 ; + CurrentTriangle.Set( ptSol, CompoVert[nj].ptInt, CompoVert[ni].ptInt) ; CurrentTriangle.Validate( true) ; + + // Test sulla degenerazione + if ( CurrentTriangle.GetArea() < EPS_SMALL) + continue ; + + // Controllo sull'inversione delle normali + if ( CurrentTriangle.GetN() * CompoVert[nj].vtNorm < - 0.7 || + CurrentTriangle.GetN() * CompoVert[ni].vtNorm < - 0.7) { + //string sInfo ; + //sInfo = "TriaN=" + ToString( CurrentTriangle.GetN()) + + // "VertJ=" + ToString( CompoVert[nj].vtNorm) + + // "VertI=" + ToString( CompoVert[ni].vtNorm) ; + //LOG_INFO( GetEGkLogger(), sInfo.c_str()) + //bInvNormal = true ; + } - // Aggiungo triangolo - triHold[nCurrent].vecTria.emplace_back( CurrentTriangle) ; + // Aggiungo triangolo al vettore temporaneo + triContainer.emplace_back( CurrentTriangle) ; } - // Ultimo triangolo - CurrentTriangle.Set( ptSol, CompoVert[0].ptInt, CompoVert[nVertComp - 1].ptInt) ; - CurrentTriangle.Validate( true) ; + // Valuto normali + int nContSize = triContainer.size() ; - // Aggiungo ultimo triangolo - triHold[nCurrent].vecTria.emplace_back( CurrentTriangle) ; - triHold[nCurrent].ptVert = ptSol ; + bool bPlane = true ; + + for ( int ni = 0 ; ni < nContSize - 1 ; ++ ni) { + for ( int nj = ni + 1 ; nj < nContSize ; ++ nj) { + + Vector3d vtI = triContainer[ni].GetN() ; + Vector3d vtJ = triContainer[nj].GetN() ; + + if ( ! AreSameVectorApprox( vtI, vtJ)) { + bPlane = false ; + break ; + } + } + } + + if ( ! ( bPlane || bInvNormal)) { + + // Aggiorno il numero di feature. + ++ nFeatureInVoxel ; + + // Se siamo in presenza della prima feature del + // voxel, ridimensiono il vettore che contiene + // la struttura dati del voxel. + if ( nFeatureInVoxel == 1) { + + triHold.resize( triHold.size() + 1) ; + + // Questi dati dipendono solo dal voxel, + // quindi sono validi validi per tutte le + // componenti che vi appartengono. + int nCurrent = int( triHold.size()) - 1 ; + + triHold[nCurrent].i = i ; + triHold[nCurrent].j = j ; + triHold[nCurrent].k = k ; + } + + // Indice che identifica la posizione del voxel + // nel vector. + int nCurrent = int( triHold.size()) - 1 ; + + + // Aggiungo vertice della componente + // connessa alla lista dei vertici. + triHold[nCurrent].ptCompoVert.emplace_back( ptSol) ; + + int nOldFeatureNum = triHold[nCurrent].vCompoTria.size() ; + int nNewFeatureNum = nOldFeatureNum + 1 ; + + // Aggiungo una componente per il vettore + // dei triangoli della componente connessa. + triHold[nCurrent].vCompoTria.resize( nNewFeatureNum) ; + + for ( int ni = 0 ; ni < nContSize ; ++ ni) + + triHold[nCurrent].vCompoTria[nOldFeatureNum].emplace_back( triContainer[ni]) ; + } + + else { + // Costruzione dei triangoli + for ( int TriIndex = 0 ; TriangleTableEn[nIndex][0][TriIndex] != - 1 ; TriIndex += 3) { + + // Costruzione triangolo + int i0 = TriangleTableEn[nIndex][0][TriIndex + 2] ; + int i1 = TriangleTableEn[nIndex][0][TriIndex + 1] ; + int i2 = TriangleTableEn[nIndex][0][TriIndex] ; + + Triangle3d CurrentTriangle ; + + // Il triangolo è pronto + CurrentTriangle.Set( VecField[i0].ptInt, VecField[i1].ptInt, VecField[i2].ptInt) ; + CurrentTriangle.Validate( true) ; + + // Se il triangolo non è degenere lo aggiungo alla lista + if ( ! ( AreSamePointApprox( CurrentTriangle.GetP( 0), CurrentTriangle.GetP( 1)) || + AreSamePointApprox( CurrentTriangle.GetP( 1), CurrentTriangle.GetP( 2)) || + AreSamePointApprox( CurrentTriangle.GetP( 2), CurrentTriangle.GetP( 0)))) + lstTria.emplace_back( CurrentTriangle) ; + } + } } // Standard MC else { @@ -915,8 +1286,11 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DLIST& lstTria, TriHolder& triHold) CurrentTriangle.Set( VecField[i0].ptInt, VecField[i1].ptInt, VecField[i2].ptInt) ; CurrentTriangle.Validate( true) ; - // Aggiungo triangolo - lstTria.emplace_back( CurrentTriangle) ; + // Se il triangolo non è degenere lo aggiungo alla lista + if ( ! ( AreSamePointApprox( CurrentTriangle.GetP( 0), CurrentTriangle.GetP( 1)) || + AreSamePointApprox( CurrentTriangle.GetP( 1), CurrentTriangle.GetP( 2)) || + AreSamePointApprox( CurrentTriangle.GetP( 2), CurrentTriangle.GetP( 0)))) + lstTria.emplace_back( CurrentTriangle) ; } } @@ -925,78 +1299,508 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DLIST& lstTria, TriHolder& triHold) } } } - - m_BlockToUpdate[nBlock] = false ; return true ; } +//---------------------------------------------------------------------------- +bool +VolZmap::ExtMarchingCubes( const std::vector VoxelsIndexes, TriHolder& triHold) const +{ + // Controllo sulla validità della dimensione del + // vector: essa deve essere un multiplo di 3 + if ( ( VoxelsIndexes.size() % 3)) + return false ; + + Point3d ptMapOrig = m_MapFrame[0].Orig() ; + + // Ciclo sui voxel + for ( size_t t = 0 ; t < VoxelsIndexes.size() - 2 ; t += 3) { + + // Indici del voxel + int i = VoxelsIndexes[t] ; + int j = VoxelsIndexes[t + 1] ; + int k = VoxelsIndexes[t + 2] ; + + // Indici i,j,k dei vertici + int IndexCorner[8][3] = { + { i, j, k}, + { i + 1, j, k}, + { i + 1, j + 1, k}, + { i, j + 1, k}, + { i, j, k + 1}, + { i + 1, j, k + 1}, + { i + 1, j + 1, k + 1}, + { i, j + 1, k + 1} + } ; + + int nIndex = 0 ; + + // Classificazione dei vertici: interni o esterni al materiale + if ( IsThereMat( i, j, k)) + nIndex |= ( 1 << 0) ; + if ( IsThereMat( i + 1, j, k)) + nIndex |= ( 1 << 1) ; + if ( IsThereMat( i + 1, j + 1, k)) + nIndex |= ( 1 << 2) ; + if ( IsThereMat( i, j + 1, k)) + nIndex |= ( 1 << 3) ; + if ( IsThereMat( i, j, k + 1)) + nIndex |= ( 1 << 4) ; + if ( IsThereMat( i + 1, j, k + 1)) + nIndex |= ( 1 << 5) ; + if ( IsThereMat( i + 1, j + 1, k + 1)) + nIndex |= ( 1 << 6) ; + if ( IsThereMat( i, j + 1, k + 1)) + nIndex |= ( 1 << 7) ; + + // Se vi è qualche intersezione fra segmenti e superficie + // continuo altrimenti passo al prossimo voxel. + if ( EdgeTable[nIndex] == 0) + continue ; + + static int intersections[12][2] = { + { 0, 1 }, { 1, 2 }, { 2, 3 }, { 0, 3 }, { 4, 5 }, { 5, 6 }, + { 6, 7 }, { 4, 7 }, { 0, 4 }, { 1, 5 }, { 2, 6 }, { 3, 7 } + } ; + + // Arrey di strutture punto di intersezione + // e normale alla superficie in esso. + VectorField VecField[12] ; + + // Ciclo sui segmenti + for ( int EdgeIndex = 0 ; EdgeIndex < 12 ; ++ EdgeIndex) { + // Se il segmento non attraversa la superficie passo al successivo + if ( ! ( EdgeTable[nIndex] & ( 1 << EdgeIndex))) + continue ; + + int n1 = intersections[EdgeIndex][0] ; + int n2 = intersections[EdgeIndex][1] ; + + // Determino con precisione il punto di intersezione sullo spigolo. + IntersPos( IndexCorner[n1], IndexCorner[n2], + VecField[EdgeIndex].ptInt, + VecField[EdgeIndex].vtNorm) ; + + VecField[EdgeIndex].ptInt.ToGlob( m_MapFrame[0]) ; + VecField[EdgeIndex].vtNorm.ToGlob( m_MapFrame[0]) ; + } + + // Determino il numero di componenti connesse + int nComponents = TriangleTableEn[nIndex][1][0] ; + + // Serve nel ciclo che salva i punti e vettori di + // una componente nell'arrey di compentenza: La tabella + // fornisce numero di componenti, numero di vertici per + // componenti per OGNUNA delle componenti e in fine + // elenca i vertici della prima componente, seguiti da quelli + // della seconda e così via. + int nTableOffset = nComponents ; + + // Numero di feature nel voxel: al più vi + // è una feature per componente connessa + int nFeatureInVoxel = 0 ; + + // Ciclo sulle componenti + for ( int nCompCount = 1 ; nCompCount <= nComponents ; ++ nCompCount) { + + // Numero vertici per componenti + int nVertComp = TriangleTableEn[nIndex][1][nCompCount] ; + + // Vettore di Vector3d + VectorField CompoVert[12] ; + + // Riempio il vettore + for ( int nVertCount = 0 ; nVertCount < nVertComp ; ++ nVertCount) + // Nota che il primo elemento dell'array (0-esimo) non viene inizializzato + CompoVert[nVertCount] = VecField[TriangleTableEn[nIndex][1][nVertCount + nTableOffset + 1]] ; + + int nFeatureType ; + + // Valuto le relazioni reciproche fra le normali + bool bExt = TestOnNormal( CompoVert, nVertComp, nFeatureType) ; + + // Extended MC + if ( bExt) { + + // Aggiorno il numero di feature. + ++ nFeatureInVoxel ; + + // Se siamo in presenza della prima feature del + // voxel, ridimensiono il vettore che contiene + // la struttura dati del voxel. + if ( nFeatureInVoxel == 1) { + + triHold.resize( triHold.size() + 1) ; + + // Questi dati dipendono solo dal voxel, + // quindi sono validi validi per tutte le + // componenti che vi appartengono. + int nCurrent = int( triHold.size()) - 1 ; + + triHold[nCurrent].i = i ; + triHold[nCurrent].j = j ; + triHold[nCurrent].k = k ; + } + + // Indice che identifica la posizione del voxel + // nel vector. + int nCurrent = int( triHold.size()) - 1 ; + + // Passo al sistema di riferimento del baricentro + Point3d ptGravityCenter( 0, 0, 0) ; + + for ( int ni = 0 ; ni < nVertComp ; ++ ni) + + ptGravityCenter += CompoVert[ni].ptInt ; + + ptGravityCenter /= nVertComp ; + + Vector3d vtO = ptGravityCenter - ORIG ; + + Point3d ptTrasf[12] ; + + for ( int ni = 0 ; ni < nVertComp ; ++ ni) + + ptTrasf[ni] = CompoVert[ni].ptInt - vtO ; + + + // Preparo le matrici per il sistema + typedef Eigen::Matrix dSystemMatrix ; + typedef Eigen::Matrix dSystemVector ; + typedef Eigen::JacobiSVD DecomposerSVD ; + + dSystemMatrix dMatrixN, dMatrixU, dMatrixV ; + dSystemVector dKnownVector, dUnknownVector, dSingularValue ; + + dMatrixN.resize( nVertComp, 3) ; + dKnownVector.resize( nVertComp, 1) ; + dUnknownVector.resize( 3, 1) ; + + // Studio del caso 4 punti su un piano + int nEqual = 0 ; + int nPosD ; + Vector3d vtD, vtE ; + + if ( nVertComp == 4 && nFeatureType == 2) { + + int nPosEq ; + + for ( int ni = 0 ; ni < 2 ; ++ ni) { + + for ( int nj = ni + 1 ; nj < nVertComp ; ++ nj) { + + if ( AreSameVectorApprox( CompoVert[ni].vtNorm, + CompoVert[nj].vtNorm)) { + + nEqual ++ ; + nPosEq = ni ; + } + } + + if ( nEqual == 2) + break ; + else + nEqual = 0 ; + } + + if ( nEqual == 2) { + + for ( int ni = 0 ; ni < nVertComp ; ++ ni) + + if ( ! AreSameVectorApprox( CompoVert[ni].vtNorm, + CompoVert[nPosEq].vtNorm)) { + + nPosD = ni ; + vtD = CompoVert[ni].vtNorm ; + vtE = CompoVert[nPosEq].vtNorm ; + } + } + } + + double dDot = abs( ( CompoVert[1].ptInt - CompoVert[0].ptInt) * + ( ( CompoVert[2].ptInt - CompoVert[1].ptInt) ^ + ( CompoVert[3].ptInt - CompoVert[2].ptInt))) ; + + + + // Caso quattro punti su un piano + if ( nVertComp == 4 && nEqual == 2 && dDot < EPS_SMALL) { + + for ( int ni = 0 ; ni < nVertComp ; ++ ni) { + + if ( ni != nPosD) { + + dMatrixN( ni, 0) = CompoVert[ni].vtNorm.x ; + dMatrixN( ni, 1) = CompoVert[ni].vtNorm.y ; + dMatrixN( ni, 2) = CompoVert[ni].vtNorm.z ; + + dKnownVector( ni) = CompoVert[ni].vtNorm * ( ptTrasf[ni] - ORIG) ; + } + else { + + dMatrixN( ni, 0) = vtE.x ; + dMatrixN( ni, 1) = vtE.y ; + dMatrixN( ni, 2) = vtE.z ; + + dKnownVector( ni) = vtE * ( ptTrasf[ni] - ORIG) ; + } + } + } + // caso generale + else { + + for ( int ni = 0 ; ni < nVertComp ; ++ ni) { + + dMatrixN( ni, 0) = CompoVert[ni].vtNorm.x ; + dMatrixN( ni, 1) = CompoVert[ni].vtNorm.y ; + dMatrixN( ni, 2) = CompoVert[ni].vtNorm.z ; + + dKnownVector( ni) = CompoVert[ni].vtNorm * ( ptTrasf[ni] - ORIG) ; + } + } + + DecomposerSVD svd( dMatrixN, Eigen::ComputeThinU | Eigen::ComputeThinV) ; + + dMatrixU = svd.matrixU() ; + dMatrixV = svd.matrixV() ; + dSingularValue = svd.singularValues() ; + + double s0 = dSingularValue( 0) ; + double s1 = dSingularValue( 1) ; + double s2 = dSingularValue( 2) ; + + if ( nFeatureType == 2 ) + dSingularValue( 2) = 0 ; + + // Back substitution: risolvo il sistema USV*x = b + // Calcolo U^T b + double vTemp[3] ; + + for ( int ni = 0 ; ni < 3 ; ++ ni) { + + double s = 0 ; + + if ( abs( dSingularValue( ni)) > EPS_SMALL) { + + for ( int nj = 0 ; nj < nVertComp ; ++ nj) + + s += dMatrixU( nj, ni) * dKnownVector( nj) ; + + s /= dSingularValue( ni) ; + } + vTemp[ni] = s ; + } + + // Moltiplico per V + for ( int ni = 0 ; ni < 3 ; ++ ni) { + + double s = 0 ; + + for ( int nj = 0 ; nj < 3 ; ++ nj) + s += dMatrixV( ni, nj) * vTemp[nj] ; + + dUnknownVector( ni) = s ; + } + + // Limito la feature entro una distanza di 3 + // volte la diagonale del voxel dal baricentro. + Vector3d vtFeature( dUnknownVector( 0), + dUnknownVector( 1), + dUnknownVector( 2)) ; + + double dDistFeature = vtFeature.Len() ; + + const double dMaxDist = 2 * sqrt( 3) * m_dStep / 2 ; + + if ( dDistFeature > dMaxDist) { + + vtFeature = ( dMaxDist / dDistFeature) * vtFeature ; + + dUnknownVector( 0) = vtFeature.x ; + dUnknownVector( 1) = vtFeature.y ; + dUnknownVector( 2) = vtFeature.z ; + } + + // Esprimo la soluzione nel sistema di riferimento dello z-map + Point3d ptSol( dUnknownVector( 0) + vtO.x, + dUnknownVector( 1) + vtO.y, + dUnknownVector( 2) + vtO.z) ; + + // Aggiungo vertice della componente + // connessa alla lista dei vertici. + triHold[nCurrent].ptCompoVert.emplace_back( ptSol) ; + + int nOldFeatureNum = triHold[nCurrent].vCompoTria.size() ; + int nNewFeatureNum = nOldFeatureNum + 1 ; + + // Aggiungo una componente per il vettore + // dei triangoli della componente connessa. + triHold[nCurrent].vCompoTria.resize( nNewFeatureNum) ; + + Triangle3d CurrentTriangle ; + TRIA3DVECTOR triContainer ; + + for ( int ni = 0 ; ni < nVertComp - 1 ; ++ ni) { + + // Il triangolo è pronto + CurrentTriangle.Set( ptSol, CompoVert[ni+1].ptInt, CompoVert[ni].ptInt) ; + CurrentTriangle.Validate( true) ; + + // Test sulla degenerazione + if ( CurrentTriangle.GetArea() < EPS_SMALL /*AreSamePointApprox( CurrentTriangle.GetP( 0), CurrentTriangle.GetP( 1)) || + AreSamePointApprox( CurrentTriangle.GetP( 1), CurrentTriangle.GetP( 2)) || + AreSamePointApprox( CurrentTriangle.GetP( 2), CurrentTriangle.GetP( 0))*/) + + continue ; + + // Aggiungo triangolo + triHold[nCurrent].vCompoTria[nOldFeatureNum].emplace_back( CurrentTriangle) ; + } + + // Ultimo triangolo + CurrentTriangle.Set( ptSol, CompoVert[0].ptInt, CompoVert[nVertComp - 1].ptInt) ; + CurrentTriangle.Validate( true) ; + + // Test sulla degenerazione + if ( CurrentTriangle.GetArea() < EPS_SMALL /*AreSamePointApprox( CurrentTriangle.GetP( 0), CurrentTriangle.GetP( 1)) || + AreSamePointApprox( CurrentTriangle.GetP( 1), CurrentTriangle.GetP( 2)) || + AreSamePointApprox( CurrentTriangle.GetP( 2), CurrentTriangle.GetP( 0))*/) + + continue ; + + // Aggiungo ultimo triangolo + triHold[nCurrent].vCompoTria[nOldFeatureNum].emplace_back( CurrentTriangle) ; + } + + nTableOffset += nVertComp ; + } + } + return true ; +} + //---------------------------------------------------------------------------- bool VolZmap::FlipEdges( TriHolder& triHold) const { + // Numero di voxel in cui si presentano sharp feature int nVoxelNum = int( triHold.size()) ; + // Ciclo su tali voxel for ( int n = 0 ; n < nVoxelNum ; ++ n) { - - for ( int m = n + 1 ; m < nVoxelNum ; ++ m) { + for ( int m = n ; m < nVoxelNum ; ++ m) { - if ( ( triHold[m].i < int( m_nNx[0]) && + // Voxel adiacenti o coincidenti + if ( m == n || + ( ( triHold[m].i < int( m_nNx[0]) && triHold[m].j < int( m_nNy[0]) && triHold[m].k < int( m_nNy[1])) && - ( ( triHold[m].i == triHold[n].i + 1) || - ( triHold[m].j == triHold[n].j + 1) || - ( triHold[m].k == triHold[n].k + 1))) { - - int nNumN = int( triHold[n].vecTria.size()) ; - int nNumM = int( triHold[m].vecTria.size()) ; - - for ( int triN = 0 ; triN < nNumN ; ++ triN) { + ( triHold[m].i == triHold[n].i + 1 || + triHold[m].j == triHold[n].j + 1 || + triHold[m].k == triHold[n].k + 1))) { - bool bModified = false ; + // Numero delle componenti connesse nei due voxel + int nNumCompoN = triHold[n].ptCompoVert.size() ; + int nNumCompoM = triHold[m].ptCompoVert.size() ; + + int nCompoN = 0 ; - for ( int triM = 0 ; triM < nNumM ; ++ triM) { + // Ciclo sulle componenti + for ( ; nCompoN < nNumCompoN ; ++ nCompoN) { - std::vector SharedIndex ; + int nCompoM = ( m == n ? nCompoN + 1 : 0) ; + + for ( ; nCompoM < nNumCompoM ; ++ nCompoM) { + + // Numero di triangoli per le componenti connesse + int nNumN = int( triHold[n].vCompoTria[nCompoN].size()) ; + int nNumM = int( triHold[m].vCompoTria[nCompoM].size()) ; + + for ( int triN = 0 ; triN < nNumN ; ++ triN) { + + bool bModified = false ; + + for ( int triM = 0 ; triM < nNumM ; ++ triM) { + + std::vector SharedIndex ; - for ( int vertN = 0 ; vertN < 3 ; ++ vertN) { + for ( int vertN = 0 ; vertN < 3 ; ++ vertN) { - for ( int vertM = 0 ; vertM < 3 ; ++ vertM) { + for ( int vertM = 0 ; vertM < 3 ; ++ vertM) { - Point3d ptN = triHold[n].vecTria[triN].GetP( vertN) ; - Point3d ptM = triHold[m].vecTria[triM].GetP( vertM) ; + Point3d ptN = triHold[n].vCompoTria[nCompoN][triN].GetP( vertN) ; + Point3d ptM = triHold[m].vCompoTria[nCompoM][triM].GetP( vertM) ; - if ( SqDist( ptN, ptM) < EPS_SMALL * EPS_SMALL) { + if ( SqDist( ptN, ptM) < EPS_SMALL * EPS_SMALL) { + + Point3d ptVertN = triHold[n].ptCompoVert[nCompoN] ; + Point3d ptVertM = triHold[m].ptCompoVert[nCompoM] ; + + if ( ! ( AreSamePointApprox( ptN, ptVertN) || + AreSamePointApprox( ptM, ptVertM))) { - SharedIndex.emplace_back( vertN) ; - SharedIndex.emplace_back( vertM) ; - } + SharedIndex.emplace_back( vertN) ; + SharedIndex.emplace_back( vertM) ; + } + } - if ( SharedIndex.size() > 2) - break ; + if ( SharedIndex.size() > 2) + break ; + } + + if ( SharedIndex.size() > 2) + break ; + } + // Si deve operare la modifica dei triangoli + if ( SharedIndex.size() > 2) { + + // Controllo sulle normali + Point3d ptMFeature = triHold[m].ptCompoVert[nCompoM] ; + Point3d ptNFeature = triHold[n].ptCompoVert[nCompoN] ; + + Vector3d vtFeature = ptMFeature - ptNFeature ; + + vtFeature.Normalize() ; + + double dDot = vtFeature * triHold[m].vCompoTria[nCompoM][triM].GetN() ; + + // Ulteriore controllo sulle normali + Point3d ptP0 = ptNFeature ; + Point3d ptP1 = triHold[n].vCompoTria[nCompoN][triN].GetP( SharedIndex[0]) ; + Point3d ptP2 = triHold[n].vCompoTria[nCompoN][triN].GetP( SharedIndex[2]) ; + Point3d ptP3 = ptMFeature ; + + double dPlane = ( ( ptP1 - ptP0) ^ ( ptP2 - ptP0)) * ( ptP3 - ptP0) ; + + Vector3d vtN = triHold[n].vCompoTria[nCompoN][triN].GetN() ; + Vector3d vtM = triHold[m].vCompoTria[nCompoM][triM].GetN() ; + + double dDotNM = vtN * vtM ; + + int nProd = ( SharedIndex[2] - SharedIndex[0]) * ( SharedIndex[3] - SharedIndex[1]) ; + + // --- + if ( nProd != 1 && nProd != - 2 && nProd != 4) { + + triHold[n].vCompoTria[nCompoN][triN].SetP( SharedIndex[0], + triHold[m].ptCompoVert[nCompoM]) ; + triHold[m].vCompoTria[nCompoM][triM].SetP( SharedIndex[3], + triHold[n].ptCompoVert[nCompoN]) ; + + triHold[n].vCompoTria[nCompoN][triN].Validate( true) ; + triHold[m].vCompoTria[nCompoM][triM].Validate( true) ; + + bModified = true ; + break ; + } + } } - if ( SharedIndex.size() > 2) - break ; + if ( bModified) + break ; } - // Si deve operare la modifica dei triangoli - if ( SharedIndex.size() > 2) { - - // Modifico i triangoli - triHold[n].vecTria[triN].SetP( SharedIndex[0], triHold[m].ptVert) ; - triHold[m].vecTria[triM].SetP( SharedIndex[3], triHold[n].ptVert) ; - - triHold[n].vecTria[triN].Validate( true) ; - triHold[m].vecTria[triM].Validate( true) ; - - bModified = true ; - break ; - } } - - if( bModified) - break ; } } } @@ -1007,152 +1811,98 @@ VolZmap::FlipEdges( TriHolder& triHold) const //---------------------------------------------------------------------------- bool -VolZmap::FlipEdges( int nBlock, TriHolder& triHold) +VolZmap::FlipEdgesLocalFlipEdges( TriaStruct& triStrCurr, TriaStruct& triStrAdj) const { - // Controllo sulla validità del blocco - if ( nBlock < 0 || nBlock > int( m_nNumBlock)) - return false ; + // Numero delle componenti connesse nei due voxel + size_t nCurVoxCompNum = triStrCurr.ptCompoVert.size() ; + size_t nAdjVoxCompNum = triStrAdj.ptCompoVert.size() ; - // Calcolo posizione del blocco nel reticolo - int nIBlock = ( nBlock % int( m_nFracLin[0] * m_nFracLin[1])) % int( m_nFracLin[0]) ; - int nJBlock = ( nBlock % int( m_nFracLin[0] * m_nFracLin[1])) / int( m_nFracLin[0]) ; - int nKBlock = ( nBlock / int( m_nFracLin[0] * m_nFracLin[1])) ; + // Ciclo sulle componenti connesse + for ( size_t nCVCurComp = 0 ; nCVCurComp < nCurVoxCompNum ; ++ nCVCurComp) { + for ( size_t nAVCurComp = 0 ; nAVCurComp < nAdjVoxCompNum ; ++ nAVCurComp) { - // Calcolo limiti per l'indice i - //int nStartI = nIBlock * int( m_nDexNumPBlock) - 1 ; - int nEndI = ( nIBlock + 1 == int( m_nFracLin[0]) ? - int( m_nNx[0]) : ( nIBlock + 1) * int( m_nDexNumPBlock)) ; + // Numero di triangoli per le componenti connesse + size_t nCVTriaNum = triStrCurr.vCompoTria[nCVCurComp].size() ; + size_t nAVTriaNum = triStrAdj.vCompoTria[nAVCurComp].size() ; - // Calcolo limiti per l'indice j - //int nStartJ = nJBlock * int( m_nDexNumPBlock) - 1 ; - int nEndJ = ( nJBlock + 1 == int( m_nFracLin[1]) ? - int( m_nNy[0]) : ( nJBlock + 1) * int( m_nDexNumPBlock)) ; + for ( size_t nCVT = 0 ; nCVT < nCVTriaNum ; ++ nCVT) { - // Calcolo limiti per l'indice k - //int nStartK = nKBlock * int( m_nDexNumPBlock) - 1 ; - int nEndK = ( nKBlock + 1 == int( m_nFracLin[2]) ? - int( m_nNy[1]) : ( nKBlock + 1) * int( m_nDexNumPBlock)) ; - - int nFirstVoxelLim = int( triHold.size()) ; - int nSecondVoxelLim ; - - for ( int n = 0 ; n < nFirstVoxelLim ; ++ n) { - - // Determino se il voxel è di frontiera - // per qualche blocco adiacente. - - int nNeighbour = 0 ; - - if ( triHold[n].i == nEndI - 1) nNeighbour |= ( 1 << 0) ; - - if ( triHold[n].j == nEndJ - 1) nNeighbour |= ( 1 << 1) ; - - if ( triHold[n].k == nEndK - 1) nNeighbour |= ( 1 << 2) ; - - int nNumAdjBlocks = NeighbourTable[nNeighbour][0] ; - - // - for ( int nTabInd = 0 ; nTabInd <= nNumAdjBlocks ; ++ nTabInd) { - - if ( ( ! nTabInd) && ( ! nNumAdjBlocks)) - - nSecondVoxelLim = nFirstVoxelLim ; - - else if ( nTabInd && ( NeighbourTable[nNeighbour][nTabInd] == 1)) { - ; - } - else if ( nTabInd && ( NeighbourTable[nNeighbour][nTabInd] == 2)) { - ; - } - else if ( nTabInd && ( NeighbourTable[nNeighbour][nTabInd] == 3)) { - ; - } - - // metti l'intero for dopo con gli aggiustamenti - } - - - - - for ( int m = n + 1 ; m < nSecondVoxelLim ; ++ m) { - - int nNumN = int( triHold[n].vecTria.size()) ; - int nNumM = int( triHold[m].vecTria.size()) ; - - bool bFlag = false ; - - std::vector SharedIndex ; - - for ( int triN = 0 ; triN < nNumN ; ++ triN) { + bool bModified = false ; - for ( int triM = 0 ; triM < nNumM ; ++ triM) { + for ( size_t nAVT = 0 ; nAVT < nAVTriaNum ; ++ nAVT) { - int nSharedVertex = 0 ; + std::vector SharedIndex ; - for ( int vertN = 0 ; vertN < 3 ; ++ vertN) { - - for ( int vertM = 0 ; vertM < 3 ; ++ vertM) { + for ( size_t nCurVoxVert = 0 ; nCurVoxVert < 3 ; ++ nCurVoxVert) { + for ( size_t nAdjVoxVert = 0 ; nAdjVoxVert < 3 ; ++ nAdjVoxVert) { - Point3d ptN = triHold[n].vecTria[triN].GetP( vertN) ; - Point3d ptM = triHold[m].vecTria[triM].GetP( vertM) ; + Point3d ptC = triStrCurr.vCompoTria[nCVCurComp][nCVT].GetP( nCurVoxVert) ; + Point3d ptA = triStrAdj.vCompoTria[nAVCurComp][nAVT].GetP( nAdjVoxVert) ; - if ( SqDist( ptN, ptM) < EPS_SMALL * EPS_SMALL) { + if ( SqDist( ptC, ptA) < EPS_SMALL * EPS_SMALL) { - nSharedVertex ++ ; + SharedIndex.emplace_back( int( nCurVoxVert)) ; + SharedIndex.emplace_back( int( nAdjVoxVert)) ; + } + + if ( SharedIndex.size() > 2) + break ; + } - SharedIndex.emplace_back( vertN) ; - SharedIndex.emplace_back( vertM) ; + if ( SharedIndex.size() > 2) + break ; + } + // Si deve operare la modifica dei triangoli + if ( SharedIndex.size() > 2) { - } + // Controllo sulle normali + Point3d ptCurFeature = triStrCurr.ptCompoVert[nCVCurComp] ; + Point3d ptAdjFeature = triStrAdj.ptCompoVert[nAVCurComp] ; - if ( nSharedVertex > 1) - break ; - } + Vector3d vtFeature = ptAdjFeature - ptCurFeature ; + + vtFeature.Normalize() ; + + double dDot = vtFeature * triStrAdj.vCompoTria[nAVCurComp][nAVT].GetN() ; - if ( nSharedVertex > 1) - break ; - } + // Ulteriore controllo sulle normali + Point3d ptP0 = ptCurFeature ; + Point3d ptP1 = triStrCurr.vCompoTria[nCVCurComp][nCVT].GetP( SharedIndex[0]) ; + Point3d ptP2 = triStrCurr.vCompoTria[nCVCurComp][nCVT].GetP( SharedIndex[2]) ; + Point3d ptP3 = ptAdjFeature ; - if ( nSharedVertex > 1) { + double dPlane = ( ( ptP1 - ptP0) ^ ( ptP2 - ptP0)) * ( ptP3 - ptP0) ; - triHold[n].vecTria[triN].SetP( SharedIndex[3], triHold[m].ptVert) ; - triHold[m].vecTria[triM].SetP( SharedIndex[2], triHold[n].ptVert) ; + Vector3d vtN = triStrCurr.vCompoTria[nCVCurComp][nCVT].GetN() ; + Vector3d vtM = triStrAdj.vCompoTria[nAVCurComp][nAVT].GetN() ; - bFlag = true ; - break ; - } + double dDotNM = vtN * vtM ; + + int nProd = ( SharedIndex[2] - SharedIndex[0]) * ( SharedIndex[3] - SharedIndex[1]) ; + + if ( nProd != 1 && nProd != - 2 && nProd != 4 && + ( dDot < - EPS_SMALL || ( dPlane < EPS_SMALL && dDotNM < - 0.95))) { + + triStrCurr.vCompoTria[nCVCurComp][nCVT].SetP( SharedIndex[0], + triStrAdj.ptCompoVert[nAVCurComp]) ; + triStrAdj.vCompoTria[nAVCurComp][nAVT].SetP( SharedIndex[3], + triStrCurr.ptCompoVert[nCVCurComp]) ; + + triStrCurr.vCompoTria[nCVCurComp][nCVT].Validate( true) ; + triStrAdj.vCompoTria[nAVCurComp][nAVT].Validate( true) ; + + bModified = true ; + break ; + } + } } - if ( bFlag) + if ( bModified) break ; - } - } - } - - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::FlipEdges( int nNumBlocks, int nBlocks[], TriHolder triHold[]) -{ - // Controllo sulla validità dei blocchi - for ( int i = 0 ; i < nNumBlocks ; ++ i) - if ( nBlocks[i] < 0 || nBlocks[i] > int( m_nNumBlock)) - return false ; - - // Dispongo i blocchi in ordine crescente - for ( int i = 0 ; i < nNumBlocks ; ++ i) - for ( int j = i + 1 ; j < nNumBlocks ; ++ j) - if ( nBlocks[i] > nBlocks[j]) - swap( nBlocks[i], nBlocks[j]) ; - - - // Ciclo sui blocchi - for ( int i = 0 ; i < nNumBlocks ; ++ i) { - - } - return true ; + } + } + } + return true ; } //---------------------------------------------------------------------------- @@ -1163,6 +1913,8 @@ VolZmap::IsThereMat( int nI, int nJ, int nK) const nJ == - 1 || nJ == m_nNy[0] || nK == - 1 || nK == m_nNy[1]) return false ; + + double dEps = 2 * EPS_SMALL ; double dZ[3] ; @@ -1194,9 +1946,9 @@ VolZmap::IsThereMat( int nI, int nJ, int nK) const size_t nIndex = 0 ; while ( nIndex < nDexSize) { - - if ( dZ[nGrid] > m_Values[nGrid][nPos][nIndex].dZVal - EPS_SMALL && - dZ[nGrid] < m_Values[nGrid][nPos][nIndex + 1].dZVal + EPS_SMALL) { + + if ( dZ[nGrid] > m_Values[nGrid][nPos][nIndex].dZVal - dEps && + dZ[nGrid] < m_Values[nGrid][nPos][nIndex + 1].dZVal + dEps) { ++ nCount ; break ; @@ -1204,7 +1956,6 @@ VolZmap::IsThereMat( int nI, int nJ, int nK) const nIndex += 2 ; } } - return ( nCount == 3) ; } @@ -1212,7 +1963,6 @@ VolZmap::IsThereMat( int nI, int nJ, int nK) const bool VolZmap::IntersPos( int nVec1[], int nVec2[], Point3d& ptInt) const { - if ( nVec1[0] != nVec2[0]) { ptInt.y = ( nVec1[1] + 0.5) * m_dStep ; @@ -1244,8 +1994,8 @@ VolZmap::IntersPos( int nVec1[], int nVec2[], Point3d& ptInt) const break ; } } - if ( ! bFound) - ptInt.x = ( dMinX + dMaxX) / 2 ; + if ( ! bFound) + ptInt.x = ( dMinX + dMaxX) / 2 ; } else if ( nVec1[1] != nVec2[1]) { @@ -1325,6 +2075,7 @@ VolZmap::IntersPos( int nVec1[], int nVec2[], Point3d& ptInt) const bool VolZmap::IntersPos( int nVec1[], int nVec2[], Point3d& ptInt, Vector3d& vtNormal) const { + double Eps = EPS_SMALL ; if ( nVec1[0] != nVec2[0]) { @@ -1345,23 +2096,83 @@ VolZmap::IntersPos( int nVec1[], int nVec2[], Point3d& ptInt, Vector3d& vtNormal double dx1 = m_Values[1][nDexel][i].dZVal ; double dx2 = m_Values[1][nDexel][i+1].dZVal ; - - if ( dx1 < dMinX - EPS_SMALL && dx2 > dMinX - EPS_SMALL && dx2 < dMaxX + EPS_SMALL) { + + if ( dx1 < dMinX - Eps && dx2 > dMinX - Eps && dx2 < dMaxX + Eps) { ptInt.x = dx2 ; vtNormal = m_Values[1][nDexel][i+1].vtN ; bFound = true ; break ; } - else if ( dx1 > dMinX - EPS_SMALL && dx1 < dMaxX + EPS_SMALL && dx2 > dMaxX + EPS_SMALL) { + else if ( dx1 > dMinX - Eps && dx1 < dMaxX + Eps && dx2 > dMaxX + Eps) { ptInt.x = dx1 ; vtNormal = m_Values[1][nDexel][i].vtN ; bFound = true ; break ; + }/* + if ( dx1 < dMinX + Eps && dx2 > dMinX && dx2 < dMaxX - Eps) { + ptInt.x = dx2 ; + vtNormal = m_Values[1][nDexel][i+1].vtN ; + bFound = true ; + break ; } + else if ( dx1 > dMinX + Eps && dx1 < dMaxX + Eps && dx2 > dMaxX + Eps) { + ptInt.x = dx1 ; + vtNormal = m_Values[1][nDexel][i].vtN ; + bFound = true ; + break ; + }*/ } if ( ! bFound) { + ptInt.x = ( dMinX + dMaxX) / 2 ; - // Versore Normale ??? + /* + if ( IsThereMat( nVec1[0], nVec1[1], nVec1[2])) { + + double dY = ( nVec2[1] + 0.5) * m_dStep ; + double dZ = ( nVec2[2] + 0.5) * m_dStep ; + + unsigned int YDirMinIndex = 0 ; + unsigned int ZDirMinIndex = 0 ; + + double dYMinDist = DBL_MAX ; + double dZMinDist = DBL_MAX ; + + unsigned int nYDirGrid = nVec2[0] * m_nNx[2] + nVec2[2] ; + unsigned int nZDirGrid = nVec2[1] * m_nNx[0] + nVec2[0] ; + + for ( unsigned int t = 0 ; t < m_Values[0][nZDirGrid].size() ; ++ t) { + + double dMZ1 = m_Values[0][nZDirGrid][t].dZVal ; + + if ( abs( dMZ1 - dZ) < dZMinDist) { + + ZDirMinIndex = t ; + dZMinDist = abs( dMZ1 - dZ) ; + } + } + + for ( unsigned int t = 0 ; t < m_Values[2][nYDirGrid].size() ; ++ t) { + + double dMY1 = m_Values[2][nYDirGrid][t].dZVal ; + + if ( abs( dMY1 - dY) < dYMinDist) { + + YDirMinIndex = t ; + dYMinDist = abs( dMY1 - dY) ; + } + } + + unsigned int AbsoluteMinIndex ; + + if ( dZMinDist < dYMinDist) + + vtNormal = m_Values[0][nZDirGrid][ZDirMinIndex].vtN ; + else + vtNormal = m_Values[0][nYDirGrid][YDirMinIndex].vtN ; + } + else { + + }*/ } } @@ -1384,19 +2195,31 @@ VolZmap::IntersPos( int nVec1[], int nVec2[], Point3d& ptInt, Vector3d& vtNormal double dy1 = m_Values[2][nDexel][j].dZVal ; double dy2 = m_Values[2][nDexel][j+1].dZVal ; - - if ( dy1 < dMinY - EPS_SMALL && dy2 > dMinY - EPS_SMALL && dy2 < dMaxY + EPS_SMALL) { + + if ( dy1 < dMinY - Eps && dy2 > dMinY - Eps && dy2 < dMaxY + Eps) { ptInt.y = dy2 ; vtNormal = m_Values[2][nDexel][j+1].vtN ; bFound = true ; break ; } - else if ( dy1 > dMinY - EPS_SMALL && dy1 < dMaxY + EPS_SMALL && dy2 > dMaxY + EPS_SMALL) { + else if ( dy1 > dMinY - Eps && dy1 < dMaxY + Eps && dy2 > dMaxY + Eps) { ptInt.y = dy1 ; vtNormal = m_Values[2][nDexel][j].vtN ; bFound = true ; break ; + }/* + if ( dy1 < dMinY + Eps && dy2 > dMinY && dy2 < dMaxY - Eps) { + ptInt.y = dy2 ; + vtNormal = m_Values[2][nDexel][j+1].vtN ; + bFound = true ; + break ; } + else if ( dy1 > dMinY + Eps && dy1 < dMaxY + Eps && dy2 > dMaxY + Eps) { + ptInt.y = dy1 ; + vtNormal = m_Values[2][nDexel][j].vtN ; + bFound = true ; + break ; + }*/ } if ( ! bFound) { ptInt.y = ( dMinY + dMaxY) / 2 ; @@ -1423,19 +2246,31 @@ VolZmap::IntersPos( int nVec1[], int nVec2[], Point3d& ptInt, Vector3d& vtNormal double dz1 = m_Values[0][nDexel][k].dZVal ; double dz2 = m_Values[0][nDexel][k+1].dZVal ; - - if ( dz1 < dMinZ - EPS_SMALL && dz2 > dMinZ - EPS_SMALL && dz2 < dMaxZ + EPS_SMALL) { + + if ( dz1 < dMinZ - Eps && dz2 > dMinZ - Eps && dz2 < dMaxZ + Eps) { ptInt.z = dz2 ; vtNormal = m_Values[0][nDexel][k+1].vtN ; bFound = true ; break ; } - else if ( dz1 > dMinZ - EPS_SMALL && dz1 < dMaxZ + EPS_SMALL && dz2 > dMaxZ + EPS_SMALL) { + else if ( dz1 > dMinZ - Eps && dz1 < dMaxZ + Eps && dz2 > dMaxZ + Eps) { ptInt.z = dz1 ; vtNormal = m_Values[0][nDexel][k].vtN ; bFound = true ; break ; + }/* + if ( dz1 < dMinZ + Eps && dz2 > dMinZ && dz2 < dMaxZ - Eps) { + ptInt.z = dz2 ; + vtNormal = m_Values[0][nDexel][k+1].vtN ; + bFound = true ; + break ; } + else if ( dz1 > dMinZ + Eps && dz1 < dMaxZ + Eps && dz2 > dMaxZ + Eps) { + ptInt.z = dz1 ; + vtNormal = m_Values[0][nDexel][k].vtN ; + bFound = true ; + break ; + }*/ } if ( ! bFound) { ptInt.z = ( dMinZ + dMaxZ) / 2 ; @@ -1445,3 +2280,231 @@ VolZmap::IntersPos( int nVec1[], int nVec2[], Point3d& ptInt, Vector3d& vtNormal return true ; } + +//---------------------------------------------------------------------------- +bool +VolZmap::NewIntersPos( int nVec1[], int nVec2[], bool bFirstCorner, Point3d& ptInt, Vector3d& vtNormal) const +{ + double dEps = 2 * EPS_SMALL ; + + if ( nVec1[0] != nVec2[0]) { + + int nMinI = min( nVec1[0], nVec2[0]) ; + int nMaxI = max( nVec1[0], nVec2[0]) ; + + double dMinX = ( nMinI + 0.5) * m_dStep ; + double dMaxX = ( nMaxI + 0.5) * m_dStep ; + + ptInt.y = ( nVec1[1] + 0.5) * m_dStep ; + ptInt.z = ( nVec1[2] + 0.5) * m_dStep ; + + size_t nDexel = nVec1[2] * m_nNx[1] + nVec1[1] ; + size_t nSize = m_Values[1][nDexel].size() ; + + if ( bFirstCorner) { + + size_t n = nSize - 1 ; + double dX = m_Values[1][nDexel][n].dZVal ; + + while ( n > 0 && dX > dMinX - dEps) { + + if ( dX < dMaxX + dEps) { + + ptInt.x = dX ; + vtNormal = m_Values[1][nDexel][n].vtN ; + break ; + } + + if ( n == 1) + break ; + + n -= 2 ; + dX = m_Values[1][nDexel][n].dZVal ; + } + } + else { + + size_t n = 0 ; + double dX = m_Values[1][nDexel][0].dZVal ; + + while ( n <= nSize - 2 && dX < dMaxX + dEps) { + + if ( dX > dMinX - dEps) { + + ptInt.x = dX ; + vtNormal = m_Values[1][nDexel][n].vtN ; + break ; + } + + if ( n == nSize - 2) + break ; + + n += 2 ; + dX = m_Values[1][nDexel][n].dZVal ; + } + } + } + + else if ( nVec1[1] != nVec2[1]) { + + int nMinJ = min( nVec1[1], nVec2[1]) ; + int nMaxJ = max( nVec1[1], nVec2[1]) ; + + double dMinY = ( nMinJ + 0.5) * m_dStep ; + double dMaxY = ( nMaxJ + 0.5) * m_dStep ; + + ptInt.x = ( nVec1[0] + 0.5) * m_dStep ; + ptInt.z = ( nVec1[2] + 0.5) * m_dStep ; + + size_t nDexel = nVec1[0] * m_nNx[2] + nVec1[2] ; + size_t nSize = m_Values[2][nDexel].size() ; + + if ( bFirstCorner) { + + size_t n = nSize - 1 ; + double dY = m_Values[2][nDexel][n].dZVal ; + + while ( n > 0 && dY > dMinY - dEps) { + + if ( dY < dMaxY + dEps) { + + ptInt.y = dY ; + vtNormal = m_Values[2][nDexel][n].vtN ; + break ; + } + + if ( n == 1) + break ; + + n -= 2 ; + dY = m_Values[2][nDexel][n].dZVal ; + } + } + else { + + size_t n = 0 ; + double dY = m_Values[2][nDexel][0].dZVal ; + + while ( n <= nSize - 2 && dY < dMaxY + dEps) { + + if ( dY > dMinY - dEps) { + + ptInt.y = dY ; + vtNormal = m_Values[2][nDexel][n].vtN ; + break ; + } + + if ( n == nSize - 2) + break ; + + n += 2 ; + dY = m_Values[2][nDexel][n].dZVal ; + } + } + } + + else if ( nVec1[2] != nVec2[2]) { + + int nMinK = min( nVec1[2], nVec2[2]) ; + int nMaxK = max( nVec1[2], nVec2[2]) ; + + double dMinZ = ( nMinK + 0.5) * m_dStep ; + double dMaxZ = ( nMaxK + 0.5) * m_dStep ; + + ptInt.x = ( nVec1[0] + 0.5) * m_dStep ; + ptInt.y = ( nVec1[1] + 0.5) * m_dStep ; + + size_t nDexel = nVec1[1] * m_nNx[0] + nVec1[0] ; + size_t nSize = m_Values[0][nDexel].size() ; + + if ( bFirstCorner) { + + size_t n = nSize - 1 ; + double dZ = m_Values[0][nDexel][n].dZVal ; + + while ( n > 0 && dZ > dMinZ - dEps) { + + if ( dZ < dMaxZ + dEps) { + + ptInt.z = dZ ; + vtNormal = m_Values[0][nDexel][n].vtN ; + break ; + } + + if ( n == 1) + break ; + + n -= 2 ; + dZ = m_Values[0][nDexel][n].dZVal ; + } + } + else { + + size_t n = 0 ; + double dZ = m_Values[0][nDexel][0].dZVal ; + + while ( n <= nSize - 2 && dZ < dMaxZ + dEps) { + + if ( dZ > dMinZ - dEps) { + + ptInt.z = dZ ; + vtNormal = m_Values[0][nDexel][n].vtN ; + break ; + } + + if ( n == nSize - 2) + break ; + + n += 2 ; + dZ = m_Values[0][nDexel][n].dZVal ; + } + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::GetBlockIJK( int nIJK[], int nBlock) const +{ + // Controllo sulla validità del blocco + if ( nBlock < 0 || nBlock >= int( m_nNumBlock)) + return false ; + + // Calcolo posizione del blocco nel reticolo + nIJK[0] = ( nBlock % int( m_nFracLin[0] * m_nFracLin[1])) % int( m_nFracLin[0]) ; + nIJK[1] = ( nBlock % int( m_nFracLin[0] * m_nFracLin[1])) / int( m_nFracLin[0]) ; + nIJK[2] = ( nBlock / int( m_nFracLin[0] * m_nFracLin[1])) ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::GetBlockLimitsIJK( const int nIJK[], int nLimits[]) const +{ + // Controllo sulla validità degli indici i, j, k del blocco + if ( nIJK[0] < 0 || nIJK[0] >= int( m_nFracLin[0]) || + nIJK[1] < 0 || nIJK[1] >= int( m_nFracLin[1]) || + nIJK[2] < 0 || nIJK[2] >= int( m_nFracLin[2])) + + return false ; + + // Calcolo limiti per l'indice i + nLimits[0] = ( nIJK[0] == 0 ? - 1 : nIJK[0] * int( m_nDexNumPBlock)) ; + nLimits[1] = ( nIJK[0] + 1 == int( m_nFracLin[0]) ? + int( m_nNx[0]) : ( nIJK[0] + 1) * int( m_nDexNumPBlock)) ; + + // Calcolo limiti per l'indice j + nLimits[2] =( nIJK[1] == 0 ? - 1 : nIJK[1] * int( m_nDexNumPBlock)) ; + nLimits[3] = ( nIJK[1] + 1 == int( m_nFracLin[1]) ? + int( m_nNy[0]) : ( nIJK[1] + 1) * int( m_nDexNumPBlock)) ; + + // Calcolo limiti per l'indice k + nLimits[4] = ( nIJK[2] == 0 ? - 1 : nIJK[2] * int( m_nDexNumPBlock)) ; + nLimits[5] = ( nIJK[2] + 1 == int( m_nFracLin[2]) ? + int( m_nNy[1]) : ( nIJK[2] + 1) * int( m_nDexNumPBlock)) ; + + return true ; +} diff --git a/VolTriZmapVolume.cpp b/VolTriZmapVolume.cpp index be29a76..f8a4722 100644 --- a/VolTriZmapVolume.cpp +++ b/VolTriZmapVolume.cpp @@ -104,7 +104,7 @@ VolZmap::SubtractIntervals( unsigned int nGrid, unsigned int nI, unsigned int nJ m_Values[nGrid][nPos][i + 1].dZVal = dMin ; m_Values[nGrid][nPos][i + 2].dZVal = dMax ; - m_Values[nGrid][nPos][i + 1].vtN = vtNMin ; + m_Values[nGrid][nPos][i + 1].vtN = vtNmi ; m_Values[nGrid][nPos][i + 2].vtN = vtNma ; i = i + 2 ; @@ -149,34 +149,208 @@ VolZmap::SubtractIntervals( unsigned int nGrid, unsigned int nI, unsigned int nJ int nXBlock = min( nI / m_nDexNumPBlock, m_nFracLin[0] - 1) ; int nYBlock = min( nJ / m_nDexNumPBlock, m_nFracLin[1] - 1) ; - int nMinZBlock = max( 0, int( floor( ( dMin / m_dStep))) / int( m_nDexNumPBlock)) ; - int nMaxZBlock = min( int( m_nFracLin[2] - 1), int( floor( ( dMax / m_dStep))) / int( m_nDexNumPBlock)) ; - - for ( int k = nMinZBlock ; k <= nMaxZBlock ; ++ k) - m_BlockToUpdate[k * nLayerBlock + nYBlock * m_nFracLin[0] + nXBlock] = true ; + int nMinK = max( int( floor( ( ( dMin - 0.5 * m_dStep) / m_dStep - EPS_SMALL))), 0) ; + int nMaxK = max( int( floor( ( ( dMax + 0.5 * m_dStep) / m_dStep + EPS_SMALL))), 0) ; + + int nMinZBlock = max( 0, nMinK / int( m_nDexNumPBlock)) ; + int nMaxZBlock = min( int( m_nFracLin[2] - 1), nMaxK / int( m_nDexNumPBlock)) ; + + for ( int k = nMinZBlock ; k <= nMaxZBlock ; ++ k) { + for ( int nIndX = nXBlock - 1 ; nIndX <= nXBlock + 1 ; nIndX ++) { + for ( int nIndY = nYBlock - 1 ; nIndY <= nYBlock + 1 ; nIndY ++) { + + if ( nIndX >= 0 && nIndX < int( m_nFracLin[0]) && + nIndY >= 0 && nIndY < int( m_nFracLin[1])) { + + int nBlockNum = k * nLayerBlock + nIndY * m_nFracLin[0] + nIndX ; + m_BlockToUpdate[nBlockNum] = true ; + } + } + } + } + /* + // Blocco adiacente in X + if ( nXBlock > 0 && + ( nI % m_nDexNumPBlock == 0) && + ( nI / m_nDexNumPBlock <= m_nFracLin[0] - 1)) { + + int nAdjXBlock = nXBlock - 1 ; + + for ( int k = nMinZBlock ; k <= nMaxZBlock ; ++ k) { + + int nBlockNum = k * nLayerBlock + nYBlock * m_nFracLin[0] + nAdjXBlock ; + m_BlockToUpdate[nBlockNum] = true ; + } + } + // Blocco adiacente in Y + if ( nYBlock > 0 && + ( nJ % m_nDexNumPBlock == 0) && + ( nJ / m_nDexNumPBlock <= m_nFracLin[1] - 1)) { + + int nAdjYBlock = nYBlock - 1 ; + + for ( int k = nMinZBlock ; k <= nMaxZBlock ; ++ k) { + + int nBlockNum = k * nLayerBlock + nAdjYBlock * m_nFracLin[0] + nXBlock ; + m_BlockToUpdate[nBlockNum] = true ; + } + } + // Blocco adiacente in XY + if ( ( nXBlock > 0 && + ( nI % m_nDexNumPBlock == 0) && + ( nI / m_nDexNumPBlock <= m_nFracLin[0] - 1)) && + ( nYBlock > 0 && + ( nJ % m_nDexNumPBlock == 0) && + ( nJ / m_nDexNumPBlock <= m_nFracLin[1] - 1))) { + + int nAdjXBlock = nXBlock - 1 ; + int nAdjYBlock = nYBlock - 1 ; + + for ( int k = nMinZBlock ; k <= nMaxZBlock ; ++ k) { + + int nBlockNum = k * nLayerBlock + nAdjYBlock * m_nFracLin[0] + nAdjXBlock ; + m_BlockToUpdate[nBlockNum] = true ; + } + }*/ } else if ( nGrid == 1) { int nYBlock = min( nI / m_nDexNumPBlock, m_nFracLin[1] - 1) ; int nZBlock = min( nJ / m_nDexNumPBlock, m_nFracLin[2] - 1) ; - int nMinXBlock = max( 0, int( floor( ( dMin / m_dStep))) / int( m_nDexNumPBlock)) ; - int nMaxXBlock = min( int( m_nFracLin[0] - 1), int( floor( ( dMax / m_dStep))) / int( m_nDexNumPBlock)) ; - - for ( int k = nMinXBlock ; k <= nMaxXBlock ; ++ k) - m_BlockToUpdate[nZBlock * nLayerBlock + nYBlock * m_nFracLin[0] + k] = true ; + int nMinI = max( int( floor( ( ( dMin - 0.5 * m_dStep) / m_dStep - EPS_SMALL))), 0) ; + int nMaxI = max( int( floor( ( ( dMax + 0.5 * m_dStep) / m_dStep + EPS_SMALL))), 0) ; + + int nMinXBlock = max( 0, nMinI / int( m_nDexNumPBlock)) ; + int nMaxXBlock = min( int( m_nFracLin[0] - 1), nMaxI / int( m_nDexNumPBlock)) ; + + for ( int k = nMinXBlock ; k <= nMaxXBlock ; ++ k) { + for( int nIndY = nYBlock - 1 ; nIndY <= nYBlock + 1 ; ++ nIndY) { + for ( int nIndZ = nZBlock - 1 ; nIndZ <= nZBlock + 1 ; ++ nIndZ) { + + if ( nIndY >= 0 && nIndY < int( m_nFracLin[1]) && + nIndZ >= 0 && nIndZ < int( m_nFracLin[2])) { + + int nBlockNum = nIndZ * nLayerBlock + nIndY * m_nFracLin[0] + k ; + m_BlockToUpdate[nBlockNum] = true ; + } + } + } + } + /* + // Blocco adiacente in Y + if ( nYBlock > 0 && + ( nI % m_nDexNumPBlock == 0) && + ( nI / m_nDexNumPBlock <= m_nFracLin[1] - 1)) { + + int nAdjYBlock = nYBlock - 1 ; + + for ( int k = nMinXBlock ; k <= nMaxXBlock ; ++ k) { + + int nBlockNum = nZBlock * nLayerBlock + nAdjYBlock * m_nFracLin[0] + k ; + m_BlockToUpdate[nBlockNum] = true ; + } + } + // Blocco adiacente in Z + if ( nZBlock > 0 && + ( nJ % m_nDexNumPBlock == 0) && + ( nJ / m_nDexNumPBlock <= m_nFracLin[2] - 1)) { + + int nAdjZBlock = nZBlock - 1 ; + + for ( int k = nMinXBlock ; k <= nMaxXBlock ; ++ k) { + + int nBlockNum = nAdjZBlock * nLayerBlock + nYBlock * m_nFracLin[0] + k ; + m_BlockToUpdate[nBlockNum] = true ; + } + } + // Blocco adiacente in YZ + if ( ( nYBlock > 0 && + ( nI % m_nDexNumPBlock == 0) && + ( nI / m_nDexNumPBlock <= m_nFracLin[1] - 1)) && + ( nZBlock > 0 && + ( nJ % m_nDexNumPBlock == 0) && + ( nJ / m_nDexNumPBlock <= m_nFracLin[2] - 1))) { + + int nAdjYBlock = nYBlock - 1 ; + int nAdjZBlock = nZBlock - 1 ; + + for ( int k = nMinXBlock ; k <= nMaxXBlock ; ++ k) { + + int nBlockNum = nAdjZBlock * nLayerBlock + nAdjYBlock * m_nFracLin[0] + k ; + m_BlockToUpdate[nBlockNum] = true ; + } + } */ } else if ( nGrid == 2) { int nXBlock = min( nJ / m_nDexNumPBlock, m_nFracLin[0] - 1) ; int nZBlock = min( nI / m_nDexNumPBlock, m_nFracLin[2] - 1) ; - int nMinYBlock = max( 0, int( floor( ( dMin / m_dStep))) / int( m_nDexNumPBlock)) ; - int nMaxYBlock = min( int( m_nFracLin[1] - 1), int( floor( ( dMax / m_dStep))) / int( m_nDexNumPBlock)) ; - - for ( int k = nMinYBlock ; k <= nMaxYBlock ; ++ k) - m_BlockToUpdate[nZBlock * nLayerBlock + k * m_nFracLin[0] + nXBlock] = true ; + int nMinJ = max( int( floor( ( ( dMin - 0.5 * m_dStep) / m_dStep - EPS_SMALL))), 0) ; + int nMaxJ = max( int( floor( ( ( dMax + 0.5 * m_dStep) / m_dStep + EPS_SMALL))), 0) ; + + int nMinYBlock = max( 0, nMinJ / int( m_nDexNumPBlock)) ; + int nMaxYBlock = min( int( m_nFracLin[1] - 1), nMaxJ / int( m_nDexNumPBlock)) ; + + for ( int k = nMinYBlock ; k <= nMaxYBlock ; ++ k) { + for ( int nIndX = nXBlock - 1 ; nIndX <= nXBlock + 1 ; ++ nIndX) { + for ( int nIndZ = nZBlock - 1 ; nIndZ <= nZBlock + 1 ; ++ nIndZ) { + + if ( nIndX >= 0 && nIndX < int( m_nFracLin[0]) && + nIndZ >= 0 && nIndZ < int( m_nFracLin[2])) { + + int nBlockNum = nIndZ * nLayerBlock + k * m_nFracLin[0] + nIndX ; + m_BlockToUpdate[nBlockNum] = true ; + } + } + } + } + /* + // Blocchi adiacenti in X + if ( nXBlock > 0 && + ( nJ % m_nDexNumPBlock == 0) && + ( nJ / m_nDexNumPBlock <= m_nFracLin[0] - 1)) { + + int nAdjXBlock = nXBlock - 1 ; + + for ( int k = nMinYBlock ; k <= nMaxYBlock ; ++ k) { + + int nBlockNum = nZBlock * nLayerBlock + k * m_nFracLin[0] + nAdjXBlock ; + m_BlockToUpdate[nBlockNum] = true ; + } + } + // Blocchi adiacenti in Z + if ( nZBlock > 0 && + ( nI % m_nDexNumPBlock == 0) && + ( nI / m_nDexNumPBlock <= m_nFracLin[2] - 1)) { + + int nAdjZBlock = nZBlock - 1 ; + + for ( int k = nMinYBlock ; k <= nMaxYBlock ; ++ k) { + + int nBlockNum = nAdjZBlock * nLayerBlock + k * m_nFracLin[0] + nXBlock ; + m_BlockToUpdate[nBlockNum] = true ; + } + } + // Blocchi adiacenti in XZ + if ( ( nXBlock > 0 && + ( nJ % m_nDexNumPBlock == 0) && + ( nJ / m_nDexNumPBlock <= m_nFracLin[0] - 1)) && + ( nZBlock > 0 && + ( nI % m_nDexNumPBlock == 0) && + ( nI / m_nDexNumPBlock <= m_nFracLin[2] - 1))) { + + int nAdjXBlock = nXBlock - 1 ; + int nAdjZBlock = nZBlock - 1 ; + + for ( int k = nMinYBlock ; k <= nMaxYBlock ; ++ k) { + + int nBlockNum = nAdjZBlock * nLayerBlock + k * m_nFracLin[0] + nAdjXBlock ; + m_BlockToUpdate[nBlockNum] = true ; + } + }*/ } m_OGrMgr.Reset() ; @@ -715,8 +889,6 @@ VolZmap::CylBall_ZDrilling( unsigned int nGrid, const Point3d & ptS, const Point double dMinStemZ = min( min( ptS.z, ptTStemS.z), min( ptE.z, ptTStemE.z)) ; double dMaxStemZ = max( max( ptS.z, ptTStemS.z), max( ptE.z, ptTStemE.z)) ; - - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { for( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { @@ -730,7 +902,7 @@ VolZmap::CylBall_ZDrilling( unsigned int nGrid, const Point3d & ptS, const Point if ( dSqLen < dSqRad) // utensile cilindrico if ( m_nToolType == CylindricalMill) - SubtractIntervals( nGrid, i, j, dMinStemZ, dMaxStemZ, vtToolDir, - vtToolDir) ; + SubtractIntervals( nGrid, i, j, dMinStemZ, dMaxStemZ, Z_AX, - Z_AX) ; // utensile sferico else if ( m_nToolType == BallEndMill) { @@ -767,14 +939,16 @@ VolZmap::CylBall_ZPerp( unsigned int nGrid, const Point3d& ptS, const Point3d& p //Parametri geometrici dell'utensile double dStemHeigth = m_dHeight - m_dTipHeight ; double dSqRad = m_dRadius * m_dRadius ; - + double dSafeRad = m_dRadius - EPS_SMALL ; + double dSafeSqRad = dSafeRad * dSafeRad ; + // Punte del gambo Point3d ptTStemS = ptS - vtToolDir * dStemHeigth ; Point3d ptTStemE = ptE - vtToolDir * dStemHeigth ; // Quote estreme del gambo - double dMinStemZ = min( min( ptS.z, ptTStemS.z), min( ptE.z, ptTStemE.z)) ; - double dMaxStemZ = max( max( ptS.z, ptTStemS.z), max( ptS.z, ptTStemS.z)) ; + double dMinStemZ = min( ptS.z, ptTStemS.z) ; + double dMaxStemZ = max( ptS.z, ptTStemS.z) ; // Vettore movimento e sua lunghezza Vector3d vtMove = ptE - ptS ; double dLen = vtMove.LenXY() ; @@ -784,9 +958,12 @@ VolZmap::CylBall_ZPerp( unsigned int nGrid, const Point3d& ptS, const Point3d& p Vector3d vtV1 = vtMove ; vtV1.Normalize() ; // se |vtMove| < EPS è un buco con dz = 0 Vector3d vtV2 = vtV1 ; vtV2.Rotate( Z_AX, 90) ; + + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { for( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - + + double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptSxy ; @@ -796,43 +973,83 @@ VolZmap::CylBall_ZPerp( unsigned int nGrid, const Point3d& ptS, const Point3d& p // Utensile cilindrico if ( m_nToolType == CylindricalMill) { // Se il punto cade nella zona di interesse taglio - if ( ( dP1 * dP1 + dP2 * dP2 < dSqRad) || - ( ( dP1 - dLen) * ( dP1 - dLen) + dP2 * dP2) < dSqRad || - ( dP1 > 0 && dP1 < dLen && abs( dP2) < m_dRadius)) + if ( ( dP1 * dP1 + dP2 * dP2 < dSafeSqRad) || + ( ( dP1 - dLen) * ( dP1 - dLen) + dP2 * dP2) < dSafeSqRad || + ( dP1 > 0 && dP1 < dLen && abs( dP2) < dSafeRad)) - SubtractIntervals( nGrid, i, j, dMinStemZ, dMaxStemZ, V_NULL, V_NULL) ; + SubtractIntervals( nGrid, i, j, dMinStemZ, dMaxStemZ, Z_AX, - Z_AX) ; } // Utensile sferico else if ( m_nToolType == BallEndMill) { - - if ( dP1 < 0 && dP1 * dP1 + dP2 * dP2 < m_dRadius * m_dRadius) { - - double dH = sqrt( dSqRad - dP1 * dP1 - dP2 * dP2) ; - - if ( vtToolDir.z > 0) - SubtractIntervals( nGrid, i, j, dMinStemZ - dH, dMaxStemZ, V_NULL, V_NULL) ; - else - SubtractIntervals( nGrid, i, j, dMinStemZ, dMaxStemZ + dH, V_NULL, V_NULL) ; - } - else if ( dP1 > dLen && ( dP1 - dLen) * ( dP1 - dLen) + dP2 * dP2 < dSqRad) { - - double dH = sqrt( dSqRad - ( dP1 - dLen) * ( dP1 - dLen) - dP2 * dP2) ; - - if ( vtToolDir.z > 0) - SubtractIntervals( nGrid, i, j, dMinStemZ - dH, dMaxStemZ, V_NULL, V_NULL) ; - else - SubtractIntervals( nGrid, i, j, dMinStemZ, dMaxStemZ + dH, V_NULL, V_NULL) ; - } - else if ( dP1 > - EPS_SMALL && dP1 < dLen + EPS_SMALL && abs( dP2) < m_dRadius) { - double dH = sqrt( dSqRad - dP2 * dP2) ; - if ( vtToolDir.z > 0) - SubtractIntervals( nGrid, i, j, dMinStemZ - dH, dMaxStemZ, V_NULL, V_NULL) ; - else - SubtractIntervals( nGrid, i, j, dMinStemZ, dMaxStemZ + dH, V_NULL, V_NULL) ; - } - } + if ( abs( dP2) < dSafeRad) { + + if ( dP1 < 0) { + + if ( dP1 * dP1 + dP2 * dP2 < dSafeSqRad) { + + double dH = sqrt( dSafeSqRad - dP1 * dP1 - dP2 * dP2) ; + + if ( vtToolDir.z > 0) { + + Point3d ptInt( dX, dY, ptTStemS.z - dH) ; + Vector3d vtN = ptTStemS - ptInt ; + vtN.Normalize() ; + SubtractIntervals( nGrid, i, j, ptTStemS.z - dH, ptS.z, vtN, - Z_AX) ; + } + else { + + Point3d ptInt( dX, dY, ptTStemS.z + dH) ; + Vector3d vtN = ptTStemS - ptInt ; + vtN.Normalize() ; + SubtractIntervals( nGrid, i, j, ptS.z, ptTStemS.z + dH, Z_AX, vtN) ; + } + } + } + else if ( dP1 < dLen) { + + double dH = sqrt( dSafeSqRad - dP2 * dP2) ; + + if ( vtToolDir.z > 0) { + + Point3d ptInt( dX, dY, ptTStemS.z - dH) ; + Vector3d vtN = - ( ptInt - ptTStemS) + ( ptInt - ptTStemS) * vtV1 * vtV1 ; + vtN.Normalize() ; + SubtractIntervals( nGrid, i, j, ptTStemS.z - dH, ptS.z, vtN, - Z_AX) ; + } + else { + + Point3d ptInt( dX, dY, ptTStemS.z + dH) ; + Vector3d vtN = - ( ptInt - ptTStemS) + ( ptInt - ptTStemS) * vtV1 * vtV1 ; + vtN.Normalize() ; + SubtractIntervals( nGrid, i, j, ptS.z, ptTStemS.z + dH, Z_AX, vtN) ; + } + } + else { + + if ( ( dP1 - dLen) * ( dP1 - dLen) + dP2 * dP2 < dSafeSqRad) { + + double dH = sqrt( dSafeSqRad - ( dP1 - dLen) * ( dP1 - dLen) - dP2 * dP2) ; + + if ( vtToolDir.z > 0) { + + Point3d ptInt( dX, dY, ptTStemE.z - dH) ; + Vector3d vtN = ptTStemE - ptInt ; + vtN.Normalize() ; + SubtractIntervals( nGrid, i, j, ptTStemE.z - dH, ptS.z, vtN, - Z_AX) ; + } + else { + + Point3d ptInt( dX, dY, ptTStemE.z + dH) ; + Vector3d vtN = ptTStemE - ptInt ; + vtN.Normalize() ; + SubtractIntervals( nGrid, i, j, ptS.z, ptTStemE.z + dH, Z_AX, vtN) ; + } + } + } + } + } } } return true ; @@ -852,14 +1069,19 @@ VolZmap::CylBall_ZMilling( unsigned int nGrid, const Point3d & ptS, const Point3 // Parametri geometrici dell'utensile double dStemHeigth = m_dHeight - m_dTipHeight ; + double dSafeRadius = m_dRadius - EPS_SMALL ; double dSqRad = m_dRadius * m_dRadius ; - + double dSafeSqRad = dSqRad - 2 * m_dRadius * EPS_SMALL ; + // Studio delle simmetrie Point3d ptI = ( ptS.z < ptE.z ? ptS : ptE) ; Point3d ptF = ( ptS.z < ptE.z ? ptE : ptS) ; Point3d ptIT = ptI - vtToolDir * dStemHeigth ; Point3d ptFT = ptF - vtToolDir * dStemHeigth ; Point3d ptIxy( ptI.x, ptI.y, 0) ; + + Point3d ptIUp( ptI.x, ptI.y, max( ptI.z, ptIT.z)) ; + Point3d ptIDw( ptI.x, ptI.y, min( ptI.z, ptIT.z)) ; // Quote iniziali e finali massime e // minime del gambo dell'utensile e DeltaZ @@ -896,13 +1118,16 @@ VolZmap::CylBall_ZMilling( unsigned int nGrid, const Point3d & ptS, const Point3 vtV1.Normalize() ; // Definisco vtV2 vtV2 = vtV1 ; - vtV2.Rotate( Z_AX, 90) ; + vtV2.Rotate( Z_AX, 90) ; + + //Frame3d frNewFrame ; frNewFrame.Set( ptIT, vtMove) ; double dMin, dMax ; for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - + + double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; @@ -913,81 +1138,61 @@ VolZmap::CylBall_ZMilling( unsigned int nGrid, const Point3d & ptS, const Point3 double dX2 = vtC * vtV2 ; // Se il punto appartiene alla proiezione del volume spazzato valuto massimo e minimo - if ( ( dX1 > 0 && dX1 < dLenXY && abs( dX2) < m_dRadius) || - ( dX1 - dLenXY) * ( dX1 - dLenXY) + dX2 * dX2 < dSqRad || - dX1 * dX1 + dX2 * dX2 < dSqRad) { + if ( ( dX1 > 0 && dX1 < dLenXY && abs( dX2) < dSafeRadius) || + ( dX1 - dLenXY) * ( dX1 - dLenXY) + dX2 * dX2 < dSafeSqRad || + dX1 * dX1 + dX2 * dX2 < dSafeSqRad) { - if ( m_nToolType == CylindricalMill) { + + double dX1_0 = sqrt( dSqRad - dX2 * dX2) ; + + Vector3d vtNmin, vtNmax ; + + // Massimo + if ( ( dX1 - dLenXY) * ( dX1 - dLenXY) + dX2 * dX2 < dSqRad) { - double dX1_0 = sqrt( dSqRad - dX2 * dX2) ; - // Massimo - if ( ( dX1 - dLenXY) * ( dX1 - dLenXY) + dX2 * dX2 < dSqRad) - - dMax = dZMaxF ; - else - dMax = dZMaxI + dDeltaZ * ( dX1 + dX1_0) / dLenXY ; - // Minimo - if ( dX1 * dX1 + dX2 * dX2 < dSqRad) - - dMin = dZMinI ; - else - dMin = dZMinI + dDeltaZ * ( dX1 - dX1_0) / dLenXY ; - - SubtractIntervals( nGrid, i, j, dMin, dMax, V_NULL, V_NULL) ; + vtNmax = - Z_AX ; + dMax = dZMaxF ; } - else if ( m_nToolType == BallEndMill) { + else { - double dCylX1_0 = sqrt( dSqRad - dX2 * dX2) ; - double dSqRoot = sqrt( dSqRad - dX2 * dX2) ; - double dX1_0 = dCos * dSqRoot ; - double dH0 = dSin * dSqRoot ; - - if ( vtToolDir.z > 0) { - // Massimo - if ( ( dX1 - dLenXY) * ( dX1 - dLenXY) + dX2 * dX2 < dSqRad) + //vtNmax = - ( dX2 / dX1_0) * vtMove ^ vtV1 - vtMove ^ vtV2 ; + dMax = dZMaxI + dDeltaZ * ( dX1 + dX1_0) / dLenXY ; - dMax = dZMaxF ; - else - dMax = dZMaxI + dDeltaZ * ( dX1 + dCylX1_0) / dLenXY ; - - // Minimo - if ( dX1 < dX1_0) - - dMin = dZMinI - sqrt( dSqRad - dX1 * dX1 - dX2 * dX2) ; - - else if ( dX1 < dLenXY + dX1_0) - - dMin = dZMinI - dH0 + dDeltaZ * ( dX1 - dX1_0) / dLenXY ; - else - dMin = dZMinF - sqrt( dSqRad - ( dX1 - dLenXY) * ( dX1 - dLenXY) - dX2 * dX2) ; - - SubtractIntervals( nGrid, i, j, dMin, dMax, V_NULL, V_NULL) ; - } - else { - // Massimo - if ( dX1 < - dX1_0) - - dMax = dZMaxI + sqrt( dSqRad - dX1 * dX1 - dX2 * dX2) ; - - else if ( dX1 < dLenXY - dX1_0) - - dMax = dZMaxI + dH0 + dDeltaZ * ( dX1 - dX1_0) / dLenXY ; - else - dMax = dZMaxF + sqrt( dSqRad - ( dX1 - dLenXY) * ( dX1 - dLenXY) - dX2 * dX2) ; - - // Minimo - if ( dX1 * dX1 + dX2 * dX2 < dSqRad) - - dMin = dZMinI ; - else - dMin = dZMinI + dDeltaZ * ( dX2 - dCylX1_0) / dLenXY ; - - SubtractIntervals( nGrid, i, j, dMin, dMax, V_NULL, V_NULL) ; - } + Vector3d vtCirc = dX1_0 * vtV1 - dX2 * vtV2 ; // Punta verso il centro + Vector3d vtTan( - vtCirc.y, vtCirc.x, 0) ; // Tangente alla circonferenza + Vector3d vtCross = vtTan ^ vtMove ; + + vtNmax = ( vtCross * vtCirc > 0 ? vtCross : - vtCross) ; + vtNmax.Normalize() ; } + // Minimo + if ( dX1 * dX1 + dX2 * dX2 < dSqRad) { + + vtNmin = Z_AX ; + dMin = dZMinI ; + } + else { + + //vtNmin = - ( dX2 / dX1_0) * vtMove ^ vtV1 + vtMove ^ vtV2 ; + dMin = dZMinI + dDeltaZ * ( dX1 - dX1_0) / dLenXY ; + + Vector3d vtCirc = - dX1_0 * vtV1 - dX2 * vtV2 ; // Punta verso il centro + Vector3d vtTan( - vtCirc.y, vtCirc.x, 0) ; // Tangente alla circonferenza + Vector3d vtCross = vtTan ^ vtMove ; + + vtNmin = ( vtCross * vtCirc > 0 ? vtCross : - vtCross) ; + vtNmin.Normalize() ; + } + + SubtractIntervals( nGrid, i, j, dMin, dMax, vtNmin, vtNmax) ; } } } + + if ( m_nToolType == 2) + + CompBall_Milling( nGrid, ptIT, ptFT, m_dRadius) ; + return true ; } @@ -1020,8 +1225,13 @@ VolZmap::Conus_ZDrilling( unsigned int nGrid, const Point3d & ptS, const Point3d double dZMax = max( max( ptS.z, ptS.z - vtToolDir.z * m_dHeight), max( ptE.z, ptE.z - vtToolDir.z * m_dHeight)) ; double dZMin = min( min( ptS.z, ptS.z - vtToolDir.z * m_dHeight), min( ptE.z, ptE.z - vtToolDir.z * m_dHeight)) ; + // Parametri geometrici per + // determinare il vettore normale + double dL = m_dTipHeight * dMaxRad / dDeltaRad ; + // Trapano if ( m_dTipRadius < m_dRadius) { + // Ciclo sui punti for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { @@ -1036,23 +1246,46 @@ VolZmap::Conus_ZDrilling( unsigned int nGrid, const Point3d & ptS, const Point3d if ( dSqDist < dSqMinRad) - SubtractIntervals( nGrid, i, j, dZMin, dZMax, V_NULL, V_NULL) ; + SubtractIntervals( nGrid, i, j, dZMin, dZMax, Z_AX, - Z_AX) ; else if ( dSqDist < dSqMaxRad) { - + double dr = sqrt( dSqDist) ; + double dl = dr * dMaxRad / dL ; - if ( vtToolDir.z > 0) - - SubtractIntervals( nGrid, i, j, dZMin + m_dTipHeight * ( dr - dMinRad) / dDeltaRad, dZMax, V_NULL, V_NULL) ; - else - SubtractIntervals( nGrid, i, j, dZMin, dZMax - m_dTipHeight * ( dr - dMinRad) / dDeltaRad, V_NULL, V_NULL) ; + if ( vtToolDir.z > 0) { + + double dMin = dZMin + m_dTipHeight * ( dr - dMinRad) / dDeltaRad ; + double dMax = dZMax ; + + Point3d ptInt( dX, dY, dMin) ; + Point3d ptPn( ptO.x, ptO.y, dMin + dl) ; + + Vector3d vtNmin = ptPn - ptInt ; + vtNmin.Normalize() ; + + SubtractIntervals( nGrid, i, j, dMin, dMax, vtNmin, - Z_AX) ; + } + else { + + double dMin = dZMin ; + double dMax = dZMax - m_dTipHeight * ( dr - dMinRad) / dDeltaRad ; + + Point3d ptInt( dX, dY, dMax) ; + Point3d ptPn( ptO.x, ptO.y, dMax - dl) ; + + Vector3d vtNmax = ptPn - ptInt ; + vtNmax.Normalize() ; + + SubtractIntervals( nGrid, i, j, dMin, dMax, Z_AX, vtNmax) ; + } } } } } // Coda di rondine else { + // Ciclo sui punti for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { @@ -1064,20 +1297,42 @@ VolZmap::Conus_ZDrilling( unsigned int nGrid, const Point3d & ptS, const Point3d Vector3d vtC = ptC - ptO ; double dSqDist = vtC.SqLenXY() ; + + if ( dSqDist < dSqMinRad) { - if ( dSqDist < dSqMinRad) - - SubtractIntervals( nGrid, i, j, dZMin, dZMax, V_NULL, V_NULL) ; - + SubtractIntervals( nGrid, i, j, dZMin, dZMax, Z_AX, - Z_AX) ; + } else if ( dSqDist < dSqMaxRad) { double dr = sqrt( dSqDist) ; + double dl = dr * dMaxRad / dL ; - if ( vtToolDir.z > 0) + if ( vtToolDir.z > 0) { + + double dMin = dZMin ; + double dMax = dZMax - dStemHeigth - m_dTipHeight * ( dr - dMinRad) / dDeltaRad ; + + Point3d ptInt( dX, dY, dMax) ; + Point3d ptPn( ptO.x, ptO.y, dMax - dl) ; + + Vector3d vtNmax = ptPn - ptInt ; + vtNmax.Normalize() ; - SubtractIntervals( nGrid, i, j, dZMin, dZMax - dStemHeigth - m_dTipHeight * ( dr - dMinRad) / dDeltaRad, V_NULL, V_NULL) ; - else - SubtractIntervals( nGrid, i, j, dZMin + dStemHeigth + m_dTipHeight * ( dr - dMinRad) / dDeltaRad, dZMax, V_NULL, V_NULL) ; + SubtractIntervals( nGrid, i, j, dMin, dMax, Z_AX, vtNmax) ; + } + else { + + double dMin = dZMin + dStemHeigth + m_dTipHeight * ( dr - dMinRad) / dDeltaRad ; + double dMax = dZMax ; + + Point3d ptInt( dX, dY, dMin) ; + Point3d ptPn( ptO.x, ptO.y, dMin + dl) ; + + Vector3d vtNmin = ptPn - ptInt ; + vtNmin.Normalize() ; + + SubtractIntervals( nGrid, i, j, dMin, dMax, vtNmin, - Z_AX) ; + } } } } @@ -1100,630 +1355,382 @@ VolZmap::Conus_ZPerp( unsigned int nGrid, const Point3d & ptS, const Point3d & p // Parametri geometrici dell'utensile double dStemHeigth = m_dHeight - m_dTipHeight ; double dMinRad = min( m_dRadius, m_dTipRadius) ; - double dMaxRad = max( m_dRadius, m_dTipRadius) ; + double dMaxRad = max( m_dRadius, m_dTipRadius) ; double dDeltaRad = dMaxRad - dMinRad ; double dSqMinRad = dMinRad * dMinRad ; double dSqMaxRad = dMaxRad * dMaxRad ; - // Quote fondo, punta e fine gambo - double dBaseZ = ptS.z ; - double dTipZ = ptS.z - m_dHeight * vtToolDir.z ; - double dStemZ = ptS.z - dStemHeigth * vtToolDir.z ; - double dZ1 = ( m_dRadius > m_dTipRadius ? dBaseZ : dTipZ) ; - double dZ2 = ( m_dRadius > m_dTipRadius ? dTipZ : dStemZ) ; - double dZ3 = ( m_dRadius > m_dTipRadius ? dStemZ : dTipZ) ; + double dSafeMinRad = dMinRad - EPS_SMALL ; + double dSafeMaxRad = dMaxRad - EPS_SMALL ; + double dSafeSqMaxRad = dSafeMaxRad * dSafeMaxRad ; + double dSafeSqMinRad = dSafeMinRad * dSafeMinRad ; - - // Sistemi di riferimento sul piano - Point3d ptIxy( ptS.x, ptS.y, 0) ; - Point3d ptFxy( ptE.x, ptE.y, 0) ; - Vector3d vtV1 = ptFxy - ptIxy ; - double dLenXY = vtV1.LenXY() ; + + Point3d ptSxy( ptS.x, ptS.y, 0) ; + Point3d ptExy( ptE.x, ptE.y, 0) ; + + Vector3d vtV1( ptE.x - ptS.x, ptE.y - ptS.y, 0) ; + Vector3d vtV2( - vtV1.y, vtV1.x, 0) ; + + double dLen = vtV1.LenXY() ; + vtV1.Normalize() ; - Vector3d vtV2 = vtV1 ; - vtV2.Rotate( Z_AX, 90) ; + vtV2.Normalize() ; + double dBaseZ = ptS.z ; + double dStemZ = ptS.z - vtToolDir.z * dStemHeigth ; + double dTipZ = ptS.z - vtToolDir.z * m_dHeight ; - // Ciclo sui punti - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - double dX = ( i + 0.5) * m_dStep ; - double dY = ( j + 0.5) * m_dStep ; + // Lunghezza cono + double dL = m_dTipHeight * dMaxRad / dDeltaRad ; - Point3d ptC( dX, dY, 0) ; - Vector3d vtCI = ptC - ptIxy ; - Vector3d vtCF = ptC - ptFxy ; + - double dSqDistI = vtCI.SqLenXY() ; - double dSqDistF = vtCF.SqLenXY() ; + // Punta a trapano + if ( m_dTipRadius < m_dRadius) { - double dX1 = vtCI * vtV1 ; - double dX2 = vtCI * vtV2 ; + double dMin, dMax ; + Vector3d vtV = vtToolDir ; - if ( dSqDistI < dSqMinRad || dSqDistF < dSqMinRad || - ( dX1 > 0 && dX1 < dLenXY && abs( dX2) < dMinRad)) - - SubtractIntervals( nGrid, i, j, min( dBaseZ, dTipZ), max( dBaseZ, dTipZ), V_NULL, V_NULL) ; - - else if ( dSqDistI < dSqMaxRad && dX1 < 0) { - - double dr = sqrt( dSqDistI) ; + Point3d ptVS = ptS - vtToolDir * ( dStemHeigth + dL) ; + Point3d ptVE = ptE - vtToolDir * ( dStemHeigth + dL) ; + + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { + for( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - SubtractIntervals( nGrid, i, j, min( dZ1, dZ2 + ( dr - dMinRad) * ( dZ3 - dZ2) / dDeltaRad), - max( dZ1, dZ2 + ( dr - dMinRad) * ( dZ3 - dZ2) / dDeltaRad), V_NULL, V_NULL) ; - } - else if ( dX1 <= dLenXY && abs( dX2) < dMaxRad) { + double dX = ( i + 0.5) * m_dStep ; + double dY = ( j + 0.5) * m_dStep ; - double dr = abs( dX2) ; + Point3d ptC( dX, dY, 0) ; - SubtractIntervals( nGrid, i, j, min( dZ1, dZ2 + ( dr - dMinRad) * ( dZ3 - dZ2) / dDeltaRad), - max( dZ1, dZ2 + ( dr - dMinRad) * ( dZ3 - dZ2) / dDeltaRad), V_NULL, V_NULL) ; + Vector3d vtCS = ptC - ptSxy ; + Vector3d vtCE = ptC - ptExy ; + + double dP1 = vtCS * vtV1 ; + double dP2 = vtCS * vtV2 ; + + double dSqLenS = vtCS.SqLenXY() ; + double dSqLenE = vtCE.SqLenXY() ; + + if ( dSqLenS < dSafeSqMaxRad || dSqLenE < dSafeSqMaxRad || + ( abs( dP2) < dSafeMaxRad && dP1 >= 0 && dP1 <= dLen)) { + + if ( dSqLenS < dSqMinRad || dSqLenE < dSqMinRad || + ( abs( dP2) < dMinRad && dP1 >= 0 && dP1 <= dLen)) { + + dMin = min( dBaseZ, dTipZ) ; + dMax = max( dBaseZ, dTipZ) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax, Z_AX, - Z_AX) ; + } + else { + + Vector3d vtNmin, vtNmax ; + + if ( dP1 < 0) { + + double dr = sqrt( dSqLenS) ; + + dMin = min( dBaseZ, dTipZ + ( dStemZ - dTipZ) * ( dr - dMinRad) / dDeltaRad) ; + dMax = max( dBaseZ, dTipZ + ( dStemZ - dTipZ) * ( dr - dMinRad) / dDeltaRad) ; + + + + if ( vtToolDir.z > 0) { + + Point3d ptInt( dX, dY, dMin) ; + + Vector3d vtU = ( ptInt - ptVS) - ( ptInt - ptVS) * vtV * vtV ; + + vtU.Normalize() ; + + vtNmin = dDeltaRad * vtV - m_dTipHeight * vtU ; + vtNmin.Normalize() ; + vtNmax = - Z_AX ; + } + else { + + Point3d ptInt( dX, dY, dMax) ; + + Vector3d vtU = ( ptInt - ptVS) - ( ptInt - ptVS) * vtV * vtV ; + + vtU.Normalize() ; + + vtNmin = Z_AX ; + vtNmax = dDeltaRad * vtV - m_dTipHeight * vtU ; + vtNmax.Normalize() ; + } + + SubtractIntervals( nGrid, i, j, dMin, dMax, vtNmin, vtNmax) ; + } + else if ( dP1 <= dLen) { + + double dr = abs( dP2) ; + + dMin = min( dBaseZ, dTipZ + ( dStemZ - dTipZ) * ( dr - dMinRad) / dDeltaRad) ; + dMax = max( dBaseZ, dTipZ + ( dStemZ - dTipZ) * ( dr - dMinRad) / dDeltaRad) ; + + + Point3d ptVtemp = ptVS + vtV1 * dP1 ; + + if ( vtToolDir.z > 0) { + + Point3d ptInt( dX, dY, dMin) ; + + Vector3d vtU = ( ptInt - ptVtemp) - ( ptInt - ptVtemp) * vtV * vtV ; + + vtU.Normalize() ; + + vtNmin = dDeltaRad * vtV - m_dTipHeight * vtU ; + vtNmin.Normalize() ; + vtNmax = - Z_AX ; + } + else { + + Point3d ptInt( dX, dY, dMax) ; + + Vector3d vtU = ( ptInt - ptVtemp) - ( ptInt - ptVtemp) * vtV * vtV ; + + vtU.Normalize() ; + + vtNmin = Z_AX ; + + vtNmax = dDeltaRad * vtV - m_dTipHeight * vtU ; + vtNmax.Normalize() ; + } + + SubtractIntervals( nGrid, i, j, dMin, dMax, vtNmin, vtNmax) ; + } + else { + + double dr = sqrt( dSqLenE) ; + + dMin = min( dBaseZ, dTipZ + ( dStemZ - dTipZ) * ( dr - dMinRad) / dDeltaRad) ; + dMax = max( dBaseZ, dTipZ + ( dStemZ - dTipZ) * ( dr - dMinRad) / dDeltaRad) ; + + + if ( vtToolDir.z > 0) { + + Point3d ptInt( dX, dY, dMin) ; + + Vector3d vtU = ( ptInt - ptVE) - ( ptInt - ptVE) * vtV * vtV ; + + vtU.Normalize() ; + + vtNmin = dDeltaRad * vtV - m_dTipHeight * vtU ; + vtNmin.Normalize() ; + vtNmax = -Z_AX ; + + } + else { + + Point3d ptInt( dX, dY, dMax) ; + + Vector3d vtU = ( ptInt - ptVE) - ( ptInt - ptVE) * vtV * vtV ; + + vtU.Normalize() ; + + vtNmin = Z_AX ; + + vtNmax = dDeltaRad * vtV - m_dTipHeight * vtU ; + vtNmax.Normalize() ; + } + + SubtractIntervals( nGrid, i, j, dMin, dMax, vtNmin, vtNmax) ; + } + } + } } - else if ( dSqDistF < dSqMaxRad) { + } + } + // Coda di rondine + else { - double dr = sqrt( dSqDistF) ; + double dMin, dMax ; - SubtractIntervals( nGrid, i, j, min( dZ1, dZ2 + ( dr - dMinRad) * ( dZ3 - dZ2) / dDeltaRad), - max( dZ1, dZ2 + ( dr - dMinRad) * ( dZ3 - dZ2) / dDeltaRad), V_NULL, V_NULL) ; + Vector3d vtV = - vtToolDir ; + + Point3d ptVS = ptS - vtToolDir * ( m_dHeight - dL) ; + Point3d ptVE = ptE - vtToolDir * ( m_dHeight - dL) ; + + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { + for( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + + double dX = ( i + 0.5) * m_dStep ; + double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; + + Vector3d vtCS = ptC - ptSxy ; + Vector3d vtCE = ptC - ptExy ; + + double dP1 = vtCS * vtV1 ; + double dP2 = vtCS * vtV2 ; + + double dSqLenS = vtCS.SqLenXY() ; + double dSqLenE = vtCE.SqLenXY() ; + + if ( dSqLenS < dSqMaxRad || dSqLenE < dSqMaxRad || + ( abs( dP2) < dMaxRad && dP1 >= 0 && dP1 <= dLen)) { + + if ( dSqLenS < dSafeSqMinRad || dSqLenE < dSafeSqMinRad || + ( abs( dP2) < dSafeMinRad && dP1 >= 0 && dP1 <= dLen)) { + + dMin = min( dBaseZ, dTipZ) ; + dMax = max( dBaseZ, dTipZ) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax, Z_AX, - Z_AX) ; + } + else { + + Vector3d vtNmin, vtNmax ; + + if ( dP1 < 0) { + + double dr = sqrt( dSqLenS) ; + + dMin = min( dTipZ, dStemZ + ( dTipZ - dStemZ) * ( dr - dMinRad) / dDeltaRad) ; + dMax = max( dTipZ, dStemZ + ( dTipZ - dStemZ) * ( dr - dMinRad) / dDeltaRad) ; + + if ( vtToolDir.z > 0) { + + Point3d ptInt( dX, dY, dMax) ; + + Vector3d vtU = ( ptInt - ptVS) - ( ptInt - ptVS) * vtV * vtV ; + vtU.Normalize() ; + + vtNmin = Z_AX ; + + vtNmax = dDeltaRad * vtV - m_dTipHeight * vtU ; + + vtNmax.Normalize() ; + + } + else { + + Point3d ptInt( dX, dY, dMin) ; + + Vector3d vtU = ( ptInt - ptVS) - ( ptInt - ptVS) * vtV * vtV ; + vtU.Normalize() ; + + vtNmax = -Z_AX ; + + vtNmin = dDeltaRad * vtV - m_dTipHeight * vtU ; + + vtNmin.Normalize() ; + } + + SubtractIntervals( nGrid, i, j, dMin, dMax, vtNmin, vtNmax) ; + + } + else if ( dP1 <= dLen) { + + double dr = abs( dP2) ; + + Point3d ptVtemp = ptVS + vtV1 * dP1 ; + + dMin = min( dTipZ, dStemZ + ( dTipZ - dStemZ) * ( dr - dMinRad) / dDeltaRad) ; + dMax = max( dTipZ, dStemZ + ( dTipZ - dStemZ) * ( dr - dMinRad) / dDeltaRad) ; + + if ( vtToolDir.z > 0) { + + Point3d ptInt( dX, dY, dMax) ; + + Vector3d vtU = ( ptInt - ptVtemp) - ( ptInt - ptVtemp) * vtV * vtV ; + vtU.Normalize() ; + + vtNmin = Z_AX ; + + vtNmax = dDeltaRad * vtV - m_dTipHeight * vtU ; + + vtNmax.Normalize() ; + } + else { + + Point3d ptInt( dX, dY, dMin) ; + + Vector3d vtU = ( ptInt - ptVtemp) - ( ptInt - ptVtemp) * vtV * vtV ; + vtU.Normalize() ; + + vtNmax = -Z_AX ; + + vtNmin = dDeltaRad * vtV - m_dTipHeight * vtU ; + + vtNmin.Normalize() ; + } + + SubtractIntervals( nGrid, i, j, dMin, dMax, vtNmin, vtNmax) ; + } + else { + + double dr = sqrt( dSqLenE) ; + + dMin = min( dTipZ, dStemZ + ( dTipZ - dStemZ) * ( dr - dMinRad) / dDeltaRad) ; + dMax = max( dTipZ, dStemZ + ( dTipZ - dStemZ) * ( dr - dMinRad) / dDeltaRad) ; + + if ( vtToolDir.z > 0) { + + Point3d ptInt( dX, dY, dMax) ; + + Vector3d vtU = ( ptInt - ptVE) - ( ptInt - ptVE) * vtV * vtV ; + vtU.Normalize() ; + + vtNmin = Z_AX ; + + vtNmax = dDeltaRad * vtV - m_dTipHeight * vtU ; + + vtNmax.Normalize() ; + + } + else { + + Point3d ptInt( dX, dY, dMin) ; + + Vector3d vtU = ( ptInt - ptVE) - ( ptInt - ptVE) * vtV * vtV ; + vtU.Normalize() ; + + vtNmax = -Z_AX ; + + vtNmin = dDeltaRad * vtV - m_dTipHeight * vtU ; + + vtNmin.Normalize() ; + } + + SubtractIntervals( nGrid, i, j, dMin, dMax, vtNmin, vtNmax) ; + } + } + } } } } return true ; -} +} //---------------------------------------------------------------------------- bool VolZmap::Conus_ZMilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) { - if ( m_dTipRadius < m_dRadius) - Dr_ZMilling( nGrid, ptS, ptE, vtToolDir) ; - else - Sw_ZMilling( nGrid, ptS, ptE, vtToolDir) ; + double dStemH = m_dHeight - m_dTipHeight ; - return true ; -} + CompCyl_ZMilling( nGrid, ptS, ptE, vtToolDir, dStemH, m_dRadius) ; -//---------------------------------------------------------------------------- -bool -VolZmap::Dr_ZMilling( unsigned int nGrid, const Point3d & ptLs, const Point3d & ptLe, const Vector3d & vtToolDir) -{ - unsigned int nStartI, nStartJ, nEndI, nEndJ ; - - // Verifica sull'interferenza dell'utensile con lo Zmap - bool bTest = BoundingBox( nGrid, ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ; - - if ( ! bTest) - return true ; - - // Punti iniziale e finale e proiezione sul piano del punto iniziale - Point3d ptI, ptF, ptO ; - - if ( vtToolDir.z > 0) { - ptI = ( ptLs.z < ptLe.z ? ptLs : ptLe) ; ptO.x = ptI.x ; ptO.y = ptI.y ; ptO.z = 0 ; - ptF = ( ptLs.z < ptLe.z ? ptLe : ptLs) ; - } - else { - ptI = ( ptLs.z < ptLe.z ? ptLe : ptLs) ; ptO.x = ptI.x ; ptO.y = ptI.y ; ptO.z = 0 ; - ptF = ( ptLs.z < ptLe.z ? ptLs : ptLe) ; - } - - // Raggio minimo e massimo - double dMaxRad = max( m_dRadius, m_dTipRadius) ; - double dMinRad = min( m_dRadius, m_dTipRadius) ; - - // Quote iniziale e finale della base dell'utensile e DeltaZ - double dZI = ptI.z ; - double dZF = ptF.z ; - double dDeltaZ = dZF - dZI ; - - - // Vettori di movimento - Vector3d vtMove = ptF - ptI ; - Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ; double dLen = vtMoveXY.LenXY() ; - - // Sistema di riferimento sul cono e vertice del cono - Vector3d vtV1 = vtToolDir ; - Vector3d vtV2 = vtMoveXY ; vtV2.Normalize() ; - Vector3d vtV3 = vtV1 ^ vtV2 ; - Point3d ptV = ptI - ( m_dHeight + m_dTipHeight * dMinRad / ( dMaxRad - dMinRad)) * vtV1 ; - - // Apertura del cono e parametri per determinare i piani - double dTanAlpha = ( dMaxRad - dMinRad) / m_dTipHeight ; - double dRatio = ( vtMove * vtV1) / ( vtMove * vtV2) ; - - double dCos = dTanAlpha * dRatio ; - double dSin = ( abs( dCos) < 1 ? sqrt( 1 - dCos * dCos) : 0) ; + if ( m_dTipRadius < m_dRadius) { - double dDen = sqrt( 1 + dTanAlpha * dTanAlpha) ; - - // Versori normali e prodotti scalari per per determinare i piani - Vector3d vtNs = - ( dTanAlpha / dDen) * vtV1 + - ( dCos / dDen) * vtV2 + - ( dSin / dDen) * vtV3 ; - Vector3d vtNd = - ( dTanAlpha / dDen) * vtV1 + - ( dCos / dDen) * vtV2 - - ( dSin / dDen) * vtV3 ; + Point3d ptSC = ptS - vtToolDir * dStemH ; + Point3d ptEC = ptE - vtToolDir * dStemH ; - Vector3d vtR0 = ptV - ORIG ; - double dDots = vtR0 * vtNs ; - double dDotd = vtR0 * vtNd ; - - - - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - // Grandezze per determinare la configurazione geometrica dell'utensile - double dMin, dMax ; - double dX = ( i + 0.5) * m_dStep ; - double dY = ( j + 0.5) * m_dStep ; - - Point3d ptC( dX, dY, 0) ; - Vector3d vtC = ptC - ptO ; - Vector3d vtCf = vtC - vtMoveXY ; - - Vector3d vtUC = vtC ; vtUC.Normalize() ; - Vector3d vtUCf = vtCf ; vtUCf.Normalize() ; - - double dCCos = vtUC * vtV2 ; - double dCCosf = vtUCf * vtV2 ; - - double dProj = vtC * vtV2 ; - Vector3d vtOrt = vtC - dProj * vtV2 ; - - double dSqDistI = vtC * vtC ; - double dSqDistM = vtOrt * vtOrt ; - double dSqDistF = vtCf * vtCf ; - - // Se dentro la zona interessata dalla lavorazione valuto - // la tipologia di tale zona - if ( ( dProj < 0 && dSqDistI < dMaxRad * dMaxRad) || - ( dProj >= 0 && dProj < dLen && dSqDistM < dMaxRad * dMaxRad) || - ( dProj >= dLen && dSqDistF < dMaxRad * dMaxRad)) { - - // Caso vettore utensile equiverso all'asse Z - if ( vtToolDir.z > 0) { - // Massimi - double dPMaxI = ( dMaxRad * dMaxRad - dSqDistM > 0 ? sqrt( dMaxRad * dMaxRad - dSqDistM) : 0) ; - - if ( dProj < dLen - dPMaxI) - - dMax = dZI + ( dDeltaZ / dLen) * ( dProj + dPMaxI) ; - else - dMax = dZF ; - - // Minimi - if ( dSqDistI < dMinRad * dMinRad) - - dMin = dZI - m_dHeight ; - - else { - - if ( ( vtMove * vtV1) / ( vtMove * vtV2) <= 1 / dTanAlpha) { - - if ( dSqDistI < dMaxRad * dMaxRad && dCCos < dCos) - - dMin = dZI - m_dHeight + ( ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight) / ( dMaxRad - dMinRad) ; - - else if ( dCCos >= dCos && dCCosf < dCos && dSqDistM < dMaxRad * dMaxRad * ( 1 - dCos * dCos)) { - - double dMinSql = dMinRad * dMinRad * ( 1 - dCos * dCos) ; - double dMaxSql = dMaxRad * dMaxRad * ( 1 - dCos * dCos) ; - double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; - - if ( dSqDistM <= dMinSql) - - dMin = dZI - m_dHeight + ( dProj - dPMinI) * dDeltaZ / dLen ; - - else if ( dSqDistM < dMaxSql) { - - if ( vtC * vtV3 > 0) - - dMin = ( dDots - dX * vtNs.x - dY * vtNs.y) / vtNs.z ; - else - dMin = ( dDotd - dX * vtNd.x - dY * vtNd.y) / vtNd.z ; - } - } - else if ( dCCosf >= dCos) { - - double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; - - if ( dSqDistF < dMinRad * dMinRad) - - dMin = dZI - m_dHeight + ( dProj - dPMinI) * dDeltaZ / dLen ; - else - dMin = dZF - m_dHeight + ( ( sqrt( dSqDistF) - dMinRad) * m_dTipHeight) / ( dMaxRad - dMinRad) ; - } - else - - dMin = dZI - m_dHeight + m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; - } - else { - - if ( dSqDistI < dMaxRad * dMaxRad) - - dMin = dZI - m_dHeight + ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight / ( dMaxRad - dMinRad) ; - - else if ( dProj >= dPMaxI && dProj < dPMaxI + dLen) - - dMin = dZI - m_dHeight + m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; - } - } - } - // Caso vettore utensile opposto all'asse Z - else { - // Massimi - double dPMaxI = ( dMaxRad * dMaxRad - dSqDistM > 0 ? sqrt( dMaxRad * dMaxRad - dSqDistM) : 0) ; - - if ( dSqDistI < dMinRad * dMinRad) - - dMax = dZI + m_dHeight ; - - else { - - if ( - ( vtMove * vtV1) / ( vtMove * vtV2) <= 1 / dTanAlpha) { - - if ( dSqDistI < dMaxRad * dMaxRad && dCCos < dCos) - - dMax = dZI + m_dHeight - ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight / ( dMaxRad - dMinRad) ; - - else if ( dCCos >= dCos && dCCosf < dCos && dSqDistM < dMaxRad * dMaxRad * ( 1 - dCos * dCos)) { - - double dMinSql = dMinRad * dMinRad * ( 1 - dCos * dCos) ; - double dMaxSql = dMaxRad * dMaxRad * ( 1 - dCos * dCos) ; - double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; - - if ( dSqDistM <= dMinSql) - - dMax = dZI + m_dHeight + ( dProj - dPMinI) * dDeltaZ / dLen ; - - else if ( dSqDistM < dMaxSql) { - - if ( vtC * vtV3 > 0) - - dMax = ( dDots - dX * vtNs.x - dY * vtNs.y) / vtNs.z ; - else - dMax = ( dDotd - dX * vtNd.x - dY * vtNd.y) / vtNd.z ; - } - } - else if ( dCCosf >= dCos) { - - double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; - - if ( dSqDistF < dMinRad * dMinRad) - - dMax = dZI + m_dHeight + ( dProj - dPMinI) * dDeltaZ / dLen ; - else - dMax = dZF + m_dHeight - ( ( sqrt( dSqDistF) - dMinRad) * m_dTipHeight) / ( dMaxRad - dMinRad) ; - } - else - - dMax = dZI + m_dHeight - m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; - - } - else { - - if ( dSqDistI < dMaxRad * dMaxRad) - - dMax = dZI + m_dHeight - ( ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight) / ( dMaxRad - dMinRad) ; - - else if ( dProj >= dPMaxI && dProj < dPMaxI + dLen) - - dMax = dZI + m_dHeight - m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; - - } - } - // Minimi - double dPMaxCirc = sqrt( dMaxRad * dMaxRad - dSqDistM) ; - - if ( dProj > dLen - dPMaxCirc) - dMin = dZF ; - else - dMin = dZI + ( dDeltaZ / dLen) * ( dProj + dPMaxCirc) ; - } - SubtractIntervals( nGrid, i, j, dMin, dMax, V_NULL, V_NULL) ; - } - } + CompConus_ZMilling( nGrid, ptSC, ptEC, vtToolDir, m_dTipHeight, m_dRadius, m_dTipRadius) ; } - - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::Sw_ZMilling( unsigned int nGrid, const Point3d & ptLs, const Point3d & ptLe, const Vector3d & vtToolDir) -{ - unsigned int nStartI, nStartJ, nEndI, nEndJ ; - - // Verifica sull'interferenza dell'utensile con lo Zmap - bool bTest = BoundingBox( nGrid, ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ; - - if ( ! bTest) - return true ; - - // Punti iniziale e finale e proiezione sul piano del punto iniziale - Point3d ptI, ptF, ptO ; - - if ( vtToolDir.z > 0) { - - ptI = ( ptLs.z < ptLe.z ? ptLe : ptLs) ; ptO.x = ptI.x ; ptO.y = ptI.y ; ptO.z = 0 ; - ptF = ( ptLs.z < ptLe.z ? ptLs : ptLe) ; - } - else { - ptI = ( ptLs.z < ptLe.z ? ptLs : ptLe) ; ptO.x = ptI.x ; ptO.y = ptI.y ; ptO.z = 0 ; - ptF = ( ptLs.z < ptLe.z ? ptLe : ptLs) ; - } - - Point3d ptICyl = ( ptLs.z < ptLe.z ? ptLs : ptLe) ; - - double dMaxRad = max( m_dRadius, m_dTipRadius) ; - double dMinRad = min( m_dRadius, m_dTipRadius) ; - double dDeltaH = m_dHeight - m_dTipHeight ; - double dMinZCyl = min( ptICyl.z, ptICyl.z - vtToolDir.z * dDeltaH) ; - - // Punti contatto cono cilindro - Point3d ptIS = ptI - ( m_dHeight - m_dTipHeight) * vtToolDir ; - Point3d ptFS = ptF - ( m_dHeight - m_dTipHeight) * vtToolDir ; - - // Quote iniziali e finali e DeltaZ - double dZI = ptI.z ; double dZF = ptF.z ; - double dDeltaZ = dZF - dZI ; double dADeltaZ = abs( dDeltaZ) ; - double dZIS = ptIS.z ; double dZFS = ptFS.z ; - - // Vettori di movimento - Vector3d vtMove = ptF - ptI ; - Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ; double dLen = vtMoveXY.LenXY() ; - - // Sistema di riferimento sul cono e vertice del cono - Vector3d vtV1 = - vtToolDir ; - Vector3d vtV2 = vtMoveXY ; vtV2.Normalize() ; - Vector3d vtV3 = vtV1 ^ vtV2 ; - Point3d ptV = ptI + ( m_dHeight - m_dTipHeight * ( 1 + dMinRad / ( dMaxRad - dMinRad))) * vtV1 ; - - // Apertura del cono e parametri per determinare i piani - double dTanAlpha = ( dMaxRad - dMinRad) / m_dTipHeight ; - double dRatio = ( vtMove * vtV1) / ( vtMove * vtV2) ; - - double dCos = dTanAlpha * dRatio ; - double dSin = ( abs( dCos) < 1 ? sqrt( 1- dCos * dCos) : 0) ; - - double dDen = sqrt( 1 + dTanAlpha * dTanAlpha) ; - - // Versori normali e prodotti scalari per per determinare i piani - Vector3d vtNp = - ( dTanAlpha / dDen) * vtV1 + - ( dCos / dDen) * vtV2 + - ( dSin / dDen) * vtV3 ; - Vector3d vtNm = - ( dTanAlpha / dDen) * vtV1 + - ( dCos / dDen) * vtV2 - - ( dSin / dDen) * vtV3 ; - - Vector3d vtR0 = ptV - ORIG ; - double dDotp = vtR0 * vtNp ; - double dDotm = vtR0 * vtNm ; - - // Ciclo sui punti - for ( unsigned int i = nStartI ; i <= nEndI ; ++i) { - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++j) { - - double dMin, dMax ; - double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; - - Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptO ; Vector3d vtCf = vtC - vtMoveXY ; - - Vector3d vtUC = vtC ; Vector3d vtUCf = vtCf ; vtUC.Normalize() ; vtUCf.Normalize() ; - - double dCCos = vtUC * vtV2 ; double dCCosf = vtUCf * vtV2 ; - - double dProj = vtC * vtV2 ; - Vector3d vtOrt = vtC - dProj * vtV2 ; - - double dSqDistI = vtC * vtC ; - double dSqDistM = vtOrt * vtOrt ; - double dSqDistF = vtCf * vtCf ; - - if ( ( dProj < 0 && dSqDistI < dMaxRad * dMaxRad) || - ( dProj >= 0 && dProj < dLen && dSqDistM < dMaxRad * dMaxRad) || - ( dProj >= dLen && dSqDistF < dMaxRad * dMaxRad)) { - // Caso vettore utensile equiverso all'asse Z - if ( vtV1.z < 0) { - - double dPMaxI = ( dMaxRad * dMaxRad - dSqDistM > 0 ? sqrt( dMaxRad * dMaxRad - dSqDistM) : 0) ; - - // Massimi - if ( dRatio <= 1 / dTanAlpha) { - - if ( dSqDistI < dMinRad * dMinRad) - - dMax = dZIS ; - - else { - - if ( dSqDistI < dMaxRad * dMaxRad && dCCos < dCos) - - dMax = dZIS - ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight / ( dMaxRad - dMinRad) ; - - else if ( dCCos >= dCos && dCCosf < dCos && dSqDistM < dMaxRad * dMaxRad * ( 1 - dCos * dCos)) { - - double dMinSql = dMinRad * dMinRad * ( 1 - dCos * dCos) ; - double dMaxSql = dMaxRad * dMaxRad * ( 1 - dCos * dCos) ; - double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; - - if ( dSqDistM <= dMinSql) - - dMax = dZIS + ( dProj - dPMinI) * dDeltaZ / dLen ; - - else if ( dSqDistM < dMaxSql) { - - if ( vtC * vtV3 > 0) - - dMax = ( dDotp - dX * vtNp.x - dY * vtNp.y) / vtNp.z ; - else - dMax = ( dDotm - dX * vtNm.x - dY * vtNm.y) / vtNm.z ; - } - } - else if ( dCCosf >= dCos) { - - double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; - - if ( dSqDistF < dMinRad * dMinRad) - - dMax = dZIS + ( dProj - dPMinI) * dDeltaZ / dLen ; - else - dMax = dZFS - ( ( sqrt( dSqDistF) - dMinRad) * m_dTipHeight) / ( dMaxRad - dMinRad) ; - } - else - dMax = dZIS - m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; - } - } - else { - - if ( dSqDistI < dMinRad * dMinRad) - - dMax = dZIS ; - - else if ( dSqDistI < dMaxRad * dMaxRad) - - dMax = dZIS - ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight / ( dMaxRad - dMinRad) ; - - else { - - if ( dProj >= dPMaxI) - - dMax = dZIS - m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; - } - } - // Minimi - - if ( dSqDistF < dMaxRad * dMaxRad) - - dMin = dZFS - m_dTipHeight ; - - else if ( dProj <= dLen - dPMaxI) - - dMin = dZIS - m_dTipHeight + ( dProj + dPMaxI) * dDeltaZ / dLen ; - - } - // Caso vettore utensile opposto all'asse Z - else { - - double dPMaxI = ( dMaxRad * dMaxRad - dSqDistM > 0 ? sqrt( dMaxRad * dMaxRad - dSqDistM) : 0) ; - - // Massimi - if ( dSqDistF < dMaxRad * dMaxRad) - - dMax = dZFS + m_dTipHeight ; - - else if ( dProj <= dLen - dPMaxI) - - dMax = dZIS + m_dTipHeight + ( dProj + dPMaxI) * dDeltaZ / dLen ; - - // Minimi - if ( dRatio <= 1 / dTanAlpha) { - - if ( dSqDistI < dMinRad * dMinRad) - - dMin = dZIS ; - - else { - - if ( dSqDistI < dMaxRad * dMaxRad && dCCos < dCos) - - dMin = dZIS + ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight / ( dMaxRad - dMinRad) ; - - else if ( dCCos >= dCos && dCCosf < dCos && dSqDistM < dMaxRad * dMaxRad * ( 1 - dCos * dCos)) { - - double dMinSql = dMinRad * dMinRad * ( 1 - dCos * dCos) ; - double dMaxSql = dMaxRad * dMaxRad * ( 1 - dCos * dCos) ; - double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; - - if ( dSqDistM <= dMinSql) - - dMin = dZIS + ( dProj - dPMinI) * dDeltaZ / dLen ; - - else if ( dSqDistM < dMaxSql) { - - if ( vtC * vtV3 > 0) - - dMin = ( dDotp - dX * vtNp.x - dY * vtNp.y) / vtNp.z ; - else - dMin = ( dDotm - dX * vtNm.x - dY * vtNm.y) / vtNm.z ; - } - } - else if ( dCCosf >= dCos) { - - double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; - - if ( dSqDistF < dMinRad * dMinRad) - - dMin = dZIS + ( dProj - dPMinI) * dDeltaZ / dLen ; - else - dMin = dZFS + ( ( sqrt( dSqDistF) - dMinRad) * m_dTipHeight) / ( dMaxRad - dMinRad) ; - } - else - dMin = dZIS + m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; - } - } - else { - - if ( dSqDistI < dMinRad * dMinRad) - - dMin = dZIS ; - - else if ( dSqDistI < dMaxRad * dMaxRad) - - dMin = dZIS + ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight / ( dMaxRad - dMinRad) ; - - else - - dMin = dZIS + m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; - - } - } - SubtractIntervals( nGrid, i, j, dMin, dMax, V_NULL, V_NULL) ; - } - - // Parte cilindrica - Vector3d vtCyl = ( vtV1.z < 0 ? vtCf : vtC) ; - Vector3d vtCylf = ( vtV1.z < 0 ? vtC : vtCf) ; - Vector3d vtMot = ( vtV1.z < 0 ? - vtV2 : vtV2) ; - - double dCylProj = vtCyl * vtMot ; - double dCylSqDistI = vtCyl * vtCyl ; - double dCylSqDistF = vtCylf * vtCylf ; - double dCylSqDistM = ( vtCyl - dCylProj * vtMot) * ( vtCyl - dCylProj * vtMot) ; - - - if ( dCylSqDistI < dMinRad * dMinRad - || dCylSqDistF < dMinRad * dMinRad - || ( dCylProj > 0 && dCylProj < dLen && dCylSqDistM < dMinRad * dMinRad)) { - - double dSt = sqrt( dMinRad * dMinRad - dCylSqDistM) ; - - // Minimi - if ( dCylSqDistI < dMinRad * dMinRad ) - - dMin = dMinZCyl ; - - else if ( dCylProj >= dSt) - - dMin = dMinZCyl + ( dCylProj - dSt) * dADeltaZ / dLen ; - - // Massimi - if ( dCylSqDistF < dMinRad * dMinRad) - - dMax = dMinZCyl + dDeltaH + dADeltaZ ; - - else if ( dCylProj <= dLen - dSt) - - dMax = dMinZCyl + dDeltaH + ( dCylProj + dSt) * dADeltaZ / dLen ; - - SubtractIntervals( nGrid, i, j, dMin, dMax, V_NULL, V_NULL) ; - - } - } + + Point3d ptSC = ptS - vtToolDir * m_dHeight ; + Point3d ptEC = ptE - vtToolDir * m_dHeight ; + + CompConus_ZMilling( nGrid, ptSC, ptEC, - vtToolDir, m_dTipHeight, m_dTipRadius, m_dRadius) ; } + return true ; } @@ -1991,17 +1998,23 @@ VolZmap::CylBall_XYDrilling( unsigned int nGrid, const Point3d & ptS, const Poin Vector3d vtBall = ptC - ptFxy ; double dSqLen = vtBall.SqLenXY() ; // Zona lavorata dalla parte cilindrica - if ( dP1 > 0 && dP1 < dStemHeigth + dLen && + if ( dP1 > EPS_SMALL && dP1 < dStemHeigth + dLen - EPS_SMALL && abs( dP2) < m_dRadius ) { double dH = sqrt( dSqRad - dP2 * dP2) ; double dMin = dZ - dH ; double dMax = dZ + dH ; - Vector3d vtMin = ( ptI - Point3d( dX, dY, dMin)) - - ( ( ptI - Point3d( dX, dY, dMin)) * vtToolDir) * vtToolDir ; - Vector3d vtMax = ( ptI - Point3d( dX, dY, dMax)) - - ( ( ptI - Point3d( dX, dY, dMax)) * vtToolDir) * vtToolDir ; + Point3d ptIntMin( dX, dY, dMin) ; + Point3d ptIntMax( dX, dY, dMax) ; + + Vector3d vtMin = ( ptI - ptIntMin) - + ( ptI - ptIntMin) * vtToolDir * vtToolDir ; + Vector3d vtMax = ( ptI - ptIntMax) - + ( ptI - ptIntMax) * vtToolDir * vtToolDir ; + + vtMin.Normalize() ; + vtMax.Normalize() ; SubtractIntervals( nGrid, i, j, dMin, dMax, vtMin, vtMax) ; } @@ -2039,11 +2052,15 @@ VolZmap::CylBall_XYPerp( unsigned int nGrid, const Point3d & ptS, const Point3d // Parametri geometrici dell'utensile double dStemHeigth = m_dHeight - m_dTipHeight ; double dSqRad = m_dRadius * m_dRadius ; + double dSafeSqRad = dSqRad - 2 * m_dRadius * EPS_SMALL ; // Studio simmetrie del problema Point3d ptI = ( ptS.z <= ptE.z ? ptS : ptE) ; Point3d ptF = ( ptS.z <= ptE.z ? ptE : ptS) ; Point3d ptIxy( ptI.x, ptI.y, 0) ; + + Point3d ptIStemT = ptI - vtToolDir * dStemHeigth ; + Point3d ptFStemT = ptF - vtToolDir * dStemHeigth ; // Quote punti iniziale e finale double dZI = ptI.z ; @@ -2083,95 +2100,223 @@ VolZmap::CylBall_XYPerp( unsigned int nGrid, const Point3d & ptS, const Point3d double dInfZ, dSupZ ; + if ( dLenXY < EPS_SMALL) { - for( unsigned int i = nStartI ; i <= nEndI ; ++ i) { - for( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - double dX = ( i + 0.5) * m_dStep ; - double dY = ( j + 0.5) * m_dStep ; + for( unsigned int i = nStartI ; i <= nEndI ; ++ i) { + for( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - Point3d ptC( dX, dY, 0) ; - Vector3d vtC = ptC - ptIxy ; + + double dX = ( i + 0.5) * m_dStep ; + double dY = ( j + 0.5) * m_dStep ; - double dP1 = vtC * vtV1 ; - double dP2 = vtC * vtV2 ; + Point3d ptC( dX, dY, 0) ; + Vector3d vtC = ptC - ptIxy ; - // Parte cilindrica - if ( dP1 > 0 && dP1 < dStemHeigth) { + double dP1 = vtC * vtV1 ; + double dP2 = vtC * vtV2 ; - if ( dP2 > - m_dRadius && dP2 < dLenXY + m_dRadius) { - // Massimi - if ( dP2 < - dSmall + EPS_SMALL) { - double dHsq = dSqRad - dP2 * dP2 ; - double dH = ( dHsq > 0 ? sqrt( dHsq) : 0) ; - dSupZ = dZI + dH ; - } - else if ( dP2 < dLenXY - dSmall - EPS_SMALL) { + Vector3d vtNmin, vtNmax ; - dSupZ = ( dDotUp - dX * vtP.x - dY * vtP.y) / vtP.z ; - } - else { + if ( dP1 > EPS_SMALL && dP1 < dStemHeigth - EPS_SMALL && + dP2 > - m_dRadius + EPS_SMALL && + dP2 < m_dRadius - EPS_SMALL) { + + dInfZ = ptI.z - sqrt( dSqRad - dP2 * dP2) ; + dSupZ = ptF.z + sqrt( dSqRad - dP2 * dP2) ; + + Point3d ptIntInf( dX, dY, dInfZ) ; + Point3d ptIntSup( dX, dY, dSupZ) ; + + vtNmin = - ( ptIntInf - ptI) + ( ptIntInf - ptI) * vtV1 * vtV1 ; + vtNmax = - ( ptIntSup - ptF) + ( ptIntSup - ptF) * vtV1 * vtV1 ; + + vtNmin.Normalize() ; + vtNmax.Normalize() ; + + SubtractIntervals( nGrid, i, j, dInfZ, dSupZ, vtNmin, vtNmax) ; + } + + if ( m_nToolType == BallEndMill) { + + if ( dP1 > dStemHeigth - 2 * EPS_SMALL && ( dP1 - dStemHeigth) * ( dP1 - dStemHeigth) + dP2 * dP2 < dSafeSqRad) { - double dH = sqrt( dSqRad - ( dP2 - dLenXY) * ( dP2 - dLenXY)) ; - dSupZ = dZF + dH ; - } - // Minimi - if ( dP2 < dSmall + EPS_SMALL) { - double dHsq = dSqRad - dP2 * dP2 ; - double dH = ( dHsq > 0 ? sqrt( dHsq) : 0) ; - dInfZ = dZI - dH ; - } - else if ( dP2 < dLenXY + dSmall - EPS_SMALL) { - - dInfZ = ( dDotDw - dX * vtP.x - dY * vtP.y) / vtP.z ; - } - else { + dInfZ = ptI.z - sqrt( dSqRad - ( dP1 - dStemHeigth) * ( dP1 - dStemHeigth) - dP2 * dP2) ; + dSupZ = ptF.z + sqrt( dSqRad - ( dP1 - dStemHeigth) * ( dP1 - dStemHeigth) - dP2 * dP2) ; - double dH = sqrt( dSqRad - ( dP2 - dLenXY) * ( dP2 - dLenXY)) ; - dInfZ = dZF - dH ; - } + Point3d ptIntInf( dX, dY, dInfZ) ; + Point3d ptIntSup( dX, dY, dSupZ) ; - SubtractIntervals( nGrid, i, j, dInfZ, dSupZ, V_NULL, V_NULL) ; + vtNmin = ptIStemT - ptIntInf ; + vtNmax = ptFStemT - ptIntSup ; + + vtNmin.Normalize() ; + vtNmax.Normalize() ; + + SubtractIntervals( nGrid, i, j, dInfZ, dSupZ, vtNmin, vtNmax) ; + } } } - // Se l'utensile è ball-end sottraggo la punta - if ( m_nToolType == BallEndMill) { + } + } + else { + + for( unsigned int i = nStartI ; i <= nEndI ; ++ i) { + for( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + + double dX = ( i + 0.5) * m_dStep ; + double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; + Vector3d vtC = ptC - ptIxy ; + + double dP1 = vtC * vtV1 ; + double dP2 = vtC * vtV2 ; + + // Parte cilindrica + if ( dP1 > EPS_SMALL && dP1 < dStemHeigth - EPS_SMALL) { + + if ( dP2 > - m_dRadius && dP2 < dLenXY + m_dRadius) { + + Vector3d vtNmin, vtNmax ; + + // Massimi + if ( dP2 < - dSmall + EPS_SMALL) { + + double dHsq = dSqRad - dP2 * dP2 ; + double dH = ( dHsq > 0 ? sqrt( dHsq) : 0) ; + dSupZ = dZI + dH ; + + Point3d ptInt( dX, dY, dSupZ) ; + + vtNmax = - ( ptInt - ptI - ( ptInt - ptI) * vtToolDir * vtToolDir) ; + vtNmax.Normalize() ; + } + else if ( dP2 < dLenXY - dSmall - EPS_SMALL) { + + dSupZ = ( dDotUp - dX * vtP.x - dY * vtP.y) / vtP.z ; + + vtNmax = vtToolDir ^ vtMove ; + vtNmax.Normalize() ; + } + else { + + double dH = sqrt( dSqRad - ( dP2 - dLenXY) * ( dP2 - dLenXY)) ; + dSupZ = dZF + dH ; + + Point3d ptInt( dX, dY, dSupZ) ; + + vtNmax = - ( ptInt - ptF - ( ptInt - ptF) * vtToolDir * vtToolDir) ; + vtNmax.Normalize() ; + } + // Minimi + if ( dP2 < dSmall + EPS_SMALL) { + double dHsq = dSqRad - dP2 * dP2 ; + double dH = ( dHsq > 0 ? sqrt( dHsq) : 0) ; + dInfZ = dZI - dH ; + + Point3d ptInt( dX, dY, dInfZ) ; + vtNmin = - ( ( ptInt - ptI) - ( ptInt - ptI) * vtToolDir * vtToolDir) ; + vtNmin.Normalize() ; + } + else if ( dP2 < dLenXY + dSmall - EPS_SMALL) { + + dInfZ = ( dDotDw - dX * vtP.x - dY * vtP.y) / vtP.z ; + + vtNmin = - vtToolDir ^ vtMove ; + vtNmin.Normalize() ; + } + else { + + double dH = sqrt( dSqRad - ( dP2 - dLenXY) * ( dP2 - dLenXY)) ; + dInfZ = dZF - dH ; + + Point3d ptInt( dX, dY, dInfZ) ; + vtNmin = - ( ( ptInt - ptF) - ( ptInt - ptF) * vtToolDir * vtToolDir) ; + vtNmin.Normalize() ; + } + + SubtractIntervals( nGrid, i, j, dInfZ, dSupZ, vtNmin, vtNmax) ; + } + } + // Se l'utensile è ball-end sottraggo la punta + if ( m_nToolType == BallEndMill) { - if ( ( ( dP1 - dStemHeigth) * ( dP1 - dStemHeigth) + dP2 * dP2 < dSqRad || - ( dP1 - dStemHeigth) * ( dP1 - dStemHeigth) + ( dP2 - dLenXY) * ( dP2 - dLenXY) < dSqRad || - ( dP2 > 0 && dP2 < dLenXY && dP1 < m_dHeight)) && ( dP1 >= dStemHeigth)) { + if ( ( ( dP1 - dStemHeigth) * ( dP1 - dStemHeigth) + dP2 * dP2 < dSqRad || + ( dP1 - dStemHeigth) * ( dP1 - dStemHeigth) + ( dP2 - dLenXY) * ( dP2 - dLenXY) < dSqRad || + ( dP2 > 0 && dP2 < dLenXY && dP1 < m_dHeight)) && ( dP1 > dStemHeigth - 2 * EPS_SMALL)) { + + double dSqRoot = sqrt( dSqRad - ( dP1 - dStemHeigth) * ( dP1 - dStemHeigth)) ; + double dP2_0 = dCos * dSqRoot ; + double dH0 = dSin * dSqRoot ; - double dSqRoot = sqrt( dSqRad - ( dP1 - dStemHeigth) * ( dP1 - dStemHeigth)) ; - double dP2_0 = dCos * dSqRoot ; - double dH0 = dSin * dSqRoot ; + double dMin, dMax ; - double dMin, dMax ; + Vector3d vtNmin, vtNmax ; - // Massimo - if ( dP2 < - dP2_0) + // Massimo + if ( dP2 < - dP2_0) { - dMax = dZI + sqrt( dSqRad - ( dP1 - dStemHeigth) * ( dP1 - dStemHeigth) - dP2 * dP2) ; + dMax = dZI + sqrt( dSqRad - ( dP1 - dStemHeigth) * ( dP1 - dStemHeigth) - dP2 * dP2) ; - else if ( dP2 < dLenXY - dP2_0) + Point3d ptInt( dX, dY, dMax) ; - dMax = dZI + dH0 + dDeltaZ * ( dP2 + dP2_0) / dLenXY ; - else - dMax = dZF + sqrt( dSqRad - ( dP1 - dStemHeigth) * ( dP1 - dStemHeigth) - ( dP2 - dLenXY) * ( dP2 - dLenXY)) ; + vtNmax = ptIStemT - ptInt ; + vtNmax.Normalize() ; + } + else if ( dP2 < dLenXY - dP2_0) { - // Minimo - if ( dP2 < dP2_0) + dMax = dZI + dH0 + dDeltaZ * ( dP2 + dP2_0) / dLenXY ; - dMin = dZI - sqrt( dSqRad - ( dP1 - dStemHeigth) * ( dP1 - dStemHeigth) - dP2 * dP2) ; + Point3d ptInt( dX, dY, dMax) ; - else if ( dP2 < dLenXY + dP2_0) + vtNmax = - ( ptInt - ptIStemT) + ( ptInt - ptIStemT) * vtMove * vtMove ; + vtNmax.Normalize() ; + } + else { - dMin = dZI - dH0 + dDeltaZ * ( dP2 - dP2_0) / dLenXY ; - else - dMin = dZF - sqrt( dSqRad - ( dP1 - dStemHeigth) * ( dP1 - dStemHeigth) - ( dP2 - dLenXY) * ( dP2 - dLenXY)) ; + dMax = dZF + sqrt( dSqRad - ( dP1 - dStemHeigth) * ( dP1 - dStemHeigth) - ( dP2 - dLenXY) * ( dP2 - dLenXY)) ; - SubtractIntervals( nGrid, i, j, dMin, dMax, V_NULL, V_NULL) ; - } - } + Point3d ptInt( dX, dY, dMax) ; + + vtNmax = ptFStemT - ptInt; + vtNmax.Normalize() ; + } + + // Minimo + if ( dP2 < dP2_0) { + + dMin = dZI - sqrt( dSqRad - ( dP1 - dStemHeigth) * ( dP1 - dStemHeigth) - dP2 * dP2) ; + + Point3d ptInt( dX, dY, dMin) ; + + vtNmin = ptIStemT - ptInt ; + vtNmin.Normalize() ; + } + else if ( dP2 < dLenXY + dP2_0) { + + dMin = dZI - dH0 + dDeltaZ * ( dP2 - dP2_0) / dLenXY ; + + Point3d ptInt( dX, dY, dMin) ; + + vtNmin = - ( ptInt - ptIStemT) + ( ptInt - ptIStemT) * vtMove * vtMove ; + vtNmin.Normalize() ; + } + else { + + dMin = dZF - sqrt( dSqRad - ( dP1 - dStemHeigth) * ( dP1 - dStemHeigth) - ( dP2 - dLenXY) * ( dP2 - dLenXY)) ; + + Point3d ptInt( dX, dY, dMin) ; + + vtNmin = ptFStemT - ptInt ; + vtNmin.Normalize() ; + } + + + SubtractIntervals( nGrid, i, j, dMin, dMax, vtNmin, vtNmax) ; + } + } + } } } return true ; @@ -2183,13 +2328,13 @@ VolZmap::CylBall_XYMilling( unsigned int nGrid, const Point3d & ptS, const Point { if ( m_nToolType == CylindricalMill) - return CompCyl_Milling( nGrid, ptS, ptE, vtToolDir, m_dHeight, m_dRadius) ; + return CompCyl_Milling( nGrid, ptS, ptE, vtToolDir, m_dHeight, m_dRadius, false, false) ; else if ( m_nToolType == BallEndMill) { double dHei = m_dHeight - m_dTipHeight ; - CompCyl_Milling( nGrid, ptS, ptE, vtToolDir, dHei, m_dRadius) ; + CompCyl_Milling( nGrid, ptS, ptE, vtToolDir, dHei, m_dRadius, false, false) ; CompBall_Milling( nGrid, ptS - dHei * vtToolDir, ptE - dHei * vtToolDir, m_dRadius) ; @@ -2228,6 +2373,24 @@ VolZmap::Conus_XYDrilling( unsigned int nGrid, const Point3d & ptS, const Point3 double dSqTipRad = m_dTipRadius * m_dTipRadius ; double dSqRad = m_dRadius * m_dRadius ; + // Determinazione del vertice del cono + double dL = m_dTipHeight * dMaxRad / dDeltaRad ; + + Point3d ptV ; // Vertice + Vector3d vtV ; // Vettore riferimento con origine nel vertice + + if ( m_dRadius > m_dTipRadius) { + + vtV = vtToolDir ; + ptV = ( vtToolDir * ( ptE - ptS) < 0 ? ptE : ptS) - vtToolDir * ( dStemHeigth + dL) ;//dStemHeigth ; + } + else { + + vtV = - vtToolDir ; + ptV = ( vtToolDir * ( ptE - ptS) < 0 ? ptS : ptE) - vtToolDir * ( m_dHeight - dL) ;//dStemHeigth ; + } + + // Sistema di riferimento sul piano Vector3d vtV1 = - vtToolDir ; Vector3d vtV2 = vtV1 ; @@ -2241,6 +2404,7 @@ VolZmap::Conus_XYDrilling( unsigned int nGrid, const Point3d & ptS, const Point3 for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; @@ -2252,28 +2416,64 @@ VolZmap::Conus_XYDrilling( unsigned int nGrid, const Point3d & ptS, const Point3 double dr = m_dRadius + ( dX1 - dMatStemLen) * ( m_dTipRadius - m_dRadius) / m_dTipHeight ; - if ( dX1 > 0 && dX1 < dMatStemLen && + if ( dX1 > EPS_SMALL && dX1 < dMatStemLen && abs( dX2) < m_dRadius) { double dH = sqrt( dSqRad - dX2 * dX2) ; - SubtractIntervals( nGrid, i, j, ptI.z - dH, ptI.z + dH, V_NULL, V_NULL) ; + double dMin = ptI.z - dH ; + double dMax = ptI.z + dH ; + + Point3d ptIntMin( dX, dY, dMin) ; + Point3d ptIntMax( dX, dY, dMax) ; + + Vector3d vtNmin = ( ptI - ptIntMin) - ( ptI - ptIntMin) * vtV1 * vtV1 ; + Vector3d vtNmax = ( ptI - ptIntMax) - ( ptI - ptIntMax) * vtV1 * vtV1 ; + + SubtractIntervals( nGrid, i, j, ptI.z - dH, ptI.z + dH, vtNmin, vtNmax) ; } else if ( dX1 >= dMatStemLen && - dX1 < dMatStemLen + m_dTipHeight && + dX1 < dMatStemLen + m_dTipHeight - EPS_SMALL && abs( dX2) < dr) { double dH = sqrt( dr * dr - dX2 * dX2) ; - SubtractIntervals( nGrid, i, j, ptI.z - dH, ptI.z + dH, V_NULL, V_NULL) ; + double dMin = ptI.z - dH ; + double dMax = ptI.z + dH ; + + Point3d ptIntMin( dX, dY, dMin) ; + Point3d ptIntMax( dX, dY, dMax) ; + + Vector3d vtUmin = ( ptIntMin - ptV) - ( ptIntMin - ptV) * vtV * vtV ; + Vector3d vtUmax = ( ptIntMax - ptV) - ( ptIntMax - ptV) * vtV * vtV ; + + Vector3d vtNmin = dDeltaRad * vtV - m_dTipHeight * vtUmin ; + Vector3d vtNmax = dDeltaRad * vtV - m_dTipHeight * vtUmax ; + + vtNmin.Normalize() ; + vtNmax.Normalize() ; + + SubtractIntervals( nGrid, i, j, dMin, dMax, vtNmin, vtNmax) ; } if ( m_dTipRadius >= m_dRadius) { - if ( dX1 >= dMatStemLen + m_dTipHeight && - dX1 < dMatStemLen + m_dTipHeight + dLenXY && + if ( dX1 > dMatStemLen + m_dTipHeight - 2 * EPS_SMALL && + dX1 < dMatStemLen + m_dTipHeight + dLenXY - EPS_SMALL && abs( dX2) < dSqTipRad) { double dH = sqrt( dSqTipRad - dX2 * dX2) ; - SubtractIntervals( nGrid, i, j, ptI.z - dH, ptI.z + dH, V_NULL, V_NULL) ; + double dMin = ptI.z - dH ; + double dMax = ptI.z + dH ; + + Point3d ptIntMin( dX, dY, dMin) ; + Point3d ptIntMax( dX, dY, dMax) ; + + Vector3d vtNmin = ( ptI - ptIntMin) - ( ptI - ptIntMin) * vtV1 * vtV1 ; + Vector3d vtNmax = ( ptI - ptIntMax) - ( ptI - ptIntMax) * vtV1 * vtV1 ; + + vtNmin.Normalize() ; + vtNmax.Normalize() ; + + SubtractIntervals( nGrid, i, j, ptI.z - dH, ptI.z + dH, vtNmin, vtNmax) ; } } } @@ -2283,7 +2483,7 @@ VolZmap::Conus_XYDrilling( unsigned int nGrid, const Point3d & ptS, const Point3 //---------------------------------------------------------------------------- bool -VolZmap::Conus_XYPerp( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) +VolZmap::Conus_XYPerp( unsigned int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir) { unsigned int nStartI, nStartJ, nEndI, nEndJ ; @@ -2303,93 +2503,41 @@ VolZmap::Conus_XYPerp( unsigned int nGrid, const Point3d & ptS, const Point3d & double dSqMinRad = dMinRad * dMinRad ; double dSqMaxRad = dMaxRad * dMaxRad ; - // Studio delle simmetrie + // Studio delle simmetrie del moto Point3d ptI = ( ptS.z < ptE.z ? ptS : ptE) ; Point3d ptF = ( ptS.z < ptE.z ? ptE : ptS) ; - // Vettori caratterizzanti il moto - Vector3d vtMove = ptF - ptI ; - Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ; - double dLen = vtMove.Len() ; - double dLenXY = vtMoveXY.LenXY() ; + Point3d ptIxy( ptI.x, ptI.y, 0) ; + Point3d ptFxy( ptF.x, ptF.y, 0) ; - // Quote iniziale e finale + // Cinematica del moto + Vector3d vtMove = ptF - ptI ; + double dLenPath = vtMove.Len() ; + double dLengthPathXY = vtMove.LenXY() ; + double dDeltaZ = ptF.z - ptI.z ; double dZI = ptI.z ; double dZF = ptF.z ; - // Sistema di riferimento sul piano - Point3d ptIxy( ptI.x, ptI.y, 0) ; - Point3d ptFxy( ptF.x, ptF.y, 0) ; - // Primo vettore del riferimento - Vector3d vtV1( - vtToolDir.x, - vtToolDir.y, 0) ; - vtV1.Normalize() ; - Vector3d vtV2 ; + vtMove.Normalize() ; - // Movimento verticale - if ( dLenXY / dLen < EPS_SMALL) { + // Riferimento coni + double dL = m_dTipHeight * dMaxRad / dDeltaRad ; + Vector3d vtV = ( m_dRadius > m_dTipRadius ? vtToolDir : - vtToolDir) ; + Point3d ptVI = ptI - ( m_dRadius > m_dTipRadius ? dStemHeigth + dL : m_dHeight - dL) * vtToolDir ; + Point3d ptVF = ptF - ( m_dRadius > m_dTipRadius ? dStemHeigth + dL : m_dHeight - dL) * vtToolDir ; - // Secondo vettore del riferimento - vtV2 = vtV1 ; - vtV2.Rotate( Z_AX, 90) ; - - // Ciclo sui punti - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - double dX = ( i + 0.5) * m_dStep ; - double dY = ( j + 0.5) * m_dStep ; - Point3d ptC( dX, dY, 0) ; - Vector3d vtC = ptC - ptIxy ; - - double dX1 = vtC * vtV1 ; - double dX2 = vtC * vtV2 ; - - double dr = m_dRadius + ( m_dTipRadius - m_dRadius) * ( dX1 - dStemHeigth) / m_dTipHeight ; - // Parte cilindrica - if ( dX1 > 0 && dX1 < dStemHeigth && abs( dX2) < m_dRadius) { - - double dH = sqrt( dSqRad - dX2 * dX2) ; - SubtractIntervals( nGrid, i, j, dZI - dH, dZF + dH, V_NULL, V_NULL) ; - } - // Parte conica - else if ( dX1 >= dStemHeigth && dX1 < m_dHeight && abs( dX2) < dr) { - - double dH = sqrt( dr * dr - dX2 * dX2) ; - SubtractIntervals ( nGrid, i, j, dZI - dH, dZF + dH, V_NULL, V_NULL) ; - } - } - } - } - else { - - // Secondo vettore del riferimento - Vector3d vtV2 = vtMoveXY ; - vtV2.Normalize() ; - - // Sistema di riferimento per determinare i piani - Vector3d vtW1 = ( m_dHeight > m_dTipHeight ? vtV1 : - vtV1) ; - Vector3d vtW2 = vtMove ; - vtW2.Normalize() ;// Se vtMove non è suff ort a vtW1 vtMove = vtMoveOrt + vtMoveLong e via - Vector3d vtW3 = vtW1 ^ vtW2 ; - - // Altezza cono - double dL = dMaxRad * m_dTipHeight / dDeltaRad ; - - // Vertice del cono iniziale - Point3d ptV = ptI - ( m_dHeight > m_dTipHeight ? ( dStemHeigth + dL) * vtW1 : ( dL - m_dHeight) * vtW1) ; - - // - double dCos = vtW2.z ; - double dSin = ( dCos < 1 ? sqrt( 1 - dCos * dCos) : 0) ; - - double dLimXY = dCos * m_dRadius ; - double dLimH = dSin * m_dRadius ; - double dDeltaZ = ptF.z - ptI.z ; + // Movimento verticale + if ( dLengthPathXY < EPS_SMALL) { + + // Riferimento sul piano + Vector3d vtV1 = - vtToolDir ; + Vector3d vtV2( - vtV1.y, vtV1.x, 0) ; double dMin, dMax ; + Vector3d vtNmin, vtNmax ; + Point3d ptIntMin, ptIntMax ; - // Ciclo sui punti for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { @@ -2399,85 +2547,296 @@ VolZmap::Conus_XYPerp( unsigned int nGrid, const Point3d & ptS, const Point3d & Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptIxy ; - double dX1 = vtC * vtV1 ; - double dX2 = vtC * vtV2 ; + double dP1 = vtC * vtV1 ; + double dP2 = vtC * vtV2 ; - double dr = m_dRadius + ( m_dTipRadius - m_dRadius) * ( dX1 - dStemHeigth) / m_dTipHeight ; + + // Parte cilindrica + if ( dP1 > EPS_SMALL && dP1 <= dStemHeigth && + dP2 > - m_dRadius + EPS_SMALL && dP2 < m_dRadius - EPS_SMALL) { - // Parte cilindrica - if ( dX1 > 0 && dX1 < dStemHeigth && - dX2 > - m_dRadius && dX2 < dLenXY + m_dRadius) { - // Massimi - if ( dX2 < - dLimXY) - dMax = dZI + sqrt( dSqRad - dX2 * dX2) ; - else if ( dX2 < dLenXY - dLimXY) - dMax = dZI + dLimH + dDeltaZ * ( dX2 + dLimXY) / dLenXY ; - else - dMax = dZF + sqrt( dSqRad - ( dX2 - dLenXY) * ( dX2 - dLenXY)) ; + dMin = dZI - sqrt( dSqRad - dP2 * dP2) ; + dMax = dZF + sqrt( dSqRad - dP2 * dP2) ; - // Minimi - if ( dX2 < dLimXY) - dMin = dZI + sqrt( dSqRad - dX2 * dX2) ; - else if ( dX2 < dLenXY + dLimXY) - dMin = dZI - dLimH + dDeltaZ * ( dX2 - dLimXY) / dLenXY ; - else - dMin = dZF + sqrt( dSqRad - ( dX2 - dLenXY) * ( dX2 - dLenXY)) ; + ptIntMin.Set( dX, dY, dMin) ; + ptIntMax.Set( dX, dY, dMax) ; - SubtractIntervals( nGrid, i, j, dMin, dMax, V_NULL, V_NULL) ; + vtNmin = - ( ptIntMin - ptI) + ( ptIntMin - ptI) * vtV1 * vtV1 ; + vtNmax = - ( ptIntMax - ptF) + ( ptIntMax - ptF) * vtV1 * vtV1 ; + + vtNmin.Normalize() ; + vtNmax.Normalize() ; + + SubtractIntervals( nGrid, i, j, dMin, dMax, vtNmin, vtNmax) ; } // Parte conica - else if ( dX1 >= dStemHeigth && dX1 < m_dHeight && - dX2 > - dr && dX2 < dLenXY + dr) { + else if ( dP1 > dStemHeigth && dP1 < m_dHeight - EPS_SMALL && abs( dP2) < m_dRadius + + ( m_dTipRadius - m_dRadius) * ( dP1 - dStemHeigth) / m_dTipHeight - EPS_SMALL) { - double dRadLimXY = dr * dCos ; - double dRadLimH = dr * dSin ; + double dr = dP2 ; + double dMr = m_dRadius + ( m_dTipRadius - m_dRadius) * ( dP1 - dStemHeigth) / m_dTipHeight ; - // Massimi - if ( dX2 < - dRadLimXY) - dMax = dZI + sqrt( dr * dr - dX2 * dX2) ; - else if ( dX2 < dLenXY - dRadLimXY) - dMax = dZI + dRadLimH + dDeltaZ * ( dX2 + dRadLimXY) / dLenXY ; - else - dMax = dZF + sqrt( dr * dr - ( dX2 - dLenXY) * ( dX2 - dLenXY)) ; + dMin = dZI - sqrt( dMr * dMr - dr * dr) ; + dMax = dZF + sqrt( dMr * dMr - dr * dr) ; - // Minimi - if ( dX2 < dRadLimXY) - dMin = dZI + sqrt( dr * dr - dX2 * dX2) ; - else if ( dX2 < dLenXY + dRadLimXY) - dMin = dZI - dRadLimH + dDeltaZ * ( dX2 - dRadLimXY) / dLenXY ; - else - dMin = dZF + sqrt( dr * dr - ( dX2 - dLenXY) * ( dX2 - dLenXY)) ; - - SubtractIntervals( nGrid, i, j, dMin, dMax, V_NULL, V_NULL) ; + ptIntMin.Set( dX, dY, dMin) ; + ptIntMax.Set( dX, dY, dMax) ; + + Vector3d vtUmin = ( ptIntMin - ptVI) - ( ptIntMin - ptVI) * vtV * vtV ; + Vector3d vtUmax = ( ptIntMax - ptVF) - ( ptIntMax - ptVF) * vtV * vtV ; + + vtUmin.Normalize() ; + vtUmax.Normalize() ; + + vtNmin = dDeltaRad * vtV - m_dTipHeight * vtUmin ; + vtNmax = dDeltaRad * vtV - m_dTipHeight * vtUmax ; + + vtNmin.Normalize() ; + vtNmax.Normalize() ; + + SubtractIntervals( nGrid, i, j, dMin, dMax, vtNmin, vtNmax) ; } } } - } - return true ; + else { + + // Riferimento sul piano + Vector3d vtV1 = - vtToolDir ; + Vector3d vtV2( vtMove.x, vtMove.y, 0) ; + vtV2.Normalize() ; + + // Vettore per individuare i punti di tangenza + // dei piani con il cilindro + Vector3d vtCross = vtToolDir ^ vtMove ; + if ( vtCross.z < 0) vtCross = - vtCross ; + + // Punti di tangenza + Point3d ptUp = ptI - vtToolDir * dStemHeigth + m_dRadius * vtCross ; + Point3d ptDw = ptI - vtToolDir * dStemHeigth - m_dRadius * vtCross ; + + double dSmallLength = m_dRadius * vtCross.LenXY() ; + + // Punti di tangenza in corrispondenza della punta + Point3d ptTipUp = ptI - vtToolDir * m_dHeight + m_dTipRadius * vtCross ; + Point3d ptTipDw = ptI - vtToolDir * m_dHeight - m_dTipRadius * vtCross ; + + Vector3d vtUpTan = ptTipUp - ptUp ; + Vector3d vtDwTan = ptTipDw - ptDw ; + + Vector3d vtUpTanXY( vtUpTan.x, vtUpTan.y, 0) ; + double dDeltaSmallAbs = abs( vtUpTanXY * vtV2) ; + double dDeltaSmall = ( m_dRadius > m_dTipRadius ? dDeltaSmallAbs : - dDeltaSmallAbs) ; + + vtUpTan.Normalize() ; + vtDwTan.Normalize() ; + + Vector3d vtUpCross = vtMove ^ vtUpTan ; + Vector3d vtDwCross = - vtMove ^ vtDwTan ; + + // Descrizione piani tangenti al cono + Vector3d vtR0Up = ptUp - ORIG ; + Vector3d vtR0Dw = ptDw - ORIG ; + + double dDotUp = vtR0Up * vtUpCross ; + double dDotDw = vtR0Dw * vtDwCross ; + + double dMin, dMax ; + Vector3d vtNmin, vtNmax ; + Point3d ptInt ; + + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + + double dX = ( i + 0.5) * m_dStep ; + double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; + + Vector3d vtC = ptC - ptIxy ; + + double dP1 = vtC * vtV1 ; + double dP2 = vtC * vtV2 ; + + // Parte cilindrica + if ( dP1 > EPS_SMALL && dP1 <= dStemHeigth && // vedere se conviene dP1 < dStemHeigth + eps oppure dP1 <= dStemHeigth + dP2 > - m_dRadius && dP2 < dLengthPathXY + m_dRadius) { + + // Massimi + if ( dP2 < - dSmallLength) { + + dMax = dZI + sqrt( dSqRad - dP2 * dP2) ; + + ptInt.Set( dX, dY, dMax) ; + + vtNmax = - ( ptInt - ptI) + ( ptInt - ptI) * vtV1 * vtV1 ; + vtNmax.Normalize() ; + } + else if ( dP2 < dLengthPathXY - dSmallLength) { + + dMax = ptUp.z + dDeltaZ * ( dP2 + dSmallLength) / dLengthPathXY ; + + vtNmax = - vtCross ; + } + else { + + dMax = dZF + sqrt( dSqRad - ( dP2 - dLengthPathXY) * ( dP2 - dLengthPathXY)) ; + + ptInt.Set( dX, dY, dMax) ; + + vtNmax = - ( ptInt - ptF) + ( ptInt - ptF) * vtV1 * vtV1 ; + vtNmax.Normalize() ; + } + + // Minimi + if ( dP2 < dSmallLength) { + + dMin = dZI - sqrt( dSqRad - dP2 * dP2) ; + + ptInt.Set( dX, dY, dMin) ; + + vtNmin = - ( ptInt - ptI) + ( ptInt - ptI) * vtV1 * vtV1 ; + vtNmin.Normalize() ; + } + else if ( dP2 < dLengthPathXY + dSmallLength) { + + dMin = ptDw.z + dDeltaZ * ( dP2 - dSmallLength) / dLengthPathXY ; + + vtNmin = vtCross ; + } + else { + + dMin = dZF - sqrt( dSqRad - ( dP2 - dLengthPathXY) * ( dP2 - dLengthPathXY)) ; + + ptInt.Set( dX, dY, dMin) ; + + vtNmin = - ( ptInt - ptF) + ( ptInt - ptF) * vtV1 * vtV1 ; + vtNmin.Normalize() ; + } + + SubtractIntervals( nGrid, i, j, dMin, dMax, vtNmin, vtNmax) ; + } + // Parte conica + else if ( dP1 > dStemHeigth && dP1 < m_dHeight - EPS_SMALL && + dP2 > - m_dRadius - ( m_dTipRadius - m_dRadius) * ( dP1 - dStemHeigth) / m_dTipHeight && + dP2 < m_dRadius + dLengthPathXY + + ( m_dTipRadius - m_dRadius) * ( dP1 - dStemHeigth) / m_dTipHeight) { + + // Massimi + if ( dP2 < - dSmallLength + dDeltaSmall * ( dP1 - dStemHeigth) / m_dTipHeight) { + + double dr = dP2 ; + double dMr = m_dRadius + ( m_dTipRadius - m_dRadius) * ( dP1 - dStemHeigth) / m_dTipHeight ; + + dMax = dZI + sqrt( dMr * dMr - dr * dr) ; + + ptInt.Set( dX, dY, dMax) ; + + Vector3d vtU = ( ptInt - ptVI) - ( ptInt - ptVI) * vtV * vtV ; + + vtU.Normalize() ; + + vtNmax = dDeltaRad * vtV - m_dTipHeight * vtU ; + + vtNmax.Normalize() ; + } + else if ( dP2 < dLengthPathXY - dSmallLength + + dDeltaSmall * ( dP1 - dStemHeigth) / m_dTipHeight) { + + dMax = ( dDotUp - dX * vtUpCross.x - dY * vtUpCross.y) / vtUpCross.z ; + + vtNmax = vtUpCross ; + } + else { + + double dr = dP2 - dLengthPathXY ; + double dMr = m_dRadius + ( m_dTipRadius - m_dRadius) * ( dP1 - dStemHeigth) / m_dTipHeight ; + + dMax = dZF + sqrt( dMr * dMr - dr * dr) ; + + ptInt.Set( dX, dY, dMax) ; + + Vector3d vtU = ( ptInt - ptVF) - ( ptInt - ptVF) * vtV * vtV ; + + vtU.Normalize() ; + + vtNmax = dDeltaRad * vtV - m_dTipHeight * vtU ; + + vtNmax.Normalize() ; + } + + // Minimi + if ( dP2 < dSmallLength - dDeltaSmall * ( dP1 - dStemHeigth) / m_dTipHeight) { + + double dr = dP2 ; + double dMr = m_dRadius + ( m_dTipRadius - m_dRadius) * ( dP1 - dStemHeigth) / m_dTipHeight ; + + dMin = dZI - sqrt( dMr * dMr - dr * dr) ; + + ptInt.Set( dX, dY, dMin) ; + + Vector3d vtU = ( ptInt - ptVI) - ( ptInt - ptVI) * vtV * vtV ; + + vtU.Normalize() ; + + vtNmin = dDeltaRad * vtV - m_dTipHeight * vtU ; + + vtNmin.Normalize() ; + } + else if ( dP2 < dLengthPathXY + dSmallLength - dDeltaSmall * ( dP1 - dStemHeigth) / m_dTipHeight) { + + dMin = ( dDotDw - dX * vtDwCross.x - dY * vtDwCross.y) / vtDwCross.z ; + + vtNmin = vtDwCross ; + } + else { + + double dr = dP2 - dLengthPathXY ; + double dMr = m_dRadius + ( m_dTipRadius - m_dRadius) * ( dP1 - dStemHeigth) / m_dTipHeight ; + + dMin = dZF - sqrt( dMr * dMr - dr * dr) ; + + ptInt.Set( dX, dY, dMin) ; + + Vector3d vtU = ( ptInt - ptVF) - ( ptInt - ptVF) * vtV * vtV ; + + vtU.Normalize() ; + + vtNmin = dDeltaRad * vtV - m_dTipHeight * vtU ; + + vtNmin.Normalize() ; + } + + SubtractIntervals( nGrid, i, j, dMin, dMax, vtNmin, vtNmax) ; + } + } + } + } + return true ; } //---------------------------------------------------------------------------- bool VolZmap::Conus_XYMilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) { - double dStemHeigth = m_dHeight - m_dTipRadius ; + double dStemHeigth = m_dHeight - m_dTipHeight ; - CompCyl_Milling( nGrid, ptS, ptE, vtToolDir, dStemHeigth, m_dRadius) ; + CompCyl_Milling( nGrid, ptS, ptE, vtToolDir, dStemHeigth, m_dRadius, false, true) ; if ( m_dTipRadius < m_dRadius) { Point3d ptSTip = ptS - dStemHeigth * vtToolDir ; Point3d ptETip = ptE - dStemHeigth * vtToolDir ; - CompConus_Milling( nGrid, ptSTip, ptETip, vtToolDir, m_dTipHeight, m_dRadius, m_dTipRadius) ; + CompConus_Milling( nGrid, ptSTip, ptETip, vtToolDir, m_dTipHeight, m_dRadius, m_dTipRadius, true, false) ; } else { Point3d ptSTip = ptS - m_dHeight * vtToolDir ; Point3d ptETip = ptE - m_dHeight * vtToolDir ; - CompConus_Milling( nGrid, ptSTip, ptETip, - vtToolDir, m_dTipHeight, m_dTipRadius, m_dRadius) ; + CompConus_Milling( nGrid, ptSTip, ptETip, - vtToolDir, m_dTipHeight, m_dTipRadius, m_dRadius, false, true) ; } return true ; @@ -2492,7 +2851,7 @@ VolZmap::CylBall_Drilling( unsigned int nGrid, const Point3d & ptS, const Point3 double dStemHeigth = m_dHeight - m_dRadius ; - CompCyl_Drilling( nGrid, ptS, ptE, vtToolDir, dStemHeigth, m_dRadius) ; + CompCyl_Drilling( nGrid, ptS, ptE, vtToolDir, dStemHeigth, m_dRadius, false, false) ; // Sfera if ( m_nToolType == 2) { @@ -2510,7 +2869,7 @@ VolZmap::CylBall_Milling( unsigned int nGrid, const Point3d & ptS, const Point3d double dStemHeigth = m_dHeight - m_dTipHeight ; - CompCyl_Milling( nGrid, ptS, ptE, vtToolDir, dStemHeigth, m_dRadius) ; + CompCyl_Milling( nGrid, ptS, ptE, vtToolDir, dStemHeigth, m_dRadius, false, false) ; // Sfera if ( m_nToolType == 2) { @@ -2530,21 +2889,21 @@ VolZmap::Conus_Drilling( unsigned int nGrid, const Point3d & ptS, const Point3d double dStemHeigth = m_dHeight - m_dTipHeight ; - CompCyl_Drilling( nGrid, ptS, ptE, vtToolDir, dStemHeigth, m_dRadius) ; + CompCyl_Drilling( nGrid, ptS, ptE, vtToolDir, dStemHeigth, m_dRadius, false, true) ; // Trapano if ( m_dTipRadius < m_dRadius) { Point3d ptSCone = ptS - dStemHeigth * vtToolDir ; Point3d ptECone = ptE - dStemHeigth * vtToolDir ; - CompConus_Drilling( nGrid, ptSCone, ptECone, vtToolDir, m_dTipHeight, m_dRadius, m_dTipRadius) ; + CompConus_Drilling( nGrid, ptSCone, ptECone, vtToolDir, m_dTipHeight, m_dRadius, m_dTipRadius, true, false) ; } else { Point3d ptSCone = ptS - m_dHeight * vtToolDir ; Point3d ptECone = ptE - m_dHeight * vtToolDir ; - CompConus_Drilling( nGrid, ptSCone, ptECone, - vtToolDir, m_dTipHeight, m_dTipRadius, m_dRadius) ; + CompConus_Drilling( nGrid, ptSCone, ptECone, - vtToolDir, m_dTipHeight, m_dTipRadius, m_dRadius, false, true) ; } return true ; @@ -2556,28 +2915,28 @@ VolZmap::Conus_Milling( unsigned int nGrid, const Point3d & ptS, const Point3d & double dStemHeigth = m_dHeight - m_dTipHeight ; - CompCyl_Milling( nGrid, ptS, ptE, vtToolDir, dStemHeigth, m_dRadius) ; + CompCyl_Milling( nGrid, ptS, ptE, vtToolDir, dStemHeigth, m_dRadius, false, true) ; // Trapano if ( m_dTipRadius < m_dRadius) { Point3d ptSBall = ptS - dStemHeigth * vtToolDir ; Point3d ptEBall = ptE - dStemHeigth * vtToolDir ; - CompConus_Milling( nGrid, ptSBall, ptEBall, vtToolDir, m_dTipHeight, m_dRadius, m_dTipRadius) ; + CompConus_Milling( nGrid, ptSBall, ptEBall, vtToolDir, m_dTipHeight, m_dRadius, m_dTipRadius, true, false) ; } else { Point3d ptSBall = ptS - m_dHeight * vtToolDir ; Point3d ptEBall = ptE - m_dHeight * vtToolDir ; - CompConus_Milling( nGrid, ptSBall, ptEBall, - vtToolDir, m_dTipHeight, m_dTipRadius, m_dRadius) ; + CompConus_Milling( nGrid, ptSBall, ptEBall, - vtToolDir, m_dTipHeight, m_dTipRadius, m_dRadius, false, true) ; } return true ; } // ---------- Utensile generico ---------------------------------------------- - + /* //---------------------------------------------------------------------------- bool VolZmap::GenTool_Drilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) @@ -2686,8 +3045,315 @@ VolZmap::GenTool_Drilling( unsigned int nGrid, const Point3d & ptS, const Point3 } return true ; +}*/ + /* +//---------------------------------------------------------------------------- +bool +VolZmap::GenTool_Drilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) +{ + // Descrizione geometrica del moto + Point3d ptI = ptS ; + Point3d ptF = ptE ; + Vector3d vtMove = ptE - ptS ; + + // Settaggio profilo + CurveComposite* pToolProfile ; + + if ( m_ToolArcLineApprox.GetCurveCount() == 0) + // Se l'utensile non è stato approssimato uso l'originale + pToolProfile = & m_ToolOutline ; + else + // altrimenti uso l'approssimazione + pToolProfile = &m_ToolArcLineApprox ; + + // Ciclo sulle curve + const ICurve* pCurve = pToolProfile->GetFirstCurve() ; + const ICurve* pFirstConst = pCurve ; + + while ( pCurve != nullptr) { + + double dHeight ; + + int nCurveType = pCurve -> GetType() ; + + // Caso di segmento + if ( nCurveType == CRV_LINE) { + + Point3d ptStart, ptEnd ; + + pCurve -> GetStartPoint( ptStart) ; + pCurve -> GetEndPoint( ptEnd) ; + + if ( abs( ptStart.y - ptEnd.y) > EPS_SMALL) { + + dHeight = abs( ptStart.y - ptEnd.y) ; + + bool bTapB, bTapT ; + + CurveComposite* pToolPrev = pToolProfile ; + CurveComposite* ptToolNext = pToolProfile ; + const ICurve* pPrev = pToolPrev -> GetPrevCurve() ; + const ICurve* pNext = ptToolNext -> GetNextCurve() ; + + // Dettagli curva precedente + int nPrevType = pPrev -> GetType() ; + Point3d ptPrevLast ; + pPrev -> GetEndPoint( ptPrevLast) ; + + // Setto le variabili per il tappo superiore + if ( pPrev == pFirstConst || + nPrevType == CRV_ARC || + ptPrevLast.x < ptStart.x) + + bTapB = false ; + else + bTapB = true ; + + // Dettagli curva successiva + int nNextType = pNext -> GetType() ; + Point3d ptNextFirst ; + pNext -> GetEndPoint( ptNextFirst) ; + + if ( pNext == nullptr || + nNextType == CRV_ARC || + ptNextFirst.x < ptEnd.x) + + bTapT = false ; + else + bTapT = true ; + + // Il componente è un cilindro + if ( abs( ptStart.x - ptEnd.x) < EPS_SMALL) { + + double dRadius = ptStart.x ; + + CompCyl_Drilling( nGrid, ptI, ptF, vtToolDir, dHeight, dRadius, bTapB, bTapT) ; + } + // Il componente è un cono con vettore equiverso a quello dell'utensile + else if ( ptStart.x > ptEnd.x) { + + double dMaxRad = ptStart.x ; + double dMinRad = ptEnd.x ; + + CompConus_Drilling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad, bTapB, bTapT) ; + } + // Il componente è un cono con vettore opposto a quello dell'utensile + else if ( ptStart.x < ptEnd.x) { + + double dMaxRad = ptEnd.x ; + double dMinRad = ptStart.x ; + + Point3d ptIn = ptI - vtToolDir * dHeight ; + Point3d ptFn = ptIn + vtMove ; + + CompConus_Drilling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad, bTapT, bTapB) ; + } + } + else + dHeight = 0 ; + } + + // Caso arco + else if ( nCurveType == CRV_ARC) { + + // Centro e Punti iniziale e finale del cerchio + Point3d ptStart, ptEnd, ptO ; + + pCurve -> GetStartPoint( ptStart) ; + pCurve -> GetEndPoint( ptEnd) ; + pCurve -> GetCenterPoint( ptO) ; + + // Determino il raggio + Vector3d vtStRad = ptStart - ptO ; + Vector3d vtEnRad = ptEnd - ptO ; + + double dRadius = 0.5 * ( vtStRad.LenXY() + vtEnRad.LenXY()) ; + + // Determino le posizioni iniziale e finale del centro della sfera + Point3d ptOSt = ptI - vtToolDir * ( ptStart.y - ptO.y) ; + Point3d ptOEn = ptOSt + vtMove ; + + // Eseguo l'asportazione del materiale + CompBall_Milling( nGrid, ptOSt, ptOEn, dRadius) ; + + + // aggiorno l'altezza + dHeight = abs( ptStart.y - ptEnd.y) ; + } + + // Determino le posizioni iniziale e finale del componente successivo + ptI = ptI - vtToolDir * dHeight ; + ptF = ptI + vtMove ; + + // Aggiorno il puntatore + pCurve = pToolProfile->GetNextCurve() ; + } + + return true ; +}*/ + +//---------------------------------------------------------------------------- +bool +VolZmap::GenTool_Drilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) +{ + // Descrizione geometrica del moto + Point3d ptI = ptS ; + Point3d ptF = ptE ; + Vector3d vtMove = ptE - ptS ; + + // Settaggio profilo + CurveComposite* pToolProfile ; + + if ( m_ToolArcLineApprox.GetCurveCount() == 0) + // Se l'utensile non è stato approssimato uso l'originale + pToolProfile = & m_ToolOutline ; + else + // altrimenti uso l'approssimazione + pToolProfile = &m_ToolArcLineApprox ; + + // Ciclo sulle curve + const ICurve* pCurve = pToolProfile->GetFirstCurve() ; + const ICurve* pFirstConst = pCurve ; + + while ( pCurve != nullptr) { + + double dHeight ; + + int nCurveType = pCurve -> GetType() ; + + // Caso di segmento + if ( nCurveType == CRV_LINE) { + + Point3d ptStart, ptEnd ; + + pCurve -> GetStartPoint( ptStart) ; + pCurve -> GetEndPoint( ptEnd) ; + + if ( abs( ptStart.y - ptEnd.y) > EPS_SMALL) { + + dHeight = abs( ptStart.y - ptEnd.y) ; + + bool bTapB, bTapT ; + + pCurve = pToolProfile -> GetPrevCurve() ; + + // Dettagli curva precedente + int nPrevType = pCurve -> GetType() ; + Point3d ptPrevFirst, ptPrevLast ; + pCurve -> GetStartPoint( ptPrevFirst) ; + pCurve -> GetEndPoint( ptPrevLast) ; + + double dAbsDYPr = abs( ptPrevFirst.y - ptPrevLast.y) ; + double dDeltaXPr = ptPrevFirst.x - ptPrevLast.x ; + + // Setto le variabili per il tappo superiore + if ( pCurve == pFirstConst || + nPrevType == CRV_ARC || + ( dDeltaXPr < 0 && dAbsDYPr)) + + bTapB = false ; + else + bTapB = true ; + + // Dettagli curva successiva + + pCurve = pToolProfile -> GetNextCurve() ; + pCurve = pToolProfile -> GetNextCurve() ; + + int nNextType = pCurve -> GetType() ; + Point3d ptNextFirst ; + Point3d ptNextLast ; + pCurve -> GetStartPoint( ptNextFirst) ; + pCurve -> GetEndPoint( ptNextLast) ; + + double dAbsDYNx = abs( ptNextFirst.y - ptNextLast.y) ; + double dDeltaXNx = ptNextFirst.x - ptNextLast.x ; + double dAbsXEnd = abs( ptNextLast.x) ; + + if ( pCurve == nullptr || + nNextType == CRV_ARC || + ( dAbsDYNx < EPS_SMALL && ( dDeltaXNx > 0 || dAbsXEnd < EPS_SMALL))) + + bTapT = false ; + else + bTapT = true ; + + // Il componente è un cilindro + if ( abs( ptStart.x - ptEnd.x) < EPS_SMALL) { + + double dRadius = ptStart.x ; + + CompCyl_Drilling( nGrid, ptI, ptF, vtToolDir, dHeight, dRadius, bTapB, bTapT) ; + } + // Il componente è un cono con vettore equiverso a quello dell'utensile + else if ( ptStart.x > ptEnd.x) { + + double dMaxRad = ptStart.x ; + double dMinRad = ptEnd.x ; + + CompConus_Drilling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad, bTapB, bTapT) ; + } + // Il componente è un cono con vettore opposto a quello dell'utensile + else if ( ptStart.x < ptEnd.x) { + + double dMaxRad = ptEnd.x ; + double dMinRad = ptStart.x ; + + Point3d ptIn = ptI - vtToolDir * dHeight ; + Point3d ptFn = ptIn + vtMove ; + + CompConus_Drilling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad, bTapT, bTapB) ; + } + } + else { + + dHeight = 0 ; + pCurve = pToolProfile -> GetNextCurve() ; + } + } + + // Caso arco + else if ( nCurveType == CRV_ARC) { + + // Centro e Punti iniziale e finale del cerchio + Point3d ptStart, ptEnd, ptO ; + + pCurve -> GetStartPoint( ptStart) ; + pCurve -> GetEndPoint( ptEnd) ; + pCurve -> GetCenterPoint( ptO) ; + + // Determino il raggio + Vector3d vtStRad = ptStart - ptO ; + Vector3d vtEnRad = ptEnd - ptO ; + + double dRadius = 0.5 * ( vtStRad.LenXY() + vtEnRad.LenXY()) ; + + // Determino le posizioni iniziale e finale del centro della sfera + Point3d ptOSt = ptI - vtToolDir * ( ptStart.y - ptO.y) ; + Point3d ptOEn = ptOSt + vtMove ; + + // Eseguo l'asportazione del materiale + CompBall_Milling( nGrid, ptOSt, ptOEn, dRadius) ; + + + // aggiorno l'altezza + dHeight = abs( ptStart.y - ptEnd.y) ; + + pCurve = pToolProfile -> GetNextCurve() ; + } + + // Determino le posizioni iniziale e finale del componente successivo + ptI = ptI - vtToolDir * dHeight ; + ptF = ptI + vtMove ; + + // Aggiorno il puntatore + // pCurve = pToolProfile->GetNextCurve() ; + } + + return true ; } +/* //---------------------------------------------------------------------------- bool VolZmap::GenTool_Milling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) @@ -2795,6 +3461,167 @@ VolZmap::GenTool_Milling( unsigned int nGrid, const Point3d & ptS, const Point3d } return true ; +}*/ + +//---------------------------------------------------------------------------- +bool +VolZmap::GenTool_Milling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) +{ + // Descrizione geometrica del moto + Point3d ptI = ptS ; + Point3d ptF = ptE ; + Vector3d vtMove = ptE - ptS ; + + // Settaggio profilo + CurveComposite* pToolProfile ; + + if ( m_ToolArcLineApprox.GetCurveCount() == 0) + // Se l'utensile non è stato approssimato uso l'originale + pToolProfile = & m_ToolOutline ; + else + // altrimenti uso l'approssimazione + pToolProfile = &m_ToolArcLineApprox ; + + // Ciclo sulle curve + const ICurve* pCurve = pToolProfile->GetFirstCurve() ; + const ICurve* pFirstConst = pCurve ; + + while ( pCurve != nullptr) { + + double dHeight ; + + int nCurveType = pCurve -> GetType() ; + + // Caso di segmento + if ( nCurveType == CRV_LINE) { + + Point3d ptStart, ptEnd ; + + pCurve -> GetStartPoint( ptStart) ; + pCurve -> GetEndPoint( ptEnd) ; + + if ( abs( ptStart.y - ptEnd.y) > EPS_SMALL) { + + dHeight = abs( ptStart.y - ptEnd.y) ; + + bool bTapB, bTapT ; + + pCurve = pToolProfile -> GetPrevCurve() ; + + // Dettagli curva precedente + int nPrevType = pCurve -> GetType() ; + Point3d ptPrevFirst, ptPrevLast ; + pCurve -> GetStartPoint( ptPrevFirst) ; + pCurve -> GetEndPoint( ptPrevLast) ; + + double dAbsDYPr = abs( ptPrevFirst.y - ptPrevLast.y) ; + double dDeltaXPr = ptPrevFirst.x - ptPrevLast.x ; + + // Setto le variabili per il tappo superiore + if ( pCurve == pFirstConst || + nPrevType == CRV_ARC || + ( dDeltaXPr < 0 && dAbsDYPr)) + + bTapB = false ; + else + bTapB = true ; + + // Dettagli curva successiva + + pCurve = pToolProfile -> GetNextCurve() ; + pCurve = pToolProfile -> GetNextCurve() ; + + int nNextType = pCurve -> GetType() ; + Point3d ptNextFirst ; + Point3d ptNextLast ; + pCurve -> GetStartPoint( ptNextFirst) ; + pCurve -> GetEndPoint( ptNextLast) ; + + double dAbsDYNx = abs( ptNextFirst.y - ptNextLast.y) ; + double dDeltaXNx = ptNextFirst.x - ptNextLast.x ; + double dAbsXEnd = abs( ptNextLast.x) ; + + if ( pCurve == nullptr || + nNextType == CRV_ARC || + ( dAbsDYNx < EPS_SMALL && ( dDeltaXNx > 0 || dAbsXEnd < EPS_SMALL))) + + bTapT = false ; + else + bTapT = true ; + + // Il componente è un cilindro + if ( abs( ptStart.x - ptEnd.x) < EPS_SMALL) { + + double dRadius = ptStart.x ; + + CompCyl_Milling( nGrid, ptI, ptF, vtToolDir, dHeight, dRadius, bTapB, bTapT) ; + } + // Il componente è un cono con vettore equiverso a quello dell'utensile + else if ( ptStart.x > ptEnd.x) { + + double dMaxRad = ptStart.x ; + double dMinRad = ptEnd.x ; + + CompConus_Milling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad, bTapB, bTapT) ; + } + // Il componente è un cono con vettore opposto a quello dell'utensile + else if ( ptStart.x < ptEnd.x) { + + double dMaxRad = ptEnd.x ; + double dMinRad = ptStart.x ; + + Point3d ptIn = ptI - vtToolDir * dHeight ; + Point3d ptFn = ptIn + vtMove ; + + CompConus_Milling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad, bTapT, bTapB) ; + } + } + else { + + dHeight = 0 ; + pCurve = pToolProfile -> GetNextCurve() ; + } + } + + // Caso arco + else if ( nCurveType == CRV_ARC) { + + // Centro e Punti iniziale e finale del cerchio + Point3d ptStart, ptEnd, ptO ; + + pCurve -> GetStartPoint( ptStart) ; + pCurve -> GetEndPoint( ptEnd) ; + pCurve -> GetCenterPoint( ptO) ; + + // Determino il raggio + Vector3d vtStRad = ptStart - ptO ; + Vector3d vtEnRad = ptEnd - ptO ; + + double dRadius = 0.5 * ( vtStRad.LenXY() + vtEnRad.LenXY()) ; + + // Determino le posizioni iniziale e finale del centro della sfera + Point3d ptOSt = ptI - vtToolDir * ( ptStart.y - ptO.y) ; + Point3d ptOEn = ptOSt + vtMove ; + + // Eseguo l'asportazione del materiale + CompBall_Milling( nGrid, ptOSt, ptOEn, dRadius) ; + + + // aggiorno l'altezza + dHeight = abs( ptStart.y - ptEnd.y) ; + + pCurve = pToolProfile -> GetNextCurve() ; + } + + // Determino le posizioni iniziale e finale del componente successivo + ptI = ptI - vtToolDir * dHeight ; + ptF = ptI + vtMove ; + + // Aggiorno il puntatore + // pCurve = pToolProfile->GetNextCurve() ; + } + + return true ; } @@ -2820,6 +3647,7 @@ VolZmap::CompCyl_ZDrilling( unsigned int nGrid, const Point3d & ptS, const Point // Parametri geometrici dell'utensile double dSqRad = dRad * dRad ; + double dSqfeSqRad = dSqRad - 2 * dRad * EPS_SMALL ; // Punte del gambo Point3d ptTStemS = ptS - vtToolDir * dHei ; @@ -2840,8 +3668,8 @@ VolZmap::CompCyl_ZDrilling( unsigned int nGrid, const Point3d & ptS, const Point double dSqLen = vtC.SqLen() ; // Se il punto si trova dentro il cerchio taglio - if ( dSqLen < dSqRad) - SubtractIntervals( nGrid, i, j, dMinStemZ, dMaxStemZ, V_NULL, V_NULL) ; + if ( dSqLen < dSqfeSqRad) + SubtractIntervals( nGrid, i, j, dMinStemZ, dMaxStemZ, Z_AX, - Z_AX) ; } } return true ; @@ -2865,6 +3693,7 @@ VolZmap::CompConus_ZDrilling( unsigned int nGrid, const Point3d & ptS, const Poi double dAngC = dHei / ( dMaxRad - dMinRad) ; double dSqMinRad = dMinRad * dMinRad ; double dSqMaxRad = dMaxRad * dMaxRad ; + double dDeltaR = dMaxRad - dMinRad ; // Studio delle simmetrie if ( vtToolDir.z > 0) { @@ -2878,6 +3707,14 @@ VolZmap::CompConus_ZDrilling( unsigned int nGrid, const Point3d & ptS, const Poi dZMax = ( ptS.z < ptE.z ? ptE.z + dHei : ptS.z + dHei) ; } + + double dL = dMaxRad * dAngC ; + + Point3d ptV = ( vtToolDir * ( ptE - ptS) < 0 ? ptE : ptS) - vtToolDir * dL ; + + double dMin, dMax ; + Vector3d vtMin, vtMax ; + // Ciclo sui punti for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { @@ -2890,17 +3727,50 @@ VolZmap::CompConus_ZDrilling( unsigned int nGrid, const Point3d & ptS, const Poi if ( dSqDist < dSqMinRad) - SubtractIntervals( nGrid, i, j, dZMin, dZMax, V_NULL, V_NULL) ; + SubtractIntervals( nGrid, i, j, dZMin, dZMax, Z_AX, -Z_AX) ; else if ( dSqDist < dSqMaxRad) { double dr = sqrt( dSqDist) ; - if ( vtToolDir.z > 0) + if ( vtToolDir.z > 0) { - SubtractIntervals( nGrid, i, j, dZMin + dAngC * ( dr - dMinRad), dZMax, V_NULL, V_NULL) ; - else - SubtractIntervals( nGrid, i, j, dZMin, dZMax - dAngC * ( dr - dMinRad), V_NULL, V_NULL) ; + dMin = dZMin + dAngC * ( dr - dMinRad) ; + dMax = dZMax ; + + vtMax = - Z_AX ; + + Point3d ptInt( dX, dY, dMin) ; + + Vector3d vtU = ( ptInt - ptV) - ( ptInt - ptV) * vtToolDir * vtToolDir ; + + vtU.Normalize() ; + + vtMin = dDeltaR * vtToolDir - dHei * vtU ; + + vtMin.Normalize() ; + + SubtractIntervals( nGrid, i, j, dMin, dMax, vtMin, vtMax) ; + } + else { + + dMin = dZMin ; + dMax = dZMax - dAngC * ( dr - dMinRad) ; + + vtMin = Z_AX ; + + Point3d ptInt( dX, dY, dMax) ; + + Vector3d vtU = ( ptInt - ptV) - ( ptInt - ptV) * vtToolDir * vtToolDir ; + + vtU.Normalize() ; + + vtMax = dDeltaR * vtToolDir - dHei * vtU ; + + vtMax.Normalize() ; + + SubtractIntervals( nGrid, i, j, dMin, dMax, vtMin, vtMax) ; + } } } @@ -2930,6 +3800,9 @@ VolZmap::CompCyl_ZMilling( unsigned int nGrid, const Point3d & ptS, const Point3 Point3d ptIT = ptI - vtToolDir * dHei ; Point3d ptFT = ptF - vtToolDir * dHei ; Point3d ptIxy( ptI.x, ptI.y, 0) ; + + Point3d ptIUp( ptI.x, ptI.y, max( ptI.z, ptIT.z)) ; + Point3d ptIDw( ptI.x, ptI.y, min( ptI.z, ptIT.z)) ; // Quote iniziali e finali massime e // minime del gambo dell'utensile e DeltaZ @@ -2953,6 +3826,8 @@ VolZmap::CompCyl_ZMilling( unsigned int nGrid, const Point3d & ptS, const Point3 double dSqSemiAxMin = dSemiAxMin * dSemiAxMin ; // da cui si ottiene x1^2 = a^2 - dCos^2 x2^2 double dSqRatio = dSqSemiAxMin / dSqRad ; + double dSafeRad = dRad - EPS_SMALL ; + // Definizione di un sistema di riferimento ad hoc Vector3d vtV1, vtV2 ; @@ -2969,6 +3844,7 @@ VolZmap::CompCyl_ZMilling( unsigned int nGrid, const Point3d & ptS, const Point3 vtV2.Rotate( Z_AX, 90) ; double dMin, dMax ; + Vector3d vtMin, vtMax ; for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { @@ -2982,32 +3858,57 @@ VolZmap::CompCyl_ZMilling( unsigned int nGrid, const Point3d & ptS, const Point3 double dX1 = vtC * vtV1 ; double dX2 = vtC * vtV2 ; + Point3d ptInt ; + // Se il punto appartiene alla proiezione del volume spazzato valuto massimo e minimo - if ( ( dX1 > 0 && dX1 < dLenXY && abs( dX2) < dRad) || + if ( ( dX1 > 0 && dX1 < dLenXY && abs( dX2) < dSafeRad) || ( dX1 - dLenXY) * ( dX1 - dLenXY) + dX2 * dX2 < dSqRad || dX1 * dX1 + dX2 * dX2 < dSqRad) { double dX1_0 = sqrt( dSqRad - dX2 * dX2) ; // Massimo - if ( ( dX1 - dLenXY) * ( dX1 - dLenXY) + dX2 * dX2 < dSqRad) + if ( ( dX1 - dLenXY) * ( dX1 - dLenXY) + dX2 * dX2 < dSqRad) { dMax = dZMaxF ; - else + vtMax = - Z_AX ; + } + else { + dMax = dZMaxI + dDeltaZ * ( dX1 + dX1_0) / dLenXY ; + + Vector3d vtCirc = dX1_0 * vtV1 - dX2 * vtV2 ; + Vector3d vtTan( - vtCirc.y, vtCirc.x, 0) ; + Vector3d vtCross = vtTan ^ vtMove ; + + vtMax = ( vtCross * vtCirc > 0 ? vtCross : - vtCross) ; + vtMax.Normalize() ; + } // Minimo - if ( dX1 * dX1 + dX2 * dX2 < dSqRad) + if ( dX1 * dX1 + dX2 * dX2 < dSqRad) { dMin = dZMinI ; - else + + vtMin = Z_AX ; + } + else { + dMin = dZMinI + dDeltaZ * ( dX1 - dX1_0) / dLenXY ; - SubtractIntervals( nGrid, i, j, dMin, dMax, V_NULL, V_NULL) ; + Vector3d vtCirc = - dX1_0 * vtV1 - dX2 * vtV2 ; + Vector3d vtTan( - vtCirc.y, vtCirc.x, 0) ; + Vector3d vtCross = vtTan ^ vtMove ; + + vtMin = ( vtCross * vtCirc > 0 ? vtCross : - vtCross) ; + vtMin.Normalize() ; + } + SubtractIntervals( nGrid, i, j, dMin, dMax, vtMin, vtMax) ; } } } return true ; } +/* //---------------------------------------------------------------------------- bool VolZmap::CompConus_ZMilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir, double dHei, double dMaxRad, double dMinRad) @@ -3161,7 +4062,516 @@ VolZmap::CompConus_ZMilling( unsigned int nGrid, const Point3d & ptS, const Poin } } return true ; -} +} */ + + +//---------------------------------------------------------------------------- +bool +VolZmap::CompConus_ZMilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir, double dHei, double dMaxRad, double dMinRad) +{ + unsigned int nStartI, nStartJ, nEndI, nEndJ ; + + bool Control = BBoxComponent( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dMaxRad, dMinRad, dHei) ; + + if ( ! Control) + return true ; + + Point3d ptI = ( vtToolDir * ( ptE - ptS) > 0 ? ptS : ptE) ; + Point3d ptF = ( vtToolDir * ( ptE - ptS) > 0 ? ptE : ptS) ; + + Point3d ptIT = ptI - vtToolDir * dHei ; + Point3d ptFT = ptF - vtToolDir * dHei ; + + Point3d ptIxy( ptI.x, ptI.y, 0) ; + Point3d ptFxy( ptF.x, ptF.y, 0) ; + + Vector3d vtMove = ptF - ptI ; double dLen = vtMove.Len() ; + Vector3d vtMLong = ( vtMove * vtToolDir) * vtToolDir ; double dLLong = vtMLong.Len() ; + Vector3d vtMOrt = vtMove - vtMLong ; double dLOrt = vtMOrt.Len() ; + + Vector3d vtV1 = vtToolDir ; + Vector3d vtV2 = vtMOrt ; vtV2.Normalize() ; + Vector3d vtV3 = vtV1 ^ vtV2 ; + + double dZI = ptI.z ; + double dZTI = ptI.z - vtV1.z * dHei ; + double dDeltaZ = ptF.z - ptI.z ; + double dDeltaR = dMaxRad - dMinRad ; + + double dTan = dDeltaR / dHei ; + double dRatio = ( vtMove * vtV1) / ( vtMove * vtV2) ; + + bool bCase = ( dRatio * dTan > 1 ? true : false) ; + + double dCos = dTan * dRatio ; + double dSin = ( 1 - dCos * dCos > 0 ? sqrt( 1 - dCos * dCos) : 0) ; + + double dDen = sqrt( 1 + dTan * dTan) ; + + Point3d ptV = ptI - vtV1 * ( dHei * dMaxRad / dDeltaR) ; + Point3d ptVF = ptV + vtMove ; + + Vector3d vtNs = - ( dTan / dDen) * vtV1 + ( dCos / dDen) * vtV2 + ( dSin / dDen) * vtV3 ; + Vector3d vtNd = - ( dTan / dDen) * vtV1 + ( dCos / dDen) * vtV2 - ( dSin / dDen) * vtV3 ; + Vector3d vtR0 = ptV - ORIG ; + + vtNs.Normalize() ; + vtNd.Normalize() ; + + double dDots = vtR0 * vtNs ; + double dDotd = vtR0 * vtNd ; + + double dMin, dMax, dPLim, dMLim ; + Vector3d vtMin, vtMax, vtP, vtM ; + + Vector3d vtUmv = vtMove ; + vtUmv.Normalize() ; + + Point3d ptInt ; + + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { + + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; + + Vector3d vtCI = ptC - ptIxy ; double dSqDI = vtCI.SqLenXY() ; + Vector3d vtCF = ptC - ptFxy ; double dSqDF = vtCF.SqLenXY() ; + + double dIDO = vtCI * vtV3 ; + double dIDL = vtCI * vtV2 ; + double dIVarCos = dIDL / sqrt( dSqDI) ; + + double dFDL = vtCF * vtV2 ; + double dFVarCos = dFDL / sqrt( dSqDF) ; + + if ( dSqDI < dMaxRad * dMaxRad || dSqDF < dMaxRad * dMaxRad || + (abs( dIDO) < dMaxRad && dIDL > 0 && dIDL < dLOrt)) { + + // Caso dTan * dRatio > 1 + if ( bCase) { + + // Limiti nella direzione positiva di vtV1 + if ( dSqDF < dMaxRad * dMaxRad) { + + dPLim = dZI + dDeltaZ ; + + vtP = - vtToolDir ; + } + else { + + double dIDL_0 = - sqrt( dMaxRad * dMaxRad - dIDO * dIDO) ; + + dPLim = dZI + ( dIDL - dIDL_0) * dDeltaZ / dLOrt ; + + Vector3d vtCirc = - dIDL_0 * vtV2 - dIDO * vtV3 ; + Vector3d vtTan( - vtCirc.y, vtCirc.x, 0) ; + Vector3d vtCross = vtTan ^ vtUmv ; + + vtP = ( vtCross * vtCirc > 0 ? vtCross : - vtCross) ; + vtP.Normalize() ; + } + + // Limiti nella direzione negativa di vtV1 + if ( dSqDI < dMinRad * dMinRad) { + + dMLim = dZTI ; + + vtM = vtToolDir ; + } + else if ( dSqDI < dMaxRad * dMaxRad) { + + dMLim = dZTI + ( sqrt( dSqDI) - dMinRad) * ( dZI - dZTI) / dDeltaR ; + + ptInt.Set( dX, dY, dMLim) ; + + Vector3d vtU = ( ptInt - ptV) - ( ptInt - ptV) * vtToolDir * vtToolDir ; + + vtU.Normalize() ; + + vtM = dDeltaR * vtToolDir - dHei * vtU ; + + vtM.Normalize() ; + } + else { + + double dIDL_0 = sqrt( dMaxRad * dMaxRad - dIDO * dIDO) ; + + dMLim = dZI + ( dIDL - dIDL_0) * dDeltaZ / dLOrt ; + + Vector3d vtCirc = - dIDL_0 * vtV2 - dIDO * vtV3 ; + Vector3d vtTan( - vtCirc.y, vtCirc.x, 0) ; + Vector3d vtCross = vtTan ^ vtUmv ; + + vtM = ( vtCross * vtMove > 0 ? vtCross : - vtCross) ; + vtM.Normalize() ; + } + } + else { + + // Limiti nella direzione positiva di vtV1 + if ( dSqDF < dMaxRad * dMaxRad) { + + dPLim = dZI + dDeltaZ ; + + vtP = - vtToolDir ; + } + else { + + double dIDL_0 = - sqrt( dMaxRad * dMaxRad - dIDO * dIDO) ; + + dPLim = dZI + ( dIDL - dIDL_0) * dDeltaZ / dLOrt ; + + Vector3d vtCirc = - dIDL_0 * vtV2 - dIDO * vtV3 ; + Vector3d vtTan( - vtCirc.y, vtCirc.x, 0) ; + Vector3d vtCross = vtTan ^ vtUmv ; + + vtP = ( vtCross * vtCirc > 0 ? vtCross : - vtCross) ; + vtP.Normalize() ; + } + + // Limiti nella direzione negativa di vtV1 + if ( dSqDI < dMinRad * dMinRad) { + + dMLim = dZTI ; + + vtM = vtToolDir ; + } + else if ( dSqDI >= dMinRad * dMinRad && dSqDI < dMaxRad * dMaxRad && dIVarCos < dCos) { + + dMLim = dZTI + ( sqrt( dSqDI) - dMinRad) * ( dZI - dZTI) / dDeltaR ; + + ptInt.Set( dX, dY, dMLim) ; + + Vector3d vtU = ( ptInt - ptV) - ( ptInt - ptV) * vtToolDir * vtToolDir ; + + vtU.Normalize() ; + + vtM = dDeltaR * vtToolDir - dHei * vtU ; + + vtM.Normalize() ; + } + else if ( dSqDI >= dMinRad * dMinRad && dIVarCos >= dCos && dFVarCos < dCos && abs( dIDO) < dMaxRad * dSin) { // da qui + + if ( dIDO > - dMaxRad * dSin && dIDO <= - dMinRad * dSin) { + + dMLim = ( dDotd - dX * vtNd.x - dY * vtNd.y) / vtNd.z ; + + vtM = - vtNd ; + } + else if ( dIDO > - dMinRad * dSin && dIDO < dMinRad * dSin) { + + double dIDL_0 = sqrt( dMinRad * dMinRad - dIDO * dIDO) ; + + dMLim = dZTI + ( dIDL - dIDL_0) * dDeltaZ / dLOrt ; + + Vector3d vtCirc = - dIDL_0 * vtV2 - dIDO * vtV3 ; + Vector3d vtTan( - vtCirc.y, vtCirc.x, 0) ; + Vector3d vtCross = vtTan ^ vtUmv ; + + vtM = ( vtCross * vtMove > 0 ? vtCross : - vtCross) ; + vtM.Normalize() ; + } + else if ( dIDO >= dMinRad * dSin && dIDO < dMaxRad * dSin) { + + dMLim = ( dDots - dX * vtNs.x - dY * vtNs.y) / vtNs.z ; // a qui + + vtM = - vtNs ; + } + } + else if ( dFVarCos >= dCos) { + + if ( dSqDF < dMinRad * dMinRad) { + + double dIDL_0 = sqrt( dMinRad * dMinRad - dIDO * dIDO) ; + + dMLim = dZTI + ( dIDL - dIDL_0) * dDeltaZ / dLOrt ; + + Vector3d vtCirc = - dIDL_0 * vtV2 - dIDO * vtV3 ; + Vector3d vtTan( - vtCirc.y, vtCirc.x, 0) ; + Vector3d vtCross = vtTan ^ vtUmv ; + vtM = ( vtCross * vtMove > 0 ? vtCross : - vtCross) ; + + vtM.Normalize() ; + } + else { + + dMLim = dZTI + dDeltaZ + ( sqrt( dSqDF) - dMinRad) * ( dZI - dZTI) / dDeltaR ; + + ptInt.Set( dX, dY, dMLim) ; + + Vector3d vtU = ( ptInt - ptVF) - ( ptInt - ptVF) * vtToolDir * vtToolDir ; + + vtU.Normalize() ; + + vtM = dDeltaR * vtToolDir - dHei * vtU ; + + vtM.Normalize() ; + } + } + else { + + double dIDL_0 = sqrt( dMaxRad * dMaxRad - dIDO * dIDO) ; + + dMLim = dZI + ( dIDL - dIDL_0) * dDeltaZ / dLOrt ; + + Vector3d vtCirc = - dIDL * vtV2 - dIDO * vtV3 ; + Vector3d vtTan( - vtCirc.y, vtCirc.x, 0) ; + Vector3d vtCross = vtTan ^ vtMove ; + + vtM = ( vtCross * vtMove > 0 ? vtCross : - vtCross) ; + vtM.Normalize() ; + } + } + + //dMin = min( dPLim, dMLim) ; + //dMax = max( dPLim, dMLim) ; + + if ( dMLim < dPLim) { + + dMin = dMLim ; + dMax = dPLim ; + + vtMin = vtM ; + vtMax = vtP ; + } + else { + + dMin = dPLim ; + dMax = dMLim ; + + vtMin = vtP ; + vtMax = vtM ; + } + + SubtractIntervals( nGrid, i, j, dMin, dMax, vtMin, vtMax) ; + } + } + } + return true ; +} +/* +//---------------------------------------------------------------------------- +bool +VolZmap::CompConus_ZMilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir, double dHei, double dMaxRad, double dMinRad) +{ + unsigned int nStartI, nStartJ, nEndI, nEndJ ; + + bool Control = BBoxComponent( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dMaxRad, dMinRad, dHei) ; + + if ( ! Control) + return true ; + + Point3d ptI = ( vtToolDir * ( ptE - ptS) > 0 ? ptS : ptE) ; + Point3d ptF = ( vtToolDir * ( ptE - ptS) > 0 ? ptE : ptS) ; + + Point3d ptIT = ptI - vtToolDir * dHei ; + Point3d ptFT = ptF - vtToolDir * dHei ; + + Point3d ptIxy( ptI.x, ptI.y, 0) ; + Point3d ptFxy( ptF.x, ptF.y, 0) ; + + Vector3d vtMove = ptF - ptI ; double dLen = vtMove.Len() ; + Vector3d vtMLong = ( vtMove * vtToolDir) * vtToolDir ; double dLLong = vtMLong.Len() ; + Vector3d vtMOrt = vtMove - vtMLong ; double dLOrt = vtMOrt.Len() ; + + Vector3d vtV1 = vtToolDir ; + Vector3d vtV2 = vtMOrt ; vtV2.Normalize() ; + Vector3d vtV3 = vtV1 ^ vtV2 ; + + double dZI = ptI.z ; + double dZTI = ptI.z - vtV1.z * dHei ; + double dDeltaZ = ptF.z - ptI.z ; + double dDeltaR = dMaxRad - dMinRad ; + + double dTan = dDeltaR / dHei ; + double dRatio = ( vtMove * vtV1) / ( vtMove * vtV2) ; + + bool bCase = ( dRatio * dTan > 1 ? false : true) ; + + double dCos = dTan * dRatio ; + double dSin = ( 1 - dCos * dCos > 0 ? sqrt( 1 - dCos * dCos) : 0) ; + + double dDen = sqrt( 1 + dTan * dTan) ; + + Point3d ptV = ptI - vtV1 * ( dHei * dMaxRad / dDeltaR) ; + Point3d ptVF = ptV + vtMove ; + + Vector3d vtNs = - ( dTan / dDen) * vtV1 + ( dCos / dDen) * vtV2 + ( dSin / dDen) * vtV3 ; + Vector3d vtNd = - ( dTan / dDen) * vtV1 + ( dCos / dDen) * vtV2 - ( dSin / dDen) * vtV3 ; + Vector3d vtR0 = ptV - ORIG ; + + vtNs.Normalize() ; + vtNd.Normalize() ; + + double dDots = vtR0 * vtNs ; + double dDotd = vtR0 * vtNd ; + + double dMin, dMax, dPLim, dMLim ; + Vector3d vtMin, vtMax, vtP, vtM ; + + Vector3d vtUmv = vtMove ; + vtUmv.Normalize() ; + + Point3d ptInt ; + + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { + + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; + + Vector3d vtCI = ptC - ptIxy ; double dSqDI = vtCI.SqLenXY() ; + Vector3d vtCF = ptC - ptFxy ; double dSqDF = vtCF.SqLenXY() ; + + double dIDO = vtCI * vtV3 ; + double dIDL = vtCI * vtV2 ; + double dIVarCos = dIDL / sqrt( dSqDI) ; + + double dFDL = vtCF * vtV2 ; + double dFVarCos = dFDL / sqrt( dSqDF) ; + + if ( dSqDI < dMaxRad * dMaxRad || dSqDF < dMaxRad * dMaxRad || + (abs( dIDO) < dMaxRad && dIDL > 0 && dIDL < dLOrt)) { + + // Caso dTan * dRatio < 1 + if ( bCase) { + + // Limiti nella direzione positiva di vtV1 + if ( dSqDF < dMaxRad * dMaxRad) { + + dPLim = dZI + dDeltaZ ; + + vtP = - vtToolDir ; + } + else { + + dPLim = dZI + ( dIDL + sqrt( dMaxRad * dMaxRad - dIDO * dIDO)) * dDeltaZ / dLOrt ; + + ptInt.Set( dX, dY, dPLim) ; + + vtP = - ( ptInt - ptI) + ( ptInt - ptI) * vtUmv * vtUmv ; + + vtP.Normalize() ; + } + + // Limiti nella direzione negativa di vtV1 + if ( dSqDI < dMinRad * dMinRad) { + + dMLim = dZTI ; + + vtM = vtToolDir ; + } + else if ( dSqDI < dMaxRad * dMaxRad) { + + dMLim = dZTI + ( sqrt( dSqDI) - dMinRad) * ( dZI - dZTI) / dDeltaR ; + + ptInt.Set( dX, dY, dMLim) ; + + Vector3d vtU = ( ptInt - ptV) - ( ptInt - ptV) * vtToolDir * vtToolDir ; + + vtU.Normalize() ; + + vtM = dDeltaR * vtToolDir - dHei * vtU ; + + vtM.Normalize() ; + } + else { + + dMLim = dZI + ( dIDL - sqrt( dMaxRad * dMaxRad - dIDO * dIDO)) * dDeltaZ / dLOrt ; + + ptInt.Set( dX, dY, dMLim) ; + + vtM = - ( ptInt - ptI) + ( ptInt - ptI) * vtUmv * vtUmv ; + + vtM.Normalize() ; + } + } + else { + + // Limiti nella direzione positiva di vtV1 + if ( dSqDF < dMaxRad * dMaxRad) { + + dPLim = dZI + dDeltaZ ; + + vtP = - vtToolDir ; + } + else { + + dPLim = dZI + ( dIDL + sqrt( dMaxRad * dMaxRad - dIDO * dIDO)) * dDeltaZ / dLOrt ; + + ptInt.Set( dX, dY, dPLim) ; + + vtP = - ( ptInt - ptI) + ( ptInt - ptI) * vtUmv * vtUmv ; + + vtP.Normalize() ; + } + + // Limiti nella direzione negativa di vtV1 + if ( dSqDI < dMinRad * dMinRad) { + + dMLim = dZTI ; + + vtM = vtToolDir ; + } + else if ( dSqDI < dMaxRad * dMaxRad) { + + dMLim = dZTI + ( sqrt( dSqDI) - dMinRad) * ( dZI - dZTI) / dDeltaR ; + + ptInt.Set( dX, dY, dMLim) ; + + Vector3d vtU = ( ptInt - ptV) - ( ptInt - ptV) * vtToolDir * vtToolDir ; + + vtU.Normalize() ; + + vtM = dDeltaR * vtToolDir - dHei * vtU ; + + vtM.Normalize() ; + } + else { + + dMLim = dZI + ( dIDL - sqrt( dMaxRad * dMaxRad - dIDO * dIDO)) * dDeltaZ / dLOrt ; + + ptInt.Set( dX, dY, dMLim) ; + + vtM = - ( ptInt - ptI) + ( ptInt - ptI) * vtUmv * vtUmv ; + + vtM.Normalize() ; + } + } + + //dMin = min( dPLim, dMLim) ; + //dMax = max( dPLim, dMLim) ; + + if ( dMLim < dPLim) { + + dMin = dMLim ; + dMax = dPLim ; + + vtMin = vtM ; + vtMax = vtP ; + } + else { + + dMin = dPLim ; + dMax = dMLim ; + + vtMin = vtP ; + vtMax = vtM ; + } + + SubtractIntervals( nGrid, i, j, dMin, dMax, vtMin, vtMax) ; + } + } + } + return true ; +}*/ + + @@ -3170,9 +4580,8 @@ VolZmap::CompConus_ZMilling( unsigned int nGrid, const Point3d & ptS, const Poin //---------------------------------------------------------------------------- bool VolZmap::CompCyl_Drilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir, - double dHei, double dRad) + double dHei, double dRad, bool bTapB, bool bTapT) { - double dMin, dMax; unsigned int nStartI, nEndI, nStartJ, nEndJ ; bool Control = BBoxComponent( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, @@ -3199,6 +4608,9 @@ VolZmap::CompCyl_Drilling( unsigned int nGrid, const Point3d & ptS, const Point3 Frame3d CylFrame ; CylFrame.Set( ptI, vtV1, vtV2, vtV3) ; + double dMin, dMax; + Vector3d vtNmin, vtNmax ; + // Lunghezzza cilindro totale altezza + moto double dLen = ( ptF - ptI).Len() ; @@ -3212,13 +4624,30 @@ VolZmap::CompCyl_Drilling( unsigned int nGrid, const Point3d & ptS, const Point3 Point3d ptC( dX, dY, 0) ; Point3d ptInt1, ptInt2 ; + Vector3d vtN1, vtN2 ; - if ( IntersLineCylinder( ptC, Z_AX, CylFrame, dLen, dRad, ptInt1, ptInt2)) { + if ( IntersLineCylinder( ptC, Z_AX, CylFrame, dLen, dRad, ptInt1, ptInt2,vtN1, vtN2, bTapB, bTapT)) { - dMin = min( ptInt1.z, ptInt2.z) ; - dMax = max( ptInt1.z, ptInt2.z) ; + //dMin = min( ptInt1.z, ptInt2.z) ; + //dMax = max( ptInt1.z, ptInt2.z) ; - SubtractIntervals( nGrid, i, j, dMin, dMax, V_NULL, V_NULL) ; + if ( ptInt1.z < ptInt2.z) { + + dMin = ptInt1.z ; + dMax = ptInt2.z ; + vtNmin = vtN1 ; + vtNmax = vtN2 ; + } + else { + + dMin = ptInt2.z ; + dMax = ptInt1.z ; + vtNmin = vtN2 ; + vtNmax = vtN1 ; + + } + + SubtractIntervals( nGrid, i, j, dMin, dMax, vtNmin, vtNmax) ; } } } @@ -3227,13 +4656,13 @@ VolZmap::CompCyl_Drilling( unsigned int nGrid, const Point3d & ptS, const Point3 //---------------------------------------------------------------------------- bool -VolZmap::CompConus_Drilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, - const Vector3d & vtToolDir, double dHei, double dMaxRad, double dMinRad) +VolZmap::CompConus_Drilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir, + double dHei, double dMaxRad, double dMinRad, bool bTapB, bool bTapT) { - double dMin, dMax ; unsigned int nStartI, nStartJ, nEndI, nEndJ ; - bool Control = BBoxComponent( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dMaxRad, dMinRad, dHei) ; + bool Control = BBoxComponent( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, + dMaxRad, dMinRad, dHei) ; if ( ! Control) return true ; @@ -3244,12 +4673,15 @@ VolZmap::CompConus_Drilling( unsigned int nGrid, const Point3d & ptS, const Poin double dL = ( ( dMaxRad * dHei) / dDeltaR) ; double dl = dL - dHei ; + bool bTapCylEn = bTapB ; + Point3d ptVertex = ( vtToolDir * ( ptE - ptS) > 0 ? ptS : ptE) - vtToolDir * dL ; // Sistema di riferimento del cono Vector3d vtV1 = vtToolDir ; - Point3d ptP = ( abs( vtV1.z) < EPS_SMALL ? Point3d( ptVertex.x, ptVertex.y, ptVertex.z + 1) : Point3d( ptVertex.x + 1, ptVertex.y, ptVertex.z)) ; + Point3d ptP = ( abs( vtV1.z) < EPS_SMALL ? Point3d( ptVertex.x, ptVertex.y, ptVertex.z + 1) : + Point3d( ptVertex.x + 1, ptVertex.y, ptVertex.z)) ; Vector3d vtV = ( abs( vtV1.z) < EPS_SMALL ? vtToolDir : Z_AX) ; @@ -3264,6 +4696,9 @@ VolZmap::CompConus_Drilling( unsigned int nGrid, const Point3d & ptS, const Poin // Lunghezzza cilindro totale altezza + moto double dLen = ( ptE - ptS).Len() ; + double dMin, dMax ; + Vector3d vtNmin, vtNmax ; + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { @@ -3274,23 +4709,51 @@ VolZmap::CompConus_Drilling( unsigned int nGrid, const Point3d & ptS, const Poin Point3d ptC( dX, dY, 0) ; Point3d ptInt1, ptInt2 ; + Vector3d vtN1, vtN2 ; // Cilindro - if ( IntersLineCylinder( ptC - vtV1 * dL, Z_AX, ConusFrame, dLen, dMaxRad, ptInt1, ptInt2)) { + if ( IntersLineCylinder( ptC - vtV1 * dL, Z_AX, ConusFrame, dLen, dMaxRad, + ptInt1, ptInt2, vtN1, vtN2, true, bTapCylEn)) { - dMin = min( ptInt1.z + vtV1.z * dL, ptInt2.z + vtV1.z * dL) ; - dMax = max( ptInt1.z + vtV1.z * dL, ptInt2.z + vtV1.z * dL) ; + + if ( ptInt1.z < ptInt2.z) { - SubtractIntervals( nGrid, i, j, dMin, dMax, V_NULL, V_NULL) ; + dMin = ptInt1.z + vtV1.z * dL ; + dMax = ptInt2.z + vtV1.z * dL ; + vtNmin = vtN1 ; + vtNmax = vtN2 ; + } + else { + + dMin = ptInt2.z + vtV1.z * dL ; + dMax = ptInt1.z + vtV1.z * dL ; + vtNmin = vtN2 ; + vtNmax = vtN1 ; + } + + SubtractIntervals( nGrid, i, j, dMin, dMax, vtNmin, vtNmax) ; } // Cono - if ( IntersLineConus( ptC , Z_AX, ConusFrame, dTan, dl, dL, ptInt1, ptInt2)) { + if ( IntersLineConus( ptC , Z_AX, ConusFrame, dTan, dl, dL, + ptInt1, ptInt2, vtN1, vtN2, bTapT, true)) { - dMin = min( ptInt1.z, ptInt2.z) ; - dMax = max( ptInt1.z, ptInt2.z) ; + + if ( ptInt1.z < ptInt2.z) { - SubtractIntervals( nGrid, i, j, dMin, dMax, V_NULL, V_NULL) ; + dMin = ptInt1.z + vtV1.z * dL ; + dMax = ptInt2.z + vtV1.z * dL ; + vtNmin = vtN1 ; + vtNmax = vtN2 ; + } + else { + + dMin = ptInt2.z + vtV1.z * dL ; + dMax = ptInt1.z + vtV1.z * dL ; + vtNmin = vtN2 ; + vtNmax = vtN1 ; + } + SubtractIntervals( nGrid, i, j, dMin, dMax, vtNmin, vtNmax) ; } } } @@ -3302,7 +4765,7 @@ VolZmap::CompConus_Drilling( unsigned int nGrid, const Point3d & ptS, const Poin //---------------------------------------------------------------------------- bool VolZmap::CompCyl_Milling( unsigned int nGrid, const Point3d& ptS, const Point3d& ptE, - const Vector3d& vtToolDir, double dHei, double dRad) + const Vector3d& vtToolDir, double dHei, double dRad, bool bTapB, bool bTapT) { unsigned int nStartI, nStartJ, nEndI, nEndJ ; @@ -3339,77 +4802,155 @@ VolZmap::CompCyl_Milling( unsigned int nGrid, const Point3d& ptS, const Point3d& double dSqRad = dRad * dRad ; double dLongLen = vtMoveLong.Len() ; double dOrtLen = vtMoveOrt.Len() ; + + // Variabili booleane per i tappi + Vector3d vtUmv = vtMove ; vtUmv.Normalize() ; + bool bCylSt = ( abs( vtToolDir * vtUmv) > EPS_SMALL ? true : bTapT) ; + bool bCylEn = ( abs( vtToolDir * vtUmv) > EPS_SMALL ? true : bTapB) ; + bool bElpsB = ( abs( vtToolDir * vtUmv) > EPS_SMALL ? true : bTapB) ; + bool bElpsT = ( abs( vtToolDir * vtUmv) > EPS_SMALL ? true : bTapT) ; // Minima e massima quota z double dMin, dMax ; + Vector3d vtNmin, vtNmax ; for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + if ( i == 4 && j == 2) + int bau = 0 ; + Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ; Point3d ptInt1, ptInt2 ; + Vector3d vtN1, vtN2 ; // Cilindro iniziale - if ( IntersLineCylinder( ptC, Z_AX, CylFrame, dHei, dRad, ptInt1, ptInt2)) { + if ( IntersLineCylinder( ptC, Z_AX, CylFrame, dHei, dRad, ptInt1, ptInt2, vtN1, vtN2, bCylSt, bCylEn)) { - dMin = min( ptInt1.z, ptInt2.z) ; - dMax = max( ptInt1.z, ptInt2.z) ; + if ( ptInt1.z < ptInt2.z) { + + dMin = ptInt1.z ; + dMax = ptInt2.z ; + vtNmin = vtN1 ; + vtNmax = vtN2 ; + } + else { - SubtractIntervals( nGrid, i, j, dMin, dMax, V_NULL, V_NULL) ; + dMin = ptInt2.z ; + dMax = ptInt1.z ; + vtNmin = vtN2 ; + vtNmax = vtN1 ; + } + + SubtractIntervals( nGrid, i, j, dMin, dMax, vtNmin, vtNmax) ; } - // Cilindro finale - if ( IntersLineCylinder( ptC - vtMove, Z_AX, CylFrame, dHei, dRad, ptInt1, ptInt2)) { + // Cilindro finale:L'unica differenza rispetto a prima è l'origine + // del sistema di riferimento, quindi usiamo lo stesso sistema sommando a ptC + // il vettore che congiunge le due origini. + if ( IntersLineCylinder( ptC - vtMove, Z_AX, CylFrame, dHei, dRad, ptInt1, ptInt2, vtN1, vtN2, bCylSt, bCylEn)) { - dMin = min( ptInt1.z + vtMove.z, ptInt2.z + vtMove.z) ; - dMax = max( ptInt1.z + vtMove.z, ptInt2.z + vtMove.z) ; + + if ( ptInt1.z < ptInt2.z) { + + dMin = ptInt1.z + vtMove.z ; + dMax = ptInt2.z + vtMove.z ; + vtNmin = vtN1 ; + vtNmax = vtN2 ; + } + else { - SubtractIntervals( nGrid, i, j, dMin, dMax, V_NULL, V_NULL) ; + dMin = ptInt2.z + vtMove.z ; + dMax = ptInt1.z + vtMove.z ; + vtNmin = vtN2 ; + vtNmax = vtN1 ; + } + + SubtractIntervals( nGrid, i, j, dMin, dMax, vtNmin, vtNmax) ; } // Poliedro interno - if ( IntersLineMyPolyhedron( ptC, Z_AX, CylFrame, dHei, dOrtLen, 2 * dRad, dLongLen, ptInt1, ptInt2)) { + if ( IntersLineMyPolyhedron( ptC, Z_AX, CylFrame, dHei, dOrtLen, 2 * dRad, dLongLen, ptInt1, ptInt2, vtN1, vtN2)) { - dMin = min( ptInt1.z, ptInt2.z) ; - dMax = max( ptInt1.z, ptInt2.z) ; + + if ( ptInt1.z < ptInt2.z) { + + dMin = ptInt1.z ; + dMax = ptInt2.z ; + vtNmin = vtN1 ; + vtNmax = vtN2 ; + } + else { - SubtractIntervals( nGrid, i, j, dMin, dMax, V_NULL, V_NULL) ; + dMin = ptInt2.z ; + dMax = ptInt1.z ; + vtNmin = vtN2 ; + vtNmax = vtN1 ; + } + + SubtractIntervals( nGrid, i, j, dMin, dMax, vtNmin, vtNmax) ; } // Cilindro ellittico di punta if ( IntersLineEllipticalCylinder( Z_AX, ptC, CylFrame, dSqRad, - dLongLen, dOrtLen, ptInt1, ptInt2)) { + dLongLen, dOrtLen, ptInt1, ptInt2, vtN1, vtN2, bElpsT, bElpsT)) { - dMin = min( ptInt1.z, ptInt2.z) ; - dMax = max( ptInt1.z, ptInt2.z) ; + + if ( ptInt1.z < ptInt2.z) { + + dMin = ptInt1.z ; + dMax = ptInt2.z ; + vtNmin = vtN1 ; + vtNmax = vtN2 ; + } + else { - SubtractIntervals( nGrid, i, j, dMin, dMax, V_NULL, V_NULL) ; + dMin = ptInt2.z ; + dMax = ptInt1.z ; + vtNmin = vtN2 ; + vtNmax = vtN1 ; + } + + SubtractIntervals( nGrid, i, j, dMin, dMax, vtNmin, vtNmax) ; } // Cilindro ellittico di base: L'unica differenza rispetto a prima è l'origine // del sistema di riferimento, quindi usiamo lo stesso sistema sommando a ptC // il vettore che congiunge le due origini. if ( IntersLineEllipticalCylinder( Z_AX, ptC - dHei * vtV1, CylFrame, dSqRad, - dLongLen, dOrtLen, ptInt1, ptInt2)) { + dLongLen, dOrtLen, ptInt1, ptInt2, vtN1, vtN2, bElpsB, bElpsB)) { - dMin = min( ptInt1.z + dHei * vtV1.z, ptInt2.z + dHei * vtV1.z) ; - dMax = max( ptInt1.z + dHei * vtV1.z, ptInt2.z + dHei * vtV1.z) ; + + if ( ptInt1.z < ptInt2.z) { + + dMin = ptInt1.z + dHei * vtV1.z ; + dMax = ptInt2.z + dHei * vtV1.z ; + vtNmin = vtN1 ; + vtNmax = vtN2 ; + } + else { - SubtractIntervals( nGrid, i, j, dMin, dMax, V_NULL, V_NULL) ; + dMin = ptInt2.z + dHei * vtV1.z ; + dMax = ptInt1.z + dHei * vtV1.z ; + vtNmin = vtN2 ; + vtNmax = vtN1 ; + } + + SubtractIntervals( nGrid, i, j, dMin, dMax, vtNmin, vtNmax) ; } } } return true ; } - + //---------------------------------------------------------------------------- bool VolZmap::CompConus_Milling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir, - double dHei, double dMaxRad, double dMinRad) + double dHei, double dMaxRad, double dMinRad, bool bTapB, bool bTapT) { unsigned int nStartI, nStartJ, nEndI, nEndJ ; @@ -3489,13 +5030,27 @@ VolZmap::CompConus_Milling( unsigned int nGrid, const Point3d & ptS, const Point // Up e Down Vector3d vtUD( - dLenY, dLenX, 0) ; + vtNs.Normalize() ; + vtNd.Normalize() ; + vtIF.Normalize() ; + vtUD.Normalize() ; + // Punti dei piani (sempre espressi nel sistema PolyFrame) Point3d ptFacet135( 0, 0, dLenZ) ; Point3d ptFacet246( dLenX + dDeltaX, dLenY + dDeltaY, - dLenZ - dDeltaZ) ; double dSqIndet = EPS_SMALL * EPS_SMALL ; + // Variabili booleane per i tappi + Vector3d vtUmv = vtMove ; vtUmv.Normalize() ; + + bool bConeT = ( abs( vtToolDir * vtUmv) > EPS_SMALL ? true : bTapT) ; + bool bConeB = ( abs( vtToolDir * vtUmv) > EPS_SMALL ? true : bTapB) ; + bool bElpsB = ( abs( vtToolDir * vtUmv) > EPS_SMALL ? true : bTapB) ; + bool bElpsT = ( abs( vtToolDir * vtUmv) > EPS_SMALL ? true : bTapT) ; + double dMin, dMax ; + Vector3d vtNmin, vtNmax ; if ( dRatio * dTan <= 1) { @@ -3508,23 +5063,54 @@ VolZmap::CompConus_Milling( unsigned int nGrid, const Point3d & ptS, const Point Point3d ptC( dX, dY, 0) ; Point3d ptInt1, ptInt2 ; + Vector3d vtN1, vtN2 ; // Cono iniziale - if ( IntersLineConus( ptC, Z_AX, ConusFrame, dTan, dl, dL, ptInt1, ptInt2)) { + if ( IntersLineConus( ptC, Z_AX, ConusFrame, dTan, dl, dL, ptInt1, ptInt2, vtN1, vtN2, bConeT, bConeB)) { - dMin = min( ptInt1.z, ptInt2.z) ; - dMax = max( ptInt1.z, ptInt2.z) ; + + if ( ptInt1.z < ptInt2.z) { + + dMin = ptInt1.z ; + dMax = ptInt2.z ; - SubtractIntervals( nGrid, i, j, dMin, dMax, V_NULL, V_NULL) ; + vtNmin = vtN1 ; + vtNmax = vtN2 ; + } + else { + + dMin = ptInt2.z ; + dMax = ptInt1.z ; + + vtNmin = vtN2 ; + vtNmax = vtN1 ; + } + + SubtractIntervals( nGrid, i, j, dMin, dMax, vtNmin, vtNmax) ; } // Cono finale - if ( IntersLineConus( ptC - vtMove, Z_AX, ConusFrame, dTan, dl, dL, ptInt1, ptInt2)) { + if ( IntersLineConus( ptC - vtMove, Z_AX, ConusFrame, dTan, dl, dL, ptInt1, ptInt2, vtN1, vtN2, bConeT, bConeB)) { - dMin = min( ptInt1.z + vtMove.z, ptInt2.z + vtMove.z) ; - dMax = max( ptInt1.z + vtMove.z, ptInt2.z + vtMove.z) ; + + if ( ptInt1.z < ptInt2.z) { + + dMin = ptInt1.z + vtMove.z ; + dMax = ptInt2.z + vtMove.z ; - SubtractIntervals( nGrid, i, j, dMin, dMax, V_NULL, V_NULL) ; + vtNmin = vtN1 ; + vtNmax = vtN2 ; + } + else { + + dMin = ptInt2.z + vtMove.z ; + dMax = ptInt1.z + vtMove.z ; + + vtNmin = vtN2 ; + vtNmax = vtN1 ; + } + + SubtractIntervals( nGrid, i, j, dMin, dMax, vtNmin, vtNmax) ; } // Solido interno @@ -3550,6 +5136,7 @@ VolZmap::CompConus_Milling( unsigned int nGrid, const Point3d & ptS, const Point dDeltaX * ( ptPoly1.y - dLenY) <= dDeltaY * ( ptPoly1.x - dLenX)) { ptInt1 = ptPoly1 ; + vtN1 = - vtNs ; ++ nIntNum ; } // Intersezione con la seconda faccia @@ -3561,11 +5148,13 @@ VolZmap::CompConus_Milling( unsigned int nGrid, const Point3d & ptS, const Point if ( nIntNum == 0) { ptInt1 = ptPoly2 ; + vtN1 = - vtNd ; ++ nIntNum ; } else if ( ( ptInt1 - ptPoly2).SqLen() > dSqIndet) { ptInt2 = ptPoly2 ; + vtN2 = - vtNd ; ++ nIntNum ; } } @@ -3577,11 +5166,13 @@ VolZmap::CompConus_Milling( unsigned int nGrid, const Point3d & ptS, const Point if ( nIntNum == 0) { ptInt1 = ptPoly3 ; + vtN1 = - vtIF ; ++ nIntNum ; } else if ( ( ptInt1 - ptPoly3).SqLen() > dSqIndet) { ptInt2 = ptPoly3 ; + vtN2 = - vtIF ; ++ nIntNum ; } } @@ -3594,11 +5185,13 @@ VolZmap::CompConus_Milling( unsigned int nGrid, const Point3d & ptS, const Point if ( nIntNum == 0) { ptInt1 = ptPoly4 ; + vtN1 = vtIF ; ++ nIntNum ; } else if ( ( ptInt1 - ptPoly4).SqLen() > dSqIndet) { ptInt2 = ptPoly4 ; + vtN2 = vtIF ; ++ nIntNum ; } } @@ -3611,11 +5204,13 @@ VolZmap::CompConus_Milling( unsigned int nGrid, const Point3d & ptS, const Point if ( nIntNum == 0) { ptInt1 = ptPoly5 ; + vtN1 = - vtUD ; ++ nIntNum ; } else if ( ( ptInt1 - ptPoly5).SqLen() > dSqIndet) { ptInt2 = ptPoly5 ; + vtN2 = - vtUD ; ++ nIntNum ; } } @@ -3628,11 +5223,13 @@ VolZmap::CompConus_Milling( unsigned int nGrid, const Point3d & ptS, const Point if ( nIntNum == 0) { ptInt1 = ptPoly6; + vtN1 = vtUD ; ++ nIntNum ; } else if ( ( ptInt1 - ptPoly6).SqLen() > dSqIndet) { ptInt2 = ptPoly6; + vtN2 = vtUD ; ++ nIntNum ; } } @@ -3643,30 +5240,75 @@ VolZmap::CompConus_Milling( unsigned int nGrid, const Point3d & ptS, const Point ptInt1.ToGlob( PolyFrame) ; ptInt2.ToGlob( PolyFrame) ; - dMin = min( ptInt1.z, ptInt2.z) ; - dMax = max( ptInt1.z, ptInt2.z) ; + vtN1.ToGlob( PolyFrame) ; + vtN2.ToGlob( PolyFrame) ; - SubtractIntervals( nGrid, i, j, dMin, dMax, V_NULL, V_NULL) ; + //dMin = min( ptInt1.z, ptInt2.z) ; + //dMax = max( ptInt1.z, ptInt2.z) ; + + if ( ptInt1.z < ptInt2.z) { + + dMin = ptInt1.z ; + dMax = ptInt2.z ; + + vtNmin = vtN1 ; + vtNmax = vtN2 ; + } + else { + + dMin = ptInt2.z ; + dMax = ptInt1.z ; + + vtNmin = vtN2 ; + vtNmax = vtN1 ; + } + + SubtractIntervals( nGrid, i, j, dMin, dMax, vtNmin, vtNmax) ; } // Traslazione ellisse di punta if ( IntersLineEllipticalCylinder( Z_AX, ptC - vtV1 * dl, ConusFrame, dSqMinRad, - dLongLen, dOrtLen, ptInt1, ptInt2)) { + dLongLen, dOrtLen, ptInt1, ptInt2, vtN1, vtN2, bElpsT, bElpsT)) { - dMin = min( ptInt1.z + vtV1.z * dl, ptInt2.z + vtV1.z * dl) ; - dMax = max( ptInt1.z + vtV1.z * dl, ptInt2.z + vtV1.z * dl) ; - - SubtractIntervals( nGrid, i, j, dMin, dMax, V_NULL, V_NULL) ; + + if( ptInt1.z < ptInt2.z) { + + dMin = ptInt1.z + vtV1.z * dl ; + dMax = ptInt2.z + vtV1.z * dl ; + vtNmin = vtN1 ; + vtNmax = vtN2 ; + } + else { + + dMin = ptInt2.z + vtV1.z * dl ; + dMax = ptInt1.z + vtV1.z * dl ; + vtNmin = vtN2 ; + vtNmax = vtN1 ; + } + + SubtractIntervals( nGrid, i, j, dMin, dMax, vtNmin, vtNmax) ; } // Traslazione ellisse di base if ( IntersLineEllipticalCylinder( Z_AX, ptC - vtV1 * dL, ConusFrame, dSqMaxRad, - dLongLen, dOrtLen, ptInt1, ptInt2)) { + dLongLen, dOrtLen, ptInt1, ptInt2, vtN1, vtN2, bElpsB, bElpsB)) { - dMin = min( ptInt1.z + vtV1.z * dL, ptInt2.z + vtV1.z * dL) ; - dMax = max( ptInt1.z + vtV1.z * dL, ptInt2.z + vtV1.z * dL) ; + if( ptInt1.z < ptInt2.z) { + + dMin = ptInt1.z + vtV1.z * dL ; + dMax = ptInt2.z + vtV1.z * dL ; + vtNmin = vtN1 ; + vtNmax = vtN2 ; + } + else { - SubtractIntervals( nGrid, i, j, dMin, dMax, V_NULL, V_NULL) ; + dMin = ptInt2.z + vtV1.z * dL ; + dMax = ptInt1.z + vtV1.z * dL ; + vtNmin = vtN2 ; + vtNmax = vtN1 ; + } + + SubtractIntervals( nGrid, i, j, dMin, dMax, vtNmin, vtNmax) ; } } } @@ -3683,37 +5325,66 @@ VolZmap::CompConus_Milling( unsigned int nGrid, const Point3d & ptS, const Point Point3d ptC( dX, dY, 0) ; Point3d ptInt1, ptInt2 ; + Vector3d vtN1, vtN2 ; // Cono - if ( IntersLineConus( ptC, Z_AX, ConusFrame, dTan, dl, dL, ptInt1, ptInt2)) { + if ( IntersLineConus( ptC, Z_AX, ConusFrame, dTan, dl, dL, ptInt1, ptInt2, vtN1, vtN2, bConeT, bConeB)) { - dMin = min( ptInt1.z, ptInt2.z) ; - dMax = max( ptInt1.z, ptInt2.z) ; + + if ( ptInt1.z < ptInt2.z) { + + dMin = ptInt1.z ; + dMax = ptInt2.z ; - SubtractIntervals( nGrid, i, j, dMin, dMax, V_NULL, V_NULL) ; + vtNmin = vtN1 ; + vtNmax = vtN2 ; + } + else { + + dMin = ptInt2.z ; + dMax = ptInt1.z ; + + vtNmin = vtN2 ; + vtNmax = vtN1 ; + } + + SubtractIntervals( nGrid, i, j, dMin, dMax, vtNmin, vtNmax) ; } // Traslazione ellisse if ( IntersLineEllipticalCylinder( Z_AX, ptC - vtV1 * dL, ConusFrame, dSqMaxRad, - dLongLen, dOrtLen, ptInt1, ptInt2)) { + dLongLen, dOrtLen, ptInt1, ptInt2, vtN1, vtN2, bConeB, bConeB)) { - dMin = min( ptInt1.z + vtV1.z * dL, ptInt2.z + vtV1.z * dL) ; - dMax = max( ptInt1.z + vtV1.z * dL, ptInt2.z + vtV1.z * dL) ; + + if( ptInt1.z < ptInt2.z) { + + dMin = ptInt1.z + vtV1.z * dL ; + dMax = ptInt2.z + vtV1.z * dL ; + vtNmin = vtN1 ; + vtNmax = vtN2 ; + } + else { - SubtractIntervals( nGrid, i, j, dMin, dMax, V_NULL, V_NULL) ; + dMin = ptInt2.z + vtV1.z * dL ; + dMax = ptInt1.z + vtV1.z * dL ; + vtNmin = vtN2 ; + vtNmax = vtN1 ; + } + + SubtractIntervals( nGrid, i, j, dMin, dMax, vtNmin, vtNmax) ; } } } return true ; } -} +} // ---------- SFERA ---------------------------------------------------------- + //---------------------------------------------------------------------------- bool VolZmap::CompBall_Milling( unsigned int nGrid, const Point3d & ptLs, const Point3d & ptLe, double dRad) { - double dMin, dMax ; unsigned int nStartI, nStartJ, nEndI, nEndJ ; bool Control = BBoxComponent( nGrid, ptLs, ptLe, V_NULL, V_NULL, nStartI, nStartJ, nEndI, nEndJ, dRad, 0, 0) ; @@ -3721,105 +5392,113 @@ VolZmap::CompBall_Milling( unsigned int nGrid, const Point3d & ptLs, const Point if ( ! Control) return true ; - Point3d ptI = ( ptLs.z < ptLe.z ? ptLs : ptLe) ; - Point3d ptF = ( ptLs.z < ptLe.z ? ptLe : ptLs) ; + Vector3d vtV = ptLe - ptLs ; + + double dLengthPath = vtV.Len() ; + + vtV.Normalize() ; + + Vector3d vtW ; + + // Costruisco sistema di riferimento + if ( vtV.x * vtV.x > 0.3) + + vtW.Set( - ( vtV.y + vtV.z) / vtV.x, 1, 1) ; - Point3d ptIxy( ptI.x, ptI.y, 0) ; - Point3d ptFxy( ptF.x, ptF.y, 0) ; + else if ( vtV.y * vtV.y > 0.3) + + vtW.Set( 1, - ( vtV.x + vtV.z) / vtV.y, 1) ; + + else - Vector3d vtMove = ptF - ptI ; - Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ; + vtW.Set( 1, 1, - ( vtV.x + vtV.y) / vtV.z) ; - double dVLen = abs( vtMove.z) ; // Verticale e planare rispetto ai dexel - double dPLen = vtMoveXY.LenXY() ; - double dLen = vtMove.Len() ; + Point3d ptOnY = ptLs + vtW ; + + + Frame3d CylFrame ; CylFrame.Set( ptLs, ptLe, ptOnY) ; - double dR1 = dVLen / dLen ; - double dR2 = dPLen / dLen ; - - double dZI = ptI.z ; - double dDeltaZ = ptF.z - ptI.z ; double dSqRad = dRad * dRad ; + double dMin, dMax ; + Vector3d vtNmin, vtNmax ; - if ( dPLen < EPS_SMALL) { + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; + double dY = ( j + 0.5) * m_dStep ; - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { + Point3d ptC( dX, dY, 0) ; - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + double dStSqDXY = SqDistXY( ptC, ptLs) ; + double dEnSqDXY = SqDistXY( ptC, ptLe) ; - double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; + // Prima sfera + if ( dStSqDXY < dSqRad) { - Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptIxy ; + dMin = ptLs.z - sqrt( dSqRad - dStSqDXY) ; + dMax = ptLs.z + sqrt( dSqRad - dStSqDXY) ; - double dSqLen = vtC.SqLen() ; + Point3d ptIntMin( dX, dY, dMin) ; + Point3d ptIntMax( dX, dY, dMax) ; - if ( dSqLen < dSqRad) { + vtNmin = ptLs - ptIntMin ; + vtNmax = ptLs - ptIntMax ; + + vtNmin.Normalize() ; + vtNmax.Normalize() ; + + SubtractIntervals( nGrid, i, j, dMin, dMax, vtNmin, vtNmax) ; + } + + // Seconda sfera + if ( dEnSqDXY < dSqRad) { + + dMin = ptLe.z - sqrt( dSqRad - dEnSqDXY) ; + dMax = ptLe.z + sqrt( dSqRad - dEnSqDXY) ; + + Point3d ptIntMin( dX, dY, dMin) ; + Point3d ptIntMax( dX, dY, dMax) ; + + vtNmin = ptLe - ptIntMin ; + vtNmax = ptLe - ptIntMax ; + + vtNmin.Normalize() ; + vtNmax.Normalize() ; + + SubtractIntervals( nGrid, i, j, dMin, dMax, vtNmin, vtNmax) ; + } + + Point3d ptInt1, ptInt2 ; + Vector3d vtN1, vtN2 ; + + // Cilindro + if ( IntersLineCylinder( ptC, Z_AX, CylFrame, dLengthPath, dRad, ptInt1, ptInt2, vtN1, vtN2, false, false)) { + + if ( ptInt1.z < ptInt2.z) { - double dH = sqrt( dSqRad - dSqLen) ; - - dMin = dZI - dH ; - dMax = dZI + dDeltaZ + dH ; - - SubtractIntervals( nGrid, i, j, dMin, dMax, V_NULL, V_NULL) ; + dMin = ptInt1.z ; + dMax = ptInt2.z ; + vtNmin = vtN1 ; + vtNmax = vtN2 ; } + else { + + dMin = ptInt2.z ; + dMax = ptInt1.z ; + vtNmin = vtN2 ; + vtNmax = vtN1 ; + } + + SubtractIntervals( nGrid, i, j, dMin, dMax, vtNmin, vtNmax) ; } } } - else { - - Vector3d vtV1 = vtMoveXY ; vtV1.Normalize() ; - Vector3d vtV2 = vtV1 ; vtV2.Rotate( Z_AX, 90) ; - - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { - - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; - - Point3d ptC( dX, dY, 0) ; Vector3d vtCI = ptC - ptIxy ; Vector3d vtCF = ptC - ptFxy ; - - double dX1 = vtCI * vtV1 ; double dX2 = vtCI * vtV2 ; - - double dISqDist = vtCI * vtCI ; double dFSqDist = vtCF * vtCF ; - - if ( dISqDist < dSqRad || dFSqDist < dSqRad || - ( dX1 > 0 && dX1 < dPLen && dX2 * dX2 < dSqRad)) { - - // Massimi - if ( dX1 < - dR1 * sqrt( dSqRad - ( dX2 * dX2))) - - dMax = dZI + sqrt( dSqRad - dISqDist) ; - - else if ( dX1 < dPLen - dR1 * sqrt( dSqRad - ( dX2 * dX2))) - - dMax = dZI + dR2 * sqrt( dSqRad - dX2 * dX2) + ( dX1 + dR1 * sqrt( dSqRad - ( dX2 * dX2))) * dVLen / dPLen ; - - else - - dMax = dZI + dDeltaZ + sqrt( dSqRad - dFSqDist) ; - - // Minimi - if ( dX1 < dR1 * sqrt( dSqRad - ( dX2 * dX2))) - - dMin = dZI - sqrt( dSqRad - dISqDist) ; - - else if ( dX1 < dPLen + dR1 * sqrt( dSqRad - ( dX2 * dX2))) - - dMin = dZI - dR2 * sqrt( dSqRad - dX2 * dX2) + ( dX1 - dR1 * sqrt( dSqRad - ( dX2 * dX2))) * dVLen / dPLen ; - - else - - dMin = dZI + dDeltaZ - sqrt( dSqRad - dFSqDist) ; - - SubtractIntervals( nGrid, i, j, dMin, dMax, V_NULL, V_NULL) ; - } - } - } - } - return true ; -} +} + + // ------------------------- BOUNDING BOX -------------------------------------------------------------------------------------- diff --git a/VolZmap.cpp b/VolZmap.cpp index 3681e1c..5feb9c8 100644 --- a/VolZmap.cpp +++ b/VolZmap.cpp @@ -142,7 +142,7 @@ VolZmap::GetType( void) const const string& VolZmap::GetTitle( void) const { - static const string sTitle = "VolZm" ; + static const string sTitle = "Zmap" ; return sTitle ; } diff --git a/VolZmap.h b/VolZmap.h index 961ddd2..6a48f53 100644 --- a/VolZmap.h +++ b/VolZmap.h @@ -26,8 +26,8 @@ //---------------------------------------------------------------------------- struct TriaStruct { int i, j, k ; - Point3d ptVert ; - TRIA3DVECTOR vecTria ; + std::vector ptCompoVert ; + std::vector vCompoTria ; } ; typedef std::vector TriHolder ; @@ -117,14 +117,15 @@ class VolZmap : public IVolZmap, public IGeoObjRW const Vector3d& vtZ, const Vector3d& vtNorm, TRIA3DLIST& lstTria) const ; bool MarchingCubes( TRIA3DLIST& lstTria) const ; bool MarchingCubes( int nBlock, TRIA3DLIST& lstTria) const ; - bool ExtMarchingCubes( int nBlock, TRIA3DLIST& lstTria, TriHolder& triHold) const ; + bool ExtMarchingCubes( const int nLimits[], TRIA3DLIST& lstTria, TriHolder& triHold) const ; + bool ExtMarchingCubes( const std::vector VoxelsIndexes, TriHolder& triHold) const ; bool FlipEdges( TriHolder& triHold) const ; - bool FlipEdges( int nBlock, TriHolder& triHold) ; - bool FlipEdges( int nNumBlocks, int nBlocks[], TriHolder triHold []) ; + bool FlipEdgesLocalFlipEdges( TriaStruct& triStrCurr, TriaStruct& triStrAdj) const ; bool IsThereMat( int nI, int nJ, int nK) const ; bool IsThereMat( const int nMatr[][3], int nNum, double & dHx, double & dHy, double & dHz) const ; bool IntersPos( int nVec1[], int nVec2[], Point3d & ptInt) const ; bool IntersPos( int nVec1[], int nVec2[], Point3d & ptInt, Vector3d & vtNormal) const ; + bool NewIntersPos( int nVec1[], int nVec2[], bool bFirstCorner, Point3d& ptInt, Vector3d& vtNormal) const ; // OPERAZIONI SU INTERVALLI bool SubtractIntervals( unsigned int nGrid, unsigned int nI, unsigned int nJ, @@ -176,22 +177,30 @@ class VolZmap : public IVolZmap, public IGeoObjRW // Asse di simmetria diretto come l'asse Z // Drilling - bool CompCyl_ZDrilling( unsigned int nGrid, const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dRad) ; - bool CompConus_ZDrilling( unsigned int nGrid, const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dMaxRad, double dMinRad) ; + bool CompCyl_ZDrilling( unsigned int nGrid, const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, + double dHei, double dRad) ; + bool CompConus_ZDrilling( unsigned int nGrid, const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, + double dHei, double dMaxRad, double dMinRad) ; // Milling - bool CompCyl_ZMilling( unsigned int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, double dHei, double dRad) ; - bool CompConus_ZMilling( unsigned int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, double dHei, double dMaxRad, double dMinRad) ; + bool CompCyl_ZMilling( unsigned int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, + double dHei, double dRad) ; + bool CompConus_ZMilling( unsigned int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, + double dHei, double dMaxRad, double dMinRad) ; // Asse di simmetria con orientazione generica // Drilling - bool CompCyl_Drilling( unsigned int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, double dHei, double dRad) ; - bool CompConus_Drilling( unsigned int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, double dHei, double dMaxRad, double dMinRad) ; + bool CompCyl_Drilling( unsigned int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, + double dHei, double dRad, bool bTapB, bool bTapT) ; + bool CompConus_Drilling( unsigned int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, + double dHei, double dMaxRad, double dMinRad, bool bTapB, bool bTapT) ; // Milling - bool CompCyl_Milling( unsigned int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, double dHei, double dRad) ; - bool CompConus_Milling( unsigned int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, double dHei, double dMaxRad, double dMinRad) ; + bool CompCyl_Milling( unsigned int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, + double dHei, double dRad, bool bTapB, bool bTapT) ; + bool CompConus_Milling( unsigned int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, + double dHei, double dMaxRad, double dMinRad, bool bTapB, bool bTapT) ; // Generica traslazione sfera bool CompBall_Milling( unsigned int nGrid, const Point3d& ptS, const Point3d& ptE, double dRad) ; @@ -205,7 +214,7 @@ class VolZmap : public IVolZmap, public IGeoObjRW // Intersezioni bool IntersLineBox( const Point3d& ptP, const Vector3d& vtV, - const Point3d& ptMin, const Point3d& ptMax, double& dU1, double& dU2) ; + const Point3d& ptMin, const Point3d& ptMax, double& dU1, double& dU2) const ; bool IntersLineZMapBBox( unsigned int nGrid, const Point3d& ptP, const Vector3d& vtV, double& dU1, double& dU2) ; bool IntersLineDexel( unsigned int nGrid, const Point3d& ptP, const Vector3d& vtV, unsigned int nI, unsigned int nJ, double& dU1, double& dU2) ; @@ -214,27 +223,34 @@ class VolZmap : public IVolZmap, public IGeoObjRW double& dU1, double& dU2) ; bool IntersLineCylinder( const Point3d& ptLineSt, const Vector3d& vtLineDir, const Frame3d& CylFrame, double dL, double dR, - Point3d& ptInt1, Point3d& ptInt2) ; + Point3d& ptInt1, Point3d& ptInt2, Vector3d& vtN1, Vector3d& vtN2, + bool bTapO, bool bTapL) ; bool IntersZLineCylinder( const Point3d& ptLine, const Point3d& ptBase, const Point3d& ptTop, double dCylR, double& dInfZ, double& dSupZ) ; bool IntersLineEllipticalCylinder( const Vector3d& vtLineDir, const Point3d& ptLineSt, const Frame3d& CircFrame, double dSqRad, double dLongMvLen, double dOrtMvLen, - Point3d& ptInt1, Point3d& ptInt2) ; + Point3d& ptInt1, Point3d& ptInt2, Vector3d& vtN1, Vector3d& vtN2, + bool bTapLow, bool bTapUp) ; bool IntersLineConus( const Point3d& ptLineSt, const Vector3d& vtLineDir, const Frame3d& ConusFrame, double dTan, double dl, double dL, - Point3d& ptInt1, Point3d& ptInt2) ; + Point3d& ptInt1, Point3d& ptInt2, Vector3d& vtN1, Vector3d& vtN2, + bool bTapLow, bool bTapUp) ; bool IntersLineSphere( const Point3d& ptLineSt, const Vector3d& vtLineDir, const Point3d& ptCenter, double dRad, Point3d& ptInt1, Point3d& ptInt2) ; bool IntersLineMyPolyhedron( const Point3d& ptLineSt, const Vector3d& vtLineDir, const Frame3d& PolyFrame, double dLenX, double dLenY, double dLenZ, double dDeltaX, - Point3d& ptInt1, Point3d& ptInt2) ; + Point3d& ptInt1, Point3d& ptInt2, Vector3d& vtN1, Vector3d& vtN2) ; + + // Funzioni di gestione dei blocchi + bool GetBlockIJK( int nIJK[], int nBlock) const ; + bool GetBlockLimitsIJK( const int nIJK[], int nLimits[]) const ; private : enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ; static const int N_MAPS = 3 ; - static const int N_DEXBLOCK = 32 ; + static const int N_DEXBLOCK = 32;//20;//32 ; private : ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto diff --git a/VolZmapTool.cpp b/VolZmapTool.cpp index ca8bed2..c5b0e48 100644 --- a/VolZmapTool.cpp +++ b/VolZmapTool.cpp @@ -17,6 +17,8 @@ #include "CurveArc.h" #include "VolZmap.h" #include "GeoConst.h" +#include "\EgtDev\Include\EGKLinePntTgCurve.h" +#include "\EgtDev\Include\EGKFilletChamfer.h" using namespace std ; @@ -100,24 +102,108 @@ VolZmap::SetAdvTool( const string& sToolName, double dH, double dR, if ( dH < EPS_SMALL || dR < EPS_SMALL) return false ; // se altezza punta nulla, ricado nel caso standard - if ( dTipH < EPS_SMALL) + if ( dTipH < EPS_SMALL || abs( dTipR - dR) < EPS_SMALL) return SetStdTool( sToolName, dH, dR, dCornR) ; - // caso avanzato - if ( abs( dTipR - dR) < EPS_SMALL) { - m_nToolType = CylindricalMill ; - m_dHeight = dH ; - m_dRadius = dR ; - m_dTipHeight = 0 ; - m_dTipRadius = m_dRadius ; - m_dRCorner = 0 ; - } + // caso avanzato else { - m_nToolType = ConusMill ; + m_dHeight = dH ; m_dRadius = dR ; m_dTipHeight = dTipH ; m_dTipRadius = max( dTipR, 0.) ; - m_dRCorner = dCornR ; + + if ( dCornR < EPS_SMALL) { + + m_nToolType = ConusMill ; + m_dRCorner = 0 ; + } + // Se il raggio corner è non nullo + // l'utensile viene descritto da + // come utensile generico. + else { + + m_dRCorner = dCornR ; + m_nToolType = GenericTool ; + + // come profilo + m_nToolType = GenericTool ; + Point3d pt0( 0, 0, 0) ; + Point3d pt1( m_dRadius, 0, 0) ; + Point3d pt2( m_dRadius, - m_dHeight + m_dTipHeight, 0) ; + + if ( m_dTipRadius < m_dRadius) { + + Point3d ptInt( dTipR, - dH, 0) ; + Point3d ptLast( 0, - dH, 0) ; + + CurveLine cLine1 ; cLine1.Set( pt2, ptInt) ; + CurveLine cLine2 ; cLine2.Set( ptInt, ptLast) ; + + double dTrim1, dTrim2 ; + + Point3d ptIn1 = ptInt + Y_AX * dCornR ; + Point3d ptIn2 = ptInt - X_AX * dCornR ; + + ICurveArc* pArc = CreateFillet( cLine1, ptIn1, cLine2, ptIn2, Z_AX, dCornR, dTrim1, dTrim2) ; + + cLine1.TrimEndAtParam( abs( dTrim1)) ; + cLine2.TrimStartAtParam( abs( dTrim2)) ; + + Point3d pt3, pt4 ; + + cLine1.GetEndPoint( pt3) ; + cLine2.GetStartPoint( pt4) ; + + Point3d ptC = pArc -> GetCenter() ; + + CurveArc cvArc ; cvArc.SetC2P( ptC, pt3, pt4) ; + + m_ToolOutline.Clear() ; + + CurveLine LineSt ; LineSt.Set( pt0, pt1) ; + + m_ToolOutline.AddCurve( LineSt) ; + m_ToolOutline.AddLine( pt2); + m_ToolOutline.AddLine( pt3); + m_ToolOutline.AddCurve( cvArc) ; + m_ToolOutline.AddLine( ptLast) ; + } + else { + + if ( dTipR - dCornR < 0) + return false ; + + Point3d ptC( dTipR - dCornR, - dH + dCornR, 0) ; + + CurveArc cvCirc ; cvCirc.SetXY( ptC, dCornR) ; + + Point3d ptNear( ptC.x + dCornR, ptC.y + dCornR, 0) ; + + ICurveLine* pLine = GetLinePointTgCurve( pt2, cvCirc, ptNear) ; + + Point3d pt3 ; + + pLine -> GetEndPoint( pt3) ; + + Point3d pt4( ptC.x, - dH, 0) ; + + CurveArc cvArc ; cvArc.SetC2P( ptC, pt3, pt4) ; + + Point3d pt5( 0, - dH, 0) ; + + m_ToolOutline.Clear() ; + + CurveLine Line ; Line.Set( pt0, pt1) ; + + m_ToolOutline.AddCurve( Line) ; + m_ToolOutline.AddLine( pt2); + m_ToolOutline.AddLine( pt3); + m_ToolOutline.AddCurve( cvArc) ; + m_ToolOutline.AddLine( pt5) ; + } + + return SetGenTool( sToolName, &m_ToolOutline) ; + } } // assegno il nome m_sToolName = sToolName ; @@ -146,7 +232,7 @@ VolZmap::SetGenTool( const string& sToolName, const ICurveComposite* pToolOutlin // Ciclo sulle curve componenti while ( pCurve != nullptr) { - // Se la curva è un arco valuto approssimarlo + // Se la curva è un arco valuto se approssimarlo if ( pCurve->GetType() == CRV_ARC) { // Centro e punti iniziale e finale dell'arco