EgtGeomKernel :

- gestiti i loop di trim di sup di Bezier che escono dal parametrico.
- corretto un errore di triangolazione per sup di Bezier.
This commit is contained in:
Daniele Bariletti
2024-04-10 09:21:49 +02:00
parent 7ce9e7e26c
commit 32a0e1d2b5
2 changed files with 43 additions and 18 deletions
+41 -17
View File
@@ -24,6 +24,7 @@
#include "/EgtDev/Include/EGkDistPointCurve.h"
#include "/EgtDev/Include/EGkCurve.h"
#include "DistPointCrvComposite.h"
#include "/EgtDev/Include/EGkSfrCreate.h"
#include <algorithm>
using namespace std ;
@@ -60,6 +61,38 @@ Tree::Tree( const Point3d ptBl, const Point3d ptTr)
m_mTree.insert( pair< int, Cell>( -1, cRoot)) ;
}
//----------------------------------------------------------------------------
bool
Tree::LimitLoop( PolyLine& pl, POLYLINEVECTOR& vPl) const
{
// creo la flat region di trim, quella del parametrico e li interseco
PtrOwner<ISurfFlatRegion> pSfrTrim( GetSurfFlatRegionFromPolyLine( pl)) ;
bool bInverted = false ;
if ( ! pSfrTrim->GetNormVersor().IsZplus()) {
pSfrTrim->Invert() ;
bInverted = true ;
}
PtrOwner<ISurfFlatRegion> pParamTrim( GetSurfFlatRegionRectangle( SBZ_TREG_COEFF * m_nSpanU, SBZ_TREG_COEFF * m_nSpanV)) ;
if ( ! pParamTrim->Intersect( *pSfrTrim) || ! pParamTrim->IsValid())
return false ;
// ricostruisco la curva tenendo solo le parti dentro lo spazio parametrico
// devo recuperare la polyline dei bordi dei vari chunk creati
for ( int c = 0 ; c < int( pParamTrim->GetChunkCount()) ; ++c) {
PtrOwner<ICurve> pCrv ( pParamTrim->GetLoop( c, 0)) ;
if ( bInverted)
pCrv->Invert() ;
PolyLine plApprox ;
double dLinTol = 10 * EPS_SMALL, dAngTolDeg = 5 ;
int nType = 0 ;
pCrv->ApproxWithLines( dLinTol, dAngTolDeg, nType, plApprox) ;
// aggiungo la polyline del chunk
vPl.push_back( plApprox) ;
}
return false ;
}
//----------------------------------------------------------------------------
void
Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMin, const Point3d& ptMax)
@@ -71,7 +104,6 @@ Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMi
m_vLoop.clear() ;
m_mChunk.clear() ;
m_vPlApprox.clear() ;
m_vChunk.clear() ;
m_vPolygons.clear() ;
m_vPlLoop2D.clear() ;
@@ -93,8 +125,6 @@ Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMi
// recupero i loop di trim e li divido per chunk
if ( m_bTrimmed) {
int nLoop = 0 ;
INTVECTOR vChunk ;
// recupero la superficie di trim per avere accesso diretto ai loop e mantenendo le informazioni sui chunk
PtrOwner<SurfFlatRegion> pTrimReg( m_pSrfBz->GetTrimRegion()->Clone()) ;
double dLinTol = 0.01 ; // questo è riferito allo spazio parametrico
@@ -102,7 +132,7 @@ Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMi
for ( int i = 0 ; i < pTrimReg->GetChunkCount() ; ++ i) {
PtrOwner<SurfFlatRegion> pChunk( pTrimReg->CloneChunk( i)) ;
for ( int j = 0 ; j < pChunk->GetLoopCount( 0) ; ++ j) {
vChunk.push_back( nLoop) ;
//vChunk.push_back( nLoop) ;
// i chunk della falt region sono ancora flat region composte da 1 chunk
PtrOwner<ICurve> pLoop ( pChunk->GetLoop( 0, j)) ;
// rimuovo i difetti dei loop prima di salvarli
@@ -127,21 +157,13 @@ Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMi
bCCW = true ;
else
bCCW = false ;
m_vPlApprox.push_back( tuple<PolyLine,bool>(plApprox,bCCW)) ;
// limito il loop allo spazio parametrico // potrei ottenere più loop a partire da quello originale
POLYLINEVECTOR vPlLimited ;
LimitLoop( plApprox, vPlLimited) ;
for ( int k = 0 ; k < int( vPlLimited.size()) ; ++k)
m_vPlApprox.push_back( tuple<PolyLine,bool>(vPlLimited[k], bCCW)) ;
}
// li riordino dal più grande al più piccolo
sort(vChunk.begin(), vChunk.end(), [this]( const int& a, const int& b) { double dArea1, dArea2 ;
m_vLoop[a]->GetAreaXY( dArea1) ;
m_vLoop[b]->GetAreaXY( dArea2) ;
return dArea1 > dArea2 ; }) ;
m_vChunk.push_back( vChunk) ;
vChunk.clear() ;
}
// li riordino dal più grande al più piccolo
sort(m_vChunk.begin(), m_vChunk.end(), [this]( const INTVECTOR& a, const INTVECTOR& b) { double dArea1, dArea2 ;
m_vLoop[a[0]]->GetAreaXY( dArea1) ;
m_vLoop[b[0]]->GetAreaXY( dArea2) ;
return dArea1 > dArea2 ;}) ;
}
// salvo i vertici 3d della cella root
Point3d ptTop( nSpanU * SBZ_TREG_COEFF, nSpanV * SBZ_TREG_COEFF) ;
@@ -3509,6 +3531,8 @@ Tree::CheckIfBetween( const Inters& inA, const Inters& inB) const
}
else if ( nEdge == 7)
nEdge = 0 ;
if ( AreSameEdge( inA.nIn, inA.nOut) && ! CheckIfBefore( inA.nIn, inA.vpt[0], inA.vpt.back()))
vEdges.push_back( nEdge) ;
// creo la sequenza di Edges da scorrere per trovare i possibili validNextStart
while ( ! AreSameEdge( nEdge, inA.nIn) || (int) vEdges.size() == 0) {
vEdges.push_back( nEdge) ;