Files
EgtExchange/ImportDxfEnts.cpp
Dario Sassi 0dd44e569a EgtExchange 2.5l3 :
- in import DXF sistemata gestione SPLINE per modifiche a EgtGeomKernel.
2023-12-18 19:57:02 +01:00

2730 lines
84 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/EGkStringUtils3d.h"
#include "/EgtDev/Include/EGkGeoPoint3d.h"
#include "/EgtDev/Include/EGkGeoVector3d.h"
#include "/EgtDev/Include/EGkCurveLine.h"
#include "/EgtDev/Include/EGkCurveArc.h"
#include "/EgtDev/Include/EGkCurveComposite.h"
#include "/EgtDev/Include/EGkCurveAux.h"
#include "/EgtDev/Include/EGkCurveByInterp.h"
#include "/EgtDev/Include/EGkSurfTriMesh.h"
#include "/EgtDev/Include/EGkExtText.h"
#include "/EgtDev/Include/EGkGdbIterator.h"
#include "/EgtDev/Include/EGnStringKeyVal.h"
#include "/EgtDev/Include/EgtStringEncoder.h"
#include "/EgtDev/Include/EgtPointerOwner.h"
#include <regex>
using namespace std ;
//----------------------------------------------------------------------------
const double RAY_LEN = 1000 ;
//----------------------------------------------------------------------------
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 Entità
if ( ReadOneEntity( sEntName, bOkLoc, bFileEnd))
;
// altrimenti ...
else {
string sOut = "ImportDxf : Skip entity " + sEntName +
" at line " + ToString( m_theScanner.GetCurrLineNbr()) ;
LOG_WARN( 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::ReadOneEntity( string& sEntName, bool& bOk, bool& bFileEnd)
{
// se Faccia 3d
if ( sEntName == "3DFACE") {
if ( ! Read3dFace( bFileEnd))
bOk = false ;
}
// se Arco
else if ( sEntName == "ARC") {
if ( ! ReadArc( bFileEnd))
bOk = false ;
}
// se AttDef (da saltare)
else if ( sEntName == "ATTDEF") {
if ( ! SkipEntity( bFileEnd))
bOk = false ;
}
// se Cerchio
else if ( sEntName == "CIRCLE") {
if ( ! ReadCircle( bFileEnd))
bOk = false ;
}
// se Ellisse
else if ( sEntName == "ELLIPSE") {
if ( ! ReadEllipse( bFileEnd))
bOk = false ;
}
// se Insert di Blocco
else if ( sEntName == "INSERT") {
if ( ! ReadInsert( bFileEnd))
bOk = false ;
}
// se Linea
else if ( sEntName == "LINE" || sEntName == "3DLINE") {
if ( ! ReadLine( bFileEnd))
bOk = false ;
}
// se LwPolyLine
else if ( sEntName == "LWPOLYLINE") {
if ( ! ReadLwPolyLine( bFileEnd))
bOk = false ;
}
// se MText
else if ( sEntName == "MTEXT") {
if ( ! ReadMText( bFileEnd))
bOk = false ;
}
// se Punto
else if ( sEntName == "POINT") {
if ( ! ReadPoint( bFileEnd))
bOk = false ;
}
// se PolyLine
else if ( sEntName == "POLYLINE") {
if ( ! ReadPolyLine( bFileEnd))
bOk = false ;
}
// se Ray (semiretta)
else if ( sEntName == "RAY") {
if ( ! ReadRayXline( true, bFileEnd))
bOk = false ;
}
// se 2D filled outline
else if ( sEntName == "SOLID") {
if ( ! ReadSolid( bFileEnd))
bOk = false ;
}
// se Spline
else if ( sEntName == "SPLINE") {
if ( ! ReadSpline( bFileEnd))
bOk = false ;
}
// se Text
else if ( sEntName == "TEXT") {
if ( ! ReadText( GDB_ID_NULL, bFileEnd))
bOk = false ;
}
// se XLINE (linea infinita)
else if ( sEntName == "XLINE") {
if ( ! ReadRayXline( false, bFileEnd))
bOk = false ;
}
// altrimenti
else {
return false ;
}
return true ;
}
//----------------------------------------------------------------------------
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::SetColor( int nId, int nColor, const string& sLayer)
{
Color cCol ;
if ( ColorFromACI( nColor, cCol)) {
if ( ! m_pGDB->SetMaterial( nId, cCol))
return false ;
}
else if ( BlockReading() && nColor == COL_BYLAYER && sLayer != "0") {
if ( m_pGDB->GetMaterial( GetLayerId( sLayer), cCol)) {
if ( ! m_pGDB->SetMaterial( nId, cCol))
return false ;
}
}
return true ;
}
//----------------------------------------------------------------------------
bool
ImportDxf::SetColorForInsert( int nId, int nIdS, const string& sLayer)
{
Color cCol ;
if ( m_pGDB->GetMaterial( nIdS, cCol)) {
if ( ! m_pGDB->SetMaterial( nId, cCol))
return false ;
}
else if ( sLayer != "0") {
if ( m_pGDB->GetMaterial( GetLayerId( sLayer), cCol)) {
if ( ! m_pGDB->SetMaterial( nId, cCol))
return false ;
}
}
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 nSpace = ENT_MODELSPACE ;
int nColor = COL_BYLAYER ;
int nHide = ENT_SHOW ;
// 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 60 :
FromString( m_sCurrItem, nSpace) ;
break ;
case 62 :
FromString( m_sCurrItem, nColor) ;
break ;
case 67 :
FromString( m_sCurrItem, nHide) ;
break ;
}
} while ( nCode != 0) ;
UngetItem() ;
// se entità in paperspace o nascosta, la salto
if ( nSpace == ENT_PAPERSPACE || nHide == ENT_HIDE)
return true ;
// eventuale aggiustamento del nome del layer per caratteri non ammessi
ValidateVal( sLayer) ;
// aggiusto per il fattore di scala
ptP0 *= m_dScaleFactor ;
ptP1 *= m_dScaleFactor ;
ptP2 *= m_dScaleFactor ;
ptP3 *= m_dScaleFactor ;
// gestisco il riferimento del gruppo di inserimento
if ( ! BlockReading()) {
ptP0.ToLoc( m_frGroup) ;
ptP1.ToLoc( m_frGroup) ;
ptP2.ToLoc( m_frGroup) ;
ptP3.ToLoc( m_frGroup) ;
}
// verifico se 3 o 4 punti
bool bQuad = ! AreSamePointApprox( ptP2, ptP3) ;
// inserisco la faccia nel DB geometrico
// creo la trimesh
PtrOwner<ISurfTriMesh> pSTM( CreateSurfTriMesh()) ;
if ( IsNull( 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 ;
// se non ci sono triangoli, non inserisco la trimesh e proseguo senza errore
if ( pSTM->GetTriangleCount() == 0)
return true ;
// inserisco la trimesh nel DB
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, GetGroupId( sLayer), Release( pSTM)) ;
if ( nId == GDB_ID_NULL)
return false ;
// eventuale assegnazione del colore
if ( ! SetColor( nId, nColor, sLayer))
return false ;
return true ;
}
//----------------------------------------------------------------------------
bool
ImportDxf::ReadArc( bool& bFileEnd)
{
Point3d ptCen ;
double dRadius ;
double dStartAng ;
double dEndAng ;
Vector3d vtExtr = Z_AX ;
double dThick = 0 ;
string sLayer ;
int nSpace = ENT_MODELSPACE ;
int nColor = COL_BYLAYER ;
int nHide = ENT_SHOW ;
// 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 39 :
FromString( m_sCurrItem, dThick) ;
break ;
case 40 :
FromString( m_sCurrItem, dRadius) ;
break ;
case 50 :
FromString( m_sCurrItem, dStartAng) ;
break ;
case 51 :
FromString( m_sCurrItem, dEndAng) ;
break ;
case 60 :
FromString( m_sCurrItem, nSpace) ;
break ;
case 62 :
FromString( m_sCurrItem, nColor) ;
break ;
case 67 :
FromString( m_sCurrItem, nHide) ;
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() ;
// se entità in paperspace o nascosta, la salto
if ( nSpace == ENT_PAPERSPACE || nHide == ENT_HIDE)
return true ;
// eventuale aggiustamento del nome del layer per caratteri non ammessi
ValidateVal( sLayer) ;
// aggiusto per il fattore di scala
ptCen *= m_dScaleFactor ;
dRadius *= m_dScaleFactor ;
dThick *= m_dScaleFactor ;
// calcolo l'angolo al centro (archi sempre CCW in DXF)
double dCentAng ;
if ( abs( 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 || abs( dCentAng) < EPS_ANG_SMALL)
return true ;
// versore iniziale
Vector3d 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
if ( ! BlockReading()) {
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 ( IsNull( pCrvArc))
return false ;
// setto l'arco
if ( ! pCrvArc->Set( ptCen, vtExtr, dRadius, vtStart, dCentAng, 0))
return false ;
// eventuale impostazione vettore estrusione e spessore
if ( abs( dThick) > EPS_SMALL) {
pCrvArc->SetExtrusion( vtExtr) ;
pCrvArc->SetThickness( dThick) ;
}
// inserisco l'arco nel DB
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, GetGroupId( sLayer), Release( pCrvArc)) ;
if ( nId == GDB_ID_NULL)
return false ;
// eventuale assegnazione del colore
if ( ! SetColor( nId, nColor, sLayer))
return false ;
return true ;
}
//----------------------------------------------------------------------------
bool
ImportDxf::ReadCircle( bool& bFileEnd)
{
Point3d ptCen ;
double dRadius ;
Vector3d vtExtr = Z_AX ;
double dThick = 0 ;
string sLayer ;
int nSpace = ENT_MODELSPACE ;
int nColor = COL_BYLAYER ;
int nHide = ENT_SHOW ;
// 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 39 :
FromString( m_sCurrItem, dThick) ;
break ;
case 40 :
FromString( m_sCurrItem, dRadius) ;
break ;
case 60 :
FromString( m_sCurrItem, nSpace) ;
break ;
case 62 :
FromString( m_sCurrItem, nColor) ;
break ;
case 67 :
FromString( m_sCurrItem, nHide) ;
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() ;
// se entità in paperspace o nascosta, la salto
if ( nSpace == ENT_PAPERSPACE || nHide == ENT_HIDE)
return true ;
// eventuale aggiustamento del nome del layer per caratteri non ammessi
ValidateVal( sLayer) ;
// aggiusto per il fattore di scala
ptCen *= m_dScaleFactor ;
dRadius *= m_dScaleFactor ;
dThick *= m_dScaleFactor ;
// 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
if ( ! BlockReading()) {
ptCen.ToLoc( m_frGroup) ;
vtExtr.ToLoc( m_frGroup) ;
}
// inserisco il cerchio nel DB geometrico
// creo il cerchio
PtrOwner<ICurveArc> pCrvArc( CreateCurveArc()) ;
if ( IsNull( pCrvArc))
return false ;
// setto il cerchio
if ( ! pCrvArc->Set( ptCen, vtExtr, dRadius))
return false ;
// eventuale impostazione vettore estrusione e spessore
if ( abs( dThick) > EPS_SMALL) {
pCrvArc->SetExtrusion( vtExtr) ;
pCrvArc->SetThickness( dThick) ;
}
// inserisco il cerchio nel DB
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, GetGroupId( sLayer), Release( pCrvArc)) ;
if ( nId == GDB_ID_NULL)
return false ;
// eventuale assegnazione del colore
if ( ! SetColor( nId, nColor, sLayer))
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 = Z_AX ;
string sLayer ;
int nSpace = ENT_MODELSPACE ;
int nColor = COL_BYLAYER ;
int nHide = ENT_SHOW ;
// 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 60 :
FromString( m_sCurrItem, nSpace) ;
break ;
case 62 :
FromString( m_sCurrItem, nColor) ;
break ;
case 67 :
FromString( m_sCurrItem, nHide) ;
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() ;
// se entità in paperspace o nascosta, la salto
if ( nSpace == ENT_PAPERSPACE || nHide == ENT_HIDE)
return true ;
// eventuale aggiustamento del nome del layer per caratteri non ammessi
ValidateVal( sLayer) ;
// aggiusto per il fattore di scala
ptCen *= m_dScaleFactor ;
vtMajorAx *= m_dScaleFactor ;
// 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 || abs( dCentAng) < EPS_ANG_SMALL)
return true ;
// versore iniziale
Vector3d vtStart = vtMajorAx ;
vtStart.Rotate( vtExtr, dStartPar * RADTODEG) ;
// gestisco il riferimento del gruppo di inserimento
if ( ! BlockReading()) {
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 ( IsNull( 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, GetGroupId( sLayer), Release( pCrvArc)) ;
if ( nId == GDB_ID_NULL)
return false ;
// eventuale scalatura
if ( abs( 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
if ( ! SetColor( nId, nColor, sLayer))
return false ;
return true ;
}
//----------------------------------------------------------------------------
bool
ImportDxf::ReadInsert( bool& bFileEnd)
{
InsertData insData ;
int nSpace = ENT_MODELSPACE ;
int nColor = COL_BYLAYER ;
int nHide = ENT_SHOW ;
bool bAttribs = false ;
// ciclo di lettura degli item del punto
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 2 :
insData.sName = m_sCurrItem ;
break ;
case 8 :
insData.sLayer = m_sCurrItem ;
break ;
case 10 :
FromString( m_sCurrItem, insData.ptP.x) ;
break ;
case 20 :
FromString( m_sCurrItem, insData.ptP.y) ;
break ;
case 30 :
FromString( m_sCurrItem, insData.ptP.z) ;
break ;
case 41 :
FromString( m_sCurrItem, insData.vtScale.x) ;
break ;
case 42 :
FromString( m_sCurrItem, insData.vtScale.y) ;
break ;
case 43 :
FromString( m_sCurrItem, insData.vtScale.z) ;
break ;
case 50 :
FromString( m_sCurrItem, insData.dRotAngDeg) ;
break ;
case 60 :
FromString( m_sCurrItem, nSpace) ;
break ;
case 62 :
FromString( m_sCurrItem, nColor) ;
break ;
case 66 :
FromString( m_sCurrItem, bAttribs) ;
break ;
case 67 :
FromString( m_sCurrItem, nHide) ;
break ;
case 210 :
FromString( m_sCurrItem, insData.vtExtr.x) ;
break ;
case 220 :
FromString( m_sCurrItem, insData.vtExtr.y) ;
break ;
case 230 :
FromString( m_sCurrItem, insData.vtExtr.z) ;
break ;
}
} while ( nCode != 0) ;
UngetItem() ;
// se entità in paperspace o nascosta, la salto
if ( nSpace == ENT_PAPERSPACE || nHide == ENT_HIDE) {
if ( bAttribs)
return ReadInsertAttribs( false, GDB_ID_NULL, bFileEnd) ;
return true ;
}
// eventuale aggiustamento del nome del blocco per caratteri non ammessi
ValidateVal( insData.sName) ;
// eventuale aggiustamento del nome del layer per caratteri non ammessi
ValidateVal( insData.sLayer) ;
// aggiusto per il fattore di scala
insData.ptP *= m_dScaleFactor ;
// calcolo riferimento di inserimento
Frame3d frOCS ;
if ( ! AreSameVectorExact( insData.vtExtr, Z_AX)) {
if ( ! frOCS.Set( ORIG, insData.vtExtr))
return false ;
}
// recupero l'identificativo del blocco
int nIdBlock = GetBlockId( insData.sName) ;
// se blocco non trovato o non risolto
if ( nIdBlock == GDB_ID_NULL || ! m_pGDB->ExistsInfo( nIdBlock, BLKOK_INFO)) {
// se sono in lettura blocchi
if ( BlockReading()) {
// incremento contatore blocchi inseriti ma non risolti
++ m_nNumNotBokInCurrBlock ;
// salvo un gruppo con i dati di inserimento
int nId = m_pGDB->AddGroup( GDB_ID_NULL, GetGroupId( insData.sLayer), GLOB_FRM) ;
if ( nId == GDB_ID_NULL || ! SaveInsertInfo( nId, insData))
return false ;
// se previsto, leggo eventuali attributi dipendenti dall'inserimento del blocco
if ( bAttribs)
return ReadInsertAttribs( true, GetGroupId( insData.sLayer), bFileEnd) ;
return true ;
}
// altrimenti errore
else
return false ;
}
// recupero il punto base del blocco per determinare lo spostamento
Point3d ptBase ;
m_pGDB->GetInfo( nIdBlock, POINT_INFO, ptBase) ;
Vector3d vtMove = insData.ptP - ptBase ;
// copio tutte le entità del blocco, trasformandole opportunamente
PtrOwner<IGdbIterator> pIter( CreateGdbIterator( m_pGDB)) ;
if ( IsNull( pIter))
return false ;
bool bFound = pIter->GoToFirstInGroup( nIdBlock) ;
while ( bFound) {
// copio l'entità geometrica
IGeoObj* pGeoS = pIter->GetGeoObj() ;
if ( pGeoS == nullptr)
return false ;
PtrOwner<IGeoObj> pGeo( pGeoS->Clone()) ;
if ( IsNull( pGeo))
return false ;
// inserisco l'entità nel DB
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, GetGroupId( insData.sLayer), Release( pGeo)) ;
if ( nId == GDB_ID_NULL)
return false ;
// eseguo le opportune trasformazioni
m_pGDB->Scale( nId, Frame3d( ptBase), insData.vtScale.x, insData.vtScale.y, insData.vtScale.z) ;
m_pGDB->Rotate( nId, ptBase, Z_AX, insData.dRotAngDeg) ;
m_pGDB->Translate( nId, vtMove) ;
m_pGDB->GetGeoObj( nId)->ToGlob( frOCS) ;
if ( ! BlockReading())
m_pGDB->GetGeoObj( nId)->ToLoc( m_frGroup) ;
// recupero il colore
if ( ! SetColorForInsert( nId, pIter->GetId(), insData.sLayer))
return false ;
// passo alla successiva
bFound = pIter->GoToNext() ;
}
// se previsto, leggo eventuali attributi dipendenti dall'inserimento del blocco
if ( bAttribs)
return ReadInsertAttribs( true, GetGroupId( insData.sLayer), bFileEnd) ;
return true ;
}
//----------------------------------------------------------------------------
bool
ImportDxf::ReadInsertAttribs( bool bSave, int nGroupId, bool& bFileEnd)
{
// Ciclo sugli Attrib, termino con SEQEND o errore
bFileEnd = false ;
bool bAttribsEnd = false ;
string sEntName ;
do {
// leggo intestazione entità, per avere il tipo
bool bOkLoc = GetEntityName( sEntName, bAttribsEnd, bFileEnd) ;
if ( bOkLoc && ! bAttribsEnd) {
// se Attrib
if ( sEntName == "ATTRIB") {
if ( bSave) {
if ( ! ReadText( nGroupId, bFileEnd))
bOkLoc = false ;
}
else {
if ( ! SkipEntity( bFileEnd))
bOkLoc = false ;
}
}
// se SeqEnd
else if ( sEntName == "SEQEND") {
if ( ! SkipEntity( bFileEnd))
bOkLoc = false ;
bAttribsEnd = 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( ! bAttribsEnd) ;
return true ;
}
//----------------------------------------------------------------------------
bool
ImportDxf::ReadLine( bool& bFileEnd)
{
Point3d ptStart ;
Point3d ptEnd ;
Vector3d vtExtr = Z_AX ;
double dThick = 0 ;
string sLayer ;
int nSpace = ENT_MODELSPACE ;
int nColor = COL_BYLAYER ;
int nHide = ENT_SHOW ;
// 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 39 :
FromString( m_sCurrItem, dThick) ;
break ;
case 60 :
FromString( m_sCurrItem, nSpace) ;
break ;
case 62 :
FromString( m_sCurrItem, nColor) ;
break ;
case 67 :
FromString( m_sCurrItem, nHide) ;
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() ;
// se entità in paperspace o nascosta, la salto
if ( nSpace == ENT_PAPERSPACE || nHide == ENT_HIDE)
return true ;
// eventuale aggiustamento del nome del layer per caratteri non ammessi
ValidateVal( sLayer) ;
// aggiusto per il fattore di scala
ptStart *= m_dScaleFactor ;
ptEnd *= m_dScaleFactor ;
dThick *= m_dScaleFactor ;
// se la linea è nulla, non la inserisco ma proseguo senza errore
if ( AreSamePointEpsilon( ptStart, ptEnd, 2 * EPS_SMALL))
return true ;
// gestisco il riferimento del gruppo di inserimento
if ( ! BlockReading()) {
ptStart.ToLoc( m_frGroup) ;
ptEnd.ToLoc( m_frGroup) ;
}
// inserisco la linea nel DB geometrico
// creo la linea
PtrOwner<ICurveLine> pCrvLine( CreateCurveLine()) ;
if ( IsNull( pCrvLine))
return false ;
// setto la linea
if ( ! pCrvLine->Set( ptStart, ptEnd))
return false ;
// eventuale impostazione vettore estrusione e spessore
if ( abs( dThick) > EPS_SMALL) {
pCrvLine->SetExtrusion( vtExtr) ;
pCrvLine->SetThickness( dThick) ;
}
// inserisco la linea nel DB
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, GetGroupId( sLayer), Release( pCrvLine)) ;
if ( nId == GDB_ID_NULL)
return false ;
// eventuale assegnazione del colore
if ( ! SetColor( nId, nColor, sLayer))
return false ;
return true ;
}
//----------------------------------------------------------------------------
bool
ImportDxf::ReadRayXline( bool bIsRay, bool& bFileEnd)
{
Point3d ptRef ;
Vector3d vtDir ;
string sLayer ;
int nSpace = ENT_MODELSPACE ;
int nColor = COL_BYLAYER ;
int nHide = ENT_SHOW ;
// ciclo di lettura degli item della Xlinea
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, ptRef.x) ;
break ;
case 20 :
FromString( m_sCurrItem, ptRef.y) ;
break ;
case 30 :
FromString( m_sCurrItem, ptRef.z) ;
break ;
case 11 :
FromString( m_sCurrItem, vtDir.x) ;
break ;
case 21 :
FromString( m_sCurrItem, vtDir.y) ;
break ;
case 31 :
FromString( m_sCurrItem, vtDir.z) ;
break ;
case 60 :
FromString( m_sCurrItem, nSpace) ;
break ;
case 62 :
FromString( m_sCurrItem, nColor) ;
break ;
case 67 :
FromString( m_sCurrItem, nHide) ;
break ;
}
} while ( nCode != 0) ;
UngetItem() ;
// se entità in paperspace o nascosta, la salto
if ( nSpace == ENT_PAPERSPACE || nHide == ENT_HIDE)
return true ;
// eventuale aggiustamento del nome del layer per caratteri non ammessi
ValidateVal( sLayer) ;
// aggiusto per il fattore di scala
ptRef *= m_dScaleFactor ;
// se la linea è nulla, non la inserisco ma proseguo senza errore
if ( vtDir.IsSmall())
return true ;
// gestisco il riferimento del gruppo di inserimento
if ( ! BlockReading()) {
ptRef.ToLoc( m_frGroup) ;
vtDir.ToLoc( m_frGroup) ;
}
// inserisco la linea nel DB geometrico
// creo la linea
PtrOwner<ICurveLine> pCrvLine( CreateCurveLine()) ;
if ( IsNull( pCrvLine))
return false ;
// setto la linea
Point3d ptStart = ptRef ;
if ( ! bIsRay)
ptStart -= RAY_LEN * vtDir ;
Point3d ptEnd = ptRef + RAY_LEN * vtDir ;
if ( ! pCrvLine->Set( ptStart, ptEnd))
return false ;
// inserisco la linea nel DB
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, GetGroupId( sLayer), Release( pCrvLine)) ;
if ( nId == GDB_ID_NULL)
return false ;
// eventuale assegnazione del colore
if ( ! SetColor( nId, nColor, sLayer))
return false ;
return true ;
}
//----------------------------------------------------------------------------
bool
ImportDxf::ReadLwPolyLine( bool& bFileEnd)
{
PolyArc PA ;
Vector3d vtExtr = Z_AX ;
double dElevation = 0 ;
double dThick = 0 ;
string sLayer ;
int nSpace = ENT_MODELSPACE ;
int nColor = COL_BYLAYER ;
int nHide = ENT_SHOW ;
int nNumVert = 0 ;
int nFlag = 0 ;
Point3d ptV ;
double dBulge = 0 ;
// 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, ptV.x) ;
++ nContX ;
if ( nContX == nContY)
PA.AddUPoint( 0, ptV, 0) ;
break ;
case 20 :
FromString( m_sCurrItem, ptV.y) ;
++ nContY ;
if ( nContX == nContY)
PA.AddUPoint( 0, ptV, 0) ;
break ;
case 38 :
FromString( m_sCurrItem, dElevation) ;
break ;
case 39 :
FromString( m_sCurrItem, dThick) ;
break ;
case 42 :
FromString( m_sCurrItem, dBulge) ;
PA.ModifyLastBulge( dBulge) ;
break ;
case 60 :
FromString( m_sCurrItem, nSpace) ;
break ;
case 62 :
FromString( m_sCurrItem, nColor) ;
break ;
case 67 :
FromString( m_sCurrItem, nHide) ;
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() ;
// se entità in paperspace o nascosta, la salto
if ( nSpace == ENT_PAPERSPACE || nHide == ENT_HIDE)
return true ;
// eventuale aggiustamento del nome del layer per caratteri non ammessi
ValidateVal( sLayer) ;
// Verifico il numero di vertici
if ( ( PA.GetPointNbr() + PA.GetRejectedNbr()) != nNumVert)
return false ;
if ( PA.GetPointNbr() < 2)
return true ;
// Se chiusa, aggiungo un punto uguale al primo in coda
if ( nFlag & 1) {
if ( PA.Close())
++ nNumVert ;
}
// aggiusto per il fattore di scala
dElevation *= m_dScaleFactor ;
dThick *= m_dScaleFactor ;
PA.Scale( GLOB_FRM, m_dScaleFactor) ;
// 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 ;
}
PA.SetElevation( dElevation) ;
PA.ToGlob( frOCS) ;
if ( ! BlockReading())
PA.ToLoc( m_frGroup) ;
// Creo la curva composita
PtrOwner<ICurveComposite> pCrvCompo( CreateCurveComposite()) ;
if ( IsNull( pCrvCompo))
return false ;
// Inserisco i punti con bulge nella curva composita come linee e archi
if ( ! pCrvCompo->FromPolyArc( PA))
return false ;
// Se non sono state inserite curve, esco senza errore
if ( pCrvCompo->GetCurveCount() == 0)
return true ;
// eventuale impostazione vettore estrusione e spessore
if ( abs( dThick) > EPS_SMALL) {
pCrvCompo->SetExtrusion( vtExtr) ;
pCrvCompo->SetThickness( dThick) ;
}
// Inserisco la curva composita nel DB
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, GetGroupId( sLayer), Release( pCrvCompo)) ;
if ( nId == GDB_ID_NULL)
return false ;
// eventuale assegnazione del colore
if ( ! SetColor( nId, nColor, sLayer))
return false ;
return true ;
}
//----------------------------------------------------------------------------
bool
ImportDxf::ReadPoint( bool& bFileEnd)
{
Point3d ptP ;
Vector3d vtExtr = Z_AX ;
double dThick = 0 ;
string sLayer ;
int nSpace = ENT_MODELSPACE ;
int nColor = COL_BYLAYER ;
int nHide = ENT_SHOW ;
// ciclo di lettura degli item del punto
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 39 :
FromString( m_sCurrItem, dThick) ;
break ;
case 60 :
FromString( m_sCurrItem, nSpace) ;
break ;
case 62 :
FromString( m_sCurrItem, nColor) ;
break ;
case 67 :
FromString( m_sCurrItem, nHide) ;
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() ;
// se entità in paperspace o nascosta, la salto
if ( nSpace == ENT_PAPERSPACE || nHide == ENT_HIDE)
return true ;
// eventuale aggiustamento del nome del layer per caratteri non ammessi
ValidateVal( sLayer) ;
// aggiusto per il fattore di scala
ptP *= m_dScaleFactor ;
dThick *= m_dScaleFactor ;
// gestisco il riferimento del gruppo di inserimento
if ( ! BlockReading())
ptP.ToLoc( m_frGroup) ;
// inserisco l'entità nel DB geometrico
PtrOwner<IGeoObj> pGeoObj ; ;
if ( abs( dThick) < EPS_SMALL) {
// creo il punto
PtrOwner<IGeoPoint3d> pGeoPnt( CreateGeoPoint3d()) ;
if ( IsNull( pGeoPnt))
return false ;
// setto il punto
if ( ! pGeoPnt->Set( ptP))
return false ;
// lo passo all'oggetto geometrico generico
pGeoObj.Set( pGeoPnt) ;
}
else {
// creo il vettore con punto base
PtrOwner<IGeoVector3d> pGeoVect( CreateGeoVector3d()) ;
if ( IsNull( pGeoVect))
return false ;
// setto il punto
if ( ! pGeoVect->Set( dThick * vtExtr, ptP))
return false ;
// lo passo all'oggetto geometrico generico
pGeoObj.Set( pGeoVect) ;
}
// inserisco l'entità nel DB
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, GetGroupId( sLayer), Release( pGeoObj)) ;
if ( nId == GDB_ID_NULL)
return false ;
// eventuale assegnazione del colore
if ( ! SetColor( nId, nColor, sLayer))
return false ;
return true ;
}
//----------------------------------------------------------------------------
bool
ImportDxf::ReadPolyLine( bool& bFileEnd)
{
Vector3d vtExtr = Z_AX ;
double dElevation = 0 ;
double dThick = 0 ;
string sLayer ;
int nSpace = ENT_MODELSPACE ;
int nColor = COL_BYLAYER ;
int nHide = ENT_SHOW ;
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 39 :
FromString( m_sCurrItem, dThick) ;
break ;
case 60 :
FromString( m_sCurrItem, nSpace) ;
break ;
case 62 :
FromString( m_sCurrItem, nColor) ;
break ;
case 67 :
FromString( m_sCurrItem, nHide) ;
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() ;
// se entità in paperspace o nascosta, la salto
bool bToSave = true ;
if ( nSpace == ENT_PAPERSPACE || nHide == ENT_HIDE)
bToSave = false ;
// eventuale aggiustamento del nome del layer per caratteri non ammessi
ValidateVal( sLayer) ;
// Se Polygon Mesh
if ( ( nFlag & 16) != 0)
return CompletePolygonMesh( sLayer, nColor, nFlag, bToSave,
dElevation, vtExtr, nNumVertM, nNumVertN, bFileEnd) ;
// se Polyface Mesh
else if ( ( nFlag & 64) != 0)
return CompletePolyfaceMesh( sLayer, nColor, nFlag, bToSave, dElevation, vtExtr, bFileEnd) ;
// altrimenti PolyLine vera e propria
else
return CompletePolyLine( sLayer, nColor, nFlag, bToSave, dElevation, dThick, vtExtr, bFileEnd) ;
}
//----------------------------------------------------------------------------
bool
ImportDxf::CompletePolyLine( const string& sLayer, int nColor, int nFlag, bool bToSave,
double dElevation, double dThick, const Vector3d& vtExtr, bool& bFileEnd)
{
int nNumVert = 0 ;
PolyArc PA ;
Point3d ptV ;
double dBulge = 0 ;
// 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( ptV, dBulge, bFileEnd))
bOkLoc = false ;
// se polilinea 3d non sono ammessi archi (bulge = 0)
if ( bIs3d)
dBulge = 0 ;
// altrimenti polilinea 2d quindi z = 0
else
ptV.z = 0 ;
PA.AddUPoint( 0, ptV, dBulge) ;
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 entità da saltare, esco
if ( ! bToSave)
return true ;
// Verifico il numero di vertici
if ( ( PA.GetPointNbr() + PA.GetRejectedNbr()) != nNumVert)
return false ;
if ( PA.GetPointNbr() < 2)
return true ;
// Se chiusa, aggiungo un punto uguale al primo in coda
if ( nFlag & 1) {
if ( PA.Close())
++ nNumVert ;
}
// aggiusto per il fattore di scala
dElevation *= m_dScaleFactor ;
dThick *= m_dScaleFactor ;
PA.Scale( GLOB_FRM, m_dScaleFactor) ;
// 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 ;
}
PA.AddElevation( dElevation) ;
PA.ToGlob( frOCS) ;
if ( ! BlockReading())
PA.ToLoc( m_frGroup) ;
// Creo la curva composita
PtrOwner<ICurveComposite> pCrvCompo( CreateCurveComposite()) ;
if ( IsNull( pCrvCompo))
return false ;
// Inserisco i punti con bulge nella curva composita come linee e archi
if ( ! pCrvCompo->FromPolyArc( PA))
return false ;
// Se non sono state inserite curve, esco senza errore
if ( pCrvCompo->GetCurveCount() == 0)
return true ;
// eventuale impostazione vettore estrusione e spessore
if ( abs( dThick) > EPS_SMALL) {
pCrvCompo->SetExtrusion( vtExtr) ;
pCrvCompo->SetThickness( dThick) ;
}
// Inserisco la curva composita nel DB
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, GetGroupId( sLayer), Release( pCrvCompo)) ;
if ( nId == GDB_ID_NULL)
return false ;
// eventuale assegnazione del colore
if ( ! SetColor( nId, nColor, sLayer))
return false ;
return true ;
}
//----------------------------------------------------------------------------
bool
ImportDxf::ReadPolyLineVertex( Point3d& ptP, double& dBulge, bool& bFileEnd)
{
// inizializzo il punto con bulge
ptP.Set( 0, 0, 0) ;
dBulge = 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 ;
case 42 :
FromString( m_sCurrItem, dBulge) ;
break ;
}
} while ( nCode != 0) ;
UngetItem() ;
return true ;
}
//----------------------------------------------------------------------------
bool
ImportDxf::CompletePolygonMesh( const string& sLayer, int nColor, int nFlag, bool bToSave,
double dElevation, const Vector3d& vtExtr, int nNumVertM, int nNumVertN, bool& bFileEnd)
{
// creo la superficie
PtrOwner<ISurfTriMesh> pSTM( CreateSurfTriMesh()) ;
if ( IsNull( 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 ;
// aggiusto per il fattore di scala
ptP *= m_dScaleFactor ;
// sistemazioni per elevazione, eventuale OCS e riferimento del gruppo di inserimento
ptP.z += dElevation ;
ptP.ToGlob( frOCS) ;
if ( ! BlockReading())
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) ;
// Se entità da saltare, esco
if ( ! bToSave)
return true ;
// 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 - 1) ? ( nIdVT1[0] + 1) : ( i * nNumVertN)) ;
nIdVT1[2] = (( i < nNumVertM - 1) ? ( nIdVT1[1] + nNumVertN) : ( j + 1)) ;
// secondo triangolo
nIdVT2[0] = nIdVT1[0] ;
nIdVT2[1] = nIdVT1[2] ;
nIdVT2[2] = (( i < nNumVertM - 1) ? ( 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 ;
// se non ci sono triangoli, non inserisco la trimesh e proseguo senza errore
if ( pSTM->GetTriangleCount() == 0)
return true ;
// inserisco la trimesh nel DB
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, GetGroupId( sLayer), Release( pSTM)) ;
if ( nId == GDB_ID_NULL)
return false ;
// eventuale assegnazione del colore
if ( ! SetColor( nId, nColor, sLayer))
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, bool bToSave,
double dElevation, const Vector3d& vtExtr, bool& bFileEnd)
{
// creo la superficie
PtrOwner<ISurfTriMesh> pSTM( CreateSurfTriMesh()) ;
if ( IsNull( 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
// aggiusto per il fattore di scala
ptP *= m_dScaleFactor ;
// sistemazioni per elevazione, eventuale OCS e riferimento del gruppo di inserimento
ptP.z += dElevation ;
ptP.ToGlob( frOCS) ;
if ( ! BlockReading())
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) ;
// se entità da saltare, esco
if ( ! bToSave)
return true ;
// valido la superficie e calcolo le adiacenze
if ( ! pSTM->AdjustTopology())
return false ;
// se non ci sono triangoli, non inserisco la trimesh e proseguo senza errore
if ( pSTM->GetTriangleCount() == 0)
return true ;
// inserisco la trimesh nel DB
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, GetGroupId( sLayer), Release( pSTM)) ;
if ( nId == GDB_ID_NULL)
return false ;
// eventuale assegnazione del colore
if ( ! SetColor( nId, nColor, sLayer))
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 = Z_AX ;
string sLayer ;
int nSpace = ENT_MODELSPACE ;
int nColor = COL_BYLAYER ;
int nHide = ENT_SHOW ;
// 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 60 :
FromString( m_sCurrItem, nSpace) ;
break ;
case 62 :
FromString( m_sCurrItem, nColor) ;
break ;
case 67 :
FromString( m_sCurrItem, nHide) ;
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() ;
// se entità in paperspace o nascosta, la salto
if ( nSpace == ENT_PAPERSPACE || nHide == ENT_HIDE)
return true ;
// eventuale aggiustamento del nome del layer per caratteri non ammessi
ValidateVal( sLayer) ;
// aggiusto per il fattore di scala
ptP0 *= m_dScaleFactor ;
ptP1 *= m_dScaleFactor ;
ptP2 *= m_dScaleFactor ;
ptP3 *= m_dScaleFactor ;
// 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
if ( ! BlockReading()) {
ptP0.ToLoc( m_frGroup) ;
ptP1.ToLoc( m_frGroup) ;
ptP2.ToLoc( m_frGroup) ;
ptP3.ToLoc( m_frGroup) ;
}
// verifico se 3 o 4 punti
bool bQuad = ! AreSamePointApprox( ptP2, ptP3) ;
// inserisco la faccia nel DB geometrico
// creo la trimesh
PtrOwner<ISurfTriMesh> pSTM( CreateSurfTriMesh()) ;
if ( IsNull( 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 nIdT0 = pSTM->AddTriangle( nIdVertT0) ;
int nIdVertT1[3] = { 2, 1, 3} ;
int nIdT1 = ( bQuad ? pSTM->AddTriangle( nIdVertT1) : SVT_DEL) ;
if ( nIdT0 == SVT_NULL || nIdT1 == SVT_NULL)
return false ;
if ( nIdT0 == SVT_DEL && nIdT1 == SVT_DEL)
return true ;
if ( ! pSTM->AdjustTopology())
return false ;
// se non ci sono triangoli, non inserisco la trimesh e proseguo senza errore
if ( pSTM->GetTriangleCount() == 0)
return true ;
// inserisco la trimesh nel DB
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, GetGroupId( sLayer), Release( pSTM)) ;
if ( nId == GDB_ID_NULL)
return false ;
// eventuale assegnazione del colore
if ( ! SetColor( nId, nColor, sLayer))
return false ;
return true ;
}
//----------------------------------------------------------------------------
bool
ImportDxf::ReadSpline( bool& bFileEnd)
{
CNurbsData cnData ;
cnData.vU.reserve( 16) ;
cnData.vCP.reserve( 16) ;
cnData.vW.reserve( 16) ;
PNTVECTOR vIntPnt ;
double dTemp ;
Point3d ptP ;
Point3d ptInt ;
string sLayer ;
int nSpace = ENT_MODELSPACE ;
int nColor = COL_BYLAYER ;
int nHide = ENT_SHOW ;
int nKnotNbr = 0 ;
int nCPntNbr = 0 ;
int nIPntNbr = 0 ;
int nFlag = 0 ;
// ciclo di lettura degli item della linea
bFileEnd = false ;
int nContX = 0 ;
int nContY = 0 ;
int nContZ = 0 ;
int nIntX = 0 ;
int nIntY = 0 ;
int nIntZ = 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)
cnData.vCP.push_back( ptP) ;
break ;
case 20 :
FromString( m_sCurrItem, ptP.y) ;
++ nContY ;
if ( nContX == nContY && nContY == nContZ)
cnData.vCP.push_back( ptP) ;
break ;
case 30 :
FromString( m_sCurrItem, ptP.z) ;
++ nContZ ;
if ( nContX == nContY && nContY == nContZ)
cnData.vCP.push_back( ptP) ;
break ;
case 11 :
FromString( m_sCurrItem, ptInt.x) ;
++ nIntX ;
if ( nIntX == nIntY && nIntY == nIntZ)
vIntPnt.push_back( ptInt) ;
break ;
case 21 :
FromString( m_sCurrItem, ptInt.y) ;
++ nIntY ;
if ( nIntX == nIntY && nIntY == nIntZ)
vIntPnt.push_back( ptInt) ;
break ;
case 31 :
FromString( m_sCurrItem, ptInt.z) ;
++ nIntZ ;
if ( nIntX == nIntY && nIntY == nIntZ)
vIntPnt.push_back( ptInt) ;
break ;
case 40 :
FromString( m_sCurrItem, dTemp) ;
cnData.vU.push_back( dTemp) ;
break;
case 41 :
FromString( m_sCurrItem, dTemp) ;
cnData.vW.push_back( dTemp) ;
break;
case 60 :
FromString( m_sCurrItem, nSpace) ;
break ;
case 62 :
FromString( m_sCurrItem, nColor) ;
break ;
case 67 :
FromString( m_sCurrItem, nHide) ;
break ;
case 70 :
FromString( m_sCurrItem, nFlag) ;
break ;
case 71 :
FromString( m_sCurrItem, cnData.nDeg) ;
break ;
case 72 :
FromString( m_sCurrItem, nKnotNbr) ;
break ;
case 73 :
FromString( m_sCurrItem, nCPntNbr) ;
break ;
case 74 :
FromString( m_sCurrItem, nIPntNbr) ;
break ;
}
} while ( nCode != 0) ;
UngetItem() ;
// se entità in paperspace o nascosta, la salto
if ( nSpace == ENT_PAPERSPACE || nHide == ENT_HIDE)
return true ;
// eventuale aggiustamento del nome del layer per caratteri non ammessi
ValidateVal( sLayer) ;
// se spline con soli punti di interpolazione
if ( ( cnData.vU.size() == 0 || cnData.vCP.size() == 0) &&
vIntPnt.size() == nIPntNbr && nIPntNbr >= 2) {
// se curva chiusa e l'ultimo punto non uguaglia il primo, copio il primo in coda
if ( (( nFlag & SPL_CLOSED) != 0) && ! AreSamePointApprox( vIntPnt.front(), vIntPnt.back()))
vIntPnt.push_back( vIntPnt.front()) ;
// aggiusto per il fattore di scala
for ( int i = 0 ; i < nIPntNbr ; ++i)
vIntPnt[i] *= m_dScaleFactor ;
// gestisco il riferimento del gruppo di inserimento
if ( ! BlockReading()) {
for ( int i = 0 ; i < nIPntNbr ; ++i)
vIntPnt[i].ToLoc( m_frGroup) ;
}
// calcolo la curva interpolata
CurveByInterp crvByInterp ;
for ( int i = 0 ; i < int( vIntPnt.size()) ; ++ i)
crvByInterp.AddPoint( vIntPnt[i]) ;
PtrOwner<ICurve> pCrv( crvByInterp.GetCurve( CurveByInterp::BESSEL, CurveByInterp::CUBIC_BEZIERS)) ;
if ( IsNull( pCrv))
return false ;
// Inserisco la curva nel DB
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, GetGroupId( sLayer), Release( pCrv)) ;
if ( nId == GDB_ID_NULL)
return false ;
// eventuale assegnazione del colore
if ( ! SetColor( nId, nColor, sLayer))
return false ;
return true ;
}
// assegnazione flag
cnData.bRat = (( nFlag & SPL_RATIONAL) != 0) ;
cnData.bPeriodic = (( nFlag & SPL_PERIODIC) != 0 && ( nKnotNbr != nCPntNbr + cnData.nDeg + 1)) ;
cnData.bClosed = (( nFlag & SPL_CLOSED) != 0) ;
cnData.bClamped = true ;
cnData.bExtraKnotes = true ;
// Verifico il numero di nodi
if ( cnData.vU.size() != nKnotNbr || nKnotNbr < 4)
return false ;
// Verifico il numero di punti di controllo
if ( cnData.vCP.size() != nCPntNbr || nCPntNbr < 2)
return false ;
// Verifico il numero dei pesi
if ( cnData.bRat && cnData.vW.size() != nCPntNbr)
return false ;
// aggiusto per il fattore di scala
for ( int i = 0 ; i < nCPntNbr ; ++i)
cnData.vCP[i] *= m_dScaleFactor ;
// gestisco il riferimento del gruppo di inserimento
if ( ! BlockReading()) {
for ( int i = 0 ; i < nCPntNbr ; ++i)
cnData.vCP[i].ToLoc( m_frGroup) ;
}
// rendo canonica la rappresentazione della curva Nurbs
if ( ! NurbsCurveCanonicalize( cnData))
return false ;
// creo la curva equivalente alla Nurbs
PtrOwner<ICurve> pCrv( NurbsToBezierCurve( cnData)) ;
if ( IsNull( pCrv))
return false ;
if ( ! pCrv->IsValid())
return true ;
// Inserisco la curva composita nel DB
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, GetGroupId( sLayer), Release( pCrv)) ;
if ( nId == GDB_ID_NULL)
return false ;
// eventuale assegnazione del colore
if ( ! SetColor( nId, nColor, sLayer))
return false ;
return true ;
}
//----------------------------------------------------------------------------
bool
ImportDxf::ReadText( int nGroupId, bool& bFileEnd)
{
Point3d ptP ;
Vector3d vtExtr = Z_AX ;
string sText ;
string sLayer ;
string sStyle = "STANDARD" ;
double dH ;
double dAngDeg = 0 ;
double dRat = 1 ;
int nSpace = ENT_MODELSPACE ;
int nColor = COL_BYLAYER ;
int nHide = ENT_SHOW ;
// 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 1 :
sText = m_sCurrItem ;
break ;
case 7 :
sStyle = m_sCurrItem ;
break ;
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 40 :
FromString( m_sCurrItem, dH) ;
break ;
case 41 :
FromString( m_sCurrItem, dRat) ;
break ;
case 50 :
FromString( m_sCurrItem, dAngDeg) ;
break ;
case 60 :
FromString( m_sCurrItem, nSpace) ;
break ;
case 62 :
FromString( m_sCurrItem, nColor) ;
break ;
case 67 :
FromString( m_sCurrItem, nHide) ;
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() ;
// se entità in paperspace o nascosta, la salto
if ( nSpace == ENT_PAPERSPACE || nHide == ENT_HIDE)
return true ;
// eventuale aggiustamento del nome del layer per caratteri non ammessi
ValidateVal( sLayer) ;
// eventuale aggiustamento dello stile per caratteri non ammessi e trasformazione in maiuscolo
ValidateVal( sStyle) ;
ToUpper( sStyle) ;
// aggiusto per il fattore di scala
ptP *= m_dScaleFactor ;
dH *= m_dScaleFactor ;
// versore iniziale
Vector3d vtDir = FromPolar( 1, dAngDeg) ;
// gestisco eventuale OCS
if ( ! AreSameVectorExact( vtExtr, Z_AX)) {
Frame3d frOCS ;
if ( ! frOCS.Set( ORIG, vtExtr))
return false ;
// trasformo il centro e il versore iniziale
ptP.ToGlob( frOCS) ;
vtDir.ToGlob( frOCS) ;
}
// gestisco il riferimento del gruppo di inserimento
if ( ! BlockReading()) {
ptP.ToLoc( m_frGroup) ;
vtExtr.ToLoc( m_frGroup) ;
vtDir.ToLoc( m_frGroup) ;
}
// aggiusto i caratteri
AdjustText( sText) ;
// se testo è nullo, non lo inserisco ma proseguo senza errore
if ( sText.empty())
return true ;
// recupero lo stile
string sFont ;
double dHStyle ;
double dRatStyle ;
GetStyleData( sStyle, sFont, dHStyle, dRatStyle) ;
if ( abs( dH) < EPS_SMALL)
dH = dHStyle ;
if ( abs( dRat) < EPS_SMALL)
dRat = dRatStyle ;
// il punto di inserimento è sempre ETXT_IPBL
// inserisco il testo nel DB geometrico
// creo il testo
PtrOwner<IExtText> pTXT( CreateExtText()) ;
if ( IsNull( pTXT))
return false ;
// setto il testo
if ( ! pTXT->Set( ptP, vtExtr, vtDir, sText, sFont, 400, false, dH, dRat, 0, ETXT_IPBL))
return false ;
// inserisco il testo nel DB
if ( nGroupId == GDB_ID_NULL)
nGroupId = GetGroupId( sLayer) ;
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, nGroupId, Release( pTXT)) ;
if ( nId == GDB_ID_NULL)
return false ;
// eventuale assegnazione del colore
if ( ! SetColor( nId, nColor, sLayer))
return false ;
return true ;
}
//----------------------------------------------------------------------------
bool
ImportDxf::AdjustText( string& sText)
{
// se non è testo UTF-8, tento di convertirlo secondo codepage dichiarata nel DXF
if ( ! IsTextUtf8( sText.c_str())) {
sText = LPSTR( WtoA( LPWSTR( AtoW( sText.c_str(), m_nCodePage)))) ;
}
// converto la codifica Unicode di AutoCad ( "\\U+NNNN")
size_t nPos ;
while ( ( nPos = sText.find( "\\U+")) != string::npos) {
string sCode = (( sText.size() > nPos + 3) ? sText.substr( nPos+3, 4) : "") ;
unsigned int nCode = 127 ;
sscanf_s( sCode.c_str(), "%x", &nCode) ;
// converto diametro in O maiuscolo barrato
if ( nCode == 8709)
nCode = 216 ;
string sVal ;
if ( ! SetCodePoint( nCode, sVal))
sVal = "\7F" ; // carattere di errore 127
ReplaceString( sText, "\\U+" + sCode, sVal) ;
}
// trasformazione caratteri di controllo (per ora solo alcuni)
ReplaceString( sText, "^I", " ") ;
ReplaceString( sText, "^J", " ") ;
ReplaceString( sText, "^ ", "^") ;
// se non ci sono "%%" posso uscire
if ( sText.find( "%%") == string::npos)
return true ;
// salvo codifica di singoli '%'
ReplaceString( sText, "%%%", "§§") ;
// elimino segnalazioni overscore e underscore
ReplaceString( sText, "%%o", "") ;
ReplaceString( sText, "%%O", "") ;
ReplaceString( sText, "%%u", "") ;
ReplaceString( sText, "%%U", "") ;
// per gradi, più o meno e diametro
ReplaceString( sText, "%%d", LPSTR( WtoA( L"°"))) ;
ReplaceString( sText, "%%D", LPSTR( WtoA( L"°"))) ;
ReplaceString( sText, "%%p", LPSTR( WtoA( L"±"))) ;
ReplaceString( sText, "%%P", LPSTR( WtoA( L"±"))) ;
ReplaceString( sText, "%%c", LPSTR( WtoA( L"Ø"))) ;
ReplaceString( sText, "%%C", LPSTR( WtoA( L"Ø"))) ;
// eventuali "%%" rimasti vanno eliminati
ReplaceString( sText, "%%", "") ;
// ripristino singoli '%'
ReplaceString( sText, "§§", "%") ;
return true ;
}
//----------------------------------------------------------------------------
bool
ImportDxf::ReadMText( bool& bFileEnd)
{
Point3d ptP ;
Vector3d vtExtr = Z_AX ;
Vector3d vtDirG = V_NULL ;
string sText ;
string sLayer ;
string sStyle = "STANDARD" ;
double dH ;
double dTextMaxWidth = 0 ;
double dAngRad = 0 ;
int nInsPos = ETXT_IPBL ;
int nSpace = ENT_MODELSPACE ;
int nColor = COL_BYLAYER ;
int nHide = ENT_SHOW ;
// ciclo di lettura degli item della linea
bFileEnd = false ;
bool bEmbObj = false ;
int nCode = CODE_NULL ;
do {
// leggo un Item
nCode = ReadNextItem() ;
if ( nCode == CODE_NULL) {
bFileEnd = true ;
return false ;
}
// se Embedded Obj da saltare
if ( bEmbObj)
continue ;
// eventuale gestione
switch ( nCode) {
case 1 :
sText += m_sCurrItem ;
break ;
case 3 :
sText += m_sCurrItem ;
break ;
case 7 :
sStyle = m_sCurrItem ;
break ;
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 11 :
FromString( m_sCurrItem, vtDirG.x) ;
break ;
case 21 :
FromString( m_sCurrItem, vtDirG.y) ;
break ;
case 31 :
FromString( m_sCurrItem, vtDirG.z) ;
break ;
case 40 :
FromString( m_sCurrItem, dH) ;
break ;
case 41 :
FromString( m_sCurrItem, dTextMaxWidth) ;
break ;
case 50 :
FromString( m_sCurrItem, dAngRad) ;
break ;
case 60 :
FromString( m_sCurrItem, nSpace) ;
break ;
case 62 :
FromString( m_sCurrItem, nColor) ;
break ;
case 67 :
FromString( m_sCurrItem, nHide) ;
break ;
case 71 :
FromString( m_sCurrItem, nInsPos) ;
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 ;
case 101 :
// per saltare gli Embedded Objects di DXF 2018 (sembra siano solo negli MTEXT)
bEmbObj = true ;
break ;
}
} while ( nCode != 0) ;
UngetItem() ;
// se entità in paperspace o nascosta, la salto
if ( nSpace == ENT_PAPERSPACE || nHide == ENT_HIDE)
return true ;
// eventuale aggiustamento del nome del layer per caratteri non ammessi
ValidateVal( sLayer) ;
// eventuale aggiustamento dello stile per caratteri non ammessi e trasformazione in maiuscolo
ValidateVal( sStyle) ;
ToUpper( sStyle) ;
// aggiusto per il fattore di scala
ptP *= m_dScaleFactor ;
dH *= m_dScaleFactor ;
// versore iniziale (da angolo)
Vector3d vtDir = FromPolar( 1, dAngRad * RADTODEG) ;
// gestisco eventuale OCS
if ( ! AreSameVectorExact( vtExtr, Z_AX)) {
Frame3d frOCS ;
if ( ! frOCS.Set( ORIG, vtExtr))
return false ;
// il punto è già in globale
// trasformo solo il versore iniziale dato come angolo
vtDir.ToGlob( frOCS) ;
}
// scelgo direzione
if ( vtDirG.IsSmall())
vtDirG = vtDir ;
// gestisco il riferimento del gruppo di inserimento
if ( ! BlockReading()) {
ptP.ToLoc( m_frGroup) ;
vtExtr.ToLoc( m_frGroup) ;
vtDirG.ToLoc( m_frGroup) ;
}
// recupero lo stile ( utilizzo font e aspect-ratio)
string sFont ;
double dHStyle ;
double dRatStyle ;
GetStyleData( sStyle, sFont, dHStyle, dRatStyle) ;
if ( dRatStyle < EPS_SMALL)
dRatStyle = 1 ;
// aggiusto i caratteri
AdjustMText( sText, dTextMaxWidth, dH * dRatStyle) ;
// se testo è nullo, non lo inserisco ma proseguo senza errore
if ( sText.empty())
return true ;
// inserisco il testo nel DB geometrico
// creo il testo
PtrOwner<IExtText> pTXT( CreateExtText()) ;
if ( IsNull( pTXT))
return false ;
// setto il testo
if ( ! pTXT->Set( ptP, vtExtr, vtDirG, sText, sFont, 400, false, dH, dRatStyle, 0, nInsPos))
return false ;
// inserisco il testo nel DB
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, GetGroupId( sLayer), Release( pTXT)) ;
if ( nId == GDB_ID_NULL)
return false ;
// eventuale assegnazione del colore
if ( ! SetColor( nId, nColor, sLayer))
return false ;
return true ;
}
//----------------------------------------------------------------------------
bool
ImportDxf::AdjustMText( string& sText, double dTextMaxWidth, double dW)
{
// sostituzioni valide anche per testi semplici
if ( ! AdjustText( sText))
return false ;
// gestione "\\\\"
ReplaceString( sText, "\\\\", "çç") ;
// elimino \L \k
sText = regex_replace( sText, regex( "\\\\[LlOoKk]"), string( "")) ;
// elimino \p...; \T...;
sText = regex_replace( sText, regex( "\\\\[pQHWFfACT][^;]*;"), string( "")) ;
// trasformo \Sxxx; in xxx
sText = regex_replace( sText, regex( "\\\\[S]([^;]*);"), string( "$1")) ;
// traformo "\~" in ' '
ReplaceString( sText, "\\~", " ") ;
// trasformo "\P" in "\n"
ReplaceString( sText, "\\P", "\n") ;
// cancello '{' e '}' trasformo "\{" in '{' e "\}" in'}'
ReplaceString( sText, "\\{", "§§") ;
ReplaceString( sText, "{", "") ;
ReplaceString( sText, "§§", "{") ;
ReplaceString( sText, "\\}", "§§") ;
ReplaceString( sText, "}", "") ;
ReplaceString( sText, "§§", "}") ;
// trasformo "\\" in '\'
ReplaceString( sText, "çç", "\\") ;
// se richiesto controllo lunghezza massima
if ( dTextMaxWidth > EPS_SMALL) {
// ATT : NON SONO GESTITI I CODICI UNICODE !!!
// coefficiente empirico che in generale migliora l'adattamento
const double COEFF_LARGH = 1.2 ;
// gestione max lunghezza riga di testo
size_t nLastSp = - 1 ;
double dCurrWidth = 0 ;
for ( size_t i = 0 ; i < sText.size() ; ++ i) {
// posso dividere solo sugli spazi
if ( sText[i] == ' ')
nLastSp = i ;
// se c'è già un a capo
if ( sText[i] == '\n') {
dCurrWidth = 0 ;
nLastSp = - 1 ;
}
// se supera il limite
else if ( dCurrWidth > COEFF_LARGH * dTextMaxWidth) {
// se nella riga c'è già uno spazio
if ( nLastSp != - 1) {
sText.replace( nLastSp, 1, ETXT_LINEBREAK) ;
dCurrWidth = ( i - nLastSp) * dW ;
i += ETXT_LINEBREAK.size() - 1 ;
nLastSp = - 1 ;
}
}
// incremento la larghezza corrente
else
// larghezza con compensazione empirica
if ( sText[i] == ' ' || sText[i] == '"')
dCurrWidth += 0.6 * dW ;
else if ( sText[i] == 'i' || sText[i] == 'l' || sText[i] == '!' ||
sText[i] == '.' || sText[i] == ',' || sText[i] == ':' ||
sText[i] == ';' || sText[i] == '\'')
dCurrWidth += 0.3 * dW ;
else
dCurrWidth += dW ;
}
}
// sostituzione finale di eventuali line break da utente
ReplaceString( sText, "\n", ETXT_LINEBREAK) ;
return true ;
}