0dd44e569a
- in import DXF sistemata gestione SPLINE per modifiche a EgtGeomKernel.
2730 lines
84 KiB
C++
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 ;
|
|
}
|