diff --git a/CurveArc.cpp b/CurveArc.cpp index 1d64693..910e7e2 100644 --- a/CurveArc.cpp +++ b/CurveArc.cpp @@ -878,23 +878,35 @@ CurveArc::ApproxWithArcs( double dLinTol, double dAngTolDeg, PolyArc& PA) const if ( m_nStatus != OK) return false ; - // la curva deve avere normale coincidente con Z - if ( ! m_VtN.IsZplus() && ! m_VtN.IsZminus()) - return false ; + // se l'arco non ha direzione normale coincidente con Z, approssimo con rette + if ( ! m_VtN.IsZplus() && ! m_VtN.IsZminus()) { + ArcApproxer aAppr( dLinTol, dAngTolDeg, true, *this) ; + double dU ; + Point3d ptPos ; + while ( aAppr.GetPoint( dU, ptPos)) { + if ( ! PA.AddUPoint( dU, ptPos, 0)) + return false ; + } + } - // inserisco punto iniziale con bulge - Point3d ptStart ; - GetStartPoint( ptStart) ; - double dBulge = tan( m_dAngCenDeg / 4 * DEGTORAD) ; - if ( m_VtN.IsZminus()) - dBulge = - dBulge ; - if ( ! PA.AddUPoint( 0, ptStart, dBulge)) - return false ; + // calcolo il numero di archi con bulge da usare ( ognuno deve avere un angolo al centro <= 240deg) + const double MAX_ANG_ARC_BULGE = 240 ; + int nArcs = int( ceil( fabs( m_dAngCenDeg) / MAX_ANG_ARC_BULGE)) ; + nArcs = max( nArcs, 1) ; + double dBulge = tan( m_dAngCenDeg / ( 4 * nArcs) * DEGTORAD) ; + // inserisco i punti di inizio di ogni arco + for ( int i = 0 ; i < nArcs ; ++ i) { + Point3d ptStart ; + double dU = i / double( nArcs) ; + if ( ! GetPointD1D2( dU, ICurve::FROM_MINUS, ptStart) || + ! PA.AddUPoint( dU, ptStart, dBulge)) + return false ; + } // inserisco punto finale senza bulge Point3d ptEnd ; - GetEndPoint( ptEnd) ; - if ( ! PA.AddUPoint( 1, ptEnd, 0)) + if ( ! GetEndPoint( ptEnd) || + ! PA.AddUPoint( 1, ptEnd, 0)) return false ; return true ; diff --git a/CurveComposite.cpp b/CurveComposite.cpp index 452dfda..a9d010e 100644 --- a/CurveComposite.cpp +++ b/CurveComposite.cpp @@ -270,33 +270,33 @@ CurveComposite::FromSplit( const ICurve& cCrv, int nParts) //---------------------------------------------------------------------------- bool -CurveComposite::FromPointVector( const PNTVECTOR& vPnt) +CurveComposite::FromPolyLine( const PolyLine& PL) { // verifico lo stato if ( m_nCounter != 0 || m_nStatus != TO_VERIFY) return false ; - // devono essere almeno 2 punti - if ( vPnt.size() < 2) + // deve esserci almeno 1 linea (2 punti) + if ( PL.GetLineNbr() < 1) return false ; // ciclo di inserimento dei segmenti che uniscono i punti - int iPrev = 0 ; - for ( int i = 1 ; i < int( vPnt.size()) ; ++ i) { + Point3d ptIni, ptFin ; + for ( bool bFound = PL.GetFirstLine( ptIni, ptFin) ; + bFound ; + bFound = PL.GetNextLine( ptIni, ptFin)) { // se i punti della coppia coincidono, passo alla coppia successiva - if ( AreSamePointApprox( vPnt[iPrev], vPnt[i])) + if ( AreSamePointApprox( ptIni, ptFin)) continue ; // creo il segmento di retta PtrOwner pCrvLine( CreateCurveLine()) ; if ( ! ::IsValid( pCrvLine)) return false ; // assegno i punti estremi - if ( ! pCrvLine->Set( vPnt[iPrev], vPnt[i])) + if ( ! pCrvLine->Set( ptIni, ptFin)) return false ; // aggiungo la retta alla curva composita if ( ! AddSimpleCurve( Release( pCrvLine))) return false ; - // aggiorno indice punto ultimo inserito - iPrev = i ; } // imposto ricalcolo della grafica @@ -307,29 +307,32 @@ CurveComposite::FromPointVector( const PNTVECTOR& vPnt) //---------------------------------------------------------------------------- bool -CurveComposite::FromPointBulgeVector( const UPNTVECTOR& vUPnt, const Vector3d& vtN) +CurveComposite::FromPolyArc( const PolyArc& PA) { // verifico lo stato if ( m_nCounter != 0 || m_nStatus != TO_VERIFY) return false ; - // devono essere almeno 2 punti - if ( vUPnt.size() < 2) + // deve esserci almeno 1 arco (2 punti) + if ( PA.GetArcNbr() < 1) return false ; // Creo le diverse curve semplici e le inserisco in quella composita - int iPrev = 0 ; - for ( int i = 1 ; i < int( vUPnt.size()) ; ++i) { + double dBulge ; + Point3d ptIni, ptFin ; + for ( bool bFound = PA.GetFirstArc( ptIni, ptFin, dBulge) ; + bFound ; + bFound = PA.GetNextArc( ptIni, ptFin, dBulge)) { // se i punti della coppia coincidono, passo alla coppia successiva - if ( AreSamePointApprox( vUPnt[iPrev].second, vUPnt[i].second)) + if ( AreSamePointApprox( ptIni, ptFin)) continue ; // se retta - if ( fabs( vUPnt[i-1].first) < EPS_SMALL) { + if ( fabs( dBulge) < EPS_SMALL) { // creo la retta PtrOwner pCrvLine( CreateBasicCurveLine()) ; if ( ! ::IsValid( pCrvLine)) return false ; // setto la linea - if ( ! pCrvLine->Set( vUPnt[iPrev].second, vUPnt[i].second)) + if ( ! pCrvLine->Set( ptIni, ptFin)) return false ; // inserisco la linea nella curva composta if ( ! AddSimpleCurve( ::Release( pCrvLine))) @@ -342,14 +345,12 @@ CurveComposite::FromPointBulgeVector( const UPNTVECTOR& vUPnt, const Vector3d& v if ( ! ::IsValid( pCrvArc)) return false ; // setto l'arco - if ( ! pCrvArc->Set2PNB( vUPnt[iPrev].second, vUPnt[i].second, vtN, vUPnt[i-1].first)) + if ( ! pCrvArc->Set2PNB( ptIni, ptFin, PA.GetExtrusion(), dBulge)) return false ; // inserisco l'arco nella curva composta if ( ! AddSimpleCurve( Release( pCrvArc))) return false ; } - // aggiorno indice punto ultimo inserito - iPrev = i ; } return true ; diff --git a/CurveComposite.h b/CurveComposite.h index 2d836a4..494adaf 100644 --- a/CurveComposite.h +++ b/CurveComposite.h @@ -106,8 +106,8 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW virtual bool AddCurve( const ICurve& cCrv, bool bEndOrStart = true, double dLinTol = EPS_SMALL) ; virtual bool AddCurve( ICurve* pCrv, bool bEndOrStart = true, double dLinTol = EPS_SMALL) ; virtual bool FromSplit( const ICurve& cCrv, int nParts) ; - virtual bool FromPointVector( const PNTVECTOR& vPnt) ; - virtual bool FromPointBulgeVector( const UPNTVECTOR& vUPnt, const Vector3d& vtN) ; + virtual bool FromPolyLine( const PolyLine& PL) ; + virtual bool FromPolyArc( const PolyArc& PA) ; virtual bool PolygonCenterCorner( int nSides, const Point3d& ptCen, const Point3d& ptCorner) ; virtual bool PolygonCenterMidSide( int nSides, const Point3d& ptCen, const Point3d& ptMidSide) ; virtual bool PolygonSide( int nSides, const Point3d& ptStart, const Point3d& ptEnd) ; diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc index 9b33d94..2c0006b 100644 Binary files a/EgtGeomKernel.rc and b/EgtGeomKernel.rc differ diff --git a/EgtGeomKernel.vcxproj b/EgtGeomKernel.vcxproj index e6ab123..bf9c44a 100644 --- a/EgtGeomKernel.vcxproj +++ b/EgtGeomKernel.vcxproj @@ -99,6 +99,7 @@ true CompileAsCpp false + true Windows @@ -131,6 +132,7 @@ copy $(TargetPath) \EgtProg\Dll32 true CompileAsCpp false + true Windows @@ -166,6 +168,8 @@ copy $(TargetPath) \EgtProg\Dll64 CompileAsCpp Speed AnySuitable + true + StreamingSIMDExtensions2 Windows @@ -202,6 +206,8 @@ copy $(TargetPath) \EgtProg\Dll32 CompileAsCpp Speed AnySuitable + true + StreamingSIMDExtensions2 Windows diff --git a/EgtGeomKernel.vcxproj.filters b/EgtGeomKernel.vcxproj.filters index 330684e..f677f16 100644 --- a/EgtGeomKernel.vcxproj.filters +++ b/EgtGeomKernel.vcxproj.filters @@ -37,6 +37,9 @@ {7284f71c-3fd5-4bb9-bfe6-2c8c312985cc} + + {40599d8d-b02a-4202-a057-4dc3ebb5fe05} + @@ -233,21 +236,6 @@ File di intestazione - - File di intestazione - - - File di intestazione - - - File di intestazione - - - File di intestazione - - - File di intestazione - File di intestazione @@ -257,24 +245,6 @@ File di intestazione - - File di intestazione - - - File di intestazione - - - File di intestazione - - - File di intestazione - - - File di intestazione - - - File di intestazione - File di intestazione @@ -284,30 +254,15 @@ File di intestazione - - File di intestazione - - - File di intestazione - File di intestazione File di intestazione - - File di intestazione - - - File di intestazione - File di intestazione - - File di intestazione - File di intestazione @@ -317,90 +272,36 @@ File di intestazione - - File di intestazione - File di intestazione - - File di intestazione - File di intestazione - - File di intestazione - - - File di intestazione - - - File di intestazione - - - File di intestazione - File di intestazione - - File di intestazione - - - File di intestazione - - - File di intestazione - File di intestazione File di intestazione - - File di intestazione - File di intestazione - - File di intestazione - - - File di intestazione - - - File di intestazione - File di intestazione File di intestazione - - File di intestazione - - - File di intestazione - File di intestazione - - File di intestazione - File di intestazione - - File di intestazione - - - File di intestazione - File di intestazione @@ -413,12 +314,6 @@ File di intestazione - - File di intestazione - - - File di intestazione - File di intestazione @@ -431,18 +326,9 @@ File di intestazione - - File di intestazione - - - File di intestazione - File di intestazione - - File di intestazione - File di intestazione @@ -458,27 +344,15 @@ File di intestazione - - File di intestazione - File di intestazione File di intestazione - - File di intestazione - - - File di intestazione - File di intestazione - - File di intestazione - File di intestazione @@ -491,21 +365,9 @@ File di intestazione - - File di intestazione - - - File di intestazione - File di intestazione - - File di intestazione - - - File di intestazione - File di intestazione @@ -518,18 +380,6 @@ File di intestazione - - File di intestazione - - - File di intestazione - - - File di intestazione - - - File di intestazione - File di intestazione @@ -539,8 +389,161 @@ File di intestazione + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + - File di intestazione + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include + + + File di intestazione\Include diff --git a/GdbExecutor.cpp b/GdbExecutor.cpp index 1851c2e..45f8ba5 100644 --- a/GdbExecutor.cpp +++ b/GdbExecutor.cpp @@ -1606,6 +1606,9 @@ GdbExecutor::ExecuteCurveCompo( const string& sCmd2, const STRVECTOR& vsParams) // creazione per interpolazione di punti else if ( sCmd2 == "PINTERP" || sCmd2 == "FROMPOINTINTERPOLATION") return CurveCompoFromPointInterpolation( vsParams) ; + // creazione per approssimazione di curva + else if ( sCmd2 == "CAPPROX" || sCmd2 == "FROMCURVEAPPROXIMATION") + return CurveCompoFromCurveApproximation( vsParams) ; // creazione da split di curva semplice else if ( sCmd2 == "S" || sCmd2 == "FROMSPLIT") return CurveCompoFromSplit( vsParams) ; @@ -1724,15 +1727,15 @@ GdbExecutor::CurveCompoFromPoints( const STRVECTOR& vsParams) if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frDest)) return false ; // recupero i punti - PNTVECTOR vPoints ; - if ( ! GetPointsParam( vsParams[2], frDest, vPoints)) + PolyLine PL ; + if ( ! GetPointsParam( vsParams[2], frDest, PL)) return false ; // creo la curva composita PtrOwner pCrvCompo( CreateCurveComposite()) ; if ( ! IsValid( pCrvCompo)) return false ; // inserisco i segmenti che uniscono i punti - if ( ! pCrvCompo->FromPointVector( vPoints)) + if ( ! pCrvCompo->FromPolyLine( PL)) return false ; // inserisco la curva composita nel DB return AddGeoObj( vsParams[0], vsParams[1], Release( pCrvCompo)) ; @@ -1750,15 +1753,15 @@ GdbExecutor::CurveCompoFromPointBulges( const STRVECTOR& vsParams) if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frDest)) return false ; // recupero i punti - UPNTVECTOR vPointWs ; - if ( ! GetPointWsParam( vsParams[2], frDest, vPointWs)) + PolyArc PA ; + if ( ! GetPointWsParam( vsParams[2], frDest, PA)) return false ; // creo la curva composita PtrOwner pCrvCompo( CreateCurveComposite()) ; if ( ! IsValid( pCrvCompo)) return false ; // inserisco i segmenti che uniscono i punti - if ( ! pCrvCompo->FromPointBulgeVector( vPointWs, Z_AX)) + if ( ! pCrvCompo->FromPolyArc( PA)) return false ; // inserisco la curva composita nel DB return AddGeoObj( vsParams[0], vsParams[1], Release( pCrvCompo)) ; @@ -1776,8 +1779,8 @@ GdbExecutor::CurveCompoFromPointInterpolation( const STRVECTOR& vsParams) if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frDest)) return false ; // recupero i punti - PNTVECTOR vPoints ; - if ( ! GetPointsParam( vsParams[2], frDest, vPoints)) + PolyLine PL ; + if ( ! GetPointsParam( vsParams[2], frDest, PL)) return false ; // recupero il metodo di interpolazione string sMethod = vsParams[3] ; @@ -1800,8 +1803,11 @@ GdbExecutor::CurveCompoFromPointInterpolation( const STRVECTOR& vsParams) // oggetto interpolatore CurveByInterp crvByInterp ; crvByInterp.Start() ; - for ( int i = 0 ; i < int( vPoints.size()) ; ++ i) - crvByInterp.AddPoint( vPoints[i]) ; + Point3d ptP ; + for ( bool bFound = PL.GetFirstPoint( ptP) ; + bFound ; + bFound = PL.GetNextPoint( ptP)) + crvByInterp.AddPoint( ptP) ; crvByInterp.End() ; PtrOwner pCrv( crvByInterp.GetCurve( nMethod, nType)) ; if ( ! ::IsValid( pCrv)) @@ -1810,6 +1816,51 @@ GdbExecutor::CurveCompoFromPointInterpolation( const STRVECTOR& vsParams) return AddGeoObj( vsParams[0], vsParams[1], ::Release( pCrv)) ; } +//---------------------------------------------------------------------------- +bool +GdbExecutor::CurveCompoFromCurveApproximation( const STRVECTOR& vsParams) +{ + // 5 parametri : Id, ParentId, SouCrvId, Method, dLinTol5 + if ( vsParams.size() != 5) + return false ; + // recupero il riferimento del gruppo destinazione + Frame3d frDest ; + if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frDest)) + return false ; + // recupero Id della curva sorgente + int nSouId = GetIdParam( vsParams[2]) ; + // recupero il tipo di approssimazione + string sType = vsParams[3] ; + ToUpper( sType) ; + int nType = 1 ; + if ( sType == "LINES") + nType = 1 ; + else if ( sType == "BIARCS") + nType = 2 ; + // recupero la tolleranza lineare + double dLinTol ; + if ( ! FromString( vsParams[4], dLinTol)) + return false ; + // eseguo l'approssimazione + PtrOwner pCC( CreateCurveComposite()) ; + if ( ! IsValid( pCC)) + return false ; + if ( nType == 1) { // con linee + PolyLine PL ; + if ( ! GetPolyLineFromCurve( nSouId,frDest, dLinTol, PL) || + ! pCC->FromPolyLine( PL)) + return false ; + } + else { // con bi-archi + PolyArc PA ; + if ( ! GetPolyArcFromCurve( nSouId,frDest, dLinTol, PA) || + ! pCC->FromPolyArc( PA)) + return false ; + } + // inserisco la curva composita nel DB + return AddGeoObj( vsParams[0], vsParams[1], ::Release( pCC)) ; +} + //---------------------------------------------------------------------------- bool GdbExecutor::CurveCompoFromSplit( const STRVECTOR& vsParams) @@ -2279,7 +2330,7 @@ GdbExecutor::SurfTriMeshByContour( const STRVECTOR& vsParams) return false ; // calcolo la polilinea che approssima la curva PolyLine PL ; - if ( ! GetPolylineFromCurve( nIdCrv, frDest, dLinTol, PL)) + if ( ! GetPolyLineFromCurve( nIdCrv, frDest, dLinTol, PL)) return false ; // creo la superficie PtrOwner pSTM( CreateSurfTriMesh()) ; @@ -2311,7 +2362,7 @@ GdbExecutor::SurfTriMeshByExtrusion( const STRVECTOR& vsParams) return false ; // calcolo la polilinea che approssima la curva PolyLine PL ; - if ( ! GetPolylineFromCurve( nIdCrv, frDest, dLinTol, PL)) + if ( ! GetPolyLineFromCurve( nIdCrv, frDest, dLinTol, PL)) return false ; // recupero il vettore di estrusione Vector3d vtExtr ; @@ -2347,13 +2398,13 @@ GdbExecutor::SurfTriMeshByTwoPaths( const STRVECTOR& vsParams) int nIdCrv1 = GetIdParam( vsParams[2]) ; // calcolo la polilinea che approssima la prima curva PolyLine PL1 ; - if ( ! GetPolylineFromCurve( nIdCrv1, frDest, dLinTol, PL1)) + if ( ! GetPolyLineFromCurve( nIdCrv1, frDest, dLinTol, PL1)) return false ; // recupero l'identificativo della seconda curva int nIdCrv2 = GetIdParam( vsParams[3]) ; // calcolo la polilinea che approssima la seconda curva PolyLine PL2 ; - if ( ! GetPolylineFromCurve( nIdCrv2, frDest, dLinTol, PL2)) + if ( ! GetPolyLineFromCurve( nIdCrv2, frDest, dLinTol, PL2)) return false ; // creo la superficie PtrOwner pSTM( CreateSurfTriMesh()) ; @@ -2403,7 +2454,7 @@ GdbExecutor::SurfTriMeshByScrewing( bool bMove, const STRVECTOR& vsParams) return false ; // calcolo la polilinea che approssima la curva PolyLine PL ; - if ( ! GetPolylineFromCurve( nIdCrv, frDest, dLinTol, PL)) + if ( ! GetPolyLineFromCurve( nIdCrv, frDest, dLinTol, PL)) return false ; // recupero il punto dell'asse di rivoluzione Point3d ptAx ; @@ -2436,7 +2487,7 @@ GdbExecutor::SurfTriMeshByScrewing( bool bMove, const STRVECTOR& vsParams) //---------------------------------------------------------------------------- bool -GdbExecutor::GetPolylineFromCurve( int nId, const Frame3d& frDest, double dLinTol, PolyLine& PL) +GdbExecutor::GetPolyLineFromCurve( int nId, const Frame3d& frDest, double dLinTol, PolyLine& PL) { // recupero la curva const ICurve* pCrv = GetCurve( m_pGDB->GetGeoObj( nId)) ; @@ -2468,6 +2519,40 @@ GdbExecutor::GetPolylineFromCurve( int nId, const Frame3d& frDest, double dLinTo return true ; } +//---------------------------------------------------------------------------- +bool +GdbExecutor::GetPolyArcFromCurve( int nId, const Frame3d& frDest, double dLinTol, PolyArc& PA) +{ + // recupero la curva + const ICurve* pCrv = GetCurve( m_pGDB->GetGeoObj( nId)) ; + if ( pCrv == nullptr) + return false ; + // recupero il riferimento della curva + Frame3d frCrv ; + if ( ! m_pGDB->GetGlobFrame( nId, frCrv)) + return false ; + // calcolo la polilinea che approssima la curva + // se i riferimenti sono uguali + if ( AreSameFrame( frCrv, frDest)) { + // ricavo l'approssimazione + if ( ! pCrv->ApproxWithArcs( dLinTol, ANG_TOL_STD_DEG, PA)) + return false ; + } + // altrimenti devo prima trasformare la curva + else { + // creo una copia della curva (da buttare alla fine) + PtrOwner pModCrv( pCrv->Clone()) ; + if ( ! IsValid( pModCrv)) + return false ; + // eseguo la trasformazione + pModCrv->LocToLoc( frCrv, frDest) ; + // ricavo l'approssimazione + if ( ! pModCrv->ApproxWithArcs( dLinTol, ANG_TOL_STD_DEG, PA)) + return false ; + } + return true ; +} + //---------------------------------------------------------------------------- bool GdbExecutor::SurfTriMeshChangeSmoothAng( const STRVECTOR& vsParams) @@ -3294,14 +3379,13 @@ GdbExecutor::GetPointParam( const string& sParam, const Frame3d& frPnt, Point3d& //---------------------------------------------------------------------------- bool -GdbExecutor::GetPointsParam( const string& sParam, const Frame3d& frPnt, PNTVECTOR& vPoints) +GdbExecutor::GetPointsParam( const string& sParam, const Frame3d& frPnt, PolyLine& PL) { // divido in parti STRVECTOR vsPoints ; Tokenize( sParam.substr( 1, sParam.length()-2), ",", "(", ")", vsPoints) ; // converto in punti - vPoints.clear() ; - vPoints.reserve( vsPoints.size()) ; + PL.Clear() ; STRVECTOR::iterator Iter ; for ( Iter = vsPoints.begin() ; Iter != vsPoints.end() ; ++Iter) { Trim( (*Iter), " \t\r\n") ; @@ -3309,17 +3393,17 @@ GdbExecutor::GetPointsParam( const string& sParam, const Frame3d& frPnt, PNTVECT int nId = m_pGDB->GetFirstSelectedObj() ; while ( nId != GDB_ID_NULL) { Point3d ptP ; - if ( ! GetPointParam( ToString( nId), frPnt, ptP)) + if ( ! GetPointParam( ToString( nId), frPnt, ptP) || + ! PL.AddUPoint( 0, ptP)) return false ; - vPoints.push_back( ptP) ; nId = m_pGDB->GetNextSelectedObj() ; } } else { Point3d ptP ; - if ( ! GetPointParam( *Iter, frPnt, ptP)) + if ( ! GetPointParam( *Iter, frPnt, ptP) || + ! PL.AddUPoint( 0, ptP)) return false ; - vPoints.push_back( ptP) ; } } @@ -3370,21 +3454,21 @@ GdbExecutor::GetPointWParam( const string& sParam, const Frame3d& frPnt, Point3d //---------------------------------------------------------------------------- bool -GdbExecutor::GetPointWsParam( const string& sParam, const Frame3d& frPnt, UPNTVECTOR& vPointWs) +GdbExecutor::GetPointWsParam( const string& sParam, const Frame3d& frPnt, PolyArc& PA) { // divido in parti STRVECTOR vsPointWs ; Tokenize( sParam.substr( 1, sParam.length()-2), ",", "(", ")", vsPointWs) ; // converto in punti - vPointWs.clear() ; - vPointWs.reserve( vsPointWs.size()) ; + PA.Clear() ; STRVECTOR::iterator Iter ; for ( Iter = vsPointWs.begin() ; Iter != vsPointWs.end() ; ++Iter) { Trim( (*Iter), " \t\r\n") ; - UPOINT ptPW ; - if ( ! GetPointWParam( *Iter, frPnt, ptPW.second, ptPW.first)) + Point3d ptP ; + double dBulge ; + if ( ! GetPointWParam( *Iter, frPnt, ptP, dBulge) || + ! PA.AddUPoint( 0, ptP, dBulge)) return false ; - vPointWs.push_back( ptPW) ; } return true ; diff --git a/GdbExecutor.h b/GdbExecutor.h index 6a20128..2871d17 100644 --- a/GdbExecutor.h +++ b/GdbExecutor.h @@ -20,6 +20,7 @@ #include "/EgtDev/Include/EgkGeoCollection.h" class PolyLine ; +class PolyArc ; //---------------------------------------------------------------------------- class GdbExecutor : public IGdbExecutor @@ -42,15 +43,16 @@ class GdbExecutor : public IGdbExecutor bool GetNamesParam( const std::string& sParam, INTVECTOR& vnNames) ; bool GetVectorParam( const std::string& sParam, const Frame3d& frVect, Vector3d& vtV) ; bool GetPointParam( const std::string& sParam, const Frame3d& frPnt, Point3d& ptP) ; - bool GetPointsParam( const std::string& sParam, const Frame3d& frPnt, PNTVECTOR& vPoints) ; + bool GetPointsParam( const std::string& sParam, const Frame3d& frPnt, PolyLine& PL) ; bool GetPointWParam( const std::string& sParam, const Frame3d& frPnt, Point3d& ptP, double& dW) ; - bool GetPointWsParam( const std::string& sParam, const Frame3d& frPnt, UPNTVECTOR& vPointWs) ; + bool GetPointWsParam( const std::string& sParam, const Frame3d& frPnt, PolyArc& PA) ; bool GetLengthParam( const std::string& sParam, double& dLen) ; bool GetDirParam( const std::string& sParam, const Frame3d& frDir, double& dDir) ; bool GetFrameParam( const std::string& sParam, const Frame3d& frRef, Frame3d& frF) ; bool GetColorParam( const std::string& sParam, bool& bByParent, Color& cCol) ; bool GetStringParam( const std::string& sParam, std::string& sString) ; - bool GetPolylineFromCurve( int nId, const Frame3d& frDest, double dLinTol, PolyLine& PL) ; + bool GetPolyLineFromCurve( int nId, const Frame3d& frDest, double dLinTol, PolyLine& PL) ; + bool GetPolyArcFromCurve( int nId, const Frame3d& frDest, double dLinTol, PolyArc& PA) ; bool ExecuteGroup( const std::string& sCmd2, const STRVECTOR& vsParams) ; bool ExecutePoint( const std::string& sCmd2, const STRVECTOR& vsParams) ; bool ExecuteVector( const std::string& sCmd2, const STRVECTOR& vsParams) ; @@ -92,6 +94,7 @@ class GdbExecutor : public IGdbExecutor bool CurveCompoFromPoints( const STRVECTOR& vsParams) ; bool CurveCompoFromPointBulges( const STRVECTOR& vsParams) ; bool CurveCompoFromPointInterpolation( const STRVECTOR& vsParams) ; + bool CurveCompoFromCurveApproximation( const STRVECTOR& vsParams) ; bool CurveCompoFromSplit( const STRVECTOR& vsParams) ; bool CurveCompoFromPolygon( const STRVECTOR& vsParams, int nType) ; bool CurveCompoFromBiarc( const STRVECTOR& vsParams) ; diff --git a/PolyArc.cpp b/PolyArc.cpp index 4111594..3f61b01 100644 --- a/PolyArc.cpp +++ b/PolyArc.cpp @@ -19,6 +19,8 @@ //---------------------------------------------------------------------------- PolyArc::PolyArc( void) { + m_vtExtr = Z_AX ; + m_nRejected = 0 ; m_nCount = 0 ; m_iter = m_lUPointBs.end() ; } @@ -32,16 +34,33 @@ PolyArc::~PolyArc( void) bool PolyArc::Clear( void) { + m_vtExtr = Z_AX ; + m_nRejected = 0 ; m_nCount = 0 ; m_lUPointBs.clear() ; m_iter = m_lUPointBs.end() ; return true ; } +//---------------------------------------------------------------------------- +bool +PolyArc::SetExtrusion( const Vector3d& vtExtr) +{ + if ( vtExtr.IsSmall()) + return false ; + m_vtExtr = vtExtr ; + return true ; +} + //---------------------------------------------------------------------------- bool PolyArc::AddUPoint( double dPar, const Point3d& ptP, double dBulge) { + // se il punto è uguale al precedente (ignoro parametro e bulge), non lo inserisco ma ok + if ( m_nCount > 0 && AreSamePointApprox( ptP, m_lUPointBs.back().ptP)) { + ++ m_nRejected ; + return true ; + } try { m_lUPointBs.push_back( UPointB( dPar, ptP, dBulge)) ; } @@ -54,6 +73,32 @@ PolyArc::AddUPoint( double dPar, const Point3d& ptP, double dBulge) return true ; } +//---------------------------------------------------------------------------- +bool +PolyArc::Close( void) +{ + // ci devono essere almeno 2 punti + if ( m_lUPointBs.size() < 2) + return false ; + // verifico non sia già chiuso + if ( AreSamePointApprox( m_lUPointBs.front().ptP, m_lUPointBs.back().ptP)) + return false ; + // aggiungo un punto uguale al primo in coda + return AddUPoint( m_lUPointBs.front().dU, m_lUPointBs.front().ptP, m_lUPointBs.front().dB) ; +} + +//---------------------------------------------------------------------------- +bool +PolyArc::ModifyLastBulge( double dBulge) +{ + // verifico esistano dei punti + if ( m_lUPointBs.empty()) + return false ; + // eseguo la modifica + m_lUPointBs.back().dB = dBulge ; + return true ; +} + //---------------------------------------------------------------------------- bool PolyArc::EraseFirstUPoint( void) @@ -91,10 +136,83 @@ PolyArc::AddOffsetToU( double dOffset) return true ; } +//---------------------------------------------------------------------------- +bool +PolyArc::SetElevation( double dZ) +{ + UPNTBLIST::iterator iter ; + for ( iter = m_lUPointBs.begin() ; iter != m_lUPointBs.end() ; ++ iter) + iter->ptP.z = dZ ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +PolyArc::AddElevation( double dZ) +{ + UPNTBLIST::iterator iter ; + for ( iter = m_lUPointBs.begin() ; iter != m_lUPointBs.end() ; ++ iter) + iter->ptP.z += dZ ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +PolyArc::Translate( const Vector3d& vtMove) +{ + // il vettore estrusione non subisce modifiche + UPNTBLIST::iterator iter ; + for ( iter = m_lUPointBs.begin() ; iter != m_lUPointBs.end() ; ++ iter) + iter->ptP.Translate( vtMove) ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +PolyArc::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, double dSinAng) +{ + m_vtExtr.Rotate( vtAx, dCosAng, dSinAng) ; + UPNTBLIST::iterator iter ; + for ( iter = m_lUPointBs.begin() ; iter != m_lUPointBs.end() ; ++ iter) + iter->ptP.Rotate( ptAx, vtAx, dCosAng, dSinAng) ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +PolyArc::Scale( const Frame3d& frRef, double dCoeff) +{ + m_vtExtr.Scale( frRef, dCoeff, dCoeff, dCoeff) ; + UPNTBLIST::iterator iter ; + for ( iter = m_lUPointBs.begin() ; iter != m_lUPointBs.end() ; ++ iter) + iter->ptP.Scale( frRef, dCoeff, dCoeff, dCoeff) ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +PolyArc::Mirror( const Point3d& ptOn, const Vector3d& vtNorm) +{ + m_vtExtr.Mirror( vtNorm) ; + UPNTBLIST::iterator iter ; + for ( iter = m_lUPointBs.begin() ; iter != m_lUPointBs.end() ; ++ iter) { + iter->ptP.Mirror( ptOn, vtNorm) ; + iter->dB *= - 1 ; + } + + return true ; +} + //---------------------------------------------------------------------------- bool PolyArc::ToGlob( const Frame3d& frRef) { + m_vtExtr.ToGlob( frRef) ; UPNTBLIST::iterator iter ; for ( iter = m_lUPointBs.begin() ; iter != m_lUPointBs.end() ; ++ iter) iter->ptP.ToGlob( frRef) ; @@ -106,6 +224,7 @@ PolyArc::ToGlob( const Frame3d& frRef) bool PolyArc::ToLoc( const Frame3d& frRef) { + m_vtExtr.ToLoc( frRef) ; UPNTBLIST::iterator iter ; for ( iter = m_lUPointBs.begin() ; iter != m_lUPointBs.end() ; ++ iter) iter->ptP.ToLoc( frRef) ; @@ -117,6 +236,7 @@ PolyArc::ToLoc( const Frame3d& frRef) bool PolyArc::LocToLoc( const Frame3d& frOri, const Frame3d& frDest) { + m_vtExtr.LocToLoc( frOri, frDest) ; UPNTBLIST::iterator iter ; for ( iter = m_lUPointBs.begin() ; iter != m_lUPointBs.end() ; ++ iter) iter->ptP.LocToLoc( frOri, frDest) ; @@ -137,12 +257,15 @@ PolyArc::Splice( PolyArc& PA) //---------------------------------------------------------------------------- bool -PolyArc::GetFirstUPoint( double* pdPar, Point3d* pptP, double* pdBulge) const +PolyArc::GetFirstUPoint( double* pdPar, Point3d* pptP, double* pdBulge, bool bNotLast) const { + // cerco il primo punto m_iter = m_lUPointBs.begin() ; if ( m_iter == m_lUPointBs.end()) return false ; - + if ( bNotLast && m_iter == -- ( m_lUPointBs.end())) + return false ; + // assegno i dati if ( pdPar != nullptr) *pdPar = m_iter->dU ; if ( pptP != nullptr) @@ -157,6 +280,7 @@ PolyArc::GetFirstUPoint( double* pdPar, Point3d* pptP, double* pdBulge) const bool PolyArc::GetNextUPoint( double* pdPar, Point3d* pptP, double* pdBulge, bool bNotLast) const { + // cerco il prossimo punto if ( m_iter == m_lUPointBs.end()) return false ; ++ m_iter ; @@ -164,7 +288,7 @@ PolyArc::GetNextUPoint( double* pdPar, Point3d* pptP, double* pdBulge, bool bNot return false ; if ( bNotLast && m_iter == -- ( m_lUPointBs.end())) return false ; - + // assegno i dati if ( pdPar != nullptr) *pdPar = m_iter->dU ; if ( pptP != nullptr) @@ -174,3 +298,56 @@ PolyArc::GetNextUPoint( double* pdPar, Point3d* pptP, double* pdBulge, bool bNot return true ; } + +//---------------------------------------------------------------------------- +bool +PolyArc::GetFirstUArc( double* pdIni, Point3d* pptIni, double* pdFin, Point3d* pptFin, double* pdBulge) const +{ + // parametro e punto iniziali + m_iter = m_lUPointBs.begin() ; + if ( m_iter == m_lUPointBs.end()) + return false ; + if ( pdIni != nullptr) + *pdIni = m_iter->dU ; + if ( pptIni != nullptr) + *pptIni = m_iter->ptP ; + // bulge dell'arco (è attaccato al punto iniziale) + if ( pdBulge != nullptr) + *pdBulge = m_iter->dB ; + // parametro e punto finali + ++ m_iter ; + if ( m_iter == m_lUPointBs.end()) + return false ; + if ( pdFin != nullptr) + *pdFin = m_iter->dU ; + if ( pptFin != nullptr) + *pptFin = m_iter->ptP ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +PolyArc::GetNextUArc( double* pdIni, Point3d* pptIni, double* pdFin, Point3d* pptFin, double* pdBulge) const +{ + // parametro e punto iniziali (è il precedente finale) + if ( m_iter == m_lUPointBs.end()) + return false ; + if ( pdIni != nullptr) + *pdIni = m_iter->dU ; + if ( pptIni != nullptr) + *pptIni = m_iter->ptP ; + // bulge (è attaccato al punto iniziale) + if ( pdBulge != nullptr) + *pdBulge = m_iter->dB ; + // parametro e punto finali + ++ m_iter ; + if ( m_iter == m_lUPointBs.end()) + return false ; + if ( pdFin != nullptr) + *pdFin = m_iter->dU ; + if ( pptFin != nullptr) + *pptFin = m_iter->ptP ; + + return true ; +} \ No newline at end of file diff --git a/PolyLine.cpp b/PolyLine.cpp index 4d4017c..66a053a 100644 --- a/PolyLine.cpp +++ b/PolyLine.cpp @@ -23,6 +23,7 @@ //---------------------------------------------------------------------------- PolyLine::PolyLine( void) { + m_nRejected = 0 ; m_nCount = 0 ; m_iter = m_lUPoints.end() ; } @@ -36,6 +37,7 @@ PolyLine::~PolyLine( void) bool PolyLine::Clear( void) { + m_nRejected = 0 ; m_nCount = 0 ; m_lUPoints.clear() ; m_iter = m_lUPoints.end() ; @@ -46,6 +48,12 @@ PolyLine::Clear( void) bool PolyLine::AddUPoint( double dPar, const Point3d& ptP) { + // se il punto è uguale al precedente (ignoro parametro), non lo inserisco ma ok + if ( m_nCount > 0 && AreSamePointApprox( ptP, m_lUPoints.back().second)) { + ++ m_nRejected ; + return true ; + } + // eseguo inserimento try { m_lUPoints.push_back( UPOINT( dPar, ptP)) ; } @@ -58,6 +66,20 @@ PolyLine::AddUPoint( double dPar, const Point3d& ptP) return true ; } +//---------------------------------------------------------------------------- +bool +PolyLine::Close( void) +{ + // ci devono essere almeno 2 punti + if ( m_lUPoints.size() < 2) + return false ; + // verifico non sia già chiuso + if ( AreSamePointApprox( m_lUPoints.front().second, m_lUPoints.back().second)) + return false ; + // aggiungo un punto uguale al primo in coda + return AddUPoint( m_lUPoints.front().first, m_lUPoints.front().second) ; +} + //---------------------------------------------------------------------------- bool PolyLine::EraseFirstUPoint( void)