Compare commits
73 Commits
ArcBox
...
3dm_import
| Author | SHA1 | Date | |
|---|---|---|---|
| e2eb219c5a | |||
| e44b08d669 | |||
| 9b34154a16 | |||
| 10dd5828ce | |||
| bf2a3f0e22 | |||
| 38146c6294 | |||
| eccf683ef4 | |||
| 381a137604 | |||
| e5ed9efdd1 | |||
| 1ec38952ed | |||
| 0eb19f1735 | |||
| 737f4f4ffa | |||
| 8a81c3543e | |||
| c0fe5f14a8 | |||
| 9fce0bd4f4 | |||
| 663784a841 | |||
| 238c0ae490 | |||
| c4a4da6945 | |||
| fb62c6d68e | |||
| 2ba32eb93c | |||
| 6e34ab6169 | |||
| 538126cfe5 | |||
| a0a6bf8377 | |||
| ba05c5307a | |||
| 234878388d | |||
| baac48f7b9 | |||
| e4815830cd | |||
| b5b48bf4c2 | |||
| 8f84f78b16 | |||
| 8a3d46416d | |||
| c4f1a7f97b | |||
| 0c1ad4dd86 | |||
| 36547c24c2 | |||
| 3d4042e274 | |||
| b9a8777b96 | |||
| 6cf009fae3 | |||
| 735c12bca7 | |||
| 393cac35c5 | |||
| 804a434e75 | |||
| 71ba650cc5 | |||
| 0a63a4c9a2 | |||
| b78212c3a1 | |||
| 8420edecb5 | |||
| 7c6ddf2a6f | |||
| 2d8c815032 | |||
| 7023d721f4 | |||
| 0f530271f0 | |||
| ec3389633c | |||
| 5c0848797c | |||
| 545e37b7cd | |||
| 469e660da0 | |||
| 13b02f51a3 | |||
| d1790d8f07 | |||
| c925c6a17a | |||
| 00ccfe967e | |||
| 3b5d145f85 | |||
| ee4592a113 | |||
| 35618b1882 | |||
| bde7ff1e5c | |||
| 10f73435bf | |||
| 21b4af444b | |||
| 4410a83631 | |||
| ca19f9e735 | |||
| aa8ae0146d | |||
| 29138a63c8 | |||
| 64a904b628 | |||
| c939a50a39 | |||
| 27f28b9f28 | |||
| 053410f43b | |||
| a74949c832 | |||
| f84aefc82d | |||
| 133b590e1c | |||
| 65909b3366 |
+6
-6
@@ -226,14 +226,14 @@ MyAdjustLoops( ICurve* pCurve, ICURVEPLIST& CrvLst)
|
||||
Point3d ptEnd2 ; pCrvCo2->GetEndPoint( ptEnd2) ;
|
||||
// se aperta, verifico se concatenabile alla principale
|
||||
if ( ! AreSamePointEpsilon( ptStart2, ptEnd2, 10 * EPS_SMALL)) {
|
||||
if ( AreSamePointEpsilon( ptEnd, ptStart2, 10 * EPS_SMALL)) {
|
||||
pCrvCo->AddCurve( pCrvCo2, true, 10 * EPS_SMALL) ;
|
||||
if ( AreSamePointEpsilon( ptEnd, ptStart2, 100 * EPS_SMALL)) {
|
||||
pCrvCo->AddCurve( pCrvCo2, true, 100 * EPS_SMALL) ;
|
||||
CrvLst.erase( iIter2) ;
|
||||
ptEnd = ptEnd2 ;
|
||||
iIter2 = next( iIter) ;
|
||||
}
|
||||
else if ( AreSamePointEpsilon( ptEnd2, ptStart, 10 * EPS_SMALL)) {
|
||||
pCrvCo->AddCurve( pCrvCo2, false, 10 * EPS_SMALL) ;
|
||||
else if ( AreSamePointEpsilon( ptEnd2, ptStart, 100 * EPS_SMALL)) {
|
||||
pCrvCo->AddCurve( pCrvCo2, false, 100 * EPS_SMALL) ;
|
||||
CrvLst.erase( iIter2) ;
|
||||
ptStart = ptStart2 ;
|
||||
iIter2 = next( iIter) ;
|
||||
@@ -278,7 +278,7 @@ MyAdjustLoops( ICurve* pCurve, ICURVEPLIST& CrvLst)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
AdjustLoops( ICurve* pCurve, ICURVEPLIST& CrvLst)
|
||||
AdjustLoops( ICurve* pCurve, ICURVEPLIST& CrvLst, bool bNeedSameProp)
|
||||
{
|
||||
// elimino eventuali sovrapposizioni e accostamenti
|
||||
if ( ! MyAdjustLoops( pCurve, CrvLst))
|
||||
@@ -291,7 +291,7 @@ AdjustLoops( ICurve* pCurve, ICURVEPLIST& CrvLst)
|
||||
// elimino eventuali Spikes e Small Z
|
||||
pCrvCo->RemoveSmallDefects( 2 * LIN_TOL_MIN, ANG_TOL_STD_DEG, true) ;
|
||||
// unisco eventuali tratti allineati
|
||||
pCrvCo->MergeCurves( LIN_TOL_MIN, ANG_TOL_STD_DEG) ;
|
||||
pCrvCo->MergeCurves( LIN_TOL_MIN, ANG_TOL_STD_DEG, true, bNeedSameProp) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -17,4 +17,4 @@
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool AdjustLoops( ICurve* pCurve, ICURVEPLIST& CrvLst) ;
|
||||
bool AdjustLoops( ICurve* pCurve, ICURVEPLIST& CrvLst, bool bNeedSameProp) ;
|
||||
|
||||
@@ -168,7 +168,7 @@ CurveArc* GetArcCenTgCompoPnt( const Point3d& ptCen, const CurveComposite& crvCo
|
||||
double dSqDist = SqDist( ptNearStart, ptTg) ;
|
||||
if ( dSqDist < dMinSqDist) {
|
||||
dMinSqDist = dSqDist ;
|
||||
pCrvArc.Set( Release( pCrvAtmp)) ;
|
||||
pCrvArc.Set( pCrvAtmp) ;
|
||||
if ( pPtTg != nullptr)
|
||||
*pPtTg = ptTg ;
|
||||
}
|
||||
|
||||
@@ -204,7 +204,7 @@ GetArcPntDirTgArc( const Point3d& ptP, const Vector3d& vtDir, const CurveArc& cr
|
||||
if ( bOk1) {
|
||||
double dOffset = ( bOutSide ? crvArcL.GetRadius() : - crvArcL.GetRadius()) ;
|
||||
if ( pCrv1->GetType() == CRV_ARC)
|
||||
bOk1 = (dynamic_cast<CurveArc*>(Get(pCrv1)))->ExtendedOffset( dOffset) ;
|
||||
bOk1 = (static_cast<CurveArc*>( Get( pCrv1)))->ExtendedOffset( dOffset) ;
|
||||
else
|
||||
bOk1 = pCrv1->SimpleOffset( dOffset) ;
|
||||
}
|
||||
@@ -235,7 +235,7 @@ GetArcPntDirTgArc( const Point3d& ptP, const Vector3d& vtDir, const CurveArc& cr
|
||||
if ( bOk2) {
|
||||
double dOffset = ( bOutSide ? - crvArcL.GetRadius() : crvArcL.GetRadius()) ;
|
||||
if ( pCrv2->GetType() == CRV_ARC)
|
||||
bOk2 = (dynamic_cast<CurveArc*>(Get(pCrv2)))->ExtendedOffset( dOffset) ;
|
||||
bOk2 = (static_cast<CurveArc*>( Get( pCrv2)))->ExtendedOffset( dOffset) ;
|
||||
else
|
||||
bOk2 = pCrv2->SimpleOffset( dOffset) ;
|
||||
}
|
||||
@@ -337,7 +337,7 @@ GetArcPntDirTgCompo( const Point3d& ptP, const Vector3d& vtDir, const CurveCompo
|
||||
double dSqDist = SqDist( ptNear, ptTg) ;
|
||||
if ( dSqDist < dMinSqDist) {
|
||||
dMinSqDist = dSqDist ;
|
||||
pCrvNew.Set( Release( pCrvTmp)) ;
|
||||
pCrvNew.Set( pCrvTmp) ;
|
||||
if ( pPtTg != nullptr)
|
||||
*pPtTg = ptTg ;
|
||||
}
|
||||
|
||||
+38
-10
@@ -1,7 +1,7 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2014-2022
|
||||
// EgalTech 2014-2023
|
||||
//----------------------------------------------------------------------------
|
||||
// File : ArcSpecial.cpp Data : 18.08.22 Versione : 2.4h2
|
||||
// File : ArcSpecial.cpp Data : 04.08.23 Versione : 2.5h1
|
||||
// Contenuto : Implementazione funzioni per calcoli speciali archi.
|
||||
//
|
||||
//
|
||||
@@ -20,7 +20,6 @@
|
||||
|
||||
using namespace std ;
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Come la CurveArc::Set2PD, ma se raggio infinito restituisce una retta
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -28,7 +27,7 @@ ICurve*
|
||||
GetArc2PD( const Point3d& ptStart, const Point3d& ptEnd, double dDirStartDeg)
|
||||
{
|
||||
// creo l'oggetto arco
|
||||
PtrOwner<ICurveArc> pArc( CreateCurveArc()) ;
|
||||
PtrOwner<CurveArc> pArc( CreateBasicCurveArc()) ;
|
||||
if ( IsNull( pArc))
|
||||
return nullptr ;
|
||||
|
||||
@@ -43,7 +42,7 @@ GetArc2PD( const Point3d& ptStart, const Point3d& ptEnd, double dDirStartDeg)
|
||||
// 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) {
|
||||
// creo l'oggetto retta
|
||||
PtrOwner<ICurveLine> pLine( CreateCurveLine()) ;
|
||||
PtrOwner<CurveLine> pLine( CreateBasicCurveLine()) ;
|
||||
if ( IsNull( pLine))
|
||||
return nullptr ;
|
||||
// calcolo retta, se ok la restituisco ed esco
|
||||
@@ -61,7 +60,7 @@ ICurve*
|
||||
GetArc2PVN( const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtDirS, const Vector3d& vtN)
|
||||
{
|
||||
// creo l'oggetto arco
|
||||
PtrOwner<ICurveArc> pArc( CreateCurveArc()) ;
|
||||
PtrOwner<CurveArc> pArc( CreateBasicCurveArc()) ;
|
||||
if ( IsNull( pArc))
|
||||
return nullptr ;
|
||||
|
||||
@@ -74,7 +73,7 @@ GetArc2PVN( const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtDirS
|
||||
// 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) {
|
||||
// creo l'oggetto retta
|
||||
PtrOwner<ICurveLine> pLine( CreateCurveLine()) ;
|
||||
PtrOwner<CurveLine> pLine( CreateBasicCurveLine()) ;
|
||||
if ( IsNull( pLine))
|
||||
return nullptr ;
|
||||
// calcolo retta, se ok la restituisco ed esco
|
||||
@@ -85,6 +84,35 @@ GetArc2PVN( const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtDirS
|
||||
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
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -92,7 +120,7 @@ ICurve*
|
||||
GetArc3P( const Point3d& ptStart, const Point3d& ptOther, const Point3d& ptEnd, bool bCirc)
|
||||
{
|
||||
// creo l'oggetto arco
|
||||
PtrOwner<ICurveArc> pArc( CreateCurveArc()) ;
|
||||
PtrOwner<CurveArc> pArc( CreateBasicCurveArc()) ;
|
||||
if ( IsNull( pArc))
|
||||
return nullptr ;
|
||||
|
||||
@@ -108,7 +136,7 @@ GetArc3P( const Point3d& ptStart, const Point3d& ptOther, const Point3d& ptEnd,
|
||||
// verifico se i punti sono allineati nel giusto verso
|
||||
if ( ( ptOther - ptStart) * ( ptEnd - ptOther) > EPS_ZERO) {
|
||||
// creo l'oggetto retta
|
||||
PtrOwner<ICurveLine> pLine( CreateCurveLine()) ;
|
||||
PtrOwner<CurveLine> pLine( CreateBasicCurveLine()) ;
|
||||
if ( IsNull( pLine))
|
||||
return nullptr ;
|
||||
// calcolo retta, se ok la restituisco ed esco
|
||||
@@ -126,7 +154,7 @@ ICurveArc*
|
||||
GetArc2PCN( const Point3d& ptStart, const Point3d& ptEnd, const Point3d& ptNearCen, const Vector3d& vtN)
|
||||
{
|
||||
// creo l'oggetto arco
|
||||
PtrOwner<ICurveArc> pArc( CreateCurveArc()) ;
|
||||
PtrOwner<CurveArc> pArc( CreateBasicCurveArc()) ;
|
||||
if ( IsNull( pArc))
|
||||
return nullptr ;
|
||||
|
||||
|
||||
@@ -362,6 +362,8 @@ 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() ;
|
||||
|
||||
+103
-30
@@ -53,7 +53,8 @@ BBox3d::Set( double dX1, double dY1, double dZ1, double dX2, double dY2, double
|
||||
bool
|
||||
BBox3d::IsValid( void) const
|
||||
{
|
||||
return ( m_ptMin.x < ( m_ptMax.x + EPS_SMALL) &&
|
||||
return ( m_ptMin.IsValid() && m_ptMax.IsValid() &&
|
||||
m_ptMin.x < ( m_ptMax.x + EPS_SMALL) &&
|
||||
m_ptMin.y < ( m_ptMax.y + EPS_SMALL) &&
|
||||
m_ptMin.z < ( m_ptMax.z + EPS_SMALL)) ;
|
||||
}
|
||||
@@ -447,69 +448,141 @@ BBox3d::EnclosesXY( const BBox3d& b3Box) const
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
BBox3d::Overlaps( const BBox3d& b3B) const
|
||||
BBox3d::Overlaps( const BBox3d& b3Box) const
|
||||
{
|
||||
if ( m_ptMax.x < b3B.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3B.m_ptMax.x + EPS_SMALL)
|
||||
if ( m_ptMax.x < b3Box.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3Box.m_ptMax.x + EPS_SMALL)
|
||||
return false ;
|
||||
if ( m_ptMax.y < b3B.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3B.m_ptMax.y + EPS_SMALL)
|
||||
if ( m_ptMax.y < b3Box.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3Box.m_ptMax.y + EPS_SMALL)
|
||||
return false ;
|
||||
if ( m_ptMax.z < b3B.m_ptMin.z - EPS_SMALL || m_ptMin.z > b3B.m_ptMax.z + EPS_SMALL)
|
||||
if ( m_ptMax.z < b3Box.m_ptMin.z - EPS_SMALL || m_ptMin.z > b3Box.m_ptMax.z + EPS_SMALL)
|
||||
return false ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
BBox3d::OverlapsXY( const BBox3d& b3B) const
|
||||
BBox3d::OverlapsXY( const BBox3d& b3Box) const
|
||||
{
|
||||
if ( m_ptMax.x < b3B.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3B.m_ptMax.x + EPS_SMALL)
|
||||
if ( m_ptMax.x < b3Box.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3Box.m_ptMax.x + EPS_SMALL)
|
||||
return false ;
|
||||
if ( m_ptMax.y < b3B.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3B.m_ptMax.y + EPS_SMALL)
|
||||
if ( m_ptMax.y < b3Box.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3Box.m_ptMax.y + EPS_SMALL)
|
||||
return false ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
BBox3d::FindIntersection( const BBox3d& b3B, BBox3d& b3Int) const
|
||||
inline bool
|
||||
TestSeparatingAxis( const Vector3d& vtAx, const Vector3d& vtDiff, const Vector3d& vtHe,
|
||||
const Vector3d& vtHe2X, const Vector3d& vtHe2Y, const Vector3d& vtHe2Z)
|
||||
{
|
||||
if ( ! IsValid() || ! b3B.IsValid())
|
||||
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
|
||||
BBox3d::Overlaps( const Frame3d& frBox, const BBox3d& b3Box) const
|
||||
{
|
||||
// Verifico validità di entrambi i box
|
||||
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 ;
|
||||
// verifico direttamente la sovrapposizione
|
||||
if ( m_ptMax.x < b3B.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3B.m_ptMax.x + EPS_SMALL)
|
||||
if ( m_ptMax.x < b3Box.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3Box.m_ptMax.x + EPS_SMALL)
|
||||
return false ;
|
||||
if ( m_ptMax.y < b3B.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3B.m_ptMax.y + EPS_SMALL)
|
||||
if ( m_ptMax.y < b3Box.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3Box.m_ptMax.y + EPS_SMALL)
|
||||
return false ;
|
||||
if ( m_ptMax.z < b3B.m_ptMin.z - EPS_SMALL || m_ptMin.z > b3B.m_ptMax.z + EPS_SMALL)
|
||||
if ( m_ptMax.z < b3Box.m_ptMin.z - EPS_SMALL || m_ptMin.z > b3Box.m_ptMax.z + EPS_SMALL)
|
||||
return false ;
|
||||
// calcolo il box intersezione
|
||||
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 >= b3B.m_ptMin.y) ? m_ptMin.y : b3B.m_ptMin.y) ;
|
||||
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 <= b3B.m_ptMax.x) ? m_ptMax.x : b3B.m_ptMax.x) ;
|
||||
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 <= b3B.m_ptMax.z) ? m_ptMax.z : b3B.m_ptMax.z) ;
|
||||
b3Int.m_ptMin.x = (( m_ptMin.x >= b3Box.m_ptMin.x) ? m_ptMin.x : b3Box.m_ptMin.x) ;
|
||||
b3Int.m_ptMin.y = (( m_ptMin.y >= b3Box.m_ptMin.y) ? m_ptMin.y : b3Box.m_ptMin.y) ;
|
||||
b3Int.m_ptMin.z = (( m_ptMin.z >= b3Box.m_ptMin.z) ? m_ptMin.z : b3Box.m_ptMin.z) ;
|
||||
b3Int.m_ptMax.x = (( m_ptMax.x <= b3Box.m_ptMax.x) ? m_ptMax.x : b3Box.m_ptMax.x) ;
|
||||
b3Int.m_ptMax.y = (( m_ptMax.y <= b3Box.m_ptMax.y) ? m_ptMax.y : b3Box.m_ptMax.y) ;
|
||||
b3Int.m_ptMax.z = (( m_ptMax.z <= b3Box.m_ptMax.z) ? m_ptMax.z : b3Box.m_ptMax.z) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
BBox3d::FindIntersectionXY( const BBox3d& b3B, BBox3d& b3Int) const
|
||||
BBox3d::FindIntersectionXY( const BBox3d& b3Box, BBox3d& b3Int) const
|
||||
{
|
||||
if ( ! IsValid() || ! b3B.IsValid())
|
||||
if ( ! IsValid() || ! b3Box.IsValid())
|
||||
return false ;
|
||||
// verifico direttamente la sovrapposizione
|
||||
if ( m_ptMax.x < b3B.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3B.m_ptMax.x + EPS_SMALL)
|
||||
if ( m_ptMax.x < b3Box.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3Box.m_ptMax.x + EPS_SMALL)
|
||||
return false ;
|
||||
if ( m_ptMax.y < b3B.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3B.m_ptMax.y + EPS_SMALL)
|
||||
if ( m_ptMax.y < b3Box.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3Box.m_ptMax.y + EPS_SMALL)
|
||||
return false ;
|
||||
// calcolo il box intersezione
|
||||
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 >= b3B.m_ptMin.y) ? m_ptMin.y : b3B.m_ptMin.y) ;
|
||||
b3Int.m_ptMin.z = 0.5 * ( m_ptMin.z + b3B.m_ptMin.z) ;
|
||||
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 <= b3B.m_ptMax.y) ? m_ptMax.y : b3B.m_ptMax.y) ;
|
||||
b3Int.m_ptMax.z = 0.5 * ( m_ptMax.z + b3B.m_ptMax.z) ;
|
||||
b3Int.m_ptMin.x = (( m_ptMin.x >= b3Box.m_ptMin.x) ? m_ptMin.x : b3Box.m_ptMin.x) ;
|
||||
b3Int.m_ptMin.y = (( m_ptMin.y >= b3Box.m_ptMin.y) ? m_ptMin.y : b3Box.m_ptMin.y) ;
|
||||
b3Int.m_ptMin.z = 0.5 * ( m_ptMin.z + b3Box.m_ptMin.z) ;
|
||||
b3Int.m_ptMax.x = (( m_ptMax.x <= b3Box.m_ptMax.x) ? m_ptMax.x : b3Box.m_ptMax.x) ;
|
||||
b3Int.m_ptMax.y = (( m_ptMax.y <= b3Box.m_ptMax.y) ? m_ptMax.y : b3Box.m_ptMax.y) ;
|
||||
b3Int.m_ptMax.z = 0.5 * ( m_ptMax.z + b3Box.m_ptMax.z) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
||||
+23
-11
@@ -20,6 +20,7 @@
|
||||
#include "/EgtDev/Include/EGkCurveComposite.h"
|
||||
#include "/EgtDev/Include/EGkArcSpecial.h"
|
||||
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
|
||||
using namespace std ;
|
||||
@@ -97,7 +98,7 @@ GetBiArc( const Point3d& ptP0, double dDir0Deg, const Point3d& ptP1, double dDir
|
||||
CurveArc* pArc = GetBasicCurveArc( pJCrv) ;
|
||||
if ( pArc == nullptr)
|
||||
return nullptr ;
|
||||
double dU = - 1 ;
|
||||
double dU = -1 ;
|
||||
double dRad = pArc->GetRadius() ;
|
||||
double dSqRad = dRad * dRad ;
|
||||
Point3d ptCen = pArc->GetCenter() ;
|
||||
@@ -121,9 +122,11 @@ GetBiArc( const Point3d& ptP0, double dDir0Deg, const Point3d& ptP1, double dDir
|
||||
}
|
||||
}
|
||||
}
|
||||
// elimino casi vicino agli estremi, danno solo problemi
|
||||
if ( dU < 0.1 || dU > 0.9)
|
||||
// non c'è intersezione, assegno valore medio
|
||||
if ( dU < -0.5)
|
||||
dU = 0.5 ;
|
||||
// elimino casi vicino agli estremi, danno solo problemi
|
||||
dU = Clamp( dU, 0.1, 0.9) ;
|
||||
pBiArc.Set( GetBiArc( ptP0, dDir0Deg, ptP1, dDir1Deg, dU)) ;
|
||||
}
|
||||
|
||||
@@ -132,15 +135,24 @@ GetBiArc( const Point3d& ptP0, double dDir0Deg, const Point3d& ptP1, double dDir
|
||||
return nullptr ;
|
||||
|
||||
// determino la massima distanza tra la curva e il biarco
|
||||
Point3d ptP ;
|
||||
double dSqDist = 0 ;
|
||||
for ( bool bPnt = PL.GetFirstPoint( ptP) ;
|
||||
bPnt ;
|
||||
bPnt = PL.GetNextPoint( ptP)) {
|
||||
DistPointCurve dstPC( ptP, *pBiArc) ;
|
||||
double dSqDistPC ;
|
||||
if ( dstPC.GetSqDist( dSqDistPC) && dSqDistPC > dSqDist)
|
||||
dSqDist = dSqDistPC ;
|
||||
const double STEP = 10 ;
|
||||
Point3d ptCurr ;
|
||||
bool bPnt = PL.GetFirstPoint( ptCurr) ;
|
||||
Point3d ptPrev = ptCurr ;
|
||||
while ( bPnt) {
|
||||
double dLen = Dist( ptCurr, ptPrev) ;
|
||||
int nStep = ( dLen < STEP ? 2 : 1) * int( dLen / STEP) + 1 ;
|
||||
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) ;
|
||||
|
||||
|
||||
+3
-3
@@ -301,11 +301,11 @@ CAvToolSurfTm::MyTestPositionHG( Point3d& ptT, const Vector3d& vtDir)
|
||||
Vector3d vtDirL = vtDir ; vtDirL.ToLoc( m_frMove) ;
|
||||
b3Tool.Add( ptTL) ;
|
||||
b3Tool.Add( ptTL - vtDirL * m_Tool.GetHeigth()) ;
|
||||
if ( vtDirL.IsXplus() || vtDirL.IsXminus())
|
||||
if ( vtDirL.IsX())
|
||||
b3Tool.Expand( 0, m_Tool.GetRadius(), m_Tool.GetRadius()) ;
|
||||
else if ( vtDirL.IsYplus() || vtDirL.IsYminus())
|
||||
else if ( vtDirL.IsY())
|
||||
b3Tool.Expand( m_Tool.GetRadius(), 0, m_Tool.GetRadius()) ;
|
||||
else if ( vtDirL.IsZplus() || vtDirL.IsZminus())
|
||||
else if ( vtDirL.IsZ())
|
||||
b3Tool.Expand( m_Tool.GetRadius(), m_Tool.GetRadius(), 0) ;
|
||||
else {
|
||||
double dExpandX = m_Tool.GetRadius() * sqrt( 1 - vtDirL.x * vtDirL.x) ;
|
||||
|
||||
+11
-8
@@ -23,17 +23,17 @@ using namespace std ;
|
||||
bool
|
||||
CDeBoxClosedSurfTm( const Frame3d& frBox, const Vector3d& vtDiag, double dSafeDist, const ISurfTriMesh& Stm)
|
||||
{
|
||||
// recupero BBox del poliedro
|
||||
// Recupero BBox del poliedro
|
||||
BBox3d b3Poly = Stm.GetAllTriaBox() ;
|
||||
// calcolo il BBox del parallelepipedo
|
||||
BBox3d b3Box( ORIG, ORIG + vtDiag) ;
|
||||
// Calcolo il BBox del parallelepipedo
|
||||
BBox3d b3BoxL( ORIG, ORIG + vtDiag) ;
|
||||
if ( dSafeDist > EPS_SMALL)
|
||||
b3Box.Expand( dSafeDist) ;
|
||||
b3Box.ToGlob( frBox) ;
|
||||
b3BoxL.Expand( dSafeDist) ;
|
||||
BBox3d b3Box = GetToGlob( b3BoxL, frBox) ;
|
||||
// Se i BBox non interferiscono, non c'è collisione
|
||||
if ( ! b3Box.Overlaps( b3Poly))
|
||||
if ( ! b3Poly.Overlaps( b3Box) || ! b3Poly.Overlaps( frBox, b3BoxL))
|
||||
return false ;
|
||||
// recupero i triangoli che interferiscono con il box
|
||||
// Verifico se il parallelepipedo interferisce con i triangoli del poliedro presenti nel suo BBox
|
||||
INTVECTOR vT ;
|
||||
Stm.GetAllTriaOverlapBox( b3Box, vT) ;
|
||||
for ( int nT : vT) {
|
||||
@@ -46,7 +46,10 @@ CDeBoxClosedSurfTm( const Frame3d& frBox, const Vector3d& vtDiag, double dSafeDi
|
||||
// Se superficie aperta, non c'è collisione
|
||||
if ( ! Stm.IsClosed())
|
||||
return false ;
|
||||
// Verifico se il box è dentro la superficie tramite calcolo distanza minima.
|
||||
// Se il BBox del parallelepipedo non è interno a quello del poliedro e viceversa, non c'è collisione
|
||||
if ( ! b3Poly.Encloses( b3Box) && ! b3Box.Encloses( b3Poly))
|
||||
return false ;
|
||||
// Verifico se il box è dentro la superficie tramite calcolo distanza minima del suo centro
|
||||
Point3d ptBoxCen = ORIG + vtDiag / 2 ;
|
||||
ptBoxCen.ToGlob( frBox) ;
|
||||
DistPointSurfTm DistBoxCenSurfCalc( ptBoxCen, Stm) ;
|
||||
|
||||
+5
-63
@@ -182,78 +182,21 @@ CDeBoxTria( const Frame3d& frBox, const Vector3d& vtDiag, double dSafeDist, cons
|
||||
return CDeSimpleBoxTria( Frame3d(), vtDiag, trTriaL) ;
|
||||
|
||||
// Verifica preliminare con box esteso
|
||||
Frame3d frEst( Point3d( -dSafeDist, -dSafeDist, -dSafeDist)) ;
|
||||
if ( ! CDeSimpleBoxTria( frEst, vtDiag + 2 * Vector3d( dSafeDist, dSafeDist, dSafeDist), trTriaL))
|
||||
Frame3d frTmp( Point3d( -dSafeDist, -dSafeDist, -dSafeDist)) ;
|
||||
if ( ! CDeSimpleBoxTria( frTmp, vtDiag + 2 * Vector3d( dSafeDist, dSafeDist, dSafeDist), trTriaL))
|
||||
return false ;
|
||||
|
||||
// Tre box aumentati con distanza di sicurezza in un sola dimensione
|
||||
Frame3d frTmp = frBox ; frTmp.Translate( - dSafeDist * frBox.VersX()) ;
|
||||
frTmp.ChangeOrig( Point3d( -dSafeDist, 0, 0)) ;
|
||||
if ( CDeSimpleBoxTria( frTmp, vtDiag + 2 * dSafeDist * X_AX, trTriaL))
|
||||
return true ;
|
||||
frTmp = frBox ; frTmp.Translate( - dSafeDist * frBox.VersY()) ;
|
||||
frTmp.ChangeOrig( Point3d( 0, -dSafeDist, 0)) ;
|
||||
if ( CDeSimpleBoxTria( frTmp, vtDiag + 2 * dSafeDist * Y_AX, trTriaL))
|
||||
return true ;
|
||||
frTmp = frBox ; frTmp.Translate( - dSafeDist * frBox.VersZ()) ;
|
||||
frTmp.ChangeOrig( Point3d( 0, 0, -dSafeDist)) ;
|
||||
if ( CDeSimpleBoxTria( frTmp, vtDiag + 2 * dSafeDist * Z_AX, trTriaL))
|
||||
return true ;
|
||||
|
||||
#if 1
|
||||
// Sfere centrate negli otto vertici
|
||||
if ( CDeSimpleSpheTria( Point3d( 0, 0, 0), dSafeDist, trTriaL))
|
||||
return true ;
|
||||
if ( CDeSimpleSpheTria( Point3d( vtDiag.x, 0, 0), dSafeDist, trTriaL))
|
||||
return true ;
|
||||
if ( CDeSimpleSpheTria( Point3d( vtDiag.x, vtDiag.y, 0), dSafeDist, trTriaL))
|
||||
return true ;
|
||||
if ( CDeSimpleSpheTria( Point3d( 0, vtDiag.y, 0), dSafeDist, trTriaL))
|
||||
return true ;
|
||||
if ( CDeSimpleSpheTria( Point3d( 0, 0, vtDiag.z), dSafeDist, trTriaL))
|
||||
return true ;
|
||||
if ( CDeSimpleSpheTria( Point3d( vtDiag.x, 0, vtDiag.z), dSafeDist, trTriaL))
|
||||
return true ;
|
||||
if ( CDeSimpleSpheTria( Point3d( vtDiag.x, vtDiag.y, vtDiag.z), dSafeDist, trTriaL))
|
||||
return true ;
|
||||
if ( CDeSimpleSpheTria( Point3d( 0, vtDiag.y, vtDiag.z), dSafeDist, trTriaL))
|
||||
return true ;
|
||||
|
||||
// Cilindri centrati sui dodici spigoli
|
||||
frTmp.Set( Point3d( 0, 0, 0), X_AX) ;
|
||||
if ( CDeSimpleCylTria( frTmp, dSafeDist, vtDiag.x, trTriaL))
|
||||
return true ;
|
||||
frTmp.Set( Point3d( 0, vtDiag.y, 0), X_AX) ;
|
||||
if ( CDeSimpleCylTria( frTmp, dSafeDist, vtDiag.x, trTriaL))
|
||||
return true ;
|
||||
frTmp.Set( Point3d( 0, 0, 0), Y_AX) ;
|
||||
if ( CDeSimpleCylTria( frTmp, dSafeDist, vtDiag.y, trTriaL))
|
||||
return true ;
|
||||
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 ;
|
||||
#else
|
||||
// Capsule centrati sui dodici spigoli
|
||||
if ( CDeSimpleCapsTria( Point3d( 0, 0, 0), Point3d( vtDiag.x, 0, 0), dSafeDist, trTriaL))
|
||||
return true ;
|
||||
@@ -279,7 +222,6 @@ CDeBoxTria( const Frame3d& frBox, const Vector3d& vtDiag, double dSafeDist, cons
|
||||
return true ;
|
||||
if ( CDeSimpleCapsTria( Point3d( 0, vtDiag.y, 0), Point3d( 0, vtDiag.y, vtDiag.z), dSafeDist, trTriaL))
|
||||
return true ;
|
||||
#endif
|
||||
|
||||
return false ;
|
||||
}
|
||||
|
||||
+24
-10
@@ -16,6 +16,7 @@
|
||||
#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"
|
||||
@@ -31,6 +32,7 @@ CDeSimpleCapsTria( const Point3d& ptP1, const Point3d& ptP2, double dR, const Tr
|
||||
|
||||
// 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)
|
||||
@@ -39,6 +41,13 @@ CDeSimpleCapsTria( const Point3d& ptP1, const Point3d& ptP2, double dR, const Tr
|
||||
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 ;
|
||||
@@ -48,15 +57,20 @@ CDeSimpleCapsTria( const Point3d& ptP1, const Point3d& ptP2, double dR, const Tr
|
||||
// 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 dDist = DistPointPlane( ptP, trTria.GetPlane()) ;
|
||||
if ( abs( dDist) >= dR)
|
||||
double dDistM = DistPointPlane( Media( ptP1, ptP2), trTria.GetPlane()) ;
|
||||
if ( abs( dDistM) >= dR)
|
||||
return false ;
|
||||
// !!! DA FARE !!!!
|
||||
// si deve intersecare l'asse del capsule con i cilindri centrati sui lati del triangolo
|
||||
// se intersezione inferiore a dLen allora collisione
|
||||
// altrimenti si deve intersecare l'asse del capsule con le sfere centrate sui vertici del triangolo
|
||||
// se intersezione inferiore a dLen allora collisione
|
||||
// per ora salto
|
||||
// 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
|
||||
@@ -65,7 +79,7 @@ CDeSimpleCapsTria( const Point3d& ptP1, const Point3d& ptP2, double dR, const Tr
|
||||
double dSqDist ;
|
||||
if ( dptDist.GetSqDist( dSqDist) && dSqDist < 4 * SQ_EPS_SMALL) {
|
||||
double dPos = ( ptP - ptD) * vtDir ;
|
||||
return ( dPos > -dR && dPos < dLen) ;
|
||||
return ( dPos > 0 && dPos < dLen) ;
|
||||
}
|
||||
// Altrimenti, recupero il punto del triangolo più vicino all'intersezione
|
||||
Point3d ptQ ;
|
||||
@@ -75,7 +89,7 @@ CDeSimpleCapsTria( const Point3d& ptP1, const Point3d& ptP2, double dR, const Tr
|
||||
if ( nLsRes != ILST_SEC)
|
||||
return false ;
|
||||
double dPos = ( ptQ - ptI1) * vtDir ;
|
||||
return ( dPos > -dR && dPos < dLen) ;
|
||||
return ( dPos > 0 && dPos < dLen) ;
|
||||
}
|
||||
|
||||
return false ;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2020-2020
|
||||
//----------------------------------------------------------------------------
|
||||
// File : CDeSurfTmSurfTm.h Data : 13.11.20 Versione :
|
||||
// File : CDeSurfTmSurfTm.h Data : 14.06.23 Versione : 2.5f3
|
||||
// Contenuto : Implementazione funzione verifica collisione tra
|
||||
// SurfTm e SurfTm.
|
||||
//
|
||||
@@ -18,8 +18,6 @@
|
||||
#include "/EgtDev/Include/EGkBBox3d.h"
|
||||
#include "/EgtDev/Include/EGkCDeClosedSurfTmClosedSurfTm.h"
|
||||
#include "/EgtDev/Include/EGkDistPointSurfTm.h"
|
||||
#include <unordered_set>
|
||||
#include <utility>
|
||||
|
||||
using namespace std ;
|
||||
|
||||
@@ -33,63 +31,67 @@ using namespace std ;
|
||||
// originale traslato di una costante pari alla distanza di sicurezza lungo la
|
||||
// sua normale.
|
||||
bool
|
||||
CDeClosedSurfTmClosedSurfTm( const SurfTriMesh& SurfA, const SurfTriMesh& SurfB, double dSafeDist)
|
||||
CDeClosedSurfTmClosedSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& SurfB, double dSafeDist)
|
||||
{
|
||||
// Se le superfici non sono valide o non sono chiuse, non ha senso proseguire.
|
||||
if ( ! ( SurfA.IsValid() && SurfB.IsValid()) || ! ( SurfA.IsClosed() && SurfB.IsClosed()))
|
||||
// Recupero le superfici base
|
||||
const SurfTriMesh* pSrfA = GetBasicSurfTriMesh( &SurfA) ;
|
||||
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 ;
|
||||
// Se i box delle superfici non si intersecano, ho finito.
|
||||
// Se i box delle superfici non si intersecano, ho finito.
|
||||
BBox3d b3BoxA, b3BoxB ;
|
||||
SurfA.GetLocalBBox( b3BoxA) ;
|
||||
SurfB.GetLocalBBox( b3BoxB) ;
|
||||
// Se è necessario, espando il box di una costante additiva pari alla distanza di sicurezza.
|
||||
pSrfA->GetLocalBBox( b3BoxA) ;
|
||||
pSrfB->GetLocalBBox( b3BoxB) ;
|
||||
// Se è necessario, espando il box di B di una costante additiva pari alla distanza di sicurezza.
|
||||
if ( dSafeDist > EPS_SMALL)
|
||||
b3BoxA.Expand( dSafeDist) ;
|
||||
// Se i box non si sovrappongono, non c'è collisione. Ho finito.
|
||||
b3BoxB.Expand( dSafeDist) ;
|
||||
// Se i box non si sovrappongono, non c'è collisione. Ho finito.
|
||||
if ( ! b3BoxA.Overlaps( b3BoxB))
|
||||
return false ;
|
||||
// Recupero i triangoli di B che interferiscono col box del triangolo di A
|
||||
// Recupero i triangoli di A che interferiscono col box di B
|
||||
INTVECTOR vTriaIndex ;
|
||||
SurfA.GetAllTriaOverlapBox( b3BoxB, vTriaIndex) ;
|
||||
// Ciclo sui triangoli della superficie A che cadono nel box della superficie B.
|
||||
pSrfA->GetAllTriaOverlapBox( b3BoxB, vTriaIndex) ;
|
||||
// Ciclo sui triangoli della superficie A che interferiscono col box della superficie B.
|
||||
for ( int nTA : vTriaIndex) {
|
||||
Triangle3d trTriaA ;
|
||||
if ( ! ( SurfA.GetTriangle( nTA, trTriaA) && trTriaA.Validate()))
|
||||
if ( ! ( pSrfA->GetTriangle( nTA, trTriaA) && trTriaA.Validate()))
|
||||
continue ;
|
||||
BBox3d 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)
|
||||
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 ;
|
||||
SurfB.GetAllTriaOverlapBox( b3BoxTriaA, vNearTria) ;
|
||||
// Settare tutti i triangoli come già processati.
|
||||
// Al termine della chiamata i TFlags dei triangoli valgono 0.
|
||||
SurfB.ResetTempInt() ;
|
||||
// Ciclo sui triangoli della superficie B che cadono nel box del triangolo corrente della Superficie A.
|
||||
pSrfB->GetAllTriaOverlapBox( b3BoxTriaA, vNearTria) ;
|
||||
// Settare tutti i triangoli come già processati.
|
||||
// Al termine della chiamata i TempInt dei triangoli valgono 0.
|
||||
pSrfB->ResetTempInts() ;
|
||||
// Ciclo sui triangoli della superficie B che cadono nel box del triangolo corrente della Superficie A.
|
||||
for ( int nTB : vNearTria) {
|
||||
// Recupero il triangolo corrente della superficie B.
|
||||
// Se triangolo non valido salto al successivo.
|
||||
// Recupero il triangolo corrente della superficie B.
|
||||
// Se triangolo non valido salto al successivo.
|
||||
Triangle3d trTriaB ;
|
||||
if ( ! ( SurfB.GetTriangle( nTB, trTriaB) && trTriaB.Validate()))
|
||||
if ( ! ( pSrfB->GetTriangle( nTB, trTriaB) && trTriaB.Validate()))
|
||||
continue ;
|
||||
// Se necessario considero l'offset
|
||||
// Se necessario considero l'offset
|
||||
if ( dSafeDist > EPS_SMALL) {
|
||||
int nAdjTriaId[3] ;
|
||||
SurfB.GetTriangleAdjacencies( nTB, nAdjTriaId) ;
|
||||
// Ciclo sui vertici del triangolo.
|
||||
pSrfB->GetTriangleAdjacencies( nTB, nAdjTriaId) ;
|
||||
// Ciclo sui vertici del triangolo.
|
||||
for ( int nVB = 0 ; nVB < 3 ; ++ nVB) {
|
||||
// Se il triangolo adiacente al triangolo corrente su questo edge
|
||||
// non è stato processato, processo il vertice e l'edge.
|
||||
// Se il triangolo adiacente al triangolo corrente su questo edge
|
||||
// non è stato processato, processo il vertice e l'edge.
|
||||
int nAdjTriaTempFlag ;
|
||||
if ( ! ( SurfB.GetTriangleTempInt( nAdjTriaId[nVB], nAdjTriaTempFlag) || nAdjTriaTempFlag == 0))
|
||||
if ( ! ( pSrfB->GetTempInt( nAdjTriaId[nVB], nAdjTriaTempFlag) || nAdjTriaTempFlag == 0))
|
||||
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))
|
||||
return true ;
|
||||
// Processo l'edge: se c'è collisione fra triangolo A e cilindro ho finito.
|
||||
Vector3d vtEdgeV = trTriaB.GetP( nVB) - trTriaB.GetP( ( nVB + 1) % 3) ;
|
||||
// Processo l'edge: se c'è collisione fra triangolo A e cilindro ho finito.
|
||||
Vector3d vtEdgeV = trTriaB.GetP( ( nVB + 1) % 3) - trTriaB.GetP( nVB) ;
|
||||
double dEdgeLen = vtEdgeV.Len() ;
|
||||
vtEdgeV /= dEdgeLen ;
|
||||
Frame3d frCyl ;
|
||||
@@ -97,22 +99,25 @@ CDeClosedSurfTmClosedSurfTm( const SurfTriMesh& SurfA, const SurfTriMesh& SurfB,
|
||||
if ( CDeSimpleCylTria( frCyl, dSafeDist, dEdgeLen, trTriaA))
|
||||
return true ;
|
||||
}
|
||||
// Traslo il triangolo
|
||||
// Traslo il triangolo
|
||||
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))
|
||||
return true ;
|
||||
// Segno il triangolo come processato: nTFlag = 1
|
||||
SurfB.SetTempInt( nTB, 1) ;
|
||||
// Segno il triangolo come processato: nTemp = 1
|
||||
pSrfB->SetTempInt( nTB, 1) ;
|
||||
}
|
||||
}
|
||||
// Non ho trovato collisioni fra triangoli delle superfici.
|
||||
// La collisione c'è se una superficie è dentro l'altra.
|
||||
// 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
|
||||
if ( ! b3BoxA.Encloses( b3BoxB) && ! b3BoxB.Encloses( b3BoxA))
|
||||
return false ;
|
||||
// La collisione c'è se una superficie è dentro l'altra.
|
||||
Point3d ptPointA, ptPointB ;
|
||||
SurfA.GetFirstVertex( ptPointA) ;
|
||||
SurfB.GetFirstVertex( ptPointB) ;
|
||||
DistPointSurfTm DistPoinASurfB( ptPointA, SurfB) ;
|
||||
DistPointSurfTm DistPoinBSurfA( ptPointB, SurfA) ;
|
||||
return ( DistPoinASurfB.IsPointInside() || DistPoinBSurfA.IsPointInside()) ;
|
||||
}
|
||||
pSrfA->GetFirstVertex( ptPointA) ;
|
||||
pSrfB->GetFirstVertex( ptPointB) ;
|
||||
DistPointSurfTm DistPoinASrfB( ptPointA, *pSrfB) ;
|
||||
DistPointSurfTm DistPoinBSrfA( ptPointB, *pSrfA) ;
|
||||
return ( DistPoinASrfB.IsPointInside() || DistPoinBSrfA.IsPointInside()) ;
|
||||
}
|
||||
|
||||
@@ -27,24 +27,25 @@ bool
|
||||
CDeConeFrustumClosedSurfTm( const Frame3d& frCone, double dBaseRad, double dTopRad, double dHeight,
|
||||
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)
|
||||
return false ;
|
||||
// Recupero BBox della trimesh
|
||||
BBox3d b3Surf = Stm.GetAllTriaBox() ;
|
||||
// Calcolo il BBox del tronco di cono
|
||||
double dMaxRad = max( dBaseRad, dTopRad) ;
|
||||
BBox3d b3Cone( - dMaxRad, - dMaxRad, 0, dMaxRad, dMaxRad, dHeight) ;
|
||||
BBox3d b3ConeL( Point3d( -dMaxRad, -dMaxRad, 0),
|
||||
Point3d( dMaxRad, dMaxRad, dHeight)) ;
|
||||
if ( dSafeDist > EPS_SMALL)
|
||||
b3Cone.Expand( dSafeDist) ;
|
||||
b3Cone.ToGlob( frCone) ;
|
||||
b3ConeL.Expand( dSafeDist) ;
|
||||
BBox3d b3Cone = GetToGlob( b3ConeL, frCone) ;
|
||||
// Se i BBox non interferiscono, non c'è collisione
|
||||
if ( ! b3Cone.Overlaps( b3Surf))
|
||||
if ( ! b3Surf.Overlaps( b3Cone) || ! b3Surf.Overlaps( frCone, b3ConeL))
|
||||
return false ;
|
||||
// Recupero i triangoli che interferiscono con il box del cono
|
||||
INTVECTOR vT ;
|
||||
Stm.GetAllTriaOverlapBox( b3Cone, vT) ;
|
||||
// Ciclo sui triangoli che interferiscono col box del cono
|
||||
// Verifico se il tronco di cono interferisce con i triangoli del poliedro presenti nel suo BBox
|
||||
for ( int nT : vT) {
|
||||
Triangle3d trTria ;
|
||||
if ( Stm.GetTriangle( nT, trTria)) {
|
||||
@@ -55,6 +56,9 @@ CDeConeFrustumClosedSurfTm( const Frame3d& frCone, double dBaseRad, double dTopR
|
||||
// Se superficie aperta, non c'è collisione
|
||||
if ( ! Stm.IsClosed())
|
||||
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.
|
||||
Point3d ptConeCen( 0, 0, dHeight / 2) ;
|
||||
ptConeCen.ToGlob( frCone) ;
|
||||
|
||||
@@ -23,42 +23,42 @@ using namespace std ;
|
||||
// Il toro è posto nel piano XY del suo riferimento, centrato sull'origine.
|
||||
// La funzione restituisce true in caso di collisione.
|
||||
bool
|
||||
CDeConvexTorusClosedSurfTm( const Frame3d& frTorusFrame, double dRad1, double dRad2,
|
||||
CDeConvexTorusClosedSurfTm( const Frame3d& frTorus, double dRad1, double dRad2,
|
||||
double dSafeDist, const ISurfTriMesh& Stm)
|
||||
{
|
||||
// I raggi devono essere non nulli e la superficie ben definita.
|
||||
if ( dRad1 < EPS_SMALL || dRad2 < EPS_SMALL || ! Stm.IsValid())
|
||||
return false ;
|
||||
// Box del toro (sempre completo)
|
||||
BBox3d b3ConvTorusBox ;
|
||||
b3ConvTorusBox.Set( Point3d( - dRad1 - dRad2, - dRad1 - dRad2, - dRad2),
|
||||
Point3d( dRad1 + dRad2, dRad1 + dRad2, dRad2)) ;
|
||||
// Aggiungo eventuale distanza di sicurezza
|
||||
if ( dSafeDist > EPS_SMALL)
|
||||
b3ConvTorusBox.Expand( dSafeDist) ;
|
||||
// Porto il box del toro nel riferimento della superficie (inteso some globale)
|
||||
b3ConvTorusBox.ToGlob( frTorusFrame) ;
|
||||
// Box della superficie
|
||||
BBox3d b3SurfBox = Stm.GetAllTriaBox() ;
|
||||
BBox3d b3Surf = Stm.GetAllTriaBox() ;
|
||||
// Box del toro (sempre completo)
|
||||
BBox3d b3TorusL( Point3d( -dRad1 - dRad2, -dRad1 - dRad2, -dRad2),
|
||||
Point3d( dRad1 + dRad2, dRad1 + dRad2, dRad2)) ;
|
||||
if ( dSafeDist > EPS_SMALL)
|
||||
b3TorusL.Expand( dSafeDist) ;
|
||||
BBox3d b3Torus = GetToGlob( b3TorusL, frTorus) ;
|
||||
// Se i BBox non interferiscono, non c'è collisione
|
||||
if ( ! b3ConvTorusBox.Overlaps( b3SurfBox))
|
||||
if ( ! b3Surf.Overlaps( b3Torus) || ! b3Surf.Overlaps( frTorus, b3TorusL))
|
||||
return false ;
|
||||
// Recupero i triangoli che interferiscono con il box del toro
|
||||
INTVECTOR vT ;
|
||||
Stm.GetAllTriaOverlapBox( b3ConvTorusBox, vT) ;
|
||||
// Ciclo sui triangoli recuperati
|
||||
Stm.GetAllTriaOverlapBox( b3Torus, vT) ;
|
||||
// Verifico se il toro interferisce con i triangoli del poliedro presenti nel suo BBox
|
||||
for ( int nT : vT) {
|
||||
Triangle3d trTria ;
|
||||
if ( Stm.GetTriangle( nT, trTria)) {
|
||||
if ( CDeConvexTorusTria( frTorusFrame, dRad1, dRad2, CT_TOT, dSafeDist, trTria))
|
||||
if ( CDeConvexTorusTria( frTorus, dRad1, dRad2, CT_TOT, dSafeDist, trTria))
|
||||
return true ;
|
||||
}
|
||||
}
|
||||
// Se superficie aperta, non c'è collisione
|
||||
if ( ! Stm.IsClosed())
|
||||
return false ;
|
||||
// Verifico se il toro è dentro la superficie tramite calcolo distanza minima.
|
||||
Point3d ptTorusOrig = frTorusFrame.Orig() ;
|
||||
// Se il BBox del toro non è interno a quello del poliedro e viceversa, non c'è collisione
|
||||
if ( ! b3Surf.Encloses( b3Torus) && ! b3Torus.Encloses( b3Surf))
|
||||
return false ;
|
||||
// Verifico se il toro è dentro la superficie tramite calcolo distanza minima del suo centro
|
||||
Point3d ptTorusOrig = frTorus.Orig() ;
|
||||
DistPointSurfTm DistConeOrigSurfCalc( ptTorusOrig, Stm) ;
|
||||
// Se il toro è interno c'è collisione
|
||||
return ( DistConeOrigSurfCalc.IsPointInside()) ;
|
||||
|
||||
+17
-13
@@ -23,38 +23,42 @@ using namespace std ;
|
||||
bool
|
||||
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() ;
|
||||
// sistemazioni cilindro
|
||||
Frame3d frC = frCyl ;
|
||||
// Sistemazioni cilindro
|
||||
Frame3d frMyCyl = frCyl ;
|
||||
if ( dH < 0) {
|
||||
frC.Translate( dH * frC.VersZ()) ;
|
||||
frMyCyl.Translate( dH * frMyCyl.VersZ()) ;
|
||||
dH = - dH ;
|
||||
}
|
||||
// calcolo il BBox del cilindro
|
||||
BBox3d b3Cyl( -dR, -dR, 0, dR, dR, dH) ;
|
||||
// Calcolo il BBox del cilindro
|
||||
BBox3d b3CylL( Point3d( -dR, -dR, 0),
|
||||
Point3d( dR, dR, dH)) ;
|
||||
if ( dSafeDist > EPS_SMALL)
|
||||
b3Cyl.Expand( dSafeDist) ;
|
||||
b3Cyl.ToGlob( frC) ;
|
||||
b3CylL.Expand( dSafeDist) ;
|
||||
BBox3d b3Cyl = GetToGlob( b3CylL, frMyCyl) ;
|
||||
// Se i BBox non interferiscono, non c'è collisione
|
||||
if ( ! b3Cyl.Overlaps( b3Poly))
|
||||
if ( ! b3Poly.Overlaps( b3Cyl) || ! b3Poly.Overlaps( frMyCyl, b3CylL))
|
||||
return false ;
|
||||
// recupero i triangoli che interferiscono con il box del Cilindro
|
||||
// Verifico se il cilindro interferisce con i triangoli del poliedro presenti nel suo BBox
|
||||
INTVECTOR vT ;
|
||||
Stm.GetAllTriaOverlapBox( b3Cyl, vT) ;
|
||||
for ( int nT : vT) {
|
||||
Triangle3d Tria ;
|
||||
if ( Stm.GetTriangle( nT, Tria)) {
|
||||
if ( CDeCylTria( frC, dR, dH, dSafeDist, Tria))
|
||||
if ( CDeCylTria( frMyCyl, dR, dH, dSafeDist, Tria))
|
||||
return true ;
|
||||
}
|
||||
}
|
||||
// Se superficie aperta, non c'è collisione
|
||||
if ( ! Stm.IsClosed())
|
||||
return false ;
|
||||
// Verifico se il cilindro è dentro la superficie tramite calcolo distanza minima.
|
||||
// Se il BBox del cilindro non è interno a quello del poliedro e viceversa, non c'è collisione
|
||||
if ( ! b3Poly.Encloses( b3Cyl) && ! b3Cyl.Encloses( b3Poly))
|
||||
return false ;
|
||||
// Verifico se il cilindro è dentro la superficie tramite calcolo distanza minima del suo centro
|
||||
Point3d ptCylCen( 0, 0, dH / 2) ;
|
||||
ptCylCen.ToGlob( frC) ;
|
||||
ptCylCen.ToGlob( frMyCyl) ;
|
||||
DistPointSurfTm DistCylCenSurfCalc( ptCylCen, Stm) ;
|
||||
// Se il cilindro è interno c'è collisione
|
||||
return ( DistCylCenSurfCalc.IsPointInside()) ;
|
||||
|
||||
@@ -37,17 +37,18 @@ CDeRectPrismoidClosedSurfTm( const Frame3d& frPrismoid, double dLenghtBaseX, dou
|
||||
// Calcolo il BBox del tronco di piramide
|
||||
double dMaxLenX = max( dLenghtBaseX, dLenghtTopX) ;
|
||||
double dMaxLenY = max( dLenghtBaseY, dLenghtTopY) ;
|
||||
BBox3d b3Pyr( -dMaxLenX / 2, -dMaxLenY / 2, 0., dMaxLenX / 2, dMaxLenY / 2, dHeight) ;
|
||||
BBox3d b3PyrL( Point3d( -dMaxLenX / 2, -dMaxLenY / 2, 0.),
|
||||
Point3d( dMaxLenX / 2, dMaxLenY / 2, dHeight)) ;
|
||||
if ( dSafeDist > EPS_SMALL)
|
||||
b3Pyr.Expand( dSafeDist) ;
|
||||
b3Pyr.ToGlob( frPrismoid) ;
|
||||
b3PyrL.Expand( dSafeDist) ;
|
||||
BBox3d b3Pyr = GetToGlob( b3PyrL, frPrismoid) ;
|
||||
// Se i BBox non interferiscono, non c'è collisione
|
||||
if ( ! b3Pyr.Overlaps( b3Surf))
|
||||
if ( ! b3Surf.Overlaps( b3Pyr) || ! b3Surf.Overlaps( frPrismoid, b3PyrL))
|
||||
return false ;
|
||||
// Recupero i triangoli che interferiscono con il box del tronco di piramide.
|
||||
INTVECTOR vT ;
|
||||
Stm.GetAllTriaOverlapBox( b3Pyr, vT) ;
|
||||
// Ciclo sui triangoli che interferiscono col box del tronco di piramide.
|
||||
// Verifico se il tronco di piramide interferisce con i triangoli del poliedro presenti nel suo BBox
|
||||
for ( int nT : vT) {
|
||||
Triangle3d trTria ;
|
||||
if ( Stm.GetTriangle( nT, trTria)) {
|
||||
@@ -59,10 +60,13 @@ CDeRectPrismoidClosedSurfTm( const Frame3d& frPrismoid, double dLenghtBaseX, dou
|
||||
// Se superficie aperta, non c'è collisione
|
||||
if ( ! Stm.IsClosed())
|
||||
return false ;
|
||||
// Verifico se il tronco di piramide è dentro la superficie tramite calcolo distanza minima.
|
||||
// Se il BBox del tronco di piramide non è interno a quello del poliedro e viceversa, non c'è collisione
|
||||
if ( ! b3Surf.Encloses( b3Pyr) && ! b3Pyr.Encloses( b3Surf))
|
||||
return false ;
|
||||
// Verifico se il tronco di piramide è dentro la superficie tramite calcolo distanza minima del suo centro
|
||||
Point3d ptPyrCen( 0, 0, dHeight / 2) ;
|
||||
ptPyrCen.ToGlob( frPrismoid) ;
|
||||
DistPointSurfTm DistPyrCenSurfCalc( ptPyrCen, Stm) ;
|
||||
// C'è collisione se il tronco di piramide è interno.
|
||||
// C'è collisione se il tronco di piramide è interno
|
||||
return ( DistPyrCenSurfCalc.IsPointInside()) ;
|
||||
}
|
||||
|
||||
+33
-53
@@ -14,6 +14,7 @@
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "CDeRectPrismoidTria.h"
|
||||
#include "CDeCapsTria.h"
|
||||
#include "CDeBoxTria.h"
|
||||
#include "CDeCylTria.h"
|
||||
#include "CDeSpheTria.h"
|
||||
@@ -141,9 +142,13 @@ CDeRectPrismoidTria( const Frame3d& frPrismoid, double dLenghtBaseX, double dLen
|
||||
dHeight < EPS_SMALL || ! trTria.IsValid())
|
||||
return false ;
|
||||
|
||||
// Porto il triangolo nel riferimento del prismoide
|
||||
Triangle3d trTriaL = trTria ;
|
||||
trTriaL.ToLoc( frPrismoid) ;
|
||||
|
||||
// Se distanza di sicurezza nulla
|
||||
if ( dSafeDist < EPS_SMALL)
|
||||
return CDeSimpleRectPrismoidTria( frPrismoid, dLenghtBaseX, dLenghtBaseY, dLenghtTopX, dLenghtTopY, dHeight, trTria) ;
|
||||
return CDeSimpleRectPrismoidTria( Frame3d(), dLenghtBaseX, dLenghtBaseY, dLenghtTopX, dLenghtTopY, dHeight, trTriaL) ;
|
||||
|
||||
// Verifiche con offset esteso
|
||||
double dHDiffX = ( dLenghtBaseX - dLenghtTopX) / 2 ;
|
||||
@@ -156,37 +161,37 @@ CDeRectPrismoidTria( const Frame3d& frPrismoid, double dLenghtBaseX, double dLen
|
||||
double dSecAy = sqrt( 1 + dTgAy * dTgAy) ;
|
||||
double dOffsBaseY = dSafeDist * ( dSecAy + dTgAy) ;
|
||||
double dOffsTopY = dSafeDist * ( dSecAy - dTgAy) ;
|
||||
Frame3d frFrame = frPrismoid ; frFrame.Translate( - dSafeDist * frFrame.VersZ()) ;
|
||||
if ( ! CDeSimpleRectPrismoidTria( frFrame, dLenghtBaseX + 2 * dOffsBaseX, dLenghtBaseY + 2 * dOffsBaseY,
|
||||
dLenghtTopX + 2 * dOffsTopX, dLenghtTopY + 2 * dOffsTopY, dHeight + 2 * dSafeDist, trTria))
|
||||
Frame3d frTmp( Point3d( 0, 0, -dSafeDist)) ;
|
||||
if ( ! CDeSimpleRectPrismoidTria( frTmp, dLenghtBaseX + 2 * dOffsBaseX, dLenghtBaseY + 2 * dOffsBaseY,
|
||||
dLenghtTopX + 2 * dOffsTopX, dLenghtTopY + 2 * dOffsTopY, dHeight + 2 * dSafeDist, trTriaL))
|
||||
return false ;
|
||||
|
||||
// Offset fine
|
||||
// Box sotto
|
||||
frFrame = frPrismoid ; frFrame.Translate( - dSafeDist * frFrame.VersZ()) ;
|
||||
if ( CDeSimpleBoxTria( frFrame, Vector3d( dLenghtBaseX, dLenghtBaseY, dSafeDist), trTria))
|
||||
frTmp.ChangeOrig( Point3d( 0, 0, -dSafeDist)) ;
|
||||
if ( CDeSimpleBoxTria( frTmp, Vector3d( dLenghtBaseX, dLenghtBaseY, dSafeDist), trTriaL))
|
||||
return true ;
|
||||
// Box sopra
|
||||
frFrame = frPrismoid ; frFrame.Translate( dHeight * frFrame.VersZ()) ;
|
||||
if ( CDeSimpleBoxTria( frFrame, Vector3d( dLenghtTopX, dLenghtTopY, dSafeDist), trTria))
|
||||
frTmp.ChangeOrig( Point3d( 0, 0, dHeight)) ;
|
||||
if ( CDeSimpleBoxTria( frTmp, Vector3d( dLenghtTopX, dLenghtTopY, dSafeDist), trTriaL))
|
||||
return true ;
|
||||
// Prismoide allungato in X
|
||||
double dHypoX = sqrt( dHDiffX * dHDiffX + dHeight * dHeight) ;
|
||||
double dOffsX = dSafeDist * dHeight / dHypoX ;
|
||||
double dMoveXZ = dSafeDist * dHDiffX / dHypoX ;
|
||||
frFrame = frPrismoid ; frFrame.Translate( dMoveXZ * frFrame.VersZ()) ;
|
||||
if ( CDeSimpleRectPrismoidTria( frFrame, dLenghtBaseX + 2 * dOffsX, dLenghtBaseY,
|
||||
dLenghtTopX + 2 * dOffsX, dLenghtTopY, dHeight, trTria))
|
||||
frTmp.ChangeOrig( Point3d( 0, 0, dMoveXZ)) ;
|
||||
if ( CDeSimpleRectPrismoidTria( frTmp, dLenghtBaseX + 2 * dOffsX, dLenghtBaseY,
|
||||
dLenghtTopX + 2 * dOffsX, dLenghtTopY, dHeight, trTriaL))
|
||||
return true ;
|
||||
// Prismoide allungato in Y
|
||||
double dHypoY = sqrt( dHDiffY * dHDiffY + dHeight * dHeight) ;
|
||||
double dOffsY = dSafeDist * dHeight / dHypoY ;
|
||||
double dMoveYZ = dSafeDist * dHDiffY / dHypoY ;
|
||||
frFrame = frPrismoid ; frFrame.Translate( dMoveYZ * frFrame.VersZ()) ;
|
||||
if ( CDeSimpleRectPrismoidTria( frFrame, dLenghtBaseX, dLenghtBaseY + 2 * dOffsY,
|
||||
dLenghtTopX, dLenghtTopY + 2 * dOffsY, dHeight, trTria))
|
||||
frTmp.ChangeOrig( Point3d( 0, 0, dMoveYZ)) ;
|
||||
if ( CDeSimpleRectPrismoidTria( frTmp, dLenghtBaseX, dLenghtBaseY + 2 * dOffsY,
|
||||
dLenghtTopX, dLenghtTopY + 2 * dOffsY, dHeight, trTriaL))
|
||||
return true ;
|
||||
// Sfere centrate nei vertici
|
||||
// Vertici
|
||||
double dHalfBaseX = dLenghtBaseX / 2 ;
|
||||
double dHalfBaseY = dLenghtBaseY / 2 ;
|
||||
double dHalfTopX = dLenghtTopX / 2 ;
|
||||
@@ -199,55 +204,30 @@ CDeRectPrismoidTria( const Frame3d& frPrismoid, double dLenghtBaseX, double dLen
|
||||
Point3d( dHalfTopX, -dHalfTopY, dHeight),
|
||||
Point3d( dHalfTopX, dHalfTopY, dHeight),
|
||||
Point3d( -dHalfTopX, dHalfTopY, dHeight)} ;
|
||||
for ( auto& ptV : vVert) {
|
||||
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))
|
||||
// Capsule centrati sui dodici spigoli
|
||||
if ( CDeSimpleCapsTria( vVert[0], vVert[1], dSafeDist, trTriaL))
|
||||
return true ;
|
||||
frFrame.Set( vVert[1], frPrismoid.VersY()) ;
|
||||
if ( CDeSimpleCylTria( frFrame, dSafeDist, dLenghtBaseY, trTria))
|
||||
if ( CDeSimpleCapsTria( vVert[1], vVert[2], dSafeDist, trTriaL))
|
||||
return true ;
|
||||
frFrame.Set( vVert[2], -frPrismoid.VersX()) ;
|
||||
if ( CDeSimpleCylTria( frFrame, dSafeDist, dLenghtBaseX, trTria))
|
||||
if ( CDeSimpleCapsTria( vVert[2], vVert[3], dSafeDist, trTriaL))
|
||||
return true ;
|
||||
frFrame.Set( vVert[3], -frPrismoid.VersY()) ;
|
||||
if ( CDeSimpleCylTria( frFrame, dSafeDist, dLenghtBaseY, trTria))
|
||||
if ( CDeSimpleCapsTria( vVert[3], vVert[0], dSafeDist, trTriaL))
|
||||
return true ;
|
||||
frFrame.Set( vVert[4], frPrismoid.VersX()) ;
|
||||
if (CDeSimpleCylTria( frFrame, dSafeDist, dLenghtTopX, trTria))
|
||||
if ( CDeSimpleCapsTria( vVert[4], vVert[5], dSafeDist, trTriaL))
|
||||
return true ;
|
||||
frFrame.Set( vVert[5], frPrismoid.VersY()) ;
|
||||
if ( CDeSimpleCylTria( frFrame, dSafeDist, dLenghtTopY, trTria))
|
||||
if ( CDeSimpleCapsTria( vVert[5], vVert[6], dSafeDist, trTriaL))
|
||||
return true ;
|
||||
frFrame.Set( vVert[6], -frPrismoid.VersX()) ;
|
||||
if ( CDeSimpleCylTria( frFrame, dSafeDist, dLenghtTopX, trTria))
|
||||
if ( CDeSimpleCapsTria( vVert[6], vVert[7], dSafeDist, trTriaL))
|
||||
return true ;
|
||||
frFrame.Set( vVert[7], -frPrismoid.VersY()) ;
|
||||
if ( CDeSimpleCylTria( frFrame, dSafeDist, dLenghtTopY, trTria))
|
||||
if ( CDeSimpleCapsTria( vVert[7], vVert[4], dSafeDist, trTriaL))
|
||||
return true ;
|
||||
Vector3d vtSeg04 = vVert[4] - vVert[0] ;
|
||||
double dLenSeg04 = vtSeg04.Len() ;
|
||||
frFrame.Set( vVert[0], vtSeg04) ;
|
||||
if ( CDeSimpleCylTria( frFrame, dSafeDist, dLenSeg04, trTria))
|
||||
if ( CDeSimpleCapsTria( vVert[0], vVert[4], dSafeDist, trTriaL))
|
||||
return true ;
|
||||
Vector3d vtSeg15 = vVert[5] - vVert[1] ;
|
||||
double dLenSeg15 = vtSeg15.Len() ;
|
||||
frFrame.Set( vVert[1], vtSeg15) ;
|
||||
if ( CDeSimpleCylTria( frFrame, dSafeDist, dLenSeg15, trTria))
|
||||
if ( CDeSimpleCapsTria( vVert[1], vVert[5], dSafeDist, trTriaL))
|
||||
return true ;
|
||||
Vector3d vtSeg26 = vVert[6] - vVert[2] ;
|
||||
double dLenSeg26 = vtSeg26.Len() ;
|
||||
frFrame.Set( vVert[2], vtSeg26) ;
|
||||
if ( CDeSimpleCylTria( frFrame, dSafeDist, dLenSeg26, trTria))
|
||||
if ( CDeSimpleCapsTria( vVert[2], vVert[6], dSafeDist, trTriaL))
|
||||
return true ;
|
||||
Vector3d vtSeg37 = vVert[7] - vVert[3] ;
|
||||
double dLenSeg37 = vtSeg37.Len();
|
||||
frFrame.Set( vVert[3], vtSeg37) ;
|
||||
if ( CDeSimpleCylTria( frFrame, dSafeDist, dLenSeg37, trTria))
|
||||
if ( CDeSimpleCapsTria( vVert[3], vVert[7], dSafeDist, trTriaL))
|
||||
return true ;
|
||||
|
||||
return false ;
|
||||
|
||||
@@ -23,16 +23,16 @@ using namespace std ;
|
||||
bool
|
||||
CDeSpheClosedSurfTm( const Point3d& ptCen, double dR, double dSafeDist, const ISurfTriMesh& Stm)
|
||||
{
|
||||
// recupero BBox del poliedro
|
||||
// Recupero BBox del poliedro
|
||||
BBox3d b3Poly = Stm.GetAllTriaBox() ;
|
||||
// calcolo il BBox della sfera
|
||||
// Calcolo il BBox della sfera
|
||||
BBox3d b3Sphe( ptCen, dR) ;
|
||||
if ( dSafeDist > EPS_SMALL)
|
||||
b3Sphe.Expand( dSafeDist) ;
|
||||
// Se i BBox non interferiscono, non c'è collisione
|
||||
if ( ! b3Sphe.Overlaps( b3Poly))
|
||||
return false ;
|
||||
// recupero i triangoli che interferiscono con il box della Sfera
|
||||
// Verifico se la sfera interferisce con i triangoli del poliedro presenti nel suo BBox
|
||||
INTVECTOR vT ;
|
||||
Stm.GetAllTriaOverlapBox( b3Sphe, vT) ;
|
||||
for ( int nT : vT) {
|
||||
@@ -45,8 +45,11 @@ CDeSpheClosedSurfTm( const Point3d& ptCen, double dR, double dSafeDist, const IS
|
||||
// Se superficie aperta, non c'è collisione
|
||||
if ( ! Stm.IsClosed())
|
||||
return false ;
|
||||
// Verifico se la sfera è dentro la superficie tramite calcolo distanza minima.
|
||||
// Se il BBox della sfera non è interno a quello del poliedro e viceversa, non c'è collisione
|
||||
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) ;
|
||||
// C'è collisione se la sfera è interna.
|
||||
// C'è collisione se la sfera è interna.
|
||||
return ( DistCenSurfCalc.IsPointInside()) ;
|
||||
}
|
||||
|
||||
@@ -239,7 +239,7 @@ GetCircleCenTgCompo( const Point3d& ptCen, const Vector3d& vtN, const CurveCompo
|
||||
double dSqDist = SqDist( ptNear, ptTg) ;
|
||||
if ( dSqDist < dMinSqDist) {
|
||||
dMinSqDist = dSqDist ;
|
||||
pCrvArc.Set( Release( pCrvAtmp)) ;
|
||||
pCrvArc.Set( pCrvAtmp) ;
|
||||
if ( pPtTg != nullptr)
|
||||
*pPtTg = ptTg ;
|
||||
}
|
||||
|
||||
+83
-107
@@ -25,6 +25,8 @@
|
||||
#include "/EgtDev/Include/EGkAngle.h"
|
||||
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
||||
#include "/EgtDev/Include/EGkUiUnits.h"
|
||||
#include "/EgtDev/Include/ENkPolynomialRoots.h"
|
||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
#include <new>
|
||||
|
||||
@@ -566,7 +568,7 @@ CurveArc::Clone( void) const
|
||||
bool
|
||||
CurveArc::CopyFrom( const IGeoObj* pGObjSrc)
|
||||
{
|
||||
const CurveArc* pCA = dynamic_cast<const CurveArc*>( pGObjSrc) ;
|
||||
const CurveArc* pCA = GetBasicCurveArc( pGObjSrc) ;
|
||||
if ( pCA == nullptr)
|
||||
return false ;
|
||||
return CopyFrom( *pCA) ;
|
||||
@@ -701,7 +703,6 @@ CurveArc::GetLocalBBox( BBox3d& b3Loc, int nFlag) const
|
||||
{
|
||||
// richiamo della funzione generale
|
||||
return GetBBox( GLOB_FRM, b3Loc, nFlag) ;
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -717,115 +718,87 @@ CurveArc::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag) const
|
||||
// assegno il box nel riferimento
|
||||
b3Ref.Reset() ;
|
||||
|
||||
// ricavo il Frame3D solidale all'arco
|
||||
Frame3d frArc; frArc.Set( m_PtCen, m_dAngCenDeg > 0 ? m_VtN : - m_VtN, m_VtS) ;
|
||||
// ricavo il riferimento intrinseco dell'arco
|
||||
Frame3d frArc;
|
||||
frArc.Set( m_PtCen, ( m_dAngCenDeg > 0 ? m_VtN : -m_VtN), m_VtS) ;
|
||||
|
||||
// cordinate nel FrRef dei versori del sistema di riferimento dell'arco
|
||||
Vector3d a = frArc.VersX() ;
|
||||
a.ToGlob( frRef) ;
|
||||
double ax = a.x ;
|
||||
double ay = a.y ;
|
||||
double az = a.z ;
|
||||
// pendenza intrinseca
|
||||
double dPitch = m_dDeltaN * ( m_dAngCenDeg > 0 ? 1 : -1) / abs( m_dAngCenDeg * DEGTORAD) ;
|
||||
|
||||
Vector3d b = frArc.VersY() ;
|
||||
b.ToGlob( frRef) ;
|
||||
double bx = b.x ;
|
||||
double by = b.y ;
|
||||
double bz = b.z ;
|
||||
|
||||
Vector3d c = frArc.VersZ() ;
|
||||
c.ToGlob( frRef) ;
|
||||
double nx = c.x ;
|
||||
double ny = c.y ;
|
||||
double nz = c.z ;
|
||||
|
||||
// vettore degli angoli e dei punti di estremi
|
||||
PNTVECTOR vPoints ;
|
||||
DBLVECTOR vdTheta ;
|
||||
// cordinate nel frRef dei versori del sistema di riferimento dell'arco
|
||||
Vector3d vtXRef = frArc.VersX() ;
|
||||
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 ;
|
||||
GetPointD1D2( 0, FROM_PLUS, ptS) ; if ( ! abs( m_dAngCenDeg - 360) < EPS_SMALL) { GetPointD1D2( 1, FROM_MINUS, ptE) ; }
|
||||
vPoints.push_back( ptS) ; if ( ! abs( m_dAngCenDeg - 360) < EPS_SMALL) { vPoints.push_back( ptE) ; }
|
||||
GetStartPoint( ptS) ;
|
||||
ptS.ToGlob( frRef) ;
|
||||
b3Ref.Add( ptS) ;
|
||||
GetEndPoint( ptE) ;
|
||||
ptE.ToGlob( frRef) ;
|
||||
b3Ref.Add( ptE) ;
|
||||
|
||||
// angolo al centro, raggio e parametro Q
|
||||
double dAngCenRad = m_dAngCenDeg * DEGTORAD ;
|
||||
ptE.ToLoc( frArc) ; ptS.ToLoc( frArc) ;
|
||||
double Q = ( ptE.z - ptS.z) / abs( dAngCenRad) ;
|
||||
double dRad = m_dRad ;
|
||||
// vettore degli angoli dei punti candidati estremi
|
||||
DBLVECTOR vdTheta ;
|
||||
|
||||
if ( abs( Q) < EPS_SMALL) {
|
||||
if ( abs( ax) > EPS_SMALL) {
|
||||
vdTheta.push_back( atan( bx / ax)) ;
|
||||
vdTheta.push_back( vdTheta.back() > 0 ? vdTheta.back() + PIGRECO : vdTheta.back() - PIGRECO) ;
|
||||
// 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) ;
|
||||
}
|
||||
if ( abs( ay) > EPS_SMALL) {
|
||||
vdTheta.push_back( atan( by / ay)) ;
|
||||
vdTheta.push_back( vdTheta.back() > 0 ? vdTheta.back() + PIGRECO : vdTheta.back() - PIGRECO) ;
|
||||
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) ;
|
||||
}
|
||||
if ( abs( az) > EPS_SMALL) {
|
||||
vdTheta.push_back( atan( bz / az)) ;
|
||||
vdTheta.push_back( vdTheta.back() > 0 ? vdTheta.back() + PIGRECO : vdTheta.back() - PIGRECO) ;
|
||||
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 {
|
||||
|
||||
vector<double> Va ; Va.push_back( ax) ; Va.push_back( ay) ; Va.push_back( az) ;
|
||||
vector<double> Vb ; Vb.push_back( bx) ; Vb.push_back( by) ; Vb.push_back( bz) ;
|
||||
vector<double> Vn ; Vn.push_back( nx) ; Vn.push_back( ny) ; Vn.push_back( nz) ;
|
||||
|
||||
for ( int i = 0 ; i < 3 ; i++) {
|
||||
double delta = dRad * dRad * Va[i] * Va[i] - Q * Q * Vn[i] * Vn[i] + Vb[i] * Vb[i] * dRad * dRad ;
|
||||
if ( delta > 0) {
|
||||
double t1 = ( dRad * Va[i] + sqrt( delta)) / ( Q * Vn[i] - dRad * Vb[i]) ;
|
||||
if ( abs( 1 - t1 * t1) > EPS_SMALL) {
|
||||
vdTheta.push_back( atan( 2 * t1 / (1 - t1 * t1))) ;
|
||||
vdTheta.push_back(vdTheta.back() > 0 ? vdTheta.back() + PIGRECO : vdTheta.back() - PIGRECO);
|
||||
}
|
||||
double t2 = ( dRad * Va[i] - sqrt( delta)) / ( Q * Vn[i] - dRad * Vb[i]) ;
|
||||
if ( abs( 1 - t2 * t2) > EPS_SMALL){
|
||||
vdTheta.push_back( atan( 2 * t2 / ( 1 - t2 * t2))) ;
|
||||
vdTheta.push_back( vdTheta.back() > 0 ? vdTheta.back() + PIGRECO : vdTheta.back() - PIGRECO) ;
|
||||
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) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vdTheta.push_back( PIGRECO) ;
|
||||
vdTheta.push_back( PIGRECO / 2) ;
|
||||
vdTheta.push_back( 3 * PIGRECO / 2) ;
|
||||
|
||||
for ( int i = 0 ; i < vdTheta.size() ; i++) {
|
||||
double dTheta = vdTheta[i] > 0 ? vdTheta[i] : 2 * PIGRECO + vdTheta[i] ;
|
||||
if ( dTheta < abs( dAngCenRad)) {
|
||||
Point3d pt ;
|
||||
GetPointD1D2( dTheta / ( abs( dAngCenRad)), FROM_MINUS, pt) ;
|
||||
vPoints.push_back( pt) ;
|
||||
// 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) ;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < vPoints.size(); i++) {
|
||||
vPoints[i].ToGlob( frRef) ;
|
||||
b3Ref.Add( vPoints[i]) ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
|
||||
/*
|
||||
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)) {
|
||||
ptPos.ToGlob( frRef) ;
|
||||
b3Ref.Add( ptPos) ;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
// se c'è estrusione, devo tenerne conto
|
||||
if ( ! m_VtExtr.IsSmall() && abs( m_dThick) > EPS_SMALL) {
|
||||
Vector3d vtFrExtr = m_VtExtr ;
|
||||
@@ -852,10 +825,10 @@ CurveArc::Validate( void)
|
||||
m_dAngCenDeg = - ANG_FULL ;
|
||||
}
|
||||
// eseguo il controllo
|
||||
m_nStatus = ( ( m_VtN.IsNormalized() && m_VtS.IsNormalized() &&
|
||||
AreOrthoApprox( m_VtN, m_VtS) &&
|
||||
m_dRad > EPS_SMALL && m_dRad < MAX_ARC_RAD &&
|
||||
abs( m_dAngCenDeg) > EPS_ANG_ZERO) ? OK : ERR) ;
|
||||
m_nStatus = ( ( m_PtCen.IsValid() &&
|
||||
m_VtN.IsNormalized() && m_VtS.IsNormalized() && AreOrthoApprox( m_VtN, m_VtS) &&
|
||||
m_dRad > EPS_SMALL && m_dRad < MAX_ARC_RAD &&
|
||||
abs( m_dAngCenDeg) > EPS_ANG_ZERO) ? OK : ERR) ;
|
||||
}
|
||||
|
||||
return ( m_nStatus == OK) ;
|
||||
@@ -978,10 +951,7 @@ CurveArc::GetDir( double dU, Vector3d& vtDir) const
|
||||
return false ;
|
||||
|
||||
// il parametro U deve essere compreso tra 0 e 1
|
||||
if ( dU < 0)
|
||||
dU = 0 ;
|
||||
else if ( dU > 1)
|
||||
dU = 1 ;
|
||||
dU = Clamp( dU, 0., 1.) ;
|
||||
|
||||
// versore al punto nel piano della circonferenza (ruoto m_VtS di dU * m_dAngCenDeg attorno a m_VtN)
|
||||
double dAng = dU * m_dAngCenDeg * DEGTORAD ;
|
||||
@@ -1003,10 +973,7 @@ CurveArc::GetPointD1D2( double dU, Side nS, Point3d& ptPos, Vector3d* pvtDer1, V
|
||||
return false ;
|
||||
|
||||
// il parametro U deve essere compreso tra 0 e 1
|
||||
if ( dU < 0)
|
||||
dU = 0 ;
|
||||
else if ( dU > 1)
|
||||
dU = 1 ;
|
||||
dU = Clamp( dU, 0., 1.) ;
|
||||
|
||||
// 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 ;
|
||||
@@ -1455,7 +1422,7 @@ bool
|
||||
CurveArc::TrimStartAtParam( double dUTrim)
|
||||
{
|
||||
// riporto i parametri nel loro range
|
||||
dUTrim = ( ( dUTrim < 0) ? 0 : (( dUTrim > 1) ? 1 : dUTrim)) ;
|
||||
dUTrim = Clamp( dUTrim, 0., 1.) ;
|
||||
|
||||
// recupero lunghezza
|
||||
double dLen ;
|
||||
@@ -1471,7 +1438,7 @@ bool
|
||||
CurveArc::TrimEndAtParam( double dUTrim)
|
||||
{
|
||||
// riporto i parametri nel loro range
|
||||
dUTrim = ( ( dUTrim < 0) ? 0 : (( dUTrim > 1) ? 1 : dUTrim)) ;
|
||||
dUTrim = Clamp( dUTrim, 0., 1.) ;
|
||||
|
||||
// recupero lunghezza
|
||||
double dLen ;
|
||||
@@ -1831,11 +1798,14 @@ CurveArc::ToGlob( const Frame3d& frRef)
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// 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
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
@@ -1853,11 +1823,14 @@ CurveArc::ToLoc( const Frame3d& frRef)
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// 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
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
@@ -1878,11 +1851,14 @@ CurveArc::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
|
||||
// verifico validità dei frame
|
||||
if ( frOri.GetType() == Frame3d::ERR || frDest.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
|
||||
// se i due riferimenti coincidono, non devo fare alcunché
|
||||
if ( AreSameFrame( frOri, frDest))
|
||||
return true ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
// trasformo il centro e i versori
|
||||
return ( m_PtCen.LocToLoc( frOri, frDest) &&
|
||||
m_VtN.LocToLoc( frOri, frDest) &&
|
||||
|
||||
+8
-4
@@ -217,12 +217,16 @@ class CurveArc : public ICurveArc, public IGeoObjRW
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline CurveArc* CreateBasicCurveArc( void)
|
||||
{ return (static_cast<CurveArc*>( CreateGeoObj( CRV_ARC))) ; }
|
||||
{ return ( static_cast<CurveArc*>( CreateGeoObj( CRV_ARC))) ; }
|
||||
inline CurveArc* CloneBasicCurveArc( const IGeoObj* pGObj)
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != CRV_ARC)
|
||||
return nullptr ;
|
||||
return (static_cast<CurveArc*>(pGObj->Clone())) ; }
|
||||
return ( static_cast<CurveArc*>( pGObj->Clone())) ; }
|
||||
inline const CurveArc* GetBasicCurveArc( const IGeoObj* pGObj)
|
||||
{ return (dynamic_cast<const CurveArc*>(pGObj)) ; }
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != CRV_ARC)
|
||||
return nullptr ;
|
||||
return ( static_cast<const CurveArc*>( pGObj)) ; }
|
||||
inline CurveArc* GetBasicCurveArc( IGeoObj* pGObj)
|
||||
{ return (dynamic_cast<CurveArc*>(pGObj)) ; }
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != CRV_ARC)
|
||||
return nullptr ;
|
||||
return ( static_cast<CurveArc*>( pGObj)) ; }
|
||||
|
||||
+207
-18
@@ -30,9 +30,8 @@ using namespace std ;
|
||||
bool
|
||||
IsClosed( const ICurve& crvC)
|
||||
{
|
||||
Point3d ptStart ;
|
||||
Point3d ptEnd ;
|
||||
return ( crvC.GetStartPoint( ptStart) && crvC.GetEndPoint( ptEnd) && AreSamePointApprox( ptStart, ptEnd)) ;
|
||||
Point3d ptStart, ptEnd ;
|
||||
return ( crvC.GetStartPoint( ptStart) && crvC.GetEndPoint( ptEnd) && AreSamePointApprox( ptStart, ptEnd)) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -295,7 +294,7 @@ CurveGetAreaXY( const ICurve& crvC, double& dArea)
|
||||
return false ;
|
||||
// approssimo la curva con una polilinea
|
||||
PolyLine PL ;
|
||||
crvC.ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL) ;
|
||||
crvC.ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL_INT, PL) ;
|
||||
// calcolo l'area
|
||||
double dAreaXY = 0 ;
|
||||
PL.GetAreaXY( dAreaXY) ;
|
||||
@@ -314,7 +313,7 @@ CurveGetArea( const ICurve& crvC, Plane3d& plPlane, double& dArea)
|
||||
return false ;
|
||||
// approssimo la curva con una polilinea
|
||||
PolyLine PL ;
|
||||
crvC.ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL) ;
|
||||
crvC.ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL_INT, PL) ;
|
||||
// calcolo l'area
|
||||
Plane3d plMyPlane ;
|
||||
double dMyArea = 0 ;
|
||||
@@ -365,9 +364,11 @@ CurveDump( const ICurve& crvC, string& sOut, bool bMM, const char* szNewLine)
|
||||
// altri dati per curva chiusa
|
||||
double 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=" +
|
||||
ToString( GetAreaInUiUnits( abs( dAreaXY), bMM),1) + szNewLine ;
|
||||
ToString( dAreaUi, nDec) + szNewLine ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
@@ -509,14 +510,7 @@ CurveToArcsPerpExtrCurve( const ICurve* pCrv, double dLinTol, double dAngTolDeg)
|
||||
bool
|
||||
NurbsCurveCanonicalize( CNurbsData& cnData)
|
||||
{
|
||||
// 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
|
||||
// se con nodi extra
|
||||
if ( cnData.bExtraKnotes) {
|
||||
int nKnotesNbr = int( cnData.vU.size()) ;
|
||||
if ( nKnotesNbr < 4)
|
||||
@@ -525,7 +519,176 @@ NurbsCurveCanonicalize( CNurbsData& cnData)
|
||||
for ( int i = 0 ; i < nKnotesNbr - 2 ; ++ i)
|
||||
cnData.vU[i] = cnData.vU[i+1] ;
|
||||
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 ;
|
||||
@@ -616,6 +779,7 @@ NurbsToBezierCurve( const CNurbsData& cnData)
|
||||
int b = cnData.nDeg ;
|
||||
bool bPrevRejected = false ;
|
||||
// ciclo
|
||||
int n = 0 ; // debug
|
||||
while ( b < nU - 1) {
|
||||
int i = b ;
|
||||
while ( b < nU - 1 && abs( cnData.vU[b+1] - cnData.vU[b]) < EPS_ZERO)
|
||||
@@ -683,7 +847,8 @@ NurbsToBezierCurve( const CNurbsData& cnData)
|
||||
pCrvBez.Reset() ;
|
||||
bPrevRejected = true ;
|
||||
}
|
||||
|
||||
// debug
|
||||
++n ;
|
||||
// inizializzazioni per la prossima curva di Bezier
|
||||
if ( b < nU - 1) {
|
||||
if ( ! cnData.bRat) {
|
||||
@@ -707,6 +872,30 @@ 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
|
||||
return Release( pCrvCompo) ;
|
||||
}
|
||||
@@ -729,7 +918,7 @@ FlattenCurve( const ICurve& crCrv, double dToler, double dAngToler, int nFlag)
|
||||
return nullptr ;
|
||||
// Verifico se curva già piatta
|
||||
PolyLine PL ;
|
||||
if ( ! crCrv.ApproxWithLines( LIN_TOL_FINE, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL))
|
||||
if ( ! crCrv.ApproxWithLines( LIN_TOL_FINE, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL_INT, PL))
|
||||
return nullptr ;
|
||||
bool bFlat = true ;
|
||||
Plane3d plFlat ; plFlat.Set( ptCen, plMid.GetVersN()) ;
|
||||
|
||||
+31
-5
@@ -266,7 +266,7 @@ CurveBezier::Clone( void) const
|
||||
bool
|
||||
CurveBezier::CopyFrom( const IGeoObj* pGObjSrc)
|
||||
{
|
||||
const CurveBezier* pCB = dynamic_cast<const CurveBezier*>( pGObjSrc) ;
|
||||
const CurveBezier* pCB = GetBasicCurveBezier( pGObjSrc) ;
|
||||
if ( pCB == nullptr)
|
||||
return false ;
|
||||
return CopyFrom( *pCB) ;
|
||||
@@ -424,6 +424,23 @@ CurveBezier::Load( NgeReader& ngeIn)
|
||||
bool
|
||||
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)
|
||||
m_nStatus = ( ( m_nDeg > 0 && m_vPtCtrl.size() > 0) ? OK : ERR) ;
|
||||
|
||||
@@ -1478,7 +1495,7 @@ CurveBezier::BiArcOrSplit( int nLev, PolyLine& PL, double dLinTol, double dAngTo
|
||||
return false ;
|
||||
if ( ! pCC->FromPolyLine( PL))
|
||||
return false ;
|
||||
pCrv.Set( Release( pCC)) ;
|
||||
pCrv.Set( pCC) ;
|
||||
dMaxDist = 0 ;
|
||||
}
|
||||
// se la polilinea ha un solo punto, esco
|
||||
@@ -1974,11 +1991,14 @@ CurveBezier::ToGlob( const Frame3d& frRef)
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// 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
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
@@ -1998,11 +2018,14 @@ CurveBezier::ToLoc( const Frame3d& frRef)
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// 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
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
@@ -2022,11 +2045,14 @@ CurveBezier::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// verifico validità dei frame
|
||||
if ( frOri.GetType() == Frame3d::ERR || frDest.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
|
||||
// se i due riferimenti coincidono, non devo fare alcunché
|
||||
if ( AreSameFrame( frOri, frDest))
|
||||
return true ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
|
||||
+8
-4
@@ -195,12 +195,16 @@ class CurveBezier : public ICurveBezier, public IGeoObjRW
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline CurveBezier* CreateBasicCurveBezier( void)
|
||||
{ return (static_cast<CurveBezier*>( CreateGeoObj( CRV_BEZIER))) ; }
|
||||
{ return ( static_cast<CurveBezier*>( CreateGeoObj( CRV_BEZIER))) ; }
|
||||
inline CurveBezier* CloneBasicCurveBezier( const IGeoObj* pGObj)
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != CRV_BEZIER)
|
||||
return nullptr ;
|
||||
return (static_cast<CurveBezier*>(pGObj->Clone())) ; }
|
||||
return ( static_cast<CurveBezier*>( pGObj->Clone())) ; }
|
||||
inline const CurveBezier* GetBasicCurveBezier( const IGeoObj* pGObj)
|
||||
{ return (dynamic_cast<const CurveBezier*>(pGObj)) ; }
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != CRV_BEZIER)
|
||||
return nullptr ;
|
||||
return ( static_cast<const CurveBezier*>( pGObj)) ; }
|
||||
inline CurveBezier* GetBasicCurveBezier( IGeoObj* pGObj)
|
||||
{ return (dynamic_cast<CurveBezier*>(pGObj)) ; }
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != CRV_BEZIER)
|
||||
return nullptr ;
|
||||
return ( static_cast<CurveBezier*>( pGObj)) ; }
|
||||
|
||||
+66
-11
@@ -57,11 +57,17 @@ ICurve*
|
||||
CurveByApprox::GetCurve( int nType, double dLinTol, double dAngTolDeg, double dLinFea)
|
||||
{
|
||||
// se da approssimare con archi
|
||||
if ( nType == ARCS_CORNER) {
|
||||
if ( nType == ARCS || nType == ARCS_CORNER) {
|
||||
// calcolo approssimazione
|
||||
PolyArc PA ;
|
||||
if ( ! GetArcs( dLinTol, dAngTolDeg, dLinFea, PA))
|
||||
return nullptr ;
|
||||
if ( nType == ARCS) {
|
||||
if ( ! GetArcs( dLinTol, dAngTolDeg, PA))
|
||||
return nullptr ;
|
||||
}
|
||||
else {
|
||||
if ( ! GetArcsCorner( dLinTol, dAngTolDeg, dLinFea, PA))
|
||||
return nullptr ;
|
||||
}
|
||||
// creo la composita formata da questa approssimazione
|
||||
PtrOwner<CurveComposite> pCC( CreateBasicCurveComposite()) ;
|
||||
if ( ! pCC->FromPolyArc( PA))
|
||||
@@ -74,13 +80,55 @@ CurveByApprox::GetCurve( int nType, double dLinTol, double dAngTolDeg, double dL
|
||||
return Release( pCC) ;
|
||||
}
|
||||
// altrimenti con curve di Bezier cubiche
|
||||
// !!! NON ANCORA IMPLEMENTATA !!!
|
||||
else if ( nType == CUBIC_BEZIERS) {
|
||||
// !!! NON ANCORA IMPLEMENTATA !!!
|
||||
return nullptr ;
|
||||
}
|
||||
// tipi non previsti
|
||||
return nullptr ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveByApprox::GetArcs( double dLinTol, double dAngTolDeg, double dLinFea, PolyArc& PA)
|
||||
CurveByApprox::GetArcs( double dLinTol, double dAngTolDeg, 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
|
||||
PA.Clear() ;
|
||||
@@ -105,9 +153,18 @@ CurveByApprox::GetArcs( double dLinTol, double dAngTolDeg, double dLinFea, PolyA
|
||||
PolyLine PL ;
|
||||
for ( int j = nPrev ; j <= m_vSplits[i] ; ++ j)
|
||||
PL.AddUPoint( j, m_vPnt[j]) ;
|
||||
// eseguo l'approssimazione con archi
|
||||
if ( ! BiArcOrSplit( 0, PL, dLinTol, dAngTolDeg, PA))
|
||||
// verifico se retta verticale
|
||||
BBox3d b3PL ;
|
||||
if ( ! PL.GetLocalBBox( b3PL))
|
||||
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
|
||||
nPrev = m_vSplits[i] ;
|
||||
}
|
||||
@@ -456,11 +513,9 @@ CurveByApprox::BiArcOrSplit( int nLev, PolyLine& PL, double dLinTol, double dAng
|
||||
return true ;
|
||||
// costruisco la retta che li unisce
|
||||
PtrOwner<CurveComposite> pCC( CreateBasicCurveComposite()) ;
|
||||
if ( IsNull( pCC))
|
||||
if ( IsNull( pCC) || ! pCC->FromPolyLine( PL))
|
||||
return false ;
|
||||
if ( ! pCC->FromPolyLine( PL))
|
||||
return false ;
|
||||
pCrv.Set( Release( pCC)) ;
|
||||
pCrv.Set( pCC) ;
|
||||
dMaxDist = 0 ;
|
||||
}
|
||||
// se la polilinea ha un solo punto, esco
|
||||
|
||||
+213
-63
@@ -136,11 +136,9 @@ CurveComposite::AddCurve( ICurve* pCrv, bool bEndOrStart, double dLinTol)
|
||||
// altrimenti curva composita, devo aggiungere le singole curve semplici
|
||||
else {
|
||||
// riloco le curve dalla composita sorgente alla corrente
|
||||
CurveComposite* pCrvCompo = dynamic_cast<CurveComposite*>( pCrv) ;
|
||||
if ( ! AddCurveByRelocate( *pCrvCompo, bEndOrStart, dLinTol))
|
||||
PtrOwner<CurveComposite> pCrvCompo( GetBasicCurveComposite( pCrv)) ;
|
||||
if ( IsNull( pCrvCompo) || ! AddCurveByRelocate( *pCrvCompo, bEndOrStart, dLinTol))
|
||||
return false ;
|
||||
// cancello la curva composita originaria
|
||||
delete pCrvCompo ;
|
||||
}
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
@@ -260,16 +258,16 @@ CurveComposite::Close( void)
|
||||
// verifico curva valida
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// se già chiusa, non faccio alcunché
|
||||
if ( IsClosed())
|
||||
return true ;
|
||||
// determino la distanza tra gli estremi
|
||||
Point3d ptStart, ptEnd ;
|
||||
if ( ! GetStartPoint( ptStart) ||
|
||||
! GetEndPoint( ptEnd))
|
||||
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 ( SqDist( ptStart, ptEnd) < 100 * SQ_EPS_SMALL) {
|
||||
if ( AreSamePointEpsilon( ptStart, ptEnd, 10 * EPS_SMALL)) {
|
||||
Point3d ptMid = Media( ptStart, ptEnd) ;
|
||||
if ( ! ModifyStart( ptMid) ||
|
||||
! ModifyEnd( ptMid))
|
||||
@@ -851,9 +849,9 @@ CurveComposite::IsFlat( Plane3d& plPlane, bool bUseExtrusion, double dToler) con
|
||||
return false ;
|
||||
// ciclo sulle curve semplici (aggiungo solo eventuali punti intermedi e finali)
|
||||
int nCount = 0 ;
|
||||
for ( const ICurve* pCrv = GetFirstCurve() ;
|
||||
for ( const ICurve* pCrv = GetCurve( nCount) ;
|
||||
pCrv != nullptr ;
|
||||
pCrv = GetNextCurve(), ++ nCount) {
|
||||
pCrv = GetCurve( ++ nCount)) {
|
||||
switch ( pCrv->GetType()) {
|
||||
case CRV_LINE :
|
||||
// punto finale
|
||||
@@ -987,7 +985,7 @@ CurveComposite::GetCentroid( Point3d& ptCen) const
|
||||
return false ;
|
||||
// approssimo la curva con una polilinea
|
||||
PolyLine PL ;
|
||||
if ( ! ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, APL_SPECIAL, PL))
|
||||
if ( ! ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, APL_SPECIAL_INT, PL))
|
||||
return false ;
|
||||
// calcolo il centro mediante PolygonPlane
|
||||
Point3d ptP ;
|
||||
@@ -1315,7 +1313,7 @@ CurveComposite::ApproxWithLines( double dLinTol, double dAngTolDeg, int nType, P
|
||||
dAngTolDeg = max( dAngTolDeg, ANG_TOL_MIN_DEG) ;
|
||||
|
||||
// se speciale, approssimo ogni singola entità e conservo le estremità interne (joint)
|
||||
if ( nType == APL_SPECIAL) {
|
||||
if ( nType == APL_SPECIAL || nType == APL_SPECIAL_INT) {
|
||||
// eseguo approssimazione
|
||||
double dStartPar = 0 ;
|
||||
for ( auto& pCrv : m_CrvSmplS) {
|
||||
@@ -1326,6 +1324,18 @@ CurveComposite::ApproxWithLines( double dLinTol, double dAngTolDeg, int nType, P
|
||||
PolyLine PLSmpl ;
|
||||
if ( ! pCrv->ApproxWithLines( dLinTol, dAngTolDeg, nType, PLSmpl))
|
||||
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)
|
||||
pCrv->SetExtrusion( V_NULL) ;
|
||||
pCrv->SetThickness( 0) ;
|
||||
@@ -1375,30 +1385,52 @@ CurveComposite::ApproxWithArcs( double dLinTol, double dAngTolDeg, PolyArc& PA)
|
||||
if ( m_nStatus != OK)
|
||||
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
|
||||
double dStartPar = 0 ;
|
||||
for ( auto& pCrv : m_CrvSmplS) {
|
||||
for ( const 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
|
||||
pCrv->SetExtrusion( m_VtExtr) ;
|
||||
pCrv->SetThickness( m_dThick) ;
|
||||
pCrvL->SetExtrusion( m_VtExtr) ;
|
||||
pCrvL->SetThickness( m_dThick) ;
|
||||
// la porto nel riferimento naturale
|
||||
pCrvL->ToLoc( frNat) ;
|
||||
// recupero approssimazione per curva semplice
|
||||
PolyArc PASmpl ;
|
||||
if ( ! pCrv->ApproxWithArcs( dLinTol, dAngTolDeg, PASmpl))
|
||||
if ( ! pCrvL->ApproxWithArcs( dLinTol, dAngTolDeg, PASmpl))
|
||||
return false ;
|
||||
// la accodo opportunamente a quella della curva composita
|
||||
if ( ! PA.Join( PASmpl, dStartPar))
|
||||
return false ;
|
||||
// ripristino estrusione e spessore della curva semplice (annullandoli)
|
||||
pCrv->SetExtrusion( V_NULL) ;
|
||||
pCrv->SetThickness( 0) ;
|
||||
// incremento inizio parametro per prossima curva semplice
|
||||
dStartPar += 1 ;
|
||||
}
|
||||
|
||||
// riporto l'approssimazione nel riferimento della composita
|
||||
PA.ToGlob( frNat) ;
|
||||
|
||||
// assegno estrusione della curva composita
|
||||
PA.SetExtrusion( m_VtExtr) ;
|
||||
|
||||
return true ;
|
||||
// eliminazione dei punti in tolleranza (opportunamente diminuita)
|
||||
return PA.RemoveAlignedPoints( 0.5 * dLinTol) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -1417,16 +1449,37 @@ CurveComposite::ApproxWithArcsEx( double dLinTol, double dAngTolDeg, double dLin
|
||||
double dMlStartPar = 0 ;
|
||||
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
|
||||
double dStartPar = 0 ;
|
||||
for ( auto& pCrv : m_CrvSmplS) {
|
||||
for ( const 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
|
||||
pCrv->SetExtrusion( m_VtExtr) ;
|
||||
pCrv->SetThickness( m_dThick) ;
|
||||
pCrvL->SetExtrusion( m_VtExtr) ;
|
||||
pCrvL->SetThickness( m_dThick) ;
|
||||
// la porto nel riferimento naturale
|
||||
pCrvL->ToLoc( frNat) ;
|
||||
// se segmento di linea non feature
|
||||
double dLen ;
|
||||
if ( pCrv->GetType() == CRV_LINE && pCrv->GetLength( dLen) && dLen < dLinFea) {
|
||||
CurveLine* pLine = GetBasicCurveLine( pCrv) ;
|
||||
if ( pCrvL->GetType() == CRV_LINE && pCrvL->GetLength( dLen) && dLen < dLinFea) {
|
||||
CurveLine* pLine = GetBasicCurveLine( pCrvL) ;
|
||||
// se inizio di approx multilinea
|
||||
if ( ! bMultiLine) {
|
||||
bMultiLine = true ;
|
||||
@@ -1434,23 +1487,38 @@ CurveComposite::ApproxWithArcsEx( double dLinTol, double dAngTolDeg, double dLin
|
||||
crvByApprox.Reset() ;
|
||||
crvByApprox.AddPoint( pLine->GetStart()) ;
|
||||
}
|
||||
// aggiungo punti a distanza opportuna
|
||||
const double STEP = 5 ;
|
||||
int nStep = int( dLen / STEP) ;
|
||||
for ( int i = 1 ; i < nStep ; ++ i) {
|
||||
double dCoeff = i / double( nStep) ;
|
||||
crvByApprox.AddPoint( Media( pLine->GetStart(), pLine->GetEnd(), dCoeff)) ;
|
||||
}
|
||||
// aggiungo il punto finale
|
||||
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
|
||||
else {
|
||||
// se in corso approx multilinee
|
||||
if ( bMultiLine) {
|
||||
bMultiLine = false ;
|
||||
PolyArc PASmpl ;
|
||||
if ( ! crvByApprox.GetArcs( dLinTol, dAngTolDeg, dLinFea, PASmpl))
|
||||
if ( ! crvByApprox.GetArcsCorner( dLinTol, dAngTolDeg, dLinFea, PASmpl))
|
||||
return false ;
|
||||
// la accodo opportunamente a quella della curva composita
|
||||
if ( ! PA.Join( PASmpl, dMlStartPar))
|
||||
@@ -1458,15 +1526,12 @@ CurveComposite::ApproxWithArcsEx( double dLinTol, double dAngTolDeg, double dLin
|
||||
}
|
||||
// recupero approssimazione per curva semplice
|
||||
PolyArc PASmpl ;
|
||||
if ( ! pCrv->ApproxWithArcs( dLinTol, dAngTolDeg, PASmpl))
|
||||
if ( ! pCrvL->ApproxWithArcs( dLinTol, dAngTolDeg, PASmpl))
|
||||
return false ;
|
||||
// la accodo opportunamente a quella della curva composita
|
||||
if ( ! PA.Join( PASmpl, dStartPar))
|
||||
return false ;
|
||||
}
|
||||
// ripristino estrusione e spessore della curva semplice (annullandoli)
|
||||
pCrv->SetExtrusion( V_NULL) ;
|
||||
pCrv->SetThickness( 0) ;
|
||||
// incremento inizio parametro per prossima curva semplice
|
||||
dStartPar += 1 ;
|
||||
}
|
||||
@@ -1474,13 +1539,16 @@ CurveComposite::ApproxWithArcsEx( double dLinTol, double dAngTolDeg, double dLin
|
||||
if ( bMultiLine) {
|
||||
bMultiLine = false ;
|
||||
PolyArc PASmpl ;
|
||||
if ( ! crvByApprox.GetArcs( dLinTol, dAngTolDeg, dLinFea, PASmpl))
|
||||
if ( ! crvByApprox.GetArcsCorner( dLinTol, dAngTolDeg, dLinFea, PASmpl))
|
||||
return false ;
|
||||
// la accodo opportunamente a quella della curva composita
|
||||
if ( ! PA.Join( PASmpl, dMlStartPar))
|
||||
return false ;
|
||||
}
|
||||
|
||||
// riporto l'approssimazione nel riferimento della composita
|
||||
PA.ToGlob( frNat) ;
|
||||
|
||||
// assegno estrusione della curva composita
|
||||
PA.SetExtrusion( m_VtExtr) ;
|
||||
|
||||
@@ -1498,6 +1566,9 @@ CurveComposite::CopyParamRange( double dUStart, double dUEnd) const
|
||||
if ( dUStart < - EPS_PARAM || dUStart > dMaxU + EPS_PARAM ||
|
||||
dUEnd < - EPS_PARAM || dUEnd > dMaxU + EPS_PARAM)
|
||||
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
|
||||
if ( dUStart > dUEnd - EPS_PARAM) {
|
||||
// se curva aperta, il trim la cancella completamente quindi non resta alcunchè
|
||||
@@ -1529,7 +1600,7 @@ CurveComposite::CopyParamRange( double dUStart, double dUEnd) const
|
||||
// eseguo il trim della copia
|
||||
if ( ! pCopy->TrimStartEndAtParam( dUStart, dUEnd))
|
||||
return nullptr ;
|
||||
return ( ::Release( pCopy)) ;
|
||||
return ( pCopy->m_CrvSmplS.empty() ? nullptr : ::Release( pCopy)) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -2039,7 +2110,7 @@ CurveComposite::ModifyCurveToArc( int nCrv, const Point3d& ptMid)
|
||||
if ( nCrv < 0 || nCrv > nCrvCount - 1)
|
||||
return false ;
|
||||
// recupero la curva corrente
|
||||
ICurve* pCrv = *(m_CrvSmplS.begin() + nCrv) ;
|
||||
ICurve* pCrv = m_CrvSmplS[nCrv] ;
|
||||
// recupero gli estremi
|
||||
Point3d ptStart, ptEnd ;
|
||||
if ( ! pCrv->GetStartPoint( ptStart) || ! pCrv->GetEndPoint( ptEnd))
|
||||
@@ -2072,7 +2143,7 @@ CurveComposite::ModifyCurveToLine( int nCrv)
|
||||
if ( nCrv < 0 || nCrv > nCrvCount - 1)
|
||||
return false ;
|
||||
// recupero la curva corrente
|
||||
ICurve* pCrv = *(m_CrvSmplS.begin() + nCrv) ;
|
||||
ICurve* pCrv = m_CrvSmplS[nCrv] ;
|
||||
// se già linea non devo fare alcunchè
|
||||
if ( pCrv->GetType() == CRV_LINE)
|
||||
return true ;
|
||||
@@ -2099,7 +2170,15 @@ CurveComposite::ModifyCurveToLine( int nCrv)
|
||||
bool
|
||||
CurveComposite::TrimStartAtParam( double dUTrim)
|
||||
{
|
||||
// ciclo sulle diverse curve dall'inizio
|
||||
// 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 dall'inizio
|
||||
double dUToTrim = dUTrim ;
|
||||
for ( auto Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ;) {
|
||||
// dominio parametrico della curva semplice
|
||||
@@ -2110,17 +2189,13 @@ CurveComposite::TrimStartAtParam( double dUTrim)
|
||||
// se lunghezza ancora da tagliare non nulla
|
||||
if ( dUToTrim > EPS_PARAM) {
|
||||
delete (*Iter) ;
|
||||
Iter ++ ;
|
||||
m_CrvSmplS.pop_front() ;
|
||||
Iter = m_CrvSmplS.erase( Iter) ;
|
||||
}
|
||||
// se lunghezza ancora da tagliare nulla (entro la tolleranza)
|
||||
else if ( dUToTrim > - EPS_PARAM ||
|
||||
! (*Iter)->TrimStartAtParam( 1 + dUToTrim)) {
|
||||
delete (*Iter) ;
|
||||
Iter ++ ;
|
||||
m_CrvSmplS.pop_front() ;
|
||||
if ( m_CrvSmplS.empty())
|
||||
return false ;
|
||||
Iter = m_CrvSmplS.erase( Iter) ;
|
||||
break ;
|
||||
}
|
||||
// altrimenti superata lunghezza ancora da tagliare (taglio già fatto al test sopra)
|
||||
@@ -2129,9 +2204,6 @@ CurveComposite::TrimStartAtParam( double dUTrim)
|
||||
}
|
||||
}
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
@@ -2139,6 +2211,14 @@ CurveComposite::TrimStartAtParam( double dUTrim)
|
||||
bool
|
||||
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
|
||||
bool bToErase = false ;
|
||||
double dUToTrim = dUTrim ;
|
||||
@@ -2180,9 +2260,6 @@ CurveComposite::TrimEndAtParam( double dUTrim)
|
||||
}
|
||||
}
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
@@ -2405,6 +2482,9 @@ CurveComposite::ExtendEndByLen( double dLenExt)
|
||||
bool
|
||||
CurveComposite::Translate( const Vector3d& vtMove)
|
||||
{
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
@@ -2419,6 +2499,9 @@ CurveComposite::Translate( const Vector3d& vtMove)
|
||||
bool
|
||||
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
|
||||
if ( vtAx.IsSmall())
|
||||
return false ;
|
||||
@@ -2440,6 +2523,9 @@ CurveComposite::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAn
|
||||
bool
|
||||
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
|
||||
if ( abs( dCoeffX) < EPS_ZERO && abs( dCoeffY) < EPS_ZERO && abs( dCoeffZ) < EPS_ZERO)
|
||||
return false ;
|
||||
@@ -2524,6 +2610,9 @@ CurveComposite::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, dou
|
||||
bool
|
||||
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
|
||||
if ( vtNorm.IsSmall())
|
||||
return false ;
|
||||
@@ -2545,6 +2634,9 @@ CurveComposite::Mirror( const Point3d& ptOn, const Vector3d& vtNorm)
|
||||
bool
|
||||
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
|
||||
if ( vtNorm.IsSmall() || vtDir.IsSmall())
|
||||
return false ;
|
||||
@@ -2575,10 +2667,17 @@ CurveComposite::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector
|
||||
bool
|
||||
CurveComposite::ToGlob( const Frame3d& frRef)
|
||||
{
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// 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
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
@@ -2596,10 +2695,17 @@ CurveComposite::ToGlob( const Frame3d& frRef)
|
||||
bool
|
||||
CurveComposite::ToLoc( const Frame3d& frRef)
|
||||
{
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// 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
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
@@ -2617,6 +2723,9 @@ CurveComposite::ToLoc( const Frame3d& frRef)
|
||||
bool
|
||||
CurveComposite::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
|
||||
{
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico validità dei frame
|
||||
if ( frOri.GetType() == Frame3d::ERR || frDest.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
@@ -2880,6 +2989,39 @@ CurveComposite::ArcsBezierCurvesToArcsPerpExtr( double dLinTol, double dAngTolDe
|
||||
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
|
||||
MergeTwoCurves( ICurve* pCrvP, ICurve* pCrvC, double& dCurrLinTol, double dCosAngTol, bool bNeedSameProp)
|
||||
@@ -2905,9 +3047,11 @@ MergeTwoCurves( ICurve* pCrvP, ICurve* pCrvC, double& dCurrLinTol, double dCosAn
|
||||
}
|
||||
}
|
||||
// verifico compatibilità delle proprietà
|
||||
int nTprP = pCrvP->GetTempProp() ;
|
||||
int nTprC = pCrvC->GetTempProp() ;
|
||||
if ( bNeedSameProp && nTprP != nTprC)
|
||||
int nTpr0P = pCrvP->GetTempProp( 0) ;
|
||||
int nTpr0C = pCrvC->GetTempProp( 0) ;
|
||||
int nTpr1P = pCrvP->GetTempProp( 1) ;
|
||||
int nTpr1C = pCrvC->GetTempProp( 1) ;
|
||||
if ( bNeedSameProp && ( nTpr0P != nTpr0C || nTpr1P != nTpr1C))
|
||||
return 0 ;
|
||||
// coefficiente deduzione tolleranza
|
||||
const double COEFF_TOL = 0.7 ;
|
||||
@@ -2929,8 +3073,10 @@ MergeTwoCurves( ICurve* pCrvP, ICurve* pCrvC, double& dCurrLinTol, double dCosAn
|
||||
// diminuisco la tolleranza corrente dell'errore attuale
|
||||
dCurrLinTol -= COEFF_TOL * sqrt( dSqDist) ;
|
||||
// se curve originali con proprietà diversa, la cancello
|
||||
if ( nTprP != nTprC)
|
||||
pLineC->SetTempProp( 0) ;
|
||||
if ( nTpr0P != nTpr0C)
|
||||
pLineC->SetTempProp( 0, 0) ;
|
||||
if ( nTpr1P != nTpr1C)
|
||||
pLineC->SetTempProp( 0, 1) ;
|
||||
// torno flag modifica
|
||||
return -1 ;
|
||||
}
|
||||
@@ -2980,8 +3126,10 @@ MergeTwoCurves( ICurve* pCrvP, ICurve* pCrvC, double& dCurrLinTol, double dCosAn
|
||||
if ( NewArc.GetNormVersor() * pArcC->GetNormVersor() < 0)
|
||||
NewArc.InvertN() ;
|
||||
// se curve originali con la stessa proprietà, la riporto
|
||||
if ( nTprP == nTprC)
|
||||
NewArc.SetTempProp( nTprC) ;
|
||||
if ( nTpr0P == nTpr0C)
|
||||
NewArc.SetTempProp( nTpr0C, 0) ;
|
||||
if ( nTpr1P == nTpr1C)
|
||||
NewArc.SetTempProp( nTpr1C, 1) ;
|
||||
// aggiorno l'arco corrente e torno flag modifica
|
||||
*pArcC = NewArc ;
|
||||
return -1 ;
|
||||
@@ -3003,8 +3151,10 @@ MergeTwoCurves( ICurve* pCrvP, ICurve* pCrvC, double& dCurrLinTol, double dCosAn
|
||||
CurveArc NewArc ;
|
||||
if ( NewArc.Set2PVN( ptP1, ptP3, vtDir1, pArcC->GetNormVersor())) {
|
||||
// se curve originali con la stessa proprietà, la riporto
|
||||
if ( nTprP == nTprC)
|
||||
NewArc.SetTempProp( nTprC) ;
|
||||
if ( nTpr0P == nTpr0C)
|
||||
NewArc.SetTempProp( nTpr0C, 0) ;
|
||||
if ( nTpr1P == nTpr1C)
|
||||
NewArc.SetTempProp( nTpr1C, 1) ;
|
||||
// aggiorno l'arco corrente e torno flag modifica
|
||||
*pArcC = NewArc ;
|
||||
return -1 ;
|
||||
|
||||
+34
-4
@@ -156,6 +156,7 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW
|
||||
bool ModifyCurveToLine( int nCrv) override ;
|
||||
bool ArcsToBezierCurves( void) 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 RemoveSmallDefects( double dLinTol, double dAngTolDeg, bool bAlsoSpikes = false) override ;
|
||||
bool RemoveUndercutOnY( double dLinTol, double dAngTolDeg) override ;
|
||||
@@ -214,12 +215,41 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline CurveComposite* CreateBasicCurveComposite( void)
|
||||
{ return (static_cast<CurveComposite*>( CreateGeoObj( CRV_COMPO))) ; }
|
||||
{ return ( static_cast<CurveComposite*>( CreateGeoObj( CRV_COMPO))) ; }
|
||||
inline CurveComposite* CloneBasicCurveComposite( const IGeoObj* pGObj)
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != CRV_COMPO)
|
||||
return nullptr ;
|
||||
return (static_cast<CurveComposite*>(pGObj->Clone())) ; }
|
||||
return ( static_cast<CurveComposite*>( pGObj->Clone())) ; }
|
||||
inline const CurveComposite* GetBasicCurveComposite( const IGeoObj* pGObj)
|
||||
{ return (dynamic_cast<const CurveComposite*>(pGObj)) ; }
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != CRV_COMPO)
|
||||
return nullptr ;
|
||||
return ( static_cast<const CurveComposite*>( pGObj)) ; }
|
||||
inline CurveComposite* GetBasicCurveComposite( IGeoObj* pGObj)
|
||||
{ return (dynamic_cast<CurveComposite*>(pGObj)) ; }
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != CRV_COMPO)
|
||||
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 ;
|
||||
}
|
||||
|
||||
+17
-9
@@ -19,6 +19,7 @@
|
||||
#include "NgeWriter.h"
|
||||
#include "NgeReader.h"
|
||||
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
#include <new>
|
||||
|
||||
@@ -32,7 +33,7 @@ CurveLine::CurveLine( void)
|
||||
: m_nStatus( TO_VERIFY), m_PtStart(), m_PtEnd(), m_VtExtr(), m_dThick()
|
||||
{
|
||||
m_nTempProp[0] = 0 ;
|
||||
m_nTempProp[0] = 0 ;
|
||||
m_nTempProp[1] = 0 ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -111,7 +112,7 @@ CurveLine::Clone( void) const
|
||||
bool
|
||||
CurveLine::CopyFrom( const IGeoObj* pGObjSrc)
|
||||
{
|
||||
const CurveLine* pCL = dynamic_cast<const CurveLine*>( pGObjSrc) ;
|
||||
const CurveLine* pCL = GetBasicCurveLine( pGObjSrc) ;
|
||||
if ( pCL == nullptr)
|
||||
return false ;
|
||||
return CopyFrom( *pCL) ;
|
||||
@@ -259,7 +260,7 @@ bool
|
||||
CurveLine::Validate( void)
|
||||
{
|
||||
if ( m_nStatus == TO_VERIFY)
|
||||
m_nStatus = ( ! AreSamePointApprox( m_PtStart, m_PtEnd) ? OK : ERR) ;
|
||||
m_nStatus = ( m_PtStart.IsValid() && m_PtEnd.IsValid() && ! AreSamePointApprox( m_PtStart, m_PtEnd) ? OK : ERR) ;
|
||||
|
||||
return ( m_nStatus == OK) ;
|
||||
}
|
||||
@@ -356,10 +357,7 @@ CurveLine::GetPointD1D2( double dU, Side nS, Point3d& ptPos, Vector3d* pvtDer1,
|
||||
return false ;
|
||||
|
||||
// il parametro U deve essere compreso tra 0 e 1
|
||||
if ( dU < 0)
|
||||
dU = 0 ;
|
||||
else if ( dU > 1)
|
||||
dU = 1 ;
|
||||
dU = Clamp( dU, 0., 1.) ;
|
||||
|
||||
// calcolo del punto
|
||||
ptPos = Media( m_PtStart, m_PtEnd, dU) ;
|
||||
@@ -642,7 +640,7 @@ bool
|
||||
CurveLine::TrimStartAtParam( double dUTrim)
|
||||
{
|
||||
// riporto i parametri nel loro range
|
||||
dUTrim = ( ( dUTrim < 0) ? 0 : (( dUTrim > 1) ? 1 : dUTrim)) ;
|
||||
dUTrim = Clamp( dUTrim, 0., 1.) ;
|
||||
|
||||
// recupero lunghezza
|
||||
double dLen ;
|
||||
@@ -658,7 +656,7 @@ bool
|
||||
CurveLine::TrimEndAtParam( double dUTrim)
|
||||
{
|
||||
// riporto i parametri nel loro range
|
||||
dUTrim = ( ( dUTrim < 0) ? 0 : (( dUTrim > 1) ? 1 : dUTrim)) ;
|
||||
dUTrim = Clamp( dUTrim, 0., 1.) ;
|
||||
|
||||
// recupero lunghezza
|
||||
double dLen ;
|
||||
@@ -787,6 +785,7 @@ CurveLine::Translate( const Vector3d& vtMove)
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
@@ -919,6 +918,10 @@ CurveLine::ToGlob( const Frame3d& frRef)
|
||||
if ( frRef.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
|
||||
// se frame identità, non devo fare alcunché
|
||||
if ( IsGlobFrame( frRef))
|
||||
return true ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
@@ -937,6 +940,10 @@ CurveLine::ToLoc( const Frame3d& frRef)
|
||||
if ( frRef.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
|
||||
// se frame identità, non devo fare alcunché
|
||||
if ( IsGlobFrame( frRef))
|
||||
return true ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
@@ -954,6 +961,7 @@ CurveLine::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
|
||||
// verifico validità dei frame
|
||||
if ( frOri.GetType() == Frame3d::ERR || frDest.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
|
||||
// se i due riferimenti coincidono, non devo fare alcunché
|
||||
if ( AreSameFrame( frOri, frDest))
|
||||
return true ;
|
||||
|
||||
+8
-4
@@ -170,12 +170,16 @@ class CurveLine : public ICurveLine, public IGeoObjRW
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline CurveLine* CreateBasicCurveLine( void)
|
||||
{ return (static_cast<CurveLine*>( CreateGeoObj( CRV_LINE))) ; }
|
||||
{ return ( static_cast<CurveLine*>( CreateGeoObj( CRV_LINE))) ; }
|
||||
inline CurveLine* CloneBasicCurveLine( const IGeoObj* pGObj)
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != CRV_LINE)
|
||||
return nullptr ;
|
||||
return (static_cast<CurveLine*>(pGObj->Clone())) ; }
|
||||
return ( static_cast<CurveLine*>( pGObj->Clone())) ; }
|
||||
inline const CurveLine* GetBasicCurveLine( const IGeoObj* pGObj)
|
||||
{ return (dynamic_cast<const CurveLine*>(pGObj)) ; }
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != CRV_LINE)
|
||||
return nullptr ;
|
||||
return ( static_cast<const CurveLine*>( pGObj)) ; }
|
||||
inline CurveLine* GetBasicCurveLine( IGeoObj* pGObj)
|
||||
{ return (dynamic_cast<CurveLine*>(pGObj)) ; }
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != CRV_LINE)
|
||||
return nullptr ;
|
||||
return ( static_cast<CurveLine*>( pGObj)) ; }
|
||||
|
||||
+105
-21
@@ -12,6 +12,7 @@
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "SurfTriMesh.h"
|
||||
#include "/EgtDev/Include/EGkDistPointTria.h"
|
||||
#include "/EgtDev/Include/EGkDistPointSurfTm.h"
|
||||
|
||||
@@ -24,7 +25,7 @@ using namespace std ;
|
||||
// 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 vettore vBoxDiff vengono restituiti i box la cui unione costituisce la differenza fra A e B.
|
||||
bool
|
||||
static bool
|
||||
BoundingBoxDifference( const BBox3d& boxA, const BBox3d& boxB, BOXVECTOR& vBoxDiff)
|
||||
{
|
||||
// Svuoto il risultato
|
||||
@@ -93,30 +94,33 @@ DistPointSurfTm::Calculate( const Point3d& ptP, const ISurfTriMesh& tmSurf)
|
||||
// Inizializzo distanza non calcolata
|
||||
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
|
||||
BBox3d b3Stm = tmSurf.GetAllTriaBox() ;
|
||||
BBox3d b3Stm = pStm->GetAllTriaBox() ;
|
||||
if ( b3Stm.IsEmpty())
|
||||
return ;
|
||||
|
||||
// Determino i triangoli vicini e fra di essi cerco quello di minima distanza.
|
||||
// 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.
|
||||
// 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( ptMax.x - ptMin.x, ptMax.y - ptMin.y), ptMax.z - ptMin.z) / 40., 10.) ;
|
||||
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 lo spazio differenza tra i due
|
||||
// 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, indice del triangolo di distanza minima, punto di distanza minima
|
||||
double dMinSqDist = DBL_MAX ;
|
||||
int nMinDistTriaIndex = SVT_NULL ;
|
||||
Point3d ptMinDistPoint ;
|
||||
bool bContinue = true ;
|
||||
// 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 ;
|
||||
@@ -131,18 +135,21 @@ DistPointSurfTm::Calculate( const Point3d& ptP, const ISurfTriMesh& tmSurf)
|
||||
// ricerca sui triangoli nel box
|
||||
bCollide = true ;
|
||||
INTVECTOR vnIds ;
|
||||
if ( tmSurf.GetAllTriaOverlapBox( b3Int, vnIds)) {
|
||||
if ( pStm->GetAllTriaOverlapBox( b3Int, vnIds)) {
|
||||
// Ciclo sui triangoli del sotto-box corrente
|
||||
for ( auto nT : vnIds) {
|
||||
int nTriaTemp ;
|
||||
Triangle3d trCurTria ;
|
||||
tmSurf.GetTriangle( nT, trCurTria) ;
|
||||
DistPointTriangle distPT( ptP, trCurTria) ;
|
||||
double dCurSqDist ;
|
||||
// Se la distanza del triangolo è valida e minore di quella attuale aggiorno
|
||||
if ( distPT.GetSqDist( dCurSqDist) && dCurSqDist < dMinSqDist) {
|
||||
dMinSqDist = dCurSqDist ;
|
||||
nMinDistTriaIndex = nT ;
|
||||
distPT.GetMinDistPoint( ptMinDistPoint) ;
|
||||
if ( pStm->GetTempInt( nT, nTriaTemp) && nTriaTemp == 0 && pStm->GetTriangle( nT, trCurTria)) {
|
||||
pStm->SetTempInt( nT, 1) ;
|
||||
DistPointTriangle distPT( ptP, trCurTria) ;
|
||||
double dCurSqDist ;
|
||||
// Se la distanza del triangolo è valida e minore di quella attuale aggiorno
|
||||
if ( distPT.GetSqDist( dCurSqDist) && dCurSqDist < dMinSqDist) {
|
||||
dMinSqDist = dCurSqDist ;
|
||||
nMinDistTriaIndex = nT ;
|
||||
distPT.GetMinDistPoint( ptMinDistPoint) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -161,9 +168,9 @@ DistPointSurfTm::Calculate( const Point3d& ptP, const ISurfTriMesh& tmSurf)
|
||||
m_nMinDistTriaIndex = nMinDistTriaIndex ;
|
||||
m_ptMinDistPoint = ptMinDistPoint ;
|
||||
Triangle3d trMinDistTria ;
|
||||
tmSurf.GetTriangle( m_nMinDistTriaIndex, trMinDistTria) ;
|
||||
pStm->GetTriangle( m_nMinDistTriaIndex, trMinDistTria) ;
|
||||
trMinDistTria.Validate() ;
|
||||
m_bIsInside = ( ( ptP - m_ptMinDistPoint) * trMinDistTria.GetN() < - EPS_SMALL) && tmSurf.IsClosed() ;
|
||||
m_bIsInside = ( ( ptP - m_ptMinDistPoint) * trMinDistTria.GetN() < - EPS_SMALL) && pStm->IsClosed() ;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,3 +209,80 @@ DistPointSurfTm::GetMinDistTriaIndex( int& nMinDistIndex)
|
||||
nMinDistIndex = m_nMinDistTriaIndex ;
|
||||
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 ;
|
||||
}
|
||||
|
||||
Binary file not shown.
+11
-1
@@ -22,7 +22,7 @@
|
||||
<ProjectGuid>{9A98A202-2853-454A-84CA-DCD1714176C9}</ProjectGuid>
|
||||
<RootNamespace>EgtGeomKernel</RootNamespace>
|
||||
<Keyword>MFCDLLProj</Keyword>
|
||||
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformVersion>10.0.20348.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
@@ -116,6 +116,7 @@
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<EnablePREfast>false</EnablePREfast>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -198,6 +199,7 @@ copy $(TargetPath) \EgtProg\DllD64</Command>
|
||||
<EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -329,6 +331,9 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClCompile Include="ExtDimension.cpp" />
|
||||
<ClCompile Include="HashGrids1d.cpp" />
|
||||
<ClCompile Include="IntersLineBox.cpp" />
|
||||
<ClCompile Include="IntersLineCaps.cpp" />
|
||||
<ClCompile Include="IntersLineCone.cpp" />
|
||||
<ClCompile Include="IntersLineCyl.cpp" />
|
||||
<ClCompile Include="IntersLineSphere.cpp" />
|
||||
<ClCompile Include="IntersLineSurfStd.cpp" />
|
||||
<ClCompile Include="IntersPlaneBox.cpp" />
|
||||
@@ -395,6 +400,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClCompile Include="RemoveCurveDefects.cpp" />
|
||||
<ClCompile Include="SelfIntersCurve.cpp" />
|
||||
<ClCompile Include="SfrCreate.cpp" />
|
||||
<ClCompile Include="SurfAux.cpp" />
|
||||
<ClCompile Include="SurfBezier.cpp" />
|
||||
<ClCompile Include="SurfFlatRegion.cpp" />
|
||||
<ClCompile Include="SurfFlatRegionBooleans.cpp" />
|
||||
@@ -597,6 +603,9 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClInclude Include="IntersCrvCompoCrvCompo.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="IntersLineSurfStd.h" />
|
||||
<ClInclude Include="IntersLineTria.h" />
|
||||
@@ -611,6 +620,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClInclude Include="FontOs.h" />
|
||||
<ClInclude Include="AdjustLoops.h" />
|
||||
<ClInclude Include="RemoveCurveDefects.h" />
|
||||
<ClInclude Include="SurfAux.h" />
|
||||
<ClInclude Include="SurfBezier.h" />
|
||||
<ClInclude Include="SurfFlatRegion.h" />
|
||||
<ClInclude Include="TextureData.h" />
|
||||
|
||||
@@ -471,6 +471,18 @@
|
||||
<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>
|
||||
<ClInclude Include="stdafx.h">
|
||||
@@ -1103,6 +1115,18 @@
|
||||
<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>
|
||||
<ResourceCompile Include="EgtGeomKernel.rc">
|
||||
|
||||
+680
-102
File diff suppressed because it is too large
Load Diff
@@ -62,6 +62,12 @@ class ExtDimension : public IExtDimension, public IGeoObjRW
|
||||
int nDecDigit, const std::string& sFont, double dTextHeight) override ;
|
||||
bool SetLinear( const Point3d& ptP1, const Point3d& ptP2, const Point3d& ptPos,
|
||||
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
|
||||
{ return m_vtN ; }
|
||||
const Vector3d& GetDirVersor( void) const override
|
||||
@@ -119,6 +125,7 @@ class ExtDimension : public IExtDimension, public IGeoObjRW
|
||||
bool GetArrowHead( const Point3d& ptTip, const Vector3d& vtDir, PolyLine& PL) const ;
|
||||
bool SetCurrFont( FontManager& fntMgr) const ;
|
||||
bool ApproxTextWithLines( double dLinTol, double dAngTolDeg, POLYLINELIST& lstPL) const ;
|
||||
bool GetTextMyBBox( BBox3d& b3Loc) const ;
|
||||
bool GetTextMyBBox( const Point3d& ptPos, BBox3d& b3Loc) const ;
|
||||
bool GetTextLocalBBox( BBox3d& b3Loc) const ;
|
||||
bool GetTextBBox( const Frame3d& frRef, BBox3d& b3Ref) const ;
|
||||
@@ -140,6 +147,7 @@ class ExtDimension : public IExtDimension, public IGeoObjRW
|
||||
mutable std::string m_sCalcText ; // testo effettivo della quota
|
||||
mutable Point3d m_ptCalcPos ; // posizione effettiva della quota
|
||||
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_ptCalcP8 ; // ottavo punto effettivo
|
||||
double m_dExtLineLen ; // lunghezza di estensione della linea
|
||||
@@ -151,3 +159,19 @@ class ExtDimension : public IExtDimension, public IGeoObjRW
|
||||
double m_dTextHeight ; // altezza del testo
|
||||
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)) ; }
|
||||
|
||||
+32
-1
@@ -161,7 +161,7 @@ ExtText::Clone( void) const
|
||||
bool
|
||||
ExtText::CopyFrom( const IGeoObj* pGObjSrc)
|
||||
{
|
||||
const ExtText* pTxt = dynamic_cast<const ExtText*>( pGObjSrc) ;
|
||||
const ExtText* pTxt = GetBasicExtText( pGObjSrc) ;
|
||||
if ( pTxt == nullptr)
|
||||
return false ;
|
||||
return CopyFrom( *pTxt) ;
|
||||
@@ -399,8 +399,11 @@ ExtText::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag) const
|
||||
bool
|
||||
ExtText::Translate( const Vector3d& vtMove)
|
||||
{
|
||||
// imposto ricalcolo della grafica
|
||||
ResetAuxSurf() ;
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
// eseguo
|
||||
m_ptP.Translate( vtMove) ;
|
||||
return true ;
|
||||
}
|
||||
@@ -409,8 +412,15 @@ ExtText::Translate( const Vector3d& vtMove)
|
||||
bool
|
||||
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() ;
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
// eseguo
|
||||
return ( m_ptP.Rotate( ptAx, vtAx, dCosAng, dSinAng) &&
|
||||
m_vtN.Rotate( vtAx, dCosAng, dSinAng) &&
|
||||
m_vtD.Rotate( vtAx, dCosAng, dSinAng)) ;
|
||||
@@ -532,9 +542,18 @@ ExtText::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d& vtD
|
||||
bool
|
||||
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
|
||||
ResetAuxSurf() ;
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
// trasformo punto e versori
|
||||
return ( m_ptP.ToGlob( frRef) &&
|
||||
m_vtN.ToGlob( frRef) &&
|
||||
@@ -545,9 +564,18 @@ ExtText::ToGlob( const Frame3d& frRef)
|
||||
bool
|
||||
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
|
||||
ResetAuxSurf() ;
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
// trasformo punto e versori
|
||||
return ( m_ptP.ToLoc( frRef) &&
|
||||
m_vtN.ToLoc( frRef) &&
|
||||
@@ -561,12 +589,15 @@ ExtText::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
|
||||
// verifico validità dei frame
|
||||
if ( frOri.GetType() == Frame3d::ERR || frDest.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
|
||||
// se i due riferimenti coincidono, non devo fare alcunché
|
||||
if ( AreSameFrame( frOri, frDest))
|
||||
return true ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
ResetAuxSurf() ;
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
// trasformo punto e versori
|
||||
return ( m_ptP.ToGlob( frOri) && m_ptP.ToLoc( frDest) &&
|
||||
m_vtN.ToGlob( frOri) && m_vtN.ToLoc( frDest) &&
|
||||
|
||||
@@ -146,3 +146,19 @@ class ExtText : public IExtText, public IGeoObjRW
|
||||
int m_nInsPos ; // posizione del punto di inserimento rispetto al testo
|
||||
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)) ; }
|
||||
|
||||
@@ -456,6 +456,9 @@ Frame3d::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
|
||||
bool
|
||||
Frame3d::Verify( void)
|
||||
{
|
||||
// verifica origine
|
||||
if ( ! m_ptOrig.IsValid())
|
||||
return false ;
|
||||
// verifica della ortogonalità dei versori e del senso destrorso
|
||||
double dOrtXY = m_vtVersX * m_vtVersY ;
|
||||
double dOrtYZ = m_vtVersY * m_vtVersZ ;
|
||||
|
||||
@@ -54,6 +54,10 @@ class GdbGeo : public GdbObj
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
inline const GdbGeo* GetGdbGeo( const GdbObj* pGObj)
|
||||
{ return dynamic_cast<const GdbGeo*>(pGObj) ; }
|
||||
{ if ( pGObj == nullptr || pGObj->GetGdbType() != GDB_TY_GEO)
|
||||
return nullptr ;
|
||||
return static_cast<const GdbGeo*>( pGObj) ; }
|
||||
inline GdbGeo* GetGdbGeo( GdbObj* pGObj)
|
||||
{ return dynamic_cast<GdbGeo*>(pGObj) ; }
|
||||
{ if ( pGObj == nullptr || pGObj->GetGdbType() != GDB_TY_GEO)
|
||||
return nullptr ;
|
||||
return static_cast<GdbGeo*>( pGObj) ; }
|
||||
|
||||
+6
-2
@@ -91,6 +91,10 @@ class GdbGroup : public GdbObj
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
inline const GdbGroup* GetGdbGroup( const GdbObj* pGObj)
|
||||
{ return dynamic_cast<const GdbGroup*>(pGObj) ; }
|
||||
{ if ( pGObj == nullptr || pGObj->GetGdbType() != GDB_TY_GROUP)
|
||||
return nullptr ;
|
||||
return static_cast<const GdbGroup*>( pGObj) ; }
|
||||
inline GdbGroup* GetGdbGroup( GdbObj* pGObj)
|
||||
{ return dynamic_cast<GdbGroup*>(pGObj) ; }
|
||||
{ if ( pGObj == nullptr || pGObj->GetGdbType() != GDB_TY_GROUP)
|
||||
return nullptr ;
|
||||
return static_cast<GdbGroup*>( pGObj) ; }
|
||||
|
||||
+32
-9
@@ -24,7 +24,7 @@ using namespace std ;
|
||||
IGdbIterator*
|
||||
CreateGdbIterator( IGeomDB* pGDB)
|
||||
{
|
||||
if ( dynamic_cast<GeomDB*>( pGDB) == nullptr)
|
||||
if ( static_cast<GeomDB*>( pGDB) == nullptr)
|
||||
return nullptr ;
|
||||
return static_cast<IGdbIterator*> ( new( nothrow) GdbIterator( pGDB)) ;
|
||||
}
|
||||
@@ -53,7 +53,7 @@ GdbIterator::~GdbIterator( void)
|
||||
bool
|
||||
GdbIterator::SetGDB( IGeomDB* pGDB)
|
||||
{
|
||||
m_pGDB = dynamic_cast<GeomDB*>( pGDB) ;
|
||||
m_pGDB = static_cast<GeomDB*>( pGDB) ;
|
||||
if ( m_pGDB == nullptr)
|
||||
return false ;
|
||||
|
||||
@@ -105,7 +105,7 @@ GdbIterator::GoToFirstInGroup( const IGdbIterator& iIter)
|
||||
return false ;
|
||||
}
|
||||
|
||||
const GdbIterator* pIter = dynamic_cast<const GdbIterator*> (&iIter) ;
|
||||
const GdbIterator* pIter = static_cast<const GdbIterator*> (&iIter) ;
|
||||
if ( pIter == nullptr || pIter->m_pGDB != m_pGDB) {
|
||||
m_pCurrObj = nullptr ;
|
||||
return false ;
|
||||
@@ -167,7 +167,7 @@ GdbIterator::GoToLastInGroup( const IGdbIterator& iIter)
|
||||
return false ;
|
||||
}
|
||||
|
||||
const GdbIterator* pIter = dynamic_cast<const GdbIterator*> (&iIter) ;
|
||||
const GdbIterator* pIter = static_cast<const GdbIterator*> (&iIter) ;
|
||||
if ( pIter == nullptr || pIter->m_pGDB != m_pGDB) {
|
||||
m_pCurrObj = nullptr ;
|
||||
return false ;
|
||||
@@ -263,7 +263,7 @@ GdbIterator::GoToFirstNameInGroup( const IGdbIterator& iIter, const string& sNam
|
||||
return false ;
|
||||
}
|
||||
// converto in oggetto iteratore di base
|
||||
const GdbIterator* pIter = dynamic_cast<const GdbIterator*> (&iIter) ;
|
||||
const GdbIterator* pIter = static_cast<const GdbIterator*> (&iIter) ;
|
||||
if ( pIter == nullptr || pIter->m_pGDB != m_pGDB) {
|
||||
m_pCurrObj = nullptr ;
|
||||
return false ;
|
||||
@@ -345,7 +345,7 @@ GdbIterator::GoToLastNameInGroup( const IGdbIterator& iIter, const string& sName
|
||||
return false ;
|
||||
}
|
||||
// converto in oggetto iteratore di base
|
||||
const GdbIterator* pIter = dynamic_cast<const GdbIterator*> (&iIter) ;
|
||||
const GdbIterator* pIter = static_cast<const GdbIterator*> (&iIter) ;
|
||||
if ( pIter == nullptr || pIter->m_pGDB != m_pGDB) {
|
||||
m_pCurrObj = nullptr ;
|
||||
return false ;
|
||||
@@ -474,7 +474,7 @@ GdbIterator::GoToFirstGroupInGroup( const IGdbIterator& iIter)
|
||||
return false ;
|
||||
}
|
||||
// converto in oggetto iteratore di base
|
||||
const GdbIterator* pIter = dynamic_cast<const GdbIterator*> (&iIter) ;
|
||||
const GdbIterator* pIter = static_cast<const GdbIterator*> (&iIter) ;
|
||||
if ( pIter == nullptr || pIter->m_pGDB != m_pGDB) {
|
||||
m_pCurrObj = nullptr ;
|
||||
return false ;
|
||||
@@ -553,7 +553,7 @@ GdbIterator::GoToLastGroupInGroup( const IGdbIterator& iIter)
|
||||
return false ;
|
||||
}
|
||||
// converto in oggetto iteratore di base
|
||||
const GdbIterator* pIter = dynamic_cast<const GdbIterator*> (&iIter) ;
|
||||
const GdbIterator* pIter = static_cast<const GdbIterator*> (&iIter) ;
|
||||
if ( pIter == nullptr || pIter->m_pGDB != m_pGDB) {
|
||||
m_pCurrObj = nullptr ;
|
||||
return false ;
|
||||
@@ -1637,7 +1637,7 @@ GdbIterator::CopyAllInfoFrom( const IGdbIterator& iIter)
|
||||
return false ;
|
||||
|
||||
// recupero l'oggetto sorgente
|
||||
const GdbIterator* pIter = dynamic_cast<const GdbIterator*> (&iIter) ;
|
||||
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 ;
|
||||
@@ -1651,6 +1651,29 @@ GdbIterator::CopyAllInfoFrom( const IGdbIterator& iIter)
|
||||
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
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
+5
-2
@@ -1,7 +1,7 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2013-2022
|
||||
// EgalTech 2013-2023
|
||||
//----------------------------------------------------------------------------
|
||||
// File : GdbIterator.h Data : 29.01.23 Versione : 2.5a2
|
||||
// File : GdbIterator.h Data : 09.07.23 Versione : 2.5g1
|
||||
// Contenuto : Dichiarazione della classe GdbIterator.
|
||||
//
|
||||
//
|
||||
@@ -144,6 +144,9 @@ class GdbIterator : public IGdbIterator
|
||||
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
|
||||
bool SetTextureName( const std::string& sTxrName) override ;
|
||||
bool SetTextureFrame( const Frame3d& frTxrRef) override ;
|
||||
|
||||
+29
-3
@@ -31,10 +31,9 @@ using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
GdbObj::GdbObj( void)
|
||||
: m_nId( GDB_ID_NULL), m_pAttribs( nullptr), m_pTxrData( nullptr), m_pUserObj( nullptr),
|
||||
m_pGDB( nullptr), m_pNext( nullptr), m_pPrev( nullptr), m_pParent( nullptr),
|
||||
: m_nId( GDB_ID_NULL), m_pAttribs( nullptr), m_nStpFactor( 0), m_nStpPattern( 0), m_pTxrData( nullptr),
|
||||
m_pUserObj( nullptr), m_pGDB( nullptr), m_pNext( nullptr), m_pPrev( nullptr), m_pParent( nullptr),
|
||||
m_pSelNext( nullptr), m_pSelPrev( nullptr)
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
@@ -73,6 +72,9 @@ GdbObj::CopyFrom( const GdbObj* pSou)
|
||||
if ( m_pAttribs != nullptr)
|
||||
delete m_pAttribs ;
|
||||
m_pAttribs = nullptr ;
|
||||
// reset stipple
|
||||
m_nStpFactor = 0 ;
|
||||
m_nStpPattern = 0 ;
|
||||
// elimino eventuali dati della texture pre-esistenti
|
||||
if ( m_pTxrData != nullptr)
|
||||
delete m_pTxrData ;
|
||||
@@ -91,6 +93,10 @@ GdbObj::CopyFrom( const GdbObj* pSou)
|
||||
// copio Id
|
||||
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
|
||||
return ( CopyAttribsFrom( pSou) && CopyTextureDataFrom( pSou) && CopyUserObjFrom( pSou)) ;
|
||||
}
|
||||
@@ -1037,6 +1043,26 @@ GdbObj::GetAllInfo( STRVECTOR& vsInfo) const
|
||||
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
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
@@ -120,6 +120,8 @@ class GdbObj
|
||||
bool ExistsInfo( const std::string& sKey) const ;
|
||||
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 LoadTextureData( NgeReader& ngeIn) ;
|
||||
TextureData* GetTextureData( void)
|
||||
@@ -161,6 +163,8 @@ class GdbObj
|
||||
public :
|
||||
int m_nId ;
|
||||
Attribs* m_pAttribs ;
|
||||
int m_nStpFactor ;
|
||||
int m_nStpPattern ;
|
||||
TextureData* m_pTxrData ;
|
||||
IUserObj* m_pUserObj ;
|
||||
|
||||
|
||||
+1
-1
@@ -104,7 +104,7 @@ GeoFrame3d::Clone( void) const
|
||||
bool
|
||||
GeoFrame3d::CopyFrom( const IGeoObj* pGObjSrc)
|
||||
{
|
||||
const GeoFrame3d* pGFr = dynamic_cast<const GeoFrame3d*>( pGObjSrc) ;
|
||||
const GeoFrame3d* pGFr = GetBasicGeoFrame3d( pGObjSrc) ;
|
||||
if ( pGFr == nullptr)
|
||||
return false ;
|
||||
return CopyFrom( *pGFr) ;
|
||||
|
||||
@@ -98,3 +98,19 @@ class GeoFrame3d : public IGeoFrame3d, public IGeoObjRW
|
||||
Frame3d m_frF ; // oggetto
|
||||
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
@@ -72,7 +72,7 @@ GeoPoint3d::Clone( void) const
|
||||
bool
|
||||
GeoPoint3d::CopyFrom( const IGeoObj* pGObjSrc)
|
||||
{
|
||||
const GeoPoint3d* pGP = dynamic_cast<const GeoPoint3d*>( pGObjSrc) ;
|
||||
const GeoPoint3d* pGP = GetBasicGeoPoint3d( pGObjSrc) ;
|
||||
if ( pGP == nullptr)
|
||||
return false ;
|
||||
return CopyFrom( *pGP) ;
|
||||
|
||||
@@ -92,3 +92,19 @@ class GeoPoint3d : public IGeoPoint3d, public IGeoObjRW
|
||||
Point3d m_ptP ; // oggetto
|
||||
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
@@ -88,7 +88,7 @@ GeoVector3d::Clone( void) const
|
||||
bool
|
||||
GeoVector3d::CopyFrom( const IGeoObj* pGObjSrc)
|
||||
{
|
||||
const GeoVector3d* pGV = dynamic_cast<const GeoVector3d*>( pGObjSrc) ;
|
||||
const GeoVector3d* pGV = GetBasicGeoVector3d( pGObjSrc) ;
|
||||
if ( pGV == nullptr)
|
||||
return false ;
|
||||
return CopyFrom( *pGV) ;
|
||||
|
||||
@@ -107,3 +107,19 @@ class GeoVector3d : public IGeoVector3d, public IGeoObjRW
|
||||
Point3d m_ptBase ; // punto base da cui tracciare il vettore
|
||||
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)) ; }
|
||||
|
||||
+173
-60
@@ -1,7 +1,7 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2013-2013
|
||||
// EgalTech 2013-2023
|
||||
//----------------------------------------------------------------------------
|
||||
// File : GeomDB.cpp Data : 08.04.13 Versione : 1.3a5
|
||||
// File : GeomDB.cpp Data : 29.05.23 Versione : 2.5e5
|
||||
// Contenuto : Implementazione della classe GeomDB.
|
||||
//
|
||||
//
|
||||
@@ -21,38 +21,63 @@
|
||||
#include "NgeReader.h"
|
||||
#include "NgeWriter.h"
|
||||
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
||||
#include "/EgtDev/Include/SELkLockId.h"
|
||||
#include "/EgtDev/Include/SELkKeyProc.h"
|
||||
#include "/EgtDev/Include/EGnGetKeyData.h"
|
||||
#include "/EgtDev/Include/EgtStringConverter.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
#include "/EgtDev/Include/EgtNumCollection.h"
|
||||
#include "/EgtDev/Include/EgtKeyCodes.h"
|
||||
#include "/EgtDev/Include/SELkLockId.h"
|
||||
#include "/EgtDev/Include/SELkKeyProc.h"
|
||||
#include <new>
|
||||
#include <stack>
|
||||
#include <thread>
|
||||
|
||||
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*
|
||||
CreateGeomDB( void)
|
||||
{
|
||||
// verifico la chiave e le opzioni
|
||||
if ( ! GetEGkNetHwKey()) {
|
||||
unsigned int nOpt1, nOpt2 ;
|
||||
int nOptExpDays ;
|
||||
int nRet = GetKeyOptions( GetEGkKey(), KEY_BASELIB_PROD, KEY_BASELIB_VER, KEY_BASELIB_LEV,
|
||||
unsigned int nOpt1, nOpt2 ;
|
||||
int nOptExpDays ;
|
||||
int nRet = GetEGnKeyOptions( KEY_BASELIB_PROD, KEY_BASELIB_VER, KEY_BASELIB_LEV,
|
||||
nOpt1, nOpt2, nOptExpDays) ;
|
||||
if ( nRet != KEY_OK && ! EqualNoCase( GetEGkKey(), "EGkBase")) {
|
||||
if ( nRet != KEY_OK) {
|
||||
string sErr = "Error on Key (GKC/" + ToString( nRet) + ")" ;
|
||||
LOG_ERROR( GetEGkLogger(), sErr.c_str()) ;
|
||||
return nullptr ;
|
||||
}
|
||||
if ( (nOpt1 & KEYOPT_EGK_BASE) == 0 || nOptExpDays < GetCurrDay()) {
|
||||
string sErr = "Error on Key (GKC/OPT)" ;
|
||||
LOG_ERROR( GetEGkLogger(), sErr.c_str()) ;
|
||||
return nullptr ;
|
||||
}
|
||||
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) {
|
||||
string sErr = "Error on Key (GKC/" + ToString( nRet) + ")" ;
|
||||
LOG_ERROR( GetEGkLogger(), sErr.c_str()) ;
|
||||
return nullptr ;
|
||||
}
|
||||
if ( ( nOpt1 & KEYOPT_EGK_BASE) == 0 || nOptExpDays < GetCurrDay()) {
|
||||
string sErr = "Error on Key (GKC/OPT)" ;
|
||||
LOG_ERROR( GetEGkLogger(), sErr.c_str()) ;
|
||||
return nullptr ;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,6 +90,7 @@ CreateGeomDB( void)
|
||||
//----------------------------------------------------------------------------
|
||||
GeomDB::GeomDB( void)
|
||||
{
|
||||
m_bAddEraseOn.clear() ;
|
||||
m_GrpRadix.SetGeomDB( this) ;
|
||||
m_GrpRadix.m_nId = GDB_ID_ROOT ;
|
||||
m_GrpRadix.SetMaterial( Color()) ;
|
||||
@@ -275,21 +301,23 @@ bool
|
||||
GeomDB::Save( int nId, const string& sFileOut, int nFlag) const
|
||||
{
|
||||
// verifico la chiave e le opzioni
|
||||
if ( ! GetEGkNetHwKey()) {
|
||||
unsigned int nOpt1, nOpt2 ;
|
||||
int nOptExpDays ;
|
||||
int nRet = GetKeyOptions( GetEGkKey(), KEY_BASELIB_PROD, KEY_BASELIB_VER, KEY_BASELIB_LEV,
|
||||
unsigned int nOpt1, nOpt2 ;
|
||||
int nOptExpDays ;
|
||||
int nRet = GetEGnKeyOptions( KEY_BASELIB_PROD, KEY_BASELIB_VER, KEY_BASELIB_LEV,
|
||||
nOpt1, nOpt2, nOptExpDays) ;
|
||||
if ( nRet != KEY_OK) {
|
||||
string sErr = "Error on Key (GKS/" + ToString( nRet) + ")" ;
|
||||
LOG_ERROR( GetEGkLogger(), sErr.c_str()) ;
|
||||
return false ;
|
||||
}
|
||||
if ( (nOpt1 & KEYOPT_EGK_SAVE) == 0 || nOptExpDays < GetCurrDay()) {
|
||||
string sErr = "Error on Key (GKS/OPT)" ;
|
||||
LOG_ERROR( GetEGkLogger(), sErr.c_str()) ;
|
||||
return false ;
|
||||
}
|
||||
if ( ! GetEGkNetHwKey())
|
||||
nRet = GetKeyOptions( GetEGkKey(), KEY_BASELIB_PROD, KEY_BASELIB_VER, KEY_BASELIB_LEV,
|
||||
nOpt1, nOpt2, nOptExpDays) ;
|
||||
// controllo i risultati
|
||||
if ( nRet != KEY_OK) {
|
||||
string sErr = "Error on Key (GKS/" + ToString( nRet) + ")" ;
|
||||
LOG_ERROR( GetEGkLogger(), sErr.c_str()) ;
|
||||
return false ;
|
||||
}
|
||||
if ( ( nOpt1 & KEYOPT_EGK_SAVE) == 0 || nOptExpDays < GetCurrDay()) {
|
||||
string sErr = "Error on Key (GKS/OPT)" ;
|
||||
LOG_ERROR( GetEGkLogger(), sErr.c_str()) ;
|
||||
return false ;
|
||||
}
|
||||
|
||||
// assegno Id base
|
||||
@@ -387,21 +415,23 @@ bool
|
||||
GeomDB::Save( const INTVECTOR& vId, const string& sFileOut, int nFlag) const
|
||||
{
|
||||
// verifico la chiave e le opzioni
|
||||
if ( ! GetEGkNetHwKey()) {
|
||||
unsigned int nOpt1, nOpt2 ;
|
||||
int nOptExpDays ;
|
||||
int nRet = GetKeyOptions( GetEGkKey(), KEY_BASELIB_PROD, KEY_BASELIB_VER, KEY_BASELIB_LEV,
|
||||
unsigned int nOpt1, nOpt2 ;
|
||||
int nOptExpDays ;
|
||||
int nRet = GetEGnKeyOptions( KEY_BASELIB_PROD, KEY_BASELIB_VER, KEY_BASELIB_LEV,
|
||||
nOpt1, nOpt2, nOptExpDays) ;
|
||||
if ( nRet != KEY_OK) {
|
||||
string sErr = "Error on Key (GKS/" + ToString( nRet) + ")" ;
|
||||
LOG_ERROR( GetEGkLogger(), sErr.c_str()) ;
|
||||
return false ;
|
||||
}
|
||||
if ( (nOpt1 & KEYOPT_EGK_SAVE) == 0 || nOptExpDays < GetCurrDay()) {
|
||||
string sErr = "Error on Key (GKS/OPT)" ;
|
||||
LOG_ERROR( GetEGkLogger(), sErr.c_str()) ;
|
||||
return false ;
|
||||
}
|
||||
if ( ! GetEGkNetHwKey())
|
||||
nRet = GetKeyOptions( GetEGkKey(), KEY_BASELIB_PROD, KEY_BASELIB_VER, KEY_BASELIB_LEV,
|
||||
nOpt1, nOpt2, nOptExpDays) ;
|
||||
// controllo i risultati
|
||||
if ( nRet != KEY_OK) {
|
||||
string sErr = "Error on Key (GKS/" + ToString( nRet) + ")" ;
|
||||
LOG_ERROR( GetEGkLogger(), sErr.c_str()) ;
|
||||
return false ;
|
||||
}
|
||||
if ( ( nOpt1 & KEYOPT_EGK_SAVE) == 0 || nOptExpDays < GetCurrDay()) {
|
||||
string sErr = "Error on Key (GKS/OPT)" ;
|
||||
LOG_ERROR( GetEGkLogger(), sErr.c_str()) ;
|
||||
return false ;
|
||||
}
|
||||
|
||||
// assegno Id base (nessuna riduzione degli Id)
|
||||
@@ -423,7 +453,7 @@ GeomDB::Save( const INTVECTOR& vId, const string& sFileOut, int nFlag) const
|
||||
return false ;
|
||||
|
||||
// ciclo sugli oggetti da esportare
|
||||
unordered_set<int> usSavedId ;
|
||||
INTUNORDSET usSavedId ;
|
||||
for ( const auto nId : vId) {
|
||||
|
||||
// se già salvato, passo oltre
|
||||
@@ -588,25 +618,32 @@ GeomDB::GetGdbObj( int nId) const
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
GeomDB::InsertInGeomDB( GdbObj* pGObj, int nRefId, int nSonBeforeAfter, bool bTestId)
|
||||
GeomDB::InsertInGeomDB( GdbObj* pGObj, int nRefId, int nSonBeforeAfter, bool bLockAddErase, bool bTestId)
|
||||
{
|
||||
// verifico validità oggetto puntato
|
||||
if ( pGObj == nullptr)
|
||||
return false ;
|
||||
|
||||
// se richiesta, verifica validità e unicità del nome
|
||||
if ( bTestId && ( pGObj->m_nId <= GDB_ID_ROOT || ExistsObj( pGObj->m_nId)))
|
||||
// verifico validità del riferimento
|
||||
if ( nRefId < GDB_ID_ROOT)
|
||||
return false ;
|
||||
|
||||
// oggetto e riferimento non possono essere la stessa cosa
|
||||
if ( pGObj->m_nId == nRefId)
|
||||
return ( ! IS_GDB_SON( nSonBeforeAfter)) ;
|
||||
|
||||
// verifico unicità esecuzione, se necessaria
|
||||
LockAddErase Lock( m_bAddEraseOn, bLockAddErase) ;
|
||||
|
||||
// cerco il riferimento
|
||||
GdbObj* pGRef = GetGdbObj( nRefId) ;
|
||||
if ( pGRef == nullptr)
|
||||
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
|
||||
pGObj->SetGeomDB( this) ;
|
||||
|
||||
@@ -622,7 +659,7 @@ GeomDB::InsertInGeomDB( GdbObj* pGObj, int nRefId, int nSonBeforeAfter, bool bTe
|
||||
}
|
||||
// inserisco come figlio, in testa alla lista del padre
|
||||
else if ( nSonBeforeAfter == GDB_FIRST_SON){
|
||||
GdbGroup* pGroup = dynamic_cast<GdbGroup*> ( pGRef) ;
|
||||
GdbGroup* pGroup = ::GetGdbGroup( pGRef) ;
|
||||
if ( pGroup == nullptr)
|
||||
return false ;
|
||||
// inserisco in testa alla lista del padre
|
||||
@@ -631,7 +668,7 @@ GeomDB::InsertInGeomDB( GdbObj* pGObj, int nRefId, int nSonBeforeAfter, bool bTe
|
||||
}
|
||||
// inserisco come figlio, in coda alla lista del padre
|
||||
else {
|
||||
GdbGroup* pGroup = dynamic_cast<GdbGroup*> ( pGRef) ;
|
||||
GdbGroup* pGroup = ::GetGdbGroup( pGRef) ;
|
||||
if ( pGroup == nullptr)
|
||||
return false ;
|
||||
// inserisco in coda alla lista del padre
|
||||
@@ -660,6 +697,8 @@ GeomDB::InsertGroup( int nId, int nRefId, int nSonBeforeAfter, const Frame3d& fr
|
||||
// verifico validità apparente RefId
|
||||
if ( nRefId < GDB_ID_ROOT)
|
||||
return GDB_ID_NULL ;
|
||||
// verifico unicità esecuzione
|
||||
LockAddErase Lock( m_bAddEraseOn) ;
|
||||
// verifico validità Id
|
||||
if ( nId <= GDB_ID_ROOT)
|
||||
nId = m_IdManager.GetNewId() ;
|
||||
@@ -674,7 +713,7 @@ GeomDB::InsertGroup( int nId, int nRefId, int nSonBeforeAfter, const Frame3d& fr
|
||||
// assegno riferimento
|
||||
pGdbGroup->SetFrame( frFrame) ;
|
||||
// inserisco nel DB
|
||||
if ( ! InsertInGeomDB( pGdbGroup, nRefId, nSonBeforeAfter)) {
|
||||
if ( ! InsertInGeomDB( pGdbGroup, nRefId, nSonBeforeAfter, false)) {
|
||||
delete pGdbGroup ;
|
||||
return GDB_ID_NULL ;
|
||||
}
|
||||
@@ -695,6 +734,8 @@ GeomDB::InsertGeoObj( int nId, int nRefId, int nSonBeforeAfter, IGeoObj* pGeoObj
|
||||
{
|
||||
// assegno GeoObj a gestore puntatore con rilascio automatico
|
||||
PtrOwner<IGeoObj> pRPGeoObj( pGeoObj) ;
|
||||
// verifico unicità esecuzione
|
||||
LockAddErase Lock( m_bAddEraseOn) ;
|
||||
// verifico validità identificativo
|
||||
if ( nId <= GDB_ID_ROOT)
|
||||
nId = m_IdManager.GetNewId() ;
|
||||
@@ -712,7 +753,7 @@ GeomDB::InsertGeoObj( int nId, int nRefId, int nSonBeforeAfter, IGeoObj* pGeoObj
|
||||
// assegno dati
|
||||
pGdbGeo->m_pGeoObj = Release( pRPGeoObj) ;
|
||||
// inserisco nel DB
|
||||
if ( ! InsertInGeomDB( pGdbGeo, nRefId, nSonBeforeAfter)) {
|
||||
if ( ! InsertInGeomDB( pGdbGeo, nRefId, nSonBeforeAfter, false)) {
|
||||
delete pGdbGeo ;
|
||||
return GDB_ID_NULL ;
|
||||
}
|
||||
@@ -1195,6 +1236,9 @@ GeomDB::GetRefBBox( int nId, const Frame3d& frRef, BBox3d& b3Ref, int nFlag) con
|
||||
int
|
||||
GeomDB::Copy( int nIdSou, int nIdDest, int nRefId, int nSonBeforeAfter, bool bGlob)
|
||||
{
|
||||
// verifico unicità esecuzione
|
||||
LockAddErase Lock( m_bAddEraseOn) ;
|
||||
|
||||
// verifico Id destinazione
|
||||
if ( nIdDest <= GDB_ID_ROOT)
|
||||
nIdDest = m_IdManager.GetNewId() ;
|
||||
@@ -1237,7 +1281,7 @@ GeomDB::Copy( int nIdSou, int nIdDest, int nRefId, int nSonBeforeAfter, bool bGl
|
||||
}
|
||||
|
||||
// inserisco nel DB (non rilascio il puntatore)
|
||||
if ( ! InsertInGeomDB( pGdODest, nRefId, nSonBeforeAfter))
|
||||
if ( ! InsertInGeomDB( pGdODest, nRefId, nSonBeforeAfter, false))
|
||||
return GDB_ID_NULL ;
|
||||
|
||||
// rilascio il puntatore
|
||||
@@ -1249,10 +1293,17 @@ GeomDB::Copy( int nIdSou, int nIdDest, int nRefId, int nSonBeforeAfter, bool bGl
|
||||
bool
|
||||
GeomDB::Relocate( int nId, int nRefId, int nSonBeforeAfter, bool bGlob)
|
||||
{
|
||||
// l'oggetto e il riferimento non possono coincidere
|
||||
// verifico validità del riferimento
|
||||
if ( nRefId < GDB_ID_ROOT)
|
||||
return false ;
|
||||
|
||||
// l'oggetto e il riferimento non possono coincidere
|
||||
if ( nId == nRefId)
|
||||
return ( ! IS_GDB_SON( nSonBeforeAfter)) ;
|
||||
|
||||
// verifico unicità esecuzione
|
||||
LockAddErase Lock( m_bAddEraseOn) ;
|
||||
|
||||
// verifico esistenza dell'oggetto
|
||||
GdbObj* pGdbObj = GetGdbObj( nId) ;
|
||||
if ( pGdbObj == nullptr)
|
||||
@@ -1296,7 +1347,7 @@ GeomDB::Relocate( int nId, int nRefId, int nSonBeforeAfter, bool bGlob)
|
||||
pGdbObj->Remove() ;
|
||||
|
||||
// lo inserisco nella posizione opportuna
|
||||
if ( ! InsertInGeomDB( pGdbObj, nRefId, nSonBeforeAfter, false)) {
|
||||
if ( ! InsertInGeomDB( pGdbObj, nRefId, nSonBeforeAfter, false, false)) {
|
||||
// in caso di errore (condizione assai remota qui) cancello tutto
|
||||
m_IdManager.RemoveObj( pGdbObj->m_nId) ;
|
||||
m_SelManager.RemoveObj( pGdbObj) ;
|
||||
@@ -1377,9 +1428,14 @@ GeomDB::GetNewId( void) const
|
||||
bool
|
||||
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é
|
||||
if ( nNewId == nId)
|
||||
return true ;
|
||||
// verifico unicità esecuzione
|
||||
LockAddErase Lock( m_bAddEraseOn) ;
|
||||
// verifico nuovo Id
|
||||
if ( ExistsObj( nNewId))
|
||||
return false ;
|
||||
@@ -1420,7 +1476,10 @@ GeomDB::Erase( GdbObj* pGdbObj)
|
||||
if ( pGdbObj == nullptr || pGdbObj == &m_GrpRadix)
|
||||
return false ;
|
||||
|
||||
// notifico eventuale UserObj
|
||||
// verifico unicità esecuzione
|
||||
LockAddErase Lock( m_bAddEraseOn) ;
|
||||
|
||||
// notifico eventuale UserObj
|
||||
if ( pGdbObj->m_pUserObj != nullptr) {
|
||||
// recupero il successivo
|
||||
const GdbObj* pGdbNext = pGdbObj->GetNext() ;
|
||||
@@ -1445,6 +1504,10 @@ GeomDB::RemoveGeoObjAndErase( int nId)
|
||||
// non si può cancellare il gruppo radice (escludo anche Id non validi)
|
||||
if ( nId <= GDB_ID_ROOT)
|
||||
return nullptr ;
|
||||
|
||||
// verifico unicità esecuzione
|
||||
LockAddErase Lock( m_bAddEraseOn) ;
|
||||
|
||||
// recupero l'oggetto geometrico
|
||||
GdbGeo* pGdbGeo = ::GetGdbGeo( m_IdManager.FindObj( nId)) ;
|
||||
if ( pGdbGeo == nullptr)
|
||||
@@ -1452,6 +1515,7 @@ GeomDB::RemoveGeoObjAndErase( int nId)
|
||||
IGeoObj* pGeoObj = pGdbGeo->m_pGeoObj ;
|
||||
// annullo il riferimento alla geometria nell'entità
|
||||
pGdbGeo->m_pGeoObj = nullptr ;
|
||||
|
||||
// tolgo dalla lista e disalloco
|
||||
pGdbGeo->Remove() ;
|
||||
delete pGdbGeo ;
|
||||
@@ -1487,6 +1551,10 @@ GeomDB::EmptyGroup( GdbObj* pGdbObj)
|
||||
GdbGroup* pGrp = ::GetGdbGroup( pGdbObj) ;
|
||||
if ( pGrp == nullptr)
|
||||
return false ;
|
||||
|
||||
// verifico unicità esecuzione
|
||||
LockAddErase Lock( m_bAddEraseOn) ;
|
||||
|
||||
// lo svuoto
|
||||
return pGrp->Clear() ;
|
||||
}
|
||||
@@ -2922,6 +2990,51 @@ GeomDB::CopyAllInfoFrom( int nId, int nSouId)
|
||||
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
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -2933,7 +3046,7 @@ GeomDB::DumpTextureData( int nId, string& sOut, bool bMM, const char* szNewLine)
|
||||
if ( pGdbObj == nullptr)
|
||||
return false ;
|
||||
// eseguo il dump
|
||||
if ( pGdbObj->m_pTxrData != nullptr)
|
||||
if ( pGdbObj->m_pTxrData != nullptr)
|
||||
return pGdbObj->m_pTxrData->Dump( *this, sOut, bMM, szNewLine) ;
|
||||
else
|
||||
return true ;
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2013-2014
|
||||
// EgalTech 2013-2023
|
||||
//----------------------------------------------------------------------------
|
||||
// File : GeomDB.h Data : 03.12.14 Versione : 1.5l1
|
||||
// File : GeomDB.h Data : 09.07.23 Versione : 2.5g1
|
||||
// Contenuto : Dichiarazione della classe GeomDB.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 22.01.13 DS Creazione modulo.
|
||||
// 03.12.14 DS Aggiunta gestione riferimento di griglia.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "SelManager.h"
|
||||
#include "GdbMaterialMgr.h"
|
||||
#include "/EgtDev/Include/EGkGeomDB.h"
|
||||
#include <atomic>
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
class GeomDB : public IGeomDB
|
||||
@@ -181,6 +182,10 @@ class GeomDB : public IGeomDB
|
||||
bool RemoveInfo( int nId, const std::string& sKey) override ;
|
||||
bool GetAllInfo( int nId, STRVECTOR& vsInfo) const 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
|
||||
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 ;
|
||||
@@ -222,14 +227,14 @@ class GeomDB : public IGeomDB
|
||||
GdbObj* GetGdbObj( int nId) ;
|
||||
const GdbObj* GetGdbObj( int nId) const ;
|
||||
GdbGeo* GetGdbGeo( int nId)
|
||||
{ return dynamic_cast<GdbGeo*>( GetGdbObj( nId)) ; }
|
||||
{ return ::GetGdbGeo( GetGdbObj( nId)) ; }
|
||||
const GdbGeo* GetGdbGeo( int nId) const
|
||||
{ return dynamic_cast<const GdbGeo*>( GetGdbObj( nId)) ; }
|
||||
{ return ::GetGdbGeo( GetGdbObj( nId)) ; }
|
||||
GdbGroup* GetGdbGroup( int nId)
|
||||
{ return dynamic_cast<GdbGroup*>( GetGdbObj( nId)) ; }
|
||||
{ return ::GetGdbGroup( GetGdbObj( nId)) ; }
|
||||
const GdbGroup* GetGdbGroup( int nId) const
|
||||
{ return dynamic_cast<const GdbGroup*>( GetGdbObj( nId)) ; }
|
||||
bool InsertInGeomDB( GdbObj* pGObj, int nRefId, int nSonBeforeAfter, bool bTestId = true) ;
|
||||
{ return ::GetGdbGroup( GetGdbObj( nId)) ; }
|
||||
bool InsertInGeomDB( GdbObj* pGObj, int nRefId, int nSonBeforeAfter, bool bLockAddErase = true, bool bTestId = true) ;
|
||||
int Copy( int nIdSou, int nIdDest, int nRefId, int nSonBeforeAfter, bool bGlob) ;
|
||||
bool Relocate( int nId, int nRefId, int nSonBeforeAfter, bool bGlob) ;
|
||||
bool Erase( GdbObj* pGObj) ;
|
||||
@@ -253,10 +258,11 @@ class GeomDB : public IGeomDB
|
||||
{ return m_IterManager.RemoveGdbIterator( pIter) ; }
|
||||
|
||||
private :
|
||||
IdManager m_IdManager ; // gestore del nuovo Id
|
||||
IterManager m_IterManager ; // gestore lista iteratori attivi
|
||||
SelManager m_SelManager ; // gestore lista oggetti selezionati
|
||||
GdbMaterialMgr m_MatManager ; // gestore lista materiali
|
||||
GdbGroup m_GrpRadix ; // gruppo radice di tutto il DB
|
||||
Frame3d m_GridFrame ; // riferimento della griglia
|
||||
IdManager m_IdManager ; // gestore del nuovo Id
|
||||
IterManager m_IterManager ; // gestore lista iteratori attivi
|
||||
SelManager m_SelManager ; // gestore lista oggetti selezionati
|
||||
GdbMaterialMgr m_MatManager ; // gestore lista materiali
|
||||
GdbGroup m_GrpRadix ; // gruppo radice di tutto il DB
|
||||
Frame3d m_GridFrame ; // riferimento della griglia
|
||||
std::atomic_flag m_bAddEraseOn ; // flag esecuzione inserimento o cancellazione in corso (per multi thread)
|
||||
} ;
|
||||
|
||||
@@ -659,11 +659,8 @@ IntersCurveCurve::CalcCurveInOrOut( const ICurve* pCurveA, const ICurve* pCurveB
|
||||
bool
|
||||
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 ;
|
||||
if ( ! PL.GetAreaXY( dArea))
|
||||
if ( ! pCurve->GetAreaXY( dArea))
|
||||
return false ;
|
||||
nClass = (( dArea > 0) ? CRVC_OUT : CRVC_IN) ;
|
||||
return true ;
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// 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 ;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// 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) ;
|
||||
@@ -0,0 +1,138 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// 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 ;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// 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) ;
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// 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) ;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// 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
@@ -66,7 +66,7 @@ IntersLineLine::IntersInfiniteLines( const ICurveLine& Line1, const ICurveLine&
|
||||
double dLen1XY = vtDir1.LenXY() ;
|
||||
if ( dLen1XY < EPS_SMALL)
|
||||
return ;
|
||||
// linea 2 : Start, Direzione e Lunghezza
|
||||
// linea 2 : Start, End, Direzione e Lunghezza
|
||||
Point3d ptS2 = Line2.GetStart() ;
|
||||
Point3d ptE2 = Line2.GetEnd() ;
|
||||
Vector3d vtDir2 = ptE2 - ptS2 ;
|
||||
|
||||
+13
-8
@@ -26,20 +26,25 @@ IntersLineSphere( const Point3d& ptL, const Vector3d& vtL, const Point3d& ptCen,
|
||||
return ILST_NO ;
|
||||
// Proiezione del centro della sfera sulla linea
|
||||
Point3d ptP = ptL + (( ptCen - ptL) * vtL) * vtL ;
|
||||
// Distanza di questo punto di proiezione dal centro della sfera
|
||||
double dDist = Dist( ptCen, ptP) ;
|
||||
// Quadrato della distanza di questo punto di proiezione dal centro della sfera
|
||||
double dSqDist = SqDist( 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
|
||||
if ( abs( dDist - dRad) < EPS_SMALL) {
|
||||
if ( dSqDelta < EPS_SMALL * EPS_SMALL) {
|
||||
ptI1 = ptP ;
|
||||
ptI2 = ptP ;
|
||||
return ILST_TG ;
|
||||
}
|
||||
// Se distanza superiore al raggio, nessuna intersezione
|
||||
if ( dDist > dRad)
|
||||
return ILST_NO ;
|
||||
|
||||
// Distanza inferiore al raggio, due intersezioni secanti
|
||||
double dDist2 = sqrt( dRad * dRad - dDist * dDist) ;
|
||||
double dDist2 = sqrt( dSqDelta) ;
|
||||
ptI1 = ptP - dDist2 * vtL ;
|
||||
ptI2 = ptP + dDist2 * vtL ;
|
||||
return ILST_SEC ;
|
||||
}
|
||||
}
|
||||
|
||||
+10
-8
@@ -800,7 +800,7 @@ IntersLineCylinder( const Point3d& ptPLine, const Vector3d& vtVLine,
|
||||
|
||||
// Parte della retta appartenente al cilindro
|
||||
if ( nIntType == CC_INF_INT) {
|
||||
dU1 = ( ptPCyl- ptPLine) * vtVLine ;
|
||||
dU1 = ( ptPCyl - ptPLine) * vtVLine ;
|
||||
// Retta e cilindro equiversi
|
||||
if ( vtVCyl * vtVLine > 0)
|
||||
dU2 = dU1 + dCylHeigth ;
|
||||
@@ -819,8 +819,7 @@ IntersLineCylinder( const Point3d& ptPLine, const Vector3d& vtVLine,
|
||||
}
|
||||
// Caso di due intersezioni
|
||||
else if ( nIntType == CC_TWO_INT) {
|
||||
// Rigetto le soluzioni fuori dalla
|
||||
// regione ammissibile del cilindro.
|
||||
// Elimino le soluzioni fuori dal cilindro finito
|
||||
Point3d ptInt1 = ptPLine + dU1 * vtVLine ;
|
||||
Point3d ptInt2 = ptPLine + dU2 * vtVLine ;
|
||||
int nSolNum = 2 ;
|
||||
@@ -832,8 +831,7 @@ IntersLineCylinder( const Point3d& ptPLine, const Vector3d& vtVLine,
|
||||
if ( ( ptInt2 - ptPCyl) * vtVCyl < 0 ||
|
||||
( ptInt2 - ptPCyl) * vtVCyl > dCylHeigth)
|
||||
-- nSolNum ;
|
||||
// Dal numero di soluzioni rimaste
|
||||
// aggiorno la tipologia di interferenza.
|
||||
// Aggiorno il tipo di intersezione
|
||||
if ( nSolNum == 1)
|
||||
nIntType = CC_ONE_INT_SEC ;
|
||||
else if ( nSolNum == 0)
|
||||
@@ -896,8 +894,7 @@ IntersSegmentCylinder( const Point3d& ptPLine, const Vector3d& vtVLine, double d
|
||||
if ( nIntType == CC_ERROR_INT)
|
||||
return nIntType ;
|
||||
|
||||
// Parte della retta associata
|
||||
// appartiene al cilindro
|
||||
// Parte della retta associata appartiene al cilindro
|
||||
if ( nIntType == CC_INF_INT) {
|
||||
// Segmento non interferisce
|
||||
if ( dU1 > dLen + EPS_SMALL)
|
||||
@@ -925,7 +922,7 @@ IntersSegmentCylinder( const Point3d& ptPLine, const Vector3d& vtVLine, double d
|
||||
if ( dU1 < - EPS_SMALL || dU1 > dLen + EPS_SMALL)
|
||||
nIntType = CC_NO_INTERS ;
|
||||
}
|
||||
// Retta associata è secante
|
||||
// Retta associata è secante con due punti di intersezione
|
||||
else if ( nIntType == CC_TWO_INT) {
|
||||
// Il segmento non interferisce
|
||||
if ( dU1 > dLen + EPS_SMALL)
|
||||
@@ -951,6 +948,11 @@ IntersSegmentCylinder( const Point3d& ptPLine, const Vector3d& vtVLine, double d
|
||||
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 ;
|
||||
}
|
||||
|
||||
|
||||
+4
-5
@@ -17,12 +17,11 @@
|
||||
|
||||
// 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.
|
||||
// Il valore di ritorno è una costante intera che individua la tipologia di interferenza.
|
||||
// Il valore di ritorno è una costante intera che individua la tipologia di intersezione.
|
||||
// Se si verificano irregolarità, essa vale ERROR_INT.
|
||||
// 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 hanno senso,
|
||||
// se vi è un'intersezione solo il valore di dU1 ha senso. Se vi sono più intersezioni,
|
||||
// dU1 e dU2 hanno entrambi senso.
|
||||
// intersezioni. Se non vi sono intersezioni i valori di dU1 e dU2 non sono definiti,
|
||||
// se vi è un'intersezione vale solo dU1, con due soluzioni valgono entrambi.
|
||||
// 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
|
||||
// versore. La sfera è divisa in due parti: una nel semi spazio Z+ e una in quello Z-.
|
||||
@@ -130,7 +129,7 @@ int IntersRayInfiniteCylinder( const Point3d& ptPLine, const Vector3d& vtVLine,
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Valuta la posizione reciproca fra un cilindro infinito e un segmento.
|
||||
// Nel caso in cui il sgmento giaccia sul cilindro, nIntType vale INF_INT e dU1 e dU2
|
||||
// Nel caso in cui il segmento giaccia sul cilindro, nIntType vale INF_INT e dU1 e dU2
|
||||
// valgono rispettivamente 0 e dLen (lunghezza del segmento).
|
||||
int IntersSegmentInfiniteCylinder( const Point3d& ptPLine, const Vector3d& vtVLine, double dLen,
|
||||
const Point3d& ptPCyl, const Vector3d& vtVCyl, double dCylRad,
|
||||
|
||||
@@ -162,7 +162,7 @@ GetLinePointPerpCompo( const Point3d& ptP, const CurveComposite& crvCompo, const
|
||||
double dSqDist = SqDist( ptNear, pCrvLtmp->GetEnd()) ;
|
||||
if ( dSqDist < dMinSqDist) {
|
||||
dMinSqDist = dSqDist ;
|
||||
pCrvLine.Set( Release( pCrvLtmp)) ;
|
||||
pCrvLine.Set( pCrvLtmp) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -195,7 +195,7 @@ GetLinePointTgCompo( const Point3d& ptP, const CurveComposite& crvCompo, const P
|
||||
double dSqDist = SqDist( ptNear, pCrvLtmp->GetEnd()) ;
|
||||
if ( dSqDist < dMinSqDist) {
|
||||
dMinSqDist = dSqDist ;
|
||||
pCrvLine.Set( Release( pCrvLtmp)) ;
|
||||
pCrvLine.Set( pCrvLtmp) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -171,7 +171,7 @@ GetLineTgTwoArcs( const CurveArc& crvArc1, const Point3d& ptNear1,
|
||||
return nullptr ;
|
||||
|
||||
// porto il secondo arco nel riferimento intrinseco del primo
|
||||
CurveArc crvArc2Loc = dynamic_cast<const CurveArc&>( crvArc2) ;
|
||||
CurveArc crvArc2Loc = crvArc2 ;
|
||||
crvArc2Loc.ToLoc( frIntr) ;
|
||||
|
||||
// calcolo le linee di tangenza alle due circonferenze
|
||||
|
||||
+77
-27
@@ -1,7 +1,7 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2015-2020
|
||||
// EgalTech 2015-2023
|
||||
//----------------------------------------------------------------------------
|
||||
// File : OffsetCurve.cpp Data : 10.10.20 Versione : 2.2j2
|
||||
// File : OffsetCurve.cpp Data : 03.08.23 Versione : 2.5h1
|
||||
// Contenuto : Classe per offset avanzato di Curve.
|
||||
//
|
||||
//
|
||||
@@ -9,16 +9,17 @@
|
||||
// Modifiche : 23.09.15 DS Creazione modulo.
|
||||
// 24.06.19 DS Agg. GetShorterCurve.
|
||||
// 10.10.20 DS Migliorata gestione angoli interni.
|
||||
// 03.08.23 DS Migliorato riconoscimento angoli esterni di valore circa 180deg.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "CurveComposite.h"
|
||||
#include "GeoConst.h"
|
||||
#include "CurveLine.h"
|
||||
#include "CurveArc.h"
|
||||
#include "CurveComposite.h"
|
||||
#include "RemoveCurveDefects.h"
|
||||
#include "GeoConst.h"
|
||||
#include "/EgtDev/Include/EGkOffsetCurve.h"
|
||||
#include "/EgtDev/Include/EGkIntersCurves.h"
|
||||
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
||||
@@ -83,9 +84,9 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
if ( pCompo != nullptr && pCompo->IsALine( 10 * EPS_SMALL, ptStart, ptEnd))
|
||||
bIsLine = true ;
|
||||
}
|
||||
// verifico che la curva sia piana
|
||||
// verifico che la curva sia piana (per le linee è comunque sempre vero)
|
||||
Plane3d plPlane ;
|
||||
if ( ! pCrv->IsFlat( plPlane, bIsLine, 10 * EPS_SMALL))
|
||||
if ( ! pCrv->IsFlat( plPlane, bIsLine, 10 * EPS_SMALL) && ! bIsLine)
|
||||
return false ;
|
||||
// recupero o assegno estrusione
|
||||
Vector3d vtExtr ;
|
||||
@@ -161,10 +162,17 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
bool bClosed = ccCopy.IsClosed() && ( nType & ICurve::OFF_FORCE_OPEN) == 0 ;
|
||||
|
||||
// elimino eventuali piccole Z
|
||||
RemoveCurveSmallZs( &ccCopy, 10 * EPS_SMALL) ;
|
||||
if ( ! RemoveCurveSmallZs( &ccCopy, 10 * EPS_SMALL))
|
||||
return false ;
|
||||
|
||||
// converto archi diritti in segmenti di retta
|
||||
const double ANG_CEN_MAX = 0.5 ;
|
||||
if ( ! ccCopy.StraightArcsToLines( 2 * EPS_SMALL, ANG_CEN_MAX))
|
||||
return false ;
|
||||
|
||||
// unisco parti allineate (tranne gli estremi)
|
||||
ccCopy.MergeCurves( 10 * EPS_SMALL, ANG_TOL_STD_DEG, false) ;
|
||||
if ( ! ccCopy.MergeCurves( 10 * EPS_SMALL, ANG_TOL_STD_DEG, false))
|
||||
return false ;
|
||||
|
||||
// calcolo le lunghezze delle diverse entità
|
||||
DBLVECTOR vLens ;
|
||||
@@ -250,7 +258,7 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
}
|
||||
// aggiorno curva precedente
|
||||
++ nInd1 ;
|
||||
pCrv1.Set( Release( pCrv2)) ;
|
||||
pCrv1.Set( pCrv2) ;
|
||||
// passo alla curva successiva
|
||||
pCrv2.Set( ccCopy2.RemoveFirstOrLastCurve( false)) ;
|
||||
}
|
||||
@@ -447,7 +455,6 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
vLen.pop_back() ;
|
||||
}
|
||||
// eseguo la divisione
|
||||
int nCount = 1 ;
|
||||
double dUPrev = 0 ;
|
||||
double dLenPrev = 0 ;
|
||||
for ( int i = 0 ; i < int( vU.size()) ; ++ i) {
|
||||
@@ -459,7 +466,6 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
if ( IsNull( pCopy))
|
||||
return false ;
|
||||
m_CrvLst.push_back( Release( pCopy)) ;
|
||||
++ nCount ;
|
||||
// trimmo l'originale
|
||||
pCompo1->TrimStartEndAtParam( dUPrev, vU[i]) ;
|
||||
// la copia diventa il nuovo corrente
|
||||
@@ -467,9 +473,15 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
dUPrev = vU[i] ;
|
||||
dLenPrev = vLen[i] ;
|
||||
}
|
||||
// se fatta almeno una suddivisione, trimmo l'ultima parte
|
||||
if ( dUPrev > EPS_PARAM)
|
||||
// se fatta almeno una suddivisione
|
||||
bool bFirstLastSame = false ;
|
||||
if ( dUPrev > EPS_PARAM) {
|
||||
// trimmo l'ultima parte
|
||||
pCompo1->TrimStartAtParam( dUPrev) ;
|
||||
// rilevo le curve chiuse con due parti di una stessa curva all'inizio e alla fine
|
||||
if ( bClosed && vU[0] > EPS_PARAM && vLen[0] >= 2 * EPS_SMALL)
|
||||
bFirstLastSame = true ;
|
||||
}
|
||||
|
||||
// sesto passo : se curva aperta, elimino i tratti che stanno nella circonferenza di offset dei punti estremi
|
||||
if ( ! bClosed) {
|
||||
@@ -574,6 +586,7 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
}
|
||||
|
||||
// settimo passo : elimino le parti che sono troppo vicine al percorso originale
|
||||
bool bFirstLastDeleted = false ;
|
||||
for ( auto iIter = m_CrvLst.begin() ; iIter != m_CrvLst.end() ;) {
|
||||
ICurve* pCrv = *iIter ;
|
||||
// distanza minima di alcuni punti interni della curva dalla curva originale
|
||||
@@ -584,8 +597,24 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
GetMinDist( 0.875, pCrv, &ccCopy) < abs( dDist) - 5 * EPS_SMALL ||
|
||||
GetMinDist( 0.0625, pCrv, &ccCopy) < abs( dDist) - 5 * EPS_SMALL ||
|
||||
GetMinDist( 0.9375, pCrv, &ccCopy) < abs( dDist) - 5 * EPS_SMALL) {
|
||||
// se prima e ultima sono la stessa curva e non ancora cancellate e prima da cancellare
|
||||
if ( bFirstLastSame && ! bFirstLastDeleted && iIter == m_CrvLst.begin()) {
|
||||
bFirstLastDeleted = true ;
|
||||
// cancello ultima
|
||||
delete *prev( m_CrvLst.end()) ;
|
||||
m_CrvLst.pop_back() ;
|
||||
}
|
||||
// se prima e ultima sono la stessa curva e non ancora cancellate e ultima da cancellare
|
||||
if ( bFirstLastSame && ! bFirstLastDeleted && iIter == prev( m_CrvLst.end())) {
|
||||
bFirstLastDeleted = true ;
|
||||
// cancello prima
|
||||
delete *m_CrvLst.begin() ;
|
||||
m_CrvLst.pop_front() ;
|
||||
}
|
||||
// cancello la corrente
|
||||
delete pCrv ;
|
||||
iIter = m_CrvLst.erase( iIter) ;
|
||||
// evito incremento
|
||||
continue ;
|
||||
}
|
||||
// passo alla successiva
|
||||
@@ -608,18 +637,16 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
pCrvCo2->GetEndPoint( ptEnd2) ;
|
||||
// verifiche di concatenamento
|
||||
if ( AreSamePointEpsilon( ptEnd, ptStart2, 10 * EPS_SMALL)) {
|
||||
if ( pCrvCo->AddCurve( pCrvCo2, true, 10 * EPS_SMALL)) {
|
||||
m_CrvLst.erase( iIter2) ;
|
||||
if ( pCrvCo->AddCurve( pCrvCo2, true, 10 * EPS_SMALL))
|
||||
ptEnd = ptEnd2 ;
|
||||
iIter2 = next( iIter) ;
|
||||
}
|
||||
m_CrvLst.erase( iIter2) ;
|
||||
iIter2 = next( iIter) ;
|
||||
}
|
||||
else if ( AreSamePointEpsilon( ptEnd2, ptStart, 10 * EPS_SMALL)) {
|
||||
if ( pCrvCo->AddCurve( pCrvCo2, false, 10 * EPS_SMALL)) {
|
||||
m_CrvLst.erase( iIter2) ;
|
||||
if ( pCrvCo->AddCurve( pCrvCo2, false, 10 * EPS_SMALL))
|
||||
ptStart = ptStart2 ;
|
||||
iIter2 = next( iIter) ;
|
||||
}
|
||||
m_CrvLst.erase( iIter2) ;
|
||||
iIter2 = next( iIter) ;
|
||||
}
|
||||
else
|
||||
++ iIter2 ;
|
||||
@@ -704,6 +731,15 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
break ;
|
||||
}
|
||||
|
||||
// se originale era chiusa, verifico le risultanti e se necessario cerco di chiuderle
|
||||
if ( bClosed) {
|
||||
for ( auto pCrv : m_CrvLst) {
|
||||
CurveComposite* pCrvCo = GetBasicCurveComposite( pCrv) ;
|
||||
if ( pCrvCo != nullptr)
|
||||
pCrvCo->Close() ;
|
||||
}
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
@@ -830,16 +866,30 @@ CalcAngle( const ICurve* pCrv1, const ICurve* pCrv2, double& dAngDeg)
|
||||
if ( ! vtDir1.GetAngleXY( vtDir2, dAngDeg))
|
||||
return false ;
|
||||
// se vicino all'angolo piatto, si devono ricalcolare spostandosi un poco
|
||||
if ( abs( dAngDeg) > ( ANG_STRAIGHT - EPS_ANG_SMALL)) {
|
||||
// eseguo calcolo spostato
|
||||
const double MAX_ANG_DELTA = 2 ;
|
||||
double dAngDelta = abs( abs( dAngDeg) - ANG_STRAIGHT) ;
|
||||
if ( dAngDelta < MAX_ANG_DELTA) {
|
||||
// angolo al centro delle curve
|
||||
double dAngCen1 = 0 ;
|
||||
if ( pCrv1->GetType() == CRV_ARC)
|
||||
dAngCen1 = abs( GetBasicCurveArc( pCrv1)->GetAngCenter()) ;
|
||||
double dAngCen2 = 0 ;
|
||||
if ( pCrv2->GetType() == CRV_ARC)
|
||||
dAngCen2 = abs( GetBasicCurveArc( pCrv2)->GetAngCenter()) ;
|
||||
// determino posizioni spostate
|
||||
double dU1 = 1 ;
|
||||
if ( dAngCen1 > EPS_ANG_SMALL) {
|
||||
dU1 = 1 - min( 1.1 * dAngDelta / ( dAngCen1 + dAngCen2), 0.5) ;
|
||||
}
|
||||
double dU2 = 0 ;
|
||||
if ( dAngCen2 > EPS_ANG_SMALL) {
|
||||
dU2 = 0 + min( 1.1 * dAngDelta / ( dAngCen1 + dAngCen2), 0.5) ;
|
||||
}
|
||||
// eseguo calcolo spostato
|
||||
Point3d ptDummy ;
|
||||
Vector3d vtDir1b ;
|
||||
Vector3d vtDir2b ;
|
||||
if ( ! MoveParamToAvoidTg( dU1, ICurve::FROM_MINUS, *pCrv1) ||
|
||||
! pCrv1->GetPointTang( dU1, ICurve::FROM_MINUS, ptDummy, vtDir1b) ||
|
||||
! MoveParamToAvoidTg( dU2, ICurve::FROM_PLUS, *pCrv2) ||
|
||||
if ( ! pCrv1->GetPointTang( dU1, ICurve::FROM_MINUS, ptDummy, vtDir1b) ||
|
||||
! pCrv2->GetPointTang( dU2, ICurve::FROM_PLUS, ptDummy, vtDir2b))
|
||||
return false ;
|
||||
if ( ! vtDir1b.GetAngleXY( vtDir2b, dAngDeg))
|
||||
@@ -954,7 +1004,7 @@ VerifyAndAdjustExternalAngle( ICurve* pCrv1, ICurve* pCrv2, double dAngDeg, doub
|
||||
nType = ICurve::OFF_CHAMFER ;
|
||||
|
||||
// se angolo esterno molto piccolo, semplifico tutto
|
||||
const double SMALL_EXT_ANG = 1.0 ;
|
||||
const double SMALL_EXT_ANG = 0.1 ;
|
||||
bool bAngSmall = ( abs( dAngDeg) < SMALL_EXT_ANG) ;
|
||||
if ( bAngSmall)
|
||||
nType = ICurve::OFF_EXTEND ;
|
||||
|
||||
+2
-2
@@ -133,7 +133,7 @@ Point3d::ToGlob( const Frame3d& frRef)
|
||||
y = ptT.x * frRef.VersX().y + ptT.y * frRef.VersY().y + ptT.z * frRef.VersZ().y + frRef.Orig().y ;
|
||||
z = ptT.x * frRef.VersX().z + ptT.y * frRef.VersY().z + ptT.z * frRef.VersZ().z + frRef.Orig().z ;
|
||||
}
|
||||
else {
|
||||
else if ( ! frRef.Orig().IsZero()) {
|
||||
x += frRef.Orig().x ;
|
||||
y += frRef.Orig().y ;
|
||||
z += frRef.Orig().z ;
|
||||
@@ -159,7 +159,7 @@ Point3d::ToLoc( const Frame3d& frRef)
|
||||
y = vtT.x * frRef.VersY().x + vtT.y * frRef.VersY().y + vtT.z * frRef.VersY().z ;
|
||||
z = vtT.x * frRef.VersZ().x + vtT.y * frRef.VersZ().y + vtT.z * frRef.VersZ().z ;
|
||||
}
|
||||
else {
|
||||
else if ( ! frRef.Orig().IsZero()) {
|
||||
x -= frRef.Orig().x ;
|
||||
y -= frRef.Orig().y ;
|
||||
z -= frRef.Orig().z ;
|
||||
|
||||
+8
-7
@@ -124,8 +124,8 @@ GetSurfFlatRegionFromFatCurve( ICurve* pCrv, double dRadius, bool bSquareEnds, b
|
||||
Vector3d vtExtr ; pCrv->GetExtrusion( vtExtr) ;
|
||||
if ( vtExtr.IsSmall())
|
||||
vtExtr = Z_AX ;
|
||||
PtrOwner<CurveComposite> pCompo1( CreateBasicCurveComposite()) ;
|
||||
if ( IsNull( pCompo1) || ! pCompo1->AddCurve( Release( pCurve)))
|
||||
PtrOwner<CurveComposite> pCompo1 ;
|
||||
if ( ! pCompo1.Set( ConvertCurveToBasicComposite( Release( pCurve))))
|
||||
return nullptr ;
|
||||
pCompo1->SetExtrusion( vtExtr) ;
|
||||
// se distanza tra gli estremi minore di due volte il raggio la chiudo, purchè curva abbastanza lunga
|
||||
@@ -154,12 +154,13 @@ GetSurfFlatRegionFromFatCurve( ICurve* pCrv, double dRadius, bool bSquareEnds, b
|
||||
Vector3d vtSLoc( vtStart) ; vtSLoc.ToLoc( frLoc) ;
|
||||
double dAngEnd ; vtELoc.ToSpherical( nullptr, nullptr, &dAngEnd) ;
|
||||
double dAngStart ; vtSLoc.ToSpherical( nullptr, nullptr, &dAngStart) ;
|
||||
PtrOwner<ICurve> pClose( GetBiArc( ptEnd, dAngEnd, ptStart, dAngStart, 0.5)) ;
|
||||
// porto il biarco in globale
|
||||
pClose->ToGlob( frLoc) ;
|
||||
PtrOwner<ICurve> pClose( GetBiArc( ptEnd, dAngEnd, ptStart, dAngStart, 0.5)) ;
|
||||
// aggiungo il biarco
|
||||
if ( ! IsNull( pClose))
|
||||
if ( ! IsNull( pClose)) {
|
||||
// porto il biarco in globale
|
||||
pClose->ToGlob( frLoc) ;
|
||||
pCompo1->AddCurve( Release( pClose)) ;
|
||||
}
|
||||
else
|
||||
pCompo1->Close() ;
|
||||
}
|
||||
@@ -436,7 +437,7 @@ SurfFlatRegionByContours::AddCurve( ICurve* pCrv)
|
||||
pMyCrv->SetThickness( 0) ;
|
||||
// rimuovo eventuali sovrapposizioni (calcolate nel suo piano)
|
||||
ICURVEPLIST CrvLst ;
|
||||
if ( ! AdjustLoops( Release( pMyCrv), CrvLst))
|
||||
if ( ! AdjustLoops( Release( pMyCrv), CrvLst, true))
|
||||
return false ;
|
||||
// la/le inserisco nel vettore delle curve
|
||||
for ( auto& pSingCrv : CrvLst)
|
||||
|
||||
+86
-76
@@ -17,10 +17,14 @@
|
||||
#include "CurveLine.h"
|
||||
#include "CurveArc.h"
|
||||
#include "CurveComposite.h"
|
||||
#include "SurfTriMesh.h"
|
||||
#include "/EgtDev/Include/EGkOffsetCurve.h"
|
||||
#include "/EgtDev/Include/EGkStmFromCurves.h"
|
||||
#include "/EgtDev/Include/EGkStmFromTriangleSoup.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
#include <algorithm>
|
||||
#include <thread>
|
||||
#include <future>
|
||||
|
||||
using namespace std ;
|
||||
|
||||
@@ -40,7 +44,7 @@ GetSurfTriMeshByFlatContour( const ICurve* pCurve, double dLinTol)
|
||||
if ( ! pCurve->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL))
|
||||
return nullptr ;
|
||||
// creo e setto la superficie trimesh
|
||||
PtrOwner<ISurfTriMesh> pSTM( CreateSurfTriMesh()) ;
|
||||
PtrOwner<SurfTriMesh> pSTM( CreateBasicSurfTriMesh()) ;
|
||||
if ( IsNull( pSTM) || ! pSTM->CreateByFlatContour( PL))
|
||||
return nullptr ;
|
||||
// salvo tolleranza lineare usata
|
||||
@@ -62,7 +66,7 @@ GetSurfTriMeshByRegion( const CICURVEPVECTOR& vpCurve, double dLinTol)
|
||||
if ( ! CalcRegionPolyLines( vpCurve, dLinTol, vPL, vtN))
|
||||
return nullptr ;
|
||||
// creo e setto la superficie trimesh
|
||||
PtrOwner<ISurfTriMesh> pSTM( CreateSurfTriMesh()) ;
|
||||
PtrOwner<SurfTriMesh> pSTM( CreateBasicSurfTriMesh()) ;
|
||||
if ( IsNull( pSTM) || ! pSTM->CreateByRegion( vPL))
|
||||
return nullptr ;
|
||||
// salvo tolleranza lineare usata
|
||||
@@ -101,25 +105,23 @@ GetSurfTriMeshByExtrusion( const ICurve* pCurve, const Vector3d& vtExtr,
|
||||
}
|
||||
}
|
||||
// creo e setto la superficie trimesh
|
||||
PtrOwner<ISurfTriMesh> pSTM( CreateSurfTriMesh()) ;
|
||||
PtrOwner<SurfTriMesh> pSTM( CreateBasicSurfTriMesh()) ;
|
||||
if ( IsNull( pSTM) || ! pSTM->CreateByExtrusion( PL, vtExtr))
|
||||
return nullptr ;
|
||||
// se da fare, metto i tappi sulle estremità
|
||||
if ( bDoCapEnds) {
|
||||
// creo la prima superficie di estremità
|
||||
PtrOwner<ISurfTriMesh> pSTM1( CreateSurfTriMesh()) ;
|
||||
if ( IsNull( pSTM1) || ! pSTM1->CreateByFlatContour( PL))
|
||||
SurfTriMesh STM1 ;
|
||||
if ( ! STM1.CreateByFlatContour( PL))
|
||||
return nullptr ;
|
||||
// la copio
|
||||
PtrOwner<ISurfTriMesh> pSTM2( pSTM1->Clone()) ;
|
||||
if ( IsNull( pSTM2))
|
||||
return nullptr ;
|
||||
SurfTriMesh STM2 = STM1 ;
|
||||
// inverto la prima superficie
|
||||
pSTM1->Invert() ;
|
||||
STM1.Invert() ;
|
||||
// traslo la seconda
|
||||
pSTM2->Translate( vtExtr) ;
|
||||
STM2.Translate( vtExtr) ;
|
||||
// le unisco alla superficie del fianco
|
||||
if ( ! pSTM->DoSewing( *pSTM1) || ! pSTM->DoSewing( *pSTM2))
|
||||
if ( ! pSTM->DoSewing( STM1) || ! pSTM->DoSewing( STM2))
|
||||
return nullptr ;
|
||||
}
|
||||
// salvo tolleranza lineare usata
|
||||
@@ -153,30 +155,28 @@ GetSurfTriMeshByRegionExtrusion( const CICURVEPVECTOR& vpCurve, const Vector3d&
|
||||
vPL[i].Invert() ;
|
||||
}
|
||||
// creo la prima superficie di estremità
|
||||
PtrOwner<ISurfTriMesh> pSTM( CreateSurfTriMesh()) ;
|
||||
PtrOwner<SurfTriMesh> pSTM( CreateBasicSurfTriMesh()) ;
|
||||
if ( IsNull( pSTM) || ! pSTM->CreateByRegion( vPL))
|
||||
return nullptr ;
|
||||
// creo la seconda superficie e la unisco alla prima
|
||||
{ // copio la prima superficie
|
||||
PtrOwner<ISurfTriMesh> pSTM2( pSTM->Clone()) ;
|
||||
if ( IsNull( pSTM2))
|
||||
return nullptr ;
|
||||
SurfTriMesh STM2 = *pSTM ;
|
||||
// inverto la prima superficie
|
||||
pSTM->Invert() ;
|
||||
// traslo la seconda
|
||||
pSTM2->Translate( vtExtr) ;
|
||||
STM2.Translate( vtExtr) ;
|
||||
// la unisco alla prima
|
||||
if ( ! pSTM->DoSewing( *pSTM2))
|
||||
if ( ! pSTM->DoSewing( STM2))
|
||||
return nullptr ;
|
||||
}
|
||||
// creo e unisco le diverse superfici di estrusione
|
||||
for ( int i = 0 ; i < int( vPL.size()) ; ++ i) {
|
||||
// estrusione
|
||||
PtrOwner<ISurfTriMesh> pSTM2( CreateSurfTriMesh()) ;
|
||||
if ( IsNull( pSTM2) || ! pSTM2->CreateByExtrusion( vPL[i], vtExtr))
|
||||
SurfTriMesh STM2 ;
|
||||
if ( ! STM2.CreateByExtrusion( vPL[i], vtExtr))
|
||||
return nullptr ;
|
||||
// la unisco alla superficie principale
|
||||
if ( ! pSTM->DoSewing( *pSTM2))
|
||||
if ( ! pSTM->DoSewing( STM2))
|
||||
return nullptr ;
|
||||
}
|
||||
// compatto la superficie
|
||||
@@ -397,15 +397,6 @@ GetSurfTriMeshSharpRectSwept( double dDimH, double dDimV, const ICurve* pGuide,
|
||||
}
|
||||
// se altrimenti guida aperta e tappi arrotondati
|
||||
if ( ! bGuideClosed && ( nCapType == RSCAP_ROUND || nCapType == RSCAP_BEVEL)) {
|
||||
// verifico che le due estremità siano chiuse e piatte
|
||||
//POLYLINEVECTOR vPL ;
|
||||
//if ( ! pSTM->GetLoops( vPL) || vPL.size() != 2)
|
||||
// return nullptr ;
|
||||
//Plane3d plEnds ; double dArea ;
|
||||
//if ( ! vPL[0].IsClosedAndFlat( plEnds, dArea, 50 * EPS_SMALL))
|
||||
// return nullptr ;
|
||||
//if ( ! vPL[1].IsClosedAndFlat( plEnds, dArea, 50 * EPS_SMALL))
|
||||
// return nullptr ;
|
||||
// step di rotazione per rispettare la tolleranza
|
||||
double dStepRotDeg = ( nCapType == RSCAP_BEVEL ? ANG_STRAIGHT / 4 : sqrt( 8 * dLinTol / dDimH) * RADTODEG) ;
|
||||
// aggiungo il cap sull'inizio
|
||||
@@ -440,8 +431,6 @@ GetSurfTriMeshSharpRectSwept( double dDimH, double dDimV, const ICurve* pGuide,
|
||||
return nullptr ;
|
||||
pSce->Invert() ;
|
||||
pSTM->DoSewing( *pSce) ;
|
||||
// elimino eventuali fessure
|
||||
//pSTM->Repair() ;
|
||||
}
|
||||
// restituisco la superficie
|
||||
return Release( pSTM) ;
|
||||
@@ -464,29 +453,37 @@ GetSurfTriMeshBeveledRectSwept( double dDimH, double dDimV, double dBevelH, doub
|
||||
// determino se la guida è chiusa
|
||||
bool bGuideClosed = pGuide->IsClosed() ;
|
||||
// curve di offset
|
||||
OffsetCurve OffsCrvR ;
|
||||
if ( ! OffsCrvR.Make( pGuide, dDimH / 2 - dBevelH, ICurve::OFF_FILLET) || OffsCrvR.GetCurveCount() == 0)
|
||||
const int NUM_OFFS = 4 ;
|
||||
OffsetCurve vOffsCrv[NUM_OFFS] ;
|
||||
double vDist[NUM_OFFS] = { dDimH / 2 - dBevelH, -dDimH / 2 + dBevelH, dDimH / 2, -dDimH / 2} ;
|
||||
future<bool> vRes[NUM_OFFS] ;
|
||||
for ( int i = 0 ; i < NUM_OFFS ; ++ i)
|
||||
vRes[i] = async( launch::async, &OffsetCurve::Make, &vOffsCrv[i], pGuide, vDist[i], ICurve::OFF_FILLET) ;
|
||||
bool bOk = true ;
|
||||
int nFin = 0 ;
|
||||
while ( nFin < NUM_OFFS) {
|
||||
for ( int i = 0 ; i < NUM_OFFS ; ++ i) {
|
||||
if ( vRes[i].valid() && vRes[i].wait_for( chrono::nanoseconds{ 1}) == future_status::ready) {
|
||||
bOk = vRes[i].get() && bOk ;
|
||||
++ nFin ;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( ! bOk ||
|
||||
vOffsCrv[0].GetCurveCount() == 0 || vOffsCrv[1].GetCurveCount() == 0 ||
|
||||
vOffsCrv[2].GetCurveCount() == 0 || vOffsCrv[3].GetCurveCount() == 0)
|
||||
return nullptr ;
|
||||
PtrOwner<ICurve> pCrvR( OffsCrvR.GetLongerCurve()) ;
|
||||
PtrOwner<ICurve> pCrvR( vOffsCrv[0].GetLongerCurve()) ;
|
||||
if ( IsNull( pCrvR))
|
||||
return nullptr ;
|
||||
OffsetCurve OffsCrvL ;
|
||||
if ( ! OffsCrvL.Make( pGuide, -dDimH / 2 + dBevelH, ICurve::OFF_FILLET) || OffsCrvL.GetCurveCount() == 0)
|
||||
return nullptr ;
|
||||
PtrOwner<ICurve> pCrvL( OffsCrvL.GetLongerCurve()) ;
|
||||
PtrOwner<ICurve> pCrvL( vOffsCrv[1].GetLongerCurve()) ;
|
||||
if ( IsNull( pCrvL))
|
||||
return nullptr ;
|
||||
OffsetCurve OffsCrvRb ;
|
||||
if ( ! OffsCrvRb.Make( pGuide, dDimH / 2, ICurve::OFF_FILLET) || OffsCrvRb.GetCurveCount() == 0)
|
||||
return nullptr ;
|
||||
PtrOwner<ICurve> pCrvRb( OffsCrvRb.GetLongerCurve()) ;
|
||||
PtrOwner<ICurve> pCrvRb( vOffsCrv[2].GetLongerCurve()) ;
|
||||
if ( IsNull( pCrvRb))
|
||||
return nullptr ;
|
||||
pCrvRb->Translate( - dBevelV * vtNorm) ;
|
||||
OffsetCurve OffsCrvLb ;
|
||||
if ( ! OffsCrvLb.Make( pGuide, -dDimH / 2, ICurve::OFF_FILLET) || OffsCrvLb.GetCurveCount() == 0)
|
||||
return nullptr ;
|
||||
PtrOwner<ICurve> pCrvLb( OffsCrvLb.GetLongerCurve()) ;
|
||||
PtrOwner<ICurve> pCrvLb( vOffsCrv[3].GetLongerCurve()) ;
|
||||
if ( IsNull( pCrvLb))
|
||||
return nullptr ;
|
||||
pCrvLb->Translate( - dBevelV * vtNorm) ;
|
||||
@@ -521,19 +518,29 @@ GetSurfTriMeshBeveledRectSwept( double dDimH, double dDimV, double dBevelH, doub
|
||||
if ( IsNull( pSrfLft))
|
||||
return nullptr ;
|
||||
// unisco le parti
|
||||
PtrOwner<ISurfTriMesh> pSTM( Release( pSrfTop)) ;
|
||||
pSTM->DoSewing( *pSrfTopR) ;
|
||||
pSTM->DoSewing( *pSrfTopL) ;
|
||||
pSTM->DoSewing( *pSrfRgt) ;
|
||||
pSTM->DoSewing( *pSrfLft) ;
|
||||
pSTM->DoSewing( *pSrfBotR) ;
|
||||
pSTM->DoSewing( *pSrfBotL) ;
|
||||
pSTM->DoSewing( *pSrfBot) ;
|
||||
// salvo tolleranza lineare usata e imposto angolo per smooth
|
||||
pSTM->SetLinearTolerance( dLinTol) ;
|
||||
pSTM->SetSmoothAngle( 20) ;
|
||||
int nBuckets = max( 4 * ( pSrfRgt->GetVertexSize() + pSrfLft->GetVertexSize()), 1000) ;
|
||||
StmFromTriangleSoup stmSoup ;
|
||||
if ( ! stmSoup.Start( nBuckets))
|
||||
return nullptr ;
|
||||
stmSoup.AddSurfTriMesh( *pSrfTop) ;
|
||||
stmSoup.AddSurfTriMesh( *pSrfTopR) ;
|
||||
stmSoup.AddSurfTriMesh( *pSrfTopL) ;
|
||||
stmSoup.AddSurfTriMesh( *pSrfRgt) ;
|
||||
stmSoup.AddSurfTriMesh( *pSrfLft) ;
|
||||
stmSoup.AddSurfTriMesh( *pSrfBotR) ;
|
||||
stmSoup.AddSurfTriMesh( *pSrfBotL) ;
|
||||
stmSoup.AddSurfTriMesh( *pSrfBot) ;
|
||||
PtrOwner<ISurfTriMesh> pSTM ;
|
||||
// se guida aperta e tappi piatti
|
||||
if ( ! bGuideClosed && nCapType == RSCAP_FLAT) {
|
||||
// completo unione e recupero la superficie risultante
|
||||
if ( ! stmSoup.End())
|
||||
return nullptr ;
|
||||
pSTM.Set( stmSoup.GetSurf()) ;
|
||||
// preparo seconda zuppa di triangoli per inserire i tappi
|
||||
StmFromTriangleSoup stmCapSoup ;
|
||||
if ( ! stmCapSoup.Start( nBuckets))
|
||||
return nullptr ;
|
||||
// verifico che le due estremità siano chiuse e piatte
|
||||
POLYLINEVECTOR vPL ;
|
||||
if ( ! pSTM->GetLoops( vPL) || vPL.size() != 2)
|
||||
@@ -543,30 +550,22 @@ GetSurfTriMeshBeveledRectSwept( double dDimH, double dDimV, double dBevelH, doub
|
||||
return nullptr ;
|
||||
if ( ! vPL[1].IsClosedAndFlat( plEnds, dArea, 50 * EPS_SMALL))
|
||||
return nullptr ;
|
||||
// aggiungo il cap sull'inizio
|
||||
// calcolo il cap sull'inizio
|
||||
PtrOwner<ISurfTriMesh> pSci( CreateSurfTriMesh()) ;
|
||||
if ( IsNull( pSci) || ! pSci->CreateByFlatContour( vPL[0]))
|
||||
return nullptr ;
|
||||
pSci->Invert() ;
|
||||
pSTM->DoSewing( *pSci) ;
|
||||
// aggiungo il cap sulla fine
|
||||
// calcolo il cap sulla fine
|
||||
PtrOwner<ISurfTriMesh> pSce( CreateSurfTriMesh()) ;
|
||||
if ( IsNull( pSce) || ! pSce->CreateByFlatContour( vPL[1]))
|
||||
return nullptr ;
|
||||
pSce->Invert() ;
|
||||
pSTM->DoSewing( *pSce) ;
|
||||
// cucio i tappi all'estrusione
|
||||
if ( ! pSTM->DoSewing( *pSci) || ! pSTM->DoSewing( *pSce))
|
||||
return nullptr ;
|
||||
}
|
||||
// se altrimenti guida aperta e tappi arrotondati
|
||||
if ( ! bGuideClosed && ( nCapType == RSCAP_ROUND || nCapType == RSCAP_BEVEL)) {
|
||||
// verifico che le due estremità siano chiuse e piatte
|
||||
//POLYLINEVECTOR vPL ;
|
||||
//if ( ! pSTM->GetLoops( vPL) || vPL.size() != 2)
|
||||
// return nullptr ;
|
||||
//Plane3d plEnds ; double dArea ;
|
||||
//if ( ! vPL[0].IsClosedAndFlat( plEnds, dArea, 50 * EPS_SMALL))
|
||||
// return nullptr ;
|
||||
//if ( ! vPL[1].IsClosedAndFlat( plEnds, dArea, 50 * EPS_SMALL))
|
||||
// return nullptr ;
|
||||
else if ( ! bGuideClosed && ( nCapType == RSCAP_ROUND || nCapType == RSCAP_BEVEL)) {
|
||||
// step di rotazione per rispettare il tipo o la tolleranza
|
||||
double dStepRotDeg = ( nCapType == RSCAP_BEVEL ? ANG_STRAIGHT / 4 : sqrt( 8 * dLinTol / dDimH) * RADTODEG) ;
|
||||
// aggiungo il cap sull'inizio
|
||||
@@ -586,7 +585,7 @@ GetSurfTriMeshBeveledRectSwept( double dDimH, double dDimV, double dBevelH, doub
|
||||
if ( IsNull( pSci) || ! pSci->CreateByScrewing( PLStart, ptStart, vtNorm, ANG_STRAIGHT, dStepRotDeg, 0))
|
||||
return nullptr ;
|
||||
pSci->Invert() ;
|
||||
pSTM->DoSewing( *pSci) ;
|
||||
stmSoup.AddSurfTriMesh( *pSci) ;
|
||||
// aggiungo il cap sulla fine
|
||||
Point3d ptEnd ;
|
||||
pGuide->GetEndPoint( ptEnd) ;
|
||||
@@ -604,10 +603,21 @@ GetSurfTriMeshBeveledRectSwept( double dDimH, double dDimV, double dBevelH, doub
|
||||
if ( IsNull( pSce) || ! pSce->CreateByScrewing( PLEnd, ptEnd, vtNorm, ANG_STRAIGHT, dStepRotDeg, 0))
|
||||
return nullptr ;
|
||||
pSce->Invert() ;
|
||||
pSTM->DoSewing( *pSce) ;
|
||||
// elimino eventuali fessure
|
||||
//pSTM->Repair() ;
|
||||
stmSoup.AddSurfTriMesh( *pSce) ;
|
||||
// completo unione e recupero la superficie risultante
|
||||
if ( ! stmSoup.End())
|
||||
return nullptr ;
|
||||
pSTM.Set( stmSoup.GetSurf()) ;
|
||||
}
|
||||
else {
|
||||
// completo unione e recupero la superficie risultante
|
||||
if ( ! stmSoup.End())
|
||||
return nullptr ;
|
||||
pSTM.Set( stmSoup.GetSurf()) ;
|
||||
}
|
||||
// salvo tolleranza lineare usata e imposto angolo per smooth
|
||||
pSTM->SetLinearTolerance( dLinTol) ;
|
||||
pSTM->SetSmoothAngle( 20) ;
|
||||
// restituisco la superficie
|
||||
return Release( pSTM) ;
|
||||
}
|
||||
@@ -685,7 +695,7 @@ GetSurfTriMeshSwept( const ICurve* pSect, const ICurve* pGuide, bool bCapEnds, d
|
||||
pSTM->DoSewing( *pSr) ;
|
||||
}
|
||||
// salvo la curva come prossima precedente
|
||||
pPrevCrv.Set( Release( pCurrCrv)) ;
|
||||
pPrevCrv.Set( pCurrCrv) ;
|
||||
// prossimo punto
|
||||
bPoint = PL.GetNextPoint( ptP) ;
|
||||
}
|
||||
|
||||
+40
-16
@@ -1,10 +1,10 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2014-2015
|
||||
// EgalTech 2014-2023
|
||||
//----------------------------------------------------------------------------
|
||||
// File : StmFromTriangleSoup.cpp Data : 19.05.14 Versione : 1.5e7
|
||||
// File : StmFromTriangleSoup.cpp Data : 07.05.23 Versione : 2.5e2
|
||||
// Contenuto : Implementazione della classe StmFromTriangleSoup, per creare
|
||||
// una superficie trimesh da un insieme disordinato di triangoli(STL).
|
||||
//
|
||||
// una superficie trimesh da un insieme di triangoli
|
||||
// (può essere disordinato come STL o può essere una superficie).
|
||||
//
|
||||
// Modifiche : 19.05.14 DS Creazione modulo.
|
||||
//
|
||||
@@ -76,42 +76,66 @@ StmFromTriangleSoup::AddTriangle( const Triangle3d& Tria)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
StmFromTriangleSoup::AddTriangle( const Point3d& ptP0, const Point3d& ptP1, const Point3d& ptP2)
|
||||
StmFromTriangleSoup::AddTriangle( const Point3d& ptP0, const Point3d& ptP1, const Point3d& ptP2,
|
||||
const double dU0, const double dV0,const double dU1, const double dV1,const double dU2, const double dV2)
|
||||
{
|
||||
// verifico inizializzazione
|
||||
// verifico inizializzazione
|
||||
if ( m_pSTM == nullptr)
|
||||
return false ;
|
||||
// ciclo sui tre vertici
|
||||
// ciclo sui tre vertici
|
||||
int nIdV[3] ;
|
||||
if ( ( nIdV[0] = AddVertex( ptP0)) == SVT_NULL)
|
||||
if ( ( nIdV[0] = AddVertex( ptP0, dU0, dV0)) == SVT_NULL)
|
||||
return false ;
|
||||
if ( ( nIdV[1] = AddVertex( ptP1)) == SVT_NULL)
|
||||
if ( ( nIdV[1] = AddVertex( ptP1, dU1, dV1)) == SVT_NULL)
|
||||
return false ;
|
||||
if ( ( nIdV[2] = AddVertex( ptP2)) == SVT_NULL)
|
||||
if ( ( nIdV[2] = AddVertex( ptP2, dU2, dV2)) == SVT_NULL)
|
||||
return false ;
|
||||
// se i vertici sono tutti diversi tra loro, inserisco il triangolo
|
||||
// se i vertici sono tutti diversi tra loro, inserisco il triangolo
|
||||
if ( nIdV[0] != nIdV[1] && nIdV[0] != nIdV[2] && nIdV[1] != nIdV[2]) {
|
||||
if ( m_pSTM->AddTriangle( nIdV) == SVT_NULL)
|
||||
return false ;
|
||||
return false ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
StmFromTriangleSoup::AddVertex( const Point3d& ptP)
|
||||
StmFromTriangleSoup::AddVertex( const Point3d& ptP, const double dU, const double dV)
|
||||
{
|
||||
// verifico se già presente
|
||||
// verifico se già presente
|
||||
int nId ;
|
||||
if ( m_VertGrid.Find( ptP, 2 * EPS_SMALL, nId))
|
||||
return nId ;
|
||||
// aggiungo il vertice
|
||||
if ( ( nId = m_pSTM->AddVertex( ptP)) == SVT_NULL)
|
||||
// aggiungo il vertice
|
||||
if ( ( nId = m_pSTM->AddVertex( ptP, dU, dV)) == SVT_NULL)
|
||||
return SVT_NULL ;
|
||||
m_VertGrid.InsertPoint( ptP, nId) ;
|
||||
return nId ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
StmFromTriangleSoup::AddSurfTriMesh( const ISurfTriMesh& stmSource)
|
||||
{
|
||||
// verifico inizializzazione
|
||||
if ( m_pSTM == nullptr)
|
||||
return false ;
|
||||
// verifico superficie sorgente
|
||||
if ( &stmSource == nullptr || ! stmSource.IsValid())
|
||||
return false ;
|
||||
// recupero tutti i triangoli della superficie
|
||||
bool bOk = true ;
|
||||
Triangle3d Tria ;
|
||||
int nT = stmSource.GetFirstTriangle( Tria) ;
|
||||
while ( nT != SVT_NULL) {
|
||||
// inserisco il triangolo nella zuppa
|
||||
bOk = AddTriangle( Tria) && bOk ;
|
||||
// passo al triangolo successivo
|
||||
nT = stmSource.GetNextTriangle( nT, Tria) ;
|
||||
}
|
||||
return bOk ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
StmFromTriangleSoup::End( void)
|
||||
|
||||
+32
-35
@@ -14,6 +14,7 @@
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "CurveArc.h"
|
||||
#include "SurfTriMesh.h"
|
||||
#include "/EgtDev/Include/EGkStmStandard.h"
|
||||
#include "/EgtDev/Include/EGkStmFromCurves.h"
|
||||
#include "/EgtDev/Include/EGkPolygon3d.h"
|
||||
@@ -22,7 +23,7 @@
|
||||
using namespace std ;
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
static ISurfTriMesh*
|
||||
static SurfTriMesh*
|
||||
GetStandardSurfTriMeshBox( double dDimX, double dDimY, double dHeight)
|
||||
{
|
||||
// creo la polilinea del contorno della base
|
||||
@@ -38,29 +39,27 @@ GetStandardSurfTriMeshBox( double dDimX, double dDimY, double dHeight)
|
||||
// vettore altezza (estrusione)
|
||||
Vector3d vtExtr( 0, 0, dHeight) ;
|
||||
// creo e setto la superficie trimesh laterale
|
||||
PtrOwner<ISurfTriMesh> pSTM( CreateSurfTriMesh()) ;
|
||||
PtrOwner<SurfTriMesh> pSTM( CreateBasicSurfTriMesh()) ;
|
||||
if ( IsNull( pSTM) || ! pSTM->CreateByExtrusion( PL, vtExtr))
|
||||
return nullptr ;
|
||||
// creo la prima superficie di estremità
|
||||
PtrOwner<ISurfTriMesh> pSTM1( CreateSurfTriMesh()) ;
|
||||
if ( IsNull( pSTM1) || ! pSTM1->CreateByFlatContour( PL))
|
||||
SurfTriMesh STM1 ;
|
||||
if ( ! STM1.CreateByFlatContour( PL))
|
||||
return nullptr ;
|
||||
// la copio
|
||||
PtrOwner<ISurfTriMesh> pSTM2( pSTM1->Clone()) ;
|
||||
if ( IsNull( pSTM2))
|
||||
return nullptr ;
|
||||
SurfTriMesh STM2 = STM1 ;
|
||||
// inverto la prima superficie
|
||||
pSTM1->Invert() ;
|
||||
STM1.Invert() ;
|
||||
// traslo la seconda
|
||||
pSTM2->Translate( Vector3d( 0, 0, dHeight)) ;
|
||||
STM2.Translate( Vector3d( 0, 0, dHeight)) ;
|
||||
// le unisco alla superficie del fianco
|
||||
if ( ! pSTM->DoSewing( *pSTM1) || ! pSTM->DoSewing( *pSTM2))
|
||||
if ( ! pSTM->DoSewing( STM1) || ! pSTM->DoSewing( STM2))
|
||||
return nullptr ;
|
||||
// restituisco la superficie
|
||||
return Release( pSTM) ;
|
||||
}
|
||||
//-------------------------------------------------------------------------------
|
||||
static ISurfTriMesh*
|
||||
static SurfTriMesh*
|
||||
GetRegularSurfTriMeshBox( double dDimX, double dDimY, double dHeight)
|
||||
{
|
||||
// i triangoli devono essere quasi equilateri pertanto calcolo come dividere le varie parti
|
||||
@@ -92,15 +91,15 @@ GetRegularSurfTriMeshBox( double dDimX, double dDimY, double dHeight)
|
||||
// vettore altezza (estrusione)
|
||||
Vector3d vtExtr1( 0, 0, dStepZ) ;
|
||||
// creo e unisco le superfici trimesh laterali
|
||||
PtrOwner<ISurfTriMesh> pSTM1 ;
|
||||
PtrOwner<SurfTriMesh> pSTM1 ;
|
||||
for ( int k = 0 ; k < nStepZ ; ++ k) {
|
||||
PtrOwner<ISurfTriMesh> pSTMz( CreateSurfTriMesh()) ;
|
||||
if ( IsNull( pSTMz) || ! pSTMz->CreateByExtrusion( PL1, vtExtr1))
|
||||
SurfTriMesh STMz ;
|
||||
if ( ! STMz.CreateByExtrusion( PL1, vtExtr1))
|
||||
return nullptr ;
|
||||
pSTMz->Translate( Vector3d( 0, 0, k * dStepZ)) ;
|
||||
STMz.Translate( Vector3d( 0, 0, k * dStepZ)) ;
|
||||
if ( IsNull( pSTM1))
|
||||
pSTM1.Set( Release( pSTMz)) ;
|
||||
else if ( ! pSTM1->DoSewing( *pSTMz))
|
||||
pSTM1.Set( STMz.Clone()) ;
|
||||
else if ( ! pSTM1->DoSewing( STMz))
|
||||
return nullptr ;
|
||||
}
|
||||
// creo la polilinea del lato sinistro della superficie inferiore
|
||||
@@ -112,26 +111,24 @@ GetRegularSurfTriMeshBox( double dDimX, double dDimY, double dHeight)
|
||||
// vettore estrusione
|
||||
Vector3d vtExtr2( dStepX, 0, 0) ;
|
||||
// creo e unisco le superfici trimesh inferiori
|
||||
PtrOwner<ISurfTriMesh> pSTM2 ;
|
||||
SurfTriMesh STM2 ;
|
||||
for ( int i = 0 ; i < nStepX ; ++ i) {
|
||||
PtrOwner<ISurfTriMesh> pSTMx( CreateSurfTriMesh()) ;
|
||||
if ( IsNull( pSTMx) || ! pSTMx->CreateByExtrusion( PL2, vtExtr2))
|
||||
SurfTriMesh STMx ;
|
||||
if ( ! STMx.CreateByExtrusion( PL2, vtExtr2))
|
||||
return nullptr ;
|
||||
pSTMx->Translate( Vector3d( i * dStepX, 0, 0)) ;
|
||||
if ( IsNull( pSTM2))
|
||||
pSTM2.Set( Release( pSTMx)) ;
|
||||
else if ( ! pSTM2->DoSewing( *pSTMx))
|
||||
STMx.Translate( Vector3d( i * dStepX, 0, 0)) ;
|
||||
if ( STM2.IsEmpty())
|
||||
STM2 = STMx ;
|
||||
else if ( ! STM2.DoSewing( STMx))
|
||||
return nullptr ;
|
||||
}
|
||||
// la copio
|
||||
PtrOwner<ISurfTriMesh> pSTM3( pSTM2->Clone()) ;
|
||||
if ( IsNull( pSTM3))
|
||||
return nullptr ;
|
||||
SurfTriMesh STM3 = STM2 ;
|
||||
// inverto e traslo la superficie superiore
|
||||
pSTM3->Invert() ;
|
||||
pSTM3->Translate( Vector3d( 0, 0, dHeight)) ;
|
||||
STM3.Invert() ;
|
||||
STM3.Translate( Vector3d( 0, 0, dHeight)) ;
|
||||
// le unisco alla superficie del fianco
|
||||
if ( ! pSTM1->DoSewing( *pSTM2) || ! pSTM1->DoSewing( *pSTM3))
|
||||
if ( ! pSTM1->DoSewing( STM2) || ! pSTM1->DoSewing( STM3))
|
||||
return nullptr ;
|
||||
// restituisco la superficie
|
||||
return Release( pSTM1) ;
|
||||
@@ -171,16 +168,16 @@ GetSurfTriMeshPyramid( double dDimX, double dDimY, double dHeight)
|
||||
// punto di vertice
|
||||
Point3d ptTip( 0.5 * dDimX, 0.5 * dDimY, dHeight) ;
|
||||
// creo e setto la superficie trimesh laterale
|
||||
PtrOwner<ISurfTriMesh> pSTM( CreateSurfTriMesh()) ;
|
||||
PtrOwner<SurfTriMesh> pSTM( CreateBasicSurfTriMesh()) ;
|
||||
if ( IsNull( pSTM) || ! pSTM->CreateByPointCurve( ptTip, PL))
|
||||
return nullptr ;
|
||||
// creo la superficie di base e ne inverto la normale
|
||||
PtrOwner<ISurfTriMesh> pSTM1( CreateSurfTriMesh()) ;
|
||||
if ( IsNull( pSTM1) || ! pSTM1->CreateByFlatContour( PL))
|
||||
SurfTriMesh STM1 ;
|
||||
if ( ! STM1.CreateByFlatContour( PL))
|
||||
return nullptr ;
|
||||
pSTM1->Invert() ;
|
||||
STM1.Invert() ;
|
||||
// la unisco alla superficie del fianco
|
||||
if ( ! pSTM->DoSewing( *pSTM1))
|
||||
if ( ! pSTM->DoSewing( STM1))
|
||||
return nullptr ;
|
||||
// restituisco la superficie
|
||||
return Release( pSTM) ;
|
||||
|
||||
+561
@@ -0,0 +1,561 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2023-2023
|
||||
//----------------------------------------------------------------------------
|
||||
// File : SurfAux.cpp Data : 09.08.23 Versione :
|
||||
// Contenuto : Implementazione di alcune funzioni di utilit? per le Superfici.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 09.08.23 DB Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "CurveAux.h"
|
||||
#include "GeoConst.h"
|
||||
#include "CurveLine.h"
|
||||
#include "CurveArc.h"
|
||||
#include "CurveBezier.h"
|
||||
#include "CurveComposite.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
#include "/EgtDev/Include/EGkSurf.h"
|
||||
#include "/EgtDev/Include/EGkSurfAux.h"
|
||||
#include "/EgtDev/Include/EGkSurfBezier.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
bool
|
||||
NurbsSurfaceCanonicalize( SNurbsSurfData& snData)
|
||||
{
|
||||
// per rendere una superficie non periodica devo recuperare i punti di controllo, suddivisi in isoparametriche lungo una direzione
|
||||
// e applicare la trasformazione ad ogni isoparametrica, sostituendola poi a quella originale. ( si mantiene il numero di punti)
|
||||
if ( snData.bPeriodicU ) {
|
||||
bool bIsRational = snData.bRat ;
|
||||
// vettore dei nodi
|
||||
DBLVECTOR vU ;
|
||||
int nKnot = (int) snData.vU.size() ;
|
||||
for ( int k = 0 ; k < nKnot ; ++k ) {
|
||||
double dKnot = snData.vU[k] ;
|
||||
vU.push_back( dKnot) ;
|
||||
}
|
||||
for( int j = 0 ; j < snData.nCPV ; ++j) {
|
||||
CNurbsData nuCurve ;
|
||||
nuCurve.bPeriodic = true ;
|
||||
nuCurve.nDeg = snData.nDegU ;
|
||||
nuCurve.vU = vU ;
|
||||
// vettore dei punti di controllo
|
||||
PNTVECTOR vPtCtrl ;
|
||||
// vettore dei pesi
|
||||
DBLVECTOR vWeCtrl ;
|
||||
for ( int i = 0 ; i < snData.nCPU ; ++i ) {
|
||||
if ( bIsRational) {
|
||||
vPtCtrl.push_back( snData.mCP[i][j] / snData.mW[i][j]) ;
|
||||
vWeCtrl.push_back( snData.mW[i][j]) ;
|
||||
}
|
||||
else
|
||||
vPtCtrl.push_back( snData.mCP[i][j]) ;
|
||||
}
|
||||
nuCurve.vCP = vPtCtrl ;
|
||||
nuCurve.vW = vWeCtrl ;
|
||||
// i punti dell' oggetto nuCurve devono essere in forma non omogenea
|
||||
NurbsCurveCanonicalize( nuCurve) ;
|
||||
for ( int i = 0 ; i < snData.nCPU ; ++i) {
|
||||
snData.mCP[i][j] = nuCurve.vCP[i] ;
|
||||
}
|
||||
snData.vU = nuCurve.vU ;
|
||||
}
|
||||
snData.bPeriodicU = false ;
|
||||
}
|
||||
if ( snData.bPeriodicV ) {
|
||||
bool bIsRational = snData.bRat ;
|
||||
// vettore dei nodi
|
||||
DBLVECTOR vV ;
|
||||
int nKnot = (int) snData.vV.size() ;
|
||||
for ( int k = 0 ; k < nKnot ; ++k ) {
|
||||
double dKnot = snData.vV[k] ;
|
||||
vV.push_back( dKnot) ;
|
||||
}
|
||||
for( int i = 0 ; i < snData.nCPU ; ++i) {
|
||||
CNurbsData nuCurve ;
|
||||
nuCurve.bPeriodic = true ;
|
||||
nuCurve.nDeg = snData.nDegV ;
|
||||
nuCurve.vU = vV ;
|
||||
// vettore dei punti di controllo
|
||||
PNTVECTOR vPtCtrl ;
|
||||
// vettore dei pesi
|
||||
DBLVECTOR vWeCtrl ;
|
||||
for ( int j = 0 ; j < snData.nCPV ; ++j ) {
|
||||
if ( bIsRational) {
|
||||
vPtCtrl.push_back( snData.mCP[i][j] / snData.mW[i][j]) ;
|
||||
vWeCtrl.push_back( snData.mW[i][j]) ;
|
||||
}
|
||||
else
|
||||
vPtCtrl.push_back( snData.mCP[i][j]) ;
|
||||
}
|
||||
nuCurve.vCP = vPtCtrl ;
|
||||
nuCurve.vW = vWeCtrl ;
|
||||
// i punti dell' oggetto nuCurve devono essere in forma non omogenea
|
||||
NurbsCurveCanonicalize( nuCurve) ;
|
||||
for ( int j = 0 ; j < snData.nCPV ; ++j ) {
|
||||
snData.mCP[i][j] = nuCurve.vCP[j] ;
|
||||
}
|
||||
snData.vV = nuCurve.vU ;
|
||||
}
|
||||
snData.bPeriodicV = false ;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
ISurf*
|
||||
NurbsToBezierSurface(const SNurbsSurfData& snData)
|
||||
{
|
||||
//INTVECTOR vInt_sub( 10) ;
|
||||
//INTMATRIX vInt( 10, vInt_sub) ;
|
||||
//for ( int i = 0 ; i < 10 ; ++i ) {
|
||||
// for ( int j = 0 ; j < 10 ; ++j ) {
|
||||
// vInt[i][j] = i + 10 * j ;
|
||||
// }
|
||||
//}
|
||||
//vInt_sub.resize( 20) ;
|
||||
//vInt[0].resize( 20) ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// la superficie Nurbs deve essere in forma canonica
|
||||
if ( snData.bPeriodicU || snData.bPeriodicV || snData.bExtraKnotes )
|
||||
return nullptr ;
|
||||
// controllo sul numero dei nodi
|
||||
int nU = snData.nCPU + snData.nDegU - 1 ;
|
||||
int nV = snData.nCPV + snData.nDegV - 1 ;
|
||||
// controllo nodi e punti di controllo
|
||||
//if ( nU != int( snData.vU.size()) || nV != int( snData.vV.size()) || snData.nCPU * snData.nCPV != int( snData.vCP.size()))
|
||||
if ( nU != int(snData.vU.size()) || nV != int(snData.vV.size())) {
|
||||
return nullptr ;
|
||||
}
|
||||
|
||||
//// numero degli intervalli
|
||||
//int nInt = nU - 2 * snData.nDeg + 1 ;
|
||||
// verifico le condizioni agli estremi sui nodi (i primi nDeg nodi e gli ultimi nDeg nodi devono essere uguali tra loro)
|
||||
bool bOk = true ;
|
||||
// direzione U
|
||||
for ( int i = 1 ; i < snData.nDegU ; ++ i) {
|
||||
if ( abs( snData.vU[i] - snData.vU[0]) >= EPS_ZERO)
|
||||
bOk = false ;
|
||||
}
|
||||
for ( int i = 1 ; i < snData.nDegU ; ++ i) {
|
||||
if ( abs( snData.vU[nU - 1 - i] - snData.vU[nU - 1]) >= EPS_ZERO)
|
||||
bOk = false ;
|
||||
}
|
||||
// direzione V
|
||||
for ( int i = 1 ; i < snData.nDegV ; ++ i) {
|
||||
if ( abs( snData.vV[i] - snData.vV[0]) >= EPS_ZERO)
|
||||
bOk = false ;
|
||||
}
|
||||
for ( int i = 1 ; i < snData.nDegV ; ++ i) {
|
||||
if ( abs( snData.vV[nV - 1 - i] - snData.vV[nV - 1]) >= EPS_ZERO)
|
||||
bOk = false ;
|
||||
}
|
||||
if ( ! bOk)
|
||||
return nullptr ;
|
||||
|
||||
//// se 1 solo intervallo, la Nurbs ? gi? una curva di Bezier
|
||||
//if ( nInt == 1) {
|
||||
// // creo la curva di Bezier
|
||||
// PtrOwner<ICurveBezier> pCrvBez( CreateCurveBezier()) ;
|
||||
// if ( IsNull( pCrvBez))
|
||||
// return nullptr ;
|
||||
// // la inizializzo
|
||||
// if ( ! pCrvBez->Init( snData.nDeg, snData.bRat))
|
||||
// return nullptr ;
|
||||
// for ( int i = 0 ; i <= snData.nDeg ; ++ i) {
|
||||
// if ( ! snData.bRat) {
|
||||
// if ( ! pCrvBez->SetControlPoint( i, snData.vCP[i]))
|
||||
// return nullptr ;
|
||||
// }
|
||||
// else {
|
||||
// if ( ! pCrvBez->SetControlPoint( i, snData.vCP[i], snData.vW[i]))
|
||||
// return nullptr ;
|
||||
// }
|
||||
// }
|
||||
// // se non ? una curva ma un punto, la invalido
|
||||
// if ( pCrvBez->IsAPoint())
|
||||
// pCrvBez->Init( snData.nDeg, snData.bRat) ;
|
||||
// // restituisco la curva
|
||||
// return Release( pCrvBez) ;
|
||||
//}
|
||||
|
||||
|
||||
// algoritmo 5.7 del libro "The NURBS book"//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// creazione delle strips nella direzione U ( trasformo le curve iso con U costante in bezier)
|
||||
int a = snData.nDegU - 1 ;
|
||||
int b = snData.nDegU ;
|
||||
int nb = 0 ; // numero di strisce in U ( lunghezza con U costante)
|
||||
//PNTVECTOR vBC ;
|
||||
//vBC.resize( snData.nCPV * snData.nDegU) ;
|
||||
//for (int row = 0 ; row < snData.nCPV ; ++row ) {
|
||||
// for ( int i = 0 ; i <= snData.nDegU ; ++i ) {
|
||||
// vBC[nDegU*row + i] = ( snData.vCP[nCPU*row + i]) ;
|
||||
// }
|
||||
//}
|
||||
vector<Point3d> vCPV( snData.nCPV) ;
|
||||
vector< vector<Point3d>> mBC (snData.nDegU + 1,vCPV ) ;
|
||||
vector< vector<Point3d>> mBC_next (snData.nDegU - 1, vCPV) ;
|
||||
vector< vector<Point3d>> mPC_strip(snData.nDegU + 1, vCPV) ; // matrice che verr? ingrandita e conterr? la superficie met? bezier e met? NURBS
|
||||
DBLVECTOR vV_W( snData.nCPV) ;
|
||||
vector<DBLVECTOR> mW( snData.nDegU + 1, vV_W) ;
|
||||
vector<DBLVECTOR> mW_next( snData.nDegU - 1, vV_W) ;
|
||||
vector<DBLVECTOR> mW_strip( snData.nDegU + 1, vV_W) ;
|
||||
DBLVECTOR vAlpha ;
|
||||
vAlpha.resize( snData.nDegU - 1) ;
|
||||
if ( ! snData.bRat ) {
|
||||
for ( int i = 0 ; i <= snData.nDegU ; ++i ) {
|
||||
for ( int row = 0 ; row < snData.nCPV ; ++row ) {
|
||||
mBC[i][row] = snData.mCP[i][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( int i = 0 ; i <= snData.nDegU ; ++i ) {
|
||||
for (int row = 0 ; row < snData.nCPV ; ++ row) {
|
||||
mW[i][row] = snData.mW[i][row] ;
|
||||
mBC[i][row] = snData.mCP[i][row] * snData.mW[i][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool bRef = false ;
|
||||
// se la superficie ? lineare nel parametro U allora ? gi? in forma di Bezier in questo parametro
|
||||
if ( b == nU - 1 ) {
|
||||
nb = 1 ;
|
||||
}
|
||||
while ( b < nU - 1) { // qui correggo un probabile errore, mettendo nU anzich? nCPV, come indicato nell'algoritmo
|
||||
int i = b ;
|
||||
while ( b < nU - 1 && abs( snData.vU[b+1] - snData.vU[b]) < EPS_ZERO)
|
||||
++ b ;
|
||||
int mult = b - i + 1 ;
|
||||
if ( mult < snData.nDegU ) {
|
||||
bRef = true ;
|
||||
// calcolo numeratore e alpha
|
||||
double numer = snData.vU[b] - snData.vU[a] ;
|
||||
for ( int j = snData.nDegU ; j > mult ; -- j)
|
||||
vAlpha[j-mult-1] = numer / ( snData.vU[a+j] - snData.vU[a]) ;
|
||||
int r = snData.nDegU - mult ;
|
||||
for ( int j = 1 ; j <= snData.nDegU - mult ; ++j ) {
|
||||
int save = r - j ;
|
||||
int s = mult + j ;
|
||||
//for ( int row = 0 ; row < snData.nCPV ; ++row) {
|
||||
// for ( int k = snData.nDegU ; k >= s ; --k ) {
|
||||
// vBC[nCPU*row + k] = vAlpha[k-s]*vBC[nCPU*row + k] + ( 1 - vAlfa[k-s]) * vBC[nCPU*row + k - 1]
|
||||
// }
|
||||
//}
|
||||
if ( ! snData.bRat ) {
|
||||
for ( int k = snData.nDegU ; k >= s ; --k ) {
|
||||
for ( int row = 0 ; row < snData.nCPV ; ++row) {
|
||||
mBC[k][row] = vAlpha[k-s] * mBC[k][row] + ( 1 - vAlpha[k-s]) * mBC[k-1][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( int k = snData.nDegU ; k >= s ; --k ) {
|
||||
for ( int row = 0 ; row < snData.nCPV ; ++row) {
|
||||
mBC[k][row] = vAlpha[k-s] * mBC[k][row] + ( 1 - vAlpha[k-s]) * mBC[k-1][row] ;
|
||||
mW[k][row] = vAlpha[k-s] * mW[k][row] + ( 1 - vAlpha[k-s]) * mW[k-1][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( b < nU - 1 ) {
|
||||
for ( int row = 0 ; row < snData.nCPV ; ++row) {
|
||||
mBC_next[save][row] = mBC[snData.nDegU][row] ;
|
||||
}
|
||||
if ( snData.bRat )
|
||||
for ( int row = 0 ; row < snData.nCPV ; ++row) {
|
||||
mW_next[save][row] = mW[snData.nDegU][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mPC_strip.resize( snData.nDegU * ( nb + 1) + 1 , vCPV) ;
|
||||
mW_strip.resize( snData.nDegU * ( nb + 1) + 1, vV_W) ;
|
||||
if ( ! snData.bRat)
|
||||
for ( int i = 0 ; i <= snData.nDegU ; ++i) {
|
||||
for ( int row = 0 ; row < snData.nCPV ; ++row ) {
|
||||
mPC_strip[i+ nb * snData.nDegU][row] = mBC[i][row] ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( int i = 0 ; i <= snData.nDegU ; ++i) {
|
||||
for ( int row = 0 ; row < snData.nCPV ; ++row ) {
|
||||
mPC_strip[i+ nb * snData.nDegU][row] = mBC[i][row]/mW[i][row] ;
|
||||
mW_strip[i+ nb * snData.nDegU][row] = mW[i][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
++ nb ;
|
||||
// ho finito di definire la patch di Bezier attuale e passo alla successiva
|
||||
|
||||
// aggiorno mBC con i valori della prossima pezza di Bezier // corrisponde a nb = nb + 1
|
||||
if ( ! snData.bRat){
|
||||
for (int i = 0 ; i < snData.nDegU - 1 ; ++ i) {
|
||||
for ( int row = 0 ; row < snData.nCPV ; ++row) {
|
||||
mBC[i][row] = mBC_next[i][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int i = 0 ; i < snData.nDegU - 1 ; ++ i) {
|
||||
for ( int row = 0 ; row < snData.nCPV ; ++row) {
|
||||
mBC[i][row] = mBC_next[i][row] ;
|
||||
mW[i][row] = mW_next[i][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( b < nU - 1 ) {
|
||||
for ( int i = snData.nDegU - mult ; i <= snData.nDegU ; ++ i) {
|
||||
for (int row = 0 ; row < snData.nCPV ; ++ row ) {
|
||||
mBC[i][row] = snData.mCP[b - snData.nDegU + i + 1][row] ;
|
||||
}
|
||||
}
|
||||
if ( snData.bRat ) {
|
||||
for ( int i = snData.nDegU - mult ; i <= snData.nDegU ; ++ i) {
|
||||
for (int row = 0 ; row < snData.nCPV ; ++ row ) {
|
||||
mW[i][row] = snData.mW[b - snData.nDegU + i + 1][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
a = b ;
|
||||
++b ;
|
||||
}
|
||||
}
|
||||
|
||||
// se non ho raffinato allora tutti i nodi avevano gi? molteplicit? massima. Converto direttamente in Bezier la dir U
|
||||
int nCPU_ref ; // numero dei punti di controllo in U dopo il raffinamento
|
||||
if ( ! bRef ) {
|
||||
nCPU_ref = snData.nCPU ;
|
||||
mPC_strip.resize( snData.nCPU, vCPV) ;
|
||||
mW_strip.resize( snData.nCPU, vV_W) ;
|
||||
if ( ! snData.bRat) {
|
||||
for ( int i = 0 ; i < nCPU_ref ; ++i) {
|
||||
for ( int row = 0 ; row < snData.nCPV ; ++ row) {
|
||||
mPC_strip[i][row] = snData.mCP[i][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( int i = 0 ; i < nCPU_ref ; ++i) {
|
||||
for ( int row = 0 ; row < snData.nCPV ; ++ row) {
|
||||
mPC_strip[i][row] = snData.mCP[i][row] ;
|
||||
mW_strip[i][row] = snData.mW[i][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
// devo vedere quante patch ci stanno prendendo i punti che ci sono
|
||||
//nb = (snData.nCPU - 1) / snData.nDegU ;
|
||||
}
|
||||
else
|
||||
nCPU_ref = snData.nDegU * nb + 1 ; // numero dei punti di controllo in U dopo il raffinamento
|
||||
|
||||
// ora ho ottenuto le strisce nDegU x nCPV
|
||||
// devo ripetere la procedura, sulla dir V, per ottenere le patch nDegU x nDegV
|
||||
a = snData.nDegV - 1 ;
|
||||
b = snData.nDegV ;
|
||||
int nc = 0 ; // numero di strisce in V ( lunghezza con V costante)
|
||||
vector<Point3d> vDegV(snData.nDegV + 1) ;
|
||||
vector<Point3d> vDegV_1(snData.nDegV - 1) ;
|
||||
vector< vector<Point3d>> m_BC1( nCPU_ref, vDegV) ;
|
||||
vector< vector<Point3d>> m_BC1_next( nCPU_ref, vDegV_1) ;
|
||||
DBLVECTOR vV1_W(snData.nDegV + 1) ;
|
||||
DBLVECTOR vV2_W(snData.nDegV - 1) ;
|
||||
vector<DBLVECTOR> mW1( nCPU_ref, vV1_W) ;
|
||||
vector<DBLVECTOR> mW1_next( nCPU_ref, vV2_W) ;
|
||||
DBLVECTOR vAlpha1( snData.nDegV - 1) ;
|
||||
vector<vector<Point3d>> mPC_tot( nCPU_ref, vDegV) ;
|
||||
vector<DBLVECTOR> mW_tot( nCPU_ref, vV1_W) ;
|
||||
if ( ! snData.bRat ) {
|
||||
for ( int i = 0 ; i < nCPU_ref ; ++i ) {
|
||||
for ( int row = 0 ; row <= snData.nDegV ; ++row ) {
|
||||
m_BC1[i][row] = mPC_strip[i][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( int i = 0 ; i < nCPU_ref ; ++i ) {
|
||||
for (int row = 0 ; row <= snData.nDegV ; ++ row) {
|
||||
mW1[i][row] = mW_strip[i][row] ;
|
||||
m_BC1[i][row] = mPC_strip[i][row] * mW_strip[i][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bRef = false ;
|
||||
// se la superficie ? lineare nel parametro V allora ? gi? in forma di Bezier in questo parametro
|
||||
if ( b == nV - 1 ) {
|
||||
nc = 1 ;
|
||||
}
|
||||
while ( b < nV - 1) {
|
||||
int i = b ;
|
||||
while ( b < nV - 1 && abs( snData.vV[b+1] - snData.vV[b]) < EPS_ZERO)
|
||||
++ b ;
|
||||
int mult = b - i + 1 ;
|
||||
if ( mult < snData.nDegV ) {
|
||||
bRef = true ;
|
||||
// calcolo numeratore e alpha
|
||||
double numer = snData.vV[b] - snData.vV[a] ;
|
||||
for ( int j = snData.nDegV ; j > mult ; -- j)
|
||||
vAlpha1[j-mult-1] = numer / ( snData.vV[a+j] - snData.vV[a]) ;
|
||||
int r = snData.nDegV - mult ;
|
||||
for ( int j = 1 ; j <= snData.nDegV - mult ; ++j ) {
|
||||
int save = r - j ;
|
||||
int s = mult + j ;
|
||||
//for ( int row = 0 ; row < snData.nCPV ; ++row) {
|
||||
// for ( int k = snData.nDegU ; k >= s ; --k ) {
|
||||
// vBC[nCPU*row + k] = vAlpha1[k-s]*vBC[nCPU*row + k] + ( 1 - vAlpha1[k-s]) * vBC[nCPU*row + k - 1]
|
||||
// }
|
||||
//}
|
||||
if ( ! snData.bRat) {
|
||||
for ( int k = 0 ; k < nCPU_ref ; ++k) {
|
||||
for ( int row = snData.nDegV ; row >= s ; --row ) {
|
||||
m_BC1[k][row] = vAlpha1[row-s] * m_BC1[k][row] + ( 1 - vAlpha1[row-s]) * m_BC1[k][row-1] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( int k = 0 ; k < nCPU_ref ; ++k) {
|
||||
for ( int row = snData.nDegV ; row >= s ; --row ) {
|
||||
m_BC1[k][row] = vAlpha1[row-s] * m_BC1[k][row] + ( 1 - vAlpha1[row-s]) * m_BC1[k][row-1] ;
|
||||
mW1[k][row] = vAlpha1[row-s] * mW1[k][row] + ( 1 - vAlpha1[row-s]) * mW1[k][row-1] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( b < nV - 1 ) {
|
||||
if ( !snData.bRat ){
|
||||
for ( int i = 0 ; i < nCPU_ref ; ++i) {
|
||||
m_BC1_next[i][save] = m_BC1[i][snData.nDegV] ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( int i = 0 ; i < nCPU_ref ; ++i) {
|
||||
m_BC1_next[i][save] = m_BC1[i][snData.nDegV] ;
|
||||
mW1_next[save] = mW1[snData.nDegV] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int nRef = snData.nDegV * ( nc + 1) + 1 ;
|
||||
for ( int k = 0 ; k < nCPU_ref; ++k){
|
||||
mPC_tot[k].resize( nRef) ;
|
||||
mW_tot[k].resize( nRef) ;
|
||||
}
|
||||
if ( ! snData.bRat)
|
||||
for ( int i = 0 ; i < nCPU_ref ; ++i) {
|
||||
for ( int row = 0 ; row <= snData.nDegV ; ++row ) {
|
||||
mPC_tot[i][row + nc * snData.nDegV] = m_BC1[i][row] ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( int i = 0 ; i < nCPU_ref ; ++i) {
|
||||
for ( int row = 0 ; row <= snData.nDegV ; ++row ) {
|
||||
mPC_tot[i][row + nc * snData.nDegV] = m_BC1[i][row]/mW1[i][row] ;
|
||||
mW_tot[i][row + nc * snData.nDegV] = mW1[i][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
++ nc ;
|
||||
// ho finito di definire la patch di Bezier attuale e passo alla successiva
|
||||
|
||||
// aggiorno mBC con i valori della prossima pezza di Bezier // corrisponde a nc = nc + 1
|
||||
if ( ! snData.bRat){
|
||||
for (int i = 0 ; i < nCPU_ref ; ++ i) {
|
||||
for ( int row = 0 ; row < snData.nDegV - 1 ; ++row) {
|
||||
m_BC1[i][row] = m_BC1_next[i][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int i = 0 ; i < nCPU_ref ; ++ i) {
|
||||
for ( int row = 0 ; row < snData.nDegV - 1 ; ++row) {
|
||||
m_BC1[i][row] = m_BC1_next[i][row] ;
|
||||
mW1[i][row] = mW1_next[i][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( b < nV - 1) {
|
||||
for (int i = 0 ; i < nCPU_ref ; ++ i ) {
|
||||
for ( int row = snData.nDegV - mult ; row <= snData.nDegV ; ++ row) {
|
||||
//m_BC1[i][row] = snData.mCP[i][b - snData.nDegV + row + 1] ;
|
||||
m_BC1[i][row] = mPC_strip[i][b - snData.nDegV + row + 1] ;
|
||||
}
|
||||
}
|
||||
if ( snData.bRat ) {
|
||||
for (int i = 0 ; i < nCPU_ref ; ++ i ) {
|
||||
for ( int row = snData.nDegV - mult ; row <= snData.nDegV ; ++ row) {
|
||||
//mW1[i][row] = snData.mW[i][b - snData.nDegV + row + 1] ;
|
||||
mW1[i][row] = mW_strip[i][b - snData.nDegV + row + 1] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
a = b ;
|
||||
++b ;
|
||||
}
|
||||
|
||||
}
|
||||
// se non ho raffinato allora aggiungo direttamente alle matrici della superficie totale
|
||||
int nCPV_ref ; // numero dei punti di controllo in V dopo il raffinamento
|
||||
if ( ! bRef) {
|
||||
nCPV_ref = snData.nCPV ;
|
||||
for ( int k = 0 ; k < nCPU_ref ; ++k){
|
||||
mPC_tot[k].resize( snData.nCPV) ;
|
||||
mW_tot[k].resize( snData.nCPV) ;
|
||||
}
|
||||
if ( ! snData.bRat) {
|
||||
for ( int i = 0 ; i < nCPU_ref ; ++i) {
|
||||
for ( int row = 0 ; row < nCPV_ref ; ++ row) {
|
||||
mPC_tot[i][row] = mPC_strip[i][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( int i = 0 ; i < nCPU_ref ; ++i) {
|
||||
for ( int row = 0 ; row < nCPV_ref ; ++ row) {
|
||||
mPC_tot[i][row] = mPC_strip[i][row] ;
|
||||
mW_tot[i][row] = mW_strip[i][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
// devo vedere quante patch ci stanno prendendo i punti che ci sono
|
||||
//nc = (snData.nCPV - 1) / snData.nDegV ;
|
||||
}
|
||||
else
|
||||
nCPV_ref = snData.nDegV * nc + 1 ;
|
||||
|
||||
// finalmente setto la superficie di bezier totale divisa in nb patch in U e nc patch in V
|
||||
PtrOwner<ISurfBezier> pSrfBz( CreateSurfBezier()) ;
|
||||
if ( IsNull( pSrfBz))
|
||||
return nullptr ;
|
||||
pSrfBz->Init(snData.nDegU, snData.nDegV, nb, nc, snData.bRat) ;
|
||||
if ( !snData.bRat ) {
|
||||
for ( int i = 0 ; i < nCPU_ref; ++ i) {
|
||||
for (int j = 0 ; j < nCPV_ref; ++j) {
|
||||
pSrfBz->SetControlPoint( i + nCPU_ref * j, mPC_tot[i][j]) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( int i = 0 ; i < nCPU_ref; ++ i) {
|
||||
for (int j = 0 ; j < nCPV_ref; ++j) {
|
||||
pSrfBz->SetControlPoint( i + nCPU_ref * j, mPC_tot[i][j] / mW_tot[i][j], mW_tot[i][j]) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
return Release( pSrfBz) ;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2023-2023
|
||||
//----------------------------------------------------------------------------
|
||||
// File : SurfAux.h Data : 09.08.23 Versione :
|
||||
// Contenuto : Dichiarazione di alcune funzioni di utilità per le superfici.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 09.08.23 DB Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "/EgtDev/Include/EGkSurfAux.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//bool IsClosed( const ICurve& crvC) ;
|
||||
//bool IsValidParam( const ICurve& crvC, double dPar, ICurve::Side nSide) ;
|
||||
//bool IsStartParam( const ICurve& crvC, double dPar) ;
|
||||
//bool IsEndParam( const ICurve& crvC, double dPar) ;
|
||||
//bool GetNearestExtremityToPoint( const Point3d& ptP, const ICurve& Curve, bool& bStart) ;
|
||||
//bool MoveParamToAvoidTg( double& dU, ICurve::Side nSide, const ICurve& Curve) ;
|
||||
//bool GetTang( const ICurve& crvC, double dU, ICurve::Side nS, Vector3d& vtTang) ;
|
||||
//bool GetPointTang( const ICurve& crvC, double dU, ICurve::Side nS, Point3d& ptPos, Vector3d& vtTang) ;
|
||||
//bool GetPointDiffGeom( const ICurve& crvC, double dU, ICurve::Side nS, CrvPointDiffGeom& oDiffG) ;
|
||||
//bool ImproveCurveParamAtPoint( double& dU, const Point3d& ptP, const ICurve* pCrv) ;
|
||||
//bool CurveGetAreaXY( const ICurve& crvC, double& dArea) ;
|
||||
//bool CurveGetArea( const ICurve& crvC, Plane3d& plPlane, double& dArea) ;
|
||||
//bool CurveDump( const ICurve& crvC, std::string& sOut, bool bMM, const char* szNewLine) ;
|
||||
//bool CopyExtrusion( const ICurve* pSouCrv, ICurve* pDestCrv) ;
|
||||
//bool CopyThickness( const ICurve* pSouCrv, ICurve* pDestCrv) ;
|
||||
+9
-8
@@ -550,7 +550,7 @@ SurfBezier::Clone( void) const
|
||||
bool
|
||||
SurfBezier::CopyFrom( const IGeoObj* pGObjSrc)
|
||||
{
|
||||
const SurfBezier* pSbz = dynamic_cast<const SurfBezier*>( pGObjSrc) ;
|
||||
const SurfBezier* pSbz = GetBasicSurfBezier( pGObjSrc) ;
|
||||
if ( pSbz == nullptr)
|
||||
return false ;
|
||||
return CopyFrom( *pSbz) ;
|
||||
@@ -822,7 +822,6 @@ SurfBezier::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, d
|
||||
// la superficie deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// verifico validità dell'asse di rotazione
|
||||
if ( vtAx.IsSmall())
|
||||
return false ;
|
||||
@@ -845,7 +844,6 @@ SurfBezier::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double
|
||||
// la superficie deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// verifico non sia nulla
|
||||
if ( abs( dCoeffX) < EPS_ZERO && abs( dCoeffY) < EPS_ZERO && abs( dCoeffZ) < EPS_ZERO)
|
||||
return false ;
|
||||
@@ -880,7 +878,6 @@ SurfBezier::Mirror( const Point3d& ptOn, const Vector3d& vtNorm)
|
||||
// la superficie deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// verifico validità del piano di specchiatura
|
||||
if ( vtNorm.IsSmall())
|
||||
return false ;
|
||||
@@ -904,7 +901,6 @@ SurfBezier::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d&
|
||||
// la superficie deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// verifico validità dei parametri
|
||||
if ( vtNorm.IsSmall() || vtDir.IsSmall())
|
||||
return false ;
|
||||
@@ -927,11 +923,14 @@ SurfBezier::ToGlob( const Frame3d& frRef)
|
||||
// la superficie deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// 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
|
||||
ResetAuxSurf() ;
|
||||
m_OGrMgr.Reset() ;
|
||||
@@ -950,11 +949,14 @@ SurfBezier::ToLoc( const Frame3d& frRef)
|
||||
// la superficie deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// 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
|
||||
ResetAuxSurf() ;
|
||||
m_OGrMgr.Reset() ;
|
||||
@@ -973,7 +975,6 @@ SurfBezier::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
|
||||
// la superficie deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// verifico validità dei frame
|
||||
if ( frOri.GetType() == Frame3d::ERR || frDest.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
|
||||
+6
-2
@@ -177,6 +177,10 @@ inline SurfBezier* CloneBasicSurfBezier( const IGeoObj* pGObj)
|
||||
return nullptr ;
|
||||
return ( static_cast<SurfBezier*>( pGObj->Clone())) ; }
|
||||
inline const SurfBezier* GetBasicSurfBezier( const IGeoObj* pGObj)
|
||||
{ return ( dynamic_cast<const SurfBezier*>( pGObj)) ; }
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != SRF_BEZIER)
|
||||
return nullptr ;
|
||||
return ( static_cast<const SurfBezier*>( pGObj)) ; }
|
||||
inline SurfBezier* GetBasicSurfBezier( IGeoObj* pGObj)
|
||||
{ return ( dynamic_cast<SurfBezier*>( pGObj)) ; }
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != SRF_BEZIER)
|
||||
return nullptr ;
|
||||
return ( static_cast<SurfBezier*>( pGObj)) ; }
|
||||
|
||||
+54
-10
@@ -103,7 +103,7 @@ SurfFlatRegion::AddExtLoop( ICurve* pCrv)
|
||||
pMyCrv->SetThickness( 0) ;
|
||||
// rimuovo eventuali sovrapposizioni (calcolate nel suo piano)
|
||||
ICURVEPLIST CrvLst ;
|
||||
if ( ! AdjustLoops( Release( pMyCrv), CrvLst))
|
||||
if ( ! AdjustLoops( Release( pMyCrv), CrvLst, true))
|
||||
return false ;
|
||||
// aggiungo le singole curve
|
||||
bool bOk = true ;
|
||||
@@ -143,11 +143,11 @@ SurfFlatRegion::AddSimpleExtLoop( ICurve* pCrv)
|
||||
else {
|
||||
// verifico che il piano della curva coincida con quello XY intrinseco
|
||||
plPlane.ToLoc( m_frF) ;
|
||||
if ( ! ( plPlane.GetVersN().IsZplus() || plPlane.GetVersN().IsZminus()) || abs( plPlane.GetDist()) > EPS_SMALL)
|
||||
if ( ! plPlane.GetVersN().IsZ() || abs( plPlane.GetDist()) > EPS_SMALL)
|
||||
return false ;
|
||||
// sistemo il senso di rotazione (deve essere CCW -> area > 0)
|
||||
if ( ( plPlane.GetVersN().IsZplus() && dArea < 0) ||
|
||||
( plPlane.GetVersN().IsZminus() && dArea > 0))
|
||||
if ( ( plPlane.GetVersN().z > 0 && dArea < 0) ||
|
||||
( plPlane.GetVersN().z < 0 && dArea > 0))
|
||||
pMyCrv->Invert() ;
|
||||
}
|
||||
// porto la curva nel riferimento intrinseco
|
||||
@@ -247,7 +247,7 @@ SurfFlatRegion::AddIntLoop( ICurve* pCrv)
|
||||
pMyCrv->SetThickness( 0) ;
|
||||
// rimuovo eventuali sovrapposizioni (calcolate nel suo piano)
|
||||
ICURVEPLIST CrvLst ;
|
||||
if ( ! AdjustLoops( Release( pMyCrv), CrvLst))
|
||||
if ( ! AdjustLoops( Release( pMyCrv), CrvLst, true))
|
||||
return false ;
|
||||
// aggiungo le singole curve
|
||||
bool bOk = true ;
|
||||
@@ -283,10 +283,10 @@ SurfFlatRegion::AddSimpleIntLoop( ICurve* pCrv)
|
||||
Plane3d plPlane ;
|
||||
if ( ! pMyCrv->GetArea( plPlane, dArea))
|
||||
return false ;
|
||||
if ( ! ( plPlane.GetVersN().IsZplus() || plPlane.GetVersN().IsZminus()) || abs( plPlane.GetDist()) > EPS_SMALL)
|
||||
if ( ! plPlane.GetVersN().IsZ() || abs( plPlane.GetDist()) > EPS_SMALL)
|
||||
return false ;
|
||||
// sistemo il senso di rotazione (deve essere CW -> se N==Z+ area < 0, se N==Z- area>0)
|
||||
if ( ( plPlane.GetVersN().IsZplus() && dArea > 0) || ( plPlane.GetVersN().IsZminus() && dArea < 0))
|
||||
// sistemo il senso di rotazione (deve essere CW -> se N==Z+ area < 0, se N==Z- area > 0)
|
||||
if ( ( plPlane.GetVersN().z > 0 && dArea > 0) || ( plPlane.GetVersN().z < 0 && dArea < 0))
|
||||
pMyCrv->Invert() ;
|
||||
// verifico non abbia auto-intersezioni
|
||||
SelfIntersCurve sInt( *pMyCrv) ;
|
||||
@@ -378,7 +378,7 @@ SurfFlatRegion::Clone( void) const
|
||||
bool
|
||||
SurfFlatRegion::CopyFrom( const IGeoObj* pGObjSrc)
|
||||
{
|
||||
const SurfFlatRegion* pSfr = dynamic_cast<const SurfFlatRegion*>( pGObjSrc) ;
|
||||
const SurfFlatRegion* pSfr = GetBasicSurfFlatRegion( pGObjSrc) ;
|
||||
if ( pSfr == nullptr)
|
||||
return false ;
|
||||
return CopyFrom( *pSfr) ;
|
||||
@@ -597,7 +597,7 @@ SurfFlatRegion::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag) const
|
||||
// è il bounding box dei loop esterni
|
||||
for ( auto i : m_vExtInd) {
|
||||
BBox3d b3Tmp ;
|
||||
if ( m_vpLoop[i]->GetBBox( frCompo, b3Ref, nFlag))
|
||||
if ( m_vpLoop[i]->GetBBox( frCompo, b3Tmp, nFlag))
|
||||
b3Ref.Add( b3Tmp) ;
|
||||
}
|
||||
return ( ! b3Ref.IsEmpty()) ;
|
||||
@@ -625,9 +625,14 @@ SurfFlatRegion::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAn
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico validità dell'asse di rotazione
|
||||
if ( vtAx.IsSmall())
|
||||
return false ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
ResetAuxSurf() ;
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
// ruoto il riferimento
|
||||
return m_frF.Rotate( ptAx, vtAx, dCosAng, dSinAng) ;
|
||||
}
|
||||
@@ -639,6 +644,10 @@ SurfFlatRegion::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, dou
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK || m_vpLoop.empty())
|
||||
return false ;
|
||||
// verifico non sia nulla
|
||||
if ( abs( dCoeffX) < EPS_ZERO && abs( dCoeffY) < EPS_ZERO && abs( dCoeffZ) < EPS_ZERO)
|
||||
return false ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
ResetAuxSurf() ;
|
||||
m_OGrMgr.Reset() ;
|
||||
@@ -688,6 +697,10 @@ SurfFlatRegion::Mirror( const Point3d& ptOn, const Vector3d& vtNorm)
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK || m_vpLoop.empty())
|
||||
return false ;
|
||||
// verifico validità del piano di specchiatura
|
||||
if ( vtNorm.IsSmall())
|
||||
return false ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
ResetAuxSurf() ;
|
||||
m_OGrMgr.Reset() ;
|
||||
@@ -732,6 +745,10 @@ SurfFlatRegion::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK || m_vpLoop.empty())
|
||||
return false ;
|
||||
// verifico validità dei parametri
|
||||
if ( vtNorm.IsSmall() || vtDir.IsSmall())
|
||||
return false ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
ResetAuxSurf() ;
|
||||
m_OGrMgr.Reset() ;
|
||||
@@ -796,9 +813,18 @@ SurfFlatRegion::ToGlob( const Frame3d& frRef)
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// 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
|
||||
ResetAuxSurf() ;
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
// trasformo il riferimento
|
||||
return m_frF.ToGlob( frRef) ; ;
|
||||
}
|
||||
@@ -810,9 +836,18 @@ SurfFlatRegion::ToLoc( const Frame3d& frRef)
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// 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
|
||||
ResetAuxSurf() ;
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
// trasformo il riferimento
|
||||
return m_frF.ToLoc( frRef) ; ;
|
||||
}
|
||||
@@ -824,9 +859,18 @@ SurfFlatRegion::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico validità dei frame
|
||||
if ( frOri.GetType() == Frame3d::ERR || frDest.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
|
||||
// se i due riferimenti coincidono, non devo fare alcunché
|
||||
if ( AreSameFrame( frOri, frDest))
|
||||
return true ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
ResetAuxSurf() ;
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
// trasformo il riferimento
|
||||
return m_frF.LocToLoc( frOri, frDest) ; ;
|
||||
}
|
||||
|
||||
+8
-4
@@ -152,12 +152,16 @@ class SurfFlatRegion : public ISurfFlatRegion, public IGeoObjRW
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline SurfFlatRegion* CreateBasicSurfFlatRegion( void)
|
||||
{ return (static_cast<SurfFlatRegion*>( CreateGeoObj( SRF_FLATRGN))) ; }
|
||||
{ return ( static_cast<SurfFlatRegion*>( CreateGeoObj( SRF_FLATRGN))) ; }
|
||||
inline SurfFlatRegion* CloneBasicSurfFlatRegion( const IGeoObj* pGObj)
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != SRF_FLATRGN)
|
||||
return nullptr ;
|
||||
return (static_cast<SurfFlatRegion*>(pGObj->Clone())) ; }
|
||||
return ( static_cast<SurfFlatRegion*>( pGObj->Clone())) ; }
|
||||
inline const SurfFlatRegion* GetBasicSurfFlatRegion( const IGeoObj* pGObj)
|
||||
{ return (dynamic_cast<const SurfFlatRegion*>( pGObj)) ; }
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != SRF_FLATRGN)
|
||||
return nullptr ;
|
||||
return ( static_cast<const SurfFlatRegion*>( pGObj)) ; }
|
||||
inline SurfFlatRegion* GetBasicSurfFlatRegion( IGeoObj* pGObj)
|
||||
{ return (dynamic_cast<SurfFlatRegion*>( pGObj)) ; }
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != SRF_FLATRGN)
|
||||
return nullptr ;
|
||||
return ( static_cast<SurfFlatRegion*>( pGObj)) ; }
|
||||
|
||||
+21
-10
@@ -27,9 +27,10 @@ bool
|
||||
SurfFlatRegion::Add( const ISurfFlatRegion& Other)
|
||||
{
|
||||
// converto l'altra regione nell'oggetto base
|
||||
const SurfFlatRegion& SfrOther = dynamic_cast<const SurfFlatRegion&>( Other) ;
|
||||
if ( &SfrOther == nullptr)
|
||||
const SurfFlatRegion* pSfrOther = GetBasicSurfFlatRegion( &Other) ;
|
||||
if ( pSfrOther == nullptr)
|
||||
return false ;
|
||||
const SurfFlatRegion& SfrOther = *pSfrOther ;
|
||||
|
||||
// verifico che le due regioni giacciano in piani paralleli
|
||||
if ( ! AreSameVectorApprox( m_frF.VersZ(), SfrOther.m_frF.VersZ()))
|
||||
@@ -110,9 +111,10 @@ bool
|
||||
SurfFlatRegion::Subtract( const ISurfFlatRegion& Other)
|
||||
{
|
||||
// converto l'altra regione nell'oggetto base
|
||||
const SurfFlatRegion& SfrOther = dynamic_cast<const SurfFlatRegion&>( Other) ;
|
||||
if ( &SfrOther == nullptr)
|
||||
const SurfFlatRegion* pSfrOther = GetBasicSurfFlatRegion( &Other) ;
|
||||
if ( pSfrOther == nullptr)
|
||||
return false ;
|
||||
const SurfFlatRegion& SfrOther = *pSfrOther ;
|
||||
|
||||
// verifico che le due regioni giacciano in piani paralleli
|
||||
if ( ! AreSameVectorApprox( m_frF.VersZ(), SfrOther.m_frF.VersZ()))
|
||||
@@ -197,9 +199,10 @@ bool
|
||||
SurfFlatRegion::Intersect( const ISurfFlatRegion& Other)
|
||||
{
|
||||
// converto l'altra regione nell'oggetto base
|
||||
const SurfFlatRegion& SfrOther = dynamic_cast<const SurfFlatRegion&>( Other) ;
|
||||
if ( &SfrOther == nullptr)
|
||||
const SurfFlatRegion* pSfrOther = GetBasicSurfFlatRegion( &Other) ;
|
||||
if ( pSfrOther == nullptr)
|
||||
return false ;
|
||||
const SurfFlatRegion& SfrOther = *pSfrOther ;
|
||||
|
||||
// verifico che le due regioni giacciano in piani paralleli
|
||||
if ( ! AreSameVectorApprox( m_frF.VersZ(), SfrOther.m_frF.VersZ()))
|
||||
@@ -355,9 +358,10 @@ SurfFlatRegion::MyChainCurves( PCRV_DEQUE& vpCurve, PCRV_DEQUE& vpLoop)
|
||||
// recupero le curve e le inserisco nella nuova curva composita
|
||||
for ( auto i : vIds) {
|
||||
// la aggiungo alla curva composta
|
||||
if ( ! pCrvCompo->AddCurve( vpCurve[i-1], true, dToler))
|
||||
return false ;
|
||||
bool bOk = pCrvCompo->AddCurve( vpCurve[i-1], true, dToler) ;
|
||||
vpCurve[i-1] = nullptr ;
|
||||
if ( ! bOk)
|
||||
return false ;
|
||||
}
|
||||
// aggiorno il nuovo punto vicino
|
||||
if ( pCrvCompo->GetCurveCount() > 0)
|
||||
@@ -396,11 +400,18 @@ SurfFlatRegion::MyNewSurfFromLoops( PCRV_DEQUE& vpLoop)
|
||||
typedef vector<INDAREA> INDAREAVECTOR ; // vettore di coppie indice, area
|
||||
INDAREAVECTOR vArea ;
|
||||
vArea.reserve( vpLoop.size()) ;
|
||||
for ( int i = 0 ; i < int( vpLoop.size()) ; ++ i) {
|
||||
for ( int i = 0 ; i < int( vpLoop.size()) ;) {
|
||||
double dArea ;
|
||||
if ( ! vpLoop[i]->GetAreaXY( dArea))
|
||||
return nullptr ;
|
||||
vArea.emplace_back( i, dArea) ;
|
||||
if ( abs( dArea) > SQ_EPS_SMALL) {
|
||||
vArea.emplace_back( i, dArea) ;
|
||||
++ i ;
|
||||
}
|
||||
else {
|
||||
delete vpLoop[i] ;
|
||||
vpLoop.erase( vpLoop.begin() + i) ;
|
||||
}
|
||||
}
|
||||
// ordino in senso decrescente sull'area
|
||||
sort( vArea.begin(), vArea.end(),
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "GeoConst.h"
|
||||
#include "CurveComposite.h"
|
||||
#include "SurfFlatRegion.h"
|
||||
#include "/EgtDev/Include/EGkOffsetCurve.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
@@ -55,6 +57,18 @@ SurfFlatRegion::Offset( double dDist, int nType)
|
||||
// recupero le curve di offset
|
||||
PtrOwner<ICurve> pOffs( OffsCrv.GetLongerCurve()) ;
|
||||
while ( bOk && ! IsNull( pOffs)) {
|
||||
if ( pOffs->GetType() == CRV_COMPO) {
|
||||
CurveComposite* pOffsCompo = GetBasicCurveComposite( pOffs) ;
|
||||
// assegno proprietà
|
||||
pOffsCompo->SetTempProp( j, 1) ;
|
||||
for ( int k = 0 ; k < pOffsCompo->GetCurveCount() ; ++k)
|
||||
pOffsCompo->SetCurveTempProp( k, j, 1) ;
|
||||
// unisco parti allineate
|
||||
if ( ! pOffsCompo->MergeCurves( 10 * EPS_SMALL, ANG_TOL_STD_DEG, true))
|
||||
return false ;
|
||||
}
|
||||
else
|
||||
pOffs->SetTempProp( j, 1) ;
|
||||
// se prima curva esterna, è il primo contorno esterno della nuova regione
|
||||
if ( j == 0 && bFirstCurve) {
|
||||
if ( ! pSfrChk->AddExtLoop( Release( pOffs)))
|
||||
|
||||
+99
-32
@@ -107,18 +107,43 @@ SurfTriMesh::Clear( void)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
SurfTriMesh::AddVertex( const Point3d& ptVert)
|
||||
SurfTriMesh::AddVertex( const Point3d& ptVert, const double dU, const double dV)
|
||||
{
|
||||
// imposto ricalcolo
|
||||
m_nStatus = TO_VERIFY ;
|
||||
m_nParts = - 1 ;
|
||||
m_OGrMgr.Reset() ;
|
||||
ResetHashGrids3d() ;
|
||||
// inserisco il vertice
|
||||
try { m_vVert.emplace_back( ptVert) ;}
|
||||
catch(...) { return SVT_NULL ;}
|
||||
// ne determino l'indice
|
||||
int nId = int( m_vVert.size() - 1) ;
|
||||
// aggiugo le coordinate corrispondenti allo spazio parametrico
|
||||
m_vVert[nId].dU = dU ;
|
||||
m_vVert[nId].dV = dV ;
|
||||
return nId ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::MoveVertex( int nInd, const Point3d& ptNewVert)
|
||||
{
|
||||
// verifico validità indice
|
||||
if ( nInd < 0 || nInd >= int( m_vVert.size()))
|
||||
return false ;
|
||||
// verifico non sia già cancellato
|
||||
if ( m_vVert[nInd].nIdTria == SVT_DEL)
|
||||
return false ;
|
||||
// sposto il vertice
|
||||
m_vVert[nInd].ptP = ptNewVert ;
|
||||
// imposto ricalcolo
|
||||
m_nStatus = TO_VERIFY ;
|
||||
m_nParts = - 1 ;
|
||||
m_OGrMgr.Reset() ;
|
||||
ResetHashGrids3d() ;
|
||||
// inserisco il vertice
|
||||
try { m_vVert.emplace_back( ptVert) ;}
|
||||
catch(...) { return SVT_NULL ;}
|
||||
// ne determino l'indice
|
||||
return int( m_vVert.size() - 1) ;
|
||||
// per aggiornare completamente la superficie chiamare DoCompacting
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -454,6 +479,20 @@ SurfTriMesh::GetVertex( int nId, Point3d& ptP) const
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::GetVertexParam( int nId, double& dU, double& dV) const
|
||||
{
|
||||
// verifico esistenza del vertice
|
||||
if ( nId < 0 || nId >= GetVertexSize() || m_vVert[nId].nIdTria == SVT_DEL)
|
||||
return false ;
|
||||
// recupero i dati
|
||||
dU = m_vVert[nId].dU ;
|
||||
dV = m_vVert[nId].dV ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
SurfTriMesh::GetFirstVertex( Point3d& ptP) const
|
||||
@@ -461,6 +500,13 @@ SurfTriMesh::GetFirstVertex( Point3d& ptP) const
|
||||
return GetNextVertex( SVT_NULL, ptP) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
SurfTriMesh::GetFirstVertexParam( int nId, double& dU, double& dV) const
|
||||
{
|
||||
return GetNextVertexParam( SVT_NULL, dU, dV) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
SurfTriMesh::GetNextVertex( int nId, Point3d& ptP) const
|
||||
@@ -478,6 +524,24 @@ SurfTriMesh::GetNextVertex( int nId, Point3d& ptP) const
|
||||
return nId ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
SurfTriMesh::GetNextVertexParam( int nId, double& dU, double& dV) const
|
||||
{
|
||||
// cerco il primo successivo valido
|
||||
do {
|
||||
nId ++ ;
|
||||
} while ( nId < GetVertexSize() && m_vVert[nId].nIdTria == SVT_DEL) ;
|
||||
// se oltrepassata fine
|
||||
if ( nId >= GetVertexSize())
|
||||
return SVT_NULL ;
|
||||
// recupero i dati
|
||||
dU = m_vVert[nId].dU ;
|
||||
dV = m_vVert[nId].dV ;
|
||||
// ritorno indice triangolo corrente
|
||||
return nId ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::GetTriangle( int nId, int nIdVert[3]) const
|
||||
@@ -758,23 +822,23 @@ SurfTriMesh::GetTriangleAdjacencies( int nId, int nIdAdjTriaId[3]) const
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::GetTriangleFlag( int nId, int& nFlag) const
|
||||
SurfTriMesh::GetTFlag( int nTriaId, int& nTFlag) const
|
||||
{
|
||||
// verifico esistenza del triangolo
|
||||
if ( nId < 0 || nId >= GetTriangleSize() || m_vTria[nId].nIdVert[0] == SVT_DEL)
|
||||
if ( nTriaId < 0 || nTriaId >= GetTriangleSize() || m_vTria[nTriaId].nIdVert[0] == SVT_DEL)
|
||||
return false ;
|
||||
nFlag = m_vTria[nId].nTFlag ;
|
||||
nTFlag = m_vTria[nTriaId].nTFlag ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::GetTriangleTempInt( int nId, int& nTempInt) const
|
||||
SurfTriMesh::GetTempInt( int nTriaId, int& nTempInt) const
|
||||
{
|
||||
// verifico esistenza del triangolo
|
||||
if ( nId < 0 || nId >= GetTriangleSize() || m_vTria[nId].nIdVert[0] == SVT_DEL)
|
||||
if ( nTriaId < 0 || nTriaId >= GetTriangleSize() || m_vTria[nTriaId].nIdVert[0] == SVT_DEL)
|
||||
return false ;
|
||||
nTempInt = m_vTria[nId].nTemp ;
|
||||
nTempInt = m_vTria[nTriaId].nTemp ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
@@ -1105,7 +1169,7 @@ SurfTriMesh::GetSilhouette( const Vector3d& vtDir, double dTol, POLYLINEVECTOR&
|
||||
pSfrPart->Offset( dTol, ICurve::OFF_FILLET) ;
|
||||
if ( IsNull( pSfr))
|
||||
if ( pSfrPart->GetNormVersor() * vtVers > 0)
|
||||
bOk = pSfr.Set( Release( pSfrPart)) ;
|
||||
bOk = pSfr.Set( pSfrPart) ;
|
||||
else
|
||||
bOk = false ;
|
||||
else {
|
||||
@@ -1151,7 +1215,7 @@ SurfTriMesh::GetSilhouette( const Vector3d& vtDir, double dTol, POLYLINEVECTOR&
|
||||
if ( ! IsNull( pSfrTria)) {
|
||||
pSfrTria->Offset( dTol, ICurve::OFF_FILLET) ;
|
||||
if ( IsNull( pSfr))
|
||||
pSfr.Set( Release( pSfrTria)) ;
|
||||
pSfr.Set( pSfrTria) ;
|
||||
else
|
||||
pSfr->Add( *pSfrTria) ;
|
||||
}
|
||||
@@ -1199,7 +1263,7 @@ SurfTriMesh::Clone( void) const
|
||||
bool
|
||||
SurfTriMesh::CopyFrom( const IGeoObj* pGObjSrc)
|
||||
{
|
||||
const SurfTriMesh* pStm = dynamic_cast<const SurfTriMesh*>( pGObjSrc) ;
|
||||
const SurfTriMesh* pStm = GetBasicSurfTriMesh( pGObjSrc) ;
|
||||
if ( pStm == nullptr)
|
||||
return false ;
|
||||
return CopyFrom( *pStm) ;
|
||||
@@ -2950,14 +3014,13 @@ SurfTriMesh::DoCompacting( double dTol)
|
||||
|
||||
// sistemo gli indici dei vertici nei triangoli
|
||||
for ( int nId = 0 ; nId < GetTriangleSize() ; ++ nId) {
|
||||
// recupero gli indici dei vertici del triangolo
|
||||
int vOId[3] ;
|
||||
vOId[0] = m_vTria[nId].nIdVert[0] ;
|
||||
vOId[1] = m_vTria[nId].nIdVert[1] ;
|
||||
vOId[2] = m_vTria[nId].nIdVert[2] ;
|
||||
// salto i triangoli cancellati
|
||||
if ( vOId[0] == SVT_DEL)
|
||||
if ( m_vTria[nId].nIdVert[0] == SVT_DEL)
|
||||
continue ;
|
||||
// recupero gli indici dei vertici del triangolo
|
||||
int vOId[3]{ m_vTria[nId].nIdVert[0],
|
||||
m_vTria[nId].nIdVert[1],
|
||||
m_vTria[nId].nIdVert[2]} ;
|
||||
// verifico la validità degli indici
|
||||
if ( vOId[0] < 0 || vOId[0] >= nVIdSize ||
|
||||
vOId[1] < 0 || vOId[1] >= nVIdSize ||
|
||||
@@ -2967,11 +3030,12 @@ SurfTriMesh::DoCompacting( double dTol)
|
||||
m_vTria[nId].nIdVert[0] = vVId[vOId[0]] ;
|
||||
m_vTria[nId].nIdVert[1] = vVId[vOId[1]] ;
|
||||
m_vTria[nId].nIdVert[2] = vVId[vOId[2]] ;
|
||||
// se due vertici coincidono, cancello il triangolo
|
||||
// se due vertici coincidono o la normale non è calcolabile, cancello il triangolo
|
||||
if ( m_vTria[nId].nIdVert[0] == m_vTria[nId].nIdVert[1] ||
|
||||
m_vTria[nId].nIdVert[0] == m_vTria[nId].nIdVert[2] ||
|
||||
m_vTria[nId].nIdVert[1] == m_vTria[nId].nIdVert[2])
|
||||
RemoveTriangle( nId) ;
|
||||
m_vTria[nId].nIdVert[1] == m_vTria[nId].nIdVert[2] ||
|
||||
! CalcTriangleNormal( nId))
|
||||
RemoveTriangle( nId) ;
|
||||
}
|
||||
|
||||
// compatto il vettore dei vertici
|
||||
@@ -2992,7 +3056,7 @@ bool
|
||||
SurfTriMesh::DoSewing( const ISurfTriMesh& stmOther, const Frame3d& frOther, double dTol)
|
||||
{
|
||||
// recupero l'altra superficie
|
||||
const SurfTriMesh* pOther = dynamic_cast<const SurfTriMesh*>( &stmOther) ;
|
||||
const SurfTriMesh* pOther = GetBasicSurfTriMesh( &stmOther) ;
|
||||
if ( pOther == nullptr)
|
||||
return false ;
|
||||
|
||||
@@ -3003,7 +3067,7 @@ SurfTriMesh::DoSewing( const ISurfTriMesh& stmOther, const Frame3d& frOther, dou
|
||||
|
||||
// definisco un Grid per i vertici delle due superfici
|
||||
PointGrid3d VertGrid ;
|
||||
int nBuckets = GetVertexSize() + pOther->GetVertexSize() ;
|
||||
int nBuckets = max( GetVertexSize() + pOther->GetVertexSize(), 1000) ;
|
||||
VertGrid.Init( nBuckets) ;
|
||||
|
||||
// inserisco i vertici della trimesh corrente (li considero tutti diversi tra loro)
|
||||
@@ -3284,7 +3348,6 @@ SurfTriMesh::Mirror( const Point3d& ptOn, const Vector3d& vtNorm)
|
||||
// la superficie deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// verifico validità del piano di specchiatura
|
||||
if ( vtNorm.IsSmall())
|
||||
return false ;
|
||||
@@ -3317,7 +3380,6 @@ SurfTriMesh::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d&
|
||||
// la superficie deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// verifico validità dei parametri
|
||||
if ( vtNorm.IsSmall() || vtDir.IsSmall())
|
||||
return false ;
|
||||
@@ -3349,11 +3411,14 @@ SurfTriMesh::ToGlob( const Frame3d& frRef)
|
||||
// la superficie deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// 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 e di hashgrids3d
|
||||
m_OGrMgr.Reset() ;
|
||||
ResetHashGrids3d() ;
|
||||
@@ -3380,11 +3445,14 @@ SurfTriMesh::ToLoc( const Frame3d& frRef)
|
||||
// la superficie deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// 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 e di hashgrids3d
|
||||
m_OGrMgr.Reset() ;
|
||||
ResetHashGrids3d() ;
|
||||
@@ -3411,7 +3479,6 @@ SurfTriMesh::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
|
||||
// la superficie deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// verifico validità dei frame
|
||||
if ( frOri.GetType() == Frame3d::ERR || frDest.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
@@ -3662,7 +3729,7 @@ SurfTriMesh::ResetTFlags( void)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::ResetTempInt( void) const
|
||||
SurfTriMesh::ResetTempInts( void) const
|
||||
{
|
||||
for ( int i = 0 ; i < int( m_vTria.size()) ; ++ i)
|
||||
m_vTria[i].nTemp = 0 ;
|
||||
|
||||
+31
-18
@@ -1,7 +1,7 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2014-2022
|
||||
// EgalTech 2014-2023
|
||||
//----------------------------------------------------------------------------
|
||||
// File : SurfTriMesh.h Data : 10.10.22 Versione : 2.4i4
|
||||
// File : SurfTriMesh.h Data : 07.07.23 Versione : 2.5g1
|
||||
// Contenuto : Dichiarazione della classe Superficie TriMesh.
|
||||
//
|
||||
//
|
||||
@@ -27,15 +27,19 @@ class SurfFlatRegion ;
|
||||
// Classe Vertice
|
||||
class StmVert
|
||||
{
|
||||
public :
|
||||
StmVert( void) : ptP(), nIdTria( SVT_NULL), nFlag( 0), nTemp( 0) {}
|
||||
StmVert( const Point3d& ptQ) : ptP( ptQ), nIdTria( SVT_NULL), nFlag( 0), nTemp( 0) {}
|
||||
StmVert( const Point3d& ptQ, int nIdT, int nF) : ptP( ptQ), nIdTria( nIdT), nFlag( nF), nTemp( 0) {}
|
||||
public :
|
||||
Point3d ptP ;
|
||||
int nIdTria ;
|
||||
int nFlag ;
|
||||
mutable int nTemp ;
|
||||
public :
|
||||
StmVert( void) : ptP(), dU( -1), dV( -1), nIdTria( SVT_NULL), nFlag( 0), nTemp( 0) {}
|
||||
StmVert( const Point3d& ptQ) : ptP( ptQ), dU( -1), dV( -1), nIdTria( SVT_NULL), nFlag( 0), nTemp( 0) {}
|
||||
StmVert( const Point3d& ptQ, int nIdT, int nF) : ptP( ptQ), dU( -1), dV( -1), nIdTria( nIdT), nFlag( nF), nTemp( 0) {}
|
||||
public :
|
||||
Point3d ptP ;
|
||||
double dU ; // parametro riferito alle coordinate del punto nello spazio parametrico ( nSpanU x 1000) ( nSpanV x 1000)
|
||||
// della sup di Bezier // -1 se non definito
|
||||
double dV ; // parametro riferito alle coordinate del punto nello spazio parametrico ( nSpanU x 1000) ( nSpanV x 1000)
|
||||
// della sup di Bezier // -1 se non definito
|
||||
int nIdTria ;
|
||||
int nFlag ;
|
||||
mutable int nTemp ;
|
||||
} ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -215,7 +219,8 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
||||
{ m_dSmoothAng = std::max( dSmoothAngDeg, EPS_ANG_SMALL) ;
|
||||
m_dCosSmAng = cos( m_dSmoothAng * DEGTORAD) ;
|
||||
m_OGrMgr.Reset() ; }
|
||||
int AddVertex( const Point3d& ptVert) override ;
|
||||
int AddVertex( const Point3d& ptVert, const double dU = -1 , const double dV = -1) override ;
|
||||
bool MoveVertex( int nInd, const Point3d& ptNewVert) override ;
|
||||
int AddTriangle( const int nIdVert[3], int nTFlag = 0) override ;
|
||||
bool RemoveTriangle( int nId) override ;
|
||||
bool AdjustTopology( void) override ;
|
||||
@@ -243,8 +248,11 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
||||
double GetSmoothAngle( void) const override
|
||||
{ return m_dSmoothAng ; }
|
||||
bool GetVertex( int nId, Point3d& ptP) const override ;
|
||||
bool GetVertexParam( int nId, double& dU, double& dV) const override ;
|
||||
int GetFirstVertex( Point3d& ptP) const override ;
|
||||
int GetFirstVertexParam( int nId, double& dU, double& dV) const override ;
|
||||
int GetNextVertex( int nId, Point3d& ptP) const override ;
|
||||
int GetNextVertexParam( int nId, double& dU, double& dV) const override ;
|
||||
bool GetTriangle( int nId, int nIdVert[3]) const override ;
|
||||
int GetFirstTriangle( int nIdVert[3]) const override ;
|
||||
int GetNextTriangle( int nId, int nIdVert[3]) const override ;
|
||||
@@ -266,6 +274,7 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
||||
{ return int( m_vFacet.size()) ; }
|
||||
int GetFacetFromTria( int nT) const override ;
|
||||
bool GetAllTriaInFacet( int nF, INTVECTOR& vT) const override ;
|
||||
bool GetAllVertInFacet( int nF, INTVECTOR& vVert) const override ;
|
||||
bool GetFacetLoops( int nF, POLYLINEVECTOR& vPL) const override ;
|
||||
bool GetFacetAdjacencies( int nF, INTMATRIX& vAdj) const override ;
|
||||
bool GetFacetNearestEndPoint( int nF, const Point3d& ptNear, Point3d& ptEnd, Vector3d& vtN) const override ;
|
||||
@@ -315,9 +324,9 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
||||
bool ExistsTriangle( int nT) const
|
||||
{ return ( nT >= 0 && nT < GetTriangleSize() && m_vTria[nT].nIdVert[0] != SVT_DEL) ; }
|
||||
bool GetTriangleAdjacencies( int nId, int nIdAdjTriaId[3]) const ;
|
||||
bool GetTriangleFlag( int nId, int& nFlag) const ;
|
||||
bool GetTriangleTempInt( int nId, int& nTempInt) const ;
|
||||
bool ResetTempInt( void) const ;
|
||||
bool GetTFlag( int nId, int& nFlag) const ;
|
||||
bool GetTempInt( int nId, int& nTempInt) const ;
|
||||
bool ResetTempInts( void) const ;
|
||||
bool SetTFlag( int nId, int nTFlag) ;
|
||||
bool SetTempInt( int nId, int nTempInt) const ;
|
||||
|
||||
@@ -360,7 +369,7 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
||||
bool UpdateOneFace( int nFacet, int nT) ;
|
||||
bool UpdateTriaFaceting( int nRefT, int nFacet, const Plane3d& plPlane, int nT) ;
|
||||
bool SetFacet( int nInd, int nT) ;
|
||||
bool VerifyAdjacTriaFacet( int nT, INTVECTOR& vT) const ;
|
||||
bool VerifyAdjacTriaFacet( INTVECTOR& vT) const ;
|
||||
bool MarchAlongFacetLoop( int nF, int nT, int nV, int nTimeStamp, PolyLine& PL) const ;
|
||||
bool MarchOneFacetTria( int nF, int& nT, int& nV, int nTimeStamp, PolyLine& PL, bool& bEnd) const ;
|
||||
void ResetHashGrids3d( void) const ;
|
||||
@@ -412,6 +421,10 @@ inline SurfTriMesh* CloneBasicSurfTriMesh( const IGeoObj* pGObj)
|
||||
return nullptr ;
|
||||
return ( static_cast<SurfTriMesh*>( pGObj->Clone())) ; }
|
||||
inline const SurfTriMesh* GetBasicSurfTriMesh( const IGeoObj* pGObj)
|
||||
{ return ( dynamic_cast<const SurfTriMesh*>( pGObj)) ; }
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != SRF_TRIMESH)
|
||||
return nullptr ;
|
||||
return ( static_cast<const SurfTriMesh*>( pGObj)) ; }
|
||||
inline SurfTriMesh* GetBasicSurfTriMesh( IGeoObj* pGObj)
|
||||
{ return ( dynamic_cast<SurfTriMesh*>( pGObj)) ; }
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != SRF_TRIMESH)
|
||||
return nullptr ;
|
||||
return ( static_cast<SurfTriMesh*>( pGObj)) ; }
|
||||
|
||||
+41
-17
@@ -394,20 +394,13 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
||||
}
|
||||
|
||||
// Fra le catene trovate separo le aperte dalle chiuse
|
||||
int nDegenerateChainNum = 0 ;
|
||||
INTVECTOR vnDegVec ;
|
||||
CHAINVECTOR cvClosedChain ;
|
||||
CHAINVECTOR cvOpenChain ;
|
||||
for ( int nL = 0 ; nL < int( vChain.size()) ; ++ nL) {
|
||||
bool bChainDegenerate = false ;
|
||||
if ( vChain[nL].size() == 1 && AreSamePointApprox( vChain[nL][0].ptSt, vChain[nL][0].ptEn)) {
|
||||
bChainDegenerate = true ;
|
||||
}
|
||||
|
||||
if ( bChainDegenerate)
|
||||
++ nDegenerateChainNum ;
|
||||
bool bChainDegenerate = ( vChain[nL].size() == 1 && AreSamePointApprox( vChain[nL][0].ptSt, vChain[nL][0].ptEn)) ;
|
||||
int nCurLoopLast = max( int( vChain[nL].size()) - 1, 0) ;
|
||||
if ( ( ! bChainDegenerate) && AreSamePointApprox( vChain[nL][0].ptSt, vChain[nL][nCurLoopLast].ptEn))
|
||||
if ( ! bChainDegenerate && AreSamePointApprox( vChain[nL][0].ptSt, vChain[nL][nCurLoopLast].ptEn))
|
||||
cvClosedChain.emplace_back( vChain[nL]) ;
|
||||
else {
|
||||
cvOpenChain.emplace_back( vChain[nL]) ;
|
||||
@@ -446,7 +439,7 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
||||
}
|
||||
|
||||
// Gestione tagli piccoli
|
||||
if ( int( cvOpenChain.size()) == 1 && int( cvOpenChain[0].size()) == 1 && int( cvClosedChain.size()) == 0) {
|
||||
if ( cvOpenChain.size() == 1 && cvOpenChain[0].size() == 1 && cvClosedChain.empty()) {
|
||||
if ( AreSamePointEpsilon( cvOpenChain[0][0].ptSt, cvOpenChain[0][0].ptEn, EPS_SMALL)) {
|
||||
Plane3d plPlane ;
|
||||
plPlane.Set( cvOpenChain[0][0].ptSt, cvOpenChain[0][0].vtOuter) ;
|
||||
@@ -511,7 +504,7 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
||||
vbInOut.push_back( true) ;
|
||||
// Divido il loop usando le catene
|
||||
if ( ! DecomposeLoop( cvOpenChain, vnDegVec, cvBoundClosedLoopVec, vbInOut)) {
|
||||
if ( int( cvBoundClosedLoopVec.size()) == 1 && int( cvOpenChain.size()) == 2) {
|
||||
if ( cvBoundClosedLoopVec.size() == 1 && cvOpenChain.size() == 2) {
|
||||
Point3d ptLink0St = cvOpenChain[0][0].ptSt ;
|
||||
Point3d ptLink0En = cvOpenChain[0].back().ptEn ;
|
||||
Point3d ptLink1St = cvOpenChain.back()[0].ptSt ;
|
||||
@@ -571,7 +564,7 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
||||
POLYLINEVECTOR vplPolyVec ;
|
||||
vplPolyVec.resize( cvBoundClosedLoopVec.size()) ;
|
||||
for ( int nLoop = 0 ; nLoop < int( vplPolyVec.size()) ; ++ nLoop) {
|
||||
for (int nLine = 0 ; nLine < int( cvBoundClosedLoopVec[nLoop].size()) ; ++ nLine) {
|
||||
for ( int nLine = 0 ; nLine < int( cvBoundClosedLoopVec[nLoop].size()) ; ++ nLine) {
|
||||
vplPolyVec[nLoop].AddUPoint( 0., cvBoundClosedLoopVec[nLoop][nLine]) ;
|
||||
}
|
||||
vplPolyVec[nLoop].AddUPoint( 0., cvBoundClosedLoopVec[nLoop][0]) ;
|
||||
@@ -694,7 +687,7 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
||||
// Elimino loop interni non validi
|
||||
bool bDouble = true ;
|
||||
for ( int nInnLoop = 0 ; nInnLoop < int( vInnerLoop.size()) ; ++ nInnLoop) {
|
||||
if ( int( cvClosedChain[vInnerLoop[nInnLoop]].size()) > 2) {
|
||||
if ( cvClosedChain[vInnerLoop[nInnLoop]].size() > 2) {
|
||||
bDouble = false ;
|
||||
break ;
|
||||
}
|
||||
@@ -820,6 +813,7 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Divido i loop che si autointercettano
|
||||
int nInitialLoopNum = int( vPolygons.size()) ;
|
||||
for ( int nL = 1 ; nL < nInitialLoopNum ; ++ nL) {
|
||||
@@ -868,8 +862,8 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
||||
itSt2 = LoopPointList.emplace( itEn2, vAddingPointWithOrder[nPi]) ;
|
||||
}
|
||||
}
|
||||
|
||||
// Spezzo i loop autointersecantesi
|
||||
|
||||
POLYLINEVECTOR vAuxPolygons ;
|
||||
vAuxPolygons.emplace_back( vPolygons[nL]) ;
|
||||
|
||||
@@ -917,7 +911,7 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
||||
}
|
||||
bool bReplaced = false ;
|
||||
for ( int nl = 0 ; nl < int( vAuxPolygons.size()) ; ++ nl) {
|
||||
if ( true/*vAuxPolygons.GetAreaXY(double& dArea)*/) {
|
||||
if ( true) {
|
||||
if ( ! bReplaced) {
|
||||
vPolygons[nL].Clear() ;
|
||||
Point3d ptP ;
|
||||
@@ -1447,8 +1441,18 @@ SurfTriMesh::Add( const ISurfTriMesh& Other)
|
||||
if ( ! IsValid() || ! Other.IsValid())
|
||||
return false ;
|
||||
|
||||
// Se la seconda è vuota non devo fare alcunchè
|
||||
if ( Other.IsEmpty())
|
||||
return true ;
|
||||
|
||||
m_OGrMgr.Clear() ;
|
||||
|
||||
// Se la prima è vuota, copio la seconda nella prima
|
||||
if ( IsEmpty()) {
|
||||
CopyFrom( &Other) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
SurfTriMesh SurfB ;
|
||||
SurfB.CopyFrom( &Other) ;
|
||||
|
||||
@@ -1507,8 +1511,20 @@ SurfTriMesh::Intersect( const ISurfTriMesh& Other)
|
||||
if ( ! IsValid() || ! Other.IsValid())
|
||||
return false ;
|
||||
|
||||
// Se la prima è vuota non devo fare alcunchè
|
||||
if ( IsEmpty())
|
||||
return true ;
|
||||
|
||||
m_OGrMgr.Clear() ;
|
||||
|
||||
// Se la seconda è vuota, basta vuotare la prima
|
||||
if ( Other.IsEmpty()) {
|
||||
Clear() ;
|
||||
m_bOriented = true ;
|
||||
m_bClosed = true ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
SurfTriMesh SurfB ;
|
||||
SurfB.CopyFrom( &Other) ;
|
||||
|
||||
@@ -1567,6 +1583,10 @@ SurfTriMesh::Subtract( const ISurfTriMesh& Other)
|
||||
if ( ! IsValid() || ! Other.IsValid())
|
||||
return false ;
|
||||
|
||||
// Se una delle due è vuota non devo fare alcunchè
|
||||
if ( IsEmpty() || Other.IsEmpty())
|
||||
return true ;
|
||||
|
||||
m_OGrMgr.Clear() ;
|
||||
|
||||
SurfTriMesh SurfB ;
|
||||
@@ -1615,7 +1635,7 @@ SurfTriMesh::Subtract( const ISurfTriMesh& Other)
|
||||
Scale( frScalingRef, 1. / BOOLEAN_SCALE, 1. / BOOLEAN_SCALE, 1. / BOOLEAN_SCALE) ;
|
||||
|
||||
if ( ! SimplifyFacets())
|
||||
LOG_ERROR( GetEGkLogger(), "Error in SimplifyFacets of Stm::Intersect")
|
||||
LOG_ERROR( GetEGkLogger(), "Error in SimplifyFacets of Stm::Subtract")
|
||||
|
||||
return bOk ;
|
||||
}
|
||||
@@ -1677,6 +1697,10 @@ SurfTriMesh::CutWithOtherSurf( const ISurfTriMesh& CutterSurf, bool bInVsOut, bo
|
||||
if ( ! IsValid() || ! CutterSurf.IsValid())
|
||||
return false ;
|
||||
|
||||
// Se una delle due è vuota non devo fare alcunchè
|
||||
if ( IsEmpty() || CutterSurf.IsEmpty())
|
||||
return true ;
|
||||
|
||||
m_OGrMgr.Clear() ;
|
||||
|
||||
SurfTriMesh SurfC ;
|
||||
@@ -1749,7 +1773,7 @@ SurfTriMesh::Repair( double dMaxEdgeLen)
|
||||
|
||||
// Ritriangolo le facce
|
||||
if ( ! SimplifyFacets( dMaxEdgeLen, true))
|
||||
LOG_ERROR( GetEGkLogger(), "Error in SimplifyFacets of Stm::Intersect")
|
||||
LOG_ERROR( GetEGkLogger(), "Error in SimplifyFacets of Stm::Repair")
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
+10
-2
@@ -32,10 +32,14 @@ const double CUT_SCALE = 1024 ;
|
||||
bool
|
||||
SurfTriMesh::Cut( const Plane3d& plPlane, bool bSaveOnEq)
|
||||
{
|
||||
// la superficie deve essere validata
|
||||
// La superficie deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// Se la superficie è vuota non devo fare alcunchè
|
||||
if ( IsEmpty())
|
||||
return true ;
|
||||
|
||||
// recupero il numero originale di triangoli e di facce
|
||||
int nTriaOriCnt = GetTriangleCount() ;
|
||||
int nFacetOriCnt = GetFacetCount() ;
|
||||
@@ -354,6 +358,10 @@ SurfTriMesh::GeneralizedCut( const ICurve& cvCurve, bool bSaveOnEq)
|
||||
if ( ! cvCurve.GetExtrusion( vtExtr) || vtExtr.IsSmall() || ! cvCurve.IsClosed())
|
||||
return false ;
|
||||
|
||||
// Se la superficie è vuota non devo fare alcunchè
|
||||
if ( IsEmpty())
|
||||
return true ;
|
||||
|
||||
// Recupero il numero originale di triangoli e di facce
|
||||
int nTriaOriCnt = GetTriangleCount() ;
|
||||
int nFacetOriCnt = GetFacetCount() ;
|
||||
@@ -367,7 +375,7 @@ SurfTriMesh::GeneralizedCut( const ICurve& cvCurve, bool bSaveOnEq)
|
||||
}
|
||||
|
||||
// Eseguo scalature
|
||||
Frame3d frScalingRef;
|
||||
Frame3d frScalingRef ;
|
||||
frScalingRef.Set( m_vVert[0].ptP, X_AX, Y_AX, Z_AX) ;
|
||||
Scale( frScalingRef, CUT_SCALE, CUT_SCALE, CUT_SCALE) ;
|
||||
cvCompo.Scale( frScalingRef, CUT_SCALE, CUT_SCALE, CUT_SCALE) ;
|
||||
|
||||
+45
-12
@@ -17,6 +17,7 @@
|
||||
#include "GeoConst.h"
|
||||
#include "PolygonPlane.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
#include <array>
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
|
||||
@@ -223,25 +224,57 @@ SurfTriMesh::GetAllTriaInFacet( int nF, INTVECTOR& vT) const
|
||||
vT.reserve( 10) ;
|
||||
vT.push_back( nT) ;
|
||||
m_vTria[nT].nTemp = m_nTimeStamp ;
|
||||
return VerifyAdjacTriaFacet( nT, vT) ;
|
||||
return VerifyAdjacTriaFacet( vT) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::VerifyAdjacTriaFacet( int nT, INTVECTOR& vT) const
|
||||
SurfTriMesh::VerifyAdjacTriaFacet( INTVECTOR& vT) const
|
||||
{
|
||||
// verifico i triangoli adiacenti
|
||||
for ( int j = 0 ; j < 3 ; ++ j) {
|
||||
int nAdjT = m_vTria[nT].nIdAdjac[j] ;
|
||||
if ( nAdjT != SVT_NULL &&
|
||||
m_vTria[nAdjT].nTemp != m_nTimeStamp &&
|
||||
m_vTria[nAdjT].nIdFacet == m_vTria[nT].nIdFacet) {
|
||||
vT.push_back( nAdjT) ;
|
||||
m_vTria[nAdjT].nTemp = m_nTimeStamp ;
|
||||
if ( ! VerifyAdjacTriaFacet( nAdjT, vT))
|
||||
return false ;
|
||||
INTVECTOR vStack{ vT.back()} ;
|
||||
while ( ! vStack.empty()) {
|
||||
array<int,3> vNew{ SVT_NULL, SVT_NULL, SVT_NULL} ;
|
||||
for ( int j = 0 ; j < 3 ; ++ j) {
|
||||
int nAdjT = m_vTria[vStack.back()].nIdAdjac[j] ;
|
||||
if ( nAdjT != SVT_NULL &&
|
||||
m_vTria[nAdjT].nTemp != m_nTimeStamp &&
|
||||
m_vTria[nAdjT].nIdFacet == m_vTria[vStack.back()].nIdFacet) {
|
||||
vT.push_back( nAdjT) ;
|
||||
vNew[j] = nAdjT ;
|
||||
m_vTria[nAdjT].nTemp = m_nTimeStamp ;
|
||||
}
|
||||
}
|
||||
vStack.pop_back() ;
|
||||
for ( int j = 0 ; j < 3 ; ++ j) {
|
||||
if ( vNew[j] != SVT_NULL)
|
||||
vStack.push_back( vNew[j]) ;
|
||||
}
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::GetAllVertInFacet( int nF, INTVECTOR& vVert) const
|
||||
{
|
||||
// recupero tutti i triangoli della faccia
|
||||
INTVECTOR vTria ;
|
||||
if ( ! GetAllTriaInFacet( nF, vTria))
|
||||
return false ;
|
||||
// ne ricavo i vertici
|
||||
vVert.clear() ;
|
||||
INTUNORDSET usTempVert ;
|
||||
for ( int nT : vTria) {
|
||||
for ( int i = 0 ; i < 3 ; ++ i) {
|
||||
int nV = m_vTria[nT].nIdVert[i] ;
|
||||
if ( usTempVert.find( nV) == usTempVert.end()) {
|
||||
usTempVert.insert( nV) ;
|
||||
vVert.push_back( nV) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
||||
+4
-2
@@ -470,18 +470,20 @@ Vector3d::GetAngleXY( const Vector3d& vtEnd, double& dAngDeg) const
|
||||
// all'asse di rotazione sulla stessa direzione della componente perpendicolare di vtEnd
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Vector3d::GetRotation( const Vector3d& vtEnd, const Vector3d& vtAx, double& dAngDeg, bool& bDet) const
|
||||
Vector3d::GetRotation( const Vector3d& vtEnd, const Vector3d& vtAx, double dEpsZero, double& dAngDeg, bool& bDet) const
|
||||
{
|
||||
// ricavo versore asse di rotazione
|
||||
Vector3d vtDirAx = vtAx ;
|
||||
if ( ! vtDirAx.Normalize())
|
||||
return false ;
|
||||
// verifico epsilon per vettore nullo
|
||||
dEpsZero = std::min( EPS_SMALL, abs( dEpsZero)) ;
|
||||
|
||||
// ricavo le componenti perpendicolari all'asse di rotazione
|
||||
Vector3d vtPerp = *this - vtDirAx * ( *this * vtDirAx) ;
|
||||
Vector3d vtPerpE = vtEnd - vtDirAx * ( vtEnd * vtDirAx) ;
|
||||
// se sono entrambe non nulle : angolo determinato
|
||||
if ( ! vtPerp.IsZero() && ! vtPerpE.IsZero()) {
|
||||
if ( vtPerp.SqLen() > dEpsZero * dEpsZero && vtPerpE.SqLen() > dEpsZero * dEpsZero) {
|
||||
// secondo vettore perpendicolare ad asse e a componente perpendicolare
|
||||
Vector3d vtPerp2 = vtDirAx ^ vtPerp ;
|
||||
// proporzionali a seno e coseno del perpendicolare E
|
||||
|
||||
+47
-1
@@ -108,7 +108,7 @@ VolZmap::Clone( void) const
|
||||
bool
|
||||
VolZmap::CopyFrom( const IGeoObj* pGObjSrc)
|
||||
{
|
||||
const VolZmap* pVzm = dynamic_cast<const VolZmap*>( pGObjSrc) ;
|
||||
const VolZmap* pVzm = GetBasicVolZmap( pGObjSrc) ;
|
||||
if ( pVzm == nullptr)
|
||||
return false ;
|
||||
return CopyFrom( *pVzm) ;
|
||||
@@ -630,8 +630,10 @@ VolZmap::Translate( const Vector3d& vtMove)
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
ResetGraphics() ;
|
||||
|
||||
// traslo il riferimento
|
||||
m_MapFrame.Translate( vtMove) ;
|
||||
return true ;
|
||||
@@ -644,8 +646,13 @@ VolZmap::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, doub
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico validità dell'asse di rotazione
|
||||
if ( vtAx.IsSmall())
|
||||
return false ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
ResetGraphics() ;
|
||||
|
||||
// ruoto il riferimento
|
||||
m_MapFrame.Rotate( ptAx, vtAx, dCosAng, dSinAng) ;
|
||||
return true ;
|
||||
@@ -658,6 +665,10 @@ VolZmap::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double dCo
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico non sia nulla
|
||||
if ( abs( dCoeffX) < EPS_ZERO && abs( dCoeffY) < EPS_ZERO && abs( dCoeffZ) < EPS_ZERO)
|
||||
return false ;
|
||||
|
||||
return false ;
|
||||
}
|
||||
|
||||
@@ -668,6 +679,10 @@ VolZmap::Mirror( const Point3d& ptOn, const Vector3d& vtNorm)
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico validità del piano di specchiatura
|
||||
if ( vtNorm.IsSmall())
|
||||
return false ;
|
||||
|
||||
return false ;
|
||||
}
|
||||
|
||||
@@ -678,6 +693,10 @@ VolZmap::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d& vtD
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico validità dei parametri
|
||||
if ( vtNorm.IsSmall() || vtDir.IsSmall())
|
||||
return false ;
|
||||
|
||||
return false ;
|
||||
}
|
||||
|
||||
@@ -688,8 +707,17 @@ VolZmap::ToGlob( const Frame3d& frRef)
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// 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
|
||||
ResetGraphics() ;
|
||||
|
||||
// trasformo il riferimento
|
||||
m_MapFrame.ToGlob( frRef) ;
|
||||
return true ;
|
||||
@@ -702,8 +730,17 @@ VolZmap::ToLoc( const Frame3d& frRef)
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// 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
|
||||
ResetGraphics() ;
|
||||
|
||||
// trasformo il riferimento
|
||||
m_MapFrame.ToLoc( frRef) ;
|
||||
return true ;
|
||||
@@ -716,8 +753,17 @@ VolZmap::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico validità dei frame
|
||||
if ( frOri.GetType() == Frame3d::ERR || frDest.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
|
||||
// se i due riferimenti coincidono, non devo fare alcunché
|
||||
if ( AreSameFrame( frOri, frDest))
|
||||
return true ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
ResetGraphics() ;
|
||||
|
||||
// trasformo il riferimento
|
||||
m_MapFrame.LocToLoc( frOri, frDest) ;
|
||||
return true ;
|
||||
|
||||
@@ -394,9 +394,6 @@ class VolZmap : public IVolZmap, public IGeoObjRW
|
||||
bool AvoidSimpleRectPrismoid( const Frame3d& frPrismoid, double dLenghtBaseX, double dLenghtBaseY,
|
||||
double dLenghtTopX, double dLenghtTopY, double dHeight, bool bPrecise = false) const ;
|
||||
bool AvoidSimpleTorus( const Frame3d& frTorus, double dMaxRad, double dMinRad, bool bPrecise = false) const ;
|
||||
// Funzioni ausiliarie per metodi avoid
|
||||
bool SingleMapDexelConeCollision( int nStI, int nEnI, int nStJ, int nEnJ, const Point3d& ptRefPoint, const Vector3d& vtRefAx,
|
||||
double dMinRad, double dMaxRad, double dHeight, double dMinBoxH, double dMaxBoxH) const ;
|
||||
// Funzione per crezione solido in parallelo
|
||||
bool CreateMapPart( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, const Vector3d& vtLen, const Point3d& ptMapOrig,
|
||||
const ISurfTriMesh& Surf, IntersParLinesSurfTm& intPLSTM) ;
|
||||
@@ -469,16 +466,16 @@ class VolZmap : public IVolZmap, public IGeoObjRW
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline VolZmap* CreateBasicVolZmap( void)
|
||||
{ return (static_cast<VolZmap*>( CreateGeoObj( VOL_ZMAP))) ; }
|
||||
{ return ( static_cast<VolZmap*>( CreateGeoObj( VOL_ZMAP))) ; }
|
||||
inline VolZmap* CloneBasicVolZmap( const IGeoObj* pGObj)
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != VOL_ZMAP)
|
||||
return nullptr ;
|
||||
return (static_cast<VolZmap*>(pGObj->Clone())) ; }
|
||||
return ( static_cast<VolZmap*>( pGObj->Clone())) ; }
|
||||
inline const VolZmap* GetBasicVolZmap( const IGeoObj* pGObj)
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != VOL_ZMAP)
|
||||
return nullptr ;
|
||||
return (static_cast<const VolZmap*>(pGObj)) ; }
|
||||
return ( static_cast<const VolZmap*>( pGObj)) ; }
|
||||
inline VolZmap* GetBasicVolZmap( IGeoObj* pGObj)
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != VOL_ZMAP)
|
||||
return nullptr ;
|
||||
return (static_cast<VolZmap*>(pGObj)) ; }
|
||||
return ( static_cast<VolZmap*>( pGObj)) ; }
|
||||
|
||||
+492
-720
File diff suppressed because it is too large
Load Diff
+2
-10
@@ -2047,14 +2047,6 @@ VolZmap::ExtMarchingCubes( int nBlock, VoxelContainer& vVox) const
|
||||
else {
|
||||
|
||||
if ( nVertComp[nComp] == 5) {
|
||||
double dDotAvarage = 0.;
|
||||
for (int m = 0; m < nVertComp[nComp] - 1; ++m) {
|
||||
for (int l = m + 1 ; l < nVertComp[nComp]; ++l) {
|
||||
dDotAvarage += CompoVert[nComp][m].vtVec * CompoVert[nComp][l].vtVec;
|
||||
}
|
||||
}
|
||||
dDotAvarage /= (( nVertComp[nComp] * ( nVertComp[nComp] - 1)) / 2) ;
|
||||
|
||||
int nNumPar = 0 ;
|
||||
for ( int m = 0 ; m < nVertComp[nComp] - 1 ; ++ m) {
|
||||
for ( int l = m + 1 ; l < nVertComp[nComp] ; ++ l) {
|
||||
@@ -2062,9 +2054,9 @@ VolZmap::ExtMarchingCubes( int nBlock, VoxelContainer& vVox) const
|
||||
++ nNumPar ;
|
||||
}
|
||||
}
|
||||
bExtConfirmed = nNumPar == 3 ;
|
||||
bExtConfirmed = ( nNumPar == 3) ;
|
||||
}
|
||||
else if (nVertComp[nComp] < 5) {
|
||||
else if ( nVertComp[nComp] < 5) {
|
||||
bExtConfirmed = false ;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user