EgtExch3dm :

- nell'import gestiti i nomi degli oggetti e le loro info( quelle salvate negli attributi)
- aggiunta funzione per la conversione delle stringhe.
This commit is contained in:
Daniele Bariletti
2026-01-27 10:06:55 +01:00
parent 5c3c9863ae
commit dcd399c379
2 changed files with 65 additions and 159 deletions
+64 -159
View File
@@ -52,6 +52,14 @@ CreateImport3dm( void)
return static_cast<IImport3dm*> ( new( nothrow) Import3dm) ;
}
//----------------------------------------------------------------------------
string
Import3dm::ConvertONwStringToString( ON_wString ON_wString)
{
return wstringtoA( wstring( ON_wString)) ;
}
int ON_nEntity = 0 ;
//----------------------------------------------------------------------------
@@ -115,11 +123,11 @@ Import3dm::Import( const string& sFile, IGeomDB* pGDB, int nIdGroup,
[uuidParent](pair< int, tuple<const ON_Layer*, ON_UUID, int, int, int>> x){ return !ON_UuidCompare( get<1>(get<1>(x)), uuidParent) ;}); // ON_UuidCompare restituisce 0 se coincidono
int nParentL1 = -1 ;
// risalgo la gerarchia dei layer finché arrivo al primo layer e aggiungo tutti i nomi al nome del sottolayer
string sName = wstringtoA( wstring( onLayer->Name())) ;
string sName = ConvertONwStringToString( onLayer->Name()) ;
bool bIsVisible = onLayer->IsVisible() ;
while ( ON_UuidCompare( uuidParent, ON_nil_uuid) ) {// ON_UuidCompare restituisce 0 se coincidono
const ON_Layer* onParentLayer = get<0>(it->second) ;
string sParentName = wstringtoA( wstring( onParentLayer->Name())) ;
string sParentName = ConvertONwStringToString( onParentLayer->Name()) ;
// se sono ad una profondità maggiore di 1 aggiungo il nome del parent
if ( get<3>(it->second) > 1)
sName = sParentName + "_" + sName ;
@@ -163,13 +171,23 @@ Import3dm::Import( const string& sFile, IGeomDB* pGDB, int nIdGroup,
// OGGETTI GEOMETRICI
ONX_ModelComponentIterator component_iterator( model, ON_ModelComponent::Type::ModelGeometry) ;
// se non riesco a convertire un oggetto, lo scarto e incremento il contatore del suo tipo nel dizionario error_count
ON_nEntity = 0 ;
int nId ;
for( const ON_ModelComponent* mc = component_iterator.FirstComponent() ; mc != nullptr ; mc = component_iterator.NextComponent())
{
const ON_ModelGeometryComponent* mgc = ON_ModelGeometryComponent::Cast( mc) ;
ON_wString onwStrName ;
mgc->GetName( onwStrName) ;
string sObjName = ConvertONwStringToString( onwStrName) ;
//// verifico se ho un oggetto che è un instance reference
//const ON_3dmObjectAttributes* model_geometry_attributes = mgc->Attributes( nullptr) ;
//bool bIsInstanceDefinitionObject = model_geometry_attributes->IsInstanceDefinitionObject() ;
//if( ! bIsInstanceDefinitionObject)
// continue ;
const ON_Object* oGeometry = mgc->Geometry( nullptr) ;
// individuo a che layer appartiene l'oggetto
const ON_3dmObjectAttributes* attributes = mgc->Attributes( nullptr) ;
@@ -355,10 +373,20 @@ Import3dm::Import( const string& sFile, IGeomDB* pGDB, int nIdGroup,
}
else
nSubLayer = nLayer ;
for (int p = 0 ; p < (int) vpGeoObj.size() ; ++p) {
if ( ! IsNull( vpGeoObj[p]) && vpGeoObj[p]->IsValid() ) {
// recupero eventuali informazioni dell'oggetto
ON_ClassArray<ON_UserString> onvUserString ;
const ON_3dmObjectAttributes* model_geometry_attributes = mgc->Attributes( nullptr) ;
int nInfo = model_geometry_attributes->GetUserStrings( onvUserString) ;
for ( int p = 0 ; p < (int) vpGeoObj.size() ; ++p) {
if ( ! IsNull( vpGeoObj[p]) && vpGeoObj[p]->IsValid()) {
nId = m_pGDB->AddGeoObj( GDB_ID_NULL, nSubLayer, Release( vpGeoObj[p])) ;
m_pGDB->SetMaterial( nId, cCol) ;
for ( int i = 0 ; i < nInfo ; ++i) {
m_pGDB->SetInfo( nId, ConvertONwStringToString( onvUserString[i].m_key), ConvertONwStringToString( onvUserString[i].m_string_value)) ;
}
m_pGDB->SetName( nId, sObjName) ;
}
}
++ ON_nEntity ;
@@ -727,7 +755,8 @@ Import3dm::ConvertBrep( const ON_Brep* onBrep, const bool bForceTriMesh)
bool bSurfTm = false ;
int nFailedBFace = 0, nFailedTm = 0, nFailedFr = 0, nFailedBz = 0, nFailedBTrim = 0 ;
for ( int i = 0 ; i < onBrep->m_F.Count() ; ++i) {
int nFaceTot = onBrep->m_F.Count() ;
for ( int i = 0 ; i < nFaceTot ; ++i) {
bool bOk = true ;
ON_BrepFace* onFace = onBrep->Face( i) ;
bool bRev = onFace->m_bRev ;
@@ -864,28 +893,30 @@ Import3dm::ConvertBrep( const ON_Brep* onBrep, const bool bForceTriMesh)
double u0,u1,v0,v1 ;
onFace->GetDomain(0, &u0, &u1) ;
onFace->GetDomain(1, &v0, &v1) ;
double dScaleU = (u1 - u0) * SBZ_TREG_COEFF ;
double dScaleV = (v1 - v0) * SBZ_TREG_COEFF ;
Vector3d vToOrig( -u0 * SBZ_TREG_COEFF, -v0 * SBZ_TREG_COEFF, 0) ;
double dScaleU = (u1 - u0) ;
double dScaleV = (v1 - v0) ;
Vector3d vToOrig( -u0, -v0, 0) ;
vToOrig *= SBZ_TREG_COEFF ;
if ( pSfrTrim != nullptr)
pSfrTrim->Translate( vToOrig) ;
else {
++ nFailedBTrim ;
continue ;
}
int nDegU, nDegV, nSpanU, nSpanV ;
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.
ON_NurbsSurface onNurbsSurface ;
onFace->GetNurbForm( onNurbsSurface) ;
// rendo uniforme lo spazio parametrico nella direzione dei parametri che non lo sono
int nDegU, nDegV, nSpanU, nSpanV ;
bool bRat, bTrim ;
pSurfBezNew->GetInfo( nDegU, nDegV, nSpanU, nSpanV, bRat, bTrim) ;
// 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 = dScaleU ;
double dParamY = dScaleV ;
double dParamX = nSpanU * SBZ_TREG_COEFF ;
double dParamY = nSpanV * SBZ_TREG_COEFF ;
double dAreaTot = dParamX * dParamY ;
double dAreaTrim = 0 ; pSfrTrim->GetArea( dAreaTrim) ;
@@ -893,27 +924,29 @@ Import3dm::ConvertBrep( const ON_Brep* onBrep, const bool bForceTriMesh)
bool bRescaled = false ;
DBLVECTOR vU0 , vV0 ;
for ( int i = 0 ; i < onNurbsSurface.KnotCount( 0) ; ++i)
vU0.push_back( onNurbsSurface.Knot( 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)) ;
vV0.push_back( onNurbsSurface.Knot( 1, j) * nSpanV / dScaleV) ;
ISurfFlatRegion* pSfrTrimCopy( pSfrTrim->Clone()) ;
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)) {
//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) ;
//}
//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) ;
//}
pSurfBezNew->SetTrimRegion( *pSfrTrim) ;
if ( pSfrTrimCopy != nullptr)
delete pSfrTrimCopy ;
@@ -982,134 +1015,6 @@ Import3dm::ApproxTrim( ICurve* pCrv)
return Release( pCC) ;
}
////----------------------------------------------------------------------------
//bool
//Import3dm::MakeUniform( ISurfFlatRegion** sfr, ON_NurbsSurface onNurbsSurface, double dScaleU, double dScaleV, bool& bRescaled, bool bRetry)
//{
// // la superficie in input arriva già scalata
// bool bRescaledU = false ;
// bool bRescaledV = false ;
// int nSpanU = 1, nSpanV = 1 ;
// PtrOwner<ISurfFlatRegion> sfr_rescaled( CreateSurfFlatRegion()) ;
// for ( int nDir = 0 ; nDir <= 1 ; ++ nDir) {
// // vettore dei nodi
// DBLVECTOR vU ;
// int nExtraKnots = 0 ;
// // se la superficie è con deg > 1, periodica, clamped o unclamped devo tagliare Deg - 1 nodi all'estremo interessato
// if ( onNurbsSurface.Degree(nDir) > 1 || onNurbsSurface.IsPeriodic( nDir)) {
// nExtraKnots = onNurbsSurface.Degree( nDir) - 1 ;
// }
// for ( int i = nExtraKnots ; i < onNurbsSurface.KnotCount( nDir) - nExtraKnots ; ++i ) {
// double dKnot = onNurbsSurface.Knot( nDir, i) * SBZ_TREG_COEFF ;
// // lo aggiungo solo se è diverso dal precedente
// if ( i == nExtraKnots || dKnot > vU.back() + EPS_SMALL || dKnot < vU.back() - EPS_SMALL)
// vU.push_back( dKnot) ;
// }
// nDir == 0 ? nSpanU = (int)vU.size() - 1 : nSpanV = (int)vU.size() - 1 ;
// // controllo se il vettore dei nodi è uniforme
// int a = 0, b = 1 ;
// double d0 = abs( vU[b] - vU[a]), d1 = d0 ;
// // il vettore è uniforme quando la distanza tra nodi consecutivi è sempre zero o un valore costante
// while ( b < (int)vU.size() && ( ( d1 < d0 + EPS_SMALL && d1 > d0 - EPS_SMALL) || d1 < EPS_SMALL)) {
// a = b ;
// ++b ;
// if ( b < (int)vU.size())
// d1 = abs( vU[b] - vU[a]) ;
// }
// if ( b != (int)vU.size()) {
// nDir == 0 ? bRescaledU = true : bRescaledV = true ;
// sfr_rescaled.Set( CreateSurfFlatRegion()) ;
// if ( IsNull( sfr_rescaled))
// return false ;
// 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]) ;
// if ( dLenStrip < EPS_SMALL)
// continue ;
// // creo la maschera per tagliare la superficie originale e ottenere una striscia
// PtrOwner<ISurfFlatRegion> pSfrTrim( CreateSurfFlatRegion()) ;
//
// // ricavo la maschera del trim, con cui poi farò l'intersezione con la sfr iniziale
// Vector3d vtTrim ;
// if ( nDir == 0) {
// pSfrTrim.Set( GetSurfFlatRegionRectangle( dLenStrip, dScaleV * SBZ_TREG_COEFF + 2)) ;
// vtTrim.Set( abs(vU[p] - vU.front()), - 1, 0) ;
// }
// else{
// pSfrTrim.Set( GetSurfFlatRegionRectangle( dScaleU * SBZ_TREG_COEFF + 2, dLenStrip)) ;
// vtTrim.Set( - 1, abs(vU[p] - vU.front()), 0) ;
// }
// pSfrTrim->Translate( vtTrim) ;
//
// if ( ! pSfr_copy->Intersect( *pSfrTrim))
// return false ;
//
// // aggiungo la nuova striscia solo se è valida
// if ( pSfr_copy->IsValid() ) {
// if ( nDir == 0)
// pSfr_copy->Scale( GLOB_FRM, SBZ_TREG_COEFF / dLenStrip, 1, 1) ;
// else
// pSfr_copy->Scale( GLOB_FRM, 1, SBZ_TREG_COEFF / dLenStrip, 1) ;
//
// // prima di riunire la striscia al resto devo traslarla sul bordo destro della superificie che sto ricostruendo
//
// Point3d pt ;
// nDir == 0 ? pt.Set( abs(vU[p] - vU.front()), 0, 0) : pt.Set( 0,abs(vU[p] - vU.front()), 0) ;
// if ( nDir == 0)
// pt.Scale( GLOB_FRM, SBZ_TREG_COEFF / dLenStrip, 1, 1) ;
// else
// pt.Scale( GLOB_FRM, 1, SBZ_TREG_COEFF / dLenStrip, 1) ;
//
// Vector3d vtJoin ;
// if ( nDir == 0)
// vtJoin.Set( p * SBZ_TREG_COEFF - pt.x, 0, 0) ;
// else
// vtJoin.Set( 0, p * SBZ_TREG_COEFF - pt.y, 0) ;
// pSfr_copy->Translate( vtJoin) ;
// // se sto ritentando MakeUniform, allora faccio anche OFFSET e controOFFSET
// if ( bRetry)
// pSfr_copy->Offset( 10*EPS_SMALL,ICurve::OFF_FILLET) ; // OFFSET
// if ( sfr_rescaled->IsValid()) {
// if ( ! sfr_rescaled->Add( *pSfr_copy))
// return false ;
// }
// else
// sfr_rescaled.Set( pSfr_copy) ;
// }
// }
// if ( nDir == 0) {
// dScaleU = (int)vU.size() - 1 ;
// if ( sfr_rescaled->IsValid()) {
// if ( bRetry)
// sfr_rescaled->Offset( -10*EPS_SMALL,ICurve::OFF_FILLET) ; //contro OFFSET
// *sfr = Release( sfr_rescaled) ;
// }
// }
// else
// dScaleV = (int)vU.size() - 1 ;
// }
// }
//
// if ( ! IsNull( sfr_rescaled) && sfr_rescaled->IsValid()) {
// if ( bRetry)
// sfr_rescaled->Offset( -10*EPS_SMALL,ICurve::OFF_FILLET) ; // contro OFFSET
// *sfr = Release( sfr_rescaled) ;
// }
//
// if ( ! bRescaledU && ! bRescaledV)
// ( *sfr)->Scale( GLOB_FRM, nSpanU / dScaleU, nSpanV / dScaleV, 1) ;
// else if ( bRescaledU && ! bRescaledV)
// ( *sfr)->Scale( GLOB_FRM, 1, nSpanV / dScaleV, 1) ;
// else if ( ! bRescaledU && bRescaledV)
// ( *sfr)->Scale( GLOB_FRM, nSpanU / dScaleU, 1, 1) ;
//
// bRescaled = bRescaledU || bRescaledV ;
// return true ;
//}
//----------------------------------------------------------------------------
ICurve*
Import3dm::ConvertBrepLoop( const ON_BrepLoop* onBrepLoop)
@@ -1336,7 +1241,7 @@ Import3dm::ConvertAnnotation( const ON_Annotation* onAnnot, const ON_DimStyle* o
switch( onAnnType) {
case ON::AnnotationType::Text : {
const ON_Text* onText = ON_Text::Cast( onAnnot) ;
string str = wstringtoA( wstring( onText->PlainText())) ;
string str = ConvertONwStringToString( onText->PlainText()) ;
ON_Plane onPlane = onText->Plane() ;
Point3d ptOrig = ConvertPoint( onPlane.origin) ;
Vector3d vtN = ConvertVector( onPlane.Normal()) ;
@@ -1354,7 +1259,7 @@ Import3dm::ConvertAnnotation( const ON_Annotation* onAnnot, const ON_DimStyle* o
}
case ON::AnnotationType::Leader : {
const ON_Leader* onLeader = ON_Leader::Cast( onAnnot) ;
string str = wstringtoA( wstring( onLeader->PlainText())) ;
string str = ConvertONwStringToString( onLeader->PlainText()) ;
ON_Plane onPlane = onAnnot->Plane() ;
Point3d ptOrig = ConvertPoint( onPlane.origin) ;
Vector3d vtX = ConvertVector( onPlane.xaxis) ;
+1
View File
@@ -56,6 +56,7 @@ class Import3dm : public IImport3dm
ICurve* ConvertBrepLoop( const ON_BrepLoop* onBrepLoop) ;
ICurveComposite* ApproxTrim( ICurve* pCrv) ;
bool ConvertCurveParam( const ON_RevSurface* onRevSurf, ICurve** pCrv) ;
std::string ConvertONwStringToString( ON_wString ON_wString) ;
private :
IGeomDB* m_pGDB ;