//---------------------------------------------------------------------------- // 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/EGkGeoPoint3d.h" #include "/EgtDev/Include/EGkGeoVector3d.h" #include "/EgtDev/Include/EGkCurveLine.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/EGkSurfLocal.h" #include "/EgtDev/Include/EGkCurveAux.h" #include "/EgtDev/Include/EGkOffsetCurve.h" #include "/EgtDev/Include/EGkMedialAxis.h" #include "/EgtDev/Include/EGkChainCurves.h" #include "/EgtDev/Include/EGkProjectCurveSurf.h" #include "/EgtDev/Include/EGkSurfFlatRegion.h" #include "/EgtDev/Include/EGkSfrCreate.h" #include "/EgtDev/Include/EGkSurfBezier.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/EGkCalcPocketing.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, double dLinTol) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // recupero la curva const ICurve* pCurve = GetCurve( pGeomDB->GetGeoObj( nId)) ; // eseguo l'offset OffsetCurve OffsCrv( dLinTol) ; 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, double dMaxSegmLen) { 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) && PL.AdjustForMaxSegmentLen( dMaxSegmLen) && pCC->FromPolyLine( PL) ; // eliminazione di small Z bOk = bOk && pCC->RemoveSmallDefects( 0.5 * dLinTol, ANG_TOL_STD_DEG) ; } else if ( nApprType == APP_ARCS) { // 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) ; } else if ( nApprType == APP_CUBIC_BEZIER) { PtrOwner pCrv( ApproxCurveWithBezier( pCurve, dLinTol)) ; bOk = bOk && ! IsNull( pCrv) ; bOk = bOk && pCC->AddCurve( Release( pCrv)) ; } // 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) + "," + ToString( dMaxSegmLen) + ")" + " -- 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 double dPar ; int nFlag ; bOk = bOk && DistPointCurve( ptPL, *pCurve).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) // 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 nuovo punto iniziale Point3d ptPL = GetPointLocal( pGeomDB, ptP, nRefType, frLoc) ; // ne modifico il punto iniziale if ( bOk && ! pCurve->ModifyStart( ptPL)) { bOk = false ; Point3d ptEnd ; if ( pCurve->GetEndPoint( ptEnd) && ! AreSamePointApprox( ptPL, ptEnd)) { PtrOwner pLine( CreateCurveLine()) ; if ( ! IsNull( pLine) && pLine->Set( ptPL, ptEnd)) bOk = pGeomDB->ReplaceGeoObj( nId, Release( pLine)) ; } } 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) // 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 nuovo punto finale Point3d ptPL = GetPointLocal( pGeomDB, ptP, nRefType, frLoc) ; // ne modifico il punto finale if ( bOk && ! pCurve->ModifyEnd( ptPL)) { bOk = false ; Point3d ptStart ; if ( pCurve->GetStartPoint( ptStart) && ! AreSamePointApprox( ptStart, ptPL)) { PtrOwner pLine( CreateCurveLine()) ; if ( ! IsNull( pLine) && pLine->Set( ptStart, ptPL)) bOk = pGeomDB->ReplaceGeoObj( nId, Release( pLine)) ; } } 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) ; // correzione per gestione ottimale degli spigoli : // individuo gli spigoli const double CORNER_COS = 0.96 ; int nTotP1 = vPnt1.size() ; int nTotP2 = vPnt2.size() ; BOOLVECTOR vSharpCorner1( nTotP1, false), vSharpCorner2( nTotP2, false) ; for ( int i = 0 ; i < nTotP1 - 1 ; i ++) { // se estremo di curva aperta non è spigolo if ( i == 0 && ! PL1.IsClosed()) continue ; // recupero direzioni precedente e successiva int nPrevI = ( i == 0 ? nTotP1 - 2 : i - 1) ; int nNextI = i + 1 ; Vector3d vtPrev = vPnt1[i].first - vPnt1[nPrevI].first ; vtPrev.Normalize() ; Vector3d vtNext = vPnt1[nNextI].first - vPnt1[i].first ; vtNext.Normalize() ; vSharpCorner1[i] = ( vtPrev * vtNext < CORNER_COS) ; } if ( bOk) vSharpCorner1.back() = vSharpCorner1.front() ; for ( int i = 0 ; i < nTotP2 - 1 ; i ++) { if ( i == 0 && ! PL2.IsClosed()) continue ; int nPrevI = ( i == 0 ? nTotP2 - 2 : i - 1) ; int nNextI = i + 1 ; Vector3d vtPrev = vPnt2[i].first - vPnt2[nPrevI].first ; vtPrev.Normalize() ; Vector3d vtNext = vPnt2[nNextI].first - vPnt2[i].first ; vtNext.Normalize() ; vSharpCorner2[i] = ( vtPrev * vtNext < CORNER_COS) ; } if ( bOk) vSharpCorner2.back() = vSharpCorner2.front() ; // se spigolo non associato ad altro spigolo, verifico se esiste un possibile spigolo da associare for ( int i = 0 ; i < nTotP1 ; i ++) { if ( vSharpCorner1[i] && ! vSharpCorner2[vPnt1[i].second]) { // individuo i limiti per la ricerca dello spigolo int nPrevI = ( i == 0 ? 0 : i - 1) ; int nNextI = ( i == nTotP1 - 1 ? i : i + 1) ; int nPrevJ = vPnt1[nPrevI].second ; int nNextJ = vPnt1[nNextI].second ; int nStart = ( vSharpCorner2[nPrevJ] ? nPrevJ + 1 : nPrevJ) ; int nEnd = ( vSharpCorner2[nNextJ] ? nNextJ - 1 : nNextJ) ; double dSqMinDist = INFINITO ; int nCorner = vPnt1[i].second ; // cerco lo spigolo più vicino nel range fissato for ( int j = nStart ; j <= nEnd ; j ++) { if ( vSharpCorner2[j]) { double dSqDist = SqDist( vPnt1[i].first, vPnt2[j].first) ; if ( dSqDist < dSqMinDist) { dSqMinDist = dSqDist ; nCorner = j ; } } } vPnt1[i].second = nCorner ; } } 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 ExeModifyArcAngCenter( int nId, double dAngCenter) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) // recupero l'arco ICurveArc* pArc = GetCurveArc( pGeomDB->GetGeoObj( nId)) ; if ( pArc == nullptr) return false ; // modifico angolo al centro return pArc->ChangeAngCenter( dAngCenter) ; } //------------------------------------------------------------------------------- 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 ; } //------------------------------------------------------------------------------- static 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 il riferimento locale Frame3d frLoc ; bOk = bOk && pGeomDB->GetGlobFrame( nId, frLoc) ; // porto in locale il nuovo punto Point3d ptPL = GetPointLocal( pGeomDB, ptP, nRefType, frLoc) ; // se l'entità da modificare è un punto geometrico if ( pGeomDB->GetGeoType( nId) == GEO_PNT3D) { // creo la curva composita PtrOwner pCompo( CreateCurveComposite()) ; bOk = bOk && ( ! IsNull( pCompo)) ; // recupero il punto di start Point3d ptStart = GetGeoPoint3d( pGeomDB->GetGeoObj( nId))->GetPoint() ; // sistemo la curva composita bOk = bOk && pCompo->AddPoint( ptStart) && pCompo->AddLine( ptPL, bEndVsStart) ; // la sostituisco al GeoPoint originale bOk = bOk && pGeomDB->ReplaceGeoObj( nId, Release( pCompo)) ; } // altrimenti deve essere curva composita else { // recupero la curva composita ICurveComposite* pCompo = GetCurveComposite( pGeomDB->GetGeoObj( nId)) ; bOk = bOk && ( pCompo != nullptr) ; // eseguo la modifica bOk = bOk && pCompo->AddLine( ptPL, bEndVsStart) ; } // dichiaro modificato progetto 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 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) ; // se l'entità da modificare è un punto geometrico if ( pGeomDB->GetGeoType( nId) == GEO_PNT3D) { // creo la curva composita PtrOwner pCompo( CreateCurveComposite()) ; bOk = bOk && ( ! IsNull( pCompo)) ; // recupero il punto di start Point3d ptStart = GetGeoPoint3d( pGeomDB->GetGeoObj( nId))->GetPoint() ; // sistemo la curva composita bOk = bOk && pCompo->AddPoint( ptStart) && pCompo->AddArc2P( ptMidL, ptPL, bEndVsStart) ; // la sostituisco al GeoPoint originale bOk = bOk && pGeomDB->ReplaceGeoObj( nId, Release( pCompo)) ; } // altrimenti deve essere curva composita else { // recupero la curva composita ICurveComposite* pCompo = GetCurveComposite( pGeomDB->GetGeoObj( nId)) ; bOk = bOk && ( pCompo != nullptr) ; // 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, false) // 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, false) // 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 ; } //---------------------------------------------------------------------------- bool ExeCurveCompoSetTempProp( int nId, int nCrv, int nProp, int nPropInd) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) // recupero la curva composita ICurveComposite* pCompo = GetCurveComposite( pGeomDB->GetGeoObj( nId)) ; bool bOk = ( pCompo != nullptr) ; // imposto il valore bOk = bOk && pCompo->SetCurveTempProp( nCrv, nProp, nPropInd) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtCurveCompoSetTempProp(" + ToString( nId) + "," + ToString( nCrv) + "," + ToString( nProp) + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } return bOk ; } //---------------------------------------------------------------------------- bool ExeCurveCompoSetTempParam( int nId, int nCrv, double dParam, int nParamInd) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) // recupero la curva composita ICurveComposite* pCompo = GetCurveComposite( pGeomDB->GetGeoObj( nId)) ; bool bOk = ( pCompo != nullptr) ; // imposto il valore bOk = bOk && pCompo->SetCurveTempParam( nCrv, dParam, nParamInd) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtCurveCompoSetTempParam(" + ToString( nId) + "," + ToString( nCrv) + "," + ToString( dParam) + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } return bOk ; } //------------------------------------------------------------------------------- static bool MyChainCurvesInGroup( int nGroupId, const Point3d& ptNear, bool bAllowInvert, int nRefType, double dToler) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) nGroupId = AdjustId( nGroupId) ; // recupero il riferimento del gruppo Frame3d frGrp ; if ( ! pGeomDB->GetGroupGlobFrame( nGroupId, frGrp)) return false ; // preparo i dati per il concatenamento 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, double dToler) { bool bOk = MyChainCurvesInGroup( nGroupId, ptNear, true, nRefType, dToler) ; 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, double dToler) { bool bOk = MyChainCurvesInGroup( nGroupId, ptNear, false, nRefType, dToler) ; 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 ; } //------------------------------------------------------------------------------- static bool MyProjectCurveOnSurf( int nCurveId, const INTVECTOR& vnSurfId, int nDestGrpId, double dLinTol, double dMaxSegmLen) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) // recupero la curva e il suo riferimento const ICurve* pCrv = GetCurve( pGeomDB->GetGeoObj( nCurveId)) ; if ( pCrv == nullptr) return false ; Frame3d frCrv ; if ( ! pGeomDB->GetGlobFrame( nCurveId, frCrv)) return false ; // deve esserci almeno una superficie if ( vnSurfId.empty()) return false ; // recupero il riferimento della prima superficie Frame3d frSurf ; if ( ! pGeomDB->GetGlobFrame( vnSurfId[0], frSurf)) return false ; // recupero le superfici e le porto tutte in locale alla prima SURFLOCALVECTOR vSurfL ; vSurfL.reserve( vnSurfId.size()) ; CISURFPVECTOR vpSurf ; vpSurf.reserve( vnSurfId.size()) ; for ( int i = 0 ; i < int( vnSurfId.size()) ; ++ i) { vSurfL.emplace_back( pGeomDB, vnSurfId[i], frSurf) ; if ( vSurfL[i].Get() == nullptr) return false ; vpSurf.emplace_back( vSurfL[i].Get()) ; } // recupero il riferimento del gruppo di destinazione nDestGrpId = AdjustId( nDestGrpId) ; Frame3d frDest ; if ( ! pGeomDB->GetGroupGlobFrame( nDestGrpId, frDest)) return false ; // porto la curva e il vettore nel riferimento della superficie CurveLocal CrvLoc( pCrv, frCrv, frSurf) ; if ( CrvLoc.Get() == nullptr) return false ; // eseguo la proiezione PNT5AXVECTOR vPt5ax ; if ( ! ProjectCurveOnSurf( *CrvLoc.Get(), vpSurf, dLinTol, dMaxSegmLen, true, vPt5ax)) return false ; // inserisco la composita nel gruppo destinazione PtrOwner pCompo ; for ( const auto& Pt5ax : vPt5ax) { if ( IsNull( pCompo)) { pCompo.Set( CreateCurveComposite()) ; if ( IsNull( pCompo)) return false ; pCompo->AddPoint( GetLocToLoc( Pt5ax.ptP, frSurf, frDest)) ; } else pCompo->AddLine( GetLocToLoc( Pt5ax.ptP, frSurf, frDest)) ; } int nCompoId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pCompo)) ; if ( nCompoId == GDB_ID_NULL) return false ; // aggiungo i versori nel gruppo destinazione int nInd = 0 ; for ( const auto& Pt5ax : vPt5ax) { PtrOwner pGeoVct( CreateGeoVector3d()) ; if ( IsNull( pGeoVct)) return false ; pGeoVct->Set( 10 * GetLocToLoc( Pt5ax.vtDir1, frSurf, frDest), GetLocToLoc( Pt5ax.ptP, frSurf, frDest)) ; int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pGeoVct)) ; if ( nNewId == GDB_ID_NULL) return false ; pGeomDB->SetInfo( nNewId, "Ind", nInd ++) ; pGeomDB->SetInfo( nNewId, "Par", Pt5ax.dPar) ; pGeomDB->SetInfo( nNewId, "Flag", Pt5ax.nFlag) ; pGeomDB->SetInfo( nNewId, "DirU", Pt5ax.vtDirU) ; pGeomDB->SetInfo( nNewId, "DirV", Pt5ax.vtDirV) ; } return true ; } //------------------------------------------------------------------------------- bool ExeProjectCurveOnSurf( int nCurveId, const INTVECTOR& vnSurfId, int nDestGrpId, double dLinTol, double dMaxSegmLen) { bool bOk = MyProjectCurveOnSurf( nCurveId, vnSurfId, nDestGrpId, dLinTol, dMaxSegmLen) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtProjectCurveOnSurf(" + ToString( nCurveId) + ",{" + ToString( vnSurfId) + "},{" + ToString( nDestGrpId) + "," + ToString( dLinTol) + "," + ToString( dMaxSegmLen) + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } return bOk ; } //------------------------------------------------------------------------------- static bool MyProjectCurveOnSurfDir( int nCurveId, const INTVECTOR& vnSurfId, const Vector3d& vtProj, int nDestGrpId, double dLinTol, double dMaxSegmLen, bool bDirFromProj, bool bFromVsTo, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) // recupero la curva e il suo riferimento const ICurve* pCrv = GetCurve( pGeomDB->GetGeoObj( nCurveId)) ; if ( pCrv == nullptr) return false ; Frame3d frCrv ; if ( ! pGeomDB->GetGlobFrame( nCurveId, frCrv)) return false ; // deve esserci almeno una superficie if ( vnSurfId.empty()) return false ; // recupero il riferimento della prima superficie Frame3d frSurf ; if ( ! pGeomDB->GetGlobFrame( vnSurfId[0], frSurf)) return false ; // recupero le superfici e le porto tutte in locale alla prima SURFLOCALVECTOR vSurfL ; vSurfL.reserve( vnSurfId.size()) ; CISURFPVECTOR vpSurf ; vpSurf.reserve( vnSurfId.size()) ; for ( int i = 0 ; i < int( vnSurfId.size()) ; ++ i) { vSurfL.emplace_back( pGeomDB, vnSurfId[i], frSurf) ; if ( vSurfL[i].Get() == nullptr) return false ; vpSurf.emplace_back( vSurfL[i].Get()) ; } // recupero il riferimento del gruppo di destinazione nDestGrpId = AdjustId( nDestGrpId) ; Frame3d frDest ; if ( ! pGeomDB->GetGroupGlobFrame( nDestGrpId, frDest)) return false ; // porto la curva e il vettore nel riferimento della superficie CurveLocal CrvLoc( pCrv, frCrv, frSurf) ; if ( CrvLoc.Get() == nullptr) return false ; Vector3d vtProjL = GetVectorLocal( pGeomDB, vtProj, nRefType, frCrv) ; vtProjL.LocToLoc( frCrv, frSurf) ; // vanno affilati gli spigoli solo se direzione non da proiezione bool bSharpEdges = ( ! bDirFromProj) ; // eseguo la proiezione PNT5AXVECTOR vPt5ax ; if ( ! ProjectCurveOnSurf( *CrvLoc.Get(), vpSurf, vtProjL, dLinTol, dMaxSegmLen, bSharpEdges, bFromVsTo, vPt5ax)) return false ; // inserisco la composita nel gruppo destinazione PtrOwner pCompo ; for ( const auto& Pt5ax : vPt5ax) { if ( IsNull( pCompo)) { pCompo.Set( CreateCurveComposite()) ; if ( IsNull( pCompo)) return false ; pCompo->AddPoint( GetLocToLoc( Pt5ax.ptP, frSurf, frDest)) ; } else pCompo->AddLine( GetLocToLoc( Pt5ax.ptP, frSurf, frDest)) ; } int nCompoId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pCompo)) ; if ( nCompoId == GDB_ID_NULL) return false ; // aggiungo i versori nel gruppo destinazione int nInd = 0 ; for ( const auto& Pt5ax : vPt5ax) { PtrOwner pGeoVct( CreateGeoVector3d()) ; if ( IsNull( pGeoVct)) return false ; Vector3d vtDir = ( bDirFromProj ? Pt5ax.vtDir2 : Pt5ax.vtDir1) ; pGeoVct->Set( 10 * GetLocToLoc( vtDir, frSurf, frDest), GetLocToLoc( Pt5ax.ptP, frSurf, frDest)) ; int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pGeoVct)) ; if ( nNewId == GDB_ID_NULL) return false ; pGeomDB->SetInfo( nNewId, "Ind", nInd ++) ; pGeomDB->SetInfo( nNewId, "Par", Pt5ax.dPar) ; pGeomDB->SetInfo( nNewId, "Flag", Pt5ax.nFlag) ; } return true ; } //------------------------------------------------------------------------------- bool ExeProjectCurveOnSurfDir( int nCurveId, const INTVECTOR& vnSurfId, const Vector3d& vtProj, int nDestGrpId, double dLinTol, double dMaxSegmLen, bool bDirFromProj, bool bFromVsTo, int nRefType) { bool bOk = MyProjectCurveOnSurfDir( nCurveId, vnSurfId, vtProj, nDestGrpId, dLinTol, dMaxSegmLen, bDirFromProj, bFromVsTo, nRefType) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtProjectCurveOnSurfDir(" + ToString( nCurveId) + ",{" + ToString( vnSurfId) + "},{" + ToString( vtProj) + "}," + ToString( nDestGrpId) + "," + ToString( dLinTol) + "," + ToString( dMaxSegmLen) + "," + ( bDirFromProj ? "true" : "false") + "," + ( bFromVsTo ? "true" : "false") + "," + RefTypeToString( nRefType) + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } return bOk ; } //------------------------------------------------------------------------------- static bool MyProjectCurveOnSurfExt( int nCurveId, const INTVECTOR& vnSurfId, int nGuideId, int nDestGrpId, double dLinTol, double dMaxSegmLen, bool bDirFromGuide, bool bFromVsTo) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) // recupero la curva e il suo riferimento const ICurve* pCrv = GetCurve( pGeomDB->GetGeoObj( nCurveId)) ; if ( pCrv == nullptr) return false ; Frame3d frCrv ; if ( ! pGeomDB->GetGlobFrame( nCurveId, frCrv)) return false ; // deve esserci almeno una superficie if ( vnSurfId.empty()) return false ; // recupero il riferimento della prima superficie Frame3d frSurf ; if ( ! pGeomDB->GetGlobFrame( vnSurfId[0], frSurf)) return false ; // recupero le superfici e le porto tutte in locale alla prima SURFLOCALVECTOR vSurfL ; vSurfL.reserve( vnSurfId.size()) ; CISURFPVECTOR vpSurf ; vpSurf.reserve( vnSurfId.size()) ; for ( int i = 0 ; i < int( vnSurfId.size()) ; ++ i) { vSurfL.emplace_back( pGeomDB, vnSurfId[i], frSurf) ; if ( vSurfL[i].Get() == nullptr) return false ; vpSurf.emplace_back( vSurfL[i].Get()) ; } // recupero l'entità guida (punto, curva o superficie) e il suo riferimento const IGeoPoint3d* pGdePnt = nullptr ; const ICurve* pGdeCrv = nullptr ; const ISurf* pGdeStm = nullptr ; pGdePnt = GetGeoPoint3d( pGeomDB->GetGeoObj( nGuideId)) ; if ( pGdePnt == nullptr) { pGdeCrv = GetCurve( pGeomDB->GetGeoObj( nGuideId)) ; if ( pGdeCrv == nullptr) { pGdeStm = GetSurf( pGeomDB->GetGeoObj( nGuideId)) ; if ( pGdeStm == nullptr) return false ; } } Frame3d frGde ; if ( ! pGeomDB->GetGlobFrame( nGuideId, frGde)) return false ; // recupero il riferimento del gruppo di destinazione nDestGrpId = AdjustId( nDestGrpId) ; Frame3d frDest ; if ( ! pGeomDB->GetGroupGlobFrame( nDestGrpId, frDest)) return false ; // porto la curva nel riferimento della superficie CurveLocal CrvLoc( pCrv, frCrv, frSurf) ; if ( CrvLoc.Get() == nullptr) return false ; // vanno affilati gli spigoli solo se direzione non da guida bool bSharpEdges = ( ! bDirFromGuide) ; // eseguo l'opportuna proiezione dopo aver portato l'entità guida nel riferimento della superficie PNT5AXVECTOR vPt5ax ; if ( pGdePnt != nullptr) { PtrOwner pGdeLoc( pGdePnt->Clone()) ; if ( pGdeLoc == nullptr) return false ; pGdeLoc->LocToLoc( frGde, frSurf) ; if ( ! ProjectCurveOnSurf( *CrvLoc.Get(), vpSurf, *pGdeLoc, dLinTol, dMaxSegmLen, bSharpEdges, bFromVsTo, vPt5ax)) return false ; } else if ( pGdeCrv != nullptr) { CurveLocal GdeLoc( pGdeCrv, frGde, frSurf) ; if ( GdeLoc.Get() == nullptr) return false ; if ( ! ProjectCurveOnSurf( *CrvLoc.Get(), vpSurf, *GdeLoc.Get(), dLinTol, dMaxSegmLen, bSharpEdges, bFromVsTo, vPt5ax)) return false ; } else { // pGdeStm != nullptr SurfLocal GdeLoc( pGdeStm, frGde, frSurf) ; const ISurf* pGdeLoc = GetSurf( GdeLoc.Get()) ; if ( pGdeLoc == nullptr) return false ; if ( ! ProjectCurveOnSurf( *CrvLoc.Get(), vpSurf, *pGdeLoc, dLinTol, dMaxSegmLen, bSharpEdges, bFromVsTo, vPt5ax)) return false ; } // inserisco la composita nel gruppo destinazione PtrOwner pCompo ; for ( const auto& Pt5ax : vPt5ax) { if ( IsNull( pCompo)) { pCompo.Set( CreateCurveComposite()) ; if ( IsNull( pCompo)) return false ; pCompo->AddPoint( GetLocToLoc( Pt5ax.ptP, frSurf, frDest)) ; } else pCompo->AddLine( GetLocToLoc( Pt5ax.ptP, frSurf, frDest)) ; } int nCompoId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pCompo)) ; if ( nCompoId == GDB_ID_NULL) return false ; // aggiungo i versori nel gruppo destinazione int nInd = 0 ; for ( const auto& Pt5ax : vPt5ax) { PtrOwner pGeoVct( CreateGeoVector3d()) ; if ( IsNull( pGeoVct)) return false ; Vector3d vtDir = ( bDirFromGuide ? Pt5ax.vtDir2 : Pt5ax.vtDir1) ; pGeoVct->Set( 10 * GetLocToLoc( vtDir, frSurf, frDest), GetLocToLoc( Pt5ax.ptP, frSurf, frDest)) ; int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pGeoVct)) ; if ( nNewId == GDB_ID_NULL) return false ; pGeomDB->SetInfo( nNewId, "Ind", nInd ++) ; pGeomDB->SetInfo( nNewId, "Par", Pt5ax.dPar) ; pGeomDB->SetInfo( nNewId, "Flag", Pt5ax.nFlag) ; } return true ; } //------------------------------------------------------------------------------- bool ExeProjectCurveOnSurfExt( int nCurveId, const INTVECTOR& vnSurfId, int nGuideId, int nDestGrpId, double dLinTol, double dMaxSegmLen, bool bDirFromGuide, bool bFromVsTo) { bool bOk = MyProjectCurveOnSurfExt( nCurveId, vnSurfId, nGuideId, nDestGrpId, dLinTol, dMaxSegmLen, bDirFromGuide, bFromVsTo) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtProjectCurveOnSurfExt(" + ToString( nCurveId) + ",{" + ToString( vnSurfId) + "}," + ToString( nGuideId) + "," + ToString( nDestGrpId) + "," + ToString( dLinTol) + "," + ToString( dMaxSegmLen) + "," + ( bDirFromGuide ? "true" : "false") + "," + ( bFromVsTo ? "true" : "false") + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } return bOk ; } //---------------------------------------------------------------------------- int ExeCurveGetVoronoi( const INTVECTOR& vIds, int nDestGrpId, int nBound, int* pnCount) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) if ( vIds.empty()) return false ; // recupero il riferimento della prima curva che sarà utilizzato da Voronoi Frame3d frCrv ; if ( ! pGeomDB->GetGlobFrame( vIds[0], frCrv)) return GDB_ID_NULL ; // recupero il riferimento di destinazione Frame3d frDest ; if ( ! pGeomDB->GetGroupGlobFrame( nDestGrpId, frDest)) return GDB_ID_NULL ; // Calcolo diagramma di Voronoi ICURVEPOVECTOR vCrv ; if ( int( vIds.size()) == 1) { // recupero la curva const ICurve* pCrv = GetCurve( pGeomDB->GetGeoObj( vIds[0])) ; if ( pCrv == nullptr) return GDB_ID_NULL ; // calcolo CalcCurveVoronoiDiagram( *pCrv, vCrv, nBound) ; } else { // recupero le curve e le porto in locale al frame della prima curva CICURVEPVECTOR vOrigCrvs ; for ( int i = 0 ; i < int( vIds.size()) ; i ++) { CurveLocal CrvLoc( pGeomDB, vIds[i], frCrv) ; if ( CrvLoc.Get() == nullptr) { for ( auto pCrv : vOrigCrvs) delete( pCrv) ; return GDB_ID_NULL ; } vOrigCrvs.emplace_back( CrvLoc->Clone()) ; } // calcolo CalcCurvesVoronoiDiagram( vOrigCrvs, vCrv, nBound) ; // libero la memoria for ( auto pCrv : vOrigCrvs) delete( pCrv) ; } // inserisco i risultati nel DB geometrico int nFirstId = GDB_ID_NULL ; int nCount = 0 ; for ( int i = 0 ; i < int( vCrv.size()) ; i++) { vCrv[i]->LocToLoc( frCrv, frDest) ; int nId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( vCrv[i])) ; if ( nId != GDB_ID_NULL) { nCount ++ ; if ( nFirstId == GDB_ID_NULL) nFirstId = nId ; } } ExeSetModified() ; if ( IsCmdLog()) { string sLua = "EgtCurveGetVoronoi({" + ToString( vIds) + "}," + ToString( nDestGrpId) + ")" + " FirstId=" + ToString( nFirstId) + " nCurveCount=" + ToString( nCount) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco risultati if ( pnCount != nullptr) *pnCount = nCount ; return nFirstId ; } //---------------------------------------------------------------------------- int ExeCurveGetMedialAxis( const INTVECTOR& vIds, int nDestGrpId, int nSide, int* pnCount) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) if ( vIds.empty()) return false ; // recupero il riferimento della prima curva che sarà utilizzato da Voronoi Frame3d frCrv ; if ( ! pGeomDB->GetGlobFrame( vIds[0], frCrv)) return GDB_ID_NULL ; // recupero il riferimento di destinazione Frame3d frDest ; if ( ! pGeomDB->GetGroupGlobFrame( nDestGrpId, frDest)) return GDB_ID_NULL ; // Calcolo il Medial Axis ICURVEPOVECTOR vCrv ; if ( int( vIds.size()) == 1) { // recupero la curva const ICurve* pCrv = GetCurve( pGeomDB->GetGeoObj( vIds[0])) ; if ( pCrv == nullptr) return GDB_ID_NULL ; // calcolo CalcCurveMedialAxis( *pCrv, vCrv, nSide) ; } else { // recupero le curve e le porto in locale al frame della prima curva CICURVEPVECTOR vOrigCrvs ; for ( int i = 0 ; i < int( vIds.size()) ; i ++) { CurveLocal CrvLoc( pGeomDB, vIds[i], frCrv) ; if ( CrvLoc.Get() == nullptr) { for ( auto pCrv : vOrigCrvs) delete( pCrv) ; return GDB_ID_NULL ; } vOrigCrvs.emplace_back( CrvLoc->Clone()) ; } // calcolo CalcCurvesMedialAxis( vOrigCrvs, vCrv, nSide) ; // libero la memoria for ( auto pCrv : vOrigCrvs) delete( pCrv) ; } // inserisco i risultati nel DB geometrico int nFirstId = GDB_ID_NULL ; int nCount = 0 ; for ( int i = 0 ; i < int( vCrv.size()) ; i++) { vCrv[i]->LocToLoc( frCrv, frDest) ; int nId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( vCrv[i])) ; if ( nId != GDB_ID_NULL) { nCount ++ ; if ( nFirstId == GDB_ID_NULL) nFirstId = nId ; } } ExeSetModified() ; if ( IsCmdLog()) { string sLua = "EgtCurveMedialAxisAdv(" + ToString( vIds[0]) + "," + ToString( nSide) + "," + ToString( nDestGrpId) + ")" + " FirstId=" + ToString( nFirstId) + " nCurveCount=" + ToString( nCount) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco risultati if ( pnCount != nullptr) *pnCount = nCount ; return nFirstId ; } //---------------------------------------------------------------------------- int ExeCurveGetFatCurve( int nId, int nDestGrpId, double dRad, bool bSquareEnds, bool bSquareMids, int* pnCount) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // recupero la curva const ICurve* pCrv = GetCurve( pGeomDB->GetGeoObj( nId)) ; if ( pCrv == nullptr) return GDB_ID_NULL ; // recupero il riferimento della curva Frame3d frCrv ; if ( ! pGeomDB->GetGlobFrame( nId, frCrv)) return GDB_ID_NULL ; // recupero il riferimento di destinazione Frame3d frDest ; if ( ! pGeomDB->GetGroupGlobFrame( nDestGrpId, frDest)) return GDB_ID_NULL ; // Calcolo la curva ingrossata ICURVEPOVECTOR vCrv ; CalcCurveFatCurve( *pCrv, vCrv, dRad, bSquareEnds, bSquareMids) ; // inserisco i risultati nel DB geometrico int nFirstId = GDB_ID_NULL ; int nCount = 0 ; for ( int i = 0 ; i < int( vCrv.size()) ; i++) { vCrv[i]->LocToLoc( frCrv, frDest) ; int nId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( vCrv[i])) ; if ( nId != GDB_ID_NULL) { nCount ++ ; if ( nFirstId == GDB_ID_NULL) nFirstId = nId ; } } ExeSetModified() ; if ( IsCmdLog()) { string sLua = "EgtCurveGetFatCurve(" + ToString( nId) + "," + ToString( nDestGrpId) + ")" + " FirstId=" + ToString( nFirstId) + " nCurveCount=" + ToString( nCount) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco risultati if ( pnCount != nullptr) *pnCount = nCount ; return nFirstId ; } //---------------------------------------------------------------------------- bool ExeCurveBezierIncreaseDegree( int nCrvId) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // recupero la curva const ICurve* pCrv = GetCurve( pGeomDB->GetGeoObj( nCrvId)) ; if ( pCrv == nullptr) return false ; //// recupero il riferimento della curva //Frame3d frCrv ; //if ( ! pGeomDB->GetGlobFrame( nCrvId, frCrv)) // return GDB_ID_NULL ; if( pCrv->GetType() != CRV_BEZIER) return false ; // aumento il grado della curva bool bOk = true ; PtrOwner pCrvBezierNew ( BezierIncreaseDegree( GetCurveBezier( pCrv))) ; Vector3d vtExtr ; if ( bOk && pCrv->GetExtrusion( vtExtr)) pCrvBezierNew->SetExtrusion( vtExtr) ; double dThick = 0 ; if ( bOk && pCrv->GetThickness( dThick)) pCrvBezierNew->SetThickness(dThick) ; // sostituisco la vecchia curva con la nuova bOk = bOk && pGeomDB->ReplaceGeoObj( nCrvId, Release( pCrvBezierNew)) ; ExeSetModified() ; if ( IsCmdLog()) { string sLua = "EgtCurveBezierIncreaseDegree(" + ToString( nCrvId) + ")" " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } return bOk ; } //---------------------------------------------------------------------------- bool ExeCurveBezierDecreaseDegree( int nCrvId, double dTol) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // recupero la curva const ICurve* pCrv = GetCurve( pGeomDB->GetGeoObj( nCrvId)) ; if ( pCrv == nullptr) return false ; //// recupero il riferimento della curva //Frame3d frCrv ; //if ( ! pGeomDB->GetGlobFrame( nCrvId, frCrv)) // return GDB_ID_NULL ; if( pCrv->GetType() != CRV_BEZIER) return false ; // riduco il grado della curva bool bOk = true ; PtrOwner pCrvBezierNew ( BezierDecreaseDegree( GetCurveBezier( pCrv), dTol)) ; bOk = bOk && ! IsNull( pCrvBezierNew) && pCrvBezierNew->IsValid() ; Vector3d vtExtr ; if ( bOk && pCrv->GetExtrusion( vtExtr)) pCrvBezierNew->SetExtrusion( vtExtr) ; double dThick = 0 ; if ( bOk && pCrv->GetThickness( dThick)) pCrvBezierNew->SetThickness(dThick) ; // sostituisco la vecchia curva con la nuova bOk = bOk && pGeomDB->ReplaceGeoObj( nCrvId, Release( pCrvBezierNew)) ; ExeSetModified() ; if ( IsCmdLog()) { string sLua = "EgtCurveBezierDecreaseDegree(" + ToString( nCrvId) + ")" " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } return bOk ; } //---------------------------------------------------------------------------- bool ExeCurveBezierApproxToNonRat( int nCrvId, double dTol) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // recupero la curva const ICurve* pCrv = GetCurve( pGeomDB->GetGeoObj( nCrvId)) ; if ( pCrv == nullptr) return false ; //// recupero il riferimento della curva //Frame3d frCrv ; //if ( ! pGeomDB->GetGlobFrame( nCrvId, frCrv)) // return GDB_ID_NULL ; // controllo che il tipo sia giusto if( pCrv->GetType() != CRV_BEZIER) { if( pCrv->GetType() != CRV_COMPO) return false ; else { const ICurveComposite* pCC = GetCurveComposite( pCrv) ; for ( int i = 0 ; i < pCC->GetCurveCount() ; ++i) { const ICurve* pSubCrv = pCC->GetCurve( i) ; if( pSubCrv->GetType() != CRV_BEZIER) return false ; } } } bool bOk = true ; if( pCrv->GetType() == CRV_BEZIER) { const ICurveBezier* pCrvBez = GetCurveBezier( pCrv) ; if( ! pCrvBez->IsRational()) return true ; // approssimo la curva con una corrispettiva non razionale PtrOwner pCrvBezierNew ( pCrvBez->Clone()) ; bOk = bOk && pCrvBezierNew->MakeNonRational( dTol) ; PtrOwner pCrvNew ; if ( ! bOk) { pCrvNew.Set( ApproxBezierWithCubics( pCrvBezierNew, dTol)) ; bOk = bOk && ! IsNull( pCrvNew) && pCrvNew->IsValid() ; } else pCrvNew.Set( Release( pCrvBezierNew)) ; bOk = bOk && ! IsNull( pCrvNew) && pCrvNew->IsValid() ; Vector3d vtExtr ; if ( bOk && pCrv->GetExtrusion( vtExtr)) pCrvNew->SetExtrusion( vtExtr) ; double dThick = 0 ; if ( bOk && pCrv->GetThickness( dThick)) pCrvNew->SetThickness(dThick) ; // sostituisco la vecchia curva con la nuova bOk = bOk && pGeomDB->ReplaceGeoObj( nCrvId, Release( pCrvNew)) ; } else { const ICurveComposite* pCC = GetCurveComposite( pCrv) ; PtrOwner pCCNew( CreateCurveComposite()) ; for( int i = 0 ; i < pCC->GetCurveCount() ; ++i) { const ICurveBezier* pCrvBez = GetCurveBezier( pCC->GetCurve( i)) ; if( ! pCrvBez->IsRational()) { continue ; } // approssimo la curva con una corrispettiva non razionale PtrOwner pCrvBezierNew ( pCrvBez->Clone()) ; bOk = bOk && pCrvBezierNew->MakeNonRational( dTol) ; PtrOwner pCrvNew ; if ( ! bOk) { pCrvNew.Set( ApproxBezierWithCubics( pCrvBezierNew, dTol)) ; bOk = bOk && ! IsNull( pCrvNew) && pCrvNew->IsValid() ; } else pCrvNew.Set( Release( pCrvBezierNew)) ; bOk = bOk && ! IsNull( pCrvNew) && pCrvNew->IsValid() ; Vector3d vtExtr ; if ( bOk && pCrv->GetExtrusion( vtExtr)) pCrvNew->SetExtrusion( vtExtr) ; double dThick = 0 ; if ( bOk && pCrv->GetThickness( dThick)) pCrvNew->SetThickness(dThick) ; if( bOk) pCCNew->AddCurve( Release(pCrvNew)) ; else break ; } // sostituisco la vecchia curva con la nuova bOk = bOk && pGeomDB->ReplaceGeoObj( nCrvId, Release( pCCNew)) ; } ExeSetModified() ; if ( IsCmdLog()) { string sLua = "EgtCurveBezierApproxToNonRat(" + ToString( nCrvId) + ", " + ToString( dTol) + ")" " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } return bOk ; } //---------------------------------------------------------------------------- bool ExeCurveBezierApproxWithCubicBeziers( int nCrvId, double dTol) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // recupero la curva const ICurve* pCrv = GetCurve( pGeomDB->GetGeoObj( nCrvId)) ; if ( pCrv == nullptr) return false ; // controllo che il tipo sia giusto if( pCrv->GetType() != CRV_BEZIER) { if( pCrv->GetType() != CRV_COMPO) return false ; else { const ICurveComposite* pCC = GetCurveComposite( pCrv) ; for ( int i = 0 ; i < pCC->GetCurveCount() ; ++i) { const ICurve* pSubCrv = pCC->GetCurve( i) ; if( pSubCrv->GetType() != CRV_BEZIER) return false ; } } } // converto in bezier cubiche bool bOk = true ; if( pCrv->GetType() == CRV_BEZIER) { const ICurveBezier* pCrvBez = GetCurveBezier( pCrv) ; // approssimo la curva con una serie di bezier PtrOwner pCrvBezierNew ( ApproxBezierWithCubics( pCrvBez, dTol)) ; bOk = bOk && ! IsNull( pCrvBezierNew) && pCrvBezierNew->IsValid() ; Vector3d vtExtr ; if ( bOk && pCrv->GetExtrusion( vtExtr)) pCrvBezierNew->SetExtrusion( vtExtr) ; double dThick = 0 ; if ( bOk && pCrv->GetThickness( dThick)) pCrvBezierNew->SetThickness(dThick) ; // sostituisco la vecchia curva con la nuova bOk = bOk && pGeomDB->ReplaceGeoObj( nCrvId, Release( pCrvBezierNew)) ; } else { const ICurveComposite* pCC = GetCurveComposite( pCrv) ; PtrOwner pCCNew( CreateCurveComposite()) ; for( int i = 0 ; i < pCC->GetCurveCount() ; ++i) { const ICurveBezier* pCrvBez = GetCurveBezier( pCC->GetCurve( i)) ; if( ! pCrvBez->IsRational()) { continue ; } // approssimo la curva con una serie di bezier PtrOwner pCrvBezierNew ( ApproxBezierWithCubics( pCrvBez, dTol)) ; bOk = bOk && ! IsNull( pCrvBezierNew) && pCrvBezierNew->IsValid() ; Vector3d vtExtr ; if ( bOk && pCrv->GetExtrusion( vtExtr)) pCrvBezierNew->SetExtrusion( vtExtr) ; double dThick = 0 ; if ( bOk && pCrv->GetThickness( dThick)) pCrvBezierNew->SetThickness(dThick) ; if( bOk) pCCNew->AddCurve( Release(pCrvBezierNew)) ; else break ; } // sostituisco la vecchia curva con la nuova bOk = bOk && pGeomDB->ReplaceGeoObj( nCrvId, Release( pCCNew)) ; } ExeSetModified() ; if ( IsCmdLog()) { string sLua = "EgtCurveBezierApproxWithCubicBeziers(" + ToString( nCrvId) + ", " + ToString( dTol) + ")" " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } return bOk ; }