dust3d/thirdparty/cgal/CGAL-4.13/include/CGAL/IO/Dxf_writer.h

290 lines
7.5 KiB
C++
Executable File

// Copyright (c) 2007 GeometryFactory (France). All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: LGPL-3.0+
//
//
// Author(s) : Fernando Cacciola
//
// Description of the file format can be found at the following address:
// http://www.autodesk.com/techpubs/autocad/acad2000/dxf/
#ifndef CGAL_IO_DXF_WRITER_H
#define CGAL_IO_DXF_WRITER_H
#include <CGAL/disable_warnings.h>
#include <CGAL/basic.h>
#include <CGAL/algorithm.h>
#include <iostream>
#include <sstream>
#include <string>
#include <list>
#include <boost/format.hpp>
namespace CGAL {
class Dxf_writer
{
typedef std::list<std::string> Lines ;
typedef Lines::iterator Line_iterator ;
typedef std::set<std::string> Layers ;
typedef Layers::iterator Layer_iterator ;
public:
Dxf_writer ( std::ostream& out ) : mOut(out), mHandle(32)
{
mPos = mLines.end();
add_header();
}
~Dxf_writer()
{
add_footer();
dump();
}
template<class XY>
void add_segment_2 ( XY const& aSrc
, XY const& aTgt
, std::string aLayer = ""
, int aColor = 255
)
{
add_entity ( "LINE" , aLayer ) ;
add_code ( 62 , to_str ( aColor ) ) ;
add_code ( 10 , to_str ( to_double(aSrc.x()) ) ) ;
add_code ( 20 , to_str ( to_double(aSrc.y()) ) ) ;
add_code ( 30 , to_str ( to_double(0.0 ) ) ) ;
add_code ( 11 , to_str ( to_double(aTgt.x()) ) ) ;
add_code ( 21 , to_str ( to_double(aTgt.y()) ) ) ;
add_code ( 31 , to_str ( to_double(0.0 ) ) ) ;
}
template<class XY_Iterator>
void add_polyline_2 ( XY_Iterator aVerticesBegin
, XY_Iterator aVerticesEnd
, bool aIsClosed
, std::string aLayer = ""
, int aColor = 255
)
{
if ( aVerticesBegin < aVerticesEnd )
{
add_entity ( "POLYLINE" , aLayer) ;
add_code ( 62 , to_str ( aColor ) ) ;
add_code ( 66 , to_str ( 1 ) ) ;
add_code ( 10 , to_str ( 0.0 ) ) ;
add_code ( 20 , to_str ( 0.0 ) ) ;
add_code ( 30 , to_str ( 0.0 ) ) ;
add_code ( 70 , to_str ( aIsClosed ? 1 : 0 ) ) ;
while ( aVerticesBegin != aVerticesEnd )
{
add_entity ( "VERTEX" , aLayer) ;
add_code ( 10 , to_str ( to_double( aVerticesBegin->x() ) ) ) ;
add_code ( 20 , to_str ( to_double( aVerticesBegin->y() ) ) ) ;
add_code ( 30 , to_str ( to_double( 0.0 ) ) ) ;
++ aVerticesBegin ;
}
add_entity ( "SEQEND" , aLayer) ;
}
}
template<class XY_Iterator>
void add_segments_2 ( XY_Iterator aVerticesBegin
, XY_Iterator aVerticesEnd
, bool aIsClosed
, std::string aLayer = ""
, int aColor = 255
)
{
if ( aVerticesBegin < aVerticesEnd )
{
XY_Iterator lFirstVertex = aVerticesBegin ;
XY_Iterator lLastVertex = aVerticesEnd ; -- lLastVertex ;
if ( lFirstVertex != lLastVertex )
{
XY_Iterator lCurrVertex = aVerticesBegin ;
while ( lCurrVertex != aVerticesEnd )
{
XY_Iterator lNextVertex = ( lCurrVertex == lLastVertex ? lFirstVertex : CGAL::cpp11::next(lCurrVertex) ) ;
add_segment_2 ( *lCurrVertex, *lNextVertex, aLayer, aColor ) ;
++ lCurrVertex ;
}
if ( aIsClosed )
add_segment_2 ( *lLastVertex, *lFirstVertex, aLayer, aColor ) ;
}
}
}
private:
std::string get_entity_handle()
{
std::ostringstream oss;
oss << boost::format("%5x") % mHandle++;
return oss.str();
}
std::string to_str ( int aN )
{
std::ostringstream oss;
oss << boost::format("%6d") % aN;
return oss.str();
}
std::string to_str ( double aN )
{
std::ostringstream oss;
oss << boost::format("%6.6f") % aN;
return oss.str();
}
void insert_line ( Line_iterator aPos, std::string aLine )
{
mLines.insert(aPos,aLine);
}
void add_line ( std::string aLine )
{
insert_line(mPos,aLine);
}
void add_code ( int aCode, std::string aValue )
{
add_line( to_str(aCode) ) ;
add_line( aValue ) ;
}
void add_group_begin ( std::string aGroup, std::string aName )
{
add_code ( 0 , aGroup ) ;
add_code ( 2 , aName ) ;
}
void add_group_end ( std::string aGroup )
{
add_code ( 0 , aGroup ) ;
}
void add_entity ( std::string aName, std::string aLayer )
{
add_code ( 0 , aName ) ;
add_code ( 5 , get_entity_handle() ) ;
if ( !aLayer.empty() && aLayer != "0" )
{
mLayers.insert(aLayer);
add_code ( 8 , aLayer ) ;
}
}
void add_header()
{
add_group_begin ( "SECTION" , "HEADER" ) ;
add_group_end ( "ENDSEC" ) ;
add_group_begin ( "SECTION" , "TABLES" ) ;
add_group_begin ( "TABLE" , "LTYPE" ) ;
add_code ( 70 , to_str ( 1 ) ) ;
add_code ( 0 , "LTYPE" ) ;
add_code ( 2 , "CONTINUOUS" ) ;
add_code ( 70 , to_str ( 0 ) ) ;
add_code ( 3 , "Solid line" ) ;
add_code ( 72 , to_str ( 65 ) ) ;
add_code ( 73 , to_str ( 0 ) ) ;
add_code ( 40 , to_str ( 0.0 ) ) ;
add_group_end ( "ENDTAB" ) ;
add_group_begin ( "TABLE" , "APPID" ) ;
add_code ( 70 , to_str ( 1 ) ) ;
add_code ( 0 , "APPID" ) ;
add_code ( 2 , "ACAD" ) ;
add_code ( 70 , to_str ( 0 ) ) ;
add_group_end ( "ENDTAB" ) ;
mLayersTablePos = mPos ; -- mLayersTablePos ;
add_group_end ( "ENDSEC" ) ;
add_group_begin ( "SECTION" , "ENTITIES" ) ;
}
void add_footer()
{
add_group_end( "ENDSEC" ) ;
add_group_end( "EOF" ) ;
insert_layers();
}
void insert_layers()
{
if ( mLayers.size() > 0 )
{
mPos = mLayersTablePos ; ++ mPos ;
add_group_begin ( "TABLE" , "LAYER" ) ;
add_code ( 70 , to_str ( int(mLayers.size() + 1) ) ) ;
add_code ( 0 , "LAYER" ) ;
add_code ( 2 , "0" ) ;
add_code ( 70 , to_str ( 0 ) ) ;
add_code ( 62 , to_str ( 7 ) ) ;
add_code ( 6 , "CONTINUOUS" ) ;
for ( Layer_iterator lit = mLayers.begin() ; lit != mLayers.end() ; ++ lit )
{
add_code ( 0 , "LAYER" ) ;
add_code ( 2 , *lit ) ;
add_code ( 70 , to_str ( 0 ) ) ;
add_code ( 62 , to_str ( 0 ) ) ;
add_code ( 6 , "CONTINUOUS" ) ;
}
add_group_end ( "ENDTAB" ) ;
}
}
void dump()
{
std::copy(mLines.begin(),mLines.end(), std::ostream_iterator<std::string>(mOut,"\n"));
}
std::ostream& mOut ;
Lines mLines ;
Line_iterator mPos ;
Line_iterator mLayersTablePos ;
Layers mLayers ;
int mHandle ;
} ;
} // end namespace CGAL
#include <CGAL/enable_warnings.h>
#endif // CGAL_IO_DXF_WRITER_H