e5f28f8de1
- agg. importazione DXF di SOLID, ELLIPSE e SPLINE (solo poligono di controllo) - migliorie e correzioni varie.
1614 lines
48 KiB
C++
1614 lines
48 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2014-2014
|
|
//----------------------------------------------------------------------------
|
|
// File : ImportDxfEnts.cpp Data : 11.05.14 Versione : 1.5e2
|
|
// Contenuto : Implementazione di ImportDxf : gestione delle entità.
|
|
//
|
|
//
|
|
//
|
|
// Modifiche : 17.04.14 DS Creazione modulo.
|
|
// 11.05.14 DS Agg. lettura SOLID.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
//--------------------------- Include ----------------------------------------
|
|
#include "stdafx.h"
|
|
#include "ImportDxf.h"
|
|
#include "DxfColors.h"
|
|
#include "DxfConst.h"
|
|
#include "DllMain.h"
|
|
#include "/EgtDev/Include/EGnStringUtils.h"
|
|
#include "/EgtDev/Include/EgtPointerOwner.h"
|
|
#include "/EgtDev/Include/EgkGeoPoint3d.h"
|
|
#include "/EgtDev/Include/EgkCurveLine.h"
|
|
#include "/EgtDev/Include/EgkCurveArc.h"
|
|
#include "/EgtDev/Include/EgkCurveComposite.h"
|
|
#include "/EgtDev/Include/EgkSurfTriMesh.h"
|
|
|
|
using namespace std ;
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportDxf::ReadEntities( bool& bFileEnd)
|
|
{
|
|
// ciclo di lettura
|
|
bool bOk = true ;
|
|
bool bSectEnd = false ;
|
|
string sEntName ;
|
|
do {
|
|
// leggo intestazione entità, per avere il tipo
|
|
bool bOkLoc = GetEntityName( sEntName, bSectEnd, bFileEnd) ;
|
|
if ( bOkLoc && ! bSectEnd) {
|
|
// se faccia 3d
|
|
if ( sEntName == "3DFACE") {
|
|
if ( ! Read3dFace( bFileEnd))
|
|
bOkLoc = false ;
|
|
}
|
|
// se arco
|
|
else if ( sEntName == "ARC") {
|
|
if ( ! ReadArc( bFileEnd))
|
|
bOkLoc = false ;
|
|
}
|
|
// se cerchio
|
|
else if ( sEntName == "CIRCLE") {
|
|
if ( ! ReadCircle( bFileEnd))
|
|
bOkLoc = false ;
|
|
}
|
|
// se ellisse
|
|
else if ( sEntName == "ELLIPSE") {
|
|
if ( ! ReadEllipse( bFileEnd))
|
|
bOkLoc = false ;
|
|
}
|
|
// se linea
|
|
else if ( sEntName == "LINE" || sEntName == "3DLINE") {
|
|
if ( ! ReadLine( bFileEnd))
|
|
bOkLoc = false ;
|
|
}
|
|
// se LwPolyLine
|
|
else if ( sEntName == "LWPOLYLINE") {
|
|
if ( ! ReadLwPolyLine( bFileEnd))
|
|
bOkLoc = false ;
|
|
}
|
|
// se punto
|
|
else if ( sEntName == "POINT") {
|
|
if ( ! ReadPoint( bFileEnd))
|
|
bOkLoc = false ;
|
|
}
|
|
// se PolyLine
|
|
else if ( sEntName == "POLYLINE") {
|
|
if ( ! ReadPolyLine( bFileEnd))
|
|
bOkLoc = false ;
|
|
}
|
|
// se 2D filled outline
|
|
else if ( sEntName == "SOLID") {
|
|
if ( ! ReadSolid( bFileEnd))
|
|
bOkLoc = false ;
|
|
}
|
|
// se Spline
|
|
else if ( sEntName == "SPLINE") {
|
|
if ( ! ReadSpline( bFileEnd))
|
|
bOkLoc = false ;
|
|
}
|
|
// altrimenti
|
|
else {
|
|
string sOut = "ImportDxf : Skip entity " + sEntName +
|
|
" at line " + ToString( m_theScanner.GetCurrLineNbr()) ;
|
|
LOG_INFO( GetEExLogger(), sOut.c_str())
|
|
if ( ! SkipEntity( bFileEnd))
|
|
bOkLoc = false ;
|
|
}
|
|
}
|
|
// gestisco eventuale errore
|
|
if ( ! bOkLoc) {
|
|
bOk = false ;
|
|
string sOut = "ImportDxf : Error on line " + ToString( m_theScanner.GetCurrLineNbr()) ;
|
|
LOG_ERROR( GetEExLogger(), sOut.c_str())
|
|
}
|
|
} while ( ! bSectEnd) ;
|
|
|
|
return bOk ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportDxf::GetEntityName( string& sEntName, bool& bSectEnd, bool& bFileEnd)
|
|
{
|
|
// inizializzo
|
|
sEntName.clear() ;
|
|
bSectEnd = false ;
|
|
bFileEnd = false ;
|
|
// leggo il primo Item (mi aspetto 0 -> NomeEntità)
|
|
int nCode = ReadNextItem() ;
|
|
if ( nCode == CODE_NULL) {
|
|
bSectEnd = true ;
|
|
bFileEnd = true ;
|
|
return false ;
|
|
}
|
|
if ( nCode != 0)
|
|
return false ;
|
|
if ( m_sCurrItem == "SECTION") {
|
|
UngetItem() ;
|
|
bSectEnd = true ;
|
|
return true ;
|
|
}
|
|
if ( m_sCurrItem == "ENDSEC") {
|
|
bSectEnd = true ;
|
|
return true ;
|
|
}
|
|
if ( m_sCurrItem == "EOF") {
|
|
bSectEnd = true ;
|
|
bFileEnd = true ;
|
|
return true ;
|
|
}
|
|
sEntName = m_sCurrItem ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportDxf::SkipEntity( bool& bFileEnd)
|
|
{
|
|
bFileEnd = false ;
|
|
int nCode = CODE_NULL ;
|
|
do {
|
|
// leggo un Item ( cerco 0 -> qualcosa)
|
|
nCode = ReadNextItem() ;
|
|
if ( nCode == CODE_NULL) {
|
|
bFileEnd = true ;
|
|
return false ;
|
|
}
|
|
} while ( nCode != 0) ;
|
|
UngetItem() ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportDxf::ColorFromACI( int nColor, Color& cCol)
|
|
{
|
|
// controllo i limiti dell'indice di colore ACI
|
|
if ( nColor < 1 || nColor > 255)
|
|
return false ;
|
|
// assegno il colore
|
|
cCol.Set( DxfColors[nColor][0], DxfColors[nColor][1], DxfColors[nColor][2]) ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportDxf::Read3dFace( bool& bFileEnd)
|
|
{
|
|
Point3d ptP0 ;
|
|
Point3d ptP1 ;
|
|
Point3d ptP2 ;
|
|
Point3d ptP3 ;
|
|
string sLayer ;
|
|
int nColor = COL_BYLAYER ;
|
|
// ciclo di lettura degli item di 3dFace
|
|
bFileEnd = false ;
|
|
int nCode = CODE_NULL ;
|
|
do {
|
|
// leggo un Item
|
|
nCode = ReadNextItem() ;
|
|
if ( nCode == CODE_NULL) {
|
|
bFileEnd = true ;
|
|
return false ;
|
|
}
|
|
// eventuale gestione
|
|
switch ( nCode) {
|
|
case 8 :
|
|
sLayer = m_sCurrItem ;
|
|
break ;
|
|
case 10 :
|
|
FromString( m_sCurrItem, ptP0.x) ;
|
|
break ;
|
|
case 20 :
|
|
FromString( m_sCurrItem, ptP0.y) ;
|
|
break ;
|
|
case 30 :
|
|
FromString( m_sCurrItem, ptP0.z) ;
|
|
break ;
|
|
case 11 :
|
|
FromString( m_sCurrItem, ptP1.x) ;
|
|
break ;
|
|
case 21 :
|
|
FromString( m_sCurrItem, ptP1.y) ;
|
|
break ;
|
|
case 31 :
|
|
FromString( m_sCurrItem, ptP1.z) ;
|
|
break ;
|
|
case 12 :
|
|
FromString( m_sCurrItem, ptP2.x) ;
|
|
break ;
|
|
case 22 :
|
|
FromString( m_sCurrItem, ptP2.y) ;
|
|
break ;
|
|
case 32 :
|
|
FromString( m_sCurrItem, ptP2.z) ;
|
|
break ;
|
|
case 13 :
|
|
FromString( m_sCurrItem, ptP3.x) ;
|
|
break ;
|
|
case 23 :
|
|
FromString( m_sCurrItem, ptP3.y) ;
|
|
break ;
|
|
case 33 :
|
|
FromString( m_sCurrItem, ptP3.z) ;
|
|
break ;
|
|
case 62 :
|
|
FromString( m_sCurrItem, nColor) ;
|
|
break ;
|
|
}
|
|
} while ( nCode != 0) ;
|
|
UngetItem() ;
|
|
// eventuale aggiustamento del nome del layer per caratteri non ammessi
|
|
ValidateName( sLayer) ;
|
|
// gestisco il riferimento del gruppo di inserimento
|
|
ptP0.ToLoc( m_frGroup) ;
|
|
ptP1.ToLoc( m_frGroup) ;
|
|
ptP2.ToLoc( m_frGroup) ;
|
|
ptP3.ToLoc( m_frGroup) ;
|
|
// verifico se 3 o 4 punti
|
|
bool bQuad = ! AreSamePointNear( ptP2, ptP3) ;
|
|
// inserisco la faccia nel DB geometrico
|
|
// creo la trimesh
|
|
PtrOwner<ISurfTriMesh> pSTM( CreateSurfTriMesh()) ;
|
|
if ( ! IsValid( pSTM))
|
|
return false ;
|
|
// costruisco la geometria della trimesh
|
|
if ( ! pSTM->Init( 4, 2))
|
|
return false ;
|
|
if ( pSTM->AddVertex( ptP0) == SVT_NULL ||
|
|
pSTM->AddVertex( ptP1) == SVT_NULL ||
|
|
pSTM->AddVertex( ptP2) == SVT_NULL ||
|
|
( bQuad && pSTM->AddVertex( ptP3) == SVT_NULL))
|
|
return false ;
|
|
int nIdVertT0[3] = { 0, 1, 2} ;
|
|
int nIdVertT1[3] = { 2, 3, 0} ;
|
|
if ( pSTM->AddTriangle( nIdVertT0) == SVT_NULL ||
|
|
( bQuad && pSTM->AddTriangle( nIdVertT1) == SVT_NULL))
|
|
return false ;
|
|
if ( ! pSTM->AdjustTopology())
|
|
return false ;
|
|
// inserisco la trimesh nel DB
|
|
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, GetLayerId( sLayer), Release( pSTM)) ;
|
|
if ( nId == GDB_ID_NULL)
|
|
return false ;
|
|
// eventuale assegnazione del colore
|
|
Color cCol ;
|
|
if ( ColorFromACI( nColor, cCol)) {
|
|
if ( ! m_pGDB->SetMaterial( nId, cCol))
|
|
return false ;
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportDxf::ReadArc( bool& bFileEnd)
|
|
{
|
|
Point3d ptCen ;
|
|
double dRadius ;
|
|
double dStartAng ;
|
|
double dEndAng ;
|
|
Vector3d vtExtr( 0, 0, 1) ;
|
|
string sLayer ;
|
|
int nColor = COL_BYLAYER ;
|
|
// ciclo di lettura degli item dell' arco
|
|
bFileEnd = false ;
|
|
int nCode = CODE_NULL ;
|
|
do {
|
|
// leggo un Item
|
|
nCode = ReadNextItem() ;
|
|
if ( nCode == CODE_NULL) {
|
|
bFileEnd = true ;
|
|
return false ;
|
|
}
|
|
// eventuale gestione
|
|
switch ( nCode) {
|
|
case 8 :
|
|
sLayer = m_sCurrItem ;
|
|
break ;
|
|
case 10 :
|
|
FromString( m_sCurrItem, ptCen.x) ;
|
|
break ;
|
|
case 20 :
|
|
FromString( m_sCurrItem, ptCen.y) ;
|
|
break ;
|
|
case 30 :
|
|
FromString( m_sCurrItem, ptCen.z) ;
|
|
break ;
|
|
case 40 :
|
|
FromString( m_sCurrItem, dRadius) ;
|
|
break ;
|
|
case 50 :
|
|
FromString( m_sCurrItem, dStartAng) ;
|
|
break ;
|
|
case 51 :
|
|
FromString( m_sCurrItem, dEndAng) ;
|
|
break ;
|
|
case 62 :
|
|
FromString( m_sCurrItem, nColor) ;
|
|
break ;
|
|
case 210 :
|
|
FromString( m_sCurrItem, vtExtr.x) ;
|
|
break ;
|
|
case 220 :
|
|
FromString( m_sCurrItem, vtExtr.y) ;
|
|
break ;
|
|
case 230 :
|
|
FromString( m_sCurrItem, vtExtr.z) ;
|
|
break ;
|
|
}
|
|
} while ( nCode != 0) ;
|
|
UngetItem() ;
|
|
// eventuale aggiustamento del nome del layer per caratteri non ammessi
|
|
ValidateName( sLayer) ;
|
|
// calcolo l'angolo al centro (archi sempre CCW in DXF)
|
|
double dCentAng ;
|
|
if ( fabs( dEndAng - dStartAng) > ( 360. - EPS_ANG_SMALL))
|
|
dCentAng = 360. ;
|
|
else if ( dEndAng > dStartAng)
|
|
dCentAng = dEndAng - dStartAng ;
|
|
else
|
|
dCentAng = dEndAng - dStartAng + 360. ;
|
|
// se l'arco è nullo, non lo inserisco ma proseguo senza errore
|
|
if ( dRadius < EPS_SMALL || fabs( dCentAng) < EPS_ANG_SMALL)
|
|
return true ;
|
|
// versore iniziale
|
|
Vector3d vtStart ;
|
|
vtStart.FromPolar( 1, dStartAng) ;
|
|
// gestisco eventuale OCS
|
|
if ( ! AreSameVectorExact( vtExtr, Z_AX)) {
|
|
Frame3d frOCS ;
|
|
if ( ! frOCS.Set( ORIG, vtExtr))
|
|
return false ;
|
|
// trasformo il centro e il versore iniziale
|
|
ptCen.ToGlob( frOCS) ;
|
|
vtStart.ToGlob( frOCS) ;
|
|
}
|
|
// gestisco il riferimento del gruppo di inserimento
|
|
ptCen.ToLoc( m_frGroup) ;
|
|
vtStart.ToLoc( m_frGroup) ;
|
|
vtExtr.ToLoc( m_frGroup) ;
|
|
// inserisco l'arco nel DB geometrico
|
|
// creo l'arco
|
|
PtrOwner<ICurveArc> pCrvArc( CreateCurveArc()) ;
|
|
if ( ! IsValid( pCrvArc))
|
|
return false ;
|
|
// setto l'arco
|
|
if ( ! pCrvArc->Set( ptCen, vtExtr, dRadius, vtStart, dCentAng, 0))
|
|
return false ;
|
|
// inserisco l'arco nel DB
|
|
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, GetLayerId( sLayer), Release( pCrvArc)) ;
|
|
if ( nId == GDB_ID_NULL)
|
|
return false ;
|
|
// eventuale assegnazione del colore
|
|
Color cCol ;
|
|
if ( ColorFromACI( nColor, cCol)) {
|
|
if ( ! m_pGDB->SetMaterial( nId, cCol))
|
|
return false ;
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportDxf::ReadCircle( bool& bFileEnd)
|
|
{
|
|
Point3d ptCen ;
|
|
double dRadius ;
|
|
Vector3d vtExtr( 0, 0, 1) ;
|
|
string sLayer ;
|
|
int nColor = COL_BYLAYER ;
|
|
// ciclo di lettura degli item della circonferenza
|
|
bFileEnd = false ;
|
|
int nCode = CODE_NULL ;
|
|
do {
|
|
// leggo un Item
|
|
nCode = ReadNextItem() ;
|
|
if ( nCode == CODE_NULL) {
|
|
bFileEnd = true ;
|
|
return false ;
|
|
}
|
|
// eventuale gestione
|
|
switch ( nCode) {
|
|
case 8 :
|
|
sLayer = m_sCurrItem ;
|
|
break ;
|
|
case 10 :
|
|
FromString( m_sCurrItem, ptCen.x) ;
|
|
break ;
|
|
case 20 :
|
|
FromString( m_sCurrItem, ptCen.y) ;
|
|
break ;
|
|
case 30 :
|
|
FromString( m_sCurrItem, ptCen.z) ;
|
|
break ;
|
|
case 40 :
|
|
FromString( m_sCurrItem, dRadius) ;
|
|
break ;
|
|
case 62 :
|
|
FromString( m_sCurrItem, nColor) ;
|
|
break ;
|
|
case 210 :
|
|
FromString( m_sCurrItem, vtExtr.x) ;
|
|
break ;
|
|
case 220 :
|
|
FromString( m_sCurrItem, vtExtr.y) ;
|
|
break ;
|
|
case 230 :
|
|
FromString( m_sCurrItem, vtExtr.z) ;
|
|
break ;
|
|
}
|
|
} while ( nCode != 0) ;
|
|
UngetItem() ;
|
|
// eventuale aggiustamento del nome del layer per caratteri non ammessi
|
|
ValidateName( sLayer) ;
|
|
// se il cerchio è nullo, non lo inserisco ma proseguo senza errore
|
|
if ( dRadius < EPS_SMALL)
|
|
return true ;
|
|
// gestisco eventuale OCS
|
|
if ( ! AreSameVectorExact( vtExtr, Z_AX)) {
|
|
Frame3d frOCS ;
|
|
if ( ! frOCS.Set( ORIG, vtExtr))
|
|
return false ;
|
|
ptCen.ToGlob( frOCS) ;
|
|
}
|
|
// gestisco il riferimento del gruppo di inserimento
|
|
ptCen.ToLoc( m_frGroup) ;
|
|
vtExtr.ToLoc( m_frGroup) ;
|
|
// inserisco il cerchio nel DB geometrico
|
|
// creo il cerchio
|
|
PtrOwner<ICurveArc> pCrvArc( CreateCurveArc()) ;
|
|
if ( ! IsValid( pCrvArc))
|
|
return false ;
|
|
// setto il cerchio
|
|
if ( ! pCrvArc->Set( ptCen, vtExtr, dRadius))
|
|
return false ;
|
|
// inserisco il cerchio nel DB
|
|
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, GetLayerId( sLayer), Release( pCrvArc)) ;
|
|
if ( nId == GDB_ID_NULL)
|
|
return false ;
|
|
// eventuale assegnazione del colore
|
|
Color cCol ;
|
|
if ( ColorFromACI( nColor, cCol)) {
|
|
if ( ! m_pGDB->SetMaterial( nId, cCol))
|
|
return false ;
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportDxf::ReadEllipse( bool& bFileEnd)
|
|
{
|
|
Point3d ptCen ;
|
|
Vector3d vtMajorAx ;
|
|
double dRatMinMaj = 1 ;
|
|
double dStartPar = 0 ;
|
|
double dEndPar = 2 * PIGRECO ;
|
|
Vector3d vtExtr( 0, 0, 1) ;
|
|
string sLayer ;
|
|
int nColor = COL_BYLAYER ;
|
|
// ciclo di lettura degli item dell' arco
|
|
bFileEnd = false ;
|
|
int nCode = CODE_NULL ;
|
|
do {
|
|
// leggo un Item
|
|
nCode = ReadNextItem() ;
|
|
if ( nCode == CODE_NULL) {
|
|
bFileEnd = true ;
|
|
return false ;
|
|
}
|
|
// eventuale gestione
|
|
switch ( nCode) {
|
|
case 8 :
|
|
sLayer = m_sCurrItem ;
|
|
break ;
|
|
case 10 :
|
|
FromString( m_sCurrItem, ptCen.x) ;
|
|
break ;
|
|
case 20 :
|
|
FromString( m_sCurrItem, ptCen.y) ;
|
|
break ;
|
|
case 30 :
|
|
FromString( m_sCurrItem, ptCen.z) ;
|
|
break ;
|
|
case 11 :
|
|
FromString( m_sCurrItem, vtMajorAx.x) ;
|
|
break ;
|
|
case 21 :
|
|
FromString( m_sCurrItem, vtMajorAx.y) ;
|
|
break ;
|
|
case 31 :
|
|
FromString( m_sCurrItem, vtMajorAx.z) ;
|
|
break ;
|
|
case 40 :
|
|
FromString( m_sCurrItem, dRatMinMaj) ;
|
|
break ;
|
|
case 41 :
|
|
FromString( m_sCurrItem, dStartPar) ;
|
|
break ;
|
|
case 42 :
|
|
FromString( m_sCurrItem, dEndPar) ;
|
|
break ;
|
|
case 62 :
|
|
FromString( m_sCurrItem, nColor) ;
|
|
break ;
|
|
case 210 :
|
|
FromString( m_sCurrItem, vtExtr.x) ;
|
|
break ;
|
|
case 220 :
|
|
FromString( m_sCurrItem, vtExtr.y) ;
|
|
break ;
|
|
case 230 :
|
|
FromString( m_sCurrItem, vtExtr.z) ;
|
|
break ;
|
|
}
|
|
} while ( nCode != 0) ;
|
|
UngetItem() ;
|
|
// eventuale aggiustamento del nome del layer per caratteri non ammessi
|
|
ValidateName( sLayer) ;
|
|
// calcolo il semiasse maggiore
|
|
double dMajorAx = vtMajorAx.Len() ;
|
|
vtMajorAx.Normalize() ;
|
|
// calcolo l'angolo al centro (ellisse sempre CCW in DXF)
|
|
double dCentAng = ( dEndPar - dStartPar) * RADTODEG ;
|
|
// se l'arco è nullo, non lo inserisco ma proseguo senza errore
|
|
if ( dMajorAx < EPS_SMALL || fabs( dCentAng) < EPS_ANG_SMALL)
|
|
return true ;
|
|
// versore iniziale
|
|
Vector3d vtStart = vtMajorAx ;
|
|
vtStart.Rotate( vtExtr, dStartPar) ;
|
|
// gestisco il riferimento del gruppo di inserimento
|
|
ptCen.ToLoc( m_frGroup) ;
|
|
vtMajorAx.ToLoc( m_frGroup) ;
|
|
vtStart.ToLoc( m_frGroup) ;
|
|
vtExtr.ToLoc( m_frGroup) ;
|
|
// inserisco l'arco nel DB geometrico
|
|
// creo l'arco
|
|
PtrOwner<ICurveArc> pCrvArc( CreateCurveArc()) ;
|
|
if ( ! IsValid( pCrvArc))
|
|
return false ;
|
|
// setto l'arco
|
|
if ( ! pCrvArc->Set( ptCen, vtExtr, dMajorAx, vtStart, dCentAng, 0))
|
|
return false ;
|
|
// inserisco l'arco nel DB
|
|
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, GetLayerId( sLayer), Release( pCrvArc)) ;
|
|
if ( nId == GDB_ID_NULL)
|
|
return false ;
|
|
// eventuale scalatura
|
|
if ( fabs( dRatMinMaj - 1) > EPS_ZERO) {
|
|
Frame3d frSca ;
|
|
Vector3d vtY = vtExtr ^ vtMajorAx ;
|
|
vtY.Normalize() ;
|
|
if ( frSca.Set( ptCen, vtMajorAx, vtY, vtExtr))
|
|
m_pGDB->Scale( nId, frSca, 1, dRatMinMaj, 1) ;
|
|
}
|
|
// eventuale assegnazione del colore
|
|
Color cCol ;
|
|
if ( ColorFromACI( nColor, cCol)) {
|
|
if ( ! m_pGDB->SetMaterial( nId, cCol))
|
|
return false ;
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportDxf::ReadLine( bool& bFileEnd)
|
|
{
|
|
Point3d ptStart ;
|
|
Point3d ptEnd ;
|
|
Vector3d vtExtr( 0, 0, 1) ;
|
|
string sLayer ;
|
|
int nColor = COL_BYLAYER ;
|
|
// ciclo di lettura degli item della linea
|
|
bFileEnd = false ;
|
|
int nCode = CODE_NULL ;
|
|
do {
|
|
// leggo un Item
|
|
nCode = ReadNextItem() ;
|
|
if ( nCode == CODE_NULL) {
|
|
bFileEnd = true ;
|
|
return false ;
|
|
}
|
|
// eventuale gestione
|
|
switch ( nCode) {
|
|
case 8 :
|
|
sLayer = m_sCurrItem ;
|
|
break ;
|
|
case 10 :
|
|
FromString( m_sCurrItem, ptStart.x) ;
|
|
break ;
|
|
case 20 :
|
|
FromString( m_sCurrItem, ptStart.y) ;
|
|
break ;
|
|
case 30 :
|
|
FromString( m_sCurrItem, ptStart.z) ;
|
|
break ;
|
|
case 11 :
|
|
FromString( m_sCurrItem, ptEnd.x) ;
|
|
break ;
|
|
case 21 :
|
|
FromString( m_sCurrItem, ptEnd.y) ;
|
|
break ;
|
|
case 31 :
|
|
FromString( m_sCurrItem, ptEnd.z) ;
|
|
break ;
|
|
case 62 :
|
|
FromString( m_sCurrItem, nColor) ;
|
|
break ;
|
|
case 210 :
|
|
FromString( m_sCurrItem, vtExtr.x) ;
|
|
break ;
|
|
case 220 :
|
|
FromString( m_sCurrItem, vtExtr.y) ;
|
|
break ;
|
|
case 230 :
|
|
FromString( m_sCurrItem, vtExtr.z) ;
|
|
break ;
|
|
}
|
|
} while ( nCode != 0) ;
|
|
UngetItem() ;
|
|
// eventuale aggiustamento del nome del layer per caratteri non ammessi
|
|
ValidateName( sLayer) ;
|
|
// se la linea è nulla, non la inserisco ma proseguo senza errore
|
|
if ( AreSamePointNear( ptStart, ptEnd))
|
|
return true ;
|
|
// gestisco il riferimento del gruppo di inserimento
|
|
ptStart.ToLoc( m_frGroup) ;
|
|
ptEnd.ToLoc( m_frGroup) ;
|
|
// inserisco la linea nel DB geometrico
|
|
// creo la linea
|
|
PtrOwner<ICurveLine> pCrvLine( CreateCurveLine()) ;
|
|
if ( ! IsValid( pCrvLine))
|
|
return false ;
|
|
// setto la linea
|
|
if ( ! pCrvLine->Set( ptStart, ptEnd))
|
|
return false ;
|
|
// inserisco la linea nel DB
|
|
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, GetLayerId( sLayer), Release( pCrvLine)) ;
|
|
if ( nId == GDB_ID_NULL)
|
|
return false ;
|
|
// eventuale assegnazione del colore
|
|
Color cCol ;
|
|
if ( ColorFromACI( nColor, cCol)) {
|
|
if ( ! m_pGDB->SetMaterial( nId, cCol))
|
|
return false ;
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportDxf::ReadLwPolyLine( bool& bFileEnd)
|
|
{
|
|
UPNTVECTOR vVert ; // uso il parametro U come bulge
|
|
vVert.reserve( 16) ;
|
|
Vector3d vtExtr( 0, 0, 1) ;
|
|
double dElevation = 0 ;
|
|
string sLayer ;
|
|
int nColor = COL_BYLAYER ;
|
|
int nNumVert = 0 ;
|
|
int nFlag = 0 ;
|
|
double dBulge = 0 ;
|
|
UPOINT VertTmp( 0, Point3d()) ;
|
|
// ciclo di lettura degli item della LwPolyLine
|
|
bFileEnd = false ;
|
|
int nContX = 0 ;
|
|
int nContY = 0 ;
|
|
int nCode = CODE_NULL ;
|
|
do {
|
|
// leggo un Item
|
|
nCode = ReadNextItem() ;
|
|
if ( nCode == CODE_NULL) {
|
|
bFileEnd = true ;
|
|
return false ;
|
|
}
|
|
// eventuale gestione
|
|
switch ( nCode) {
|
|
case 8 :
|
|
sLayer = m_sCurrItem ;
|
|
break ;
|
|
case 10 :
|
|
FromString( m_sCurrItem, VertTmp.second.x) ;
|
|
++ nContX ;
|
|
if ( nContX == nContY) {
|
|
vVert.push_back( VertTmp) ;
|
|
VertTmp.first = 0 ;
|
|
}
|
|
break ;
|
|
case 20 :
|
|
FromString( m_sCurrItem, VertTmp.second.y) ;
|
|
++ nContY ;
|
|
if ( nContX == nContY) {
|
|
vVert.push_back( VertTmp) ;
|
|
VertTmp.first = 0 ;
|
|
}
|
|
break ;
|
|
case 38 :
|
|
FromString( m_sCurrItem, dElevation) ;
|
|
break ;
|
|
case 42 :
|
|
FromString( m_sCurrItem, dBulge) ;
|
|
// modifica il bulge dell'ultimo vertice inserito
|
|
if ( ! vVert.empty())
|
|
vVert.back().first = dBulge ;
|
|
break ;
|
|
case 62 :
|
|
FromString( m_sCurrItem, nColor) ;
|
|
break ;
|
|
case 70 :
|
|
FromString( m_sCurrItem, nFlag) ;
|
|
break ;
|
|
case 90 :
|
|
FromString( m_sCurrItem, nNumVert) ;
|
|
break ;
|
|
case 210 :
|
|
FromString( m_sCurrItem, vtExtr.x) ;
|
|
break ;
|
|
case 220 :
|
|
FromString( m_sCurrItem, vtExtr.y) ;
|
|
break ;
|
|
case 230 :
|
|
FromString( m_sCurrItem, vtExtr.z) ;
|
|
break ;
|
|
}
|
|
} while ( nCode != 0) ;
|
|
UngetItem() ;
|
|
// eventuale aggiustamento del nome del layer per caratteri non ammessi
|
|
ValidateName( sLayer) ;
|
|
// Verifico il numero di vertici
|
|
if ( vVert.size() != nNumVert || nNumVert < 2)
|
|
return false ;
|
|
// Se chiusa, aggiungo un punto uguale al primo in coda
|
|
if ( nFlag & 1) {
|
|
vVert.push_back( vVert[0]) ;
|
|
++ nNumVert ;
|
|
}
|
|
// aggiusto i punti per elevazione, eventuale OCS e riferimento del gruppo di inserimento
|
|
Frame3d frOCS ;
|
|
if ( ! AreSameVectorExact( vtExtr, Z_AX)) {
|
|
if ( ! frOCS.Set( ORIG, vtExtr))
|
|
return false ;
|
|
}
|
|
for ( int i = 0 ; i < nNumVert ; ++i) {
|
|
vVert[i].second.z = dElevation ;
|
|
vVert[i].second.ToGlob( frOCS) ;
|
|
vVert[i].second.ToLoc( m_frGroup) ;
|
|
}
|
|
// gestisco il riferimento del gruppo di inserimento
|
|
vtExtr.ToLoc( m_frGroup) ;
|
|
// Creo la curva composita
|
|
PtrOwner<ICurveComposite> pCrvCompo( CreateCurveComposite()) ;
|
|
if ( ! IsValid( pCrvCompo))
|
|
return false ;
|
|
// Inserisco i punti con bulge nella curva composita come linee e archi
|
|
if ( ! pCrvCompo->FromPointBulgeVector( vVert, vtExtr))
|
|
return false ;
|
|
// Se non sono state inserite curve, esco senza errore
|
|
if ( pCrvCompo->GetCurveNumber() == 0)
|
|
return true ;
|
|
// Inserisco la curva composita nel DB
|
|
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, GetLayerId( sLayer), Release( pCrvCompo)) ;
|
|
if ( nId == GDB_ID_NULL)
|
|
return false ;
|
|
// eventuale assegnazione del colore
|
|
Color cCol ;
|
|
if ( ColorFromACI( nColor, cCol)) {
|
|
if ( ! m_pGDB->SetMaterial( nId, cCol))
|
|
return false ;
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportDxf::ReadPoint( bool& bFileEnd)
|
|
{
|
|
Point3d ptP ;
|
|
Vector3d vtExtr( 0, 0, 1) ;
|
|
string sLayer ;
|
|
int nColor = COL_BYLAYER ;
|
|
// ciclo di lettura degli item della linea
|
|
bFileEnd = false ;
|
|
int nCode = CODE_NULL ;
|
|
do {
|
|
// leggo un Item
|
|
nCode = ReadNextItem() ;
|
|
if ( nCode == CODE_NULL) {
|
|
bFileEnd = true ;
|
|
return false ;
|
|
}
|
|
// eventuale gestione
|
|
switch ( nCode) {
|
|
case 8 :
|
|
sLayer = m_sCurrItem ;
|
|
break ;
|
|
case 10 :
|
|
FromString( m_sCurrItem, ptP.x) ;
|
|
break ;
|
|
case 20 :
|
|
FromString( m_sCurrItem, ptP.y) ;
|
|
break ;
|
|
case 30 :
|
|
FromString( m_sCurrItem, ptP.z) ;
|
|
break ;
|
|
case 62 :
|
|
FromString( m_sCurrItem, nColor) ;
|
|
break ;
|
|
case 210 :
|
|
FromString( m_sCurrItem, vtExtr.x) ;
|
|
break ;
|
|
case 220 :
|
|
FromString( m_sCurrItem, vtExtr.y) ;
|
|
break ;
|
|
case 230 :
|
|
FromString( m_sCurrItem, vtExtr.z) ;
|
|
break ;
|
|
}
|
|
} while ( nCode != 0) ;
|
|
UngetItem() ;
|
|
// eventuale aggiustamento del nome del layer per caratteri non ammessi
|
|
ValidateName( sLayer) ;
|
|
// gestisco il riferimento del gruppo di inserimento
|
|
ptP.ToLoc( m_frGroup) ;
|
|
// inserisco il punto nel DB geometrico
|
|
// creo il punto
|
|
PtrOwner<IGeoPoint3d> pGeoPnt( CreateGeoPoint3d()) ;
|
|
if ( ! IsValid( pGeoPnt))
|
|
return false ;
|
|
// setto il punto
|
|
if ( ! pGeoPnt->Set( ptP))
|
|
return false ;
|
|
// inserisco il punto nel DB
|
|
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, GetLayerId( sLayer), Release( pGeoPnt)) ;
|
|
if ( nId == GDB_ID_NULL)
|
|
return false ;
|
|
// eventuale assegnazione del colore
|
|
Color cCol ;
|
|
if ( ColorFromACI( nColor, cCol)) {
|
|
if ( ! m_pGDB->SetMaterial( nId, cCol))
|
|
return false ;
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportDxf::ReadPolyLine( bool& bFileEnd)
|
|
{
|
|
Vector3d vtExtr( 0, 0, 1) ;
|
|
double dElevation = 0 ;
|
|
string sLayer ;
|
|
int nColor = COL_BYLAYER ;
|
|
int nFlag = 0 ;
|
|
int nNumVertM = 0 ;
|
|
int nNumVertN = 0 ;
|
|
// ciclo di lettura degli item della PolyLine
|
|
bFileEnd = false ;
|
|
int nCode = CODE_NULL ;
|
|
do {
|
|
// leggo un Item
|
|
nCode = ReadNextItem() ;
|
|
if ( nCode == CODE_NULL) {
|
|
bFileEnd = true ;
|
|
return false ;
|
|
}
|
|
// eventuale gestione
|
|
switch ( nCode) {
|
|
case 8 :
|
|
sLayer = m_sCurrItem ;
|
|
break ;
|
|
case 30 :
|
|
FromString( m_sCurrItem, dElevation) ;
|
|
break ;
|
|
case 62 :
|
|
FromString( m_sCurrItem, nColor) ;
|
|
break ;
|
|
case 70 :
|
|
FromString( m_sCurrItem, nFlag) ;
|
|
break ;
|
|
case 71 :
|
|
FromString( m_sCurrItem, nNumVertM) ;
|
|
break ;
|
|
case 72 :
|
|
FromString( m_sCurrItem, nNumVertN) ;
|
|
break ;
|
|
case 210 :
|
|
FromString( m_sCurrItem, vtExtr.x) ;
|
|
break ;
|
|
case 220 :
|
|
FromString( m_sCurrItem, vtExtr.y) ;
|
|
break ;
|
|
case 230 :
|
|
FromString( m_sCurrItem, vtExtr.z) ;
|
|
break ;
|
|
}
|
|
} while ( nCode != 0) ;
|
|
UngetItem() ;
|
|
// eventuale aggiustamento del nome del layer per caratteri non ammessi
|
|
ValidateName( sLayer) ;
|
|
// Se Polygon Mesh
|
|
if ( ( nFlag & 16) != 0)
|
|
return CompletePolygonMesh( sLayer, nColor, nFlag, dElevation, vtExtr, nNumVertM, nNumVertN, bFileEnd) ;
|
|
// se Polyface Mesh
|
|
else if ( ( nFlag & 64) != 0)
|
|
return CompletePolyfaceMesh( sLayer, nColor, nFlag, dElevation, vtExtr, bFileEnd) ;
|
|
// altrimenti PolyLine vera e propria
|
|
else
|
|
return CompletePolyLine( sLayer, nColor, nFlag, dElevation, vtExtr, bFileEnd) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportDxf::CompletePolyLine( const string& sLayer, int nColor, int nFlag, double dElevation, const Vector3d& vtExtr, bool& bFileEnd)
|
|
{
|
|
int nNumVert = 0 ;
|
|
UPNTVECTOR vVert ; // uso il parametro U come bulge
|
|
vVert.reserve( 16) ;
|
|
UPOINT VertTmp( 0, Point3d()) ;
|
|
|
|
// Ciclo sui Vertex, termino con SEQEND o errore
|
|
bFileEnd = false ;
|
|
bool bIs3d = (( nFlag & 8) != 0) ;
|
|
bool bPolyEnd = false ;
|
|
string sEntName ;
|
|
do {
|
|
// leggo intestazione entità, per avere il tipo
|
|
bool bOkLoc = GetEntityName( sEntName, bPolyEnd, bFileEnd) ;
|
|
if ( bOkLoc && ! bPolyEnd) {
|
|
// se Vertex
|
|
if ( sEntName == "VERTEX") {
|
|
if ( ! ReadPolyLineVertex( VertTmp, bFileEnd))
|
|
bOkLoc = false ;
|
|
if ( ! bIs3d)
|
|
VertTmp.second.z = 0 ;
|
|
vVert.push_back( VertTmp) ;
|
|
nNumVert ++ ;
|
|
}
|
|
// se SeqEnd
|
|
else if ( sEntName == "SEQEND") {
|
|
if ( ! SkipEntity( bFileEnd))
|
|
bOkLoc = false ;
|
|
bPolyEnd = true ;
|
|
}
|
|
// altrimenti errore
|
|
else {
|
|
UngetItem() ;
|
|
return false ;
|
|
}
|
|
}
|
|
// gestisco eventuale errore
|
|
if ( ! bOkLoc) {
|
|
string sOut = "ImportDxf : Error on line " + ToString( m_theScanner.GetCurrLineNbr()) ;
|
|
LOG_ERROR( GetEExLogger(), sOut.c_str())
|
|
return false ;
|
|
}
|
|
} while( ! bPolyEnd) ;
|
|
|
|
// Se chiusa, aggiungo un punto uguale al primo in coda
|
|
if ( nFlag & 1) {
|
|
vVert.push_back( vVert[0]) ;
|
|
++ nNumVert ;
|
|
}
|
|
// aggiusto i punti per elevazione, eventuale OCS e riferimento del gruppo di inserimento
|
|
Frame3d frOCS ;
|
|
if ( ! bIs3d && ! AreSameVectorExact( vtExtr, Z_AX)) {
|
|
if ( ! frOCS.Set( ORIG, vtExtr))
|
|
return false ;
|
|
}
|
|
for ( int i = 0 ; i < nNumVert ; ++i) {
|
|
vVert[i].second.z += dElevation ;
|
|
vVert[i].second.ToGlob( frOCS) ;
|
|
vVert[i].second.ToLoc( m_frGroup) ;
|
|
}
|
|
// gestisco il riferimento del gruppo di inserimento
|
|
Vector3d vtExtrIn = vtExtr ;
|
|
vtExtrIn.ToLoc( m_frGroup) ;
|
|
// Creo la curva composita
|
|
PtrOwner<ICurveComposite> pCrvCompo( CreateCurveComposite()) ;
|
|
if ( ! IsValid( pCrvCompo))
|
|
return false ;
|
|
// Inserisco i punti con bulge nella curva composita come linee e archi
|
|
if ( ! pCrvCompo->FromPointBulgeVector( vVert, vtExtrIn))
|
|
return false ;
|
|
// Se non sono state inserite curve, esco senza errore
|
|
if ( pCrvCompo->GetCurveNumber() == 0)
|
|
return true ;
|
|
// Inserisco la curva composita nel DB
|
|
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, GetLayerId( sLayer), Release( pCrvCompo)) ;
|
|
if ( nId == GDB_ID_NULL)
|
|
return false ;
|
|
// eventuale assegnazione del colore
|
|
Color cCol ;
|
|
if ( ColorFromACI( nColor, cCol)) {
|
|
if ( ! m_pGDB->SetMaterial( nId, cCol))
|
|
return false ;
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportDxf::ReadPolyLineVertex( UPOINT& uPnt, bool& bFileEnd)
|
|
{
|
|
// inizializzo il punto con bulge
|
|
uPnt.first = 0 ;
|
|
uPnt.second.Set( 0, 0, 0) ;
|
|
// ciclo di lettura degli item della linea
|
|
bFileEnd = false ;
|
|
int nCode = CODE_NULL ;
|
|
do {
|
|
// leggo un Item
|
|
nCode = ReadNextItem() ;
|
|
if ( nCode == CODE_NULL) {
|
|
bFileEnd = true ;
|
|
return false ;
|
|
}
|
|
// eventuale gestione
|
|
switch ( nCode) {
|
|
case 10 :
|
|
FromString( m_sCurrItem, uPnt.second.x) ;
|
|
break ;
|
|
case 20 :
|
|
FromString( m_sCurrItem, uPnt.second.y) ;
|
|
break ;
|
|
case 30 :
|
|
FromString( m_sCurrItem, uPnt.second.z) ;
|
|
break ;
|
|
case 42 :
|
|
FromString( m_sCurrItem, uPnt.first) ;
|
|
break ;
|
|
}
|
|
} while ( nCode != 0) ;
|
|
UngetItem() ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportDxf::CompletePolygonMesh( const string& sLayer, int nColor, int nFlag, double dElevation,
|
|
const Vector3d& vtExtr, int nNumVertM, int nNumVertN, bool& bFileEnd)
|
|
{
|
|
// creo la superficie
|
|
PtrOwner<ISurfTriMesh> pSTM( CreateSurfTriMesh()) ;
|
|
if ( ! IsValid( pSTM))
|
|
return false ;
|
|
// la inizializzo
|
|
int nNumVert = nNumVertM * nNumVertN ;
|
|
bool bClosedM = (( nFlag & 1) != 0) ;
|
|
bool bClosedN = (( nFlag & 32) != 0) ;
|
|
int nNumTria = 0 ;
|
|
if ( bClosedM && bClosedN)
|
|
nNumTria = 2 * nNumVertM * nNumVertN ;
|
|
else if ( bClosedM)
|
|
nNumTria = 2 * nNumVertM * ( nNumVertN - 1) ;
|
|
else if ( bClosedN)
|
|
nNumTria = 2 * ( nNumVertM - 1) * nNumVertN ;
|
|
else
|
|
nNumTria = 2 * ( nNumVertM - 1) * ( nNumVertN - 1) ;
|
|
if ( ! pSTM->Init( nNumVert, nNumTria))
|
|
return false ;
|
|
// determino eventuale OCS
|
|
Frame3d frOCS ;
|
|
if ( ! ( nFlag & 8) && ! AreSameVectorExact( vtExtr, Z_AX)) {
|
|
if ( ! frOCS.Set( ORIG, vtExtr))
|
|
return false ;
|
|
}
|
|
|
|
// Ciclo sui Vertex, termino con SEQEND o errore
|
|
bFileEnd = false ;
|
|
bool bPolyEnd = false ;
|
|
int nReadVert = 0 ;
|
|
string sEntName ;
|
|
Point3d ptP ;
|
|
do {
|
|
// leggo intestazione entità, per avere il tipo
|
|
bool bOkLoc = GetEntityName( sEntName, bPolyEnd, bFileEnd) ;
|
|
if ( bOkLoc && ! bPolyEnd) {
|
|
// se Vertex
|
|
if ( sEntName == "VERTEX") {
|
|
// leggo il punto
|
|
if ( ! ReadPolygonMeshVertex( ptP, bFileEnd))
|
|
bOkLoc = false ;
|
|
// sistemazioni per elevazione, eventuale OCS e riferimento del gruppo di inserimento
|
|
ptP.z += dElevation ;
|
|
ptP.ToGlob( frOCS) ;
|
|
ptP.ToLoc( m_frGroup) ;
|
|
// inserimento del vertice nella trimesh
|
|
if ( pSTM->AddVertex( ptP) == SVT_NULL)
|
|
return false ;
|
|
nReadVert ++ ;
|
|
}
|
|
// se SeqEnd
|
|
else if ( sEntName == "SEQEND") {
|
|
if ( ! SkipEntity( bFileEnd))
|
|
bOkLoc = false ;
|
|
bPolyEnd = true ;
|
|
}
|
|
// altrimenti errore
|
|
else {
|
|
UngetItem() ;
|
|
return false ;
|
|
}
|
|
}
|
|
// gestisco eventuale errore
|
|
if ( ! bOkLoc) {
|
|
string sOut = "ImportDxf : Error on line " + ToString( m_theScanner.GetCurrLineNbr()) ;
|
|
LOG_ERROR( GetEExLogger(), sOut.c_str())
|
|
return false ;
|
|
}
|
|
} while( ! bPolyEnd) ;
|
|
// Verifico il numero di vertici
|
|
if ( nNumVert != nReadVert)
|
|
return false ;
|
|
// Definisco i triangoli
|
|
int nMmax = ( bClosedM ? nNumVertM : ( nNumVertM - 1)) ;
|
|
int nNmax = ( bClosedN ? nNumVertN : ( nNumVertN - 1)) ;
|
|
int nIdVT1[3] ;
|
|
int nIdVT2[3] ;
|
|
for ( int i = 0 ; i < nMmax ; ++ i) {
|
|
for ( int j = 0 ; j < nNmax ; ++ j) {
|
|
// primo triangolo
|
|
nIdVT1[0] = i * nNumVertN + j ;
|
|
nIdVT1[1] = (( j < nNumVertN) ? ( nIdVT1[0] + 1) : ( i * nNumVertN)) ;
|
|
nIdVT1[2] = (( i < nNumVertM) ? ( nIdVT1[1] + nNumVertN) : j) ;
|
|
// secondo triangolo
|
|
nIdVT2[0] = nIdVT1[0] ;
|
|
nIdVT2[1] = nIdVT1[2] ;
|
|
nIdVT2[2] = (( i < nNumVertM) ? ( nIdVT2[0] + nNumVertN) : j) ;
|
|
// inserisco i triangoli nella trimesh
|
|
if ( pSTM->AddTriangle( nIdVT1) == SVT_NULL ||
|
|
pSTM->AddTriangle( nIdVT2) == SVT_NULL)
|
|
return false ;
|
|
}
|
|
}
|
|
// valido la superficie e calcolo le adiacenze
|
|
if ( ! pSTM->AdjustTopology())
|
|
return false ;
|
|
// inserisco la trimesh nel DB
|
|
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, GetLayerId( sLayer), Release( pSTM)) ;
|
|
if ( nId == GDB_ID_NULL)
|
|
return false ;
|
|
// eventuale assegnazione del colore
|
|
Color cCol ;
|
|
if ( ColorFromACI( nColor, cCol)) {
|
|
if ( ! m_pGDB->SetMaterial( nId, cCol))
|
|
return false ;
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportDxf::ReadPolygonMeshVertex( Point3d& ptP, bool& bFileEnd)
|
|
{
|
|
// inizializzo il punto
|
|
ptP.Set( 0, 0, 0) ;
|
|
// ciclo di lettura degli item della linea
|
|
bFileEnd = false ;
|
|
int nCode = CODE_NULL ;
|
|
do {
|
|
// leggo un Item
|
|
nCode = ReadNextItem() ;
|
|
if ( nCode == CODE_NULL) {
|
|
bFileEnd = true ;
|
|
return false ;
|
|
}
|
|
// eventuale gestione
|
|
switch ( nCode) {
|
|
case 10 :
|
|
FromString( m_sCurrItem, ptP.x) ;
|
|
break ;
|
|
case 20 :
|
|
FromString( m_sCurrItem, ptP.y) ;
|
|
break ;
|
|
case 30 :
|
|
FromString( m_sCurrItem, ptP.z) ;
|
|
break ;
|
|
}
|
|
} while ( nCode != 0) ;
|
|
UngetItem() ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportDxf::CompletePolyfaceMesh( const string& sLayer, int nColor, int nFlag, double dElevation,
|
|
const Vector3d& vtExtr, bool& bFileEnd)
|
|
{
|
|
// creo la superficie
|
|
PtrOwner<ISurfTriMesh> pSTM( CreateSurfTriMesh()) ;
|
|
if ( ! IsValid( pSTM))
|
|
return false ;
|
|
// la inizializzo
|
|
if ( ! pSTM->Init( 3, 1))
|
|
return false ;
|
|
// determino eventuale OCS
|
|
Frame3d frOCS ;
|
|
if ( ! ( nFlag & 8) && ! AreSameVectorExact( vtExtr, Z_AX)) {
|
|
if ( ! frOCS.Set( ORIG, vtExtr))
|
|
return false ;
|
|
}
|
|
|
|
// Ciclo sui Vertex, termino con SEQEND o errore
|
|
bFileEnd = false ;
|
|
bool bPolyEnd = false ;
|
|
string sEntName ;
|
|
int nStat ;
|
|
Point3d ptP ;
|
|
int nIdVT1[3], nIdVT2[3] ;
|
|
do {
|
|
// leggo intestazione entità, per avere il tipo
|
|
bool bOkLoc = GetEntityName( sEntName, bPolyEnd, bFileEnd) ;
|
|
if ( bOkLoc && ! bPolyEnd) {
|
|
// se Vertex
|
|
if ( sEntName == "VERTEX") {
|
|
// leggo il punto
|
|
if ( ! ReadPolyfaceMeshVertex( nStat, ptP, nIdVT1, nIdVT2, bFileEnd))
|
|
bOkLoc = false ;
|
|
switch ( nStat) {
|
|
case 0 : // è un vertice
|
|
// sistemazioni per elevazione, eventuale OCS e riferimento del gruppo di inserimento
|
|
ptP.z += dElevation ;
|
|
ptP.ToGlob( frOCS) ;
|
|
ptP.ToLoc( m_frGroup) ;
|
|
// inserimento del vertice nella trimesh
|
|
if ( pSTM->AddVertex( ptP) == SVT_NULL)
|
|
return false ;
|
|
break ;
|
|
case 1 : // è un triangolo
|
|
// inserimento del triangolo nella trimesh
|
|
if ( pSTM->AddTriangle( nIdVT1) == SVT_NULL)
|
|
return false ;
|
|
break ;
|
|
case 2 : // sono due triangoli
|
|
// inserimento dei triangoli nella trimesh
|
|
if ( pSTM->AddTriangle( nIdVT1) == SVT_NULL ||
|
|
pSTM->AddTriangle( nIdVT2) == SVT_NULL)
|
|
return false ;
|
|
}
|
|
}
|
|
// se SeqEnd
|
|
else if ( sEntName == "SEQEND") {
|
|
if ( ! SkipEntity( bFileEnd))
|
|
bOkLoc = false ;
|
|
bPolyEnd = true ;
|
|
}
|
|
// altrimenti errore
|
|
else {
|
|
UngetItem() ;
|
|
return false ;
|
|
}
|
|
}
|
|
// gestisco eventuale errore
|
|
if ( ! bOkLoc) {
|
|
string sOut = "ImportDxf : Error on line " + ToString( m_theScanner.GetCurrLineNbr()) ;
|
|
LOG_ERROR( GetEExLogger(), sOut.c_str())
|
|
return false ;
|
|
}
|
|
} while( ! bPolyEnd) ;
|
|
// valido la superficie e calcolo le adiacenze
|
|
if ( ! pSTM->AdjustTopology())
|
|
return false ;
|
|
// inserisco la trimesh nel DB
|
|
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, GetLayerId( sLayer), Release( pSTM)) ;
|
|
if ( nId == GDB_ID_NULL)
|
|
return false ;
|
|
// eventuale assegnazione del colore
|
|
Color cCol ;
|
|
if ( ColorFromACI( nColor, cCol)) {
|
|
if ( ! m_pGDB->SetMaterial( nId, cCol))
|
|
return false ;
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportDxf::ReadPolyfaceMeshVertex( int& nStat, Point3d& ptP, int nIdVT1[3], int nIdVT2[3], bool& bFileEnd)
|
|
{
|
|
// inizializzo il punto e gli indici
|
|
ptP.Set( 0, 0, 0) ;
|
|
nIdVT1[0] = - 1 ; nIdVT1[1] = - 1 ; nIdVT1[2] = - 1 ;
|
|
nIdVT2[0] = - 1 ; nIdVT2[1] = - 1 ; nIdVT2[2] = - 1 ;
|
|
// ciclo di lettura degli item della linea
|
|
bFileEnd = false ;
|
|
int nFlag = 0 ;
|
|
int nVal = 0 ;
|
|
int nCode = CODE_NULL ;
|
|
do {
|
|
// leggo un Item
|
|
nCode = ReadNextItem() ;
|
|
if ( nCode == CODE_NULL) {
|
|
bFileEnd = true ;
|
|
return false ;
|
|
}
|
|
// eventuale gestione
|
|
switch ( nCode) {
|
|
case 10 :
|
|
FromString( m_sCurrItem, ptP.x) ;
|
|
break ;
|
|
case 20 :
|
|
FromString( m_sCurrItem, ptP.y) ;
|
|
break ;
|
|
case 30 :
|
|
FromString( m_sCurrItem, ptP.z) ;
|
|
break ;
|
|
case 70 :
|
|
FromString( m_sCurrItem, nFlag) ;
|
|
break ;
|
|
case 71 :
|
|
FromString( m_sCurrItem, nVal) ;
|
|
nIdVT1[0] = abs( nVal) - 1 ; // in DXF indici 1 based, in STM 0 based
|
|
break ; // (negativi indicano edge nascosto)
|
|
case 72 :
|
|
FromString( m_sCurrItem, nVal) ;
|
|
nIdVT1[1] = abs( nVal) - 1 ;
|
|
break ;
|
|
case 73 :
|
|
FromString( m_sCurrItem, nVal) ;
|
|
nIdVT1[2] = abs( nVal) - 1 ;
|
|
break ;
|
|
case 74 :
|
|
FromString( m_sCurrItem, nVal) ;
|
|
nIdVT2[2] = abs( nVal) - 1 ;
|
|
break ;
|
|
}
|
|
} while ( nCode != 0) ;
|
|
UngetItem() ;
|
|
// se è un vertice
|
|
if ( ( nFlag & 128) != 0 && ( nFlag & 64) != 0)
|
|
nStat = 0 ;
|
|
// se è una faccia (formata da uno o due triangoli)
|
|
else if ( ( nFlag & 128) != 0) {
|
|
// se non c'è il secondo triangolo
|
|
if ( nIdVT2[2] == - 1)
|
|
nStat = 1 ;
|
|
else {
|
|
nStat = 2 ;
|
|
nIdVT2[0] = nIdVT1[0] ;
|
|
nIdVT2[1] = nIdVT1[2] ;
|
|
}
|
|
}
|
|
// altrimenti nulla
|
|
else
|
|
nStat = - 1 ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportDxf::ReadSolid( bool& bFileEnd)
|
|
{
|
|
Point3d ptP0 ;
|
|
Point3d ptP1 ;
|
|
Point3d ptP2 ;
|
|
Point3d ptP3 ;
|
|
Vector3d vtExtr( 0, 0, 1) ;
|
|
string sLayer ;
|
|
int nColor = COL_BYLAYER ;
|
|
// ciclo di lettura degli item di SOLID
|
|
bFileEnd = false ;
|
|
int nCode = CODE_NULL ;
|
|
do {
|
|
// leggo un Item
|
|
nCode = ReadNextItem() ;
|
|
if ( nCode == CODE_NULL) {
|
|
bFileEnd = true ;
|
|
return false ;
|
|
}
|
|
// eventuale gestione
|
|
switch ( nCode) {
|
|
case 8 :
|
|
sLayer = m_sCurrItem ;
|
|
break ;
|
|
case 10 :
|
|
FromString( m_sCurrItem, ptP0.x) ;
|
|
break ;
|
|
case 20 :
|
|
FromString( m_sCurrItem, ptP0.y) ;
|
|
break ;
|
|
case 30 :
|
|
FromString( m_sCurrItem, ptP0.z) ;
|
|
break ;
|
|
case 11 :
|
|
FromString( m_sCurrItem, ptP1.x) ;
|
|
break ;
|
|
case 21 :
|
|
FromString( m_sCurrItem, ptP1.y) ;
|
|
break ;
|
|
case 31 :
|
|
FromString( m_sCurrItem, ptP1.z) ;
|
|
break ;
|
|
case 12 :
|
|
FromString( m_sCurrItem, ptP2.x) ;
|
|
break ;
|
|
case 22 :
|
|
FromString( m_sCurrItem, ptP2.y) ;
|
|
break ;
|
|
case 32 :
|
|
FromString( m_sCurrItem, ptP2.z) ;
|
|
break ;
|
|
case 13 :
|
|
FromString( m_sCurrItem, ptP3.x) ;
|
|
break ;
|
|
case 23 :
|
|
FromString( m_sCurrItem, ptP3.y) ;
|
|
break ;
|
|
case 33 :
|
|
FromString( m_sCurrItem, ptP3.z) ;
|
|
break ;
|
|
case 62 :
|
|
FromString( m_sCurrItem, nColor) ;
|
|
break ;
|
|
case 210 :
|
|
FromString( m_sCurrItem, vtExtr.x) ;
|
|
break ;
|
|
case 220 :
|
|
FromString( m_sCurrItem, vtExtr.y) ;
|
|
break ;
|
|
case 230 :
|
|
FromString( m_sCurrItem, vtExtr.z) ;
|
|
break ;
|
|
}
|
|
} while ( nCode != 0) ;
|
|
UngetItem() ;
|
|
// eventuale aggiustamento del nome del layer per caratteri non ammessi
|
|
ValidateName( sLayer) ;
|
|
// gestisco eventuale OCS
|
|
if ( ! AreSameVectorExact( vtExtr, Z_AX)) {
|
|
Frame3d frOCS ;
|
|
if ( ! frOCS.Set( ORIG, vtExtr))
|
|
return false ;
|
|
// trasformo i punti
|
|
ptP0.ToGlob( frOCS) ;
|
|
ptP1.ToGlob( frOCS) ;
|
|
ptP2.ToGlob( frOCS) ;
|
|
ptP3.ToGlob( frOCS) ;
|
|
}
|
|
// gestisco il riferimento del gruppo di inserimento
|
|
ptP0.ToLoc( m_frGroup) ;
|
|
ptP1.ToLoc( m_frGroup) ;
|
|
ptP2.ToLoc( m_frGroup) ;
|
|
ptP3.ToLoc( m_frGroup) ;
|
|
// verifico se 3 o 4 punti
|
|
bool bQuad = ! AreSamePointNear( ptP2, ptP3) ;
|
|
// inserisco la faccia nel DB geometrico
|
|
// creo la trimesh
|
|
PtrOwner<ISurfTriMesh> pSTM( CreateSurfTriMesh()) ;
|
|
if ( ! IsValid( pSTM))
|
|
return false ;
|
|
// costruisco la geometria della trimesh
|
|
if ( ! pSTM->Init( 4, 2))
|
|
return false ;
|
|
if ( pSTM->AddVertex( ptP0) == SVT_NULL ||
|
|
pSTM->AddVertex( ptP1) == SVT_NULL ||
|
|
pSTM->AddVertex( ptP2) == SVT_NULL ||
|
|
( bQuad && pSTM->AddVertex( ptP3) == SVT_NULL))
|
|
return false ;
|
|
int nIdVertT0[3] = { 0, 1, 2} ;
|
|
int nIdVertT1[3] = { 2, 1, 3} ;
|
|
if ( pSTM->AddTriangle( nIdVertT0) == SVT_NULL ||
|
|
( bQuad && pSTM->AddTriangle( nIdVertT1) == SVT_NULL))
|
|
return false ;
|
|
if ( ! pSTM->AdjustTopology())
|
|
return false ;
|
|
// inserisco la trimesh nel DB
|
|
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, GetLayerId( sLayer), Release( pSTM)) ;
|
|
if ( nId == GDB_ID_NULL)
|
|
return false ;
|
|
// eventuale assegnazione del colore
|
|
Color cCol ;
|
|
if ( ColorFromACI( nColor, cCol)) {
|
|
if ( ! m_pGDB->SetMaterial( nId, cCol))
|
|
return false ;
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportDxf::ReadSpline( bool& bFileEnd)
|
|
{
|
|
PNTVECTOR vCPnt ;
|
|
vCPnt.reserve( 16) ;
|
|
Point3d ptP ;
|
|
string sLayer ;
|
|
int nColor = COL_BYLAYER ;
|
|
int nDegree = 0 ;
|
|
int nKnotNbr = 0 ;
|
|
int nCPntNbr = 0 ;
|
|
int nFlag = 0 ;
|
|
// ciclo di lettura degli item della linea
|
|
bFileEnd = false ;
|
|
int nContX = 0 ;
|
|
int nContY = 0 ;
|
|
int nContZ = 0 ;
|
|
int nCode = CODE_NULL ;
|
|
do {
|
|
// leggo un Item
|
|
nCode = ReadNextItem() ;
|
|
if ( nCode == CODE_NULL) {
|
|
bFileEnd = true ;
|
|
return false ;
|
|
}
|
|
// eventuale gestione
|
|
switch ( nCode) {
|
|
case 8 :
|
|
sLayer = m_sCurrItem ;
|
|
break ;
|
|
case 10 :
|
|
FromString( m_sCurrItem, ptP.x) ;
|
|
++ nContX ;
|
|
if ( nContX == nContY && nContY == nContZ)
|
|
vCPnt.push_back( ptP) ;
|
|
break ;
|
|
case 20 :
|
|
FromString( m_sCurrItem, ptP.y) ;
|
|
++ nContY ;
|
|
if ( nContX == nContY && nContY == nContZ)
|
|
vCPnt.push_back( ptP) ;
|
|
break ;
|
|
case 30 :
|
|
FromString( m_sCurrItem, ptP.z) ;
|
|
++ nContZ ;
|
|
if ( nContX == nContY && nContY == nContZ)
|
|
vCPnt.push_back( ptP) ;
|
|
break ;
|
|
case 62 :
|
|
FromString( m_sCurrItem, nColor) ;
|
|
break ;
|
|
case 70 :
|
|
FromString( m_sCurrItem, nFlag) ;
|
|
break ;
|
|
case 71 :
|
|
FromString( m_sCurrItem, nDegree) ;
|
|
break ;
|
|
case 72 :
|
|
FromString( m_sCurrItem, nKnotNbr) ;
|
|
break ;
|
|
case 73 :
|
|
FromString( m_sCurrItem, nCPntNbr) ;
|
|
break ;
|
|
}
|
|
} while ( nCode != 0) ;
|
|
UngetItem() ;
|
|
// eventuale aggiustamento del nome del layer per caratteri non ammessi
|
|
ValidateName( sLayer) ;
|
|
// Verifico il numero di punti di controllo
|
|
if ( vCPnt.size() != nCPntNbr || nCPntNbr < 2)
|
|
return false ;
|
|
// gestisco il riferimento del gruppo di inserimento
|
|
for ( int i = 0 ; i < nCPntNbr ; ++i)
|
|
vCPnt[i].ToLoc( m_frGroup) ;
|
|
// Creo la curva composita
|
|
PtrOwner<ICurveComposite> pCrvCompo( CreateCurveComposite()) ;
|
|
if ( ! IsValid( pCrvCompo))
|
|
return false ;
|
|
// Inserisco i punti nella curva composita come segmenti
|
|
if ( ! pCrvCompo->FromPointVector( vCPnt))
|
|
return false ;
|
|
// Se non sono state inserite curve, esco senza errore
|
|
if ( pCrvCompo->GetCurveNumber() == 0)
|
|
return true ;
|
|
// Inserisco la curva composita nel DB
|
|
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, GetLayerId( sLayer), Release( pCrvCompo)) ;
|
|
if ( nId == GDB_ID_NULL)
|
|
return false ;
|
|
// eventuale assegnazione del colore
|
|
Color cCol ;
|
|
if ( ColorFromACI( nColor, cCol)) {
|
|
if ( ! m_pGDB->SetMaterial( nId, cCol))
|
|
return false ;
|
|
}
|
|
return true ;
|
|
}
|