Files
EgtConverter/EgtConverter.cpp
T
DarioS 4e22cf9590 EgtConverter :
- eliminate dipendenze inutili.
2023-01-04 09:10:39 +01:00

1091 lines
40 KiB
C++

//----------------------------------------------------------------------------
// EgalTech 2020-2023
//----------------------------------------------------------------------------
// File : EgtConverter.cpp Data : 04.01.23 Versione : 2.5a1
// Contenuto : Importatore da formati avanzati tramite C3d.
//
//
//
// Modifiche : 12.09.20 DS Creazione modulo.
// 20.11.20 SP Trasformazione diretta in nge.
//
//----------------------------------------------------------------------------
//--------------------------- Include ----------------------------------------
#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/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 "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/EGnStringUtils.h"
#include "/EgtDev/Include/EGnFileUtils.h"
#include "/EgtDev/Include/EgtStringConverter.h"
#include "/EgtDev/Include/EgtLogger.h"
#include "/EgtDev/Include/EgtPointerOwner.h"
#include "/EgtDev/Include/SELkLockId.h"
using namespace c3d ;
using namespace std ;
using namespace egtlogger ;
//--------------------------- Costanti ----------------------------------------
#if defined( _WIN64)
#if defined( _DEBUG)
const char* EXE_STR = "EgtConverterD64.exe ver 2.5a1" ;
#else
const char* EXE_STR = "EgtConverterR64.exe ver 2.5a1" ;
#endif
#elif defined( _WIN32)
#if defined( _DEBUG)
const char* EXE_STR = "EgtConverterD32.exe ver 2.5a1" ;
#else
const char* EXE_STR = "EgtConverterR32.exe ver 2.5a1" ;
#endif
#endif
const double dTol = 2 * EPS_SMALL ;
const double TOL_LIM_S = 0.101 ;
const double TOL_LIM_B = 1.001 ;
//------------------------- Prototipi locali ---------------------------------
uint32 GetSolidColor( MbSolid* pSolid) ;
bool CreateMeshData( MbStepData& stepData, MbFormNote& note) ;
bool point_handler( const MbPoint3D* pPoint, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog) ;
bool curve_handler( const MbCurve3D* pCurve, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog) ;
bool surface_handler( const MbSurface* pSurface, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog, uint32 color) ;
bool nurbs2D_handler( MbNurbs* pNurbs, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog) ;
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) ;
bool solid_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog) ;
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) ;
bool planeinstance_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog) ;
bool assembly_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog) ;
bool instance_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog) ;
//------------------------- Variabili locali ---------------------------------
static double s_dLinToler = 0.1 ;
//----------------------------------------------------------------------------
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) ;
// Creo il logger
Logger* pGenLog = new( nothrow) Logger( ( nDebugLev > 0 ? LL_DEBUG : LL_INFO), "EgtConverter") ;
if ( pGenLog == nullptr) {
cout << "Error creating logger" ;
return 4 ;
}
// assegno il file
string sLogFile = ChangeFileExtension( sExpName, "txt") ;
pGenLog->AddOutputStream( new( nothrow) ofstream( sLogFile), true) ;
// Imposto la chiave di protezione alle librerie di base
SetEGkKeyType( KEY_LOCK_TYPE_HW) ;
SetEGkKey( sKeyCode) ;
// Imposto livello di debug alle librerie di base
SetEGkDebugLev( nDebugLev) ;
// Imposto logger
SetEGkLogger( pGenLog) ;
// Dichiaro inizio programma
LOG_DATETIME( pGenLog, " Init")
// messaggio dall'applicazione
LOG_INFO( pGenLog, EXE_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())
// Activation of the geometric kernel C3D.
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) {
LOG_ERROR( pGenLog, "Error activating Modeler or Converter") ;
return 9 ;
}
// File import
LOG_INFO( pGenLog, ( "File to import : " + sInpName).c_str())
MbModel geomModel ;
int nReadRes = ImportFromFile( geomModel, C3DToPathstring( swInpName)) ;
if ( nReadRes != cnv_Success) {
if ( nReadRes == cnv_FileOpenError)
LOG_ERROR( pGenLog, "Error opening input file")
else if ( nReadRes == cnv_UnknownExtension)
LOG_ERROR( pGenLog, "Unkwown input file type")
else if ( nReadRes == cnv_NotEnoughMemory)
LOG_ERROR( pGenLog, "Not enough memory")
else
LOG_ERROR( pGenLog, "Internal error during read")
return 11 ;
}
// Creo GeomDB
PtrOwner<IGeomDB> pGeomDB( CreateGeomDB()) ;
if ( IsNull( pGeomDB)){
LOG_ERROR( 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()) ;
// 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) ;
else if ( ( *it )->IsA() == st_Solid )
bSolOk = solid_handler( *it, nLayId, pGeomDB, pGenLog) ;
else if ( ( *it)->IsA() == st_Instance)
bSolOk = instance_handler(*it, nLayId, pGeomDB, pGenLog) ;
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) ;
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)
return 14 ;
}
// Salvo il progetto
bool bOk = pGeomDB->Save( GDB_ID_ROOT, sExpName, GDB_SV_BIN) ;
if ( ! bOk) {
LOG_ERROR( pGenLog, "Error saving GeomDB") ;
return 13 ;
}
else
LOG_INFO( pGenLog, "Conversion finished with success")
// Free of the geometric kernel C3D
FreeMathModulesChecker() ;
LOG_DATETIME( pGenLog, " Exit")
delete pGenLog ;
return 0 ;
}
//----------------------------------------------------------------------------
bool
mesh_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog, 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 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 ;
}
//----------------------------------------------------------------------------
bool
solid_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog)
{
MbSolid* pSolid = static_cast<MbSolid*>( pIt) ;
if ( pSolid == nullptr) {
LOG_ERROR( pGenLog, "Error : Solid pointer null") ;
return false ;
}
// Creazione mesh
MbStepData stepdata ;
MbFormNote note ;
CreateMeshData( stepdata, note) ;
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 dal mesh_handler
// 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())) ;
}
}
// Gestione colori
uint32 col=GetSolidColor( pSolid) ;
// 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<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, pGenLog) ;
if ( ! bPointOk)
return false ;
}
return true;
}
//----------------------------------------------------------------------------
bool
wireframe_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog)
{
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, pGenLog) ;
if ( ! bCurveOk)
return false ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
assembly_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog)
{
MbAssembly* pAss = static_cast<MbAssembly*>( pIt) ;
if ( pAss == nullptr)
return false ;
// analizzo gl elementi dell'assembly
RPArray <MbItem> assItems ;
pAss->GetItems( assItems) ;
for ( MbItem** it = assItems.begin() ; it != assItems.end() ; it ++) {
bool bSolOk = true ;
if ( (*it)->IsA() == st_Assembly)
bSolOk = assembly_handler( *it, nLayId, pGeomDB, pGenLog) ;
else if ( (*it)->IsA() == st_Solid)
bSolOk = solid_handler( *it, nLayId, pGeomDB, pGenLog) ;
else if ( (*it)->IsA() == st_Instance)
bSolOk = instance_handler( *it, nLayId, pGeomDB, pGenLog) ;
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) ;
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)
return false ;
}
return true;
}
//----------------------------------------------------------------------------
bool
instance_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog)
{
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, pGenLog) ;
else if ( pInstItem->IsA() == st_Assembly)
return assembly_handler( pItem, nLayId, pGeomDB, pGenLog) ;
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) ;
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<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) < dTol && abs( it->y - ( it-1)->y) < dTol) {
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 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) < dTol && abs( start.y - end.y) < dTol ) {
LOG_ERROR( pGenLog, "Warining : curve 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") ;
return false ;
}
bool bLineOk = pLine->Set( Point3d( start.x, start.y), Point3d( end.x, end.y)) ;
if ( ! bLineOk) {
LOG_ERROR( pGenLog, "Error : creating CurveLine") ;
return false ;
}
int nId = pGeomDB->AddGeoObj( GDB_ID_NULL, nLayId, pLine) ;
if ( nId == GDB_ID_NULL) {
LOG_ERROR( pGenLog, "Error : adding object 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 : Nurbs 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<MbCurve*>( pPlaneIt) ;
if ( pCurve == nullptr) {
LOG_ERROR( pGenLog, "Error : Curve pointer null") ;
return false ;
}
// Approssimo la curva con Nurbs
MbNurbs* pNurbs = pCurve->NurbsCurve() ;
if ( pNurbs == nullptr) {
LOG_ERROR( pGenLog, "Error : converting the curve 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<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 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 to GeomDB") ;
return false ;
}
pGeomDB->SetMaterial( nId, Color( 0, 0, 0)) ;
return true ;
}
//----------------------------------------------------------------------------
bool
spaceinstance_handler ( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog)
{
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, pGenLog) ;
}
// 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, pGenLog) ;
}
// 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, pGenLog, color) ;
}
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 to GeomDB") ;
return false ;
}
pGeomDB->SetMaterial( nId, Color( 0, 0, 0)) ;
return true ;
}
//----------------------------------------------------------------------------
bool
curve_handler( const MbCurve3D* pCurve, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog)
{
// Polyline
if ( pCurve->IsA() == st_Polyline3D) {
const MbPolyline3D * pPolyline = static_cast<const MbPolyline3D*>( pCurve) ;
if ( pPolyline == nullptr) {
LOG_ERROR( pGenLog, "Error : Polyline pointer null") ;
return false ;
}
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) < dTol && abs( it->y - ( it-1)->y) < dTol && abs( it->z - ( it-1)->z) < dTol) {
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") ;
MbPoint3D ptP( points[0]) ;
return point_handler( &ptP, 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, points[0].z)) ; // 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, points[i].z), false) ;
if ( ! bAddLineOk) {
LOG_ERROR( pGenLog, "Error : creating CurveComposite") ;
return false ;
}
}
bool bAddLineOk = pCurveCompo->AddLine( Point3d( points.back().x, points.back().y, points.back().z), 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 to GeomDB") ;
return false ;
}
pGeomDB->SetMaterial( nId, Color( 0, 0, 0)) ;
}
// LineSegment
else if ( pCurve->IsA() == st_LineSegment3D ){
const MbLineSegment3D * pSegment = static_cast<const MbLineSegment3D*>( pCurve) ;
if ( pSegment == nullptr) {
LOG_ERROR( pGenLog, "Error : Segment pointer null") ;
return false ;
}
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) < dTol && abs( start.y - end.y) < dTol && abs( start.z - end.z) < dTol) {
LOG_ERROR( pGenLog, "Warining : curve degenerated in one point") ;
MbPoint3D ptP( start) ;
return point_handler( &ptP, nLayId, pGeomDB, pGenLog) ;
}
ICurveLine* pLine = CreateCurveLine() ;
if ( pLine == nullptr) {
LOG_ERROR( pGenLog, "Error : creating CurveLine") ;
return false ;
}
bool bLineOk = pLine->Set( Point3d( start.x, start.y, start.z), Point3d( end.x, end.y, end.z)) ;
if ( ! bLineOk) {
LOG_ERROR( pGenLog, "Error : creating CurveLine") ;
return false ;
}
int nId = pGeomDB->AddGeoObj( GDB_ID_NULL, nLayId, pLine) ;
if ( nId == GDB_ID_NULL) {
LOG_ERROR( pGenLog, "Error : adding object 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 ;
}
MbCartPoint3D start = pArc->GetLimitPoint( 1) ;
MbCartPoint3D end = pArc->GetLimitPoint( 2) ;
MbCartPoint3D mid ;
double t = pArc->GetTMid() ;
pArc->PointOn( t, mid) ;
double radius = pArc->GetRadius() ;
ICurveArc* pCurveArc = CreateCurveArc() ;
if ( pCurveArc == nullptr) {
LOG_ERROR( pGenLog, "Error : creating CurveArc") ;
return false ;
}
bool bArcOk = false ;
if ( abs( start.x - end.x) < dTol && abs( start.y - end.y) < dTol && abs( start.z - end.z) < dTol && radius != 0) { //circonferenza
MbAxis3D axis ;
bool bAxisOk = pArc->GetCircleAxis( axis) ;
if ( ! bAxisOk ) {
LOG_ERROR( pGenLog, "Error : no circle axis") ;
return false ;
}
bArcOk = pCurveArc->Set( Point3d( axis.GetOrigin().x, axis.GetOrigin().y, axis.GetOrigin().z),
Vector3d( axis.GetAxisZ().x, axis.GetAxisZ().y, axis.GetAxisZ().z), radius) ;
}
else // arco generico
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) {
LOG_ERROR( pGenLog, "Error : creating CurveArc") ;
return false ;
}
int nId = pGeomDB->AddGeoObj( GDB_ID_NULL, nLayId, pCurveArc) ;
if ( nId == GDB_ID_NULL) {
LOG_ERROR( pGenLog, "Error : adding object 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, 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 ;
}
//----------------------------------------------------------------------------
bool
nurbs3D_handler( const MbNurbs3D* 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<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 ;
ICurve* pBezierCurve = NurbsToBezierCurve( NurbsData) ;
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 to GeomDB") ;
return false ;
}
pGeomDB->SetMaterial( nId, Color( 0, 0, 0)) ;
return true ;
}
//----------------------------------------------------------------------------
bool
surface_handler( const MbSurface* pSurface, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog, uint32 color)
{
// 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 ;
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 ;
}