EgtExchange :

- corretta la riparametrizzazione tra superficie NURBS e Bezier.
This commit is contained in:
Daniele Bariletti
2023-10-31 09:44:26 +01:00
parent 2e385022f3
commit d3bf0a7839
2 changed files with 115 additions and 3 deletions
+112 -3
View File
@@ -39,8 +39,8 @@
#include "/EgtDev/Include/EGkExtText.h"
#include "/EgtDev/Include/EGkExtDimension.h"
#include "/EgtDev/Include/EGkVector3d.h"
//#include "C:/EgtDev/opennurbs/opennurbs.h"
#include "/EgtDev/Extern/opennurbs/Include/opennurbs.h"
#include "/EgtDev/Include/EGkGeoObjSave.h"
using namespace std ;
@@ -974,8 +974,6 @@ Import3dm::ConvertSurface( const ON_Surface* onSurf)
ON_NurbsSurface onNurbsSurface( *onNurbsSurface_) ;
int nSpanU = onNurbsSurface.SpanCount(0);
int nSpanV = onNurbsSurface.SpanCount(1);
//onNurbsSurface.MakeClampedUniformKnotVector( 0) ; // rende non periodico, ma non toglie i punti in più
//onNurbsSurface.MakeClampedUniformKnotVector( 1) ;
SNurbsSurfData sNurbsSurf ;
sNurbsSurf.bClosedU = onNurbsSurface.IsClosed( 0) ;
sNurbsSurf.bClosedV = onNurbsSurface.IsClosed( 1) ;
@@ -1215,6 +1213,12 @@ Import3dm::ConvertBrep( const ON_Brep* onBrep, const bool bForceTriMesh )
double dScaleV = v1 - v0 ;
Vector3d vToOrig( -u0, -v0, 0) ;
sfrTrim->Translate( vToOrig) ;
// se la superficie di partenza aveva vettori dei nodi non uniformi devo riscalare lo spazio parametrico in modo da renderli uniformi
// e applicando la trasformazione anche alle curve di trim.
ON_NurbsSurface onNurbsSurface ;
onFace->GetNurbForm( onNurbsSurface) ;
// rendo uniforme lo spazio parametrico nella direzione dei parametri che non lo sono
MakeUniform( &sfrTrim, onNurbsSurface, dScaleU, dScaleV) ;
int nDegU, nDegV, nSpanU, nSpanV ;
bool bRat, bTrim ;
pSurfBezNew->GetInfo( nDegU, nDegV, nSpanU, nSpanV, bRat, bTrim) ;
@@ -1256,6 +1260,111 @@ Import3dm::ConvertBrep( const ON_Brep* onBrep, const bool bForceTriMesh )
return vSurf ;
}
//----------------------------------------------------------------------------
bool
Import3dm::MakeUniform( ISurfFlatRegion** sfr, ON_NurbsSurface onNurbsSurface, double& dScaleU, double& dScaleV)
{
PtrOwner<ISurfFlatRegion> sfr_rescaled( CreateSurfFlatRegion()) ;
for ( int nDir = 0 ; nDir <= 1 ; ++ nDir) {
// vettore dei nodi
DBLVECTOR vU ;
for ( int i = 0 ; i < onNurbsSurface.KnotCount( nDir) ; ++i ) {
vU.push_back( onNurbsSurface.Knot( nDir, i)) ;
}
int a = 0, b = 1 ;
double d0 = abs( vU[b] - vU[a]), d1 = d0, d00 = d0 ;
while ( b < (int)vU.size() && d1 < d0 + EPS_SMALL && d1 > d0 - EPS_SMALL) {
d0 = d1 ;
a = b ;
++b ;
if ( b < (int)vU.size())
d1 = abs( vU[b] - vU[a]) ;
}
sfr_rescaled.Set( CreateSurfFlatRegion()) ;
if ( IsNull( sfr_rescaled))
return false ;
bool bDone = false ;
if ( b != (int)vU.size()) {
double dLenTot = vU.back() - vU.front() ;
for ( int p = 0 ; p < (int)vU.size() - 1 ; ++p) {
PtrOwner<ISurfFlatRegion> pSfr_copy( (*sfr)->Clone()) ;
if ( IsNull( pSfr_copy))
return false ;
double dLenStrip = abs( vU[p+1] - vU[p]) ;
// creo la maschera per tagliare la superficie originale e ottenere una striscia
PtrOwner<ISurfFlatRegion> pSfrTrim( CreateSurfFlatRegion()) ;
if ( IsNull( pSfrTrim))
return false ;
if ( p != (int)vU.size() - 2) {
Vector3d vt ;
if ( nDir == 0) {
pSfrTrim.Set( GetSurfFlatRegionRectangle( dLenTot - abs(vU[p+1]), dScaleV)) ;
vt.Set( abs(vU[p+1]), 0, 0) ;
}
else{
pSfrTrim.Set( GetSurfFlatRegionRectangle( dScaleU, dLenTot - abs(vU[p+1]))) ;
vt.Set( 0, abs(vU[p+1]), 0) ;
}
pSfrTrim->Translate( vt) ;
}
if ( p != 0 ) {
PtrOwner<ISurfFlatRegion> pSfrTrim1( CreateSurfFlatRegion()) ;
if ( nDir == 0)
pSfrTrim1.Set( GetSurfFlatRegionRectangle( abs(vU[p] - vU.front()), dScaleV)) ;
else
pSfrTrim1.Set( GetSurfFlatRegionRectangle( dScaleU, abs( vU[p] - vU.front()))) ;
if ( IsNull( pSfrTrim1))
return false ;
if ( pSfrTrim->IsValid()) {
if ( ! pSfrTrim->Add( *pSfrTrim1))
return false ;
}
else
pSfrTrim.Set( pSfrTrim1) ;
}
bDone = SaveGeoObj( pSfrTrim, "D:\\Temp\\trim.nge") ;
if ( ! pSfr_copy->Subtract( *pSfrTrim))
return false ;
if ( nDir == 0)
pSfr_copy->Scale( GLOB_FRM, d00 / dLenStrip, 1, 1) ;
else
pSfr_copy->Scale( GLOB_FRM, 1, d00 / dLenStrip, 1) ;
bDone = SaveGeoObj( pSfr_copy, "D:\\Temp\\trimmed.nge") ;
if ( sfr_rescaled->IsValid()) {
// prima di riunire la striscia al resto devo traslarla sul bordo destro della superificie che sto ricostruendo
BBox3d bbSrf, bbSrf_copy ;
sfr_rescaled->GetLocalBBox( bbSrf) ;
pSfr_copy->GetLocalBBox( bbSrf_copy) ;
Vector3d vt ;
if ( nDir == 0)
vt.Set( bbSrf.GetMax().x - bbSrf_copy.GetMin().x, 0, 0) ;
else
vt.Set( 0, bbSrf.GetMax().y - bbSrf_copy.GetMin().y, 0) ;
pSfr_copy->Translate( vt) ;
if ( ! sfr_rescaled->Add( *pSfr_copy))
return false ;
}
else
sfr_rescaled.Set( pSfr_copy) ;
bDone = SaveGeoObj( sfr_rescaled, "D:\\Temp\\scaled_additive.nge") ;
}
}
BBox3d bbSrf ;
sfr_rescaled->GetLocalBBox( bbSrf) ;
if ( nDir == 0) {
dScaleU = bbSrf.GetMax().x ;
*sfr = Release( sfr_rescaled) ;
}
else
dScaleV = bbSrf.GetMax().y ;
}
*sfr = Release( sfr_rescaled) ;
return true ;
}
//----------------------------------------------------------------------------
ICurve*
Import3dm::ConvertBrepLoop( const ON_BrepLoop* onBrepLoop)
{
+3
View File
@@ -28,11 +28,13 @@ class ON_Brep ;
class ON_BrepLoop ;
class ON_3dVector ;
class ON_2dVector ;
class ON_NurbsSurface ;
class ICurve ;
class ICurveArc ;
class ICurveLine ;
class ISurf ;
class ISurfTriMesh ;
class ISurfFlatRegion ;
//----------------------------------------------------------------------------
class Import3dm : public IImport3dm
@@ -53,6 +55,7 @@ private :
ISurf* ConvertSurface( const ON_Surface* onSurf) ;
ISURFPVECTOR ConvertBrep( const ON_Brep* onBrep, const bool bForceTriMesh) ;
ICurve* ConvertBrepLoop( const ON_BrepLoop* onBrepLoop) ;
bool MakeUniform( ISurfFlatRegion** sfr, ON_NurbsSurface onNurbsSurface, double& dScaleU, double& dScaleV) ;
private :
IGeomDB* m_pGDB ;