6be67258d2
- Modifiche stilistiche e cambio di versione.
258 lines
10 KiB
C++
258 lines
10 KiB
C++
//----------------------------------------------------------------------------
|
|
// 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<ICurve> 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<ICurve> 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 ;
|
|
}
|