//---------------------------------------------------------------------------- // EgalTech 2020-2024 //---------------------------------------------------------------------------- // File : EgtConverter.cpp Data : 09.04.24 Versione : 2.6d2 // Contenuto : Importatore da formati avanzati tramite C3d. // // // // Modifiche : 12.09.20 DS Creazione modulo. // 20.11.20 SP Trasformazione diretta in nge. // 09.04.24 DS Aggiunto ottavo parametro Flag. // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "/EgtDev/Include/EGkDllMain.h" #include "/EgtDev/Include/EGkGeomDB.h" #include "/EgtDev/Include/EGkColor.h" #include "/EgtDev/Include/EGkGeoPoint3d.h" #include "/EgtDev/Include/EGkCurveLine.h" #include "/EgtDev/Include/EGkCurveArc.h" #include "/EgtDev/Include/EGkCurveComposite.h" #include "/EgtDev/Include/EGkCurveAux.h" #include "/EgtDev/Include/EGkCurveBezier.h" #include "/EgtDev/Include/EGkStmFromTriangleSoup.h" #include "/EgtDev/Include/EGnDllMain.h" #include "/EgtDev/Include/EGnGetModuleVer.h" #include "/EgtDev/Include/EGnStringUtils.h" #include "/EgtDev/Include/EGnFileUtils.h" #include "/EgtDev/Include/EGnGetKeyData.h" #include "/EgtDev/Include/EgtStringConverter.h" #include "/EgtDev/Include/EgtLogger.h" #include "/EgtDev/Include/EgtPointerOwner.h" #include "/EgtDev/Include/EgtKeyCodes.h" #include "/EgtDev/Include/SELkLockId.h" #include "/EgtDev/Include/SELkKeyProc.h" #include "/EgtDev/Include/EGkSurfAux.h" #include "/EgtDev/Include/EGkSurfBezier.h" #include "/EgtDev/Include/EGkSfrCreate.h" #include "/EgtDev/Include/EGkCurve.h" #include "/EgtDev/Extern/C3d/Include/tool_enabler.h" #include "/EgtDev/Extern/C3d/Include/model.h" #include "/EgtDev/Extern/C3d/Include/conv_model_exchange.h" #include "/EgtDev/Extern/C3d/Include/conv_exchange_settings.h" #include "/EgtDev/Extern/C3d/Include/mb_placement.h" #include "/EgtDev/Extern/C3d/Include/solid.h" #include "/EgtDev/Extern/C3d/Include/assembly.h" #include "/EgtDev/Extern/C3d/Include/mesh.h" #include "/EgtDev/Extern/C3d/Include/point_frame.h" #include "/EgtDev/Extern/C3d/Include/wire_frame.h" #include "/EgtDev/Extern/C3d/Include/space_instance.h" #include "/EgtDev/Extern/C3d/Include/plane_instance.h" #include "/EgtDev/Extern/C3d/Include/point3d.h" #include "/EgtDev/Extern/C3d/Include/cur_polyline3d.h" #include "/EgtDev/Extern/C3d/Include/cur_polyline.h" #include "/EgtDev/Extern/C3d/Include/cur_line_segment3d.h" #include "/EgtDev/Extern/C3d/Include/cur_line_segment.h" #include "/EgtDev/Extern/C3d/Include/cur_arc3d.h" #include "/EgtDev/Extern/C3d/Include/cur_arc.h" #include "/EgtDev/Extern/C3d/Include/cur_nurbs3d.h" #include "/EgtDev/Extern/C3d/Include/cur_nurbs.h" #include "/EgtDev/Extern/C3d/Include/curve3d.h" #include "/EgtDev/Extern/C3d/Include/attr_color.h" #include "/EgtDev/Extern/C3d/Include/mb_property.h" #include "/EgtDev/Extern/C3d/Include/attr_product.h" #include "/EgtDev/Extern/C3d/Include/mip_solid_area_volume.h" #include "/EgtDev/Extern/C3d/Include/surf_spline_surface.h" #include "/EgtDev/Extern/C3d/Include/surf_curve_bounded_surface.h" #include "/EgtDev/Extern/C3d/Include/cur_contour_on_surface.h" using namespace std ; using namespace c3d ; using namespace egtlogger ; //--------------------------- Costanti ---------------------------------------- #if defined( _WIN64) #if defined( _DEBUG) const string EXE_NAME = "EgtConverterD64.exe" ; #else const string EXE_NAME = "EgtConverterR64.exe" ; #endif #elif defined( _WIN32) #if defined( _DEBUG) const string EXE_NAME = "EgtConverterD32.exe" ; #else const string EXE_NAME = "EgtConverterR32.exe" ; #endif #endif const double TOL_STD = 2 * EPS_SMALL ; const double TOL_LIM_S = 0.101 ; const double TOL_LIM_B = 1.001 ; //------------------------- Prototipi locali --------------------------------- bool PrepareExit( Logger* pLog = nullptr, const char* szOut = nullptr) ; uint32 GetSolidColor( MbSolid* pSolid) ; bool CreateMeshData( MbStepData& stepData, MbFormNote& note) ; Point3d ConvertPoint( MbCartPoint3D& mbCPoint) ; Point3d ConvertPoint( MbPoint3D& mbCPoint) ; bool point_handler( const MbPoint3D* pPoint, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog) ; ICurveComposite* ConvertLoop( MbLoop* mbLoop) ; ICurve* ConvertCurve( const MbCurve& pCurve, Point3d& ptDegen, double dScale = 1.) ; ICurve* ConvertCurve3D( const MbCurve3D& pCurve, Point3d& ptDegen) ; ICurveComposite* ConvertContour( const MbContour& mbContour) ; bool curve_handler( const MbCurve3D* pCurve, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog) ; ISurfBezier* ConvertSurface( const MbSurface* mbSurface, DBLVECTOR& vU, DBLVECTOR& vV) ; bool surface_handler( const MbSurface* pSurface, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog, uint32 color, int nFlag = 0) ; bool nurbs2D_handler( MbNurbs* pNurbs, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog) ; ICurve* ConvertNurbs( const MbNurbs* pNurbs, double dScale, bool bEraseSrc) ; ICurve* ConvertNurbs3D( const MbNurbs3D* pNurbs, bool bEraseSrc) ; bool nurbs3D_handler( const MbNurbs3D* pNurbs, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog) ; bool mesh_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog, bool bColor = true) ; ISurfBezier* ConvertFace( const MbFace* mbF, Logger* pGenLog) ; bool solid_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog, const int nFlag = 0) ; bool pointframe_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog) ; bool wireframe_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog) ; bool spaceinstance_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog, int nFlag = 0) ; bool planeinstance_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog) ; bool assembly_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog, int nFlag = 0) ; bool instance_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog, int nFlag = 0) ; bool SimplifyCurve( ICurveComposite*& pCrv) ; bool LimitLoop( double u0, double u1, double v0, double v1, ICurveComposite* pCrv, ICRVCOMPOPOVECTOR& vCC) ; //------------------------- Variabili locali --------------------------------- static double s_dLinToler = 0.1 ; //debug int nObject = 0 ; //---------------------------------------------------------------------------- int wmain( int argc, wchar_t* argv[]) { // Primo parametro della linea di comando : nome eseguibile // Non interessa // Secondo parametro della linea di comando : file di input wstring swInpName = ( argc >= 2 ? argv[1] : L"") ; if ( swInpName.empty()) { cout << "Missing input file path" ; return 1 ; } string sInpName = wstringtoA( swInpName) ; // Terzo parametro della linea di comando : file di output wstring swExpName = ( argc >= 3 ? argv[2] : L"") ; if ( swExpName.empty()) { cout << "Missing output file path" ; return 2 ; } string sExpName = wstringtoA( swExpName) ; // Quarto parametro della linea di comando : errore cordale massimo wstring swToler = ( argc >= 4 ? argv[3] : L"0.1") ; string sToler = wstringtoA( swToler) ; FromString( sToler, s_dLinToler) ; // Quinto parametro della linea di comando : livello di debug wstring swDebugLev = ( argc >= 5 ? argv[4] : L"0") ; string sDebugLev = wstringtoA( swDebugLev) ; int nDebugLev = 0 ; FromString( sDebugLev, nDebugLev) ; // Sesto parametro della linea di comando : licenza wstring swKeyCode = ( argc >= 6 ? argv[5] : L"") ; if ( swKeyCode.empty()) { cout << "Missing key code" ; return 3 ; } string sKeyCode = wstringtoA( swKeyCode) ; // Settimo parametro della linea di comando : LockId wstring swLockId = ( argc >= 7 ? argv[6] : L"") ; string sLockId = wstringtoA( swLockId) ; // Ottavo parametro della linea di comando : Flag wstring swFlag = ( argc >= 8 ? argv[7] : L"") ; string sFlag = wstringtoA( swFlag) ; int nFlag = 0 ; FromString( sFlag, nFlag) ; // Creo il logger PtrOwner pGenLog( new( nothrow) Logger( ( nDebugLev > 0 ? LL_DEBUG : LL_INFO), "EgtConverter")) ; if ( IsNull( pGenLog)) { cout << "Error creating logger" ; return 4 ; } // assegno il file string sLogFile = ChangeFileExtension( sExpName, "txt") ; pGenLog->AddOutputStream( new( nothrow) ofstream( sLogFile), true) ; // Imposto livello di debug alle librerie di base SetEGkDebugLev( nDebugLev) ; // Imposto logger SetEGkLogger( pGenLog) ; SetEGnLogger( pGenLog) ; // Imposto il tipo di chiave SetLockType( KEY_LOCK_TYPE_HW) ; SetEGkKeyType( KEY_LOCK_TYPE_HW) ; SetEGnKeyType( KEY_LOCK_TYPE_HW) ; if ( ! sLockId.empty()) { int nKeyType = KEY_LOCK_TYPE_HW ; bool bNetHwKey = false ; int nUserId = 0 ; if ( GetLockIdStringInfo( sLockId, nKeyType, bNetHwKey, nUserId)) { string sAddrPort = "" ; if ( nKeyType == KEY_LOCK_TYPE_HW) GetLockIdStringNetData( sLockId, sAddrPort) ; SetNetHwKey( bNetHwKey, nUserId, sAddrPort) ; SetEGkNetHwKey( bNetHwKey) ; SetEGnNetHwKey( bNetHwKey) ; } } // Verifico la chiave int nKLev, nKeyExpDays ; int nLevRet = GetKeyLevel( sKeyCode, KEY_BASELIB_PROD, KEY_BASELIB_VER, KEY_BASELIB_LEV, nKLev, nKeyExpDays) ; SetEGnKeyLevel( nLevRet, nKLev, nKeyExpDays) ; unsigned int nOpt1, nOpt2 ; int nKeyOptExpDays ; int nOptRet = GetKeyOptions( sKeyCode, KEY_BASELIB_PROD, KEY_BASELIB_VER, KEY_BASELIB_LEV, nOpt1, nOpt2, nKeyOptExpDays) ; SetEGnKeyOptions( nOptRet, nOpt1, nOpt2, nKeyOptExpDays) ; // Imposto la chiave di protezione alle librerie di base SetEGkKey( sKeyCode) ; SetEGnKey( sKeyCode) ; // Dichiaro inizio programma LOG_DATETIME( pGenLog, " Init") // messaggio dall'applicazione string sExeVer ; GetModuleVersion( NULL, sExeVer) ; string sAppMsg = EXE_NAME + " ver." + sExeVer ; LOG_INFO( pGenLog, sAppMsg.c_str()) // versione dei componenti string sVer ; sVer += GetEGkVersion() ; LOG_INFO( pGenLog, sVer.c_str()) // tolleranza lineare LOG_INFO( pGenLog, ( "Toler=" + sToler).c_str()) // livello di log LOG_INFO( pGenLog, ( "DbgLev=" + sDebugLev).c_str()) // flag LOG_INFO( pGenLog, ( "Flag=" + sFlag).c_str()) // Activation of the geometric kernel C3D. // chiavi licenza dalla versione 117955 di c3d string str0( "Egalware..[C3D][cnv][mdl]") ; string str1( "1RM6ZehiyVYJeIbiHEWppkPKTE0Qfw+EGGDNQjAtvEFueEjOCSSvdx9dmZzoHTpu9ugDha+cR3qIAUYXcjvMfB6pHhvXX8f2DwIcbxzf9pMk/7umVH/1fUk485Z/7y+wj7TdscCmJ4sgooAc1CLn++0BXvukeXPhGXNFuS4YUSE=") ; // chiavi licenza per vecchie versioni // string str0( "Egaltech..[cnv][mdl]") ; // string str1( "JW02HxzIKyBIMzDWswgytSRB98wcImMzPTohT44M5EbQK8BpmEHA54hEkogovfCbtMufHIT2HbjX6NSp1+gpEw==") ; EnableMathModules( str0.c_str(), (int)str0.length(), str1.c_str(), (int)str1.length()) ; // Verify module activation bool bModOk = IsMathModelerEnable() ; bool bConvOk = IsMathConverterEnable() ; if ( ! bModOk || ! bConvOk) { PrepareExit( pGenLog, "Error activating Modeler or Converter") ; return 10 ; } // File import LOG_INFO( pGenLog, ( "File to import : " + sInpName).c_str()) MbModel geomModel ; int nReadRes = ImportFromFile( geomModel, C3DToPathstring(ToC3Dstring( swInpName))) ; if ( nReadRes != cnv_Success) { if ( nReadRes == cnv_FileOpenError) PrepareExit( pGenLog, "Error opening input file") ; else if ( nReadRes == cnv_UnknownExtension) PrepareExit( pGenLog, "Unkwown input file type") ; else if ( nReadRes == cnv_NotEnoughMemory) PrepareExit( pGenLog, "Not enough memory") ; else PrepareExit( pGenLog, "Internal error during read") ; return 11 ; } // Creo GeomDB PtrOwner pGeomDB( CreateGeomDB()) ; if ( IsNull( pGeomDB)){ PrepareExit( pGenLog, "Error creating GeomDB") ; return 12 ; } // Inserisco gli oggetti nel GeomDB (sotto pezzo/layer) pGeomDB->SetDefaultMaterial( Color( 176, 176, 176)) ; int nPartId = pGeomDB->AddGroup( GDB_ID_NULL, GDB_ID_ROOT, Frame3d()) ; int nLayId = pGeomDB->AddGroup( GDB_ID_NULL, nPartId, Frame3d()) ; nObject = 0 ; // debug // scorro il modello importato for ( MbModel::ItemIterator it = geomModel.Begin() ; it != geomModel.End() ; it++ ) { bool bSolOk = true ; if ( ( *it)->IsA() == st_Assembly) bSolOk = assembly_handler( *it, nLayId, pGeomDB, pGenLog, nFlag) ; else if ( ( *it )->IsA() == st_Solid ) bSolOk = solid_handler( *it, nLayId, pGeomDB, pGenLog, nFlag) ; else if ( ( *it)->IsA() == st_Instance) bSolOk = instance_handler(*it, nLayId, pGeomDB, pGenLog, nFlag) ; else if ( ( *it)->IsA() == st_PointFrame) bSolOk = pointframe_handler(*it, nLayId, pGeomDB, pGenLog) ; else if ( ( *it)->IsA() == st_WireFrame) bSolOk = wireframe_handler(*it, nLayId, pGeomDB, pGenLog) ; else if ( ( *it)->IsA() == st_SpaceInstance) bSolOk = spaceinstance_handler(*it, nLayId, pGeomDB, pGenLog, nFlag) ; else if ( ( *it)->IsA() == st_Mesh) bSolOk = mesh_handler(*it, nLayId, pGeomDB, pGenLog) ; else if ( ( *it)->IsA() == st_PlaneInstance) bSolOk = planeinstance_handler(*it, nLayId, pGeomDB, pGenLog) ; if ( ! bSolOk) { PrepareExit( pGenLog, "Error on model") ; return 14 ; } ++nObject ; // debug } // Salvo il progetto bool bOk = pGeomDB->Save( GDB_ID_ROOT, sExpName, GDB_SV_BIN) ; if ( ! bOk) { PrepareExit( pGenLog, "Error saving GeomDB") ; return 13 ; } else LOG_INFO( pGenLog, "Conversion finished with success") PrepareExit() ; LOG_DATETIME( pGenLog, " Exit") return 0 ; } //---------------------------------------------------------------------------- Point3d ConvertPoint( MbCartPoint3D& mbCPoint) { Point3d pt( mbCPoint.x, mbCPoint.y ,mbCPoint.z) ; return pt ; } //---------------------------------------------------------------------------- Point3d ConvertPoint( MbPoint3D& mbPoint) { MbCartPoint3D mbCPoint3d = mbPoint.GetCartPoint() ; return ConvertPoint( mbCPoint3d) ; } //---------------------------------------------------------------------------- ICurveComposite* ConvertLoop( MbLoop* mbLoop) { PtrOwner pCC( CreateCurveComposite()) ; if ( IsNull( pCC)) return nullptr ; EdgesVector mbVEdges ; EdgesSet mbSEdges ; mbLoop->GetEdges( mbVEdges, mbSEdges) ; for ( int i = 0 ; i < int( mbVEdges.size()) ; ++ i) { Point3d ptDegen = P_INVALID ; MbOrientedEdge* mbOEdge = mbLoop->GetOrientedEdge( i) ; bool bDir = mbOEdge->GetOrientation() ; PtrOwner pCrv( ConvertCurve3D( mbOEdge->GetCurve(), ptDegen)) ; if ( IsNull( pCrv) || ! pCrv->IsValid()) return nullptr ; if ( ! bDir) pCrv->Invert() ; pCC->AddCurve( Release( pCrv)) ; } return Release( pCC) ; } //---------------------------------------------------------------------------- ICurveComposite* ConvertContour( const MbContour& mbContour) { Point3d ptDegen = P_INVALID ; PtrOwner pCC( GetCurveComposite( ConvertCurve( mbContour.GetBasisCurve(), ptDegen, SBZ_TREG_COEFF))) ; return Release( pCC) ; } //---------------------------------------------------------------------------- bool PrepareExit( Logger* pLog, const char* szOut) { // Free of the geometric kernel C3D FreeMathModulesChecker() ; // Close NetKey if necessary CloseNetHwKey() ; // Log if requested if ( pLog != nullptr && szOut != nullptr) LOG_ERROR( pLog, szOut) ; return true ; } //---------------------------------------------------------------------------- bool mesh_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog, bool bColor) { MbMesh * pMesh = static_cast( pIt) ; if ( pMesh == nullptr) { LOG_ERROR( pGenLog, "Error : Mesh pointer null") ; return false ; } PtrOwner pStm( CreateSurfTriMesh()) ; if ( IsNull( pStm) || ! pStm->Init( 3, 1)) return false ; // scorro le grids int nVertexNbr = 0 ; for ( size_t i = 0 ; i < pMesh->GridsCount() ; i++) { const MbGrid* pGrid = pMesh->GetGrid( i) ; // scorro i punti for ( size_t j = 0 ; j < pGrid->PointsCount() ; j ++) { MbCartPoint3D pt ; pGrid->GetPoint ( j, pt) ; pStm->AddVertex( Point3d( pt.x, pt.y, pt.z)) ; } // scorro i triangoli for ( size_t j = 0 ; j < pGrid->TrianglesCount() ; j++) { uint idx0, idx1, idx2 ; pGrid->GetTriangleIndex( j, idx0, idx1, idx2) ; int nIdV[3] = { int( nVertexNbr + idx0), int( nVertexNbr + idx1), int( nVertexNbr + idx2)} ; pStm->AddTriangle( nIdV) ; } // scorro i quadrilateri for ( size_t j = 0 ; j < pGrid->QuadranglesCount() ; j++) { uint idx0, idx1, idx2, idx3 ; pGrid->GetQuadrangleIndex( j, idx0, idx1, idx2, idx3) ; int nIdV[3] = { int( nVertexNbr + idx0), int( nVertexNbr + idx2), int( nVertexNbr + idx3)} ; pStm->AddTriangle( nIdV) ; int nIdV2[3] = { int( nVertexNbr + idx0), int( nVertexNbr + idx1), int( nVertexNbr + idx2)} ; pStm->AddTriangle( nIdV2) ; } nVertexNbr += ( int)pGrid->PointsCount() ; } pStm->DoCompacting() ; int nId = pGeomDB->AddGeoObj( GDB_ID_NULL, nLayId, Release( pStm)) ; if ( nId == GDB_ID_NULL) { LOG_ERROR( pGenLog, "Error : adding object Stm to GeomDB") ; return false ; } if ( bColor) { uint32 MeshColor = pMesh->GetColor() ; if ( MeshColor == 16744192) // colore "nullo" return true ; float r, g, b ; uint322RGB( MeshColor, r, g, b) ; pGeomDB->SetMaterial( nId, Color( r, g, b)) ; } return true ; } //---------------------------------------------------------------------------- uint32 GetSolidColor( MbSolid* pSolid) { unordered_map < uint32, double> color_map ; uint32 color = 16744192 ; //colore "nullo" RGB (0,127,255) double max_area = 0.0 ; FacesVector faces ; pSolid -> GetFaces( faces) ; // cerco il colore che occupa l'area maggiore su tutte le facce del solido for ( size_t i = 0 ; i < faces.size() ; i++){ uint32 colFace = faces[i]->GetColor() ; if ( color_map.find( colFace) == color_map.end()) color_map.insert( make_pair( colFace, CalculateArea( *faces[i], 1))) ; else color_map[colFace]=color_map[colFace] + CalculateArea( *faces[i], 1) ; if ( color_map[colFace] > max_area) { color = colFace ; max_area = color_map[colFace] ; } } if ( color == 16744192) return pSolid->GetColor() ; return color ; } //---------------------------------------------------------------------------- struct Inters { int nIn ; int nOut ; Point3d ptStart ; Point3d ptEnd ; PtrOwner pCrv ; // riordino le intersezioni per lato in senso antiorario dal top // se ho pi� intersezioni che entrano in un lato le riordino considerando che percorro i lati in senso antiorario a partire da ptTR bool operator < ( Inters& b) { // trovo in che ordine stanno i due start, tenendo conto anche della possibilit� che siano vertici INTVECTOR vEdges = { 7, 0, 4, 1, 5, 2, 6, 3} ; const auto iter1 = find( vEdges.begin(), vEdges.end(), nIn) ; int nPos1 = std::distance( vEdges.begin(), iter1) ; const auto iter2 = find( vEdges.begin(), vEdges.end(), b.nIn) ; int nPos2 = std::distance( vEdges.begin(), iter2) ; // se sono loop interni li ordino in modo decrescente rispetto all'area bool bEqIn = ( nIn == b.nIn) ; // se nIn � un vertice sistemo il valore int nEdgeIn = nIn ; if ( nIn > 3) nEdgeIn = nIn - 4 ; return ( nPos1 < nPos2 || ( bEqIn && nEdgeIn == 0 && ptStart.x > b.ptStart.x) || ( bEqIn && nEdgeIn == 1 && ptStart.y > b.ptStart.y) || ( bEqIn && nEdgeIn == 2 && ptStart.x < b.ptStart.x) || ( bEqIn && nEdgeIn == 3 && ptStart.y < b.ptStart.y)) ; } } ; //---------------------------------------------------------------------------- bool AreSameEdge( int nEdge1, int nEdge2) { if ( nEdge1 == 0) return ( nEdge2 == 4 || nEdge2 == 0 || nEdge2 == 7) ; else if ( nEdge1 == 1) return ( nEdge2 == 4 || nEdge2 == 1 || nEdge2 == 5) ; else if ( nEdge1 == 2) return ( nEdge2 == 6 || nEdge2 == 2 || nEdge2 == 5) ; else if ( nEdge1 == 3) return ( nEdge2 == 6 || nEdge2 == 3 || nEdge2 == 7) ; else if ( nEdge1 == 4) return ( nEdge2 == 0 || nEdge2 == 1 || nEdge2 == 7 || nEdge2 == 5) ; else if ( nEdge1 == 5) return ( nEdge2 == 2 || nEdge2 == 1 || nEdge2 == 4 || nEdge2 == 6) ; else if ( nEdge1 == 6) return ( nEdge2 == 2 || nEdge2 == 3 || nEdge2 == 5 || nEdge2 == 7) ; else if ( nEdge1 == 7) return ( nEdge2 == 0 || nEdge2 == 3 || nEdge2 == 4 || nEdge2 == 6) ; else return false ; } //---------------------------------------------------------------------------- bool SimplifyCurve( ICurveComposite*& pCrv) { if( pCrv == nullptr) return false ; PolyArc paApprox ; if ( ! pCrv->ApproxWithArcs( 0.1, 15, paApprox)) { PolyLine plApprox ; if ( ! pCrv->ApproxWithLines( 0.1, 15, 0, plApprox)) return false ; pCrv->Clear() ; if ( ! pCrv->FromPolyLine( plApprox)) return false ; } else { pCrv->Clear() ; if ( ! pCrv->FromPolyArc( paApprox)) return false ; } if ( ! pCrv->RemoveSmallParts(0.1, 15) || ! pCrv->MergeCurves( 0.1, 15) || ! pCrv->RemoveSmallDefects( 0.1, 15, true)) return false ; return true ; } //---------------------------------------------------------------------------- bool LimitLoop( double u0, double u1, double v0, double v1, ICurveComposite* pCrv, ICRVCOMPOPOVECTOR& vCC) { PtrOwner pCCEdge( CreateCurveComposite()) ; pCCEdge->AddPoint( Point3d( u1,v1)) ; pCCEdge->AddLine( Point3d( u0,v1)) ; pCCEdge->AddLine( Point3d( u0,v0)) ; pCCEdge->AddLine( Point3d( u1,v0)) ; pCCEdge->Close() ; IntersCurveCurve icc( *pCCEdge, *pCrv) ; CRVCVECTOR vCrvClass ; if ( ! icc.GetCurveClassification( 1, 0.01, vCrvClass)) return false ; int nLast = 0 ; for ( int i = 0 ; i < int( vCrvClass.size()) ; ++i) { if ( vCrvClass[i].nClass != 2) { // se continua la curva precedente allora la giunta if ( vCC.size() != 0 && vCrvClass[i].dParS == vCrvClass[nLast].dParE) vCC.back()->AddCurve( pCrv->CopyParamRange( vCrvClass[i].dParS, vCrvClass[i].dParE)) ; // senn� creo una nuova curva else vCC.emplace_back( GetCurveComposite(pCrv->CopyParamRange( vCrvClass[i].dParS, vCrvClass[i].dParE))) ; nLast = i ; } } return true ; } //---------------------------------------------------------------------------- ISurfBezier* ConvertFace( const MbFace* mbF, Logger* pGenLog) { bool bSameSense = mbF->IsSameSense() ; std::vector > vMbContours ; SurfaceSPtr mbSurf ( mbF->GetSurfaceCurvesData( vMbContours)) ; //// controllo il tipo // qui devo poi fare tutti i casi con superfici che non richiedono di essere trasformate in bezier MbeSpaceType mbSubType = mbF->GetSurface().IsA() ; DBLVECTOR vU, vV ; // N.B.: NON USARE direttamente mbSurf al posto di mbF->GetSurface(). Evidenza empirica mostra che restituiscono oggetti differenti PtrOwner pSurfBez(GetSurfBezier(ConvertSurface( &(mbF->GetSurface()), vU, vV))) ; if ( IsNull( pSurfBez) || ! pSurfBez->IsValid()){ LOG_ERROR( pGenLog, "Error converting the face ( before trim) of a solid into a Bezier surface") ; goto exit ; // porta alla fine per fare il delete dei puntatori a oggetti e un return nullptr } if ( mbSubType == st_CurveBoundedSurface) { bool bPlanarSurf = pSurfBez->IsPlanar() ; SurfFlatRegionByContours SfrCntr ; // recupero i bordi dello spazio parametrico // N.B.: NON USARE direttamente mbSurf al posto di mbF->GetSurface(). Evidenza empirica mostra che restituiscono oggetti differenti double u0 = mbF->GetSurface().GetUMin() * SBZ_TREG_COEFF ; double v0 = mbF->GetSurface().GetVMin() * SBZ_TREG_COEFF ; double u1 = mbF->GetSurface().GetUMax() * SBZ_TREG_COEFF ; double v1 = mbF->GetSurface().GetVMax() * SBZ_TREG_COEFF ; Point3d ptTR( u1, v1) ; Point3d ptTl( u0, v1) ; Point3d ptBL( u0, v0) ; Point3d ptBr( u1, v0) ; int nLoops = vMbContours.size() ; vector vInters ; // usando la MbCurveBoundedSurface for ( int l = 0 ; l < nLoops ; ++l) { ICurveComposite* pCrv( ConvertContour( *vMbContours[l])) ; if ( pCrv == nullptr || ! pCrv->IsValid()) { delete pCrv ; LOG_ERROR( pGenLog, "Error converting the contour of a face of a Solid") ; goto exit ; } if ( ! pCrv->IsClosed()){ // controllo se Start e End distano meno di 1 allora chiudo la curva a mano. Point3d ptStart ; pCrv->GetStartPoint( ptStart) ; Point3d ptEnd ; pCrv->GetEndPoint( ptEnd) ; if ( AreSamePointEpsilon(ptStart, ptEnd, 1)) { pCrv->Close() ; if ( ! bPlanarSurf) { if ( ! SimplifyCurve( pCrv)){ delete pCrv ; LOG_ERROR( pGenLog, "Error simplifying open (but actually closed) curve") ; goto exit ; } } SfrCntr.AddCurve( pCrv) ; } else { if ( ! bPlanarSurf) { if ( ! SimplifyCurve( pCrv)) { delete pCrv ; LOG_ERROR( pGenLog, "Error simplifying open curve") ; goto exit ; } } vInters.emplace_back() ; Point3d ptStart ; pCrv->GetStartPoint( ptStart) ; Point3d ptEnd ; pCrv->GetEndPoint( ptEnd) ; vInters.back().ptStart = ptStart ; vInters.back().ptEnd = ptEnd ; int nIn = -1, nOut = -1 ; if ( ! OnWhichEdge( u0, u1, v0, v1, ptStart, nIn) || ! OnWhichEdge( u0, u1, v0, v1, ptEnd, nOut)) { // visto che non sono riuscito ad identificare su quali edge inizia o finisce la curva allora la limito allo spazio parametrico // prima di riprovare ICRVCOMPOPOVECTOR vCC ; if ( ! LimitLoop( u0, u1, v0, v1, pCrv, vCC)) { delete pCrv ; LOG_ERROR( pGenLog, "Error limiting an open trim") ; goto exit ; } // scorro su tutte le curve che si sono create for ( int i = 0 ; i < int( vCC.size()) ; ++i) { Point3d ptStart ; vCC[i]->GetStartPoint(ptStart) ; Point3d ptEnd ; vCC[i]->GetEndPoint( ptEnd) ; if ( ! OnWhichEdge( u0, u1, v0, v1, ptStart, nIn) || ! OnWhichEdge( u0, u1, v0, v1, ptEnd, nOut)) { delete pCrv ; LOG_ERROR( pGenLog, "Error identifying edges touched by an open trim") ; goto exit ; } vInters.back().nIn = nIn ; vInters.back().nOut = nOut ; vInters.back().pCrv.Set( Release(vCC[i])) ; } } else { vInters.back().nIn = nIn ; vInters.back().nOut = nOut ; vInters.back().pCrv.Set( pCrv) ; } } } else { if ( ! bPlanarSurf) { PtrOwner pCrvCopy( pCrv->Clone()) ; if ( ! SimplifyCurve( pCrv)) { delete pCrv ; LOG_ERROR( pGenLog, "Error simplifying closed curve") ; goto exit ; } double dArea = -1 ; pCrv->GetAreaXY( dArea) ; if ( dArea < EPS_ZERO ) { pCrv->Clear() ; pCrv = Release( pCrvCopy) ; } } // queste curve dovrebbero essere gi� nel parametrico SfrCntr.AddCurve( pCrv) ; } } // aggiungo anche le curve aperte tutte insieme if ( vInters.size() != 0) { ICurveComposite* pCCOpen ( Release( vInters[0].pCrv)) ; sort( vInters.begin(), vInters.end()) ; bool bNotCameBack = true ; int nEdge = vInters[0].nOut ; // se ero in un vertice passo all'edge successivo if ( nEdge > 3 && nEdge != 7) nEdge = nEdge - 4 ; else if ( nEdge == 7) nEdge = 0 ; int nInters = 0 ; while ( bNotCameBack) { bool bAtNextStart = false ; PolyLine plEdge ; int nCount = 0 ; plEdge.AddUPoint( nCount, vInters[nInters].ptEnd) ; ++ nCount ; ++ nInters ; if ( nInters == vInters.size()) nInters = 0 ; // scorro tutti i lati finch� non torno allo start del loop while( ! bAtNextStart) { Point3d ptToAdd ; if ( nEdge == 0) ptToAdd = ptTl ; else if ( nEdge == 1) ptToAdd = ptBL ; else if ( nEdge == 2) ptToAdd = ptBr ; else if ( nEdge == 3) ptToAdd = ptTR ; if ( plEdge.AddUPoint( nCount, ptToAdd)) ++ nCount ; if ( nEdge > 3 && nEdge != 7) nEdge = nEdge - 4 ; else if ( nEdge < 3) ++ nEdge ; else nEdge = 0 ; if ( AreSameEdge(nEdge,vInters[nInters].nIn)) bAtNextStart = true ; } ICurveComposite* pCC( CreateCurveComposite()) ; pCC->FromPolyLine( plEdge) ; // aggiungo il tratto di edge pCCOpen->AddCurve( pCC) ; // agggiungo il prossio taglio if ( nInters != 0) pCCOpen->AddCurve( Release( vInters[nInters].pCrv)) ; if ( AreSameEdge(nEdge, vInters[0].nIn)) { pCCOpen->Close() ; bNotCameBack = false ; } } if ( ! pCCOpen->IsClosed()) { delete pCCOpen ; LOG_ERROR( pGenLog, "Error creating the contour from open trims") ; goto exit ; } if ( ! bPlanarSurf) { if ( ! SimplifyCurve( pCCOpen)) { delete pCCOpen ; LOG_ERROR( pGenLog, "Error simplifying the contour recreated from the open trims") ; goto exit ; } } SfrCntr.AddCurve( pCCOpen) ; } double dScaleU = u1 - u0 ; double dScaleV = v1 - v0 ; ISurfFlatRegion* pTrimReg( SfrCntr.GetSurf()) ; if ( pTrimReg == nullptr || ! pTrimReg->IsValid()) { delete pTrimReg ; LOG_ERROR( pGenLog, "Error creating the trim surface") ; goto exit ; } Vector3d vToOrig( -u0, -v0, 0) ; pTrimReg->Translate( vToOrig) ; bool bRescaled = false ; int nDegU, nDegV , nSpanU, nSpanV ; bool bRat, bTrimmed ; pSurfBez->GetInfo( nDegU, nDegV, nSpanU, nSpanV, bRat, bTrimmed) ; ISurfFlatRegion* pSurfCopy0 ( pTrimReg->Clone()) ; if ( ! MakeUniform( pTrimReg, bRescaled, vU, vV, nDegU, nDegV, dScaleU, dScaleV, false)) { delete pTrimReg ; pTrimReg = pSurfCopy0->Clone() ; if ( ! MakeUniform( pTrimReg, bRescaled, vU, vV, nDegU, nDegV, dScaleU, dScaleV, true)) { delete pTrimReg ; delete pSurfCopy0 ; LOG_ERROR( pGenLog, "Error making uniform the trim surface") ; goto exit ; } } if ( ! pTrimReg->IsValid()){ delete pTrimReg ; delete pSurfCopy0 ; LOG_ERROR( pGenLog, "Error making uniform the trim surface") ; goto exit ; } if ( ! pSurfBez->SetTrimRegion(*pTrimReg)) { if ( ! MakeUniform( pSurfCopy0, bRescaled, vU, vV, nDegU, nDegV, dScaleU, dScaleV, true)) { delete pTrimReg ; delete pSurfCopy0 ; LOG_ERROR( pGenLog, "Error during the second try of making uniform the trim surface") ; goto exit ; } if ( ! pSurfBez->SetTrimRegion(*pSurfCopy0)) { // se � fallita nuovamente l'intersezione allora provo a semplificare i loop della trim region SurfFlatRegionByContours sfrTrim ; for ( int c = 0 ; c < pTrimReg->GetChunkCount() ; ++c) { for ( int l = 0 ; l < pTrimReg->GetLoopCount( c) ; ++l) { ICurveComposite* pCC( GetCurveComposite(pTrimReg->GetLoop( c, l))) ; if ( ! SimplifyCurve( pCC)) { LOG_ERROR( pGenLog, "Error simplifying a curve of a trim region ( surface was not trimmed)") ; delete pCC ; delete pTrimReg ; delete pSurfCopy0 ; goto exit ; } if ( ! sfrTrim.AddCurve( pCC)) { LOG_ERROR( pGenLog, "Error adding a curve to the trim region ( surface was not trimmed)") ; delete pCC ; delete pTrimReg ; delete pSurfCopy0 ; goto exit ; } } } PtrOwner pSfrTrimNew ( sfrTrim.GetSurf()) ; if ( IsNull( pSfrTrimNew) || ! pSfrTrimNew->IsValid()) { delete pTrimReg ; delete pSurfCopy0 ; LOG_DBG_ERR( pGenLog, "Error recreating trim region, in attempt to retry an intersection with the parameter space") ; goto exit ; } if ( ! pSurfBez->SetTrimRegion(*pSfrTrimNew)) { delete pTrimReg ; delete pSurfCopy0 ; LOG_DBG_ERR( pGenLog, "Error intersecating parameter space and trim surface") ; goto exit ; } } } delete pTrimReg ; delete pSurfCopy0 ; pSurfBez->RemoveCollapsedSpans() ; } exit : if ( IsNull( pSurfBez) || ! pSurfBez->IsValid()) return nullptr ; if ( ! bSameSense) pSurfBez->Invert() ; return Release( pSurfBez) ; } //debug int nAssObj = 0 ; //---------------------------------------------------------------------------- bool solid_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog, int nFlag) { MbSolid* pSolid = static_cast( pIt) ; if ( pSolid == nullptr) { LOG_ERROR( pGenLog, "Error : Solid pointer null") ; return false ; } INTVECTOR vIds ; // conversione diretta in trimesh if ( nFlag == 0) { // Creazione mesh MbStepData stepdata ; MbFormNote note ; CreateMeshData( stepdata, note) ; // conversione in mesh MbMesh mesh ; pSolid->CalculateMesh( stepdata, note, mesh) ; if ( ! mesh_handler( & mesh, nLayId, pGeomDB, pGenLog, false)) return false ; int nId = pGeomDB->GetLastInGroup( nLayId) ; // recupero id dell'oggetto appena aggiunto vIds.push_back( nId) ; } // conversione in superfici di Bezier ( una per ogni faccia) else if ( nFlag == 1) { // reucpero le facce e le converto in NURBS prima di importarle const MbFaceShell* FaceShell = pSolid->GetShell() ; int nFaces = int( FaceShell->GetFacesCount()) ; for ( int f = 0 ; f < nFaces ; ++ f) { MbFace* mbF = FaceShell->GetFace(f) ; PtrOwner pSurf( ConvertFace( mbF, pGenLog)) ; if ( IsNull(pSurf) || ! pSurf->IsValid()) { LOG_ERROR( pGenLog, "Error converting a face of a solid") ; continue ; } // qui potrei inserire un controllo per evitare di aggiungere superfici di Bezier che sono collassate in punti vIds.push_back( pGeomDB->AddGeoObj( GDB_ID_NULL, nLayId, Release( pSurf))) ; } } // Gestione colori uint32 col=GetSolidColor( pSolid) ; for ( int nId : vIds) { // Aggiungo attributes AttrVector attributes ; pSolid->GetAttributes( attributes, at_Undefined, at_Undefined) ; for ( unsigned int i = 0 ; i < attributes.size() ; i++) { MbAttribute* pAttr = attributes[i] ; if ( pAttr == nullptr) continue ; if ( pAttr->AttributeType() == at_ProductInfo) { MbProductInfo* pInfo = static_cast( pAttr) ; if ( ! pInfo->GetName().empty()) { pGeomDB->SetName( nId, ToSTDstring( pInfo->GetName())) ; if ( ! pInfo->GetId().empty()) pGeomDB->SetInfo( nId, "Id", ToSTDstring( pInfo->GetId())) ; } else if ( ! pInfo->GetId().empty()) pGeomDB->SetName( nId, ToSTDstring( pInfo->GetName())) ; if ( ! pInfo->GetDescription().empty()) pGeomDB->SetInfo( nId, "Description", ToSTDstring( pInfo->GetDescription())) ; } } // verifico non sia il colore "nullo" if ( col != 16744192) { float r, g, b = 0 ; uint322RGB( col, r, g, b) ; pGeomDB->SetMaterial( nId, Color( r, g, b)) ; } } return true ; } //---------------------------------------------------------------------------- bool pointframe_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog) { MbPointFrame* pPointFr = static_cast( pIt) ; if ( pPointFr == nullptr) { LOG_ERROR( pGenLog, "Error : Point Frame pointer null") ; return false ; } // scorro i punti del PointFrame for ( size_t i = 0 ; i < pPointFr->GetVerticesCount() ; i++) { MbCartPoint3D pt ; pPointFr->GetCartPoint( i, pt) ; MbPoint3D ptP( pt) ; bool bPointOk = point_handler( &ptP, nLayId, pGeomDB, pGenLog) ; if ( ! bPointOk) return false ; } return true; } //---------------------------------------------------------------------------- bool wireframe_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog) { MbWireFrame* pWireFr = static_cast( pIt) ; if ( pWireFr == nullptr) { LOG_ERROR( pGenLog, "Error : Point Frame pointer null") ; return false ; } vector curves ; pWireFr->GetCurves(curves) ; for ( size_t i =0 ; i < curves.size() ; i++) { // scorro tutte le curve del WireFrame bool bCurveOk = curve_handler( curves[i], nLayId, pGeomDB, pGenLog) ; if ( ! bCurveOk) return false ; } return true ; } //---------------------------------------------------------------------------- bool assembly_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog, int nFlag) { MbAssembly* pAss = static_cast( pIt) ; if ( pAss == nullptr) return false ; // analizzo gl elementi dell'assembly RPArray assItems ; pAss->GetItems( assItems) ; nAssObj = 0 ; for ( MbItem** it = assItems.begin() ; it != assItems.end() ; it ++) { bool bSolOk = true ; if ( (*it)->IsA() == st_Assembly) bSolOk = assembly_handler( *it, nLayId, pGeomDB, pGenLog, nFlag) ; else if ( (*it)->IsA() == st_Solid) bSolOk = solid_handler( *it, nLayId, pGeomDB, pGenLog, nFlag) ; else if ( (*it)->IsA() == st_Instance) bSolOk = instance_handler( *it, nLayId, pGeomDB, pGenLog, nFlag) ; else if ( (*it)->IsA() == st_PointFrame) bSolOk = pointframe_handler( *it, nLayId, pGeomDB, pGenLog) ; else if ( (*it)->IsA() == st_WireFrame) bSolOk = wireframe_handler( *it, nLayId, pGeomDB, pGenLog) ; else if ( (*it)->IsA() == st_SpaceInstance) bSolOk = spaceinstance_handler( *it, nLayId, pGeomDB, pGenLog, nFlag) ; else if ( (*it)->IsA() == st_Mesh) bSolOk = mesh_handler( *it, nLayId, pGeomDB, pGenLog) ; else if ( (*it)->IsA() == st_PlaneInstance) bSolOk = planeinstance_handler( *it, nLayId, pGeomDB, pGenLog) ; ++ nAssObj ; if ( ! bSolOk) return false ; } return true; } //---------------------------------------------------------------------------- bool instance_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog, int nFlag) { MbInstance* pInst = static_cast( pIt) ; if ( pInst == nullptr) return false ; const MbItem* pInstItem = pInst->GetItem() ; if ( pInstItem == nullptr) return false ; MbItem* pItem = static_cast( &pInstItem->Duplicate()) ; if ( pItem == nullptr) return false ; MbPlacement3D InstPlacement = pInst->GetPlacement() ; // Matrice di trasformazione dalle coord locali a quelle assolute MbMatrix3D matrix( InstPlacement) ; pItem->Transform( matrix) ; // Analizzo l'item dell'instance if ( pInstItem->IsA() == st_Solid) return solid_handler( pItem, nLayId, pGeomDB, pGenLog, nFlag) ; else if ( pInstItem->IsA() == st_Assembly) return assembly_handler( pItem, nLayId, pGeomDB, pGenLog, nFlag) ; else if ( (pInstItem)->IsA() == st_PointFrame) return pointframe_handler( pItem, nLayId, pGeomDB, pGenLog) ; else if ( (pInstItem)->IsA() == st_WireFrame) return wireframe_handler( pItem, nLayId, pGeomDB, pGenLog) ; else if ( (pInstItem)->IsA() == st_SpaceInstance) return spaceinstance_handler( pItem, nLayId, pGeomDB, pGenLog, nFlag) ; else if ( (pInstItem)->IsA() == st_Mesh) return mesh_handler( pItem, nLayId, pGeomDB, pGenLog) ; else if ( (pInstItem)->IsA() == st_PlaneInstance) return planeinstance_handler( pItem, nLayId, pGeomDB, pGenLog) ; return false ; } //---------------------------------------------------------------------------- bool planeinstance_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog) { MbPlaneInstance * pPlaneInstance = static_cast (pIt) ; if ( pPlaneInstance == nullptr) { LOG_ERROR( pGenLog, "Error : Plane Instance pointer null") ; return false ; } vector pConstPlaneItems ; pPlaneInstance->GetItems ( pConstPlaneItems) ; const MbPlacement3D placement = pPlaneInstance->GetPlacement() ; // matrice di trasformazione dalle coord locali a quelle assolute MbCartPoint placement2D_origin( placement.GetOrigin().x, placement.GetOrigin().y) ; MbVector placement2D_xaxis( placement.GetAxisX().x, placement.GetAxisX().y) ; MbVector placement2D_yaxis( placement.GetAxisY().x, placement.GetAxisY().y) ; MbPlacement placement2D( placement2D_origin, placement2D_xaxis, placement2D_yaxis) ; MbMatrix matrix( placement2D) ; // scorro tutti i PlaneItems contenuti in PlaneInstance for ( size_t i = 0 ; i < pConstPlaneItems.size() ; i++) { MbPlaneItem * pPlaneIt = &pConstPlaneItems[i]->Duplicate() ; if ( pPlaneIt == nullptr) return false ; // trasformo in coordinate assolute pPlaneIt->Transform( matrix) ; // Plane Polyline if ( pPlaneIt->IsA() == pt_Polyline) { MbPolyline * pPolyline = static_cast ( pPlaneIt) ; if ( pPlaneInstance == nullptr) { LOG_ERROR( pGenLog, "Error : Polyline pointer null") ; return false ; } vector points ; pPolyline->GetPoints( points) ; // elimino punti coincidenti rispetto alla tol fissata for ( vector::iterator it = points.begin() + 1 ; it != points.end() ; it++) if ( abs( it->x - ( it-1)->x) < TOL_STD && abs( it->y - ( it-1)->y) < TOL_STD) { points.erase( it) ; it-- ; } // se dopo la rimozione è rimasto un solo punto, la curva è degenerata in un GeoPoint if ( points.size() == 1) { LOG_ERROR( pGenLog, "Warining : curve degenerated in one point") ; const MbPoint3D point( MbCartPoint3D( points[0].x, points[0].y, 0)) ; return point_handler( &point, nLayId, pGeomDB, pGenLog) ; } ICurveComposite* pCurveCompo = CreateCurveComposite() ; if ( pCurveCompo == nullptr){ LOG_ERROR( pGenLog, "Error : creating CurveComposite") ; return false ; } bool bStartPointOk = pCurveCompo->AddPoint( Point3d( points[0].x, points[0].y)) ; //starting point if ( ! bStartPointOk) { LOG_ERROR( pGenLog, "Error : creating CurveComposite") ; return false ; } for ( size_t i = 1 ; i < points.size() - 1 ; i++){ //mid points bool bAddLineOk = pCurveCompo->AddLine( Point3d( points[i].x, points[i].y), false) ; if ( ! bAddLineOk) { LOG_ERROR( pGenLog, "Error : creating CurveComposite") ; return false ; } } bool bAddLineOk = pCurveCompo->AddLine( Point3d( points.back().x, points.back().y), false) ; //end point if ( ! bAddLineOk) { LOG_ERROR( pGenLog, "Error : creating CurveComposite") ; return false ; } int nId = pGeomDB->AddGeoObj( GDB_ID_NULL, nLayId, pCurveCompo) ; if ( nId == GDB_ID_NULL) { LOG_ERROR( pGenLog, "Error : adding object CurveComposite 2D to GeomDB") ; return false ; } pGeomDB->SetMaterial( nId, Color( 0, 0, 0)) ; } // Plane LineSegment else if ( pPlaneIt->IsA() == pt_LineSegment) { MbLineSegment * pSegment = static_cast( pPlaneIt) ; if ( pSegment == nullptr) { LOG_ERROR( pGenLog, "Error : Segment pointer null") ; return false ; } MbCartPoint start = pSegment->GetLimitPoint( 1) ; MbCartPoint end = pSegment->GetLimitPoint( 2) ; // se i due punti sono coincidenti per la toll fissata, la curva è degenerata in un GeoPoint if ( abs( start.x - end.x) < TOL_STD && abs( start.y - end.y) < TOL_STD) { LOG_ERROR( pGenLog, "Warining : CurveLine 2D degenerated in one point") ; const MbPoint3D point( MbCartPoint3D( start.x, start.y, 0)) ; return point_handler( &point, nLayId, pGeomDB, pGenLog) ; } ICurveLine* pLine = CreateCurveLine() ; if ( pLine == nullptr) { LOG_ERROR( pGenLog, "Error : creating CurveLine 2D") ; return false ; } bool bLineOk = pLine->Set( Point3d( start.x, start.y), Point3d( end.x, end.y)) ; if ( ! bLineOk) { LOG_ERROR( pGenLog, "Error : creating CurveLine 2D") ; return false ; } int nId = pGeomDB->AddGeoObj( GDB_ID_NULL, nLayId, pLine) ; if ( nId == GDB_ID_NULL) { LOG_ERROR( pGenLog, "Error : adding object CurveLine 2D to GeomDB") ; return false ; } pGeomDB->SetMaterial( nId, Color( 0, 0, 0)) ; } // Plane Nurbs else if ( pPlaneIt->IsA() == pt_Nurbs) { MbNurbs * pNurbs= static_cast( pPlaneIt) ; if ( pNurbs == nullptr) { LOG_ERROR( pGenLog, "Error : Curve Nurbs 2D pointer null") ; return false ; } bool bNurbsOk = nurbs2D_handler( pNurbs, nLayId, pGeomDB, pGenLog) ; if ( ! bNurbsOk) return false ; } // Plane Generic Curve else if ( pPlaneIt->Family() == pt_Curve) { MbCurve * pCurve= static_cast( pPlaneIt) ; if ( pCurve == nullptr) { LOG_ERROR( pGenLog, "Error : Curve 2D pointer null") ; return false ; } // Approssimo la curva con Nurbs MbNurbs* pNurbs = pCurve->NurbsCurve() ; if ( pNurbs == nullptr) { LOG_ERROR( pGenLog, "Error : converting the curve 2D to a NURBS") ; return false ; } bool bNurbsOk = nurbs2D_handler( pNurbs, nLayId, pGeomDB, pGenLog) ; if ( ! bNurbsOk) return false ; } } // ciclo sui planeitems return true ; } //---------------------------------------------------------------------------- bool nurbs2D_handler( MbNurbs* pNurbs, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog) { // se la Nurbs è periodica non la considero e passo all'item successivo if ( pNurbs->IsPeriodic()) { LOG_ERROR( pGenLog, "Warning : periodic NURBS is ignored") ; return true ; } vector ctrlPoints ; DBLVECTOR knots, weights ; pNurbs->GetPoints( ctrlPoints) ; pNurbs->GetKnots( knots) ; pNurbs->GetWeights( weights) ; PNTVECTOR ctrlPoints_vector( ctrlPoints.size()) ; for ( size_t i = 0 ; i < ctrlPoints.size() ; i++) ctrlPoints_vector[i] = Point3d( ctrlPoints[i].x, ctrlPoints[i].y) ; // creo la struct NurbsData CNurbsData NurbsData; NurbsData.nDeg = int( pNurbs->GetDegree()) - 1 ; // la funzione GetDegree di c3d restituisce l'ordine NurbsData.bRat = pNurbs->IsRational() ; NurbsData.bClosed = pNurbs->IsClosed() ; NurbsData.bPeriodic = pNurbs->IsPeriodic() ; NurbsData.bExtraKnotes = false ; if ( knots.size() == ctrlPoints.size() + NurbsData.nDeg + 1) // significa che ci sono due nodi extra, uno all'inizio e uno alla fine, da togliere NurbsData.vU = vector( knots.begin() + 1, knots.end() - 1) ; else NurbsData.vU = knots ; NurbsData.vCP = ctrlPoints_vector ; NurbsData.vW = weights ; ICurve* pBezierCurve = NurbsToBezierCurve( NurbsData) ; if ( pBezierCurve == nullptr) { LOG_ERROR( pGenLog, "Error : cannot create CrvBezier 2D from given Nurbs") ; return false ; } int nId = pGeomDB->AddGeoObj( GDB_ID_NULL, nLayId, pBezierCurve) ; if ( nId == GDB_ID_NULL) { LOG_ERROR( pGenLog, "Error : adding object CrvBezier 2D to GeomDB") ; return false ; } pGeomDB->SetMaterial( nId, Color( 0, 0, 0)) ; return true ; } //---------------------------------------------------------------------------- bool spaceinstance_handler ( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog, int nFlag) { MbSpaceInstance* pSpaceInst = static_cast( pIt) ; if ( pSpaceInst == nullptr) { LOG_ERROR( pGenLog, "Error : Space Instance pointer null") ; return false ; } uint32 color = pSpaceInst->GetColor() ; // ricavo l'oggetto contenuto nello space instance const MbSpaceItem * pSpaceIt = pSpaceInst->GetSpaceItem() ; if ( pSpaceIt == nullptr) { LOG_ERROR( pGenLog, "Error : null space item") ; return false ; } // point if ( pSpaceIt->IsA() == st_Point3D) { const MbPoint3D* pPoint = static_cast( pSpaceIt) ; if ( pPoint == nullptr) { LOG_ERROR( pGenLog, "Error : Point pointer null") ; return false ; } return point_handler( pPoint, nLayId, pGeomDB, pGenLog) ; } // curve else if ( pSpaceIt->Family() == st_Curve3D) { const MbCurve3D* pCurve = static_cast( pSpaceIt) ; if ( pCurve == nullptr) { LOG_ERROR( pGenLog, "Error : Curve pointer null") ; return false ; } return curve_handler( pCurve, nLayId, pGeomDB, pGenLog) ; } // surface else if ( pSpaceIt->Family() == st_Surface) { const MbSurface* pSurface = static_cast( pSpaceIt) ; if ( pSurface == nullptr) { LOG_ERROR( pGenLog, "Error : Surface pointer null") ; return false ; } return surface_handler( pSurface, nLayId, pGeomDB, pGenLog, color, nFlag) ; } return true ; } //---------------------------------------------------------------------------- bool point_handler( const MbPoint3D* pPoint, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog) { MbCartPoint3D pt = pPoint->GetCartPoint() ; IGeoPoint3d* pGeoPoint = CreateGeoPoint3d() ; if ( pGeoPoint == nullptr) { LOG_ERROR( pGenLog, "Error : creating GeoPoint") ; return false ; } bool bPointOk = pGeoPoint->Set( Point3d( pt.x, pt.y, pt.z)) ; if ( ! bPointOk) { LOG_ERROR( pGenLog, "Error : creating GeoPoint") ; return false ; } int nId = pGeomDB->AddGeoObj( GDB_ID_NULL, nLayId, pGeoPoint) ; if ( nId == GDB_ID_NULL) { LOG_ERROR( pGenLog, "Error : adding object GeoPoint to GeomDB") ; return false ; } pGeomDB->SetMaterial( nId, Color( 0, 0, 0)) ; return true ; } //---------------------------------------------------------------------------- ICurve* ConvertCurve3D( const MbCurve3D& pCurve, Point3d& ptDegen) { PtrOwner pCrv ; // Polyline if ( pCurve.IsA() == st_Polyline3D) { const MbPolyline3D* pPolyline = static_cast( &pCurve) ; if ( pPolyline == nullptr) return nullptr ; vector< MbCartPoint3D > points ; pPolyline->GetPoints( points) ; // elimino punti coincidenti rispetto alla tol fissata for ( vector::iterator it = points.begin() + 1 ; it != points.end() ; it++) if ( abs( it->x - ( it-1)->x) < TOL_STD && abs( it->y - ( it-1)->y) < TOL_STD && abs( it->z - ( it-1)->z) < TOL_STD) { points.erase( it) ; it-- ; } // se dopo la rimozione è rimasto un solo punto, la curva è degenerata in un GeoPoint if ( points.size() == 1) { MbPoint3D ptP( points[0]) ; ptDegen = ConvertPoint( ptP) ; return nullptr ; } ICurveComposite* pCurveCompo = CreateCurveComposite() ; if ( pCurveCompo == nullptr) return nullptr ; bool bStartPointOk = pCurveCompo->AddPoint( Point3d( points[0].x, points[0].y, points[0].z)) ; // starting point if ( ! bStartPointOk) return nullptr ; for ( size_t i = 1 ; i < points.size() - 1 ; i++) { // mid points bool bAddLineOk = pCurveCompo->AddLine( Point3d( points[i].x, points[i].y, points[i].z), false) ; if ( ! bAddLineOk) return nullptr ; } bool bAddLineOk = pCurveCompo->AddLine( Point3d( points.back().x, points.back().y, points.back().z), false) ; // end point if ( ! bAddLineOk) return nullptr ; return pCurveCompo ; } // LineSegment else if ( pCurve.IsA() == st_LineSegment3D ){ const MbLineSegment3D * pSegment = static_cast( &pCurve) ; if ( pSegment == nullptr) return nullptr ; MbCartPoint3D start = pSegment->GetLimitPoint( 1) ; MbCartPoint3D end = pSegment->GetLimitPoint( 2) ; // Se i due punti sono coincidenti per la toll fissata, la curva è degenerata in un GeoPoint if ( abs( start.x - end.x) < TOL_STD && abs( start.y - end.y) < TOL_STD && abs( start.z - end.z) < TOL_STD) { MbPoint3D ptP( start) ; ptDegen = ConvertPoint( ptP) ; return nullptr ; } ICurveLine* pLine = CreateCurveLine() ; if ( pLine == nullptr) return nullptr ; bool bLineOk = pLine->Set( Point3d( start.x, start.y, start.z), Point3d( end.x, end.y, end.z)) ; if ( ! bLineOk) return nullptr ; return pLine ; } // Arc else if ( pCurve.IsA() == st_Arc3D ) { const MbArc3D * pArc = static_cast( &pCurve) ; if ( pArc == nullptr) return nullptr ; MbCartPoint3D start = pArc->GetLimitPoint( 1) ; MbCartPoint3D end = pArc->GetLimitPoint( 2) ; double dRad = pArc->GetRadius() ; ICurveArc* pCurveArc = CreateCurveArc() ; if ( pCurveArc == nullptr) return nullptr ; bool bArcOk = false ; // circonferenza if ( abs( start.x - end.x) < TOL_STD && abs( start.y - end.y) < TOL_STD && abs( start.z - end.z) < TOL_STD) { MbAxis3D axis ; bool bAxisOk = pArc->GetCircleAxis( axis) ; if ( ! bAxisOk ) return nullptr ; if ( dRad < TOL_STD) { MbPoint3D ptP( start) ; ptDegen = ConvertPoint( ptP) ; return nullptr ; } bArcOk = pCurveArc->Set( Point3d( axis.GetOrigin().x, axis.GetOrigin().y, axis.GetOrigin().z), Vector3d( axis.GetAxisZ().x, axis.GetAxisZ().y, axis.GetAxisZ().z), dRad) ; } // arco generico else { MbCartPoint3D mid ; double t = pArc->GetTMid() ; pArc->PointOn( t, mid) ; bArcOk = pCurveArc->Set3P( Point3d( start.x, start.y, start.z), Point3d( mid.x, mid.y, mid.z), Point3d( end.x, end.y, end.z)) ; } if ( ! bArcOk) return nullptr ; return pCurveArc ; } // Nurbs else if ( pCurve.IsA() == st_Nurbs3D) { const MbNurbs3D * pNurbs= static_cast( &pCurve) ; return ConvertNurbs3D( pNurbs, false) ; } // Generic curve else { // Approssimo la curva con Nurbs const MbNurbs3D* pNurbs = pCurve.NurbsCurve() ; return ConvertNurbs3D( pNurbs, true) ; } return nullptr ; } //---------------------------------------------------------------------------- ICurve* ConvertCurve( const MbCurve& pCurve, Point3d& ptDegen, double dScale) { PtrOwner pCrv ; // Polyline if ( pCurve.IsA() == pt_Polyline) { const MbPolyline* pPolyline = static_cast( &pCurve) ; if ( pPolyline == nullptr) return nullptr ; vector< MbCartPoint> points ; pPolyline->GetPoints( points) ; // elimino punti coincidenti rispetto alla tol fissata for ( vector::iterator it = points.begin() + 1 ; it != points.end() ; it++) if ( abs( it->x - ( it-1)->x) < TOL_STD && abs( it->y - ( it-1)->y) < TOL_STD) { points.erase( it) ; it-- ; } // se dopo la rimozione è rimasto un solo punto, la curva è degenerata in un GeoPoint if ( points.size() == 1) { MbPoint3D ptP( points[0].x, points[0].y, 0) ; ptDegen = ConvertPoint( ptP) ; ptDegen.Scale( GLOB_FRM, dScale, dScale, 1.) ; return nullptr ; } ICurveComposite* pCurveCompo = CreateCurveComposite() ; if ( pCurveCompo == nullptr) return nullptr ; bool bStartPointOk = pCurveCompo->AddPoint( Point3d( points[0].x * dScale, points[0].y * dScale, 0)) ; // starting point if ( ! bStartPointOk) return nullptr ; for ( size_t i = 1 ; i < points.size() - 1 ; i++){ // mid points bool bAddLineOk = pCurveCompo->AddLine( Point3d( points[i].x * dScale, points[i].y, 0) * dScale, false) ; if ( ! bAddLineOk) return nullptr ; } bool bAddLineOk = pCurveCompo->AddLine( Point3d( points.back().x * dScale, points.back().y * dScale, 0), false) ; // end point if ( ! bAddLineOk) return nullptr ; return pCurveCompo ; } // LineSegment else if ( pCurve.IsA() == pt_LineSegment ){ const MbLineSegment * pSegment = static_cast( &pCurve) ; if ( pSegment == nullptr) return nullptr ; MbCartPoint start = pSegment->GetLimitPoint( 1) ; MbCartPoint end = pSegment->GetLimitPoint( 2) ; // Se i due punti sono coincidenti per la toll fissata, la curva è degenerata in un GeoPoint if ( abs( start.x - end.x) * dScale < TOL_STD && abs( start.y - end.y) * dScale < TOL_STD) { MbCartPoint3D mbCPt3D ; mbCPt3D.Init( start) ; MbPoint3D ptP( mbCPt3D) ; ptDegen = ConvertPoint( ptP) ; ptDegen.Scale( GLOB_FRM, dScale, dScale, 1.) ; return nullptr ; } ICurveLine* pLine = CreateCurveLine() ; if ( pLine == nullptr) return nullptr ; bool bLineOk = pLine->Set( Point3d( start.x * dScale, start.y * dScale, 0), Point3d( end.x * dScale, end.y * dScale, 0)) ; if ( ! bLineOk) return nullptr ; return pLine ; } // Arc else if ( pCurve.IsA() == pt_Arc) { const MbArc * pArc = static_cast( &pCurve) ; if ( pArc == nullptr) return nullptr ; MbCartPoint start = pArc->GetLimitPoint( 1) ; MbCartPoint end = pArc->GetLimitPoint( 2) ; double dRad = pArc->GetRadius() ; ICurveArc* pCurveArc = CreateCurveArc() ; if ( pCurveArc == nullptr) return nullptr ; bool bArcOk = false ; // circonferenza if ( abs( start.x - end.x) * dScale < TOL_STD && abs( start.y - end.y) * dScale < TOL_STD) { MbPlacement mbPlacement = pArc->GetPlacement() ; MbVector mvVtX = mbPlacement.GetAxisX() ; MbVector mvVtY = mbPlacement.GetAxisY() ; if ( dRad * dScale < TOL_STD) { ptDegen = Point3d( mbPlacement.GetOrigin().x, mbPlacement.GetOrigin().y, 0) * dScale ; return nullptr ; } bArcOk = pCurveArc->Set( Point3d( mbPlacement.GetOrigin().x, mbPlacement.GetOrigin().y, 0) * dScale, Z_AX, dRad * dScale) ; } // arco generico else { MbCartPoint mid ; double t = pArc->GetTMid() ; pArc->PointOn( t, mid) ; bArcOk = pCurveArc->Set3P( Point3d( start.x * dScale, start.y * dScale, 0), Point3d( mid.x * dScale, mid.y * dScale, 0), Point3d( end.x * dScale, end.y * dScale, 0)) ; } if ( ! bArcOk) return nullptr ; return pCurveArc ; } // Nurbs else if ( pCurve.IsA() == pt_Nurbs) { const MbNurbs * pNurbs = static_cast( &pCurve) ; return ConvertNurbs( pNurbs, dScale, false) ; } // Generic curve else { // Approssimo la curva con Nurbs MbNurbs* pNurbs = pCurve.NurbsCurve() ; return ConvertNurbs( pNurbs, dScale, true) ; } return nullptr ; } //---------------------------------------------------------------------------- bool curve_handler( const MbCurve3D* pCurve, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog) { // Polyline if ( pCurve->IsA() == st_Polyline3D) { Point3d ptDegen = P_INVALID ; ICurve* pCurveCompo = ConvertCurve3D( *pCurve, ptDegen) ; if ( pCurveCompo == nullptr) { if ( ! ptDegen.IsValid()) { LOG_ERROR( pGenLog, "Error : creating CurveComposite") ; return false ; } LOG_ERROR( pGenLog, "Warining : curve degenerated in one point") ; MbPoint3D mbCPt( ptDegen.x, ptDegen.y, ptDegen.z) ; return point_handler( &mbCPt, nLayId, pGeomDB, pGenLog) ; } int nId = pGeomDB->AddGeoObj( GDB_ID_NULL, nLayId, pCurveCompo) ; if ( nId == GDB_ID_NULL) { LOG_ERROR( pGenLog, "Error : adding object CurveComposite to GeomDB") ; return false ; } pGeomDB->SetMaterial( nId, Color( 0, 0, 0)) ; } // LineSegment else if ( pCurve->IsA() == st_LineSegment3D) { Point3d ptDegen = P_INVALID ; ICurve* pLine = ConvertCurve3D( *pCurve, ptDegen) ; if ( pLine == nullptr) { if ( ! ptDegen.IsValid()) { LOG_ERROR( pGenLog, "Error : creating CurveLine") ; return false ; } LOG_ERROR( pGenLog, "Warning : CurveLine degenerated in one point") ; MbPoint3D mbCPt( ptDegen.x, ptDegen.y, ptDegen.z) ; return point_handler( &mbCPt, nLayId, pGeomDB, pGenLog) ; } int nId = pGeomDB->AddGeoObj( GDB_ID_NULL, nLayId, pLine) ; if ( nId == GDB_ID_NULL) { LOG_ERROR( pGenLog, "Error : adding object CurveLine to GeomDB") ; return false ; } pGeomDB->SetMaterial( nId, Color( 0, 0, 0)) ; } // Arc else if ( pCurve->IsA() == st_Arc3D ) { const MbArc3D * pArc = static_cast( pCurve) ; if ( pArc == nullptr) { LOG_ERROR( pGenLog, "Error : Arc pointer null") ; return false ; } Point3d ptDegen = P_INVALID ; ICurve* pCurveArc = ConvertCurve3D( *pCurve, ptDegen) ; if ( pCurveArc == nullptr) { if ( ! ptDegen.IsValid()) { LOG_ERROR( pGenLog, "Error : creating CurveArc") ; return false ; } LOG_ERROR( pGenLog, "Warning : CurveArc degenerated in one point") ; MbPoint3D mbCPt( ptDegen.x, ptDegen.y, ptDegen.z) ; return point_handler( &mbCPt, nLayId, pGeomDB, pGenLog) ; } int nId = pGeomDB->AddGeoObj( GDB_ID_NULL, nLayId, pCurveArc) ; if ( nId == GDB_ID_NULL) { LOG_ERROR( pGenLog, "Error : adding object CurveArc to GeomDB") ; return false ; } pGeomDB->SetMaterial( nId, Color( 0, 0, 0)) ; } // Nurbs else if ( pCurve->IsA() == st_Nurbs3D) { const MbNurbs3D * pNurbs= static_cast( pCurve) ; if ( pNurbs == nullptr) { LOG_ERROR( pGenLog, "Error : Nurbs pointer null") ; return false ; } return nurbs3D_handler( pNurbs, nLayId, pGeomDB, pGenLog) ; } // Generic curve else { // Approssimo la curva con Nurbs const MbNurbs3D* pNurbs = pCurve->NurbsCurve() ; if ( pNurbs == nullptr) { LOG_ERROR( pGenLog, "Error : converting the curve to a NURBS") ; return false ; } return nurbs3D_handler( pNurbs, nLayId, pGeomDB, pGenLog) ; } return true ; } //---------------------------------------------------------------------------- ICurve* ConvertNurbs( const MbNurbs* pNurbs, double dScale, bool bEraseSrc) { vector ctrlPoints ; DBLVECTOR knots, weights ; pNurbs->GetPoints( ctrlPoints) ; pNurbs->GetKnots( knots) ; pNurbs->GetWeights( weights) ; PNTVECTOR ctrlPoints_vector( ctrlPoints.size()) ; // salvo i punti di controllo e li scalo con il fattore richiesto for ( size_t i = 0 ; i < ctrlPoints.size() ; i++) ctrlPoints_vector[i] = Point3d( ctrlPoints[i].x * dScale, ctrlPoints[i].y * dScale, 0) ; // creo la struct NurbsData CNurbsData NurbsData; NurbsData.nDeg = int( pNurbs->GetDegree()) - 1 ; // la funzione GetDegree di c3d restituisce l'ordine NurbsData.bRat = pNurbs->IsRational() ; NurbsData.bClosed = pNurbs->IsClosed() ; NurbsData.bPeriodic = pNurbs->IsPeriodic() ; NurbsData.bExtraKnotes = false ; if ( knots.size() == ctrlPoints.size() + NurbsData.nDeg + 1) // significa che ci sono due nodi extra, uno all'inizio e uno alla fine, da togliere NurbsData.vU = vector( knots.begin() + 1, knots.end() - 1) ; else NurbsData.vU = knots ; NurbsData.vCP = ctrlPoints_vector ; NurbsData.vW = weights ; if ( NurbsData.bPeriodic || ! NurbsData.bClamped ) { NurbsCurveCanonicalize( NurbsData) ; } if ( bEraseSrc) // cancello l'oggetto del puntatore delete pNurbs ; PtrOwner pCrv( NurbsToBezierCurve( NurbsData)) ; return Release(pCrv) ; } //---------------------------------------------------------------------------- ICurve* ConvertNurbs3D( const MbNurbs3D* pNurbs, bool bEraseSrc) { vector ctrlPoints ; DBLVECTOR knots, weights ; pNurbs->GetPoints( ctrlPoints) ; pNurbs->GetKnots( knots) ; pNurbs->GetWeights( weights) ; PNTVECTOR ctrlPoints_vector( ctrlPoints.size()) ; for ( size_t i = 0 ; i < ctrlPoints.size() ; i++) ctrlPoints_vector[i] = Point3d( ctrlPoints[i].x, ctrlPoints[i].y, ctrlPoints[i].z) ; // creo la struct NurbsData CNurbsData NurbsData; NurbsData.nDeg = int( pNurbs->GetDegree()) - 1 ; // la funzione GetDegree di c3d restituisce l'ordine NurbsData.bRat = pNurbs->IsRational() ; NurbsData.bClosed = pNurbs->IsClosed() ; NurbsData.bPeriodic = pNurbs->IsPeriodic() ; NurbsData.bExtraKnotes = false ; if ( knots.size() == ctrlPoints.size() + NurbsData.nDeg + 1) // significa che ci sono due nodi extra, uno all'inizio e uno alla fine, da togliere NurbsData.vU = vector( knots.begin() + 1, knots.end() - 1) ; else NurbsData.vU = knots ; NurbsData.vCP = ctrlPoints_vector ; NurbsData.vW = weights ; if ( NurbsData.bPeriodic || ! NurbsData.bClamped) NurbsCurveCanonicalize( NurbsData) ; if ( bEraseSrc) delete pNurbs ; PtrOwner pCrv( NurbsToBezierCurve( NurbsData)) ; if ( ! IsNull( pCrv)) return Release( pCrv) ; // Non è riuscita la conversione, creo la composita dei punti di controllo PtrOwner pCrvCompo( CreateCurveComposite()) ; PolyLine PL ; if ( PL.FromPointVector( ctrlPoints_vector) && pCrvCompo->FromPolyLine( PL)) return Release( pCrvCompo) ; return nullptr ; } //---------------------------------------------------------------------------- bool nurbs3D_handler( const MbNurbs3D* pNurbs, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog) { ICurve* pBezierCurve = ConvertNurbs3D( pNurbs, false) ; if ( pBezierCurve == nullptr) { LOG_ERROR( pGenLog, "Error : cannot create Bezier Curve from given Nurbs") ; return false ; } int nId = pGeomDB->AddGeoObj( GDB_ID_NULL, nLayId, pBezierCurve) ; if ( nId == GDB_ID_NULL) { LOG_ERROR( pGenLog, "Error : adding object CrvBezier to GeomDB") ; return false ; } pGeomDB->SetMaterial( nId, Color( 0, 0, 0)) ; return true ; } //---------------------------------------------------------------------------- ISurfBezier* ConvertSurface(const MbSurface* pSurface, DBLVECTOR& vU, DBLVECTOR& vV) { SNurbsSurfData sNurbsSurf ; sNurbsSurf.bClosedU = pSurface->IsUClosed() ; sNurbsSurf.bClosedV = pSurface->IsVClosed() ; sNurbsSurf.bPeriodicU = pSurface->IsUPeriodic() ; sNurbsSurf.bPeriodicV = pSurface->IsVPeriodic() ; sNurbsSurf.bClampedU = true ; // di questi non ho trovato il membro da copiare, quindi li setto a true, senn� viene chiamata la canonicalize sNurbsSurf.bClampedV = true ; // superficie che deve essere trasformata in NURBS e poi in Bezier MbSplineSurface* mbNurbs = pSurface->NurbsSurface( true) ; sNurbsSurf.bRat = mbNurbs->IsRational() ; sNurbsSurf.nDegU = mbNurbs->GetUDegree() - 1 ; // la funzione degree restituisce l'ordine in realt�, quindi devo ridurre il valore di 1 sNurbsSurf.nDegV = mbNurbs->GetVDegree() - 1 ; //MbControlData3D mbCtrlPt ; mbNurbs->GetBasisPoints( mbCtrlPt) ; int nUKnots = int( mbNurbs->GetKnotsCount( true)) ; int nVKnots = int( mbNurbs->GetKnotsCount( false)) ; sNurbsSurf.nCPU = mbNurbs->GetPointsUCount() ; // numero di colonne sNurbsSurf.nCPV = mbNurbs->GetPointsVCount() ; // numero di righe PNTVECTOR vCPV( sNurbsSurf.nCPV) ; sNurbsSurf.mCP.resize( sNurbsSurf.nCPU, vCPV) ; DBLVECTOR vWV( sNurbsSurf.nCPV) ; sNurbsSurf.mW.resize( sNurbsSurf.nCPU, vWV) ; for ( int i = 0 ; i < sNurbsSurf.nCPU ; ++i) { for ( int j = 0 ; j < sNurbsSurf.nCPV ; ++j) { MbCartPoint3D mbPt ; mbNurbs->GetPoint(j, i, mbPt) ; Point3d ptCP = ConvertPoint( mbPt) ; sNurbsSurf.mCP[i][j] = ptCP ; if ( sNurbsSurf.bRat){ double dW = mbNurbs->GetWeight( j, i) ; //sNurbsSurf.mCP[i][j] = ptCP/* / dW */; sNurbsSurf.mW[i][j] = dW ; } //else // sNurbsSurf.mCP[i][j] = ptCP ; } } for ( int i = 0 ; i < nUKnots ; ++i) sNurbsSurf.vU.push_back( mbNurbs->GetKnot( true, i)) ; if ( sNurbsSurf.vU.size() == sNurbsSurf.nCPU + sNurbsSurf.nDegU + 1) // significa che ci sono due nodi extra, uno all'inizio e uno alla fine, da togliere sNurbsSurf.vU = vector( sNurbsSurf.vU.begin() + 1, sNurbsSurf.vU.end() - 1) ; for ( int j = 0 ; j < nVKnots ; ++j) sNurbsSurf.vV.push_back( mbNurbs->GetKnot( false, j)) ; if ( sNurbsSurf.vV.size() == sNurbsSurf.nCPV + sNurbsSurf.nDegV + 1) // significa che ci sono due nodi extra, uno all'inizio e uno alla fine, da togliere sNurbsSurf.vV = vector( sNurbsSurf.vV.begin() + 1, sNurbsSurf.vV.end() - 1) ; if ( sNurbsSurf.bPeriodicU || sNurbsSurf.bPeriodicV || ! sNurbsSurf.bClampedU || ! sNurbsSurf.bClampedV) NurbsSurfaceCanonicalize( sNurbsSurf) ; // salvo i vettori dei nodi vU = sNurbsSurf.vU ; vV = sNurbsSurf.vV ; delete mbNurbs ; PtrOwner pSurfBez( GetSurfBezier(NurbsToBezierSurface( sNurbsSurf))) ; if ( IsNull( pSurfBez) || ! pSurfBez->IsValid()) return nullptr ; return Release( pSurfBez) ; } //---------------------------------------------------------------------------- bool surface_handler( const MbSurface* pSurface, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog, uint32 color, int nFlag) { // conversione diretta in trimesh if ( nFlag == 0) { // Creazione mesh MbStepData stepdata ; MbFormNote note ; CreateMeshData( stepdata, note) ; MbMesh mesh ; pSurface->CalculateMesh( stepdata, note, mesh) ; bool bMeshOk = mesh_handler( & mesh, nLayId, pGeomDB, pGenLog, false) ; if ( ! bMeshOk) return false ; } // conversione in superficie di Bezier else if ( nFlag == 1) { DBLVECTOR vU, vV ; PtrOwner pSurf( ConvertSurface( pSurface, vU, vV)) ; if ( IsNull( pSurf) || ! pSurf->IsValid()) return false ; pSurf->RemoveCollapsedSpans() ; pGeomDB->AddGeoObj( GDB_ID_NULL, nLayId, Release(pSurf)) ; } int nId = pGeomDB->GetLastInGroup( nLayId) ; // recupero id dell'oggetto appena aggiunto dal mesh_handler if ( color != 16744192) { float r, g, b ; uint322RGB( color, r, g, b) ; pGeomDB->SetMaterial( nId, Color( r, g, b)) ; } return true ; } //--------------------------------------------------- bool CreateMeshData( MbStepData& stepData, MbFormNote& note) { stepData.Init( ist_SpaceStep, s_dLinToler, M_PI / 12, ( s_dLinToler > TOL_LIM_S ? 1000 : 100)) ; stepData.SetStepType( ist_DeviationStep) ; if ( s_dLinToler < TOL_LIM_B) stepData.SetStepType( ist_MetricStep) ; note.SetWire( true) ; note.SetGrid( true) ; note.SetSeam( true) ; note.SetExact( true) ; note.SetQuad( false) ; note.SetFair( true) ; note.SetMere( true) ; return true ; }