//---------------------------------------------------------------------------- // EgalTech 2014-2014 //---------------------------------------------------------------------------- // File : API_ModifyCurve.cpp Data : 03.10.14 Versione : 1.5i5 // Contenuto : Funzioni di modifica delle curve per API. // // // // Modifiche : 03.10.14 DS Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "EXE.h" #include "EXE_Const.h" #include "EXE_Macro.h" #include "AuxTools.h" #include "GeoTools.h" #include "/EgtDev/Include/EXeExecutor.h" #include "/EgtDev/Include/EXeConst.h" #include "/EgtDev/Include/EGkCurve.h" #include "/EgtDev/Include/EGkCurveArc.h" #include "/EgtDev/Include/EGkCurveBezier.h" #include "/EgtDev/Include/EGkCurveComposite.h" #include "/EgtDev/Include/EGkIntersCurves.h" #include "/EgtDev/Include/EGkDistPointCurve.h" #include "/EgtDev/Include/EGkCurveLocal.h" #include "/EgtDev/Include/EGkCurveAux.h" #include "/EgtDev/Include/EGkOffsetCurve.h" #include "/EgtDev/Include/EGkMedialAxis.h" #include "/EgtDev/Include/EGkChainCurves.h" #include "/EgtDev/Include/EGkSurfFlatRegion.h" #include "/EgtDev/Include/EGkExtTExt.h" #include "/EgtDev/Include/EGkGdbIterator.h" #include "/EgtDev/Include/EGkStringUtils3d.h" #include "/EgtDev/Include/EGkIntervals.h" #include "/EgtDev/Include/EGkPolygon3d.h" #include "/EgtDev/Include/EgtPointerOwner.h" #include using namespace std ; //---------------------------------------------------------------------------- bool ExeInvertCurve( const INTVECTOR& vIds) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) // eseguo inversione bool bOk = true ; for ( size_t i = 0 ; i < vIds.size() && bOk ; ++ i) { int nId = (( vIds[i] != GDB_ID_SEL) ? vIds[i] : pGeomDB->GetFirstSelectedObj()) ; while ( nId != GDB_ID_NULL && bOk) { // recupero la curva e la inverto ICurve* pCurve = GetCurve( pGeomDB->GetGeoObj( nId)) ; bOk = ( pCurve != nullptr && pCurve->Invert()) ; // passo alla successiva nId = (( vIds[i] != GDB_ID_SEL) ? GDB_ID_NULL : pGeomDB->GetNextSelectedObj()) ; } } ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtInvertCurve({" + IdListToString( vIds) + "})" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco risultato return bOk ; } //---------------------------------------------------------------------------- bool ExeOffsetCurve( int nId, double dDist, int nType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) // recupero la curva ICurve* pCurve = GetCurve( pGeomDB->GetGeoObj( nId)) ; // eseguo l'offset bool bOk = ( pCurve != nullptr) && pCurve->SimpleOffset( dDist, nType) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua ; sLua = "EgtOffsetCurve(" + ToString( nId) + "," + ToString( dDist) + "," + OffsTypeToString( nType) + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco risultato return bOk ; } //---------------------------------------------------------------------------- int ExeOffsetCurveAdv( int nId, double dDist, int nType, int* pnCount) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // recupero la curva const ICurve* pCurve = GetCurve( pGeomDB->GetGeoObj( nId)) ; // eseguo l'offset OffsetCurve OffsCrv ; bool bOk = OffsCrv.Make( pCurve, dDist, nType) ; // salvo le curve di offset int nRefId = nId ; int nCount = 0 ; int nFirstId = GDB_ID_NULL ; PtrOwner pOffs( OffsCrv.GetLongerCurve()) ; while ( bOk && ! IsNull( pOffs)) { // inserisco la curva nel DB geometrico int nNewId = pGeomDB->InsertGeoObj( GDB_ID_NULL, nRefId, GDB_AFTER, Release( pOffs)) ; // copio gli attributi pGeomDB->CopyAttributes( nId, nNewId) ; // aggiorno contatori if ( nNewId != GDB_ID_NULL) ++ nCount ; if ( nFirstId == GDB_ID_NULL) nFirstId = nNewId ; // aggiorno Id di riferimento per inserimento if ( nNewId != GDB_ID_NULL) nRefId = nNewId ; // passo alla successiva pOffs.Set( OffsCrv.GetLongerCurve()) ; } if ( bOk) ExeSetModified() ; else nCount = - 1 ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua ; sLua = "EgtOffsetCurveAdv(" + ToString( nId) + "," + ToString( dDist) + "," + OffsTypeToString( nType) + ")" + " -- Id1=" + ToString( nFirstId) + ",Nbr=" + ToString( nCount) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco risultato if ( pnCount != nullptr) *pnCount = nCount ; return nFirstId ; } //---------------------------------------------------------------------------- int ExeCurveMedialAxis( int nId) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // recupero la curva const ICurve* pCurve = GetCurve( pGeomDB->GetGeoObj( nId)) ; // eseguo il calcolo PolyLine PL ; if ( ! CurveSimpleMedialAxis( pCurve, PL)) return GDB_ID_NULL ; // creo la curva PtrOwner pCompo( CreateCurveComposite()) ; if ( IsNull( pCompo) || ! pCompo->FromPolyLine( PL)) return GDB_ID_NULL ; // la inserisco nel DB geometrico int nNewId = pGeomDB->InsertGeoObj( GDB_ID_NULL, nId, GDB_AFTER, Release( pCompo)) ; // copio gli attributi pGeomDB->CopyAttributes( nId, nNewId) ; // notifico la modifica if ( nNewId != GDB_ID_NULL) ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua ; sLua = "EgtCurveMedialAxis(" + ToString( nId) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } return nNewId ; } //------------------------------------------------------------------------------- bool ExeApproxCurve( int nId, int nApprType, double dLinTol) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // recupero la curva const ICurve* pCurve = GetCurve( pGeomDB->GetGeoObj( nId)) ; bool bOk = ( pCurve != nullptr) ; // eseguo l'approssimazione PtrOwner pCC( CreateCurveComposite()) ; bOk = bOk && ! IsNull( pCC) ; if ( nApprType == APP_LINES || nApprType == APP_SPECIAL_LINES || nApprType == APP_LEFT_LINES || nApprType == APP_LEFT_CONVEX_LINES || nApprType == APP_RIGHT_LINES || nApprType == APP_RIGHT_CONVEX_LINES) { PolyLine PL ; bOk = bOk && pCurve->ApproxWithLines( dLinTol, ANG_TOL_MAX_DEG, nApprType, PL) && pCC->FromPolyLine( PL) ; // eliminazione di small Z bOk = bOk && pCC->RemoveSmallDefects( 0.5 * dLinTol, ANG_TOL_STD_DEG) ; } else { // con bi-archi PolyArc PA ; double dLinFea = LIN_FEA_STD ; double dAngTol = ANG_TOL_STD_DEG ; if ( dLinTol > LIN_TOL_STD) { double dCoeff = ( dLinTol - LIN_TOL_STD) / LIN_TOL_STD ; dLinFea = min( LIN_FEA_STD + 1.0 * dCoeff * LIN_FEA_STD, LIN_FEA_MAX) ; dAngTol = min( ANG_TOL_STD_DEG + 0.2 * dCoeff * ANG_TOL_STD_DEG, ANG_TOL_MAX_DEG) ; } bOk = bOk && pCurve->ApproxWithArcsEx( dLinTol, dAngTol, dLinFea, PA) && pCC->FromPolyArc( PA) ; // eliminazione di small Z bOk = bOk && pCC->RemoveSmallDefects( 0.5 * dLinTol, ANG_TOL_STD_DEG) ; // merge di archi identici di biarchi bOk = bOk && pCC->MergeCurves( 0.5 * dLinTol, ANG_TOL_STD_DEG) ; } // copio estrusione e spessore Vector3d vtExtr ; if ( bOk && pCurve->GetExtrusion( vtExtr)) pCC->SetExtrusion( vtExtr) ; double dThick ; if ( bOk && pCurve->GetThickness( dThick)) pCC->SetThickness(dThick) ; // sostituisco la vecchia curva con la nuova bOk = bOk && pGeomDB->ReplaceGeoObj( nId, Release( pCC)) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtApproxCurve(" + ToString( nId) + "," + ApproxTypeToString( nApprType) + "," + ToString( dLinTol) + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco risultato return bOk ; } //------------------------------------------------------------------------------- bool ExeProjectCurveOnPlane( int nId, const Point3d& ptOn, const Vector3d& vtN, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // recupero la curva ICurve* pCurve = GetCurve( pGeomDB->GetGeoObj( nId)) ; bool bOk = ( pCurve != nullptr) ; // recupero il riferimento locale Frame3d frLoc ; bOk = bOk && pGeomDB->GetGlobFrame( nId, frLoc) ; // porto in locale il punto e la normale del piano Point3d ptOnL = GetPointLocal( pGeomDB, ptOn, nRefType, frLoc) ; Vector3d vtNL = GetVectorLocal( pGeomDB, vtN, nRefType, frLoc) ; // calcolo il piano di proiezione Plane3d plPlane ; bOk = bOk && plPlane.Set( ptOnL, vtNL) ; // eseguo la proiezione PtrOwner pProCrv( bOk ? ProjectCurveOnPlane( *pCurve, plPlane) : nullptr) ; bOk = bOk && ! IsNull( pProCrv) ; // copio estrusione e spessore Vector3d vtExtr ; if ( bOk && pCurve->GetExtrusion( vtExtr)) pProCrv->SetExtrusion( vtExtr) ; double dThick ; if ( bOk && pCurve->GetThickness( dThick)) pProCrv->SetThickness(dThick) ; // sostituisco la vecchia curva con la nuova bOk = bOk && pGeomDB->ReplaceGeoObj( nId, Release( pProCrv)) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtProjectCurveOnPlane(" + ToString( nId) + ",{" + ToString( ptOn) + "},{" + ToString( vtN) + "}," + RefTypeToString( nRefType) + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco risultato return bOk ; } //---------------------------------------------------------------------------- bool ExeChangeClosedCurveStart( int nId, double dU) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) bool bOk = true ; // recupero la curva ICurve* pCurve = GetCurve( pGeomDB->GetGeoObj( nId)) ; bOk = bOk && ( pCurve != nullptr) ; // cambio il punto iniziale if ( bOk && pCurve->GetType() == CRV_ARC) bOk = bOk && GetCurveArc( pCurve)->ChangeStartPoint(dU) ; else if ( bOk && pCurve->GetType() == CRV_COMPO) bOk = bOk && GetCurveComposite( pCurve)->ChangeStartPoint(dU) ; else bOk = false ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtChangeClosedCurveStart(" + ToString( nId) + "," + ToString( dU) + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco il risultato return bOk ; } //---------------------------------------------------------------------------- bool ExeChangeClosedCurveStartPoint( int nId, const Point3d& ptP, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) bool bOk = true ; // recupero la curva ICurve* pCurve = GetCurve( pGeomDB->GetGeoObj( nId)) ; bOk = bOk && ( pCurve != nullptr) ; // recupero il riferimento locale Frame3d frLoc ; bOk = bOk && pGeomDB->GetGlobFrame( nId, frLoc) ; // porto in locale il punto vicino ad iniziale Point3d ptPL = GetPointLocal( pGeomDB, ptP, nRefType, frLoc) ; // recupero la posizione parametrica della proiezione di questo punto sulla curva DistPointCurve distPC( ptPL, *pCurve) ; double dPar ; int nFlag ; bOk = bOk && distPC.GetParamAtMinDistPoint( 0, dPar, nFlag) ; // cambio il punto iniziale if ( bOk && pCurve->GetType() == CRV_ARC) bOk = bOk && GetCurveArc(pCurve)->ChangeStartPoint(dPar) ; else if ( bOk && pCurve->GetType() == CRV_COMPO) bOk = bOk && GetCurveComposite( pCurve)->ChangeStartPoint(dPar) ; else bOk = false ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtChangeClosedCurveStartPoint(" + ToString( nId) + ",{" + ToString( ptP) + "}," + RefTypeToString( nRefType) + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco il risultato return bOk ; } //---------------------------------------------------------------------------- bool ExeModifyCurveStartPoint( int nId, const Point3d& ptP, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) bool bOk = true ; // recupero la curva ICurve* pCurve = GetCurve( pGeomDB->GetGeoObj( nId)) ; bOk = bOk && ( pCurve != nullptr) ; // recupero il riferimento locale Frame3d frLoc ; bOk = bOk && pGeomDB->GetGlobFrame( nId, frLoc) ; // porto in locale il nuovo punto iniziale Point3d ptPL = GetPointLocal( pGeomDB, ptP, nRefType, frLoc) ; // ne modifico il punto iniziale bOk = bOk && pCurve->ModifyStart( ptPL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtModifyCurveStartPoint(" + ToString( nId) + ",{" + ToString( ptP) + "}," + RefTypeToString( nRefType) + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco il risultato return bOk ; } //---------------------------------------------------------------------------- bool ExeModifyCurveEndPoint( int nId, const Point3d& ptP, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) bool bOk = true ; // recupero la curva ICurve* pCurve = GetCurve( pGeomDB->GetGeoObj( nId)) ; bOk = bOk && ( pCurve != nullptr) ; // recupero il riferimento locale Frame3d frLoc ; bOk = bOk && pGeomDB->GetGlobFrame( nId, frLoc) ; // porto in locale il nuovo punto finale Point3d ptPL = GetPointLocal( pGeomDB, ptP, nRefType, frLoc) ; // ne modifico il punto finale bOk = bOk && pCurve->ModifyEnd( ptPL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtModifyCurveEndPoint(" + ToString( nId) + ",{" + ToString( ptP) + "}," + RefTypeToString( nRefType) + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco il risultato return bOk ; } //---------------------------------------------------------------------------- bool ExeSpiralizeCurveAlongExtrusion( int nId, double dDelta) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) bool bOk = true ; // recupero la curva ICurve* pCurve = GetCurve( pGeomDB->GetGeoObj( nId)) ; bOk = bOk && ( pCurve != nullptr) ; Vector3d vtExtr ; bOk = bOk && pCurve->GetExtrusion( vtExtr) ; Point3d ptEnd ; bOk = bOk && pCurve->GetEndPoint( ptEnd) ; // se linea o arco if ( bOk && ( pCurve->GetType() == CRV_LINE || pCurve->GetType() == CRV_ARC)) bOk = bOk && pCurve->ModifyEnd( ptEnd + dDelta * vtExtr) ; // se composita il delta va ripartito su tutte le sottocurve else if ( bOk && pCurve->GetType() == CRV_COMPO) { ICurveComposite* pCompo = GetCurveComposite( pCurve) ; double dLen ; bOk = bOk && pCompo->GetLength( dLen) ; // calcolo il delta di ogni sottocurva DBLVECTOR vdDelta( pCompo->GetCurveCount() - 1) ; for ( int i = 1 ; bOk && i < pCompo->GetCurveCount() ; i ++) { double dLenU ; pCompo->GetLengthAtParam( i, dLenU) ; vdDelta[i-1] = dDelta * dLenU / dLen ; } for ( int i = 1 ; bOk && i < pCompo->GetCurveCount() ; i ++) { Point3d ptJoint ; pCompo->GetPointD1D2( i, ICurve::FROM_MINUS, ptJoint) ; ptJoint += vtExtr * vdDelta[i-1] ; pCompo->ModifyJoint( i, ptJoint) ; } // ultimo punto bOk = bOk && pCompo->ModifyEnd( ptEnd + dDelta * vtExtr) ; } ExeSetModified() ; // restituisco il risultato return bOk ; } //---------------------------------------------------------------------------- bool ExeSpiralizeCurveAlongGuide( int nCrvId, int nGuideId, double dLinTol) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) bool bOk = true ; // recupero la curva e il suo riferimento ICurve* pCrv = GetCurve( pGeomDB->GetGeoObj( nCrvId)) ; bOk = bOk && ( pCrv != nullptr) ; Frame3d frCrv ; bOk = bOk && pGeomDB->GetGlobFrame( nCrvId, frCrv) ; // recupero la curva guida e il suo riferimento const ICurve * pCrvGuide = GetCurve( pGeomDB->GetGeoObj( nGuideId)) ; bOk = bOk && ( pCrvGuide != nullptr) ; Frame3d frGuide ; bOk = bOk && pGeomDB->GetGlobFrame( nGuideId, frGuide) ; // approssimo le curve con polylines PolyLine PL1, PL2 ; bOk = bOk && pCrv->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, APP_SPECIAL_LINES, PL1) ; bOk = bOk && pCrvGuide->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, APP_SPECIAL_LINES, PL2) ; // porto la polyline della curva guida nel riferimento locale bOk = bOk && PL2.LocToLoc( frGuide, frCrv) ; // modifico PL2 per gestire eventuali punti di intersezione PtrOwner pCompoGuide( CreateCurveComposite()) ; bOk = bOk && ( ! IsNull( pCompoGuide)) ; bOk = bOk && pCompoGuide->FromPolyLine( PL2) ; Point3d ptP1 ; bool bFound = bOk && PL1.GetFirstPoint( ptP1) ; while ( bOk && bFound) { double dAddPar ; if ( bOk && pCompoGuide->GetParamAtPoint( ptP1, dAddPar, 100 * EPS_SMALL)) bOk = bOk && pCompoGuide->AddJoint( dAddPar) ; bFound = PL1.GetNextPoint( ptP1) ; } bOk = bOk && pCompoGuide->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, APP_SPECIAL_LINES, PL2) ; // associo i punti a minima distanza delle polylines PNTIVECTOR vPnt1, vPnt2 ; bool bTmp ; bOk = bOk && AssociatePolyLinesMinDistPoints( PL1, PL2, vPnt1, vPnt2, bTmp) ; PtrOwner pCompo( CreateCurveComposite()) ; bOk = bOk && ! IsNull( pCompo) ; double dLenTot ; Point3d ptOld ; if ( bOk) ptOld = vPnt2[0].first ; bOk = bOk && pCrv->GetLength( dLenTot) ; bOk = bOk && pCompo->AddPoint( vPnt2[0].first) ; for ( int i = 1 ; bOk && i < ( int)vPnt1.size() - 1 ; i++) { double dPar ; bOk = bOk && pCrv->GetParamAtPoint( vPnt1[i].first, dPar) ; double dLen = 0 ; bOk = bOk && pCrv-> GetLengthAtParam( dPar, dLen) ; // calcolo il nuovo punto per la curva Point3d ptNew = Media( vPnt2[ vPnt1[i].second].first, vPnt1[i].first, dLen / dLenTot) ; if ( ! AreSamePointApprox( ptOld, ptNew)) { bOk = bOk && pCompo->AddLine( ptNew) ; ptOld = ptNew ; } } if ( bOk && ! AreSamePointApprox( ptOld, vPnt1.back().first)) bOk = bOk && pCompo->AddLine( vPnt1.back().first) ; // copio estrusione e spessore Vector3d vtExtr ; if ( bOk && pCrv->GetExtrusion( vtExtr)) pCompo->SetExtrusion( vtExtr) ; double dThick ; if ( bOk && pCrv->GetThickness( dThick)) pCompo->SetThickness(dThick) ; // sostituisco la vecchia curva con la nuova bOk = bOk && pGeomDB->ReplaceGeoObj( nCrvId, Release( pCompo)) ; ExeSetModified() ; // restituisco il risultato return bOk ; } //---------------------------------------------------------------------------- static bool ModifyOneCurveExtrusion( IGeomDB* pGeomDB, int nId, const Vector3d& vtExtr, int nRefType) { // recupero il riferimento locale Frame3d frLoc ; if ( ! pGeomDB->GetGroupGlobFrame( nId, frLoc) && ! pGeomDB->GetGlobFrame( nId, frLoc)) return false ; // porto in locale il versore estrusione Vector3d vtExtrL = GetVectorLocal( pGeomDB, vtExtr, nRefType, frLoc) ; // se gruppo, agisco sulle sole curve componenti if ( pGeomDB->GetGdbType( nId) == GDB_TY_GROUP) { PtrOwner pIter( CreateGdbIterator( pGeomDB)) ; if ( IsNull( pIter)) return false ; for ( bool bFound = pIter->GoToFirstInGroup( nId) ; bFound ; bFound = pIter->GoToNext()) { // recupero la curva e ne modifico il vettore estrusione ICurve* pCurve = GetCurve( pIter->GetGeoObj()) ; if ( pCurve != nullptr && ! pCurve->SetExtrusion( vtExtrL)) return false ; } return true ; } // se oggetto geometrico else { // recupero la curva ICurve* pCurve = GetCurve( pGeomDB->GetGeoObj( nId)) ; // ne modifico il vettore estrusione return ( pCurve == nullptr || pCurve->SetExtrusion( vtExtrL)) ; } } //---------------------------------------------------------------------------- bool ExeModifyCurveExtrusion( const INTVECTOR& vIds, const Vector3d& vtExtr, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) bool bOk = true ; // se estrusione espressa in locale, verifico che tutte le curve siano nello stesso riferimento if ( nRefType == RTY_LOC) bOk = bOk && VerifySameFrame( pGeomDB, vIds) ; // ciclo sul vettore degli identificativi for ( size_t i = 0 ; i < vIds.size() && bOk ; ++ i) { // impostazione estrusione singola if ( vIds[i] != GDB_ID_SEL) { bOk = bOk && ModifyOneCurveExtrusion( pGeomDB, vIds[i], vtExtr, nRefType) ; } // impostazione estrusione dei selezionati else { int nI = pGeomDB->GetFirstSelectedObj() ; while ( nI != GDB_ID_NULL && bOk) { if ( ! ModifyOneCurveExtrusion( pGeomDB, nI, vtExtr, nRefType)) bOk = false ; // passo alla successiva nI = pGeomDB->GetNextSelectedObj() ; } } } ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtModifyCurveExtrusion({" + IdListToString( vIds) + "},{" + ToString( Vector3d( vtExtr)) + "}," + RefTypeToString( nRefType) + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco risultato return bOk ; } //---------------------------------------------------------------------------- static bool ModifyOneCurveThickness( IGeomDB* pGeomDB, int nId, double dThick) { // se gruppo, agisco sulle sole curve componenti if ( pGeomDB->GetGdbType( nId) == GDB_TY_GROUP) { PtrOwner pIter( CreateGdbIterator( pGeomDB)) ; if ( IsNull( pIter)) return false ; bool bOk = true ; for ( bool bFound = pIter->GoToFirstInGroup( nId) ; bFound ; bFound = pIter->GoToNext()) { // recupero la curva e ne modifico lo spessore ICurve* pCurve = GetCurve( pIter->GetGeoObj()) ; if ( pCurve != nullptr && ! pCurve->SetThickness( dThick)) bOk = false ; } return bOk ; } // se oggetto geometrico else { // recupero la curva ICurve* pCurve = GetCurve( pGeomDB->GetGeoObj( nId)) ; // ne modifico lo spessore, se curva return ( pCurve == nullptr || pCurve->SetThickness( dThick)) ; } } //---------------------------------------------------------------------------- bool ExeModifyCurveThickness( const INTVECTOR& vIds, double dThick) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) bool bOk = true ; // ciclo sul vettore degli identificativi for ( size_t i = 0 ; i < vIds.size() && bOk ; ++ i) { // eseguo impostazione spessore singola if ( vIds[i] != GDB_ID_SEL) { bOk = bOk && ModifyOneCurveThickness( pGeomDB, vIds[i], dThick) ; } // eseguo impostazione spessore dei selezionati else { int nI = pGeomDB->GetFirstSelectedObj() ; while ( nI != GDB_ID_NULL && bOk) { if ( ! ModifyOneCurveThickness( pGeomDB, nI, dThick)) bOk = false ; // passo alla successiva nI = pGeomDB->GetNextSelectedObj() ; } } } ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtModifyCurveThickness({" + IdListToString( vIds) + "}," + ToString( dThick) + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco risultato return bOk ; } //---------------------------------------------------------------------------- bool ExeTrimCurveStartAtLen( int nId, double dLen) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) // recupero la curva ICurve* pCurve = GetCurve( pGeomDB->GetGeoObj( nId)) ; if ( pCurve == nullptr) return false ; // taglio la curva all'inizio bool bOk = pCurve->TrimStartAtLen( dLen) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtTrimCurveStartAtLen(" + ToString( nId) + "," + ToString( dLen) + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco risultato return bOk ; } //---------------------------------------------------------------------------- bool ExeTrimCurveEndAtLen( int nId, double dLen) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) // recupero la curva ICurve* pCurve = GetCurve( pGeomDB->GetGeoObj( nId)) ; if ( pCurve == nullptr) return false ; // taglio la curva alla fine bool bOk = pCurve->TrimEndAtLen( dLen) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtTrimCurveEndAtLen(" + ToString( nId) + "," + ToString( dLen) + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco risultato return bOk ; } //---------------------------------------------------------------------------- bool ExeTrimCurveStartAtParam( int nId, double dPar) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) // recupero la curva ICurve* pCurve = GetCurve( pGeomDB->GetGeoObj( nId)) ; if ( pCurve == nullptr) return false ; // taglio la curva all'inizio bool bOk = pCurve->TrimStartAtParam( dPar) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtTrimCurveStartAtParam(" + ToString( nId) + "," + ToString( dPar) + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco risultato return bOk ; } //---------------------------------------------------------------------------- bool ExeTrimCurveEndAtParam( int nId, double dPar) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) // recupero la curva ICurve* pCurve = GetCurve( pGeomDB->GetGeoObj( nId)) ; if ( pCurve == nullptr) return false ; // taglio la curva alla fine bool bOk = pCurve->TrimEndAtParam( dPar) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtTrimCurveEndAtParam(" + ToString( nId) + "," + ToString( dPar) + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco risultato return bOk ; } //---------------------------------------------------------------------------- bool ExeTrimCurveStartEndAtParam( int nId, double dParS, double dParE) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) // recupero la curva ICurve* pCurve = GetCurve( pGeomDB->GetGeoObj( nId)) ; if ( pCurve == nullptr) return false ; // taglio la curva agli estremi bool bOk = pCurve->TrimStartEndAtParam( dParS, dParE) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtTrimCurveStartEndAtParam(" + ToString( nId) + "," + ToString( dParS) + "," + ToString( dParE) + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco risultato return bOk ; } //---------------------------------------------------------------------------- bool ExeExtendCurveStartByLen( int nId, double dLen) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) // recupero la curva ICurve* pCurve = GetCurve( pGeomDB->GetGeoObj( nId)) ; if ( pCurve == nullptr) return false ; // estendo la curva all'inizio bool bOk = pCurve->ExtendStartByLen( dLen) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtExtendCurveStartByLen(" + ToString( nId) + "," + ToString( dLen) + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco risultato return bOk ; } //---------------------------------------------------------------------------- bool ExeExtendCurveEndByLen( int nId, double dLen) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) // recupero la curva ICurve* pCurve = GetCurve( pGeomDB->GetGeoObj( nId)) ; if ( pCurve == nullptr) return false ; // estendo la curva alla fine bool bOk = pCurve->ExtendEndByLen( dLen) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtExtendCurveEndByLen(" + ToString( nId) + "," + ToString( dLen) + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco risultato return bOk ; } //---------------------------------------------------------------------------- bool ExeTrimExtendCurveByLen( int nId, double dLen, const Point3d& ptNear, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) // recupero la curva ICurve* pCurve = GetCurve( pGeomDB->GetGeoObj( nId)) ; bool bOk = ( pCurve != nullptr) ; // recupero il riferimento locale Frame3d frLoc ; bOk = bOk && pGeomDB->GetGlobFrame( nId, frLoc) ; // porto in locale il punto Point3d ptNearL = GetPointLocal( pGeomDB, ptNear, nRefType, frLoc) ; // cerco l'estremo più vicino al punto passato bool bStart ; if ( bOk && pCurve->GetNearestExtremityToPoint( ptNearL, bStart)) { if ( bStart) { if ( dLen < - EPS_SMALL) bOk = pCurve->TrimStartAtLen( - dLen) ; else if ( dLen > EPS_SMALL) bOk = pCurve->ExtendStartByLen( dLen) ; } else { if ( dLen < - EPS_SMALL) { double dCrvLen ; bOk = pCurve->GetLength( dCrvLen) && pCurve->TrimEndAtLen( dCrvLen + dLen) ; } else if ( dLen > EPS_SMALL) bOk = pCurve->ExtendEndByLen( dLen) ; } } else bOk = false ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtTrimExtendCurveByLen(" + ToString( nId) + "," + ToString( dLen) + ",{" + ToString( ptNear) + "}," + RefTypeToString( nRefType) + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco risultato return bOk ; } //---------------------------------------------------------------------------- static int MyTrimCurveWithRegion( int nCrvId, int nRegId, bool bInVsOut, bool bOn, int& nCount) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // recupero la regione ISurfFlatRegion* pSFR = GetSurfFlatRegion( pGeomDB->GetGeoObj( nRegId)) ; if ( pSFR == nullptr) return GDB_ID_NULL ; // recupero il riferimento della regione Frame3d frReg ; if ( ! pGeomDB->GetGlobFrame( nRegId, frReg)) return GDB_ID_NULL ; // recupero la curva ICurve* pCrv = GetCurve( pGeomDB->GetGeoObj( nCrvId)) ; if ( pCrv == nullptr) return GDB_ID_NULL ; // recupero la curva in locale alla regione CurveLocal CrvLoc( pGeomDB, nCrvId, frReg) ; if ( CrvLoc.Get() == nullptr) return GDB_ID_NULL ; // calcolo la classificazione della curva rispetto alla regione CRVCVECTOR ccClass ; if ( ! pSFR->GetCurveClassification( *CrvLoc, EPS_SMALL, ccClass)) return GDB_ID_NULL ; // determino gli intervalli di curva da conservare Intervals inOk( 100 * EPS_PARAM) ; for ( auto& ccOne : ccClass) { if ( ( bInVsOut && ccOne.nClass == CRVC_IN) || ( ! bInVsOut && ccOne.nClass == CRVC_OUT) || ( bOn && ( ccOne.nClass == CRVC_ON_P || ccOne.nClass == CRVC_ON_M))) inOk.Add( ccOne.dParS, ccOne.dParE) ; } // recupero un intervallo di id contigui per tutte le parti int nFirstId = pGeomDB->GetNewId() ; if ( nFirstId == nCrvId + 1) nFirstId = nCrvId ; int nCurrId = nFirstId ; if ( ! pGeomDB->ChangeId( nCrvId, nFirstId)) return GDB_ID_NULL ; // eseguo la divisione nCount = 0 ; double dParS, dParE ; bool bFound = inOk.GetFirst( dParS, dParE) ; while ( bFound) { // copio la curva int nCopyId = pGeomDB->Copy( nCurrId, GDB_ID_NULL, nCurrId, GDB_AFTER) ; ICurve* pCopyCrv = GetCurve( pGeomDB->GetGeoObj( nCopyId)) ; if ( pCopyCrv == nullptr) return GDB_ID_NULL ; ++ nCount ; // modifico l'originale if ( ! pCrv->TrimStartEndAtParam( dParS, dParE)) return GDB_ID_NULL ; // la copia diventa il nuovo corrente nCurrId = nCopyId ; pCrv = pCopyCrv ; // passo alla successiva divisione bFound = inOk.GetNext( dParS, dParE) ; } // cancello l'ultima copia (se non c'erano intervalli validi è l'originale) pGeomDB->Erase( nCurrId) ; return nFirstId ; } //---------------------------------------------------------------------------- int ExeTrimCurveWithRegion( int nCrvId, int nRegId, bool bInVsOut, bool bOn, int* pnCount) { int nCount ; int nFirstId = MyTrimCurveWithRegion( nCrvId, nRegId, bInVsOut, bOn, nCount) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtTrimCurveWithRegion(" + ToString( nCrvId) + "," + ToString( nRegId) + "," + ToString( bInVsOut) + "," + ToString( bOn) + ")" + " -- Id1=" + ToString( nFirstId) + ",Nbr=" + ToString( nCount) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco risultati if ( pnCount != nullptr) *pnCount = nCount ; return nFirstId ; } //---------------------------------------------------------------------------- static int MyTrimFlatCurveWithBox( int nCrvId, const Frame3d& frBox, const Vector3d& vtDiag, bool bInVsOut, bool bOn, int nRefType, int& nCount) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // recupero la curva ICurve* pCrv = GetCurve( pGeomDB->GetGeoObj( nCrvId)) ; if ( pCrv == nullptr) return GDB_ID_NULL ; // recupero il riferimento della curva Frame3d frCrv ; if ( ! pGeomDB->GetGlobFrame( nCrvId, frCrv)) return GDB_ID_NULL ; // determino il piano della curva (annullo temporaneamente l'estrusione per non avere problemi) Plane3d plPlane ; if ( ! pCrv->IsFlat( plPlane, false, 10 * EPS_SMALL)) return GDB_ID_NULL ; // porto in locale alla curva il riferimento del box (il vettore è già in locale a questo stesso riferimento) Frame3d frBoxL = GetFrameLocal( pGeomDB, frBox, nRefType, frCrv) ; // determino la parte di piano (poligono) compresa nel box (applicando le opportune trasformazioni di riferimento) plPlane.ToLoc( frBoxL) ; Polygon3d Polyg ; if ( ! Polyg.FromPlaneTrimmedWithBox( plPlane, ORIG, ORIG + vtDiag, bOn, bOn)) return GDB_ID_NULL ; Polyg.ToGlob( frBoxL) ; // se poligono vuoto, la curva non interseca il box if ( Polyg.GetSideCount() == 0) { if ( bInVsOut) { pGeomDB->Erase( nCrvId) ; nCount = 0 ; } else nCount = 1 ; return nCrvId ; } // creo la regione corrispondente PtrOwner pContour( CreateCurveComposite()) ; if ( IsNull( pContour) || ! pContour->FromPolyLine( Polyg.GetPolyLine())) return false ; PtrOwner pSfr( CreateSurfFlatRegion()) ; if ( IsNull( pSfr) || ! pSfr->AddExtLoop( Release( pContour))) return false ; // calcolo la classificazione della curva rispetto alla regione CRVCVECTOR ccClass ; if ( ! pSfr->GetCurveClassification( *pCrv, EPS_SMALL, ccClass)) return GDB_ID_NULL ; // determino gli intervalli di curva da conservare Intervals inOk ; for ( auto& ccOne : ccClass) { if ( ( bInVsOut && ccOne.nClass == CRVC_IN) || ( ! bInVsOut && ccOne.nClass == CRVC_OUT) || ( bOn && ( ccOne.nClass == CRVC_ON_P || ccOne.nClass == CRVC_ON_M))) inOk.Add( ccOne.dParS, ccOne.dParE) ; } // recupero un intervallo di id contigui per tutte le parti int nFirstId = pGeomDB->GetNewId() ; if ( nFirstId == nCrvId + 1) nFirstId = nCrvId ; if ( ! pGeomDB->ChangeId( nCrvId, nFirstId)) return GDB_ID_NULL ; int nCurrId = nFirstId ; // eseguo la divisione nCount = 0 ; double dParS, dParE ; bool bFound = inOk.GetFirst( dParS, dParE) ; while ( bFound) { // copio la curva int nCopyId = pGeomDB->Copy( nCurrId, GDB_ID_NULL, nCurrId, GDB_AFTER) ; ICurve* pCopyCrv = GetCurve( pGeomDB->GetGeoObj( nCopyId)) ; if ( pCopyCrv == nullptr) return GDB_ID_NULL ; ++ nCount ; // modifico l'originale if ( ! pCrv->TrimStartEndAtParam( dParS, dParE)) return GDB_ID_NULL ; // la copia diventa il nuovo corrente nCurrId = nCopyId ; pCrv = pCopyCrv ; // passo alla successiva divisione bFound = inOk.GetNext( dParS, dParE) ; } // cancello l'ultima copia (se non c'erano intervalli validi è l'originale) pGeomDB->Erase( nCurrId) ; return nFirstId ; } //---------------------------------------------------------------------------- int ExeTrimFlatCurveWithBox( int nCrvId, const Frame3d& frBox, const Vector3d& vtDiag, bool bInVsOut, bool bOn, int nRefType, int* pnCount) { int nCount ; int nFirstId = MyTrimFlatCurveWithBox( nCrvId, frBox, vtDiag, bInVsOut, bOn, nRefType, nCount) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtTrimFlatCurveWithBox(" + ToString( nCrvId) + "," + ToString( frBox) + "," + ToString( vtDiag) + "," + ToString( bInVsOut) + "," + ToString( bOn) + "," + RefTypeToString( nRefType) + ")" + " -- Id1=" + ToString( nFirstId) + ",Nbr=" + ToString( nCount) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco risultati if ( pnCount != nullptr) *pnCount = nCount ; return nFirstId ; } //---------------------------------------------------------------------------- int ExeSplitCurve( int nId, int nParts) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // recupero la curva ICurve* pCurve = GetCurve( pGeomDB->GetGeoObj( nId)) ; bool bOk = ( pCurve != nullptr) ; // il numero di parti non può essere inferiore a 1 nParts = max( nParts, 1) ; // lunghezza totale della curva double dLenTot = 0 ; bOk = bOk && pCurve->GetLength( dLenTot) ; // lunghezza di una parte double dLen = dLenTot / nParts ; bOk = bOk && ( dLen > 10 * EPS_SMALL) ; // recupero un intervallo di id contigui per tutte le parti int nFirstId = pGeomDB->GetNewId() ; if ( nFirstId == nId + 1) nFirstId = nId ; bOk = bOk && pGeomDB->ChangeId( nId, nFirstId) ; int nCurrId = nFirstId ; // eseguo la divisione for ( int i = 1; i < nParts ; ++ i) { // copio la curva int nCopyId = pGeomDB->Copy( nCurrId, GDB_ID_NULL, nCurrId, GDB_AFTER) ; ICurve* pCopyCrv = GetCurve( pGeomDB->GetGeoObj( nCopyId)) ; bOk = bOk && ( pCopyCrv != nullptr) ; // tengo la prima parte dell'originale e la seconda parte della copia bOk = bOk && pCurve->TrimEndAtLen( dLen) ; bOk = bOk && pCopyCrv->TrimStartAtLen( dLen) ; // la copia diventa il nuovo corrente nCurrId = nCopyId ; pCurve = pCopyCrv ; } nFirstId = ( bOk ? nFirstId : GDB_ID_NULL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSplitCurve(" + ToString( nId) + "," + ToString( nParts) + ")" + " -- Id1=" + ToString( nFirstId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco risultato return nFirstId ; } //---------------------------------------------------------------------------- int ExeSplitCurveAtPoint( int nId, const Point3d& ptOn, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // recupero la curva ICurve* pCurve = GetCurve( pGeomDB->GetGeoObj( nId)) ; bool bOk = ( pCurve != nullptr) ; // recupero il riferimento locale Frame3d frLoc ; bOk = bOk && pGeomDB->GetGlobFrame( nId, frLoc) ; // porto in locale il punto Point3d ptOnL = GetPointLocal( pGeomDB, ptOn, nRefType, frLoc) ; // determino la posizione parametrica del punto sulla curva (con tolleranza) double dU = 0 ; if ( bOk) { DistPointCurve dstPC( ptOnL, *pCurve) ; int nFlag ; if ( ! dstPC.GetParamAtMinDistPoint( 0, dU, nFlag) || nFlag != MDPCI_NORMAL) bOk = false ; // se sull'inizio, provo se c'è una soluzione successiva if ( bOk && dU < EPS_PARAM) dstPC.GetParamAtMinDistPoint( 1, dU, nFlag) ; } // verifico che il punto di taglio sia interno alla curva bool bIsInside = false ; if ( bOk) { // determino lunghezza totale della curva double dLen ; bOk = bOk && pCurve->GetLength( dLen) ; // determino lunghezza al parametro di taglio double dCutLen ; bOk = bOk && pCurve->GetLengthAtParam( dU, dCutLen) ; // interno se la lunghezza al parametro e la lunghezza rimanente sono entrambe significative if ( bOk && dCutLen > EPS_SMALL && dLen - dCutLen > EPS_SMALL) bIsInside = true ; } // se il punto di taglio è interno, devo realmente tagliare int nNewId = GDB_ID_NULL ; if ( bIsInside) { // copio la curva nNewId = pGeomDB->Copy( nId, GDB_ID_NULL, nId, GDB_AFTER) ; ICurve* pCopyCrv = GetCurve( pGeomDB->GetGeoObj( nNewId)) ; bOk = bOk && ( pCopyCrv != nullptr) ; // tengo la prima parte dell'originale e la seconda parte della copia bOk = bOk && pCurve->TrimEndAtParam( dU) ; bOk = bOk && pCopyCrv->TrimStartAtParam( dU) ; } nNewId = ( bOk ? nNewId : GDB_ID_NULL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSplitCurveAtPoint(" + ToString( nId) + ",{" + ToString( ptOn) + "}," + RefTypeToString( nRefType) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco risultato return nNewId ; } //---------------------------------------------------------------------------- int ExeSplitCurveAtParam( int nId, double dParam) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // recupero la curva ICurve* pCurve = GetCurve( pGeomDB->GetGeoObj( nId)) ; bool bOk = ( pCurve != nullptr) ; // verifico che il punto di taglio sia interno alla curva bool bIsInside = false ; if ( bOk) { // determino lunghezza totale della curva double dLen ; bOk = bOk && pCurve->GetLength( dLen) ; // determino lunghezza al parametro di taglio double dCutLen ; bOk = bOk && pCurve->GetLengthAtParam( dParam, dCutLen) ; // interno se la lunghezza al parametro e la lunghezza rimanente sono entrambe significative if ( bOk && dCutLen > EPS_SMALL && dLen - dCutLen > EPS_SMALL) bIsInside = true ; } // se il punto di taglio è interno, devo realmente tagliare int nNewId = GDB_ID_NULL ; if ( bIsInside) { // copio la curva nNewId = pGeomDB->Copy( nId, GDB_ID_NULL, nId, GDB_AFTER) ; ICurve* pCopyCrv = GetCurve( pGeomDB->GetGeoObj( nNewId)) ; bOk = bOk && ( pCopyCrv != nullptr) ; // tengo la prima parte dell'originale e la seconda parte della copia bOk = bOk && pCurve->TrimEndAtParam( dParam) ; bOk = bOk && pCopyCrv->TrimStartAtParam( dParam) ; } nNewId = ( bOk ? nNewId : GDB_ID_NULL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSplitCurveAtParam(" + ToString( nId) + "," + ToString( dParam) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco risultato return nNewId ; } //---------------------------------------------------------------------------- int ExeSplitCurveAtCorners( int nId, double dTgAngToler, int* pnCount) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // !!! deve essere fatta anche sulle curve di Bezier !!! // recupero la curva composita ICurveComposite* pCompo = GetCurveComposite( pGeomDB->GetGeoObj( nId)) ; bool bOk = ( pCompo != nullptr) ; // calcolo i punti di perdita di tangenza DBLVECTOR vU ; double dMinCos = cos( dTgAngToler * DEGTORAD) ; for ( int i = 1 ; bOk && i < pCompo->GetCurveCount() ; ++ i) { Point3d ptPrev, ptNext ; Vector3d vtPrev, vtNext ; if ( pCompo->GetPointTang( i, ICurve::FROM_MINUS, ptPrev, vtPrev) && pCompo->GetPointTang( i, ICurve::FROM_PLUS, ptNext, vtNext) && vtPrev * vtNext < dMinCos) vU.push_back( i) ; } // recupero un intervallo di id contigui per tutte le parti int nFirstId = pGeomDB->GetNewId() ; if ( nFirstId == nId + 1) nFirstId = nId ; bOk = bOk && pGeomDB->ChangeId( nId, nFirstId) ; int nCurrId = nFirstId ; // eseguo la divisione int nCount = 1 ; double dUPrev = 0 ; for ( int i = 0 ; i < int( vU.size()) ; ++ i) { // copio la curva int nCopyId = pGeomDB->Copy( nCurrId, GDB_ID_NULL, nCurrId, GDB_AFTER) ; ICurveComposite* pCopyCrv = GetCurveComposite( pGeomDB->GetGeoObj( nCopyId)) ; bOk = bOk && ( pCopyCrv != nullptr) ; ++ nCount ; // trimmo l'originale bOk = bOk && pCompo->TrimStartEndAtParam( dUPrev, vU[i]) ; // la copia diventa il nuovo corrente nCurrId = nCopyId ; pCompo = pCopyCrv ; dUPrev = vU[i] ; } // se fatta almeno una suddivisione, trimmo l'ultima parte if ( dUPrev > EPS_PARAM) bOk = bOk && pCompo->TrimStartAtParam( dUPrev) ; nFirstId = ( bOk ? nFirstId : GDB_ID_NULL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSplitCurveAtCorners(" + ToString( nId) + "," + ToString( dTgAngToler) + ")" + " -- Id1=" + ToString( nFirstId) + ",Nbr=" + ToString( nCount) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco risultati if ( pnCount != nullptr) *pnCount = nCount ; return nFirstId ; } //---------------------------------------------------------------------------- int ExeSplitCurveAtSelfInters( int nId, int* pnCount) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // recupero la curva ICurve* pCurve = GetCurve( pGeomDB->GetGeoObj( nId)) ; bool bOk = ( pCurve != nullptr) ; // calcolo le auto-intersezioni DBLVECTOR vU ; if ( bOk) { SelfIntersCurve sintC( *pCurve) ; IntCrvCrvInfo iccInfo ; for ( int i = 0 ; sintC.GetIntCrvCrvInfo( i, iccInfo) ; ++ i) { if ( ! iccInfo.bOverlap) { vU.push_back( iccInfo.IciA[0].dU) ; vU.push_back( iccInfo.IciB[0].dU) ; } else { vU.push_back( iccInfo.IciA[0].dU) ; vU.push_back( iccInfo.IciA[1].dU) ; vU.push_back( iccInfo.IciB[0].dU) ; vU.push_back( iccInfo.IciB[1].dU) ; } } } // ordino il vettore in senso crescente sort( vU.begin(), vU.end(), less()) ; // calcolo il vettore delle lunghezze di ogni parte di curva double dLen ; bOk = bOk && pCurve->GetLength( dLen) ; DBLVECTOR vLen ; for ( const auto& dU : vU) { double dULen ; bOk = bOk && pCurve->GetLengthAtParam( dU, dULen) ; vLen.push_back( dULen) ; } // se ultima parte molto piccola, la elimino if ( bOk && ! vU.empty() && ( dLen - vLen.back()) < 2 * EPS_SMALL) { vU.pop_back() ; vLen.pop_back() ; } // recupero un intervallo di id contigui per tutte le parti int nFirstId = pGeomDB->GetNewId() ; if ( nFirstId == nId + 1) nFirstId = nId ; bOk = bOk && pGeomDB->ChangeId( nId, nFirstId) ; int nCurrId = nFirstId ; // eseguo la divisione int nCount = 1 ; double dUPrev = 0 ; double dLenPrev = 0 ; for ( int i = 0 ; i < int( vU.size()) ; ++ i) { // se lunghezza della curva risulta piccola, salto if ( ( vLen[i] - dLenPrev) < 2 * EPS_SMALL) continue ; // copio la curva int nCopyId = pGeomDB->Copy( nCurrId, GDB_ID_NULL, nCurrId, GDB_AFTER) ; ICurve* pCopyCrv = GetCurve( pGeomDB->GetGeoObj( nCopyId)) ; bOk = bOk && ( pCopyCrv != nullptr) ; ++ nCount ; // trimmo l'originale bOk = bOk && pCurve->TrimStartEndAtParam( dUPrev, vU[i]) ; // la copia diventa il nuovo corrente nCurrId = nCopyId ; pCurve = pCopyCrv ; dUPrev = vU[i] ; dLenPrev = vLen[i] ; } // se fatta almeno una suddivisione, trimmo l'ultima parte if ( dUPrev > EPS_PARAM) bOk = bOk && pCurve->TrimStartAtParam( dUPrev) ; nFirstId = ( bOk ? nFirstId : GDB_ID_NULL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSplitCurveAtSelfIntersections(" + ToString( nId) + ")" + " -- Id1=" + ToString( nFirstId) + ",Nbr=" + ToString( nCount) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco risultati if ( pnCount != nullptr) *pnCount = nCount ; return nFirstId ; } //---------------------------------------------------------------------------- int ExeGetCurveLinearConvexHullXY( int nId, double dLinTol, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // recupero la curva ICurve* pCurve = GetCurve( pGeomDB->GetGeoObj( nId)) ; bool bOk = ( pCurve != nullptr) ; // recupero il riferimento della curva Frame3d frCrv ; bOk = bOk && pGeomDB->GetGlobFrame( nId, frCrv) ; // derivo la polilinea di approssimazione della curva entro la tolleranza data PolyLine PL ; bOk = bOk && pCurve->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, APP_LINES, PL) ; // eventuale trasformazione per riferimento di espressione if ( bOk && nRefType == RTY_GLOB) PL.ToGlob( frCrv) ; else if ( bOk && nRefType == RTY_GRID) PL.LocToLoc( frCrv, pGeomDB->GetGridFrame()) ; // derivo il convex hull lineare di questa PNTVECTOR vCH ; bOk = bOk && PL.GetConvexHullXY( vCH) ; PolyLine PLCH ; for ( size_t i = 0 ; i < vCH.size() ; ++ i) PLCH.AddUPoint( double( i), vCH[i]) ; PLCH.Close() ; // creo la curva composita PtrOwner pCrvCompo( CreateCurveComposite()) ; bOk = bOk && ! IsNull( pCrvCompo) ; // inserisco i segmenti che uniscono i punti bOk = bOk && pCrvCompo->FromPolyLine( PLCH) ; // assegno il versore estrusione bOk = bOk && pCrvCompo->SetExtrusion( Z_AX) ; // eventuale trasformazione per riferimento di espressione if ( bOk && nRefType == RTY_GLOB) pCrvCompo->ToLoc( frCrv) ; else if ( bOk && nRefType == RTY_GRID) pCrvCompo->LocToLoc( pGeomDB->GetGridFrame(), frCrv) ; // inserisco la curva composita nel DB int nNewId = ( bOk ? pGeomDB->InsertGeoObj( GDB_ID_NULL, nId, GDB_AFTER, Release( pCrvCompo)) : GDB_ID_NULL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtGetCurveLinearConvexHullXY(" + IdToString( nId) + "," + ToString( dLinTol) + "," + RefTypeToString( nRefType) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nNewId ; } //------------------------------------------------------------------------------- bool ExeModifyCircleCP( int nId, const Point3d& ptOn, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) // recupero l'arco e i suoi dati ICurveArc* pArc = GetCurveArc( pGeomDB->GetGeoObj( nId)) ; if ( pArc == nullptr) return false ; Point3d ptCen = pArc->GetCenter() ; Vector3d vtN = pArc->GetNormVersor() ; double dOldRad = pArc->GetRadius() ; // recupero il riferimento locale Frame3d frLoc ; if ( ! pGeomDB->GetGlobFrame( nId, frLoc)) return false ; // porto in locale il nuovo punto Point3d ptOnL = GetPointLocal( pGeomDB, ptOn, nRefType, frLoc) ; // calcolo il nuovo raggio double dRad = (( ptOnL - ptCen) ^ vtN).Len() ; // imposto il nuovo raggio if ( pArc->Set( ptCen, vtN, dRad)) return true ; // in caso di errore, ripristino i vecchi dati else { pArc->Set( ptCen, vtN, dOldRad) ; return false ; } } //------------------------------------------------------------------------------- bool ExeModifyCircle3P( int nId, const Point3d& ptP1, const Point3d& ptP2, const Point3d& ptP3, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) // verifico esistenza cerchio originale if ( GetCurveArc( pGeomDB->GetGeoObj( nId)) == nullptr) return false ; // creo l'arco PtrOwner pCrvArc( CreateCurveArc()) ; if ( IsNull( pCrvArc)) return false ; // recupero il riferimento locale Frame3d frLoc ; if ( ! pGeomDB->GetGlobFrame( nId, frLoc)) return false ; // porto in locale i nuovi punti e l'estrusione di riferimento Point3d ptP1L = GetPointLocal( pGeomDB, ptP1, nRefType, frLoc) ; Point3d ptP2L = GetPointLocal( pGeomDB, ptP2, nRefType, frLoc) ; Point3d ptP3L = GetPointLocal( pGeomDB, ptP3, nRefType, frLoc) ; // imposto i nuovi punti if ( pCrvArc->Set3P( ptP1L, ptP2L, ptP3L, true)) { Vector3d vtExtrL = GetVectorLocal( pGeomDB, Z_AX, nRefType, frLoc) ; if ( ( pCrvArc->GetNormVersor() * vtExtrL) < 0) pCrvArc->InvertN() ; pCrvArc->SetExtrusion( pCrvArc->GetNormVersor()) ; return pGeomDB->ReplaceGeoObj( nId, Release( pCrvArc)) ; } // in caso di errore else return false ; } //------------------------------------------------------------------------------- static bool MyModifyArcRadius( IGeomDB* pGeomDB, int nId, double dRad) { // recupero l'arco e i suoi dati ICurveArc* pArc = GetCurveArc( pGeomDB->GetGeoObj( nId)) ; if ( pArc == nullptr) return false ; // imposto il nuovo raggio return pArc->ChangeRadius( dRad) ; } //------------------------------------------------------------------------------- static bool MyModifyArcRadiusEx( IGeomDB* pGeomDB, int nId, double dRad) { // recupero l'arco e i suoi dati ICurveArc* pArc = GetCurveArc( pGeomDB->GetGeoObj( nId)) ; if ( pArc == nullptr) return false ; // recupero gli estremi dell'arco e la loro distanza nel piano dell'arco Point3d ptStart, ptEnd ; if ( ! pArc->GetStartPoint( ptStart) || ! pArc->GetEndPoint( ptEnd)) return false ; double dPlaneDist = OrthoCompo( ( ptEnd - ptStart), pArc->GetNormVersor()).Len() ; // se angolo al centro maggiore o uguale ad un giro o estremi coincidenti, conservo il centro if ( abs( pArc->GetAngCenter()) >= ANG_FULL - EPS_ANG_ZERO || dPlaneDist < 2 * EPS_SMALL) return MyModifyArcRadius( pGeomDB, nId, dRad) ; // mantengo i punti estremi (pertanto il nuovo raggio non può essere inferiore a metà della loro distanza nel piano) if ( dRad < dPlaneDist / 2 - EPS_ZERO) return false ; // creo arco con gli stessi estremi, con identica normale e con nuovo raggio PtrOwner pCrvArc( CreateCurveArc()) ; if ( IsNull( pCrvArc) || ! pCrvArc->Set2PNRS( ptStart, ptEnd, pArc->GetNormVersor(), dRad, pArc->GetAngCenter() > 0)) return false ; // lo sostituisco all'originale return pGeomDB->ReplaceGeoObj( nId, Release( pCrvArc)) ; } //------------------------------------------------------------------------------- bool ExeModifyArcRadius( int nId, double dRad, bool bKeepCenter) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) bool bOk = ( bKeepCenter ? MyModifyArcRadius( pGeomDB, nId, dRad) : MyModifyArcRadiusEx( pGeomDB, nId, dRad)) ; if ( bOk) ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtModifyArcRadius(" + IdToString( nId) + "," + ToString( dRad) + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } return bOk ; } //------------------------------------------------------------------------------- bool ExeModifyArcC2P( int nId, const Point3d& ptEnd, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) // recupero l'arco e i suoi dati ICurveArc* pArc = GetCurveArc( pGeomDB->GetGeoObj( nId)) ; if ( pArc == nullptr) return false ; Point3d ptCen = pArc->GetCenter() ; Vector3d vtN = pArc->GetNormVersor() ; Point3d ptStart, ptOldEnd ; if ( ! pArc->GetStartPoint( ptStart) || ! pArc->GetEndPoint( ptOldEnd)) return false ; // recupero il riferimento locale Frame3d frLoc ; if ( ! pGeomDB->GetGlobFrame( nId, frLoc)) return false ; // porto in locale il nuovo punto finale Point3d ptEndL = GetPointLocal( pGeomDB, ptEnd, nRefType, frLoc) ; // imposto il nuovo punto finale if ( pArc->SetC2PN( ptCen, ptStart, ptEndL, vtN)) return true ; // in caso di errore, ripristino i vecchi dati else { pArc->SetC2PN( ptCen, ptStart, ptOldEnd, vtN) ; return false ; } } //------------------------------------------------------------------------------- bool ExeModifyArc3P( int nId, const Point3d& ptMid, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) // recupero l'arco e i suoi punti notevoli ICurveArc* pArc = GetCurveArc( pGeomDB->GetGeoObj( nId)) ; if ( pArc == nullptr) return false ; Point3d ptStartL, ptOldMidL, ptEndL ; if ( ! pArc->GetStartPoint( ptStartL) || ! pArc->GetMidPoint( ptOldMidL) || ! pArc->GetEndPoint( ptEndL)) return false ; // recupero il riferimento locale Frame3d frLoc ; if ( ! pGeomDB->GetGlobFrame( nId, frLoc)) return false ; // porto in locale il nuovo punto medio Point3d ptMidL = GetPointLocal( pGeomDB, ptMid, nRefType, frLoc) ; // imposto il nuovo punto medio if ( pArc->Set3P( ptStartL, ptMidL, ptEndL)) { Vector3d vtExtrL = GetVectorLocal( pGeomDB, Z_AX, nRefType, frLoc) ; if ( ( pArc->GetNormVersor() * vtExtrL) < 0) pArc->InvertN() ; pArc->SetExtrusion( pArc->GetNormVersor()) ; return true ; } // in caso di errore, ripristino i vecchi dati else { pArc->Set3P( ptStartL, ptOldMidL, ptEndL) ; return false ; } } //------------------------------------------------------------------------------- bool ExeModifyArcToExplementary( int nId) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) // recupero l'arco ICurveArc* pArc = GetCurveArc( pGeomDB->GetGeoObj( nId)) ; if ( pArc == nullptr) return false ; // eseguo trasformazione return pArc->ToExplementary() ; } //------------------------------------------------------------------------------- bool ExeModifyArcByFlip( int nId) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) // recupero l'arco ICurveArc* pArc = GetCurveArc( pGeomDB->GetGeoObj( nId)) ; if ( pArc == nullptr) return false ; // eseguo trasformazione return pArc->Flip() ; } //------------------------------------------------------------------------------- bool ExeCloseCurveCompo( int nId) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) bool bOk = true ; // recupero la curva composita ICurveComposite* pCompo = GetCurveComposite( pGeomDB->GetGeoObj( nId)) ; bOk = bOk && ( pCompo != nullptr) ; // eseguo chiusura bOk = bOk && pCompo->Close() ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtCloseCurveCompo(" + ToString( nId) + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco il risultato return bOk ; } //------------------------------------------------------------------------------- bool MyAddCurveCompoCurve( int nId, int nAddCrvId, bool bEraseOrig, bool bEndVsStart) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) // recupero la curva composita ICurveComposite* pCompo = GetCurveComposite( pGeomDB->GetGeoObj( nId)) ; if ( pCompo == nullptr) return false ; // recupero il riferimento locale Frame3d frLoc ; if ( ! pGeomDB->GetGlobFrame( nId, frLoc)) return false ; // recupero la curva const ICurve* pCrv = GetCurve( pGeomDB->GetGeoObj( nAddCrvId)) ; if ( pCrv == nullptr) return false ; // recupero il riferimento della curva Frame3d frSou ; if ( ! pGeomDB->GetGlobFrame( nAddCrvId, frSou)) return false ; // creo una copia della curva PtrOwner pCopCrv( pCrv->Clone()) ; if ( IsNull( pCopCrv)) return false ; // se i riferimenti sono diversi, eseguo la trasformazione if ( ! AreSameFrame( frSou, frLoc)) pCopCrv->LocToLoc( frSou, frLoc) ; // aggiungo alla composita if ( ! pCompo->AddCurve( Release( pCopCrv), bEndVsStart)) return false ; // se richiesto, cancello la curva originale if ( bEraseOrig) pGeomDB->Erase( nAddCrvId) ; return true ; } //------------------------------------------------------------------------------- bool ExeAddCurveCompoCurve( int nId, int nAddCrvId, bool bEraseOrig, bool bEndVsStart) { // eseguo bool bOk = MyAddCurveCompoCurve( nId, nAddCrvId, bEraseOrig, bEndVsStart) ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtAddCurveCompoCurve(" + IdToString( nId) + "," + IdToString( nAddCrvId) + "," + ( bEraseOrig ? "true" : "false") + "," + ( bEndVsStart ? "true" : "false") + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return bOk ; } //------------------------------------------------------------------------------- bool ExeAddCurveCompoLine( int nId, const Point3d& ptP, bool bEndVsStart, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) bool bOk = true ; // recupero la curva composita ICurveComposite* pCompo = GetCurveComposite( pGeomDB->GetGeoObj( nId)) ; bOk = bOk && ( pCompo != nullptr) ; // recupero il riferimento locale Frame3d frLoc ; bOk = bOk && pGeomDB->GetGlobFrame( nId, frLoc) ; // porto in locale il nuovo punto Point3d ptPL = GetPointLocal( pGeomDB, ptP, nRefType, frLoc) ; // eseguo la modifica bOk = bOk && pCompo->AddLine( ptPL, bEndVsStart) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtAddCurveCompoLine(" + ToString( nId) + ",{" + ToString( ptP) + "}," + ( bEndVsStart ? "true" : "false") + "," + RefTypeToString( nRefType) + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco il risultato return bOk ; } //------------------------------------------------------------------------------- bool ExeAddCurveCompoLineTg( int nId, double dLen, bool bEndVsStart) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) bool bOk = true ; // recupero la curva composita ICurveComposite* pCompo = GetCurveComposite( pGeomDB->GetGeoObj( nId)) ; bOk = bOk && ( pCompo != nullptr) ; // eseguo la modifica bOk = bOk && pCompo->AddLineTg( dLen, bEndVsStart) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtAddCurveCompoLineTg(" + ToString( nId) + ",{" + ToString( dLen) + "}," + ( bEndVsStart ? "true" : "false") + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco il risultato return bOk ; } //------------------------------------------------------------------------------- bool ExeAddCurveCompoArc2P( int nId, const Point3d& ptMid, const Point3d& ptP, bool bEndVsStart, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) bool bOk = true ; // recupero la curva composita ICurveComposite* pCompo = GetCurveComposite( pGeomDB->GetGeoObj( nId)) ; bOk = bOk && ( pCompo != nullptr) ; // recupero il riferimento locale Frame3d frLoc ; bOk = bOk && pGeomDB->GetGlobFrame( nId, frLoc) ; // porto in locale i punti Point3d ptMidL = GetPointLocal( pGeomDB, ptMid, nRefType, frLoc) ; Point3d ptPL = GetPointLocal( pGeomDB, ptP, nRefType, frLoc) ; // eseguo la modifica bOk = bOk && pCompo->AddArc2P( ptMidL, ptPL, bEndVsStart) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtAddCurveCompoArc2P(" + ToString( nId) + ",{" + ToString( ptMid) + "},{" + ToString( ptP) + "}," + ( bEndVsStart ? "true" : "false") + "," + RefTypeToString( nRefType) + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco il risultato return bOk ; } //------------------------------------------------------------------------------- bool ExeAddCurveCompoArcTg( int nId, const Point3d& ptP, bool bEndVsStart, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) bool bOk = true ; // recupero la curva composita ICurveComposite* pCompo = GetCurveComposite( pGeomDB->GetGeoObj( nId)) ; bOk = bOk && ( pCompo != nullptr) ; // recupero il riferimento locale Frame3d frLoc ; bOk = bOk && pGeomDB->GetGlobFrame( nId, frLoc) ; // porto in locale il nuovo punto Point3d ptPL = GetPointLocal( pGeomDB, ptP, nRefType, frLoc) ; // eseguo la modifica bOk = bOk && pCompo->AddArcTg( ptPL, bEndVsStart) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtAddCurveCompoArcTg(" + ToString( nId) + ",{" + ToString( ptP) + "}," + ( bEndVsStart ? "true" : "false") + "," + RefTypeToString( nRefType) + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco il risultato return bOk ; } //------------------------------------------------------------------------------- bool ExeRemoveCurveCompoCurve( int nId, bool bLast) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) bool bOk = true ; // recupero la curva composita ICurveComposite* pCompo = GetCurveComposite( pGeomDB->GetGeoObj( nId)) ; bOk = bOk && ( pCompo != nullptr) ; // eseguo la modifica if ( bOk) delete( pCompo->RemoveFirstOrLastCurve( bLast)) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtRemoveCurveCompoCurve(" + ToString( nId) + "," + ( bLast ? "true" : "false") + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco il risultato return bOk ; } //------------------------------------------------------------------------------- bool ExeAddCurveCompoJoint( int nId, double dU) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) bool bOk = true ; // recupero la curva composita ICurveComposite* pCompo = GetCurveComposite( pGeomDB->GetGeoObj( nId)) ; bOk = bOk && ( pCompo != nullptr) ; // eseguo la modifica bOk = bOk && pCompo->AddJoint( dU) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtAddCurveCompoJoint(" + ToString( nId) + "," + ToString( dU) + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco il risultato return bOk ; } //------------------------------------------------------------------------------- bool ExeModifyCurveCompoJoint( int nId, int nU, const Point3d& ptP, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) bool bOk = true ; // recupero la curva composita ICurveComposite* pCompo = GetCurveComposite( pGeomDB->GetGeoObj( nId)) ; bOk = bOk && ( pCompo != nullptr) ; // recupero il riferimento locale Frame3d frLoc ; bOk = bOk && pGeomDB->GetGlobFrame( nId, frLoc) ; // porto in locale il nuovo punto Point3d ptPL = GetPointLocal( pGeomDB, ptP, nRefType, frLoc) ; // eseguo la modifica bOk = bOk && pCompo->ModifyJoint( nU, ptPL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtModifyCurveCompoJoint(" + ToString( nId) + "," + ToString( nU) + ",{" + ToString( ptP) + "}," + RefTypeToString( nRefType) + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco il risultato return bOk ; } //------------------------------------------------------------------------------- int ExeGetCurveCompoJointCount( int nId) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, 0) // recupero la curva composita ICurveComposite* pCompo = GetCurveComposite( pGeomDB->GetGeoObj( nId)) ; if ( pCompo == nullptr) return 0 ; // calcolo il numero di giunzioni (se chiusa è uguale al numero delle curve altrimenti -1) if ( pCompo->IsClosed()) return pCompo->GetCurveCount() ; else return ( pCompo->GetCurveCount() - 1) ; } //------------------------------------------------------------------------------- bool ExeRemoveCurveCompoJoint( int nId, int nU) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) bool bOk = true ; // recupero la curva composita ICurveComposite* pCompo = GetCurveComposite( pGeomDB->GetGeoObj( nId)) ; bOk = bOk && ( pCompo != nullptr) ; // eseguo la modifica bOk = bOk && pCompo->RemoveJoint( nU) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtRemoveCurveCompoJoint(" + ToString( nId) + "," + ToString( nU) + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco il risultato return bOk ; } //------------------------------------------------------------------------------- bool ExeMoveCurveCompoCurve( int nId, int nCrv, const Vector3d& vtMove, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) bool bOk = true ; // recupero la curva composita ICurveComposite* pCompo = GetCurveComposite( pGeomDB->GetGeoObj( nId)) ; bOk = bOk && ( pCompo != nullptr) ; // recupero il riferimento locale Frame3d frLoc ; bOk = bOk && pGeomDB->GetGlobFrame( nId, frLoc) ; // porto in locale il movimento Vector3d vtMoveL = GetVectorLocal( pGeomDB, vtMove, nRefType, frLoc) ; // eseguo la modifica bOk = bOk && pCompo->MoveCurve( nCrv, vtMoveL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtMoveCurveCompoCurve(" + ToString( nId) + "," + ToString( nCrv) + ",{" + ToString( vtMove) + "}," + RefTypeToString( nRefType) + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco il risultato return bOk ; } //------------------------------------------------------------------------------- bool ExeModifyCurveCompoCurveToArc( int nId, int nCrv, const Point3d& ptMid, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) bool bOk = true ; // recupero la curva composita ICurveComposite* pCompo = GetCurveComposite( pGeomDB->GetGeoObj( nId)) ; bOk = bOk && ( pCompo != nullptr) ; // recupero il riferimento locale Frame3d frLoc ; bOk = bOk && pGeomDB->GetGlobFrame( nId, frLoc) ; // porto in locale il nuovo punto Point3d ptMidL = GetPointLocal( pGeomDB, ptMid, nRefType, frLoc) ; // eseguo la modifica bOk = bOk && pCompo->ModifyCurveToArc( nCrv, ptMidL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtModifyCurveCompoCurveToArc(" + ToString( nId) + "," + ToString( nCrv) + ",{" + ToString( ptMid) + "}," + RefTypeToString( nRefType) + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco il risultato return bOk ; } //------------------------------------------------------------------------------- bool ExeModifyCurveCompoCurveToLine( int nId, int nCrv) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) bool bOk = true ; // recupero la curva composita ICurveComposite* pCompo = GetCurveComposite( pGeomDB->GetGeoObj( nId)) ; bOk = bOk && ( pCompo != nullptr) ; // eseguo la modifica bOk = bOk && pCompo->ModifyCurveToLine( nCrv) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtModifyCurveCompoCurveToLine(" + ToString( nId) + "," + ToString( nCrv) + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco il risultato return bOk ; } //------------------------------------------------------------------------------- int ExeExplodeCurveCompo( int nId, int* pnCount) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // recupero la curva composita ICurveComposite* pCompo = GetCurveComposite( pGeomDB->GetGeoObj( nId)) ; bool bOk = ( pCompo != nullptr) ; // estraggo tutte le curve int nFirstId = GDB_ID_NULL ; int nCount = 0 ; ICurve* pCrv ; while ( bOk && ( pCrv = pCompo->RemoveFirstOrLastCurve( false)) != nullptr) { // inserisco la curva nello stesso gruppo e nello stesso posto del GeomDB int nCrvId = pGeomDB->InsertGeoObj( GDB_ID_NULL, nId, GDB_BEFORE, pCrv) ; bOk = bOk && ( nCrvId != GDB_ID_NULL) ; // copio gli attributi bOk = bOk && pGeomDB->CopyAttributes( nId, nCrvId) ; // aggiorno contatori if ( bOk) { if ( nFirstId == GDB_ID_NULL) nFirstId = nCrvId ; ++ nCount ; } } nFirstId = ( bOk ? nFirstId : GDB_ID_NULL) ; // elimino la curva composita ormai vuota bOk = bOk && pGeomDB->Erase( nId) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtExplodeCurveCompo(" + ToString( nId) + ")" + " -- Id1=" + ToString( nFirstId) + ",Nbr=" + ToString( nCount) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco risultati if ( pnCount != nullptr) *pnCount = nCount ; return nFirstId ; } //------------------------------------------------------------------------------- bool ExeMergeCurvesInCurveCompo( int nId, double dLinTol, bool bStartEnd) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // recupero la curva composita ICurveComposite* pCompo = GetCurveComposite( pGeomDB->GetGeoObj( nId)) ; bool bOk = ( pCompo != nullptr) ; // lancio il merge delle curve componenti bOk = bOk && pCompo->MergeCurves( dLinTol, ANG_TOL_STD_DEG, bStartEnd) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtMergeCurvesInCurveCompo(" + ToString( nId) + "," + ToString( dLinTol) + "," + ( bStartEnd ? "true" : "false") + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } return bOk ; } //------------------------------------------------------------------------------- bool ExeRemoveCurveCompoUndercutOnY( int nId, double dLinTol) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // recupero la curva composita ICurveComposite* pCompo = GetCurveComposite( pGeomDB->GetGeoObj( nId)) ; bool bOk = ( pCompo != nullptr) ; // lancio l'eliminazione delle parti sotto rispetto alla direzione Y+ bOk = bOk && pCompo->RemoveUndercutOnY( dLinTol, ANG_TOL_STD_DEG) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtRemoveCurveCompoUndercutOnY(" + ToString( nId) + "," + ToString( dLinTol) + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } return bOk ; } //------------------------------------------------------------------------------- static bool MyChainCurvesInGroup( int nGroupId, const Point3d& ptNear, bool bAllowInvert, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nGroupId = AdjustId( nGroupId) ; // recupero il riferimento del gruppo Frame3d frGrp ; if ( ! pGeomDB->GetGroupGlobFrame( nGroupId, frGrp)) return false ; // preparo i dati per il concatenamento double dToler = 10 * EPS_SMALL ; ChainCurves chainC ; chainC.Init( bAllowInvert, dToler, pGeomDB->GetGroupObjs( nGroupId)) ; int nId = pGeomDB->GetFirstInGroup( nGroupId) ; while ( nId != GDB_ID_NULL) { // recupero la curva ICurve* pCrv = GetCurve( pGeomDB->GetGeoObj( nId)) ; if ( pCrv != nullptr) { // recupero i dati della curva necessari al concatenamento e li assegno Point3d ptStart, ptEnd ; Vector3d vtStart, vtEnd ; if ( ! pCrv->GetStartPoint( ptStart) || ! pCrv->GetStartDir( vtStart) || ! pCrv->GetEndPoint( ptEnd) || ! pCrv->GetEndDir( vtEnd)) return false ; if ( ! chainC.AddCurve( nId, ptStart, vtStart, ptEnd, vtEnd)) return false ; } // passo al successivo nId = pGeomDB->GetNext( nId) ; } // recupero i percorsi concatenati Point3d ptNearL = GetPointLocal( pGeomDB, ptNear, nRefType, frGrp) ; INTVECTOR vId2s ; while ( chainC.GetChainFromNear( ptNearL, false, vId2s)) { // recupero le curve e le sposto in fondo al gruppo for ( size_t i = 0 ; i < vId2s.size() ; ++ i) { int nId = abs( vId2s[i]) ; bool bInvert = ( vId2s[i] < 0) ; // sposto la curva in fondo pGeomDB->Relocate( nId, nGroupId) ; // se da invertire if ( bInvert) { ICurve* pCrv = GetCurve( pGeomDB->GetGeoObj( nId)) ; if ( pCrv == nullptr) return false ; pCrv->Invert() ; } } } return true ; } //------------------------------------------------------------------------------- bool ExeChainCurvesInGroup( int nGroupId, const Point3d& ptNear, int nRefType) { bool bOk = MyChainCurvesInGroup(nGroupId, ptNear, true, nRefType) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtChainCurvesInGroup(" + ToString( nGroupId) + "," + ToString( ptNear) + "}," + RefTypeToString( nRefType) + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } return bOk ; } //------------------------------------------------------------------------------- bool ExeReorderCurvesInGroup( int nGroupId, const Point3d& ptNear, int nRefType) { bool bOk = MyChainCurvesInGroup(nGroupId, ptNear, false, nRefType) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtReorderCurvesInGroup(" + ToString( nGroupId) + "," + ToString( ptNear) + "}," + RefTypeToString( nRefType) + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } return bOk ; }