From a58f18822870e3fbffc9ea7cc02ca97e62b764cc Mon Sep 17 00:00:00 2001 From: LorenzoM Date: Tue, 20 Jul 2021 14:12:26 +0200 Subject: [PATCH] Asportazioni avanzate volumi virtual milling --- GdbExecutor.cpp | 443 ++++++++++++++- SurfTriMeshBooleans.cpp | 86 +-- Tool.cpp | 2 +- Tool.h | 1 + VolZmap.h | 39 ++ VolZmapVolume.cpp | 1136 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 1662 insertions(+), 45 deletions(-) diff --git a/GdbExecutor.cpp b/GdbExecutor.cpp index 370b888..9a52c96 100644 --- a/GdbExecutor.cpp +++ b/GdbExecutor.cpp @@ -2775,7 +2775,448 @@ GdbExecutor::ExecuteVolZmap( const string& sCmd2, const STRVECTOR& vsParams) //else if ( sCmd2 == "EDGES") { // return ExecuteVolZmapEdges( vsParams) ; //} - return false ; + ///////////////////////////if ( sCmd2 == "ELLCYL") { + /////////////////////////// // Parametri: nParentId, nLineId1, nLineId2, ptLine, vtLine, ptCirc, vtAx, dRad, vtSweptVec, nInOut, ptPP1, vtPV1, ptPP2, vtPV2, ptPP3, vtPV3 + /////////////////////////// if (vsParams.size() != 16) + /////////////////////////// return false; + /////////////////////////// // recupero il riferimento in cui è immerso + /////////////////////////// Frame3d frRef; + /////////////////////////// if (!m_pGDB->GetGroupGlobFrame(GetIdParam(vsParams[0]), frRef)) + /////////////////////////// return false; + /////////////////////////// // recupero punto iniziale retta + /////////////////////////// Point3d ptLine; + /////////////////////////// if (!GetPointParam(vsParams[3], frRef, ptLine)) + /////////////////////////// return false; + /////////////////////////// // recupero vettore retta + /////////////////////////// Vector3d vtLine; + /////////////////////////// if (!GetVectorParam(vsParams[4], frRef, vtLine)) + /////////////////////////// return false; + /////////////////////////// vtLine.Normalize(); + /////////////////////////// // recupero centro circonferenza + /////////////////////////// Point3d ptCirc; + /////////////////////////// if (!GetPointParam(vsParams[5], frRef, ptCirc)) + /////////////////////////// return false; + /////////////////////////// // recupero vettore asse circonferenza + /////////////////////////// Vector3d vtAx; + /////////////////////////// if (!GetVectorParam(vsParams[6], frRef, vtAx)) + /////////////////////////// return false; + /////////////////////////// vtAx.Normalize(); + /////////////////////////// // recupero raggio della circonferenza + /////////////////////////// double dRad; + /////////////////////////// if (!FromString(vsParams[7], dRad)) + /////////////////////////// return false; + /////////////////////////// // recupero vettore di traslazione + /////////////////////////// Vector3d vtSweptVec; + /////////////////////////// if (!GetVectorParam(vsParams[8], frRef, vtSweptVec)) + /////////////////////////// return false; + /////////////////////////// // intero per recupero flag bInOut + /////////////////////////// int nInOut; + /////////////////////////// if (!FromString(vsParams[9], nInOut)) + /////////////////////////// return false; + /////////////////////////// bool bInOut = nInOut == 0 ? false : true; + /////////////////////////// // recupero punto piano 1 + /////////////////////////// Point3d ptPP1; + /////////////////////////// if (!GetPointParam(vsParams[10], frRef, ptPP1)) + /////////////////////////// return false; + /////////////////////////// // recupero vettore piano 1 + /////////////////////////// Vector3d vtPV1; + /////////////////////////// if (!GetVectorParam(vsParams[11], frRef, vtPV1)) + /////////////////////////// return false; + /////////////////////////// vtPV1.Normalize(); + /////////////////////////// // recupero punto piano 2 + /////////////////////////// Point3d ptPP2; + /////////////////////////// if (!GetPointParam(vsParams[12], frRef, ptPP2)) + /////////////////////////// return false; + /////////////////////////// // recupero vettore piano 2 + /////////////////////////// Vector3d vtPV2; + /////////////////////////// if (!GetVectorParam(vsParams[13], frRef, vtPV2)) + /////////////////////////// return false; + /////////////////////////// vtPV2.Normalize(); + /////////////////////////// // recupero punto piano 3 + /////////////////////////// Point3d ptPP3; + /////////////////////////// if (!GetPointParam(vsParams[14], frRef, ptPP3)) + /////////////////////////// return false; + /////////////////////////// // recupero vettore piano 3 + /////////////////////////// Vector3d vtPV3; + /////////////////////////// if (!GetVectorParam(vsParams[15], frRef, vtPV3)) + /////////////////////////// return false; + /////////////////////////// vtPV3.Normalize(); + /////////////////////////// // definisco i piani + /////////////////////////// Plane3d plPlane1; + /////////////////////////// plPlane1.Set(ptPP1, vtPV1); + /////////////////////////// Plane3d plPlane2; + /////////////////////////// plPlane2.Set(ptPP2, vtPV2); + /////////////////////////// Plane3d plPlane3; + /////////////////////////// plPlane3.Set(ptPP3, vtPV3); + /////////////////////////// vector vPlanesVec; + /////////////////////////// /*vPlanesVec.emplace_back( plPlane1) ; + /////////////////////////// vPlanesVec.emplace_back( plPlane2) ; + /////////////////////////// vPlanesVec.emplace_back( plPlane3) ;*/ + /////////////////////////// // Intersezione + /////////////////////////// VolZmap MyVol; + /////////////////////////// Point3d ptInt1; + /////////////////////////// Vector3d vtN1; + /////////////////////////// Point3d ptInt2; + /////////////////////////// Vector3d vtN2; + /////////////////////////// int nSol = MyVol.IntersLineCircSweptSurfCuttedByPlanes(ptLine, vtLine, ptCirc, vtAx, dRad, vtSweptVec, bInOut, vPlanesVec, + /////////////////////////// ptInt1, vtN1, ptInt2, vtN2); + /////////////////////////// if (nSol == 1) { + /////////////////////////// PtrOwner pLine(CreateBasicCurveLine()); + /////////////////////////// pLine->Set(ptInt1, ptInt1 + vtN1); + /////////////////////////// // inserisco nel DB + /////////////////////////// return AddGeoObj(vsParams[1], vsParams[0], Release(pLine)); + /////////////////////////// } + /////////////////////////// else if (nSol == 2) { + /////////////////////////// PtrOwner pLine1(CreateBasicCurveLine()); + /////////////////////////// pLine1->Set(ptInt1, ptInt1 + vtN1); + /////////////////////////// PtrOwner pLine2(CreateBasicCurveLine()); + /////////////////////////// pLine2->Set(ptInt2, ptInt2 + vtN2); + /////////////////////////// // inserisco nel DB + /////////////////////////// return AddGeoObj(vsParams[1], vsParams[0], Release(pLine1)) && + /////////////////////////// AddGeoObj(vsParams[2], vsParams[0], Release(pLine2)); + /////////////////////////// } + ///////////////////////////} + ///////////////////////////else if (sCmd2 == "STDCYL") { + /////////////////////////// // Parametri : nParentId, nLineId1, nLineId2, ptLineP, vtLineDir, ptBaseCen, vtAx, dRad, dH, nInOut, ptPP1, vtPV1, ptPP2, vtPV2, ptPP3, vtPV3 + /////////////////////////// if (vsParams.size() != 16) + /////////////////////////// return false; + /////////////////////////// // recupero il riferimento in cui è immerso + /////////////////////////// Frame3d frRef; + /////////////////////////// if (!m_pGDB->GetGroupGlobFrame(GetIdParam(vsParams[0]), frRef)) + /////////////////////////// return false; + /////////////////////////// // recupero punto iniziale retta + /////////////////////////// Point3d ptLineP; + /////////////////////////// if (!GetPointParam(vsParams[3], frRef, ptLineP)) + /////////////////////////// return false; + /////////////////////////// // recupero vettore retta + /////////////////////////// Vector3d vtLineDir; + /////////////////////////// if (!GetVectorParam(vsParams[4], frRef, vtLineDir)) + /////////////////////////// return false; + /////////////////////////// vtLineDir.Normalize(); + /////////////////////////// // recupero centro circonferenza + /////////////////////////// Point3d ptBaseCen; + /////////////////////////// if (!GetPointParam(vsParams[5], frRef, ptBaseCen)) + /////////////////////////// return false; + /////////////////////////// // recupero vettore asse circonferenza + /////////////////////////// Vector3d vtAx; + /////////////////////////// if (!GetVectorParam(vsParams[6], frRef, vtAx)) + /////////////////////////// return false; + /////////////////////////// vtAx.Normalize(); + /////////////////////////// // recupero raggio della circonferenza + /////////////////////////// double dRad; + /////////////////////////// if (!FromString(vsParams[7], dRad)) + /////////////////////////// return false; + /////////////////////////// // recupero raggio della circonferenza + /////////////////////////// double dH; + /////////////////////////// if (!FromString(vsParams[8], dH)) + /////////////////////////// return false; + /////////////////////////// // intero per recupero flag bInOut + /////////////////////////// int nInOut; + /////////////////////////// if (!FromString(vsParams[9], nInOut)) + /////////////////////////// return false; + /////////////////////////// bool bInOut = nInOut == 0 ? false : true; + /////////////////////////// // recupero punto piano 1 + /////////////////////////// Point3d ptPP1; + /////////////////////////// if (!GetPointParam(vsParams[10], frRef, ptPP1)) + /////////////////////////// return false; + /////////////////////////// // recupero vettore piano 1 + /////////////////////////// Vector3d vtPV1; + /////////////////////////// if (!GetVectorParam(vsParams[11], frRef, vtPV1)) + /////////////////////////// return false; + /////////////////////////// vtPV1.Normalize(); + /////////////////////////// // recupero punto piano 2 + /////////////////////////// Point3d ptPP2; + /////////////////////////// if (!GetPointParam(vsParams[12], frRef, ptPP2)) + /////////////////////////// return false; + /////////////////////////// // recupero vettore piano 2 + /////////////////////////// Vector3d vtPV2; + /////////////////////////// if (!GetVectorParam(vsParams[13], frRef, vtPV2)) + /////////////////////////// return false; + /////////////////////////// vtPV2.Normalize(); + /////////////////////////// // recupero punto piano 3 + /////////////////////////// Point3d ptPP3; + /////////////////////////// if (!GetPointParam(vsParams[14], frRef, ptPP3)) + /////////////////////////// return false; + /////////////////////////// // recupero vettore piano 3 + /////////////////////////// Vector3d vtPV3; + /////////////////////////// if (!GetVectorParam(vsParams[15], frRef, vtPV3)) + /////////////////////////// return false; + /////////////////////////// vtPV3.Normalize(); + /////////////////////////// // definisco i piani + /////////////////////////// Plane3d plPlane1; + /////////////////////////// plPlane1.Set(ptPP1, vtPV1); + /////////////////////////// Plane3d plPlane2; + /////////////////////////// plPlane2.Set(ptPP2, vtPV2); + /////////////////////////// Plane3d plPlane3; + /////////////////////////// plPlane3.Set(ptPP3, vtPV3); + /////////////////////////// vector vPlanesVec; + /////////////////////////// /*vPlanesVec.emplace_back( plPlane1) ; + /////////////////////////// vPlanesVec.emplace_back( plPlane2) ; + /////////////////////////// vPlanesVec.emplace_back( plPlane3) ;*/ + /////////////////////////// // Intersezione + /////////////////////////// VolZmap MyVol; + /////////////////////////// Point3d ptInt1; + /////////////////////////// Vector3d vtN1; + /////////////////////////// Point3d ptInt2; + /////////////////////////// Vector3d vtN2; + /////////////////////////// int nSol = MyVol.IntersLineCylinderCuttedByPlanes(ptLineP, vtLineDir, ptBaseCen, vtAx, dRad, dH, bInOut, vPlanesVec, ptInt1, vtN1, ptInt2, vtN2); + /////////////////////////// if (nSol == 1) { + /////////////////////////// PtrOwner pLine(CreateBasicCurveLine()); + /////////////////////////// pLine->Set(ptInt1, ptInt1 + vtN1); + /////////////////////////// // inserisco nel DB + /////////////////////////// return AddGeoObj(vsParams[1], vsParams[0], Release(pLine)); + /////////////////////////// } + /////////////////////////// else if (nSol == 2) { + /////////////////////////// PtrOwner pLine1(CreateBasicCurveLine()); + /////////////////////////// pLine1->Set(ptInt1, ptInt1 + vtN1); + /////////////////////////// PtrOwner pLine2(CreateBasicCurveLine()); + /////////////////////////// pLine2->Set(ptInt2, ptInt2 + vtN2); + /////////////////////////// // inserisco nel DB + /////////////////////////// return AddGeoObj(vsParams[1], vsParams[0], Release(pLine1)) && + /////////////////////////// AddGeoObj(vsParams[2], vsParams[0], Release(pLine2)); + /////////////////////////// } + ///////////////////////////} + ///////////////////////////else if ( sCmd2 == "PLANE") { + /////////////////////////// // Parametri : nParentId, nLineId, ptLineP, vtLineDir, ptParOrig, vtSeg1, vtSeg2, nExtNorm + /////////////////////////// if (vsParams.size() != 8) + /////////////////////////// return false; + /////////////////////////// // recupero il riferimento in cui è immerso + /////////////////////////// Frame3d frRef; + /////////////////////////// if (!m_pGDB->GetGroupGlobFrame(GetIdParam(vsParams[0]), frRef)) + /////////////////////////// return false; + /////////////////////////// // recupero punto iniziale retta + /////////////////////////// Point3d ptLineP; + /////////////////////////// if (!GetPointParam(vsParams[2], frRef, ptLineP)) + /////////////////////////// return false; + /////////////////////////// // recupero vettore retta + /////////////////////////// Vector3d vtLineDir; + /////////////////////////// if (!GetVectorParam(vsParams[3], frRef, vtLineDir)) + /////////////////////////// return false; + /////////////////////////// vtLineDir.Normalize(); + /////////////////////////// // recupero origine parallelogramma + /////////////////////////// Point3d ptParOrig; + /////////////////////////// if (!GetPointParam(vsParams[4], frRef, ptParOrig)) + /////////////////////////// return false; + /////////////////////////// // recupero vettore segmento 1 + /////////////////////////// Vector3d vtSeg1; + /////////////////////////// if (!GetVectorParam(vsParams[5], frRef, vtSeg1)) + /////////////////////////// return false; + /////////////////////////// // recupero vettore segmento 2 + /////////////////////////// Vector3d vtSeg2; + /////////////////////////// if (!GetVectorParam(vsParams[6], frRef, vtSeg2)) + /////////////////////////// return false; + /////////////////////////// // intero per recupero flag nExtNorm + /////////////////////////// int nExtNorm; + /////////////////////////// if (!FromString(vsParams[7], nExtNorm)) + /////////////////////////// return false; + /////////////////////////// bool bExtNorm = nExtNorm == 0 ? false : true; + /////////////////////////// // Intersezione + /////////////////////////// VolZmap MyVol; + /////////////////////////// Point3d ptInt; + /////////////////////////// Vector3d vtN; + /////////////////////////// int nSol = MyVol.IntersLineParallelogram( ptLineP, vtLineDir, ptParOrig, vtSeg1, vtSeg2, bExtNorm, ptInt, vtN) ; + /////////////////////////// if (nSol == 1) { + /////////////////////////// PtrOwner pLine(CreateBasicCurveLine()); + /////////////////////////// pLine->Set(ptInt, ptInt + vtN); + /////////////////////////// // inserisco nel DB + /////////////////////////// return AddGeoObj(vsParams[1], vsParams[0], Release(pLine)); + /////////////////////////// } + ///////////////////////////} + ///////////////////////////else if (sCmd2 == "CONE") { + /////////////////////////// // Parametri : nParentId, nLineId1, nLineId2, ptLineP, vtLineDir, ptVert, vtAx, dRad, dH, nInOut, ptPP1, vtPV1, ptPP2, vtPV2, ptPP3, vtPV3 + /////////////////////////// if (vsParams.size() != 16) + /////////////////////////// return false; + /////////////////////////// // recupero il riferimento in cui è immerso + /////////////////////////// Frame3d frRef; + /////////////////////////// if (!m_pGDB->GetGroupGlobFrame(GetIdParam(vsParams[0]), frRef)) + /////////////////////////// return false; + /////////////////////////// // recupero punto iniziale retta + /////////////////////////// Point3d ptLineP; + /////////////////////////// if (!GetPointParam(vsParams[3], frRef, ptLineP)) + /////////////////////////// return false; + /////////////////////////// // recupero vettore retta + /////////////////////////// Vector3d vtLineDir; + /////////////////////////// if (!GetVectorParam(vsParams[4], frRef, vtLineDir)) + /////////////////////////// return false; + /////////////////////////// vtLineDir.Normalize(); + /////////////////////////// // recupero vertice cono + /////////////////////////// Point3d ptVert; + /////////////////////////// if (!GetPointParam(vsParams[5], frRef, ptVert)) + /////////////////////////// return false; + /////////////////////////// // recupero vettore asse cono + /////////////////////////// Vector3d vtAx; + /////////////////////////// if (!GetVectorParam(vsParams[6], frRef, vtAx)) + /////////////////////////// return false; + /////////////////////////// vtAx.Normalize(); + /////////////////////////// // recupero raggio della base del cono + /////////////////////////// double dRad; + /////////////////////////// if (!FromString(vsParams[7], dRad)) + /////////////////////////// return false; + /////////////////////////// // recupero altezza del cono + /////////////////////////// double dH; + /////////////////////////// if (!FromString(vsParams[8], dH)) + /////////////////////////// return false; + /////////////////////////// // intero per recupero flag nExtNorm + /////////////////////////// int nInOut; + /////////////////////////// if (!FromString(vsParams[9], nInOut)) + /////////////////////////// return false; + /////////////////////////// bool bInOut = nInOut == 0 ? false : true; + /////////////////////////// // recupero punto piano 1 + /////////////////////////// Point3d ptPP1; + /////////////////////////// if (!GetPointParam(vsParams[10], frRef, ptPP1)) + /////////////////////////// return false; + /////////////////////////// // recupero vettore piano 1 + /////////////////////////// Vector3d vtPV1; + /////////////////////////// if (!GetVectorParam(vsParams[11], frRef, vtPV1)) + /////////////////////////// return false; + /////////////////////////// vtPV1.Normalize(); + /////////////////////////// // recupero punto piano 2 + /////////////////////////// Point3d ptPP2; + /////////////////////////// if (!GetPointParam(vsParams[12], frRef, ptPP2)) + /////////////////////////// return false; + /////////////////////////// // recupero vettore piano 2 + /////////////////////////// Vector3d vtPV2; + /////////////////////////// if (!GetVectorParam(vsParams[13], frRef, vtPV2)) + /////////////////////////// return false; + /////////////////////////// vtPV2.Normalize(); + /////////////////////////// // recupero punto piano 3 + /////////////////////////// Point3d ptPP3; + /////////////////////////// if (!GetPointParam(vsParams[14], frRef, ptPP3)) + /////////////////////////// return false; + /////////////////////////// // recupero vettore piano 3 + /////////////////////////// Vector3d vtPV3; + /////////////////////////// if (!GetVectorParam(vsParams[15], frRef, vtPV3)) + /////////////////////////// return false; + /////////////////////////// vtPV3.Normalize(); + /////////////////////////// // definisco i piani + /////////////////////////// Plane3d plPlane1; + /////////////////////////// plPlane1.Set(ptPP1, vtPV1); + /////////////////////////// Plane3d plPlane2; + /////////////////////////// plPlane2.Set(ptPP2, vtPV2); + /////////////////////////// Plane3d plPlane3; + /////////////////////////// plPlane3.Set(ptPP3, vtPV3); + /////////////////////////// vector vPlanesVec; + /////////////////////////// /*vPlanesVec.emplace_back( plPlane1) ; + /////////////////////////// vPlanesVec.emplace_back( plPlane2) ; + /////////////////////////// vPlanesVec.emplace_back( plPlane3) ;*/ + /////////////////////////// // Intersezione + /////////////////////////// VolZmap MyVol; + /////////////////////////// Point3d ptInt1; + /////////////////////////// Vector3d vtN1; + /////////////////////////// Point3d ptInt2; + /////////////////////////// Vector3d vtN2; + /////////////////////////// int nSol = MyVol.IntersLineConeCuttedByPlanes( ptLineP, vtLineDir, ptVert, vtAx, dRad, dH, bInOut, vPlanesVec, ptInt1, vtN1, ptInt2, vtN2); + /////////////////////////// if (nSol == 1) { + /////////////////////////// PtrOwner pLine(CreateBasicCurveLine()); + /////////////////////////// pLine->Set(ptInt1, ptInt1 + vtN1); + /////////////////////////// // inserisco nel DB + /////////////////////////// return AddGeoObj(vsParams[1], vsParams[0], Release(pLine)); + /////////////////////////// } + /////////////////////////// else if (nSol == 2) { + /////////////////////////// PtrOwner pLine1(CreateBasicCurveLine()); + /////////////////////////// pLine1->Set(ptInt1, ptInt1 + vtN1); + /////////////////////////// PtrOwner pLine2(CreateBasicCurveLine()); + /////////////////////////// pLine2->Set(ptInt2, ptInt2 + vtN2); + /////////////////////////// // inserisco nel DB + /////////////////////////// return AddGeoObj(vsParams[1], vsParams[0], Release(pLine1)) && + /////////////////////////// AddGeoObj(vsParams[2], vsParams[0], Release(pLine2)); + /////////////////////////// } + ///////////////////////////} + ///////////////////////////else if (sCmd2 == "SPHERE") { + /////////////////////////// // Parametri: nParentId, nLineId1, nLineId2, ptLineP, vtLineD, ptCen, dRad, nInOut, ptPP1, vtPV1, ptPP2, vtPV2, ptPP3, vtPV3 + /////////////////////////// if (vsParams.size() != 14) + /////////////////////////// return false; + /////////////////////////// // recupero il riferimento in cui è immerso + /////////////////////////// Frame3d frRef; + /////////////////////////// if (!m_pGDB->GetGroupGlobFrame(GetIdParam(vsParams[0]), frRef)) + /////////////////////////// return false; + /////////////////////////// // recupero punto iniziale retta + /////////////////////////// Point3d ptLineP; + /////////////////////////// if (!GetPointParam(vsParams[3], frRef, ptLineP)) + /////////////////////////// return false; + /////////////////////////// // recupero vettore retta + /////////////////////////// Vector3d vtLineD; + /////////////////////////// if (!GetVectorParam(vsParams[4], frRef, vtLineD)) + /////////////////////////// return false; + /////////////////////////// vtLineD.Normalize(); + /////////////////////////// // recupero centro sfera + /////////////////////////// Point3d ptCen; + /////////////////////////// if (!GetPointParam(vsParams[5], frRef, ptCen)) + /////////////////////////// return false; + /////////////////////////// // recupero raggio della sfera + /////////////////////////// double dRad; + /////////////////////////// if (!FromString(vsParams[6], dRad)) + /////////////////////////// return false; + /////////////////////////// // intero per recupero flag nExtNorm + /////////////////////////// int nInOut; + /////////////////////////// if (!FromString(vsParams[7], nInOut)) + /////////////////////////// return false; + /////////////////////////// bool bInOut = nInOut == 0 ? false : true; + /////////////////////////// // recupero punto piano 1 + /////////////////////////// Point3d ptPP1; + /////////////////////////// if (!GetPointParam(vsParams[8], frRef, ptPP1)) + /////////////////////////// return false; + /////////////////////////// // recupero vettore piano 1 + /////////////////////////// Vector3d vtPV1; + /////////////////////////// if (!GetVectorParam(vsParams[9], frRef, vtPV1)) + /////////////////////////// return false; + /////////////////////////// vtPV1.Normalize(); + /////////////////////////// // recupero punto piano 2 + /////////////////////////// Point3d ptPP2; + /////////////////////////// if (!GetPointParam(vsParams[10], frRef, ptPP2)) + /////////////////////////// return false; + /////////////////////////// // recupero vettore piano 2 + /////////////////////////// Vector3d vtPV2; + /////////////////////////// if (!GetVectorParam(vsParams[11], frRef, vtPV2)) + /////////////////////////// return false; + /////////////////////////// vtPV2.Normalize(); + /////////////////////////// // recupero punto piano 3 + /////////////////////////// Point3d ptPP3; + /////////////////////////// if (!GetPointParam(vsParams[12], frRef, ptPP3)) + /////////////////////////// return false; + /////////////////////////// // recupero vettore piano 3 + /////////////////////////// Vector3d vtPV3; + /////////////////////////// if (!GetVectorParam(vsParams[13], frRef, vtPV3)) + /////////////////////////// return false; + /////////////////////////// vtPV3.Normalize(); + /////////////////////////// // definisco i piani + /////////////////////////// Plane3d plPlane1; + /////////////////////////// plPlane1.Set(ptPP1, vtPV1); + /////////////////////////// Plane3d plPlane2; + /////////////////////////// plPlane2.Set(ptPP2, vtPV2); + /////////////////////////// Plane3d plPlane3; + /////////////////////////// plPlane3.Set(ptPP3, vtPV3); + /////////////////////////// vector vPlanesVec; + /////////////////////////// /*vPlanesVec.emplace_back( plPlane1) ; + /////////////////////////// vPlanesVec.emplace_back( plPlane2) ; + /////////////////////////// vPlanesVec.emplace_back( plPlane3) ;*/ + /////////////////////////// // Intersezione + /////////////////////////// VolZmap MyVol; + /////////////////////////// Point3d ptInt1; + /////////////////////////// Vector3d vtN1; + /////////////////////////// Point3d ptInt2; + /////////////////////////// Vector3d vtN2; + /////////////////////////// int nSol = MyVol.IntersLineSphereCuttedByPlanes(ptLineP, vtLineD, ptCen, dRad, bInOut, vPlanesVec, ptInt1, vtN1, ptInt2, vtN2); + /////////////////////////// if (nSol == 1) { + /////////////////////////// PtrOwner pLine(CreateBasicCurveLine()); + /////////////////////////// pLine->Set(ptInt1, ptInt1 + vtN1); + /////////////////////////// // inserisco nel DB + /////////////////////////// return AddGeoObj(vsParams[1], vsParams[0], Release(pLine)); + /////////////////////////// } + /////////////////////////// else if (nSol == 2) { + /////////////////////////// PtrOwner pLine1(CreateBasicCurveLine()); + /////////////////////////// pLine1->Set(ptInt1, ptInt1 + vtN1); + /////////////////////////// PtrOwner pLine2(CreateBasicCurveLine()); + /////////////////////////// pLine2->Set(ptInt2, ptInt2 + vtN2); + /////////////////////////// // inserisco nel DB + /////////////////////////// return AddGeoObj(vsParams[1], vsParams[0], Release(pLine1)) && + /////////////////////////// AddGeoObj(vsParams[2], vsParams[0], Release(pLine2)); + /////////////////////////// } + ///////////////////////////} + ///////////////////////////else + /////////////////////////// return false ; + ///////////////////////////return true ; + return true; } /* //---------------------------------------------------------------------------- diff --git a/SurfTriMeshBooleans.cpp b/SurfTriMeshBooleans.cpp index 21f052c..d452e6e 100644 --- a/SurfTriMeshBooleans.cpp +++ b/SurfTriMeshBooleans.cpp @@ -495,7 +495,7 @@ SurfTriMesh::GeneralizedCut( const ICurve& cvCurve, bool bSaveOnEq) vPL.emplace_back( plInLoop) ; PNTVECTOR vPt ; INTVECTOR vTr ; - if ( Triangulate().Make( vPL, vPt, vTr, TrgType::TRG_DEL_QUALITY)) { + if ( Triangulate().Make( vPL, vPt, vTr, TrgType::TRG_STANDARD)) { // Inserisco i nuovi triangoli for ( int n = 0 ; n < int( vTr.size()) - 2 ; n += 3) { int nNewTriaVertId[3] = { vTr[n], vTr[n + 1], vTr[n + 2] } ; @@ -711,7 +711,7 @@ SurfTriMesh::GeneralizedCut( const ICurve& cvCurve, bool bSaveOnEq) Triangulate CreateTriangulation ; PNTVECTOR vPt ; INTVECTOR vTr ; - if ( Triangulate().Make( vplPolyVec[nLoop], vPt, vTr, TrgType::TRG_DEL_QUALITY)) { + if ( Triangulate().Make( vplPolyVec[nLoop], vPt, vTr, TrgType::TRG_STANDARD)) { // Inserisco i nuovi triangoli for ( int n = 0 ; n < int( vTr.size()) - 2 ; n += 3) { int nNewTriaVertId[3] = { vTr[n], vTr[n + 1], vTr[n + 2] } ; @@ -1350,7 +1350,7 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT // Eseguo triangolazione PNTVECTOR vPt ; INTVECTOR vTr ; - if ( Triangulate().Make( vplPolyVec[nLoop], vPt, vTr, TrgType::TRG_DEL_QUALITY)) { + if ( Triangulate().Make( vplPolyVec[nLoop], vPt, vTr, TrgType::TRG_STANDARD)) { // Inserisco i nuovi triangoli for ( int n = 0 ; n < int( vTr.size()) - 2 ; n += 3) { int nNewTriaVertId[3] = { vTr[n], vTr[n + 1], vTr[n + 2] } ; @@ -1446,7 +1446,7 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT PNTVECTOR vPt ; INTVECTOR vTr ; - if ( Triangulate().Make( vPolygons, vPt, vTr, TrgType::TRG_DEL_QUALITY)) { + if ( Triangulate().Make( vPolygons, vPt, vTr, TrgType::TRG_STANDARD)) { // Inserisco i nuovi triangoli for ( int n = 0 ; n < int( vTr.size()) - 2 ; n += 3) { int nNewTriaVertId[3] = { vTr[n], vTr[n + 1], vTr[n + 2]} ; @@ -1582,7 +1582,7 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT } for ( int nL = 1 ; nL < int( vPolygons.size()) ; ++ nL) { vPolygons[nL].Invert() ; - if ( Triangulate().Make( vPolygons[nL], vPt, vTr, TrgType::TRG_DEL_QUALITY)) { + if ( Triangulate().Make( vPolygons[nL], vPt, vTr, TrgType::TRG_STANDARD)) { // Inserisco i nuovi triangoli for (int n = 0 ; n < int( vTr.size()) - 2 ; n += 3) { int nNewTriaVertId[3] = { vTr[n], vTr[n + 1], vTr[n + 2]} ; @@ -1949,6 +1949,7 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other) if ( nTriaNum >= 0) { Triangle3d trTriaB ; SurfB.GetTriangle( nTriaNum, trTriaB) ; + trTriaB.Validate(); if ( ( ptFirstV - trTriaB.GetP(0)) * trTriaB.GetN() < - EPS_SMALL) nInOutNum = 1 ; else if ( ( ptFirstV - trTriaB.GetP(0)) * trTriaB.GetN() > EPS_SMALL) @@ -1985,6 +1986,7 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other) if ( nTriaNum >= 0) { Triangle3d trTriaA ; GetTriangle( nTriaNum, trTriaA) ; + trTriaA.Validate(); if ( ( ptFirstV - trTriaA.GetP( 0)) * trTriaA.GetN() < - EPS_SMALL) { nInOutNum = 1 ; } @@ -2997,7 +2999,7 @@ TrimLineWithExtPolygon( const CurveLine& cvLine, const POLYLINEVECTOR& vContourV // Definisco le parti di linea dentro il poligono esteso. bool bStateInside = true ; for ( int nC = 0 ; nC < int( vMyContourVec.size()) ; ++ nC) { - bStateInside = bStateInside && IsPointInsidePolyLine( cvMyLine.GetStart(), vMyContourVec[nC]) ; + bStateInside = bStateInside && vMyContourVec[nC].IsPointInsidePolyLine( cvMyLine.GetStart()) ; } if ( bStateInside) vLinePart.emplace_back( 0, -1, LCP_ERROR) ; @@ -3082,7 +3084,7 @@ DistPointFacet( const Point3d& ptP, /*const*/ POLYLINEVECTOR& vPolyVec, double& dPointPlaneSignedDist = ( ptP - ptPlaneP) * vtPlaneN ; ptProjP = ptP + dPointPlaneSignedDist * vtPlaneN ; } - if ( ! IsPointInsidePolyLine( ptProjP, vPolyVec[nLoop])) + if ( ! vPolyVec[nLoop].IsPointInsidePolyLine( ptProjP)) bPointIsInside = false ; } // Se la proiezione del punto sul piano della faccia � interno, ho finito. @@ -3096,7 +3098,7 @@ DistPointFacet( const Point3d& ptP, /*const*/ POLYLINEVECTOR& vPolyVec, double& dPointFacetDist = DBL_MAX ; for ( int nLoop = 0 ; nLoop < int( vPolyVec.size()) ; ++ nLoop) { double dDist ; - if ( DistPointPolyLine( ptP, vPolyVec[nLoop], dDist) && dDist < dPointFacetDist) + if ( vPolyVec[nLoop].DistPointPolyLine( ptP, dDist) && dDist < dPointFacetDist) dPointFacetDist = dDist ; } return true ; @@ -3212,14 +3214,14 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet for ( int nLoop = 0 ; nLoop < int( vNewPieces[nPart].vPieceLoop.size()) && int( vLoopIndexes.size()) < 2 ; ++ nLoop) { int nSegNum ; double dParOnSeg ; - if ( PointPositionOnPolyLine( cvOpenChain[nLastChainNum][0].ptSt, vNewPieces[nPart].vPieceLoop[nLoop], nSegNum, dParOnSeg, 9 * EPS_SMALL)) { + if ( vNewPieces[nPart].vPieceLoop[nLoop].PointPositionOnPolyLine( cvOpenChain[nLastChainNum][0].ptSt, nSegNum, dParOnSeg, 9 * EPS_SMALL)) { vLoopIndexes.emplace_back( nLoop) ; if ( vLoopIndexes.size() > 1) { swap( vLoopIndexes[0], vLoopIndexes[1]) ; } } - if ( PointPositionOnPolyLine( cvOpenChain[nLastChainNum][cvOpenChain[nLastChainNum].size() - 1].ptEn, - vNewPieces[nPart].vPieceLoop[nLoop], nSegNum, dParOnSeg, 9 * EPS_SMALL)) { + if ( vNewPieces[nPart].vPieceLoop[nLoop].PointPositionOnPolyLine( cvOpenChain[nLastChainNum][cvOpenChain[nLastChainNum].size() - 1].ptEn, + nSegNum, dParOnSeg, 9 * EPS_SMALL)) { vLoopIndexes.emplace_back( nLoop) ; } } @@ -3229,7 +3231,7 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet // La catena finisce sul loop ove inizia. Divido la nuova parte. if ( vLoopIndexes[0] == vLoopIndexes[1]) { // Cambio inizio al loop iniziale. - ChangePolyLineStart( cvOpenChain[nLastChainNum].back().ptEn, vNewPieces[nPart].vPieceLoop[vLoopIndexes[0]], 9 * EPS_SMALL) ; + vNewPieces[nPart].vPieceLoop[vLoopIndexes[0]].ChangePolyLineStart( cvOpenChain[nLastChainNum].back().ptEn, 9 * EPS_SMALL) ; // Divido il loop della parte // Loop1 PolyLine NewLoop1 ; @@ -3241,14 +3243,13 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet } // Spezzo il loop successivo alla catena nel punto in cui comincia la catena successiva. PolyLine SplitLoop1, SplitLoop2 ; - SplitPolyLineAtPoint( cvOpenChain[nLastChainNum][0].ptSt, - vNewPieces[nPart].vPieceLoop[vLoopIndexes[0]], - SplitLoop1, SplitLoop2, 9 * EPS_SMALL) ; + vNewPieces[nPart].vPieceLoop[vLoopIndexes[0]].SplitPolyLineAtPoint( cvOpenChain[nLastChainNum][0].ptSt, + SplitLoop1, SplitLoop2, 9 * EPS_SMALL) ; // Aggiungo i punti precedenti il punto di frattura nella in NewLoop1. - AddPolyLineToPolyLine( NewLoop1, SplitLoop1, 10 * EPS_SMALL) ; + NewLoop1.AddPolyLineToPolyLine( SplitLoop1, 10 * EPS_SMALL) ; // Loop2 PolyLine NewLoop2 ; - AddPolyLineToPolyLine( NewLoop2, SplitLoop2, 10 * EPS_SMALL) ; + NewLoop2.AddPolyLineToPolyLine( SplitLoop2, 10 * EPS_SMALL) ; // Inserisco i punti della catena nella PolyLine del nuovo loop. for ( int m = int( cvOpenChain[nLastChainNum].size()) - 1 ; m >= 0 ; -- m) { NewLoop2.AddUPoint( 0., cvOpenChain[nLastChainNum][m].ptEn) ; @@ -3270,7 +3271,7 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet Point3d ptPointInnerLoop ; vNewPieces[nPart].vPieceLoop[nIL].GetFirstPoint( ptPointInnerLoop) ; if ( PieceInn.vPieceLoop[0].GetPointNbr() < PieceOut.vPieceLoop[0].GetPointNbr()) { - if ( IsPointInsidePolyLine( ptPointInnerLoop, PieceInn.vPieceLoop[0])) { + if ( PieceInn.vPieceLoop[0].IsPointInsidePolyLine( ptPointInnerLoop)) { PieceInn.vPieceLoop.emplace_back( vNewPieces[nPart].vPieceLoop[nIL]) ; } else { @@ -3278,7 +3279,7 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet } } else { - if ( IsPointInsidePolyLine( ptPointInnerLoop, PieceOut.vPieceLoop[0])) { + if ( PieceOut.vPieceLoop[0].IsPointInsidePolyLine( ptPointInnerLoop)) { PieceOut.vPieceLoop.emplace_back( vNewPieces[nPart].vPieceLoop[nIL]) ; } else { @@ -3320,7 +3321,7 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet continue ; Point3d ptPointInnerLoop ; vNewPieces[nPart].vPieceLoop[nIL].GetFirstPoint( ptPointInnerLoop) ; - if ( IsPointInsidePolyLine( ptPointInnerLoop, DetachedPiece.vPieceLoop[0])) { + if ( DetachedPiece.vPieceLoop[0].IsPointInsidePolyLine( ptPointInnerLoop)) { DetachedPiece.vPieceLoop.emplace_back( vNewPieces[nPart].vPieceLoop[nIL]) ; vNewPieces[nPart].vPieceLoop.erase( vNewPieces[nPart].vPieceLoop.begin() + nIL) ; // Cambio il numero dei loop talgiati @@ -3350,14 +3351,14 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet int nIter = 0 ; while ( vLoopIndexes.back() != vLoopIndexes[0] && nIter == 0) { // Cambio inizio del loop corrente in modo che il punto di inizio sia il punto finale dell'ultima catena trovata. - ChangePolyLineStart( cvOpenChain[vChainIndex.back()].back().ptEn, vNewPieces[nPart].vPieceLoop[vLoopIndexes.back()], 9 * EPS_SMALL) ; + vNewPieces[nPart].vPieceLoop[vLoopIndexes.back()].ChangePolyLineStart( cvOpenChain[vChainIndex.back()].back().ptEn, 9 * EPS_SMALL) ; // Cerco catene che iniziano sul loop coorente vector vChainStartingOnLoop ; for ( int nCh = 0 ; nCh < nLastChainNum ; ++ nCh) { int nSegNum ; double dParOnSeg ; - if ( PointPositionOnPolyLine( cvOpenChain[nCh][0].ptSt, vNewPieces[nPart].vPieceLoop[vLoopIndexes.back()], nSegNum, dParOnSeg, 9 * EPS_SMALL)) { - vChainStartingOnLoop.emplace_back( PositionOnPolyLine(nCh, nSegNum, dParOnSeg)) ; + if ( vNewPieces[nPart].vPieceLoop[vLoopIndexes.back()].PointPositionOnPolyLine( cvOpenChain[nCh][0].ptSt, nSegNum, dParOnSeg, 9 * EPS_SMALL)) { + vChainStartingOnLoop.emplace_back( PositionOnPolyLine(nCh, nSegNum, dParOnSeg)) ; } } // Ordino le catene secondo la vicinanza lungo il loop del loro punto d'inizio al punto d'inizio del loop stesso. @@ -3386,7 +3387,7 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet double dParOnSeg ; // La catena termina su questo loop diverso da quello corrente. if ( nLoop != vLoopIndexes.back() && - PointPositionOnPolyLine( cvOpenChain[nCh][nLastLineIndex].ptEn, vNewPieces[nPart].vPieceLoop[nLoop], nSegNum, dParOnSeg, 9 * EPS_SMALL)) { + vNewPieces[nPart].vPieceLoop[nLoop].PointPositionOnPolyLine( cvOpenChain[nCh][nLastLineIndex].ptEn, nSegNum, dParOnSeg, 9 * EPS_SMALL)) { nIter = 0 ; // Salvo l'indice della catena e quello del loop. vChainIndex.emplace_back( nCh) ; @@ -3400,7 +3401,7 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet } } // Cambio inizio al loop iniziale. - ChangePolyLineStart( cvOpenChain[vChainIndex.back()].back().ptEn, vNewPieces[nPart].vPieceLoop[vLoopIndexes[0]], 9 * EPS_SMALL) ; + vNewPieces[nPart].vPieceLoop[vLoopIndexes[0]].ChangePolyLineStart( cvOpenChain[vChainIndex.back()].back().ptEn, 9 * EPS_SMALL) ; // Divido i loop della parte. POLYLINEVECTOR vPolySecondPartVec ; PolyLine NewLoop1 ; @@ -3413,18 +3414,17 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet } // Spezzo il loop successivo alla catena nel punto in cui comincia la catena successiva. PolyLine SplitLoop1, SplitLoop2 ; - SplitPolyLineAtPoint( cvOpenChain[vChainIndex[( n + 1) % int( vChainIndex.size())]][0].ptSt, - vNewPieces[nPart].vPieceLoop[vLoopIndexes[n + 1]], - SplitLoop1, SplitLoop2, 9 * EPS_SMALL) ; + vNewPieces[nPart].vPieceLoop[vLoopIndexes[n + 1]].SplitPolyLineAtPoint( cvOpenChain[vChainIndex[( n + 1) % int( vChainIndex.size())]][0].ptSt, + SplitLoop1, SplitLoop2, 9 * EPS_SMALL) ; // Aggiungo i punti precedenti il punto di frattura in NewLoop1. - AddPolyLineToPolyLine( NewLoop1, SplitLoop1, 10 * EPS_SMALL) ; + NewLoop1.AddPolyLineToPolyLine( SplitLoop1, 10 * EPS_SMALL) ; // Salvo la parte dopo il punto di frattura in un apposito vettore. vPolySecondPartVec.emplace_back( SplitLoop2) ; } PolyLine NewLoop2 ; for ( int n = int( vChainIndex.size()) - 1 ; n >= 0 ; -- n) { // Aggiungo i punti successivi il punto di frattura in NewLoop2. - AddPolyLineToPolyLine( NewLoop2, vPolySecondPartVec[n], 10 * EPS_SMALL) ; + NewLoop2.AddPolyLineToPolyLine( vPolySecondPartVec[n], 10 * EPS_SMALL) ; // Inserisco i punti della catena nella PolyLine del nuovo loop. for ( int m = int( cvOpenChain[vChainIndex[n]].size()) - 1 ; m >= 0 ; -- m) { NewLoop2.AddUPoint( 0., cvOpenChain[vChainIndex[n]][m].ptEn) ; @@ -3460,7 +3460,7 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet Point3d ptPointInnerLoop ; vNewPieces[nPart].vPieceLoop[nIL].GetFirstPoint( ptPointInnerLoop) ; if ( PieceInn.vPieceLoop[0].GetPointNbr() < PieceOut.vPieceLoop[0].GetPointNbr()) { - if ( IsPointInsidePolyLine( ptPointInnerLoop, PieceInn.vPieceLoop[0])) { + if ( PieceInn.vPieceLoop[0].IsPointInsidePolyLine( ptPointInnerLoop)) { PieceInn.vPieceLoop.emplace_back( vNewPieces[nPart].vPieceLoop[nIL]) ; } else { @@ -3468,7 +3468,7 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet } } else { - if ( IsPointInsidePolyLine( ptPointInnerLoop, PieceOut.vPieceLoop[0])) { + if ( PieceOut.vPieceLoop[0].IsPointInsidePolyLine( ptPointInnerLoop)) { PieceOut.vPieceLoop.emplace_back( vNewPieces[nPart].vPieceLoop[nIL]) ; } else { @@ -3545,7 +3545,7 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet continue ; Point3d ptPointInnerLoop ; vNewPieces[nPart].vPieceLoop[nIL].GetFirstPoint( ptPointInnerLoop) ; - if ( IsPointInsidePolyLine( ptPointInnerLoop, DetachedPiece.vPieceLoop[0])) { + if ( DetachedPiece.vPieceLoop[0].IsPointInsidePolyLine( ptPointInnerLoop)) { DetachedPiece.vPieceLoop.emplace_back( vNewPieces[nPart].vPieceLoop[nIL]) ; vNewPieces[nPart].vPieceLoop.erase( vNewPieces[nPart].vPieceLoop.begin() + nIL) ; // Cambio il numero dei loop talgiati @@ -3604,8 +3604,8 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet ++ itInnNext ; if ( itInnNext != LoopList.end()) ptInnNextP = itInnNext->first ; - if ( IsPointInsidePolyLine( ptInnP, vNewPieces[nPieceN].vPieceLoop[0]) || ( itInnNext != LoopList.end() && - IsPointInsidePolyLine( 0.5 * ( ptInnP + ptInnNextP), vNewPieces[nPieceN].vPieceLoop[0]))) { + if ( vNewPieces[nPieceN].vPieceLoop[0].IsPointInsidePolyLine( ptInnP) || ( itInnNext != LoopList.end() && + vNewPieces[nPieceN].vPieceLoop[0].IsPointInsidePolyLine( 0.5 * ( ptInnP + ptInnNextP)))) { double dPieceArea ; vNewPieces[nPieceN].vPieceLoop[0].IsClosedAndFlat( Plane3d(), dPieceArea) ; if ( vNewPieces[nPieceN].vPieceLoop[0].IsClosedAndFlat( Plane3d(), dPieceArea) && dPieceArea < dIncluderPieceArea) { @@ -3634,7 +3634,7 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet PNTULIST& SecLevLoopList = vNewPieces[nIncluderPiece].vPieceLoop[nSI].GetUPointList() ; for ( auto itSL = SecLevLoopList.begin() ; itSL != SecLevLoopList.end() ; ++ itSL) { Point3d ptPntSL = itSL->first ; - if ( IsPointInsidePolyLine( ptPntSL, vNewPieces.back().vPieceLoop.back())) { + if ( vNewPieces.back().vPieceLoop.back().IsPointInsidePolyLine( ptPntSL)) { vSecondLevel.emplace_back( nSI) ; break ; } @@ -3661,7 +3661,7 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet PNTULIST& SecLevLoopList = vNewPieces[nIncluderPiece].vPieceLoop[nSI].GetUPointList() ; for ( auto itSL = SecLevLoopList.begin() ; itSL != SecLevLoopList.end() ; ++ itSL) { Point3d ptPntSL = itSL->first ; - if ( IsPointInsidePolyLine( ptPntSL, vNewPieces.back().vPieceLoop.back())) { + if ( vNewPieces.back().vPieceLoop.back().IsPointInsidePolyLine( ptPntSL)) { vSecondLevel.emplace_back( nSI) ; break ; } @@ -4208,8 +4208,8 @@ SplitPolyLineContour( const POLYLINEVECTOR& vContourVec, POLYLINEVECTOR& vContou AuxPoly.AddUPoint( 0, vPointsVec[nP]) ; // Cambio origine al contorno e lo divido. vContourVec1.emplace_back() ; vContourVec2.emplace_back() ; - if ( ChangePolyLineStart( vPointsVec[nSplitI], AuxPoly, 9 * EPS_SMALL) && - SplitPolyLineAtPoint( vPointsVec[nSplitJ], AuxPoly, vContourVec1[0], vContourVec2[0], 9 * EPS_SMALL)) { + if ( AuxPoly.ChangePolyLineStart( vPointsVec[nSplitI], 9 * EPS_SMALL) && + AuxPoly.SplitPolyLineAtPoint( vPointsVec[nSplitJ], vContourVec1[0], vContourVec2[0], 9 * EPS_SMALL)) { // Chiudo i contorni. vContourVec1[0].AddUPoint( 0, vPointsVec[nSplitI]) ; vContourVec2[0].AddUPoint( 0, vPointsVec[nSplitJ]) ; @@ -4218,7 +4218,7 @@ SplitPolyLineContour( const POLYLINEVECTOR& vContourVec, POLYLINEVECTOR& vContou const PNTULIST& InnContourList = MyPolyVecRef[nC].GetUPointList() ; for ( auto it = InnContourList.begin() ; it != InnContourList.end() ; ++ it) { if ( vContourVec1[0].GetPointNbr() < vContourVec2[0].GetPointNbr()) { - if ( IsPointInsidePolyLine( it->first, vContourVec1[0])) { + if ( vContourVec1[0].IsPointInsidePolyLine( it->first)) { vContourVec1.emplace_back( vContourVec[nC]) ; break ; } @@ -4228,7 +4228,7 @@ SplitPolyLineContour( const POLYLINEVECTOR& vContourVec, POLYLINEVECTOR& vContou } } else { - if ( IsPointInsidePolyLine( it->first, vContourVec2[0])) { + if ( vContourVec2[0].IsPointInsidePolyLine( it->first)) { vContourVec2.emplace_back( vContourVec[nC]) ; break ; } @@ -4270,7 +4270,7 @@ SurfTriMesh::RetriangulateFacetPieces( const PieceMap& NewFacet, for ( int nPart = 0 ; nPart < nPartNum ; ++ nPart) { PNTVECTOR vPt ; INTVECTOR vTr ; - if ( Triangulate().Make( PiecesVector[nPart].vPieceLoop, vPt, vTr, TrgType::TRG_DEL_QUALITY)) { + if ( Triangulate().Make( PiecesVector[nPart].vPieceLoop, vPt, vTr, TrgType::TRG_STANDARD)) { // Inserisco i nuovi triangoli for ( int n = 0 ; n < int( vTr.size()) - 2 ; n += 3) { int nNewTriaVertId[3] = { vTr[n], vTr[n + 1], vTr[n + 2]} ; @@ -4362,7 +4362,7 @@ SurfTriMesh::RetriangulateFacetPieces( const PieceMap& NewFacet, bool bContinue = SplitPolyLineContour( PiecesVector[nPart].vPieceLoop, vSubPieceLoop[0], vSubPieceLoop[1]) ; while ( bContinue) { for ( int nSub = 0 ; nSub < int( vSubPieceLoop.size()) ; ++ nSub) { - if (Triangulate().Make(vSubPieceLoop[nSub], vPt, vTr, TrgType::TRG_DEL_QUALITY)) { + if (Triangulate().Make(vSubPieceLoop[nSub], vPt, vTr, TrgType::TRG_STANDARD)) { // Inserisco i nuovi triangoli for (int n = 0; n < int(vTr.size()) - 2; n += 3) { int nNewTriaVertId[3] = { vTr[n], vTr[n + 1], vTr[n + 2] }; diff --git a/Tool.cpp b/Tool.cpp index 73a24c3..42c5420 100644 --- a/Tool.cpp +++ b/Tool.cpp @@ -29,7 +29,7 @@ using namespace std ; Tool::Tool( bool bApproxWithLines) : m_dLinTol( LIN_TOL_STD), m_dAngTolDeg( ANG_TOL_APPROX_DEG), m_nType( UNDEF), m_nCurrentNum( 0), m_dHeight( 0), m_dTipHeight( 0), m_dRadius( 0), m_dRCorner( 0), m_dTipRadius( 0), m_dRefRadius( 0), m_dCutterHeight( 0), m_dMrtChsWidth( 0), m_dMrtChsThickness( 0), - m_bApproxWithLines( bApproxWithLines) + m_bAllPartCut( true), m_bApproxWithLines( bApproxWithLines) { } diff --git a/Tool.h b/Tool.h index acc340f..1fda871 100644 --- a/Tool.h +++ b/Tool.h @@ -77,6 +77,7 @@ class Tool private : bool m_bApproxWithLines ; + bool m_bAllPartCut ; double m_dLinTol ; double m_dAngTolDeg ; std::string m_sName ; diff --git a/VolZmap.h b/VolZmap.h index f2218b1..e1ecc99 100644 --- a/VolZmap.h +++ b/VolZmap.h @@ -302,6 +302,21 @@ class VolZmap : public IVolZmap, public IGeoObjRW inline bool TestParaBBox( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtD, const Vector3d& vtA, double dLenX, double dLenY, double dLenZ, int& nStI, int& nStJ, int& nEnI, int& nEnJ) ; + + // Asportazioni superfici elementari vuote + /*bool SurfCyl_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, + double dHei, double dRad, bool bTapB, bool bTapT) ; + bool SurfCyl_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, + double dHei, double dRad, bool bTapB, bool bTapT) ;*/ + bool SurfCyl_ZMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, + double dHei, double dRad, bool bOuterCutter, bool bTapB, bool bTapT) ; + bool SurfCyl_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, + const Vector3d& vtToolDir, double dHei, double dRad, bool bTapB, bool bTapT) ; + bool SurfConus_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, double dHei, double dMaxRad, double dMinRad, + const Vector3d& vtArcNormMaxR, const Vector3d& vtArcNormMinR) ; + bool SurfConus_ZMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, double dHei, double dMaxRad, double dMinRad, + const Vector3d& vtArcNormMaxR, const Vector3d& vtArcNormMinR) ; + // Intersezioni bool IntersLineBox( const Point3d& ptP, const Vector3d& vtV, const Point3d& ptMin, const Point3d& ptMax) const ; bool IntersLineBox( const Point3d& ptP, const Vector3d& vtV, const Point3d& ptMin, const Point3d& ptMax, @@ -331,6 +346,30 @@ class VolZmap : public IVolZmap, public IGeoObjRW const Frame3d& frTruncPyramFrame, double dSegMin, double dSegMax, double dHeight, Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const ; bool TestIntersPlaneZmapBBox( const Plane3d& plPlane) const ; + // Intersezioni 2 + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /*public:*/ + int IntersLineParallelogram( const Point3d& ptLineP, const Vector3d& vtLineDir, + const Point3d& ptParOrig, const Vector3d& vtSeg1, const Vector3d& vtSeg2, + bool bExtNorm, Point3d& ptInt, Vector3d& vtN) const ; + int IntersLineCylinderCuttedByPlanes( const Point3d& ptLineP, const Vector3d& vtLineDir, + const Point3d& ptBaseCen, const Vector3d& vtAx, double dRad, double dH, bool bInOut, + const std::vector& vPlanesVec, + Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const ; + int IntersLineCircSweptSurfCuttedByPlanes( const Point3d& ptLineP, const Vector3d& vtLineDir, + const Point3d& ptCen, const Vector3d& vtAx, double dRad, const Vector3d& vtSweptVec, bool bInOut, + const std::vector& vPlanesVec, + Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const ; + int IntersLineConeCuttedByPlanes( const Point3d& ptLineP, const Vector3d& vtLineDir, + const Point3d& ptVert, const Vector3d& vtAx, double dRad, double dH, bool bInOut, + const std::vector& vPlanesVec, + Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const ; + int IntersLineSphereCuttedByPlanes( const Point3d& ptLineP, const Vector3d& vtLineD, + const Point3d& ptCen, double dRad, bool bInOut, + const std::vector& vPlanesVec, + Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const ; + /*private:*/ + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Voxel: esistenza e passaggio da N a ijk per i voxel bool IsValidVoxel( int nN) const ; bool IsValidVoxel( int nI, int nJ, int nK) const ; diff --git a/VolZmapVolume.cpp b/VolZmapVolume.cpp index aa11d6d..70bf9ab 100644 --- a/VolZmapVolume.cpp +++ b/VolZmapVolume.cpp @@ -20,6 +20,9 @@ #include "GeoConst.h" #include "/EgtDev/Include/EgtNumUtils.h" #include "/EgtDev/Include/EGkStringUtils3d.h" +#include "/EgtDev/Include/EGkIntersLinePlane.h" +#include "/EgtDev/Include/EGkIntersLineSphere.h" +#include "/EgtDev/Include/ENkPolynomialRoots.h" #include "/EgtDev/Include/EgtPerfCounter.h" #include @@ -4658,6 +4661,1139 @@ VolZmap::CompBall_Milling( int nGrid, const Point3d& ptLs, const Point3d& ptLe, return true ; } + +// Superfici laterali + +// Superfici ausiliarie + +//---------------------------------------------------------------------------- +// Calcola l'intersezione di una retta, descritta da punto iniziale ptLineP e versore della +// direzione vtLineDir, e la superficie definita da un parallelogramma nello spazio, descritto da un punto +// ptParOrig e i vettori che da esso spiccano. +// Se bExtNorm è true la normale alla superficie ha lo stesso verso di vtSeg2 ^ vtSeg1, altrimenti +// quello opposto. +int +VolZmap::IntersLineParallelogram( const Point3d& ptLineP, const Vector3d& vtLineDir, + const Point3d& ptParOrig, const Vector3d& vtSeg1, const Vector3d& vtSeg2, + bool bExtNorm, Point3d& ptInt, Vector3d& vtN) const +{ + // Definisco il versore normale al piano e il piano stesso. + Plane3d plMyPlane ; + Vector3d vtPlaneN = vtSeg2 ^ vtSeg1 ; + if ( ! vtPlaneN.Normalize() || ! plMyPlane.Set( ptParOrig, vtPlaneN)) + return 0 ; + + // Intersezione retta piano + int nIntType = IntersLinePlane( ptLineP, vtLineDir, 1000, plMyPlane, ptInt, false) ; + if ( nIntType == ILPT_YES /* || nIntType == ILPT_START || nIntType == ILPT_END*/) { + // Creo un sistema di riferimento per stabilire se l'intersezione avviene in un + // punto del piano interno alla superficie o meno. + Vector3d vtUnit2 = vtSeg2 ; + double dLen2 = vtUnit2.Len() ; + vtUnit2 /= dLen2 ; + Vector3d vtPerpToUnit2 = vtPlaneN ^ vtUnit2 ; + double dSegProjPerpLen1 = vtSeg1 * vtPerpToUnit2 ; + double dSegProjLongLen1 = vtSeg1 * vtUnit2 ; + Vector3d vtIntV = ptInt - ptParOrig ; + double dIntPerp = vtIntV * vtPerpToUnit2 ; + double dIntLong = vtIntV * vtUnit2 ; + if ( dIntPerp > 0 && dIntPerp < dSegProjPerpLen1 && + dIntLong * dSegProjPerpLen1 > dIntPerp * dSegProjLongLen1 && + ( dIntLong - dLen2) * dSegProjPerpLen1 < dIntPerp * dSegProjLongLen1) { + vtN = bExtNorm ? - vtPlaneN : vtPlaneN ; + return 1 ; + } + // Oppure crei poliline e chiami la funzione per testare se + // un punto è interno o meno a una polyline chiusa e piana. + } + return 0 ; +} + +//---------------------------------------------------------------------------- +// Calcola le intersezioni di una retta con la superficie ottenuta dal taglio di un cilindro, inteso come la sola superficie +// laterale, con un numero arbitrario di piani. +// Nel taglio del cilindro si esclude la parte che sta nel semispazio verso cui punta la normale al piano. +// Il cilindro è descritto dal centro della base ptBaseCen, dal versore vtAx del suo asse di simmetria, dal raggio dRad, +// dall'altezza dH e da un flag bInOut che indica se il campo delle normali al cilindro volge verso l'asse di simmetria o meno. +// I piani devono essere espressi nello stesso sistema di riferimento in cui sono espressi i punti e i vettori che descrivono +// retta e cilindro. +// Le soluzioni verranno espresse nel medesimo sistema di riferimeno. I versori normali vtN1 e vtN2 saranno opposti alla normale +// della superficie nei punti ptInt1 e ptInt2 rispettivamente in cui avviene l'intersezione. +// La funzione restituisce 0 in caso di errore o assenza di soluzioni, altrimenti il numero di soluzioni trovate (al massimo 2). +int +VolZmap::IntersLineCylinderCuttedByPlanes( const Point3d& ptLineP, const Vector3d& vtLineDir, + const Point3d& ptBaseCen, const Vector3d& vtAx, double dRad, double dH, bool bInOut, + const vector& vPlanesVec, + Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const +{ + // Definisco il sistema di riferimento S; se non è possibile, c'è un errore. + Frame3d frFrameS ; + if ( ! frFrameS.Set( ptBaseCen, vtAx)) + return 0 ; + + // Se l'altezza è negativa, cambio sistema di riferimento. + if ( dH < 0) { + frFrameS.Translate( dH * frFrameS.VersZ()) ; + dH *= - 1 ; + } + + // Porto la linea nel riferimento del cilindro + Point3d ptP = ptLineP ; ptP.ToLoc( frFrameS) ; + Vector3d vtV = vtLineDir ; vtV.ToLoc( frFrameS) ; + + // Se la retta è parallela all'asse, non ci sono intersezioni. + if ( vtV.SqLenXY() < EPS_ZERO * EPS_ZERO) + return 0 ; + + // Determino le intersezioni con la superficie cilindrica + DBLVECTOR vdCoef( 3) ; + double dSqRad = dRad * dRad ; + vdCoef[0] = ptP.x * ptP.x + ptP.y * ptP.y - dSqRad ; + vdCoef[1] = 2 * ( ptP.x * vtV.x + ptP.y * vtV.y) ; + vdCoef[2] = vtV.x * vtV.x + vtV.y * vtV.y ; + DBLVECTOR vdRoots ; + int nRoot = PolynomialRoots( 2, vdCoef, vdRoots) ; + + // Se non ho trovato soluzioni, ho terminato. + if ( nRoot == 0) + return nRoot ; + + // Punti di intersezione e versori alla superficie in corrispondenza di essi + ptInt1 = ptP + vdRoots[0] * vtV ; + vtN1.Set( ptInt1.x, ptInt1.y, 0) ; vtN1.Normalize() ; + if ( nRoot == 2) { + ptInt2 = ptP + vdRoots[1] * vtV ; + vtN2.Set( ptInt2.x, ptInt2.y, 0) ; vtN2.Normalize() ; + } + if ( ! bInOut) { + vtN1 *= - 1 ; + vtN2 *= - 1 ; + } + + // Elimino le soluzioni cha danno intersezioni fuori dai limiti in Z. + if ( ptInt1.z < 0 || ptInt1.z > dH) { + ptInt1 = ptInt2 ; + vtN1 = vtN2 ; + -- nRoot ; + } + if ( nRoot > 0 && ( ptInt2.z < 0 || ptInt2.z > dH)) { + -- nRoot ; + } + + // Esprimo punti e vettori nel sistema in cui è immerso S. + if ( nRoot > 0) { + ptInt1.ToGlob( frFrameS) ; + vtN1.ToGlob( frFrameS) ; + if ( nRoot == 2) { + ptInt2.ToGlob( frFrameS) ; + vtN2.ToGlob( frFrameS) ; + } + } + + // Elimino le intersezioni sul cono che non fanno parte della superficie. + for ( int n = 0 ; n < int( vPlanesVec.size()) && nRoot > 0 ; ++ n) { + if ( DistPointPlane( ptInt1, vPlanesVec[n]) > 0) { + ptInt1 = ptInt2 ; + vtN1 = vtN2 ; + -- nRoot ; + } + if ( nRoot > 0 && DistPointPlane( ptInt2, vPlanesVec[n]) > 0) + -- nRoot ; + } + + return nRoot ; +} + +//---------------------------------------------------------------------------- +// Calcola le intersezioni di una retta con una superficie di traslazione di una circonferenza di un vettore vtSweptVec +// tagliata da un numero arbitrario di piani. +// Nel taglio della superficie di traslazione si esclude la parte che sta nel semispazio verso cui punta la normale al piano. +// La circonferenza è descritta dal centro ptCen, dal versore vtAx del suo asse di simmetria rotazionale e dal raggio dRad. +// Il flag bInOut indica se la proiezione sul piano della circonferenza del campo delle normail alla superficie volge verso il +// centro di quest'ultima o meno. +// I piani devono essere espressi nello stesso sistema di riferimento in cui sono espressi i punti e i vettori che descrivono +// retta e la superficie di traslazione. +// Le soluzioni verranno espresse nel medesimo sistema di riferimeno. I versori normali vtN1 e vtN2 saranno opposti alla normale +// della superficie nei punti ptInt1 e ptInt2 rispettivamente in cui avviene l'intersezione. +// La funzione restituisce 0 in caso di errore o assenza di soluzioni, altrimenti il numero di soluzioni trovate (al massimo 2). +int +VolZmap::IntersLineCircSweptSurfCuttedByPlanes( const Point3d& ptLineP, const Vector3d& vtLineDir, + const Point3d& ptCen, const Vector3d& vtAx, double dRad, const Vector3d& vtSweptVec, bool bInOut, + const vector& vPlanesVec, + Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const +{ + // Studio delle simmetrie + Point3d ptMyCen = ptCen ; + Vector3d vtMySweptVec = vtSweptVec ; + if ( vtSweptVec * vtAx < 0) { + ptMyCen += vtSweptVec ; + vtMySweptVec *= - 1 ; + } + + // Calcolo le lunghezze del moto nella direzione dell'asse di simmetria rotazionale e + // in quella ortogonale. + double dLongVecLen = vtMySweptVec * vtAx ; + double dOrtVecLen = sqrt( max( vtMySweptVec.SqLen() - dLongVecLen * dLongVecLen, 0.)) ; + + // Definisco il sistema di riferimento S; se non è possibile, c'è un errore. + Vector3d vtV1 = vtMySweptVec - dLongVecLen * vtAx ; + Frame3d frFrameS ; + if ( ! frFrameS.Set( ptMyCen, vtV1, vtAx ^ vtV1, vtAx)) + return 0 ; + + // Se la suerficie degenera in un piano, non bisogna tagliare + if ( abs( dLongVecLen) < EPS_SMALL) + return 0 ; + + // Porto la linea nel riferimento S + Point3d ptP = ptLineP ; ptP.ToLoc( frFrameS) ; + Vector3d vtV = vtLineDir ; vtV.ToLoc( frFrameS) ; + + // Asse cilindro ellittico + Vector3d vtSurfAx( dOrtVecLen, 0, dLongVecLen) ; + vtSurfAx.Normalize() ; + + // Retta parallela a quella del moto + if ( AreSameOrOppositeVectorExact( vtV, vtSurfAx)) + return 0 ; + + // Quadrato del raggio, coefficiente angolare della retta di movimento nel + // piano ZX del sistema di riferimento del movimento e suo quadrato + double dSqRad = dRad * dRad ; + double dObCoef = dLongVecLen / dOrtVecLen ; + double dSqCoef = dObCoef * dObCoef ; + // Setto i coeficienti dell'equazione d'intersezione della + // retta con la superficie di traslazione della circonferenza. + DBLVECTOR vdCoef(3) ; + vdCoef[0] = dSqCoef * ( ptP.x * ptP.x + ptP.y * ptP.y) + ptP.z * ptP.z + - 2 * dObCoef * ptP.x * ptP.z - dSqCoef * dSqRad ; + vdCoef[1] = 2 * dSqCoef * ( ptP.x * vtV.x + ptP.y * vtV.y) + 2 * ptP.z * vtV.z - 2 * dObCoef * ( ptP.x * vtV.z + ptP.z * vtV.x) ; + vdCoef[2] = dSqCoef * ( vtV.x * vtV.x + vtV.y * vtV.y) + vtV.z * vtV.z - 2 * dObCoef * vtV.x * vtV.z ; + // Numero di soluzioni + DBLVECTOR vdRoots ; + int nRoot = PolynomialRoots( 2, vdCoef, vdRoots) ; + + + dObCoef = dLongVecLen / dOrtVecLen ; + dSqCoef = dObCoef * dObCoef ; + + // L'equazione ammette o due soluzioni (eventualmente + // coincidenti) oppure nessuna o infinite se la la retta + // appartiene alla superficie + + // Se numero di soluzioni diverso da due le eventuali intersezioni sono già state trovate + if ( nRoot != 2) + return 0 ; + + // Punti di intersezione e versori alla superficie in corrispondenza di essi + ptInt1 = ptP + vdRoots[0] * vtV ; + ptInt2 = ptP + vdRoots[1] * vtV ; + vtN1.Set( dSqCoef * ptInt1.x - dObCoef * ptInt1.z, dSqCoef * ptInt1.y, ptInt1.z - dObCoef * ptInt1.x) ; + vtN1.Normalize() ; + vtN2.Set( dSqCoef * ptInt2.x - dObCoef * ptInt2.z, dSqCoef * ptInt2.y, ptInt2.z - dObCoef * ptInt2.x) ; + vtN2.Normalize() ; + if ( ! bInOut) { + vtN1 *= - 1 ; + vtN2 *= - 1 ; + } + + // Elimino le soluzioni cha non stanno sulla superficie di traslazione, ovvero le intersezioni fuori dai limiti in Z. + if ( ptInt1.z < 0 || ptInt1.z > dLongVecLen) { + ptInt1 = ptInt2 ; + vtN1 = vtN2 ; + -- nRoot ; + } + if ( ptInt2.z < 0 || ptInt2.z > dLongVecLen) { + -- nRoot ; + } + + // Esprimo punti e vettori nel sistema in cui è immerso S. + if ( nRoot > 0) { + ptInt1.ToGlob( frFrameS) ; + vtN1.ToGlob( frFrameS) ; + if ( nRoot == 2) { + ptInt2.ToGlob( frFrameS) ; + vtN2.ToGlob( frFrameS) ; + } + } + + // Escludo le soluzioni che non stanno dalla parte ammissibile rispetto al piano. + for ( int n = 0 ; n < int( vPlanesVec.size()) && nRoot > 0 ; ++ n) { + if ( DistPointPlane( ptInt1, vPlanesVec[n]) > 0) { + ptInt1 = ptInt2 ; + vtN1 = vtN2 ; + -- nRoot ; + } + if ( nRoot > 0 && DistPointPlane( ptInt2, vPlanesVec[n]) > 0) + -- nRoot ; + } + + return nRoot ; +} + +//---------------------------------------------------------------------------- +// Calcola le intersezioni di una retta con la superficie ottenuta dal taglio di un cono, inteso come la sola superficie +// laterale, con un numero arbitrario di piani. +// Nel taglio del cono si esclude la parte che sta nel semispazio verso cui punta la normale al piano. +// Il cono è descritto dal vertice ptVert, dal versore vtAx del suo asse di simmetria, dal raggio dRad, dall'altezza dH +// e da un flag bInOut che indica se il campo delle normali al cono volge verso l'asse di simmetria o meno. +// I piani devono essere espressi nello stesso sistema di riferimento in cui sono espressi i punti e i vettori che descrivono +// retta e cono. +// Le soluzioni verranno espresse nel medesimo sistema di riferimeno. I versori normali vtN1 e vtN2 saranno opposti alla normale +// della superficie nei punti ptInt1 e ptInt2 rispettivamente in cui avviene l'intersezione. +// La funzione restituisce 0 in caso di errore o assenza di soluzioni, altrimenti il numero di soluzioni trovate (al massimo 2). +int +VolZmap::IntersLineConeCuttedByPlanes( const Point3d& ptLineP, const Vector3d& vtLineDir, + const Point3d& ptVert, const Vector3d& vtAx, double dRad, double dH, bool bInOut, + const vector& vPlanesVec, + Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const +{ + // Definisco il sistema di riferimento S; se non è possibile, c'è un errore. + Frame3d frFrameS ; + if ( ! frFrameS.Set( ptVert, vtAx)) + return 0 ; + + // Porto la linea nel riferimento del cilindro + Point3d ptP = ptLineP ; ptP.ToLoc( frFrameS) ; + Vector3d vtV = vtLineDir ; vtV.ToLoc( frFrameS) ; + + // Tangente dell'angolo di semi-apertura + double dTan = dRad / dH ; + + // Determino le intersezioni con la superficie laterale del cono + DBLVECTOR vdCoef( 3) ; + double dSqTan = dTan * dTan ; + vdCoef[0] = dSqTan * ptP.z * ptP.z - ptP.x * ptP.x - ptP.y * ptP.y ; + vdCoef[1] = 2 * ( dSqTan * ptP.z * vtV.z - ptP.x * vtV.x - ptP.y * vtV.y) ; + vdCoef[2] = dSqTan * vtV.z * vtV.z - vtV.x * vtV.x - vtV.y * vtV.y ; + DBLVECTOR vdRoots ; + int nRoot = PolynomialRoots( 2, vdCoef, vdRoots) ; + + // Se non ho trovato soluzioni, ho terminato. + if ( nRoot == 0) + return nRoot ; + + // Intersezioni + ptInt1 = ptP + vdRoots[0] * vtV ; + vtN1 = Vector3d( ptInt1.x, ptInt1.y, - dSqTan * ptInt1.z) ; + vtN1.Normalize() ; + if ( nRoot == 2) { + ptInt2 = ptP + vdRoots[1] * vtV ; + vtN2 = Vector3d( ptInt2.x, ptInt2.y, - dSqTan * ptInt2.z) ; + vtN2.Normalize() ; + } + if ( ! bInOut) { + vtN1 *= - 1 ; + vtN2 *= - 1 ; + } + + // Elimino le intersezioni che non fanno parte del cono. + if ( ptInt1.z < 0 || ptInt1.z > dH) { + ptInt1 = ptInt2 ; + vtN1 = vtN2 ; + -- nRoot ; + } + if ( nRoot > 0 && ( ptInt2.z < 0 || ptInt2.z > dH)) + -- nRoot ; + + // Esprimo punti e vettori nel sistema in cui è immerso S. + if ( nRoot > 0) { + ptInt1.ToGlob( frFrameS) ; + vtN1.ToGlob( frFrameS) ; + if ( nRoot == 2) { + ptInt2.ToGlob( frFrameS) ; + vtN2.ToGlob( frFrameS) ; + } + } + + // Elimino le intersezioni sul cono che non fanno parte della superficie. + for ( int n = 0 ; n < int( vPlanesVec.size()) && nRoot > 0 ; ++ n) { + if ( DistPointPlane( ptInt1, vPlanesVec[n]) > 0) { + ptInt1 = ptInt2 ; + vtN1 = vtN2 ; + -- nRoot ; + } + if ( nRoot > 0 && DistPointPlane( ptInt2, vPlanesVec[n]) > 0) + -- nRoot ; + } + + return nRoot ; +} + +//---------------------------------------------------------------------------- +// Calcola le intersezioni di una retta con una superficie sferica tagliata da un numero arbitrario di piani. +// Nel taglio della sfera si esclude la parte che sta nel semispazio verso cui punta la normale al piano. +// Il cono è descritto dal vertice ptVert, dal versore vtAx del suo asse di simmetria, dal raggio dRad, dall'altezza dH +// e da un flag bInOut che indica se il campo delle normali volge verso l'interno della sfera o meno. +// I piani devono essere espressi nello stesso sistema di riferimento in cui sono espressi i punti e i vettori che descrivono +// retta e cono. +// Le soluzioni verranno espresse nel medesimo sistema di riferimeno. I versori normali vtN1 e vtN2 saranno opposti alla normale +// della superficie nei punti ptInt1 e ptInt2 rispettivamente in cui avviene l'intersezione. +// La funzione restituisce 0 in caso di errore o assenza di soluzioni, altrimenti il numero di soluzioni trovate (al massimo 2). +int +VolZmap::IntersLineSphereCuttedByPlanes( const Point3d& ptLineP, const Vector3d& vtLineD, + const Point3d& ptCen, double dRad, bool bInOut, + const vector& vPlanesVec, + Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const +{ + // Intersezione fra retta e sfera + int nSol = IntersLineSphere( ptLineP, vtLineD, ptCen, dRad, ptInt1, ptInt2) ; + + // Non ci sono soluzioni. + if ( nSol == ILST_NO) + return nSol ; + + // Calcolo le normali + vtN1 = ( ptInt1 - ptCen) ; vtN1.Normalize() ; + vtN2 = ( ptInt2 - ptCen) ; vtN2.Normalize() ; + if ( ! bInOut) { + vtN1 *= - 1 ; + vtN2 *= - 1 ; + } + + + // Escludo le soluzioni fuori dalla parte ammissibile. + for ( int n = 0 ; n < int( vPlanesVec.size()) && nSol != 0 ; ++ n) { + if ( DistPointPlane( ptInt1, vPlanesVec[n]) > 0) { + ptInt1 = ptInt2 ; + vtN1 = vtN2 ; + -- nSol ; + } + if ( nSol > 0 && DistPointPlane( ptInt2, vPlanesVec[n]) > 0) + -- nSol ; + } + + return nSol ; +} + + +// Cilindro +//---------------------------------------------------------------------------- +//bool +//VolZmap::SurfCyl_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, +// double dHei, double dRad, bool bTapB, bool bTapT) +//{ +// return true ; +//} +// +////---------------------------------------------------------------------------- +//bool +//VolZmap::SurfCyl_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, +// double dHei, double dRad, bool bTapB, bool bTapT) +//{ +// return true ; +//} + +//---------------------------------------------------------------------------- +bool +VolZmap::SurfCyl_ZMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, + double dHei, double dRad, bool bOuterCutter, bool bTapB, bool bTapT) +{ + // Verifica sull'interferenza utensile Zmap + int nStartI, nStartJ, nEndI, nEndJ ; + if ( ! TestCompoBBox( nGrid, ptS, ptE, vtToolDir, dRad, dRad, dHei, nStartI, nStartJ, nEndI, nEndJ)) + return true ; + + // Vettore spostamento + Vector3d vtDisp = ptE - ptS ; + + // Dimensioni del moto nella direzione utensile e ortogonale e quote iniziali e finali + double dDispZ = vtDisp * vtToolDir ; + double dDispXY = sqrt( max( vtDisp.SqLen() - dDispZ * dDispZ, 0.)) ; + double dStartTopZ = ptS.z ; + double dStartBotZ = ( ptS - dHei * vtToolDir).z ; + + // Sistema di riferimento del moto + Vector3d vtV3 = vtToolDir ; + Vector3d vtV1 = vtDisp - dDispZ * vtV3 ; vtV1.Normalize() ; + Vector3d vtV2 = vtV3 ^ vtV1 ; + Point3d ptSxy( ptS.x, ptS.y, 0) ; + + // Ciclo sui dexel. + for ( int i = nStartI ; i <= nEndI ; ++ i) { + for ( int j = nStartJ ; j <= nEndJ ; ++ j) { + Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ; + double dProj1 = ( ptC - ptSxy) * vtV1 ; + double dProj2 = ( ptC - ptSxy) * vtV2 ; + double dCirc1 = ( bOuterCutter ? 1 : - 1) * sqrt( max( dRad * dRad - dProj2 * dProj2, 0.)) ; + if ( abs( dProj2) < dRad && dProj1 > dCirc1 && dProj1 < dDispXY + dCirc1) { + // Quote inferiore e superiore rispetto alla direzione del versore utensile + double dInfZ = dStartBotZ + ( dProj1 - dCirc1) * dDispZ / dDispXY ; + double dSupZ = dStartTopZ + ( dProj1 - dCirc1) * dDispZ / dDispXY ; + // Calcolo dei versori normali associati + Vector3d vtRad = dCirc1 * vtV1 + dProj2 * vtV2 ; + Vector3d vtTan( - vtRad.y, vtRad.x, 0) ; + Vector3d vtCross = vtTan ^ vtDisp ; + Vector3d vtSup = ( vtCross * vtToolDir > 0 ? - vtCross : vtCross) ; + vtSup.Normalize() ; + Vector3d vtInf = - vtSup ; + // Quote inferiore e superiore rispetto al sistema griglia e versori normali associati + double dMin, dMax ; + Vector3d vtMax, vtMin ; + if ( vtToolDir.z > 0) { + dMin = dInfZ ; + dMax = dSupZ ; + vtMax = vtSup ; + vtMin = vtInf ; + } + else { + dMin = dSupZ ; + dMax = dInfZ ; + vtMax = vtInf ; + vtMin = vtSup ; + } + // Taglio dei dexel + SubtractIntervals( nGrid, i, j, dMin, dMax, vtMin, vtMax) ; + } + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::SurfCyl_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, + const Vector3d& vtToolDir, double dHei, double dRad, bool bOuterCutter, bool bTapB, bool bTapT) +{ + // Verifica sull'interferenza utensile Zmap + int nStartI, nStartJ, nEndI, nEndJ ; + if ( ! TestCompoBBox( nGrid, ptS, ptE, vtToolDir, dRad, dRad, dHei, nStartI, nStartJ, nEndI, nEndJ)) + return true ; + + // Vettore spostamento + Vector3d vtDisp = ptE - ptS ; + + // Versore della componente del moto ortogonale all'asse dell'utensile + double dDispZ = vtDisp * vtToolDir ; + Vector3d vtOrtDisp = vtDisp - dDispZ * vtToolDir ; + vtOrtDisp.Normalize() ; + + // Definisco i piani utilizzati per tagliare le superfici elementari. + // Piano per cilindro in posizione iniziale + vector vCutCylPlaneVecSt ; + vCutCylPlaneVecSt.emplace_back() ; + vCutCylPlaneVecSt.back().Set( ptS, ( bOuterCutter ? - 1 : 1) * vtOrtDisp) ; + // Piano per cilindro in posizione finale + vector vCutCylPlaneVecEn ; + vCutCylPlaneVecEn.emplace_back() ; + vCutCylPlaneVecEn.back().Set( ptE, ( bOuterCutter ? - 1 : 1) * vtOrtDisp) ; + // Piani per cilindro ellittico superiore + vector vCutEllipCylPlaneVecUp ; + if ( dDispZ > 0) { + Vector3d vtDispDir = vtDisp ; + vtDispDir.Normalize() ; + Vector3d vtRadial = vtToolDir ^ vtDisp ; + vtRadial.Normalize() ; + vCutEllipCylPlaneVecUp.emplace_back() ; + vCutEllipCylPlaneVecUp.back().Set( ptS, ( bOuterCutter ? 1 : - 1) * vtDispDir ^ vtRadial) ; + } + else { + Vector3d vtDispDir = vtDisp ; + vtDispDir.Normalize() ; + Vector3d vtRadial = vtToolDir ^ vtDisp ; + vtRadial.Normalize() ; + vCutEllipCylPlaneVecUp.emplace_back() ; + vCutEllipCylPlaneVecUp.back().Set( ptS, ( bOuterCutter ? 1 : - 1) * vtRadial ^ vtDispDir) ; + } + // Piani per cilindro ellittico inferiore + vector vCutEllipCylPlaneVecDw ; + if ( dDispZ > 0) { + Vector3d vtDispDir = vtDisp ; + vtDispDir.Normalize() ; + Vector3d vtRadial = vtToolDir ^ vtDisp ; + vtRadial.Normalize() ; + vCutEllipCylPlaneVecDw.emplace_back() ; + vCutEllipCylPlaneVecDw.back().Set( ptS - dHei * vtToolDir, ( bOuterCutter ? 1 : - 1) * vtDispDir ^ vtRadial) ; + } + else { + Vector3d vtDispDir = vtDisp ; + vtDispDir.Normalize() ; + Vector3d vtRadial = vtToolDir ^ vtDisp ; + vtRadial.Normalize() ; + vCutEllipCylPlaneVecDw.emplace_back() ; + vCutEllipCylPlaneVecDw.back().Set( ptS - dHei * vtToolDir, ( bOuterCutter ? 1 : - 1) * vtRadial ^ vtDispDir) ; + } + + // Deduzione dei punti per la definizione dei piani laterali + Point3d ptPlanePlus = ptS - dHei * vtToolDir + dRad * ( vtToolDir ^ vtOrtDisp) ; + Point3d ptPlaneMinus = ptS - dHei * vtToolDir - dRad * ( vtToolDir ^ vtOrtDisp) ; + + for ( int i = nStartI ; i <= nEndI ; ++ i) { + for ( int j = nStartJ ; j <= nEndJ ; ++ j) { + + Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ; + + vector> vParAndNormIntersVec ; + Point3d ptInt1, ptInt2 ; + Vector3d vtN1, vtN2 ; + + // Intersezione con cilindro in posizione iniziale + int nIntNum = IntersLineCylinderCuttedByPlanes( ptC, Z_AX, ptS, vtToolDir, dRad, - dHei, false, vCutCylPlaneVecSt, + ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con cilindro in posizione finale + nIntNum = IntersLineCylinderCuttedByPlanes( ptC, Z_AX, ptE, vtToolDir, dRad, - dHei, false, vCutCylPlaneVecEn, + ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con cilindro ellittico superiore + nIntNum = IntersLineCircSweptSurfCuttedByPlanes( ptC, Z_AX, ptS, vtToolDir, dRad, vtDisp, true, vCutEllipCylPlaneVecUp, + ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con cilindro ellittico inferiore + nIntNum = IntersLineCircSweptSurfCuttedByPlanes( ptC, Z_AX, ptS - dHei * vtToolDir, vtToolDir, dRad, vtDisp, false, vCutEllipCylPlaneVecDw, + ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Piano + (con normale + vtToolDir ^ vtOrtDisp) + nIntNum = IntersLineParallelogram( ptC, Z_AX, ptPlanePlus, dHei * vtToolDir, vtDisp, + true, ptInt1, vtN1) ; + if ( nIntNum == 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + } + + // Piano - (con normale - vtToolDir ^ vtOrtDisp) + nIntNum = IntersLineParallelogram( ptC, Z_AX, ptPlaneMinus, dHei * vtToolDir, vtDisp, + false, ptInt1, vtN1) ; + if ( nIntNum == 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + } + + // Riordino le intersezioni in funzione del parametro lungo la retta in corrispondenza del quale occorrono. + sort( vParAndNormIntersVec.begin(), vParAndNormIntersVec.end(), [] ( pair Int1, pair Int2) + { return Int1.first < Int2.first ; }) ; + + // Sottraggo gli intervalli + double dMyEps = EPS_ZERO ; + for ( int nI = 0 ; nI < int( vParAndNormIntersVec.size()) - 1 ; ++ nI) { + if ( vParAndNormIntersVec[nI].second.z < - dMyEps && vParAndNormIntersVec[nI+1].second.z > dMyEps) { + SubtractIntervals( nGrid, i, j, vParAndNormIntersVec[nI].first, vParAndNormIntersVec[nI+1].first, + vParAndNormIntersVec[nI].second, vParAndNormIntersVec[nI+1].second) ; + } + } + } + } + + return true ; +} + +// Cono +//---------------------------------------------------------------------------- +bool +VolZmap::SurfConus_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, double dHei, double dMaxRad, double dMinRad, + const Vector3d& vtArcNormMaxR, const Vector3d& vtArcNormMinR) +{ + // Verifica sull'interferenza con lo Zmap + int nStartI, nStartJ, nEndI, nEndJ ; + if ( ! TestCompoBBox( nGrid, ptS, ptE, vtToolDir, dMaxRad, dMinRad, dHei, nStartI, nStartJ, nEndI, nEndJ)) + return true ; + + // Raggi di sicurezza per evitare di tagliare i dexel a filo del bordo dela regione interessata dal taglio. + double dSqSafeMinRad = dMinRad * dMinRad + 2 * dMinRad * EPS_SMALL ; + double dSqSafeMaxRad = dMaxRad * dMaxRad - 2 * dMaxRad * EPS_SMALL ; + + //// Ciclo sui punti + //for ( int i = nStartI ; i <= nEndI ; ++ i) { + // for ( int j = nStartJ ; j <= nEndJ ; ++ j) { + // + // double dX = ( i + 0.5) * m_dStep - ptS.x ; + // double dY = ( j + 0.5) * m_dStep - ptS.y ; + // double dR = dX * dX + dY * dY ; + // + // if ( dR < dSqSafeMinRad || dR > dSqSafeMaxRad) + // continue ; + // + // if ( vtToolDir.z > 0) { + // double dr = sqrt( dR) ; + // // Quote Z + // double dMinZ = min( ptS.z, ptE.z) - dHei + ( dr - dMinRad) * dHei / ( dMaxRad - dMinRad) ; + // double dMaxZ = max( ptS.z, ptE.z) - dHei + ( dr - dMinRad) * dHei / ( dMaxRad - dMinRad) ; + // // Normali + // // distinguere vtMove * vtToolDir < 0 e vtMove * vtToolDir > 0 + // } + // else { + // double dr = sqrt( dR) ; + // // Quote Z + // double dMinZ = min( ptS.z, ptE.z) + dHei - ( dr - dMinRad) * dHei / ( dMaxRad - dMinRad) ; + // double dMaxZ = max( ptS.z, ptE.z) + dHei - ( dr - dMinRad) * dHei / ( dMaxRad - dMinRad) ; + // // Normali + // // distinguere vtMove * vtToolDir < 0 e vtMove * vtToolDir > 0 + // } + // } + //} + + return true ; +} + +//---------------------------------------------------------------------------- +/*bool +VolZmap::SurfConus_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, + double dHei, double dMaxRad, double dMinRad, bool bTapB, bool bTapT, + const Vector3d& vtArcNormMaxR, const Vector3d& vtArcNormMinR) +{ + int nStartI, nStartJ, nEndI, nEndJ ; + if ( ! TestCompoBBox( nGrid, ptS, ptE, vtToolDir, dMaxRad, dMinRad, dHei, nStartI, nStartJ, nEndI, nEndJ)) + return true ; + + // Vettore spostamento + Vector3d vtDisp = ptE - ptS ; + + // Vertici cono iniziale e finale + double dDeltaHei = ( dMinRad * dHei) / ( dMaxRad - dMinRad) ; + Point3d ptVs = ptS - ( dHei + dDeltaHei) * vtToolDir ; + Point3d ptVe = ptE - ( dHei + dDeltaHei) * vtToolDir ; + + // Piani per tagliare le superfici elementari. + vector vCutConePlaneVecSt ; vCutConePlaneVecSt.emplace_back() ; + vCutConePlaneVecSt.back().Set( ptS - dHei * vtToolDir, - vtToolDir) ; + vector vCutConePlaneVecEn ; vCutConePlaneVecEn.emplace_back() ; + vCutConePlaneVecEn.back().Set( ptE - dHei * vtToolDir, - vtToolDir) ; + vector vEmptyPlaneVec ; + + // Ciclo sui punti + for ( int i = nStartI ; i < nEndI ; ++ i) { + for ( int j = nStartJ ; j < nEndJ ; ++ j) { + + Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ; + + vector> vParAndNormIntersVec ; + Point3d ptInt1, ptInt2 ; + Vector3d vtN1, vtN2 ; + + // Intersezione con il cono in posizione iniziale + int nIntNum = IntersLineConeCuttedByPlanes( ptC, Z_AX, ptS, vtToolDir, dMaxRad, dHei, true, + vCutConePlaneVecSt, ptInt1, vtN1, ptInt2, vtN2); + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con il cono in posizione finale + nIntNum = IntersLineConeCuttedByPlanes( ptC, Z_AX, ptE, vtToolDir, dMaxRad, dHei, true, + vCutConePlaneVecEn, ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con il cilindro esterno + nIntNum = IntersLineCylinderCuttedByPlanes( ptC, Z_AX, ptS, vtDisp * vtAx, dMaxRad, dHei, true, + vEmptyPlaneVec, ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con il cilindro interno + nIntNum = IntersLineCylinderCuttedByPlanes( ptC, Z_AX, ptS - dHei * vtToolDir, vtToolDir, dMinRad, dHei, true, + vEmptyPlaneVec, ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Riordino le intersezioni in funzione del parametro lungo la retta in corrispondenza del quale occorrono. + sort( vParAndNormIntersVec.begin(), vParAndNormIntersVec.end(), [] ( pair Int1, pair Int2) + { return Int1.first < Int2.first ; }) ; + + // Sottraggo gli intervalli + double dMyEps = EPS_ZERO ; + for ( int nI = 0 ; nI < int( vParAndNormIntersVec.size()) - 1 ; ++ nI) { + if ( vParAndNormIntersVec[nI].second.z < - dMyEps && vParAndNormIntersVec[nI+1].second.z > dMyEps) { + SubtractIntervals( nGrid, i, j, vParAndNormIntersVec[nI].first, vParAndNormIntersVec[nI+1].first, + vParAndNormIntersVec[nI].second, vParAndNormIntersVec[nI+1].second) ; + } + } + } + } + + return true ; +}*/ + +//---------------------------------------------------------------------------- +/*bool +VolZmap::SurfConus_ZMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, double dHei, double dMaxRad, double dMinRad, + const Vector3d& vtArcNormMaxR, const Vector3d& vtArcNormMinR) +{ + int nStartI, nStartJ, nEndI, nEndJ ; + if ( ! TestCompoBBox( nGrid, ptS, ptE, vtToolDir, dMaxRad, dMinRad, dHei, nStartI, nStartJ, nEndI, nEndJ)) + return true ; + + // Descrizione del moto + Point3d ptSXY( ptS.x, ptS.y, 0) ; + Vector3d vtDisp = ptE - ptS ; + double dDispLong = vtDisp * vtToolDir ; + Vector3d vtDispXY( vtDisp.x, vtDisp.y, 0) ; // = vtDisp - dDispLong * vtToolDir; + double dDispOrt = vtDispXY.Len(); + vtDispXY /= dDispOrt ; + double dDeltaHei = dMinRad * dHei / ( dMaxRad - dMinRad) ; + double dTanAlpha = dMaxRad / ( dHei + dDeltaHei) ; + double dCosTheta = ( dTanAlpha * vtDisp * vtToolDir) / ( vtDisp * vtDispXY) ; + bool bElevation = dDispLong > 0 ; + bool bLimPassed = dCosTheta > 1 ; + + //// Ciclo sui punti + //for ( int i = nStartI ; i <= nEndI ; ++ i) { + // for ( int j = nStartJ ; j <= nEndJ ; ++ j) { + // + // Point3d ptC( ( i + 0.5) * m_dSetp, ( j + 0.5) * m_dStep, 0) ; + // Vector3d vtPosXY = ptC - ptSXY ; + // double dLongXY = vtPosXY * vtDispXY ; + // double dOrtXY = sqrt( max( vtPosXY.SqLen() - dLongXY * dLongXY, 0)) ; + // + // if ( bElevation) { + // if ( bLimPassed) { + // ; + // } + // else { + // double dSqMinRad = dMinRad * dMinRad ; + // double dSqMaxRad = dMaxRad * dMaxRad ; + // double dSqRadDist = dLongXY * dLongXY + dOrtXY * dOrtXY ; + // double dCurCos = dLongXY / sqrt( dSqRadDist) ; + // if ( dSqRadDist > dSqMinRad && dSqRadDist < dSqMaxRad && dCurCos > dCosTheta) { + // ; + // } + // else if ( dSqRadDist > dSqMaxRad && abs( dOrtXY) < dMaxRad) { + // if ( dLongXY - dCosTheta * dMaxRad < dDispOrt) { + // + // } + // else { + // + // } + // } + // } + // } + // else { + // if ( bLimPassed) { + // ; + // } + // else { + // ; + // } + // } + // } + //} + + return true ; +}*/ + +//---------------------------------------------------------------------------- +/*bool +VolZmap::SurfConus_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, + double dHei, double dMaxRad, double dMinRad, bool bTapB, bool bTapT, + const Vector3d& vtArcNormMaxR, const Vector3d& vtArcNormMinR) +{ + // Verifico interferenza + int nStartI, nStartJ, nEndI, nEndJ ; + if ( ! TestCompoBBox( nGrid, ptS, ptE, vtToolDir, dMaxRad, dMinRad, dHei, nStartI, nStartJ, nEndI, nEndJ)) + return true ; + + // Vettore spostamento + Vector3d vtDisp = ptE - ptS ; + + // Spostamento nella direzione utensile e in quella ortogonale + double dDispProjOnToolDir = vtDisp * vtToolDir ; + Vector3d vtDispLong = dDispProjOnToolDir * vtToolDir ; + Vector3d vtDispOrt = vtDisp - vtDispLong ; + // Terna di riferimento del movimento + Vector3d vtV1 = vtDispOrt ; vtV2.Normalize() ; + Vector3d vtV2 = vtToolDir ^ vtV1 ; + Vector3d vtV3 = vtToolDir ; + // Parametri geometrici descriventi il cono e il moto + double dDeltaHei = dMinRad * dHei / ( dMaxRad - dMinRad) ; + double dTanAlpha = dMaxRad / ( dHei + dDeltaHei) ; + double dCosTheta = ( dTanAlpha * vtDisp * vtToolDir) / ( vtDisp * vtDispXY) ; + double dSinTheta = sqrt( max( 1 - dCosTheta * dCosTheta, 0.)) ; + bool bLimPassed = dCosTheta > 1 ; + // Vertici del cono nelle posizioni iniziale e finale + Point3d ptVertSt = ptS - dHei * vtToolDir ; + Point3d ptVertEn = ptE - dHei * vtToolDir ; + // Vettori radiali per definire i piani + Vector3d vtRadPlus = dCosTheta * vtV1 + dSinTheta * vtV2 ; + Vector3d vtRadMinus = dCosTheta * vtV1 - dSinTheta * vtV2 ; + + // Piani per tagliare le superfici elementari. + // Piani per cono in posizione iniziale + vector vCutConePlaneVecSt ; + vCutConePlaneVecSt.emplace_back() ; + vCutConePlaneVecSt.back().Set( ptS - dHei * vtToolDir, - vtToolDir) ; + Vector3d vtConePlaneNormSt = ( ptS + vtRadPlus - ptVertSt) ^ ( ptS + vtRadMinus - ptVertSt) ; vtConePlaneNormSt.Normalize() ; + vCutConePlaneVecSt.emplace_back() ; + vCutConePlaneVecSt.back().Set( ptVertSt, vtConePlaneNormSt) ; + // Piani per cono in posizione finale + vector vCutConePlaneVecEn ; + vCutConePlaneVecEn.emplace_back() ; + vCutConePlaneVecEn.back().Set( ptE - dHei * vtToolDir, - vtToolDir) ; + vCutConePlaneVecEn.emplace_back() ; + Vector3d vtConePlaneNormEn = ( ptE + vtRadPlus - ptVertEn) ^ ( ptE + vtRadMinus - ptVertEn) ; vtConePlaneNormEn.Normalize() ; + vCutConePlaneVecEn.back().Set( ptVertEn, vtConePlaneNormEn) ; + // Piani per cilindro ellittico superiore + vector vCutEllipCylPlaneVecUpSt ; + vCutEllipCylPlaneVecUpSt.emplace_back() ; + vCutEllipCylPlaneVecUpSt.back(); + vCutEllipCylPlaneVecUpSt.emplace_back() ; + vCutEllipCylPlaneVecUpSt.back(); + vCutEllipCylPlaneVecUpSt.emplace_back() ; + vCutEllipCylPlaneVecUpSt.back(); + // Piani per cilindro ellittico inferiore + vector vCutEllipCylPlaneVecUpEn ; + vCutEllipCylPlaneVecUpEn.emplace_back() ; + vCutEllipCylPlaneVecUpEn.back(); + vCutEllipCylPlaneVecUpEn.emplace_back() ; + vCutEllipCylPlaneVecUpEn.back(); + vCutEllipCylPlaneVecUpEn.emplace_back() ; + vCutEllipCylPlaneVecUpEn.back(); + // Vettore di piani vuoto + vector vEmptyPlaneVec ; + + //// Ciclo sui punti + //for ( int i = nStartI ; i <= nEndI ; ++ i) { + // for ( int j = nStartJ ; j <= nEndJ ; ++ j) { + // + // Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ; + // + // if ( bLimPassed) { + // + // vector> vParAndNormIntersVec ; + // Point3d ptInt1, ptInt2 ; + // Vector3d vtN1, vtN2 ; + // + // // Intersezione con il cono in posizione iniziale + // int nIntNum = IntersLineConeCuttedByPlanes( ptC, Z_AX, ptS, vtToolDir, dMaxRad, dHei, true, + // vCutConePlaneVecSt, ptInt1, vtN1, ptInt2, vtN2); + // if ( nIntNum >= 1) { + // vParAndNormIntersVec.emplace_back() ; + // vParAndNormIntersVec.back().first = ptInt1.z ; + // vParAndNormIntersVec.back().second = vtN1 ; + // if ( nIntNum == 2) { + // vParAndNormIntersVec.emplace_back() ; + // vParAndNormIntersVec.back().first = ptInt2.z ; + // vParAndNormIntersVec.back().second = vtN2 ; + // } + // } + // + // // Intersezione con il cono in posizione finale + // nIntNum = IntersLineConeCuttedByPlanes( ptC, Z_AX, ptE, vtToolDir, dMaxRad, dHei, true, + // vCutConePlaneVecEn, ptInt1, vtN1, ptInt2, vtN2) ; + // if ( nIntNum >= 1) { + // vParAndNormIntersVec.emplace_back() ; + // vParAndNormIntersVec.back().first = ptInt1.z ; + // vParAndNormIntersVec.back().second = vtN1 ; + // if ( nIntNum == 2) { + // vParAndNormIntersVec.emplace_back() ; + // vParAndNormIntersVec.back().first = ptInt2.z ; + // vParAndNormIntersVec.back().second = vtN2 ; + // } + // } + // + // // Intersezione con cilindro ellittico esterno + // nIntNum = IntersLineCircSweptSurfCuttedByPlanes( ptC, Z_AX, ptS, vtToolDir, dMaxRad, vtDisp,true, , + // ptInt1, vtN1, ptInt2, vtN2) ; + // if ( nIntNum >= 1) { + // vParAndNormIntersVec.emplace_back() ; + // vParAndNormIntersVec.back().first = ptInt1.z ; + // vParAndNormIntersVec.back().second = vtN1 ; + // if ( nIntNum == 2) { + // vParAndNormIntersVec.emplace_back() ; + // vParAndNormIntersVec.back().first = ptInt2.z ; + // vParAndNormIntersVec.back().second = vtN2 ; + // } + // } + // + // // Intersezione con cilindro ellittico interno + // nIntNum = IntersLineCircSweptSurfCuttedByPlanes( ptC, Z_AX, ptS - dHei * vtToolDir, vtToolDir, dMinRad, vtDisp, true, vCutEllipCylPlaneVecUpSt, + // ptInt1, vtN1, ptInt2, vtN2) ; + // if ( nIntNum >= 1) { + // vParAndNormIntersVec.emplace_back() ; + // vParAndNormIntersVec.back().first = ptInt1.z ; + // vParAndNormIntersVec.back().second = vtN1 ; + // if ( nIntNum == 2) { + // vParAndNormIntersVec.emplace_back() ; + // vParAndNormIntersVec.back().first = ptInt2.z ; + // vParAndNormIntersVec.back().second = vtN2 ; + // } + // } + // + // // Riordino le intersezioni in funzione del parametro lungo la retta in corrispondenza del quale occorrono. + // sort( vParAndNormIntersVec.begin(), vParAndNormIntersVec.end(), [] ( pair Int1, pair Int2) + // { return Int1.first < Int2.first ; }) ; + // + // // Sottraggo gli intervalli + // double dMyEps = EPS_ZERO ; + // for ( int nI = 0 ; nI < int( vParAndNormIntersVec.size()) - 1 ; ++ nI) { + // if ( vParAndNormIntersVec[nI].second.z < - dMyEps && vParAndNormIntersVec[nI+1].second.z > dMyEps) { + // SubtractIntervals( nGrid, i, j, vParAndNormIntersVec[nI].first, vParAndNormIntersVec[nI+1].first, + // vParAndNormIntersVec[nI].second, vParAndNormIntersVec[nI+1].second) ; + // } + // } + // } + // else { + // + // vector> vParAndNormIntersVec ; + // Point3d ptInt1, ptInt2 ; + // Vector3d vtN1, vtN2 ; + // + // // Intersezione con il cono in posizione iniziale + // int nIntNum = IntersLineConeCuttedByPlanes( ptC, Z_AX, ptS, vtToolDir, dMaxRad, dHei, true, + // vCutConePlaneVecSt, ptInt1, vtN1, ptInt2, vtN2); + // if ( nIntNum >= 1) { + // vParAndNormIntersVec.emplace_back() ; + // vParAndNormIntersVec.back().first = ptInt1.z ; + // vParAndNormIntersVec.back().second = vtN1 ; + // if ( nIntNum == 2) { + // vParAndNormIntersVec.emplace_back() ; + // vParAndNormIntersVec.back().first = ptInt2.z ; + // vParAndNormIntersVec.back().second = vtN2 ; + // } + // } + // + // // Intersezione con il cono in posizione finale + // nIntNum = IntersLineConeCuttedByPlanes( ptC, Z_AX, ptE, vtToolDir, dMaxRad, dHei, true, + // vCutConePlaneVecEn, ptInt1, vtN1, ptInt2, vtN2) ; + // if ( nIntNum >= 1) { + // vParAndNormIntersVec.emplace_back() ; + // vParAndNormIntersVec.back().first = ptInt1.z ; + // vParAndNormIntersVec.back().second = vtN1 ; + // if ( nIntNum == 2) { + // vParAndNormIntersVec.emplace_back() ; + // vParAndNormIntersVec.back().first = ptInt2.z ; + // vParAndNormIntersVec.back().second = vtN2 ; + // } + // } + // + // // Intersezione con cilindro ellittico superiore + // nIntNum = IntersLineCircSweptSurfCuttedByPlanes( ptC, Z_AX, ptS, vtToolDir, dMaxRad, vtDisp, , vCutEllipCylPlaneVecUpSt, + // ptInt1, vtN1, ptInt2, vtN2) ; + // if ( nIntNum >= 1) { + // vParAndNormIntersVec.emplace_back() ; + // vParAndNormIntersVec.back().first = ptInt1.z ; + // vParAndNormIntersVec.back().second = vtN1 ; + // if ( nIntNum == 2) { + // vParAndNormIntersVec.emplace_back() ; + // vParAndNormIntersVec.back().first = ptInt2.z ; + // vParAndNormIntersVec.back().second = vtN2 ; + // } + // } + // + // // Intersezione con cilindro ellittico inferiore + // nIntNum = IntersLineCircSweptSurfCuttedByPlanes( ptC, Z_AX, ptS - dHei * vtToolDir, vtToolDir, dMinRad, vtDisp, , vCutEllipCylPlaneVecUpSt, + // ptInt1, vtN1, ptInt2, vtN2) ; + // if ( nIntNum >= 1) { + // vParAndNormIntersVec.emplace_back() ; + // vParAndNormIntersVec.back().first = ptInt1.z ; + // vParAndNormIntersVec.back().second = vtN1 ; + // if ( nIntNum == 2) { + // vParAndNormIntersVec.emplace_back() ; + // vParAndNormIntersVec.back().first = ptInt2.z ; + // vParAndNormIntersVec.back().second = vtN2 ; + // } + // } + // + // // Piano + (con normale + vtToolDir ^ vtOrtDisp) + // nIntNum = IntersLineParallelogram( ptC, Z_AX, ptPlanePlus, dHei * vtToolDir, vtDisp, + // true, ptInt1, vtN1) ; + // if ( nIntNum == 1) { + // vParAndNormIntersVec.emplace_back() ; + // vParAndNormIntersVec.back().first = ptInt1.z ; + // vParAndNormIntersVec.back().second = vtN1 ; + // } + // + // // Piano - (con normale - vtToolDir ^ vtOrtDisp) + // nIntNum = IntersLineParallelogram( ptC, Z_AX, ptPlaneMinus, dHei * vtToolDir, vtDisp, + // false, ptInt1, vtN1) ; + // if ( nIntNum == 1) { + // vParAndNormIntersVec.emplace_back() ; + // vParAndNormIntersVec.back().first = ptInt1.z ; + // vParAndNormIntersVec.back().second = vtN1 ; + // } + // + // // Riordino le intersezioni in funzione del parametro lungo la retta in corrispondenza del quale occorrono. + // sort( vParAndNormIntersVec.begin(), vParAndNormIntersVec.end(), [] ( pair Int1, pair Int2) + // { return Int1.first < Int2.first ; }) ; + // + // // Sottraggo gli intervalli + // double dMyEps = EPS_ZERO ; + // for ( int nI = 0 ; nI < int( vParAndNormIntersVec.size()) - 1 ; ++ nI) { + // if ( vParAndNormIntersVec[nI].second.z < - dMyEps && vParAndNormIntersVec[nI+1].second.z > dMyEps) { + // SubtractIntervals( nGrid, i, j, vParAndNormIntersVec[nI].first, vParAndNormIntersVec[nI+1].first, + // vParAndNormIntersVec[nI].second, vParAndNormIntersVec[nI+1].second) ; + // } + // } + // } + // } + //} + + return true ; +}*/ + + // ------------------------- BOUNDING BOX -------------------------------------------------------------------------------------- //----------------------------------------------------------------------------