EgtGeomKernel :

- correzioni e miglioramenti alla triangolazione delle bezier.
This commit is contained in:
Daniele Bariletti
2024-08-09 17:33:26 +02:00
parent b5fcceaa75
commit e1ab88302f
2 changed files with 67 additions and 26 deletions
+18 -2
View File
@@ -40,7 +40,6 @@
#include "/EgtDev/Include/EGkGeoPoint3d.h"
#include "/EgtDev/Include/EGkIntervals.h"
#include "/EgtDev/Extern/Eigen/Dense"
#include "EgtDev/Include/EGkGeoObjSave.h"
using namespace std ;
@@ -49,6 +48,7 @@ GEOOBJ_REGISTER( SRF_BEZIER, NGE_S_BEZ, SurfBezier) ;
static bool ChangeStartForClosed( PolyLine& plU0, PolyLine& plU1, ICurveComposite* pCrvU0, ICurveComposite* pCrvU1) ;
static bool ParametrizeByLen( const ICurveComposite* pCurve, DBLVECTOR& vParam) ;
static bool BuildCommonParam( const DBLMATRIX& mParam, DBLVECTOR& vCommonParam) ;
//----------------------------------------------------------------------------
SurfBezier::SurfBezier( void)
@@ -4769,8 +4769,24 @@ ParametrizeByLen( const ICurveComposite* pCurve, DBLVECTOR& vParam)
//----------------------------------------------------------------------------
static bool
FindCommonParametrization( const DBLMATRIX& mParam, DBLVECTOR& vCommonParam)
BuildCommonParam( const DBLMATRIX& mParam, DBLVECTOR& vCommonParam)
{
// aggiungo tutti gli end delle sottocurve
Intervals iInt ;
iInt.Set( 0, 1) ;
for ( int i = 0 ; i < int( mParam.size()) ; ++i) {
for ( int j = 0 ; j < int(mParam[i].size()) - 1 ; ++j) {
iInt.Add( mParam[i][j], mParam[i][j+1]) ;
}
}
//// NON FUNZIONANO COSì GLI INTERVALSS!!!!!!///////////////////////////
//
//// controllo che non ce ne siano di troppo vicini
//// in tal caso elimino il secondo
//for ( ) {
// iInt.
//}
return true ;
}
+49 -24
View File
@@ -282,7 +282,7 @@ Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMi
// se richiesto divido preliminarmente le patches
m_vnParents.clear() ;
bool bIsPlanar = m_pSrfBz->IsPlanar() ;
if( ! bIsPlanar) {
if( ! bIsPlanar || m_bMulti) {
if ( m_bSplitPatches && ( nSpanU > 1 || nSpanV > 1)) {
int nId = -1 ;
// se la superficie è chiusa lungo il parametro U, sistemo le adiacenze al bordo
@@ -698,6 +698,7 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax)
// suddivido lo spazio parametrico con divisioni a metà su uno dei due parametri
int nCToSplit = -1 ;
Cell* pcToSplit = &m_mTree[nCToSplit] ;
bool bIsPlanar = m_pSrfBz->IsPlanar() ;
if ( ! m_bBilinear) {
while ( nCToSplit != -2 && pcToSplit->IsProcessed() == false) {
// controllo che la cella non sia già stata preliminarmente splittata
@@ -767,35 +768,60 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax)
// posso guardare la distanza tra le due diagonali
bool bTwist = false ;
Point3d ptP00, ptP10, ptP11, ptP01 ;
// distanza reale tra i vertici della cella
// i vertici della cella
ptP00 = m_mVert[nCToSplit][0] ;
ptP10 = m_mVert[nCToSplit][1] ;
ptP11 = m_mVert[nCToSplit][2] ;
ptP01 = m_mVert[nCToSplit][3] ;
// serve una valutazione più fine, sennò approssimo la superficie in modo troppo grossolano
DistLineLine dll( ptP00, ptP11, ptP10, ptP01, true, true) ;
double dDist = 0 ; dll.GetDist( dDist) ;
if ( dDist > max(dCurvU, dCurvV) && dDist > EPS_SMALL) {
bTwist = true ;
// devo decidere in quale direzione splittare
// dovrei capire in quale delle due direzioni è più torta la superficie
Vector3d vtU0 = ptP10 - ptP00 ;
Vector3d vtU1 = ptP11 - ptP01 ;
double dAngU ;
bool bDetU = false ;
vtU0.GetRotation( vtU1, vtU0 ^ vtU1, dAngU, bDetU) ;
Vector3d vtV0 = ptP01 - ptP00 ;
Vector3d vtV1 = ptP11 - ptP10 ;
double dAngV ;
bool bDetV = false ;
// faccio la get rotation tra le coppie vettori, usando come asse il loro prodotto vettoriale per ottenere la rotazione tra i due lati
// splitto nella direzione perpendicolare alla coppia di vettori più torti tra loro.
vtV0.GetRotation( vtV1, vtV0 ^ vtV1, dAngV, bDetV) ;
if ( dAngU > dAngV)
dCurvV = dDist ;
else
dCurvU = dDist ;
if ( dDist > max(dCurvU, dCurvV) || dDist < 5 * EPS_SMALL) {
bool bFlat = false ;
// controllo se la cella è twistata di 180 gradi e quindi piatta
Triangle3d tria1, tria2 ;
tria1.Set( ptP00, ptP10, ptP11) ; tria1.Validate( true) ;
tria2.Set( ptP00, ptP11, ptP01) ; tria2.Validate( true) ;
if( AreOppositeVectorEpsilon(tria1.GetN(), tria2.GetN(), 5 * EPS_SMALL)) {
bTwist = true ;
bFlat = true ;
}
// controllo che la cella non sia piatta
if( ! bTwist) {
PolyLine plCell ;
plCell.AddUPoint(0,ptP00) ;
plCell.AddUPoint(1,ptP10) ;
plCell.AddUPoint(2,ptP11) ;
double dU = (pcToSplit->GetTopRight().x + pcToSplit->GetBottomLeft().x) / (SBZ_TREG_COEFF * 2) ;
double dV = (pcToSplit->GetTopRight().y + pcToSplit->GetBottomLeft().y) / (SBZ_TREG_COEFF * 2) ;
Point3d ptCen ; m_pSrfBz->GetPointD1D2( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptCen) ;
plCell.AddUPoint(3,ptCen) ;
plCell.AddUPoint(4,ptP01) ;
plCell.Close() ;
Plane3d plPlane ; double dArea = 0 ;
bFlat = plCell.IsClosedAndFlat( plPlane, dArea, 10 * EPS_SMALL) ;
}
if( ! bFlat) {
bTwist = true ;
// devo decidere in quale direzione splittare
// dovrei capire in quale delle due direzioni è più torta la superficie
Vector3d vtU0 = ptP10 - ptP00 ;
Vector3d vtU1 = ptP11 - ptP01 ;
double dAngU ;
bool bDetU = false ;
vtU0.GetRotation( vtU1, vtU0 ^ vtU1, dAngU, bDetU) ;
Vector3d vtV0 = ptP01 - ptP00 ;
Vector3d vtV1 = ptP11 - ptP10 ;
double dAngV ;
bool bDetV = false ;
// faccio la get rotation tra le coppie vettori, usando come asse il loro prodotto vettoriale per ottenere la rotazione tra i due lati
// splitto nella direzione perpendicolare alla coppia di vettori più torti tra loro.
vtV0.GetRotation( vtV1, vtV0 ^ vtV1, dAngV, bDetV) ;
if ( dAngU > dAngV)
dCurvV = dDist ;
else
dCurvU = dDist ;
}
}
// per lo split scelgo la direzione che è più vicina alla superficie originale nel punto di maggior distanza
@@ -978,7 +1004,6 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax)
}
// bilineare
else {
bool bIsPlanar = m_pSrfBz->IsPlanar() ;
while ( nCToSplit != -2 && pcToSplit->IsProcessed() == false) {
if ( pcToSplit->IsLeaf()) {
// vertici della cella