EgtExch3dm 3.1c1 :

- nuova MakeUniform
- cambio versione.
This commit is contained in:
Daniele Bariletti
2026-03-06 17:29:23 +01:00
parent b6d788ea4f
commit 3d019e4efd
3 changed files with 157 additions and 65 deletions
BIN
View File
Binary file not shown.
+156 -64
View File
@@ -31,8 +31,20 @@
#include "/EgtDev/Include/EGnStringUtils.h"
#include "/EgtDev/Include/EgtStringConverter.h"
#include "/EgtDev/Include/EgtKeyCodes.h"
#include "/EgtDev/Include/EGkSbzFromCurves.h"
//#include "/EgtDev/Include/EgtPerfCounter.h"
#define SAVEREVOLVECURVE 0
#define SAVEREVOLVESURF 0
#define SAVEREVOLVETRIM 0
#define SAVETRIMLOOP 0
#if SAVEREVOLVECURVE || SAVEREVOLVESURF || SAVEREVOLVETRIM || SAVETRIMLOOP
#include "/EgtDev/Include/EGkGeoVector3d.h"
#include "/EgtDev/Include/EGkGeoObjSave.h"
#endif
using namespace std ;
////----------------------------------------------------------------------------
@@ -577,7 +589,7 @@ Import3dm::ConvertCurve( const ON_Curve* onCurve)
//----------------------------------------------------------------------------
ISurf*
Import3dm::ConvertSurface( const ON_Surface* onSurf)
Import3dm::ConvertSurface( const ON_Surface* onSurf, DBLVECTOR* vU, DBLVECTOR* vV)
{
if ( const ON_NurbsSurface* onNurbsSurface_ = ON_NurbsSurface::Cast( onSurf)) {
ON_NurbsSurface onNurbsSurface( *onNurbsSurface_) ;
@@ -618,6 +630,11 @@ Import3dm::ConvertSurface( const ON_Surface* onSurf)
if ( sNurbsSurf.bPeriodicU || sNurbsSurf.bPeriodicV || ! sNurbsSurf.bClampedU || ! sNurbsSurf.bClampedV)
NurbsSurfaceCanonicalize( sNurbsSurf) ;
if ( vU != nullptr) {
*vU = sNurbsSurf.vU ;
*vV = sNurbsSurf.vV ;
}
return NurbsToBezierSurface( sNurbsSurf) ;
}
else if ( const ON_PlaneSurface* onPlaneSurface = ON_PlaneSurface::Cast( onSurf)) {
@@ -662,13 +679,42 @@ Import3dm::ConvertSurface( const ON_Surface* onSurf)
ON_Interval onInter = onRevSurface->m_angle ;
double dAngRotDeg = ( onInter[1] - onInter[0]) * RADTODEG ;
double dAngStartDeg = onInter[0] * RADTODEG ;
// uso la nurbs form per ottenere i vettori
ON_NurbsSurface onNurbsSurface ;
int nOk = onRevSurface->GetNurbForm( onNurbsSurface) ;
if ( nOk != 0)
return nullptr ;
ConvertSurface( &onNurbsSurface, vU, vV) ;
// provo a convertire usando una bezier
#if SAVEREVOLVECURVE
vector<IGeoObj*> vGeo ;
vGeo.push_back( pCurve->Clone()) ;
IGeoVector3d* pVec = CreateGeoVector3d() ;
pVec->Set( vtDir, ptTo) ;
vGeo.push_back( pCurve->Clone()) ;
vGeo.push_back( pVec) ;
SaveGeoObj( vGeo, "D:\\Temp\\bezier\\import3dm\\revolve_surf\\crv.nge") ;
#endif
PtrOwner<ISurfBezier> pSurfBez( GetSurfBezierByRevolve( pCurve, ptFrom, vtDir, false, 0.01)) ;
#if SAVEREVOLVECURVE
if ( ! IsNull(pSurfBez))
SaveGeoObj( pSurfBez->Clone(), "D:\\Temp\\bezier\\import3dm\\revolve_surf\\srf.nge") ;
#endif
if ( ! IsNull( pSurfBez) && pSurfBez->IsValid())
return Release( pSurfBez) ;
// sennò uso una trimesh
PtrOwner<ISurfTriMesh> pSurf( CreateSurfTriMesh()) ;
if ( IsNull( pSurf))
return nullptr ;
// se l'angolo è significativo allora effettuo la rivoluzione
// se l'angolo è significativo allora effettuo la rivoluzione
if ( dAngRotDeg > EPS_SMALL * 10) {
pSurf.Set( GetSurfTriMeshByScrewing( pCurve, ptFrom, vtDir, dAngRotDeg, 0., false)) ;
// se la rivoluzione è meno di un angolo giro e la partenza non era a zero devo ruotare la superficie ottenuta
// se la rivoluzione è meno di un angolo giro e la partenza non era a zero devo ruotare la superficie ottenuta
if ( dAngRotDeg < 360 - EPS_SMALL * 50 && onInter[0] * RADTODEG > EPS_SMALL * 50)
pSurf->Rotate( ptFrom, vtDir, dAngStartDeg) ;
}
@@ -680,7 +726,7 @@ Import3dm::ConvertSurface( const ON_Surface* onSurf)
int nOk = onSumSurface->GetNurbForm( onNurbsSurface) ;
PtrOwner<ISurf> pSurf ;
if ( nOk != 0)
pSurf.Set( ConvertSurface( &onNurbsSurface)) ;
pSurf.Set( ConvertSurface( &onNurbsSurface, vU, vV)) ;
if ( ! IsNull( pSurf) && pSurf->IsValid())
return Release( pSurf) ;
@@ -709,39 +755,50 @@ Import3dm::ConvertSurface( const ON_Surface* onSurf)
PtrOwner<ISurf> pSurf ;
// bool bTransposed = onSurfaceProxy->ProxySurfaceIsTransposed() ;
if ( const ON_BrepFace* onBrepFace = ON_BrepFace::Cast( onSurfaceProxy)) {
// uso la nurbs form
// uso la nurbs form
ON_NurbsSurface onNurbsSurface ;
int nOk = onBrepFace->GetNurbForm( onNurbsSurface) ;
if ( nOk != 0){
pSurf.Set( ConvertSurface( & onNurbsSurface)) ;
pSurf.Set( ConvertSurface( & onNurbsSurface, vU, vV)) ;
#if SAVEREVOLVECURVE
SaveGeoObj( pSurf->Clone(), "D:\\Temp\\bezier\\import3dm\\revolve_surf\\srf_nurbs.nge") ;
#endif
}
else {
// QUI PERò NON TENGO CONTO DEL TRIM!!!!!!
//
// se non è riuscita la conversione in nurbs tengo la superficie originale
// QUI PERò NON TENGO CONTO DEL TRIM!!!!!!
//
// se non è riuscita la conversione in nurbs tengo la superficie originale
const ON_Surface* onSurfFace = onBrepFace->ProxySurface() ;
// qui devo applicare a mano le trasformazioni dalla superfice originale alla proxy
// la funzione getNurbsForm lo fa in automatico
pSurf.Set( ConvertSurface( onSurfFace)) ;
pSurf.Set( ConvertSurface( onSurfFace, vU, vV)) ;
LOG_ERROR( GetEE3Logger(), "Import3dm : Importing a surface without its trim, because of conversione errors") ;
}
////// questa versione è da usare per usare le superfici proxy anziché la versione nurbs
//pSurf.Set( ConvertSurface( onBrepFace->ProxySurface(), vU, vV)) ;
}
else if ( const ON_OffsetSurface* onOffsetSurface = ON_OffsetSurface::Cast( onSurfaceProxy)) {
//pSurf.Set( ConvertSurface( onOffsetSurface->BaseSurface())) ;
ON_NurbsSurface onNurbsSurface ;
int nOk = onOffsetSurface->GetNurbForm( onNurbsSurface) ;
if ( nOk != 0)
pSurf.Set( ConvertSurface( &onNurbsSurface)) ;
pSurf.Set( ConvertSurface( &onNurbsSurface, vU, vV)) ;
}
else
pSurf.Set( ConvertSurface( onSurfaceProxy->ProxySurface())) ;
pSurf.Set( ConvertSurface( onSurfaceProxy->ProxySurface(), vU, vV)) ;
return Release( pSurf) ;
}
return nullptr ;
}
int nFailedBFace = 0, nFailedTm = 0, nFailedFr = 0, nFailedBz = 0, nFailedBTrim = 0 ;
#if SAVETRIMLOOP
int nLoop = 0 ;
#endif
//----------------------------------------------------------------------------
ISURFPOVECTOR
@@ -755,17 +812,15 @@ Import3dm::ConvertBrep( const ON_Brep* onBrep, const bool bForceTriMesh)
StmFromTriangleSoup stmSoup ;
if ( ! stmSoup.Start())
return vSurf ;
bool bSurfTm = false ;
int nFailedBFace = 0, nFailedTm = 0, nFailedFr = 0, nFailedBz = 0, nFailedBTrim = 0 ;
int nFaceTot = onBrep->m_F.Count() ;
for ( int i = 0 ; i < nFaceTot ; ++i) {
bool bOk = true ;
ON_BrepFace* onFace = onBrep->Face( i) ;
bool bOk = true ;
bool bRev = onFace->m_bRev ;
const ON_Surface* onSurface = onFace->SurfaceOf() ;
PtrOwner<ISurf> pSurf ;
bool bTooSmallOnlyLoop = false ;
DBLVECTOR vU, vV ;
if ( const ON_PlaneSurface* onPlaneSurface = ON_PlaneSurface::Cast( onSurface)) {
SurfFlatRegionByContours SfrCntr ;
// ricavo il riferimento del piano
@@ -790,14 +845,14 @@ Import3dm::ConvertBrep( const ON_Brep* onBrep, const bool bForceTriMesh)
}
pSurf.Set( SfrCntr.GetSurf()) ;
if ( ! IsNull( pSurf) && pSurf->IsValid()) {
// porto le coordinate dal riferimento del piano di trim alle coordinate globali
// porto le coordinate dal riferimento del piano di trim alle coordinate globali
Frame3d frPlane ;
frPlane.Set( ptOrig, vtX, vtY, vtZ) ;
pSurf->ToGlob( frPlane) ;
}
}
else
pSurf.Set( ConvertSurface( onFace)) ;
pSurf.Set( ConvertSurface( onFace, &vU, &vV)) ;
if ( IsNull( pSurf) || ! pSurf->IsValid()) {
// se la superficie aveva un solo loop e questo era troppo piccolo allora NON lo segno come errore
@@ -806,10 +861,9 @@ Import3dm::ConvertBrep( const ON_Brep* onBrep, const bool bForceTriMesh)
++ nFailedBFace ;
}
else {
// se ho una trimesh o una flatregion la aggiungo alla zuppa, se è una bezier la aggiungo al vettore delle superfici
// se ho una trimesh o una flatregion la aggiungo alla zuppa, se è una bezier la aggiungo al vettore delle superfici
int nType = pSurf->GetType() ;
if ( nType == SRF_TRIMESH) {
bSurfTm = true ;
PtrOwner<ISurfTriMesh> pSurfTm( GetSurfTriMesh( Release( pSurf))) ;
if ( !IsNull(pSurfTm) && pSurfTm->IsValid() ) {
if ( bRev)
@@ -820,7 +874,6 @@ Import3dm::ConvertBrep( const ON_Brep* onBrep, const bool bForceTriMesh)
++ nFailedTm ;
}
else if ( nType == SRF_FLATRGN) {
bSurfTm = true ;
PtrOwner<ISurfFlatRegion> pSurfFr( GetSurfFlatRegion( Release( pSurf))) ;
if ( ! IsNull( pSurfFr) && pSurfFr->IsValid()) {
if ( bRev)
@@ -833,13 +886,13 @@ Import3dm::ConvertBrep( const ON_Brep* onBrep, const bool bForceTriMesh)
else if ( nType == SRF_BEZIER) {
PtrOwner<ISurfBezier> pSurfBezNew( GetSurfBezier( Release( pSurf))) ;
if ( ! IsNull( pSurfBezNew) && pSurfBezNew->IsValid()) {
ON_BrepFace* onFace = onBrep->Face( i) ;
SurfFlatRegionByContours SfrCntr ;
const ON_Surface* onSurface = onFace->SurfaceOf() ;
// se la superficie era una superficie di rivoluzione, le eventuali curve di trim erano parametrizzate con la coordinata x in radianti,
// e non riferita allo spazio parametrico della nurbs corrispondente ( che sarebbe una nurbs razionale, dovendo approssimare un arco di circonferenza)
// devo quindi prelevare le curve di trim e cambiarne le coordinate per matcharle allo spazio parametrico della nurbs
// se la superficie era una superficie di rivoluzione, le eventuali curve di trim erano parametrizzate con la coordinata x in radianti,
// e non riferita allo spazio parametrico della nurbs corrispondente ( che sarebbe una nurbs razionale, dovendo approssimare un arco di circonferenza)
// devo quindi prelevare le curve di trim e cambiarne le coordinate per matcharle allo spazio parametrico della nurbs
bool bAddedLoop = false ;
bool bTrimTooSmall = false ;
if ( const ON_RevSurface* onRevSurf = ON_RevSurface::Cast( onSurface) ) {
for ( int k = 0 ; k < onFace->LoopCount(); ++k ) {
ICurve* pCrv( ConvertBrepLoop( onFace->Loop( k))) ;
@@ -859,7 +912,7 @@ Import3dm::ConvertBrep( const ON_Brep* onBrep, const bool bForceTriMesh)
bAddedLoop = true ;
}
else
continue ;
bTrimTooSmall = true ;
}
if ( ! bOk)
continue ;
@@ -867,7 +920,13 @@ Import3dm::ConvertBrep( const ON_Brep* onBrep, const bool bForceTriMesh)
else {
for ( int k = 0 ; k < onFace->LoopCount() && bOk ; ++k ) {
PtrOwner<ICurve> pCrv( ConvertBrepLoop( onFace->Loop( k))) ;
if ( IsNull(pCrv) || ! pCrv->IsValid()) {
#if SAVETRIMLOOP
SaveGeoObj( pCrv->Clone(), "D:\\Temp\\bezier\\import3dm\\import_trim\\loop" + ToString(nLoop) + ".nge") ;
++nLoop ;
#endif
if ( IsNull( pCrv) || ! pCrv->IsValid()) {
++ nFailedBTrim ;
bOk = false ;
break ;
@@ -880,19 +939,24 @@ Import3dm::ConvertBrep( const ON_Brep* onBrep, const bool bForceTriMesh)
if ( SfrCntr.AddCurve( Release( pCrvCompo)))
bAddedLoop = true ;
}
else
else {
bTrimTooSmall = true ;
continue ;
}
}
if ( ! bOk)
continue ;
}
if ( ! bAddedLoop)
if ( ! bAddedLoop) {
if ( ! bTrimTooSmall)
++ nFailedBTrim ;
continue ;
}
ISurfFlatRegion* pSfrTrim = SfrCntr.GetSurf() ;
// questa regione di Trim deve essere riferita al rettangolo parametrico totale ( spaz param 1x1 -> regione trim 1000x1000)
// devo anche controllare che il sistema di riferimento dello spazio di trim totale sia giusto ( con l'angolo BottomLeft in (0,0)
//posizonato nel primo quadrante del piano XY)
// questa regione di Trim deve essere riferita al rettangolo parametrico totale ( spaz param 1x1 -> regione trim 1000x1000)
// devo anche controllare che il sistema di riferimento dello spazio di trim totale sia giusto ( con l'angolo BottomLeft in (0,0)
//posizonato nel primo quadrante del piano XY)
double u0,u1,v0,v1 ;
onFace->GetDomain(0, &u0, &u1) ;
onFace->GetDomain(1, &v0, &v1) ;
@@ -911,48 +975,70 @@ Import3dm::ConvertBrep( const ON_Brep* onBrep, const bool bForceTriMesh)
bool bRat, bTrim ;
pSurfBezNew->GetInfo( nDegU, nDegV, nSpanU, nSpanV, bRat, bTrim) ;
pSfrTrim->Scale( GLOB_FRM, nSpanU / dScaleU, nSpanV / dScaleV, 1.) ;
// se la superficie di partenza aveva vettori dei nodi non uniformi devo riscalare lo spazio parametrico in modo da renderli uniformi
// applicando così la trasformazione anche alle curve di trim.
// se la superficie di partenza aveva vettori dei nodi non uniformi devo riscalare lo spazio parametrico in modo da renderli uniformi
// applicando così 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
// devo rendere lo spazio parametrico uniforme solo se la superficie è trimmata, sennò non serve
// per capire se la superficie sia trimmata controllo che lo spazio parametrico trimmato non coincida con tutto lo spazio parametrico
// rendo uniforme lo spazio parametrico nella direzione dei parametri che non lo sono
// devo rendere lo spazio parametrico uniforme solo se la superficie è trimmata, sennò non serve
// per capire se la superficie sia trimmata controllo che lo spazio parametrico trimmato non coincida con tutto lo spazio parametrico
double dParamX = nSpanU * SBZ_TREG_COEFF ;
double dParamY = nSpanV * SBZ_TREG_COEFF ;
double dAreaTot = dParamX * dParamY ;
double dAreaTrim = 0 ; pSfrTrim->GetArea( dAreaTrim) ;
if( dAreaTrim / dAreaTot < 1 - EPS_SMALL) {
if ( dAreaTrim / dAreaTot < 1 - EPS_SMALL) {
bool bRescaled = false ;
DBLVECTOR vU0 , vV0 ;
for ( int i = 0 ; i < onNurbsSurface.KnotCount( 0) ; ++i)
vU0.push_back( onNurbsSurface.Knot( 0, i) * nSpanU / dScaleU) ;
for ( int j = 0 ; j < onNurbsSurface.KnotCount( 1) ; ++j)
vV0.push_back( onNurbsSurface.Knot( 1, j) * nSpanV / dScaleV) ;
ISurfFlatRegion* pSfrTrimCopy( pSfrTrim->Clone()) ;
for ( int i = 0 ; i < ssize(vU) ; ++i)
vU0.push_back( vU[i] * nSpanU / dScaleU) ;
for ( int j = 0 ; j < ssize(vV) ; ++j)
vV0.push_back( vV[j] * nSpanV / dScaleV) ;
dScaleU = dParamX ;
dScaleV = dParamY ;
if ( ! MakeUniform( pSfrTrim, bRescaled, vU0, vV0, nDegU, nDegV, dScaleU, dScaleV, false)) {
// se make uniform fallisce potrei provare a farlo rigirare con gli offset ad ogni passaggio, per non avere errori nelle operazioni tra flat region/////////
//if ( *! MakeUniform( pSfrTrimCopy, bRescaled, vU0, vV0, nDegU, nDegV, dScaleU, dScaleV, true)) {
++ nFailedBTrim ;
continue ;
//}
//else {
// delete pSfrTrim ;
// pSfrTrim = pSfrTrimCopy ;
// pSfrTrimCopy = nullptr ;
//}
}
//if ( bRescaled) {
// // per correggere eventuali crack create dal lavoro di collage sullo spazio parametrico faccio un OFFSET e controOFFSET
// pSfrTrim->Offset( 100*EPS_SMALL, ICurve::OFF_FILLET) ;
// pSfrTrim->Offset( -100*EPS_SMALL, ICurve::OFF_FILLET) ;
//if ( ssize( vU0) == 0 || ssize(vV0) == 0 ) {
// vU0.clear() ;
// vV0.clear() ;
// int nU = onFace->SpanCount(0) ;
// int nV = onFace->SpanCount(1) ;
// double* vdU = new double[nU] ;
// double* vdV = new double[nV] ;
// onFace->GetSpanVector(0,vdU) ;
// onFace->GetSpanVector(1,vdV) ;
// for ( int i = 0 ; i < nU ; ++i)
// vU0.push_back( vdU[i] * nSpanU / dScaleU) ;
// for ( int j = 0 ; j < nV ; ++j)
// vV0.push_back( vdV[j] * nSpanU / dScaleU) ;
// delete[] vdU ;
// delete[] vdV ;
// ///////// PER FAR FUNZIONARE LA CANONICALIZE SERVONO ANCHE I PUNTI
// // devo solo togliere i nodi di troppo passando il vettore alla nurbsCanonicalize
// if ( onFace->IsPeriodic(0)) {
// CNurbsData cnU ;
// cnU.bPeriodic = true ;
// cnU.vU = vU0 ;
// NurbsCurveCanonicalize( cnU) ;
// vU0 = cnU.vU ;
// }
// if ( onFace->IsPeriodic(1)) {
// CNurbsData cnV ;
// cnV.bPeriodic = true ;
// cnV.vU = vV0 ;
// NurbsCurveCanonicalize( cnV) ;
// vV0 = cnV.vU ;
// }
//}
#if SAVEREVOLVETRIM
SaveGeoObj( pSfrTrim->Clone(), "D:\\Temp\\bezier\\import3dm\\trim_error\\non_uniform_trim.nge") ;
#endif
if ( ! MakeUniform( pSfrTrim, bRescaled, vU0, vV0, nDegU, nDegV, dScaleU, dScaleV, false)) {
++ nFailedBTrim ;
continue ;
}
pSurfBezNew->SetTrimRegion( *pSfrTrim) ;
if ( pSfrTrimCopy != nullptr)
delete pSfrTrimCopy ;
}
else
pSfrTrim->Scale( GLOB_FRM, nSpanU / dScaleU, nSpanV / dScaleV, 1) ;
@@ -965,10 +1051,14 @@ Import3dm::ConvertBrep( const ON_Brep* onBrep, const bool bForceTriMesh)
pSurfBezNew->RemoveCollapsedSpans() ;
#if SAVEREVOLVESURF
SaveGeoObj( pSurfBezNew->Clone(), "D:\\Temp\\bezier\\import3dm\\revolve_surf\\surf_ok.nge") ;
#endif
if ( ! bForceTriMesh)
vSurf.emplace_back( Release( pSurfBezNew)) ;
else
stmSoup.AddSurfTriMesh( *(Release( pSurfBezNew)->GetAuxSurf())) ;
stmSoup.AddSurfTriMesh( *(pSurfBezNew->GetAuxSurf())) ;
}
else {
++nFailedBz ;
@@ -1000,8 +1090,10 @@ Import3dm::ConvertBrep( const ON_Brep* onBrep, const bool bForceTriMesh)
if ( ! stmSoup.End())
return vSurf ;
if ( bSurfTm || bForceTriMesh)
vSurf.emplace_back( stmSoup.GetSurf()) ;
PtrOwner<ISurfTriMesh> pSTM( stmSoup.GetSurf()) ;
if ( ! IsNull( pSTM) && pSTM->IsValid())
vSurf.emplace_back( Release( pSTM)) ;
return vSurf ;
}
+1 -1
View File
@@ -47,7 +47,7 @@ class Import3dm : public IImport3dm
Vector3d ConvertVector( const ON_2dVector& onVector)
{ return Vector3d( onVector.x, onVector.y, 0) ; } ;
ICurve* ConvertCurve( const ON_Curve* onCurve) ;
ISurf* ConvertSurface( const ON_Surface* onSurf) ;
ISurf* ConvertSurface( const ON_Surface* onSurf, DBLVECTOR* vU = nullptr, DBLVECTOR* vV = nullptr) ;
ISURFPOVECTOR ConvertExtrusion( const ON_Extrusion* onExtrusion) ;
ISurfTriMesh* ConvertMesh( const ON_Mesh* onMesh) ;
std::vector<PtrOwner<IGeoObj>> ConvertAnnotation( const ON_Annotation* onAnnot, const ON_DimStyle* onDimStyle, double dTextHeight, double dExtLine, double dArrLen, double dTextDist,