EgtExch3dm :

- corretto un errore di esportazione delle superfici di bezier.
- aggiunta la possibilità di eliminare il layer rimasti vuoti durante
l'esportazione.
- aggiunte le facce composte nelle Mesh di un 3dm
- corretta gestione dell'orientazione delle superfici importate
- corretta l'importazione delle curve di trim delle superfici di
rivoluzione ( spazio param diverso da quello della nurbs corrispondente)
- resa più robusta la conversione dei BrepLoop in caso di curve compo
composte da tratti molto corti.
This commit is contained in:
Daniele Bariletti
2023-11-27 12:47:44 +01:00
parent 9ebdf4a8b3
commit 87fec5a111
4 changed files with 222 additions and 57 deletions
+46 -10
View File
@@ -115,10 +115,11 @@ Export3dm::Export( IGeomDB* pGDB, int nId, const string& sFile)
return false ;
pIter->GoTo( nId) ;
// esporto l'oggetto e i suoi eventuali figli
bool bOk = ExportObject( *pIter, 0) ;
bool bAdded = false ;
bool bOk = ExportObject( *pIter, 0, bAdded) ;
// stampo il file
int version = 7 ;
int version = 8 ;
// errors printed to stdout
ON_TextLog error_log ;
// writes model to archive
@@ -131,7 +132,7 @@ Export3dm::Export( IGeomDB* pGDB, int nId, const string& sFile)
//----------------------------------------------------------------------------
bool
Export3dm::ExportObject( const IGdbIterator& iIter, const int& nLayer)
Export3dm::ExportObject( const IGdbIterator& iIter, const int& nLayer, bool& bAdded)
{
// recupero il livello dell'oggetto
int nLev = GDB_LV_USER ;
@@ -164,36 +165,50 @@ Export3dm::ExportObject( const IGdbIterator& iIter, const int& nLayer)
case GEO_PNT3D: {
if ( ! ExportPnt( sName, iIter, frFrame, cCol, nLayer))
return false ;
else
bAdded = true ;
break ;
}
case SRF_BEZIER: {
if ( ! ExportSrfBz( sName, iIter, frFrame, cCol, nLayer))
return false ;
else
bAdded = true ;
break ;
}
case SRF_FLATRGN :
case SRF_TRIMESH :
if ( ! ExportSTM( sName, iIter, frFrame, cCol, nLayer))
return false ;
else
bAdded = true ;
break ;
case CRV_ARC : {
if ( ! ExportCrvArc( sName, iIter, frFrame, cCol, nLayer))
return false ;
else
bAdded = true ;
break ;
}
case CRV_BEZIER : {
if ( ! ExportCrvBezier( sName, iIter, frFrame, cCol, nLayer))
return false ;
else
bAdded = true ;
break ;
}
case CRV_COMPO : {
if ( ! ExportCrvCompo( sName, iIter, frFrame, cCol, nLayer))
return false ;
else
bAdded = true ;
break ;
}
case CRV_LINE : {
if ( ! ExportCrvLine( sName, iIter, frFrame, cCol, nLayer))
return false ;
else
bAdded = true ;
break ;
}
default :
@@ -205,7 +220,8 @@ Export3dm::ExportObject( const IGdbIterator& iIter, const int& nLayer)
int nLayer = iIter.GetId() ;
if ( nLayer == 0) {
m_model.RemoveModelComponent( ON_ModelComponent::Type::Layer, m_model.LayerFromIndex( 0).ModelComponentId()) ;
return ScanGroup( iIter, nLayer) ;
bool bEmpty = false ;
return ScanGroup( iIter, nLayer, bEmpty) ;
}
// creo il layer e setto le proprietà
ON_Layer* layer = new ON_Layer() ;
@@ -236,11 +252,19 @@ Export3dm::ExportObject( const IGdbIterator& iIter, const int& nLayer)
// aggiungo il layer
ON_ModelComponentReference mcr = m_model.AddManagedModelComponent( layer) ;
ON_UUID uuid = mcr.ModelComponentId() ;
int nIndex = mcr.ModelComponentIndex() ;
m_mLayer.insert( pair< int, int>( nLayer, nIndex)) ;
// esploro il gruppo
return ScanGroup( iIter, nIndex) ;
bool bEmpty = false ;
bool bOk = ScanGroup( iIter, nIndex, bEmpty) ;
if ( bEmpty)
;
//m_model.RemoveModelComponent( ON_ModelComponent::Type::Layer, uuid) ; // se si volessero cancellare i layer vuoti
else
bAdded = true ;
return bOk ;
}
default :
return false ;
@@ -434,10 +458,10 @@ Export3dm::ExportSrfBz( const string& sName, const IGdbIterator& iIter, const Fr
// imposto il vettore dei nodi in V
int nKnotCountV = nDegV + nCPV - 1 ;
dKnot = 0 ;
// per costruzione nKnotCount é un multiplo di nDegU
// per costruzione nKnotCount é un multiplo di nDegV
for ( int v = 0 ; v < int ( nKnotCountV / nDegV) ; ++v) {
for ( int p = 0 ; p < nDegV ; ++p)
onNurbsSurf->SetKnot( 0, v * nDegV + p, dKnot) ;
onNurbsSurf->SetKnot( 1, v * nDegV + p, dKnot) ;
++dKnot ;
}
// aggiungo l'oggetto al modello
@@ -482,6 +506,11 @@ Export3dm::ExportSTM( const string& sName, const IGdbIterator& iIter, const Fram
int nIdVert[3] ; pSrfTm->GetTriangle( t, nIdVert) ;
onMesh->SetTriangle( t, nIdVert[0], nIdVert[1], nIdVert[2]) ;
}
ON_MeshVertexFaceMap onMeshVertMap ;
onMeshVertMap.SetFromMesh( onMesh, false) ;
onMesh->AddPlanarNgons( onMeshVertMap.VertexFaceMap(), 0.1, 3, 1, true) ;
onMesh->ComputeFaceNormals() ;
onMesh->Compact() ;
// aggiungo l'oggetto al modello
return AddObjectToModel( iIter, onMesh, nLayer, sName, cCol) ;
}
@@ -689,7 +718,7 @@ Export3dm::ExportCrvLine( const string& sName, const IGdbIterator& iIter, const
//----------------------------------------------------------------------------
bool
Export3dm::ScanGroup( const IGdbIterator& iIter, const int& nLayer)
Export3dm::ScanGroup( const IGdbIterator& iIter, const int& nLayer, bool& bEmpty)
{
// creo un iteratore
PtrOwner<IGdbIterator> pIter( CreateGdbIterator( iIter.GetGDB())) ;
@@ -697,12 +726,19 @@ Export3dm::ScanGroup( const IGdbIterator& iIter, const int& nLayer)
return false ;
// scandisco il gruppo
bool bOk = true ;
int nCount = 0 ;
for ( bool bNext = pIter->GoToFirstInGroup( iIter) ;
bNext ;
bNext = pIter->GoToNext()) {
if ( ! ExportObject( *pIter, nLayer))
bool bAdded = false ;
if ( ! ExportObject( *pIter, nLayer, bAdded))
bOk = false ;
else if ( bAdded)
++ nCount ;
}
if ( nCount == 0)
bEmpty = true ;
return bOk ;
}
+2 -2
View File
@@ -41,11 +41,11 @@ class Export3dm : public IExport3dm
}
private :
bool ExportObject( const IGdbIterator& iIter, const int& nLayer) ;
bool ExportObject( const IGdbIterator& iIter, const int& nLayer, bool& bAdded) ;
bool AddObjectToModel( const IGdbIterator& iIter, ON_Object* onObject, const int& nLayer, const std::string& sName, const Color& cCol,
ON_3dmObjectAttributes* pOnAttr = nullptr) ;
bool AddInfoToObject( const IGdbIterator& iIter, ON_Object* onObject) ;
bool ScanGroup( const IGdbIterator& iIter, const int& nLayer) ;
bool ScanGroup( const IGdbIterator& iIter, const int& nLayer, bool& bEmpty) ; // nCount restituisce il numero di oggetti inseriti nel gruppo
bool TestFilter( int nLev, int nMode, int nStat, bool bGroup = false) ;
std::wstring ConvertString( const std::string& sName) { return std::wstring( sName.begin(), sName.end()) ;} ;
ON_3dPoint ConvertPoint( const Point3d& pt) { return ON_3dPoint( pt.x, pt.y, pt.z) ;} ;
+173 -45
View File
@@ -102,7 +102,7 @@ Import3dm::Import( const string& sFile, IGeomDB* pGDB, int nIdGroup,
int nFirstId = 0 ;
ON_UUID ON_nil_uuid = { 0,0,0,{ 0,0,0,0,0,0,0,0}} ;
int nLayDelCount = 0 ;
//int nLayDelCount = 0 ; //serve solo se si vogliono cancellare i layer parent. Se però questi layer contengono oggetti, che non sono in sottolayer del parent, non verranno visualizzati
for ( const ON_ModelComponent* mc = component_iterator_l.FirstComponent() ; mc != nullptr ; mc = component_iterator_l.NextComponent()) {
ON_UUID uuid = mc->Id() ;
const ON_Layer* onLayer = ON_Layer::Cast( mc) ;
@@ -125,18 +125,21 @@ Import3dm::Import( const string& sFile, IGeomDB* pGDB, int nIdGroup,
[uuidParent](pair< int, tuple<const ON_Layer*, ON_UUID, int, bool>> x){ return !ON_UuidCompare( get<1>(get<1>(x)), uuidParent) ;});
}
// se era già stato aggiunto il parent e non era già indicata la presenza di sottolayer
// devo eliminare il parent e mettere a true il flag dei sottolayer nella mappa dei layer
if ( it_parent != m_mLayer.end() ) {
if ( !get<3>(it_parent->second) ) {
get<3>(it_parent->second) = true ;
m_pGDB->Erase( it_parent->first) ;
auto LayerDeleted = m_mLayer.extract(it_parent->first);
LayerDeleted.key() = nLayDelCount ;
-- nLayDelCount ;
m_mLayer.insert(std::move(LayerDeleted));
}
}
// COMMENTO QUESTO TRATTO PERCHé, LASCIO I LAYER PARENT E LI CANCELLO ALLA FINE DELL'IMPORT SOLO SE RESTANO VUOTI
//
//// se era già stato aggiunto il parent e non era già indicata la presenza di sottolayer
//// devo eliminare il parent e mettere a true il flag dei sottolayer nella mappa dei layer
// if ( it_parent != m_mLayer.end() ) {
// if ( !get<3>(it_parent->second) ) {
// get<3>(it_parent->second) = true ;
// m_pGDB->Erase( it_parent->first) ;
// auto LayerDeleted = m_mLayer.extract(it_parent->first);
// LayerDeleted.key() = nLayDelCount ;
// -- nLayDelCount ;
// m_mLayer.insert(std::move(LayerDeleted));
// }
// }
int nIdLayer = m_pGDB->AddGroup( GDB_ID_NULL, nIdGroup, GLOB_FRM) ;
if ( nFirstId == 0)
@@ -151,9 +154,7 @@ Import3dm::Import( const string& sFile, IGeomDB* pGDB, int nIdGroup,
// se non riesco a convertire un oggetto, lo scarto e incremento il contatore del suo tipo nel dizionario error_count
int nId ;
int nCount = 0 ;
for( const ON_ModelComponent* mc = component_iterator.FirstComponent() ; mc != nullptr ; mc = component_iterator.NextComponent()) {
++ nCount ;
const ON_ModelGeometryComponent* mgc = ON_ModelGeometryComponent::Cast( mc) ;
const ON_Object* oGeometry = mgc->Geometry( nullptr) ;
// individuo a che layer appartiene l'oggetto
@@ -327,6 +328,7 @@ Import3dm::Import( const string& sFile, IGeomDB* pGDB, int nIdGroup,
}
}
// CANCELLO I LAYER RIMASTI VUOTI ??
// messaggio di errore da mettere nel log per dire quanti oggetti sono stati ignorati perché la conversione non è riuscita
map<string, int>::iterator it = m_mError_count.begin() ;
@@ -456,7 +458,7 @@ Import3dm::ConvertCurve( const ON_Curve* onCurve)
}
case ON::eCurveType::ctProxy :{
const ON_CurveProxy* onProxyCurve = ON_CurveProxy::Cast( onCurve) ;
ON_Curve* onCurve = onProxyCurve->DuplicateCurve() ;
const ON_Curve* onCurve = onProxyCurve->ProxyCurve() ;
return ConvertCurve( onCurve) ;
break ;
}
@@ -631,9 +633,13 @@ Import3dm::ConvertSurface( const ON_Surface* onSurf)
// uso la nurbs form
ON_NurbsSurface onNurbsSurface ;
int nOk = onBrepFace->GetNurbForm( onNurbsSurface) ;
if ( nOk != 0)
if ( nOk != 0){
pSurf.Set( ConvertSurface( & onNurbsSurface)) ;
}
else {
// 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
@@ -649,7 +655,7 @@ Import3dm::ConvertSurface( const ON_Surface* onSurf)
pSurf.Set( ConvertSurface( &onNurbsSurface)) ;
}
else
pSurf.Set( ConvertSurface( onSurfaceProxy->DuplicateSurface())) ;
pSurf.Set( ConvertSurface( onSurfaceProxy->ProxySurface())) ;
return Release( pSurf) ;
}
@@ -670,10 +676,11 @@ Import3dm::ConvertBrep( const ON_Brep* onBrep, const bool bForceTriMesh)
if ( ! stmSoup.Start())
return vSurf ;
bool bSurfTm = false ;
int nFailedBFace = 0, nFailedTm = 0, nFailedFr = 0, nFailedBz = 0 ;
int nFailedBFace = 0, nFailedTm = 0, nFailedFr = 0, nFailedBz = 0, nFailedBTrim = 0 ;
for ( int i = 0 ; i < onBrep->m_F.Count() ; ++i) {
ON_BrepFace* onFace = onBrep->Face( i) ;
bool bRev = onFace->m_bRev ;
const ON_Surface* onSurface = onFace->SurfaceOf() ;
PtrOwner<ISurf> pSurf ;
if ( const ON_PlaneSurface* onPlaneSurface = ON_PlaneSurface::Cast( onSurface)) {
@@ -706,61 +713,93 @@ Import3dm::ConvertBrep( const ON_Brep* onBrep, const bool bForceTriMesh)
if ( nType == SRF_TRIMESH) {
bSurfTm = true ;
PtrOwner<ISurfTriMesh> pSurfTm( GetSurfTriMesh( Release( pSurf))) ;
if ( ! IsNull( pSurfTm) && pSurfTm->IsValid())
if ( !IsNull(pSurfTm) && pSurfTm->IsValid() ) {
if ( bRev)
pSurfTm->Invert() ;
stmSoup.AddSurfTriMesh( *pSurfTm) ;
}
else
++ nFailedTm ;
}
else if ( nType == SRF_FLATRGN) {
bSurfTm = true ;
PtrOwner<ISurfFlatRegion> pSurfFr( GetSurfFlatRegion( Release( pSurf))) ;
if ( ! IsNull( pSurfFr) && pSurfFr->IsValid())
stmSoup.AddSurfTriMesh( *pSurfFr->GetAuxSurf()) ;
if ( ! IsNull( pSurfFr) && pSurfFr->IsValid()) {
if ( bRev)
pSurfFr->Invert() ;
stmSoup.AddSurfTriMesh(*pSurfFr->GetAuxSurf()) ;
}
else
++ nFailedFr ;
}
else if ( nType == SRF_BEZIER) {
PtrOwner<ISurfBezier> pSurfBezNew( GetSurfBezier( Release( pSurf))) ;
// se ho più di un loop vuol dire che ho dei trim sulla faccia e quindi li aggiungo alla superficie di bezier
// prima della triangolazione
if ( ! IsNull( pSurfBezNew) && pSurfBezNew->IsValid()) {
ON_BrepFace* onFace = onBrep->Face( i) ;
SurfFlatRegionByContours SfrCntr ;
for ( int k = 0 ; k < onFace->LoopCount() ; ++k )
SfrCntr.AddCurve( ConvertBrepLoop( onFace->Loop( k))) ;
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
if ( const ON_RevSurface* onRevSurf = ON_RevSurface::Cast( onSurface) ) {
for ( int k = 0 ; k < onFace->LoopCount() ; ++k ) {
ICurve* pCrv( ConvertBrepLoop( onFace->Loop( k))) ;
// qui devo spostare ogni punto della curva dallo spazio parametrico della superificie rev allo spazio della superficie nurbs
ConvertCurveParam( onRevSurf, &pCrv) ;
pCrv->Scale( GLOB_FRM, SBZ_TREG_COEFF, SBZ_TREG_COEFF, 1) ;
SfrCntr.AddCurve( pCrv) ;
}
}
else {
for ( int k = 0 ; k < onFace->LoopCount() ; ++k ) {
PtrOwner<ICurve> pCrv( ConvertBrepLoop( onFace->Loop( k))) ;
pCrv->Scale( GLOB_FRM, SBZ_TREG_COEFF, SBZ_TREG_COEFF, 1) ;
SfrCntr.AddCurve( Release( pCrv)) ;
}
}
ISurfFlatRegion* sfrTrim = 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) ;
double dScaleU = u1 - u0 ;
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
// applicando così la trasformazione anche alle curve di trim.
Vector3d vToOrig( -u0 * SBZ_TREG_COEFF, -v0 * SBZ_TREG_COEFF, 0) ;
if ( sfrTrim != nullptr)
sfrTrim->Translate( vToOrig) ;
else {
++ nFailedBTrim ;
return vSurf ;
}
// 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
// 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
PtrOwner<ISurfFlatRegion> pSurfParam( GetSurfFlatRegionRectangle( dScaleU - EPS_SMALL, dScaleV - EPS_SMALL)) ;
pSurfParam->Subtract( *sfrTrim) ;
if ( pSurfParam->IsValid())
// 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
PtrOwner<ISurfFlatRegion> pSurfParam(GetSurfFlatRegionRectangle(( dScaleU - EPS_SMALL ) * SBZ_TREG_COEFF, ( dScaleV - EPS_SMALL) * SBZ_TREG_COEFF)) ;
// se la sottrazione tra spazio parametrico e superficie di trim è diversa da zero, allora la superficie era trimmata
if ( sfrTrim != nullptr && pSurfParam->Subtract( *sfrTrim) && pSurfParam->IsValid()) {
MakeUniform( &sfrTrim, onNurbsSurface, dScaleU, dScaleV) ;
pSurfBezNew->SetTrimRegion( *sfrTrim) ;
}
else
sfrTrim->Scale( GLOB_FRM, nSpanU * SBZ_TREG_COEFF / dScaleU, nSpanV * SBZ_TREG_COEFF / dScaleV, 1) ;
pSurfBezNew->SetTrimRegion( *sfrTrim) ;
sfrTrim->Scale( GLOB_FRM, nSpanU / dScaleU, nSpanV / dScaleV, 1) ;
if ( sfrTrim != nullptr)
delete sfrTrim ;
if ( bRev)
pSurfBezNew->Invert() ;
if ( ! bForceTriMesh)
vSurf.emplace_back( Release( pSurfBezNew)) ;
else
@@ -789,6 +828,10 @@ Import3dm::ConvertBrep( const ON_Brep* onBrep, const bool bForceTriMesh)
string sOut = "Import3dm : Failed conversion of " + to_string( nFailedBz) + " NURBS belonging to a Brep" ;
LOG_ERROR( GetEE3Logger(), sOut.c_str()) ;
}
if ( nFailedBTrim != 0) {
string sOut = "Import3dm : Failed conversion of " + to_string( nFailedBTrim) + " trims of surfaces belonging to a Brep" ;
LOG_ERROR( GetEE3Logger(), sOut.c_str()) ;
}
if ( ! stmSoup.End())
return vSurf ;
@@ -803,7 +846,8 @@ bool
Import3dm::MakeUniform( ISurfFlatRegion** sfr, ON_NurbsSurface onNurbsSurface, double dScaleU, double dScaleV)
{
// riscalo le superfici prima di effettuare una serie di operazioni di collage
(*sfr)->Scale( GLOB_FRM, SBZ_TREG_COEFF, SBZ_TREG_COEFF, 1) ;
//(*sfr)->Scale( GLOB_FRM, SBZ_TREG_COEFF, SBZ_TREG_COEFF, 1) ;
// la superficie in input arriva già scalata
bool bRescaledU = false ;
bool bRescaledV = false ;
int nSpanU = 1, nSpanV = 1 ;
@@ -928,8 +972,24 @@ Import3dm::ConvertBrepLoop( const ON_BrepLoop* onBrepLoop)
for ( int i = 0 ; i < nTrim ; ++i) {
ON_BrepTrim* onBrepTrim = onBrepLoop->Trim( i) ;
ON_CurveProxy* onCurveProxy = ON_CurveProxy::Cast( onBrepTrim);
pCrvCompo->AddCurve( ConvertCurve( onCurveProxy)) ;
PtrOwner<ICurve> pCrv( ConvertCurve( onCurveProxy)) ;
if ( ! pCrvCompo->AddCurve( pCrv->Clone())) {
Point3d ptEnd ; pCrvCompo->GetEndPoint( ptEnd) ;
pCrv->ModifyStart( ptEnd) ;
if ( ! pCrvCompo->AddCurve( pCrv->Clone()))
return nullptr ;
}
}
//// APPROSSIMO I BREP LOOP PER ALLEGGERIRE LE OPERAZIONI DI TRIM DELLE BEZIER
//pCrvCompo->RemoveSmallParts( 0.1, 15) ;
//pCrvCompo->MergeCurves( 0.1, 15) ;
//PolyArc paApprox ;
//pCrvCompo->ApproxWithArcs( 0.1, 15, paApprox) ;
//pCrvCompo->FromPolyArc( paApprox) ;
return Release( pCrvCompo) ;
}
@@ -1046,7 +1106,6 @@ Import3dm::ConvertExtrusion( const ON_Extrusion* onExtrusion)
ISurfTriMesh*
Import3dm::ConvertMesh( const ON_Mesh* onMesh)
{
ON_Mesh* onMeshToConvert = onMesh->Duplicate() ;
PtrOwner<ISurfTriMesh> pSurfTm( CreateSurfTriMesh()) ;
if ( IsNull( pSurfTm))
@@ -1106,6 +1165,9 @@ Import3dm::ConvertMesh( const ON_Mesh* onMesh)
}
}
}
delete onMeshToConvert ;
pSurfTm->AdjustTopology() ;
return Release( pSurfTm) ;
}
@@ -1304,3 +1366,69 @@ Import3dm::ConvertAnnotation( const ON_Annotation* onAnnot, const ON_DimStyle* o
m_mError_count["annotation"] += 1 ;
return vpObj ;
}
//----------------------------------------------------------------------------
bool
Import3dm::ConvertCurveParam( const ON_RevSurface* onRevSurf, ICurve** pCrv)
{
PtrOwner<ICurve> pCrvNew ;
if ( (*pCrv)->GetType() == CRV_LINE) {
PtrOwner<ICurveLine> pCrvLine( CreateCurveLine()) ;
double dnurbsU ;
double dnurbsV ;
Point3d ptStart ; (*pCrv)->GetStartPoint( ptStart) ;
onRevSurf->GetNurbFormParameterFromSurfaceParameter( ptStart.x, ptStart.y, &dnurbsU, &dnurbsV) ;
ptStart.Set( dnurbsU, dnurbsV, 0) ;
Point3d ptEnd ; (*pCrv)->GetEndPoint( ptEnd) ;
onRevSurf->GetNurbFormParameterFromSurfaceParameter( ptEnd.x, ptEnd.y, &dnurbsU, &dnurbsV) ;
ptEnd.Set( dnurbsU, dnurbsV, 0) ;
pCrvLine->Set( ptStart, ptEnd) ;
pCrvNew.Set( Release( pCrvLine)) ;
}
else if ( (*pCrv)->GetType() == CRV_ARC) {
double dnurbsU ;
double dnurbsV ;
Point3d ptStart ; (*pCrv)->GetStartPoint( ptStart) ;
onRevSurf->GetNurbFormParameterFromSurfaceParameter( ptStart.x, ptStart.y, &dnurbsU, &dnurbsV) ;
ptStart.Set( dnurbsU, dnurbsV, 0) ;
Point3d ptEnd ; (*pCrv)->GetEndPoint( ptEnd) ;
onRevSurf->GetNurbFormParameterFromSurfaceParameter( ptEnd.x, ptEnd.y, &dnurbsU, &dnurbsV) ;
ptEnd.Set( dnurbsU, dnurbsV, 0) ;
Vector3d vtDir, vtN ;
(*pCrv)->GetStartDir( vtDir) ;
ICurveArc* pCrvArcOrig = GetCurveArc( (*pCrv)) ;
vtN = pCrvArcOrig->GetNormVersor( ) ;
PtrOwner<ICurveArc> pCrvArc( CreateCurveArc()) ;
pCrvArc->Set2PVN( ptStart, ptEnd, vtDir, vtN) ;
pCrvNew.Set( Release( pCrvArc)) ;
}
else if ( (*pCrv)->GetType() == CRV_BEZIER) {
double dnurbsU ;
double dnurbsV ;
PtrOwner<ICurveBezier> pCrvBez( GetCurveBezier( (*pCrv))) ;
int nDeg = pCrvBez->GetDegree() ;
int nCV = nDeg + 1 ;
for ( int i = 0 ; i < nCV ; ++i) {
Point3d ptNew = pCrvBez->GetControlPoint( i) ;
onRevSurf->GetNurbFormParameterFromSurfaceParameter( ptNew.x, ptNew.y, &dnurbsU, &dnurbsV) ;
ptNew.Set( dnurbsU, dnurbsV, 0) ;
// sto cambiando le coordinate dei CP nella curva, mentre i pesi non sono da modificare
pCrvBez->SetControlPoint( i, ptNew) ;
}
pCrvNew.Set( pCrvBez) ;
}
else if ( (*pCrv)->GetType() == CRV_COMPO) {
PtrOwner<ICurveComposite> pCrvCompo( GetCurveComposite( (*pCrv))) ;
PtrOwner<ICurveComposite> pCrvCompoNew( CreateCurveComposite()) ;
for ( const ICurve* pCrvSimpleOrig = pCrvCompo->GetFirstCurve() ; pCrvSimpleOrig != nullptr ; pCrvSimpleOrig = pCrvCompo->GetNextCurve()) {
ICurve* pCrvSimple( pCrvSimpleOrig->Clone()) ;
ConvertCurveParam( onRevSurf, &pCrvSimple) ;
pCrvCompoNew->AddCurve( pCrvSimple) ;
}
pCrvNew.Set( pCrvCompoNew) ;
}
(*pCrv) = Release( pCrvNew) ;
return true ;
}
+1
View File
@@ -53,6 +53,7 @@ class Import3dm : public IImport3dm
ISURFPOVECTOR 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) ;
bool ConvertCurveParam( const ON_RevSurface* onRevSurf, ICurve** pCrv) ;
private :
IGeomDB* m_pGDB ;