43655cedb6
- aggiunto controllo - reso il log globale.
2206 lines
82 KiB
C++
2206 lines
82 KiB
C++
//----------------------------------------------------------------------------
|
|
// 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"
|
|
|
|
#define SAVETRIMLOOPS 0
|
|
#define SAVECONTOUR 0
|
|
#if SAVETRIMLOOPS || SAVECONTOUR
|
|
std::vector<IGeoObj*> vGeo ;
|
|
#include "/EgtDev/Include/EGkGeoObjSave.h"
|
|
#endif
|
|
|
|
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) ;
|
|
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) ;
|
|
ISurfBezier* ConvertSurface( const MbSurface* mbSurface, DBLVECTOR& vU, DBLVECTOR& vV) ;
|
|
bool surface_handler( const MbSurface* pSurface, int nLayId, IGeomDB* pGeomDB, uint32 color, int nFlag = 0) ;
|
|
bool nurbs2D_handler( MbNurbs* pNurbs, int nLayId, IGeomDB* pGeomDB) ;
|
|
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) ;
|
|
bool mesh_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, bool bColor = true) ;
|
|
ISurfBezier* ConvertFace( const MbFace* mbF) ;
|
|
bool solid_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, const int nFlag = 0) ;
|
|
bool pointframe_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB) ;
|
|
bool wireframe_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB) ;
|
|
bool spaceinstance_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, int nFlag = 0) ;
|
|
bool planeinstance_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB) ;
|
|
bool assembly_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, int nFlag = 0) ;
|
|
bool instance_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, int nFlag = 0) ;
|
|
bool SimplifyCurve( ICurveComposite*& pCrv) ;
|
|
bool LimitLoop( double u0, double u1, double v0, double v1, ICurveComposite* pCrv, ICRVCOMPOPOVECTOR& vCC, bool bOpenOrClosed) ;
|
|
|
|
//------------------------- Variabili locali ---------------------------------
|
|
static double s_dLinToler = 0.1 ;
|
|
|
|
int nObject = 0 ;
|
|
PtrOwner<Logger> pGenLog ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
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
|
|
pGenLog.Set( 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<IGeomDB> 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 ;
|
|
|
|
// 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, nFlag) ;
|
|
else if ( ( *it )->IsA() == st_Solid )
|
|
bSolOk = solid_handler( *it, nLayId, pGeomDB, nFlag) ;
|
|
else if ( ( *it)->IsA() == st_Instance)
|
|
bSolOk = instance_handler(*it, nLayId, pGeomDB, nFlag) ;
|
|
else if ( ( *it)->IsA() == st_PointFrame)
|
|
bSolOk = pointframe_handler(*it, nLayId, pGeomDB) ;
|
|
else if ( ( *it)->IsA() == st_WireFrame)
|
|
bSolOk = wireframe_handler(*it, nLayId, pGeomDB) ;
|
|
else if ( ( *it)->IsA() == st_SpaceInstance)
|
|
bSolOk = spaceinstance_handler(*it, nLayId, pGeomDB, nFlag) ;
|
|
else if ( ( *it)->IsA() == st_Mesh)
|
|
bSolOk = mesh_handler(*it, nLayId, pGeomDB) ;
|
|
else if ( ( *it)->IsA() == st_PlaneInstance)
|
|
bSolOk = planeinstance_handler(*it, nLayId, pGeomDB) ;
|
|
|
|
if ( ! bSolOk) {
|
|
PrepareExit( pGenLog, "Error on model") ;
|
|
return 14 ;
|
|
}
|
|
|
|
++nObject ;
|
|
}
|
|
|
|
// 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<ICurveComposite> 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<ICurve> 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<ICurveComposite> pCC( ConvertCurveToComposite( 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, bool bColor)
|
|
{
|
|
MbMesh * pMesh = static_cast<MbMesh*>( pIt) ;
|
|
if ( pMesh == nullptr) {
|
|
LOG_ERROR( pGenLog, "Error : Mesh pointer null") ;
|
|
return false ;
|
|
}
|
|
|
|
PtrOwner<ISurfTriMesh> 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<ICurveComposite> 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, bool bOpenOrClosed) {
|
|
PtrOwner<ICurveComposite> 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( *pCrv, *pCCEdge) ;
|
|
CRVCVECTOR vCrvClass0 ;
|
|
CRVCVECTOR vCrvClass1 ;
|
|
|
|
#if SAVETRIMLOOPS
|
|
vGeo.clear() ;
|
|
vGeo.push_back( pCrv->Clone()) ;
|
|
vGeo.push_back( pCCEdge->Clone()) ;
|
|
SaveGeoObj( vGeo, "D:\\Temp\\bezier\\import\\trim_loops_during_limiting.nge") ;
|
|
#endif
|
|
|
|
if ( ! icc.GetCurveClassification( 0, EPS_SMALL, vCrvClass0) || ( ! bOpenOrClosed && ! icc.GetCurveClassification( 1, EPS_SMALL, vCrvClass1)))
|
|
return false ;
|
|
|
|
int nInters = icc.GetIntersCount() ;
|
|
ICCIVECTOR vICCI ;
|
|
for ( int i = 0 ; i < nInters ; ++i) {
|
|
IntCrvCrvInfo icci ; icc.GetIntCrvCrvInfo( i, icci) ;
|
|
vICCI.push_back( std::move( icci)) ;
|
|
}
|
|
|
|
double dLastParam0 = 0 ;
|
|
double dLastParam1 = 0 ;
|
|
double dStartA, dEndA ;
|
|
pCrv->GetDomain( dStartA, dEndA) ;
|
|
double dEndB = 4 ;
|
|
for ( int i = 0 ; i < ssize( vCrvClass0) ; ++i) {
|
|
if ( vCrvClass0[i].nClass == CRVC_IN || vCrvClass0[i].nClass == CRVC_ON_P) {
|
|
// se continua la curva precedente allora la giunta
|
|
if ( vCC.size() != 0 && abs( dLastParam0 - vCrvClass0[i].dParS) < EPS_PARAM)
|
|
vCC.back()->AddCurve( pCrv->CopyParamRange( vCrvClass0[i].dParS, vCrvClass0[i].dParE)) ;
|
|
// sennò creo una nuova curva
|
|
else
|
|
vCC.emplace_back( ConvertCurveToComposite( pCrv->CopyParamRange( vCrvClass0[i].dParS, vCrvClass0[i].dParE))) ;
|
|
|
|
dLastParam0 = vCrvClass0[i].dParE ;
|
|
for ( int j = 0 ; j < ssize( vICCI) ; ++j) {
|
|
int k = vICCI[j].bOverlap ? 1 : 0 ;
|
|
if ( abs( vICCI[j].IciA[k].dU - vCrvClass0[i].dParE) < EPS_PARAM) {
|
|
dLastParam1 = vICCI[j].IciB[k].dU ;
|
|
if ( dEndB - dLastParam1 < EPS_ZERO)
|
|
dLastParam1 = 0 ;
|
|
break ;
|
|
}
|
|
}
|
|
}
|
|
else if ( vCrvClass0[i].nClass == CRVC_OUT && ! bOpenOrClosed){
|
|
// aggiungo la parte di curva di edge al posto della parte di curva che esce dal parametrico
|
|
// se non ho ancora aggiunto un tratto parto dal primo punto di intersezione
|
|
if ( ssize( vCC) == 0) {
|
|
double dPar0 = vCrvClass0[i].dParS ;
|
|
for ( int j = 0 ; j < ssize( vICCI) ; ++j) {
|
|
int k = vICCI[j].bOverlap ? 1 : 0 ;
|
|
if ( abs(vICCI[j].IciA[k].dU - dPar0) < EPS_PARAM ||
|
|
( ! bOpenOrClosed && abs( dEndA - vICCI[j].IciA[k].dU - dPar0) < EPS_PARAM)) {
|
|
if ( abs( dEndB - vICCI[j].IciB[k].dU) < EPS_PARAM)
|
|
dLastParam1 = 0 ;
|
|
else
|
|
dLastParam1 = vICCI[j].IciB[k].dU ;
|
|
break ;
|
|
}
|
|
}
|
|
}
|
|
int c = 0 ;
|
|
while ( c < ssize( vCrvClass1) - 1 && abs( vCrvClass1[c].dParS - dLastParam1) > EPS_PARAM)
|
|
++c ;
|
|
|
|
if ( vCrvClass1[c].nClass == CRVC_IN && abs( vCrvClass1[c].dParS - dLastParam1) < EPS_PARAM) {
|
|
if ( ssize( vCC) == 0)
|
|
vCC.emplace_back( ConvertCurveToComposite( pCCEdge->CopyParamRange( vCrvClass1[c].dParS, vCrvClass1[c].dParE))) ;
|
|
else
|
|
vCC.back()->AddCurve( pCCEdge->CopyParamRange( vCrvClass1[c].dParS, vCrvClass1[c].dParE)) ;
|
|
dLastParam1 = vCrvClass1[c].dParE ;
|
|
// se sono alla fine curva verifico se devo aggiungere anche un pezzo di inizio
|
|
if ( dLastParam1 == dEndB && vCrvClass1[0].nClass == CRVC_IN) {
|
|
c = 0 ;
|
|
vCC.back()->AddCurve( pCCEdge->CopyParamRange( vCrvClass1[c].dParS, vCrvClass1[c].dParE)) ;
|
|
dLastParam1 = vCrvClass1[c].dParE ;
|
|
}
|
|
|
|
for ( int j = 0 ; j < ssize( vICCI) ; ++j) {
|
|
int k = vICCI[j].bOverlap ? 1 : 0 ;
|
|
if ( abs(vICCI[j].IciB[k].dU - dLastParam1) < EPS_PARAM) {
|
|
dLastParam0 = vICCI[j].IciA[k].dU ;
|
|
break ;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
return false ;
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
ISurfBezier*
|
|
ConvertFace( const MbFace* mbF) {
|
|
bool bSameSense = mbF->IsSameSense() ;
|
|
std::vector<SPtr<MbContour> > 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<ISurfBezier> 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<Inters> 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 SAVECONTOUR
|
|
vGeo.clear() ;
|
|
vGeo.push_back( pCrv->Clone()) ;
|
|
SaveGeoObj( vGeo, "D:\\Temp\\bezier\\import\\contour.nge") ;
|
|
#endif
|
|
|
|
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 ;
|
|
}
|
|
}
|
|
ICRVCOMPOPOVECTOR vCC ;
|
|
if ( ! LimitLoop( u0, u1, v0, v1, pCrv, vCC, false)) {
|
|
delete pCrv ;
|
|
LOG_ERROR( pGenLog, "Error limiting open (but actually closed) curve") ;
|
|
goto exit ;
|
|
}
|
|
delete pCrv ;
|
|
if ( IsNull(vCC[0]) || ! vCC[0]->IsValid() || ! SfrCntr.AddCurve( Release( vCC[0]))) {
|
|
LOG_ERROR( pGenLog, "Error adding open curve") ;
|
|
goto exit ;
|
|
}
|
|
}
|
|
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, true)) {
|
|
delete pCrv ;
|
|
LOG_ERROR( pGenLog, "Error limiting an open trim") ;
|
|
goto exit ;
|
|
}
|
|
delete pCrv ;
|
|
// 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)) {
|
|
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<ICurveComposite> 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) ;
|
|
}
|
|
}
|
|
|
|
#if SAVETRIMLOOPS
|
|
SaveGeoObj( pCrv->Clone(), "D:\\Temp\\bezier\\import\\trim_loops_before_limiting.nge") ;
|
|
#endif
|
|
|
|
// se il box ha dimensioni che sforano il dominio limito il loop
|
|
BBox3d bbCrv ;
|
|
pCrv->GetBBox( GLOB_FRM, bbCrv) ;
|
|
const Point3d& ptMin = bbCrv.GetMin() ;
|
|
const Point3d& ptMax = bbCrv.GetMax() ;
|
|
if ( ptMin.x < u0 - EPS_ZERO || ptMin.y < v0 - EPS_ZERO || ptMax.x > u1 + EPS_ZERO || ptMax.y > v1 + EPS_ZERO) {
|
|
ICRVCOMPOPOVECTOR vCC ;
|
|
if ( ! LimitLoop( u0, u1, v0, v1, pCrv, vCC, false)) {
|
|
LOG_ERROR( pGenLog, "Error 1 limiting closed curve") ;
|
|
goto exit ;
|
|
}
|
|
delete pCrv ;
|
|
|
|
if ( ssize( vCC) == 0) {
|
|
LOG_ERROR( pGenLog, "Error 2 limiting closed curve") ;
|
|
goto exit ;
|
|
}
|
|
#if SAVETRIMLOOPS
|
|
vector<IGeoObj*> vGeo ;
|
|
for ( int j = 0 ; j < ssize( vCC) ; ++j)
|
|
vGeo.push_back( vCC[j]->Clone()) ;
|
|
SaveGeoObj( vGeo, "D:\\Temp\\bezier\\import\\trim_loops_after_limiting.nge") ;
|
|
#endif
|
|
|
|
//devo fare la chain di queste curve prima di metterele nella SFR
|
|
GetChainedCurves( vCC) ;
|
|
#if SAVETRIMLOOPS
|
|
vGeo.clear() ;
|
|
vGeo.push_back( vCC[0]) ;
|
|
SaveGeoObj( vGeo, "D:\\Temp\\bezier\\import\\trim_loops_after_chain.nge") ;
|
|
#endif
|
|
|
|
for( int i = 0 ; i < ssize(vCC) ; ++i){
|
|
vCC[i]->Close() ;
|
|
SfrCntr.AddCurve( Release(vCC[i])) ;
|
|
}
|
|
}
|
|
else {
|
|
// 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 ;
|
|
}
|
|
#if SAVETRIMLOOPS
|
|
SaveGeoObj( pTrimReg->Clone(), "D:\\Temp\\bezier\\import\\trim_loops.nge") ;
|
|
#endif
|
|
|
|
Vector3d vToOrig( -u0, -v0, 0) ;
|
|
pTrimReg->Translate( vToOrig) ;
|
|
#if SAVETRIMLOOPS
|
|
SaveGeoObj( pTrimReg->Clone(), "D:\\Temp\\bezier\\import\\trim_loops_moved.nge") ;
|
|
#endif
|
|
bool bRescaled = false ;
|
|
int nDegU, nDegV , nSpanU, nSpanV ;
|
|
bool bRat, bTrimmed ;
|
|
pSurfBez->GetInfo( nDegU, nDegV, nSpanU, nSpanV, bRat, bTrimmed) ;
|
|
|
|
if ( ! MakeUniform( pTrimReg, bRescaled, vU, vV, nDegU, nDegV, dScaleU, dScaleV, false)) {
|
|
LOG_ERROR( pGenLog, "Error making uniform the trim surface") ;
|
|
goto exit ;
|
|
}
|
|
|
|
if ( ! pSurfBez->SetTrimRegion(*pTrimReg)) {
|
|
// se l'intersezione è fallita 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 ;
|
|
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 ;
|
|
goto exit ;
|
|
}
|
|
}
|
|
}
|
|
PtrOwner<ISurfFlatRegion> pSfrTrimNew ( sfrTrim.GetSurf()) ;
|
|
if ( IsNull( pSfrTrimNew) || ! pSfrTrimNew->IsValid()) {
|
|
delete pTrimReg ;
|
|
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 ;
|
|
LOG_DBG_ERR( pGenLog, "Error intersecating parameter space and trim surface") ;
|
|
goto exit ;
|
|
}
|
|
}
|
|
delete pTrimReg ;
|
|
pSurfBez->RemoveCollapsedSpans() ;
|
|
}
|
|
|
|
exit :
|
|
if ( IsNull( pSurfBez) || ! pSurfBez->IsValid())
|
|
return nullptr ;
|
|
if ( ! bSameSense)
|
|
pSurfBez->Invert() ;
|
|
return Release( pSurfBez) ;
|
|
}
|
|
|
|
int nAssObj = 0 ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
solid_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, int nFlag)
|
|
{
|
|
MbSolid* pSolid = static_cast<MbSolid*>( 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, 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<ISurf> pSurf( ConvertFace( mbF)) ;
|
|
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
|
|
int nId = pGeomDB->AddGeoObj( GDB_ID_NULL, nLayId, Release( pSurf)) ;
|
|
vIds.push_back( nId) ;
|
|
}
|
|
}
|
|
|
|
// 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<MbProductInfo*>( 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)
|
|
{
|
|
MbPointFrame* pPointFr = static_cast<MbPointFrame*>( 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) ;
|
|
if ( ! bPointOk)
|
|
return false ;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
wireframe_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB)
|
|
{
|
|
MbWireFrame* pWireFr = static_cast<MbWireFrame*>( pIt) ;
|
|
if ( pWireFr == nullptr) {
|
|
LOG_ERROR( pGenLog, "Error : Point Frame pointer null") ;
|
|
return false ;
|
|
}
|
|
|
|
vector<MbCurve3D*> 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) ;
|
|
if ( ! bCurveOk)
|
|
return false ;
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
assembly_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, int nFlag)
|
|
{
|
|
MbAssembly* pAss = static_cast<MbAssembly*>( pIt) ;
|
|
if ( pAss == nullptr)
|
|
return false ;
|
|
|
|
// analizzo gl elementi dell'assembly
|
|
RPArray <MbItem> 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, nFlag) ;
|
|
else if ( (*it)->IsA() == st_Solid)
|
|
bSolOk = solid_handler( *it, nLayId, pGeomDB, nFlag) ;
|
|
else if ( (*it)->IsA() == st_Instance)
|
|
bSolOk = instance_handler( *it, nLayId, pGeomDB, nFlag) ;
|
|
else if ( (*it)->IsA() == st_PointFrame)
|
|
bSolOk = pointframe_handler( *it, nLayId, pGeomDB) ;
|
|
else if ( (*it)->IsA() == st_WireFrame)
|
|
bSolOk = wireframe_handler( *it, nLayId, pGeomDB) ;
|
|
else if ( (*it)->IsA() == st_SpaceInstance)
|
|
bSolOk = spaceinstance_handler( *it, nLayId, pGeomDB, nFlag) ;
|
|
else if ( (*it)->IsA() == st_Mesh)
|
|
bSolOk = mesh_handler( *it, nLayId, pGeomDB) ;
|
|
else if ( (*it)->IsA() == st_PlaneInstance)
|
|
bSolOk = planeinstance_handler( *it, nLayId, pGeomDB) ;
|
|
|
|
++ nAssObj ;
|
|
|
|
if ( ! bSolOk)
|
|
return false ;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
instance_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, int nFlag)
|
|
{
|
|
MbInstance* pInst = static_cast<MbInstance*>( pIt) ;
|
|
if ( pInst == nullptr)
|
|
return false ;
|
|
const MbItem* pInstItem = pInst->GetItem() ;
|
|
if ( pInstItem == nullptr)
|
|
return false ;
|
|
MbItem* pItem = static_cast<MbItem*>( &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, nFlag) ;
|
|
else if ( pInstItem->IsA() == st_Assembly)
|
|
return assembly_handler( pItem, nLayId, pGeomDB, nFlag) ;
|
|
else if ( (pInstItem)->IsA() == st_PointFrame)
|
|
return pointframe_handler( pItem, nLayId, pGeomDB) ;
|
|
else if ( (pInstItem)->IsA() == st_WireFrame)
|
|
return wireframe_handler( pItem, nLayId, pGeomDB) ;
|
|
else if ( (pInstItem)->IsA() == st_SpaceInstance)
|
|
return spaceinstance_handler( pItem, nLayId, pGeomDB, nFlag) ;
|
|
else if ( (pInstItem)->IsA() == st_Mesh)
|
|
return mesh_handler( pItem, nLayId, pGeomDB) ;
|
|
else if ( (pInstItem)->IsA() == st_PlaneInstance)
|
|
return planeinstance_handler( pItem, nLayId, pGeomDB) ;
|
|
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
planeinstance_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB)
|
|
{
|
|
MbPlaneInstance * pPlaneInstance = static_cast<MbPlaneInstance*> (pIt) ;
|
|
if ( pPlaneInstance == nullptr) {
|
|
LOG_ERROR( pGenLog, "Error : Plane Instance pointer null") ;
|
|
return false ;
|
|
}
|
|
vector<const MbPlaneItem *> 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<MbPolyline*> ( pPlaneIt) ;
|
|
if ( pPlaneInstance == nullptr) {
|
|
LOG_ERROR( pGenLog, "Error : Polyline pointer null") ;
|
|
return false ;
|
|
}
|
|
|
|
vector<MbCartPoint> points ;
|
|
pPolyline->GetPoints( points) ;
|
|
|
|
// elimino punti coincidenti rispetto alla tol fissata
|
|
for ( vector<MbCartPoint>::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) ;
|
|
}
|
|
|
|
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<MbLineSegment*>( 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) ;
|
|
}
|
|
|
|
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<MbNurbs*>( pPlaneIt) ;
|
|
if ( pNurbs == nullptr) {
|
|
LOG_ERROR( pGenLog, "Error : Curve Nurbs 2D pointer null") ;
|
|
return false ;
|
|
}
|
|
|
|
bool bNurbsOk = nurbs2D_handler( pNurbs, nLayId, pGeomDB) ;
|
|
if ( ! bNurbsOk)
|
|
return false ;
|
|
}
|
|
|
|
// Plane Generic Curve
|
|
else if ( pPlaneIt->Family() == pt_Curve) {
|
|
MbCurve * pCurve= static_cast<MbCurve*>( 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) ;
|
|
if ( ! bNurbsOk)
|
|
return false ;
|
|
}
|
|
|
|
} // ciclo sui planeitems
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
nurbs2D_handler( MbNurbs* pNurbs, int nLayId, IGeomDB* pGeomDB)
|
|
{
|
|
// 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<MbCartPoint> 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<double>( 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, int nFlag)
|
|
{
|
|
MbSpaceInstance* pSpaceInst = static_cast<MbSpaceInstance*>( 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<const MbPoint3D*>( pSpaceIt) ;
|
|
if ( pPoint == nullptr) {
|
|
LOG_ERROR( pGenLog, "Error : Point pointer null") ;
|
|
return false ;
|
|
}
|
|
return point_handler( pPoint, nLayId, pGeomDB) ;
|
|
}
|
|
// curve
|
|
else if ( pSpaceIt->Family() == st_Curve3D) {
|
|
const MbCurve3D* pCurve = static_cast<const MbCurve3D*>( pSpaceIt) ;
|
|
if ( pCurve == nullptr) {
|
|
LOG_ERROR( pGenLog, "Error : Curve pointer null") ;
|
|
return false ;
|
|
}
|
|
return curve_handler( pCurve, nLayId, pGeomDB) ;
|
|
}
|
|
// surface
|
|
else if ( pSpaceIt->Family() == st_Surface) {
|
|
const MbSurface* pSurface = static_cast<const MbSurface*>( pSpaceIt) ;
|
|
if ( pSurface == nullptr) {
|
|
LOG_ERROR( pGenLog, "Error : Surface pointer null") ;
|
|
return false ;
|
|
}
|
|
return surface_handler( pSurface, nLayId, pGeomDB, color, nFlag) ;
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
point_handler( const MbPoint3D* pPoint, int nLayId, IGeomDB* pGeomDB)
|
|
{
|
|
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<ICurve> pCrv ;
|
|
// Polyline
|
|
if ( pCurve.IsA() == st_Polyline3D) {
|
|
const MbPolyline3D* pPolyline = static_cast<const MbPolyline3D*>( &pCurve) ;
|
|
if ( pPolyline == nullptr)
|
|
return nullptr ;
|
|
|
|
vector< MbCartPoint3D > points ;
|
|
pPolyline->GetPoints( points) ;
|
|
|
|
// elimino punti coincidenti rispetto alla tol fissata
|
|
for ( vector<MbCartPoint3D>::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<const MbLineSegment3D*>( &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<const MbArc3D*>( &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<const MbNurbs3D*>( &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)
|
|
{
|
|
MbePlaneType mbCrvType = pCurve.IsA() ;
|
|
// Polyline
|
|
if ( mbCrvType == pt_Polyline) {
|
|
const MbPolyline* pPolyline = static_cast<const MbPolyline*>( &pCurve) ;
|
|
if ( pPolyline == nullptr)
|
|
return nullptr ;
|
|
|
|
vector< MbCartPoint> points ;
|
|
pPolyline->GetPoints( points) ;
|
|
|
|
// elimino punti coincidenti rispetto alla tol fissata
|
|
for ( vector<MbCartPoint>::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 ( mbCrvType == pt_LineSegment ){
|
|
const MbLineSegment * pSegment = static_cast<const MbLineSegment*>( &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 ;
|
|
}
|
|
|
|
PtrOwner<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 Release( pLine) ;
|
|
}
|
|
|
|
// Arc
|
|
else if ( mbCrvType == pt_Arc) {
|
|
const MbArc * pArc = static_cast<const MbArc*>( &pCurve) ;
|
|
if ( pArc == nullptr)
|
|
return nullptr ;
|
|
|
|
MbCartPoint start = pArc->GetLimitPoint( 1) ;
|
|
MbCartPoint end = pArc->GetLimitPoint( 2) ;
|
|
double dRad = pArc->GetRadius() ;
|
|
|
|
PtrOwner<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) ;
|
|
double dUStart ;
|
|
if ( pCurveArc->GetParamAtPoint( Point3d( start.x * dScale, start.y * dScale), dUStart, EPS_SMALL * dScale)) {
|
|
pCurveArc->ChangeStartPoint( dUStart) ;
|
|
Vector3d vtStartDir ; pCurveArc->GetStartDir( vtStartDir) ;
|
|
double dStart = 0 ;
|
|
MbDirection mbStartDir = pArc->Tangent( dStart) ;
|
|
Vector3d vtStartOrig( mbStartDir.ax, mbStartDir.ay) ;
|
|
bool bSameDir = vtStartDir * vtStartOrig > 0 ;
|
|
if ( ! bSameDir)
|
|
pCurveArc->Invert() ;
|
|
}
|
|
}
|
|
// 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 Release( pCurveArc) ;
|
|
}
|
|
|
|
// Nurbs
|
|
else if ( mbCrvType == pt_Nurbs) {
|
|
const MbNurbs * pNurbs = static_cast<const MbNurbs*>( &pCurve) ;
|
|
return ConvertNurbs( pNurbs, dScale, false) ;
|
|
}
|
|
|
|
// curve di contorno
|
|
else if ( mbCrvType == pt_Contour) {
|
|
double dJoinTol = 20 * EPS_SMALL * dScale ;
|
|
const MbContour* pContour = static_cast<const MbContour*>( &pCurve) ;
|
|
PtrOwner<ICurveComposite> pCC( CreateCurveComposite()) ;
|
|
for( int nS = 0 ; nS < int( pContour->GetSegmentsCount()) ; ++nS) {
|
|
const MbCurve* pSubCrv = pContour->GetSegment( nS) ;
|
|
Point3d ptDegen = P_INVALID ;
|
|
PtrOwner<ICurve> pCrvConv( ConvertCurve( *pSubCrv, ptDegen, dScale)) ;
|
|
#if SAVECONTOUR
|
|
vGeo.clear() ;
|
|
if ( pCC->IsValid())
|
|
vGeo.push_back( pCC->Clone()) ;
|
|
if ( pCrvConv->IsValid())
|
|
vGeo.push_back( pCrvConv->Clone()) ;
|
|
SaveGeoObj( vGeo, "D:\\Temp\\bezier\\import\\contour.nge") ;
|
|
#endif
|
|
|
|
if ( ptDegen.IsValid())
|
|
continue ;
|
|
Point3d ptEndCurr, ptStartNext ;
|
|
if ( pCC->IsValid()) {
|
|
if ( pCrvConv == nullptr) {
|
|
LOG_ERROR( pGenLog, "Error : failed conversion of contour") ;
|
|
return nullptr ;
|
|
}
|
|
pCC->GetEndPoint( ptEndCurr) ;
|
|
pCrvConv->GetStartPoint( ptStartNext) ;
|
|
if ( Dist( ptEndCurr, ptStartNext) < dJoinTol) {
|
|
if ( ! pCC->AddCurve( Release( pCrvConv), true, dJoinTol))
|
|
return nullptr ;
|
|
}
|
|
else {
|
|
PtrOwner<ICurveLine> pCL( CreateCurveLine()) ;
|
|
pCL->Set( ptEndCurr, ptStartNext) ;
|
|
if ( ! pCC->AddCurve( Release( pCL), true, dJoinTol) || ! pCC->AddCurve( Release( pCrvConv), true, dJoinTol))
|
|
return nullptr ;
|
|
}
|
|
}
|
|
else {
|
|
if ( ! pCC->AddCurve( Release( pCrvConv), true, dJoinTol))
|
|
return nullptr ;
|
|
}
|
|
}
|
|
return Release( pCC) ;
|
|
|
|
|
|
////////// conversione in NURBS
|
|
// MbNurbs* pNurbs = pCurve.NurbsCurve() ;
|
|
// PtrOwner<ICurve> pCrv( ConvertNurbs( pNurbs, dScale, true)) ;
|
|
//#if SAVECONTOUR
|
|
// vGeo.clear() ;
|
|
// vGeo.push_back( pCrv->Clone()) ;
|
|
// SaveGeoObj( vGeo, "D:\\Temp\\bezier\\import\\contour.nge") ;
|
|
//#endif
|
|
// return Release(pCrv) ;
|
|
}
|
|
|
|
// 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)
|
|
{
|
|
// Polyline
|
|
if ( pCurve->IsA() == st_Polyline3D) {
|
|
Point3d ptDegen = P_INVALID ;
|
|
ICurve* pCurveCompo = ConvertCurveToComposite( ConvertCurve3D( *pCurve, ptDegen)) ;
|
|
if ( pCurveCompo == nullptr) {
|
|
if ( ! ptDegen.IsValid()) {
|
|
LOG_ERROR( pGenLog, "Error : creating CurveComposite") ;
|
|
return false ;
|
|
}
|
|
LOG_ERROR( pGenLog, "Warning : curve degenerated in one point") ;
|
|
MbPoint3D mbCPt( ptDegen.x, ptDegen.y, ptDegen.z) ;
|
|
return point_handler( &mbCPt, nLayId, pGeomDB) ;
|
|
}
|
|
|
|
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) ;
|
|
}
|
|
|
|
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<const MbArc3D*>( 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) ;
|
|
}
|
|
|
|
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<const MbNurbs3D*>( pCurve) ;
|
|
if ( pNurbs == nullptr) {
|
|
LOG_ERROR( pGenLog, "Error : Nurbs pointer null") ;
|
|
return false ;
|
|
}
|
|
|
|
return nurbs3D_handler( pNurbs, nLayId, pGeomDB) ;
|
|
}
|
|
|
|
// 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) ;
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
ICurve*
|
|
ConvertNurbs( const MbNurbs* pNurbs, double dScale, bool bEraseSrc)
|
|
{
|
|
vector<MbCartPoint> 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<double>( 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<ICurve> pCrv( NurbsToBezierCurve( NurbsData)) ;
|
|
return Release(pCrv) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
ICurve*
|
|
ConvertNurbs3D( const MbNurbs3D* pNurbs, bool bEraseSrc)
|
|
{
|
|
vector<MbCartPoint3D> 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<double>( 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<ICurve> pCrv( NurbsToBezierCurve( NurbsData)) ;
|
|
if ( ! IsNull( pCrv))
|
|
return Release( pCrv) ;
|
|
|
|
// Non è riuscita la conversione, creo la composita dei punti di controllo
|
|
PtrOwner<ICurveComposite> 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)
|
|
{
|
|
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<double>( 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<double>( 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<ISurfBezier> pSurfBez( GetSurfBezier(NurbsToBezierSurface( sNurbsSurf))) ;
|
|
if ( IsNull( pSurfBez) || ! pSurfBez->IsValid())
|
|
return nullptr ;
|
|
|
|
return Release( pSurfBez) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
surface_handler( const MbSurface* pSurface, int nLayId, IGeomDB* pGeomDB, 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, false) ;
|
|
if ( ! bMeshOk)
|
|
return false ;
|
|
}
|
|
// conversione in superficie di Bezier
|
|
else if ( nFlag == 1) {
|
|
DBLVECTOR vU, vV ;
|
|
PtrOwner<ISurfBezier> 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 ;
|
|
} |