Compare commits

..

5 Commits

Author SHA1 Message Date
LorenzoM d1cf3f1f2f Tolto un commento 2021-11-05 17:06:12 +01:00
LorenzoM ffa7c3dad5 Corretto errore bModif 2021-11-05 17:00:47 +01:00
LorenzoM a3502b5c07 Merge remote-tracking branch 'origin/master' into develop 2021-11-04 12:40:10 +01:00
LorenzoM a9259e8679 Merge modifiche Dario su SurfTriMeshBoolean 2021-11-04 12:37:25 +01:00
LorenzoM d3bc7bee64 TEST Taglio generalizzato 2021-11-04 12:30:24 +01:00
145 changed files with 6353 additions and 11470 deletions
+27 -90
View File
@@ -15,30 +15,15 @@
#include "stdafx.h" #include "stdafx.h"
#include "GeoConst.h" #include "GeoConst.h"
#include "CurveComposite.h" #include "CurveComposite.h"
#include "RemoveCurveDefects.h" #include "RemoveCurveSpikes.h"
#include "AdjustLoops.h" #include "AdjustLoops.h"
#include "/EgtDev/Include/EGkIntersCurves.h" #include "/EgtDev/Include/EGkIntersCurves.h"
#include "/EgtDev/Include/EGkIntervals.h" #include "/EgtDev/Include/EGkIntervals.h"
#include "/EgtDev/Include/EgtNumUtils.h"
#include "/EgtDev/Include/EgtPointerOwner.h" #include "/EgtDev/Include/EgtPointerOwner.h"
#include <algorithm> #include <algorithm>
using namespace std ; using namespace std ;
//-------------------------------------------------------
static bool
SortCrvCrvInfo( const IntCrvCrvInfo& aInfo1, const IntCrvCrvInfo& aInfo2)
{
// confronto i valori del primo punto della curva A
double dU1 = aInfo1.IciA[0].dU ;
double dU2 = aInfo2.IciA[0].dU ;
if ( abs( dU1 - dU2) < EPS_SMALL)
// se sono uguali confronto i valori del primo punto della curva B
return aInfo1.IciB[0].dU > aInfo2.IciB[0].dU ;
else
return dU1 < dU2 ;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
static bool static bool
MyAdjustLoops( ICurve* pCurve, ICURVEPLIST& CrvLst) MyAdjustLoops( ICurve* pCurve, ICURVEPLIST& CrvLst)
@@ -88,75 +73,43 @@ MyAdjustLoops( ICurve* pCurve, ICURVEPLIST& CrvLst)
return false ; return false ;
Intervals inOk( EPS_PARAM) ; Intervals inOk( EPS_PARAM) ;
inOk.Set( dStart, dEnd) ; inOk.Set( dStart, dEnd) ;
// recupero tutte le info delle autointersezioni
IntCrvCrvInfo iccInfo ;
ICCIVECTOR vIccInfo( sintC.GetIntersCount()) ;
for ( int i = 0 ; sintC.GetIntCrvCrvInfo( i, iccInfo) ; ++ i)
vIccInfo[i]= iccInfo ;
// ordino il vettore
sort( vIccInfo.begin(), vIccInfo.end(), SortCrvCrvInfo) ;
// Tolgo le parti da eliminare // Tolgo le parti da eliminare
int nCross = 0 ; IntCrvCrvInfo iccInfo ;
for ( int i = 0 ; i < int( vIccInfo.size()) ; ++ i) { for ( int i = 0 ; sintC.GetIntCrvCrvInfo( i, iccInfo) ; ++ i) {
if ( i < int( vIccInfo.size()) - 1) {
// se anche l'intersezione successiva è overlap che parte dallo stesso punto
if ( vIccInfo[i].bOverlap && vIccInfo[i+1].bOverlap &&
abs( vIccInfo[i].IciA[0].dU - vIccInfo[i+1].IciA[0].dU) < EPS_SMALL &&
abs( vIccInfo[i].IciB[0].dU - vIccInfo[i+1].IciB[0].dU) < EPS_SMALL) {
// elimino il tratto
inOk.Subtract( vIccInfo[i].IciA[0].dU, vIccInfo[i].IciB[0].dU) ;
// salto le intersezioni successive già considerate rimuovendo questo intervallo
int j = i + 2 ;
while ( j < ( int)vIccInfo.size() && vIccInfo[j].IciA[0].dU > vIccInfo[i].IciA[0].dU - EPS_SMALL &&
vIccInfo[j].IciA[1].dU < vIccInfo[i].IciB[0].dU + EPS_SMALL) {
j ++ ;
}
// aggiorno il contatore
i = j - 1 ;
continue ;
}
}
// se con sovrapposizione // se con sovrapposizione
if ( vIccInfo[i].bOverlap) { if ( iccInfo.bOverlap) {
// se solo touch // se solo touch
if ( ( vIccInfo[i].IciA[0].nPrevTy == vIccInfo[i].IciA[1].nNextTy || if ( ( iccInfo.IciA[0].nPrevTy == iccInfo.IciA[1].nNextTy ||
vIccInfo[i].IciA[0].nPrevTy == ICCT_SPK || vIccInfo[i].IciA[1].nNextTy == ICCT_SPK) && iccInfo.IciA[0].nPrevTy == ICCT_SPK || iccInfo.IciA[1].nNextTy == ICCT_SPK) &&
vIccInfo[i].IciA[0].nPrevTy != ICCT_NULL && vIccInfo[i].IciA[1].nNextTy != ICCT_NULL) { iccInfo.IciA[0].nPrevTy != ICCT_NULL && iccInfo.IciA[1].nNextTy != ICCT_NULL) {
// obbligatoriamente controversi, elimino entrambi i tratti // obbligatoriamente controversi, elimino entrambi i tratti
inOk.Subtract( vIccInfo[i].IciA[0].dU, vIccInfo[i].IciA[1].dU) ; inOk.Subtract( iccInfo.IciA[0].dU, iccInfo.IciA[1].dU) ;
inOk.Subtract( vIccInfo[i].IciB[0].dU, vIccInfo[i].IciB[1].dU) ; inOk.Subtract( iccInfo.IciB[0].dU, iccInfo.IciB[1].dU) ;
} }
// altrimenti attraversamento // altrimenti attraversamento
else { else {
// elimino la parte interna // elimino la parte interna
if ( vIccInfo[i].bCBOverEq) if ( iccInfo.bCBOverEq)
inOk.Subtract( vIccInfo[i].IciA[0].dU, vIccInfo[i].IciB[0].dU) ; inOk.Subtract( iccInfo.IciA[0].dU, iccInfo.IciB[0].dU) ;
else else
inOk.Subtract( min( vIccInfo[i].IciA[0].dU, vIccInfo[i].IciB[1].dU), max( vIccInfo[i].IciB[0].dU, vIccInfo[i].IciA[1].dU)) ; inOk.Subtract( min( iccInfo.IciA[0].dU, iccInfo.IciB[1].dU), max( iccInfo.IciB[0].dU, iccInfo.IciA[1].dU)) ;
} }
} }
// altrimenti // altrimenti
else { else {
// se solo touch // se solo touch
if ( vIccInfo[i].IciA[0].nPrevTy == vIccInfo[i].IciA[0].nNextTy && if ( iccInfo.IciA[0].nPrevTy == iccInfo.IciA[0].nNextTy &&
vIccInfo[i].IciA[0].nPrevTy != ICCT_NULL && vIccInfo[i].IciA[0].nNextTy != ICCT_NULL) { iccInfo.IciA[0].nPrevTy != ICCT_NULL && iccInfo.IciA[0].nNextTy != ICCT_NULL) {
inOk.Subtract( vIccInfo[i].IciA[0].dU, vIccInfo[i].IciA[0].dU) ; inOk.Subtract( iccInfo.IciA[0].dU, iccInfo.IciA[0].dU) ;
inOk.Subtract( vIccInfo[i].IciB[0].dU, vIccInfo[i].IciB[0].dU) ; inOk.Subtract( iccInfo.IciB[0].dU, iccInfo.IciB[0].dU) ;
} }
// altrimenti attraversamento // altrimenti attraversamento
else { else {
if ( IsEven( nCross)) inOk.Subtract( iccInfo.IciA[0].dU, iccInfo.IciB[0].dU) ;
inOk.Subtract( vIccInfo[i].IciA[0].dU, vIccInfo[i].IciB[0].dU) ;
else
inOk.Add( vIccInfo[i].IciA[0].dU, vIccInfo[i].IciB[0].dU) ;
++ nCross ;
} }
} }
} }
// Copio le parti da conservare // Copio le parti da conservare
double dParS, dParE ; double dParS, dParE ;
@@ -226,14 +179,14 @@ MyAdjustLoops( ICurve* pCurve, ICURVEPLIST& CrvLst)
Point3d ptEnd2 ; pCrvCo2->GetEndPoint( ptEnd2) ; Point3d ptEnd2 ; pCrvCo2->GetEndPoint( ptEnd2) ;
// se aperta, verifico se concatenabile alla principale // se aperta, verifico se concatenabile alla principale
if ( ! AreSamePointEpsilon( ptStart2, ptEnd2, 10 * EPS_SMALL)) { if ( ! AreSamePointEpsilon( ptStart2, ptEnd2, 10 * EPS_SMALL)) {
if ( AreSamePointEpsilon( ptEnd, ptStart2, 100 * EPS_SMALL)) { if ( AreSamePointEpsilon( ptEnd, ptStart2, 10 * EPS_SMALL)) {
pCrvCo->AddCurve( pCrvCo2, true, 100 * EPS_SMALL) ; pCrvCo->AddCurve( pCrvCo2, true, 10 * EPS_SMALL) ;
CrvLst.erase( iIter2) ; CrvLst.erase( iIter2) ;
ptEnd = ptEnd2 ; ptEnd = ptEnd2 ;
iIter2 = next( iIter) ; iIter2 = next( iIter) ;
} }
else if ( AreSamePointEpsilon( ptEnd2, ptStart, 100 * EPS_SMALL)) { else if ( AreSamePointEpsilon( ptEnd2, ptStart, 10 * EPS_SMALL)) {
pCrvCo->AddCurve( pCrvCo2, false, 100 * EPS_SMALL) ; pCrvCo->AddCurve( pCrvCo2, false, 10 * EPS_SMALL) ;
CrvLst.erase( iIter2) ; CrvLst.erase( iIter2) ;
ptStart = ptStart2 ; ptStart = ptStart2 ;
iIter2 = next( iIter) ; iIter2 = next( iIter) ;
@@ -248,22 +201,6 @@ MyAdjustLoops( ICurve* pCurve, ICURVEPLIST& CrvLst)
++ iIter ; ++ iIter ;
} }
// elimino le curve troppo piccole
for ( auto iIter = CrvLst.begin() ; iIter != CrvLst.end() ;) {
CurveComposite* pCrvCo = GetBasicCurveComposite( *iIter) ;
BBox3d b3CrvCo ;
double dDiam ;
if ( ! pCrvCo->GetLocalBBox( b3CrvCo) || b3CrvCo.IsEmpty() ||
! b3CrvCo.GetDiameter( dDiam) || dDiam < 20 * EPS_SMALL) {
delete pCrvCo ;
pCrvCo = nullptr ;
iIter = CrvLst.erase( iIter) ;
}
else {
++ iIter ;
}
}
// riporto le curve nel riferimento originale // riporto le curve nel riferimento originale
if ( bNeedRef) { if ( bNeedRef) {
for ( auto pCrv : CrvLst) for ( auto pCrv : CrvLst)
@@ -278,7 +215,7 @@ MyAdjustLoops( ICurve* pCurve, ICURVEPLIST& CrvLst)
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool bool
AdjustLoops( ICurve* pCurve, ICURVEPLIST& CrvLst, bool bNeedSameProp) AdjustLoops( ICurve* pCurve, ICURVEPLIST& CrvLst)
{ {
// elimino eventuali sovrapposizioni e accostamenti // elimino eventuali sovrapposizioni e accostamenti
if ( ! MyAdjustLoops( pCurve, CrvLst)) if ( ! MyAdjustLoops( pCurve, CrvLst))
@@ -288,10 +225,10 @@ AdjustLoops( ICurve* pCurve, ICURVEPLIST& CrvLst, bool bNeedSameProp)
// se curva composita // se curva composita
CurveComposite* pCrvCo = GetBasicCurveComposite( pCrv) ; CurveComposite* pCrvCo = GetBasicCurveComposite( pCrv) ;
if ( pCrvCo != nullptr) { if ( pCrvCo != nullptr) {
// elimino eventuali Spikes e Small Z
pCrvCo->RemoveSmallDefects( 2 * LIN_TOL_MIN, ANG_TOL_STD_DEG, true) ;
// unisco eventuali tratti allineati // unisco eventuali tratti allineati
pCrvCo->MergeCurves( LIN_TOL_MIN, ANG_TOL_STD_DEG, true, bNeedSameProp) ; pCrvCo->MergeCurves( LIN_TOL_MIN, ANG_TOL_STD_DEG) ;
// elimino eventuali spikes
RemoveCurveSpikes( pCrvCo) ;
} }
} }
+1 -1
View File
@@ -17,4 +17,4 @@
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool AdjustLoops( ICurve* pCurve, ICURVEPLIST& CrvLst, bool bNeedSameProp) ; bool AdjustLoops( ICurve* pCurve, ICURVEPLIST& CrvLst) ;
-54
View File
@@ -63,57 +63,3 @@ AngleInSpan( double dAngDeg, double dAngRefDeg, double dAngSpanDeg)
dAngDiffDeg < dHalfAngSpanDeg + EPS_ANG_SMALL) ; dAngDiffDeg < dHalfAngSpanDeg + EPS_ANG_SMALL) ;
} }
} }
//----------------------------------------------------------------------------
bool
AngleInRange( double dAngDeg, double dAngMinDeg, double dAngMaxDeg)
{
return AngleInSpan( dAngDeg, ( dAngMinDeg + dAngMaxDeg) / 2, dAngMaxDeg - dAngMinDeg) ;
}
//----------------------------------------------------------------------------
bool
AdjustAngleInSpan( double& dAngDeg, double dAngRefDeg, double dAngSpanDeg)
{
// Verifico consistenza intervallo
if ( dAngSpanDeg < -EPS_ANG_ZERO)
return false ;
// Se intervallo vero
if ( dAngSpanDeg > EPS_ANG_SMALL) {
double dTryDeg = dAngDeg ;
// eseguo gli aggiustamenti
while ( dTryDeg < dAngRefDeg - dAngSpanDeg)
dTryDeg += ANG_FULL ;
while ( dTryDeg > dAngRefDeg + dAngSpanDeg)
dTryDeg -= ANG_FULL ;
// verifico
if ( dTryDeg >= dAngRefDeg - dAngSpanDeg && dTryDeg <= dAngRefDeg + dAngSpanDeg) {
dAngDeg = dTryDeg ;
return true ;
}
return false ;
}
// altrimenti un valore
else {
double dTryDeg = dAngDeg ;
// eseguo gli aggiustamenti
while ( dTryDeg < dAngRefDeg - EPS_ANG_SMALL)
dTryDeg += ANG_FULL ;
while ( dTryDeg > dAngRefDeg + EPS_ANG_SMALL)
dTryDeg -= ANG_FULL ;
// verifico
if ( abs( dTryDeg - dAngRefDeg) < EPS_ANG_SMALL) {
dAngDeg = dAngRefDeg ;
return true ;
}
else
return false ;
}
}
//----------------------------------------------------------------------------
bool
AdjustAngleInRange( double& dAngDeg, double dAngMinDeg, double dAngMaxDeg)
{
return AdjustAngleInSpan( dAngDeg, ( dAngMinDeg + dAngMaxDeg) / 2, dAngMaxDeg - dAngMinDeg) ;
}
+5 -5
View File
@@ -17,10 +17,10 @@
#include "CurveComposite.h" #include "CurveComposite.h"
#include "CreateCurveAux.h" #include "CreateCurveAux.h"
#include "GeoConst.h" #include "GeoConst.h"
#include "/EgtDev/Include/EGkArcCenTgCurvePnt.h" #include "/EgtDev/Include/EgkArcCenTgCurvePnt.h"
#include "/EgtDev/Include/EGkArcSpecial.h" #include "/EgtDev/Include/EgkArcSpecial.h"
#include "/EgtDev/Include/EGkCircleCenTgCurve.h" #include "/EgtDev/Include/EgkCircleCenTgCurve.h"
#include "/EgtDev/Include/EGkDistPointCurve.h" #include "/EgtDev/Include/EgkDistPointCurve.h"
#include "/EgtDev/Include/EgtPointerOwner.h" #include "/EgtDev/Include/EgtPointerOwner.h"
@@ -168,7 +168,7 @@ CurveArc* GetArcCenTgCompoPnt( const Point3d& ptCen, const CurveComposite& crvCo
double dSqDist = SqDist( ptNearStart, ptTg) ; double dSqDist = SqDist( ptNearStart, ptTg) ;
if ( dSqDist < dMinSqDist) { if ( dSqDist < dMinSqDist) {
dMinSqDist = dSqDist ; dMinSqDist = dSqDist ;
pCrvArc.Set( pCrvAtmp) ; pCrvArc.Set( Release( pCrvAtmp)) ;
if ( pPtTg != nullptr) if ( pPtTg != nullptr)
*pPtTg = ptTg ; *pPtTg = ptTg ;
} }
+6 -6
View File
@@ -18,9 +18,9 @@
#include "CreateCurveAux.h" #include "CreateCurveAux.h"
#include "DistPointLine.h" #include "DistPointLine.h"
#include "GeoConst.h" #include "GeoConst.h"
#include "/EgtDev/Include/EGkArcPntDirTgCurve.h" #include "/EgtDev/Include/EgkArcPntDirTgCurve.h"
#include "/EgtDev/Include/EGkDistPointCurve.h" #include "/EgtDev/Include/EgkDistPointCurve.h"
#include "/EgtDev/Include/EGkArcSpecial.h" #include "/EgtDev/Include/EgkArcSpecial.h"
#include "/EgtDev/Include/EgtPointerOwner.h" #include "/EgtDev/Include/EgtPointerOwner.h"
@@ -204,7 +204,7 @@ GetArcPntDirTgArc( const Point3d& ptP, const Vector3d& vtDir, const CurveArc& cr
if ( bOk1) { if ( bOk1) {
double dOffset = ( bOutSide ? crvArcL.GetRadius() : - crvArcL.GetRadius()) ; double dOffset = ( bOutSide ? crvArcL.GetRadius() : - crvArcL.GetRadius()) ;
if ( pCrv1->GetType() == CRV_ARC) if ( pCrv1->GetType() == CRV_ARC)
bOk1 = (static_cast<CurveArc*>( Get( pCrv1)))->ExtendedOffset( dOffset) ; bOk1 = (dynamic_cast<CurveArc*>(Get(pCrv1)))->ExtendedOffset( dOffset) ;
else else
bOk1 = pCrv1->SimpleOffset( dOffset) ; bOk1 = pCrv1->SimpleOffset( dOffset) ;
} }
@@ -235,7 +235,7 @@ GetArcPntDirTgArc( const Point3d& ptP, const Vector3d& vtDir, const CurveArc& cr
if ( bOk2) { if ( bOk2) {
double dOffset = ( bOutSide ? - crvArcL.GetRadius() : crvArcL.GetRadius()) ; double dOffset = ( bOutSide ? - crvArcL.GetRadius() : crvArcL.GetRadius()) ;
if ( pCrv2->GetType() == CRV_ARC) if ( pCrv2->GetType() == CRV_ARC)
bOk2 = (static_cast<CurveArc*>( Get( pCrv2)))->ExtendedOffset( dOffset) ; bOk2 = (dynamic_cast<CurveArc*>(Get(pCrv2)))->ExtendedOffset( dOffset) ;
else else
bOk2 = pCrv2->SimpleOffset( dOffset) ; bOk2 = pCrv2->SimpleOffset( dOffset) ;
} }
@@ -337,7 +337,7 @@ GetArcPntDirTgCompo( const Point3d& ptP, const Vector3d& vtDir, const CurveCompo
double dSqDist = SqDist( ptNear, ptTg) ; double dSqDist = SqDist( ptNear, ptTg) ;
if ( dSqDist < dMinSqDist) { if ( dSqDist < dMinSqDist) {
dMinSqDist = dSqDist ; dMinSqDist = dSqDist ;
pCrvNew.Set( pCrvTmp) ; pCrvNew.Set( Release( pCrvTmp)) ;
if ( pPtTg != nullptr) if ( pPtTg != nullptr)
*pPtTg = ptTg ; *pPtTg = ptTg ;
} }
+36 -86
View File
@@ -1,7 +1,7 @@
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// EgalTech 2014-2023 // EgalTech 2014-2015
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// File : ArcSpecial.cpp Data : 04.08.23 Versione : 2.5h1 // File : ArcSpecial.cpp Data : 15.03.15 Versione : 1.6c2
// Contenuto : Implementazione funzioni per calcoli speciali archi. // Contenuto : Implementazione funzioni per calcoli speciali archi.
// //
// //
@@ -14,12 +14,13 @@
//--------------------------- Include ---------------------------------------- //--------------------------- Include ----------------------------------------
#include "stdafx.h" #include "stdafx.h"
#include "CreateCurveAux.h" #include "CreateCurveAux.h"
#include "/EgtDev/Include/EGkCurveLine.h" #include "/EgtDev/Include/EgkCurveLine.h"
#include "/EgtDev/Include/EGkArcSpecial.h" #include "/EgtDev/Include/EgkArcSpecial.h"
#include "/EgtDev/Include/EgtPointerOwner.h" #include "/EgtDev/Include/EgtPointerOwner.h"
using namespace std ; using namespace std ;
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// Come la CurveArc::Set2PD, ma se raggio infinito restituisce una retta // Come la CurveArc::Set2PD, ma se raggio infinito restituisce una retta
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@@ -27,13 +28,15 @@ ICurve*
GetArc2PD( const Point3d& ptStart, const Point3d& ptEnd, double dDirStartDeg) GetArc2PD( const Point3d& ptStart, const Point3d& ptEnd, double dDirStartDeg)
{ {
// creo l'oggetto arco // creo l'oggetto arco
PtrOwner<CurveArc> pArc( CreateBasicCurveArc()) ; ICurveArc* pArc = CreateCurveArc() ;
if ( IsNull( pArc)) if ( pArc == nullptr)
return nullptr ; return nullptr ;
// inizializzo il puntatore a curva con l'arco
PtrOwner<ICurve> pCrv( pArc) ;
// calcolo l'arco, se ok lo restituisco ed esco // calcolo l'arco, se ok lo restituisco ed esco
if ( pArc->Set2PD( ptStart, ptEnd, dDirStartDeg)) if ( pArc->Set2PD( ptStart, ptEnd, dDirStartDeg))
return Release( pArc) ; return Release( pCrv) ;
// calcolo arco non riuscito, verifico se retta va bene // calcolo arco non riuscito, verifico se retta va bene
Vector3d vtDiff = ptEnd - ptStart ; Vector3d vtDiff = ptEnd - ptStart ;
@@ -42,12 +45,14 @@ GetArc2PD( const Point3d& ptStart, const Point3d& ptEnd, double dDirStartDeg)
// verifico se i punti sono allineati con la direzione e nel giusto verso // verifico se i punti sono allineati con la direzione e nel giusto verso
if ( abs( CrossXY( vtDiff, vtDir)) < EPS_SMALL && ScalarXY( vtDiff, vtDir) > EPS_SMALL) { if ( abs( CrossXY( vtDiff, vtDir)) < EPS_SMALL && ScalarXY( vtDiff, vtDir) > EPS_SMALL) {
// creo l'oggetto retta // creo l'oggetto retta
PtrOwner<CurveLine> pLine( CreateBasicCurveLine()) ; ICurveLine* pLine = CreateCurveLine() ;
if ( IsNull( pLine)) if ( pLine == nullptr)
return nullptr ; return nullptr ;
// inizializzo il puntatore a curva con la retta
pCrv.Set( pLine) ;
// calcolo retta, se ok la restituisco ed esco // calcolo retta, se ok la restituisco ed esco
if ( pLine->Set( ptStart, ptEnd)) if ( pLine->Set( ptStart, ptEnd))
return Release( pLine) ; return Release( pCrv) ;
} }
return nullptr ; return nullptr ;
@@ -60,59 +65,34 @@ ICurve*
GetArc2PVN( const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtDirS, const Vector3d& vtN) GetArc2PVN( const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtDirS, const Vector3d& vtN)
{ {
// creo l'oggetto arco // creo l'oggetto arco
PtrOwner<CurveArc> pArc( CreateBasicCurveArc()) ; ICurveArc* pArc = CreateCurveArc() ;
if ( IsNull( pArc)) if ( pArc == nullptr)
return nullptr ; return nullptr ;
// inizializzo il puntatore a curva con l'arco
PtrOwner<ICurve> pCrv( pArc) ;
// calcolo l'arco, se ok lo restituisco ed esco // calcolo l'arco, se ok lo restituisco ed esco
if ( pArc->Set2PVN( ptStart, ptEnd, vtDirS, vtN)) if ( pArc->Set2PVN( ptStart, ptEnd, vtDirS, vtN))
return Release( pArc) ; return Release( pCrv) ;
// calcolo arco non riuscito, verifico se retta va bene // calcolo arco non riuscito, verifico se retta va bene
Vector3d vtDiff = ptEnd - ptStart ; Vector3d vtDiff = ptEnd - ptStart ;
// verifico se i punti sono allineati con la direzione e nel giusto verso nel piano perpendicolare a vtN // verifico se i punti sono allineati con la direzione e nel giusto verso nel piano perpendicolare a vtN
if ( abs( ( vtDiff ^ vtDirS) * vtN) < EPS_SMALL && vtDiff * vtDirS > EPS_SMALL) { if ( abs( ( vtDiff ^ vtDirS) * vtN) < EPS_SMALL && vtDiff * vtDirS > EPS_SMALL) {
// creo l'oggetto retta // creo l'oggetto retta
PtrOwner<CurveLine> pLine( CreateBasicCurveLine()) ; ICurveLine* pLine = CreateCurveLine() ;
if ( IsNull( pLine)) if ( pLine == nullptr)
return nullptr ; return nullptr ;
// inizializzo il puntatore a curva con la retta
pCrv.Set( pLine) ;
// calcolo retta, se ok la restituisco ed esco // calcolo retta, se ok la restituisco ed esco
if ( pLine->Set( ptStart, ptEnd)) if ( pLine->Set( ptStart, ptEnd))
return Release( pLine) ; return Release( pCrv) ;
} }
return nullptr ; return nullptr ;
} }
//----------------------------------------------------------------------------
// Come la CurveArc::Set2PNB, ma se bulge nullo restituisce una retta
//----------------------------------------------------------------------------
ICurve*
GetArc2PNB( const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtN, double dBulge)
{
// creo l'oggetto arco
PtrOwner<CurveArc> pArc( CreateBasicCurveArc()) ;
if ( IsNull( pArc))
return nullptr ;
// calcolo l'arco, se ok lo restituisco ed esco
if ( pArc->Set2PNB( ptStart, ptEnd, vtN, dBulge))
return Release( pArc) ;
// calcolo arco non riuscito, verifico se retta va bene
if ( abs( dBulge) > EPS_SMALL)
return nullptr ;
// creo l'oggetto retta
PtrOwner<CurveLine> pLine( CreateBasicCurveLine()) ;
if ( IsNull( pLine))
return nullptr ;
// calcolo retta, se ok la restituisco ed esco
if ( pLine->Set( ptStart, ptEnd))
return Release( pLine) ;
return nullptr ;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// Come la CurveArc::Set3P, ma se raggio infinito restituisce una retta // Come la CurveArc::Set3P, ma se raggio infinito restituisce una retta
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@@ -120,15 +100,17 @@ ICurve*
GetArc3P( const Point3d& ptStart, const Point3d& ptOther, const Point3d& ptEnd, bool bCirc) GetArc3P( const Point3d& ptStart, const Point3d& ptOther, const Point3d& ptEnd, bool bCirc)
{ {
// creo l'oggetto arco // creo l'oggetto arco
PtrOwner<CurveArc> pArc( CreateBasicCurveArc()) ; ICurveArc* pArc = CreateCurveArc() ;
if ( IsNull( pArc)) if ( pArc == nullptr)
return nullptr ; return nullptr ;
// inizializzo il puntatore a curva con l'arco
PtrOwner<ICurve> pCrv( pArc) ;
// calcolo l'arco, se ok lo restituisco ed esco // calcolo l'arco, se ok lo restituisco ed esco
if ( pArc->Set3P( ptStart, ptOther, ptEnd, bCirc)) if ( pArc->Set3P( ptStart, ptOther, ptEnd, bCirc))
return Release( pArc) ; return Release( pCrv) ;
// se era richiesta una circonferenza, errore perchè punti allineati // se era richiesta una circonferenza, errore
if ( bCirc) if ( bCirc)
return nullptr ; return nullptr ;
@@ -136,47 +118,15 @@ GetArc3P( const Point3d& ptStart, const Point3d& ptOther, const Point3d& ptEnd,
// verifico se i punti sono allineati nel giusto verso // verifico se i punti sono allineati nel giusto verso
if ( ( ptOther - ptStart) * ( ptEnd - ptOther) > EPS_ZERO) { if ( ( ptOther - ptStart) * ( ptEnd - ptOther) > EPS_ZERO) {
// creo l'oggetto retta // creo l'oggetto retta
PtrOwner<CurveLine> pLine( CreateBasicCurveLine()) ; ICurveLine* pLine = CreateCurveLine() ;
if ( IsNull( pLine)) if ( pLine == nullptr)
return nullptr ; return nullptr ;
// inizializzo il puntatore a curva con la retta
pCrv.Set( pLine) ;
// calcolo retta, se ok la restituisco ed esco // calcolo retta, se ok la restituisco ed esco
if ( pLine->Set( ptStart, ptEnd)) if ( pLine->Set( ptStart, ptEnd))
return Release( pLine) ; return Release( pCrv) ;
} }
return nullptr ; return nullptr ;
} }
//----------------------------------------------------------------------------
// Come la CurveArc::SetC2PN, ma garantisce il passaggio per gli estremi e minimizza errore sul centro
//----------------------------------------------------------------------------
ICurveArc*
GetArc2PCN( const Point3d& ptStart, const Point3d& ptEnd, const Point3d& ptNearCen, const Vector3d& vtN)
{
// creo l'oggetto arco
PtrOwner<CurveArc> pArc( CreateBasicCurveArc()) ;
if ( IsNull( pArc))
return nullptr ;
// vettori dal centro a inizio e fine
Vector3d vtStart = ptStart - ptNearCen ;
Vector3d vtEnd = ptEnd - ptNearCen ;
// determino il raggio medio
double dStartRad = OrthoCompo( vtStart, vtN).Len() ;
double dEndRad = OrthoCompo( vtEnd, vtN).Len() ;
double dRad = ( dStartRad + dEndRad) / 2 ;
if ( dRad < EPS_SMALL)
return nullptr ;
// determino un valore approssimato dell'angolo al centro
double dAngDeg ; bool bDet ;
if ( ! vtStart.GetRotation( vtEnd, vtN, dAngDeg, bDet) || ! bDet || abs( dAngDeg) < EPS_ANG_ZERO)
return nullptr ;
// calcolo l'arco antiorario per i due punti con il raggio medio
if ( pArc->Set2PNRS( ptStart, ptEnd, vtN, dRad, ( dAngDeg > 0)))
return Release( pArc) ;
return nullptr ;
}
+3 -21
View File
@@ -18,7 +18,7 @@
#include "NgeReader.h" #include "NgeReader.h"
#include "GeomDB.h" #include "GeomDB.h"
#include "/EgtDev/Include/EGkStringUtils3d.h" #include "/EgtDev/Include/EGkStringUtils3d.h"
#include "/EgtDev/Include/EGnStringKeyVal.h" #include "/EgtDev/Include/EgnStringKeyVal.h"
using namespace std ; using namespace std ;
@@ -212,7 +212,7 @@ bool
Attribs::SetName( const string& sName) Attribs::SetName( const string& sName)
{ {
// se nome non valido, esco con errore // se nome non valido, esco con errore
if ( sName.empty() || ! IsValidVal( sName)) if ( ! IsValidVal( sName))
return false ; return false ;
// può essere solo la prima stringa // può essere solo la prima stringa
@@ -282,7 +282,7 @@ bool
Attribs::SetInfo( const string& sKey, const string& sVal) Attribs::SetInfo( const string& sKey, const string& sVal)
{ {
// se chiave o valore non validi, esco con errore // se chiave o valore non validi, esco con errore
if ( ! IsValidKey( sKey) || sVal.empty() || ! IsValidVal( sVal)) if ( ! IsValidKey( sKey) || ! IsValidVal( sVal))
return false ; return false ;
// se è il nome // se è il nome
@@ -356,24 +356,6 @@ Attribs::RemoveInfo( const string& sKey)
return true ; return true ;
} }
//----------------------------------------------------------------------------
bool
Attribs::GetAllInfo( STRVECTOR& vsInfo) const
{
// riservo spazio opportuno per il vettore delle stringhe
vsInfo.clear() ;
if ( (int) m_slInfo.size() == 0)
return true ;
vsInfo.reserve( m_slInfo.size()) ;
// recupero tutte le info tranne il nome (se presente sempre al primo posto)
auto iIter = m_slInfo.cbegin() ;
if ( FindKey( *iIter, NAME))
++ iIter ;
for ( ; iIter != m_slInfo.cend() ; ++ iIter)
vsInfo.emplace_back( *iIter) ;
return true ;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool bool
Attribs::CopyAllInfoFrom( const Attribs& attrSou) Attribs::CopyAllInfoFrom( const Attribs& attrSou)
+3 -4
View File
@@ -89,7 +89,6 @@ class Attribs
bool GetInfo( const std::string& sKey, std::string& sVal) const ; bool GetInfo( const std::string& sKey, std::string& sVal) const ;
bool ExistsInfo( const std::string& sKey) const ; bool ExistsInfo( const std::string& sKey) const ;
bool RemoveInfo( const std::string& sKey) ; bool RemoveInfo( const std::string& sKey) ;
bool GetAllInfo( STRVECTOR& vsInfo) const ;
bool CopyAllInfoFrom( const Attribs& attrSou) ; bool CopyAllInfoFrom( const Attribs& attrSou) ;
private : private :
@@ -101,7 +100,7 @@ class Attribs
private : private :
unsigned char m_Data[DIM] ; unsigned char m_Data[DIM] ;
unsigned char m_OldData[DIM] ; unsigned char m_OldData[DIM] ;
int m_Material ; int m_Material ;
Color m_Color ; Color m_Color ;
STRLIST m_slInfo ; STRLIST m_slInfo ;
} ; } ;
+31 -131
View File
@@ -1,7 +1,7 @@
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// EgalTech 2014-2022 // EgalTech 2013-2013
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// File : BBox3d.cpp Data : 17.08.22 Versione : 2.4h1 // File : BBox3d.cpp Data : 14.01.14 Versione : 1.5a3
// Contenuto : Implementazione della classe axis aligned bounding box BBox3d. // Contenuto : Implementazione della classe axis aligned bounding box BBox3d.
// //
// //
@@ -53,8 +53,7 @@ BBox3d::Set( double dX1, double dY1, double dZ1, double dX2, double dY2, double
bool bool
BBox3d::IsValid( void) const BBox3d::IsValid( void) const
{ {
return ( m_ptMin.IsValid() && m_ptMax.IsValid() && return ( m_ptMin.x < ( m_ptMax.x + EPS_SMALL) &&
m_ptMin.x < ( m_ptMax.x + EPS_SMALL) &&
m_ptMin.y < ( m_ptMax.y + EPS_SMALL) && m_ptMin.y < ( m_ptMax.y + EPS_SMALL) &&
m_ptMin.z < ( m_ptMax.z + EPS_SMALL)) ; m_ptMin.z < ( m_ptMax.z + EPS_SMALL)) ;
} }
@@ -211,33 +210,6 @@ BBox3d::GetMinDim( Point3d& ptMin, double& dDimX, double& dDimY, double& dDimZ)
return true ; return true ;
} }
//----------------------------------------------------------------------------
double
BBox3d::GetDimX( void) const
{
if ( ! IsValid())
return 0 ;
return ( m_ptMax.x - m_ptMin.x) ;
}
//----------------------------------------------------------------------------
double
BBox3d::GetDimY( void) const
{
if ( ! IsValid())
return 0 ;
return ( m_ptMax.y - m_ptMin.y) ;
}
//----------------------------------------------------------------------------
double
BBox3d::GetDimZ( void) const
{
if ( ! IsValid())
return 0 ;
return ( m_ptMax.z - m_ptMin.z) ;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool bool
BBox3d::GetCenterExtent( Point3d& ptCenter, Vector3d& vtExtent) const BBox3d::GetCenterExtent( Point3d& ptCenter, Vector3d& vtExtent) const
@@ -448,141 +420,69 @@ BBox3d::EnclosesXY( const BBox3d& b3Box) const
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool bool
BBox3d::Overlaps( const BBox3d& b3Box) const BBox3d::Overlaps( const BBox3d& b3B) const
{ {
if ( m_ptMax.x < b3Box.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3Box.m_ptMax.x + EPS_SMALL) if ( m_ptMax.x < b3B.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3B.m_ptMax.x + EPS_SMALL)
return false ; return false ;
if ( m_ptMax.y < b3Box.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3Box.m_ptMax.y + EPS_SMALL) if ( m_ptMax.y < b3B.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3B.m_ptMax.y + EPS_SMALL)
return false ; return false ;
if ( m_ptMax.z < b3Box.m_ptMin.z - EPS_SMALL || m_ptMin.z > b3Box.m_ptMax.z + EPS_SMALL) if ( m_ptMax.z < b3B.m_ptMin.z - EPS_SMALL || m_ptMin.z > b3B.m_ptMax.z + EPS_SMALL)
return false ; return false ;
return true ; return true ;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool bool
BBox3d::OverlapsXY( const BBox3d& b3Box) const BBox3d::OverlapsXY( const BBox3d& b3B) const
{ {
if ( m_ptMax.x < b3Box.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3Box.m_ptMax.x + EPS_SMALL) if ( m_ptMax.x < b3B.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3B.m_ptMax.x + EPS_SMALL)
return false ; return false ;
if ( m_ptMax.y < b3Box.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3Box.m_ptMax.y + EPS_SMALL) if ( m_ptMax.y < b3B.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3B.m_ptMax.y + EPS_SMALL)
return false ; return false ;
return true ; return true ;
} }
//----------------------------------------------------------------------------
inline bool
TestSeparatingAxis( const Vector3d& vtAx, const Vector3d& vtDiff, const Vector3d& vtHe,
const Vector3d& vtHe2X, const Vector3d& vtHe2Y, const Vector3d& vtHe2Z)
{
if ( vtAx.IsSmall())
return false ;
double dLen = ( vtAx.IsNormalized() ? 1 : vtAx.Len()) ;
return ( abs( vtDiff * vtAx) >
abs( vtHe.x * vtAx.x) + abs( vtHe.y * vtAx.y) + abs( vtHe.z * vtAx.z) +
abs( vtHe2X * vtAx) + abs( vtHe2Y * vtAx) + abs( vtHe2Z * vtAx) + EPS_SMALL * dLen) ;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool bool
BBox3d::Overlaps( const Frame3d& frBox, const BBox3d& b3Box) const BBox3d::FindIntersection( const BBox3d& b3B, BBox3d& b3Int) const
{ {
// Verifico validità di entrambi i box if ( ! IsValid() || ! b3B.IsValid())
if ( ! IsValid() || ! b3Box.IsValid())
return false ;
// Centro e semiampiezza del box
Point3d ptCen = ( m_ptMin + m_ptMax) / 2 ;
Vector3d vtHe = ( m_ptMax - m_ptMin) / 2 ;
// Centro e semiampiezza dell'altro box
Point3d ptCen2 = GetToGlob( ( b3Box.m_ptMin + b3Box.m_ptMax) / 2, frBox) ;
Vector3d vtHe2X = GetToGlob( Vector3d( ( b3Box.GetDimX()) / 2, 0, 0), frBox) ;
Vector3d vtHe2Y = GetToGlob( Vector3d( 0, ( b3Box.GetDimY()) / 2, 0), frBox) ;
Vector3d vtHe2Z = GetToGlob( Vector3d( 0, 0, ( b3Box.GetDimZ()) / 2), frBox) ;
// Vettore tra i due centri
Vector3d vtDiff = ptCen2 - ptCen ;
// Verifico separazione sulle normali ai piani principali del riferimento globale
if ( TestSeparatingAxis( X_AX, vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
return false ;
if ( TestSeparatingAxis( Y_AX, vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
return false ;
if ( TestSeparatingAxis( Z_AX, vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
return false ;
// Verifico separazione sulle normali ai piani principali del secondo riferimento
if ( TestSeparatingAxis( frBox.VersX(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
return false ;
if ( TestSeparatingAxis( frBox.VersY(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
return false ;
if ( TestSeparatingAxis( frBox.VersZ(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
return false ;
// Verifico separazione sulle altre normali ottenute come prodotto vettoriali di quelle precedenti
if ( TestSeparatingAxis( X_AX ^ frBox.VersX(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
return false ;
if ( TestSeparatingAxis( X_AX ^ frBox.VersY(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
return false ;
if ( TestSeparatingAxis( X_AX ^ frBox.VersZ(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
return false ;
if ( TestSeparatingAxis( Y_AX ^ frBox.VersX(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
return false ;
if ( TestSeparatingAxis( Y_AX ^ frBox.VersY(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
return false ;
if ( TestSeparatingAxis( Y_AX ^ frBox.VersZ(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
return false ;
if ( TestSeparatingAxis( Z_AX ^ frBox.VersX(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
return false ;
if ( TestSeparatingAxis( Z_AX ^ frBox.VersY(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
return false ;
if ( TestSeparatingAxis( Z_AX ^ frBox.VersZ(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
return false ;
// Si sovrappongono
return true ;
}
//----------------------------------------------------------------------------
bool
BBox3d::FindIntersection( const BBox3d& b3Box, BBox3d& b3Int) const
{
if ( ! IsValid() || ! b3Box.IsValid())
return false ; return false ;
// verifico direttamente la sovrapposizione // verifico direttamente la sovrapposizione
if ( m_ptMax.x < b3Box.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3Box.m_ptMax.x + EPS_SMALL) if ( m_ptMax.x < b3B.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3B.m_ptMax.x + EPS_SMALL)
return false ; return false ;
if ( m_ptMax.y < b3Box.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3Box.m_ptMax.y + EPS_SMALL) if ( m_ptMax.y < b3B.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3B.m_ptMax.y + EPS_SMALL)
return false ; return false ;
if ( m_ptMax.z < b3Box.m_ptMin.z - EPS_SMALL || m_ptMin.z > b3Box.m_ptMax.z + EPS_SMALL) if ( m_ptMax.z < b3B.m_ptMin.z - EPS_SMALL || m_ptMin.z > b3B.m_ptMax.z + EPS_SMALL)
return false ; return false ;
// calcolo il box intersezione // calcolo il box intersezione
b3Int.m_ptMin.x = (( m_ptMin.x >= b3Box.m_ptMin.x) ? m_ptMin.x : b3Box.m_ptMin.x) ; b3Int.m_ptMin.x = (( m_ptMin.x >= b3B.m_ptMin.x) ? m_ptMin.x : b3B.m_ptMin.x) ;
b3Int.m_ptMin.y = (( m_ptMin.y >= b3Box.m_ptMin.y) ? m_ptMin.y : b3Box.m_ptMin.y) ; b3Int.m_ptMin.y = (( m_ptMin.y >= b3B.m_ptMin.y) ? m_ptMin.y : b3B.m_ptMin.y) ;
b3Int.m_ptMin.z = (( m_ptMin.z >= b3Box.m_ptMin.z) ? m_ptMin.z : b3Box.m_ptMin.z) ; b3Int.m_ptMin.z = (( m_ptMin.z >= b3B.m_ptMin.z) ? m_ptMin.z : b3B.m_ptMin.z) ;
b3Int.m_ptMax.x = (( m_ptMax.x <= b3Box.m_ptMax.x) ? m_ptMax.x : b3Box.m_ptMax.x) ; b3Int.m_ptMax.x = (( m_ptMax.x <= b3B.m_ptMax.x) ? m_ptMax.x : b3B.m_ptMax.x) ;
b3Int.m_ptMax.y = (( m_ptMax.y <= b3Box.m_ptMax.y) ? m_ptMax.y : b3Box.m_ptMax.y) ; b3Int.m_ptMax.y = (( m_ptMax.y <= b3B.m_ptMax.y) ? m_ptMax.y : b3B.m_ptMax.y) ;
b3Int.m_ptMax.z = (( m_ptMax.z <= b3Box.m_ptMax.z) ? m_ptMax.z : b3Box.m_ptMax.z) ; b3Int.m_ptMax.z = (( m_ptMax.z <= b3B.m_ptMax.z) ? m_ptMax.z : b3B.m_ptMax.z) ;
return true ; return true ;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool bool
BBox3d::FindIntersectionXY( const BBox3d& b3Box, BBox3d& b3Int) const BBox3d::FindIntersectionXY( const BBox3d& b3B, BBox3d& b3Int) const
{ {
if ( ! IsValid() || ! b3Box.IsValid()) if ( ! IsValid() || ! b3B.IsValid())
return false ; return false ;
// verifico direttamente la sovrapposizione // verifico direttamente la sovrapposizione
if ( m_ptMax.x < b3Box.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3Box.m_ptMax.x + EPS_SMALL) if ( m_ptMax.x < b3B.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3B.m_ptMax.x + EPS_SMALL)
return false ; return false ;
if ( m_ptMax.y < b3Box.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3Box.m_ptMax.y + EPS_SMALL) if ( m_ptMax.y < b3B.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3B.m_ptMax.y + EPS_SMALL)
return false ; return false ;
// calcolo il box intersezione // calcolo il box intersezione
b3Int.m_ptMin.x = (( m_ptMin.x >= b3Box.m_ptMin.x) ? m_ptMin.x : b3Box.m_ptMin.x) ; b3Int.m_ptMin.x = (( m_ptMin.x >= b3B.m_ptMin.x) ? m_ptMin.x : b3B.m_ptMin.x) ;
b3Int.m_ptMin.y = (( m_ptMin.y >= b3Box.m_ptMin.y) ? m_ptMin.y : b3Box.m_ptMin.y) ; b3Int.m_ptMin.y = (( m_ptMin.y >= b3B.m_ptMin.y) ? m_ptMin.y : b3B.m_ptMin.y) ;
b3Int.m_ptMin.z = 0.5 * ( m_ptMin.z + b3Box.m_ptMin.z) ; b3Int.m_ptMin.z = 0.5 * ( m_ptMin.z + b3B.m_ptMin.z) ;
b3Int.m_ptMax.x = (( m_ptMax.x <= b3Box.m_ptMax.x) ? m_ptMax.x : b3Box.m_ptMax.x) ; b3Int.m_ptMax.x = (( m_ptMax.x <= b3B.m_ptMax.x) ? m_ptMax.x : b3B.m_ptMax.x) ;
b3Int.m_ptMax.y = (( m_ptMax.y <= b3Box.m_ptMax.y) ? m_ptMax.y : b3Box.m_ptMax.y) ; b3Int.m_ptMax.y = (( m_ptMax.y <= b3B.m_ptMax.y) ? m_ptMax.y : b3B.m_ptMax.y) ;
b3Int.m_ptMax.z = 0.5 * ( m_ptMax.z + b3Box.m_ptMax.z) ; b3Int.m_ptMax.z = 0.5 * ( m_ptMax.z + b3B.m_ptMax.z) ;
return true ; return true ;
} }
+14 -26
View File
@@ -16,11 +16,10 @@
#include "BiArcs.h" #include "BiArcs.h"
#include "CurveArc.h" #include "CurveArc.h"
#include "/EgtDev/Include/EGkAngle.h" #include "/EgtDev/Include/EGkAngle.h"
#include "/EgtDev/Include/EGkCurveLine.h" #include "/EgtDev/Include/EgkCurveLine.h"
#include "/EgtDev/Include/EGkCurveComposite.h" #include "/EgtDev/Include/EgkCurveComposite.h"
#include "/EgtDev/Include/EGkArcSpecial.h" #include "/EgtDev/Include/EgkArcSpecial.h"
#include "/EgtDev/Include/EGkDistPointCurve.h" #include "/EgtDev/Include/EGkDistPointCurve.h"
#include "/EgtDev/Include/EgtNumUtils.h"
#include "/EgtDev/Include/EgtPointerOwner.h" #include "/EgtDev/Include/EgtPointerOwner.h"
using namespace std ; using namespace std ;
@@ -98,7 +97,7 @@ GetBiArc( const Point3d& ptP0, double dDir0Deg, const Point3d& ptP1, double dDir
CurveArc* pArc = GetBasicCurveArc( pJCrv) ; CurveArc* pArc = GetBasicCurveArc( pJCrv) ;
if ( pArc == nullptr) if ( pArc == nullptr)
return nullptr ; return nullptr ;
double dU = -1 ; double dU = - 1 ;
double dRad = pArc->GetRadius() ; double dRad = pArc->GetRadius() ;
double dSqRad = dRad * dRad ; double dSqRad = dRad * dRad ;
Point3d ptCen = pArc->GetCenter() ; Point3d ptCen = pArc->GetCenter() ;
@@ -122,11 +121,9 @@ GetBiArc( const Point3d& ptP0, double dDir0Deg, const Point3d& ptP1, double dDir
} }
} }
} }
// non c'è intersezione, assegno valore medio
if ( dU < -0.5)
dU = 0.5 ;
// elimino casi vicino agli estremi, danno solo problemi // elimino casi vicino agli estremi, danno solo problemi
dU = Clamp( dU, 0.1, 0.9) ; if ( dU < 0.1 || dU > 0.9)
dU = 0.5 ;
pBiArc.Set( GetBiArc( ptP0, dDir0Deg, ptP1, dDir1Deg, dU)) ; pBiArc.Set( GetBiArc( ptP0, dDir0Deg, ptP1, dDir1Deg, dU)) ;
} }
@@ -135,24 +132,15 @@ GetBiArc( const Point3d& ptP0, double dDir0Deg, const Point3d& ptP1, double dDir
return nullptr ; return nullptr ;
// determino la massima distanza tra la curva e il biarco // determino la massima distanza tra la curva e il biarco
Point3d ptP ;
double dSqDist = 0 ; double dSqDist = 0 ;
const double STEP = 10 ; for ( bool bPnt = PL.GetFirstPoint( ptP) ;
Point3d ptCurr ; bPnt ;
bool bPnt = PL.GetFirstPoint( ptCurr) ; bPnt = PL.GetNextPoint( ptP)) {
Point3d ptPrev = ptCurr ; DistPointCurve dstPC( ptP, *pBiArc) ;
while ( bPnt) { double dSqDistPC ;
double dLen = Dist( ptCurr, ptPrev) ; if ( dstPC.GetSqDist( dSqDistPC) && dSqDistPC > dSqDist)
int nStep = ( dLen < STEP ? 2 : 1) * int( dLen / STEP) + 1 ; dSqDist = dSqDistPC ;
for ( int i = 1 ; i <= nStep ; ++ i) {
double dCoeff = double( i) / nStep ;
Point3d ptP = Media( ptPrev, ptCurr, dCoeff) ;
DistPointCurve dstPC( ptP, *pBiArc) ;
double dSqDistPC ;
if ( dstPC.GetSqDist( dSqDistPC) && dSqDistPC > dSqDist)
dSqDist = dSqDistPC ;
}
ptPrev = ptCurr ;
bPnt = PL.GetNextPoint( ptCurr) ;
} }
dDist = sqrt( dSqDist) ; dDist = sqrt( dSqDist) ;
+1 -1
View File
@@ -13,7 +13,7 @@
#pragma once #pragma once
#include "/EgtDev/Include/EGkBiArcs.h" #include "/EgtDev/Include/EgkBiArcs.h"
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
ICurve* GetBiArc( const Point3d& ptP0, double dDir0Deg, const Point3d& ptP1, double dDir1Deg, ICurve* GetBiArc( const Point3d& ptP0, double dDir0Deg, const Point3d& ptP1, double dDir1Deg,
+3 -3
View File
@@ -301,11 +301,11 @@ CAvToolSurfTm::MyTestPositionHG( Point3d& ptT, const Vector3d& vtDir)
Vector3d vtDirL = vtDir ; vtDirL.ToLoc( m_frMove) ; Vector3d vtDirL = vtDir ; vtDirL.ToLoc( m_frMove) ;
b3Tool.Add( ptTL) ; b3Tool.Add( ptTL) ;
b3Tool.Add( ptTL - vtDirL * m_Tool.GetHeigth()) ; b3Tool.Add( ptTL - vtDirL * m_Tool.GetHeigth()) ;
if ( vtDirL.IsX()) if ( vtDirL.IsXplus() || vtDirL.IsXminus())
b3Tool.Expand( 0, m_Tool.GetRadius(), m_Tool.GetRadius()) ; b3Tool.Expand( 0, m_Tool.GetRadius(), m_Tool.GetRadius()) ;
else if ( vtDirL.IsY()) else if ( vtDirL.IsYplus() || vtDirL.IsYminus())
b3Tool.Expand( m_Tool.GetRadius(), 0, m_Tool.GetRadius()) ; b3Tool.Expand( m_Tool.GetRadius(), 0, m_Tool.GetRadius()) ;
else if ( vtDirL.IsZ()) else if ( vtDirL.IsZplus() || vtDirL.IsZminus())
b3Tool.Expand( m_Tool.GetRadius(), m_Tool.GetRadius(), 0) ; b3Tool.Expand( m_Tool.GetRadius(), m_Tool.GetRadius(), 0) ;
else { else {
double dExpandX = m_Tool.GetRadius() * sqrt( 1 - vtDirL.x * vtDirL.x) ; double dExpandX = m_Tool.GetRadius() * sqrt( 1 - vtDirL.x * vtDirL.x) ;
+13 -17
View File
@@ -23,17 +23,16 @@ using namespace std ;
bool bool
CDeBoxClosedSurfTm( const Frame3d& frBox, const Vector3d& vtDiag, double dSafeDist, const ISurfTriMesh& Stm) CDeBoxClosedSurfTm( const Frame3d& frBox, const Vector3d& vtDiag, double dSafeDist, const ISurfTriMesh& Stm)
{ {
// Recupero BBox del poliedro // recupero BBox del poliedro
BBox3d b3Poly = Stm.GetAllTriaBox() ; BBox3d b3Poly = Stm.GetAllTriaBox() ;
// Calcolo il BBox del parallelepipedo // calcolo il BBox del parallelepipedo
BBox3d b3BoxL( ORIG, ORIG + vtDiag) ; BBox3d b3Box( ORIG, ORIG + vtDiag) ;
if ( dSafeDist > EPS_SMALL) b3Box.Expand( dSafeDist) ;
b3BoxL.Expand( dSafeDist) ; b3Box.ToGlob( frBox) ;
BBox3d b3Box = GetToGlob( b3BoxL, frBox) ; // confronto i due Box
// Se i BBox non interferiscono, non c'è collisione if ( ! b3Box.Overlaps( b3Poly))
if ( ! b3Poly.Overlaps( b3Box) || ! b3Poly.Overlaps( frBox, b3BoxL))
return false ; return false ;
// Verifico se il parallelepipedo interferisce con i triangoli del poliedro presenti nel suo BBox // recupero i triangoli che interferiscono con il box
INTVECTOR vT ; INTVECTOR vT ;
Stm.GetAllTriaOverlapBox( b3Box, vT) ; Stm.GetAllTriaOverlapBox( b3Box, vT) ;
for ( int nT : vT) { for ( int nT : vT) {
@@ -46,13 +45,10 @@ CDeBoxClosedSurfTm( const Frame3d& frBox, const Vector3d& vtDiag, double dSafeDi
// Se superficie aperta, non c'è collisione // Se superficie aperta, non c'è collisione
if ( ! Stm.IsClosed()) if ( ! Stm.IsClosed())
return false ; return false ;
// Se il BBox del parallelepipedo non è interno a quello del poliedro e viceversa, non c'è collisione // Verifico se il box è dentro la superficie tramite calcolo distanza minima.
if ( ! b3Poly.Encloses( b3Box) && ! b3Box.Encloses( b3Poly)) Point3d ptBoxOrig, ptBoxMax ;
return false ; b3Box.GetMinMax( ptBoxOrig, ptBoxMax) ;
// Verifico se il box è dentro la superficie tramite calcolo distanza minima del suo centro DistPointSurfTm DistBoxOrigSurfCalc( ptBoxOrig, Stm) ;
Point3d ptBoxCen = ORIG + vtDiag / 2 ;
ptBoxCen.ToGlob( frBox) ;
DistPointSurfTm DistBoxCenSurfCalc( ptBoxCen, Stm) ;
// Se il box è interno c'è collisione // Se il box è interno c'è collisione
return DistBoxCenSurfCalc.IsPointInside() ; return DistBoxOrigSurfCalc.IsPointInside() ;
} }
+48 -27
View File
@@ -16,7 +16,6 @@
#include "CDeBoxTria.h" #include "CDeBoxTria.h"
#include "CDeSpheTria.h" #include "CDeSpheTria.h"
#include "CDeCylTria.h" #include "CDeCylTria.h"
#include "CDeCapsTria.h"
#include "/EgtDev/Include/EGkPlane3d.h" #include "/EgtDev/Include/EGkPlane3d.h"
using namespace std ; using namespace std ;
@@ -100,17 +99,9 @@ CDeSimpleBoxTria( const Frame3d& frBox, const Vector3d& vtDiag, const Triangle3d
Triangle3d trTriaL = trTria ; Triangle3d trTriaL = trTria ;
trTriaL.ToLoc( frBox) ; trTriaL.ToLoc( frBox) ;
// Calcolo il box locale del triangolo
BBox3d b3TriaL ;
trTriaL.GetLocalBBox( b3TriaL) ;
// Calcolo il box come tale // Calcolo il box come tale
BBox3d b3Box( ORIG, ORIG + vtDiag) ; BBox3d b3Box( ORIG, ORIG + vtDiag) ;
// Se i BBox non interferiscono, non c'è collisione
if ( ! b3Box.Overlaps( b3TriaL))
return false ;
// Compute box center and extents // Compute box center and extents
Point3d ptCen ; Point3d ptCen ;
Vector3d vtExt ; Vector3d vtExt ;
@@ -182,45 +173,75 @@ CDeBoxTria( const Frame3d& frBox, const Vector3d& vtDiag, double dSafeDist, cons
return CDeSimpleBoxTria( Frame3d(), vtDiag, trTriaL) ; return CDeSimpleBoxTria( Frame3d(), vtDiag, trTriaL) ;
// Verifica preliminare con box esteso // Verifica preliminare con box esteso
Frame3d frTmp( Point3d( -dSafeDist, -dSafeDist, -dSafeDist)) ; Frame3d frEst( Point3d( -dSafeDist, -dSafeDist, -dSafeDist)) ;
if ( ! CDeSimpleBoxTria( frTmp, vtDiag + 2 * Vector3d( dSafeDist, dSafeDist, dSafeDist), trTriaL)) if ( ! CDeSimpleBoxTria( frEst, vtDiag + 2 * Vector3d( dSafeDist, dSafeDist, dSafeDist), trTriaL))
return false ; return false ;
// Tre box aumentati con distanza di sicurezza in un sola dimensione // Tre box aumentati con distanza di sicurezza in un sola dimensione
frTmp.ChangeOrig( Point3d( -dSafeDist, 0, 0)) ; Frame3d frTmp = frBox ; frTmp.Translate( - dSafeDist * frBox.VersX()) ;
if ( CDeSimpleBoxTria( frTmp, vtDiag + 2 * dSafeDist * X_AX, trTriaL)) if ( CDeSimpleBoxTria( frTmp, vtDiag + 2 * dSafeDist * X_AX, trTriaL))
return true ; return true ;
frTmp.ChangeOrig( Point3d( 0, -dSafeDist, 0)) ; frTmp = frBox ; frTmp.Translate( - dSafeDist * frBox.VersY()) ;
if ( CDeSimpleBoxTria( frTmp, vtDiag + 2 * dSafeDist * Y_AX, trTriaL)) if ( CDeSimpleBoxTria( frTmp, vtDiag + 2 * dSafeDist * Y_AX, trTriaL))
return true ; return true ;
frTmp.ChangeOrig( Point3d( 0, 0, -dSafeDist)) ; frTmp = frBox ; frTmp.Translate( - dSafeDist * frBox.VersZ()) ;
if ( CDeSimpleBoxTria( frTmp, vtDiag + 2 * dSafeDist * Z_AX, trTriaL)) if ( CDeSimpleBoxTria( frTmp, vtDiag + 2 * dSafeDist * Z_AX, trTriaL))
return true ; return true ;
// Capsule centrati sui dodici spigoli // Sfere centrate negli otto vertici
if ( CDeSimpleCapsTria( Point3d( 0, 0, 0), Point3d( vtDiag.x, 0, 0), dSafeDist, trTriaL)) if ( CDeSimpleSpheTria( Point3d( 0, 0, 0), dSafeDist, trTriaL))
return true ; return true ;
if ( CDeSimpleCapsTria( Point3d( 0, vtDiag.y, 0), Point3d( vtDiag.x, vtDiag.y, 0), dSafeDist, trTriaL)) if ( CDeSimpleSpheTria( Point3d( vtDiag.x, 0, 0), dSafeDist, trTriaL))
return true ; return true ;
if ( CDeSimpleCapsTria( Point3d( 0, 0, 0), Point3d( 0, vtDiag.y, 0), dSafeDist, trTriaL)) if ( CDeSimpleSpheTria( Point3d( vtDiag.x, vtDiag.y, 0), dSafeDist, trTriaL))
return true ; return true ;
if ( CDeSimpleCapsTria( Point3d( vtDiag.x, 0, 0), Point3d( vtDiag.x, vtDiag.y, 0), dSafeDist, trTriaL)) if ( CDeSimpleSpheTria( Point3d( 0, vtDiag.y, 0), dSafeDist, trTriaL))
return true ; return true ;
if ( CDeSimpleCapsTria( Point3d( 0, 0, vtDiag.z), Point3d( vtDiag.x, 0, vtDiag.z), dSafeDist, trTriaL)) if ( CDeSimpleSpheTria( Point3d( 0, 0, vtDiag.z), dSafeDist, trTriaL))
return true ; return true ;
if ( CDeSimpleCapsTria( Point3d( 0, vtDiag.y, vtDiag.z), Point3d( vtDiag.x, vtDiag.y, vtDiag.z), dSafeDist, trTriaL)) if ( CDeSimpleSpheTria( Point3d( vtDiag.x, 0, vtDiag.z), dSafeDist, trTriaL))
return true ; return true ;
if ( CDeSimpleCapsTria( Point3d( 0, 0, vtDiag.z), Point3d( 0, vtDiag.y, vtDiag.z), dSafeDist, trTriaL)) if ( CDeSimpleSpheTria( Point3d( vtDiag.x, vtDiag.y, vtDiag.z), dSafeDist, trTriaL))
return true ; return true ;
if ( CDeSimpleCapsTria( Point3d( vtDiag.x, 0, vtDiag.z), Point3d( vtDiag.x, vtDiag.y, vtDiag.z), dSafeDist, trTriaL)) if ( CDeSimpleSpheTria( Point3d( 0, vtDiag.y, vtDiag.z), dSafeDist, trTriaL))
return true ; return true ;
if ( CDeSimpleCapsTria( Point3d( 0, 0, 0), Point3d( 0, 0, vtDiag.z), dSafeDist, trTriaL))
// Cilindri centrati sui dodici spigoli
frTmp.Set( Point3d( 0, 0, 0), X_AX) ;
if ( CDeSimpleCylTria( frTmp, dSafeDist, vtDiag.x, trTriaL))
return true ; return true ;
if ( CDeSimpleCapsTria( Point3d( vtDiag.x, 0, 0), Point3d( vtDiag.x, 0, vtDiag.z), dSafeDist, trTriaL)) frTmp.Set( Point3d( 0, vtDiag.y, 0), X_AX) ;
if ( CDeSimpleCylTria( frTmp, dSafeDist, vtDiag.x, trTriaL))
return true ; return true ;
if ( CDeSimpleCapsTria( Point3d( vtDiag.x, vtDiag.y, 0), Point3d( vtDiag.x, vtDiag.y, vtDiag.z), dSafeDist, trTriaL)) frTmp.Set( Point3d( 0, 0, 0), Y_AX) ;
if ( CDeSimpleCylTria( frTmp, dSafeDist, vtDiag.y, trTriaL))
return true ; return true ;
if ( CDeSimpleCapsTria( Point3d( 0, vtDiag.y, 0), Point3d( 0, vtDiag.y, vtDiag.z), dSafeDist, trTriaL)) frTmp.Set( Point3d( vtDiag.x, 0, 0), Y_AX) ;
if ( CDeSimpleCylTria( frTmp, dSafeDist, vtDiag.y, trTriaL))
return true ;
frTmp.Set( Point3d( 0, 0, vtDiag.z), X_AX) ;
if ( CDeSimpleCylTria( frTmp, dSafeDist, vtDiag.x, trTriaL))
return true ;
frTmp.Set( Point3d( 0, vtDiag.y, vtDiag.z), X_AX) ;
if ( CDeSimpleCylTria( frTmp, dSafeDist, vtDiag.x, trTriaL))
return true ;
frTmp.Set( Point3d( 0, 0, vtDiag.z), Y_AX) ;
if ( CDeSimpleCylTria( frTmp, dSafeDist, vtDiag.y, trTriaL))
return true ;
frTmp.Set( Point3d( vtDiag.x, 0, vtDiag.z), Y_AX) ;
if ( CDeSimpleCylTria( frTmp, dSafeDist, vtDiag.y, trTriaL))
return true ;
frTmp.Set( Point3d( 0., 0., 0.), Z_AX) ;
if ( CDeSimpleCylTria( frTmp, dSafeDist, vtDiag.z, trTriaL))
return true ;
frTmp.Set( Point3d( vtDiag.x, 0., 0.), Z_AX) ;
if ( CDeSimpleCylTria( frTmp, dSafeDist, vtDiag.z, trTriaL))
return true ;
frTmp.Set( Point3d( vtDiag.x, vtDiag.y, 0.), Z_AX) ;
if ( CDeSimpleCylTria( frTmp, dSafeDist, vtDiag.z, trTriaL))
return true ;
frTmp.Set( Point3d( 0., vtDiag.y, 0.), Z_AX) ;
if ( CDeSimpleCylTria( frTmp, dSafeDist, vtDiag.z, trTriaL))
return true ; return true ;
return false ; return false ;
-104
View File
@@ -1,104 +0,0 @@
//----------------------------------------------------------------------------
// EgalTech 2022-2022
//----------------------------------------------------------------------------
// File : CDeCapsTria.cpp Data : 14.05.22 Versione : 2.4e2
// Contenuto : Implementazione della verifica di collisione tra
// Capsule (cilindro con estremità semisferiche) e Triangle3d.
//
//
// Modifiche :14.05.22 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "CDeCapsTria.h"
#include "CDeSpheTria.h"
#include "ProjPlane.h"
#include "IntersLineCaps.h"
#include "/EgtDev/Include/EGkPolygon3d.h"
#include "/EgtDev/Include/EGkIntersLinePlane.h"
#include "/EgtDev/Include/EGkDistPointTria.h"
#include "/EgtDev/Include/EGkIntersLineSphere.h"
using namespace std ;
//----------------------------------------------------------------------------
bool
CDeSimpleCapsTria( const Point3d& ptP1, const Point3d& ptP2, double dR, const Triangle3d& trTria)
{
// vedi Ericson, Real-Time Collision Detection, pag. 226 (Nettle method)
// Dati della capsule come sfera che si muove
Point3d ptC = ptP1 ;
Point3d ptE = ptP2 ;
Vector3d vtDir = ptP2 - ptP1 ;
double dLen = vtDir.Len() ;
if ( dLen < EPS_SMALL)
return CDeSimpleSpheTria( Media( ptP1, ptP2), dR, trTria) ;
vtDir /= dLen ;
if ( vtDir * trTria.GetN() > 0) {
vtDir.Invert() ;
ptC = ptP2 ;
ptE = ptP1 ;
}
// Se sfera finale dista dal piano come o meno del raggio, devo verificarla direttamente (il retro è escluso dal calcolo standard)
double dDistE = DistPointPlane( ptE, trTria.GetPlane()) ;
if ( abs( dDistE) <= dR) {
if ( CDeSimpleSpheTria( ptE, dR, trTria))
return true ;
}
// Determinazione primo possibile punto di contatto della sfera con il piano
Point3d ptD = ptC - trTria.GetN() * dR ;
// Intersezione della linea di movimento di questo punto con il piano del triangolo
Point3d ptP ;
int nLpRes = IntersLinePlane( ptD, vtDir, 1, trTria.GetPlane(), ptP, false) ;
// Se non c'è intersezione passante
if ( nLpRes != ILPT_YES) {
// se il centro dista dal piano non meno del raggio, allora non c'è sicuramente collisione
double dDistM = DistPointPlane( Media( ptP1, ptP2), trTria.GetPlane()) ;
if ( abs( dDistM) >= dR)
return false ;
// interseco l'asse del capsule con capsule di pari raggio con asse i lati del triangolo
double dU1 = INFINITO, dU2 = -INFINITO ;
for ( int i = 0 ; i < 3 ; ++ i) {
double dInt1, dInt2 ;
if ( IntersLineCaps( ptC, vtDir, trTria.GetP( i), trTria.GetP( ( i + 1) % 3), dR, dInt1, dInt2)) {
dU1 = min( dU1, dInt1) ;
dU2 = max( dU2, dInt2) ;
if ( ! ( dU1 >= dLen || dU2 <= 0))
return true ;
}
}
return false ;
}
// Determino la posizione dell'intersezione rispetto al triangolo
DistPointTriangle dptDist( ptP, trTria) ;
// Se l'intersezione sta nel triangolo
double dSqDist ;
if ( dptDist.GetSqDist( dSqDist) && dSqDist < 4 * SQ_EPS_SMALL) {
double dPos = ( ptP - ptD) * vtDir ;
return ( dPos > 0 && dPos < dLen) ;
}
// Altrimenti, recupero il punto del triangolo più vicino all'intersezione
Point3d ptQ ;
if ( dptDist.GetMinDistPoint( ptQ)) {
Point3d ptI1, ptI2 ;
int nLsRes = IntersLineSphere( ptQ, -vtDir, ptC, dR, ptI1, ptI2) ;
if ( nLsRes != ILST_SEC)
return false ;
double dPos = ( ptQ - ptI1) * vtDir ;
return ( dPos > 0 && dPos < dLen) ;
}
return false ;
}
//----------------------------------------------------------------------------
bool
CDeCapsTria( const Point3d& ptP1, const Point3d& ptP2, double dR, double dSafeDist, const Triangle3d& trTria)
{
return CDeSimpleCapsTria( ptP1, ptP2, dR + max( 0., dSafeDist), trTria) ;
}
-19
View File
@@ -1,19 +0,0 @@
//----------------------------------------------------------------------------
// EgalTech 2022-2022
//----------------------------------------------------------------------------
// File : EGkCDeCapsTria.h Data : 14.05.22 Versione : 2.4e2
// Contenuto : Dichiarazione funzione verifica collisione tra
// Capsule (cilindro con estremità semisferiche) e Triangle3d.
//
// Modifiche : 14.05.22 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
#pragma once
#include "/EgtDev/Include/EGkTriangle3d.h"
//----------------------------------------------------------------------------
bool CDeSimpleCapsTria( const Point3d& ptP1, const Point3d& ptP2, double dR, const Triangle3d& trTria) ;
bool CDeCapsTria( const Point3d& ptP1, const Point3d& ptP2, double dR, double dSafeDist, const Triangle3d& trTria) ;
+47 -52
View File
@@ -1,7 +1,7 @@
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// EgalTech 2020-2020 // EgalTech 2020-2020
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// File : CDeSurfTmSurfTm.h Data : 14.06.23 Versione : 2.5f3 // File : CDeSurfTmSurfTm.h Data : 13.11.20 Versione :
// Contenuto : Implementazione funzione verifica collisione tra // Contenuto : Implementazione funzione verifica collisione tra
// SurfTm e SurfTm. // SurfTm e SurfTm.
// //
@@ -18,6 +18,8 @@
#include "/EgtDev/Include/EGkBBox3d.h" #include "/EgtDev/Include/EGkBBox3d.h"
#include "/EgtDev/Include/EGkCDeClosedSurfTmClosedSurfTm.h" #include "/EgtDev/Include/EGkCDeClosedSurfTmClosedSurfTm.h"
#include "/EgtDev/Include/EGkDistPointSurfTm.h" #include "/EgtDev/Include/EGkDistPointSurfTm.h"
#include <unordered_set>
#include <utility>
using namespace std ; using namespace std ;
@@ -31,67 +33,63 @@ using namespace std ;
// originale traslato di una costante pari alla distanza di sicurezza lungo la // originale traslato di una costante pari alla distanza di sicurezza lungo la
// sua normale. // sua normale.
bool bool
CDeClosedSurfTmClosedSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& SurfB, double dSafeDist) CDeClosedSurfTmClosedSurfTm( const SurfTriMesh& SurfA, const SurfTriMesh& SurfB, double dSafeDist)
{ {
// Recupero le superfici base // Se le superfici non sono valide o non sono chiuse, non ha senso proseguire.
const SurfTriMesh* pSrfA = GetBasicSurfTriMesh( &SurfA) ; if ( ! ( SurfA.IsValid() && SurfB.IsValid()) || ! ( SurfA.IsClosed() && SurfB.IsClosed()))
const SurfTriMesh* pSrfB = GetBasicSurfTriMesh( &SurfB) ;
// Se le superfici non sono valide o non sono chiuse, non ha senso proseguire.
if ( pSrfA == nullptr || ! pSrfA->IsValid() || ! pSrfA->IsClosed() ||
pSrfB == nullptr || ! pSrfB->IsValid() || ! pSrfB->IsClosed())
return false ; return false ;
// Se i box delle superfici non si intersecano, ho finito. // Se i box delle superfici non si intersecano, ho finito.
BBox3d b3BoxA, b3BoxB ; BBox3d b3BoxA, b3BoxB ;
pSrfA->GetLocalBBox( b3BoxA) ; SurfA.GetLocalBBox( b3BoxA) ;
pSrfB->GetLocalBBox( b3BoxB) ; SurfB.GetLocalBBox( b3BoxB) ;
// Se è necessario, espando il box di B di una costante additiva pari alla distanza di sicurezza. // Se è necessario, espando il box di una costante additiva pari alla distanza di sicurezza.
if ( dSafeDist > EPS_SMALL) if ( dSafeDist > EPS_SMALL)
b3BoxB.Expand( dSafeDist) ; b3BoxA.Expand( dSafeDist) ;
// Se i box non si sovrappongono, non c'è collisione. Ho finito. // Se i box non si sovrappongono, non c'è collisione. Ho finito.
if ( ! b3BoxA.Overlaps( b3BoxB)) if ( ! b3BoxA.Overlaps( b3BoxB))
return false ; return false ;
// Recupero i triangoli di A che interferiscono col box di B // Recupero i triangoli di B che interferiscono col box del triangolo di A
INTVECTOR vTriaIndex ; INTVECTOR vTriaIndex ;
pSrfA->GetAllTriaOverlapBox( b3BoxB, vTriaIndex) ; SurfA.GetAllTriaOverlapBox( b3BoxB, vTriaIndex) ;
// Ciclo sui triangoli della superficie A che interferiscono col box della superficie B. // Ciclo sui triangoli della superficie A che cadono nel box della superficie B.
for ( int nTA : vTriaIndex) { for ( int nTA : vTriaIndex) {
Triangle3d trTriaA ; Triangle3d trTriaA ;
if ( ! ( pSrfA->GetTriangle( nTA, trTriaA) && trTriaA.Validate())) if ( ! ( SurfA.GetTriangle( nTA, trTriaA) && trTriaA.Validate()))
continue ; continue ;
BBox3d b3BoxTriaA ; BBox3d b3BoxTriaA ;
trTriaA.GetLocalBBox( b3BoxTriaA) ; trTriaA.GetLocalBBox( b3BoxTriaA) ;
// Se è necessario, espando il box di una costante additiva pari alla distanza di sicurezza. // Se è necessario, espando il box di una costante additiva pari alla distanza di sicurezza.
if ( dSafeDist > EPS_SMALL) if ( dSafeDist > EPS_SMALL)
b3BoxTriaA.Expand( dSafeDist) ; b3BoxTriaA.Expand( dSafeDist) ;
// Recupero i triangoli di B che interferiscono col box del triangolo di A // Recupero i triangoli di B che interferiscono col box del triangolo di A
INTVECTOR vNearTria ; INTVECTOR vNearTria ;
pSrfB->GetAllTriaOverlapBox( b3BoxTriaA, vNearTria) ; SurfB.GetAllTriaOverlapBox( b3BoxTriaA, vNearTria) ;
// Settare tutti i triangoli come già processati. // Settare tutti i triangoli come già processati.
// Al termine della chiamata i TempInt dei triangoli valgono 0. // Al termine della chiamata i TFlags dei triangoli valgono 0.
pSrfB->ResetTempInts() ; SurfB.ResetTempInt() ;
// Ciclo sui triangoli della superficie B che cadono nel box del triangolo corrente della Superficie A. // Ciclo sui triangoli della superficie B che cadono nel box del triangolo corrente della Superficie A.
for ( int nTB : vNearTria) { for ( int nTB : vNearTria) {
// Recupero il triangolo corrente della superficie B. // Recupero il triangolo corrente della superficie B.
// Se triangolo non valido salto al successivo. // Se triangolo non valido salto al successivo.
Triangle3d trTriaB ; Triangle3d trTriaB ;
if ( ! ( pSrfB->GetTriangle( nTB, trTriaB) && trTriaB.Validate())) if ( ! ( SurfB.GetTriangle( nTB, trTriaB) && trTriaB.Validate()))
continue ; continue ;
// Se necessario considero l'offset // Se necessario considero l'offset
if ( dSafeDist > EPS_SMALL) { if ( dSafeDist > EPS_SMALL) {
int nAdjTriaId[3] ; int nAdjTriaId[3] ;
pSrfB->GetTriangleAdjacencies( nTB, nAdjTriaId) ; SurfB.GetTriangleAdjacencies( nTB, nAdjTriaId) ;
// Ciclo sui vertici del triangolo. // Ciclo sui vertici del triangolo.
for ( int nVB = 0 ; nVB < 3 ; ++ nVB) { for ( int nVB = 0 ; nVB < 3 ; ++ nVB) {
// Se il triangolo adiacente al triangolo corrente su questo edge // Se il triangolo adiacente al triangolo corrente su questo edge
// non è stato processato, processo il vertice e l'edge. // non è stato processato, processo il vertice e l'edge.
int nAdjTriaTempFlag ; int nAdjTriaTempFlag ;
if ( ! ( pSrfB->GetTempInt( nAdjTriaId[nVB], nAdjTriaTempFlag) || nAdjTriaTempFlag == 0)) if ( ! ( SurfB.GetTriangleTempInt( nAdjTriaId[nVB], nAdjTriaTempFlag) || nAdjTriaTempFlag == 0))
continue ; continue ;
// Processo il vertice: se c'è collisione fra triangolo A e sfera ho finito. // Processo il vertice: se c'è collisione fra triangolo A e sfera ho finito.
if ( CDeSimpleSpheTria( trTriaB.GetP( nVB), dSafeDist, trTriaA)) if ( CDeSimpleSpheTria( trTriaB.GetP( nVB), dSafeDist, trTriaA))
return true ; return true ;
// Processo l'edge: se c'è collisione fra triangolo A e cilindro ho finito. // Processo l'edge: se c'è collisione fra triangolo A e cilindro ho finito.
Vector3d vtEdgeV = trTriaB.GetP( ( nVB + 1) % 3) - trTriaB.GetP( nVB) ; Vector3d vtEdgeV = trTriaB.GetP( nVB) - trTriaB.GetP( ( nVB + 1) % 3) ;
double dEdgeLen = vtEdgeV.Len() ; double dEdgeLen = vtEdgeV.Len() ;
vtEdgeV /= dEdgeLen ; vtEdgeV /= dEdgeLen ;
Frame3d frCyl ; Frame3d frCyl ;
@@ -99,25 +97,22 @@ CDeClosedSurfTmClosedSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& Surf
if ( CDeSimpleCylTria( frCyl, dSafeDist, dEdgeLen, trTriaA)) if ( CDeSimpleCylTria( frCyl, dSafeDist, dEdgeLen, trTriaA))
return true ; return true ;
} }
// Traslo il triangolo // Traslo il triangolo
trTriaB.Translate( dSafeDist * trTriaB.GetN()) ; trTriaB.Translate( dSafeDist * trTriaB.GetN()) ;
} }
// Processo il triangolo: se i due triangoli collidono ho finito. // Processo il triangolo: se i due triangoli collidono ho finito.
if ( CDeTriaTria( trTriaA, trTriaB)) if ( CDeTriaTria( trTriaA, trTriaB))
return true ; return true ;
// Segno il triangolo come processato: nTemp = 1 // Segno il triangolo come processato: nTFlag = 1
pSrfB->SetTempInt( nTB, 1) ; SurfB.SetTempInt( nTB, 1) ;
} }
} }
// Non ho trovato collisioni fra triangoli delle superfici. // Non ho trovato collisioni fra triangoli delle superfici.
// Se il BBox della prima superficie non è interno a quello della seconda e viceversa, non c'è collisione // La collisione c'è se una superficie è dentro l'altra.
if ( ! b3BoxA.Encloses( b3BoxB) && ! b3BoxB.Encloses( b3BoxA))
return false ;
// La collisione c'è se una superficie è dentro l'altra.
Point3d ptPointA, ptPointB ; Point3d ptPointA, ptPointB ;
pSrfA->GetFirstVertex( ptPointA) ; SurfA.GetFirstVertex( ptPointA) ;
pSrfB->GetFirstVertex( ptPointB) ; SurfB.GetFirstVertex( ptPointB) ;
DistPointSurfTm DistPoinASrfB( ptPointA, *pSrfB) ; DistPointSurfTm DistPoinASurfB( ptPointA, SurfB) ;
DistPointSurfTm DistPoinBSrfA( ptPointB, *pSrfA) ; DistPointSurfTm DistPoinBSurfA( ptPointB, SurfA) ;
return ( DistPoinASrfB.IsPointInside() || DistPoinBSrfA.IsPointInside()) ; return ( DistPoinASurfB.IsPointInside() || DistPoinBSurfA.IsPointInside()) ;
} }
+13 -17
View File
@@ -20,32 +20,31 @@
using namespace std ; using namespace std ;
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// Il sistema di riferimento deve avere l'asse di simmetria del cono come asse Z e origine nel centro della base. // Il sisitema di riferimento deve avere l'asse di simmetria del cono come asse Z e origine nel centro della base.
// La distanza di sicurezza ha effetto solo se maggiore di epsilon, altrimenti è ignorata ed è ininfluente. // La distanza di sicurezza ha effetto solo se maggiore di epsilon, altrimenti è ignorata ed è ininfluente.
// Il sistema di riferimento del cono deve essere immerso in quello della superficie. // Il sistema di riferimento del cono deve essere immerso in quello della superficie.
bool bool
CDeConeFrustumClosedSurfTm( const Frame3d& frCone, double dBaseRad, double dTopRad, double dHeight, CDeConeFrustumClosedSurfTm( const Frame3d& frCone, double dBaseRad, double dTopRad, double dHeight,
double dSafeDist, const ISurfTriMesh& Stm) double dSafeDist, const ISurfTriMesh& Stm)
{ {
// Se il tronco di cono non è ben definito non ha senso proseguire // Se il tronco di cono non è ben definito non ha senso proseguire.
if ( max( dBaseRad, dTopRad) < EPS_SMALL || dHeight < EPS_SMALL) if ( max( dBaseRad, dTopRad) < EPS_SMALL || dHeight < EPS_SMALL)
return false ; return false ;
// Recupero BBox della trimesh // Recupero BBox della trimesh
BBox3d b3Surf = Stm.GetAllTriaBox() ; BBox3d b3Surf = Stm.GetAllTriaBox() ;
// Calcolo il BBox del tronco di cono // Calcolo il BBox del tronco di cono
double dMaxRad = max( dBaseRad, dTopRad) ; double dMaxRad = max( dBaseRad, dTopRad) ;
BBox3d b3ConeL( Point3d( -dMaxRad, -dMaxRad, 0), BBox3d b3Cone( - dMaxRad, - dMaxRad, 0, dMaxRad, dMaxRad, dHeight) ;
Point3d( dMaxRad, dMaxRad, dHeight)) ; b3Cone.Expand( dSafeDist) ;
if ( dSafeDist > EPS_SMALL) // Porto BBox del cono nel sistema della superficie.
b3ConeL.Expand( dSafeDist) ; b3Cone.ToGlob( frCone) ;
BBox3d b3Cone = GetToGlob( b3ConeL, frCone) ; // Se i BBox non interferiscono, ho finito.
// Se i BBox non interferiscono, non c'è collisione if ( ! b3Cone.Overlaps( b3Surf))
if ( ! b3Surf.Overlaps( b3Cone) || ! b3Surf.Overlaps( frCone, b3ConeL))
return false ; return false ;
// Recupero i triangoli che interferiscono con il box del cono // Recupero i triangoli che interferiscono con il box del cono
INTVECTOR vT ; INTVECTOR vT ;
Stm.GetAllTriaOverlapBox( b3Cone, vT) ; Stm.GetAllTriaOverlapBox( b3Cone, vT) ;
// Verifico se il tronco di cono interferisce con i triangoli del poliedro presenti nel suo BBox // Ciclo sui triangoli che interferiscono col box del cono
for ( int nT : vT) { for ( int nT : vT) {
Triangle3d trTria ; Triangle3d trTria ;
if ( Stm.GetTriangle( nT, trTria)) { if ( Stm.GetTriangle( nT, trTria)) {
@@ -56,13 +55,10 @@ CDeConeFrustumClosedSurfTm( const Frame3d& frCone, double dBaseRad, double dTopR
// Se superficie aperta, non c'è collisione // Se superficie aperta, non c'è collisione
if ( ! Stm.IsClosed()) if ( ! Stm.IsClosed())
return false ; return false ;
// Se il BBox del tronco di cono non è interno a quello del poliedro e viceversa, non c'è collisione
if ( ! b3Surf.Encloses( b3Cone) && ! b3Cone.Encloses( b3Surf))
return false ;
// Verifico se il tronco di cono è dentro la superficie tramite calcolo distanza minima. // Verifico se il tronco di cono è dentro la superficie tramite calcolo distanza minima.
Point3d ptConeCen( 0, 0, dHeight / 2) ; Point3d ptConeOrig ;
ptConeCen.ToGlob( frCone) ; ptConeOrig.ToGlob( frCone) ;
DistPointSurfTm DistConeCenSurfCalc( ptConeCen, Stm) ; DistPointSurfTm DistConeOrigSurfCalc( ptConeOrig, Stm) ;
// Se il tronco di cono è interno c'è collisione // Se il tronco di cono è interno c'è collisione
return DistConeCenSurfCalc.IsPointInside() ; return DistConeOrigSurfCalc.IsPointInside() ;
} }
+16 -16
View File
@@ -23,42 +23,42 @@ using namespace std ;
// Il toro è posto nel piano XY del suo riferimento, centrato sull'origine. // Il toro è posto nel piano XY del suo riferimento, centrato sull'origine.
// La funzione restituisce true in caso di collisione. // La funzione restituisce true in caso di collisione.
bool bool
CDeConvexTorusClosedSurfTm( const Frame3d& frTorus, double dRad1, double dRad2, CDeConvexTorusClosedSurfTm( const Frame3d& frTorusFrame, double dRad1, double dRad2,
double dSafeDist, const ISurfTriMesh& Stm) double dSafeDist, const ISurfTriMesh& Stm)
{ {
// I raggi devono essere non nulli e la superficie ben definita. // I raggi devono essere non nulli e la superficie ben definita.
if ( dRad1 < EPS_SMALL || dRad2 < EPS_SMALL || ! Stm.IsValid()) if ( dRad1 < EPS_SMALL || dRad2 < EPS_SMALL || ! Stm.IsValid())
return false ; return false ;
// Box della superficie
BBox3d b3Surf = Stm.GetAllTriaBox() ;
// Box del toro (sempre completo) // Box del toro (sempre completo)
BBox3d b3TorusL( Point3d( -dRad1 - dRad2, -dRad1 - dRad2, -dRad2), BBox3d b3ConvTorusBox ;
Point3d( dRad1 + dRad2, dRad1 + dRad2, dRad2)) ; b3ConvTorusBox.Set( Point3d( - dRad1 - dRad2, - dRad1 - dRad2, - dRad2),
Point3d( dRad1 + dRad2, dRad1 + dRad2, dRad2)) ;
// Aggiungo eventuale distanza di sicurezza
if ( dSafeDist > EPS_SMALL) if ( dSafeDist > EPS_SMALL)
b3TorusL.Expand( dSafeDist) ; b3ConvTorusBox.Expand( dSafeDist) ;
BBox3d b3Torus = GetToGlob( b3TorusL, frTorus) ; // Porto il box del toro nel riferimento della superficie (inteso some globale)
b3ConvTorusBox.ToGlob( frTorusFrame) ;
// Box della superficie
BBox3d b3SurfBox = Stm.GetAllTriaBox() ;
// Se i BBox non interferiscono, non c'è collisione // Se i BBox non interferiscono, non c'è collisione
if ( ! b3Surf.Overlaps( b3Torus) || ! b3Surf.Overlaps( frTorus, b3TorusL)) if ( ! b3ConvTorusBox.Overlaps( b3SurfBox))
return false ; return false ;
// Recupero i triangoli che interferiscono con il box del toro // Recupero i triangoli che interferiscono con il box del toro
INTVECTOR vT ; INTVECTOR vT ;
Stm.GetAllTriaOverlapBox( b3Torus, vT) ; Stm.GetAllTriaOverlapBox( b3ConvTorusBox, vT) ;
// Verifico se il toro interferisce con i triangoli del poliedro presenti nel suo BBox // Ciclo sui triangoli recuperati
for ( int nT : vT) { for ( int nT : vT) {
Triangle3d trTria ; Triangle3d trTria ;
if ( Stm.GetTriangle( nT, trTria)) { if ( Stm.GetTriangle( nT, trTria)) {
if ( CDeConvexTorusTria( frTorus, dRad1, dRad2, CT_TOT, dSafeDist, trTria)) if ( CDeConvexTorusTria( frTorusFrame, dRad1, dRad2, CT_TOT, dSafeDist, trTria))
return true ; return true ;
} }
} }
// Se superficie aperta, non c'è collisione // Se superficie aperta, non c'è collisione
if ( ! Stm.IsClosed()) if ( ! Stm.IsClosed())
return false ; return false ;
// Se il BBox del toro non è interno a quello del poliedro e viceversa, non c'è collisione // Verifico se il toro è dentro la superficie tramite calcolo distanza minima.
if ( ! b3Surf.Encloses( b3Torus) && ! b3Torus.Encloses( b3Surf)) Point3d ptTorusOrig = frTorusFrame.Orig() ;
return false ;
// Verifico se il toro è dentro la superficie tramite calcolo distanza minima del suo centro
Point3d ptTorusOrig = frTorus.Orig() ;
DistPointSurfTm DistConeOrigSurfCalc( ptTorusOrig, Stm) ; DistPointSurfTm DistConeOrigSurfCalc( ptTorusOrig, Stm) ;
// Se il toro è interno c'è collisione // Se il toro è interno c'è collisione
return ( DistConeOrigSurfCalc.IsPointInside()) ; return ( DistConeOrigSurfCalc.IsPointInside()) ;
+17 -22
View File
@@ -23,43 +23,38 @@ using namespace std ;
bool bool
CDeCylClosedSurfTm( const Frame3d& frCyl, double dR, double dH, double dSafeDist, const ISurfTriMesh& Stm) CDeCylClosedSurfTm( const Frame3d& frCyl, double dR, double dH, double dSafeDist, const ISurfTriMesh& Stm)
{ {
// Recupero BBox del poliedro // recupero BBox del poliedro
BBox3d b3Poly = Stm.GetAllTriaBox() ; BBox3d b3Poly = Stm.GetAllTriaBox() ;
// Sistemazioni cilindro // sistemazioni cilindro
Frame3d frMyCyl = frCyl ; Frame3d frC = frCyl ;
if ( dH < 0) { if ( dH < 0) {
frMyCyl.Translate( dH * frMyCyl.VersZ()) ; frC.Translate( dH * frC.VersZ()) ;
dH = - dH ; dH = - dH ;
} }
// Calcolo il BBox del cilindro // calcolo il BBox del cilindro
BBox3d b3CylL( Point3d( -dR, -dR, 0), BBox3d b3Cyl( -dR, -dR, 0, dR, dR, dH) ;
Point3d( dR, dR, dH)) ; b3Cyl.Expand( dSafeDist) ;
if ( dSafeDist > EPS_SMALL) b3Cyl.ToGlob( frC) ;
b3CylL.Expand( dSafeDist) ; // confronto i due Box
BBox3d b3Cyl = GetToGlob( b3CylL, frMyCyl) ; if ( ! b3Cyl.Overlaps( b3Poly))
// Se i BBox non interferiscono, non c'è collisione
if ( ! b3Poly.Overlaps( b3Cyl) || ! b3Poly.Overlaps( frMyCyl, b3CylL))
return false ; return false ;
// Verifico se il cilindro interferisce con i triangoli del poliedro presenti nel suo BBox // recupero i triangoli che interferiscono con il box del Cilindro
INTVECTOR vT ; INTVECTOR vT ;
Stm.GetAllTriaOverlapBox( b3Cyl, vT) ; Stm.GetAllTriaOverlapBox( b3Cyl, vT) ;
for ( int nT : vT) { for ( int nT : vT) {
Triangle3d Tria ; Triangle3d Tria ;
if ( Stm.GetTriangle( nT, Tria)) { if ( Stm.GetTriangle( nT, Tria)) {
if ( CDeCylTria( frMyCyl, dR, dH, dSafeDist, Tria)) if ( CDeCylTria( frC, dR, dH, dSafeDist, Tria))
return true ; return true ;
} }
} }
// Se superficie aperta, non c'è collisione // Se superficie aperta, non c'è collisione
if ( ! Stm.IsClosed()) if ( ! Stm.IsClosed())
return false ; return false ;
// Se il BBox del cilindro non è interno a quello del poliedro e viceversa, non c'è collisione // Verifico se il cilindro è dentro la superficie tramite calcolo distanza minima.
if ( ! b3Poly.Encloses( b3Cyl) && ! b3Cyl.Encloses( b3Poly)) Point3d ptCylOrig( 0., 0., - dSafeDist) ;
return false ; ptCylOrig.ToGlob( frC) ;
// Verifico se il cilindro è dentro la superficie tramite calcolo distanza minima del suo centro DistPointSurfTm DistCylOrigSurfCalc( ptCylOrig, Stm) ;
Point3d ptCylCen( 0, 0, dH / 2) ;
ptCylCen.ToGlob( frMyCyl) ;
DistPointSurfTm DistCylCenSurfCalc( ptCylCen, Stm) ;
// Se il cilindro è interno c'è collisione // Se il cilindro è interno c'è collisione
return ( DistCylCenSurfCalc.IsPointInside()) ; return ( DistCylOrigSurfCalc.IsPointInside()) ;
} }
+14 -16
View File
@@ -37,18 +37,20 @@ CDeRectPrismoidClosedSurfTm( const Frame3d& frPrismoid, double dLenghtBaseX, dou
// Calcolo il BBox del tronco di piramide // Calcolo il BBox del tronco di piramide
double dMaxLenX = max( dLenghtBaseX, dLenghtTopX) ; double dMaxLenX = max( dLenghtBaseX, dLenghtTopX) ;
double dMaxLenY = max( dLenghtBaseY, dLenghtTopY) ; double dMaxLenY = max( dLenghtBaseY, dLenghtTopY) ;
BBox3d b3PyrL( Point3d( -dMaxLenX / 2, -dMaxLenY / 2, 0.), BBox3d b3Pyr( -dMaxLenX / 2, -dMaxLenY / 2, 0., dMaxLenX / 2, dMaxLenY / 2, dHeight) ;
Point3d( dMaxLenX / 2, dMaxLenY / 2, dHeight)) ; // Se la distanza di sicurezza è maggiore di epsilon aumento le dimensioni del tronco di piramide.
if ( dSafeDist > EPS_SMALL) if ( dSafeDist > EPS_SMALL) {
b3PyrL.Expand( dSafeDist) ; b3Pyr.Expand( dSafeDist) ;
BBox3d b3Pyr = GetToGlob( b3PyrL, frPrismoid) ; }
// Porto BBox del tronco di piramide nel sistema della superficie.
b3Pyr.ToGlob( frPrismoid) ;
// Se i BBox non interferiscono, non c'è collisione // Se i BBox non interferiscono, non c'è collisione
if ( ! b3Surf.Overlaps( b3Pyr) || ! b3Surf.Overlaps( frPrismoid, b3PyrL)) if ( ! b3Pyr.Overlaps( b3Surf))
return false ; return false ;
// Recupero i triangoli che interferiscono con il box del tronco di piramide. // Recupero i triangoli che interferiscono con il box del tronco di piramide.
INTVECTOR vT ; INTVECTOR vT ;
Stm.GetAllTriaOverlapBox( b3Pyr, vT) ; Stm.GetAllTriaOverlapBox( b3Pyr, vT) ;
// Verifico se il tronco di piramide interferisce con i triangoli del poliedro presenti nel suo BBox // Ciclo sui triangoli che interferiscono col box del tronco di piramide.
for ( int nT : vT) { for ( int nT : vT) {
Triangle3d trTria ; Triangle3d trTria ;
if ( Stm.GetTriangle( nT, trTria)) { if ( Stm.GetTriangle( nT, trTria)) {
@@ -60,13 +62,9 @@ CDeRectPrismoidClosedSurfTm( const Frame3d& frPrismoid, double dLenghtBaseX, dou
// Se superficie aperta, non c'è collisione // Se superficie aperta, non c'è collisione
if ( ! Stm.IsClosed()) if ( ! Stm.IsClosed())
return false ; return false ;
// Se il BBox del tronco di piramide non è interno a quello del poliedro e viceversa, non c'è collisione // Verifico se il tronco di piramide è dentro la superficie tramite calcolo distanza minima.
if ( ! b3Surf.Encloses( b3Pyr) && ! b3Pyr.Encloses( b3Surf)) Point3d ptPyrOrig = frPrismoid.Orig() ;
return false ; DistPointSurfTm DistBoxOrigSurfCalc( ptPyrOrig, Stm) ;
// Verifico se il tronco di piramide è dentro la superficie tramite calcolo distanza minima del suo centro // C'è collisione se il tronco di piramide è interno.
Point3d ptPyrCen( 0, 0, dHeight / 2) ; return ( DistBoxOrigSurfCalc.IsPointInside()) ;
ptPyrCen.ToGlob( frPrismoid) ;
DistPointSurfTm DistPyrCenSurfCalc( ptPyrCen, Stm) ;
// C'è collisione se il tronco di piramide è interno
return ( DistPyrCenSurfCalc.IsPointInside()) ;
} }
+53 -33
View File
@@ -14,7 +14,6 @@
//--------------------------- Include ---------------------------------------- //--------------------------- Include ----------------------------------------
#include "stdafx.h" #include "stdafx.h"
#include "CDeRectPrismoidTria.h" #include "CDeRectPrismoidTria.h"
#include "CDeCapsTria.h"
#include "CDeBoxTria.h" #include "CDeBoxTria.h"
#include "CDeCylTria.h" #include "CDeCylTria.h"
#include "CDeSpheTria.h" #include "CDeSpheTria.h"
@@ -142,13 +141,9 @@ CDeRectPrismoidTria( const Frame3d& frPrismoid, double dLenghtBaseX, double dLen
dHeight < EPS_SMALL || ! trTria.IsValid()) dHeight < EPS_SMALL || ! trTria.IsValid())
return false ; return false ;
// Porto il triangolo nel riferimento del prismoide
Triangle3d trTriaL = trTria ;
trTriaL.ToLoc( frPrismoid) ;
// Se distanza di sicurezza nulla // Se distanza di sicurezza nulla
if ( dSafeDist < EPS_SMALL) if ( dSafeDist < EPS_SMALL)
return CDeSimpleRectPrismoidTria( Frame3d(), dLenghtBaseX, dLenghtBaseY, dLenghtTopX, dLenghtTopY, dHeight, trTriaL) ; return CDeSimpleRectPrismoidTria( frPrismoid, dLenghtBaseX, dLenghtBaseY, dLenghtTopX, dLenghtTopY, dHeight, trTria) ;
// Verifiche con offset esteso // Verifiche con offset esteso
double dHDiffX = ( dLenghtBaseX - dLenghtTopX) / 2 ; double dHDiffX = ( dLenghtBaseX - dLenghtTopX) / 2 ;
@@ -161,37 +156,37 @@ CDeRectPrismoidTria( const Frame3d& frPrismoid, double dLenghtBaseX, double dLen
double dSecAy = sqrt( 1 + dTgAy * dTgAy) ; double dSecAy = sqrt( 1 + dTgAy * dTgAy) ;
double dOffsBaseY = dSafeDist * ( dSecAy + dTgAy) ; double dOffsBaseY = dSafeDist * ( dSecAy + dTgAy) ;
double dOffsTopY = dSafeDist * ( dSecAy - dTgAy) ; double dOffsTopY = dSafeDist * ( dSecAy - dTgAy) ;
Frame3d frTmp( Point3d( 0, 0, -dSafeDist)) ; Frame3d frFrame = frPrismoid ; frFrame.Translate( - dSafeDist * frFrame.VersZ()) ;
if ( ! CDeSimpleRectPrismoidTria( frTmp, dLenghtBaseX + 2 * dOffsBaseX, dLenghtBaseY + 2 * dOffsBaseY, if ( ! CDeSimpleRectPrismoidTria( frFrame, dLenghtBaseX + 2 * dOffsBaseX, dLenghtBaseY + 2 * dOffsBaseY,
dLenghtTopX + 2 * dOffsTopX, dLenghtTopY + 2 * dOffsTopY, dHeight + 2 * dSafeDist, trTriaL)) dLenghtTopX + 2 * dOffsTopX, dLenghtTopY + 2 * dOffsTopY, dHeight + 2 * dSafeDist, trTria))
return false ; return false ;
// Offset fine // Offset fine
// Box sotto // Box sotto
frTmp.ChangeOrig( Point3d( 0, 0, -dSafeDist)) ; frFrame = frPrismoid ; frFrame.Translate( - dSafeDist * frFrame.VersZ()) ;
if ( CDeSimpleBoxTria( frTmp, Vector3d( dLenghtBaseX, dLenghtBaseY, dSafeDist), trTriaL)) if ( CDeSimpleBoxTria( frFrame, Vector3d( dLenghtBaseX, dLenghtBaseY, dSafeDist), trTria))
return true ; return true ;
// Box sopra // Box sopra
frTmp.ChangeOrig( Point3d( 0, 0, dHeight)) ; frFrame = frPrismoid ; frFrame.Translate( dHeight * frFrame.VersZ()) ;
if ( CDeSimpleBoxTria( frTmp, Vector3d( dLenghtTopX, dLenghtTopY, dSafeDist), trTriaL)) if ( CDeSimpleBoxTria( frFrame, Vector3d( dLenghtTopX, dLenghtTopY, dSafeDist), trTria))
return true ; return true ;
// Prismoide allungato in X // Prismoide allungato in X
double dHypoX = sqrt( dHDiffX * dHDiffX + dHeight * dHeight) ; double dHypoX = sqrt( dHDiffX * dHDiffX + dHeight * dHeight) ;
double dOffsX = dSafeDist * dHeight / dHypoX ; double dOffsX = dSafeDist * dHeight / dHypoX ;
double dMoveXZ = dSafeDist * dHDiffX / dHypoX ; double dMoveXZ = dSafeDist * dHDiffX / dHypoX ;
frTmp.ChangeOrig( Point3d( 0, 0, dMoveXZ)) ; frFrame = frPrismoid ; frFrame.Translate( dMoveXZ * frFrame.VersZ()) ;
if ( CDeSimpleRectPrismoidTria( frTmp, dLenghtBaseX + 2 * dOffsX, dLenghtBaseY, if ( CDeSimpleRectPrismoidTria( frFrame, dLenghtBaseX + 2 * dOffsX, dLenghtBaseY,
dLenghtTopX + 2 * dOffsX, dLenghtTopY, dHeight, trTriaL)) dLenghtTopX + 2 * dOffsX, dLenghtTopY, dHeight, trTria))
return true ; return true ;
// Prismoide allungato in Y // Prismoide allungato in Y
double dHypoY = sqrt( dHDiffY * dHDiffY + dHeight * dHeight) ; double dHypoY = sqrt( dHDiffY * dHDiffY + dHeight * dHeight) ;
double dOffsY = dSafeDist * dHeight / dHypoY ; double dOffsY = dSafeDist * dHeight / dHypoY ;
double dMoveYZ = dSafeDist * dHDiffY / dHypoY ; double dMoveYZ = dSafeDist * dHDiffY / dHypoY ;
frTmp.ChangeOrig( Point3d( 0, 0, dMoveYZ)) ; frFrame = frPrismoid ; frFrame.Translate( dMoveYZ * frFrame.VersZ()) ;
if ( CDeSimpleRectPrismoidTria( frTmp, dLenghtBaseX, dLenghtBaseY + 2 * dOffsY, if ( CDeSimpleRectPrismoidTria( frFrame, dLenghtBaseX, dLenghtBaseY + 2 * dOffsY,
dLenghtTopX, dLenghtTopY + 2 * dOffsY, dHeight, trTriaL)) dLenghtTopX, dLenghtTopY + 2 * dOffsY, dHeight, trTria))
return true ; return true ;
// Vertici // Sfere centrate nei vertici
double dHalfBaseX = dLenghtBaseX / 2 ; double dHalfBaseX = dLenghtBaseX / 2 ;
double dHalfBaseY = dLenghtBaseY / 2 ; double dHalfBaseY = dLenghtBaseY / 2 ;
double dHalfTopX = dLenghtTopX / 2 ; double dHalfTopX = dLenghtTopX / 2 ;
@@ -204,30 +199,55 @@ CDeRectPrismoidTria( const Frame3d& frPrismoid, double dLenghtBaseX, double dLen
Point3d( dHalfTopX, -dHalfTopY, dHeight), Point3d( dHalfTopX, -dHalfTopY, dHeight),
Point3d( dHalfTopX, dHalfTopY, dHeight), Point3d( dHalfTopX, dHalfTopY, dHeight),
Point3d( -dHalfTopX, dHalfTopY, dHeight)} ; Point3d( -dHalfTopX, dHalfTopY, dHeight)} ;
// Capsule centrati sui dodici spigoli for ( auto& ptV : vVert) {
if ( CDeSimpleCapsTria( vVert[0], vVert[1], dSafeDist, trTriaL)) ptV.ToGlob( frPrismoid) ;
if ( CDeSimpleSpheTria( ptV, dSafeDist, trTria))
return true ;
}
// Cilindri con i segmenti come asse
frFrame.Set( vVert[0], frPrismoid.VersX()) ;
if ( CDeSimpleCylTria( frFrame, dSafeDist, dLenghtBaseX, trTria))
return true ; return true ;
if ( CDeSimpleCapsTria( vVert[1], vVert[2], dSafeDist, trTriaL)) frFrame.Set( vVert[1], frPrismoid.VersY()) ;
if ( CDeSimpleCylTria( frFrame, dSafeDist, dLenghtBaseY, trTria))
return true ; return true ;
if ( CDeSimpleCapsTria( vVert[2], vVert[3], dSafeDist, trTriaL)) frFrame.Set( vVert[2], -frPrismoid.VersX()) ;
if ( CDeSimpleCylTria( frFrame, dSafeDist, dLenghtBaseX, trTria))
return true ; return true ;
if ( CDeSimpleCapsTria( vVert[3], vVert[0], dSafeDist, trTriaL)) frFrame.Set( vVert[3], -frPrismoid.VersY()) ;
if ( CDeSimpleCylTria( frFrame, dSafeDist, dLenghtBaseY, trTria))
return true ; return true ;
if ( CDeSimpleCapsTria( vVert[4], vVert[5], dSafeDist, trTriaL)) frFrame.Set( vVert[4], frPrismoid.VersX()) ;
if (CDeSimpleCylTria( frFrame, dSafeDist, dLenghtTopX, trTria))
return true ; return true ;
if ( CDeSimpleCapsTria( vVert[5], vVert[6], dSafeDist, trTriaL)) frFrame.Set( vVert[5], frPrismoid.VersY()) ;
if ( CDeSimpleCylTria( frFrame, dSafeDist, dLenghtTopY, trTria))
return true ; return true ;
if ( CDeSimpleCapsTria( vVert[6], vVert[7], dSafeDist, trTriaL)) frFrame.Set( vVert[6], -frPrismoid.VersX()) ;
if ( CDeSimpleCylTria( frFrame, dSafeDist, dLenghtTopX, trTria))
return true ; return true ;
if ( CDeSimpleCapsTria( vVert[7], vVert[4], dSafeDist, trTriaL)) frFrame.Set( vVert[7], -frPrismoid.VersY()) ;
if ( CDeSimpleCylTria( frFrame, dSafeDist, dLenghtTopY, trTria))
return true ; return true ;
if ( CDeSimpleCapsTria( vVert[0], vVert[4], dSafeDist, trTriaL)) Vector3d vtSeg04 = vVert[4] - vVert[0] ;
double dLenSeg04 = vtSeg04.Len() ;
frFrame.Set( vVert[0], vtSeg04) ;
if ( CDeSimpleCylTria( frFrame, dSafeDist, dLenSeg04, trTria))
return true ; return true ;
if ( CDeSimpleCapsTria( vVert[1], vVert[5], dSafeDist, trTriaL)) Vector3d vtSeg15 = vVert[5] - vVert[1] ;
double dLenSeg15 = vtSeg15.Len() ;
frFrame.Set( vVert[1], vtSeg15) ;
if ( CDeSimpleCylTria( frFrame, dSafeDist, dLenSeg15, trTria))
return true ; return true ;
if ( CDeSimpleCapsTria( vVert[2], vVert[6], dSafeDist, trTriaL)) Vector3d vtSeg26 = vVert[6] - vVert[2] ;
double dLenSeg26 = vtSeg26.Len() ;
frFrame.Set( vVert[2], vtSeg26) ;
if ( CDeSimpleCylTria( frFrame, dSafeDist, dLenSeg26, trTria))
return true ; return true ;
if ( CDeSimpleCapsTria( vVert[3], vVert[7], dSafeDist, trTriaL)) Vector3d vtSeg37 = vVert[7] - vVert[3] ;
double dLenSeg37 = vtSeg37.Len();
frFrame.Set( vVert[3], vtSeg37) ;
if ( CDeSimpleCylTria( frFrame, dSafeDist, dLenSeg37, trTria))
return true ; return true ;
return false ; return false ;
+7 -11
View File
@@ -23,16 +23,15 @@ using namespace std ;
bool bool
CDeSpheClosedSurfTm( const Point3d& ptCen, double dR, double dSafeDist, const ISurfTriMesh& Stm) CDeSpheClosedSurfTm( const Point3d& ptCen, double dR, double dSafeDist, const ISurfTriMesh& Stm)
{ {
// Recupero BBox del poliedro // recupero BBox del poliedro
BBox3d b3Poly = Stm.GetAllTriaBox() ; BBox3d b3Poly = Stm.GetAllTriaBox() ;
// Calcolo il BBox della sfera // calcolo il BBox della sfera
BBox3d b3Sphe( ptCen, dR) ; BBox3d b3Sphe( ptCen, dR) ;
if ( dSafeDist > EPS_SMALL) b3Sphe.Expand( dSafeDist) ;
b3Sphe.Expand( dSafeDist) ; // confronto i due Box
// Se i BBox non interferiscono, non c'è collisione
if ( ! b3Sphe.Overlaps( b3Poly)) if ( ! b3Sphe.Overlaps( b3Poly))
return false ; return false ;
// Verifico se la sfera interferisce con i triangoli del poliedro presenti nel suo BBox // recupero i triangoli che interferiscono con il box della Sfera
INTVECTOR vT ; INTVECTOR vT ;
Stm.GetAllTriaOverlapBox( b3Sphe, vT) ; Stm.GetAllTriaOverlapBox( b3Sphe, vT) ;
for ( int nT : vT) { for ( int nT : vT) {
@@ -45,11 +44,8 @@ CDeSpheClosedSurfTm( const Point3d& ptCen, double dR, double dSafeDist, const IS
// Se superficie aperta, non c'è collisione // Se superficie aperta, non c'è collisione
if ( ! Stm.IsClosed()) if ( ! Stm.IsClosed())
return false ; return false ;
// Se il BBox della sfera non è interno a quello del poliedro e viceversa, non c'è collisione // Verifico se la sfera è dentro la superficie tramite calcolo distanza minima.
if ( ! b3Sphe.Encloses( b3Poly) && ! b3Poly.Encloses( b3Sphe))
return false ;
// Verifico se la sfera è dentro la superficie tramite calcolo distanza minima del suo centro
DistPointSurfTm DistCenSurfCalc( ptCen, Stm) ; DistPointSurfTm DistCenSurfCalc( ptCen, Stm) ;
// C'è collisione se la sfera è interna. // C'è collisione se la sfera è interna.
return ( DistCenSurfCalc.IsPointInside()) ; return ( DistCenSurfCalc.IsPointInside()) ;
} }
+5 -5
View File
@@ -109,7 +109,7 @@ CDeTriaTria( const Triangle3d& trTriaA, const Triangle3d& trTriaB)
DistLineLine LineLineDistCalc( ptStA, PtEnA, ptStB, PtEnB) ; DistLineLine LineLineDistCalc( ptStA, PtEnA, ptStB, PtEnB) ;
double dSqSegSegDist ; double dSqSegSegDist ;
LineLineDistCalc.GetSqDist( dSqSegSegDist) ; LineLineDistCalc.GetSqDist( dSqSegSegDist) ;
if ( dSqSegSegDist < SQ_EPS_SMALL) if ( dSqSegSegDist < EPS_SMALL * EPS_SMALL)
return true ; return true ;
} }
} }
@@ -136,14 +136,14 @@ CDeTriaTria( const Triangle3d& trTriaA, const Triangle3d& trTriaB)
vtSegFirstA /= dSegLenFirstA ; vtSegFirstA /= dSegLenFirstA ;
DistLineLine LineLineDistCalcFirstA( ptLineP, vtLineV, 100., trTriaA.GetP( nFirstMaxPosA), vtSegFirstA, dSegLenFirstA, false) ; DistLineLine LineLineDistCalcFirstA( ptLineP, vtLineV, 100., trTriaA.GetP( nFirstMaxPosA), vtSegFirstA, dSegLenFirstA, false) ;
double dIntParStA, dOtherParFirstA ; double dIntParStA, dOtherParFirstA ;
LineLineDistCalcFirstA.GetPositionsAtMinDistPoints( dIntParStA, dOtherParFirstA) ; LineLineDistCalcFirstA.GetParamsAtMinDistPoints( dIntParStA, dOtherParFirstA) ;
// Limito la retta col secondo segmento trovato di A // Limito la retta col secondo segmento trovato di A
Vector3d vtSegSecondA = trTriaA.GetP( ( nSecondMaxPosA + 1) % 3) - trTriaA.GetP( nSecondMaxPosA) ; Vector3d vtSegSecondA = trTriaA.GetP( ( nSecondMaxPosA + 1) % 3) - trTriaA.GetP( nSecondMaxPosA) ;
double dSegLenSecondA = vtSegSecondA.Len() ; double dSegLenSecondA = vtSegSecondA.Len() ;
vtSegSecondA /= dSegLenSecondA ; vtSegSecondA /= dSegLenSecondA ;
DistLineLine LineLineDistCalcSecondA( ptLineP, vtLineV, 100., trTriaA.GetP( nSecondMaxPosA), vtSegSecondA, dSegLenSecondA, false) ; DistLineLine LineLineDistCalcSecondA( ptLineP, vtLineV, 100., trTriaA.GetP( nSecondMaxPosA), vtSegSecondA, dSegLenSecondA, false) ;
double dIntParEnA, dOtherParSecondA ; double dIntParEnA, dOtherParSecondA ;
LineLineDistCalcSecondA.GetPositionsAtMinDistPoints( dIntParEnA, dOtherParSecondA) ; LineLineDistCalcSecondA.GetParamsAtMinDistPoints( dIntParEnA, dOtherParSecondA) ;
// Ordino i parametri lungo la retta di intersezione fra i piani // Ordino i parametri lungo la retta di intersezione fra i piani
if ( dIntParStA > dIntParEnA) { if ( dIntParStA > dIntParEnA) {
swap( dIntParStA, dIntParEnA) ; swap( dIntParStA, dIntParEnA) ;
@@ -163,14 +163,14 @@ CDeTriaTria( const Triangle3d& trTriaA, const Triangle3d& trTriaB)
vtSegFirstB /= dSegLenFirstB ; vtSegFirstB /= dSegLenFirstB ;
DistLineLine LineLineDistCalcFirstB( ptLineP, vtLineV, 100., trTriaB.GetP( nFirstMaxPosB), vtSegFirstB, dSegLenFirstB, false) ; DistLineLine LineLineDistCalcFirstB( ptLineP, vtLineV, 100., trTriaB.GetP( nFirstMaxPosB), vtSegFirstB, dSegLenFirstB, false) ;
double dIntParStB, dOtherParFirstB ; double dIntParStB, dOtherParFirstB ;
LineLineDistCalcFirstB.GetPositionsAtMinDistPoints( dIntParStB, dOtherParFirstB) ; LineLineDistCalcFirstB.GetParamsAtMinDistPoints( dIntParStB, dOtherParFirstB) ;
// Limito la retta col secondo segmento trovato di B // Limito la retta col secondo segmento trovato di B
Vector3d vtSegSecondB = trTriaB.GetP( ( nSecondMaxPosB + 1) % 3) - trTriaB.GetP( nSecondMaxPosB) ; Vector3d vtSegSecondB = trTriaB.GetP( ( nSecondMaxPosB + 1) % 3) - trTriaB.GetP( nSecondMaxPosB) ;
double dSegLenSecondB = vtSegSecondB.Len() ; double dSegLenSecondB = vtSegSecondB.Len() ;
vtSegSecondB /= dSegLenSecondB ; vtSegSecondB /= dSegLenSecondB ;
DistLineLine LineLineDistCalcSecondB( ptLineP, vtLineV, 100., trTriaB.GetP( nSecondMaxPosA), vtSegSecondB, dSegLenSecondB, false) ; DistLineLine LineLineDistCalcSecondB( ptLineP, vtLineV, 100., trTriaB.GetP( nSecondMaxPosA), vtSegSecondB, dSegLenSecondB, false) ;
double dIntParEnB, dOtherParSecondB ; double dIntParEnB, dOtherParSecondB ;
LineLineDistCalcSecondB.GetPositionsAtMinDistPoints( dIntParEnB, dOtherParSecondB) ; LineLineDistCalcSecondB.GetParamsAtMinDistPoints( dIntParEnB, dOtherParSecondB) ;
// Ordino i parametri lungo la retta di intersezione fra i piani // Ordino i parametri lungo la retta di intersezione fra i piani
if ( dIntParStB > dIntParEnB) { if ( dIntParStB > dIntParEnB) {
swap( dIntParStB, dIntParEnB) ; swap( dIntParStB, dIntParEnB) ;
+3 -3
View File
@@ -13,9 +13,9 @@
//--------------------------- Include ---------------------------------------- //--------------------------- Include ----------------------------------------
#include "stdafx.h" #include "stdafx.h"
#include "/EgtDev/Include/EGkChainCurves.h" #include "/EgtDev/Include/EgkChainCurves.h"
#include "/EgtDev/Include/EGkGeomDB.h" #include "/EgtDev/Include/EgkGeomDB.h"
#include "/EgtDev/Include/EGkCurve.h" #include "/EgtDev/Include/EgkCurve.h"
#include <algorithm> #include <algorithm>
using namespace std ; using namespace std ;
-44
View File
@@ -1,44 +0,0 @@
//----------------------------------------------------------------------------
// EgalTech 2022-2022
//----------------------------------------------------------------------------
// File : Circle2P.cpp Data : 18.08.22 Versione : 2.4h2
// Contenuto : Implementazione funzioni per calcolo circonferenze per 2 punti
// diametrali.
//
//
// Modifiche : 18.08.22 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "CurveArc.h"
#include "/EgtDev/Include/EGkCircle2P.h"
#include "/EgtDev/Include/EgtPointerOwner.h"
using namespace std ;
//----------------------------------------------------------------------------
ICurveArc*
GetCircle2P( const Point3d& ptP1, const Point3d& ptP2, const Vector3d& vtN)
{
// Verifico che i due punti siano distinti
if ( AreSamePointEpsilon( ptP1, ptP2, EPS_SMALL))
return nullptr ;
// verifico che la normale non sia allineata con i punti
Vector3d vtO = OrthoCompo( vtN, ptP2 - ptP1) ;
if ( ! vtO.Normalize())
return nullptr ;
// Creo l'oggetto arco
PtrOwner<CurveArc> pCrvArc( CreateBasicCurveArc()) ;
if ( IsNull( pCrvArc))
return nullptr ;
// Eseguo calcoli
if ( ! pCrvArc->SetCPAN( Media( ptP1, ptP2), ptP1, ANG_FULL, 0, vtO))
return nullptr ;
return Release( pCrvArc) ;
}
+3 -3
View File
@@ -18,8 +18,8 @@
#include "CreateCurveAux.h" #include "CreateCurveAux.h"
#include "DistPointLine.h" #include "DistPointLine.h"
#include "GeoConst.h" #include "GeoConst.h"
#include "/EgtDev/Include/EGkCircleCenTgCurve.h" #include "/EgtDev/Include/EgkCircleCenTgCurve.h"
#include "/EgtDev/Include/EGkDistPointCurve.h" #include "/EgtDev/Include/EgkDistPointCurve.h"
#include "/EgtDev/Include/EgtPointerOwner.h" #include "/EgtDev/Include/EgtPointerOwner.h"
using namespace std ; using namespace std ;
@@ -239,7 +239,7 @@ GetCircleCenTgCompo( const Point3d& ptCen, const Vector3d& vtN, const CurveCompo
double dSqDist = SqDist( ptNear, ptTg) ; double dSqDist = SqDist( ptNear, ptTg) ;
if ( dSqDist < dMinSqDist) { if ( dSqDist < dMinSqDist) {
dMinSqDist = dSqDist ; dMinSqDist = dSqDist ;
pCrvArc.Set( pCrvAtmp) ; pCrvArc.Set( Release( pCrvAtmp)) ;
if ( pPtTg != nullptr) if ( pPtTg != nullptr)
*pPtTg = ptTg ; *pPtTg = ptTg ;
} }
+1 -1
View File
@@ -17,7 +17,7 @@
#include "/EgtDev/Include/EGkColor.h" #include "/EgtDev/Include/EGkColor.h"
#include "/EgtDev/Include/EGkAngle.h" #include "/EgtDev/Include/EGkAngle.h"
#include "/EgtDev/Include/EGnStringUtils.h" #include "/EgtDev/Include/EGnStringUtils.h"
#include "/EgtDev/Include/EgtNumUtils.h" #include "/EgtDev/Include/EGtNumUtils.h"
#include <algorithm> #include <algorithm>
using namespace std ; using namespace std ;
+79 -131
View File
@@ -25,8 +25,6 @@
#include "/EgtDev/Include/EGkAngle.h" #include "/EgtDev/Include/EGkAngle.h"
#include "/EgtDev/Include/EGkStringUtils3d.h" #include "/EgtDev/Include/EGkStringUtils3d.h"
#include "/EgtDev/Include/EGkUiUnits.h" #include "/EgtDev/Include/EGkUiUnits.h"
#include "/EgtDev/Include/ENkPolynomialRoots.h"
#include "/EgtDev/Include/EgtNumUtils.h"
#include "/EgtDev/Include/EgtPointerOwner.h" #include "/EgtDev/Include/EgtPointerOwner.h"
#include <new> #include <new>
@@ -568,7 +566,7 @@ CurveArc::Clone( void) const
bool bool
CurveArc::CopyFrom( const IGeoObj* pGObjSrc) CurveArc::CopyFrom( const IGeoObj* pGObjSrc)
{ {
const CurveArc* pCA = GetBasicCurveArc( pGObjSrc) ; const CurveArc* pCA = dynamic_cast<const CurveArc*>( pGObjSrc) ;
if ( pCA == nullptr) if ( pCA == nullptr)
return false ; return false ;
return CopyFrom( *pCA) ; return CopyFrom( *pCA) ;
@@ -701,8 +699,29 @@ CurveArc::Load( NgeReader& ngeIn)
bool bool
CurveArc::GetLocalBBox( BBox3d& b3Loc, int nFlag) const CurveArc::GetLocalBBox( BBox3d& b3Loc, int nFlag) const
{ {
// richiamo della funzione generale // verifico lo stato
return GetBBox( GLOB_FRM, b3Loc, nFlag) ; if ( m_nStatus != OK)
return false ;
// assegno il box in locale
b3Loc.Reset() ;
double dLinTol = LIN_TOL_APPROX ;
double dAngTolDeg = ANG_TOL_APPROX_DEG ;
if ( ( nFlag & BBF_EXACT) != 0)
dLinTol = LIN_TOL_MIN ;
ArcApproxer aAppr( dLinTol, dAngTolDeg, false, *this) ;
double dU ;
Point3d ptPos ;
while ( aAppr.GetPoint( dU, ptPos))
b3Loc.Add( ptPos) ;
// se c'è estrusione, devo tenerne conto
if ( ! m_VtExtr.IsSmall() && abs( m_dThick) > EPS_SMALL) {
Point3d ptMinExtr = b3Loc.GetMin() + m_VtExtr * m_dThick ;
Point3d ptMaxExtr = b3Loc.GetMax() + m_VtExtr * m_dThick ;
b3Loc.Add( ptMinExtr) ;
b3Loc.Add( ptMaxExtr) ;
}
return true ;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@@ -717,88 +736,17 @@ CurveArc::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag) const
return false ; return false ;
// assegno il box nel riferimento // assegno il box nel riferimento
b3Ref.Reset() ; b3Ref.Reset() ;
double dLinTol = LIN_TOL_APPROX ;
// ricavo il riferimento intrinseco dell'arco double dAngTolDeg = ANG_TOL_APPROX_DEG ;
Frame3d frArc; if ( ( nFlag & BBF_EXACT) != 0)
frArc.Set( m_PtCen, ( m_dAngCenDeg > 0 ? m_VtN : -m_VtN), m_VtS) ; dLinTol = LIN_TOL_MIN ;
ArcApproxer aAppr( dLinTol, dAngTolDeg, false, *this) ;
// pendenza intrinseca double dU ;
double dPitch = m_dDeltaN * ( m_dAngCenDeg > 0 ? 1 : -1) / abs( m_dAngCenDeg * DEGTORAD) ; Point3d ptPos ;
while ( aAppr.GetPoint( dU, ptPos)) {
// cordinate nel frRef dei versori del sistema di riferimento dell'arco ptPos.ToGlob( frRef) ;
Vector3d vtXRef = frArc.VersX() ; b3Ref.Add( ptPos) ;
vtXRef.ToGlob( frRef) ;
Vector3d vtYRef = frArc.VersY() ;
vtYRef.ToGlob( frRef) ;
Vector3d vtZRef = frArc.VersZ() ;
vtZRef.ToGlob( frRef) ;
// il punto iniziale e finale sono punti candidati per estremanti
Point3d ptS, ptE ;
GetStartPoint( ptS) ;
ptS.ToGlob( frRef) ;
b3Ref.Add( ptS) ;
GetEndPoint( ptE) ;
ptE.ToGlob( frRef) ;
b3Ref.Add( ptE) ;
// vettore degli angoli dei punti candidati estremi
DBLVECTOR vdTheta ;
// arco piatto
if ( abs( dPitch) < EPS_SMALL) {
double dAngXDeg = atan2( vtYRef.x, vtXRef.x) * RADTODEG ;
bool bAngXSmall = (abs( dAngXDeg) <= EPS_ANG_ZERO) ;
if ( ! bAngXSmall) {
vdTheta.push_back( dAngXDeg) ;
vdTheta.push_back( dAngXDeg + ANG_STRAIGHT) ;
}
double dAngYDeg = atan2( vtYRef.y, vtXRef.y) * RADTODEG ;
bool bAngYSmall = (abs( dAngYDeg) <= EPS_ANG_ZERO) ;
if ( ! bAngYSmall) {
vdTheta.push_back( dAngYDeg) ;
vdTheta.push_back( dAngYDeg + ANG_STRAIGHT) ;
}
double dAngZDeg = atan2( vtYRef.z, vtXRef.z) * RADTODEG ;
bool bAngZSmall = (abs( dAngZDeg) <= EPS_ANG_ZERO) ;
if ( ! bAngZSmall) {
vdTheta.push_back( dAngZDeg) ;
vdTheta.push_back( dAngZDeg + ANG_STRAIGHT) ;
}
if ( bAngXSmall || bAngYSmall || bAngZSmall)
vdTheta.push_back( ANG_STRAIGHT) ;
} }
// altrimenti arco di elica
else {
for ( int i = 0 ; i < 3 ; ++ i) {
DBLVECTOR vdPoly{ m_dRad * vtYRef.v[i] + dPitch * vtZRef.v[i],
- 2 * m_dRad * vtXRef.v[i],
- m_dRad * vtYRef.v[i] + dPitch * vtZRef.v[i]} ;
DBLVECTOR vdRoot ;
int nRoot = PolynomialRoots( 2, vdPoly, vdRoot) ;
for ( int i = 0 ; i < nRoot ; ++ i) {
double dAngDeg = atan2( 2 * vdRoot[i], (1 - vdRoot[i] * vdRoot[i])) * RADTODEG ;
if ( abs( dAngDeg) > EPS_ANG_ZERO) {
vdTheta.push_back( dAngDeg) ;
vdTheta.push_back( dAngDeg + ANG_STRAIGHT) ;
}
else
vdTheta.push_back( ANG_STRAIGHT) ;
}
}
}
// verifica degli angoli sull'arco ed eventuale considerazione dei punti
for ( int i = 0 ; i < int( vdTheta.size()) ; ++ i) {
double dTheta = ( vdTheta[i] > 0 ? vdTheta[i] : vdTheta[i] + ANG_FULL) ;
if ( dTheta < abs( m_dAngCenDeg)) {
Point3d ptP ;
GetPointD1D2( dTheta / ( abs( m_dAngCenDeg)), FROM_MINUS, ptP) ;
ptP.ToGlob( frRef) ;
b3Ref.Add( ptP) ;
}
}
// se c'è estrusione, devo tenerne conto // se c'è estrusione, devo tenerne conto
if ( ! m_VtExtr.IsSmall() && abs( m_dThick) > EPS_SMALL) { if ( ! m_VtExtr.IsSmall() && abs( m_dThick) > EPS_SMALL) {
Vector3d vtFrExtr = m_VtExtr ; Vector3d vtFrExtr = m_VtExtr ;
@@ -825,10 +773,10 @@ CurveArc::Validate( void)
m_dAngCenDeg = - ANG_FULL ; m_dAngCenDeg = - ANG_FULL ;
} }
// eseguo il controllo // eseguo il controllo
m_nStatus = ( ( m_PtCen.IsValid() && m_nStatus = ( ( m_VtN.IsNormalized() && m_VtS.IsNormalized() &&
m_VtN.IsNormalized() && m_VtS.IsNormalized() && AreOrthoApprox( m_VtN, m_VtS) && AreOrthoApprox( m_VtN, m_VtS) &&
m_dRad > EPS_SMALL && m_dRad < MAX_ARC_RAD && m_dRad > EPS_SMALL && m_dRad < MAX_ARC_RAD &&
abs( m_dAngCenDeg) > EPS_ANG_ZERO) ? OK : ERR) ; abs( m_dAngCenDeg) > EPS_ANG_ZERO) ? OK : ERR) ;
} }
return ( m_nStatus == OK) ; return ( m_nStatus == OK) ;
@@ -883,7 +831,7 @@ CurveArc::GetEndPoint( Point3d& ptEnd) const
double dAng = m_dAngCenDeg * DEGTORAD ; double dAng = m_dAngCenDeg * DEGTORAD ;
Vector3d vtDir = cos( dAng) * m_VtS + sin( dAng) * ( m_VtN ^ m_VtS) ; Vector3d vtDir = cos( dAng) * m_VtS + sin( dAng) * ( m_VtN ^ m_VtS) ;
ptEnd = m_PtCen + m_dRad * vtDir ; ptEnd = m_PtCen + m_dRad * vtDir ;
if ( abs( m_dDeltaN) > 0.1 * EPS_SMALL) if ( abs( m_dDeltaN) > EPS_SMALL)
ptEnd += m_dDeltaN * m_VtN ; ptEnd += m_dDeltaN * m_VtN ;
return true ; return true ;
@@ -901,7 +849,7 @@ CurveArc::GetMidPoint( Point3d& ptMid) const
double dAng = 0.5 * m_dAngCenDeg * DEGTORAD ; double dAng = 0.5 * m_dAngCenDeg * DEGTORAD ;
Vector3d vtDir = cos( dAng) * m_VtS + sin( dAng) * ( m_VtN ^ m_VtS) ; Vector3d vtDir = cos( dAng) * m_VtS + sin( dAng) * ( m_VtN ^ m_VtS) ;
ptMid = m_PtCen + m_dRad * vtDir ; ptMid = m_PtCen + m_dRad * vtDir ;
if ( abs( m_dDeltaN) > 0.1 * EPS_SMALL) if ( abs( m_dDeltaN) > EPS_SMALL)
ptMid += ( 0.5 * m_dDeltaN) * m_VtN ; ptMid += ( 0.5 * m_dDeltaN) * m_VtN ;
return true ; return true ;
@@ -929,7 +877,7 @@ CurveArc::GetCentroid( Point3d& ptCen) const
return false ; return false ;
// approssimo la curva con una polilinea // approssimo la curva con una polilinea
PolyLine PL ; PolyLine PL ;
if ( ! ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, APL_STD, PL)) if ( ! ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_STD, PL))
return false ; return false ;
// calcolo il centro mediante PolygonPlane // calcolo il centro mediante PolygonPlane
Point3d ptP ; Point3d ptP ;
@@ -951,14 +899,17 @@ CurveArc::GetDir( double dU, Vector3d& vtDir) const
return false ; return false ;
// il parametro U deve essere compreso tra 0 e 1 // il parametro U deve essere compreso tra 0 e 1
dU = Clamp( dU, 0., 1.) ; if ( dU < 0)
dU = 0 ;
else if ( dU > 1)
dU = 1 ;
// versore al punto nel piano della circonferenza (ruoto m_VtS di dU * m_dAngCenDeg attorno a m_VtN) // versore al punto nel piano della circonferenza (ruoto m_VtS di dU * m_dAngCenDeg attorno a m_VtN)
double dAng = dU * m_dAngCenDeg * DEGTORAD ; double dAng = dU * m_dAngCenDeg * DEGTORAD ;
Vector3d vtRad = cos( dAng) * m_VtS + sin( dAng) * ( m_VtN ^ m_VtS) ; Vector3d vtRad = cos( dAng) * m_VtS + sin( dAng) * ( m_VtN ^ m_VtS) ;
// calcolo della tangente nel punto finale // calcolo della tangente nel punto finale
vtDir = ( m_dRad * m_dAngCenDeg * DEGTORAD) * ( m_VtN ^ vtRad) ; vtDir = ( m_dRad * m_dAngCenDeg * DEGTORAD) * ( m_VtN ^ vtRad) ;
if ( abs( m_dDeltaN) > 0.1 * EPS_SMALL) if ( abs( m_dDeltaN) > EPS_SMALL)
vtDir += m_dDeltaN * m_VtN ; vtDir += m_dDeltaN * m_VtN ;
// normalizzo // normalizzo
return vtDir.Normalize( EPS_ZERO) ; return vtDir.Normalize( EPS_ZERO) ;
@@ -973,7 +924,10 @@ CurveArc::GetPointD1D2( double dU, Side nS, Point3d& ptPos, Vector3d* pvtDer1, V
return false ; return false ;
// il parametro U deve essere compreso tra 0 e 1 // il parametro U deve essere compreso tra 0 e 1
dU = Clamp( dU, 0., 1.) ; if ( dU < 0)
dU = 0 ;
else if ( dU > 1)
dU = 1 ;
// versore al punto nel piano della circonferenza (ruoto m_VtS di dU di m_dAngCenDeg attorno a m_VtN) // versore al punto nel piano della circonferenza (ruoto m_VtS di dU di m_dAngCenDeg attorno a m_VtN)
double dAng = dU * m_dAngCenDeg * DEGTORAD ; double dAng = dU * m_dAngCenDeg * DEGTORAD ;
@@ -981,13 +935,13 @@ CurveArc::GetPointD1D2( double dU, Side nS, Point3d& ptPos, Vector3d* pvtDer1, V
// calcolo del punto // calcolo del punto
ptPos = m_PtCen + m_dRad * vtDir ; ptPos = m_PtCen + m_dRad * vtDir ;
if ( abs( m_dDeltaN) > 0.1 * EPS_SMALL) if ( abs( m_dDeltaN) > EPS_SMALL)
ptPos += ( dU * m_dDeltaN) * m_VtN ; ptPos += ( dU * m_dDeltaN) * m_VtN ;
// calcolo della derivata prima // calcolo della derivata prima
if ( pvtDer1 != nullptr) { if ( pvtDer1 != nullptr) {
*pvtDer1 = ( m_dRad * m_dAngCenDeg * DEGTORAD) * ( m_VtN ^ vtDir) ; *pvtDer1 = ( m_dRad * m_dAngCenDeg * DEGTORAD) * ( m_VtN ^ vtDir) ;
if ( abs( m_dDeltaN) > 0.1 * EPS_SMALL) if ( abs( m_dDeltaN) > EPS_SMALL)
*pvtDer1 += m_dDeltaN * m_VtN ; *pvtDer1 += m_dDeltaN * m_VtN ;
} }
@@ -1009,7 +963,7 @@ CurveArc::GetLength( double& dLen) const
// lunghezza dell'arco piano // lunghezza dell'arco piano
dLen = m_dRad * abs( m_dAngCenDeg) * DEGTORAD ; dLen = m_dRad * abs( m_dAngCenDeg) * DEGTORAD ;
// aggiunta eventuale parte ortogonale // aggiunta eventuale parte ortogonale
if ( abs( m_dDeltaN) > 0.1 * EPS_SMALL) if ( abs( m_dDeltaN) > EPS_SMALL)
dLen = sqrt( dLen * dLen + m_dDeltaN * m_dDeltaN) ; dLen = sqrt( dLen * dLen + m_dDeltaN * m_dDeltaN) ;
return ( dLen > EPS_SMALL) ; return ( dLen > EPS_SMALL) ;
@@ -1250,7 +1204,7 @@ CurveArc::Invert( void)
return false ; return false ;
// il centro va spostato di DeltaN // il centro va spostato di DeltaN
if ( abs( m_dDeltaN) > 0.1 * EPS_SMALL) if ( abs( m_dDeltaN) > EPS_SMALL)
m_PtCen += m_dDeltaN * m_VtN ; m_PtCen += m_dDeltaN * m_VtN ;
// il versore normale rimane inalterato // il versore normale rimane inalterato
// il versore iniziale diventa quello finale // il versore iniziale diventa quello finale
@@ -1421,11 +1375,13 @@ CurveArc::ModifyEnd( const Point3d& ptNewEnd)
bool bool
CurveArc::TrimStartAtParam( double dUTrim) CurveArc::TrimStartAtParam( double dUTrim)
{ {
double dLen ;
// riporto i parametri nel loro range // riporto i parametri nel loro range
dUTrim = Clamp( dUTrim, 0., 1.) ; dUTrim = ( ( dUTrim < 0) ? 0 : (( dUTrim > 1) ? 1 : dUTrim)) ;
// recupero lunghezza // recupero lunghezza
double dLen ;
if ( ! GetLength( dLen)) if ( ! GetLength( dLen))
return false ; return false ;
@@ -1437,11 +1393,13 @@ CurveArc::TrimStartAtParam( double dUTrim)
bool bool
CurveArc::TrimEndAtParam( double dUTrim) CurveArc::TrimEndAtParam( double dUTrim)
{ {
double dLen ;
// riporto i parametri nel loro range // riporto i parametri nel loro range
dUTrim = Clamp( dUTrim, 0., 1.) ; dUTrim = ( ( dUTrim < 0) ? 0 : (( dUTrim > 1) ? 1 : dUTrim)) ;
// recupero lunghezza // recupero lunghezza
double dLen ;
if ( ! GetLength( dLen)) if ( ! GetLength( dLen))
return false ; return false ;
@@ -1489,7 +1447,7 @@ CurveArc::TrimStartAtLen( double dLenTrim)
dAngRot = m_dAngCenDeg * dLenTrim / dLen ; dAngRot = m_dAngCenDeg * dLenTrim / dLen ;
m_VtS.Rotate( m_VtN, dAngRot) ; m_VtS.Rotate( m_VtN, dAngRot) ;
m_dAngCenDeg -= dAngRot ; m_dAngCenDeg -= dAngRot ;
if ( abs( m_dDeltaN) > 0.1 * EPS_SMALL) { if ( abs( m_dDeltaN) > EPS_SMALL) {
dMoveN = m_dDeltaN * dLenTrim / dLen ; dMoveN = m_dDeltaN * dLenTrim / dLen ;
m_PtCen.Translate( m_VtN * dMoveN) ; m_PtCen.Translate( m_VtN * dMoveN) ;
m_dDeltaN -= dMoveN ; m_dDeltaN -= dMoveN ;
@@ -1519,7 +1477,7 @@ CurveArc::TrimEndAtLen( double dLenTrim)
// eseguo il trim // eseguo il trim
if ( ( dLen - dLenTrim) > EPS_ZERO) { if ( ( dLen - dLenTrim) > EPS_ZERO) {
m_dAngCenDeg *= dLenTrim / dLen ; m_dAngCenDeg *= dLenTrim / dLen ;
if ( abs( m_dDeltaN) > 0.1 * EPS_SMALL) if ( abs( m_dDeltaN) > EPS_SMALL)
m_dDeltaN *= dLenTrim / dLen ; m_dDeltaN *= dLenTrim / dLen ;
} }
@@ -1798,14 +1756,11 @@ CurveArc::ToGlob( const Frame3d& frRef)
// la curva deve essere validata // la curva deve essere validata
if ( m_nStatus != OK) if ( m_nStatus != OK)
return false ; return false ;
// verifico validità del frame // verifico validità del frame
if ( frRef.GetType() == Frame3d::ERR) if ( frRef.GetType() == Frame3d::ERR)
return false ; return false ;
// se frame identità, non devo fare alcunché
if ( IsGlobFrame( frRef))
return true ;
// imposto ricalcolo della grafica // imposto ricalcolo della grafica
m_OGrMgr.Reset() ; m_OGrMgr.Reset() ;
@@ -1823,14 +1778,11 @@ CurveArc::ToLoc( const Frame3d& frRef)
// la curva deve essere validata // la curva deve essere validata
if ( m_nStatus != OK) if ( m_nStatus != OK)
return false ; return false ;
// verifico validità del frame // verifico validità del frame
if ( frRef.GetType() == Frame3d::ERR) if ( frRef.GetType() == Frame3d::ERR)
return false ; return false ;
// se frame identità, non devo fare alcunché
if ( IsGlobFrame( frRef))
return true ;
// imposto ricalcolo della grafica // imposto ricalcolo della grafica
m_OGrMgr.Reset() ; m_OGrMgr.Reset() ;
@@ -1851,14 +1803,11 @@ CurveArc::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
// verifico validità dei frame // verifico validità dei frame
if ( frOri.GetType() == Frame3d::ERR || frDest.GetType() == Frame3d::ERR) if ( frOri.GetType() == Frame3d::ERR || frDest.GetType() == Frame3d::ERR)
return false ; return false ;
// se i due riferimenti coincidono, non devo fare alcunché // se i due riferimenti coincidono, non devo fare alcunché
if ( AreSameFrame( frOri, frDest)) if ( AreSameFrame( frOri, frDest))
return true ; return true ;
// imposto ricalcolo della grafica // imposto ricalcolo della grafica
m_OGrMgr.Reset() ; m_OGrMgr.Reset() ;
// trasformo il centro e i versori // trasformo il centro e i versori
return ( m_PtCen.LocToLoc( frOri, frDest) && return ( m_PtCen.LocToLoc( frOri, frDest) &&
m_VtN.LocToLoc( frOri, frDest) && m_VtN.LocToLoc( frOri, frDest) &&
@@ -1952,10 +1901,6 @@ CurveArc::ChangeRadius( double dNewRadius)
if ( m_nStatus != OK) if ( m_nStatus != OK)
return false ; return false ;
// verifico validità del raggio
if ( ! ( dNewRadius > EPS_SMALL && dNewRadius < MAX_ARC_RAD))
return false ;
// cambio il raggio // cambio il raggio
m_dRad = dNewRadius ; m_dRad = dNewRadius ;
@@ -1994,10 +1939,6 @@ CurveArc::ChangeAngCenter( double dNewAngCenDeg)
if ( m_nStatus != OK) if ( m_nStatus != OK)
return false ; return false ;
// verifico accettabilità angolo
if ( ! ( abs( m_dAngCenDeg) > EPS_ANG_ZERO))
return false ;
// cambio il parametro // cambio il parametro
m_dAngCenDeg = dNewAngCenDeg ; m_dAngCenDeg = dNewAngCenDeg ;
@@ -2090,6 +2031,10 @@ CurveArc::Flip( void)
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
ArcApproxer::ArcApproxer( double dLinTol, double dAngTolDeg, bool bInside, const CurveArc& arArc) ArcApproxer::ArcApproxer( double dLinTol, double dAngTolDeg, bool bInside, const CurveArc& arArc)
{ {
int nStep ;
double dAngStepDeg ;
// inizializzazioni // inizializzazioni
m_nTotPnt = 0 ; m_nTotPnt = 0 ;
m_nCurrPnt = - 1 ; m_nCurrPnt = - 1 ;
@@ -2107,7 +2052,6 @@ ArcApproxer::ArcApproxer( double dLinTol, double dAngTolDeg, bool bInside, const
dAngTolDeg = min( dAngTolDeg, ANG_TOL_EXT_MAX_DEG) ; dAngTolDeg = min( dAngTolDeg, ANG_TOL_EXT_MAX_DEG) ;
// determinazione dello step angolare // determinazione dello step angolare
double dAngStepDeg ;
double dLinTolRel = dLinTol / arArc.GetRadius() ; double dLinTolRel = dLinTol / arArc.GetRadius() ;
if ( bInside) if ( bInside)
dAngStepDeg = sqrt( 8 * dLinTolRel) * RADTODEG ; dAngStepDeg = sqrt( 8 * dLinTolRel) * RADTODEG ;
@@ -2116,7 +2060,7 @@ ArcApproxer::ArcApproxer( double dLinTol, double dAngTolDeg, bool bInside, const
dAngStepDeg = min( dAngStepDeg, dAngTolDeg) ; dAngStepDeg = min( dAngStepDeg, dAngTolDeg) ;
// dall'angolo al centro ricavo il numero di passi // dall'angolo al centro ricavo il numero di passi
int nStep = int( abs( arArc.GetAngCenter()) / dAngStepDeg + 0.999) ; nStep = (int) ( abs( arArc.GetAngCenter()) / dAngStepDeg + 0.999) ;
nStep = max( nStep, 1) ; nStep = max( nStep, 1) ;
// sistemo lo step (per il numero intero di passi) // sistemo lo step (per il numero intero di passi)
@@ -2143,6 +2087,10 @@ ArcApproxer::ArcApproxer( double dLinTol, double dAngTolDeg, bool bInside, const
bool bool
ArcApproxer::GetPoint( double& dU, Point3d& ptP) ArcApproxer::GetPoint( double& dU, Point3d& ptP)
{ {
Vector3d vtA1p ;
Vector3d vtA2p ;
// incremento indice punto corrente // incremento indice punto corrente
++ m_nCurrPnt ; ++ m_nCurrPnt ;
@@ -2161,7 +2109,7 @@ ArcApproxer::GetPoint( double& dU, Point3d& ptP)
if ( ! m_bInside && m_nCurrPnt == m_nTotPnt - 1) { if ( ! m_bInside && m_nCurrPnt == m_nTotPnt - 1) {
dU = 1 ; dU = 1 ;
ptP = m_PtCen + m_vtA1 * m_dRad ; ptP = m_PtCen + m_vtA1 * m_dRad ;
if ( abs( m_dDeltaN) > 0.1 * EPS_SMALL) if ( abs( m_dDeltaN) > EPS_SMALL)
ptP += ( dU * m_dDeltaN) * m_VtN ; ptP += ( dU * m_dDeltaN) * m_VtN ;
return true ; return true ;
} }
@@ -2173,8 +2121,8 @@ ArcApproxer::GetPoint( double& dU, Point3d& ptP)
else else
dU = ( m_nCurrPnt - 0.5) / (double) ( m_nTotPnt - 2) ; dU = ( m_nCurrPnt - 0.5) / (double) ( m_nTotPnt - 2) ;
// nuovo valore versori // nuovo valore versori
Vector3d vtA1p = m_vtA1 ; vtA1p = m_vtA1 ;
Vector3d vtA2p = m_vtA2 ; vtA2p = m_vtA2 ;
m_vtA1 = m_dCosA * vtA1p + m_dSinA * vtA2p ; m_vtA1 = m_dCosA * vtA1p + m_dSinA * vtA2p ;
m_vtA2 = - m_dSinA * vtA1p + m_dCosA * vtA2p ; m_vtA2 = - m_dSinA * vtA1p + m_dCosA * vtA2p ;
// calcolo del punto // calcolo del punto
@@ -2182,7 +2130,7 @@ ArcApproxer::GetPoint( double& dU, Point3d& ptP)
ptP = m_PtCen + m_vtA1 * m_dRad ; ptP = m_PtCen + m_vtA1 * m_dRad ;
else else
ptP = m_PtCen + ( vtA1p + m_vtA1) * ( m_dRad / ( 1 + m_dCosA)) ; ptP = m_PtCen + ( vtA1p + m_vtA1) * ( m_dRad / ( 1 + m_dCosA)) ;
if ( abs( m_dDeltaN) > 0.1 * EPS_SMALL) if ( abs( m_dDeltaN) > EPS_SMALL)
ptP += ( dU * m_dDeltaN) * m_VtN ; ptP += ( dU * m_dDeltaN) * m_VtN ;
return true ; return true ;
+4 -8
View File
@@ -217,16 +217,12 @@ class CurveArc : public ICurveArc, public IGeoObjRW
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
inline CurveArc* CreateBasicCurveArc( void) inline CurveArc* CreateBasicCurveArc( void)
{ return ( static_cast<CurveArc*>( CreateGeoObj( CRV_ARC))) ; } { return (static_cast<CurveArc*>( CreateGeoObj( CRV_ARC))) ; }
inline CurveArc* CloneBasicCurveArc( const IGeoObj* pGObj) inline CurveArc* CloneBasicCurveArc( const IGeoObj* pGObj)
{ if ( pGObj == nullptr || pGObj->GetType() != CRV_ARC) { if ( pGObj == nullptr || pGObj->GetType() != CRV_ARC)
return nullptr ; return nullptr ;
return ( static_cast<CurveArc*>( pGObj->Clone())) ; } return (static_cast<CurveArc*>(pGObj->Clone())) ; }
inline const CurveArc* GetBasicCurveArc( const IGeoObj* pGObj) inline const CurveArc* GetBasicCurveArc( const IGeoObj* pGObj)
{ if ( pGObj == nullptr || pGObj->GetType() != CRV_ARC) { return (dynamic_cast<const CurveArc*>(pGObj)) ; }
return nullptr ;
return ( static_cast<const CurveArc*>( pGObj)) ; }
inline CurveArc* GetBasicCurveArc( IGeoObj* pGObj) inline CurveArc* GetBasicCurveArc( IGeoObj* pGObj)
{ if ( pGObj == nullptr || pGObj->GetType() != CRV_ARC) { return (dynamic_cast<CurveArc*>(pGObj)) ; }
return nullptr ;
return ( static_cast<CurveArc*>( pGObj)) ; }
+19 -208
View File
@@ -30,8 +30,9 @@ using namespace std ;
bool bool
IsClosed( const ICurve& crvC) IsClosed( const ICurve& crvC)
{ {
Point3d ptStart, ptEnd ; Point3d ptStart ;
return ( crvC.GetStartPoint( ptStart) && crvC.GetEndPoint( ptEnd) && AreSamePointApprox( ptStart, ptEnd)) ; Point3d ptEnd ;
return ( crvC.GetStartPoint( ptStart) && crvC.GetEndPoint( ptEnd) && AreSamePointApprox( ptStart, ptEnd)) ;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@@ -294,7 +295,7 @@ CurveGetAreaXY( const ICurve& crvC, double& dArea)
return false ; return false ;
// approssimo la curva con una polilinea // approssimo la curva con una polilinea
PolyLine PL ; PolyLine PL ;
crvC.ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL_INT, PL) ; crvC.ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL) ;
// calcolo l'area // calcolo l'area
double dAreaXY = 0 ; double dAreaXY = 0 ;
PL.GetAreaXY( dAreaXY) ; PL.GetAreaXY( dAreaXY) ;
@@ -313,7 +314,7 @@ CurveGetArea( const ICurve& crvC, Plane3d& plPlane, double& dArea)
return false ; return false ;
// approssimo la curva con una polilinea // approssimo la curva con una polilinea
PolyLine PL ; PolyLine PL ;
crvC.ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL_INT, PL) ; crvC.ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL) ;
// calcolo l'area // calcolo l'area
Plane3d plMyPlane ; Plane3d plMyPlane ;
double dMyArea = 0 ; double dMyArea = 0 ;
@@ -364,11 +365,9 @@ CurveDump( const ICurve& crvC, string& sOut, bool bMM, const char* szNewLine)
// altri dati per curva chiusa // altri dati per curva chiusa
double dAreaXY ; double dAreaXY ;
if ( CurveGetAreaXY( crvC, dAreaXY)) { if ( CurveGetAreaXY( crvC, dAreaXY)) {
bool bCCW = ( dAreaXY > 0) ; bool bCCW = ( dAreaXY > 0) ;
double dAreaUi = GetAreaInUiUnits( abs( dAreaXY), bMM) ;
int nDec = ( dAreaUi > 100 ? 1 : ( dAreaUi > 0.1 ? 3 : 6)) ;
sOut += string( "Closed") + ( bCCW ? " CCW" : " CW") + " AreaXY=" + sOut += string( "Closed") + ( bCCW ? " CCW" : " CW") + " AreaXY=" +
ToString( dAreaUi, nDec) + szNewLine ; ToString( GetAreaInUiUnits( abs( dAreaXY), bMM),1) + szNewLine ;
} }
return true ; return true ;
@@ -510,7 +509,14 @@ CurveToArcsPerpExtrCurve( const ICurve* pCrv, double dLinTol, double dAngTolDeg)
bool bool
NurbsCurveCanonicalize( CNurbsData& cnData) NurbsCurveCanonicalize( CNurbsData& cnData)
{ {
// se con nodi extra // se periodica
if ( cnData.bPeriodic) {
// va trasformata in non-periodica (clamped)
// vedere The NurbsBook di Les Piegl e Tiller
// mancano esempi per testare
return false ;
}
// se con nodi extra
if ( cnData.bExtraKnotes) { if ( cnData.bExtraKnotes) {
int nKnotesNbr = int( cnData.vU.size()) ; int nKnotesNbr = int( cnData.vU.size()) ;
if ( nKnotesNbr < 4) if ( nKnotesNbr < 4)
@@ -519,176 +525,7 @@ NurbsCurveCanonicalize( CNurbsData& cnData)
for ( int i = 0 ; i < nKnotesNbr - 2 ; ++ i) for ( int i = 0 ; i < nKnotesNbr - 2 ; ++ i)
cnData.vU[i] = cnData.vU[i+1] ; cnData.vU[i] = cnData.vU[i+1] ;
cnData.vU.resize( nKnotesNbr - 2) ; cnData.vU.resize( nKnotesNbr - 2) ;
} return true ;
// se periodica
if ( cnData.bPeriodic) {
// va trasformata in non-periodica (clamped)
// bisogna aumentare la molteplicità dei nodi u_p-1 e u_(m-p+1) fino ad arrivare al grado della nurbs
// e poi scartare nodi e punti fuori dalla regione clamped ( al di fuori della regione u_p-1 -> u_(m-p+1))
// l'agoritmo per l'inserimento dei nodi l' A5.1 del libro delle Nurbs ( Piegl e Tiller), con qualche modifica
// agli indici perché uso u_p-1 e u_(m-p+1), anziché u_p e u_m-p
// comincio ad aumentare la molteplictià del nodo u_m-p+1
int nCP = int( cnData.vCP.size()) ;
int nU = nCP + cnData.nDeg - 1 ;
int nDeg = cnData.nDeg ;
PNTVECTOR vBC ;
vBC.resize( nDeg + 1) ;
DBLVECTOR vBW ;
vBW.resize( nDeg + 1) ;
// trovo il nodo di cui aumentare la molteplicità e ne calcolo la molteplicità
int b = nU - nDeg - 1 +1;
int i = b ;
while ( abs( cnData.vU[b] - cnData.vU[b - 1]) < EPS_ZERO)
-- b ;
int mult = min( i - b + 1, nDeg) ; // mi aspetto che sia 1, ma comunque sarà < nDeg
// recupero i punti da modificare
if ( ! cnData.bRat) {
for ( int i = 0 ; i <= nDeg - mult ; ++ i)
vBC[i] = cnData.vCP[b - nDeg + 1 + i] ;
}
else {
for ( int i = 0 ; i <= nDeg - mult ; ++ i) {
vBC[i] = cnData.vCP[b - nDeg + 1 + i] * cnData.vW[b - nDeg + 1 + i] ;
vBW[i] = cnData.vW[b - nDeg + 1 + i] ;
}
}
// salvo i punti inalterati
int r = nDeg - mult ; // numero di volte che dovrò inserire il nodo
cnData.vCP.resize( nCP + r) ;
for ( int p = nCP - 1 ; p > b - mult ; --p) {
cnData.vCP[r + p] = cnData.vCP[p] ;
}
if ( cnData.bRat ) {
cnData.vW.resize( nCP + r) ;
for ( int p = nCP - 1 ; p > b - mult ; --p) {
cnData.vW[r + p] = cnData.vW[p] ;
}
}
// procedo all'inserimento
int L = 0 ;
double alpha ;
double num, den ;
if ( mult < nDeg) {
// inserisco il nodo r volte
for ( int j = 1 ; j <= r ; ++ j) {
L = b - nDeg + j ;
for ( int i = 0; i <= r - j ; ++i) {
num = (cnData.vU[b] - cnData.vU[L + i]) ;
den = ( cnData.vU[i + b + 1] - cnData.vU[L + i]) ;
alpha = (cnData.vU[b] - cnData.vU[L + i])/ ( cnData.vU[i + b + 1] - cnData.vU[L + i]) ;
vBC[i] = alpha * vBC[i +1 ] + ( 1 - alpha) * vBC[i] ;
if ( cnData.bRat) {
vBW[i] = alpha * vBW[i + 1] + ( 1 - alpha) * vBW[i] ;
}
}
cnData.vCP[L + 1] = vBC[0] ;
cnData.vCP[b + nDeg - j - mult] = vBC[r - j] ;
if ( cnData.bRat ) {
cnData.vW[L + 1] = vBW[0] ;
cnData.vW[b + nDeg - j - mult] = vBW[r-j] ;
}
}
}
// allungo il vettore dei nodi e sposto gli ultimi nodi
cnData.vU.resize(nU + r) ;
for ( int p = nU - 1 ; p > b ; --p)
cnData.vU[p + r] = cnData.vU[p] ;
// aggiungo i nodi nuovi
for ( int p = 0 ; p < r ; ++p)
cnData.vU[b + 1 + p] = cnData.vU[b] ;
nU = nU + r ;
nCP = nCP + r ;
// aumento la molteplicità del punto u_p-1
b = nDeg -1;
i = b ;
while ( abs( cnData.vU[b] - cnData.vU[b - 1]) < EPS_ZERO)
-- b ;
mult = min( i - b + 1, nDeg) ; // mi aspetto che sia 1, ma comunque sarà < cnData.nDeg
// recupero i punti da modificare
if ( ! cnData.bRat) {
for ( int i = 0 ; i <= nDeg - mult ; ++ i)
vBC[i] = cnData.vCP[i] ;
}
else {
for ( int i = 0 ; i <= nDeg - mult ; ++ i) {
vBC[i] = cnData.vCP[i] * cnData.vW[i] ;
vBW[i] = cnData.vW[i] ;
}
}
r = nDeg - mult ;
// salvo i punti inalterati
cnData.vCP.resize( nCP + r) ;
for ( int p = nCP - 1 ; p > b - mult ; --p) {
cnData.vCP[r + p] = cnData.vCP[p] ;
}
if ( cnData.bRat ) {
cnData.vW.resize( nCP + r) ;
for ( int p = nCP - 1 ; p > b - mult ; --p) {
cnData.vW[r + p] = cnData.vW[p] ;
}
}
// procedo all'inserimento
L = 0 ;
if ( mult < nDeg) {
// inserisco il nodo r volte
for ( int j = 1 ; j <= r ; ++ j) {
L = b - nDeg + j ;
for ( int i = 0; i <= r - j ; ++i) {
alpha = (cnData.vU[b] - cnData.vU[L + i])/ ( cnData.vU[i + b + 1] - cnData.vU[L + i]) ;
vBC[i] = alpha * vBC[i + 1] + ( 1 - alpha) * vBC[i] ;
if ( cnData.bRat) {
vBW[i] = alpha * vBW[i + 1] + ( 1 - alpha) * vBW[i] ;
}
}
cnData.vCP[L + 1] = vBC[0] ;
cnData.vCP[b + nDeg - j - mult] = vBC[r - j] ;
if ( cnData.bRat ) {
cnData.vW[L + 1] = vBW[0] ;
cnData.vW[b + nDeg - j - mult] = vBW[r - j] ;
}
}
}
// allungo il vettore dei nodi e sposto gli ultimi nodi
cnData.vU.resize(nU + r) ;
for ( int p = nU - 1 ; p > b ; --p)
cnData.vU[p+r] = cnData.vU[p] ;
// aggiungo i nodi nuovi
for ( int p = 0 ; p < r ; ++p)
cnData.vU[b + 1 + p] = cnData.vU[b] ;
nU = nU + r ;
nCP = nCP + r ;
// rendo la curva chiusa e non periodica eliminando i primi e gli ultimi nDeg punti e nodi
cnData.bPeriodic = false ;
nCP = nCP - 2 * ( nDeg - 1);
nU = nU - 2 * ( nDeg - 1);
PNTVECTOR vCP_clamped ;
vCP_clamped.resize( nCP) ;
DBLVECTOR vU_clamped ;
vU_clamped.resize( nU) ;
for ( int i = 0 ; i < nCP ; ++i) {
if ( ! cnData.bRat)
vCP_clamped[i] = cnData.vCP[i + nDeg - 1] ;
else
vCP_clamped[i] = cnData.vCP[i + nDeg - 1] / cnData.vW[i + nDeg - 1] ;
}
cnData.vCP = vCP_clamped ;
for ( int i = 0 ; i < nU ; ++i) {
vU_clamped[i] = cnData.vU[i + nDeg - 1] ;
}
cnData.vU = vU_clamped ;
} }
return true ; return true ;
@@ -779,7 +616,6 @@ NurbsToBezierCurve( const CNurbsData& cnData)
int b = cnData.nDeg ; int b = cnData.nDeg ;
bool bPrevRejected = false ; bool bPrevRejected = false ;
// ciclo // ciclo
int n = 0 ; // debug
while ( b < nU - 1) { while ( b < nU - 1) {
int i = b ; int i = b ;
while ( b < nU - 1 && abs( cnData.vU[b+1] - cnData.vU[b]) < EPS_ZERO) while ( b < nU - 1 && abs( cnData.vU[b+1] - cnData.vU[b]) < EPS_ZERO)
@@ -847,8 +683,7 @@ NurbsToBezierCurve( const CNurbsData& cnData)
pCrvBez.Reset() ; pCrvBez.Reset() ;
bPrevRejected = true ; bPrevRejected = true ;
} }
// debug
++n ;
// inizializzazioni per la prossima curva di Bezier // inizializzazioni per la prossima curva di Bezier
if ( b < nU - 1) { if ( b < nU - 1) {
if ( ! cnData.bRat) { if ( ! cnData.bRat) {
@@ -872,30 +707,6 @@ NurbsToBezierCurve( const CNurbsData& cnData)
} }
} }
// se la curva ha grado 1, manca da aggiungere l'ultimo tratto
if ( cnData.nDeg == 1 ) {
// costruisco la curva di Bezier e la inserisco nella curva composita
PtrOwner<ICurveBezier> pCrvBez( CreateCurveBezier()) ;
if ( ! pCrvBez->Init( cnData.nDeg, cnData.bRat))
return nullptr ;
if ( ! cnData.bRat) {
for ( int i = 0 ; i <= cnData.nDeg ; ++ i) {
if ( ! pCrvBez->SetControlPoint( i, vBC[i]))
return nullptr ;
}
}
else {
for ( int i = 0 ; i <= cnData.nDeg ; ++ i) {
if ( ! pCrvBez->SetControlPoint( i, vBC[i] / vBW[i], vBW[i]))
return nullptr ;
}
}
if ( ! pCrvBez->IsAPoint()) {
if ( ! pCrvCompo->AddCurve( Release( pCrvBez)))
return nullptr ;
}
}
// restituisco la curva composita // restituisco la curva composita
return Release( pCrvCompo) ; return Release( pCrvCompo) ;
} }
@@ -918,7 +729,7 @@ FlattenCurve( const ICurve& crCrv, double dToler, double dAngToler, int nFlag)
return nullptr ; return nullptr ;
// Verifico se curva già piatta // Verifico se curva già piatta
PolyLine PL ; PolyLine PL ;
if ( ! crCrv.ApproxWithLines( LIN_TOL_FINE, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL_INT, PL)) if ( ! crCrv.ApproxWithLines( LIN_TOL_FINE, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL))
return nullptr ; return nullptr ;
bool bFlat = true ; bool bFlat = true ;
Plane3d plFlat ; plFlat.Set( ptCen, plMid.GetVersN()) ; Plane3d plFlat ; plFlat.Set( ptCen, plMid.GetVersN()) ;
@@ -979,7 +790,7 @@ ProjectCurveOnPlane( const ICurve& crCrv, const Plane3d& plPlane)
{ {
// determino se curva piana e suo eventuale piano // determino se curva piana e suo eventuale piano
Plane3d plCrv ; Plane3d plCrv ;
if ( crCrv.IsFlat( plCrv, false, EPS_SMALL / 2)) { if ( crCrv.IsFlat( plCrv)) {
// se il piano della curva è parallelo a quello di proiezione // se il piano della curva è parallelo a quello di proiezione
if ( AreSameOrOppositeVectorExact( plCrv.GetVersN(), plPlane.GetVersN())) { if ( AreSameOrOppositeVectorExact( plCrv.GetVersN(), plPlane.GetVersN())) {
// copio la curva // copio la curva
+1 -1
View File
@@ -13,7 +13,7 @@
#pragma once #pragma once
#include "/EgtDev/Include/EGkCurveAux.h" #include "/EgtDev/Include/EgkCurveAux.h"
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool IsClosed( const ICurve& crvC) ; bool IsClosed( const ICurve& crvC) ;
+9 -35
View File
@@ -266,7 +266,7 @@ CurveBezier::Clone( void) const
bool bool
CurveBezier::CopyFrom( const IGeoObj* pGObjSrc) CurveBezier::CopyFrom( const IGeoObj* pGObjSrc)
{ {
const CurveBezier* pCB = GetBasicCurveBezier( pGObjSrc) ; const CurveBezier* pCB = dynamic_cast<const CurveBezier*>( pGObjSrc) ;
if ( pCB == nullptr) if ( pCB == nullptr)
return false ; return false ;
return CopyFrom( *pCB) ; return CopyFrom( *pCB) ;
@@ -424,23 +424,6 @@ CurveBezier::Load( NgeReader& ngeIn)
bool bool
CurveBezier::Validate( void) CurveBezier::Validate( void)
{ {
if ( m_nStatus == TO_VERIFY) {
for ( const auto& ptP : m_vPtCtrl) {
if ( ! ptP.IsValid()) {
m_nStatus = ERR ;
break ;
}
}
}
if ( m_nStatus == TO_VERIFY) {
for ( const auto& dWe : m_vWeCtrl) {
if ( ! isfinite( dWe)) {
m_nStatus = ERR ;
break ;
}
}
}
if ( m_nStatus == TO_VERIFY) if ( m_nStatus == TO_VERIFY)
m_nStatus = ( ( m_nDeg > 0 && m_vPtCtrl.size() > 0) ? OK : ERR) ; m_nStatus = ( ( m_nDeg > 0 && m_vPtCtrl.size() > 0) ? OK : ERR) ;
@@ -465,7 +448,7 @@ CurveBezier::GetLocalBBox( BBox3d& b3Loc, int nFlag) const
else { else {
// costruisco una approssimazione lineare // costruisco una approssimazione lineare
PolyLine PL ; PolyLine PL ;
if ( ! ApproxWithLines( LIN_TOL_MIN, ANG_TOL_APPROX_DEG, APL_STD, PL)) if ( ! ApproxWithLines( LIN_TOL_MIN, ANG_TOL_APPROX_DEG, ICurve::APL_STD, PL))
return false ; return false ;
// ciclo sui punti della approssimazione // ciclo sui punti della approssimazione
Point3d ptTemp ; Point3d ptTemp ;
@@ -508,7 +491,7 @@ CurveBezier::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag) const
else { else {
// costruisco una approssimazione lineare // costruisco una approssimazione lineare
PolyLine PL ; PolyLine PL ;
if ( ! ApproxWithLines( LIN_TOL_MIN, ANG_TOL_APPROX_DEG, APL_STD, PL)) if ( ! ApproxWithLines( LIN_TOL_MIN, ANG_TOL_APPROX_DEG, ICurve::APL_STD, PL))
return false ; return false ;
// ciclo sui punti della approssimazione // ciclo sui punti della approssimazione
Point3d ptTemp ; Point3d ptTemp ;
@@ -635,7 +618,7 @@ CurveBezier::GetCentroid( Point3d& ptCen) const
return false ; return false ;
// approssimo la curva con una polilinea // approssimo la curva con una polilinea
PolyLine PL ; PolyLine PL ;
if ( ! ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, APL_STD, PL)) if ( ! ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_STD, PL))
return false ; return false ;
// calcolo il centro mediante PolygonPlane // calcolo il centro mediante PolygonPlane
Point3d ptP ; Point3d ptP ;
@@ -1446,7 +1429,7 @@ CurveBezier::ApproxWithArcsXY( double dLinTol, double dAngTolDeg, PolyArc& PA) c
// costruisco una approssimazione lineare // costruisco una approssimazione lineare
PolyLine PL ; PolyLine PL ;
if ( ! ApproxWithLines( dLinTol, dAngTolDeg, APL_STD, PL)) if ( ! ApproxWithLines( dLinTol, dAngTolDeg, ICurve::APL_STD, PL))
return false ; return false ;
// approssimo la curva per approssimazioni successive mediante bisezione // approssimo la curva per approssimazioni successive mediante bisezione
@@ -1495,7 +1478,7 @@ CurveBezier::BiArcOrSplit( int nLev, PolyLine& PL, double dLinTol, double dAngTo
return false ; return false ;
if ( ! pCC->FromPolyLine( PL)) if ( ! pCC->FromPolyLine( PL))
return false ; return false ;
pCrv.Set( pCC) ; pCrv.Set( Release( pCC)) ;
dMaxDist = 0 ; dMaxDist = 0 ;
} }
// se la polilinea ha un solo punto, esco // se la polilinea ha un solo punto, esco
@@ -1991,14 +1974,11 @@ CurveBezier::ToGlob( const Frame3d& frRef)
// la curva deve essere validata // la curva deve essere validata
if ( m_nStatus != OK) if ( m_nStatus != OK)
return false ; return false ;
// verifico validità del frame // verifico validità del frame
if ( frRef.GetType() == Frame3d::ERR) if ( frRef.GetType() == Frame3d::ERR)
return false ; return false ;
// se frame identità, non devo fare alcunché
if ( IsGlobFrame( frRef))
return true ;
// imposto ricalcolo della grafica // imposto ricalcolo della grafica
m_OGrMgr.Reset() ; m_OGrMgr.Reset() ;
@@ -2018,14 +1998,11 @@ CurveBezier::ToLoc( const Frame3d& frRef)
// la curva deve essere validata // la curva deve essere validata
if ( m_nStatus != OK) if ( m_nStatus != OK)
return false ; return false ;
// verifico validità del frame // verifico validità del frame
if ( frRef.GetType() == Frame3d::ERR) if ( frRef.GetType() == Frame3d::ERR)
return false ; return false ;
// se frame identità, non devo fare alcunché
if ( IsGlobFrame( frRef))
return true ;
// imposto ricalcolo della grafica // imposto ricalcolo della grafica
m_OGrMgr.Reset() ; m_OGrMgr.Reset() ;
@@ -2045,14 +2022,11 @@ CurveBezier::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
// la curva deve essere validata // la curva deve essere validata
if ( m_nStatus != OK) if ( m_nStatus != OK)
return false ; return false ;
// verifico validità dei frame // verifico validità dei frame
if ( frOri.GetType() == Frame3d::ERR || frDest.GetType() == Frame3d::ERR) if ( frOri.GetType() == Frame3d::ERR || frDest.GetType() == Frame3d::ERR)
return false ; return false ;
// se i due riferimenti coincidono, non devo fare alcunché
if ( AreSameFrame( frOri, frDest))
return true ;
// imposto ricalcolo della grafica // imposto ricalcolo della grafica
m_OGrMgr.Reset() ; m_OGrMgr.Reset() ;
+4 -8
View File
@@ -195,16 +195,12 @@ class CurveBezier : public ICurveBezier, public IGeoObjRW
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
inline CurveBezier* CreateBasicCurveBezier( void) inline CurveBezier* CreateBasicCurveBezier( void)
{ return ( static_cast<CurveBezier*>( CreateGeoObj( CRV_BEZIER))) ; } { return (static_cast<CurveBezier*>( CreateGeoObj( CRV_BEZIER))) ; }
inline CurveBezier* CloneBasicCurveBezier( const IGeoObj* pGObj) inline CurveBezier* CloneBasicCurveBezier( const IGeoObj* pGObj)
{ if ( pGObj == nullptr || pGObj->GetType() != CRV_BEZIER) { if ( pGObj == nullptr || pGObj->GetType() != CRV_BEZIER)
return nullptr ; return nullptr ;
return ( static_cast<CurveBezier*>( pGObj->Clone())) ; } return (static_cast<CurveBezier*>(pGObj->Clone())) ; }
inline const CurveBezier* GetBasicCurveBezier( const IGeoObj* pGObj) inline const CurveBezier* GetBasicCurveBezier( const IGeoObj* pGObj)
{ if ( pGObj == nullptr || pGObj->GetType() != CRV_BEZIER) { return (dynamic_cast<const CurveBezier*>(pGObj)) ; }
return nullptr ;
return ( static_cast<const CurveBezier*>( pGObj)) ; }
inline CurveBezier* GetBasicCurveBezier( IGeoObj* pGObj) inline CurveBezier* GetBasicCurveBezier( IGeoObj* pGObj)
{ if ( pGObj == nullptr || pGObj->GetType() != CRV_BEZIER) { return (dynamic_cast<CurveBezier*>(pGObj)) ; }
return nullptr ;
return ( static_cast<CurveBezier*>( pGObj)) ; }
+11 -69
View File
@@ -17,7 +17,6 @@
#include "CalcDerivate.h" #include "CalcDerivate.h"
#include "BiArcs.h" #include "BiArcs.h"
#include "DistPointLine.h" #include "DistPointLine.h"
#include "RemoveCurveDefects.h"
#include "/EgtDev/Include/EGkCurveByApprox.h" #include "/EgtDev/Include/EGkCurveByApprox.h"
#include "/EgtDev/Include/EGkPolyLine.h" #include "/EgtDev/Include/EGkPolyLine.h"
#include "/EgtDev/Include/EGkPolyArc.h" #include "/EgtDev/Include/EGkPolyArc.h"
@@ -57,78 +56,28 @@ ICurve*
CurveByApprox::GetCurve( int nType, double dLinTol, double dAngTolDeg, double dLinFea) CurveByApprox::GetCurve( int nType, double dLinTol, double dAngTolDeg, double dLinFea)
{ {
// se da approssimare con archi // se da approssimare con archi
if ( nType == ARCS || nType == ARCS_CORNER) { if ( nType == ARCS_CORNER) {
// calcolo approssimazione // calcolo approssimazione
PolyArc PA ; PolyArc PA ;
if ( nType == ARCS) { if ( ! GetArcs( dLinTol, dAngTolDeg, dLinFea, PA))
if ( ! GetArcs( dLinTol, dAngTolDeg, PA)) return nullptr ;
return nullptr ;
}
else {
if ( ! GetArcsCorner( dLinTol, dAngTolDeg, dLinFea, PA))
return nullptr ;
}
// creo la composita formata da questa approssimazione // creo la composita formata da questa approssimazione
PtrOwner<CurveComposite> pCC( CreateBasicCurveComposite()) ; PtrOwner<CurveComposite> pCC( CreateBasicCurveComposite()) ;
if ( ! pCC->FromPolyArc( PA)) if ( ! pCC->FromPolyArc( PA))
return nullptr ; return nullptr ;
// elimino eventuali Small Z
pCC->RemoveSmallDefects( dLinTol, dAngTolDeg) ;
// eventuale fusione di curve compatibili // eventuale fusione di curve compatibili
pCC->MergeCurves( dLinTol, dAngTolDeg) ; pCC->MergeCurves( dLinTol, dAngTolDeg) ;
// restituisco la curva // restituisco la curva
return Release( pCC) ; return Release( pCC) ;
} }
// altrimenti con curve di Bezier cubiche // altrimenti con curve di Bezier cubiche
else if ( nType == CUBIC_BEZIERS) { // !!! NON ANCORA IMPLEMENTATA !!!
// !!! NON ANCORA IMPLEMENTATA !!!
return nullptr ;
}
// tipi non previsti
return nullptr ; return nullptr ;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool bool
CurveByApprox::GetArcs( double dLinTol, double dAngTolDeg, PolyArc& PA) CurveByApprox::GetArcs( double dLinTol, double dAngTolDeg, double dLinFea, PolyArc& PA)
{
// pulisco il poliarco
PA.Clear() ;
// calcolo una parametrizzazione
if ( ! CalcParameterization())
return false ;
// calcolo le tangenti
if ( ! CalcAkimaTangents( false))
return false ;
// approssimo come unico tratto
// creo la polilinea che unisce i punti
PolyLine PL ;
int nPnt = int( m_vPnt.size()) ;
for ( int j = 0 ; j < nPnt ; ++ j)
PL.AddUPoint( j, m_vPnt[j]) ;
// verifico se retta verticale
BBox3d b3PL ;
if ( ! PL.GetLocalBBox( b3PL))
return false ;
if ( b3PL.GetDimX() < EPS_SMALL && b3PL.GetDimY() < EPS_SMALL) {
PA.AddUPoint( 0, m_vPnt[0], 0) ;
PA.AddUPoint( nPnt - 1, m_vPnt[nPnt - 1], 0) ;
}
// altrimenti eseguo l'approssimazione con archi
else {
if ( ! BiArcOrSplit( 0, PL, dLinTol, dAngTolDeg, PA))
return false ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
CurveByApprox::GetArcsCorner( double dLinTol, double dAngTolDeg, double dLinFea, PolyArc& PA)
{ {
// pulisco il poliarco // pulisco il poliarco
PA.Clear() ; PA.Clear() ;
@@ -153,18 +102,9 @@ CurveByApprox::GetArcsCorner( double dLinTol, double dAngTolDeg, double dLinFea,
PolyLine PL ; PolyLine PL ;
for ( int j = nPrev ; j <= m_vSplits[i] ; ++ j) for ( int j = nPrev ; j <= m_vSplits[i] ; ++ j)
PL.AddUPoint( j, m_vPnt[j]) ; PL.AddUPoint( j, m_vPnt[j]) ;
// verifico se retta verticale // eseguo l'approssimazione con archi
BBox3d b3PL ; if ( ! BiArcOrSplit( 0, PL, dLinTol, dAngTolDeg, PA))
if ( ! PL.GetLocalBBox( b3PL))
return false ; return false ;
if ( b3PL.GetDimX() < EPS_SMALL && b3PL.GetDimY() < EPS_SMALL) {
PA.AddUPoint( m_vSplits[i], m_vPnt[m_vSplits[i]], 0) ;
}
// altrimenti eseguo l'approssimazione con archi
else {
if ( ! BiArcOrSplit( 0, PL, dLinTol, dAngTolDeg, PA))
return false ;
}
// salvo fine come prox inizio // salvo fine come prox inizio
nPrev = m_vSplits[i] ; nPrev = m_vSplits[i] ;
} }
@@ -513,9 +453,11 @@ CurveByApprox::BiArcOrSplit( int nLev, PolyLine& PL, double dLinTol, double dAng
return true ; return true ;
// costruisco la retta che li unisce // costruisco la retta che li unisce
PtrOwner<CurveComposite> pCC( CreateBasicCurveComposite()) ; PtrOwner<CurveComposite> pCC( CreateBasicCurveComposite()) ;
if ( IsNull( pCC) || ! pCC->FromPolyLine( PL)) if ( IsNull( pCC))
return false ; return false ;
pCrv.Set( pCC) ; if ( ! pCC->FromPolyLine( PL))
return false ;
pCrv.Set( Release( pCC)) ;
dMaxDist = 0 ; dMaxDist = 0 ;
} }
// se la polilinea ha un solo punto, esco // se la polilinea ha un solo punto, esco
+3 -3
View File
@@ -15,9 +15,9 @@
#include "stdafx.h" #include "stdafx.h"
#include "CalcDerivate.h" #include "CalcDerivate.h"
#include "/EgtDev/Include/EGkCurveByInterp.h" #include "/EgtDev/Include/EGkCurveByInterp.h"
#include "/EgtDev/Include/EGkCurveComposite.h" #include "/EgtDev/Include/EgkCurveComposite.h"
#include "/EgtDev/Include/EGkBiArcs.h" #include "/EgtDev/Include/EgkBiArcs.h"
#include "/EgtDev/Include/EGkCurveBezier.h" #include "/EgtDev/Include/EgkCurveBezier.h"
#include "/EgtDev/Include/EgtPointerOwner.h" #include "/EgtDev/Include/EgtPointerOwner.h"
+68 -373
View File
@@ -1,7 +1,7 @@
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// EgalTech 2013-2022 // EgalTech 2013-2013
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// File : CurveComposite.cpp Data : 23.01.22 Versione : 2.4a4 // File : CurveComposite.cpp Data : 23.11.13 Versione : 1.3a1
// Contenuto : Implementazione della classe CCurveComposite. // Contenuto : Implementazione della classe CCurveComposite.
// //
// //
@@ -21,17 +21,15 @@
#include "CurveBezier.h" #include "CurveBezier.h"
#include "PolygonPlane.h" #include "PolygonPlane.h"
#include "SurfFlatRegion.h" #include "SurfFlatRegion.h"
#include "RemoveCurveDefects.h"
#include "GeoConst.h" #include "GeoConst.h"
#include "GeoObjFactory.h" #include "GeoObjFactory.h"
#include "NgeWriter.h" #include "NgeWriter.h"
#include "NgeReader.h" #include "NgeReader.h"
#include "/EgtDev/Include/EGkCurveByApprox.h" #include "/EgtDev/Include/EGkCurveByApprox.h"
#include "/EgtDev/Include/EGkArcSpecial.h" #include "/EgtDev/Include/EgkArcSpecial.h"
#include "/EgtDev/Include/EGkSfrCreate.h" #include "/EgtDev/Include/EGkSfrCreate.h"
#include "/EgtDev/Include/EGkIntervals.h" #include "/EgtDev/Include/EGkIntervals.h"
#include "/EgtDev/Include/EGkStringUtils3d.h" #include "/EgtDev/Include/EGkStringUtils3d.h"
#include "/EgtDev/Include/EgtNumUtils.h"
#include "/EgtDev/Include/EgtPointerOwner.h" #include "/EgtDev/Include/EgtPointerOwner.h"
#include <algorithm> #include <algorithm>
@@ -136,9 +134,11 @@ CurveComposite::AddCurve( ICurve* pCrv, bool bEndOrStart, double dLinTol)
// altrimenti curva composita, devo aggiungere le singole curve semplici // altrimenti curva composita, devo aggiungere le singole curve semplici
else { else {
// riloco le curve dalla composita sorgente alla corrente // riloco le curve dalla composita sorgente alla corrente
PtrOwner<CurveComposite> pCrvCompo( GetBasicCurveComposite( pCrv)) ; CurveComposite* pCrvCompo = dynamic_cast<CurveComposite*>( pCrv) ;
if ( IsNull( pCrvCompo) || ! AddCurveByRelocate( *pCrvCompo, bEndOrStart, dLinTol)) if ( ! AddCurveByRelocate( *pCrvCompo, bEndOrStart, dLinTol))
return false ; return false ;
// cancello la curva composita originaria
delete pCrvCompo ;
} }
// imposto ricalcolo della grafica // imposto ricalcolo della grafica
@@ -208,15 +208,8 @@ CurveComposite::AddSimpleCurve( ICurve* pSmplCrv, bool bEndOrStart, double dLinT
if ( ! AreSamePointEpsilon( ptCrvStart, ptEnd, 0.01 * EPS_SMALL)) { if ( ! AreSamePointEpsilon( ptCrvStart, ptEnd, 0.01 * EPS_SMALL)) {
// se in tolleranza, modifico l'inizio dell'entità // se in tolleranza, modifico l'inizio dell'entità
if ( SqDist( ptCrvStart, ptEnd) < ( dLinTol * dLinTol)) { if ( SqDist( ptCrvStart, ptEnd) < ( dLinTol * dLinTol)) {
// lunghezza della curva originale
double dOldLen ; pCrv->GetLength( dOldLen) ;
// eseguo modifica
if ( ! pCrv->ModifyStart( ptEnd)) if ( ! pCrv->ModifyStart( ptEnd))
return false ; return false ;
// verifico che la lunghezza non sia variata troppo
double dNewLen ; pCrv->GetLength( dNewLen) ;
if ( abs( dNewLen - dOldLen) > 10 * dLinTol)
return false ;
} }
else else
return false ; return false ;
@@ -258,28 +251,17 @@ CurveComposite::Close( void)
// verifico curva valida // verifico curva valida
if ( m_nStatus != OK) if ( m_nStatus != OK)
return false ; return false ;
// determino la distanza tra gli estremi // se già chiusa, non faccio alcunché
if ( IsClosed())
return true ;
// aggiungo la linea di chiusura
PtrOwner<CurveLine> pLine( CreateBasicCurveLine()) ;
Point3d ptStart, ptEnd ; Point3d ptStart, ptEnd ;
if ( ! GetStartPoint( ptStart) || if ( ! GetStartPoint( ptStart) ||
! GetEndPoint( ptEnd)) ! GetEndPoint( ptEnd) ||
! pLine->Set( ptEnd, ptStart) ||
! AddSimpleCurve( Release( pLine)))
return false ; return false ;
// se distanza inferiore al limite ridotto, non faccio alcunché
if ( AreSamePointEpsilon( ptStart, ptEnd, EPS_SMALL / 10))
return true ;
// se molto vicini li modifico
if ( AreSamePointEpsilon( ptStart, ptEnd, 10 * EPS_SMALL)) {
Point3d ptMid = Media( ptStart, ptEnd) ;
if ( ! ModifyStart( ptMid) ||
! ModifyEnd( ptMid))
return false ;
}
// altrimenti aggiungo la linea di chiusura
else {
PtrOwner<CurveLine> pLine( CreateBasicCurveLine()) ;
if ( ! pLine->Set( ptEnd, ptStart) ||
! AddSimpleCurve( Release( pLine)))
return false ;
}
// imposto ricalcolo della grafica // imposto ricalcolo della grafica
m_OGrMgr.Reset() ; m_OGrMgr.Reset() ;
@@ -849,9 +831,9 @@ CurveComposite::IsFlat( Plane3d& plPlane, bool bUseExtrusion, double dToler) con
return false ; return false ;
// ciclo sulle curve semplici (aggiungo solo eventuali punti intermedi e finali) // ciclo sulle curve semplici (aggiungo solo eventuali punti intermedi e finali)
int nCount = 0 ; int nCount = 0 ;
for ( const ICurve* pCrv = GetCurve( nCount) ; for ( const ICurve* pCrv = GetFirstCurve() ;
pCrv != nullptr ; pCrv != nullptr ;
pCrv = GetCurve( ++ nCount)) { pCrv = GetNextCurve(), ++ nCount) {
switch ( pCrv->GetType()) { switch ( pCrv->GetType()) {
case CRV_LINE : case CRV_LINE :
// punto finale // punto finale
@@ -985,7 +967,7 @@ CurveComposite::GetCentroid( Point3d& ptCen) const
return false ; return false ;
// approssimo la curva con una polilinea // approssimo la curva con una polilinea
PolyLine PL ; PolyLine PL ;
if ( ! ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, APL_SPECIAL_INT, PL)) if ( ! ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL))
return false ; return false ;
// calcolo il centro mediante PolygonPlane // calcolo il centro mediante PolygonPlane
Point3d ptP ; Point3d ptP ;
@@ -1034,7 +1016,7 @@ CurveComposite::GetMidDir( Vector3d& vtDir) const
if ( ! GetLength( dLen) || ! GetParamAtLength( 0.5 * dLen, dMid)) if ( ! GetLength( dLen) || ! GetParamAtLength( 0.5 * dLen, dMid))
return false ; return false ;
// calcolo la direzione // calcolo la direzione
return ::GetTang( *this, dMid, FROM_MINUS, vtDir) ; return ::GetTang( *this, 0.5 * m_CrvSmplS.size(), FROM_MINUS, vtDir) ;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@@ -1313,7 +1295,7 @@ CurveComposite::ApproxWithLines( double dLinTol, double dAngTolDeg, int nType, P
dAngTolDeg = max( dAngTolDeg, ANG_TOL_MIN_DEG) ; dAngTolDeg = max( dAngTolDeg, ANG_TOL_MIN_DEG) ;
// se speciale, approssimo ogni singola entità e conservo le estremità interne (joint) // se speciale, approssimo ogni singola entità e conservo le estremità interne (joint)
if ( nType == APL_SPECIAL || nType == APL_SPECIAL_INT) { if ( nType == APL_SPECIAL) {
// eseguo approssimazione // eseguo approssimazione
double dStartPar = 0 ; double dStartPar = 0 ;
for ( auto& pCrv : m_CrvSmplS) { for ( auto& pCrv : m_CrvSmplS) {
@@ -1324,18 +1306,6 @@ CurveComposite::ApproxWithLines( double dLinTol, double dAngTolDeg, int nType, P
PolyLine PLSmpl ; PolyLine PLSmpl ;
if ( ! pCrv->ApproxWithLines( dLinTol, dAngTolDeg, nType, PLSmpl)) if ( ! pCrv->ApproxWithLines( dLinTol, dAngTolDeg, nType, PLSmpl))
return false ; return false ;
// se richiesto almeno un punto interno con curve non rettilinee e ci sono solo gli estremi
if ( nType == APL_SPECIAL_INT && pCrv->GetType() != CRV_LINE && PLSmpl.GetPointNbr() == 2) {
// aggiungo il punto interno
Point3d ptMid ;
if ( ! pCrv->GetMidPoint( ptMid))
return false ;
double dU ;
PLSmpl.GetLastU( dU) ;
dU /= 2 ;
PNTULIST& List = PLSmpl.GetUPointList() ;
List.insert( ++ List.begin(), { ptMid, dU}) ;
}
// ripristino estrusione e spessore della curva semplice (annullandoli) // ripristino estrusione e spessore della curva semplice (annullandoli)
pCrv->SetExtrusion( V_NULL) ; pCrv->SetExtrusion( V_NULL) ;
pCrv->SetThickness( 0) ; pCrv->SetThickness( 0) ;
@@ -1351,8 +1321,8 @@ CurveComposite::ApproxWithLines( double dLinTol, double dAngTolDeg, int nType, P
// se lineare con lato obbligato... // se lineare con lato obbligato...
if ( nType == APL_LEFT || nType == APL_LEFT_CONVEX || if ( nType == APL_LEFT || nType == APL_LEFT_CONVEX ||
nType == APL_RIGHT || nType == APL_RIGHT_CONVEX) { nType == APL_RIGHT || nType == APL_RIGHT_CONVEX) {
// prima approssimazione lineare alla tolleranza minima del programma // prima approssimazione lineare a 10 * Epsilon
if ( ! ApproxWithLines( EPS_SMALL, dAngTolDeg, APL_SPECIAL, PL)) if ( ! ApproxWithLines( 10 * EPS_SMALL, dAngTolDeg, APL_SPECIAL, PL))
return false ; return false ;
// eliminazione dei punti in tolleranza andando solo dalla parte ammessa // eliminazione dei punti in tolleranza andando solo dalla parte ammessa
Vector3d vtExtr = ( m_VtExtr.IsSmall() ? Z_AX : m_VtExtr) ; Vector3d vtExtr = ( m_VtExtr.IsSmall() ? Z_AX : m_VtExtr) ;
@@ -1385,52 +1355,30 @@ CurveComposite::ApproxWithArcs( double dLinTol, double dAngTolDeg, PolyArc& PA)
if ( m_nStatus != OK) if ( m_nStatus != OK)
return false ; return false ;
// determino riferimento naturale della curva in base all'estrusione o al piano medio se questa è nulla
Frame3d frNat ;
if ( ! m_VtExtr.IsSmall()) {
frNat.Set( ORIG, m_VtExtr) ;
}
else {
Plane3d plPlane ;
IsFlat( plPlane, false) ;
if ( plPlane.IsValid()) {
if ( plPlane.GetVersN().z < -EPS_ZERO)
plPlane.Invert() ;
frNat.Set( ORIG, plPlane.GetVersN()) ;
}
}
// eseguo approssimazione // eseguo approssimazione
double dStartPar = 0 ; double dStartPar = 0 ;
for ( const auto& pCrv : m_CrvSmplS) { for ( auto& pCrv : m_CrvSmplS) {
// ne faccio una copia
PtrOwner<ICurve> pCrvL( pCrv->Clone()) ;
if ( IsNull( pCrvL))
return false ;
// assegno estrusione e spessore della curva composita // assegno estrusione e spessore della curva composita
pCrvL->SetExtrusion( m_VtExtr) ; pCrv->SetExtrusion( m_VtExtr) ;
pCrvL->SetThickness( m_dThick) ; pCrv->SetThickness( m_dThick) ;
// la porto nel riferimento naturale
pCrvL->ToLoc( frNat) ;
// recupero approssimazione per curva semplice // recupero approssimazione per curva semplice
PolyArc PASmpl ; PolyArc PASmpl ;
if ( ! pCrvL->ApproxWithArcs( dLinTol, dAngTolDeg, PASmpl)) if ( ! pCrv->ApproxWithArcs( dLinTol, dAngTolDeg, PASmpl))
return false ; return false ;
// la accodo opportunamente a quella della curva composita // la accodo opportunamente a quella della curva composita
if ( ! PA.Join( PASmpl, dStartPar)) if ( ! PA.Join( PASmpl, dStartPar))
return false ; return false ;
// ripristino estrusione e spessore della curva semplice (annullandoli)
pCrv->SetExtrusion( V_NULL) ;
pCrv->SetThickness( 0) ;
// incremento inizio parametro per prossima curva semplice // incremento inizio parametro per prossima curva semplice
dStartPar += 1 ; dStartPar += 1 ;
} }
// riporto l'approssimazione nel riferimento della composita
PA.ToGlob( frNat) ;
// assegno estrusione della curva composita // assegno estrusione della curva composita
PA.SetExtrusion( m_VtExtr) ; PA.SetExtrusion( m_VtExtr) ;
// eliminazione dei punti in tolleranza (opportunamente diminuita) return true ;
return PA.RemoveAlignedPoints( 0.5 * dLinTol) ;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@@ -1449,37 +1397,16 @@ CurveComposite::ApproxWithArcsEx( double dLinTol, double dAngTolDeg, double dLin
double dMlStartPar = 0 ; double dMlStartPar = 0 ;
CurveByApprox crvByApprox ; CurveByApprox crvByApprox ;
// determino riferimento naturale della curva in base all'estrusione o al piano medio se questa è nulla
Frame3d frNat ;
if ( ! m_VtExtr.IsSmall()) {
frNat.Set( ORIG, m_VtExtr) ;
}
else {
Plane3d plPlane ;
IsFlat( plPlane, false) ;
if ( plPlane.IsValid()) {
if ( plPlane.GetVersN().z < -EPS_ZERO)
plPlane.Invert() ;
frNat.Set( ORIG, plPlane.GetVersN()) ;
}
}
// eseguo approssimazione // eseguo approssimazione
double dStartPar = 0 ; double dStartPar = 0 ;
for ( const auto& pCrv : m_CrvSmplS) { for ( auto& pCrv : m_CrvSmplS) {
// ne faccio una copia
PtrOwner<ICurve> pCrvL( pCrv->Clone()) ;
if ( IsNull( pCrvL))
return false ;
// assegno estrusione e spessore della curva composita // assegno estrusione e spessore della curva composita
pCrvL->SetExtrusion( m_VtExtr) ; pCrv->SetExtrusion( m_VtExtr) ;
pCrvL->SetThickness( m_dThick) ; pCrv->SetThickness( m_dThick) ;
// la porto nel riferimento naturale
pCrvL->ToLoc( frNat) ;
// se segmento di linea non feature // se segmento di linea non feature
double dLen ; double dLen ;
if ( pCrvL->GetType() == CRV_LINE && pCrvL->GetLength( dLen) && dLen < dLinFea) { if ( pCrv->GetType() == CRV_LINE && pCrv->GetLength( dLen) && dLen < dLinFea) {
CurveLine* pLine = GetBasicCurveLine( pCrvL) ; CurveLine* pLine = GetBasicCurveLine( pCrv) ;
// se inizio di approx multilinea // se inizio di approx multilinea
if ( ! bMultiLine) { if ( ! bMultiLine) {
bMultiLine = true ; bMultiLine = true ;
@@ -1490,35 +1417,13 @@ CurveComposite::ApproxWithArcsEx( double dLinTol, double dAngTolDeg, double dLin
// aggiungo il punto finale // aggiungo il punto finale
crvByApprox.AddPoint( pLine->GetEnd()) ; crvByApprox.AddPoint( pLine->GetEnd()) ;
} }
// se altrimenti arco di circonferenza o curva di Bezier non feature
else if ( ( pCrvL->GetType() == CRV_ARC || pCrvL->GetType() == CRV_BEZIER) &&
pCrvL->GetLength( dLen) && dLen < dLinFea) {
// se inizio di approx multilinea
if ( ! bMultiLine) {
bMultiLine = true ;
dMlStartPar = dStartPar ;
crvByApprox.Reset() ;
Point3d ptStart ;
if ( ! pCrvL->GetStartPoint( ptStart))
return false ;
crvByApprox.AddPoint( ptStart) ;
}
// aggiungo i punti opportunamente campionati sulla curva (compreso il finale)
PolyLine PL ;
if ( ! pCrvL->ApproxWithLines( dLinTol / 2, dAngTolDeg / 2, ICurve::APL_STD, PL))
return false ;
Point3d ptFin ;
PL.GetFirstPoint( ptFin) ;
while ( PL.GetNextPoint( ptFin))
crvByApprox.AddPoint( ptFin) ;
}
// altrimenti // altrimenti
else { else {
// se in corso approx multilinee // se in corso approx multilinee
if ( bMultiLine) { if ( bMultiLine) {
bMultiLine = false ; bMultiLine = false ;
PolyArc PASmpl ; PolyArc PASmpl ;
if ( ! crvByApprox.GetArcsCorner( dLinTol, dAngTolDeg, dLinFea, PASmpl)) if ( ! crvByApprox.GetArcs( dLinTol, dAngTolDeg, dLinFea, PASmpl))
return false ; return false ;
// la accodo opportunamente a quella della curva composita // la accodo opportunamente a quella della curva composita
if ( ! PA.Join( PASmpl, dMlStartPar)) if ( ! PA.Join( PASmpl, dMlStartPar))
@@ -1526,12 +1431,15 @@ CurveComposite::ApproxWithArcsEx( double dLinTol, double dAngTolDeg, double dLin
} }
// recupero approssimazione per curva semplice // recupero approssimazione per curva semplice
PolyArc PASmpl ; PolyArc PASmpl ;
if ( ! pCrvL->ApproxWithArcs( dLinTol, dAngTolDeg, PASmpl)) if ( ! pCrv->ApproxWithArcs( dLinTol, dAngTolDeg, PASmpl))
return false ; return false ;
// la accodo opportunamente a quella della curva composita // la accodo opportunamente a quella della curva composita
if ( ! PA.Join( PASmpl, dStartPar)) if ( ! PA.Join( PASmpl, dStartPar))
return false ; return false ;
} }
// ripristino estrusione e spessore della curva semplice (annullandoli)
pCrv->SetExtrusion( V_NULL) ;
pCrv->SetThickness( 0) ;
// incremento inizio parametro per prossima curva semplice // incremento inizio parametro per prossima curva semplice
dStartPar += 1 ; dStartPar += 1 ;
} }
@@ -1539,21 +1447,18 @@ CurveComposite::ApproxWithArcsEx( double dLinTol, double dAngTolDeg, double dLin
if ( bMultiLine) { if ( bMultiLine) {
bMultiLine = false ; bMultiLine = false ;
PolyArc PASmpl ; PolyArc PASmpl ;
if ( ! crvByApprox.GetArcsCorner( dLinTol, dAngTolDeg, dLinFea, PASmpl)) if ( ! crvByApprox.GetArcs( dLinTol, dAngTolDeg, dLinFea, PASmpl))
return false ; return false ;
// la accodo opportunamente a quella della curva composita // la accodo opportunamente a quella della curva composita
if ( ! PA.Join( PASmpl, dMlStartPar)) if ( ! PA.Join( PASmpl, dMlStartPar))
return false ; return false ;
} }
// riporto l'approssimazione nel riferimento della composita
PA.ToGlob( frNat) ;
// assegno estrusione della curva composita // assegno estrusione della curva composita
PA.SetExtrusion( m_VtExtr) ; PA.SetExtrusion( m_VtExtr) ;
// eliminazione dei punti in tolleranza (opportunamente diminuita) // eliminazione dei punti in tolleranza
return PA.RemoveAlignedPoints( 0.5 * dLinTol) ; return PA.RemoveAlignedPoints( dLinTol) ;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@@ -1566,9 +1471,6 @@ CurveComposite::CopyParamRange( double dUStart, double dUEnd) const
if ( dUStart < - EPS_PARAM || dUStart > dMaxU + EPS_PARAM || if ( dUStart < - EPS_PARAM || dUStart > dMaxU + EPS_PARAM ||
dUEnd < - EPS_PARAM || dUEnd > dMaxU + EPS_PARAM) dUEnd < - EPS_PARAM || dUEnd > dMaxU + EPS_PARAM)
return nullptr ; return nullptr ;
// se i parametri coincidono, non resta alcunchè
if ( abs( dUEnd - dUStart) < EPS_PARAM)
return nullptr ;
// se il parametro start supera quello di end // se il parametro start supera quello di end
if ( dUStart > dUEnd - EPS_PARAM) { if ( dUStart > dUEnd - EPS_PARAM) {
// se curva aperta, il trim la cancella completamente quindi non resta alcunchè // se curva aperta, il trim la cancella completamente quindi non resta alcunchè
@@ -1600,7 +1502,7 @@ CurveComposite::CopyParamRange( double dUStart, double dUEnd) const
// eseguo il trim della copia // eseguo il trim della copia
if ( ! pCopy->TrimStartEndAtParam( dUStart, dUEnd)) if ( ! pCopy->TrimStartEndAtParam( dUStart, dUEnd))
return nullptr ; return nullptr ;
return ( pCopy->m_CrvSmplS.empty() ? nullptr : ::Release( pCopy)) ; return ( ::Release( pCopy)) ;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@@ -1712,40 +1614,6 @@ CurveComposite::AddPoint( const Point3d& ptStart)
return true ; return true ;
} }
//----------------------------------------------------------------------------
bool
CurveComposite::AddLineTg( double dLen, bool bEndOrStart)
{
// verifico lo stato
if ( m_nStatus != OK)
return false ;
// costruisco la linea
PtrOwner<CurveLine> pLine( CreateBasicCurveLine()) ;
if ( IsNull( pLine))
return false ;
// se da aggiungere alla fine
if ( bEndOrStart) {
Point3d ptEnd ;
Vector3d vtEnd ;
if ( ! GetEndPoint( ptEnd) || ! GetEndDir( vtEnd))
return false ;
Point3d ptNew = ptEnd + vtEnd * dLen ;
if ( ! pLine->Set( ptEnd, ptNew))
return false ;
}
// altrimenti da aggiungere all'inizio
else {
Point3d ptStart ;
Vector3d vtStart ;
if ( ! GetStartPoint( ptStart) || ! GetStartDir( vtStart))
return false ;
Point3d ptNew = ptStart - vtStart * dLen ;
if ( ! pLine->Set( ptNew, ptStart))
return false ;
}
return AddCurve( Release( pLine), bEndOrStart) ;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool bool
CurveComposite::AddLine( const Point3d& ptNew, bool bEndOrStart) CurveComposite::AddLine( const Point3d& ptNew, bool bEndOrStart)
@@ -2110,7 +1978,7 @@ CurveComposite::ModifyCurveToArc( int nCrv, const Point3d& ptMid)
if ( nCrv < 0 || nCrv > nCrvCount - 1) if ( nCrv < 0 || nCrv > nCrvCount - 1)
return false ; return false ;
// recupero la curva corrente // recupero la curva corrente
ICurve* pCrv = m_CrvSmplS[nCrv] ; ICurve* pCrv = *(m_CrvSmplS.begin() + nCrv) ;
// recupero gli estremi // recupero gli estremi
Point3d ptStart, ptEnd ; Point3d ptStart, ptEnd ;
if ( ! pCrv->GetStartPoint( ptStart) || ! pCrv->GetEndPoint( ptEnd)) if ( ! pCrv->GetStartPoint( ptStart) || ! pCrv->GetEndPoint( ptEnd))
@@ -2143,7 +2011,7 @@ CurveComposite::ModifyCurveToLine( int nCrv)
if ( nCrv < 0 || nCrv > nCrvCount - 1) if ( nCrv < 0 || nCrv > nCrvCount - 1)
return false ; return false ;
// recupero la curva corrente // recupero la curva corrente
ICurve* pCrv = m_CrvSmplS[nCrv] ; ICurve* pCrv = *(m_CrvSmplS.begin() + nCrv) ;
// se già linea non devo fare alcunchè // se già linea non devo fare alcunchè
if ( pCrv->GetType() == CRV_LINE) if ( pCrv->GetType() == CRV_LINE)
return true ; return true ;
@@ -2170,15 +2038,7 @@ CurveComposite::ModifyCurveToLine( int nCrv)
bool bool
CurveComposite::TrimStartAtParam( double dUTrim) CurveComposite::TrimStartAtParam( double dUTrim)
{ {
// verifico validità parametro // ciclo sulle diverse curve dall'inizio
double dMaxU = double( m_CrvSmplS.size()) ;
if ( dUTrim < -EPS_PARAM || dUTrim > dMaxU - EPS_PARAM)
return false ;
// imposto ricalcolo della grafica
m_OGrMgr.Reset() ;
// ciclo sulle diverse curve dall'inizio
double dUToTrim = dUTrim ; double dUToTrim = dUTrim ;
for ( auto Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ;) { for ( auto Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ;) {
// dominio parametrico della curva semplice // dominio parametrico della curva semplice
@@ -2189,13 +2049,17 @@ CurveComposite::TrimStartAtParam( double dUTrim)
// se lunghezza ancora da tagliare non nulla // se lunghezza ancora da tagliare non nulla
if ( dUToTrim > EPS_PARAM) { if ( dUToTrim > EPS_PARAM) {
delete (*Iter) ; delete (*Iter) ;
Iter = m_CrvSmplS.erase( Iter) ; Iter ++ ;
m_CrvSmplS.pop_front() ;
} }
// se lunghezza ancora da tagliare nulla (entro la tolleranza) // se lunghezza ancora da tagliare nulla (entro la tolleranza)
else if ( dUToTrim > - EPS_PARAM || else if ( dUToTrim > - EPS_PARAM ||
! (*Iter)->TrimStartAtParam( 1 + dUToTrim)) { ! (*Iter)->TrimStartAtParam( 1 + dUToTrim)) {
delete (*Iter) ; delete (*Iter) ;
Iter = m_CrvSmplS.erase( Iter) ; Iter ++ ;
m_CrvSmplS.pop_front() ;
if ( m_CrvSmplS.empty())
return false ;
break ; break ;
} }
// altrimenti superata lunghezza ancora da tagliare (taglio già fatto al test sopra) // altrimenti superata lunghezza ancora da tagliare (taglio già fatto al test sopra)
@@ -2204,6 +2068,9 @@ CurveComposite::TrimStartAtParam( double dUTrim)
} }
} }
// imposto ricalcolo della grafica
m_OGrMgr.Reset() ;
return true ; return true ;
} }
@@ -2211,14 +2078,6 @@ CurveComposite::TrimStartAtParam( double dUTrim)
bool bool
CurveComposite::TrimEndAtParam( double dUTrim) CurveComposite::TrimEndAtParam( double dUTrim)
{ {
// verifico validità parametro
double dMaxU = double( m_CrvSmplS.size()) ;
if ( dUTrim < EPS_PARAM || dUTrim > dMaxU + EPS_PARAM)
return false ;
// imposto ricalcolo della grafica
m_OGrMgr.Reset() ;
// ciclo sulle diverse curve dalla fine // ciclo sulle diverse curve dalla fine
bool bToErase = false ; bool bToErase = false ;
double dUToTrim = dUTrim ; double dUToTrim = dUTrim ;
@@ -2260,6 +2119,9 @@ CurveComposite::TrimEndAtParam( double dUTrim)
} }
} }
// imposto ricalcolo della grafica
m_OGrMgr.Reset() ;
return true ; return true ;
} }
@@ -2482,9 +2344,6 @@ CurveComposite::ExtendEndByLen( double dLenExt)
bool bool
CurveComposite::Translate( const Vector3d& vtMove) CurveComposite::Translate( const Vector3d& vtMove)
{ {
// la curva deve essere validata
if ( m_nStatus != OK)
return false ;
// imposto ricalcolo della grafica // imposto ricalcolo della grafica
m_OGrMgr.Reset() ; m_OGrMgr.Reset() ;
@@ -2499,9 +2358,6 @@ CurveComposite::Translate( const Vector3d& vtMove)
bool bool
CurveComposite::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, double dSinAng) CurveComposite::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, double dSinAng)
{ {
// la curva deve essere validata
if ( m_nStatus != OK)
return false ;
// verifico validità dell'asse di rotazione // verifico validità dell'asse di rotazione
if ( vtAx.IsSmall()) if ( vtAx.IsSmall())
return false ; return false ;
@@ -2523,9 +2379,6 @@ CurveComposite::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAn
bool bool
CurveComposite::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double dCoeffZ) CurveComposite::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double dCoeffZ)
{ {
// la curva deve essere validata
if ( m_nStatus != OK)
return false ;
// verifico non sia nulla // verifico non sia nulla
if ( abs( dCoeffX) < EPS_ZERO && abs( dCoeffY) < EPS_ZERO && abs( dCoeffZ) < EPS_ZERO) if ( abs( dCoeffX) < EPS_ZERO && abs( dCoeffY) < EPS_ZERO && abs( dCoeffZ) < EPS_ZERO)
return false ; return false ;
@@ -2610,9 +2463,6 @@ CurveComposite::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, dou
bool bool
CurveComposite::Mirror( const Point3d& ptOn, const Vector3d& vtNorm) CurveComposite::Mirror( const Point3d& ptOn, const Vector3d& vtNorm)
{ {
// la curva deve essere validata
if ( m_nStatus != OK)
return false ;
// verifico validità del piano di specchiatura // verifico validità del piano di specchiatura
if ( vtNorm.IsSmall()) if ( vtNorm.IsSmall())
return false ; return false ;
@@ -2634,9 +2484,6 @@ CurveComposite::Mirror( const Point3d& ptOn, const Vector3d& vtNorm)
bool bool
CurveComposite::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d& vtDir, double dCoeff) CurveComposite::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d& vtDir, double dCoeff)
{ {
// la curva deve essere validata
if ( m_nStatus != OK)
return false ;
// verifico validità dei parametri // verifico validità dei parametri
if ( vtNorm.IsSmall() || vtDir.IsSmall()) if ( vtNorm.IsSmall() || vtDir.IsSmall())
return false ; return false ;
@@ -2667,17 +2514,10 @@ CurveComposite::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector
bool bool
CurveComposite::ToGlob( const Frame3d& frRef) CurveComposite::ToGlob( const Frame3d& frRef)
{ {
// la curva deve essere validata
if ( m_nStatus != OK)
return false ;
// verifico validità del frame // verifico validità del frame
if ( frRef.GetType() == Frame3d::ERR) if ( frRef.GetType() == Frame3d::ERR)
return false ; return false ;
// se frame identità, non devo fare alcunché
if ( IsGlobFrame( frRef))
return true ;
// imposto ricalcolo della grafica // imposto ricalcolo della grafica
m_OGrMgr.Reset() ; m_OGrMgr.Reset() ;
@@ -2695,17 +2535,10 @@ CurveComposite::ToGlob( const Frame3d& frRef)
bool bool
CurveComposite::ToLoc( const Frame3d& frRef) CurveComposite::ToLoc( const Frame3d& frRef)
{ {
// la curva deve essere validata
if ( m_nStatus != OK)
return false ;
// verifico validità del frame // verifico validità del frame
if ( frRef.GetType() == Frame3d::ERR) if ( frRef.GetType() == Frame3d::ERR)
return false ; return false ;
// se frame identità, non devo fare alcunché
if ( IsGlobFrame( frRef))
return true ;
// imposto ricalcolo della grafica // imposto ricalcolo della grafica
m_OGrMgr.Reset() ; m_OGrMgr.Reset() ;
@@ -2723,9 +2556,6 @@ CurveComposite::ToLoc( const Frame3d& frRef)
bool bool
CurveComposite::LocToLoc( const Frame3d& frOri, const Frame3d& frDest) CurveComposite::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
{ {
// la curva deve essere validata
if ( m_nStatus != OK)
return false ;
// verifico validità dei frame // verifico validità dei frame
if ( frOri.GetType() == Frame3d::ERR || frDest.GetType() == Frame3d::ERR) if ( frOri.GetType() == Frame3d::ERR || frDest.GetType() == Frame3d::ERR)
return false ; return false ;
@@ -2989,39 +2819,6 @@ CurveComposite::ArcsBezierCurvesToArcsPerpExtr( double dLinTol, double dAngTolDe
return true ; return true ;
} }
//----------------------------------------------------------------------------
bool
CurveComposite::StraightArcsToLines( double dLinTol, double dAngTolDeg)
{
// controllo le tolleranze
dLinTol = max( dLinTol, EPS_SMALL) ;
dAngTolDeg = Clamp( dAngTolDeg, EPS_ANG_SMALL, ANG_RIGHT) ;
// verifico le singole curve
for ( auto Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++ Iter) {
CurveArc* pArc = GetBasicCurveArc( *Iter) ;
if ( pArc != nullptr &&
abs( pArc->GetAngCenter()) < dAngTolDeg &&
pArc->GetRadius() * ( 1 - cos( pArc->GetAngCenter() / 2 * DEGTORAD)) < dLinTol) {
// recupero gli estremi
Point3d ptStart, ptEnd ;
if ( ! pArc->GetStartPoint( ptStart) || ! pArc->GetEndPoint( ptEnd))
return false ;
// creo la linea
PtrOwner<CurveLine> pLine( CreateBasicCurveLine()) ;
if ( IsNull( pLine) || ! pLine->Set( ptStart, ptEnd))
return false ;
// elimino la curva originale e la sostituisco con la nuova
delete (*Iter) ;
(*Iter) = Release( pLine) ;
}
}
// imposto ricalcolo della grafica
m_OGrMgr.Reset() ;
return true ;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
static int static int
MergeTwoCurves( ICurve* pCrvP, ICurve* pCrvC, double& dCurrLinTol, double dCosAngTol, bool bNeedSameProp) MergeTwoCurves( ICurve* pCrvP, ICurve* pCrvC, double& dCurrLinTol, double dCosAngTol, bool bNeedSameProp)
@@ -3047,11 +2844,9 @@ MergeTwoCurves( ICurve* pCrvP, ICurve* pCrvC, double& dCurrLinTol, double dCosAn
} }
} }
// verifico compatibilità delle proprietà // verifico compatibilità delle proprietà
int nTpr0P = pCrvP->GetTempProp( 0) ; int nTprP = pCrvP->GetTempProp() ;
int nTpr0C = pCrvC->GetTempProp( 0) ; int nTprC = pCrvC->GetTempProp() ;
int nTpr1P = pCrvP->GetTempProp( 1) ; if ( bNeedSameProp && nTprP != nTprC)
int nTpr1C = pCrvC->GetTempProp( 1) ;
if ( bNeedSameProp && ( nTpr0P != nTpr0C || nTpr1P != nTpr1C))
return 0 ; return 0 ;
// coefficiente deduzione tolleranza // coefficiente deduzione tolleranza
const double COEFF_TOL = 0.7 ; const double COEFF_TOL = 0.7 ;
@@ -3073,10 +2868,8 @@ MergeTwoCurves( ICurve* pCrvP, ICurve* pCrvC, double& dCurrLinTol, double dCosAn
// diminuisco la tolleranza corrente dell'errore attuale // diminuisco la tolleranza corrente dell'errore attuale
dCurrLinTol -= COEFF_TOL * sqrt( dSqDist) ; dCurrLinTol -= COEFF_TOL * sqrt( dSqDist) ;
// se curve originali con proprietà diversa, la cancello // se curve originali con proprietà diversa, la cancello
if ( nTpr0P != nTpr0C) if ( nTprP != nTprC)
pLineC->SetTempProp( 0, 0) ; pLineC->SetTempProp( 0) ;
if ( nTpr1P != nTpr1C)
pLineC->SetTempProp( 0, 1) ;
// torno flag modifica // torno flag modifica
return -1 ; return -1 ;
} }
@@ -3126,10 +2919,8 @@ MergeTwoCurves( ICurve* pCrvP, ICurve* pCrvC, double& dCurrLinTol, double dCosAn
if ( NewArc.GetNormVersor() * pArcC->GetNormVersor() < 0) if ( NewArc.GetNormVersor() * pArcC->GetNormVersor() < 0)
NewArc.InvertN() ; NewArc.InvertN() ;
// se curve originali con la stessa proprietà, la riporto // se curve originali con la stessa proprietà, la riporto
if ( nTpr0P == nTpr0C) if ( nTprP == nTprC)
NewArc.SetTempProp( nTpr0C, 0) ; NewArc.SetTempProp( nTprC) ;
if ( nTpr1P == nTpr1C)
NewArc.SetTempProp( nTpr1C, 1) ;
// aggiorno l'arco corrente e torno flag modifica // aggiorno l'arco corrente e torno flag modifica
*pArcC = NewArc ; *pArcC = NewArc ;
return -1 ; return -1 ;
@@ -3151,10 +2942,8 @@ MergeTwoCurves( ICurve* pCrvP, ICurve* pCrvC, double& dCurrLinTol, double dCosAn
CurveArc NewArc ; CurveArc NewArc ;
if ( NewArc.Set2PVN( ptP1, ptP3, vtDir1, pArcC->GetNormVersor())) { if ( NewArc.Set2PVN( ptP1, ptP3, vtDir1, pArcC->GetNormVersor())) {
// se curve originali con la stessa proprietà, la riporto // se curve originali con la stessa proprietà, la riporto
if ( nTpr0P == nTpr0C) if ( nTprP == nTprC)
NewArc.SetTempProp( nTpr0C, 0) ; NewArc.SetTempProp( nTprC) ;
if ( nTpr1P == nTpr1C)
NewArc.SetTempProp( nTpr1C, 1) ;
// aggiorno l'arco corrente e torno flag modifica // aggiorno l'arco corrente e torno flag modifica
*pArcC = NewArc ; *pArcC = NewArc ;
return -1 ; return -1 ;
@@ -3226,13 +3015,6 @@ CurveComposite::MergeCurves( double dLinTol, double dAngTolDeg, bool bStartEnd,
return true ; return true ;
} }
//----------------------------------------------------------------------------
bool
CurveComposite::RemoveSmallDefects( double dLinTol, double dAngTolDeg, bool bAlsoSpikes)
{
return (( ! bAlsoSpikes || RemoveCurveSpikes( this, dLinTol)) && RemoveCurveSmallZs(this, dLinTol)) ;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
static bool static bool
SplitTopBottomArcs( CurveComposite& cCompo) SplitTopBottomArcs( CurveComposite& cCompo)
@@ -3464,93 +3246,6 @@ CurveComposite::IsACircle( double dLinTol, Point3d& ptCen, Vector3d& vtN, double
return CrvTemp.IsOneCircle( ptCen, vtN, dRad, bCCW) ; return CrvTemp.IsOneCircle( ptCen, vtN, dRad, bCCW) ;
} }
//----------------------------------------------------------------------------
bool
CurveComposite::IsARectangle( double dLinTol, Point3d& ptP, Vector3d& vtL1, Vector3d& vtL2) const
{
// deve essere chiusa
if ( ! IsClosed())
return false ;
// approssimo con segmenti di retta
PolyLine PL ;
if ( ! ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, APL_STD, PL))
return false ;
// deve giacere in un piano entro la tolleranza
Plane3d plPlane ;
if ( ! PL.IsFlat( plPlane, dLinTol))
return false ;
// deve essere formata da 4 segmenti
if ( PL.GetLineNbr() != 4)
return false ;
// recupero i 4 vertici
Point3d ptV1 ; PL.GetFirstPoint( ptV1) ;
Point3d ptV2 ; PL.GetNextPoint( ptV2) ;
Point3d ptV3 ; PL.GetNextPoint( ptV3) ;
Point3d ptV4 ; PL.GetNextPoint( ptV4) ;
// verifico che le diagonali si incontrino nel loro punto medio (-> è un parallelogramma)
if ( ! AreSamePointEpsilon( Media( ptV1, ptV3), Media( ptV2, ptV4), dLinTol / 2))
return false ;
// verifico che le diagonali abbiano la stessa lunghezza (-> è un rettangolo)
if ( abs( Dist( ptV1, ptV3) - Dist( ptV2, ptV4)) > dLinTol)
return false ;
// assegno i parametri del rettangolo
ptP = ptV1 ;
vtL1 = ptV2 - ptV1 ;
vtL2 = ptV4 - ptV1 ;
return true ;
}
//----------------------------------------------------------------------------
bool
CurveComposite::IsATrapezoid( double dLinTol, Point3d& ptP, Vector3d& vtB1, Vector3d& vtL1, Vector3d& vtB2) const
{
// deve essere chiusa
if ( ! IsClosed())
return false ;
// approssimo con segmenti di retta
PolyLine PL ;
if ( ! ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, APL_STD, PL))
return false ;
// deve giacere in un piano entro la tolleranza
Plane3d plPlane ;
if ( ! PL.IsFlat( plPlane, dLinTol))
return false ;
// deve essere formata da 4 segmenti
if ( PL.GetLineNbr() != 4)
return false ;
// recupero i 4 vertici
Point3d ptV1 ; PL.GetFirstPoint( ptV1) ;
Point3d ptV2 ; PL.GetNextPoint( ptV2) ;
Point3d ptV3 ; PL.GetNextPoint( ptV3) ;
Point3d ptV4 ; PL.GetNextPoint( ptV4) ;
// verifico se V4->V3 è parallelo a V1->V2
double dV3B12, dV4B12 ;
if ( ! DistPointLine( ptV3, ptV1, ptV2, false).GetDist( dV3B12) ||
! DistPointLine( ptV4, ptV1, ptV2, false).GetDist( dV4B12))
return false ;
if ( abs( dV3B12 - dV4B12) < EPS_SMALL) {
ptP = ptV1 ;
vtB1 = ptV2 - ptV1 ;
vtL1 = ptV4 - ptV1 ;
vtB2 = ptV3 - ptV4 ;
return true ;
}
// verifico se V1->V4 è parallelo a V2->V3
double dV1B23, dV4B23 ;
if ( ! DistPointLine( ptV1, ptV2, ptV3, false).GetDist( dV1B23) ||
! DistPointLine( ptV4, ptV2, ptV3, false).GetDist( dV4B23))
return false ;
if ( abs( dV1B23 - dV4B23) < EPS_SMALL) {
ptP = ptV2 ;
vtB1 = ptV3 - ptV2 ;
vtL1 = ptV1 - ptV2 ;
vtB2 = ptV4 - ptV1 ;
return true ;
}
// non è un trapezio
return false ;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool bool
CurveComposite::SetCurveTempProp( int nCrv, int nProp, int nPropNum) CurveComposite::SetCurveTempProp( int nCrv, int nProp, int nPropNum)
+7 -42
View File
@@ -1,13 +1,12 @@
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// EgalTech 2013-2022 // EgalTech 2013-2021
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// File : CurveComposite.h Data : 24.03.22 Versione : 2.4c2 // File : CurveComposite.h Data : 03.04.21 Versione : 2.3d1
// Contenuto : Dichiarazione della classe Curva composita. // Contenuto : Dichiarazione della classe Curva composita.
// //
// //
// //
// Modifiche : 16.04.13 DS Creazione modulo. // Modifiche : 16.04.13 DS Creazione modulo.
// 24.03.22 DS Aggiunto metodo AddLineTg.
// //
// //
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@@ -145,9 +144,8 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW
bool ChangeStartPoint( double dU) override ; bool ChangeStartPoint( double dU) override ;
bool AddPoint( const Point3d& ptStart) override ; bool AddPoint( const Point3d& ptStart) override ;
bool AddLine( const Point3d& ptNew, bool bEndOrStart = true) override ; bool AddLine( const Point3d& ptNew, bool bEndOrStart = true) override ;
bool AddLineTg( double dLen, bool bEndOrStart = true) override ;
bool AddArc2P( const Point3d& ptOther, const Point3d& ptNew, bool bEndOrStart = true) override ;
bool AddArcTg( const Point3d& ptNew, bool bEndOrStart = true) override ; bool AddArcTg( const Point3d& ptNew, bool bEndOrStart = true) override ;
bool AddArc2P( const Point3d& ptOther, const Point3d& ptNew, bool bEndOrStart = true) override ;
bool AddJoint( double dU) override ; bool AddJoint( double dU) override ;
bool ModifyJoint( int nU, const Point3d& ptNewJoint) override ; bool ModifyJoint( int nU, const Point3d& ptNewJoint) override ;
bool RemoveJoint( int nU) override ; bool RemoveJoint( int nU) override ;
@@ -156,15 +154,11 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW
bool ModifyCurveToLine( int nCrv) override ; bool ModifyCurveToLine( int nCrv) override ;
bool ArcsToBezierCurves( void) override ; bool ArcsToBezierCurves( void) override ;
bool ArcsBezierCurvesToArcsPerpExtr( double dLinTol, double dAngTolDeg) override ; bool ArcsBezierCurvesToArcsPerpExtr( double dLinTol, double dAngTolDeg) override ;
bool StraightArcsToLines( double dLinTol, double dAngTolDeg) override ;
bool MergeCurves( double dLinTol, double dAngTolDeg, bool bStartEnd = true, bool bNeedSameProp = false) override ; bool MergeCurves( double dLinTol, double dAngTolDeg, bool bStartEnd = true, bool bNeedSameProp = false) override ;
bool RemoveSmallDefects( double dLinTol, double dAngTolDeg, bool bAlsoSpikes = false) override ;
bool RemoveUndercutOnY( double dLinTol, double dAngTolDeg) override ; bool RemoveUndercutOnY( double dLinTol, double dAngTolDeg) override ;
bool IsAPoint( void) const override ; bool IsAPoint( void) const override ;
bool IsALine( double dLinTol, Point3d& ptStart, Point3d& ptEnd) const override ; bool IsALine( double dLinTol, Point3d& ptStart, Point3d& ptEnd) const override ;
bool IsACircle( double dLinTol, Point3d& ptCen, Vector3d& vtN, double& dRad, bool& bCCW) const override ; bool IsACircle( double dLinTol, Point3d& ptCen, Vector3d& vtN, double& dRad, bool& bCCW) const override ;
bool IsARectangle( double dLinTol, Point3d& ptP, Vector3d& vtL1, Vector3d& vtL2) const override ;
bool IsATrapezoid( double dLinTol, Point3d& ptP, Vector3d& vtB1, Vector3d& vtL1, Vector3d& vtB2) const override ;
bool SetCurveTempProp( int nCrv, int nProp, int nPropNum = 0) override ; bool SetCurveTempProp( int nCrv, int nProp, int nPropNum = 0) override ;
bool GetCurveTempProp( int nCrv, int& nProp, int nPropNum = 0) const override ; bool GetCurveTempProp( int nCrv, int& nProp, int nPropNum = 0) const override ;
@@ -215,41 +209,12 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
inline CurveComposite* CreateBasicCurveComposite( void) inline CurveComposite* CreateBasicCurveComposite( void)
{ return ( static_cast<CurveComposite*>( CreateGeoObj( CRV_COMPO))) ; } { return (static_cast<CurveComposite*>( CreateGeoObj( CRV_COMPO))) ; }
inline CurveComposite* CloneBasicCurveComposite( const IGeoObj* pGObj) inline CurveComposite* CloneBasicCurveComposite( const IGeoObj* pGObj)
{ if ( pGObj == nullptr || pGObj->GetType() != CRV_COMPO) { if ( pGObj == nullptr || pGObj->GetType() != CRV_COMPO)
return nullptr ; return nullptr ;
return ( static_cast<CurveComposite*>( pGObj->Clone())) ; } return (static_cast<CurveComposite*>(pGObj->Clone())) ; }
inline const CurveComposite* GetBasicCurveComposite( const IGeoObj* pGObj) inline const CurveComposite* GetBasicCurveComposite( const IGeoObj* pGObj)
{ if ( pGObj == nullptr || pGObj->GetType() != CRV_COMPO) { return (dynamic_cast<const CurveComposite*>(pGObj)) ; }
return nullptr ;
return ( static_cast<const CurveComposite*>( pGObj)) ; }
inline CurveComposite* GetBasicCurveComposite( IGeoObj* pGObj) inline CurveComposite* GetBasicCurveComposite( IGeoObj* pGObj)
{ if ( pGObj == nullptr || pGObj->GetType() != CRV_COMPO) { return (dynamic_cast<CurveComposite*>(pGObj)) ; }
return nullptr ;
return ( static_cast<CurveComposite*>( pGObj)) ; }
inline CurveComposite* ConvertCurveToBasicComposite( IGeoObj* pGObj)
{ if ( pGObj == nullptr || ( pGObj->GetType() & GEO_CURVE) == 0) {
delete pGObj ;
return nullptr ;
}
CurveComposite* pCrvCo = CreateBasicCurveComposite() ;
if ( pCrvCo == nullptr) {
delete pGObj ;
return nullptr ;
}
ICurve* pCrv = static_cast<ICurve*>( pGObj) ;
Vector3d vtExtr ;
if ( pCrv->GetExtrusion( vtExtr) && ! vtExtr.IsSmall())
pCrvCo->SetExtrusion( vtExtr) ;
double dThick ;
if ( pCrv->GetThickness( dThick) && abs( dThick) > EPS_SMALL)
pCrvCo->SetThickness( dThick) ;
for ( int i = 0 ; i < 2 ; ++ i) {
int nProp = pCrv->GetTempProp( i) ;
if ( nProp != 0)
pCrvCo->SetTempProp( nProp, i) ;
}
pCrvCo->AddCurve( pCrv) ;
return pCrvCo ;
}
+2 -2
View File
@@ -17,8 +17,8 @@
#include "CurveLine.h" #include "CurveLine.h"
#include "CurveArc.h" #include "CurveArc.h"
#include "GeoConst.h" #include "GeoConst.h"
#include "/EgtDev/Include/EGkCurve.h" #include "/EgtDev/Include/EgkCurve.h"
#include "/EgtDev/Include/EGkIntersCurves.h" #include "/EgtDev/Include/EgkIntersCurves.h"
#include "/EgtDev/Include/EgtPointerOwner.h" #include "/EgtDev/Include/EgtPointerOwner.h"
using namespace std ; using namespace std ;
+9 -17
View File
@@ -19,7 +19,6 @@
#include "NgeWriter.h" #include "NgeWriter.h"
#include "NgeReader.h" #include "NgeReader.h"
#include "/EgtDev/Include/EGkStringUtils3d.h" #include "/EgtDev/Include/EGkStringUtils3d.h"
#include "/EgtDev/Include/EgtNumUtils.h"
#include "/EgtDev/Include/EgtPointerOwner.h" #include "/EgtDev/Include/EgtPointerOwner.h"
#include <new> #include <new>
@@ -33,7 +32,7 @@ CurveLine::CurveLine( void)
: m_nStatus( TO_VERIFY), m_PtStart(), m_PtEnd(), m_VtExtr(), m_dThick() : m_nStatus( TO_VERIFY), m_PtStart(), m_PtEnd(), m_VtExtr(), m_dThick()
{ {
m_nTempProp[0] = 0 ; m_nTempProp[0] = 0 ;
m_nTempProp[1] = 0 ; m_nTempProp[0] = 0 ;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@@ -112,7 +111,7 @@ CurveLine::Clone( void) const
bool bool
CurveLine::CopyFrom( const IGeoObj* pGObjSrc) CurveLine::CopyFrom( const IGeoObj* pGObjSrc)
{ {
const CurveLine* pCL = GetBasicCurveLine( pGObjSrc) ; const CurveLine* pCL = dynamic_cast<const CurveLine*>( pGObjSrc) ;
if ( pCL == nullptr) if ( pCL == nullptr)
return false ; return false ;
return CopyFrom( *pCL) ; return CopyFrom( *pCL) ;
@@ -260,7 +259,7 @@ bool
CurveLine::Validate( void) CurveLine::Validate( void)
{ {
if ( m_nStatus == TO_VERIFY) if ( m_nStatus == TO_VERIFY)
m_nStatus = ( m_PtStart.IsValid() && m_PtEnd.IsValid() && ! AreSamePointApprox( m_PtStart, m_PtEnd) ? OK : ERR) ; m_nStatus = ( ! AreSamePointApprox( m_PtStart, m_PtEnd) ? OK : ERR) ;
return ( m_nStatus == OK) ; return ( m_nStatus == OK) ;
} }
@@ -357,7 +356,10 @@ CurveLine::GetPointD1D2( double dU, Side nS, Point3d& ptPos, Vector3d* pvtDer1,
return false ; return false ;
// il parametro U deve essere compreso tra 0 e 1 // il parametro U deve essere compreso tra 0 e 1
dU = Clamp( dU, 0., 1.) ; if ( dU < 0)
dU = 0 ;
else if ( dU > 1)
dU = 1 ;
// calcolo del punto // calcolo del punto
ptPos = Media( m_PtStart, m_PtEnd, dU) ; ptPos = Media( m_PtStart, m_PtEnd, dU) ;
@@ -640,7 +642,7 @@ bool
CurveLine::TrimStartAtParam( double dUTrim) CurveLine::TrimStartAtParam( double dUTrim)
{ {
// riporto i parametri nel loro range // riporto i parametri nel loro range
dUTrim = Clamp( dUTrim, 0., 1.) ; dUTrim = ( ( dUTrim < 0) ? 0 : (( dUTrim > 1) ? 1 : dUTrim)) ;
// recupero lunghezza // recupero lunghezza
double dLen ; double dLen ;
@@ -656,7 +658,7 @@ bool
CurveLine::TrimEndAtParam( double dUTrim) CurveLine::TrimEndAtParam( double dUTrim)
{ {
// riporto i parametri nel loro range // riporto i parametri nel loro range
dUTrim = Clamp( dUTrim, 0., 1.) ; dUTrim = ( ( dUTrim < 0) ? 0 : (( dUTrim > 1) ? 1 : dUTrim)) ;
// recupero lunghezza // recupero lunghezza
double dLen ; double dLen ;
@@ -785,7 +787,6 @@ CurveLine::Translate( const Vector3d& vtMove)
// la curva deve essere validata // la curva deve essere validata
if ( m_nStatus != OK) if ( m_nStatus != OK)
return false ; return false ;
// imposto ricalcolo della grafica // imposto ricalcolo della grafica
m_OGrMgr.Reset() ; m_OGrMgr.Reset() ;
@@ -918,10 +919,6 @@ CurveLine::ToGlob( const Frame3d& frRef)
if ( frRef.GetType() == Frame3d::ERR) if ( frRef.GetType() == Frame3d::ERR)
return false ; return false ;
// se frame identità, non devo fare alcunché
if ( IsGlobFrame( frRef))
return true ;
// imposto ricalcolo della grafica // imposto ricalcolo della grafica
m_OGrMgr.Reset() ; m_OGrMgr.Reset() ;
@@ -940,10 +937,6 @@ CurveLine::ToLoc( const Frame3d& frRef)
if ( frRef.GetType() == Frame3d::ERR) if ( frRef.GetType() == Frame3d::ERR)
return false ; return false ;
// se frame identità, non devo fare alcunché
if ( IsGlobFrame( frRef))
return true ;
// imposto ricalcolo della grafica // imposto ricalcolo della grafica
m_OGrMgr.Reset() ; m_OGrMgr.Reset() ;
@@ -961,7 +954,6 @@ CurveLine::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
// verifico validità dei frame // verifico validità dei frame
if ( frOri.GetType() == Frame3d::ERR || frDest.GetType() == Frame3d::ERR) if ( frOri.GetType() == Frame3d::ERR || frDest.GetType() == Frame3d::ERR)
return false ; return false ;
// se i due riferimenti coincidono, non devo fare alcunché // se i due riferimenti coincidono, non devo fare alcunché
if ( AreSameFrame( frOri, frDest)) if ( AreSameFrame( frOri, frDest))
return true ; return true ;
+4 -8
View File
@@ -170,16 +170,12 @@ class CurveLine : public ICurveLine, public IGeoObjRW
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
inline CurveLine* CreateBasicCurveLine( void) inline CurveLine* CreateBasicCurveLine( void)
{ return ( static_cast<CurveLine*>( CreateGeoObj( CRV_LINE))) ; } { return (static_cast<CurveLine*>( CreateGeoObj( CRV_LINE))) ; }
inline CurveLine* CloneBasicCurveLine( const IGeoObj* pGObj) inline CurveLine* CloneBasicCurveLine( const IGeoObj* pGObj)
{ if ( pGObj == nullptr || pGObj->GetType() != CRV_LINE) { if ( pGObj == nullptr || pGObj->GetType() != CRV_LINE)
return nullptr ; return nullptr ;
return ( static_cast<CurveLine*>( pGObj->Clone())) ; } return (static_cast<CurveLine*>(pGObj->Clone())) ; }
inline const CurveLine* GetBasicCurveLine( const IGeoObj* pGObj) inline const CurveLine* GetBasicCurveLine( const IGeoObj* pGObj)
{ if ( pGObj == nullptr || pGObj->GetType() != CRV_LINE) { return (dynamic_cast<const CurveLine*>(pGObj)) ; }
return nullptr ;
return ( static_cast<const CurveLine*>( pGObj)) ; }
inline CurveLine* GetBasicCurveLine( IGeoObj* pGObj) inline CurveLine* GetBasicCurveLine( IGeoObj* pGObj)
{ if ( pGObj == nullptr || pGObj->GetType() != CRV_LINE) { return (dynamic_cast<CurveLine*>(pGObj)) ; }
return nullptr ;
return ( static_cast<CurveLine*>( pGObj)) ; }
+96 -100
View File
@@ -1,13 +1,13 @@
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// EgalTech 2020-2022 // EgalTech 2020-2020
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// File : DistLineLine.h Data : 12.08.22 Versione : 2.4h1 // File : DistLineLine.h Data : 06.11.20 Versione : 2.2k1
// Contenuto : Implementazione della classe distanza fra elementi lineari. // Contenuto : Implementazione della classe distanza fra elementi lineari.
// //
// //
// //
// Modifiche : 06.11.20 LM Creazione modulo. // Modifiche : 06.11.20 LM Creazione modulo.
// 12.08.22 DS Correzioni e migliorie varie. //
// //
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@@ -18,26 +18,22 @@
#include "/EgtDev/Include/EGkGeoConst.h" #include "/EgtDev/Include/EGkGeoConst.h"
#include <algorithm> #include <algorithm>
using namespace std ;
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
DistLineLine::DistLineLine( const Point3d& ptSt1, const Point3d& ptEn1, DistLineLine::DistLineLine( const Point3d& ptSt1, const Point3d& ptEn1,
const Point3d& ptSt2, const Point3d& ptEn2, const Point3d& ptSt2, const Point3d& ptEn2,
bool bIsSegment1, bool bIsSegment2) bool bIsSegment1, bool bIsSegment2)
{ {
// reset oggetto
m_dSqDist = - 1 ;
m_dDist = - 1 ;
// calcolo direzione segmenti
Vector3d vtD1 = ptEn1 - ptSt1 ; Vector3d vtD1 = ptEn1 - ptSt1 ;
double dLen1 = vtD1.Len() ; double dLen1 = vtD1.Len() ;
Vector3d vtD2 = ptEn2 - ptSt2 ; Vector3d vtD2 = ptEn2 - ptSt2 ;
double dLen2 = vtD2.Len() ; double dLen2 = vtD1.Len() ;
if ( dLen1 < EPS_SMALL || dLen2 < EPS_SMALL) if ( dLen1 < EPS_SMALL || dLen2 < EPS_SMALL) {
m_dSqDist = - 1 ;
m_dDist = - 1 ;
return ; return ;
}
vtD1 /= dLen1 ; vtD1 /= dLen1 ;
vtD2 /= dLen2 ; vtD2 /= dLen2 ;
// eseguo
Calculate( ptSt1, vtD1, dLen1, ptSt2, vtD2, dLen2, bIsSegment1, bIsSegment2) ; Calculate( ptSt1, vtD1, dLen1, ptSt2, vtD2, dLen2, bIsSegment1, bIsSegment2) ;
} }
@@ -47,13 +43,11 @@ DistLineLine::DistLineLine( const Point3d& ptSt1, const Vector3d& vtD1, double d
const Point3d& ptSt2, const Vector3d& vtD2, double dLen2, const Point3d& ptSt2, const Vector3d& vtD2, double dLen2,
bool bIsSegment1, bool bIsSegment2) bool bIsSegment1, bool bIsSegment2)
{ {
// reset oggetto if ( dLen1 < EPS_SMALL || dLen2 < EPS_SMALL) {
m_dSqDist = - 1 ; m_dSqDist = - 1 ;
m_dDist = - 1 ; m_dDist = - 1 ;
// verifico segmenti
if ( dLen1 < EPS_SMALL || dLen2 < EPS_SMALL)
return ; return ;
// eseguo }
Calculate( ptSt1, vtD1, dLen1, ptSt2, vtD2, dLen2, bIsSegment1, bIsSegment2) ; Calculate( ptSt1, vtD1, dLen1, ptSt2, vtD2, dLen2, bIsSegment1, bIsSegment2) ;
} }
@@ -63,7 +57,6 @@ DistLineLine::GetSqDist( double& dSqDist)
{ {
if ( m_dSqDist < 0) if ( m_dSqDist < 0)
return false ; return false ;
dSqDist = m_dSqDist ; dSqDist = m_dSqDist ;
return true ; return true ;
} }
@@ -74,10 +67,7 @@ DistLineLine::GetDist( double& dDist)
{ {
if ( m_dSqDist < 0) if ( m_dSqDist < 0)
return false ; return false ;
dDist = sqrt( m_dSqDist) ;
if ( m_dDist < 0)
m_dDist = sqrt( m_dSqDist) ;
dDist = m_dDist ;
return true ; return true ;
} }
@@ -94,48 +84,55 @@ DistLineLine::GetMinDistPoints( Point3d& ptMinDist1, Point3d& ptMinDist2)
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool bool
DistLineLine::GetPositionsAtMinDistPoints( double& dPos1, double& dPos2) DistLineLine::GetParamsAtMinDistPoints( double& dPar1, double& dPar2)
{ {
if ( m_dSqDist < 0) if ( m_dSqDist < 0)
return false ; return false ;
dPos1 = m_dPos1 ; dPar1 = m_dPar1 ;
dPos2 = m_dPos2 ; dPar2 = m_dPar2 ;
return true ; return true ;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// Calcola la distanza fra i due elementi lineari, i punti di minima distanza e le loro posizioni. // Calcola la distanza fra i due elemnti lineari, i punti di minima distanza e
// Se i due elementi sono paralleli i punti di minimo sono scelti secondo convenienza. // i loro rispettivi parametri.
// Se la coppia di punti di minima distanza non è unica ne viene scelta una
// in base a comodità di calcolo.
void void
DistLineLine::Calculate( const Point3d& ptSt1, const Vector3d& vtD1, double dLen1, DistLineLine::Calculate( const Point3d& ptSt1, const Vector3d& vtD1, double dLen1,
const Point3d& ptSt2, const Vector3d& vtD2, double dLen2, const Point3d& ptSt2, const Vector3d& vtD2, double dLen2,
bool bIsSegment1, bool bIsSegment2) bool bIsSegment1, bool bIsSegment2)
{ {
// Se elementi paralleli o antiparalleli // Caso di elementi lineari paralleli/antiparalleli
if ( AreSameOrOppositeVectorExact( vtD1, vtD2)) { if ( AreSameOrOppositeVectorExact( vtD1, vtD2)) {
// Se il primo elemento è una retta infinita // Almeno un elemento è una retta
if ( ! bIsSegment1) { if ( ! ( bIsSegment1 && bIsSegment2)) {
Vector3d vtStSt = ptSt2 - ptSt1 ; // Il primo elemento è segmento, quindi deve essere una retta il secondo
double dLong = vtStSt * vtD1 ; if ( bIsSegment1) {
Vector3d vtDist = vtStSt - dLong * vtD1 ; Vector3d vtStSt = ptSt1 - ptSt2 ;
m_dSqDist = vtDist.SqLen() ; double dLong = vtStSt * vtD2 ;
m_dPos1 = dLong ; Vector3d vtDist = vtStSt - dLong * vtD2 ;
m_dPos2 = 0 ; m_dSqDist = vtDist.SqLen() ;
m_ptMinDist1 = ptSt1 + dLong * vtD1 ; m_dDist = sqrt( m_dSqDist) ;
m_ptMinDist2 = ptSt2 ; m_dPar1 = 0 ;
} m_dPar2 = dLong ;
// se altrimenti il secondo elemento è una retta infinita m_ptMinDist1 = ptSt1 ;
else if ( ! bIsSegment2) { m_ptMinDist2 = ptSt2 + dLong * vtD2 ;
Vector3d vtStSt = ptSt1 - ptSt2 ; }
double dLong = vtStSt * vtD2 ; // Il primo elemento è una retta
Vector3d vtDist = vtStSt - dLong * vtD2 ; else {
m_dSqDist = vtDist.SqLen() ; Vector3d vtStSt = ptSt2 - ptSt1 ;
m_dPos1 = 0 ; double dLong = vtStSt * vtD1 ;
m_dPos2 = dLong ; Vector3d vtDist = vtStSt - dLong * vtD1 ;
m_ptMinDist1 = ptSt1 ; m_dSqDist = vtDist.SqLen() ;
m_ptMinDist2 = ptSt2 + dLong * vtD2 ; m_dDist = sqrt( m_dSqDist) ;
m_dPar1 = dLong ;
m_dPar2 = 0 ;
m_ptMinDist1 = ptSt1 + dLong * vtD1 ;
m_ptMinDist2 = ptSt2 ;
}
} }
// altrimenti entrambi gli elementi sono segmenti // Entrambi gli elementi sono segmenti
else { else {
Point3d ptEn1 = ptSt1 + dLen1 * vtD1 ; Point3d ptEn1 = ptSt1 + dLen1 * vtD1 ;
Point3d ptEn2 = ptSt2 + dLen2 * vtD2 ; Point3d ptEn2 = ptSt2 + dLen2 * vtD2 ;
@@ -143,7 +140,7 @@ DistLineLine::Calculate( const Point3d& ptSt1, const Vector3d& vtD1, double dLen
Vector3d vtStEn = ptEn2 - ptSt1 ; Vector3d vtStEn = ptEn2 - ptSt1 ;
double dStU = vtStSt * vtD1 ; double dStU = vtStSt * vtD1 ;
double dEnU = vtStEn * vtD1 ; double dEnU = vtStEn * vtD1 ;
// Classifico i punti del secondo segmento in base alla loro // Classifico i punti del segmento segmento in base alla loro
// coordinata rispetto all'ordinamento generato dal primo. // coordinata rispetto all'ordinamento generato dal primo.
double dMinPar, dMaxPar ; double dMinPar, dMaxPar ;
Point3d ptMinPar, ptMaxPar ; Point3d ptMinPar, ptMaxPar ;
@@ -162,71 +159,70 @@ DistLineLine::Calculate( const Point3d& ptSt1, const Vector3d& vtD1, double dLen
// Possibili posizioni reciproche dei segmenti // Possibili posizioni reciproche dei segmenti
if ( dMinPar > dLen1) { if ( dMinPar > dLen1) {
m_dSqDist = SqDist( ptEn1, ptMinPar) ; m_dSqDist = SqDist( ptEn1, ptMinPar) ;
m_dDist = sqrt( m_dSqDist) ;
m_ptMinDist1 = ptEn1 ; m_ptMinDist1 = ptEn1 ;
m_ptMinDist2 = ptMinPar ; m_ptMinDist2 = ptMinPar ;
m_dPos1 = dLen1 ; m_dPar1 = dLen1 ;
m_dPos2 = Clamp( ( m_ptMinDist2 - ptSt2) * vtD2, 0., dLen2) ; m_dPar2 = Clamp( ( m_ptMinDist2 - ptSt2) * vtD2, 0., dLen2) ;
} }
else if ( dMinPar > 0) { else if ( dMinPar > 0) {
m_dSqDist = max( vtStSt * vtStSt - dStU * dStU, 0.) ; m_dSqDist = std::max( vtStSt * vtStSt - dStU * dStU, 0.) ;
m_dDist = sqrt( m_dSqDist) ;
m_ptMinDist1 = ptSt1 + dMinPar * vtD1 ; m_ptMinDist1 = ptSt1 + dMinPar * vtD1 ;
m_ptMinDist2 = ptMinPar ; m_ptMinDist2 = ptMinPar ;
m_dPos1 = dMinPar ; m_dPar1 = dMinPar ;
m_dPos2 = Clamp( ( m_ptMinDist2 - ptSt2) * vtD2, 0., dLen2) ; m_dPar2 = Clamp( ( m_ptMinDist2 - ptSt2) * vtD2, 0., dLen2) ;
} }
else if ( dMaxPar > 0) { else if ( dMaxPar > 0) {
m_dSqDist = max( vtStSt * vtStSt - dStU * dStU, 0.) ; m_dSqDist = std::max( vtStSt * vtStSt - dStU * dStU, 0.) ;
m_dDist = sqrt( m_dSqDist) ;
m_ptMinDist1 = ptSt1 ; m_ptMinDist1 = ptSt1 ;
m_ptMinDist2 = ptSt2 + ( ptSt1 - ptSt2) * vtD2 * vtD2 ; m_ptMinDist2 = ptSt2 + ( ptSt1 - ptSt2) * vtD2 * vtD2 ;
m_dPos1 = 0 ; m_dPar1 = 0 ;
m_dPos2 = Clamp( ( m_ptMinDist2 - ptSt2) * vtD2, 0., dLen2) ; m_dPar2 = Clamp( ( m_ptMinDist2 - ptSt2) * vtD2, 0., dLen2) ;
} }
else { else {
m_dSqDist = SqDist( ptSt1, ptMaxPar) ; m_dSqDist = SqDist( ptSt1, ptMaxPar) ;
m_dDist = sqrt( m_dSqDist) ;
m_ptMinDist1 = ptSt1 ; m_ptMinDist1 = ptSt1 ;
m_ptMinDist2 = ptMaxPar ; m_ptMinDist2 = ptMaxPar ;
m_dPos1 = 0 ; m_dPar1 = 0 ;
m_dPos2 = Clamp( ( m_ptMinDist2 - ptSt2) * vtD2, 0., dLen2) ; m_dPar2 = Clamp( ( m_ptMinDist2 - ptSt2) * vtD2, 0., dLen2) ;
} }
} }
return ;
} }
// Caso generale // Caso generale
else { Vector3d vtDist0 = ptSt2 - ptSt1 ;
// Posizioni a distanza minima tra rette illimitate double dDist01 = vtDist0 * vtD1 ;
Vector3d vtStSt = ptSt2 - ptSt1 ; double dDist02 = vtDist0 * vtD2 ;
double dDist01 = vtStSt * vtD1 ; double dDotD1D2 = vtD1 * vtD2 ;
double dDist02 = vtStSt * vtD2 ; double dT1 = dDist01 + ( ( dDist01 * dDotD1D2 - dDist02) * dDotD1D2) / ( 1 - dDotD1D2 * dDotD1D2) ;
double dDotD1D2 = vtD1 * vtD2 ; double dT2 = ( dDist01 * dDotD1D2 - dDist02) / ( 1 - dDotD1D2 * dDotD1D2) ;
double dT1 = ( dDist01 - dDotD1D2 * dDist02) / ( 1 - dDotD1D2 * dDotD1D2) ; double dMin1 = - INFINITO ;
double dT2 = ( dDotD1D2 * dDist01 - dDist02) / ( 1 - dDotD1D2 * dDotD1D2) ; double dMax1 = INFINITO ;
// Posizioni minime e massime sui segmenti double dMin2 = - INFINITO ;
double dMin1 = ( bIsSegment1 ? 0 : -INFINITO) ; double dMax2 = INFINITO ;
double dMax1 = ( bIsSegment1 ? dLen1 : INFINITO) ; double dSt1On2 = ( ptSt1 - ptSt2) * vtD2 ;
double dMin2 = ( bIsSegment2 ? 0 : -INFINITO) ; double dEn1On2 = ( ptSt1 + dLen1 * vtD1 - ptSt2) * vtD2 ;
double dMax2 = ( bIsSegment2 ? dLen2 : INFINITO) ; if ( bIsSegment1) {
// Se entrambe le posizioni stanno nei segmenti dMin1 = 0 ;
if ( dT1 >= dMin1 && dT1 <= dMax1 && dT2 >= dMin2 && dT2 <= dMax2) { dMax1 = dLen1 ;
m_dPos1 = dT1 ; dMin2 = std::min( dSt1On2, dEn1On2) ;
m_dPos2 = dT2 ; dMax2 = std::max( dSt1On2, dEn1On2) ;
}
// se altrimenti solo la prima sta nel segmento
else if ( dT1 >= dMin1 && dT1 <= dMax1) {
m_dPos2 = Clamp( dT2, dMin2, dMax2) ;
m_dPos1 = Clamp( (( ptSt2 + m_dPos2 * vtD2) - ptSt1) * vtD1, dMin1, dMax1) ;
}
// se altrimenti solo la seconda sta nel segmento
else if ( dT2 >= dMin2 && dT2 <= dMax2) {
m_dPos1 = Clamp( dT1, dMin1, dMax1) ;
m_dPos2 = Clamp( (( ptSt1 + m_dPos1 * vtD1) - ptSt2) * vtD2, dMin2, dMax2) ;
}
// altrimenti nessuna sta nel suo segmento
else {
m_dPos1 = Clamp( dT1, dMin1, dMax1) ;
m_dPos2 = Clamp( (( ptSt1 + m_dPos1 * vtD1) - ptSt2) * vtD2, dMin2, dMax2) ;
m_dPos1 = Clamp( (( ptSt2 + m_dPos2 * vtD2) - ptSt1) * vtD1, dMin1, dMax1) ;
}
m_ptMinDist1 = ptSt1 + m_dPos1 * vtD1 ;
m_ptMinDist2 = ptSt2 + m_dPos2 * vtD2 ;
m_dSqDist = SqDist( m_ptMinDist1, m_ptMinDist2) ;
} }
} if ( bIsSegment2) {
double dSt2On1 = ( ptSt2 - ptSt1) * vtD1 ;
double dEn2On1 = ( ptSt2 + dLen2 * vtD2 - ptSt1) * vtD1 ;
dMin1 = std::max( dMin1, std::min( dSt2On1, dEn2On1)) ;
dMax1 = std::min( dMax1, std::max( dSt2On1, dEn2On1)) ;
dMin2 = std::max( dMin2, 0.) ;
dMax2 = std::min( dMax2, dLen2) ;
}
m_dPar1 = Clamp( dT1, dMin1, dMax1) ;
m_dPar2 = Clamp( dT2, dMin2, dMax2) ;
m_ptMinDist1 = ptSt1 + m_dPar1 * vtD1 ;
m_ptMinDist2 = ptSt2 + m_dPar2 * vtD2 ;
m_dSqDist = SqDist( m_ptMinDist1, m_ptMinDist2) ;
m_dDist = sqrt( m_dSqDist) ;
}
+4 -4
View File
@@ -37,17 +37,17 @@ class DistLineLine
bool IsSmall( void) { return IsEpsilon( EPS_SMALL) ; } bool IsSmall( void) { return IsEpsilon( EPS_SMALL) ; }
bool IsZero( void) { return IsEpsilon( EPS_ZERO) ; } bool IsZero( void) { return IsEpsilon( EPS_ZERO) ; }
bool GetMinDistPoints( Point3d& ptMinDist1, Point3d& ptMinDist2) ; bool GetMinDistPoints( Point3d& ptMinDist1, Point3d& ptMinDist2) ;
bool GetPositionsAtMinDistPoints( double& dPos1, double& dPos2) ; bool GetParamsAtMinDistPoints( double& dPar1, double& dPar2) ;
private : private :
void Calculate( const Point3d& ptSt1, const Vector3d& vtD1, double dLen1, void Calculate( const Point3d& ptSt1, const Vector3d& vtD1, double dLen1,
const Point3d& ptSt2, const Vector3d& vtD2, double dLen2, const Point3d& ptSt2, const Vector3d& vtD2, double dLen2,
bool bIsSegment1, bool bIsSegment2) ; bool bIsSegment1 = true, bool bIsSegment2 = true) ;
private: private:
double m_dSqDist ; double m_dSqDist ;
double m_dDist ; double m_dDist ;
double m_dPos1 ; double m_dPar1 ;
double m_dPos2 ; double m_dPar2 ;
Point3d m_ptMinDist1 ; Point3d m_ptMinDist1 ;
Point3d m_ptMinDist2 ; Point3d m_ptMinDist2 ;
} ; } ;
+2 -12
View File
@@ -89,18 +89,8 @@ DistPointCrvComposite::DistPointCrvComposite( const Point3d& ptP, const ICurveCo
} }
} }
// altrimenti aggiungo // altrimenti aggiungo
else { else
if ( dCurrDist < m_dDist) { m_Info.push_back( aInfo) ;
// aggiorno i minimi
m_dDist = dCurrDist ;
// inserisco in testa
m_Info.insert( m_Info.begin(), aInfo) ;
}
else {
// inserisco in coda
m_Info.push_back( aInfo) ;
}
}
// passo al successivo // passo al successivo
++ i ; ++ i ;
} }
+21 -105
View File
@@ -12,7 +12,6 @@
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
#include "stdafx.h" #include "stdafx.h"
#include "SurfTriMesh.h"
#include "/EgtDev/Include/EGkDistPointTria.h" #include "/EgtDev/Include/EGkDistPointTria.h"
#include "/EgtDev/Include/EGkDistPointSurfTm.h" #include "/EgtDev/Include/EGkDistPointSurfTm.h"
@@ -25,7 +24,7 @@ using namespace std ;
// I casi in cui non vengono trovati box di misura positiva sono quelli in cui o il box A è contenuto // I casi in cui non vengono trovati box di misura positiva sono quelli in cui o il box A è contenuto
// nel box B; uno di questi si verifica se il box A è vuoto. // nel box B; uno di questi si verifica se il box A è vuoto.
// Nel vettore vBoxDiff vengono restituiti i box la cui unione costituisce la differenza fra A e B. // Nel vettore vBoxDiff vengono restituiti i box la cui unione costituisce la differenza fra A e B.
static bool bool
BoundingBoxDifference( const BBox3d& boxA, const BBox3d& boxB, BOXVECTOR& vBoxDiff) BoundingBoxDifference( const BBox3d& boxA, const BBox3d& boxB, BOXVECTOR& vBoxDiff)
{ {
// Svuoto il risultato // Svuoto il risultato
@@ -94,33 +93,30 @@ DistPointSurfTm::Calculate( const Point3d& ptP, const ISurfTriMesh& tmSurf)
// Inizializzo distanza non calcolata // Inizializzo distanza non calcolata
m_dDist = - 1. ; m_dDist = - 1. ;
// Lavoro con l'oggetto superficie trimesh di base
const SurfTriMesh* pStm = GetBasicSurfTriMesh( &tmSurf) ;
if ( pStm == nullptr)
return ;
// Recupero e verifico il box locale della superficie // Recupero e verifico il box locale della superficie
BBox3d b3Stm = pStm->GetAllTriaBox() ; BBox3d b3Stm = tmSurf.GetAllTriaBox() ;
if ( b3Stm.IsEmpty()) if ( b3Stm.IsEmpty())
return ; return ;
// Cerco triangoli in box centrati sul punto dato di ampiezza crescente ed escludendo le parti già verificate. // Determino i triangoli vicini e fra di essi cerco quello di minima distanza.
// Termino quando non trovo più triangoli che possano soddisfare la richiesta. // Considero un box centrato nel punto P; finché all'interno del box non trovo un set di triangoli
// fra cui quello a distanza minima dal punto P ha distanza minore del minimo semi-lato del box,
// continuo a ingrandire il box. La condizione di terminazione garantisce di trovare il tiangolo di
// distanza minima della trimesh intera.
Point3d ptMin, ptMax ; b3Stm.GetMinMax( ptMin, ptMax) ; Point3d ptMin, ptMax ; b3Stm.GetMinMax( ptMin, ptMax) ;
double dDeltaLen = max( min( min( b3Stm.GetDimX(), b3Stm.GetDimY()), b3Stm.GetDimZ()) / 40., 20.) ; double dDeltaLen = max( min( min( ptMax.x - ptMin.x, ptMax.y - ptMin.y), ptMax.z - ptMin.z) / 40., 10.) ;
double dBoxHalfLenX = max( max( ptMin.x - ptP.x, ptP.x - ptMax.x), 0.) + dDeltaLen ; double dBoxHalfLenX = max( max( ptMin.x - ptP.x, ptP.x - ptMax.x), 0.) + dDeltaLen ;
double dBoxHalfLenY = max( max( ptMin.y - ptP.y, ptP.y - ptMax.y), 0.) + dDeltaLen ; double dBoxHalfLenY = max( max( ptMin.y - ptP.y, ptP.y - ptMax.y), 0.) + dDeltaLen ;
double dBoxHalfLenZ = max( max( ptMin.z - ptP.z, ptP.z - ptMax.z), 0.) + dDeltaLen ; double dBoxHalfLenZ = max( max( ptMin.z - ptP.z, ptP.z - ptMax.z), 0.) + dDeltaLen ;
// Considero anche il box precedente per poter analizzare solo il volume differenza tra i due // Considero anche il box precedente per poter analizzare solo lo spazio differenza tra i due
BBox3d boxPPrev( ptP) ; BBox3d boxPPrev( ptP) ;
BBox3d boxP( ptP, dBoxHalfLenX, dBoxHalfLenY, dBoxHalfLenZ) ; BBox3d boxP( ptP, dBoxHalfLenX, dBoxHalfLenY, dBoxHalfLenZ) ;
// Variabili distanza minima, indice del triangolo di distanza minima, punto di distanza minima // Variabili distanza minima, indice del triangolo di distanza minima, punto di distanza minima
double dMinSqDist = DBL_MAX ; double dMinSqDist = DBL_MAX ;
int nMinDistTriaIndex = SVT_NULL ; int nMinDistTriaIndex = SVT_NULL ;
Point3d ptMinDistPoint ; Point3d ptMinDistPoint ;
// Finché non si verifica la condizione di terminazione ingrandisco il box.
pStm->ResetTempInts() ;
bool bContinue = true ; bool bContinue = true ;
// Finché non si verifica la condizione di terminazione ingrandisco il box.
while ( bContinue) { while ( bContinue) {
// Calcolo il box differenza con il precedente per non esplorare parti già considerate // Calcolo il box differenza con il precedente per non esplorare parti già considerate
BOXVECTOR vBox ; BOXVECTOR vBox ;
@@ -135,21 +131,18 @@ DistPointSurfTm::Calculate( const Point3d& ptP, const ISurfTriMesh& tmSurf)
// ricerca sui triangoli nel box // ricerca sui triangoli nel box
bCollide = true ; bCollide = true ;
INTVECTOR vnIds ; INTVECTOR vnIds ;
if ( pStm->GetAllTriaOverlapBox( b3Int, vnIds)) { if ( tmSurf.GetAllTriaOverlapBox( b3Int, vnIds)) {
// Ciclo sui triangoli del sotto-box corrente // Ciclo sui triangoli del sotto-box corrente
for ( auto nT : vnIds) { for ( auto nT : vnIds) {
int nTriaTemp ;
Triangle3d trCurTria ; Triangle3d trCurTria ;
if ( pStm->GetTempInt( nT, nTriaTemp) && nTriaTemp == 0 && pStm->GetTriangle( nT, trCurTria)) { tmSurf.GetTriangle( nT, trCurTria) ;
pStm->SetTempInt( nT, 1) ; DistPointTriangle distPT( ptP, trCurTria) ;
DistPointTriangle distPT( ptP, trCurTria) ; double dCurSqDist ;
double dCurSqDist ; // Se la distanza del triangolo è valida e minore di quella attuale aggiorno
// Se la distanza del triangolo è valida e minore di quella attuale aggiorno if ( distPT.GetSqDist( dCurSqDist) && dCurSqDist < dMinSqDist) {
if ( distPT.GetSqDist( dCurSqDist) && dCurSqDist < dMinSqDist) { dMinSqDist = dCurSqDist ;
dMinSqDist = dCurSqDist ; nMinDistTriaIndex = nT ;
nMinDistTriaIndex = nT ; distPT.GetMinDistPoint( ptMinDistPoint) ;
distPT.GetMinDistPoint( ptMinDistPoint) ;
}
} }
} }
} }
@@ -168,9 +161,9 @@ DistPointSurfTm::Calculate( const Point3d& ptP, const ISurfTriMesh& tmSurf)
m_nMinDistTriaIndex = nMinDistTriaIndex ; m_nMinDistTriaIndex = nMinDistTriaIndex ;
m_ptMinDistPoint = ptMinDistPoint ; m_ptMinDistPoint = ptMinDistPoint ;
Triangle3d trMinDistTria ; Triangle3d trMinDistTria ;
pStm->GetTriangle( m_nMinDistTriaIndex, trMinDistTria) ; tmSurf.GetTriangle( m_nMinDistTriaIndex, trMinDistTria) ;
trMinDistTria.Validate() ; trMinDistTria.Validate() ;
m_bIsInside = ( ( ptP - m_ptMinDistPoint) * trMinDistTria.GetN() < - EPS_SMALL) && pStm->IsClosed() ; m_bIsInside = ( ( ptP - m_ptMinDistPoint) * trMinDistTria.GetN() < - EPS_SMALL) && tmSurf.IsClosed() ;
} }
} }
@@ -209,80 +202,3 @@ DistPointSurfTm::GetMinDistTriaIndex( int& nMinDistIndex)
nMinDistIndex = m_nMinDistTriaIndex ; nMinDistIndex = m_nMinDistTriaIndex ;
return true ; return true ;
} }
//----------------------------------------------------------------------------
int
GetSurfTmNearestVertex( const Point3d& ptP, const ISurfTriMesh& tmSurf)
{
// Lavoro con l'oggetto superficie trimesh di base
const SurfTriMesh* pStm = GetBasicSurfTriMesh( &tmSurf) ;
if ( pStm == nullptr)
return SVT_NULL ;
// Recupero e verifico il box locale della superficie
BBox3d b3Stm = pStm->GetAllTriaBox() ;
if ( b3Stm.IsEmpty())
return SVT_NULL ;
// Cerco triangoli in box centrati sul punto dato di ampiezza crescente ed escludendo le parti già verificate.
// Termino quando non trovo più triangoli che possano soddisfare la richiesta.
Point3d ptMin, ptMax ; b3Stm.GetMinMax( ptMin, ptMax) ;
double dDeltaLen = max( min( min( b3Stm.GetDimX(), b3Stm.GetDimY()), b3Stm.GetDimZ()) / 40., 20.) ;
double dBoxHalfLenX = max( max( ptMin.x - ptP.x, ptP.x - ptMax.x), 0.) + dDeltaLen ;
double dBoxHalfLenY = max( max( ptMin.y - ptP.y, ptP.y - ptMax.y), 0.) + dDeltaLen ;
double dBoxHalfLenZ = max( max( ptMin.z - ptP.z, ptP.z - ptMax.z), 0.) + dDeltaLen ;
// Considero anche il box precedente per poter analizzare solo il volume differenza tra i due
BBox3d boxPPrev( ptP) ;
BBox3d boxP( ptP, dBoxHalfLenX, dBoxHalfLenY, dBoxHalfLenZ) ;
// Variabili distanza minima
int nVert = SVT_NULL ;
double dMinSqDist = DBL_MAX ;
// Finché non si verifica la condizione di terminazione ingrandisco il box.
pStm->ResetTempInts() ;
bool bContinue = true ;
while ( bContinue) {
// Calcolo il box differenza con il precedente per non esplorare parti già considerate
BOXVECTOR vBox ;
BoundingBoxDifference( boxP, boxPPrev, vBox) ;
// Ciclo sui box differenza
bool bCollide = false ;
for ( const auto& b3Box : vBox) {
// interseco il box con quello della superficie e ne verifico la distanza minima dal punto
BBox3d b3Int ;
if ( ! b3Box.FindIntersection( b3Stm, b3Int) || b3Int.SqDistFromPoint( ptP) > dMinSqDist)
continue ;
// ricerca sui triangoli nel box
bCollide = true ;
INTVECTOR vnIds ;
if ( pStm->GetAllTriaOverlapBox( b3Int, vnIds)) {
// Ciclo sui triangoli del sotto-box corrente
for ( auto nT : vnIds) {
int nTriaTemp ;
int nIdVert[3] ;
if ( pStm->GetTempInt( nT, nTriaTemp) && nTriaTemp == 0 && pStm->GetTriangle( nT, nIdVert)) {
pStm->SetTempInt( nT, 1) ;
for ( int i = 0 ; i < 3 ; ++ i) {
Point3d ptVert ;
if ( ! pStm->GetVertex( nIdVert[i], ptVert))
continue ;
double dCurrSqDist = SqDist( ptP, ptVert) ;
if ( dCurrSqDist < dMinSqDist) {
dMinSqDist = dCurrSqDist ;
nVert = nIdVert[i] ;
}
}
}
}
}
}
// Se si verifica la condizione di terminazione arresto il ciclo altrimenti aggiorno i box
if ( ! bCollide || dMinSqDist < EPS_SMALL * EPS_SMALL)
bContinue = false ;
else {
boxPPrev = boxP ;
boxP.Expand( dDeltaLen) ;
}
}
return nVert ;
}
-1
View File
@@ -20,5 +20,4 @@
int GetEGkDebugLev( void) ; int GetEGkDebugLev( void) ;
ILogger* GetEGkLogger( void) ; ILogger* GetEGkLogger( void) ;
const std::string& GetEGkKey( void) ; const std::string& GetEGkKey( void) ;
bool GetEGkNetHwKey( void) ;
int ProcessEvents( int nProg, int nPause) ; int ProcessEvents( int nProg, int nPause) ;
+1 -16
View File
@@ -16,7 +16,7 @@
#include "DllMain.h" #include "DllMain.h"
#include "FontManager.h" #include "FontManager.h"
#include "\EgtDev\Include\EGkDllMain.h" #include "\EgtDev\Include\EGkDllMain.h"
#include "\EgtDev\Include\EGnGetModuleVer.h" #include "\EgtDev\Include\EgnGetModuleVer.h"
#include "\EgtDev\Include\EgtTrace.h" #include "\EgtDev\Include\EgtTrace.h"
#include "\EgtDev\Include\SELkLockId.h" #include "\EgtDev\Include\SELkLockId.h"
@@ -115,7 +115,6 @@ GetEGkLogger( void)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static string s_sKey ; static string s_sKey ;
static int s_nKeyType = KEY_LOCK_TYPE_ANY ; static int s_nKeyType = KEY_LOCK_TYPE_ANY ;
static bool s_bNetHwKey = false ;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void void
@@ -131,13 +130,6 @@ SetEGkKeyType( int nType)
s_nKeyType = nType ; s_nKeyType = nType ;
} }
//-----------------------------------------------------------------------------
void
SetEGkNetHwKey( bool bNetHwKey)
{
s_bNetHwKey = bNetHwKey ;
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
const string& const string&
GetEGkKey( void) GetEGkKey( void)
@@ -146,13 +138,6 @@ GetEGkKey( void)
return s_sKey ; return s_sKey ;
} }
//-----------------------------------------------------------------------------
bool
GetEGkNetHwKey( void)
{
return s_bNetHwKey ;
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void void
InitFontManager( const string& sNfeFontDir, const string& sDefaultFont) InitFontManager( const string& sNfeFontDir, const string& sDefaultFont)
BIN
View File
Binary file not shown.
+11 -32
View File
@@ -22,7 +22,7 @@
<ProjectGuid>{9A98A202-2853-454A-84CA-DCD1714176C9}</ProjectGuid> <ProjectGuid>{9A98A202-2853-454A-84CA-DCD1714176C9}</ProjectGuid>
<RootNamespace>EgtGeomKernel</RootNamespace> <RootNamespace>EgtGeomKernel</RootNamespace>
<Keyword>MFCDLLProj</Keyword> <Keyword>MFCDLLProj</Keyword>
<WindowsTargetPlatformVersion>10.0.20348.0</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
@@ -30,7 +30,7 @@
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
<UseOfMfc>false</UseOfMfc> <UseOfMfc>false</UseOfMfc>
<PlatformToolset>v141_xp</PlatformToolset> <PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
@@ -46,7 +46,7 @@
<WholeProgramOptimization>false</WholeProgramOptimization> <WholeProgramOptimization>false</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
<UseOfMfc>false</UseOfMfc> <UseOfMfc>false</UseOfMfc>
<PlatformToolset>v141_xp</PlatformToolset> <PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
@@ -116,7 +116,6 @@
<MultiProcessorCompilation>true</MultiProcessorCompilation> <MultiProcessorCompilation>true</MultiProcessorCompilation>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<EnablePREfast>false</EnablePREfast> <EnablePREfast>false</EnablePREfast>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
@@ -152,7 +151,6 @@ copy $(TargetPath) \EgtProg\DllD32</Command>
<MultiProcessorCompilation>true</MultiProcessorCompilation> <MultiProcessorCompilation>true</MultiProcessorCompilation>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<LanguageStandard>stdcpp17</LanguageStandard> <LanguageStandard>stdcpp17</LanguageStandard>
<AdditionalOptions>-Wno-tautological-undefined-compare</AdditionalOptions>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
@@ -199,7 +197,6 @@ copy $(TargetPath) \EgtProg\DllD64</Command>
<EnableParallelCodeGeneration>true</EnableParallelCodeGeneration> <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
<WholeProgramOptimization>false</WholeProgramOptimization> <WholeProgramOptimization>false</WholeProgramOptimization>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
@@ -246,8 +243,6 @@ copy $(TargetPath) \EgtProg\Dll32</Command>
<WholeProgramOptimization>false</WholeProgramOptimization> <WholeProgramOptimization>false</WholeProgramOptimization>
<DebugInformationFormat>None</DebugInformationFormat> <DebugInformationFormat>None</DebugInformationFormat>
<LanguageStandard>stdcpp17</LanguageStandard> <LanguageStandard>stdcpp17</LanguageStandard>
<AdditionalOptions>-Wno-tautological-undefined-compare</AdditionalOptions>
<IntelJCCErratum>true</IntelJCCErratum>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
@@ -285,7 +280,6 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
<ClCompile Include="CAvToolTriangle.cpp" /> <ClCompile Include="CAvToolTriangle.cpp" />
<ClCompile Include="CDeBoxClosedSurfTm.cpp" /> <ClCompile Include="CDeBoxClosedSurfTm.cpp" />
<ClCompile Include="CDeBoxTria.cpp" /> <ClCompile Include="CDeBoxTria.cpp" />
<ClCompile Include="CDeCapsTria.cpp" />
<ClCompile Include="CDeClosedSurfTmClosedSurfTm.cpp" /> <ClCompile Include="CDeClosedSurfTmClosedSurfTm.cpp" />
<ClCompile Include="CDeConeFrustumClosedSurfTm.cpp" /> <ClCompile Include="CDeConeFrustumClosedSurfTm.cpp" />
<ClCompile Include="CDeConeFrustumTria.cpp" /> <ClCompile Include="CDeConeFrustumTria.cpp" />
@@ -301,7 +295,6 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
<ClCompile Include="CDeTriaTria.cpp" /> <ClCompile Include="CDeTriaTria.cpp" />
<ClCompile Include="CDeUtility.cpp" /> <ClCompile Include="CDeUtility.cpp" />
<ClCompile Include="ChainCurves.cpp" /> <ClCompile Include="ChainCurves.cpp" />
<ClCompile Include="Circle2P.cpp" />
<ClCompile Include="CircleCenTgCurve.cpp" /> <ClCompile Include="CircleCenTgCurve.cpp" />
<ClCompile Include="Color.cpp" /> <ClCompile Include="Color.cpp" />
<ClCompile Include="CreateCurveAux.cpp" /> <ClCompile Include="CreateCurveAux.cpp" />
@@ -315,7 +308,6 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
<ClInclude Include="..\Include\EGkIntersLineBox.h" /> <ClInclude Include="..\Include\EGkIntersLineBox.h" />
<ClInclude Include="..\Include\EGkIntersPlaneBox.h" /> <ClInclude Include="..\Include\EGkIntersPlaneBox.h" />
<ClInclude Include="CDeBoxTria.h" /> <ClInclude Include="CDeBoxTria.h" />
<ClInclude Include="CDeCapsTria.h" />
<ClInclude Include="CDeConeFrustumTria.h" /> <ClInclude Include="CDeConeFrustumTria.h" />
<ClInclude Include="CDeConeTria.h" /> <ClInclude Include="CDeConeTria.h" />
<ClInclude Include="CDeConvexTorusTria.h" /> <ClInclude Include="CDeConvexTorusTria.h" />
@@ -329,11 +321,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
<ClCompile Include="DistPointSurfTm.cpp" /> <ClCompile Include="DistPointSurfTm.cpp" />
<ClCompile Include="DistPointTria.cpp" /> <ClCompile Include="DistPointTria.cpp" />
<ClCompile Include="ExtDimension.cpp" /> <ClCompile Include="ExtDimension.cpp" />
<ClCompile Include="HashGrids1d.cpp" />
<ClCompile Include="IntersLineBox.cpp" /> <ClCompile Include="IntersLineBox.cpp" />
<ClCompile Include="IntersLineCaps.cpp" />
<ClCompile Include="IntersLineCone.cpp" />
<ClCompile Include="IntersLineCyl.cpp" />
<ClCompile Include="IntersLineSphere.cpp" /> <ClCompile Include="IntersLineSphere.cpp" />
<ClCompile Include="IntersLineSurfStd.cpp" /> <ClCompile Include="IntersLineSurfStd.cpp" />
<ClCompile Include="IntersPlaneBox.cpp" /> <ClCompile Include="IntersPlaneBox.cpp" />
@@ -342,7 +330,6 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
<ClCompile Include="IntersPlaneTria.cpp" /> <ClCompile Include="IntersPlaneTria.cpp" />
<ClCompile Include="IntersSurfTmSurfTm.cpp" /> <ClCompile Include="IntersSurfTmSurfTm.cpp" />
<ClCompile Include="IntersTriaTria.cpp" /> <ClCompile Include="IntersTriaTria.cpp" />
<ClCompile Include="MedialAxis.cpp" />
<ClCompile Include="OffsetCurve.cpp" /> <ClCompile Include="OffsetCurve.cpp" />
<ClCompile Include="DistPointArc.cpp" /> <ClCompile Include="DistPointArc.cpp" />
<ClCompile Include="DistPointCrvAux.cpp" /> <ClCompile Include="DistPointCrvAux.cpp" />
@@ -397,16 +384,14 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
<ClCompile Include="OffsetCurveOnX.cpp" /> <ClCompile Include="OffsetCurveOnX.cpp" />
<ClCompile Include="Polygon3d.cpp" /> <ClCompile Include="Polygon3d.cpp" />
<ClCompile Include="AdjustLoops.cpp" /> <ClCompile Include="AdjustLoops.cpp" />
<ClCompile Include="RemoveCurveDefects.cpp" /> <ClCompile Include="RemoveCurveSpikes.cpp" />
<ClCompile Include="SelfIntersCurve.cpp" /> <ClCompile Include="SelfIntersCurve.cpp" />
<ClCompile Include="SfrCreate.cpp" /> <ClCompile Include="SfrCreate.cpp" />
<ClCompile Include="SurfAux.cpp" />
<ClCompile Include="SurfBezier.cpp" /> <ClCompile Include="SurfBezier.cpp" />
<ClCompile Include="SurfFlatRegion.cpp" /> <ClCompile Include="SurfFlatRegion.cpp" />
<ClCompile Include="SurfFlatRegionBooleans.cpp" /> <ClCompile Include="SurfFlatRegionBooleans.cpp" />
<ClCompile Include="SurfFlatRegionOffset.cpp" /> <ClCompile Include="SurfFlatRegionOffset.cpp" />
<ClCompile Include="SurfTriMeshBooleans.cpp" /> <ClCompile Include="SurfTriMeshBooleans.cpp" />
<ClCompile Include="SurfTriMeshCuts.cpp" />
<ClCompile Include="SurfTriMeshUtilities.cpp" /> <ClCompile Include="SurfTriMeshUtilities.cpp" />
<ClCompile Include="TextureData.cpp" /> <ClCompile Include="TextureData.cpp" />
<ClCompile Include="Tool.cpp" /> <ClCompile Include="Tool.cpp" />
@@ -456,14 +441,14 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
<ClInclude Include="..\Include\EGkChainCurves.h" /> <ClInclude Include="..\Include\EGkChainCurves.h" />
<ClInclude Include="..\Include\EGkCircleCenTgCurve.h" /> <ClInclude Include="..\Include\EGkCircleCenTgCurve.h" />
<ClInclude Include="..\Include\EGkColor.h" /> <ClInclude Include="..\Include\EGkColor.h" />
<ClInclude Include="..\Include\EGkCurve.h" /> <ClInclude Include="..\Include\EgkCurve.h" />
<ClInclude Include="..\Include\EGkCurveArc.h" /> <ClInclude Include="..\Include\EgkCurveArc.h" />
<ClInclude Include="..\Include\EGkCurveAux.h" /> <ClInclude Include="..\Include\EgkCurveAux.h" />
<ClInclude Include="..\Include\EGkCurveBezier.h" /> <ClInclude Include="..\Include\EgkCurveBezier.h" />
<ClInclude Include="..\Include\EGkCurveByApprox.h" /> <ClInclude Include="..\Include\EGkCurveByApprox.h" />
<ClInclude Include="..\Include\EGkCurveComposite.h" /> <ClInclude Include="..\Include\EgkCurveComposite.h" />
<ClInclude Include="..\Include\EGkCurveByInterp.h" /> <ClInclude Include="..\Include\EGkCurveByInterp.h" />
<ClInclude Include="..\Include\EGkCurveLine.h" /> <ClInclude Include="..\Include\EgkCurveLine.h" />
<ClInclude Include="..\Include\EGkCurveLocal.h" /> <ClInclude Include="..\Include\EGkCurveLocal.h" />
<ClInclude Include="..\Include\EGkCurvePointDiffGeom.h" /> <ClInclude Include="..\Include\EGkCurvePointDiffGeom.h" />
<ClInclude Include="..\Include\EGkDistPointCurve.h" /> <ClInclude Include="..\Include\EGkDistPointCurve.h" />
@@ -573,7 +558,6 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
<ClInclude Include="DistPointCrvComposite.h" /> <ClInclude Include="DistPointCrvComposite.h" />
<ClInclude Include="DistPointLine.h" /> <ClInclude Include="DistPointLine.h" />
<ClInclude Include="DllMain.h" /> <ClInclude Include="DllMain.h" />
<ClInclude Include="earcut.hpp" />
<ClInclude Include="ExtDimension.h" /> <ClInclude Include="ExtDimension.h" />
<ClInclude Include="ExtText.h" /> <ClInclude Include="ExtText.h" />
<ClInclude Include="FontAux.h" /> <ClInclude Include="FontAux.h" />
@@ -602,10 +586,6 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
<ClInclude Include="IntersArcArc.h" /> <ClInclude Include="IntersArcArc.h" />
<ClInclude Include="IntersCrvCompoCrvCompo.h" /> <ClInclude Include="IntersCrvCompoCrvCompo.h" />
<ClInclude Include="IntersLineArc.h" /> <ClInclude Include="IntersLineArc.h" />
<ClInclude Include="IntersLineBox.h" />
<ClInclude Include="IntersLineCaps.h" />
<ClInclude Include="IntersLineCone.h" />
<ClInclude Include="IntersLineCyl.h" />
<ClInclude Include="IntersLineLine.h" /> <ClInclude Include="IntersLineLine.h" />
<ClInclude Include="IntersLineSurfStd.h" /> <ClInclude Include="IntersLineSurfStd.h" />
<ClInclude Include="IntersLineTria.h" /> <ClInclude Include="IntersLineTria.h" />
@@ -619,8 +599,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
<ClInclude Include="ObjGraphicsMgr.h" /> <ClInclude Include="ObjGraphicsMgr.h" />
<ClInclude Include="FontOs.h" /> <ClInclude Include="FontOs.h" />
<ClInclude Include="AdjustLoops.h" /> <ClInclude Include="AdjustLoops.h" />
<ClInclude Include="RemoveCurveDefects.h" /> <ClInclude Include="RemoveCurveSpikes.h" />
<ClInclude Include="SurfAux.h" />
<ClInclude Include="SurfBezier.h" /> <ClInclude Include="SurfBezier.h" />
<ClInclude Include="SurfFlatRegion.h" /> <ClInclude Include="SurfFlatRegion.h" />
<ClInclude Include="TextureData.h" /> <ClInclude Include="TextureData.h" />
+8 -56
View File
@@ -327,7 +327,7 @@
<ClCompile Include="OffsetCurveOnX.cpp"> <ClCompile Include="OffsetCurveOnX.cpp">
<Filter>File di origine\GeoOffset</Filter> <Filter>File di origine\GeoOffset</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="RemoveCurveDefects.cpp"> <ClCompile Include="RemoveCurveSpikes.cpp">
<Filter>File di origine\GeoInters</Filter> <Filter>File di origine\GeoInters</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Polygon3d.cpp"> <ClCompile Include="Polygon3d.cpp">
@@ -456,33 +456,6 @@
<ClCompile Include="SurfTriMeshUtilities.cpp"> <ClCompile Include="SurfTriMeshUtilities.cpp">
<Filter>File di origine\Geo</Filter> <Filter>File di origine\Geo</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="SurfTriMeshCuts.cpp">
<Filter>File di origine\Geo</Filter>
</ClCompile>
<ClCompile Include="HashGrids1d.cpp">
<Filter>File di origine\Base</Filter>
</ClCompile>
<ClCompile Include="CDeCapsTria.cpp">
<Filter>File di origine\GeoCollision</Filter>
</ClCompile>
<ClCompile Include="Circle2P.cpp">
<Filter>File di origine\GeoCreate</Filter>
</ClCompile>
<ClCompile Include="MedialAxis.cpp">
<Filter>File di origine\GeoOffset</Filter>
</ClCompile>
<ClCompile Include="IntersLineCyl.cpp">
<Filter>File di origine\GeoInters</Filter>
</ClCompile>
<ClCompile Include="IntersLineCone.cpp">
<Filter>File di origine\GeoInters</Filter>
</ClCompile>
<ClCompile Include="IntersLineCaps.cpp">
<Filter>File di origine\GeoInters</Filter>
</ClCompile>
<ClCompile Include="SurfAux.cpp">
<Filter>File di origine\Geo</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="stdafx.h"> <ClInclude Include="stdafx.h">
@@ -653,28 +626,28 @@
<ClInclude Include="..\Include\EGkChainCurves.h"> <ClInclude Include="..\Include\EGkChainCurves.h">
<Filter>File di intestazione\Include</Filter> <Filter>File di intestazione\Include</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\Include\EGkCurveBezier.h"> <ClInclude Include="..\Include\EgkCurveBezier.h">
<Filter>File di intestazione\Include</Filter> <Filter>File di intestazione\Include</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\Include\EGkColor.h"> <ClInclude Include="..\Include\EGkColor.h">
<Filter>File di intestazione\Include</Filter> <Filter>File di intestazione\Include</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\Include\EGkCurve.h"> <ClInclude Include="..\Include\EgkCurve.h">
<Filter>File di intestazione\Include</Filter> <Filter>File di intestazione\Include</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\Include\EGkCurveArc.h"> <ClInclude Include="..\Include\EgkCurveArc.h">
<Filter>File di intestazione\Include</Filter> <Filter>File di intestazione\Include</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\Include\EGkCurveAux.h"> <ClInclude Include="..\Include\EgkCurveAux.h">
<Filter>File di intestazione\Include</Filter> <Filter>File di intestazione\Include</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\Include\EGkCurveByInterp.h"> <ClInclude Include="..\Include\EGkCurveByInterp.h">
<Filter>File di intestazione\Include</Filter> <Filter>File di intestazione\Include</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\Include\EGkCurveComposite.h"> <ClInclude Include="..\Include\EgkCurveComposite.h">
<Filter>File di intestazione\Include</Filter> <Filter>File di intestazione\Include</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\Include\EGkCurveLine.h"> <ClInclude Include="..\Include\EgkCurveLine.h">
<Filter>File di intestazione\Include</Filter> <Filter>File di intestazione\Include</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\Include\EGkCurvePointDiffGeom.h"> <ClInclude Include="..\Include\EGkCurvePointDiffGeom.h">
@@ -869,7 +842,7 @@
<ClInclude Include="..\Include\EGkIntersLineSurfTm.h"> <ClInclude Include="..\Include\EGkIntersLineSurfTm.h">
<Filter>File di intestazione\Include</Filter> <Filter>File di intestazione\Include</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="RemoveCurveDefects.h"> <ClInclude Include="RemoveCurveSpikes.h">
<Filter>File di intestazione</Filter> <Filter>File di intestazione</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\Include\EGkIntersPlanePlane.h"> <ClInclude Include="..\Include\EGkIntersPlanePlane.h">
@@ -1106,27 +1079,6 @@
<ClInclude Include="CDeRectPrismoidTria.h"> <ClInclude Include="CDeRectPrismoidTria.h">
<Filter>File di intestazione</Filter> <Filter>File di intestazione</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="earcut.hpp">
<Filter>File di intestazione</Filter>
</ClInclude>
<ClInclude Include="IntersLineBox.h">
<Filter>File di intestazione</Filter>
</ClInclude>
<ClInclude Include="CDeCapsTria.h">
<Filter>File di intestazione</Filter>
</ClInclude>
<ClInclude Include="IntersLineCyl.h">
<Filter>File di intestazione</Filter>
</ClInclude>
<ClInclude Include="IntersLineCone.h">
<Filter>File di intestazione</Filter>
</ClInclude>
<ClInclude Include="IntersLineCaps.h">
<Filter>File di intestazione</Filter>
</ClInclude>
<ClInclude Include="SurfAux.h">
<Filter>File di intestazione</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="EgtGeomKernel.rc"> <ResourceCompile Include="EgtGeomKernel.rc">
+103 -681
View File
File diff suppressed because it is too large Load Diff
-24
View File
@@ -62,12 +62,6 @@ class ExtDimension : public IExtDimension, public IGeoObjRW
int nDecDigit, const std::string& sFont, double dTextHeight) override ; int nDecDigit, const std::string& sFont, double dTextHeight) override ;
bool SetLinear( const Point3d& ptP1, const Point3d& ptP2, const Point3d& ptPos, bool SetLinear( const Point3d& ptP1, const Point3d& ptP2, const Point3d& ptPos,
const Vector3d& vtN, const Vector3d& vtDir, const std::string& sText) override ; const Vector3d& vtN, const Vector3d& vtDir, const std::string& sText) override ;
bool SetRadial( const Point3d& ptCen, const Point3d& ptPos,
const Vector3d& vtN, const std::string& sText) override ;
bool SetDiametral( const Point3d& ptCen, const Point3d& ptPos,
const Vector3d& vtN, const std::string& sText) override ;
bool SetAngular( const Point3d& ptP1, const Point3d& ptP2, const Point3d& ptV, const Point3d& ptPos,
const Vector3d& vtN, const std::string& sText) override ;
const Vector3d& GetNormVersor( void) const override const Vector3d& GetNormVersor( void) const override
{ return m_vtN ; } { return m_vtN ; }
const Vector3d& GetDirVersor( void) const override const Vector3d& GetDirVersor( void) const override
@@ -125,7 +119,6 @@ class ExtDimension : public IExtDimension, public IGeoObjRW
bool GetArrowHead( const Point3d& ptTip, const Vector3d& vtDir, PolyLine& PL) const ; bool GetArrowHead( const Point3d& ptTip, const Vector3d& vtDir, PolyLine& PL) const ;
bool SetCurrFont( FontManager& fntMgr) const ; bool SetCurrFont( FontManager& fntMgr) const ;
bool ApproxTextWithLines( double dLinTol, double dAngTolDeg, POLYLINELIST& lstPL) const ; bool ApproxTextWithLines( double dLinTol, double dAngTolDeg, POLYLINELIST& lstPL) const ;
bool GetTextMyBBox( BBox3d& b3Loc) const ;
bool GetTextMyBBox( const Point3d& ptPos, BBox3d& b3Loc) const ; bool GetTextMyBBox( const Point3d& ptPos, BBox3d& b3Loc) const ;
bool GetTextLocalBBox( BBox3d& b3Loc) const ; bool GetTextLocalBBox( BBox3d& b3Loc) const ;
bool GetTextBBox( const Frame3d& frRef, BBox3d& b3Ref) const ; bool GetTextBBox( const Frame3d& frRef, BBox3d& b3Ref) const ;
@@ -147,7 +140,6 @@ class ExtDimension : public IExtDimension, public IGeoObjRW
mutable std::string m_sCalcText ; // testo effettivo della quota mutable std::string m_sCalcText ; // testo effettivo della quota
mutable Point3d m_ptCalcPos ; // posizione effettiva della quota mutable Point3d m_ptCalcPos ; // posizione effettiva della quota
mutable bool m_bCalcArrowIn ; // flag posizione effettiva delle frecce mutable bool m_bCalcArrowIn ; // flag posizione effettiva delle frecce
mutable bool m_bCalcTextOn ; // flag posizione del testo sulla linea di misura
mutable Point3d m_ptCalcP7 ; // settimo punto effettivo mutable Point3d m_ptCalcP7 ; // settimo punto effettivo
mutable Point3d m_ptCalcP8 ; // ottavo punto effettivo mutable Point3d m_ptCalcP8 ; // ottavo punto effettivo
double m_dExtLineLen ; // lunghezza di estensione della linea double m_dExtLineLen ; // lunghezza di estensione della linea
@@ -159,19 +151,3 @@ class ExtDimension : public IExtDimension, public IGeoObjRW
double m_dTextHeight ; // altezza del testo double m_dTextHeight ; // altezza del testo
int m_nTempProp[2] ; // vettore proprietà temporanee int m_nTempProp[2] ; // vettore proprietà temporanee
} ; } ;
//-----------------------------------------------------------------------------
inline ExtDimension* CreateBasicExtDimension( void)
{ return ( static_cast<ExtDimension*>( CreateGeoObj( EXT_DIMENSION))) ; }
inline ExtDimension* CloneBasicExtDimension( const IGeoObj* pGObj)
{ if ( pGObj == nullptr || pGObj->GetType() != EXT_DIMENSION)
return nullptr ;
return ( static_cast<ExtDimension*>( pGObj->Clone())) ; }
inline const ExtDimension* GetBasicExtDimension( const IGeoObj* pGObj)
{ if ( pGObj == nullptr || pGObj->GetType() != EXT_DIMENSION)
return nullptr ;
return ( static_cast<const ExtDimension*>( pGObj)) ; }
inline ExtDimension* GetBasicExtDimension( IGeoObj* pGObj)
{ if ( pGObj == nullptr || pGObj->GetType() != EXT_DIMENSION)
return nullptr ;
return ( static_cast<ExtDimension*>( pGObj)) ; }
+1 -32
View File
@@ -161,7 +161,7 @@ ExtText::Clone( void) const
bool bool
ExtText::CopyFrom( const IGeoObj* pGObjSrc) ExtText::CopyFrom( const IGeoObj* pGObjSrc)
{ {
const ExtText* pTxt = GetBasicExtText( pGObjSrc) ; const ExtText* pTxt = dynamic_cast<const ExtText*>( pGObjSrc) ;
if ( pTxt == nullptr) if ( pTxt == nullptr)
return false ; return false ;
return CopyFrom( *pTxt) ; return CopyFrom( *pTxt) ;
@@ -399,11 +399,8 @@ ExtText::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag) const
bool bool
ExtText::Translate( const Vector3d& vtMove) ExtText::Translate( const Vector3d& vtMove)
{ {
// imposto ricalcolo della grafica
ResetAuxSurf() ; ResetAuxSurf() ;
m_OGrMgr.Reset() ; m_OGrMgr.Reset() ;
// eseguo
m_ptP.Translate( vtMove) ; m_ptP.Translate( vtMove) ;
return true ; return true ;
} }
@@ -412,15 +409,8 @@ ExtText::Translate( const Vector3d& vtMove)
bool bool
ExtText::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, double dSinAng) ExtText::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, double dSinAng)
{ {
// verifico validità dell'asse di rotazione
if ( vtAx.IsSmall())
return false ;
// imposto ricalcolo della grafica
ResetAuxSurf() ; ResetAuxSurf() ;
m_OGrMgr.Reset() ; m_OGrMgr.Reset() ;
// eseguo
return ( m_ptP.Rotate( ptAx, vtAx, dCosAng, dSinAng) && return ( m_ptP.Rotate( ptAx, vtAx, dCosAng, dSinAng) &&
m_vtN.Rotate( vtAx, dCosAng, dSinAng) && m_vtN.Rotate( vtAx, dCosAng, dSinAng) &&
m_vtD.Rotate( vtAx, dCosAng, dSinAng)) ; m_vtD.Rotate( vtAx, dCosAng, dSinAng)) ;
@@ -542,18 +532,9 @@ ExtText::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d& vtD
bool bool
ExtText::ToGlob( const Frame3d& frRef) ExtText::ToGlob( const Frame3d& frRef)
{ {
// verifico validità del frame
if ( frRef.GetType() == Frame3d::ERR)
return false ;
// se frame identità, non devo fare alcunché
if ( IsGlobFrame( frRef))
return true ;
// imposto ricalcolo della grafica // imposto ricalcolo della grafica
ResetAuxSurf() ; ResetAuxSurf() ;
m_OGrMgr.Reset() ; m_OGrMgr.Reset() ;
// trasformo punto e versori // trasformo punto e versori
return ( m_ptP.ToGlob( frRef) && return ( m_ptP.ToGlob( frRef) &&
m_vtN.ToGlob( frRef) && m_vtN.ToGlob( frRef) &&
@@ -564,18 +545,9 @@ ExtText::ToGlob( const Frame3d& frRef)
bool bool
ExtText::ToLoc( const Frame3d& frRef) ExtText::ToLoc( const Frame3d& frRef)
{ {
// verifico validità del frame
if ( frRef.GetType() == Frame3d::ERR)
return false ;
// se frame identità, non devo fare alcunché
if ( IsGlobFrame( frRef))
return true ;
// imposto ricalcolo della grafica // imposto ricalcolo della grafica
ResetAuxSurf() ; ResetAuxSurf() ;
m_OGrMgr.Reset() ; m_OGrMgr.Reset() ;
// trasformo punto e versori // trasformo punto e versori
return ( m_ptP.ToLoc( frRef) && return ( m_ptP.ToLoc( frRef) &&
m_vtN.ToLoc( frRef) && m_vtN.ToLoc( frRef) &&
@@ -589,15 +561,12 @@ ExtText::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
// verifico validità dei frame // verifico validità dei frame
if ( frOri.GetType() == Frame3d::ERR || frDest.GetType() == Frame3d::ERR) if ( frOri.GetType() == Frame3d::ERR || frDest.GetType() == Frame3d::ERR)
return false ; return false ;
// se i due riferimenti coincidono, non devo fare alcunché // se i due riferimenti coincidono, non devo fare alcunché
if ( AreSameFrame( frOri, frDest)) if ( AreSameFrame( frOri, frDest))
return true ; return true ;
// imposto ricalcolo della grafica // imposto ricalcolo della grafica
ResetAuxSurf() ; ResetAuxSurf() ;
m_OGrMgr.Reset() ; m_OGrMgr.Reset() ;
// trasformo punto e versori // trasformo punto e versori
return ( m_ptP.ToGlob( frOri) && m_ptP.ToLoc( frDest) && return ( m_ptP.ToGlob( frOri) && m_ptP.ToLoc( frDest) &&
m_vtN.ToGlob( frOri) && m_vtN.ToLoc( frDest) && m_vtN.ToGlob( frOri) && m_vtN.ToLoc( frDest) &&
-16
View File
@@ -146,19 +146,3 @@ class ExtText : public IExtText, public IGeoObjRW
int m_nInsPos ; // posizione del punto di inserimento rispetto al testo int m_nInsPos ; // posizione del punto di inserimento rispetto al testo
int m_nTempProp[2] ; // vettore proprietà temporanee int m_nTempProp[2] ; // vettore proprietà temporanee
} ; } ;
//-----------------------------------------------------------------------------
inline ExtText* CreateBasicExtText( void)
{ return ( static_cast<ExtText*>( CreateGeoObj( EXT_TEXT))) ; }
inline ExtText* CloneBasicExtText( const IGeoObj* pGObj)
{ if ( pGObj == nullptr || pGObj->GetType() != EXT_TEXT)
return nullptr ;
return ( static_cast<ExtText*>( pGObj->Clone())) ; }
inline const ExtText* GetBasicExtText( const IGeoObj* pGObj)
{ if ( pGObj == nullptr || pGObj->GetType() != EXT_TEXT)
return nullptr ;
return ( static_cast<const ExtText*>( pGObj)) ; }
inline ExtText* GetBasicExtText( IGeoObj* pGObj)
{ if ( pGObj == nullptr || pGObj->GetType() != EXT_TEXT)
return nullptr ;
return ( static_cast<ExtText*>( pGObj)) ; }
+71 -107
View File
@@ -15,90 +15,13 @@
#include "stdafx.h" #include "stdafx.h"
#include "CurveArc.h" #include "CurveArc.h"
#include "CurveLine.h" #include "CurveLine.h"
#include "/EgtDev/Include/EGkFilletChamfer.h" #include "/EgtDev/Include/EgkFilletChamfer.h"
#include "/EgtDev/Include/EGkDistPointCurve.h" #include "/EgtDev/Include/EgkDistPointCurve.h"
#include "/EgtDev/Include/EGkIntersCurves.h" #include "/EgtDev/Include/EgkIntersCurves.h"
#include "/EgtDev/Include/EgtPointerOwner.h" #include "/EgtDev/Include/EgtPointerOwner.h"
using namespace std ; using namespace std ;
//----------------------------------------------------------------------------
static bool
CalcForFillet( const ICurve& cCrv1, const Point3d& ptNear1,
const ICurve& cCrv2, const Point3d& ptNear2,
const Vector3d& vtNorm, double dRadius,
Point3d& ptCen, Point3d& ptTg1, Point3d& ptTg2,
int& nSide1, int& nSide2, double& dSinA, double& dTgPar1, double& dTgPar2)
{
// calcolo un riferimento sul piano perpendicolare alla normale
Frame3d frIntr ;
if ( ! frIntr.Set( ORIG, vtNorm))
return false ;
// determino il lato di offset della curva 1
DistPointCurve dPC1( ptNear2, cCrv1) ;
if ( ! dPC1.GetSideAtMinDistPoint( 0, vtNorm, nSide1))
return false ;
double dOffs1 = ( nSide1 == MDS_RIGHT ? dRadius : - dRadius) ;
// calcolo l'offset nel piano locale e dal lato opportuno di una copia della curva 1
PtrOwner<ICurve> pCopy1( cCrv1.Clone()) ;
if ( IsNull( pCopy1))
return false ;
pCopy1->ToLoc( frIntr) ;
pCopy1->SetExtrusion( Z_AX) ;
if ( ! pCopy1->SimpleOffset( dOffs1, ICurve::OFF_FILLET))
return false ;
// determino il lato di offset della curva 2
DistPointCurve dPC2( ptNear1, cCrv2) ;
if ( ! dPC2.GetSideAtMinDistPoint( 0, vtNorm, nSide2))
return false ;
double dOffs2 = ( nSide2 == MDS_RIGHT ? dRadius : - dRadius) ;
// calcolo l'offset nel piano locale e dal lato opportuno di una copia della curva 2
PtrOwner<ICurve> pCopy2( cCrv2.Clone()) ;
if ( IsNull( pCopy2))
return false ;
pCopy2->ToLoc( frIntr) ;
pCopy2->SetExtrusion( Z_AX) ;
if ( ! pCopy2->SimpleOffset( dOffs2, ICurve::OFF_FILLET))
return false ;
// calcolo l'intersezione tra le due curve
Point3d ptInt1, ptInt2 ;
Point3d ptNearI = Media( ptNear1, ptNear2) ;
ptNearI.ToLoc( frIntr) ;
IntersCurveCurve intCC( *pCopy1, *pCopy2) ;
if ( ! intCC.GetIntersPointNearTo( 0, ptNearI, ptInt1) ||
! intCC.GetIntersPointNearTo( 1, ptNearI, ptInt2))
return false ;
ptInt1.ToGlob( frIntr) ;
ptInt2.ToGlob( frIntr) ;
ptCen = Media( ptInt1, ptInt2) ;
// proiezione del punto di intersezione sulla prima curva
DistPointCurve dPCI1( ptInt1, cCrv1) ;
int nFlag1 ;
if ( ! dPCI1.GetParamAtMinDistPoint( 0, dTgPar1, nFlag1) || nFlag1 != MDPCI_NORMAL)
return false ;
Vector3d vtTg1 ;
if ( ! cCrv1.GetPointTang( dTgPar1, ICurve::FROM_MINUS, ptTg1, vtTg1))
return false ;
// proiezione del punto di intersezione sulla seconda curva
DistPointCurve dPCI2( ptInt2, cCrv2) ;
int nFlag2 ;
if ( ! dPCI2.GetParamAtMinDistPoint( 0, dTgPar2, nFlag2) || nFlag2 != MDPCI_NORMAL)
return false ;
Vector3d vtTg2 ;
if ( ! cCrv2.GetPointTang( dTgPar2, ICurve::FROM_MINUS, ptTg2, vtTg2))
return false ;
// determino rotazione tra le curve
dSinA = ( vtTg1 ^ vtTg2) * vtNorm ;
return true ;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
ICurveArc* ICurveArc*
CreateFillet( const ICurve& cCrv1, const Point3d& ptNear1, CreateFillet( const ICurve& cCrv1, const Point3d& ptNear1,
@@ -111,26 +34,76 @@ CreateFillet( const ICurve& cCrv1, const Point3d& ptNear1,
&vtNorm == nullptr || &dPar1 == nullptr || &dPar2 == nullptr) &vtNorm == nullptr || &dPar1 == nullptr || &dPar2 == nullptr)
return nullptr ; return nullptr ;
// eseguo calcoli // calcolo un riferimento sul piano perpendicolare alla normale
Point3d ptCen, ptTg1, ptTg2 ; Frame3d frIntr ;
int nSide1, nSide2 ; if ( ! frIntr.Set( ORIG, vtNorm))
double dSinA, dTgPar1, dTgPar2 ;
if ( ! CalcForFillet( cCrv1, ptNear1, cCrv2, ptNear2, vtNorm, dRadius,
ptCen, ptTg1, ptTg2, nSide1, nSide2, dSinA, dTgPar1, dTgPar2))
return nullptr ; return nullptr ;
// se tangenti parallele al contatto con fillet, ricalcolo con raggio più piccolo // determino il lato di offset della curva 1
bool bParallel = ( abs( dSinA) < EPS_SMALL) ; DistPointCurve dPC1( ptNear2, cCrv1) ;
if ( bParallel) { int nSide1 ;
Point3d ptQQQ, ptQQ1, ptQQ2 ; if ( ! dPC1.GetSideAtMinDistPoint( 0, vtNorm, nSide1))
double dQQQ1, dQQQ2 ; return nullptr ;
if ( ! CalcForFillet( cCrv1, ptNear1, cCrv2, ptNear2, vtNorm, dRadius - 10 * EPS_SMALL, double dOffs1 = ( nSide1 == MDS_RIGHT ? dRadius : - dRadius) ;
ptQQQ, ptQQ1, ptQQ2, nSide1, nSide2, dSinA, dQQQ1, dQQQ2) || abs( dSinA) < EPS_SMALL) // calcolo l'offset nel piano locale e dal lato opportuno di una copia della curva 1
return nullptr ; PtrOwner<ICurve> pCopy1( cCrv1.Clone()) ;
} if ( IsNull( pCopy1))
return nullptr ;
pCopy1->ToLoc( frIntr) ;
pCopy1->SetExtrusion( Z_AX) ;
if ( ! pCopy1->SimpleOffset( dOffs1, ICurve::OFF_FILLET))
return nullptr ;
// orientamento tra le curve // determino il lato di offset della curva 2
bool bCCW = ( dSinA > 0) ; DistPointCurve dPC2( ptNear1, cCrv2) ;
int nSide2 ;
if ( ! dPC2.GetSideAtMinDistPoint( 0, vtNorm, nSide2))
return nullptr ;
double dOffs2 = ( nSide2 == MDS_RIGHT ? dRadius : - dRadius) ;
// calcolo l'offset nel piano locale e dal lato opportuno di una copia della curva 2
PtrOwner<ICurve> pCopy2( cCrv2.Clone()) ;
if ( IsNull( pCopy2))
return nullptr ;
pCopy2->ToLoc( frIntr) ;
pCopy2->SetExtrusion( Z_AX) ;
if ( ! pCopy2->SimpleOffset( dOffs2, ICurve::OFF_FILLET))
return nullptr ;
// calcolo l'intersezione tra le due curve
Point3d ptInt1, ptInt2 ;
Point3d ptNear1I = ptNear1 ;
ptNear1I.ToLoc( frIntr) ;
IntersCurveCurve intCC( *pCopy1, *pCopy2) ;
if ( ! intCC.GetIntersPointNearTo( 0, ptNear1I, ptInt1) ||
! intCC.GetIntersPointNearTo( 1, ptNear1I, ptInt2))
return nullptr ;
ptInt1.ToGlob( frIntr) ;
ptInt2.ToGlob( frIntr) ;
// proiezione del punto di intersezione sulla prima curva
DistPointCurve dPCI1( ptInt1, cCrv1) ;
double dTgPar1 ;
int nFlag1 ;
if ( ! dPCI1.GetParamAtMinDistPoint( 0, dTgPar1, nFlag1) || nFlag1 != MDPCI_NORMAL)
return nullptr ;
Point3d ptTg1 ;
Vector3d vtTg1 ;
if ( ! cCrv1.GetPointTang( dTgPar1, ICurve::FROM_MINUS, ptTg1, vtTg1))
return nullptr ;
// proiezione del punto di intersezione sulla seconda curva
DistPointCurve dPCI2( ptInt2, cCrv2) ;
double dTgPar2 ;
int nFlag2 ;
if ( ! dPCI2.GetParamAtMinDistPoint( 0, dTgPar2, nFlag2) || nFlag2 != MDPCI_NORMAL)
return nullptr ;
Point3d ptTg2 ;
Vector3d vtTg2 ;
if ( ! cCrv2.GetPointTang( dTgPar2, ICurve::FROM_MINUS, ptTg2, vtTg2))
return nullptr ;
// determino rotazione tra le curve
bool bCCW = (( vtTg1 ^ vtTg2) * vtNorm) > 0 ;
// assegno i valori dei parametri di trim (+ da inizio, - da fine) // assegno i valori dei parametri di trim (+ da inizio, - da fine)
if ( bCCW) { if ( bCCW) {
@@ -145,17 +118,8 @@ CreateFillet( const ICurve& cCrv1, const Point3d& ptNear1,
// creo l'arco di fillet // creo l'arco di fillet
PtrOwner<CurveArc> crvFillet( CreateBasicCurveArc()) ; PtrOwner<CurveArc> crvFillet( CreateBasicCurveArc()) ;
if ( IsNull( crvFillet) || if ( IsNull( crvFillet) ||
! crvFillet->SetC2PN( ptCen, ptTg1, ptTg2, vtNorm)) ! crvFillet->SetC2PN( ptInt1, ptTg1, ptTg2, vtNorm))
return nullptr ; return nullptr ;
// se direzioni agli estremi praticamente parallele
if ( bParallel) {
// calcolo il verso dell'arco di fillet
bool bFilletCcw = ( ( bCCW && nSide1 == nSide2) || ( ! bCCW && nSide1 != nSide2)) ;
// si deve verificare se va usato l'arco esplementare
bool bArcCcw = ( crvFillet->GetAngCenter() > 0) ;
if ( bFilletCcw != bArcCcw)
crvFillet->ToExplementary() ;
}
return Release(crvFillet) ; return Release(crvFillet) ;
} }
+1 -1
View File
@@ -14,7 +14,7 @@
#pragma once #pragma once
#include "/EgtDev/Include/EGkVector3d.h" #include "/EgtDev/Include/EGkVector3d.h"
#include "/EgtDev/Include/EgtNumCollection.h" #include "/EgtDev/Include/EGtNumCollection.h"
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
double AdjustFontRatio( double dRatio) ; double AdjustFontRatio( double dRatio) ;
+2 -2
View File
@@ -17,9 +17,9 @@
#include "/EgtDev/Include/EGkGeomDB.h" #include "/EgtDev/Include/EGkGeomDB.h"
#include "/EgtDev/Include/EGkGdbIterator.h" #include "/EgtDev/Include/EGkGdbIterator.h"
#include "/EgtDev/Include/EGkCurve.h" #include "/EgtDev/Include/EGkCurve.h"
#include "/EgtDev/Include/EGnStringUtils.h"
#include "/EgtDev/Include/EGnFileUtils.h"
#include "/EgtDev/Include/EgtPointerOwner.h" #include "/EgtDev/Include/EgtPointerOwner.h"
#include "/EgtDev/Include/EgnStringUtils.h"
#include "/EgtDev/Include/EgnFileUtils.h"
using namespace std ; using namespace std ;
+2 -1
View File
@@ -378,7 +378,8 @@ OsFont::GetRegion( const string& sText, int nInsPos, ISURFFRPLIST& lstSFR) const
if ( ! GetCharOutline( vCode[i], dAdvance, lstPC)) if ( ! GetCharOutline( vCode[i], dAdvance, lstPC))
return false ; return false ;
// lo trasformo opportunamente // lo trasformo opportunamente
for ( auto iIter = lstPC.begin() ; iIter != lstPC.end() ; ++ iIter) { ICURVEPLIST::iterator iIter ;
for ( iIter = lstPC.begin() ; iIter != lstPC.end() ; ++ iIter) {
// inverto i percorsi per avere gli esterni CCW // inverto i percorsi per avere gli esterni CCW
(*iIter)->Invert() ; (*iIter)->Invert() ;
// la trasformo per avere solo archi e rette // la trasformo per avere solo archi e rette
+3 -6
View File
@@ -224,10 +224,10 @@ Frame3d::Set( const Point3d& ptOrig, double dAngCDeg, double dAngADeg, double dA
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool bool
Frame3d::Reset( bool bGlob) Frame3d::Reset( void)
{ {
m_nType = ( bGlob ? TOP : ERR) ; m_nType = TOP ;
m_nZType = ( bGlob ? TOP : ERR) ; m_nZType = TOP ;
m_ptOrig = ORIG ; m_ptOrig = ORIG ;
m_vtVersX = X_AX ; m_vtVersX = X_AX ;
m_vtVersY = Y_AX ; m_vtVersY = Y_AX ;
@@ -456,9 +456,6 @@ Frame3d::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
bool bool
Frame3d::Verify( void) Frame3d::Verify( void)
{ {
// verifica origine
if ( ! m_ptOrig.IsValid())
return false ;
// verifica della ortogonalità dei versori e del senso destrorso // verifica della ortogonalità dei versori e del senso destrorso
double dOrtXY = m_vtVersX * m_vtVersY ; double dOrtXY = m_vtVersX * m_vtVersY ;
double dOrtYZ = m_vtVersY * m_vtVersZ ; double dOrtYZ = m_vtVersY * m_vtVersZ ;
+2 -2
View File
@@ -7921,7 +7921,7 @@ GdbExecutor::ExecuteOutTextIcci( const string& sCmd2, const STRVECTOR& vsParams)
sText += "<br/> " ; sText += "<br/> " ;
sText += " U=" + ToString( aInfo.IciA[j].dU,7) + " P=(" + ToString( aInfo.IciA[j].ptI,4) + ")" ; sText += " U=" + ToString( aInfo.IciA[j].dU,7) + " P=(" + ToString( aInfo.IciA[j].ptI,4) + ")" ;
switch( aInfo.IciA[j].nPrevTy) { switch( aInfo.IciA[j].nPrevTy) {
case ICCT_NULL : sText += " ?" "?-" ; break ; case ICCT_NULL : sText += " ??-" ; break ;
case ICCT_IN : sText += " IN-" ; break ; case ICCT_IN : sText += " IN-" ; break ;
case ICCT_OUT : sText += " OUT-" ; break ; case ICCT_OUT : sText += " OUT-" ; break ;
case ICCT_ON : sText += " ON-" ; break ; case ICCT_ON : sText += " ON-" ; break ;
@@ -7940,7 +7940,7 @@ GdbExecutor::ExecuteOutTextIcci( const string& sCmd2, const STRVECTOR& vsParams)
sText += string( "<br/>") + ( aInfo.bCBOverEq ? " + " : " - ") ; sText += string( "<br/>") + ( aInfo.bCBOverEq ? " + " : " - ") ;
sText += " U=" + ToString( aInfo.IciB[j].dU,7) + " P=(" + ToString( aInfo.IciB[j].ptI,4) + ")" ; sText += " U=" + ToString( aInfo.IciB[j].dU,7) + " P=(" + ToString( aInfo.IciB[j].ptI,4) + ")" ;
switch( aInfo.IciB[j].nPrevTy) { switch( aInfo.IciB[j].nPrevTy) {
case ICCT_NULL : sText += " ?" "?-" ; break ; case ICCT_NULL : sText += " ??-" ; break ;
case ICCT_IN : sText += " IN-" ; break ; case ICCT_IN : sText += " IN-" ; break ;
case ICCT_OUT : sText += " OUT-" ; break ; case ICCT_OUT : sText += " OUT-" ; break ;
case ICCT_ON : sText += " ON-" ; break ; case ICCT_ON : sText += " ON-" ; break ;
+2 -2
View File
@@ -14,10 +14,10 @@
#pragma once #pragma once
#include "OutTsc.h" #include "OutTsc.h"
#include "/EgtDev/Include/EGkGdbExecutor.h" #include "/EgtDev/Include/EgkGdbExecutor.h"
#include "/EgtDev/Include/EgtPerfCounter.h" #include "/EgtDev/Include/EgtPerfCounter.h"
#include "/EgtDev/Include/EgtExecMgr.h" #include "/EgtDev/Include/EgtExecMgr.h"
#include "/EgtDev/Include/EGkGeoCollection.h" #include "/EgtDev/Include/EgkGeoCollection.h"
#include "Tool.h" #include "Tool.h"
class PolyLine ; class PolyLine ;
+2 -6
View File
@@ -54,10 +54,6 @@ class GdbGeo : public GdbObj
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
inline const GdbGeo* GetGdbGeo( const GdbObj* pGObj) inline const GdbGeo* GetGdbGeo( const GdbObj* pGObj)
{ if ( pGObj == nullptr || pGObj->GetGdbType() != GDB_TY_GEO) { return dynamic_cast<const GdbGeo*>(pGObj) ; }
return nullptr ;
return static_cast<const GdbGeo*>( pGObj) ; }
inline GdbGeo* GetGdbGeo( GdbObj* pGObj) inline GdbGeo* GetGdbGeo( GdbObj* pGObj)
{ if ( pGObj == nullptr || pGObj->GetGdbType() != GDB_TY_GEO) { return dynamic_cast<GdbGeo*>(pGObj) ; }
return nullptr ;
return static_cast<GdbGeo*>( pGObj) ; }
+2 -6
View File
@@ -91,10 +91,6 @@ class GdbGroup : public GdbObj
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
inline const GdbGroup* GetGdbGroup( const GdbObj* pGObj) inline const GdbGroup* GetGdbGroup( const GdbObj* pGObj)
{ if ( pGObj == nullptr || pGObj->GetGdbType() != GDB_TY_GROUP) { return dynamic_cast<const GdbGroup*>(pGObj) ; }
return nullptr ;
return static_cast<const GdbGroup*>( pGObj) ; }
inline GdbGroup* GetGdbGroup( GdbObj* pGObj) inline GdbGroup* GetGdbGroup( GdbObj* pGObj)
{ if ( pGObj == nullptr || pGObj->GetGdbType() != GDB_TY_GROUP) { return dynamic_cast<GdbGroup*>(pGObj) ; }
return nullptr ;
return static_cast<GdbGroup*>( pGObj) ; }
+8 -64
View File
@@ -24,7 +24,7 @@ using namespace std ;
IGdbIterator* IGdbIterator*
CreateGdbIterator( IGeomDB* pGDB) CreateGdbIterator( IGeomDB* pGDB)
{ {
if ( static_cast<GeomDB*>( pGDB) == nullptr) if ( dynamic_cast<GeomDB*>( pGDB) == nullptr)
return nullptr ; return nullptr ;
return static_cast<IGdbIterator*> ( new( nothrow) GdbIterator( pGDB)) ; return static_cast<IGdbIterator*> ( new( nothrow) GdbIterator( pGDB)) ;
} }
@@ -53,7 +53,7 @@ GdbIterator::~GdbIterator( void)
bool bool
GdbIterator::SetGDB( IGeomDB* pGDB) GdbIterator::SetGDB( IGeomDB* pGDB)
{ {
m_pGDB = static_cast<GeomDB*>( pGDB) ; m_pGDB = dynamic_cast<GeomDB*>( pGDB) ;
if ( m_pGDB == nullptr) if ( m_pGDB == nullptr)
return false ; return false ;
@@ -105,7 +105,7 @@ GdbIterator::GoToFirstInGroup( const IGdbIterator& iIter)
return false ; return false ;
} }
const GdbIterator* pIter = static_cast<const GdbIterator*> (&iIter) ; const GdbIterator* pIter = dynamic_cast<const GdbIterator*> (&iIter) ;
if ( pIter == nullptr || pIter->m_pGDB != m_pGDB) { if ( pIter == nullptr || pIter->m_pGDB != m_pGDB) {
m_pCurrObj = nullptr ; m_pCurrObj = nullptr ;
return false ; return false ;
@@ -167,7 +167,7 @@ GdbIterator::GoToLastInGroup( const IGdbIterator& iIter)
return false ; return false ;
} }
const GdbIterator* pIter = static_cast<const GdbIterator*> (&iIter) ; const GdbIterator* pIter = dynamic_cast<const GdbIterator*> (&iIter) ;
if ( pIter == nullptr || pIter->m_pGDB != m_pGDB) { if ( pIter == nullptr || pIter->m_pGDB != m_pGDB) {
m_pCurrObj = nullptr ; m_pCurrObj = nullptr ;
return false ; return false ;
@@ -263,7 +263,7 @@ GdbIterator::GoToFirstNameInGroup( const IGdbIterator& iIter, const string& sNam
return false ; return false ;
} }
// converto in oggetto iteratore di base // converto in oggetto iteratore di base
const GdbIterator* pIter = static_cast<const GdbIterator*> (&iIter) ; const GdbIterator* pIter = dynamic_cast<const GdbIterator*> (&iIter) ;
if ( pIter == nullptr || pIter->m_pGDB != m_pGDB) { if ( pIter == nullptr || pIter->m_pGDB != m_pGDB) {
m_pCurrObj = nullptr ; m_pCurrObj = nullptr ;
return false ; return false ;
@@ -345,7 +345,7 @@ GdbIterator::GoToLastNameInGroup( const IGdbIterator& iIter, const string& sName
return false ; return false ;
} }
// converto in oggetto iteratore di base // converto in oggetto iteratore di base
const GdbIterator* pIter = static_cast<const GdbIterator*> (&iIter) ; const GdbIterator* pIter = dynamic_cast<const GdbIterator*> (&iIter) ;
if ( pIter == nullptr || pIter->m_pGDB != m_pGDB) { if ( pIter == nullptr || pIter->m_pGDB != m_pGDB) {
m_pCurrObj = nullptr ; m_pCurrObj = nullptr ;
return false ; return false ;
@@ -474,7 +474,7 @@ GdbIterator::GoToFirstGroupInGroup( const IGdbIterator& iIter)
return false ; return false ;
} }
// converto in oggetto iteratore di base // converto in oggetto iteratore di base
const GdbIterator* pIter = static_cast<const GdbIterator*> (&iIter) ; const GdbIterator* pIter = dynamic_cast<const GdbIterator*> (&iIter) ;
if ( pIter == nullptr || pIter->m_pGDB != m_pGDB) { if ( pIter == nullptr || pIter->m_pGDB != m_pGDB) {
m_pCurrObj = nullptr ; m_pCurrObj = nullptr ;
return false ; return false ;
@@ -553,7 +553,7 @@ GdbIterator::GoToLastGroupInGroup( const IGdbIterator& iIter)
return false ; return false ;
} }
// converto in oggetto iteratore di base // converto in oggetto iteratore di base
const GdbIterator* pIter = static_cast<const GdbIterator*> (&iIter) ; const GdbIterator* pIter = dynamic_cast<const GdbIterator*> (&iIter) ;
if ( pIter == nullptr || pIter->m_pGDB != m_pGDB) { if ( pIter == nullptr || pIter->m_pGDB != m_pGDB) {
m_pCurrObj = nullptr ; m_pCurrObj = nullptr ;
return false ; return false ;
@@ -1618,62 +1618,6 @@ GdbIterator::RemoveInfo( const string& sKey)
return m_pCurrObj->RemoveInfo( sKey) ; return m_pCurrObj->RemoveInfo( sKey) ;
} }
//----------------------------------------------------------------------------
bool
GdbIterator::GetAllInfo( STRVECTOR& vsInfo) const
{
if ( m_pGDB == nullptr || m_pCurrObj == nullptr)
return false ;
// recupero tutte le Info
return m_pCurrObj->GetAllInfo( vsInfo) ;
}
//----------------------------------------------------------------------------
bool
GdbIterator::CopyAllInfoFrom( const IGdbIterator& iIter)
{
if ( m_pGDB == nullptr || m_pCurrObj == nullptr)
return false ;
// recupero l'oggetto sorgente
const GdbIterator* pIter = static_cast<const GdbIterator*> (&iIter) ;
if ( pIter == nullptr || pIter->m_pGDB != m_pGDB || pIter->m_pCurrObj == nullptr)
return false ;
const GdbObj* pGdbObjSou = pIter->m_pCurrObj ;
// copio tutte le Info
if ( m_pCurrObj != pGdbObjSou && pGdbObjSou->m_pAttribs != nullptr) {
m_pCurrObj->GetSafeAttribs() ;
return ( m_pCurrObj->m_pAttribs != nullptr && m_pCurrObj->m_pAttribs->CopyAllInfoFrom( *(pGdbObjSou->m_pAttribs))) ;
}
else
return true ;
}
//----------------------------------------------------------------------------
// Stipple (significativo solo per curve)
//----------------------------------------------------------------------------
bool
GdbIterator::SetStipple( int nFactor, int nPattern)
{
if ( m_pGDB == nullptr || m_pCurrObj == nullptr)
return false ;
// imposto lo stipple
return m_pCurrObj->SetStipple( nFactor, nPattern) ;
}
//----------------------------------------------------------------------------
bool
GdbIterator::GetStipple( int& nFactor, int& nPattern) const
{
if ( m_pGDB == nullptr || m_pCurrObj == nullptr)
return false ;
// recupero lo stipple
return m_pCurrObj->GetStipple( nFactor, nPattern) ;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// TextureData // TextureData
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
+2 -7
View File
@@ -1,7 +1,7 @@
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// EgalTech 2013-2023 // EgalTech 2013-2013
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// File : GdbIterator.h Data : 09.07.23 Versione : 2.5g1 // File : GdbIterator.h Data : 04.12.13 Versione : 1.4a3
// Contenuto : Dichiarazione della classe GdbIterator. // Contenuto : Dichiarazione della classe GdbIterator.
// //
// //
@@ -142,11 +142,6 @@ class GdbIterator : public IGdbIterator
bool GetInfo( const std::string& sKey, STRVECTOR& vsInfo) const override ; bool GetInfo( const std::string& sKey, STRVECTOR& vsInfo) const override ;
bool ExistsInfo( const std::string& sKey) const override ; bool ExistsInfo( const std::string& sKey) const override ;
bool RemoveInfo( const std::string& sKey) override ; bool RemoveInfo( const std::string& sKey) override ;
bool GetAllInfo( STRVECTOR& vsInfo) const override ;
bool CopyAllInfoFrom( const IGdbIterator& iIter) override ;
// Stipple
bool SetStipple( int nFactor, int nPattern) override ;
bool GetStipple( int& nFactor, int& nPattern) const override ;
// TextureData // TextureData
bool SetTextureName( const std::string& sTxrName) override ; bool SetTextureName( const std::string& sTxrName) override ;
bool SetTextureFrame( const Frame3d& frTxrRef) override ; bool SetTextureFrame( const Frame3d& frTxrRef) override ;
+3 -42
View File
@@ -31,9 +31,10 @@ using namespace std ;
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
GdbObj::GdbObj( void) GdbObj::GdbObj( void)
: m_nId( GDB_ID_NULL), m_pAttribs( nullptr), m_nStpFactor( 0), m_nStpPattern( 0), m_pTxrData( nullptr), : m_nId( GDB_ID_NULL), m_pAttribs( nullptr), m_pTxrData( nullptr), m_pUserObj( nullptr),
m_pUserObj( nullptr), m_pGDB( nullptr), m_pNext( nullptr), m_pPrev( nullptr), m_pParent( nullptr), m_pGDB( nullptr), m_pNext( nullptr), m_pPrev( nullptr), m_pParent( nullptr),
m_pSelNext( nullptr), m_pSelPrev( nullptr) m_pSelNext( nullptr), m_pSelPrev( nullptr)
{ {
} }
@@ -72,9 +73,6 @@ GdbObj::CopyFrom( const GdbObj* pSou)
if ( m_pAttribs != nullptr) if ( m_pAttribs != nullptr)
delete m_pAttribs ; delete m_pAttribs ;
m_pAttribs = nullptr ; m_pAttribs = nullptr ;
// reset stipple
m_nStpFactor = 0 ;
m_nStpPattern = 0 ;
// elimino eventuali dati della texture pre-esistenti // elimino eventuali dati della texture pre-esistenti
if ( m_pTxrData != nullptr) if ( m_pTxrData != nullptr)
delete m_pTxrData ; delete m_pTxrData ;
@@ -93,10 +91,6 @@ GdbObj::CopyFrom( const GdbObj* pSou)
// copio Id // copio Id
m_nId = pSou->m_nId ; m_nId = pSou->m_nId ;
// copio stipple
m_nStpFactor = pSou->m_nStpFactor ;
m_nStpPattern = pSou->m_nStpPattern ;
// copio gli attributi, i dati della texture e UserObj // copio gli attributi, i dati della texture e UserObj
return ( CopyAttribsFrom( pSou) && CopyTextureDataFrom( pSou) && CopyUserObjFrom( pSou)) ; return ( CopyAttribsFrom( pSou) && CopyTextureDataFrom( pSou) && CopyUserObjFrom( pSou)) ;
} }
@@ -1030,39 +1024,6 @@ GdbObj::RemoveInfo( const string& sKey)
return m_pAttribs->RemoveInfo( sKey) ; return m_pAttribs->RemoveInfo( sKey) ;
} }
//----------------------------------------------------------------------------
bool
GdbObj::GetAllInfo( STRVECTOR& vsInfo) const
{
// se non ci sono attributi
if ( m_pAttribs == nullptr) {
vsInfo.clear() ;
return true ;
}
// recupero tutte le Info
return m_pAttribs->GetAllInfo( vsInfo) ;
}
//----------------------------------------------------------------------------
// Stipple (significativo solo per curve, per ora non viene salvato)
//----------------------------------------------------------------------------
bool
GdbObj::SetStipple( int nFactor, int nPattern)
{
m_nStpFactor = nFactor ;
m_nStpPattern = nPattern ;
return true ;
}
//----------------------------------------------------------------------------
bool
GdbObj::GetStipple( int& nFactor, int& nPattern) const
{
nFactor = m_nStpFactor ;
nPattern = m_nStpPattern ;
return true ;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// TextureData // TextureData
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
-5
View File
@@ -119,9 +119,6 @@ class GdbObj
bool GetInfo( const std::string& sKey, STRVECTOR& vsInfo) const ; bool GetInfo( const std::string& sKey, STRVECTOR& vsInfo) const ;
bool ExistsInfo( const std::string& sKey) const ; bool ExistsInfo( const std::string& sKey) const ;
bool RemoveInfo( const std::string& sKey) ; bool RemoveInfo( const std::string& sKey) ;
bool GetAllInfo( STRVECTOR& vsInfo) const ;
bool SetStipple( int nFactor, int nPattern) ;
bool GetStipple( int& nFactor, int& nPattern) const ;
bool SaveTextureData( NgeWriter& ngeOut) const ; bool SaveTextureData( NgeWriter& ngeOut) const ;
bool LoadTextureData( NgeReader& ngeIn) ; bool LoadTextureData( NgeReader& ngeIn) ;
TextureData* GetTextureData( void) TextureData* GetTextureData( void)
@@ -163,8 +160,6 @@ class GdbObj
public : public :
int m_nId ; int m_nId ;
Attribs* m_pAttribs ; Attribs* m_pAttribs ;
int m_nStpFactor ;
int m_nStpPattern ;
TextureData* m_pTxrData ; TextureData* m_pTxrData ;
IUserObj* m_pUserObj ; IUserObj* m_pUserObj ;
+2 -6
View File
@@ -50,11 +50,7 @@ const double BEZARC_ANG_CEN_MAX = 90 ;
//----------------- Costanti per superfici TriMesh --------------------------- //----------------- Costanti per superfici TriMesh ---------------------------
// tolleranza lineare standard // tolleranza lineare standard
const double STM_STD_LIN_TOL = 0.1 ; const double STM_STD_LIN_TOL = 0.1 ;
// angolo limite standard per definire un edge che è contorno di poligono // angolo limite per definire un edge che è contorno di poligono
const double STM_STD_BOUNDARY_ANG = 0.1 ; const double STM_STD_BOUNDARY_ANG = 0.1 ;
// angolo limite standard per mediare le normali in un vertice // angolo limite per mediare le normali in un vertice
const double STM_STD_SMOOTH_ANG = 25.0 ; const double STM_STD_SMOOTH_ANG = 25.0 ;
// distanza limite tra diagonali per quadrilatero con twist
const double STM_TWIST_DIAG_DIST = 1.0 ;
// angolo limite con twist per mediare le normali in un vertice
const double STM_TWIST_SMOOTH_ANG = 35.0 ;
+1 -1
View File
@@ -104,7 +104,7 @@ GeoFrame3d::Clone( void) const
bool bool
GeoFrame3d::CopyFrom( const IGeoObj* pGObjSrc) GeoFrame3d::CopyFrom( const IGeoObj* pGObjSrc)
{ {
const GeoFrame3d* pGFr = GetBasicGeoFrame3d( pGObjSrc) ; const GeoFrame3d* pGFr = dynamic_cast<const GeoFrame3d*>( pGObjSrc) ;
if ( pGFr == nullptr) if ( pGFr == nullptr)
return false ; return false ;
return CopyFrom( *pGFr) ; return CopyFrom( *pGFr) ;
-16
View File
@@ -98,19 +98,3 @@ class GeoFrame3d : public IGeoFrame3d, public IGeoObjRW
Frame3d m_frF ; // oggetto Frame3d m_frF ; // oggetto
int m_nTempProp[2] ; // vettore proprietà temporanee int m_nTempProp[2] ; // vettore proprietà temporanee
} ; } ;
//-----------------------------------------------------------------------------
inline GeoFrame3d* CreateBasicGeoFrame3d( void)
{ return ( static_cast<GeoFrame3d*>( CreateGeoObj( GEO_FRAME3D))) ; }
inline GeoFrame3d* CloneBasicGeoFrame3d( const IGeoObj* pGObj)
{ if ( pGObj == nullptr || pGObj->GetType() != GEO_FRAME3D)
return nullptr ;
return ( static_cast<GeoFrame3d*>( pGObj->Clone())) ; }
inline const GeoFrame3d* GetBasicGeoFrame3d( const IGeoObj* pGObj)
{ if ( pGObj == nullptr || pGObj->GetType() != GEO_FRAME3D)
return nullptr ;
return ( static_cast<const GeoFrame3d*>( pGObj)) ; }
inline GeoFrame3d* GetBasicGeoFrame3d( IGeoObj* pGObj)
{ if ( pGObj == nullptr || pGObj->GetType() != GEO_FRAME3D)
return nullptr ;
return ( static_cast<GeoFrame3d*>( pGObj)) ; }
+1 -1
View File
@@ -72,7 +72,7 @@ GeoPoint3d::Clone( void) const
bool bool
GeoPoint3d::CopyFrom( const IGeoObj* pGObjSrc) GeoPoint3d::CopyFrom( const IGeoObj* pGObjSrc)
{ {
const GeoPoint3d* pGP = GetBasicGeoPoint3d( pGObjSrc) ; const GeoPoint3d* pGP = dynamic_cast<const GeoPoint3d*>( pGObjSrc) ;
if ( pGP == nullptr) if ( pGP == nullptr)
return false ; return false ;
return CopyFrom( *pGP) ; return CopyFrom( *pGP) ;
-16
View File
@@ -92,19 +92,3 @@ class GeoPoint3d : public IGeoPoint3d, public IGeoObjRW
Point3d m_ptP ; // oggetto Point3d m_ptP ; // oggetto
int m_nTempProp[2] ; // vettore proprietà temporanee int m_nTempProp[2] ; // vettore proprietà temporanee
} ; } ;
//-----------------------------------------------------------------------------
inline GeoPoint3d* CreateBasicGeoPoint3d( void)
{ return ( static_cast<GeoPoint3d*>( CreateGeoObj( GEO_PNT3D))) ; }
inline GeoPoint3d* CloneBasicGeoPoint3d( const IGeoObj* pGObj)
{ if ( pGObj == nullptr || pGObj->GetType() != GEO_PNT3D)
return nullptr ;
return ( static_cast<GeoPoint3d*>( pGObj->Clone())) ; }
inline const GeoPoint3d* GetBasicGeoPoint3d( const IGeoObj* pGObj)
{ if ( pGObj == nullptr || pGObj->GetType() != GEO_PNT3D)
return nullptr ;
return ( static_cast<const GeoPoint3d*>( pGObj)) ; }
inline GeoPoint3d* GetBasicGeoPoint3d( IGeoObj* pGObj)
{ if ( pGObj == nullptr || pGObj->GetType() != GEO_PNT3D)
return nullptr ;
return ( static_cast<GeoPoint3d*>( pGObj)) ; }
+1 -1
View File
@@ -88,7 +88,7 @@ GeoVector3d::Clone( void) const
bool bool
GeoVector3d::CopyFrom( const IGeoObj* pGObjSrc) GeoVector3d::CopyFrom( const IGeoObj* pGObjSrc)
{ {
const GeoVector3d* pGV = GetBasicGeoVector3d( pGObjSrc) ; const GeoVector3d* pGV = dynamic_cast<const GeoVector3d*>( pGObjSrc) ;
if ( pGV == nullptr) if ( pGV == nullptr)
return false ; return false ;
return CopyFrom( *pGV) ; return CopyFrom( *pGV) ;
-16
View File
@@ -107,19 +107,3 @@ class GeoVector3d : public IGeoVector3d, public IGeoObjRW
Point3d m_ptBase ; // punto base da cui tracciare il vettore Point3d m_ptBase ; // punto base da cui tracciare il vettore
int m_nTempProp[2] ; // vettore proprietà temporanee int m_nTempProp[2] ; // vettore proprietà temporanee
} ; } ;
//-----------------------------------------------------------------------------
inline GeoVector3d* CreateBasicGeoVector3d( void)
{ return ( static_cast<GeoVector3d*>( CreateGeoObj( GEO_VECT3D))) ; }
inline GeoVector3d* CloneBasicGeoVector3d( const IGeoObj* pGObj)
{ if ( pGObj == nullptr || pGObj->GetType() != GEO_VECT3D)
return nullptr ;
return ( static_cast<GeoVector3d*>( pGObj->Clone())) ; }
inline const GeoVector3d* GetBasicGeoVector3d( const IGeoObj* pGObj)
{ if ( pGObj == nullptr || pGObj->GetType() != GEO_VECT3D)
return nullptr ;
return ( static_cast<const GeoVector3d*>( pGObj)) ; }
inline GeoVector3d* GetBasicGeoVector3d( IGeoObj* pGObj)
{ if ( pGObj == nullptr || pGObj->GetType() != GEO_VECT3D)
return nullptr ;
return ( static_cast<GeoVector3d*>( pGObj)) ; }
+28 -167
View File
@@ -1,7 +1,7 @@
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// EgalTech 2013-2023 // EgalTech 2013-2013
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// File : GeomDB.cpp Data : 29.05.23 Versione : 2.5e5 // File : GeomDB.cpp Data : 08.04.13 Versione : 1.3a5
// Contenuto : Implementazione della classe GeomDB. // Contenuto : Implementazione della classe GeomDB.
// //
// //
@@ -21,40 +21,17 @@
#include "NgeReader.h" #include "NgeReader.h"
#include "NgeWriter.h" #include "NgeWriter.h"
#include "/EgtDev/Include/EGkStringUtils3d.h" #include "/EgtDev/Include/EGkStringUtils3d.h"
#include "/EgtDev/Include/EGnGetKeyData.h" #include "/EgtDev/Include/SELkLockId.h"
#include "/EgtDev/Include/SELkKeyProc.h"
#include "/EgtDev/Include/EgtStringConverter.h" #include "/EgtDev/Include/EgtStringConverter.h"
#include "/EgtDev/Include/EgtPointerOwner.h" #include "/EgtDev/Include/EgtPointerOwner.h"
#include "/EgtDev/Include/EgtNumCollection.h" #include "/EgtDev/Include/EgtNumCollection.h"
#include "/EgtDev/Include/EgtKeyCodes.h" #include "/EgtDev/Include/EgtKeyCodes.h"
#include "/EgtDev/Include/SELkLockId.h"
#include "/EgtDev/Include/SELkKeyProc.h"
#include <new> #include <new>
#include <stack> #include <stack>
#include <thread>
using namespace std ; using namespace std ;
//----------------------------------------------------------------------------
class LockAddErase
{
public :
LockAddErase(std::atomic_flag& bAddEraseOn, bool bUse = true): m_bAddEraseOn( bAddEraseOn), m_bUse( bUse)
{ if ( ! m_bUse) return ;
while ( m_bAddEraseOn.test_and_set()) {
this_thread::sleep_for( chrono::nanoseconds{ 1}) ;
}
} ;
~LockAddErase( void)
{ if ( ! m_bUse) return ;
m_bAddEraseOn.clear() ;
} ;
private :
std::atomic_flag& m_bAddEraseOn ;
bool m_bUse ;
} ;
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
IGeomDB* IGeomDB*
CreateGeomDB( void) CreateGeomDB( void)
@@ -62,25 +39,20 @@ CreateGeomDB( void)
// verifico la chiave e le opzioni // verifico la chiave e le opzioni
unsigned int nOpt1, nOpt2 ; unsigned int nOpt1, nOpt2 ;
int nOptExpDays ; int nOptExpDays ;
int nRet = GetEGnKeyOptions( KEY_BASELIB_PROD, KEY_BASELIB_VER, KEY_BASELIB_LEV, int nRet = GetKeyOptions( GetEGkKey(), KEY_BASELIB_PROD, KEY_BASELIB_VER, KEY_BASELIB_LEV,
nOpt1, nOpt2, nOptExpDays) ; nOpt1, nOpt2, nOptExpDays) ;
if ( ! GetEGkNetHwKey())
nRet = GetKeyOptions( GetEGkKey(), KEY_BASELIB_PROD, KEY_BASELIB_VER, KEY_BASELIB_LEV,
nOpt1, nOpt2, nOptExpDays) ;
// controllo i risultati
if ( nRet != KEY_OK && ! EqualNoCase( GetEGkKey(), "EGkBase")) { if ( nRet != KEY_OK && ! EqualNoCase( GetEGkKey(), "EGkBase")) {
if ( nRet != KEY_OK) { if ( nRet != KEY_OK) {
string sErr = "Error on Key (GKC/" + ToString( nRet) + ")" ; string sErr = "Error on Key (GKC/" + ToString( nRet) + ")" ;
LOG_ERROR( GetEGkLogger(), sErr.c_str()) ; LOG_ERROR( GetEGkLogger(), sErr.c_str()) ;
return nullptr ; return nullptr ;
} }
if ( ( nOpt1 & KEYOPT_EGK_BASE) == 0 || nOptExpDays < GetCurrDay()) { if ( (nOpt1 & KEYOPT_EGK_BASE) == 0 || nOptExpDays < GetCurrDay()) {
string sErr = "Error on Key (GKC/OPT)" ; string sErr = "Error on Key (GKC/OPT)" ;
LOG_ERROR( GetEGkLogger(), sErr.c_str()) ; LOG_ERROR( GetEGkLogger(), sErr.c_str()) ;
return nullptr ; return nullptr ;
} }
} }
// creo il GeomDB // creo il GeomDB
return static_cast<IGeomDB*> ( new( nothrow) GeomDB) ; return static_cast<IGeomDB*> ( new( nothrow) GeomDB) ;
} }
@@ -90,7 +62,6 @@ CreateGeomDB( void)
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
GeomDB::GeomDB( void) GeomDB::GeomDB( void)
{ {
m_bAddEraseOn.clear() ;
m_GrpRadix.SetGeomDB( this) ; m_GrpRadix.SetGeomDB( this) ;
m_GrpRadix.m_nId = GDB_ID_ROOT ; m_GrpRadix.m_nId = GDB_ID_ROOT ;
m_GrpRadix.SetMaterial( Color()) ; m_GrpRadix.SetMaterial( Color()) ;
@@ -303,18 +274,14 @@ GeomDB::Save( int nId, const string& sFileOut, int nFlag) const
// verifico la chiave e le opzioni // verifico la chiave e le opzioni
unsigned int nOpt1, nOpt2 ; unsigned int nOpt1, nOpt2 ;
int nOptExpDays ; int nOptExpDays ;
int nRet = GetEGnKeyOptions( KEY_BASELIB_PROD, KEY_BASELIB_VER, KEY_BASELIB_LEV, int nRet = GetKeyOptions( GetEGkKey(), KEY_BASELIB_PROD, KEY_BASELIB_VER, KEY_BASELIB_LEV,
nOpt1, nOpt2, nOptExpDays) ; nOpt1, nOpt2, nOptExpDays) ;
if ( ! GetEGkNetHwKey())
nRet = GetKeyOptions( GetEGkKey(), KEY_BASELIB_PROD, KEY_BASELIB_VER, KEY_BASELIB_LEV,
nOpt1, nOpt2, nOptExpDays) ;
// controllo i risultati
if ( nRet != KEY_OK) { if ( nRet != KEY_OK) {
string sErr = "Error on Key (GKS/" + ToString( nRet) + ")" ; string sErr = "Error on Key (GKS/" + ToString( nRet) + ")" ;
LOG_ERROR( GetEGkLogger(), sErr.c_str()) ; LOG_ERROR( GetEGkLogger(), sErr.c_str()) ;
return false ; return false ;
} }
if ( ( nOpt1 & KEYOPT_EGK_SAVE) == 0 || nOptExpDays < GetCurrDay()) { if ( (nOpt1 & KEYOPT_EGK_SAVE) == 0 || nOptExpDays < GetCurrDay()) {
string sErr = "Error on Key (GKS/OPT)" ; string sErr = "Error on Key (GKS/OPT)" ;
LOG_ERROR( GetEGkLogger(), sErr.c_str()) ; LOG_ERROR( GetEGkLogger(), sErr.c_str()) ;
return false ; return false ;
@@ -417,18 +384,14 @@ GeomDB::Save( const INTVECTOR& vId, const string& sFileOut, int nFlag) const
// verifico la chiave e le opzioni // verifico la chiave e le opzioni
unsigned int nOpt1, nOpt2 ; unsigned int nOpt1, nOpt2 ;
int nOptExpDays ; int nOptExpDays ;
int nRet = GetEGnKeyOptions( KEY_BASELIB_PROD, KEY_BASELIB_VER, KEY_BASELIB_LEV, int nRet = GetKeyOptions( GetEGkKey(), KEY_BASELIB_PROD, KEY_BASELIB_VER, KEY_BASELIB_LEV,
nOpt1, nOpt2, nOptExpDays) ; nOpt1, nOpt2, nOptExpDays) ;
if ( ! GetEGkNetHwKey())
nRet = GetKeyOptions( GetEGkKey(), KEY_BASELIB_PROD, KEY_BASELIB_VER, KEY_BASELIB_LEV,
nOpt1, nOpt2, nOptExpDays) ;
// controllo i risultati
if ( nRet != KEY_OK) { if ( nRet != KEY_OK) {
string sErr = "Error on Key (GKS/" + ToString( nRet) + ")" ; string sErr = "Error on Key (GKS/" + ToString( nRet) + ")" ;
LOG_ERROR( GetEGkLogger(), sErr.c_str()) ; LOG_ERROR( GetEGkLogger(), sErr.c_str()) ;
return false ; return false ;
} }
if ( ( nOpt1 & KEYOPT_EGK_SAVE) == 0 || nOptExpDays < GetCurrDay()) { if ( (nOpt1 & KEYOPT_EGK_SAVE) == 0 || nOptExpDays < GetCurrDay()) {
string sErr = "Error on Key (GKS/OPT)" ; string sErr = "Error on Key (GKS/OPT)" ;
LOG_ERROR( GetEGkLogger(), sErr.c_str()) ; LOG_ERROR( GetEGkLogger(), sErr.c_str()) ;
return false ; return false ;
@@ -453,7 +416,7 @@ GeomDB::Save( const INTVECTOR& vId, const string& sFileOut, int nFlag) const
return false ; return false ;
// ciclo sugli oggetti da esportare // ciclo sugli oggetti da esportare
INTUNORDSET usSavedId ; unordered_set<int> usSavedId ;
for ( const auto nId : vId) { for ( const auto nId : vId) {
// se già salvato, passo oltre // se già salvato, passo oltre
@@ -550,10 +513,7 @@ GeomDB::SaveHeader( NgeWriter& ngeOut) const
// LockId del sistema come commento // LockId del sistema come commento
string sLockId ; string sLockId ;
if ( GetEGkNetHwKey()) { if ( ! GetLockId( sLockId)) {
sLockId = "NET-000000" ;
}
else if ( ! GetLockId( sLockId)) {
LOG_ERROR( GetEGkLogger(), "Error on Key (1)") LOG_ERROR( GetEGkLogger(), "Error on Key (1)")
return false ; return false ;
} }
@@ -618,32 +578,25 @@ GeomDB::GetGdbObj( int nId) const
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool bool
GeomDB::InsertInGeomDB( GdbObj* pGObj, int nRefId, int nSonBeforeAfter, bool bLockAddErase, bool bTestId) GeomDB::InsertInGeomDB( GdbObj* pGObj, int nRefId, int nSonBeforeAfter, bool bTestId)
{ {
// verifico validità oggetto puntato // verifico validità oggetto puntato
if ( pGObj == nullptr) if ( pGObj == nullptr)
return false ; return false ;
// verifico validità del riferimento // se richiesta, verifica validità e unicità del nome
if ( nRefId < GDB_ID_ROOT) if ( bTestId && ( pGObj->m_nId <= GDB_ID_ROOT || ExistsObj( pGObj->m_nId)))
return false ; return false ;
// oggetto e riferimento non possono essere la stessa cosa // oggetto e riferimento non possono essere la stessa cosa
if ( pGObj->m_nId == nRefId) if ( pGObj->m_nId == nRefId)
return ( ! IS_GDB_SON( nSonBeforeAfter)) ; return ( ! IS_GDB_SON( nSonBeforeAfter)) ;
// verifico unicità esecuzione, se necessaria
LockAddErase Lock( m_bAddEraseOn, bLockAddErase) ;
// cerco il riferimento // cerco il riferimento
GdbObj* pGRef = GetGdbObj( nRefId) ; GdbObj* pGRef = GetGdbObj( nRefId) ;
if ( pGRef == nullptr) if ( pGRef == nullptr)
return false ; return false ;
// se richiesta, verifica validità e unicità del nome
if ( bTestId && ( pGObj->m_nId <= GDB_ID_ROOT || ExistsObj( pGObj->m_nId)))
return false ;
// assegno il riferimento al DB geometrico // assegno il riferimento al DB geometrico
pGObj->SetGeomDB( this) ; pGObj->SetGeomDB( this) ;
@@ -659,7 +612,7 @@ GeomDB::InsertInGeomDB( GdbObj* pGObj, int nRefId, int nSonBeforeAfter, bool bLo
} }
// inserisco come figlio, in testa alla lista del padre // inserisco come figlio, in testa alla lista del padre
else if ( nSonBeforeAfter == GDB_FIRST_SON){ else if ( nSonBeforeAfter == GDB_FIRST_SON){
GdbGroup* pGroup = ::GetGdbGroup( pGRef) ; GdbGroup* pGroup = dynamic_cast<GdbGroup*> ( pGRef) ;
if ( pGroup == nullptr) if ( pGroup == nullptr)
return false ; return false ;
// inserisco in testa alla lista del padre // inserisco in testa alla lista del padre
@@ -668,7 +621,7 @@ GeomDB::InsertInGeomDB( GdbObj* pGObj, int nRefId, int nSonBeforeAfter, bool bLo
} }
// inserisco come figlio, in coda alla lista del padre // inserisco come figlio, in coda alla lista del padre
else { else {
GdbGroup* pGroup = ::GetGdbGroup( pGRef) ; GdbGroup* pGroup = dynamic_cast<GdbGroup*> ( pGRef) ;
if ( pGroup == nullptr) if ( pGroup == nullptr)
return false ; return false ;
// inserisco in coda alla lista del padre // inserisco in coda alla lista del padre
@@ -697,8 +650,6 @@ GeomDB::InsertGroup( int nId, int nRefId, int nSonBeforeAfter, const Frame3d& fr
// verifico validità apparente RefId // verifico validità apparente RefId
if ( nRefId < GDB_ID_ROOT) if ( nRefId < GDB_ID_ROOT)
return GDB_ID_NULL ; return GDB_ID_NULL ;
// verifico unicità esecuzione
LockAddErase Lock( m_bAddEraseOn) ;
// verifico validità Id // verifico validità Id
if ( nId <= GDB_ID_ROOT) if ( nId <= GDB_ID_ROOT)
nId = m_IdManager.GetNewId() ; nId = m_IdManager.GetNewId() ;
@@ -713,7 +664,7 @@ GeomDB::InsertGroup( int nId, int nRefId, int nSonBeforeAfter, const Frame3d& fr
// assegno riferimento // assegno riferimento
pGdbGroup->SetFrame( frFrame) ; pGdbGroup->SetFrame( frFrame) ;
// inserisco nel DB // inserisco nel DB
if ( ! InsertInGeomDB( pGdbGroup, nRefId, nSonBeforeAfter, false)) { if ( ! InsertInGeomDB( pGdbGroup, nRefId, nSonBeforeAfter)) {
delete pGdbGroup ; delete pGdbGroup ;
return GDB_ID_NULL ; return GDB_ID_NULL ;
} }
@@ -734,8 +685,6 @@ GeomDB::InsertGeoObj( int nId, int nRefId, int nSonBeforeAfter, IGeoObj* pGeoObj
{ {
// assegno GeoObj a gestore puntatore con rilascio automatico // assegno GeoObj a gestore puntatore con rilascio automatico
PtrOwner<IGeoObj> pRPGeoObj( pGeoObj) ; PtrOwner<IGeoObj> pRPGeoObj( pGeoObj) ;
// verifico unicità esecuzione
LockAddErase Lock( m_bAddEraseOn) ;
// verifico validità identificativo // verifico validità identificativo
if ( nId <= GDB_ID_ROOT) if ( nId <= GDB_ID_ROOT)
nId = m_IdManager.GetNewId() ; nId = m_IdManager.GetNewId() ;
@@ -753,7 +702,7 @@ GeomDB::InsertGeoObj( int nId, int nRefId, int nSonBeforeAfter, IGeoObj* pGeoObj
// assegno dati // assegno dati
pGdbGeo->m_pGeoObj = Release( pRPGeoObj) ; pGdbGeo->m_pGeoObj = Release( pRPGeoObj) ;
// inserisco nel DB // inserisco nel DB
if ( ! InsertInGeomDB( pGdbGeo, nRefId, nSonBeforeAfter, false)) { if ( ! InsertInGeomDB( pGdbGeo, nRefId, nSonBeforeAfter)) {
delete pGdbGeo ; delete pGdbGeo ;
return GDB_ID_NULL ; return GDB_ID_NULL ;
} }
@@ -1236,9 +1185,6 @@ GeomDB::GetRefBBox( int nId, const Frame3d& frRef, BBox3d& b3Ref, int nFlag) con
int int
GeomDB::Copy( int nIdSou, int nIdDest, int nRefId, int nSonBeforeAfter, bool bGlob) GeomDB::Copy( int nIdSou, int nIdDest, int nRefId, int nSonBeforeAfter, bool bGlob)
{ {
// verifico unicità esecuzione
LockAddErase Lock( m_bAddEraseOn) ;
// verifico Id destinazione // verifico Id destinazione
if ( nIdDest <= GDB_ID_ROOT) if ( nIdDest <= GDB_ID_ROOT)
nIdDest = m_IdManager.GetNewId() ; nIdDest = m_IdManager.GetNewId() ;
@@ -1281,7 +1227,7 @@ GeomDB::Copy( int nIdSou, int nIdDest, int nRefId, int nSonBeforeAfter, bool bGl
} }
// inserisco nel DB (non rilascio il puntatore) // inserisco nel DB (non rilascio il puntatore)
if ( ! InsertInGeomDB( pGdODest, nRefId, nSonBeforeAfter, false)) if ( ! InsertInGeomDB( pGdODest, nRefId, nSonBeforeAfter))
return GDB_ID_NULL ; return GDB_ID_NULL ;
// rilascio il puntatore // rilascio il puntatore
@@ -1293,17 +1239,10 @@ GeomDB::Copy( int nIdSou, int nIdDest, int nRefId, int nSonBeforeAfter, bool bGl
bool bool
GeomDB::Relocate( int nId, int nRefId, int nSonBeforeAfter, bool bGlob) GeomDB::Relocate( int nId, int nRefId, int nSonBeforeAfter, bool bGlob)
{ {
// verifico validità del riferimento // l'oggetto e il riferimento non possono coincidere
if ( nRefId < GDB_ID_ROOT)
return false ;
// l'oggetto e il riferimento non possono coincidere
if ( nId == nRefId) if ( nId == nRefId)
return ( ! IS_GDB_SON( nSonBeforeAfter)) ; return ( ! IS_GDB_SON( nSonBeforeAfter)) ;
// verifico unicità esecuzione
LockAddErase Lock( m_bAddEraseOn) ;
// verifico esistenza dell'oggetto // verifico esistenza dell'oggetto
GdbObj* pGdbObj = GetGdbObj( nId) ; GdbObj* pGdbObj = GetGdbObj( nId) ;
if ( pGdbObj == nullptr) if ( pGdbObj == nullptr)
@@ -1347,7 +1286,7 @@ GeomDB::Relocate( int nId, int nRefId, int nSonBeforeAfter, bool bGlob)
pGdbObj->Remove() ; pGdbObj->Remove() ;
// lo inserisco nella posizione opportuna // lo inserisco nella posizione opportuna
if ( ! InsertInGeomDB( pGdbObj, nRefId, nSonBeforeAfter, false, false)) { if ( ! InsertInGeomDB( pGdbObj, nRefId, nSonBeforeAfter, false)) {
// in caso di errore (condizione assai remota qui) cancello tutto // in caso di errore (condizione assai remota qui) cancello tutto
m_IdManager.RemoveObj( pGdbObj->m_nId) ; m_IdManager.RemoveObj( pGdbObj->m_nId) ;
m_SelManager.RemoveObj( pGdbObj) ; m_SelManager.RemoveObj( pGdbObj) ;
@@ -1428,14 +1367,9 @@ GeomDB::GetNewId( void) const
bool bool
GeomDB::ChangeId( int nId, int nNewId) GeomDB::ChangeId( int nId, int nNewId)
{ {
// se Id non validi, ritorno errore
if ( nId <= GDB_ID_ROOT || nNewId <= GDB_ID_ROOT)
return false ;
// se Id identici, non faccio alcunché // se Id identici, non faccio alcunché
if ( nNewId == nId) if ( nNewId == nId)
return true ; return true ;
// verifico unicità esecuzione
LockAddErase Lock( m_bAddEraseOn) ;
// verifico nuovo Id // verifico nuovo Id
if ( ExistsObj( nNewId)) if ( ExistsObj( nNewId))
return false ; return false ;
@@ -1476,10 +1410,7 @@ GeomDB::Erase( GdbObj* pGdbObj)
if ( pGdbObj == nullptr || pGdbObj == &m_GrpRadix) if ( pGdbObj == nullptr || pGdbObj == &m_GrpRadix)
return false ; return false ;
// verifico unicità esecuzione // notifico eventuale UserObj
LockAddErase Lock( m_bAddEraseOn) ;
// notifico eventuale UserObj
if ( pGdbObj->m_pUserObj != nullptr) { if ( pGdbObj->m_pUserObj != nullptr) {
// recupero il successivo // recupero il successivo
const GdbObj* pGdbNext = pGdbObj->GetNext() ; const GdbObj* pGdbNext = pGdbObj->GetNext() ;
@@ -1504,10 +1435,6 @@ GeomDB::RemoveGeoObjAndErase( int nId)
// non si può cancellare il gruppo radice (escludo anche Id non validi) // non si può cancellare il gruppo radice (escludo anche Id non validi)
if ( nId <= GDB_ID_ROOT) if ( nId <= GDB_ID_ROOT)
return nullptr ; return nullptr ;
// verifico unicità esecuzione
LockAddErase Lock( m_bAddEraseOn) ;
// recupero l'oggetto geometrico // recupero l'oggetto geometrico
GdbGeo* pGdbGeo = ::GetGdbGeo( m_IdManager.FindObj( nId)) ; GdbGeo* pGdbGeo = ::GetGdbGeo( m_IdManager.FindObj( nId)) ;
if ( pGdbGeo == nullptr) if ( pGdbGeo == nullptr)
@@ -1515,7 +1442,6 @@ GeomDB::RemoveGeoObjAndErase( int nId)
IGeoObj* pGeoObj = pGdbGeo->m_pGeoObj ; IGeoObj* pGeoObj = pGdbGeo->m_pGeoObj ;
// annullo il riferimento alla geometria nell'entità // annullo il riferimento alla geometria nell'entità
pGdbGeo->m_pGeoObj = nullptr ; pGdbGeo->m_pGeoObj = nullptr ;
// tolgo dalla lista e disalloco // tolgo dalla lista e disalloco
pGdbGeo->Remove() ; pGdbGeo->Remove() ;
delete pGdbGeo ; delete pGdbGeo ;
@@ -1551,10 +1477,6 @@ GeomDB::EmptyGroup( GdbObj* pGdbObj)
GdbGroup* pGrp = ::GetGdbGroup( pGdbObj) ; GdbGroup* pGrp = ::GetGdbGroup( pGdbObj) ;
if ( pGrp == nullptr) if ( pGrp == nullptr)
return false ; return false ;
// verifico unicità esecuzione
LockAddErase Lock( m_bAddEraseOn) ;
// lo svuoto // lo svuoto
return pGrp->Clear() ; return pGrp->Clear() ;
} }
@@ -2599,9 +2521,6 @@ GeomDB::GetCalcMaterial( const GdbObj* pGdbObj, Material& mMat) const
Color cCol ; Color cCol ;
if ( pGdbObj->GetCalcMaterial( cCol)) { if ( pGdbObj->GetCalcMaterial( cCol)) {
mMat.Set( cCol) ; mMat.Set( cCol) ;
Color cDiff = cCol ;
cDiff.Intensify( 1.25) ;
mMat.SetDiffuse( cDiff) ;
return true ; return true ;
} }
} }
@@ -2955,19 +2874,6 @@ GeomDB::RemoveInfo( int nId, const string& sKey)
return pGdbObj->RemoveInfo( sKey) ; return pGdbObj->RemoveInfo( sKey) ;
} }
//----------------------------------------------------------------------------
bool
GeomDB::GetAllInfo( int nId, STRVECTOR& vsInfo) const
{
// recupero l'oggetto
const GdbObj* pGdbObj = GetGdbObj( nId) ;
if ( pGdbObj == nullptr)
return false ;
// recupero tutte le Info
return pGdbObj->GetAllInfo( vsInfo) ;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool bool
GeomDB::CopyAllInfoFrom( int nId, int nSouId) GeomDB::CopyAllInfoFrom( int nId, int nSouId)
@@ -2977,7 +2883,7 @@ GeomDB::CopyAllInfoFrom( int nId, int nSouId)
if ( pGdbObj == nullptr) if ( pGdbObj == nullptr)
return false ; return false ;
// recupero l'oggetto sorgente // recupero l'oggetto sorgente
const GdbObj* pGdbObjSou = GetGdbObj( nSouId) ; GdbObj* pGdbObjSou = GetGdbObj( nSouId) ;
if ( pGdbObjSou == nullptr) if ( pGdbObjSou == nullptr)
return false ; return false ;
@@ -2990,51 +2896,6 @@ GeomDB::CopyAllInfoFrom( int nId, int nSouId)
return true ; return true ;
} }
//----------------------------------------------------------------------------
// Stipple (significativo solo per curve)
//----------------------------------------------------------------------------
bool
GeomDB::DumpStipple( int nId, string& sOut, bool bMM, const char* szNewLine) const
{
// recupero l'oggetto
const GdbObj* pGdbObj = GetGdbObj( nId) ;
if ( pGdbObj == nullptr)
return false ;
// eseguo il dump
if ( pGdbObj->m_nStpFactor != 0) {
// nome della texture
sOut += "Stipple=" ;
sOut += ToString( pGdbObj->m_nStpFactor) ;
sOut += "-" + ToString( pGdbObj->m_nStpPattern, 1, 16) ;
sOut += szNewLine ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
GeomDB::SetStipple( int nId, int nFactor, int nPattern)
{
// recupero l'oggetto
GdbObj* pGdbObj = GetGdbObj( nId) ;
if ( pGdbObj == nullptr)
return false ;
// imposto lo stipple
return pGdbObj->SetStipple( nFactor, nPattern) ;
}
//----------------------------------------------------------------------------
bool
GeomDB::GetStipple( int nId, int& nFactor, int& nPattern) const
{
// recupero l'oggetto
const GdbObj* pGdbObj = GetGdbObj( nId) ;
if ( pGdbObj == nullptr)
return false ;
// recupero lo stipple
return pGdbObj->GetStipple( nFactor, nPattern) ;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// TextureData // TextureData
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@@ -3046,7 +2907,7 @@ GeomDB::DumpTextureData( int nId, string& sOut, bool bMM, const char* szNewLine)
if ( pGdbObj == nullptr) if ( pGdbObj == nullptr)
return false ; return false ;
// eseguo il dump // eseguo il dump
if ( pGdbObj->m_pTxrData != nullptr) if ( pGdbObj->m_pTxrData != nullptr)
return pGdbObj->m_pTxrData->Dump( *this, sOut, bMM, szNewLine) ; return pGdbObj->m_pTxrData->Dump( *this, sOut, bMM, szNewLine) ;
else else
return true ; return true ;
+14 -21
View File
@@ -1,13 +1,13 @@
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// EgalTech 2013-2023 // EgalTech 2013-2014
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// File : GeomDB.h Data : 09.07.23 Versione : 2.5g1 // File : GeomDB.h Data : 03.12.14 Versione : 1.5l1
// Contenuto : Dichiarazione della classe GeomDB. // Contenuto : Dichiarazione della classe GeomDB.
// //
// //
// //
// Modifiche : 22.01.13 DS Creazione modulo. // Modifiche : 22.01.13 DS Creazione modulo.
// // 03.12.14 DS Aggiunta gestione riferimento di griglia.
// //
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@@ -20,7 +20,6 @@
#include "SelManager.h" #include "SelManager.h"
#include "GdbMaterialMgr.h" #include "GdbMaterialMgr.h"
#include "/EgtDev/Include/EGkGeomDB.h" #include "/EgtDev/Include/EGkGeomDB.h"
#include <atomic>
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
class GeomDB : public IGeomDB class GeomDB : public IGeomDB
@@ -180,12 +179,7 @@ class GeomDB : public IGeomDB
bool GetInfo( int nId, const std::string& sKey, STRVECTOR& vsInfo) const override ; bool GetInfo( int nId, const std::string& sKey, STRVECTOR& vsInfo) const override ;
bool ExistsInfo( int nId, const std::string& sKey) const override ; bool ExistsInfo( int nId, const std::string& sKey) const override ;
bool RemoveInfo( int nId, const std::string& sKey) override ; bool RemoveInfo( int nId, const std::string& sKey) override ;
bool GetAllInfo( int nId, STRVECTOR& vsInfo) const override ;
bool CopyAllInfoFrom( int nId, int nSouId) override ; bool CopyAllInfoFrom( int nId, int nSouId) override ;
// Stipple (significativo solo per curve)
bool DumpStipple( int nId, std::string& sOut, bool bMM = true, const char* szNewLine = "\n") const override ;
bool SetStipple( int nId, int nFactor, int nPattern) override ;
bool GetStipple( int nId, int& nFactor, int& nPattern) const override ;
// TextureData // TextureData
bool DumpTextureData( int nId, std::string& sOut, bool bMM = true, const char* szNewLine = "\n") const override ; bool DumpTextureData( int nId, std::string& sOut, bool bMM = true, const char* szNewLine = "\n") const override ;
bool SetTextureName( int nId, const std::string& sTxrName) override ; bool SetTextureName( int nId, const std::string& sTxrName) override ;
@@ -227,14 +221,14 @@ class GeomDB : public IGeomDB
GdbObj* GetGdbObj( int nId) ; GdbObj* GetGdbObj( int nId) ;
const GdbObj* GetGdbObj( int nId) const ; const GdbObj* GetGdbObj( int nId) const ;
GdbGeo* GetGdbGeo( int nId) GdbGeo* GetGdbGeo( int nId)
{ return ::GetGdbGeo( GetGdbObj( nId)) ; } { return dynamic_cast<GdbGeo*>( GetGdbObj( nId)) ; }
const GdbGeo* GetGdbGeo( int nId) const const GdbGeo* GetGdbGeo( int nId) const
{ return ::GetGdbGeo( GetGdbObj( nId)) ; } { return dynamic_cast<const GdbGeo*>( GetGdbObj( nId)) ; }
GdbGroup* GetGdbGroup( int nId) GdbGroup* GetGdbGroup( int nId)
{ return ::GetGdbGroup( GetGdbObj( nId)) ; } { return dynamic_cast<GdbGroup*>( GetGdbObj( nId)) ; }
const GdbGroup* GetGdbGroup( int nId) const const GdbGroup* GetGdbGroup( int nId) const
{ return ::GetGdbGroup( GetGdbObj( nId)) ; } { return dynamic_cast<const GdbGroup*>( GetGdbObj( nId)) ; }
bool InsertInGeomDB( GdbObj* pGObj, int nRefId, int nSonBeforeAfter, bool bLockAddErase = true, bool bTestId = true) ; bool InsertInGeomDB( GdbObj* pGObj, int nRefId, int nSonBeforeAfter, bool bTestId = true) ;
int Copy( int nIdSou, int nIdDest, int nRefId, int nSonBeforeAfter, bool bGlob) ; int Copy( int nIdSou, int nIdDest, int nRefId, int nSonBeforeAfter, bool bGlob) ;
bool Relocate( int nId, int nRefId, int nSonBeforeAfter, bool bGlob) ; bool Relocate( int nId, int nRefId, int nSonBeforeAfter, bool bGlob) ;
bool Erase( GdbObj* pGObj) ; bool Erase( GdbObj* pGObj) ;
@@ -258,11 +252,10 @@ class GeomDB : public IGeomDB
{ return m_IterManager.RemoveGdbIterator( pIter) ; } { return m_IterManager.RemoveGdbIterator( pIter) ; }
private : private :
IdManager m_IdManager ; // gestore del nuovo Id IdManager m_IdManager ; // gestore del nuovo Id
IterManager m_IterManager ; // gestore lista iteratori attivi IterManager m_IterManager ; // gestore lista iteratori attivi
SelManager m_SelManager ; // gestore lista oggetti selezionati SelManager m_SelManager ; // gestore lista oggetti selezionati
GdbMaterialMgr m_MatManager ; // gestore lista materiali GdbMaterialMgr m_MatManager ; // gestore lista materiali
GdbGroup m_GrpRadix ; // gruppo radice di tutto il DB GdbGroup m_GrpRadix ; // gruppo radice di tutto il DB
Frame3d m_GridFrame ; // riferimento della griglia Frame3d m_GridFrame ; // riferimento della griglia
std::atomic_flag m_bAddEraseOn ; // flag esecuzione inserimento o cancellazione in corso (per multi thread)
} ; } ;
-759
View File
@@ -1,759 +0,0 @@
//----------------------------------------------------------------------------
// EgalTech 2015-2018
//----------------------------------------------------------------------------
// File : HashGrids1d.cpp Data : 02.05.22 Versione : 2.4e1
// Contenuto : Funzioni della classe HashGrids1d.
//
//
//
// Modifiche : 04.07.15 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "DllMain.h"
#include "/EgtDev/Include/EGkHashGrids1d.h"
#include "/EgtDev/Include/EGnStringUtils.h"
#include <algorithm>
using namespace std ;
//----------------------------------------------------------------------------
const size_t CellCount = 16 ;
const size_t cellVectorSize = 16 ;
const size_t occupiedCellsVectorSize = 256 ;
const size_t minimalGridDensity = 1 ;
const size_t gridActivationThreshold = 64 ;
const double hierarchyFactor = 2 ;
const double MIN_CELL_SIZE = 5.0 ;
//----------------------------------------------------------------------------
// HashGrid1d
//----------------------------------------------------------------------------
class HashGrid1d
{
private :
struct Cell
{
HashGrids1d::PtrObjVector* m_Objs ; // Vettore dei puntatori agli oggetti nella cella, come puntatore
int* m_neighborOffset ; // Puntatore ad array con offsets per accedere direttamente ai vicini
size_t m_occupiedCellsId ; // Indice della cella nel vettore delle celle occupate
Cell( void)
: m_Objs( nullptr), m_neighborOffset( nullptr), m_occupiedCellsId( 0) {}
} ;
typedef vector<Cell*> CellVector ;
public :
explicit HashGrid1d( double dCellSpan) ;
~HashGrid1d( void) ;
double GetCellSpan( void) const
{ return m_dCellSpan ; }
void Add( HashGrids1d::ObjData& obj) ;
void Remove( HashGrids1d::ObjData& obj) ;
void Update( HashGrids1d::ObjData& obj) ;
void Find( const BBox3d& b3Test, INTVECTOR& vnIds) ;
void Clear( void) ;
private :
void InitNeighborOffsets( void) ;
size_t Hash( const Point3d& ptP) const ;
void Add( HashGrids1d::ObjData& obj, Cell* cell) ;
void Remove( HashGrids1d::ObjData& obj, Cell* cell) ;
void Enlarge( void) ;
static inline bool PowerOfTwo( size_t number) ;
private :
Cell* m_cell ; // Vettore di celle della griglia
size_t m_CellCount ; // Numero di celle allocate in direzione Z
size_t m_HashMask ; // Maschera di bit per calcolo hash
size_t m_enlargementThreshold ; // Soglia corrente per incremetare le dimensioni della griglia
double m_dCellSpan ; // Dimensione di una cella (cubica) della griglia
double m_dInvCellSpan ; // Inverso della dimensione di una cella
CellVector m_occupiedCells ; // Vettore delle celle occupate in questa griglia
size_t m_objCount ; // Numero di oggetti presenti in questa griglia
int m_stdNeighborOffset[3] ; // Array degli offset standard per le adiacenze
BBox3d m_b3Grid ; // Box totale degli oggetti inseriti in questa griglia
} ;
//----------------------------------------------------------------------------
HashGrid1d::HashGrid1d( double dCellSpan)
{
// Initialization of all member variables and ...
m_CellCount = PowerOfTwo( CellCount) ? CellCount : 16 ;
m_HashMask = m_CellCount - 1 ;
m_enlargementThreshold = m_CellCount / minimalGridDensity ;
// allocazione dell'array lineare che rappresenta lo hash grid.
m_cell = new Cell[ m_CellCount] ;
// ogni cella è già inizializzata come vuota
// imposto gli offset ai vicini
InitNeighborOffsets() ;
m_dCellSpan = max( dCellSpan, 10 * EPS_SMALL) ;
m_dInvCellSpan = 1. / dCellSpan ;
m_occupiedCells.reserve( occupiedCellsVectorSize) ;
m_objCount = 0 ;
}
//----------------------------------------------------------------------------
HashGrid1d::~HashGrid1d( void)
{
Clear() ;
for ( Cell* pCell = m_cell ; pCell < m_cell + m_CellCount ; ++ pCell) {
if ( pCell->m_neighborOffset != m_stdNeighborOffset)
delete[] pCell->m_neighborOffset ;
}
delete[] m_cell ;
}
//----------------------------------------------------------------------------
void
HashGrid1d::Add( HashGrids1d::ObjData& obj)
{
// If adding the body will cause the total number of bodies assigned to this grid to exceed the
// enlargement threshold, the size of this hash grid must be increased.
if ( m_objCount == m_enlargementThreshold)
Enlarge() ;
// Calculate (and store) the hash value (= the body's cell association) and ...
size_t h = Hash( obj.box.GetMin()) ;
obj.nHash = h ;
// ... insert the body into the corresponding cell.
Cell* pCell = m_cell + h ;
Add( obj, pCell) ;
++ m_objCount ;
// Aggiorno box di griglia
m_b3Grid.Add( obj.box) ;
}
//----------------------------------------------------------------------------
void
HashGrid1d::Remove( HashGrids1d::ObjData& obj)
{
// The stored hash value (= the body's cell association) is used in order to directly access the
// cell from which this body will be removed.
Cell* pCell = m_cell + obj.nHash ;
Remove( obj, pCell) ;
-- m_objCount ;
}
//----------------------------------------------------------------------------
void
HashGrid1d::Update( HashGrids1d::ObjData& obj)
{
// The hash value is recomputed based on the body's current spatial location.
size_t newHash = Hash( obj.box.GetMin()) ;
size_t oldHash = obj.nHash ;
// If this new hash value is identical to the hash value of the previous time step, the body
// remains assigned to its current grid cell.
if ( newHash == oldHash)
return ;
// Only if the hash value changes, the cell association has to be changed, too - meaning, the
// body has to be removed from its currently assigned cell and ...
Cell* pCell = m_cell + oldHash ;
Remove( obj, pCell) ;
obj.nHash = newHash ;
// ... stored in the cell that corresponds to the new hash value.
pCell = m_cell + newHash ;
Add( obj, pCell) ;
// Aggiorno box di griglia
m_b3Grid.Add( obj.box) ;
}
//----------------------------------------------------------------------------
void
HashGrid1d::Find( const BBox3d& b3Test, INTVECTOR& vnIds)
{
// Limito il box a quello di griglia
BBox3d b3Int ;
if ( ! b3Test.FindIntersection( m_b3Grid, b3Int))
return ;
// Recupero gli estremi del box
Point3d ptMin ;
double dXDim, dYDim, dZDim ;
if ( ! b3Int.GetMinDim( ptMin, dXDim, dYDim, dZDim))
return ;
// Sposto p.to minimo in meno di una cella (oggetti possono occupare 2 celle) e allargo tutto di EPS_SMALL
ptMin -= Vector3d( 0, 0, 1) * ( m_dCellSpan + EPS_SMALL) ;
dZDim += m_dCellSpan + 2 * EPS_SMALL ;
// Numero di celle da esplorare sull'asse Z
int nZSpan = min( static_cast<int>( ceil( dZDim * m_dInvCellSpan)), int( m_CellCount)) ;
//string sOut = "Celle=" + ToString( int( m_CellCount)) + " Occupate=" + ToString( int(m_occupiedCells.size())) + " Span=" + ToString( nZSpan) ;
//LOG_INFO( GetEGkLogger(), sOut.c_str()) ;
// Se conviene verificare queste celle
if ( nZSpan < 5 * int( m_occupiedCells.size())) {
// cella di base
int nZ = static_cast<int>( Hash( ptMin)) ;
for ( int i = 0 ; i <= nZSpan ; ++ i) {
// inserisco in lista gli oggetti della cella
if ( m_cell[nZ].m_Objs != nullptr) {
for ( auto pObj : *( m_cell[nZ].m_Objs)) {
if ( b3Int.Overlaps( pObj->box))
vnIds.push_back( pObj->nId) ;
}
}
// passo alla successiva in Z+
nZ += m_cell[nZ].m_neighborOffset[2] ;
}
}
// altrimenti verifico direttamente tutte e sole quelle occupate
else {
// ciclo sulle celle occupate
for ( auto cell : m_occupiedCells) {
// inserisco in lista gli oggetti della cella
if ( cell->m_Objs != nullptr) {
for ( auto pObj : *(cell->m_Objs)) {
if ( b3Int.Overlaps( pObj->box))
vnIds.push_back( pObj->nId) ;
}
}
}
}
}
//----------------------------------------------------------------------------
void
HashGrid1d::Clear( void)
{
for ( auto cell : m_occupiedCells) {
delete cell->m_Objs ;
cell->m_Objs = nullptr ;
}
m_occupiedCells.clear() ;
m_objCount = 0 ;
m_b3Grid.Reset() ;
}
//----------------------------------------------------------------------------
void
HashGrid1d::InitNeighborOffsets( void)
{
int nc = static_cast<int>( m_CellCount) ;
// Initialization of the grid-global offset array that is valid for all inner cells in the hash grid.
m_stdNeighborOffset[0] = -1 ;
m_stdNeighborOffset[1] = 0 ;
m_stdNeighborOffset[2] = 1 ;
// Allocation and initialization of the offset arrays of all the border cells. All inner cells
// are set to point to the grid-global offset array.
Cell* c = m_cell ;
for ( int i = 0 ; i < nc ; ++ i, ++ c) {
// cella di bordo
if ( i == 0) {
c->m_neighborOffset = new int[3] ;
c->m_neighborOffset[0] = nc - 1 ;
c->m_neighborOffset[1] = 0 ;
c->m_neighborOffset[2] = 1 ;
}
else if ( i == nc - 1) {
c->m_neighborOffset = new int[3] ;
c->m_neighborOffset[0] = -1 ;
c->m_neighborOffset[1] = 0 ;
c->m_neighborOffset[2] = -nc + 1 ;
}
// cella interna
else {
c->m_neighborOffset = m_stdNeighborOffset ;
}
}
}
//----------------------------------------------------------------------------
size_t
HashGrid1d::Hash( const Point3d& ptP) const
{
size_t nHash ;
if ( ptP.z < 0) {
double i = ( - ptP.z ) * m_dInvCellSpan ;
nHash = m_CellCount - 1 - ( static_cast<size_t>( i ) & m_HashMask) ;
}
else {
double i = ptP.z * m_dInvCellSpan ;
nHash = static_cast<size_t>( i ) & m_HashMask ;
}
return nHash ;
}
//----------------------------------------------------------------------------
void
HashGrid1d::Add( HashGrids1d::ObjData& obj, Cell* cell)
{
// If this cell is already occupied by other bodies, which means the pointer to the body
// container holds a valid address and thus the container itself is properly initialized, then
// the body is simply added to this already existing body container. Note that the index position
// is memorized (=> "body->setCellId()") in order to ensure constant time removal.
if ( cell->m_Objs != nullptr) {
obj.nCellId = cell->m_Objs->size() ;
cell->m_Objs->push_back( &obj) ;
}
// If, however, the cell is still empty, then the object container, first of all, must be created
// (i.e., allocated) and properly initialized (i.e., sufficient initial storage capacity must be
// reserved). Furthermore, the cell must be inserted into the grid-global vector 'm_occupiedCells'
// in which all cells that are currently occupied by bodies are recorded.
else {
cell->m_Objs = new HashGrids1d::PtrObjVector ;
cell->m_Objs->reserve( cellVectorSize) ;
obj.nCellId = 0 ;
cell->m_Objs->push_back( &obj) ;
cell->m_occupiedCellsId = m_occupiedCells.size() ;
m_occupiedCells.push_back( cell) ;
}
}
//----------------------------------------------------------------------------
void
HashGrid1d::Remove( HashGrids1d::ObjData& obj, Cell* cell )
{
// If the body is the last body that is stored in this cell ...
if ( cell->m_Objs->size() == 1) {
// ... the cell's body container is destroyed and ...
delete cell->m_Objs ;
cell->m_Objs = nullptr ;
// ... the cell is removed from the grid-global vector 'm_occupiedCells' that records all
// body-occupied cells. Since the cell memorized its index (=> 'm_occupiedCellsId') in this
// vector, it can be removed in constant time, O(1).
if ( cell->m_occupiedCellsId == m_occupiedCells.size() - 1) {
m_occupiedCells.pop_back() ;
}
else {
Cell* lastCell = m_occupiedCells.back() ;
m_occupiedCells.pop_back() ;
lastCell->m_occupiedCellsId = cell->m_occupiedCellsId ;
m_occupiedCells[ cell->m_occupiedCellsId ] = lastCell ;
}
}
// If the body is *not* the last body that is stored in this cell ...
else {
size_t cellId = obj.nCellId ;
// ... the body is removed from the cell's body container. Since the body memorized its
// index (=> 'cellId') in this container, it can be removed in constant time, O(1).
if ( cellId == cell->m_Objs->size() - 1) {
cell->m_Objs->pop_back() ;
}
else {
HashGrids1d::ObjData* lastElement = cell->m_Objs->back() ;
cell->m_Objs->pop_back() ;
lastElement->nCellId = cellId ;
(*cell->m_Objs)[ cellId] = lastElement ;
}
}
}
//----------------------------------------------------------------------------
void
HashGrid1d::Enlarge( void)
{
HashGrids1d::PtrObjVector PObjVecTemp ;
PObjVecTemp.reserve( m_objCount) ;
// All objs that are assigned to this grid are temporarily removed, ...
for ( auto cell = m_occupiedCells.begin() ; cell < m_occupiedCells.end() ; ++ cell) {
HashGrids1d::PtrObjVector* cellBodies = (*cell)->m_Objs ;
for ( auto e = cellBodies->begin() ; e < cellBodies->end() ; ++ e) {
PObjVecTemp.push_back( *e) ;
}
}
// ... the grid's current data structures are deleted, ...
Clear() ;
for ( auto pCell = m_cell ; pCell < m_cell + m_CellCount ; ++ pCell) {
if ( pCell->m_neighborOffset != m_stdNeighborOffset)
delete[] pCell->m_neighborOffset ;
}
delete[] m_cell ;
// ... the number of cells is doubled in each coordinate direction, ...
m_CellCount *= 2 ;
m_HashMask = m_CellCount - 1 ;
// ... a new threshold for enlarging this hash grid is set, ...
m_enlargementThreshold = m_CellCount / minimalGridDensity ;
// ... a new linear array of cells representing this enlarged hash grid is allocated and ...
m_cell = new Cell[ m_CellCount] ;
// ... initialized, and finally ...
InitNeighborOffsets() ;
// ... all previously removed objs are reinserted.
for ( auto p = PObjVecTemp.begin() ; p < PObjVecTemp.end() ; ++ p) {
Add( **p) ;
}
}
//----------------------------------------------------------------------------
bool
HashGrid1d::PowerOfTwo( size_t number)
{
return ( ( number > 0) && ( ( number & ( number - 1)) == 0)) ;
}
//----------------------------------------------------------------------------
// HashGrids1d
//----------------------------------------------------------------------------
HashGrids1d::HashGrids1d( void)
{
try {
// Finchè il numero di oggetti non supera la soglia non si usano le griglie
m_nonGridObjs.reserve( gridActivationThreshold) ;
m_bActivate = true ;
m_bGridActive = false ;
}
catch(...) {
LOG_ERROR( GetEGkLogger(), "Error in HashGrids1d constructor") ;
}
}
//----------------------------------------------------------------------------
HashGrids1d::~HashGrids1d( void)
{
// Delete all grids that are stored in the grid hierarchy (=> m_GridList).
for ( auto pGrid : m_GridList) {
delete pGrid ;
}
}
//----------------------------------------------------------------------------
void
HashGrids1d::SetActivationGrid( bool bActivate)
{
m_bActivate = bActivate ;
}
//----------------------------------------------------------------------------
bool
HashGrids1d::Add( int nObjId, const BBox3d& box)
{
try {
// The body is marked as being added to 'm_objsToAdd' by setting the grid pointer to nullptr and
// setting the cell-ID to '0'. Additionally, the hash value is used to memorize the body's
// index position in the 'm_objsToAdd' vector.
m_ObjsList.emplace_back( nObjId, box, nullptr, m_objsToAdd.size(), 0) ;
// inserisco nel Map
m_ObjsMap.emplace( nObjId, &(m_ObjsList.back())) ;
// Temporarily add the body to 'm_objsToAdd'. As soon as "findContacts()" is called, all
// bodies stored in 'm_objsToAdd' are finally inserted into the data structure.
m_objsToAdd.push_back( &(m_ObjsList.back())) ;
// Aggiorno il box complessivo
m_b3Objs.Add( box) ;
return true ;
}
catch(...) {
LOG_ERROR( GetEGkLogger(), "Error in HashGrids1d::Add") ;
return false ;
}
}
//----------------------------------------------------------------------------
bool
HashGrids1d::Modify( int nObjId, const BBox3d& box)
{
// Cerco l'oggetto con l'Id voluto
auto iIter = m_ObjsMap.find( nObjId) ;
if ( iIter == m_ObjsMap.end())
return false ;
ObjData* pObj = iIter->second ;
if ( pObj == nullptr)
return false ;
// Modifico il suo box
pObj->box = box ;
// Aggiorno il box complessivo
m_b3Objs.Add( box) ;
return true ;
}
//----------------------------------------------------------------------------
bool
HashGrids1d::Remove( int nObjId)
{
// Cerco l'oggetto con l'Id voluto
auto iIter = m_ObjsMap.find( nObjId) ;
if ( iIter == m_ObjsMap.end())
return false ;
ObjData* pObj = iIter->second ;
if ( pObj == nullptr)
return false ;
// Recupero la griglia di appartenenza
HashGrid1d* pGrid = pObj->pHGrid ;
// The body is stored in a hash grid from which it must be removed.
if ( pGrid != nullptr) {
pGrid->Remove( *pObj) ;
}
// The body's grid pointer is equal to nullptr.
// => The body is either stored in 'm_objsToAdd' (-> cell-ID = 0) or 'm_nonGridObjs' (-> cell-ID = 1).
else {
if ( pObj->nCellId == 0) {
// the body's hash value => index of this body in 'm_objsToAdd'
if ( pObj->nHash == m_objsToAdd.size() - 1) {
m_objsToAdd.pop_back() ;
}
else if ( pObj->nHash < m_objsToAdd.size()) {
ObjData* pLastObj = m_objsToAdd.back() ;
m_objsToAdd.pop_back() ;
pLastObj->nHash = pObj->nHash ;
m_objsToAdd[ pObj->nHash] = pLastObj ;
}
else
return false ;
}
else {
// the body's hash value => index of this body in 'm_nonGridObjs'
if ( pObj->nHash == m_nonGridObjs.size() - 1) {
m_nonGridObjs.pop_back();
}
else if ( pObj->nHash < m_nonGridObjs.size()) {
ObjData* pLastObj = m_nonGridObjs.back() ;
m_nonGridObjs.pop_back() ;
pLastObj->nHash = pObj->nHash ;
m_nonGridObjs[ pObj->nHash] = pLastObj ;
}
else
return false ;
}
}
return true ;
}
//----------------------------------------------------------------------------
bool
HashGrids1d::Update( void)
{
try {
// Salvo stato di precedente attivazione delle griglie
bool bGridActivePrev = m_bGridActive ;
// Inseriamo gli oggetti presenti nel vettore m_objsToAdd
if ( m_objsToAdd.size() > 0 ) {
for ( auto pObj : m_objsToAdd) {
if ( m_bGridActive)
addGrid( *pObj) ;
else
addList( *pObj) ;
}
m_objsToAdd.clear() ;
}
// Aggiorniamo per eventuali modifiche agli oggetti già precedentemente presenti nelle griglie
if ( bGridActivePrev) {
for ( auto& Obj : m_ObjsList) {
HashGrid1d* pGrid = Obj.pHGrid ;
if ( pGrid != nullptr) {
double dSize = 0 ;
Obj.box.GetDiameter( dSize) ;
double dCellSpan = pGrid->GetCellSpan() ;
if ( dSize >= dCellSpan || dSize < ( dCellSpan / hierarchyFactor)) {
pGrid->Remove( Obj) ;
addGrid( Obj) ;
}
else {
pGrid->Update( Obj) ;
}
}
}
}
return true ;
}
catch(...) {
LOG_ERROR( GetEGkLogger(), "Error in HashGrids1d::Update") ;
return false ;
}
}
//----------------------------------------------------------------------------
bool
HashGrids1d::Find( const BBox3d& b3Test, INTVECTOR& vnIds) const
{
// pulisco il risultato
vnIds.clear() ;
vnIds.reserve( 128) ;
// limito con box globale
BBox3d b3Int ;
if ( ! b3Test.FindIntersection( m_b3Objs, b3Int))
return false ;
// ricerca nelle griglie
if ( m_bGridActive) {
for ( auto pGrid : m_GridList)
pGrid->Find( b3Int, vnIds) ;
}
// ricerca negli oggetti fuori griglia
for ( auto pObj : m_nonGridObjs) {
if ( b3Int.Overlaps( pObj->box))
vnIds.push_back( pObj->nId) ;
}
// ordino il risultato ed elimino gli indici ripetuti
sort( vnIds.begin(), vnIds.end()) ;
vnIds.erase( unique( vnIds.begin(), vnIds.end()), vnIds.end()) ;
return ( vnIds.size() > 0) ;
}
//----------------------------------------------------------------------------
void
HashGrids1d::Clear( void)
{
for ( auto pGrid : m_GridList) {
delete pGrid ;
}
m_GridList.clear() ;
m_bGridActive = false ;
m_nonGridObjs.clear() ;
m_objsToAdd.clear() ;
m_b3Objs.Reset() ;
}
//----------------------------------------------------------------------------
void
HashGrids1d::addGrid( ObjData& obj)
{
double size = - 1 ;
obj.box.GetDiameter( size) ;
// If the body is finite in size, it must be assigned to a grid with suitably sized cells.
if ( size > - EPS_ZERO) {
size = max( size, MIN_CELL_SIZE) ;
HashGrid1d* pGrid = nullptr ;
if ( m_GridList.empty()) {
// If no hash grid yet exists in the hierarchy, an initial hash grid is created
// based on the body's size.
pGrid = new HashGrid1d( size * sqrt( hierarchyFactor)) ;
}
else {
// Check the hierarchy for a hash grid with suitably sized cells - if such a grid does not
// yet exist, it will be created.
double cellSpan = 0;
for ( auto g = m_GridList.begin(); g != m_GridList.end(); ++ g) {
pGrid = *g;
cellSpan = pGrid->GetCellSpan();
if ( size < cellSpan) {
cellSpan /= hierarchyFactor ;
if ( size < cellSpan ) {
while ( size < cellSpan)
cellSpan /= hierarchyFactor ;
pGrid = new HashGrid1d( cellSpan * hierarchyFactor) ;
m_GridList.insert( g, pGrid) ;
}
pGrid->Add( obj) ;
obj.pHGrid = pGrid ;
return ;
}
}
while ( size >= cellSpan)
cellSpan *= hierarchyFactor ;
pGrid = new HashGrid1d( cellSpan) ;
}
pGrid->Add( obj) ;
obj.pHGrid = pGrid ;
m_GridList.push_back( pGrid) ;
return ;
}
// The body - which is infinite in size - is marked as being added to 'm_nonGridObjs' by setting
// the grid pointer to nullptr and setting the cell-ID to '1'. Additionally, the hash value is used
// to memorize the body's index position in the 'm_nonGridObjs' vector.
obj.pHGrid = nullptr ;
obj.nHash = m_nonGridObjs.size() ;
obj.nCellId = 1 ;
m_nonGridObjs.push_back( &obj) ;
}
//----------------------------------------------------------------------------
void
HashGrids1d::addList( ObjData& obj)
{
// Se abilitato e superata la soglia ...
if ( m_bActivate && m_nonGridObjs.size() == gridActivationThreshold) {
if ( gridActivationThreshold > 0) {
// all objs stored in 'm_nonGridObjs' are inserted in grids
for ( size_t i = 0; i < gridActivationThreshold; ++i ) {
addGrid( *m_nonGridObjs[i] );
}
// ... the 'm_nonGridObjs' vector is cleared ...
m_nonGridObjs.clear() ;
}
addGrid( obj) ;
// ... and the usage of the hierarchical hash grids is activated irrevocably.
m_bGridActive = true ;
return ;
}
// The body is marked as being added to 'm_nonGridObjs' by setting the grid pointer to nullptr and
// setting the cell-ID to '1'. Additionally, the hash value is used to memorize the body's index
// position in the 'm_nonGridObjs' vector.
obj.pHGrid = nullptr ;
obj.nHash = m_nonGridObjs.size() ;
obj.nCellId = 1 ;
m_nonGridObjs.push_back( &obj) ;
}
+1 -1
View File
@@ -15,7 +15,7 @@
#include "stdafx.h" #include "stdafx.h"
#include "DllMain.h" #include "DllMain.h"
#include "/EgtDev/Include/EGkHashGrids2d.h" #include "/EgtDev/Include/EGkHashGrids2d.h"
#include "/EgtDev/Include/EGnStringUtils.h" #include "/EgtDev/Include/EgnStringUtils.h"
#include <algorithm> #include <algorithm>
using namespace std ; using namespace std ;
+2 -1
View File
@@ -15,7 +15,7 @@
#include "stdafx.h" #include "stdafx.h"
#include "DllMain.h" #include "DllMain.h"
#include "/EgtDev/Include/EGkHashGrids3d.h" #include "/EgtDev/Include/EGkHashGrids3d.h"
#include "/EgtDev/Include/EGnStringUtils.h" #include "/EgtDev/Include/EgnStringUtils.h"
#include <algorithm> #include <algorithm>
using namespace std ; using namespace std ;
@@ -684,6 +684,7 @@ HashGrids3d::Update( void)
double dSize = 0 ; double dSize = 0 ;
Obj.box.GetDiameter( dSize) ; Obj.box.GetDiameter( dSize) ;
double dCellSpan = pGrid->GetCellSpan() ; double dCellSpan = pGrid->GetCellSpan() ;
if ( dSize >= dCellSpan || dSize < ( dCellSpan / hierarchyFactor)) { if ( dSize >= dCellSpan || dSize < ( dCellSpan / hierarchyFactor)) {
pGrid->Remove( Obj) ; pGrid->Remove( Obj) ;
addGrid( Obj) ; addGrid( Obj) ;
+7 -7
View File
@@ -15,7 +15,7 @@
#include "stdafx.h" #include "stdafx.h"
#include "IntersCrvCompoCrvCompo.h" #include "IntersCrvCompoCrvCompo.h"
#include "CurveAux.h" #include "CurveAux.h"
#include "/EgtDev/Include/EGkDistPointCurve.h" #include "/EgtDev/Include/EgkDistPointCurve.h"
#include "/EgtDev/Include/EGkAngle.h" #include "/EgtDev/Include/EGkAngle.h"
#include "/EgtDev/Include/EGkHashGrids2d.h" #include "/EgtDev/Include/EGkHashGrids2d.h"
#include <algorithm> #include <algorithm>
@@ -541,7 +541,7 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
for ( int i = 0 ; i < m_nNumInters ; ++ i) { for ( int i = 0 ; i < m_nNumInters ; ++ i) {
// se il tipo di accostamento per la curva A non è definito // se il tipo di accostamento per la curva A non è definito
if ( m_Info[i].IciA[0].nPrevTy == ICCT_NULL) { if ( m_Info[i].IciA[0].nPrevTy == ICCT_NULL) {
if ( i > 0 || ( bCrvAClosed && ! bAutoInters)) { if ( i > 0 || bCrvAClosed) {
int j = ( i > 0 ? i - 1 : m_nNumInters - 1) ; int j = ( i > 0 ? i - 1 : m_nNumInters - 1) ;
m_Info[i].IciA[0].nPrevTy = ( m_Info[j].bOverlap ? m_Info[j].IciA[1].nNextTy : m_Info[j].IciA[0].nNextTy) ; m_Info[i].IciA[0].nPrevTy = ( m_Info[j].bOverlap ? m_Info[j].IciA[1].nNextTy : m_Info[j].IciA[0].nNextTy) ;
} }
@@ -549,7 +549,7 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
// se il tipo di allontanamento per la curva A non è definito // se il tipo di allontanamento per la curva A non è definito
int ki = ( m_Info[i].bOverlap ? 1 : 0) ; int ki = ( m_Info[i].bOverlap ? 1 : 0) ;
if ( m_Info[i].IciA[ki].nNextTy == ICCT_NULL) { if ( m_Info[i].IciA[ki].nNextTy == ICCT_NULL) {
if ( i < m_nNumInters - 1 || ( bCrvAClosed && ! bAutoInters)) { if ( i < m_nNumInters - 1 || bCrvAClosed) {
int j = ( i < m_nNumInters - 1 ? i + 1 : 0) ; int j = ( i < m_nNumInters - 1 ? i + 1 : 0) ;
m_Info[i].IciA[ki].nNextTy = m_Info[j].IciA[0].nPrevTy ; m_Info[i].IciA[ki].nNextTy = m_Info[j].IciA[0].nPrevTy ;
} }
@@ -561,14 +561,14 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
for ( int i = 0 ; i < m_nNumInters ; ++ i) { for ( int i = 0 ; i < m_nNumInters ; ++ i) {
// se il tipo di accostamento per la curva B non è definito // se il tipo di accostamento per la curva B non è definito
if ( m_Info[i].IciB[0].nPrevTy == ICCT_NULL) { if ( m_Info[i].IciB[0].nPrevTy == ICCT_NULL) {
if ( i > 0 || ( bCrvBClosed && ! bAutoInters)) { if ( i > 0 || bCrvBClosed) {
int j = ( i > 0 ? i - 1 : m_nNumInters - 1) ; int j = ( i > 0 ? i - 1 : m_nNumInters - 1) ;
m_Info[i].IciB[0].nPrevTy = ( m_Info[j].bOverlap && ! m_Info[j].bCBOverEq ? m_Info[j].IciB[1].nNextTy : m_Info[j].IciB[0].nNextTy) ; m_Info[i].IciB[0].nPrevTy = ( m_Info[j].bOverlap && ! m_Info[j].bCBOverEq ? m_Info[j].IciB[1].nNextTy : m_Info[j].IciB[0].nNextTy) ;
} }
} }
// se il tipo di allontanamento per la curva B non è definito // se il tipo di allontanamento per la curva B non è definito
if ( m_Info[i].IciB[0].nNextTy == ICCT_NULL) { if ( m_Info[i].IciB[0].nNextTy == ICCT_NULL) {
if ( i < m_nNumInters - 1 || ( bCrvBClosed && ! bAutoInters)) { if ( i < m_nNumInters - 1 || bCrvBClosed) {
int j = ( i < m_nNumInters - 1 ? i + 1 : 0) ; int j = ( i < m_nNumInters - 1 ? i + 1 : 0) ;
m_Info[i].IciB[0].nNextTy = ( m_Info[j].bOverlap && ! m_Info[j].bCBOverEq ? m_Info[j].IciB[1].nPrevTy : m_Info[j].IciB[0].nPrevTy) ; m_Info[i].IciB[0].nNextTy = ( m_Info[j].bOverlap && ! m_Info[j].bCBOverEq ? m_Info[j].IciB[1].nPrevTy : m_Info[j].IciB[0].nPrevTy) ;
} }
@@ -702,9 +702,9 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
// assegno sottoindici (considero solo intersezioni overlap) // assegno sottoindici (considero solo intersezioni overlap)
int ki = 0 ; int ki = 0 ;
int kj = 1 ; int kj = 1 ;
// verifico se entrambe overlap con lo stesso verso, la precedente termina con ON e la successiva inizia con ON // verifico se entrambe overlap, la precedente termina con ON e la successiva inizia con ON
// sia sulla curva A sia sulla curva B (tenendo conto del senso equiverso/controverso) // sia sulla curva A sia sulla curva B (tenendo conto del senso equiverso/controverso)
if ( m_Info[j].bOverlap && m_Info[i].bOverlap && m_Info[j].bCBOverEq == m_Info[i].bCBOverEq && if ( m_Info[j].bOverlap && m_Info[i].bOverlap &&
m_Info[j].IciA[kj].nNextTy == ICCT_ON && m_Info[i].IciA[ki].nPrevTy == ICCT_ON && m_Info[j].IciA[kj].nNextTy == ICCT_ON && m_Info[i].IciA[ki].nPrevTy == ICCT_ON &&
GetCrvBDirANext( m_Info[j]) == ICCT_ON && GetCrvBDirAPrev( m_Info[i]) == ICCT_ON) { GetCrvBDirANext( m_Info[j]) == ICCT_ON && GetCrvBDirAPrev( m_Info[i]) == ICCT_ON) {
// CurvaA : riporto il secondo punto del successivo sul secondo punto del precedente // CurvaA : riporto il secondo punto del successivo sul secondo punto del precedente
+5 -2
View File
@@ -23,7 +23,7 @@
#include "/EgtDev/Include/EGkIntersCurves.h" #include "/EgtDev/Include/EGkIntersCurves.h"
#include "/EgtDev/Include/EGkDistPointCurve.h" #include "/EgtDev/Include/EGkDistPointCurve.h"
#include "/EgtDev/Include/EGkPlane3d.h" #include "/EgtDev/Include/EGkPlane3d.h"
#include "/EgtDev/Include/EgtPointerOwner.h" #include "/EgtDev/Include/EGtPointerOwner.h"
#include <algorithm> #include <algorithm>
using namespace std ; using namespace std ;
@@ -659,8 +659,11 @@ IntersCurveCurve::CalcCurveInOrOut( const ICurve* pCurveA, const ICurve* pCurveB
bool bool
IntersCurveCurve::GetCurveOutClass( const ICurve* pCurve, int& nClass) IntersCurveCurve::GetCurveOutClass( const ICurve* pCurve, int& nClass)
{ {
PolyLine PL ;
if ( ! pCurve->ApproxWithLines( LIN_TOL_APPROX, ANG_TOL_APPROX_DEG, ICurve::APL_SPECIAL, PL))
return false ;
double dArea ; double dArea ;
if ( ! pCurve->GetAreaXY( dArea)) if ( ! PL.GetAreaXY( dArea))
return false ; return false ;
nClass = (( dArea > 0) ? CRVC_OUT : CRVC_IN) ; nClass = (( dArea > 0) ? CRVC_OUT : CRVC_IN) ;
return true ; return true ;
+104 -123
View File
@@ -1,7 +1,7 @@
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// EgalTech 2020-2022 // EgalTech 2020-2020
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// File : IntersLineBox.cpp Data : 08.01.22 Versione : 2.4a3 // File : IntersLineBox.cpp Data : 07.05.20 Versione : 2.2e1
// Contenuto : Implementazione della intersezione linea/box. // Contenuto : Implementazione della intersezione linea/box.
// //
// //
@@ -13,77 +13,13 @@
//--------------------------- Include ---------------------------------------- //--------------------------- Include ----------------------------------------
#include "stdafx.h" #include "stdafx.h"
#include "IntersLineBox.h" #include "SurfTriMesh.h"
#include "/EgtDev/Include/EGkIntersLineBox.h" #include "/EgtDev/Include/EGkIntersLineBox.h"
#include "/EgtDev/Include/EgtNumUtils.h" #include "/EgtDev/Include/EGkIntersLineSurfTm.h"
#include <algorithm> #include <algorithm>
using namespace std ; using namespace std ;
//----------------------------------------------------------------------------
// Linea e box allineato assi devono essere nel medesimo sistema di riferimento.
// In caso di intersezione viene restituito true e i parametri in dU1 e dU2.
//----------------------------------------------------------------------------
bool
IntersLineBox( const Point3d& ptL, const Vector3d& vtL,
const Point3d& ptMin, const Point3d& ptMax,
double& dU1, double& dU2)
{
// Verifico il versore
if ( vtL.IsSmall())
return false ;
// Verifico gli estremi del box
if ( ptMin.x > ptMax.x + EPS_SMALL ||
ptMin.y > ptMax.y + EPS_SMALL ||
ptMin.z > ptMax.z + EPS_SMALL)
return false ;
// Casi di intersezione impossibile
if ( abs( vtL.x) < EPS_ZERO && ( ptL.x < ptMin.x - EPS_SMALL || ptL.x > ptMax.x + EPS_SMALL))
return false ;
if ( abs( vtL.y) < EPS_ZERO && ( ptL.y < ptMin.y - EPS_SMALL || ptL.y > ptMax.y + EPS_SMALL))
return false ;
if ( abs( vtL.z) < EPS_ZERO && ( ptL.z < ptMin.z - EPS_SMALL || ptL.z > ptMax.z + EPS_SMALL))
return false ;
// Parametri degli estremi della retta
dU1 = -INFINITO ;
dU2 = INFINITO ;
// Confronto con piani YZ (perpendicolari ad asse X)
if ( vtL.x > EPS_ZERO) {
dU1 = max( dU1, ( ptMin.x - ptL.x) / vtL.x) ;
dU2 = min( dU2, ( ptMax.x - ptL.x) / vtL.x) ;
}
else if ( vtL.x < -EPS_ZERO) {
dU1 = max( dU1, ( ptMax.x - ptL.x) / vtL.x) ;
dU2 = min( dU2, ( ptMin.x - ptL.x) / vtL.x) ;
}
// Confronto con piani ZX (perpendicolari ad asse Y)
if ( vtL.y > EPS_ZERO) {
dU1 = max( dU1, ( ptMin.y - ptL.y) / vtL.y) ;
dU2 = min( dU2, ( ptMax.y - ptL.y) / vtL.y) ;
}
else if ( vtL.y < -EPS_ZERO) {
dU1 = max( dU1, ( ptMax.y - ptL.y) / vtL.y) ;
dU2 = min( dU2, ( ptMin.y - ptL.y) / vtL.y) ;
}
// Confronto con piani XY (perpendicolari ad asse Z)
if ( vtL.z > EPS_ZERO) {
dU1 = max( dU1, ( ptMin.z - ptL.z) / vtL.z) ;
dU2 = min( dU2, ( ptMax.z - ptL.z) / vtL.z) ;
}
else if ( vtL.z < -EPS_ZERO){
dU1 = max( dU1, ( ptMax.z - ptL.z) / vtL.z) ;
dU2 = min( dU2, ( ptMin.z - ptL.z) / vtL.z) ;
}
return ( dU2 >= dU1) ;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool bool
IntersLineBox( const Point3d& ptL1, const Point3d& ptL2, const BBox3d& b3Box, INTDBLVECTOR& vInters, bool bFinite) IntersLineBox( const Point3d& ptL1, const Point3d& ptL2, const BBox3d& b3Box, INTDBLVECTOR& vInters, bool bFinite)
@@ -102,69 +38,114 @@ bool
IntersLineBox( const Point3d& ptL, const Vector3d& vtL, double dLen, const BBox3d& b3Box, INTDBLVECTOR& vInters, bool bFinite) IntersLineBox( const Point3d& ptL, const Vector3d& vtL, double dLen, const BBox3d& b3Box, INTDBLVECTOR& vInters, bool bFinite)
{ {
// Recupero i dati del Box // Recupero i dati del Box
Point3d ptMin, ptMax ; Point3d ptMin ;
if ( ! b3Box.GetMinMax( ptMin, ptMax)) double dDimX, dDimY, dDimZ ;
if ( ! b3Box.GetMinDim( ptMin, dDimX, dDimY, dDimZ))
return false ; return false ;
// Contorno di base
// Pulisco vettore intersezioni PolyLine PL ;
vInters.clear() ; PL.AddUPoint( 0, ptMin) ;
PL.AddUPoint( 1, ptMin + Vector3d( dDimX, 0, 0)) ;
// Eseguo intersezione della linea completa PL.AddUPoint( 2, ptMin + Vector3d( dDimX, dDimY, 0)) ;
double dU1, dU2 ; PL.AddUPoint( 3, ptMin + Vector3d( 0, dDimY, 0)) ;
bool bInters = IntersLineBox( ptL, vtL, b3Box.GetMin(), b3Box.GetMax(), dU1, dU2) ; PL.Close() ;
// Vettore altezza
// Se non c'è intersezione Vector3d vtExtr( 0, 0, dDimZ) ;
if ( ! bInters || ( bFinite && ( dU1 > dLen + EPS_SMALL || dU2 < -EPS_SMALL))) // Creo la superficie trimesh equivalente
return true ; SurfTriMesh Stm ;
if ( ! Stm.CreateByExtrusion( PL, vtExtr))
// Se le due intersezioni coincidono return false ;
if ( ( dU2 - dU1) < EPS_SMALL) { SurfTriMesh StmBot ;
double dU = ( dU1 + dU2) / 2 ; if ( ! StmBot.CreateByFlatContour( PL))
if ( ! bFinite) { return false ;
vInters.emplace_back( ILBT_TOUCH, dU) ; StmBot.Invert() ;
SurfTriMesh StmTop ;
if ( ! StmTop.CreateByFlatContour( PL))
return false ;
StmTop.Translate( vtExtr) ;
if ( ! Stm.DoSewing( StmBot) || ! Stm.DoSewing( StmTop))
return false ;
// Calcolo l'intersezione
ILSIVECTOR vInfo ;
if ( ! IntersLineSurfTm( ptL, vtL, dLen, Stm, vInfo, bFinite))
return false ;
// ciclo sulle intersezioni
double dUcurr = -INFINITO ;
for ( const auto& Info : vInfo) {
// se intersezione puntuale
if ( Info.nILTT == ILTT_VERT || Info.nILTT == ILTT_EDGE || Info.nILTT == ILTT_IN) {
int nFlag = ILBT_TOUCH ;
if ( Info.dCosDN > EPS_ZERO)
nFlag = ILBT_OUT ;
else if ( Info.dCosDN < -EPS_ZERO)
nFlag = ILBT_IN ;
vInters.emplace_back( nFlag, Info.dU) ;
dUcurr = Info.dU ;
} }
else { // se altrimenti intersezione con coincidenza
if ( dU > - EPS_SMALL && dU < dLen + EPS_SMALL) else if ( Info.nILTT == ILTT_SEGM || Info.nILTT == ILTT_SEGM_ON_EDGE) {
vInters.emplace_back( ILBT_TOUCH, Clamp( dU, 0., dLen)) ; if ( Info.dU > dUcurr - EPS_SMALL)
vInters.emplace_back( ILBT_TG_INI, Info.dU) ;
vInters.emplace_back( ILBT_TG_FIN, Info.dU2) ;
dUcurr = Info.dU2 ;
} }
return true ;
} }
// elimino intersezioni ripetute
// Se sono due intersezioni con la linea giacente su una faccia del box for ( size_t j = 1 ; j < vInters.size() ; ) {
if ( ( abs( vtL.x) < EPS_ZERO && ( abs( ptL.x - ptMin.x) < EPS_SMALL || abs( ptL.x - ptMax.x) < EPS_SMALL)) || // intersezione precedente
( abs( vtL.y) < EPS_ZERO && ( abs( ptL.y - ptMin.y) < EPS_SMALL || abs( ptL.y - ptMax.y) < EPS_SMALL)) || size_t i = j - 1 ;
( abs( vtL.z) < EPS_ZERO && ( abs( ptL.z - ptMin.z) < EPS_SMALL || abs( ptL.z - ptMax.z) < EPS_SMALL))) { // se sono dello stesso tipo, elimino una delle due
if ( ! bFinite) { if ( vInters[i].first == vInters[j].first) {
vInters.emplace_back( ILBT_TG_INI, dU1) ; // se entranti elimino la prima
vInters.emplace_back( ILBT_TG_FIN, dU2) ; if ( vInters[i].first == ILBT_IN || vInters[i].first == ILBT_TG_INI)
vInters.erase( vInters.begin() + i) ;
// altrimenti la seconda
else
vInters.erase( vInters.begin() + j) ;
if ( i > 0)
-- j ;
continue ;
} }
else { // se hanno lo stesso parametro
if ( dU1 > dLen - EPS_SMALL) else if ( abs( vInters[i].second - vInters[j].second) < EPS_SMALL) {
vInters.emplace_back( ILBT_IN, dLen) ; // se una entrante e l'altra uscente, cambio in touch ed elimino la seconda
else if ( dU2 < EPS_SMALL) if ( ( vInters[i].first == ILBT_IN && vInters[j].first == ILBT_OUT) ||
vInters.emplace_back( ILBT_OUT, 0) ; ( vInters[i].first == ILBT_OUT && vInters[j].first == ILBT_IN)) {
else { vInters[i].first = ILBT_TOUCH ;
vInters.emplace_back( ILBT_TG_INI, Clamp( dU1, 0., dLen)) ; vInters.erase( vInters.begin() + j) ;
vInters.emplace_back( ILBT_TG_FIN, Clamp( dU2, 0., dLen)) ; if ( i > 0)
-- j ;
continue ;
}
// se prima puntuale e l'altra inizio o fine di coincidenza, elimino la prima
else if ( ( vInters[i].first == ILBT_IN || vInters[i].first == ILBT_OUT || vInters[i].first == ILBT_TOUCH) &&
( vInters[j].first == ILBT_TG_INI || vInters[j].first == ILBT_TG_FIN)) {
vInters.erase( vInters.begin() + i) ;
if ( i > 0)
-- j ;
continue ;
}
// se prima inizio o fine di coincidenza e l'altra puntuale, elimino la seconda
else if ( ( vInters[i].first == ILBT_TG_INI || vInters[i].first == ILBT_TG_FIN) &&
( vInters[j].first == ILBT_IN || vInters[j].first == ILBT_OUT || vInters[j].first == ILBT_TOUCH)) {
vInters.erase( vInters.begin() + j) ;
if ( i > 0)
-- j ;
continue ;
}
// se una fine di coincidenza e l'altra inizio di coincidenza, elimino entrambe
else if ( ( vInters[i].first == ILBT_TG_FIN && vInters[j].first == ILBT_TG_INI) ||
( vInters[i].first == ILBT_TG_INI && vInters[j].first == ILBT_TG_FIN)) {
vInters.erase( vInters.begin() + j) ;
vInters.erase( vInters.begin() + i) ;
if ( i > 0)
-- j ;
continue ;
} }
} }
return true ; // passo alla successiva
++ j ;
} }
// Altrimenti sono due intersezioni con attraversamento
if ( ! bFinite) {
vInters.emplace_back( ILBT_IN, dU1) ;
vInters.emplace_back( ILBT_OUT, dU2) ;
}
else {
if ( dU1 > dLen - EPS_SMALL)
vInters.emplace_back( ILBT_IN, dLen) ;
else if ( dU2 < EPS_SMALL)
vInters.emplace_back( ILBT_OUT, 0) ;
else {
vInters.emplace_back( ILBT_IN, Clamp( dU1, 0., dLen)) ;
vInters.emplace_back( ILBT_OUT, Clamp( dU2, 0., dLen)) ;
}
}
return true ; return true ;
} }
-34
View File
@@ -1,34 +0,0 @@
//----------------------------------------------------------------------------
// EgalTech 2022-2022
//----------------------------------------------------------------------------
// File : IntersLineBox.h Data : 08.01.22 Versione : 2.4a3
// Contenuto : Dichiarazione delle funzioni base per intersezione linea/box.
//
//
//
// Modifiche : 08.01.22 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
#pragma once
#include "/EgtDev/Include/EGkPoint3d.h"
//----------------------------------------------------------------------------
// Linea e box allineato agli assi sono nel medesimo riferimento.
// Con intersezione viene restituito true e i parametri in dU1 e dU2.
//----------------------------------------------------------------------------
bool
IntersLineBox( const Point3d& ptL, const Vector3d& vtL,
const Point3d& ptMin, const Point3d& ptMax,
double& dU1, double& dU2) ;
//----------------------------------------------------------------------------
inline bool
TestIntersLineBox( const Point3d& ptL, const Vector3d& vtL,
const Point3d& ptMin, const Point3d& ptMax)
{
double dU1, dU2 ;
return IntersLineBox( ptL, vtL, ptMin, ptMax, dU1, dU2) ;
}
-58
View File
@@ -1,58 +0,0 @@
//----------------------------------------------------------------------------
// EgalTech 2023-2023
//----------------------------------------------------------------------------
// File : IntersLineCaps.cpp Data : 22.05.23 Versione : 2.5e3
// Contenuto : Implementazione della intersezione linea/capsule.
//
//
//
// Modifiche : 22.05.23 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "IntersLineCaps.h"
#include "DistLineLine.h"
#include "/EgtDev/Include/EGkIntersLineSphere.h"
using namespace std ;
//----------------------------------------------------------------------------
// Linea e capsule sono nel medesimo riferimento.
// Il capsule è definito con centri delle due estremità, e raggio.
// In caso di intersezione viene restituito true e i parametri in dU1 e dU2.
//----------------------------------------------------------------------------
bool
IntersLineCaps( const Point3d& ptL, const Vector3d& vtL,
const Point3d& ptCaps1, const Point3d& ptCaps2, double dRad,
double& dU1, double& dU2)
{
// Determino versore e lunghezza asse Capsule
Vector3d vtCaps = ptCaps2 - ptCaps1 ;
double dLen = vtCaps.Len() ;
if ( dLen < EPS_SMALL) {
Point3d ptInt1, ptInt2 ;
if ( IntersLineSphere( ptL, vtL, Media( ptCaps1, ptCaps2), dRad, ptInt1, ptInt2) != ILST_SEC)
return false ;
dU1 = ( ptInt1 - ptL) * vtL ;
dU2 = ( ptInt2 - ptL) * vtL ;
return true ;
}
vtCaps /= dLen ;
// Distanza tra la linea e il segmento asse del capsule
DistLineLine dstLL( ptL, vtL, 1, ptCaps1, vtCaps, dLen, false, true) ;
double dSqDist ;
if ( dstLL.GetSqDist( dSqDist) && dSqDist >= dRad * dRad)
return false ;
// Calcolo i punti di intersezione
Point3d ptRef, ptTmp ;
dstLL.GetMinDistPoints( ptRef, ptTmp) ;
double dSqDelta = dRad * dRad - dSqDist ;
double dDist = sqrt( dSqDelta) ;
dU1 = ( ptRef - ptL) * vtL - dDist ;
dU2 = dU1 + 2 * dDist ;
return true ;
}
-25
View File
@@ -1,25 +0,0 @@
//----------------------------------------------------------------------------
// EgalTech 2023-2023
//----------------------------------------------------------------------------
// File : IntersLineCaps.h Data : 22.05.23 Versione : 2.5e4
// Contenuto : Dichiarazione funzioni base per intersezione linea/capsule.
//
//
//
// Modifiche : 22.05.23 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
#pragma once
#include "/EgtDev/Include/EGkPoint3d.h"
//----------------------------------------------------------------------------
// Linea e capsule sono nel medesimo riferimento.
// Il capsule è definito con centri delle due estremità, e raggio.
// In caso di intersezione viene restituito true e i parametri in dU1 e dU2.
//----------------------------------------------------------------------------
bool IntersLineCaps( const Point3d& ptL, const Vector3d& vtL,
const Point3d& ptCaps1, const Point3d& ptCaps2, double dRad,
double& dU1, double& dU2) ;
-138
View File
@@ -1,138 +0,0 @@
//----------------------------------------------------------------------------
// EgalTech 2023-2023
//----------------------------------------------------------------------------
// File : IntersLineCone.cpp Data : 16.05.23 Versione : 2.5e3
// Contenuto : Implementazione della intersezione linea/tronco di cono.
//
//
//
// Modifiche : 16.05.23 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "IntersLineCone.h"
#include "IntersLineCyl.h"
#include "/EgtDev/Include/ENkPolynomialRoots.h"
using namespace std ;
//----------------------------------------------------------------------------
// Linea e tronco di cono sono nel medesimo riferimento.
// Il tronco di cono è centrato sull'asse Z e appoggiato con RMin sul piano XY.
// In caso di intersezione viene restituito true e i parametri in dU1 e dU2.
//----------------------------------------------------------------------------
bool
IntersLineCone( const Point3d& ptL, const Vector3d& vtL,
double dRadMin, double dRadMax, double dHeight,
double& dU1, double& dU2)
{
// Verifico il versore
if ( vtL.IsSmall())
return false ;
// Verifico il tronco di cono
if ( ( dRadMin < EPS_SMALL && dRadMax < EPS_SMALL) || dHeight < EPS_SMALL)
return false ;
// Se è un cilindro, rimando a questo
if ( abs( dRadMax - dRadMin) < EPS_SMALL)
return IntersLineCyl( ptL, vtL, ( dRadMin + dRadMax) / 2, dHeight, dU1, dU2) ;
// Se raggi invertiti, li scambio
if ( dRadMin > dRadMax)
swap( dRadMin, dRadMax) ;
// Tangente dell'angolo di semi-apertura del cono
double dTanTheta = ( dRadMax - dRadMin) / dHeight ;
double dSqTanTheta = dTanTheta * dTanTheta ;
double dSqCosTheta = 1 / ( 1 + dSqTanTheta) ;
// Determino le eventuali intersezioni con le due basi a quota minima e massima (solo se linea non giace sul cono)
int nBasInt = 0 ;
if ( abs( vtL.z) > EPS_ZERO) {
// le linee tangenti al cono non sono considerate intersecanti
bool bSameHAng = ( abs( abs( vtL.x) - abs( vtL.y)) < EPS_SMALL && abs( dSqCosTheta - vtL.z * vtL.z) < 2 * abs( vtL.z) * EPS_SMALL) ;
double EpsRad = ( bSameHAng ? - EPS_SMALL : EPS_SMALL) ;
Point3d ptInt1 = ptL + ( ( 0 - ptL.z) / vtL.z) * vtL ;
if ( ptInt1.x * ptInt1.x + ptInt1.y * ptInt1.y < dRadMin * dRadMin + 2 * dRadMin * EpsRad) {
dU1 = ( ptInt1 - ptL) * vtL ;
nBasInt += 1 ;
}
Point3d ptInt2 = ptL + ( ( dHeight - ptL.z) / vtL.z) * vtL ;
if ( ptInt2.x * ptInt2.x + ptInt2.y * ptInt2.y < dRadMax * dRadMax + 2 * dRadMax * EpsRad) {
dU2 = ( ptInt2 - ptL) * vtL ;
nBasInt += 2 ;
}
}
// Se la linea interseca entrambe le basi, si sono trovate le due intersezioni
if ( nBasInt == 3) {
if ( dU1 > dU2)
swap( dU1, dU2) ;
// Trovate intersezioni
return true ;
}
// Posizione del vertice del cono
double dDeltaH = ( dRadMin < EPS_SMALL ? 0 : dRadMin / dTanTheta) ;
// Sposto il punto di passaggio della linea di conseguenza
Point3d ptMyL = ptL + Z_AX * dDeltaH ;
// Determino le intersezioni con la superficie laterale del cono
DBLVECTOR vdCoeff{ ptMyL.x * ptMyL.x + ptMyL.y * ptMyL.y - ptMyL.z * ptMyL.z * dSqTanTheta,
2 * ( ptMyL.x * vtL.x + ptMyL.y * vtL.y - ptMyL.z * vtL.z * dSqTanTheta),
vtL.x * vtL.x + vtL.y * vtL.y - vtL.z * vtL.z * dSqTanTheta} ;
DBLVECTOR vdRoots ;
int nRoot = PolynomialRoots( 2, vdCoeff, vdRoots) ;
// Elimino le soluzioni cha danno intersezioni fuori dai limiti in Z del tronco di cono
if ( nRoot == 2) {
double dIntZ2 = ptL.z + vdRoots[1] * vtL.z ;
if ( dIntZ2 < 0 - EPS_SMALL || dIntZ2 > dHeight + EPS_SMALL)
-- nRoot ;
}
if ( nRoot >= 1) {
double dIntZ1 = ptL.z + vdRoots[0] * vtL.z ;
if ( dIntZ1 < 0 - EPS_SMALL || dIntZ1 > dHeight + EPS_SMALL) {
if ( nRoot == 2)
vdRoots[0] = vdRoots[1] ;
-- nRoot ;
}
}
// Due soluzioni: la retta interseca due volte la superficie laterale
if ( nRoot == 2) {
dU1 = vdRoots[0] ;
dU2 = vdRoots[1] ;
if ( dU1 > dU2)
swap( dU1, dU2) ;
// Trovate intersezioni
return true ;
}
// Una soluzione : la retta interseca la superficie laterale e un piano
else if ( nRoot == 1) {
// Se piano superiore
if ( nBasInt == 2) {
dU1 = vdRoots[0] ;
}
// altrimenti piano inferiore
else if ( nBasInt == 1) {
dU2 = vdRoots[0] ;
}
// altrimenti niente
else
return false ;
if ( dU1 > dU2)
swap( dU1, dU2) ;
// Trovate intersezioni
return true ;
}
// Nessuna soluzione : nessuna intersezione
else
return false ;
}
-35
View File
@@ -1,35 +0,0 @@
//----------------------------------------------------------------------------
// EgalTech 2023-2023
//----------------------------------------------------------------------------
// File : IntersLineCone.h Data : 16.05.23 Versione : 2.5e3
// Contenuto : Dichiarazione funzioni base per intersezione linea/cono tronco.
//
//
//
// Modifiche : 16.05.23 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
#pragma once
#include "/EgtDev/Include/EGkPoint3d.h"
//----------------------------------------------------------------------------
// Linea e tronco di cono sono nel medesimo riferimento.
// Il tronco di cono è centrato sull'asse Z e appoggiato con RMin sul piano XY.
// Con intersezione viene restituito true e i parametri in dU1 e dU2.
//----------------------------------------------------------------------------
bool
IntersLineCone( const Point3d& ptL, const Vector3d& vtL,
double dRadMin, double dRadMax, double dHeight,
double& dU1, double& dU2) ;
//----------------------------------------------------------------------------
inline bool
TestIntersLineCone( const Point3d& ptL, const Vector3d& vtL,
double dRadMin, double dRadMax, double dHeight)
{
double dU1, dU2 ;
return IntersLineCone( ptL, vtL, dRadMin, dRadMax, dHeight, dU1, dU2) ;
}
-161
View File
@@ -1,161 +0,0 @@
//----------------------------------------------------------------------------
// EgalTech 2023-2023
//----------------------------------------------------------------------------
// File : IntersLineCyl.cpp Data : 16.05.23 Versione : 2.5e3
// Contenuto : Implementazione della intersezione linea/cilindro.
//
//
//
// Modifiche : 16.05.23 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "IntersLineCyl.h"
#include "/EgtDev/Include/EGkFrame3d.h"
#include "/EgtDev/Include/ENkPolynomialRoots.h"
using namespace std ;
//----------------------------------------------------------------------------
// Linea e cilindro sono nel medesimo riferimento.
// Il cilindro è centrato sull'asse Z e appoggiato sul piano XY.
// In caso di intersezione viene restituito true e i parametri in dU1 e dU2.
//----------------------------------------------------------------------------
bool
IntersLineCyl( const Point3d& ptL, const Vector3d& vtL,
double dRad, double dHeight,
double& dU1, double& dU2)
{
// Verifico il versore
if ( vtL.IsSmall())
return false ;
// Verifico il cilindro
if ( dRad < EPS_SMALL || dHeight < EPS_SMALL)
return false ;
// Determino le eventuali intersezioni con le due basi a quota minima e massima (solo se linea non parallela ad esse)
int nBasInt = 0 ;
if ( abs( vtL.z) > EPS_ZERO) {
// le linee tangenti al cilindro non sono considerate intersecanti
double EpsRad = ( vtL.IsZeroXY() ? - EPS_SMALL : EPS_SMALL) ;
Point3d ptInt1 = ptL + ( ( 0 - ptL.z) / vtL.z) * vtL ;
if ( ptInt1.x * ptInt1.x + ptInt1.y * ptInt1.y < dRad * dRad + 2 * dRad * EpsRad) {
dU1 = ( ptInt1 - ptL) * vtL ;
nBasInt += 1 ;
}
Point3d ptInt2 = ptL + ( ( dHeight - ptL.z) / vtL.z) * vtL ;
if ( ptInt2.x * ptInt2.x + ptInt2.y * ptInt2.y < dRad * dRad + 2 * dRad * EpsRad) {
dU2 = ( ptInt2 - ptL) * vtL ;
nBasInt += 2 ;
}
}
// Se la linea interseca entrambe le basi, si sono trovate le due intersezioni
if ( nBasInt == 3) {
if ( dU1 > dU2)
swap( dU1, dU2) ;
// Trovate intersezioni
return true ;
}
// Determino le intersezioni con la superficie laterale del cilindro
DBLVECTOR vdCoeff{ ptL.x * ptL.x + ptL.y * ptL.y - dRad * dRad,
2 * ( ptL.x * vtL.x + ptL.y * vtL.y),
vtL.x * vtL.x + vtL.y * vtL.y} ;
DBLVECTOR vdRoots ;
int nRoot = PolynomialRoots( 2, vdCoeff, vdRoots) ;
// Elimino le soluzioni cha danno intersezioni fuori dai limiti in Z del cilindro
if ( nRoot == 2) {
double dIntZ2 = ptL.z + vdRoots[1] * vtL.z ;
if ( dIntZ2 < 0 - EPS_SMALL || dIntZ2 > dHeight + EPS_SMALL)
-- nRoot ;
}
if ( nRoot >= 1) {
double dIntZ1 = ptL.z + vdRoots[0] * vtL.z ;
if ( dIntZ1 < 0 - EPS_SMALL || dIntZ1 > dHeight + EPS_SMALL) {
if ( nRoot == 2)
vdRoots[0] = vdRoots[1] ;
-- nRoot ;
}
}
// Due soluzioni: la retta interseca due volte la superficie laterale
if ( nRoot == 2) {
dU1 = vdRoots[0] ;
dU2 = vdRoots[1] ;
if ( dU1 > dU2)
swap( dU1, dU2) ;
// Trovate intersezioni
return true ;
}
// Una soluzione : la retta interseca la superficie laterale e un piano
else if ( nRoot == 1) {
// Se piano superiore
if ( nBasInt == 2) {
dU1 = vdRoots[0] ;
}
// altrimenti piano inferiore
else if ( nBasInt == 1) {
dU2 = vdRoots[0] ;
}
// altrimenti niente
else
return false ;
if ( dU1 > dU2)
swap( dU1, dU2) ;
// Trovate intersezioni
return true ;
}
// Nessuna soluzione : nessuna intersezione
else
return false ;
}
//----------------------------------------------------------------------------
// Linea e cilindro sono nel medesimo riferimento.
// Il cilindro è definito con centro della base, asse, raggio e altezza.
// In caso di intersezione viene restituito true e i parametri in dU1 e dU2.
//----------------------------------------------------------------------------
bool
IntersLineCyl( const Point3d& ptL, const Vector3d& vtL,
const Point3d& ptCyl, const Vector3d& vtCyl, double dRad, double dHeight,
double& dU1, double& dU2)
{
// Riferimento intrinseco del cilindro
Frame3d frCyl ;
if ( ! frCyl.Set( ptCyl, vtCyl))
return false ;
// Ora eseguo i conti nel riferimento intrinseco
return IntersLineCyl( GetToLoc( ptL, frCyl), GetToLoc( vtL, frCyl), dRad, dHeight, dU1, dU2) ;
}
//----------------------------------------------------------------------------
// Linea e cilindro sono nel medesimo riferimento.
// Il cilindro è definito con centri delle due basi, e raggio.
// In caso di intersezione viene restituito true e i parametri in dU1 e dU2.
//----------------------------------------------------------------------------
bool
IntersLineCyl( const Point3d& ptL, const Vector3d& vtL,
const Point3d& ptCyl1, const Point3d& ptCyl2, double dRad,
double& dU1, double& dU2)
{
// Determino asse ed altezza del cilindro
Vector3d vtCyl = ptCyl2 - ptCyl1 ;
double dHeight = vtCyl.Len() ;
if ( dHeight < EPS_SMALL)
return false ;
vtCyl /= dHeight ;
// Riferimento intrinseco del cilindro
Frame3d frCyl ;
if ( ! frCyl.Set( ptCyl1, vtCyl))
return false ;
// Ora eseguo i conti nel riferimento intrinseco
return IntersLineCyl( GetToLoc( ptL, frCyl), GetToLoc( vtL, frCyl), dRad, dHeight, dU1, dU2) ;
}
-52
View File
@@ -1,52 +0,0 @@
//----------------------------------------------------------------------------
// EgalTech 2023-2023
//----------------------------------------------------------------------------
// File : IntersLineCyl.h Data : 16.05.23 Versione : 2.5e3
// Contenuto : Dichiarazione funzioni base per intersezione linea/cilindro.
//
//
//
// Modifiche : 16.05.23 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
#pragma once
#include "/EgtDev/Include/EGkPoint3d.h"
//----------------------------------------------------------------------------
// Linea e cilindro sono nel medesimo riferimento.
// Il cilindro è centrato sull'asse Z e appoggiato sul piano XY.
// Con intersezione viene restituito true e i parametri in dU1 e dU2.
//----------------------------------------------------------------------------
bool IntersLineCyl( const Point3d& ptL, const Vector3d& vtL,
double dRad, double dHeight,
double& dU1, double& dU2) ;
//----------------------------------------------------------------------------
inline bool
TestIntersLineCyl( const Point3d& ptL, const Vector3d& vtL,
double dRad, double dHeight)
{
double dU1, dU2 ;
return IntersLineCyl( ptL, vtL, dRad, dHeight, dU1, dU2) ;
}
//----------------------------------------------------------------------------
// Linea e cilindro sono nel medesimo riferimento.
// Il cilindro è definito con centro della base, asse raggio e altezza.
// In caso di intersezione viene restituito true e i parametri in dU1 e dU2.
//----------------------------------------------------------------------------
bool IntersLineCyl( const Point3d& ptL, const Vector3d& vtL,
const Point3d& ptCyl, const Vector3d& vtCyl, double dRad, double dHeight,
double& dU1, double& dU2) ;
//----------------------------------------------------------------------------
// Linea e cilindro sono nel medesimo riferimento.
// Il cilindro è definito con centri delle due basi, e raggio.
// In caso di intersezione viene restituito true e i parametri in dU1 e dU2.
//----------------------------------------------------------------------------
bool IntersLineCyl( const Point3d& ptL, const Vector3d& vtL,
const Point3d& ptCyl1, const Point3d& ptCyl2, double dRad,
double& dU1, double& dU2) ;
+1 -1
View File
@@ -66,7 +66,7 @@ IntersLineLine::IntersInfiniteLines( const ICurveLine& Line1, const ICurveLine&
double dLen1XY = vtDir1.LenXY() ; double dLen1XY = vtDir1.LenXY() ;
if ( dLen1XY < EPS_SMALL) if ( dLen1XY < EPS_SMALL)
return ; return ;
// linea 2 : Start, End, Direzione e Lunghezza // linea 2 : Start, Direzione e Lunghezza
Point3d ptS2 = Line2.GetStart() ; Point3d ptS2 = Line2.GetStart() ;
Point3d ptE2 = Line2.GetEnd() ; Point3d ptE2 = Line2.GetEnd() ;
Vector3d vtDir2 = ptE2 - ptS2 ; Vector3d vtDir2 = ptE2 - ptS2 ;
+8 -13
View File
@@ -26,25 +26,20 @@ IntersLineSphere( const Point3d& ptL, const Vector3d& vtL, const Point3d& ptCen,
return ILST_NO ; return ILST_NO ;
// Proiezione del centro della sfera sulla linea // Proiezione del centro della sfera sulla linea
Point3d ptP = ptL + (( ptCen - ptL) * vtL) * vtL ; Point3d ptP = ptL + (( ptCen - ptL) * vtL) * vtL ;
// Quadrato della distanza di questo punto di proiezione dal centro della sfera // Distanza di questo punto di proiezione dal centro della sfera
double dSqDist = SqDist( ptCen, ptP) ; double dDist = Dist( ptCen, ptP) ;
// Differenza tra quadrato del raggio e quadrato della distanza
double dSqDelta = dRad * dRad - dSqDist ;
// Se distanza superiore al raggio, nessuna intersezione
if ( dSqDelta < - 2 * dRad * EPS_SMALL)
return ILST_NO ;
// Se distanza uguale al raggio, intersezione tangente // Se distanza uguale al raggio, intersezione tangente
if ( dSqDelta < EPS_SMALL * EPS_SMALL) { if ( abs( dDist - dRad) < EPS_SMALL) {
ptI1 = ptP ; ptI1 = ptP ;
ptI2 = ptP ; ptI2 = ptP ;
return ILST_TG ; return ILST_TG ;
} }
// Se distanza superiore al raggio, nessuna intersezione
if ( dDist > dRad)
return ILST_NO ;
// Distanza inferiore al raggio, due intersezioni secanti // Distanza inferiore al raggio, due intersezioni secanti
double dDist2 = sqrt( dSqDelta) ; double dDist2 = sqrt( dRad * dRad - dDist * dDist) ;
ptI1 = ptP - dDist2 * vtL ; ptI1 = ptP - dDist2 * vtL ;
ptI2 = ptP + dDist2 * vtL ; ptI2 = ptP + dDist2 * vtL ;
return ILST_SEC ; return ILST_SEC ;
} }
+64 -13
View File
@@ -1,7 +1,7 @@
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// EgalTech 2017-2022 // EgalTech 2017-2018
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// File : IntersLineSurfStd.cpp Data : 08.01.22 Versione : 2.4a3 // File : IntersLineSurfStd.cpp Data : 03.12.18 Versione : 1.9l1
// Contenuto : Implementazione delle funzioni di intersezione // Contenuto : Implementazione delle funzioni di intersezione
// componente lineare e superficie standard. // componente lineare e superficie standard.
// //
@@ -13,7 +13,6 @@
#include "stdafx.h" #include "stdafx.h"
#include "IntersLineSurfStd.h" #include "IntersLineSurfStd.h"
#include "IntersLineBox.h"
#include "/EgtDev/Include/EGkIntersLinePlane.h" #include "/EgtDev/Include/EGkIntersLinePlane.h"
#include "/EgtDev/Include/EGkFrame3d.h" #include "/EgtDev/Include/EGkFrame3d.h"
#include "/EgtDev/Include/ENkPolynomialRoots.h" #include "/EgtDev/Include/ENkPolynomialRoots.h"
@@ -22,6 +21,60 @@
using namespace std ; using namespace std ;
//----------------------------------------------------------------------------
// Punti e vettore devono essere espressi nel medesimo sistema di riferimento.
// Il box è allineato con gli assi di questo sistema di riferimento.
// In caso di intersezione viene restituito true e i parametri in dU1 e dU2.
//----------------------------------------------------------------------------
bool
IntersLineBox( const Point3d& ptP, const Vector3d& vtV,
const Point3d& ptMin, const Point3d& ptMax, double& dU1, double& dU2)
{
// Casi di intersezione impossibile
if ( abs( vtV.x) < EPS_ZERO && ( ptP.x < ptMin.x - EPS_SMALL || ptP.x > ptMax.x + EPS_SMALL))
return false ;
if ( abs( vtV.y) < EPS_ZERO && ( ptP.y < ptMin.y - EPS_SMALL || ptP.y > ptMax.y + EPS_SMALL))
return false ;
if ( abs( vtV.z) < EPS_ZERO && ( ptP.z < ptMin.z - EPS_SMALL || ptP.z > ptMax.z + EPS_SMALL))
return false ;
// Inizializzo parametri intersezioni
dU1 = -INFINITO ;
dU2 = INFINITO ;
// Confronto con piani YZ (perpendicolari ad asse X)
if ( vtV.x > EPS_ZERO) {
dU1 = max( dU1, ( ptMin.x - ptP.x) / vtV.x) ;
dU2 = min( dU2, ( ptMax.x - ptP.x) / vtV.x) ;
}
else if ( vtV.x < -EPS_ZERO) {
dU1 = max( dU1, ( ptMax.x - ptP.x) / vtV.x) ;
dU2 = min( dU2, ( ptMin.x - ptP.x) / vtV.x) ;
}
// Confronto con piani ZX (perpendicolari ad asse Y)
if ( vtV.y > EPS_ZERO) {
dU1 = max( dU1, ( ptMin.y - ptP.y) / vtV.y) ;
dU2 = min( dU2, ( ptMax.y - ptP.y) / vtV.y) ;
}
else if ( vtV.y < -EPS_ZERO) {
dU1 = max( dU1, ( ptMax.y - ptP.y) / vtV.y) ;
dU2 = min( dU2, ( ptMin.y - ptP.y) / vtV.y) ;
}
// Confronto con piani XY (perpendicolari ad asse Z)
if ( vtV.z > EPS_ZERO) {
dU1 = max( dU1, ( ptMin.z - ptP.z) / vtV.z) ;
dU2 = min( dU2, ( ptMax.z - ptP.z) / vtV.z) ;
}
else if ( vtV.z < -EPS_ZERO) {
dU1 = max( dU1, ( ptMax.z - ptP.z) / vtV.z) ;
dU2 = min( dU2, ( ptMin.z - ptP.z) / vtV.z) ;
}
return ( dU2 >= dU1) ;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
int int
LineDisc( const Point3d& ptPLine, const Vector3d& vtVLine, LineDisc( const Point3d& ptPLine, const Vector3d& vtVLine,
@@ -800,7 +853,7 @@ IntersLineCylinder( const Point3d& ptPLine, const Vector3d& vtVLine,
// Parte della retta appartenente al cilindro // Parte della retta appartenente al cilindro
if ( nIntType == CC_INF_INT) { if ( nIntType == CC_INF_INT) {
dU1 = ( ptPCyl - ptPLine) * vtVLine ; dU1 = ( ptPCyl- ptPLine) * vtVLine ;
// Retta e cilindro equiversi // Retta e cilindro equiversi
if ( vtVCyl * vtVLine > 0) if ( vtVCyl * vtVLine > 0)
dU2 = dU1 + dCylHeigth ; dU2 = dU1 + dCylHeigth ;
@@ -819,7 +872,8 @@ IntersLineCylinder( const Point3d& ptPLine, const Vector3d& vtVLine,
} }
// Caso di due intersezioni // Caso di due intersezioni
else if ( nIntType == CC_TWO_INT) { else if ( nIntType == CC_TWO_INT) {
// Elimino le soluzioni fuori dal cilindro finito // Rigetto le soluzioni fuori dalla
// regione ammissibile del cilindro.
Point3d ptInt1 = ptPLine + dU1 * vtVLine ; Point3d ptInt1 = ptPLine + dU1 * vtVLine ;
Point3d ptInt2 = ptPLine + dU2 * vtVLine ; Point3d ptInt2 = ptPLine + dU2 * vtVLine ;
int nSolNum = 2 ; int nSolNum = 2 ;
@@ -831,7 +885,8 @@ IntersLineCylinder( const Point3d& ptPLine, const Vector3d& vtVLine,
if ( ( ptInt2 - ptPCyl) * vtVCyl < 0 || if ( ( ptInt2 - ptPCyl) * vtVCyl < 0 ||
( ptInt2 - ptPCyl) * vtVCyl > dCylHeigth) ( ptInt2 - ptPCyl) * vtVCyl > dCylHeigth)
-- nSolNum ; -- nSolNum ;
// Aggiorno il tipo di intersezione // Dal numero di soluzioni rimaste
// aggiorno la tipologia di interferenza.
if ( nSolNum == 1) if ( nSolNum == 1)
nIntType = CC_ONE_INT_SEC ; nIntType = CC_ONE_INT_SEC ;
else if ( nSolNum == 0) else if ( nSolNum == 0)
@@ -894,7 +949,8 @@ IntersSegmentCylinder( const Point3d& ptPLine, const Vector3d& vtVLine, double d
if ( nIntType == CC_ERROR_INT) if ( nIntType == CC_ERROR_INT)
return nIntType ; return nIntType ;
// Parte della retta associata appartiene al cilindro // Parte della retta associata
// appartiene al cilindro
if ( nIntType == CC_INF_INT) { if ( nIntType == CC_INF_INT) {
// Segmento non interferisce // Segmento non interferisce
if ( dU1 > dLen + EPS_SMALL) if ( dU1 > dLen + EPS_SMALL)
@@ -922,7 +978,7 @@ IntersSegmentCylinder( const Point3d& ptPLine, const Vector3d& vtVLine, double d
if ( dU1 < - EPS_SMALL || dU1 > dLen + EPS_SMALL) if ( dU1 < - EPS_SMALL || dU1 > dLen + EPS_SMALL)
nIntType = CC_NO_INTERS ; nIntType = CC_NO_INTERS ;
} }
// Retta associata è secante con due punti di intersezione // Retta associata è secante
else if ( nIntType == CC_TWO_INT) { else if ( nIntType == CC_TWO_INT) {
// Il segmento non interferisce // Il segmento non interferisce
if ( dU1 > dLen + EPS_SMALL) if ( dU1 > dLen + EPS_SMALL)
@@ -948,11 +1004,6 @@ IntersSegmentCylinder( const Point3d& ptPLine, const Vector3d& vtVLine, double d
nIntType = CC_NO_INTERS ; nIntType = CC_NO_INTERS ;
} }
} }
// Retta associata è secante con un punto di intersezione
else if ( nIntType == CC_ONE_INT_SEC) {
if ( dU1 < -EPS_SMALL || dU1 > dLen + EPS_SMALL)
nIntType = CC_NO_INTERS ;
}
return nIntType ; return nIntType ;
} }
+10 -4
View File
@@ -17,11 +17,12 @@
// In tutte le funzioni dichiarate i punti e i vettori che definiscono gli oggetti geometrici // In tutte le funzioni dichiarate i punti e i vettori che definiscono gli oggetti geometrici
// devono essere espressi nel medesimo sistema di riferimento. I vettori devono essere normalizzati. // devono essere espressi nel medesimo sistema di riferimento. I vettori devono essere normalizzati.
// Il valore di ritorno è una costante intera che individua la tipologia di intersezione. // Il valore di ritorno è una costante intera che individua la tipologia di interferenza.
// Se si verificano irregolarità, essa vale ERROR_INT. // Se si verificano irregolarità, essa vale ERROR_INT.
// Per riferimento vengono restituiti i parametri lungo la retta a cui avvengono le // Per riferimento vengono restituiti i parametri lungo la retta a cui avvengono le
// intersezioni. Se non vi sono intersezioni i valori di dU1 e dU2 non sono definiti, // intersezioni. Se non vi sono intersezioni i valori di dU1 e dU2 non hanno senso,
// se vi è un'intersezione vale solo dU1, con due soluzioni valgono entrambi. // se vi è un'intersezione solo il valore di dU1 ha senso. Se vi sono più intersezioni,
// dU1 e dU2 hanno entrambi senso.
// Nelle routine per la semi-sfera come argomento appare un versore, che ne individua l'orientazione // Nelle routine per la semi-sfera come argomento appare un versore, che ne individua l'orientazione
// nello spazio. Si immagini uno spazio con origine nel centro della sfera e asse Z diretto come tale // nello spazio. Si immagini uno spazio con origine nel centro della sfera e asse Z diretto come tale
// versore. La sfera è divisa in due parti: una nel semi spazio Z+ e una in quello Z-. // versore. La sfera è divisa in due parti: una nel semi spazio Z+ e una in quello Z-.
@@ -33,6 +34,11 @@
// Costanti tipologia di componente lineare // Costanti tipologia di componente lineare
enum LinType { Line = 0, Ray = 1, Segment = 2} ; enum LinType { Line = 0, Ray = 1, Segment = 2} ;
//----------------------------------------------------------------------------
bool IntersLineBox( const Point3d& ptP, const Vector3d& vtV,
const Point3d& ptMin, const Point3d& ptMax, double& dU1, double& dU2) ;
// Costanti tipologia di intersezioni fra un componente lineare e un disco // Costanti tipologia di intersezioni fra un componente lineare e un disco
enum LinCompDiscIntersType { D_ERROR_INT = -1, D_NO_INTERS = 0, D_BOUNDARY_INT_LINE_NOT_IN_PLANE = 1, enum LinCompDiscIntersType { D_ERROR_INT = -1, D_NO_INTERS = 0, D_BOUNDARY_INT_LINE_NOT_IN_PLANE = 1,
D_INNER_INT_LINE_NOT_IN_PLANE = 2, D_ONE_INT_LINE_ON_PLANE = 3, D_INNER_INT_LINE_NOT_IN_PLANE = 2, D_ONE_INT_LINE_ON_PLANE = 3,
@@ -129,7 +135,7 @@ int IntersRayInfiniteCylinder( const Point3d& ptPLine, const Vector3d& vtVLine,
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// Valuta la posizione reciproca fra un cilindro infinito e un segmento. // Valuta la posizione reciproca fra un cilindro infinito e un segmento.
// Nel caso in cui il segmento giaccia sul cilindro, nIntType vale INF_INT e dU1 e dU2 // Nel caso in cui il sgmento giaccia sul cilindro, nIntType vale INF_INT e dU1 e dU2
// valgono rispettivamente 0 e dLen (lunghezza del segmento). // valgono rispettivamente 0 e dLen (lunghezza del segmento).
int IntersSegmentInfiniteCylinder( const Point3d& ptPLine, const Vector3d& vtVLine, double dLen, int IntersSegmentInfiniteCylinder( const Point3d& ptPLine, const Vector3d& vtVLine, double dLen,
const Point3d& ptPCyl, const Vector3d& vtVCyl, double dCylRad, const Point3d& ptPCyl, const Vector3d& vtVCyl, double dCylRad,
+4 -3
View File
@@ -1,7 +1,7 @@
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// EgalTech 2015-2022 // EgalTech 2015-2019
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// File : IntersLineSurfTm.cpp Data : 08.01.22 Versione : 2.4a3 // File : IntersLineSurfTm.cpp Data : 09.03.15 Versione : 2.1b6
// Contenuto : Implementazione della intersezione linea/superficie trimesh. // Contenuto : Implementazione della intersezione linea/superficie trimesh.
// //
// //
@@ -14,7 +14,8 @@
//--------------------------- Include ---------------------------------------- //--------------------------- Include ----------------------------------------
#include "stdafx.h" #include "stdafx.h"
#include "ProjPlane.h" #include "ProjPlane.h"
#include "IntersLineBox.h" #include "IntersLineSurfStd.h"
#include "/EgtDev/Include/EGkSurfTriMesh.h"
#include "/EgtDev/Include/EGkIntersLineTria.h" #include "/EgtDev/Include/EGkIntersLineTria.h"
#include "/EgtDev/Include/EGkIntersLineSurfTm.h" #include "/EgtDev/Include/EGkIntersLineSurfTm.h"
+6 -34
View File
@@ -1,8 +1,8 @@
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// EgalTech 2020-2020 // EgalTech 2020-2020
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// File : IntersPlaneBox.cpp Data : 07.05.20 Versione : 2.2e1 // File : IntersLineBox.cpp Data : 07.05.20 Versione : 2.2e1
// Contenuto : Implementazione della intersezione piano/box. // Contenuto : Implementazione della intersezione linea/box.
// //
// //
// //
@@ -20,47 +20,19 @@
using namespace std ; using namespace std ;
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// Box e piano devono essere nello stesso riferimento. Il box deve essere axis aligned.
bool bool
TestIntersPlaneBox( const Plane3d& plPlane, const BBox3d& b3Box) IntersPlaneBox( const Point3d& ptOn, const Vector3d& vtN, const BBox3d& b3Box,
{
// Verifica del piano
if ( ! plPlane.IsValid())
return false ;
// Centro e estensione del box
Point3d ptCen ;
Vector3d vtExt ;
if ( ! b3Box.GetCenterExtent( ptCen, vtExt))
return false ;
// Distanza del centro dal piano
double dDist = DistPointPlane( ptCen, plPlane) ;
// Proiezione dell'estensione sulla normale al piano
Vector3d vtN = plPlane.GetVersN() ;
double dProjExt = vtExt.x * abs( vtN.x) + vtExt.y * abs( vtN.y) + vtExt.z * abs( vtN.z) ;
// Confronto distanza del centro con estensione proiettata
return ( abs( dDist) < dProjExt + EPS_SMALL) ;
}
//----------------------------------------------------------------------------
bool
IntersPlaneBox( const Plane3d& plPlane, const BBox3d& b3Box,
PNTVECTOR& vPnt, BIPNTVECTOR& vBpt, TRIA3DVECTOR& vTria) PNTVECTOR& vPnt, BIPNTVECTOR& vBpt, TRIA3DVECTOR& vTria)
{ {
// Verifico il piano // Creo il piano
if ( ! plPlane.IsValid()) Plane3d plPlane ;
if ( ! plPlane.Set( ptOn, vtN))
return false ; return false ;
// Recupero i dati del Box // Recupero i dati del Box
Point3d ptMin ; Point3d ptMin ;
double dDimX, dDimY, dDimZ ; double dDimX, dDimY, dDimZ ;
if ( ! b3Box.GetMinDim( ptMin, dDimX, dDimY, dDimZ)) if ( ! b3Box.GetMinDim( ptMin, dDimX, dDimY, dDimZ))
return false ; return false ;
// Pulisco vettori intersezioni
vPnt.clear() ;
vBpt.clear() ;
vTria.clear() ;
// Verifico se può esistere intersezione
if ( ! TestIntersPlaneBox( plPlane, b3Box))
return true ;
// Contorno di base // Contorno di base
PolyLine PL ; PolyLine PL ;
PL.AddUPoint( 0, ptMin) ; PL.AddUPoint( 0, ptMin) ;
+97 -223
View File
@@ -27,39 +27,102 @@
using namespace std ; using namespace std ;
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
static void // Intersezione di un piano con una superficie TriMesh
UpdateIntersPlaneSurfTm( const Plane3d& plPlane, const Triangle3d& Tria, PNTVECTOR& vPnt, BIPNTVECTOR& vBpt, TRIA3DVECTOR& vTria, //----------------------------------------------------------------------------
PointGrid3d& PtGrid, HashGrids3d& LnGrid, HashGrids3d& TrGrid) bool
{ IntersPlaneSurfTm( const Plane3d& plPlane, const ISurfTriMesh& Stm,
// intersezione tra il piano e il triangolo PNTVECTOR& vPnt, BIPNTVECTOR& vBpt, TRIA3DVECTOR& vTria)
Point3d ptInt, ptInt2 ; {
int nRes = IntersPlaneTria( plPlane, Tria, ptInt, ptInt2) ; // verifico piano
// se vertice if ( &plPlane == nullptr || plPlane.GetVersN().IsSmall())
if ( nRes == IPTT_VERT) { return false ;
// verifico se punto già inserito // verifico superficie
int nId ; if ( &Stm == nullptr || ! Stm.IsValid())
if ( ! PtGrid.Find( ptInt, 10 * EPS_SMALL, nId)) { return false ;
vPnt.emplace_back( ptInt) ; // verifico parametri di ritorno
PtGrid.InsertPoint( ptInt, int( vPnt.size()) - 1) ; if ( &vPnt == nullptr || &vBpt == nullptr || &vTria == nullptr)
return false ;
vPnt.clear() ;
vBpt.clear() ;
vTria.clear() ;
// per ricerca veloce di punti ripetuti
PointGrid3d PtGrid ;
PtGrid.Init( 100) ;
// per ricerca veloce di linee ripetute
HashGrids3d LnGrid ;
LnGrid.SetActivationGrid( true) ;
// per ricerca veloce di triangoli ripetuti
HashGrids3d TrGrid ;
TrGrid.SetActivationGrid( true) ;
// cerco i triangoli intersecati dal piano
Triangle3d Tria ;
int nT = Stm.GetFirstTriangle( Tria) ;
while ( nT != SVT_NULL) {
// intersezione tra il piano e il triangolo
Point3d ptInt, ptInt2 ;
int nRes = IntersPlaneTria( plPlane, Tria, ptInt, ptInt2) ;
// se vertice
if ( nRes == IPTT_VERT) {
// verifico se punto già inserito
int nId ;
if ( ! PtGrid.Find( ptInt, 10 * EPS_SMALL, nId)) {
vPnt.emplace_back( ptInt) ;
PtGrid.InsertPoint( ptInt, int( vPnt.size()) - 1) ;
}
} }
} // se altrimenti segmento
// se altrimenti segmento else if ( nRes == IPTT_EDGE || nRes == IPTT_YES) {
else if ( nRes == IPTT_EDGE || nRes == IPTT_YES) { // se abbastanza lungo
// se abbastanza lungo if ( ! AreSamePointApprox( ptInt, ptInt2)) {
if ( ! AreSamePointApprox( ptInt, ptInt2)) { // verifico se già inserito
// verifico se già inserito bool bFound = false ;
BBox3d b3Line( ptInt, ptInt2) ;
INTVECTOR vnIds ;
if ( LnGrid.Find( b3Line, vnIds)) {
for ( int i = 0 ; i < int( vnIds.size()) ; ++ i) {
int nA = vnIds[i] ;
const Point3d& ptOth = vBpt[nA].first ;
const Point3d& ptOth2 = vBpt[nA].second ;
if ( ( AreSamePointEpsilon( ptInt, ptOth, 10 * EPS_SMALL) &&
AreSamePointEpsilon( ptInt2, ptOth2, 10 * EPS_SMALL)) ||
( AreSamePointEpsilon( ptInt, ptOth2, 10 * EPS_SMALL) &&
AreSamePointEpsilon( ptInt2, ptOth, 10 * EPS_SMALL))) {
bFound = true ;
break ;
}
}
}
// se non inserito, procedo
if ( ! bFound) {
vBpt.emplace_back( ptInt, ptInt2) ;
LnGrid.Add( int( vBpt.size()) - 1, b3Line) ;
LnGrid.Update() ;
}
}
}
// se altrimenti l'intero triangolo
else if ( nRes == IPTT_OVERLAPS) {
// verifico se triangolo già inserito
bool bFound = false ; bool bFound = false ;
BBox3d b3Line( ptInt, ptInt2) ; BBox3d b3Tria( Tria.GetP( 0), Tria.GetP( 1)) ;
b3Tria.Add( Tria.GetP( 2)) ;
INTVECTOR vnIds ; INTVECTOR vnIds ;
if ( LnGrid.Find( b3Line, vnIds)) { if ( TrGrid.Find( b3Tria, vnIds)) {
for ( int i = 0 ; i < int( vnIds.size()) ; ++ i) { for ( int i = 0 ; i < int( vnIds.size()) ; ++ i) {
int nA = vnIds[i] ; int nA = vnIds[i] ;
const Point3d& ptOth = vBpt[nA].first ; const Triangle3d& trOth = vTria[nA] ;
const Point3d& ptOth2 = vBpt[nA].second ; array< bool, 3> bOth = { false, false, false} ;
if ( ( AreSamePointEpsilon( ptInt, ptOth, 10 * EPS_SMALL) && for ( int j = 0 ; j < 3 ; ++ j) {
AreSamePointEpsilon( ptInt2, ptOth2, 10 * EPS_SMALL)) || for ( int k = 0 ; k < 3 ; ++ k) {
( AreSamePointEpsilon( ptInt, ptOth2, 10 * EPS_SMALL) && if ( ! bOth[k])
AreSamePointEpsilon( ptInt2, ptOth, 10 * EPS_SMALL))) { bOth[k] = AreSamePointEpsilon( Tria.GetP( j), trOth.GetP( k), 10 * EPS_SMALL) ;
}
}
if ( bOth[0] && bOth[1] && bOth[2]) {
bFound = true ; bFound = true ;
break ; break ;
} }
@@ -67,52 +130,15 @@ UpdateIntersPlaneSurfTm( const Plane3d& plPlane, const Triangle3d& Tria, PNTVECT
} }
// se non inserito, procedo // se non inserito, procedo
if ( ! bFound) { if ( ! bFound) {
vBpt.emplace_back( ptInt, ptInt2) ; vTria.emplace_back( Tria) ;
LnGrid.Add( int( vBpt.size()) - 1, b3Line) ; TrGrid.Add( int( vTria.size()) - 1, b3Tria) ;
LnGrid.Update() ; TrGrid.Update() ;
} }
} }
} // passo al prossimo triangolo
// se altrimenti l'intero triangolo nT = Stm.GetNextTriangle( nT, Tria) ;
else if ( nRes == IPTT_OVERLAPS) {
// verifico se triangolo già inserito
bool bFound = false ;
BBox3d b3Tria( Tria.GetP( 0), Tria.GetP( 1)) ;
b3Tria.Add( Tria.GetP( 2)) ;
INTVECTOR vnIds ;
if ( TrGrid.Find( b3Tria, vnIds)) {
for ( int i = 0 ; i < int( vnIds.size()) ; ++ i) {
int nA = vnIds[i] ;
const Triangle3d& trOth = vTria[nA] ;
array< bool, 3> bOth = { false, false, false} ;
for ( int j = 0 ; j < 3 ; ++ j) {
for ( int k = 0 ; k < 3 ; ++ k) {
if ( ! bOth[k])
bOth[k] = AreSamePointEpsilon( Tria.GetP( j), trOth.GetP( k), 10 * EPS_SMALL) ;
}
}
if ( bOth[0] && bOth[1] && bOth[2]) {
bFound = true ;
break ;
}
}
}
// se non inserito, procedo
if ( ! bFound) {
vTria.emplace_back( Tria) ;
TrGrid.Add( int( vTria.size()) - 1, b3Tria) ;
TrGrid.Update() ;
}
} }
return ;
}
//----------------------------------------------------------------------------
static void
AdjustIntersPlaneSurfTm( PNTVECTOR& vPnt, BIPNTVECTOR& vBpt, TRIA3DVECTOR& vTria,
const Plane3d& plPlane, const HashGrids3d& LnGrid, const HashGrids3d& TrGrid)
{
// rimuovo i punti che stanno sui segmenti // rimuovo i punti che stanno sui segmenti
for ( int i = int( vPnt.size()) - 1 ; i >= 0 ; -- i) { for ( int i = int( vPnt.size()) - 1 ; i >= 0 ; -- i) {
bool bFound = false ; bool bFound = false ;
@@ -164,7 +190,7 @@ AdjustIntersPlaneSurfTm( PNTVECTOR& vPnt, BIPNTVECTOR& vBpt, TRIA3DVECTOR& vTria
int nA = vnIds[j] ; int nA = vnIds[j] ;
const Triangle3d& trOth = vTria[nA] ; const Triangle3d& trOth = vTria[nA] ;
if ( DistPointTriangle( ptStart, trOth).IsEpsilon( 10 * EPS_SMALL) && if ( DistPointTriangle( ptStart, trOth).IsEpsilon( 10 * EPS_SMALL) &&
DistPointTriangle( ptEnd, trOth).IsEpsilon( 10 * EPS_SMALL)) { DistPointTriangle( ptEnd, trOth).IsEpsilon( 10 * EPS_SMALL)) {
bFound = true ; bFound = true ;
break ; break ;
} }
@@ -174,157 +200,5 @@ AdjustIntersPlaneSurfTm( PNTVECTOR& vPnt, BIPNTVECTOR& vBpt, TRIA3DVECTOR& vTria
vBpt.erase( vBpt.begin() + i) ; vBpt.erase( vBpt.begin() + i) ;
} }
// porto i punti esattamente nel piano
for ( int i = 0 ; i < int( vPnt.size()) ; ++ i) {
vPnt[i] = ProjectPointOnPlane( vPnt[i], plPlane) ;
}
// porto i segmenti esattamente nel piano
for ( int i = 0 ; i < int( vBpt.size()) ; ++ i) {
vBpt[i].first = ProjectPointOnPlane( vBpt[i].first, plPlane) ;
vBpt[i].second = ProjectPointOnPlane( vBpt[i].second, plPlane) ;
}
// porto i triangoli esattamente nel piano
for ( int i = 0 ; i < int( vTria.size()) ; ++ i) {
Triangle3d& trTria = vTria[i] ;
trTria.SetP( 0, ProjectPointOnPlane( trTria.GetP( 0), plPlane)) ;
trTria.SetP( 1, ProjectPointOnPlane( trTria.GetP( 1), plPlane)) ;
trTria.SetP( 2, ProjectPointOnPlane( trTria.GetP( 2), plPlane)) ;
trTria.Validate( true) ;
}
return ;
}
//----------------------------------------------------------------------------
// Intersezione di un piano con una superficie TriMesh
//----------------------------------------------------------------------------
bool
IntersPlaneSurfTm( const Plane3d& plPlane, const ISurfTriMesh& Stm,
PNTVECTOR& vPnt, BIPNTVECTOR& vBpt, TRIA3DVECTOR& vTria)
{
// verifico piano
if ( &plPlane == nullptr || plPlane.GetVersN().IsSmall())
return false ;
// verifico superficie
if ( &Stm == nullptr || ! Stm.IsValid())
return false ;
// verifico parametri di ritorno
if ( &vPnt == nullptr || &vBpt == nullptr || &vTria == nullptr)
return false ;
vPnt.clear() ;
vBpt.clear() ;
vTria.clear() ;
// per ricerca veloce di punti ripetuti
PointGrid3d PtGrid ;
PtGrid.Init( 100) ;
// per ricerca veloce di linee ripetute
HashGrids3d LnGrid ;
LnGrid.SetActivationGrid( true) ;
// per ricerca veloce di triangoli ripetuti
HashGrids3d TrGrid ;
TrGrid.SetActivationGrid( true) ;
// cerco i triangoli intersecati dal piano
Triangle3d Tria ;
int nT = Stm.GetFirstTriangle( Tria) ;
while ( nT != SVT_NULL) {
UpdateIntersPlaneSurfTm( plPlane, Tria, vPnt, vBpt, vTria, PtGrid, LnGrid, TrGrid) ;
nT = Stm.GetNextTriangle( nT, Tria) ;
}
AdjustIntersPlaneSurfTm( vPnt, vBpt, vTria, plPlane, LnGrid, TrGrid) ;
return true ; return true ;
} }
//----------------------------------------------------------------------------
// Intersezione di molti piani paralleli con una superficie TriMesh
//----------------------------------------------------------------------------
IntersParPlanesSurfTm::IntersParPlanesSurfTm( const Frame3d& frPlanes, const ISurfTriMesh& Stm)
: m_bOk( false), m_frPlanes( frPlanes), m_pSTm( &Stm)
{
// verifico esistenza superficie
if ( m_pSTm == nullptr || ! m_pSTm->IsValid())
return ;
// creo HashGrid 1d
const int LIM_HG_TRIA = 127 ;
m_HGrids.SetActivationGrid( m_pSTm->GetTriangleCount() > LIM_HG_TRIA) ;
// riempio HashGrid
Triangle3d Tria ;
int nT = Stm.GetFirstTriangle( Tria) ;
while ( nT != SVT_NULL) {
// calcolo il BBox del triangolo nel riferimento dei piani
Tria.ToLoc( m_frPlanes) ;
BBox3d b3Tria ;
b3Tria.Add( Tria.GetP( 0)) ;
b3Tria.Add( Tria.GetP( 1)) ;
b3Tria.Add( Tria.GetP( 2)) ;
// inserisco nella griglia
if ( ! m_HGrids.Add( nT, b3Tria))
return ;
// passo al prossimo triangolo
nT = Stm.GetNextTriangle( nT, Tria) ;
}
// aggiorno
m_bOk = m_HGrids.Update() ;
}
//----------------------------------------------------------------------------
bool
IntersParPlanesSurfTm::GetInters( double dDist, PNTVECTOR& vPnt, BIPNTVECTOR& vBpt, TRIA3DVECTOR& vTria) const
{
// verifico validità
if ( ! m_bOk)
return false ;
// verifico parametri di ritorno
if ( &vPnt == nullptr || &vBpt == nullptr || &vTria == nullptr)
return false ;
vPnt.clear() ;
vBpt.clear() ;
vTria.clear() ;
// per ricerca veloce di punti ripetuti
PointGrid3d PtGrid ;
PtGrid.Init( 100) ;
// per ricerca veloce di linee ripetute
HashGrids3d LnGrid ;
LnGrid.SetActivationGrid( true) ;
// per ricerca veloce di triangoli ripetuti
HashGrids3d TrGrid ;
TrGrid.SetActivationGrid( true) ;
// calcolo il piano ( in globale)
Point3d ptPl = m_frPlanes.Orig() + dDist * m_frPlanes.VersZ() ;
Plane3d plPlane ;
plPlane.Set( ptPl, m_frPlanes.VersZ()) ;
// calcolo box del piano ( nel riferimento)
BBox3d b3Plane ;
b3Plane.Add( Point3d( 0, 0, dDist)) ;
b3Plane.Expand( INFINITO - 1 , INFINITO - 1, 0) ;
// recupero indici triangoli che intersecano box
INTVECTOR vnIds ;
if ( m_HGrids.Find( b3Plane, vnIds)) {
for ( int i = 0 ; i < int( vnIds.size()) ; ++ i) {
int nT = vnIds[i] ;
Triangle3d Tria ;
m_pSTm->GetTriangle( nT, Tria) ;
UpdateIntersPlaneSurfTm( plPlane, Tria, vPnt, vBpt, vTria, PtGrid, LnGrid, TrGrid) ;
}
}
AdjustIntersPlaneSurfTm( vPnt, vBpt, vTria, plPlane, LnGrid, TrGrid) ;
return true ;
}
+2 -2
View File
@@ -21,7 +21,7 @@
#include "/EgtDev/Include/EGkPointGrid3d.h" #include "/EgtDev/Include/EGkPointGrid3d.h"
#include "/EgtDev/Include/EGkHashGrids3d.h" #include "/EgtDev/Include/EGkHashGrids3d.h"
#include "/EgtDev/Include/EGkDistPointTria.h" #include "/EgtDev/Include/EGkDistPointTria.h"
#include "/EgtDev/Include/EGnStringUtils.h" #include "/EgtDev/Include/EgnStringUtils.h"
#include <array> #include <array>
using namespace std ; using namespace std ;
@@ -116,7 +116,7 @@ IntersSurfTmSurfTm( const ISurfTriMesh& Stm1, const ISurfTriMesh& Stm2,
} }
} }
// se altrimenti sovrapposizione // se altrimenti sovrapposizione
else if ( nRes == ITTT_OVERLAPS || nRes == ITTT_COUNTER_OVERLAPS) { else if ( nRes == ITTT_OVERLAPS) {
for ( const auto& Tria : vIttTria) { for ( const auto& Tria : vIttTria) {
// verifico se triangolo già inserito // verifico se triangolo già inserito
bool bFound = false ; bool bFound = false ;
+5 -34
View File
@@ -83,37 +83,8 @@ IntersTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, Point3d& p
// se i triangoli sono complanari // se i triangoli sono complanari
if ( nResPP == IPPT_OVERLAPS || if ( nResPP == IPPT_OVERLAPS ||
((( nVertPos1 == 0 && nVertNeg1 == 0) || ( nVertPos2 == 0 && nVertNeg2 == 0)) && ((( nVertPos1 == 0 && nVertNeg1 == 0) || ( nVertPos2 == 0 && nVertNeg2 == 0)) &&
( trTria1.GetN() ^ trTria2.GetN()).SqLen() < 25 * SIN_EPS_ANG_SMALL * SIN_EPS_ANG_SMALL)) { ( trTria1.GetN() ^ trTria2.GetN()).SqLen() < 25 * SIN_EPS_ANG_SMALL * SIN_EPS_ANG_SMALL))
// verifica per triangoli con normali controverse return IntersCoplanarTriaTria( trTria1, trTria2, vTria) ;
bool bCounter = false ;
Triangle3d trMyTria2 = trTria2 ;
if ( trTria1.GetN() * trTria2.GetN() < 0) {
Point3d ptV0 = trMyTria2.GetP( 0) ;
trMyTria2.SetP( 0, trMyTria2.GetP( 1)) ;
trMyTria2.SetP( 1, ptV0) ;
trMyTria2.Validate() ;
bCounter = true ;
}
// verifica per triangoli coincidenti
bool bAreSameTria = ( ( AreSamePointExact( trTria1.GetP( 0), trMyTria2.GetP( 0)) &&
AreSamePointExact( trTria1.GetP( 1), trMyTria2.GetP( 1)) &&
AreSamePointExact( trTria1.GetP( 2), trMyTria2.GetP( 2))) ||
( AreSamePointExact( trTria1.GetP( 0), trMyTria2.GetP( 1)) &&
AreSamePointExact( trTria1.GetP( 1), trMyTria2.GetP( 2)) &&
AreSamePointExact( trTria1.GetP( 2), trMyTria2.GetP( 0))) ||
( AreSamePointExact( trTria1.GetP( 0), trMyTria2.GetP( 2)) &&
AreSamePointExact( trTria1.GetP( 1), trMyTria2.GetP( 0)) &&
AreSamePointExact( trTria1.GetP( 2), trMyTria2.GetP( 1)))) &&
( AreSameVectorExact( trTria1.GetN(), trMyTria2.GetN())) ;
if ( bAreSameTria) {
vTria.emplace_back( trTria1) ;
return ( bCounter ? ITTT_COUNTER_OVERLAPS : ITTT_OVERLAPS) ;
}
if ( ITTT_OVERLAPS == IntersCoplanarTriaTria( trTria1, trMyTria2, vTria)) {
return ( bCounter ? ITTT_COUNTER_OVERLAPS : ITTT_OVERLAPS) ;
}
return ITTT_NO ;
}
// limito la linea di intersezione con il primo triangolo // limito la linea di intersezione con il primo triangolo
Point3d ptSt1, ptEn1 ; Point3d ptSt1, ptEn1 ;
@@ -141,7 +112,7 @@ IntersTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, Point3d& p
int int
IntersCoplanarTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, TRIA3DVECTOR& vTria) IntersCoplanarTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, TRIA3DVECTOR& vTria)
{ {
// Se i tre vertici del secondo triangolo stanno tutti a destra di almeno un lato del primo, non c' intersezione // Se i tre vertici del secondo triangolo stanno tutti a destra di almeno un lato del primo, non c'è intersezione
for ( int i = 0 ; i < 3 ; ++ i) { for ( int i = 0 ; i < 3 ; ++ i) {
Vector3d vtSide = trTria1.GetP( ( i + 1) % 3) - trTria1.GetP( i) ; Vector3d vtSide = trTria1.GetP( ( i + 1) % 3) - trTria1.GetP( i) ;
Vector3d vtSN = vtSide ^ trTria1.GetN() ; Vector3d vtSN = vtSide ^ trTria1.GetN() ;
@@ -151,7 +122,7 @@ IntersCoplanarTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, TR
( trTria2.GetP( 2) - trTria1.GetP( i)) * vtSN > - EPS_TRIA_H) ( trTria2.GetP( 2) - trTria1.GetP( i)) * vtSN > - EPS_TRIA_H)
return ITTT_NO ; return ITTT_NO ;
} }
// Se i tre vertici del primo triangolo stanno tutti a destra di almeno un lato del secondo, non c' intersezione // Se i tre vertici del primo triangolo stanno tutti a destra di almeno un lato del secondo, non c'è intersezione
for ( int i = 0 ; i < 3 ; ++ i) { for ( int i = 0 ; i < 3 ; ++ i) {
Vector3d vtSide = trTria2.GetP( ( i + 1) % 3) - trTria2.GetP( i) ; Vector3d vtSide = trTria2.GetP( ( i + 1) % 3) - trTria2.GetP( i) ;
Vector3d vtSN = vtSide ^ trTria2.GetN() ; Vector3d vtSN = vtSide ^ trTria2.GetN() ;
@@ -234,7 +205,7 @@ int
FindTriaTriaIntersType( const Triangle3d& trTria1, const Triangle3d& trTria2, const Point3d& ptLineSt, const Vector3d& vtLineDir, FindTriaTriaIntersType( const Triangle3d& trTria1, const Triangle3d& trTria2, const Point3d& ptLineSt, const Vector3d& vtLineDir,
double dStU1, double dEnU1, double dStU2, double dEnU2, int nRes1, int nRes2, double& dIntStU, double& dIntEnU) double dStU1, double dEnU1, double dStU2, double dEnU2, int nRes1, int nRes2, double& dIntStU, double& dIntEnU)
{ {
// Controllo su validit input // Controllo su validità input
if ( ! ( trTria1.IsValid() && trTria2.IsValid() && vtLineDir.IsNormalized())) if ( ! ( trTria1.IsValid() && trTria2.IsValid() && vtLineDir.IsNormalized()))
return ITTT_NO ; return ITTT_NO ;
// Casi // Casi
+3 -3
View File
@@ -16,9 +16,9 @@
#include "CurveLine.h" #include "CurveLine.h"
#include "CurveArc.h" #include "CurveArc.h"
#include "CreateCurveAux.h" #include "CreateCurveAux.h"
#include "/EgtDev/Include/EGkLinePerpTwoCurves.h" #include "/EgtDev/Include/EgkLinePerpTwoCurves.h"
#include "/EgtDev/Include/EGkLinePntPerpCurve.h" #include "/EgtDev/Include/EgkLinePntPerpCurve.h"
#include "/EgtDev/Include/EGkDistPointCurve.h" #include "/EgtDev/Include/EgkDistPointCurve.h"
#include "/EgtDev/Include/EgtPointerOwner.h" #include "/EgtDev/Include/EgtPointerOwner.h"
using namespace std ; using namespace std ;
+2 -2
View File
@@ -14,8 +14,8 @@
//--------------------------- Include ---------------------------------------- //--------------------------- Include ----------------------------------------
#include "stdafx.h" #include "stdafx.h"
#include "CurveLine.h" #include "CurveLine.h"
#include "/EgtDev/Include/EGkLinePntMinDistCurve.h" #include "/EgtDev/Include/EgkLinePntMinDistCurve.h"
#include "/EgtDev/Include/EGkDistPointCurve.h" #include "/EgtDev/Include/EgkDistPointCurve.h"
#include "/EgtDev/Include/EgtPointerOwner.h" #include "/EgtDev/Include/EgtPointerOwner.h"
using namespace std ; using namespace std ;

Some files were not shown because too many files have changed in this diff Show More