From 09fd122b306be22c26a04cdc8fc52444c7256abd Mon Sep 17 00:00:00 2001 From: Riccardo Elitropi Date: Tue, 11 Mar 2025 11:18:51 +0100 Subject: [PATCH] =?UTF-8?q?EgtMachKernel=20:=20-=20Migliorie=20a=20finitur?= =?UTF-8?q?e=20Optimal=20e=20ZConst.=20-=20controllo=20validit=C3=A0=20cur?= =?UTF-8?q?ve=20per=20Sgrossature.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SurfFinishing.cpp | 564 +++++++++++++++++++++++++++++----------------- SurfFinishing.h | 12 +- SurfRoughing.cpp | 3 +- 3 files changed, 363 insertions(+), 216 deletions(-) diff --git a/SurfFinishing.cpp b/SurfFinishing.cpp index a609bfc..1ee1e09 100644 --- a/SurfFinishing.cpp +++ b/SurfFinishing.cpp @@ -1643,7 +1643,6 @@ SurfFinishing::ProcessSfr( int nPathId, int nPvId, int nClId) } } } - // se regione risultante vuota, non devo fare altro if ( ! pSfrCnt->IsValid()) return true ; @@ -2456,29 +2455,6 @@ SurfFinishing::GetZConstQuotesInsideSfrParallelToTool( const SURFLOCALVECTOR& vS return true ; } -//---------------------------------------------------------------------------- -ICAvParSilhouettesSurfTm* -SurfFinishing::GetParSilhouettesForZConst( const ISURFTMPOVECTOR& vStm, const ISurfFlatRegion* pSfr) const -{ - // controllo dei parametri - if ( vStm.empty() || pSfr == nullptr || ! pSfr->IsValid()) - return nullptr ; - - // inizializzo la classe di calcolo delle silhouette nei piani come sopra - CISURFTMPVECTOR vpStm ; vpStm.reserve( vStm.size()) ; - for ( int i = 0 ; i < int( vStm.size()) ; ++ i) - vpStm.emplace_back( vStm[i]) ; - - const double SILH_SHARPED_ANG_TOL = ANG_TOL_STD_DEG ; - PtrOwner pCavParSilh( CreateCAvParSilhouettesSurfTm()) ; - if ( IsNull( pCavParSilh) || - ! pCavParSilh->SetDataForRegion( vpStm, pSfr, m_TParams.m_dSideAng, m_TParams.m_dDiam, - m_TParams.m_dCornRad, m_TParams.m_dMaxMat, GetOffsR(), SILH_SAMPLING, SILH_SHARPED_ANG_TOL)) - return nullptr ; - - return ( Release( pCavParSilh)) ; -} - //---------------------------------------------------------------------------- ISurfFlatRegion* SurfFinishing::GetSfrSilhouette( const SURFLOCALVECTOR& vSrfLoc, const Frame3d& frLvl0, double dDepth) const @@ -2569,8 +2545,35 @@ SurfFinishing::CalcZConstSilCrv( ICAvParSilhouettesSurfTm* pCavParSilh, const SU } // calcolo vettore di PolyLine ottenute al piano corrente POLYLINEVECTOR vPL ; - if ( ! pCavParSilh->GetSilhouetteInsideRegion( dZLoc, vPL)) + if ( ! pCavParSilh->GetSilhouette( dZLoc, vPL)) return false ; + // classifico le PolyLine in base alla regione + POLYLINEVECTOR vPL_InsideSfr ; + for ( auto& PL : vPL) { + // porto la PolyLine a contatto con la regione + PL.Translate( - dZLoc * pSfrClass->GetNormVersor()) ; + // converto in curva composita + PtrOwner pCrv_PL( CreateCurveComposite()) ; + if ( IsNull( pCrv_PL) || ! pCrv_PL->FromPolyLine( PL)) + return false ; + // classifico la curva con la superficie + CRVCVECTOR ccClass ; + if ( ! pSfrClass->GetCurveClassification( *pCrv_PL, EPS_SMALL, ccClass)) + return false ; + // tengo tutti i tratti non esterni alla superficie + for ( int i = 0 ; i < int( ccClass.size()) ; ++ i) { + if ( ccClass[i].nClass != CRVC_OUT) { + PtrOwner pCrvCompoPartIn( ConvertCurveToComposite( pCrv_PL->CopyParamRange( ccClass[i].dParS, ccClass[i].dParE))) ; + if ( ! IsNull( pCrvCompoPartIn) && pCrvCompoPartIn->IsValid()) { + vPL_InsideSfr.emplace_back( PolyLine()) ; + // riporto la curva alla quota giusta + pCrvCompoPartIn->Translate( dZLoc * pSfrClass->GetNormVersor()) ; + pCrvCompoPartIn->ApproxWithLines( 0, 0, ICurve::APL_SPECIAL, vPL_InsideSfr.back()) ; + } + } + } + } + swap( vPL, vPL_InsideSfr) ; for ( auto& PL : vPL) { // recupero la curva dalla silhouette PtrOwner pSilCrv( CreateCurveComposite()) ; @@ -3027,8 +3030,16 @@ SurfFinishing::AddZConst( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSrf // aggiorno la ProgressBar del 5% per simulare l'inizio della funzione ExeProcessEvents( 5, 0) ; + // definisco un frame implicito dalla superficie + Frame3d frSfr ; + Point3d ptC ; pSfr->GetCentroid( ptC) ; + if ( ! frSfr.Set( ptC, pSfr->GetNormVersor())) + return false ; + frSfr.ToLoc( frSurf) ; // in locale alle SrfLoc + // aggiusto la regione a seconda dei parametri e la porto nel frame locale delle superfici - PtrOwner pSfrClass( pSfr->CreateOffsetSurf( - m_TParams.m_dDiam / 2. + m_Params.m_dOverlap, ICurve::OFF_FILLET)) ; + double dOffsClass = - GetOffsR() + m_Params.m_dOverlap + 200 * EPS_SMALL ; + PtrOwner pSfrClass( pSfr->CreateOffsetSurf( dOffsClass, ICurve::OFF_FILLET)) ; if ( IsNull( pSfrClass) || ! pSfrClass->IsValid() || ! pSfrClass->ToLoc( frSurf)) return false ; @@ -3041,10 +3052,11 @@ SurfFinishing::AddZConst( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSrf if ( pStm != nullptr && pStm->IsValid() && pStm->GetTriangleCount() > 0) vpStm.emplace_back( pStm) ; } + const double TOL_SAMPLING = 1. ; PtrOwner pCavParSilh( CreateCAvParSilhouettesSurfTm()) ; if ( IsNull( pCavParSilh) || - ! pCavParSilh->SetDataForRegion( vpStm, pSfrClass, m_TParams.m_dSideAng, m_TParams.m_dDiam, - m_TParams.m_dCornRad, m_TParams.m_dMaxMat, GetOffsR(), SILH_SAMPLING, ANG_TOL_STD_DEG)) + ! pCavParSilh->SetData( vpStm, frSfr, TOL_SAMPLING, m_TParams.m_dSideAng, m_TParams.m_dDiam, + m_TParams.m_dCornRad, m_TParams.m_dMaxMat, GetOffsR(), dDepth)) return false ; // aggiorno la ProgressBar al 30% @@ -3811,12 +3823,10 @@ SurfFinishing::GetSfrProjectedStmLoops( const ISURFTMPOVECTOR& vStm, const ISurf } //---------------------------------------------------------------------------- -bool +Point3d SurfFinishing::CalcShapedPoint( const PNTUVVECT& myInfoStart, const PNTUVVECT& myInfoEnd, bool bSpiral, const Vector3d& vtAxL, - const Vector3d& vtMoveL, double dClippingAngle, ICAvToolSurfTm* pCAvTlStm, Point3d& ptShaped, int _debug_ind) const + const Vector3d& vtMoveL, double dCosSplitAngle, ICAvToolSurfTm* pCAvTlStm, int _nInd_debug) const { - // cos di ripartizione - double dCosClipping = cos( dClippingAngle * DEGTORAD) ; // altrimenti effettuo bisezione const int MAX_ITER = 10 ; @@ -3826,37 +3836,33 @@ SurfFinishing::CalcShapedPoint( const PNTUVVECT& myInfoStart, const PNTUVVECT& m Point3d ptMid = Media( get<0>( ptU_vt1), get<0>( ptU_vt2)) ; while ( nCount < MAX_ITER) { // se estremi coincidenti, allora mi fermo - if ( SqDist( get<0>( ptU_vt1), get<0>( ptU_vt2)) < EPS_SMALL * EPS_SMALL) { - ptShaped = ptMid ; - return true ; - } + if ( SqDist( get<0>( ptU_vt1), get<0>( ptU_vt2)) < 4 * SQ_EPS_SMALL) + return ptMid ; // verifica del punto medio Point3d ptTest = ptMid ; double dMove = 0. ; VCT3DVECTOR vVtN ; - if ( ! pCAvTlStm->TestPointAdv( ptTest, vtAxL, vtMoveL, dMove, vVtN)) - return false ; - + if ( ! pCAvTlStm->TestPositionAdv( ptTest, vtAxL, vtMoveL, dMove, vVtN)) + return P_INVALID ; + // collisione nel punto medio bool bMidColl = false ; - for ( int nV = 0 ; nV < int( vVtN.size()) ; ++ nV) { + for ( int nV = 0 ; nV < int( vVtN.size()) && ! bMidColl ; ++ nV) { double dAbsCos = abs( vVtN[nV] * vtAxL) ; - if ( ! bMidColl) - bMidColl = ( bSpiral ? dAbsCos > dCosClipping + EPS_ANG_ZERO : dAbsCos < dCosClipping + EPS_ANG_ZERO) ; + bMidColl = ( bSpiral ? dAbsCos > dCosSplitAngle + EPS_ANG_ZERO : dAbsCos < dCosSplitAngle + EPS_ANG_ZERO) ; } - bool b1Coll = false ; - for ( int nV = 0 ; nV < int( get<2>( ptU_vt1).size()) ; ++ nV) { - double dAbsCos = abs( get<2>( ptU_vt1)[nV] * vtAxL) ; - if ( ! b1Coll) - b1Coll = ( bSpiral ? dAbsCos > dCosClipping + EPS_ANG_ZERO : dAbsCos < dCosClipping + EPS_ANG_ZERO) ; - } - #if ENABLE_OPTIMAL_DEBUG - PtrOwner pt( CreateGeoPoint3d()) ; - pt->Set( ptMid) ; - int _a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, _debug_ind, pt->Clone()) ; + PtrOwner myPt( CreateGeoPoint3d()) ; + myPt->Set( ptMid) ; + int _a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, _nInd_debug, myPt->Clone()) ; m_pGeomDB->SetMaterial( _a, bMidColl ? ORANGE : AQUA) ; #endif - + // collisione nel punto 1 di riferimento + bool b1Coll = false ; + for ( int nV = 0 ; nV < int( get<2>( ptU_vt1).size()) && ! b1Coll ; ++ nV) { + double dAbsCos = abs( get<2>( ptU_vt1)[nV] * vtAxL) ; + b1Coll = ( bSpiral ? dAbsCos > dCosSplitAngle + EPS_ANG_ZERO : dAbsCos < dCosSplitAngle + EPS_ANG_ZERO) ; + } + // definizione del nuovo intervallo per interpolazione if ( b1Coll != bMidColl) ptU_vt2 = make_tuple( ptMid, dMove, vVtN) ; else @@ -3865,23 +3871,14 @@ SurfFinishing::CalcShapedPoint( const PNTUVVECT& myInfoStart, const PNTUVVECT& m ++ nCount ; } - ptShaped = ptMid ; - return true ; + return ptMid ; } //---------------------------------------------------------------------------- int -AdvancedProcessSquare( int nFlag, const INTVECTOR& vInds, const DBLVECTOR& vdU, INTINTVECTOR& vIndBounds) +SurfFinishing::ProcessSquare( int nFlag, double dLevel, double dQPt0, double dQpt1, double dQpt2, double dQpt3, + int& nI1s, int& nI1e, int& nI2s, int& nI2e) const { - // controllo dei parametri - if ( nFlag < 0 || nFlag > 15 || - int( vInds.size()) != 4 || int( vdU.size()) != 4 || int( vIndBounds.size()) != 4) - return -1 ; - // assegno valori di default agli indici degli estremi - for ( int i = 0 ; i < 4 ; ++ i) - vIndBounds[i] = make_pair( -1, -1) ; - - //---------------------------------------------------------------------------- // Quadrato (C=corner E=edge) : // // C3 - E2 - C2 @@ -3889,66 +3886,107 @@ AdvancedProcessSquare( int nFlag, const INTVECTOR& vInds, const DBLVECTOR& vdU, // E3 * E1 // | * * | // C0 - E0 - C1 - // - //---------------------------------------------------------------------------- - // LineTable avanzata - static int LineTable[16][7] = { { 0, -1, -1, -1, -1, -1, -1}, // ( 0) - { 2, 0, 1, 0, 2, 0, 3}, // ( 1) - { 2, 1, 2, 1, 3, 1, 0}, // ( 2) - { 1, 1, 2, 0, 3, -1, -1}, // ( 3) - { 2, 2, 3, 2, 0, 2, 1}, // ( 4) - { -1, -1, -1, -1, -1, -1, -1}, // ( 5) -> ambiguo - { 1, 2, 3, 1, 0, -1, -1}, // ( 6) - { 2, 2, 3, 1, 3, 0, 3}, // ( 7) - { 2, 3, 0, 3, 1, 3, 2}, // ( 8) - { 1, 0, 1, 3, 2, -1, -1}, // ( 9) - { -1, -1, -1, -1, -1, -1, -1}, // ( 10) -> ambiguo - { 2, 1, 2, 0, 2, 3, 2}, // ( 11) - { 1, 3, 0, 2, 1, -1, -1}, // ( 12) - { 2, 0, 1, 3, 1, 2, 1}, // ( 13) - { 2, 3, 0, 2, 0, 1, 0}, // ( 14) - { 0, -1, -1, -1, -1, -1, -1} } ; // ( 15) - static int LineTabelAmbiguos[4][9] = { { 2, 2, 3, 2, 1, 0, 1, 0, 3}, // ( 5-split) - { 2, 2, 3, 0, 3, 0, 1, 2, 1}, // ( 5-stick) - { 2, 1, 2, 1, 0, 3, 0, 3, 2}, // ( 10-split) - { 2, 1, 2, 3, 2, 3, 0, 0, 1} } ; // ( 10-stick) + static int LineTable[16][4] = { { 0, -1, -1, -1}, // ( 0) + { 2, 0, 5, 3}, // ( 1) + { 2, 1, 4, 0}, // ( 2) + { 1, 1, 3, -1}, // ( 3) + { 2, 2, 5, 1}, // ( 4) + { -1, -1, -1, -1}, // ( 5) -> ambiguo + { 1, 2, 0, -1}, // ( 6) + { 2, 2, 4, 3}, // ( 7) + { 2, 3, 4, 2}, // ( 8) + { 1, 0, 2, -1}, // ( 9) + { -1, -1, -1, -1}, // ( 10) -> ambiguo + { 2, 1, 5, 2}, // ( 11) + { 1, 3, 1, -1}, // ( 12) + { 2, 0, 4, 1}, // ( 13) + { 2, 3, 5, 0}, // ( 14) + { 0, -1, -1, -1} } ; // ( 15) + static int LineTableAmbiguos[4][5] = { { 2, 2, 1, 0, 3}, // ( 5-split) + { 2, 2, 3, 0, 1}, // ( 5-stick) + { 2, 1, 0, 3, 2}, // ( 10-split) + { 2, 1, 2, 3, 0} } ; // ( 10-stick) + + // flag fuori dai limiti + if ( nFlag < 0 || nFlag > 15) + return -1 ; + // nessuna linea + if ( LineTable[nFlag][0] == 0) + return 0 ; int nLines = LineTable[nFlag][0] ; // se almeno una linea - if ( LineTable[nFlag][0] > 0) { - vIndBounds[0] = make_pair( vInds[LineTable[nFlag][1]], vInds[LineTable[nFlag][2]]) ; - vIndBounds[1] = make_pair( vInds[LineTable[nFlag][3]], vInds[LineTable[nFlag][4]]) ; + if ( nLines > 0) { + nI1s = LineTable[nFlag][1] ; + nI1e = LineTable[nFlag][2] ; } // se due linee - if ( LineTable[nFlag][0] == 2) { - vIndBounds[2] = make_pair( vInds[LineTable[nFlag][3]], vInds[LineTable[nFlag][4]]) ; - vIndBounds[3] = make_pair( vInds[LineTable[nFlag][5]], vInds[LineTable[nFlag][6]]) ; + if ( nLines == 2) { + nI2s = LineTable[nFlag][2] ; + nI2e = LineTable[nFlag][3] ; } // se ambiguo - if ( LineTable[nFlag][0] == -1) { - int nJump = ( nFlag == 5 ? 0 : 2) ; - int nShift = ( vdU[0] * vdU[2] < vdU[1] * vdU[3] ? 0 : 1) ; - vIndBounds[0] = make_pair( vInds[LineTabelAmbiguos[nJump + nShift][1]], - vInds[LineTabelAmbiguos[nJump + nShift][2]]) ; - vIndBounds[1] = make_pair( vInds[LineTabelAmbiguos[nJump + nShift][3]], - vInds[LineTabelAmbiguos[nJump + nShift][4]]) ; - vIndBounds[2] = make_pair( vInds[LineTabelAmbiguos[nJump + nShift][5]], - vInds[LineTabelAmbiguos[nJump + nShift][6]]) ; - vIndBounds[3] = make_pair( vInds[LineTabelAmbiguos[nJump + nShift][7]], - vInds[LineTabelAmbiguos[nJump + nShift][8]]) ; + if ( nLines == -1) { nLines = 2 ; + int nJump = ( nFlag == 5 ? 0 : 2) ; + int nShift = ( ( dQPt0 - dLevel) * ( dQpt2 - dLevel) > ( dQpt1 - dLevel) * ( dQpt3 - dLevel) ? 1 : 0) ; + nI1s = LineTableAmbiguos[nJump + nShift][1] ; + nI1e = LineTableAmbiguos[nJump + nShift][2] ; + nI2s = LineTableAmbiguos[nJump + nShift][3] ; + nI2e = LineTableAmbiguos[nJump + nShift][4] ; } return nLines ; } +//---------------------------------------------------------------------------- +bool +SurfFinishing::TestSubEdges( unordered_map& umEdgePnt, const INTVECTOR& vEdgeInd, bool bSpiral, int nFirst, int nLast, + const VECTORCOLLISIONSFR& vPntM, int nStepX, const Vector3d vtAxL, const Vector3d& vtMoveL, + double dCosSplitAng, ICAvToolSurfTm* pCAvTlStm, int _nInd_debug) const +{ + for ( int k = nFirst ; k <= nLast ; ++ k) { + // recupero i differenti indici + int nKey = vEdgeInd[k] ; + int nInd = nKey / 4 ; + int nIndS, nIndE ; + int nMod = nKey % 4 ; + switch ( nMod) + { + case ( 0) : + nIndS = nInd ; + nIndE = nInd + 1 ; + break ; + case ( 1) : + nIndS = nInd ; + nIndE = nInd + nStepX + 1 ; + break ; + case ( 2) : + nIndS = nInd + 1 ; + nIndE = nInd + nStepX + 1 ; + break ; + case ( 3) : + nIndS = nInd ; + nIndE = nInd + nStepX + 2 ; + break ; + } + // calcolo il punto + Point3d ptQ = CalcShapedPoint( vPntM[nIndS].CollisionInfo, vPntM[nIndE].CollisionInfo, bSpiral, + vtAxL, vtMoveL, dCosSplitAng, pCAvTlStm, _nInd_debug) ; + if ( ! ptQ.IsValid()) + return false ; + umEdgePnt[ nKey] = ptQ ; + } + return true ; +} + //---------------------------------------------------------------------------- bool SurfFinishing::MarchingSquares( const VECTORCOLLISIONSFR& vPntM, bool bSpiral, double dOffsTol, int nStepX, int nStepY, double dClippingAngle, const Vector3d& vtAxL, const Vector3d& vtMoveL, ICAvToolSurfTm* pCAvTlStm, ICRVCOMPOPOVECTOR& vCrvCompo) const { - pair _debug_inds = make_pair( GDB_ID_NULL, GDB_ID_ROOT) ; + int _nInd_debug = GDB_ID_NULL ; #if ENABLE_OPTIMAL_DEBUG int nGrp = m_pGeomDB->AddGroup( GDB_ID_NULL, GDB_ID_ROOT, GLOB_FRM) ; m_pGeomDB->SetName( nGrp, "_marchingsquare") ; @@ -3959,90 +3997,191 @@ SurfFinishing::MarchingSquares( const VECTORCOLLISIONSFR& vPntM, bool bSpiral, d nLyS = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrp, GLOB_FRM) ; m_pGeomDB->SetName( nLyS, "_spiral") ; m_pGeomDB->SetStatus( nLyS, GDB_ST_OFF) ; - _debug_inds.first = nLyS ; + _nInd_debug = nLyS ; } else { nLyZC = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrp, GLOB_FRM) ; m_pGeomDB->SetName( nLyZC, "_zconst") ; m_pGeomDB->SetStatus( nLyZC, GDB_ST_OFF) ; - _debug_inds.second = nLyZC ; + _nInd_debug = nLyZC ; } #endif - // Predispongo il concatenamento - BIPNTVECTOR vBiPnt ; vBiPnt.reserve( 2 * ( nStepX + nStepY)) ; - ChainCurves chainC ; chainC.Init( false, EPS_SMALL, 2 * ( nStepX + nStepY)) ; + // Analizzo gli edge da cui passano le curve cercate + vCrvCompo.clear() ; + unordered_map umEdgePnt( 6 * ( nStepX + nStepY)) ; + INTVECTOR vEdgeInd ; + vEdgeInd.reserve( 6 * ( nStepX + nStepY)) ; + double dCosSplitAngle = cos( dClippingAngle * DEGTORAD) ; // Ciclo sui quadrati da analizzare for ( int j = 0 ; j < nStepY ; ++ j) { for ( int i = 0 ; i < nStepX ; ++ i) { - // vettore degli indici - INTVECTOR vInd{ i + j * ( nStepX + 1), ( i + 1) + j * ( nStepX + 1), - ( i + 1) + ( j + 1) * ( nStepX + 1), i + ( j + 1) * ( nStepX + 1)} ; + // indici dei vertici nella griglia + int nInd0 = i + j * ( nStepX + 1) ; + int nInd1 = ( i + 1) + j * ( nStepX + 1) ; + int nInd2 = ( i + 1) + ( j + 1) * ( nStepX + 1) ; + int nInd3 = i + ( j + 1) * ( nStepX + 1) ; // flag del quadrato - int nFlag = ( bSpiral ? ( ( vPntM[vInd[0]].bInSpiral ? 1 : 0) + ( vPntM[vInd[1]].bInSpiral ? 2 : 0) + - ( vPntM[vInd[2]].bInSpiral ? 4 : 0) + ( vPntM[vInd[3]].bInSpiral ? 8 : 0)) : - ( ( vPntM[vInd[0]].bInZConst ? 1 : 0) + ( vPntM[vInd[1]].bInZConst ? 2 : 0) + - ( vPntM[vInd[2]].bInZConst ? 4 : 0) + ( vPntM[vInd[3]].bInZConst ? 8 : 0))) ; - // vettore degli estremi dei segmenti - INTINTVECTOR vIndBounds( 4, make_pair( -1, -1)) ; - // vettore dei parametri dU - DBLVECTOR vdU{ get<1>( vPntM[vInd[0]].CollisionInfo), get<1>( vPntM[vInd[1]].CollisionInfo), - get<1>( vPntM[vInd[2]].CollisionInfo), get<1>( vPntM[vInd[3]].CollisionInfo)} ; - // analisi del quadrato - int nLines = AdvancedProcessSquare( nFlag, vInd, vdU, vIndBounds) ; - if ( nLines == -1) + bool bUp0 = ( bSpiral ? ( vPntM[nInd0].bInSpiral) : vPntM[nInd0].bInZConst) ; + bool bUp1 = ( bSpiral ? ( vPntM[nInd1].bInSpiral) : vPntM[nInd1].bInZConst) ; + bool bUp2 = ( bSpiral ? ( vPntM[nInd2].bInSpiral) : vPntM[nInd2].bInZConst) ; + bool bUp3 = ( bSpiral ? ( vPntM[nInd3].bInSpiral) : vPntM[nInd3].bInZConst) ; + // se tutti uguali, passo al successivo + if ( bUp0 == bUp1 && bUp0 == bUp2 && bUp0 == bUp3) + continue ; + // verifico Edge da calcolare + if ( bUp0 != bUp1) { + int nKey = 4 * nInd0 ; + if ( umEdgePnt.find( nKey) == umEdgePnt.end()) { + umEdgePnt[ nKey] = P_INVALID ; + vEdgeInd.emplace_back( nKey) ; + } + } + if ( bUp3 != bUp2) { + int nKey = 4 * nInd3 ; + if ( umEdgePnt.find( nKey) == umEdgePnt.end()) { + umEdgePnt[ nKey] = P_INVALID ; + vEdgeInd.emplace_back( nKey) ; + } + } + if ( bUp0 != bUp3) { + int nKey = 4 * nInd0 + 1 ; + if ( umEdgePnt.find( nKey) == umEdgePnt.end()) { + umEdgePnt[ nKey] = P_INVALID ; + vEdgeInd.emplace_back( nKey) ; + } + } + if ( bUp1 != bUp2) { + int nKey = 4 * nInd1 + 1 ; + if ( umEdgePnt.find( nKey) == umEdgePnt.end()) { + umEdgePnt[ nKey] = P_INVALID ; + vEdgeInd.emplace_back( nKey) ; + } + } + int nFlag = ( bSpiral ? ( ( vPntM[nInd0].bInSpiral ? 1 : 0) + ( vPntM[nInd1].bInSpiral ? 2 : 0) + + ( vPntM[nInd2].bInSpiral ? 4 : 0) + ( vPntM[nInd3].bInSpiral ? 8 : 0)) : + ( ( vPntM[nInd0].bInZConst ? 1 : 0) + ( vPntM[nInd1].bInZConst ? 2 : 0) + + ( vPntM[nInd2].bInZConst ? 4 : 0) + ( vPntM[nInd3].bInZConst ? 8 : 0))) ; + if ( nFlag == 1 || nFlag == 2 || nFlag == 4 || nFlag == 7 || nFlag == 8 || nFlag == 11 || + nFlag == 13 || nFlag == 14) { + if ( bUp1 != bUp3) { + int nKey = 4 * nInd0 + 2 ; + if ( umEdgePnt.find( nKey) == umEdgePnt.end()) { + umEdgePnt[ nKey] = P_INVALID ; + vEdgeInd.emplace_back( nKey) ; + } + } + if ( bUp0 != bUp2) { + int nKey = 4 * nInd0 + 3 ; + if ( umEdgePnt.find( nKey) == umEdgePnt.end()) { + umEdgePnt[ nKey] = P_INVALID ; + vEdgeInd.emplace_back( nKey) ; + } + } + } + } + } + // Numero di edge da valutare + int nEdgeCnt = int( vEdgeInd.size()) ; + // Recupero il numero massimo di thread concorrenti + int nThreadMax = ( thread::hardware_concurrency()) / 2 ; + bool bOk = true ; + // Se un solo thread o pochi punti + if ( nThreadMax <= 1 || nEdgeCnt < 50) + TestSubEdges( umEdgePnt, vEdgeInd, bSpiral, 0, nEdgeCnt - 1, vPntM, nStepX, vtAxL, vtMoveL, dCosSplitAngle, pCAvTlStm, _nInd_debug) ; + // altrimenti + else { + const int MAX_PARTS = 32 ; + INTINTVECTOR vFstLst( MAX_PARTS) ; + // calcolo le parti del vettore + int nPartCnt = min( nThreadMax, MAX_PARTS) ; + int nPartDim = nEdgeCnt / nPartCnt + 1 ; + for ( int i = 0 ; i < nPartCnt ; ++ i) { + vFstLst[i].first = i * nPartDim ; + vFstLst[i].second = min( ( i + 1) * nPartDim, nEdgeCnt) - 1 ; + } + // processo le parti + future vRes[MAX_PARTS] ; + for ( int i = 0 ; i < nPartCnt ; ++ i) + vRes[i] = async( launch::async, &SurfFinishing::TestSubEdges, this, ref( umEdgePnt), cref( vEdgeInd), bSpiral, vFstLst[i].first, vFstLst[i].second, + cref( vPntM), nStepX, cref( vtAxL), cref( vtMoveL), dCosSplitAngle, ref( pCAvTlStm), _nInd_debug) ; + // attendo i risultati + int nFin = 0 ; + while ( nFin < nPartCnt) { + for ( int i = 0 ; i < nPartCnt ; ++ i) { + if ( vRes[i].valid() && vRes[i].wait_for( chrono::nanoseconds{ 1}) == future_status::ready) { + bOk = vRes[i].get() && bOk ; + ++ nFin ; + } + } + } + } + + // Predispongo il concatenamento + BIPNTVECTOR vBiPnt ; + vBiPnt.reserve( 2 * ( nStepX + nStepY)) ; + ChainCurves chainC ; + chainC.Init( false, EPS_SMALL, 2 * ( nStepX + nStepY)) ; + // Ciclo sui quadrati da analizzare + for ( int j = 0 ; j < nStepY ; ++ j) { + for ( int i = 0 ; i < nStepX ; ++ i) { + // indici dei vertici nella griglia + int nInd0 = i + j * ( nStepX + 1) ; + int nInd1 = ( i + 1) + j * ( nStepX + 1) ; + int nInd2 = ( i + 1) + ( j + 1) * ( nStepX + 1) ; + int nInd3 = i + ( j + 1) * ( nStepX + 1) ; + // flag del quadrato + int nFlag = ( bSpiral ? ( ( vPntM[nInd0].bInSpiral ? 1 : 0) + ( vPntM[nInd1].bInSpiral ? 2 : 0) + + ( vPntM[nInd2].bInSpiral ? 4 : 0) + ( vPntM[nInd3].bInSpiral ? 8 : 0)) : + ( ( vPntM[nInd0].bInZConst ? 1 : 0) + ( vPntM[nInd1].bInZConst ? 2 : 0) + + ( vPntM[nInd2].bInZConst ? 4 : 0) + ( vPntM[nInd3].bInZConst ? 8 : 0))) ; + // se quadrato con vertici tutti dello stesso tipo, passo al successivo + if ( nFlag == 0 || nFlag == 15) + continue ; + // chiavi + int vKey[6] = { 4 * nInd0, 4 * nInd1 + 1, 4 * nInd3, 4 * nInd0 + 1, 4 * nInd0 + 2, 4 * nInd0 + 3} ; + // calcolo segmenti da inserire + int nI1s, nI1e, nI2s, nI2e ; + double dLevel = .25 * ( get<1>( vPntM[nInd0].CollisionInfo) + get<1>( vPntM[nInd1].CollisionInfo) + + get<1>( vPntM[nInd2].CollisionInfo) + get<1>( vPntM[nInd3].CollisionInfo)) ; + int nSegCnt = ProcessSquare( nFlag, dLevel, get<1>( vPntM[nInd0].CollisionInfo), get<1>( vPntM[nInd1].CollisionInfo), + get<1>( vPntM[nInd1].CollisionInfo), get<1>( vPntM[nInd3].CollisionInfo), nI1s, nI1e, nI2s, nI2e) ; + if ( nSegCnt == -1) return false ; - // se esiste una linea - if ( nLines > 0) { - // controllo interpolazine - Point3d ptL1s ; - if ( ! CalcShapedPoint( vPntM[vIndBounds[0].first].CollisionInfo, vPntM[vIndBounds[0].second].CollisionInfo, - bSpiral, vtAxL, vtMoveL, dClippingAngle, pCAvTlStm, ptL1s, bSpiral ? _debug_inds.first : _debug_inds.second)) - ptL1s = get<0>( vPntM[vIndBounds[0].first].CollisionInfo) ; - Point3d ptL1e ; - if ( ! CalcShapedPoint( vPntM[vIndBounds[1].first].CollisionInfo, vPntM[vIndBounds[1].second].CollisionInfo, - bSpiral, vtAxL, vtMoveL, dClippingAngle, pCAvTlStm, ptL1e, bSpiral ? _debug_inds.first : _debug_inds.second)) - ptL1e = get<0>( vPntM[vIndBounds[1].first].CollisionInfo) ; + else if ( nSegCnt > 0) { + // inserisco il primo + Point3d ptL1s = umEdgePnt.find( vKey[nI1s])->second ; + Point3d ptL1e = umEdgePnt.find( vKey[nI1e])->second ; vBiPnt.emplace_back( ptL1s, ptL1e) ; Vector3d vtDir1 = ptL1e - ptL1s ; vtDir1.Normalize() ; chainC.AddCurve( int( vBiPnt.size()), ptL1s, vtDir1, ptL1e, vtDir1) ; #if ENABLE_OPTIMAL_DEBUG - PtrOwner myLine( CreateCurveLine()) ; - myLine->Set( ptL1s, ptL1e) ; - if ( ! IsNull( myLine) && myLine->IsValid()) { - myLine->SetExtrusion( vtAxL) ; - int _a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, bSpiral ? nLyS : nLyZC, myLine->Clone()) ; - m_pGeomDB->SetMaterial( _a, GREEN) ; - } + PtrOwner pMyLine( CreateCurveLine()) ; + pMyLine->Set( ptL1s, ptL1e) ; + pMyLine->SetExtrusion( vtAxL) ; + int a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, _nInd_debug , Release( pMyLine)) ; + m_pGeomDB->SetMaterial( a, GREEN) ; #endif - // interpolazione seconda linea - if ( nLines == 2) { - Point3d ptL2s ; - if ( ! CalcShapedPoint( vPntM[vIndBounds[2].first].CollisionInfo, vPntM[vIndBounds[2].second].CollisionInfo, - bSpiral, vtAxL, vtMoveL, dClippingAngle, pCAvTlStm, ptL2s, bSpiral ? _debug_inds.first : _debug_inds.second)) - ptL2s = get<0>( vPntM[vIndBounds[2].first].CollisionInfo) ; - Point3d ptL2e ; - if ( ! CalcShapedPoint( vPntM[vIndBounds[3].first].CollisionInfo, vPntM[vIndBounds[3].second].CollisionInfo, - bSpiral, vtAxL, vtMoveL, dClippingAngle, pCAvTlStm, ptL2e, bSpiral ? _debug_inds.first : _debug_inds.second)) - ptL2e = get<0>( vPntM[vIndBounds[3].first].CollisionInfo) ; + // inserisco il secondo se esiste + if ( nSegCnt == 2) { + Point3d ptL2s = umEdgePnt.find( vKey[nI2s])->second ; + Point3d ptL2e = umEdgePnt.find( vKey[nI2e])->second ; vBiPnt.emplace_back( ptL2s, ptL2e) ; Vector3d vtDir2 = ptL2e - ptL2s ; vtDir2.Normalize() ; chainC.AddCurve( int( vBiPnt.size()), ptL2s, vtDir2, ptL2e, vtDir2) ; #if ENABLE_OPTIMAL_DEBUG - PtrOwner myLine( CreateCurveLine()) ; - myLine->Set( ptL2s, ptL2e) ; - if ( ! IsNull( myLine) && myLine->IsValid()) { - myLine->SetExtrusion( vtAxL) ; - int _a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, bSpiral ? nLyS : nLyZC, myLine->Clone()) ; - m_pGeomDB->SetMaterial( _a, YELLOW) ; - } + PtrOwner pMyLine( CreateCurveLine()) ; + pMyLine->Set( ptL2s, ptL2e) ; + pMyLine->SetExtrusion( vtAxL) ; + int a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, _nInd_debug, Release( pMyLine)) ; + m_pGeomDB->SetMaterial( a, YELLOW) ; #endif } } } } - // recupero i contorni + // Recupero i contorni INTVECTOR vnId ; while ( chainC.GetChainFromNear( ORIG, false, vnId)) { // creo la curva @@ -4101,6 +4240,7 @@ SurfFinishing::GetOptimalSfr( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& // angolo di scelta per divisione dei triangoli double dSplitAngle = 45. ; GetValInNotes( m_Params.m_sUserNotes, "SplitAngle", dSplitAngle) ; + double dCosClipping = cos( dSplitAngle * DEGTORAD) ; // costanti const double TOL_SAMPLE = 2. ; // Tolleranza di campionamento per collisioni @@ -4126,8 +4266,8 @@ SurfFinishing::GetOptimalSfr( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& frXY.ChangeOrig( GetToGlob( BBoxLoc.GetMin(), frXY)) ; // definisco una griglia di ( sempre in FrLoc) - PNTUVVECTLIST lPntM ; // per TestPath con collisioni (lista) - INTVECTOR vIndBorder ; // indici di bordo + PNTUVVECTVECTOR vPntM( ( nStepX + 1) * ( nStepY + 1)) ; // per TestPath con collisioni + INTVECTOR vIndBorder ; // indici di bordo for ( int j = 0 ; j <= nStepY ; ++ j) { for ( int i = 0 ; i <= nStepX ; ++ i) { int nInd = i + j * ( nStepX + 1) ; @@ -4136,12 +4276,12 @@ SurfFinishing::GetOptimalSfr( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vIndBorder.push_back( nInd) ; // controtraslo i punti della lunghezza utensile ptTest.Translate( vtAxL * ( m_TParams.m_dLen - dDepth)) ; - lPntM.emplace_back( make_tuple( ptTest, 0., VCT3DVECTOR{V_NULL})) ; + vPntM[nInd] = ( make_tuple( ptTest, 0., VCT3DVECTOR{V_NULL})) ; } } // effettuo verifica Collisione avanzata ( i versori normali sono solo quelli ad alzata massima dalle superfici) - if ( ! pCAvTlStm->TestPointsAdv( lPntM, vtAxL, vtMoveL)) + if ( ! pCAvTlStm->TestSeriesAdv( vPntM, vtAxL, vtMoveL)) return false ; #if ENABLE_OPTIMAL_DEBUG @@ -4159,59 +4299,55 @@ SurfFinishing::GetOptimalSfr( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& m_pGeomDB->SetStatus( nLyN, GDB_ST_OFF) ; #endif - // controllo dei versori normali di collisione per Marching Square - // NB. viene definita una struttura con due booleani, il primo associato al Marching Square - // per la superficie Spiral e il secondo per la superficie ZConst - VECTORCOLLISIONSFR vCollision( ( nStepX + 1) * ( nStepY + 1)) ; - int nInd = 0 ; - double dCosClipping = cos( dSplitAngle * DEGTORAD) ; - for ( auto it = lPntM.begin() ; it != lPntM.end() ; ++ it) { - // inserisco il punto di Test - get<0>( vCollision[nInd].CollisionInfo) = get<0>( *it) ; - // controllo se il punto è sulla frontiera del Box2d della griglia - bool bOnBorder = ( find( vIndBorder.begin(), vIndBorder.end(), nInd) != vIndBorder.end()) ; - // inserisco il parametro dU di salita del tool per evitare la collisione - get<1>( vCollision[nInd].CollisionInfo) = ( bOnBorder ? INFINITO : get<1>( *it)) ; - // inserisco i versori tangenti di collisione e valuto quale superficie ( Spiral o ZConst) è definita - vCollision[nInd].bInSpiral = false ; - vCollision[nInd].bInZConst = false ; - for ( int nV = 0 ; nV < int( get<2>( *it).size()) ; ++ nV) { - if ( ! bOnBorder) { - double dAbsCos = abs( get<2>( *it)[nV] * vtAxL) ; - if ( ! vCollision[nInd].bInZConst) - vCollision[nInd].bInZConst = ( dAbsCos < dCosClipping + EPS_ANG_ZERO) ; // theta <= ClippingAng - if ( ! vCollision[nInd].bInSpiral) - vCollision[nInd].bInSpiral = ( dAbsCos > dCosClipping + EPS_ANG_ZERO) ; // theta > ClippingAng + // definisco nuovi parametri per marching Square + VECTORCOLLISIONSFR vCollision( vPntM.size()) ; + for ( int j = 0 ; j <= nStepY ; ++ j) { + for ( int i = 0 ; i <= nStepX ; ++ i) { + int nInd = i + j * ( nStepX + 1) ; + get<0>( vCollision[nInd].CollisionInfo) = get<0>( vPntM[nInd]) ; + bool bOnBorder = ( find( vIndBorder.begin(), vIndBorder.end(), nInd) != vIndBorder.end()) ; + get<1>( vCollision[nInd].CollisionInfo) = ( bOnBorder ? INFINITO : get<1>( vPntM[nInd])) ; + vCollision[nInd].bInSpiral = false ; + vCollision[nInd].bInZConst = false ; + for ( int nV = 0 ; nV < int( get<2>( vPntM[nInd]).size()) ; ++ nV) { + if ( ! bOnBorder) { + double dAbsCos = abs( get<2>( vPntM[nInd])[nV] * vtAxL) ; + if ( ! vCollision[nInd].bInZConst) + vCollision[nInd].bInZConst = ( dAbsCos < dCosClipping + EPS_ANG_ZERO) ; // theta <= ClippingAng + if ( ! vCollision[nInd].bInSpiral) + vCollision[nInd].bInSpiral = ( dAbsCos > dCosClipping + EPS_ANG_ZERO) ; // theta > ClippingAng + } + get<2>( vCollision[nInd].CollisionInfo).push_back( get<2>( vPntM[nInd])[nV]) ; } - get<2>( vCollision[nInd].CollisionInfo).push_back( get<2>( *it)[nV]) ; + #if ENABLE_OPTIMAL_DEBUG + PtrOwner pt( CreateGeoPoint3d()) ; + pt->Set( get<0>( vCollision[nInd].CollisionInfo)) ; + int _pS = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLyS, pt->Clone()) ; + int _pZC = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLyZC, pt->Clone()) ; + Color myColS = ( vCollision[nInd].bInSpiral ? RED : BLUE) ; + Color myColZC = ( vCollision[nInd].bInZConst ? RED : BLUE) ; + m_pGeomDB->SetMaterial( _pS, myColS) ; + m_pGeomDB->SetMaterial( _pZC, myColZC) ; + for ( int nV = 0 ; nV < int( get<2>( vCollision[nInd].CollisionInfo).size()) ; ++ nV) { + PtrOwner vt( CreateGeoVector3d()) ; + vt->Set( get<2>( vCollision[nInd].CollisionInfo)[nV]) ; + vt->Translate( pt->GetPoint() - ORIG) ; + int _vN = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLyN, vt->Clone()) ; + m_pGeomDB->SetMaterial( _vN, Color( abs( vt->GetVector().x), abs( vt->GetVector().y), abs( vt->GetVector().z))) ; + } + #endif } - #if ENABLE_OPTIMAL_DEBUG - PtrOwner pt( CreateGeoPoint3d()) ; - pt->Set( get<0>( vCollision[nInd].CollisionInfo)) ; - int _pS = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLyS, pt->Clone()) ; - int _pZC = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLyZC, pt->Clone()) ; - Color myColS = ( vCollision[nInd].bInSpiral ? RED : BLUE) ; - Color myColZC = ( vCollision[nInd].bInZConst ? RED : BLUE) ; - m_pGeomDB->SetMaterial( _pS, myColS) ; - m_pGeomDB->SetMaterial( _pZC, myColZC) ; - for ( int nV = 0 ; nV < int( get<2>( vCollision[nInd].CollisionInfo).size()) ; ++ nV) { - PtrOwner vt( CreateGeoVector3d()) ; - vt->Set( get<2>( vCollision[nInd].CollisionInfo)[nV]) ; - vt->Translate( pt->GetPoint() - ORIG) ; - int _vN = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLyN, vt->Clone()) ; - m_pGeomDB->SetMaterial( _vN, Color( abs( vt->GetVector().x), abs( vt->GetVector().y), abs( vt->GetVector().z))) ; - } - #endif - ++ nInd ; } ICRVCOMPOPOVECTOR vCrvSpiral, vCrvZConst ; int nThreadMax = thread::hardware_concurrency() ; if ( nThreadMax <= 1) { // recupero le curve di contorno per la superficie Spiral + ICRVCOMPOPOVECTOR vCrvSpiral ; if ( ! MarchingSquares( vCollision, true, TOL_SAMPLE / 2., nStepX, nStepY, dSplitAngle, vtAxL, vtMoveL, pCAvTlStm, vCrvSpiral)) return false ; // recupero le curve di contorno per la superficie ZConst + ICRVCOMPOPOVECTOR vCrvZConst ; if ( ! MarchingSquares( vCollision, false, TOL_SAMPLE / 2., nStepX, nStepY, dSplitAngle, vtAxL, vtMoveL, pCAvTlStm, vCrvZConst)) return false ; } @@ -4430,7 +4566,7 @@ SurfFinishing::AddOptimal( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSr // ----------------------- Lavorazione Zconst ------------------------------- if ( ! IsNull( pSfrZConst) && pSfrZConst->IsValid()) { // mi assicuro di non uscire dalla superficie originale - PtrOwner pSfrOverlap( pSfr->CreateOffsetSurf( m_Params.m_dOverlap, ICurve::OFF_FILLET)) ; + PtrOwner pSfrOverlap( pSfr->CreateOffsetSurf( m_Params.m_dOverlap + GetOffsR(), ICurve::OFF_FILLET)) ; if ( ! IsNull( pSfrOverlap) && pSfrOverlap->IsValid()) { if ( ! pSfrOverlap->ToLoc( frSurf) || ! pSfrZConst->Intersect( *pSfrOverlap)) return false ; @@ -4450,10 +4586,16 @@ SurfFinishing::AddOptimal( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSr if ( pStm != nullptr && pStm->IsValid() && pStm->GetTriangleCount() > 0) vpStm.emplace_back( pStm) ; } + // definisco il frame della regione piana + Frame3d frSfr ; + Point3d ptC ; pSfrZConst->GetCentroid( ptC) ; + if ( ! frSfr.Set( ptC, pSfrZConst->GetNormVersor())) + return false ; + // inizializzo classe di calcolo per le curve a ZConst PtrOwner pCavParSilh( CreateCAvParSilhouettesSurfTm()) ; if ( IsNull( pCavParSilh) || - ! pCavParSilh->SetDataForRegion( vpStm, pSfrZConst, m_TParams.m_dSideAng, m_TParams.m_dDiam, - m_TParams.m_dCornRad, m_TParams.m_dMaxMat, GetOffsR(), SILH_SAMPLING, ANG_TOL_STD_DEG)) + ! pCavParSilh->SetData( vpStm, frSfr, SILH_SAMPLING, m_TParams.m_dSideAng, m_TParams.m_dDiam, + m_TParams.m_dCornRad, m_TParams.m_dMaxMat, GetOffsR(), dDepth)) return false ; // recupero le curve singole definite dal bordo della Silhouette vector vCrvCompo ; diff --git a/SurfFinishing.h b/SurfFinishing.h index a2ce0cd..9799736 100644 --- a/SurfFinishing.h +++ b/SurfFinishing.h @@ -115,7 +115,7 @@ class SurfFinishing : public Machining bool AddZConst( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSrfLoc, const Frame3d& frSurf, const ISurfFlatRegion* pSfr, const Vector3d& vtTool, double dDepth, double dElev, bool bSplitArcs) ; bool AddOptimal( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSrfLoc, const Frame3d& frSurf, const ISurfFlatRegion* pSfr, - const Vector3d& vtTool, double dDepth, double dElev, bool bSplitArcs) ; + const Vector3d& vtTool, double dDepth, double dElev, bool bSplitArcs) ; // lavorazioni per curve bool AddProjection( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSrfLoc, const Frame3d& frSurf, const ICurveComposite* pCompo, const Vector3d& vtTool, double dDepth, double dElev, bool bSplitArcs) ; @@ -129,7 +129,6 @@ class SurfFinishing : public Machining ISURFTMPOVECTOR& vpStm1, ISURFTMPOVECTOR& vpStm2, double& dMaxFrontTriaRad) const ; bool GetZConstQuotesInsideSfrParallelToTool( const SURFLOCALVECTOR&, const Frame3d& frSurf, const ISurfFlatRegion* pSfr, const Vector3d& vtTool, std::set& setZAmbiguos) ; - ICAvParSilhouettesSurfTm* GetParSilhouettesForZConst( const ISURFTMPOVECTOR& vStm, const ISurfFlatRegion* pSfr) const ; ISurfFlatRegion* GetSfrSilhouette( const SURFLOCALVECTOR& vSrfLoc, const Frame3d& frLvl0, double dDepth) const ; ISurfFlatRegion* GetSfrProjectedStmLoops( const ISURFTMPOVECTOR& vStm, const ISurfFlatRegion* pSfrContour, const DBLVECTOR& vdLinFeaTol, const DBLVECTOR& vdAngTol, const DBLVECTOR& vdMaxLinTol) const ; @@ -154,11 +153,16 @@ class SurfFinishing : public Machining bool GetSurfaceNormalAtPoint( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, const Point3d& ptTool, const Vector3d& vtTool, Vector3d& vtNorm) const ; bool GetActiveSurfaces( INTVECTOR& vSurfId) const ; + int ProcessSquare( int nFlag, double dLevel, double dQPt0, double dQpt1, double dQpt2, double dQpt3, + int& nI1s, int& nI1e, int& nI2s, int& nI2e) const ; + Point3d CalcShapedPoint( const PNTUVVECT& myInfoStart, const PNTUVVECT& myInfoEnd, bool bSpiral, const Vector3d& vtAxL, + const Vector3d& vtMoveL, double dCosSplitAngle, ICAvToolSurfTm* pCAvTlStm, int _nInd_debug) const ; + bool TestSubEdges( std::unordered_map& umEdgePnt, const INTVECTOR& vEdgeInd, bool bSpiral, int nFirst, int nLast, + const VECTORCOLLISIONSFR& vPntM, int nStepX, const Vector3d vtAxL, const Vector3d& vtMoveL, + double dCosSplitAng, ICAvToolSurfTm* pCAvTlStm, int _nInd_debug) const ; bool MarchingSquares( const VECTORCOLLISIONSFR& vPntM, bool bSpiral, double dOffsTol, int nStepX, int nStepY, double dClippingAngle, const Vector3d& vtAxL, const Vector3d& vtMoveL, ICAvToolSurfTm* pCAvTlStm, ICRVCOMPOPOVECTOR& vCrvCompo) const ; - bool CalcShapedPoint( const PNTUVVECT& myInfoStart, const PNTUVVECT& myInfoEnd, bool bSpiral, const Vector3d& vtAxL, - const Vector3d& vtMoveL, double dClippingAngle, ICAvToolSurfTm* pCAvTlStm, Point3d& ptShaped, int _debug_ind = -1) const ; double GetRightFeed( const Vector3d& vtMove, const Vector3d& vtTool) const ; double GetRadiusForStartEndElevation( void) const ; diff --git a/SurfRoughing.cpp b/SurfRoughing.cpp index 2cf6e56..c110fbc 100644 --- a/SurfRoughing.cpp +++ b/SurfRoughing.cpp @@ -2173,7 +2173,8 @@ SurfRoughing::GetSfrSilhouette( ICAvParSilhouettesSurfTm* pCavParSilh, double dD if ( ! IsNull( pTempCrv) && pTempCrv->FromPolyArc( PA) && pTempCrv->RemoveSmallDefects( SILH_ARC_TOL / 2, ANG_TOL_STD_DEG) && - pTempCrv->MergeCurves( SILH_ARC_TOL / 2, ANG_TOL_STD_DEG)) + pTempCrv->MergeCurves( SILH_ARC_TOL / 2, ANG_TOL_STD_DEG) && + pTempCrv->IsValid()) pSilCrv.Set( pTempCrv) ; } // aggiungo per regione