EgtExch3dm :

- superfici di estrusione importate come bezier e non come trimesh.
This commit is contained in:
Daniele Bariletti
2026-02-05 16:51:12 +01:00
parent f4471e8c30
commit f94cc0d1db
2 changed files with 135 additions and 83 deletions
+134 -82
View File
@@ -40,6 +40,7 @@ using namespace std ;
const double ANG_TOL_FINE = 1 ;
// tolleranza lineare affinata
const double LIN_TOL_FINE = 0.002 ;
const double LIN_TOL_STD = 0.05 ;
//----------------------------------------------------------------------------
IImport3dm*
@@ -286,12 +287,14 @@ Import3dm::Import( const string& sFile, IGeomDB* pGDB, int nIdGroup,
}
case ON::object_type::extrusion_object : {
const ON_Extrusion* onExtrusion = ON_Extrusion::Cast( oGeometry) ;
PtrOwner<ISurfTriMesh> pSurfTm( ConvertExtrusion( onExtrusion)) ;
if ( ! IsNull( pSurfTm) && pSurfTm->IsValid())
vpGeoObj.emplace_back( Release( pSurfTm)) ;
else
m_mError_count["mesh"] += 1 ;
break ;
ISURFPOVECTOR vpSurf = ConvertExtrusion( onExtrusion) ;
for ( int k = 0 ; k < int( vpSurf.size()) ; ++ k) {
PtrOwner<ISurf> pSurf( GetSurf( Release( vpSurf[k]))) ;
if ( ! IsNull( pSurf) && pSurf->IsValid())
vpGeoObj.emplace_back( Release( pSurf)) ;
else
m_mError_count["extrusion"] += 1 ;
}
break ;
}
case ON::object_type::mesh_object :{
@@ -1050,24 +1053,22 @@ Import3dm::ConvertBrepLoop( const ON_BrepLoop* onBrepLoop)
}
//----------------------------------------------------------------------------
ISurfTriMesh*
ISURFPOVECTOR
Import3dm::ConvertExtrusion( const ON_Extrusion* onExtrusion)
{
ISURFPOVECTOR vpSurf ;
Point3d ptStart( ConvertPoint( onExtrusion->PathStart())) ;
Point3d ptEnd( ConvertPoint( onExtrusion->PathEnd())) ;
Vector3d vDir = ptEnd - ptStart ;
Vector3d vtDir = ptEnd - ptStart ;
int nIsCapped = onExtrusion->IsCapped() ; // 0: no or profile is open /1: bottom cap( ptEnd) /2: top cap( ptStart) /3: both ends capped.
PtrOwner<ISurfTriMesh> pSurfTm( CreateSurfTriMesh()) ;
if ( IsNull(pSurfTm))
return nullptr ;
// creo la superficie a partire dalle curve
CICURVEPVECTOR vCrvProfile ;
int nProfiles = onExtrusion->ProfileCount() ;
////////// versione con le curve 2d da trasformare in 3d ( a volte manca un pezzo di trasformazione)
//ON_SimpleArray<const ON_Curve*> onSaProfile ;
//int nProfiles = onExtrusion->GetProfileCurves( onSaProfile) ;
for (int i = 0 ; i < nProfiles ; ++i ) {
for ( int i = 0 ; i < nProfiles ; ++i ) {
//const ON_Curve* onCurve = onSaProfile[i] ;
//ON_Xform onProfileFrame ; onExtrusion->GetProfileTransformation( 0, onProfileFrame) ;
//ON_Curve* onCurveCopy = onCurve->DuplicateCurve() ;
@@ -1078,92 +1079,143 @@ Import3dm::ConvertExtrusion( const ON_Extrusion* onExtrusion)
ON_Curve* onCurve = onExtrusion->Profile3d( i, 0) ; // do per scontato che il profilo resti uguale dall'inizio alla fine del path
PtrOwner<ICurve> pCurve( ConvertCurve( onCurve)) ;
delete onCurve ;
if ( IsNull(pCurve) || ! pCurve->IsValid()) {
if ( IsNull( pCurve) || ! pCurve->IsValid()) {
m_mError_count["extrusion"] += 1 ;
break ;
}
vCrvProfile.emplace_back( Release(pCurve)) ;
}
// se l'estrusione è capped sia sopra che sotto uso la funzione *byRegionExtrusion
if ( nIsCapped == 3) {
pSurfTm.Set( GetSurfTriMeshByRegionExtrusion( vCrvProfile, vDir)) ;
// uso l'estrusione con le bezier
for ( int i = 0 ; i < ssize( vCrvProfile); ++i) {
PtrOwner<ISurfBezier> pSurfBez( CreateSurfBezier()) ;
pSurfBez->CreateByExtrusion( vCrvProfile[i], vtDir) ;
vpSurf.emplace_back() ;
vpSurf.back().Set( Release( pSurfBez)) ;
}
else {
StmFromTriangleSoup stmSoup ;
if ( ! stmSoup.Start())
return nullptr ;
for ( int i = 0 ; i < (int)vCrvProfile.size() ; ++i )
stmSoup.AddSurfTriMesh( *GetSurfTriMeshByExtrusion( vCrvProfile[i], vDir, false)) ;
// controllo se la superficie è capped solo sopra o sotto ed eventualmente aggiungo alla trimesh la superficie adeguata
if ( nIsCapped != 0) {
PtrOwner<ISurfTriMesh> pSurfTmCap( GetSurfTriMeshByRegion( vCrvProfile)) ;
if ( ! IsNull( pSurfTmCap) && pSurfTmCap->IsValid()) {
// se capped sopra traslo la trimeshregion
if ( nIsCapped == 1)
pSurfTmCap->Translate(vDir) ;
// sennò la aggiungo direttamente
stmSoup.AddSurfTriMesh( *pSurfTmCap) ;
}
///// quando ci saranno le surf compo allora la superficie con cap dovrà essere un'unica surfcompo
if ( nIsCapped != 0) {
// aggiungo anche le due superfici di cap
PtrOwner<ISurfBezier> pSurfBezCap( CreateSurfBezier()) ;
POLYLINEVECTOR vPL ;
for ( int i = 0 ; i < ssize( vCrvProfile) ; ++i) {
vPL.emplace_back() ;
vCrvProfile[i]->ApproxWithLines( LIN_TOL_STD, ANG_TOL_FINE, ICurve::ApprLineType::APL_STD, vPL.back()) ;
}
if ( nIsCapped == 2 || nIsCapped == 3) { // top o entrambe
if ( ! pSurfBezCap->CreateByRegion( vPL) || ! pSurfBezCap->Invert()) {
m_mError_count["extrusion"] += 1 ;
goto exit ;
}
vpSurf.emplace_back() ;
vpSurf.back().Set( Release( pSurfBezCap)) ;
}
if ( nIsCapped == 1 || nIsCapped == 3) { // bottom o entrambe
if ( nIsCapped == 3) {
vpSurf.emplace_back( vpSurf.back()->Clone()) ;
vpSurf.back()->Invert() ;
}
else {
pSurfBezCap.Set( CreateSurfBezier()) ;
if( ! pSurfBezCap->CreateByRegion( vPL)) {
m_mError_count["extrusion"] += 1 ;
goto exit ;
}
vpSurf.emplace_back() ;
vpSurf.back().Set( Release( pSurfBezCap)) ;
}
vpSurf.back()->Translate( vtDir) ;
}
if ( ! stmSoup.End())
return nullptr ;
pSurfTm.Set( GetSurfTriMesh( stmSoup.GetSurf())) ;
}
// se ho fallito con le bezier procedo con le trimesh
if( ssize( vpSurf) == 0) {
if ( nIsCapped == 3) {
vpSurf.emplace_back( GetSurfTriMeshByRegionExtrusion( vCrvProfile, vtDir)) ;
}
else {
StmFromTriangleSoup stmSoup ;
if ( ! stmSoup.Start()) {
m_mError_count["extrusion"] += 1 ;
goto exit ;
}
for ( int i = 0 ; i < (int)vCrvProfile.size() ; ++i )
stmSoup.AddSurfTriMesh( *GetSurfTriMeshByExtrusion( vCrvProfile[i], vtDir, false)) ;
// controllo se la superficie è capped solo sopra o sotto ed eventualmente aggiungo alla trimesh la superficie adeguata
if ( nIsCapped != 0) {
PtrOwner<ISurfTriMesh> pSurfTmCap( GetSurfTriMeshByRegion( vCrvProfile)) ;
if ( ! IsNull( pSurfTmCap) && pSurfTmCap->IsValid()) {
// se capped sopra traslo la trimeshregion
if ( nIsCapped == 1)
pSurfTmCap->Translate(vtDir) ;
// sennò la aggiungo direttamente
stmSoup.AddSurfTriMesh( *pSurfTmCap) ;
}
}
if ( ! stmSoup.End()){
m_mError_count["extrusion"] += 1 ;
goto exit ;
}
vpSurf.emplace_back( GetSurfTriMesh( stmSoup.GetSurf())) ;
}
}
exit :
for ( int k = 0 ; k < (int)vCrvProfile.size() ; ++k) {
if ( vCrvProfile[k] != nullptr)
delete vCrvProfile[k] ;
}
return vpSurf ;
if ( ! IsNull( pSurfTm) && pSurfTm->IsValid())
return Release( pSurfTm) ;
else {
// se non sono riuscito a creare la superficie per qualche motivo, allora tento una conversione con gli strumenti di OPENURBS prima
// di convertire la superficie
//// CONVERSIONE DELL'EXTRUSION AD UN'ALTRA SUPERFICIE RHINO PRIMA DI ESSERE CONVERTITA
ON_Object* onObject = nullptr ;
ISurf* pSurf = nullptr ;
PtrOwner<ISurfBezier> pSurfBz( CreateSurfBezier()) ;
if ( IsNull( pSurfBz))
return nullptr ;
PtrOwner<ISurfTriMesh> pSurfTm( CreateSurfTriMesh()) ;
if ( IsNull( pSurfTm))
return nullptr ;
if ( onExtrusion->IsCapped() || onExtrusion->ProfileCount() >= 2) {
onObject = onExtrusion->BrepForm(0) ;
if ( nullptr != onObject) {
const ON_Brep* onBrep = ON_Brep::Cast( onObject) ;
ISURFPOVECTOR vpSurf ;
vpSurf = ConvertBrep( onBrep, true) ; // chiedo di ottenere un'unica superficie trimesh
pSurfTm.Set( GetSurfTriMesh( Release(vpSurf[0]))) ;
}
}
if ( onObject == nullptr) {
onObject = onExtrusion->SumSurfaceForm(0) ;
if ( onObject != nullptr) {
const ON_Surface* onSurface = ON_Surface::Cast( onObject) ;
pSurf = ConvertSurface( onSurface) ;
pSurfTm.Set( GetSurfTriMesh(pSurf)) ;
}
}
if ( onObject == nullptr) {
onObject = onExtrusion->NurbsSurface(0) ;
if ( onObject != nullptr) {
const ON_NurbsSurface* onNurbsSurface = ON_NurbsSurface::Cast( onObject) ;
pSurf = ConvertSurface( onNurbsSurface) ;
// in questo caso devo anche trasformare la superficie di bezier che ho appenta ottenuto in una trimesh
pSurfBz.Set( GetSurfBezier( pSurf)) ;
pSurfTm.Set( pSurfBz->GetAuxSurf()->Clone()) ;
}
}
if ( ! IsNull( pSurfTm) && pSurfTm->IsValid())
return Release( pSurfTm) ;
}
////////////////// VERSIONE CON BREP - RIDONDANTE
//if ( ! IsNull( pSurfTm) && pSurfTm->IsValid())
// return Release( pSurfTm) ;
//else {
// // se non sono riuscito a creare la superficie per qualche motivo, allora tento una conversione con gli strumenti di OPENURBS prima
// // di convertire la superficie
// //// CONVERSIONE DELL'EXTRUSION AD UN'ALTRA SUPERFICIE RHINO PRIMA DI ESSERE CONVERTITA
// ON_Object* onObject = nullptr ;
// ISurf* pSurf = nullptr ;
// PtrOwner<ISurfBezier> pSurfBz( CreateSurfBezier()) ;
// if ( IsNull( pSurfBz))
// return nullptr ;
// PtrOwner<ISurfTriMesh> pSurfTm( CreateSurfTriMesh()) ;
// if ( IsNull( pSurfTm))
// return nullptr ;
// if ( onExtrusion->IsCapped() || onExtrusion->ProfileCount() >= 2) {
// onObject = onExtrusion->BrepForm(0) ;
// if ( nullptr != onObject) {
// const ON_Brep* onBrep = ON_Brep::Cast( onObject) ;
// ISURFPOVECTOR vpSurf ;
// vpSurf = ConvertBrep( onBrep, true) ; // chiedo di ottenere un'unica superficie trimesh
// pSurfTm.Set( GetSurfTriMesh( Release(vpSurf[0]))) ;
// }
// }
// if ( onObject == nullptr) {
// onObject = onExtrusion->SumSurfaceForm(0) ;
// if ( onObject != nullptr) {
// const ON_Surface* onSurface = ON_Surface::Cast( onObject) ;
// pSurf = ConvertSurface( onSurface) ;
// pSurfTm.Set( GetSurfTriMesh(pSurf)) ;
// }
// }
// if ( onObject == nullptr) {
// onObject = onExtrusion->NurbsSurface(0) ;
// if ( onObject != nullptr) {
// const ON_NurbsSurface* onNurbsSurface = ON_NurbsSurface::Cast( onObject) ;
// pSurf = ConvertSurface( onNurbsSurface) ;
// // in questo caso devo anche trasformare la superficie di bezier che ho appenta ottenuto in una trimesh
// pSurfBz.Set( GetSurfBezier( pSurf)) ;
// pSurfTm.Set( pSurfBz->GetAuxSurf()->Clone()) ;
// }
// }
// if ( ! IsNull( pSurfTm) && pSurfTm->IsValid())
// return Release( pSurfTm) ;
//}
m_mError_count["extrusion"] += 1 ;
return nullptr ;
//m_mError_count["extrusion"] += 1 ;
//return nullptr ;
}
//----------------------------------------------------------------------------
+1 -1
View File
@@ -48,7 +48,7 @@ class Import3dm : public IImport3dm
{ return Vector3d( onVector.x, onVector.y, 0) ; } ;
ICurve* ConvertCurve( const ON_Curve* onCurve) ;
ISurf* ConvertSurface( const ON_Surface* onSurf) ;
ISurfTriMesh* ConvertExtrusion( const ON_Extrusion* onExtrusion) ;
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,
bool bLenIsMM, int nDecDig, std::string sFont) ;