EgtGeomKernel :
- correzioni e miglioramenti alla triangolazione delle bezier.
This commit is contained in:
+18
-2
@@ -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 ;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user