2804bf0b60
- correzioni varie a import/export 3dm.
691 lines
24 KiB
C++
691 lines
24 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2023
|
|
//----------------------------------------------------------------------------
|
|
// File : Export3dm.cpp Data : 21.09.23 Versione :
|
|
// Contenuto : Implementazione della classe per l'esportazione in formato 3dm.
|
|
//
|
|
//
|
|
//
|
|
// Modifiche : 21.09.23 DB Creazione modulo.
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
//--------------------------- Include ----------------------------------------
|
|
#include "stdafx.h"
|
|
#include "Export3dm.h"
|
|
#include "DllMain.h"
|
|
#include "/EgtDev/Include/EExDllMain.h"
|
|
#include "/EgtDev/Include/EGkGeomDB.h"
|
|
#include "/EgtDev/Include/EGkSurfFlatRegion.h"
|
|
#include "/EgtDev/Include/EGkSurfTriMesh.h"
|
|
#include "/EgtDev/Include/EGkSurfBezier.h"
|
|
#include "/EgtDev/Include/EGkCurveLine.h"
|
|
#include "/EgtDev/Include/EGkCurveArc.h"
|
|
#include "/EgtDev/Include/EGkCurveBezier.h"
|
|
#include "/EgtDev/Include/EGkCurveComposite.h"
|
|
#include "/EgtDev/Include/EGkGdbIterator.h"
|
|
#include "/EgtDev/Include/EGkGeoObjType.h"
|
|
#include "/EgtDev/Include/EGkGeoPoint3d.h"
|
|
#include "/EgtDev/Include/EGnStringUtils.h"
|
|
#include "/EgtDev/Include/SELkKeyProc.h"
|
|
#include "/EgtDev/Include/EgtKeyCodes.h"
|
|
#include "/EgtDev/Include/EgtStringConverter.h"
|
|
#include "/EgtDev/Include/EgtPointerOwner.h"
|
|
#include <fstream>
|
|
//#include "C:/EgtDev/opennurbs/opennurbs.h"
|
|
#include "/EgtDev/Extern/opennurbs/Include/opennurbs.h"
|
|
#include <map>
|
|
#include "/EgtDev/Include/EGnStringUtils.h"
|
|
|
|
using namespace std ;
|
|
class ON_Color ;
|
|
//class ON_UUID ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
IExport3dm*
|
|
CreateExport3dm( void)
|
|
{
|
|
// verifico la chiave e le opzioni
|
|
if ( ! VerifyKey( KEYOPT_EEX_EXPBASE))
|
|
return nullptr ;
|
|
// creo l'oggetto
|
|
return static_cast<IExport3dm*> ( new( nothrow) Export3dm) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Export3dm::SetOptions( int nFilter)
|
|
{
|
|
m_nFilter = nFilter ;
|
|
return true ;
|
|
}
|
|
|
|
static void Internal_SetExampleModelProperties(
|
|
ONX_Model& model,
|
|
const char* source_file_name
|
|
)
|
|
{
|
|
const bool bHaveFileName = ( nullptr != source_file_name && 0 != source_file_name[0]) ;
|
|
if ( !bHaveFileName)
|
|
source_file_name = "" ;
|
|
|
|
model.m_sStartSectionComments = "This file was created using openNURBS to convert an .nge into .3dm" ;
|
|
|
|
// set application information
|
|
const ON_wString wide_source_file_name( source_file_name) ;
|
|
|
|
model.m_properties.m_Application.m_application_URL = L"http://www.opennurbs.org" ;
|
|
|
|
// some notes
|
|
if ( /*bHaveFunctionName &&*/ bHaveFileName && 0)
|
|
{
|
|
model.m_properties.m_Notes.m_notes
|
|
= ON_wString::FormatToString(
|
|
L"This .3dm file was made with the OpenNURBS toolkit, converting the file %ls.",
|
|
static_cast<const wchar_t*>( wide_source_file_name)) ;
|
|
//model.m_properties.m_Notes.m_bVisible = model.m_properties.m_Notes.m_notes.IsNotEmpty() ;// questa opzione fa visualizzare le note all'apertura del file con Rhino
|
|
model.m_properties.m_Notes.m_bVisible = false ;
|
|
}
|
|
|
|
// set revision history information
|
|
model.m_properties.m_RevisionHistory.NewRevision() ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Export3dm::Export( IGeomDB* pGDB, int nId, const string& sFile)
|
|
{
|
|
Internal_SetExampleModelProperties( m_model, sFile.c_str()) ;
|
|
ON::Begin() ;
|
|
// verifico il DB geometrico
|
|
if ( pGDB == nullptr) {
|
|
LOG_ERROR( GetEExLogger(), "Export3dm : Error on GeomDB")
|
|
return false ;
|
|
}
|
|
|
|
// verifico l'Id dell'oggetto da esportare
|
|
if ( ! pGDB->ExistsObj( nId)) {
|
|
LOG_ERROR( GetEExLogger(), "Export3dm : Error on Id")
|
|
return false ;
|
|
}
|
|
|
|
//// file settings ( units, tolerances, views, ...)
|
|
//// OPTIONAL - change values from defaults
|
|
m_model.m_settings.m_ModelUnitsAndTolerances.m_unit_system = ON::LengthUnitSystem::Meters ;
|
|
m_model.m_settings.m_ModelUnitsAndTolerances.m_absolute_tolerance = 0.01 ;
|
|
m_model.m_settings.m_ModelUnitsAndTolerances.m_angle_tolerance = ON_PI/180.0 ;// radians
|
|
m_model.m_settings.m_ModelUnitsAndTolerances.m_relative_tolerance = 0.01 ;// 1%
|
|
|
|
// creo un iteratore
|
|
PtrOwner<IGdbIterator> pIter( CreateGdbIterator( pGDB)) ;
|
|
if ( IsNull( pIter))
|
|
return false ;
|
|
pIter->GoTo( nId) ;
|
|
// esporto l'oggetto e i suoi eventuali figli
|
|
bool bOk = ExportObject( *pIter, 0) ;
|
|
|
|
// stampo il file
|
|
int version = 7 ;
|
|
// errors printed to stdout
|
|
ON_TextLog error_log ;
|
|
// writes model to archive
|
|
bOk = bOk && m_model.Write( ConvertString( sFile).c_str(), version, &error_log) ;
|
|
|
|
ON::End() ;
|
|
|
|
return bOk ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Export3dm::ExportObject( const IGdbIterator& iIter, const int& nLayer)
|
|
{
|
|
switch ( iIter.GetGdbType()) {
|
|
case GDB_TY_GEO :
|
|
{
|
|
// recupero il riferimento globale dell'oggetto
|
|
Frame3d frFrame ;
|
|
if ( ! iIter.GetGlobFrame( frFrame))
|
|
return false ;
|
|
//recupero il colore dell'oggetto
|
|
Color cCol ;
|
|
iIter.GetMaterial( cCol) ;
|
|
// recupero il livello dell'oggetto
|
|
int nLev = GDB_LV_USER ;
|
|
iIter.GetCalcLevel( nLev) ;
|
|
// recupero il modo dell'oggetto
|
|
int nMode = GDB_MD_STD ;
|
|
iIter.GetCalcMode( nMode) ;
|
|
// recupero lo stato dell'oggetto
|
|
int nStat = GDB_ST_ON ;
|
|
iIter.GetCalcStatus( nStat) ;
|
|
// se il filtro lo abilita
|
|
if ( TestFilter( nLev, nMode, nStat)) {
|
|
// recupero eventuale nome
|
|
string sName ;
|
|
if ( ! iIter.GetName( sName))
|
|
sName = ToString( iIter.GetId()) ;
|
|
// emetto l'oggetto
|
|
switch ( iIter.GetGeoType()) {
|
|
case GEO_PNT3D: {
|
|
if ( ! ExportPnt( sName, iIter, frFrame, cCol, nLayer))
|
|
return false ;
|
|
break ;
|
|
}
|
|
case SRF_BEZIER: {
|
|
if ( ! ExportSrfBz( sName, iIter, frFrame, cCol, nLayer))
|
|
return false ;
|
|
break ;
|
|
}
|
|
case SRF_TRIMESH :
|
|
if ( ! ExportSTM( sName, iIter, frFrame, cCol, nLayer, nullptr))
|
|
return false ;
|
|
break ;
|
|
case SRF_FLATRGN :
|
|
if ( ! ExportSFR( sName, iIter, frFrame, cCol, nLayer))
|
|
return false ;
|
|
break ;
|
|
case CRV_ARC : {
|
|
if ( ! ExportCrvArc( sName, iIter, frFrame, cCol, nLayer))
|
|
return false ;
|
|
break ;
|
|
}
|
|
case CRV_BEZIER : {
|
|
if ( ! ExportCrvBezier( sName, iIter, frFrame, cCol, nLayer))
|
|
return false ;
|
|
break ;
|
|
}
|
|
case CRV_COMPO : {
|
|
if ( ! ExportCrvCompo( sName, iIter, frFrame, cCol, nLayer))
|
|
return false ;
|
|
break ;
|
|
}
|
|
case CRV_LINE : {
|
|
if ( ! ExportCrvLine( sName, iIter, frFrame, cCol, nLayer))
|
|
return false ;
|
|
break ;
|
|
}
|
|
default :
|
|
break ;
|
|
}
|
|
}
|
|
}
|
|
return true ;
|
|
case GDB_TY_GROUP: {
|
|
int nLayer = iIter.GetId() ;
|
|
if ( nLayer == 0) {
|
|
m_model.RemoveModelComponent( ON_ModelComponent::Type::Layer, m_model.LayerFromIndex( 0).ModelComponentId()) ;
|
|
return ScanGroup( iIter, nLayer) ;
|
|
}
|
|
// creo il layer e setto le proprietà
|
|
ON_Layer* layer = new ON_Layer() ;
|
|
std::string sLayName ;
|
|
iIter.GetName( sLayName) ;
|
|
if ( sLayName == "" ) {
|
|
sLayName = "Layer " + ToString( nLayer) ;
|
|
}
|
|
layer->SetName( ConvertString( sLayName).c_str()) ;
|
|
bool bDone = layer->SetIndex( nLayer) ;
|
|
ON_Color onCol( 0, 0, 0, 0) ; // black
|
|
layer->SetColor( onCol) ;
|
|
layer->SetVisible( true) ;
|
|
layer->SetLocked( false) ;
|
|
int nParent = iIter.GetParentId() ;
|
|
if ( nParent != 0 ) {
|
|
// setto il parent
|
|
const ON_Layer* onParLay = ON_Layer::Cast( m_model.LayerFromIndex( m_mLayer[nParent]).ModelComponent()) ;
|
|
layer->SetParentLayerId( onParLay->Id()) ;
|
|
}
|
|
// copio le info
|
|
STRVECTOR vStrInfo, vStrInfo_split ;
|
|
iIter.GetAllInfo( vStrInfo) ;
|
|
for ( string sInfo : vStrInfo) {
|
|
Tokenize( sInfo, "=", vStrInfo_split) ;
|
|
layer->SetUserString( ConvertString( vStrInfo_split[0]).c_str(), ConvertString( vStrInfo_split[1]).c_str()) ;
|
|
}
|
|
|
|
// aggiungo il layer
|
|
ON_ModelComponentReference mcr = m_model.AddManagedModelComponent( layer) ;
|
|
int nIndex = mcr.ModelComponentIndex() ;
|
|
m_mLayer.insert( pair< int, int>( nLayer, nIndex)) ;
|
|
|
|
// esploro il gruppo
|
|
return ScanGroup( iIter, nIndex) ;
|
|
}
|
|
default :
|
|
return false ;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Export3dm::AddObjectToModel( const IGdbIterator& iIter, ON_Object* onObject, const int& nLayer, const std::string& sName, const Color& cCol,
|
|
ON_3dmObjectAttributes* pOnAttr)
|
|
{
|
|
if ( pOnAttr == nullptr)
|
|
pOnAttr = new ON_3dmObjectAttributes() ;
|
|
pOnAttr->m_layer_index = nLayer ;
|
|
pOnAttr->m_name = ConvertString( sName).c_str() ;
|
|
pOnAttr->SetColorSource( ON::color_from_object) ;
|
|
//N.B. RHINO ha i valori di Alpha invertiti rispetto ai nostri, oltre che su una scala diversa! per loro 0 = opaco e 255 = trasparente
|
|
// per noi invece 0 = trasparente, 100 = opaco
|
|
ON_Color onCol( cCol.GetIntRed(), cCol.GetIntGreen(), cCol.GetIntBlue(), abs( int ( cCol.GetIntAlpha() * 2.55) - 255)) ;
|
|
pOnAttr->m_color = onCol ;
|
|
// copio le info
|
|
STRVECTOR vStrInfo, vStrInfo_split ;
|
|
iIter.GetAllInfo(vStrInfo) ;
|
|
for ( string sInfo : vStrInfo ) {
|
|
Tokenize(sInfo, "=", vStrInfo_split) ;
|
|
pOnAttr->SetUserString(ConvertString(vStrInfo_split[0]).c_str(), ConvertString(vStrInfo_split[1]).c_str()) ;
|
|
}
|
|
// aggiungo al modello
|
|
ON_ModelComponentReference mcr = m_model.AddManagedModelGeometryComponent( onObject, pOnAttr) ;
|
|
return ! mcr.IsEmpty() ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Export3dm::AddInfoToObject( const IGdbIterator& iIter, ON_Object* onObject)
|
|
{
|
|
// copio le info
|
|
STRVECTOR vStrInfo, vStrInfo_split ;
|
|
iIter.GetAllInfo( vStrInfo) ;
|
|
for ( string sInfo : vStrInfo) {
|
|
Tokenize( sInfo, "=", vStrInfo_split) ;
|
|
onObject->SetUserString( ConvertString( vStrInfo_split[0]).c_str(), ConvertString( vStrInfo_split[1]).c_str()) ;
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
std::wstring
|
|
Export3dm::ConvertString( const std::string& sName)
|
|
{
|
|
std::wstring ws = std::wstring( sName.begin(), sName.end()) ;
|
|
return ws ;
|
|
|
|
//wstring ws ;
|
|
//for( int i = 0 ; i < sName.length() ; ++i)
|
|
// ws += wchar_t( sName[i] ) ;
|
|
//return ws.c_str() ;
|
|
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
ON_3dPoint
|
|
Export3dm::ConvertPoint( const Point3d& pt)
|
|
{
|
|
ON_3dPoint onPt( pt.x,pt.y,pt.z) ;
|
|
return onPt ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
ON_3dVector
|
|
Export3dm::ConvertVector( const Vector3d& vt)
|
|
{
|
|
ON_3dVector onVt( vt.x,vt.y,vt.z) ;
|
|
return onVt ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Export3dm::TestFilter( int nLev, int nMode, int nStat)
|
|
{
|
|
if ( ( nLev == GDB_LV_USER && ( m_nFilter & EEXFLT_LEVUSER) == 0) ||
|
|
( nLev == GDB_LV_SYSTEM && ( m_nFilter & EEXFLT_LEVSYSTEM) == 0) ||
|
|
( nLev == GDB_LV_TEMP && ( m_nFilter & EEXFLT_LEVTEMP) == 0))
|
|
return false ;
|
|
if ( ( nMode == GDB_MD_STD && ( m_nFilter & EEXFLT_MODESTD) == 0) ||
|
|
( nMode == GDB_MD_LOCKED && ( m_nFilter & EEXFLT_MODELOCKED) == 0) ||
|
|
( nMode == GDB_MD_HIDDEN && ( m_nFilter & EEXFLT_MODEHIDDEN) == 0))
|
|
return false ;
|
|
if ( ( nStat == GDB_ST_OFF && ( m_nFilter & EEXFLT_STAOFF) == 0) ||
|
|
( nStat == GDB_ST_ON && ( m_nFilter & EEXFLT_STAON) == 0) ||
|
|
( nStat == GDB_ST_SEL && ( m_nFilter & EEXFLT_STASEL) == 0))
|
|
return false ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Export3dm::ExportPnt(const string& sName, const IGdbIterator& iIter, const Frame3d& frFrame, const Color& cCol, const int& nLayer)
|
|
{
|
|
// recupero l'oggetto geometrico
|
|
const IGeoObj* pGeoObj = iIter.GetGeoObj() ;
|
|
if ( pGeoObj == nullptr)
|
|
return false ;
|
|
// verifico oggetto
|
|
IGeoPoint3d* pGeoPnt = GetGeoPoint3d( pGeoObj->Clone()) ;
|
|
if ( pGeoPnt == nullptr)
|
|
return false ;
|
|
// lo porto nel riferimento globale
|
|
pGeoPnt->ToGlob( frFrame) ;
|
|
Point3d pt = pGeoPnt->GetPoint() ;
|
|
ON_Point* onPt = new ON_Point(ConvertPoint( pt)) ;
|
|
// aggiungo l'oggetto al modello
|
|
return AddObjectToModel( iIter, onPt, nLayer, sName, cCol) ; ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Export3dm::ExportSrfBz( const string& sName, const IGdbIterator& iIter, const Frame3d& frFrame, const Color& cCol, const int& nLayer)
|
|
{
|
|
|
|
//MANCA DA IMPLEMENTARE IL TRIM DELLE SUPERFICI!!/////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// recupero l'oggetto geometrico
|
|
const IGeoObj* pGeoObj = iIter.GetGeoObj() ;
|
|
if ( pGeoObj == nullptr)
|
|
return false ;
|
|
// verifico oggetto
|
|
ISurfBezier* pSrfBz = GetSurfBezier( pGeoObj->Clone()) ;
|
|
if ( pSrfBz == nullptr)
|
|
return false ;
|
|
// lo porto nel riferimento globale
|
|
pSrfBz->ToGlob( frFrame) ;
|
|
bool bOk = true ;
|
|
int nDegU, nDegV, nSpanU, nSpanV ;
|
|
bool bRat = false ;
|
|
bool bTrimmed = false ;
|
|
pSrfBz->GetInfo( nDegU, nDegV, nSpanU, nSpanV, bRat, bTrimmed) ;
|
|
int nCPU = nDegU * nSpanU + 1 ;
|
|
int nCPV = nDegV * nSpanV + 1 ;
|
|
ON_NurbsSurface* onNurbsSurf = new ON_NurbsSurface( 3, bRat, nDegU + 1, nDegV + 1, nCPU, nCPV) ;
|
|
for ( int u = 0 ; u < nCPU ; ++u) {
|
|
for ( int v = 0 ; v < nCPV ; ++v) {
|
|
Point3d ptCV = pSrfBz->GetControlPoint( u, v, &bOk) ;
|
|
if ( ! bRat) {
|
|
onNurbsSurf->SetCV( u, v, ConvertPoint( ptCV )) ;
|
|
}
|
|
else {
|
|
double dW = pSrfBz->GetControlWeight( u, v, &bOk) ;
|
|
onNurbsSurf->SetCV( u, v, ConvertPoint( ptCV * dW)) ;
|
|
onNurbsSurf->SetWeight( u, v, dW) ;
|
|
}
|
|
}
|
|
}
|
|
// imposto il vettore dei nodi in U
|
|
int nKnotCountU = nDegU + nCPU - 1 ;
|
|
int nLastKnotU = nCPU - nDegU ;
|
|
double dKnot = 0 ;
|
|
// per costruzione nKnotCount è un multiplo di nDegU
|
|
for ( int u = 0 ; u < int ( nKnotCountU / nDegU) ; ++u){
|
|
for ( int p = 0 ; p < nDegU ; ++p)
|
|
onNurbsSurf->SetKnot( 0, u * nDegU + p, dKnot) ;
|
|
++dKnot ;
|
|
}
|
|
|
|
// imposto il vettore dei nodi in V
|
|
int nKnotCountV = nDegV + nCPV - 1 ;
|
|
int nLastKnotV = nCPV - nDegV ;
|
|
dKnot = 0 ;
|
|
// per costruzione nKnotCount è un multiplo di nDegU
|
|
for ( int v = 0 ; v < int ( nKnotCountV / nDegV) ; ++v){
|
|
for ( int p = 0 ; p < nDegV ; ++p)
|
|
onNurbsSurf->SetKnot( 0, v * nDegV + p, dKnot) ;
|
|
++dKnot ;
|
|
}
|
|
// aggiungo l'oggetto al modello
|
|
return AddObjectToModel( iIter, onNurbsSurf, nLayer, sName, cCol) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Export3dm::ExportSFR( const string& sName, const IGdbIterator& iIter, const Frame3d& frFrame, const Color& cCol, const int& nLayer)
|
|
{
|
|
// recupero l'oggetto geometrico
|
|
const IGeoObj* pGeoObj = iIter.GetGeoObj() ;
|
|
if ( pGeoObj == nullptr)
|
|
return false ;
|
|
ISurfFlatRegion* pSrfFr = GetSurfFlatRegion( pGeoObj->Clone()) ;
|
|
if ( pSrfFr == nullptr)
|
|
return false ;
|
|
ExportSTM( sName, iIter, frFrame, cCol, nLayer, pSrfFr) ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Export3dm::ExportSTM( const string& sName, const IGdbIterator& iIter, const Frame3d& frFrame, const Color& cCol, const int& nLayer, ISurfFlatRegion* pSrfFr)
|
|
{
|
|
// recupero l'oggetto geometrico
|
|
const IGeoObj* pGeoObj = iIter.GetGeoObj() ;
|
|
if ( pGeoObj == nullptr)
|
|
return false ;
|
|
// verifico oggetto
|
|
const ISurfTriMesh* pSrfTm_ = nullptr ;
|
|
if ( pSrfFr == nullptr)
|
|
pSrfTm_ = GetSurfTriMesh( pGeoObj->Clone()) ;
|
|
else {
|
|
const ISurfFlatRegion* pSrfFr = GetSurfFlatRegion( pGeoObj) ;
|
|
pSrfTm_ = pSrfFr->GetAuxSurf() ;
|
|
}
|
|
|
|
if ( pSrfTm_ == nullptr)
|
|
return false ;
|
|
|
|
ISurfTriMesh* pSrfTm = pSrfTm_->Clone() ;
|
|
// lo porto nel frame globale
|
|
pSrfTm->ToGlob( frFrame) ;
|
|
|
|
int nVertices = pSrfTm->GetVertexCount() ;
|
|
int nTriangles = pSrfTm->GetTriangleCount() ;
|
|
ON_Mesh* onMesh = new ON_Mesh ;
|
|
for ( int v = 0 ; v < nVertices ; ++v ) {
|
|
Point3d pt ; pSrfTm->GetVertex( v, pt) ;
|
|
onMesh->SetVertex( v, ConvertPoint( pt)) ;
|
|
}
|
|
for ( int t = 0 ; t < nTriangles ; ++t ) {
|
|
int nIdVert[3] ; pSrfTm->GetTriangle( t, nIdVert) ;
|
|
onMesh->SetTriangle( t, nIdVert[0], nIdVert[1], nIdVert[2]) ;
|
|
}
|
|
// aggiungo l'oggetto al modello
|
|
return AddObjectToModel( iIter, onMesh, nLayer, sName, cCol) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
ON_ArcCurve*
|
|
Export3dm::ConvertCrvArc( ICurveArc* pCrvArc)
|
|
{
|
|
double dRad = pCrvArc->GetRadius() ;
|
|
Point3d ptCen ;
|
|
pCrvArc->GetCenterPoint( ptCen) ;
|
|
PtrOwner<ON_ArcCurve> onArcCrv( new ON_ArcCurve()) ;
|
|
if ( ! pCrvArc->IsACircle() ) {
|
|
Vector3d vtZ = pCrvArc->GetNormVersor() ;
|
|
Vector3d vtX, vtY ;
|
|
vtX = pCrvArc->GetStartVersor() ;
|
|
vtY = vtZ ^ vtX ;
|
|
double dAngDeg = pCrvArc->GetAngCenter() ;
|
|
ON_Plane onPlane( ConvertPoint( ptCen), ConvertVector( vtX), ConvertVector( vtY)) ;
|
|
onArcCrv.Set( new ON_ArcCurve( ON_Arc( onPlane, dRad, dAngDeg*DEGTORAD))) ;
|
|
}
|
|
else
|
|
onArcCrv.Set( new ON_ArcCurve ( ON_Circle( ConvertPoint( ptCen), dRad))) ;
|
|
return Release( onArcCrv) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Export3dm::ExportCrvArc( const string& sName, const IGdbIterator& iIter, const Frame3d& frFrame, const Color& cCol, const int& nLayer)
|
|
{
|
|
// recupero l'oggetto geometrico
|
|
const IGeoObj* pGeoObj = iIter.GetGeoObj() ;
|
|
if ( pGeoObj == nullptr)
|
|
return false ;
|
|
// verifico oggetto
|
|
ICurveArc* pCrvArc = GetCurveArc( pGeoObj->Clone()) ;
|
|
if ( pCrvArc == nullptr)
|
|
return false ;
|
|
// lo porto nel fram globale
|
|
pCrvArc->ToGlob( frFrame) ;
|
|
ON_ArcCurve* onArcCrv = ConvertCrvArc( pCrvArc) ;
|
|
if ( onArcCrv == nullptr)
|
|
return false ;
|
|
// aggiungo l'oggetto al modello
|
|
return AddObjectToModel( iIter, onArcCrv, nLayer, sName, cCol) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
ON_NurbsCurve*
|
|
Export3dm::ConvertCrvBezier( ICurveBezier* pCrvBz)
|
|
{
|
|
// creo l'oggetto da esportare
|
|
int nDeg = pCrvBz->GetDegree() ;
|
|
int nCV = nDeg + 1 ;
|
|
PtrOwner<ON_NurbsCurve> onNurbsCrv( new ON_NurbsCurve( 3,// dim
|
|
pCrvBz->IsRational(),// bRat
|
|
nDeg + 1, // order = deg + 1
|
|
nCV)) ;// numero di CP
|
|
// imposto i punti di controllo con gli eventuali pesi
|
|
if ( ! pCrvBz->IsRational()) {
|
|
bool bOk = true ;
|
|
for ( int i = 0 ; i < nCV ; ++i) {
|
|
ON_3dPoint onPt = ConvertPoint( pCrvBz->GetControlPoint( i, &bOk)) ;
|
|
onNurbsCrv->SetCV( i, onPt) ;
|
|
}
|
|
}
|
|
else {
|
|
bool bOk = true ;
|
|
for ( int i = 0 ; i < nCV ; ++i) {
|
|
ON_3dPoint onPt = ConvertPoint( pCrvBz->GetControlPoint( i, &bOk)) ;
|
|
double dWeight = pCrvBz->GetControlWeight( i, &bOk) ;
|
|
onNurbsCrv->SetCV( i, onPt * dWeight) ;
|
|
onNurbsCrv->SetWeight( i, dWeight) ;
|
|
}
|
|
}
|
|
// imposto il vettore dei nodi
|
|
int nKnotCount = nDeg + nCV - 1 ;
|
|
double dKnot = 0 ;
|
|
for ( int u = 0 ; u < int ( nKnotCount / nDeg) ; ++u){
|
|
for ( int p = 0 ; p < nDeg ; ++p)
|
|
onNurbsCrv->SetKnot( u * nDeg + p, dKnot) ;
|
|
++dKnot ;
|
|
}
|
|
|
|
return Release( onNurbsCrv) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Export3dm::ExportCrvBezier( const string& sName, const IGdbIterator& iIter, const Frame3d& frFrame, const Color& cCol, const int& nLayer)
|
|
{
|
|
// recupero l'oggetto geometrico
|
|
const IGeoObj* pGeoObj = iIter.GetGeoObj() ;
|
|
if ( pGeoObj == nullptr)
|
|
return false ;
|
|
// verifico oggetto
|
|
ICurveBezier* pCrvBz = GetCurveBezier( pGeoObj->Clone()) ;
|
|
if ( pCrvBz == nullptr)
|
|
return false ;
|
|
// lo porto nel riferimento globale
|
|
pCrvBz->ToGlob( frFrame) ;
|
|
ON_NurbsCurve* onNurbsCrv = ConvertCrvBezier( pCrvBz) ;
|
|
if ( onNurbsCrv == nullptr)
|
|
return false ;
|
|
// aggiungo l'oggetto al modello
|
|
return AddObjectToModel( iIter, onNurbsCrv, nLayer, sName, cCol) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Export3dm::ExportCrvCompo( const string& sName, const IGdbIterator& iIter, const Frame3d& frFrame, const Color& cCol, const int& nLayer)
|
|
{
|
|
// recupero l'oggetto geometrico
|
|
const IGeoObj* pGeoObj = iIter.GetGeoObj() ;
|
|
if ( pGeoObj == nullptr)
|
|
return false ;
|
|
// verifico oggetto
|
|
ICurveComposite* pCrvCompo = GetCurveComposite( pGeoObj->Clone()) ;
|
|
if ( pCrvCompo == nullptr)
|
|
return false ;
|
|
// lo porto nel riferimento globale
|
|
pCrvCompo->ToGlob( frFrame) ;
|
|
ON_PolyCurve* onPolyCrv = new ON_PolyCurve ;
|
|
for ( const ICurve* pCrv = pCrvCompo->GetFirstCurve() ;
|
|
pCrv != nullptr ;
|
|
pCrv = pCrvCompo->GetNextCurve()) {
|
|
GeoObjType type = pCrv->GetType() ;
|
|
switch ( type) {
|
|
case CRV_LINE : {
|
|
ICurveLine* pCrvL = GetCurveLine( pCrv->Clone()) ;
|
|
ON_LineCurve* onLine = ConvertCrvLine( pCrvL) ;
|
|
if ( onLine == nullptr)
|
|
return false ;
|
|
onPolyCrv->Append( onLine) ;
|
|
break ;
|
|
}
|
|
case CRV_ARC : {
|
|
ICurveArc* pCrvArc = GetCurveArc( pCrv->Clone()) ;
|
|
ON_ArcCurve* onArcCrv = ConvertCrvArc( pCrvArc) ;
|
|
if ( onArcCrv == nullptr)
|
|
return false ;
|
|
onPolyCrv->Append( onArcCrv) ;
|
|
break ;
|
|
}
|
|
case CRV_BEZIER : {
|
|
ICurveBezier* pCrvBz = GetCurveBezier( pCrv->Clone()) ;
|
|
ON_NurbsCurve* onNurbsCrv = ConvertCrvBezier( pCrvBz) ;
|
|
if ( onNurbsCrv == nullptr)
|
|
return false ;
|
|
onPolyCrv->Append( onNurbsCrv) ;
|
|
break ;
|
|
}
|
|
default : break ;
|
|
}
|
|
}
|
|
// aggiungo l'oggetto al modello
|
|
return AddObjectToModel( iIter, onPolyCrv, nLayer, sName, cCol) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
ON_LineCurve*
|
|
Export3dm::ConvertCrvLine( ICurveLine* pCrvL)
|
|
{
|
|
Point3d ptStart, ptEnd ;
|
|
pCrvL->GetStartPoint ( ptStart) ;
|
|
pCrvL->GetEndPoint ( ptEnd) ;
|
|
PtrOwner<ON_LineCurve> onCrvLine( new ON_LineCurve( ON_Line( ConvertPoint( ptStart), ConvertPoint( ptEnd)))) ;
|
|
return Release( onCrvLine) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Export3dm::ExportCrvLine( const string& sName, const IGdbIterator& iIter, const Frame3d& frFrame, const Color& cCol, const int& nLayer)
|
|
{
|
|
// recupero l'oggetto geometrico
|
|
const IGeoObj* pGeoObj = iIter.GetGeoObj() ;
|
|
if ( pGeoObj == nullptr)
|
|
return false ;
|
|
// verifico oggetto
|
|
ICurveLine* pCrvL = GetCurveLine( pGeoObj->Clone()) ;
|
|
if ( pCrvL == nullptr)
|
|
return false ;
|
|
// lo porto nel frame globale
|
|
pCrvL->ToGlob( frFrame) ;
|
|
ON_LineCurve* onCrvLine = ConvertCrvLine( pCrvL) ;
|
|
// aggiungo l'oggetto al modello
|
|
return AddObjectToModel( iIter, onCrvLine, nLayer, sName, cCol) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Export3dm::ScanGroup( const IGdbIterator& iIter, const int& nLayer)
|
|
{
|
|
// creo un iteratore
|
|
PtrOwner<IGdbIterator> pIter( CreateGdbIterator( iIter.GetGDB())) ;
|
|
if ( IsNull( pIter))
|
|
return false ;
|
|
// scandisco il gruppo
|
|
bool bOk = true ;
|
|
for ( bool bNext = pIter->GoToFirstInGroup( iIter) ;
|
|
bNext ;
|
|
bNext = pIter->GoToNext()) {
|
|
if ( ! ExportObject( *pIter, nLayer))
|
|
bOk = false ;
|
|
}
|
|
|
|
return bOk ;
|
|
}
|