//---------------------------------------------------------------------------- // EgalTech 2026-2026 //---------------------------------------------------------------------------- // File : CASurfFrMove.cpp Data : 26.03.2026 Versione : 3.1c7 // Contenuto : Implementazione delle funzioni di movimento per SurfFlatRegion // senza collisione con altri oggetti dello stesso tipo e nello // stesso piano o in piani paralleli. // // // Modifiche : 26.03.2026 RE Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "CAvSurfFrMove.h" #include "SurfFlatRegion.h" #include "CurveLine.h" #include "CurveArc.h" #include "CurveComposite.h" #include "IntersLineArc.h" #include "GeoConst.h" #include "/EgtDev/Include/EGkCAvSurfFrMove.h" #include "/EgtDev/Include/EgtPointerOwner.h" using namespace std ; //---------------------------------------------------------------------------- // CASurfFrMove //---------------------------------------------------------------------------- CAvSurfFrMove::CAvSurfFrMove( const ISurfFlatRegion& SfrM, const ISurfFlatRegion& SfrF) { // salvo puntatori alle regioni m_pRegM = &SfrM ; m_pRegF = &SfrF ; } //---------------------------------------------------------------------------- bool CAvSurfFrMove::Translate( const Vector3d& vtDir, double& dLen) { MyCAvSurfFrMove ScdMove( *m_pRegM, *m_pRegF) ; m_CollInfo.nType = SCI_NONE ; if ( ! ScdMove.Translate( vtDir, dLen)) return false ; m_CollInfo = ScdMove.GetCollInfo() ; return true ; } //---------------------------------------------------------------------------- bool CAvSurfFrMove::Rotate( const Point3d& ptCen, double& dAng) { MyCAvSurfFrMove ScdMove( *m_pRegM, *m_pRegF) ; m_CollInfo.nType = SCI_NONE ; return ScdMove.Rotate( ptCen, dAng) ; } //---------------------------------------------------------------------------- bool MyCAvSurfFrMove::Translate( const Vector3d& vtDir, double& dLen) { // verifico validità regioni if ( m_pRegM == nullptr || m_pRegF == nullptr) return false ; // verifico che le due regioni giacciano in piani paralleli if ( ! AreSameVectorApprox( m_pRegM->m_frF.VersZ(), m_pRegF->m_frF.VersZ())) return false ; // reset info di collisione m_SCollInfo.nType = SCI_NONE ; // porto il vettore di movimento nel riferimento intrinseco e ne annullo la componente Z Vector3d vtDirL = vtDir ; vtDirL.ToLoc( m_pRegM->m_frF) ; vtDirL.z = 0 ; double dLenXY = vtDirL.Len() ; if ( dLenXY < EPS_SMALL) return true ; vtDirL /= dLenXY ; dLenXY *= dLen ; double dNewLenXY = dLenXY ; // ciclo sui chunk della seconda superficie for ( int nCF = 0 ; nCF < m_pRegF->GetChunkCount() ; ++ nCF) { // ciclo sui bordi dei chunk for ( int nLF = 0 ; nLF < m_pRegF->GetLoopCount( nCF) ; ++ nLF) { // curva corrente del chunk della seconda regione in locale nel riferimento intrinseco della prima const ICurve* pCrv2Loc = nullptr ; PtrOwner pCopyCrv ; if ( AreSameFrame( m_pRegM->m_frF, m_pRegF->m_frF)) pCrv2Loc = m_pRegF->GetMyLoop( nCF, nLF) ; else { pCopyCrv.Set( m_pRegF->GetMyLoop( nCF, nLF)->Clone()) ; if ( IsNull( pCopyCrv)) return false ; pCopyCrv->LocToLoc( m_pRegF->m_frF, m_pRegM->m_frF) ; pCrv2Loc = pCopyCrv ; } const CurveComposite* pCompo2 = GetBasicCurveComposite( pCrv2Loc) ; // ciclo sui chunk della prima superficie for ( int nCM = 0 ; nCM < m_pRegM->GetChunkCount() ; ++ nCM) { // ciclo sui bordi del chunk for ( int nLM = 0 ; nLM < m_pRegM->GetLoopCount( nCM) ; ++ nLM) { // per CAv non ha senso confrontare due loop interni tra di loro. // posso confrontatare - due loop esterni (come per la CAvSimpleSurfFrMove) // - un loop esterno con uno interno (nel caso in cui un Chunk sia contenuto dentro un isola) if ( nLF > 0 && nLM > 0) continue ; // curva corrente del chunk della prima regione (ovviamente già in locale al riferimento intrinseco) const ICurve* pCrv1Loc = m_pRegM->GetMyLoop( nCM, nLM) ; const CurveComposite* pCompo1 = GetBasicCurveComposite( pCrv1Loc) ; // verifico la collisione tra le entità dei loop esterni dei due chunk int k = 0 ; const ICurve* pCrv1 = ( pCompo1 != nullptr ? pCompo1->GetFirstCurve() : pCrv1Loc) ; while ( pCrv1 != nullptr) { int l = 0 ; const ICurve* pCrv2 = ( pCompo2 != nullptr ? pCompo2->GetFirstCurve() : pCrv2Loc) ; while ( pCrv2 != nullptr) { SCollInfo cInfoCurr ; double dPrevLenXY = dNewLenXY ; if ( ! TranslateCurveNoCollisionCurve( pCrv1, pCrv2, vtDirL, dNewLenXY, cInfoCurr)) return false ; if ( abs( dNewLenXY - dPrevLenXY) < EPS_SMALL) { if ( cInfoCurr.nType == SCI_LINE_LINE || cInfoCurr.nType == SCI_PNT_LINE) { m_SCollInfo = cInfoCurr ; m_SCollInfo.nChunkM = nCM ; m_SCollInfo.nLoopM = nLM ; m_SCollInfo.nCrvM = k ; m_SCollInfo.nChunkF = nCF ; m_SCollInfo.nLoopF = nLF ; m_SCollInfo.nCrvF = l ; } } else if ( dNewLenXY < dPrevLenXY) { m_SCollInfo = cInfoCurr ; m_SCollInfo.nChunkM = nCM ; m_SCollInfo.nLoopM = nLM ; m_SCollInfo.nCrvM = k ; m_SCollInfo.nChunkF = nCF ; m_SCollInfo.nLoopF = nLF ; m_SCollInfo.nCrvF = l ; } pCrv2 = ( pCompo2 != nullptr ? pCompo2->GetNextCurve() : nullptr) ; ++ l ; } pCrv1 = ( pCompo1 != nullptr ? pCompo1->GetNextCurve() : nullptr) ; ++ k ; } } } } } // se da limitare il movimento if ( dNewLenXY < dLenXY - EPS_SMALL) dLen *= dNewLenXY / dLenXY ; // porto i punti e le direzioni di SCollInfo da intrinseco a locale della prima regione if ( m_SCollInfo.nType != SCI_NONE) { m_SCollInfo.ptP1.ToGlob( m_pRegM->m_frF) ; m_SCollInfo.vtDirM.ToGlob( m_pRegM->m_frF) ; m_SCollInfo.vtDirF.ToGlob( m_pRegM->m_frF) ; } if ( m_SCollInfo.nType == SCI_LINE_LINE) m_SCollInfo.ptP2.ToGlob( m_pRegM->m_frF) ; return true ; } //---------------------------------------------------------------------------- bool MyCAvSurfFrMove::Rotate( const Point3d& ptCen, double& dAng) { // verifico validità regioni if ( m_pRegM == nullptr || m_pRegF == nullptr) return false ; // verifico che le due regioni giacciano in piani paralleli if ( ! AreSameVectorApprox( m_pRegM->m_frF.VersZ(), m_pRegF->m_frF.VersZ())) return false ; // reset info di collisione m_SCollInfo.nType = SCI_NONE ; // porto il centro di rotazione nel riferimento intrinseco e ne annullo la componente Z Point3d ptCenL = ptCen ; ptCenL.ToLoc( m_pRegM->m_frF) ; ptCenL.z = 0 ; if ( abs( dAng) < EPS_ANG_SMALL) return true ; double dNewAng = dAng ; // ciclo sui chunk della seconda superficie for ( int nCF = 0 ; nCF < m_pRegF->GetChunkCount() ; ++ nCF) { // ciclo sui bordi del Chunk for ( int nLF = 0 ; nLF < m_pRegF->GetLoopCount( nCF) ; ++ nLF) { // curva corrente del chunk della seconda regione in locale nel riferimento intrinseco della prima const ICurve* pCrv2Loc = nullptr ; PtrOwner pCopyCrv ; if ( AreSameFrame( m_pRegM->m_frF, m_pRegF->m_frF)) pCrv2Loc = m_pRegF->GetMyLoop( nCF, nLF) ; else { pCopyCrv.Set( m_pRegF->GetMyLoop( nCF, nLF)->Clone()) ; if ( IsNull( pCopyCrv)) return false ; pCopyCrv->LocToLoc( m_pRegF->m_frF, m_pRegM->m_frF) ; pCrv2Loc = pCopyCrv ; } const CurveComposite* pCompo2 = GetBasicCurveComposite( pCrv2Loc) ; // ciclo sui chunk della prima superficie for ( int nCM = 0 ; nCM < m_pRegM->GetChunkCount() ; ++ nCM) { // ciclo sui bordi del chunk for ( int nLM = 0 ; nLM < m_pRegM->GetLoopCount( nCM) ; ++ nLM) { // per CAv non ha senso confrontare due loop interni tra di loro. // posso confrontatare - due loop esterni (come per la CAvSimpleSurfFrMove) // - un loop esterno con uno interno (nel caso in cui un Chunk sia contenuto dentro un isola) if ( nLF > 0 && nLM > 0) continue ; // curva esterna del chunk della prima regione (ovviamente già in locale al riferimento intrinseco) const ICurve* pCrv1Loc = m_pRegM->GetMyLoop( nCM, nLM) ; const CurveComposite* pCompo1 = GetBasicCurveComposite( pCrv1Loc) ; // verifico la collisione tra le entità dei loop esterni dei due chunk const ICurve* pCrv1 = ( pCompo1 != nullptr ? pCompo1->GetFirstCurve() : pCrv1Loc) ; while ( pCrv1 != nullptr) { const ICurve* pCrv2 = ( pCompo2 != nullptr ? pCompo2->GetFirstCurve() : pCrv2Loc) ; while ( pCrv2 != nullptr) { if ( ! RotateCurveNoCollisionCurve( pCrv1, pCrv2, ptCenL, dNewAng)) return false ; pCrv2 = ( pCompo2 != nullptr ? pCompo2->GetNextCurve() : nullptr) ; } pCrv1 = ( pCompo1 != nullptr ? pCompo1->GetNextCurve() : nullptr) ; } } } } } // se da limitare il movimento if ( ( dAng > 0 && dNewAng < dAng - EPS_ANG_SMALL) || ( dAng < 0 && dNewAng > dAng + EPS_ANG_SMALL)) dAng = dNewAng ; return true ; }