Add dxflib dxf read/write library from qcad project and tinyspline library. tinyspline library allows dxf splines conversion to Bezier curves supported by Pcbnew

This commit is contained in:
jean-pierre charras 2018-07-04 20:19:45 +02:00
parent 5ee1caf0b9
commit 66f00746c9
21 changed files with 14611 additions and 0 deletions

View File

@ -0,0 +1,8 @@
set(LIBDXF_SRCS
dl_dxf.cpp
dl_writer_ascii.cpp
tinyspline_lib/tinyspline.c
tinyspline_lib/tinysplinecpp.cpp
)
add_library(lib_dxf STATIC ${LIBDXF_SRCS})

249
dxflib_qcad/dl_attributes.h Normal file
View File

@ -0,0 +1,249 @@
/****************************************************************************
** Copyright (C) 2001-2013 RibbonSoft, GmbH. All rights reserved.
**
** This file is part of the dxflib project.
**
** This file is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** Licensees holding valid dxflib Professional Edition licenses may use
** this file in accordance with the dxflib 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.
**
** See http://www.ribbonsoft.com for further details.
**
** Contact info@ribbonsoft.com if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/
#ifndef DL_ATTRIBUTES_H
#define DL_ATTRIBUTES_H
#include "dl_global.h"
#include <string>
#include <vector>
#include "dl_codes.h"
/**
* Storing and passing around attributes. Attributes
* are the layer name, color, width and line type.
*
* @author Andrew Mustun
*/
class DXFLIB_EXPORT DL_Attributes
{
public:
/**
* Default constructor.
*/
DL_Attributes() :
layer( "" ),
color( 0 ),
color24( -1 ),
width( 0 ),
linetype( "BYLAYER" ),
linetypeScale( 1.0 ),
handle( -1 ),
inPaperSpace( false )
{
}
/**
* Constructor for DXF attributes.
*
* @param layer Layer name for this entity or NULL for no layer
* (every entity should be on a named layer!).
* @param color Color number (0..256). 0 = BYBLOCK, 256 = BYLAYER.
* @param width Line thickness. Defaults to zero. -1 = BYLAYER,
* -2 = BYBLOCK, -3 = default width
* @param linetype Line type name or "BYLAYER" or "BYBLOCK". Defaults
* to "BYLAYER"
*/
DL_Attributes( const std::string& alayer,
int acolor, int awidth,
const std::string& alinetype,
double alinetypeScale ) :
layer( alayer ), color( acolor ), color24( -1 ), width( awidth ),
linetype( alinetype ), linetypeScale( alinetypeScale ),
handle( -1 ), inPaperSpace( false )
{
}
/**
* Constructor for DXF attributes.
*
* @param layer Layer name for this entity or NULL for no layer
* (every entity should be on a named layer!).
* @param color Color number (0..256). 0 = BYBLOCK, 256 = BYLAYER.
* @param color24 24 bit color (0x00RRGGBB, see DXF reference).
* @param width Line thickness. Defaults to zero. -1 = BYLAYER,
* -2 = BYBLOCK, -3 = default width
* @param linetype Line type name or "BYLAYER" or "BYBLOCK". Defaults
* to "BYLAYER"
*/
DL_Attributes( const std::string& alayer,
int acolor, int acolor24, int awidth,
const std::string& alinetype, int ahandle = -1 ) :
layer( alayer ),
color( acolor ), color24( acolor24 ),
width( awidth ), linetype( alinetype ), linetypeScale( 1.0 ),
handle( ahandle ),
inPaperSpace( false )
{
}
/**
* Sets the layer. If the given pointer points to NULL, the
* new layer name will be an empty but valid string.
*/
void setLayer( const std::string& alayer )
{
layer = alayer;
}
/**
* @return Layer name.
*/
std::string getLayer() const
{
return layer;
}
/**
* Sets the color.
*
* @see DL_Codes, dxfColors
*/
void setColor( int acolor )
{
color = acolor;
}
/**
* Sets the 24bit color.
*
* @see DL_Codes, dxfColors
*/
void setColor24( int acolor )
{
color24 = acolor;
}
/**
* @return Color.
*
* @see DL_Codes, dxfColors
*/
int getColor() const
{
return color;
}
/**
* @return 24 bit color or -1 if no 24bit color is defined.
*
* @see DL_Codes, dxfColors
*/
int getColor24() const
{
return color24;
}
/**
* Sets the width.
*/
void setWidth( int awidth )
{
width = awidth;
}
/**
* @return Width.
*/
int getWidth() const
{
return width;
}
/**
* Sets the line type. This can be any string and is not
* checked to be a valid line type.
*/
void setLinetype( const std::string& alinetype )
{
linetype = alinetype;
}
/**
* Sets the entity specific line type scale.
*/
void setLinetypeScale( double alinetypeScale )
{
linetypeScale = alinetypeScale;
}
double getLinetypeScale() const
{
return linetypeScale;
}
/**
* @return Line type.
*/
std::string getLinetype() const
{
if( linetype.length()==0 )
{
return "BYLAYER";
}
else
{
return linetype;
}
}
void setHandle( int h )
{
handle = h;
}
int getHandle() const
{
return handle;
}
void setInPaperSpace( bool on )
{
inPaperSpace = on;
}
bool isInPaperSpace() const
{
return inPaperSpace;
}
private:
std::string layer;
int color;
int color24;
int width;
std::string linetype;
double linetypeScale;
int handle;
// DXF code 67 (true: entity in paper space, false: entity in model space (default):
bool inPaperSpace;
};
#endif
// EOF

546
dxflib_qcad/dl_codes.h Normal file
View File

@ -0,0 +1,546 @@
/****************************************************************************
** Copyright (C) 2001-2013 RibbonSoft, GmbH. All rights reserved.
** Copyright (C) 2001 Robert J. Campbell Jr.
**
** This file is part of the dxflib project.
**
** This file is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** Licensees holding valid dxflib Professional Edition licenses may use
** this file in accordance with the dxflib 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.
**
** See http://www.ribbonsoft.com for further details.
**
** Contact info@ribbonsoft.com if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/
/**
* Defines common DXF codes and constants.
*/
#ifndef DXF_CODES_H
#define DXF_CODES_H
#include "dl_global.h"
#if defined(__OS2__)||defined(__EMX__)
#define strcasecmp( s, t ) stricmp( s, t )
#endif
#if defined(_WIN32)
#define strcasecmp( s, t ) stricmp( s, t )
#endif
#ifdef _WIN32
#undef M_PI
#define M_PI 3.14159265358979323846
#endif
#ifndef M_PI
#define M_PI 3.1415926535897932384626433832795
#endif
#define DL_DXF_MAXLINE 1024
#define DL_DXF_MAXGROUPCODE 1100
// used to mark invalid vectors:
// #define DL_DXF_MAXDOUBLE 1.0E+10
/**
* Codes for colors and DXF versions.
*/
class DXFLIB_EXPORT DL_Codes
{
public:
/**
* Standard DXF colors.
*/
enum color
{
black = 250,
green = 3,
red = 1,
brown = 15,
yellow = 2,
cyan = 4,
magenta = 6,
gray = 8,
blue = 5,
l_blue = 163,
l_green = 121,
l_cyan = 131,
l_red = 23,
l_magenta = 221,
l_gray = 252,
white = 7,
bylayer = 256,
byblock = 0
};
/**
* Version numbers for the DXF Format.
*/
enum version
{
AC1009_MIN, // R12, minimalistic
AC1009, // R12
AC1012,
AC1014,
AC1015 // R2000
};
};
// Extended color palette:
// The first entry is only for direct indexing starting with [1]
// Color 1 is red (1,0,0)
const double dxfColors[][3] =
{
{ 0, 0, 0 }, // unused
{ 1, 0, 0 }, // 1
{ 1, 1, 0 },
{ 0, 1, 0 },
{ 0, 1, 1 },
{ 0, 0, 1 },
{ 1, 0, 1 },
{ 1, 1, 1 }, // black or white
{ 0.5, 0.5, 0.5 },
{ 0.75, 0.75, 0.75 },
{ 1, 0, 0 }, // 10
{ 1, 0.5, 0.5 },
{ 0.65, 0, 0 },
{ 0.65, 0.325, 0.325 },
{ 0.5, 0, 0 },
{ 0.5, 0.25, 0.25 },
{ 0.3, 0, 0 },
{ 0.3, 0.15, 0.15 },
{ 0.15, 0, 0 },
{ 0.15, 0.075, 0.075 },
{ 1, 0.25, 0 }, // 20
{ 1, 0.625, 0.5 },
{ 0.65, 0.1625, 0 },
{ 0.65, 0.4063, 0.325 },
{ 0.5, 0.125, 0 },
{ 0.5, 0.3125, 0.25 },
{ 0.3, 0.075, 0 },
{ 0.3, 0.1875, 0.15 },
{ 0.15, 0.0375, 0 },
{ 0.15, 0.0938, 0.075 },
{ 1, 0.5, 0 }, // 30
{ 1, 0.75, 0.5 },
{ 0.65, 0.325, 0 },
{ 0.65, 0.4875, 0.325 },
{ 0.5, 0.25, 0 },
{ 0.5, 0.375, 0.25 },
{ 0.3, 0.15, 0 },
{ 0.3, 0.225, 0.15 },
{ 0.15, 0.075, 0 },
{ 0.15, 0.1125, 0.075 },
{ 1, 0.75, 0 }, // 40
{ 1, 0.875, 0.5 },
{ 0.65, 0.4875, 0 },
{ 0.65, 0.5688, 0.325 },
{ 0.5, 0.375, 0 },
{ 0.5, 0.4375, 0.25 },
{ 0.3, 0.225, 0 },
{ 0.3, 0.2625, 0.15 },
{ 0.15, 0.1125, 0 },
{ 0.15, 0.1313, 0.075 },
{ 1, 1, 0 }, // 50
{ 1, 1, 0.5 },
{ 0.65, 0.65, 0 },
{ 0.65, 0.65, 0.325 },
{ 0.5, 0.5, 0 },
{ 0.5, 0.5, 0.25 },
{ 0.3, 0.3, 0 },
{ 0.3, 0.3, 0.15 },
{ 0.15, 0.15, 0 },
{ 0.15, 0.15, 0.075 },
{ 0.75, 1, 0 }, // 60
{ 0.875, 1, 0.5 },
{ 0.4875, 0.65, 0 },
{ 0.5688, 0.65, 0.325 },
{ 0.375, 0.5, 0 },
{ 0.4375, 0.5, 0.25 },
{ 0.225, 0.3, 0 },
{ 0.2625, 0.3, 0.15 },
{ 0.1125, 0.15, 0 },
{ 0.1313, 0.15, 0.075 },
{ 0.5, 1, 0 }, // 70
{ 0.75, 1, 0.5 },
{ 0.325, 0.65, 0 },
{ 0.4875, 0.65, 0.325 },
{ 0.25, 0.5, 0 },
{ 0.375, 0.5, 0.25 },
{ 0.15, 0.3, 0 },
{ 0.225, 0.3, 0.15 },
{ 0.075, 0.15, 0 },
{ 0.1125, 0.15, 0.075 },
{ 0.25, 1, 0 }, // 80
{ 0.625, 1, 0.5 },
{ 0.1625, 0.65, 0 },
{ 0.4063, 0.65, 0.325 },
{ 0.125, 0.5, 0 },
{ 0.3125, 0.5, 0.25 },
{ 0.075, 0.3, 0 },
{ 0.1875, 0.3, 0.15 },
{ 0.0375, 0.15, 0 },
{ 0.0938, 0.15, 0.075 },
{ 0, 1, 0 }, // 90
{ 0.5, 1, 0.5 },
{ 0, 0.65, 0 },
{ 0.325, 0.65, 0.325 },
{ 0, 0.5, 0 },
{ 0.25, 0.5, 0.25 },
{ 0, 0.3, 0 },
{ 0.15, 0.3, 0.15 },
{ 0, 0.15, 0 },
{ 0.075, 0.15, 0.075 },
{ 0, 1, 0.25 }, // 100
{ 0.5, 1, 0.625 },
{ 0, 0.65, 0.1625 },
{ 0.325, 0.65, 0.4063 },
{ 0, 0.5, 0.125 },
{ 0.25, 0.5, 0.3125 },
{ 0, 0.3, 0.075 },
{ 0.15, 0.3, 0.1875 },
{ 0, 0.15, 0.0375 },
{ 0.075, 0.15, 0.0938 },
{ 0, 1, 0.5 }, // 110
{ 0.5, 1, 0.75 },
{ 0, 0.65, 0.325 },
{ 0.325, 0.65, 0.4875 },
{ 0, 0.5, 0.25 },
{ 0.25, 0.5, 0.375 },
{ 0, 0.3, 0.15 },
{ 0.15, 0.3, 0.225 },
{ 0, 0.15, 0.075 },
{ 0.075, 0.15, 0.1125 },
{ 0, 1, 0.75 }, // 120
{ 0.5, 1, 0.875 },
{ 0, 0.65, 0.4875 },
{ 0.325, 0.65, 0.5688 },
{ 0, 0.5, 0.375 },
{ 0.25, 0.5, 0.4375 },
{ 0, 0.3, 0.225 },
{ 0.15, 0.3, 0.2625 },
{ 0, 0.15, 0.1125 },
{ 0.075, 0.15, 0.1313 },
{ 0, 1, 1 }, // 130
{ 0.5, 1, 1 },
{ 0, 0.65, 0.65 },
{ 0.325, 0.65, 0.65 },
{ 0, 0.5, 0.5 },
{ 0.25, 0.5, 0.5 },
{ 0, 0.3, 0.3 },
{ 0.15, 0.3, 0.3 },
{ 0, 0.15, 0.15 },
{ 0.075, 0.15, 0.15 },
{ 0, 0.75, 1 }, // 140
{ 0.5, 0.875, 1 },
{ 0, 0.4875, 0.65 },
{ 0.325, 0.5688, 0.65 },
{ 0, 0.375, 0.5 },
{ 0.25, 0.4375, 0.5 },
{ 0, 0.225, 0.3 },
{ 0.15, 0.2625, 0.3 },
{ 0, 0.1125, 0.15 },
{ 0.075, 0.1313, 0.15 },
{ 0, 0.5, 1 }, // 150
{ 0.5, 0.75, 1 },
{ 0, 0.325, 0.65 },
{ 0.325, 0.4875, 0.65 },
{ 0, 0.25, 0.5 },
{ 0.25, 0.375, 0.5 },
{ 0, 0.15, 0.3 },
{ 0.15, 0.225, 0.3 },
{ 0, 0.075, 0.15 },
{ 0.075, 0.1125, 0.15 },
{ 0, 0.25, 1 }, // 160
{ 0.5, 0.625, 1 },
{ 0, 0.1625, 0.65 },
{ 0.325, 0.4063, 0.65 },
{ 0, 0.125, 0.5 },
{ 0.25, 0.3125, 0.5 },
{ 0, 0.075, 0.3 },
{ 0.15, 0.1875, 0.3 },
{ 0, 0.0375, 0.15 },
{ 0.075, 0.0938, 0.15 },
{ 0, 0, 1 }, // 170
{ 0.5, 0.5, 1 },
{ 0, 0, 0.65 },
{ 0.325, 0.325, 0.65 },
{ 0, 0, 0.5 },
{ 0.25, 0.25, 0.5 },
{ 0, 0, 0.3 },
{ 0.15, 0.15, 0.3 },
{ 0, 0, 0.15 },
{ 0.075, 0.075, 0.15 },
{ 0.25, 0, 1 }, // 180
{ 0.625, 0.5, 1 },
{ 0.1625, 0, 0.65 },
{ 0.4063, 0.325, 0.65 },
{ 0.125, 0, 0.5 },
{ 0.3125, 0.25, 0.5 },
{ 0.075, 0, 0.3 },
{ 0.1875, 0.15, 0.3 },
{ 0.0375, 0, 0.15 },
{ 0.0938, 0.075, 0.15 },
{ 0.5, 0, 1 }, // 190
{ 0.75, 0.5, 1 },
{ 0.325, 0, 0.65 },
{ 0.4875, 0.325, 0.65 },
{ 0.25, 0, 0.5 },
{ 0.375, 0.25, 0.5 },
{ 0.15, 0, 0.3 },
{ 0.225, 0.15, 0.3 },
{ 0.075, 0, 0.15 },
{ 0.1125, 0.075, 0.15 },
{ 0.75, 0, 1 }, // 200
{ 0.875, 0.5, 1 },
{ 0.4875, 0, 0.65 },
{ 0.5688, 0.325, 0.65 },
{ 0.375, 0, 0.5 },
{ 0.4375, 0.25, 0.5 },
{ 0.225, 0, 0.3 },
{ 0.2625, 0.15, 0.3 },
{ 0.1125, 0, 0.15 },
{ 0.1313, 0.075, 0.15 },
{ 1, 0, 1 }, // 210
{ 1, 0.5, 1 },
{ 0.65, 0, 0.65 },
{ 0.65, 0.325, 0.65 },
{ 0.5, 0, 0.5 },
{ 0.5, 0.25, 0.5 },
{ 0.3, 0, 0.3 },
{ 0.3, 0.15, 0.3 },
{ 0.15, 0, 0.15 },
{ 0.15, 0.075, 0.15 },
{ 1, 0, 0.75 }, // 220
{ 1, 0.5, 0.875 },
{ 0.65, 0, 0.4875 },
{ 0.65, 0.325, 0.5688 },
{ 0.5, 0, 0.375 },
{ 0.5, 0.25, 0.4375 },
{ 0.3, 0, 0.225 },
{ 0.3, 0.15, 0.2625 },
{ 0.15, 0, 0.1125 },
{ 0.15, 0.075, 0.1313 },
{ 1, 0, 0.5 }, // 230
{ 1, 0.5, 0.75 },
{ 0.65, 0, 0.325 },
{ 0.65, 0.325, 0.4875 },
{ 0.5, 0, 0.25 },
{ 0.5, 0.25, 0.375 },
{ 0.3, 0, 0.15 },
{ 0.3, 0.15, 0.225 },
{ 0.15, 0, 0.075 },
{ 0.15, 0.075, 0.1125 },
{ 1, 0, 0.25 }, // 240
{ 1, 0.5, 0.625 },
{ 0.65, 0, 0.1625 },
{ 0.65, 0.325, 0.4063 },
{ 0.5, 0, 0.125 },
{ 0.5, 0.25, 0.3125 },
{ 0.3, 0, 0.075 },
{ 0.3, 0.15, 0.1875 },
{ 0.15, 0, 0.0375 },
{ 0.15, 0.075, 0.0938 },
{ 0.33, 0.33, 0.33 }, // 250
{ 0.464, 0.464, 0.464 },
{ 0.598, 0.598, 0.598 },
{ 0.732, 0.732, 0.732 },
{ 0.866, 0.866, 0.866 },
{ 1, 1, 1 } // 255
}
;
// AutoCAD VERSION aliases
#define DL_VERSION_R12 DL_Codes::AC1009
#define DL_VERSION_LT2 DL_Codes::AC1009
#define DL_VERSION_R13 DL_Codes::AC1012 // not supported yet
#define DL_VERSION_LT95 DL_Codes::AC1012 // not supported yet
#define DL_VERSION_R14 DL_Codes::AC1014 // not supported yet
#define DL_VERSION_LT97 DL_Codes::AC1014 // not supported yet
#define DL_VERSION_LT98 DL_Codes::AC1014 // not supported yet
#define DL_VERSION_2000 DL_Codes::AC1015
#define DL_VERSION_2002 DL_Codes::AC1015
// DXF Group Codes:
// Strings
#define DL_STRGRP_START 0
#define DL_STRGRP_END 9
// Coordinates
#define DL_CRDGRP_START 10
#define DL_CRDGRP_END 19
// Real values
#define DL_RLGRP_START 38
#define DL_RLGRP_END 59
// Short integer values
#define DL_SHOGRP_START 60
#define DL_SHOGRP_END 79
// New in Release 13,
#define DL_SUBCLASS 100
// More coordinates
#define DL_CRD2GRP_START 210
#define DL_CRD2GRP_END 239
// Extended data strings
#define DL_ESTRGRP_START 1000
#define DL_ESTRGRP_END 1009
// Extended data reals
#define DL_ERLGRP_START 1010
#define DL_ERLGRP_END 1059
#define DL_Y8_COORD_CODE 28
#define DL_Z0_COORD_CODE 30
#define DL_Z8_COORD_CODE 38
#define DL_POINT_COORD_CODE 10
#define DL_INSERT_COORD_CODE 10
#define DL_CRD2GRP_START 210
#define DL_CRD2GRP_END 239
#define DL_THICKNESS 39
#define DL_FIRST_REAL_CODE THICKNESS
#define DL_LAST_REAL_CODE 59
#define DL_FIRST_INT_CODE 60
#define DL_ATTFLAGS_CODE 70
#define DL_PLINE_FLAGS_CODE 70
#define DL_LAYER_FLAGS_CODE 70
#define DL_FLD_LEN_CODE 73 // Inside ATTRIB resbuf
#define DL_LAST_INT_CODE 79
#define DL_X_EXTRU_CODE 210
#define DL_Y_EXTRU_CODE 220
#define DL_Z_EXTRU_CODE 230
#define DL_COMMENT_CODE 999
// Start and endpoints of a line
#define DL_LINE_START_CODE 10 // Followed by x coord
#define DL_LINE_END_CODE 11 // Followed by x coord
// Some codes used by blocks
#define DL_BLOCK_FLAGS_CODE 70 // An int containing flags
#define DL_BLOCK_BASE_CODE 10 // Origin of block definition
#define DL_XREF_DEPENDENT 16 // If a block contains an XREF
#define DL_XREF_RESOLVED 32 // If a XREF resolved ok
#define DL_REFERENCED 64 // If a block is ref'd in DWG
#define DL_XSCALE_CODE 41
#define DL_YSCALE_CODE 42
#define DL_ANGLE_CODE 50
#define DL_INS_POINT_CODE 10 // Followed by x of ins pnt
#define DL_NAME2_CODE 3 // Second appearance of name
// Some codes used by circle entities
#define DL_CENTER_CODE 10 // Followed by x of center
#define DL_RADIUS_CODE 40 // Followd by radius of circle
#define DL_COND_OP_CODE -4 // Conditional op,ads_ssget
// When using ads_buildlist you MUST use RTDXF0 instead of these
#define DL_ENTITY_TYPE_CODE 0 // Then there is LINE, 3DFACE..
#define DL_SES_CODE 0 // Start End String Code
#define DL_FILE_SEP_CODE 0 // File separator
#define DL_SOT_CODE 0 // Start Of Table
#define DL_TEXTVAL_CODE 1
#define DL_NAME_CODE 2
#define DL_BLOCK_NAME_CODE 2
#define DL_SECTION_NAME_CODE 2
#define DL_ENT_HAND_CODE 5 // What follows is hexa string
#define DL_TXT_STYLE_CODE 7 // Inside attributes
#define DL_LAYER_NAME_CODE 8 // What follows is layer name
#define DL_FIRST_XCOORD_CODE 10 // Group code x of 1st coord
#define DL_FIRST_YCOORD_CODE 20 // Group code y of 1st coord
#define DL_FIRST_ZCOORD_CODE 30 // Group code z of 1st coord
#define DL_L_START_CODE 10
#define DL_L_END_CODE 11
#define DL_TXTHI_CODE 40
#define DL_SCALE_X_CODE 41
#define DL_SCALE_Y_CODE 42
#define DL_SCALE_Z_CODE 43
#define DL_BULGE_CODE 42 // Used in PLINE verts for arcs
#define DL_ROTATION_CODE 50
#define DL_COLOUR_CODE 62 // What follows is a color int
#define DL_LTYPE_CODE 6 // What follows is a linetype
// Attribute flags
#define DL_ATTS_FOLLOW_CODE 66
#define DL_ATT_TAG_CODE 2
#define DL_ATT_VAL_CODE 1
#define DL_ATT_FLAGS_CODE 70 // 4 1 bit flags as follows...
#define DL_ATT_INVIS_FLAG 1
#define DL_ATT_CONST_FLAG 2
#define DL_ATT_VERIFY_FLAG 4 // Prompt and verify
#define DL_ATT_PRESET_FLAG 8 // No prompt and no verify
// PLINE defines
// Flags
#define DL_OPEN_PLINE 0x00
#define DL_CLOSED_PLINE 0x01
#define DL_POLYLINE3D 0x80
#define DL_PFACE_MESH 0x40
#define DL_PGON_MESH 0x10
// Vertices follow entity, required in POLYLINES
#define DL_VERTS_FOLLOW_CODE 66 // Value should always be 1
#define DL_VERTEX_COORD_CODE 10
// LAYER flags
#define DL_FROZEN 1
#define DL_FROZEN_BY_DEF 2
#define DL_LOCKED 4
#define DL_OBJECT_USED 64 // Object is ref'd in the dwg
#define DL_BLOCK_EN_CODE -2 // Block entity definition
#define DL_E_NAME -1 // Entity name
// Extended data codes
#define DL_EXTD_SENTINEL (-3)
#define DL_EXTD_STR 1000
#define DL_EXTD_APP_NAME 1001
#define DL_EXTD_CTL_STR 1002
#define DL_EXTD_LYR_STR 1003
#define DL_EXTD_CHUNK 1004
#define DL_EXTD_HANDLE 1005
#define DL_EXTD_POINT 1010
#define DL_EXTD_POS 1011
#define DL_EXTD_DISP 1012
#define DL_EXTD_DIR 1013
#define DL_EXTD_FLOAT 1040
#define DL_EXTD_DIST 1041
#define DL_EXTD_SCALE 1042
#define DL_EXTD_INT16 1070
#define DL_EXTD_INT32 1071
// UCS codes for use in ads_trans
#define DL_WCS_TRANS_CODE 0
#define DL_UCS_TRANS_CODE 1
#define DL_DCS_TRANS_CODE 2
#define DL_PCS_TRANS_CODE 3
#endif

View File

@ -0,0 +1,140 @@
/****************************************************************************
** Copyright (C) 2001-2013 RibbonSoft, GmbH. All rights reserved.
**
** This file is part of the dxflib project.
**
** This file is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** Licensees holding valid dxflib Professional Edition licenses may use
** this file in accordance with the dxflib 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.
**
** See http://www.ribbonsoft.com for further details.
**
** Contact info@ribbonsoft.com if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/
#ifndef DL_CREATIONADAPTER_H
#define DL_CREATIONADAPTER_H
#include "dl_global.h"
#include "dl_creationinterface.h"
/**
* An abstract adapter class for receiving DXF events when a DXF file is being read.
* The methods in this class are empty. This class exists as convenience for creating
* listener objects.
*
* @author Andrew Mustun
*/
class DXFLIB_EXPORT DL_CreationAdapter : public DL_CreationInterface
{
public:
DL_CreationAdapter() {}
virtual ~DL_CreationAdapter() {}
virtual void processCodeValuePair( unsigned int, const std::string& ) override {}
virtual void endSection() override {}
virtual void addLayer( const DL_LayerData& ) override {}
virtual void addLinetype( const DL_LinetypeData& ) override {}
virtual void addLinetypeDash( double ) override {}
virtual void addBlock( const DL_BlockData& ) override {}
virtual void endBlock() override {}
virtual void addTextStyle( const DL_StyleData& ) override {}
virtual void addPoint( const DL_PointData& ) override {}
virtual void addLine( const DL_LineData& ) override {}
virtual void addXLine( const DL_XLineData& ) override {}
virtual void addRay( const DL_RayData& ) override {}
virtual void addArc( const DL_ArcData& ) override {}
virtual void addCircle( const DL_CircleData& ) override {}
virtual void addEllipse( const DL_EllipseData& ) override {}
virtual void addPolyline( const DL_PolylineData& ) override {}
virtual void addVertex( const DL_VertexData& ) override {}
virtual void addSpline( const DL_SplineData& ) override {}
virtual void addControlPoint( const DL_ControlPointData& ) override {}
virtual void addFitPoint( const DL_FitPointData& ) override {}
virtual void addKnot( const DL_KnotData& ) override {}
virtual void addInsert( const DL_InsertData& ) override {}
virtual void addMText( const DL_MTextData& ) override {}
virtual void addMTextChunk( const std::string& ) override {}
virtual void addText( const DL_TextData& ) override {}
virtual void addArcAlignedText( const DL_ArcAlignedTextData& ) override {}
virtual void addAttribute( const DL_AttributeData& ) override {}
virtual void addDimAlign( const DL_DimensionData&,
const DL_DimAlignedData& ) override {}
virtual void addDimLinear( const DL_DimensionData&,
const DL_DimLinearData& ) override {}
virtual void addDimRadial( const DL_DimensionData&,
const DL_DimRadialData& ) override {}
virtual void addDimDiametric( const DL_DimensionData&,
const DL_DimDiametricData& ) override {}
virtual void addDimAngular( const DL_DimensionData&,
const DL_DimAngularData& ) override {}
virtual void addDimAngular3P( const DL_DimensionData&,
const DL_DimAngular3PData& ) override {}
virtual void addDimOrdinate( const DL_DimensionData&,
const DL_DimOrdinateData& ) override {}
virtual void addLeader( const DL_LeaderData& ) override {}
virtual void addLeaderVertex( const DL_LeaderVertexData& ) override {}
virtual void addHatch( const DL_HatchData& ) override {}
virtual void addTrace( const DL_TraceData& ) override {}
virtual void add3dFace( const DL_3dFaceData& ) override {}
virtual void addSolid( const DL_SolidData& ) override {}
virtual void addImage( const DL_ImageData& ) override {}
virtual void linkImage( const DL_ImageDefData& ) override {}
virtual void addHatchLoop( const DL_HatchLoopData& ) override {}
virtual void addHatchEdge( const DL_HatchEdgeData& ) override {}
virtual void addXRecord( const std::string& ) override {}
virtual void addXRecordString( int, const std::string& ) override {}
virtual void addXRecordReal( int, double ) override {}
virtual void addXRecordInt( int, int ) override {}
virtual void addXRecordBool( int, bool ) override {}
virtual void addXDataApp( const std::string& ) override {}
virtual void addXDataString( int, const std::string& ) override {}
virtual void addXDataReal( int, double ) override {}
virtual void addXDataInt( int, int ) override {}
virtual void addDictionary( const DL_DictionaryData& ) override {}
virtual void addDictionaryEntry( const DL_DictionaryEntryData& ) override {}
virtual void endEntity() override {}
virtual void addComment( const std::string& ) override {}
virtual void setVariableVector( const std::string&, double, double, double, int ) override {}
virtual void setVariableString( const std::string&, const std::string&, int ) override {}
virtual void setVariableInt( const std::string&, int, int ) override {}
virtual void setVariableDouble( const std::string&, double, int ) override {}
#ifdef DL_COMPAT
virtual void setVariableVector( const char*, double, double, double, int ) {}
virtual void setVariableString( const char*, const char*, int ) {}
virtual void setVariableInt( const char*, int, int ) {}
virtual void setVariableDouble( const char*, double, int ) {}
virtual void processCodeValuePair( unsigned int, char* ) {}
virtual void addComment( const char* ) {}
virtual void addMTextChunk( const char* ) {}
#endif
virtual void endSequence() override {}
};
#endif

View File

@ -0,0 +1,385 @@
/****************************************************************************
** Copyright (C) 2001-2013 RibbonSoft, GmbH. All rights reserved.
**
** This file is part of the dxflib project.
**
** This file is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** Licensees holding valid dxflib Professional Edition licenses may use
** this file in accordance with the dxflib 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.
**
** See http://www.ribbonsoft.com for further details.
**
** Contact info@ribbonsoft.com if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/
#ifndef DL_CREATIONINTERFACE_H
#define DL_CREATIONINTERFACE_H
#include "dl_global.h"
#include <string.h>
#include "dl_attributes.h"
#include "dl_codes.h"
#include "dl_entities.h"
#include "dl_extrusion.h"
/**
* Abstract class (interface) for the creation of new entities.
* Inherit your class which takes care of the entities in the
* processed DXF file from this interface.
*
* Double arrays passed to your implementation contain 3 double
* values for x, y, z coordinates unless stated differently.
*
* @author Andrew Mustun
*/
class DXFLIB_EXPORT DL_CreationInterface
{
public:
DL_CreationInterface()
{
extrusion = new DL_Extrusion;
}
virtual ~DL_CreationInterface()
{
delete extrusion;
}
/**
* Called for every code / value tuple of the DXF file. The complete DXF file
* contents can be handled by the implemetation of this function.
*/
virtual void processCodeValuePair( unsigned int groupCode, const std::string& groupValue ) = 0;
/**
* Called when a section (entity, table entry, etc.) is finished.
*/
virtual void endSection() = 0;
/**
* Called for every layer.
*/
virtual void addLayer( const DL_LayerData& data ) = 0;
/**
* Called for every linetype.
*/
virtual void addLinetype( const DL_LinetypeData& data ) = 0;
/**
* Called for every dash in linetype pattern
*/
virtual void addLinetypeDash( double length ) = 0;
/**
* Called for every block. Note: all entities added after this
* command go into this block until endBlock() is called.
*
* @see endBlock()
*/
virtual void addBlock( const DL_BlockData& data ) = 0;
/** Called to end the current block */
virtual void endBlock() = 0;
/** Called for every text style */
virtual void addTextStyle( const DL_StyleData& data ) = 0;
/** Called for every point */
virtual void addPoint( const DL_PointData& data ) = 0;
/** Called for every line */
virtual void addLine( const DL_LineData& data ) = 0;
/** Called for every xline */
virtual void addXLine( const DL_XLineData& data ) = 0;
/** Called for every ray */
virtual void addRay( const DL_RayData& data ) = 0;
/** Called for every arc */
virtual void addArc( const DL_ArcData& data ) = 0;
/** Called for every circle */
virtual void addCircle( const DL_CircleData& data ) = 0;
/** Called for every ellipse */
virtual void addEllipse( const DL_EllipseData& data ) = 0;
/** Called for every polyline start */
virtual void addPolyline( const DL_PolylineData& data ) = 0;
/** Called for every polyline vertex */
virtual void addVertex( const DL_VertexData& data ) = 0;
/** Called for every spline */
virtual void addSpline( const DL_SplineData& data ) = 0;
/** Called for every spline control point */
virtual void addControlPoint( const DL_ControlPointData& data ) = 0;
/** Called for every spline fit point */
virtual void addFitPoint( const DL_FitPointData& data ) = 0;
/** Called for every spline knot value */
virtual void addKnot( const DL_KnotData& data ) = 0;
/** Called for every insert. */
virtual void addInsert( const DL_InsertData& data ) = 0;
/** Called for every trace start */
virtual void addTrace( const DL_TraceData& data ) = 0;
/** Called for every 3dface start */
virtual void add3dFace( const DL_3dFaceData& data ) = 0;
/** Called for every solid start */
virtual void addSolid( const DL_SolidData& data ) = 0;
/** Called for every multi Text entity. */
virtual void addMText( const DL_MTextData& data ) = 0;
/**
* Called for additional text chunks for MTEXT entities.
* The chunks come at 250 character in size each. Note that
* those chunks come <b>before</b> the actual MTEXT entity.
*/
virtual void addMTextChunk( const std::string& text ) = 0;
/** Called for every text entity. */
virtual void addText( const DL_TextData& data ) = 0;
/** Called for every arc aligned text entity. */
virtual void addArcAlignedText( const DL_ArcAlignedTextData& data ) = 0;
/** Called for every block Attribute entity. */
virtual void addAttribute( const DL_AttributeData& data ) = 0;
/**
* Called for every aligned dimension entity.
*/
virtual void addDimAlign( const DL_DimensionData& data,
const DL_DimAlignedData& edata ) = 0;
/**
* Called for every linear or rotated dimension entity.
*/
virtual void addDimLinear( const DL_DimensionData& data,
const DL_DimLinearData& edata ) = 0;
/**
* Called for every radial dimension entity.
*/
virtual void addDimRadial( const DL_DimensionData& data,
const DL_DimRadialData& edata ) = 0;
/**
* Called for every diametric dimension entity.
*/
virtual void addDimDiametric( const DL_DimensionData& data,
const DL_DimDiametricData& edata ) = 0;
/**
* Called for every angular dimension (2 lines version) entity.
*/
virtual void addDimAngular( const DL_DimensionData& data,
const DL_DimAngularData& edata ) = 0;
/**
* Called for every angular dimension (3 points version) entity.
*/
virtual void addDimAngular3P( const DL_DimensionData& data,
const DL_DimAngular3PData& edata ) = 0;
/**
* Called for every ordinate dimension entity.
*/
virtual void addDimOrdinate( const DL_DimensionData& data,
const DL_DimOrdinateData& edata ) = 0;
/**
* Called for every leader start.
*/
virtual void addLeader( const DL_LeaderData& data ) = 0;
/**
* Called for every leader vertex
*/
virtual void addLeaderVertex( const DL_LeaderVertexData& data ) = 0;
/**
* Called for every hatch entity.
*/
virtual void addHatch( const DL_HatchData& data ) = 0;
/**
* Called for every image entity.
*/
virtual void addImage( const DL_ImageData& data ) = 0;
/**
* Called for every image definition.
*/
virtual void linkImage( const DL_ImageDefData& data ) = 0;
/**
* Called for every hatch loop.
*/
virtual void addHatchLoop( const DL_HatchLoopData& data ) = 0;
/**
* Called for every hatch edge entity.
*/
virtual void addHatchEdge( const DL_HatchEdgeData& data ) = 0;
/**
* Called for every XRecord with the given handle.
*/
virtual void addXRecord( const std::string& handle ) = 0;
/**
* Called for XRecords of type string.
*/
virtual void addXRecordString( int code, const std::string& value ) = 0;
/**
* Called for XRecords of type double.
*/
virtual void addXRecordReal( int code, double value ) = 0;
/**
* Called for XRecords of type int.
*/
virtual void addXRecordInt( int code, int value ) = 0;
/**
* Called for XRecords of type bool.
*/
virtual void addXRecordBool( int code, bool value ) = 0;
/**
* Called for every beginning of an XData section of the given application.
*/
virtual void addXDataApp( const std::string& appId ) = 0;
/**
* Called for XData tuples.
*/
virtual void addXDataString( int code, const std::string& value ) = 0;
/**
* Called for XData tuples.
*/
virtual void addXDataReal( int code, double value ) = 0;
/**
* Called for XData tuples.
*/
virtual void addXDataInt( int code, int value ) = 0;
/**
* Called for dictionary objects.
*/
virtual void addDictionary( const DL_DictionaryData& data ) = 0;
/**
* Called for dictionary entries.
*/
virtual void addDictionaryEntry( const DL_DictionaryEntryData& data ) = 0;
/**
* Called after an entity has been completed.
*/
virtual void endEntity() = 0;
/**
* Called for every comment in the DXF file (code 999).
*/
virtual void addComment( const std::string& comment ) = 0;
/**
* Called for every vector variable in the DXF file (e.g. "$EXTMIN").
*/
virtual void setVariableVector( const std::string& key,
double v1,
double v2,
double v3,
int code ) = 0;
/**
* Called for every string variable in the DXF file (e.g. "$ACADVER").
*/
virtual void setVariableString( const std::string& key, const std::string& value,
int code ) = 0;
/**
* Called for every int variable in the DXF file (e.g. "$ACADMAINTVER").
*/
virtual void setVariableInt( const std::string& key, int value, int code ) = 0;
/**
* Called for every double variable in the DXF file (e.g. "$DIMEXO").
*/
virtual void setVariableDouble( const std::string& key, double value, int code ) = 0;
#ifdef DL_COMPAT
virtual void setVariableVector( const char* key, double v1, double v2, double v3,
int code ) = 0;
virtual void setVariableString( const char* key, const char* value, int code ) = 0;
virtual void setVariableInt( const char* key, int value, int code ) = 0;
virtual void setVariableDouble( const char* key, double value, int code ) = 0;
virtual void processCodeValuePair( unsigned int groupCode, char* groupValue ) = 0;
virtual void addComment( const char* comment ) = 0;
virtual void addMTextChunk( const char* text ) = 0;
#endif
/**
* Called when a SEQEND occurs (when a POLYLINE or ATTRIB is done)
*/
virtual void endSequence() = 0;
/** Sets the current attributes for entities. */
void setAttributes( const DL_Attributes& attrib )
{
attributes = attrib;
}
/** @return the current attributes used for new entities. */
DL_Attributes getAttributes()
{
return attributes;
}
/** Sets the current attributes for entities. */
void setExtrusion( double dx, double dy, double dz, double elevation )
{
extrusion->setDirection( dx, dy, dz );
extrusion->setElevation( elevation );
}
/** @return the current attributes used for new entities. */
DL_Extrusion* getExtrusion()
{
return extrusion;
}
protected:
DL_Attributes attributes;
DL_Extrusion* extrusion;
};
#endif

6384
dxflib_qcad/dl_dxf.cpp Normal file

File diff suppressed because it is too large Load Diff

551
dxflib_qcad/dl_dxf.h Normal file
View File

@ -0,0 +1,551 @@
/****************************************************************************
** Copyright (C) 2001-2013 RibbonSoft, GmbH. All rights reserved.
**
** This file is part of the dxflib project.
**
** This file is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** Licensees holding valid dxflib Professional Edition licenses may use
** this file in accordance with the dxflib 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.
**
** See http://www.ribbonsoft.com for further details.
**
** Contact info@ribbonsoft.com if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/
#ifndef DL_DXF_H
#define DL_DXF_H
#include "dl_global.h"
#include <limits>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <sstream>
#include <map>
#include "dl_attributes.h"
#include "dl_codes.h"
#include "dl_entities.h"
#include "dl_writer_ascii.h"
#ifdef _WIN32
#undef M_PI
#define M_PI 3.14159265358979323846
#endif
#ifndef M_PI
#define M_PI 3.1415926535897932384626433832795
#endif
#ifndef DL_NANDOUBLE
#define DL_NANDOUBLE std::numeric_limits<double>::quiet_NaN()
#endif
class DL_CreationInterface;
class DL_WriterA;
#define DL_VERSION "3.17.0.0"
#define DL_VERSION_MAJOR 3
#define DL_VERSION_MINOR 17
#define DL_VERSION_REV 0
#define DL_VERSION_BUILD 0
#define DL_UNKNOWN 0
#define DL_LAYER 10
#define DL_BLOCK 11
#define DL_ENDBLK 12
#define DL_LINETYPE 13
#define DL_STYLE 20
#define DL_SETTING 50
#define DL_ENTITY_POINT 100
#define DL_ENTITY_LINE 101
#define DL_ENTITY_POLYLINE 102
#define DL_ENTITY_LWPOLYLINE 103
#define DL_ENTITY_VERTEX 104
#define DL_ENTITY_SPLINE 105
#define DL_ENTITY_KNOT 106
#define DL_ENTITY_CONTROLPOINT 107
#define DL_ENTITY_ARC 108
#define DL_ENTITY_CIRCLE 109
#define DL_ENTITY_ELLIPSE 110
#define DL_ENTITY_INSERT 111
#define DL_ENTITY_TEXT 112
#define DL_ENTITY_MTEXT 113
#define DL_ENTITY_DIMENSION 114
#define DL_ENTITY_LEADER 115
#define DL_ENTITY_HATCH 116
#define DL_ENTITY_ATTRIB 117
#define DL_ENTITY_IMAGE 118
#define DL_ENTITY_IMAGEDEF 119
#define DL_ENTITY_TRACE 120
#define DL_ENTITY_SOLID 121
#define DL_ENTITY_3DFACE 122
#define DL_ENTITY_XLINE 123
#define DL_ENTITY_RAY 124
#define DL_ENTITY_ARCALIGNEDTEXT 125
#define DL_ENTITY_SEQEND 126
#define DL_XRECORD 200
#define DL_DICTIONARY 210
/**
* Reading and writing of DXF files.
*
* This class can read in a DXF file and calls methods from the
* interface DL_EntityContainer to add the entities to the
* contianer provided by the user of the library.
*
* It can also be used to write DXF files to a certain extent.
*
* When saving entities, special values for colors and linetypes
* can be used:
*
* Special colors are 0 (=BYBLOCK) and 256 (=BYLAYER).
* Special linetypes are "BYLAYER" and "BYBLOCK".
*
* @author Andrew Mustun
*/
class DXFLIB_EXPORT DL_Dxf
{
public:
DL_Dxf();
~DL_Dxf();
bool in( const std::string& file,
DL_CreationInterface* creationInterface );
bool readDxfGroups( FILE* fp,
DL_CreationInterface* creationInterface );
static bool getStrippedLine( std::string& s, unsigned int size,
FILE* stream, bool stripSpace = true );
bool readDxfGroups( std::stringstream& stream,
DL_CreationInterface* creationInterface );
bool in( std::stringstream& stream,
DL_CreationInterface* creationInterface );
static bool getStrippedLine( std::string& s, unsigned int size,
std::stringstream& stream, bool stripSpace = true );
static bool stripWhiteSpace( char** s, bool stripSpaces = true );
bool processDXFGroup( DL_CreationInterface* creationInterface,
int groupCode, const std::string& groupValue );
void addSetting( DL_CreationInterface* creationInterface );
void addLayer( DL_CreationInterface* creationInterface );
void addLinetype( DL_CreationInterface* creationInterface );
void addBlock( DL_CreationInterface* creationInterface );
void endBlock( DL_CreationInterface* creationInterface );
void addTextStyle( DL_CreationInterface* creationInterface );
void addPoint( DL_CreationInterface* creationInterface );
void addLine( DL_CreationInterface* creationInterface );
void addXLine( DL_CreationInterface* creationInterface );
void addRay( DL_CreationInterface* creationInterface );
void addPolyline( DL_CreationInterface* creationInterface );
void addVertex( DL_CreationInterface* creationInterface );
void addSpline( DL_CreationInterface* creationInterface );
void addArc( DL_CreationInterface* creationInterface );
void addCircle( DL_CreationInterface* creationInterface );
void addEllipse( DL_CreationInterface* creationInterface );
void addInsert( DL_CreationInterface* creationInterface );
void addTrace( DL_CreationInterface* creationInterface );
void add3dFace( DL_CreationInterface* creationInterface );
void addSolid( DL_CreationInterface* creationInterface );
void addMText( DL_CreationInterface* creationInterface );
void addText( DL_CreationInterface* creationInterface );
void addArcAlignedText( DL_CreationInterface* creationInterface );
void addAttribute( DL_CreationInterface* creationInterface );
DL_DimensionData getDimData();
void addDimLinear( DL_CreationInterface* creationInterface );
void addDimAligned( DL_CreationInterface* creationInterface );
void addDimRadial( DL_CreationInterface* creationInterface );
void addDimDiametric( DL_CreationInterface* creationInterface );
void addDimAngular( DL_CreationInterface* creationInterface );
void addDimAngular3P( DL_CreationInterface* creationInterface );
void addDimOrdinate( DL_CreationInterface* creationInterface );
void addLeader( DL_CreationInterface* creationInterface );
void addHatch( DL_CreationInterface* creationInterface );
void addHatchLoop();
void addHatchEdge();
bool handleHatchData( DL_CreationInterface* creationInterface );
void addImage( DL_CreationInterface* creationInterface );
void addImageDef( DL_CreationInterface* creationInterface );
void addComment( DL_CreationInterface* creationInterface, const std::string& comment );
void addDictionary( DL_CreationInterface* creationInterface );
void addDictionaryEntry( DL_CreationInterface* creationInterface );
bool handleXRecordData( DL_CreationInterface* creationInterface );
bool handleDictionaryData( DL_CreationInterface* creationInterface );
bool handleXData( DL_CreationInterface* creationInterface );
bool handleMTextData( DL_CreationInterface* creationInterface );
bool handleLWPolylineData( DL_CreationInterface* creationInterface );
bool handleSplineData( DL_CreationInterface* creationInterface );
bool handleLeaderData( DL_CreationInterface* creationInterface );
bool handleLinetypeData( DL_CreationInterface* creationInterface );
void endEntity( DL_CreationInterface* creationInterface );
void endSequence( DL_CreationInterface* creationInterface );
// int stringToInt(const char* s, bool* ok=NULL);
DL_WriterA* out( const char* file,
DL_Codes::version version = DL_VERSION_2000 );
void writeHeader( DL_WriterA& dw );
void writePoint( DL_WriterA& dw,
const DL_PointData& data,
const DL_Attributes& attrib );
void writeLine( DL_WriterA& dw,
const DL_LineData& data,
const DL_Attributes& attrib );
void writeXLine( DL_WriterA& dw,
const DL_XLineData& data,
const DL_Attributes& attrib );
void writeRay( DL_WriterA& dw,
const DL_RayData& data,
const DL_Attributes& attrib );
void writePolyline( DL_WriterA& dw,
const DL_PolylineData& data,
const DL_Attributes& attrib );
void writeVertex( DL_WriterA& dw,
const DL_VertexData& data );
void writePolylineEnd( DL_WriterA& dw );
void writeSpline( DL_WriterA& dw,
const DL_SplineData& data,
const DL_Attributes& attrib );
void writeControlPoint( DL_WriterA& dw,
const DL_ControlPointData& data );
void writeFitPoint( DL_WriterA& dw,
const DL_FitPointData& data );
void writeKnot( DL_WriterA& dw,
const DL_KnotData& data );
void writeCircle( DL_WriterA& dw,
const DL_CircleData& data,
const DL_Attributes& attrib );
void writeArc( DL_WriterA& dw,
const DL_ArcData& data,
const DL_Attributes& attrib );
void writeEllipse( DL_WriterA& dw,
const DL_EllipseData& data,
const DL_Attributes& attrib );
void writeSolid( DL_WriterA& dw,
const DL_SolidData& data,
const DL_Attributes& attrib );
void writeTrace( DL_WriterA& dw,
const DL_TraceData& data,
const DL_Attributes& attrib );
void write3dFace( DL_WriterA& dw,
const DL_3dFaceData& data,
const DL_Attributes& attrib );
void writeInsert( DL_WriterA& dw,
const DL_InsertData& data,
const DL_Attributes& attrib );
void writeMText( DL_WriterA& dw,
const DL_MTextData& data,
const DL_Attributes& attrib );
void writeText( DL_WriterA& dw,
const DL_TextData& data,
const DL_Attributes& attrib );
void writeAttribute( DL_WriterA& dw,
const DL_AttributeData& data,
const DL_Attributes& attrib );
void writeDimStyleOverrides( DL_WriterA& dw,
const DL_DimensionData& data );
void writeDimAligned( DL_WriterA& dw,
const DL_DimensionData& data,
const DL_DimAlignedData& edata,
const DL_Attributes& attrib );
void writeDimLinear( DL_WriterA& dw,
const DL_DimensionData& data,
const DL_DimLinearData& edata,
const DL_Attributes& attrib );
void writeDimRadial( DL_WriterA& dw,
const DL_DimensionData& data,
const DL_DimRadialData& edata,
const DL_Attributes& attrib );
void writeDimDiametric( DL_WriterA& dw,
const DL_DimensionData& data,
const DL_DimDiametricData& edata,
const DL_Attributes& attrib );
void writeDimAngular( DL_WriterA& dw,
const DL_DimensionData& data,
const DL_DimAngularData& edata,
const DL_Attributes& attrib );
void writeDimAngular3P( DL_WriterA& dw,
const DL_DimensionData& data,
const DL_DimAngular3PData& edata,
const DL_Attributes& attrib );
void writeDimOrdinate( DL_WriterA& dw,
const DL_DimensionData& data,
const DL_DimOrdinateData& edata,
const DL_Attributes& attrib );
void writeLeader( DL_WriterA& dw,
const DL_LeaderData& data,
const DL_Attributes& attrib );
void writeLeaderVertex( DL_WriterA& dw,
const DL_LeaderVertexData& data );
void writeHatch1( DL_WriterA& dw,
const DL_HatchData& data,
const DL_Attributes& attrib );
void writeHatch2( DL_WriterA& dw,
const DL_HatchData& data,
const DL_Attributes& attrib );
void writeHatchLoop1( DL_WriterA& dw,
const DL_HatchLoopData& data );
void writeHatchLoop2( DL_WriterA& dw,
const DL_HatchLoopData& data );
void writeHatchEdge( DL_WriterA& dw,
const DL_HatchEdgeData& data );
int writeImage( DL_WriterA& dw,
const DL_ImageData& data,
const DL_Attributes& attrib );
void writeImageDef( DL_WriterA& dw, int handle,
const DL_ImageData& data );
void writeLayer( DL_WriterA& dw,
const DL_LayerData& data,
const DL_Attributes& attrib );
void writeLinetype( DL_WriterA& dw,
const DL_LinetypeData& data );
void writeAppid( DL_WriterA& dw, const std::string& name );
void writeBlock( DL_WriterA& dw,
const DL_BlockData& data );
void writeEndBlock( DL_WriterA& dw, const std::string& name );
void writeVPort( DL_WriterA& dw );
void writeStyle( DL_WriterA& dw, const DL_StyleData& style );
void writeView( DL_WriterA& dw );
void writeUcs( DL_WriterA& dw );
void writeDimStyle( DL_WriterA& dw,
double dimasz, double dimexe, double dimexo,
double dimgap, double dimtxt );
void writeBlockRecord( DL_WriterA& dw );
void writeBlockRecord( DL_WriterA& dw, const std::string& name );
void writeObjects( DL_WriterA& dw, const std::string& appDictionaryName = "" );
void writeAppDictionary( DL_WriterA& dw );
int writeDictionaryEntry( DL_WriterA& dw, const std::string& name );
void writeXRecord( DL_WriterA& dw, int handle, int value );
void writeXRecord( DL_WriterA& dw, int handle, double value );
void writeXRecord( DL_WriterA& dw, int handle, bool value );
void writeXRecord( DL_WriterA& dw, int handle, const std::string& value );
void writeObjectsEnd( DL_WriterA& dw );
void writeComment( DL_WriterA& dw, const std::string& comment );
/**
* Converts the given string into a double or returns the given
* default valud (def) if value is NULL or empty.
*/
// static double toReal(const char* value, double def=0.0);
/**
* Converts the given string into an int or returns the given
* default valud (def) if value is NULL or empty.
*/
// static int toInt(const char* value, int def=0) {
// if (value!=NULL && value[0] != '\0') {
// return atoi(value);
// }
// return def;
// }
/**
* Converts the given string into a string or returns the given
* default valud (def) if value is NULL or empty.
*/
// static const char* toString(const char* value, const char* def="") {
// if (value!=NULL && value[0] != '\0') {
// return value;
// } else {
// return def;
// }
// }
static bool checkVariable( const char* var, DL_Codes::version version );
DL_Codes::version getVersion()
{
return version;
}
int getLibVersion( const std::string& str );
static void test();
bool hasValue( int code )
{
return values.count( code )==1;
}
int getIntValue( int code, int def )
{
if( !hasValue( code ) )
{
return def;
}
return toInt( values[code] );
}
int toInt( const std::string& str )
{
char* p;
return strtol( str.c_str(), &p, 10 );
}
int getInt16Value( int code, int def )
{
if( !hasValue( code ) )
{
return def;
}
return toInt16( values[code] );
}
int toInt16( const std::string& str )
{
char* p;
return strtol( str.c_str(), &p, 16 );
}
bool toBool( const std::string& str )
{
char* p;
return (bool) strtol( str.c_str(), &p, 10 );
}
std::string getStringValue( int code, const std::string& def )
{
if( !hasValue( code ) )
{
return def;
}
return values[code];
}
double getRealValue( int code, double def )
{
if( !hasValue( code ) )
{
return def;
}
return toReal( values[code] );
}
double toReal( const std::string& str )
{
double ret;
// make sure the real value uses '.' not ',':
std::string str2 = str;
std::replace( str2.begin(), str2.end(), ',', '.' );
// make sure c++ expects '.' not ',':
std::istringstream istr( str2 );
// istr.imbue(std::locale("C"));
istr >> ret;
return ret;
}
private:
DL_Codes::version version;
std::string polylineLayer;
double* vertices;
int maxVertices;
int vertexIndex;
double* knots;
int maxKnots;
int knotIndex;
double* weights;
int weightIndex;
double* controlPoints;
int maxControlPoints;
int controlPointIndex;
double* fitPoints;
int maxFitPoints;
int fitPointIndex;
double* leaderVertices;
int maxLeaderVertices;
int leaderVertexIndex;
bool firstHatchLoop;
DL_HatchEdgeData hatchEdge;
std::vector<std::vector<DL_HatchEdgeData> > hatchEdges;
std::string xRecordHandle;
bool xRecordValues;
// Only the useful part of the group code
std::string groupCodeTmp;
// ...same as integer
unsigned int groupCode;
// Only the useful part of the group value
std::string groupValue;
// Current entity type
int currentObjectType;
// Value of the current setting
char settingValue[DL_DXF_MAXLINE + 1];
// Key of the current setting (e.g. "$ACADVER")
std::string settingKey;
// Stores the group codes
std::map<int, std::string> values;
// First call of this method. We initialize all group values in
// the first call.
bool firstCall;
// Attributes of the current entity (layer, color, width, line type)
DL_Attributes attrib;
// library version. hex: 0x20003001 = 2.0.3.1
int libVersion;
// app specific dictionary handle:
unsigned long appDictionaryHandle;
// handle of standard text style, referenced by dimstyle:
unsigned long styleHandleStd;
};
#endif
// EOF

2047
dxflib_qcad/dl_entities.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,55 @@
/****************************************************************************
** Copyright (C) 2001-2013 RibbonSoft, GmbH. All rights reserved.
** Copyright (C) 2001 Robert J. Campbell Jr.
**
** This file is part of the dxflib project.
**
** This file is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** Licensees holding valid dxflib Professional Edition licenses may use
** this file in accordance with the dxflib 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.
**
** See http://www.ribbonsoft.com for further details.
**
** Contact info@ribbonsoft.com if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/
#ifndef DL_EXCEPTION_H
#define DL_EXCEPTION_H
#include "dl_global.h"
/**
* Used for exception handling.
*/
class DXFLIB_EXPORT DL_Exception
{
}
;
/**
* Used for exception handling.
*/
class DXFLIB_EXPORT DL_NullStrExc : public DL_Exception
{
}
;
/**
* Used for exception handling.
*/
class DXFLIB_EXPORT DL_GroupCodeExc : public DL_Exception
{
DL_GroupCodeExc( int gc = 0 ) : groupCode( gc ) {}
int groupCode;
};
#endif

135
dxflib_qcad/dl_extrusion.h Normal file
View File

@ -0,0 +1,135 @@
/****************************************************************************
** Copyright (C) 2001-2013 RibbonSoft, GmbH. All rights reserved.
**
** This file is part of the dxflib project.
**
** This file is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** Licensees holding valid dxflib Professional Edition licenses may use
** this file in accordance with the dxflib 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.
**
** See http://www.ribbonsoft.com for further details.
**
** Contact info@ribbonsoft.com if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/
#ifndef DL_EXTRUSION_H
#define DL_EXTRUSION_H
#include "dl_global.h"
#include <math.h>
/**
* Extrusion direction.
*
* @author Andrew Mustun
*/
class DXFLIB_EXPORT DL_Extrusion
{
public:
/**
* Default constructor.
*/
DL_Extrusion()
{
direction = new double[3];
setDirection( 0.0, 0.0, 1.0 );
setElevation( 0.0 );
}
/**
* Destructor.
*/
~DL_Extrusion()
{
delete[] direction;
}
/**
* Constructor for DXF extrusion.
*
* @param direction Vector of axis along which the entity shall be extruded
* this is also the Z axis of the Entity coordinate system
* @param elevation Distance of the entities XY plane from the origin of the
* world coordinate system
*/
DL_Extrusion( double adx, double ady, double adz, double aelevation )
{
direction = new double[3];
setDirection( adx, ady, adz );
setElevation( aelevation );
}
/**
* Sets the direction vector.
*/
void setDirection( double dx, double dy, double dz )
{
direction[0] = dx;
direction[1] = dy;
direction[2] = dz;
}
/**
* @return direction vector.
*/
double* getDirection() const
{
return direction;
}
/**
* @return direction vector.
*/
void getDirection( double dir[] ) const
{
dir[0] = direction[0];
dir[1] = direction[1];
dir[2] = direction[2];
}
/**
* Sets the elevation.
*/
void setElevation( double aelevation )
{
this->elevation = aelevation;
}
/**
* @return Elevation.
*/
double getElevation() const
{
return elevation;
}
/**
* Copies extrusion (deep copies) from another extrusion object.
*/
DL_Extrusion operator =( const DL_Extrusion& extru )
{
setDirection( extru.direction[0], extru.direction[1], extru.direction[2] );
setElevation( extru.elevation );
return *this;
}
private:
double* direction;
double elevation;
};
#endif

13
dxflib_qcad/dl_global.h Normal file
View File

@ -0,0 +1,13 @@
#if defined(DXFLIB_DLL)
# ifdef _WIN32
# if defined(DXFLIB_LIBRARY)
# define DXFLIB_EXPORT __declspec( dllexport )
# else
# define DXFLIB_EXPORT __declspec( dllimport )
# endif
# else
# define DXFLIB_EXPORT
# endif
#else
# define DXFLIB_EXPORT
#endif

750
dxflib_qcad/dl_writer.h Normal file
View File

@ -0,0 +1,750 @@
/****************************************************************************
** Copyright (C) 2001-2013 RibbonSoft, GmbH. All rights reserved.
** Copyright (C) 2001 Robert J. Campbell Jr.
**
** This file is part of the dxflib project.
**
** This file is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** Licensees holding valid dxflib Professional Edition licenses may use
** this file in accordance with the dxflib 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.
**
** See http://www.ribbonsoft.com for further details.
**
** Contact info@ribbonsoft.com if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/
#ifndef DL_WRITER_H
#define DL_WRITER_H
#include "dl_global.h"
#ifndef _WIN32
#include <strings.h>
#endif
#include <iostream>
#include <algorithm>
#include "dl_attributes.h"
#include "dl_codes.h"
/**
* Defines interface for writing low level DXF constructs to
* a file. Implementation is defined in derived classes that write
* to binary or ASCII files.
*
* Implements functions that write higher level constructs in terms of
* the low level ones.
*
* @todo Add error checking for string/entry length.
*/
class DXFLIB_EXPORT DL_Writer
{
public:
/**
* @param version DXF version. Defaults to DL_VERSION_2002.
*/
DL_Writer( DL_Codes::version aversion ) : m_handle( 0x30 )
{
version = aversion;
modelSpaceHandle = 0;
paperSpaceHandle = 0;
paperSpace0Handle = 0;
}
virtual ~DL_Writer() {}
;
/** Generic section for section 'name'.
*
* <pre>
* 0
* SECTION
* 2
* name
* </pre>
*/
void section( const char* name ) const
{
dxfString( 0, "SECTION" );
dxfString( 2, name );
}
/**
* Section HEADER
*
* <pre>
* 0
* SECTION
* 2
* HEADER
* </pre>
*/
void sectionHeader() const
{
section( "HEADER" );
}
/**
* Section TABLES
*
* <pre>
* 0
* SECTION
* 2
* TABLES
* </pre>
*/
void sectionTables() const
{
section( "TABLES" );
}
/**
* Section BLOCKS
*
* <pre>
* 0
* SECTION
* 2
* BLOCKS
* </pre>
*/
void sectionBlocks() const
{
section( "BLOCKS" );
}
/**
* Section ENTITIES
*
* <pre>
* 0
* SECTION
* 2
* ENTITIES
* </pre>
*/
void sectionEntities() const
{
section( "ENTITIES" );
}
/**
* Section CLASSES
*
* <pre>
* 0
* SECTION
* 2
* CLASSES
* </pre>
*/
void sectionClasses() const
{
section( "CLASSES" );
}
/**
* Section OBJECTS
*
* <pre>
* 0
* SECTION
* 2
* OBJECTS
* </pre>
*/
void sectionObjects() const
{
section( "OBJECTS" );
}
/**
* End of a section.
*
* <pre>
* 0
* ENDSEC
* </pre>
*/
void sectionEnd() const
{
dxfString( 0, "ENDSEC" );
}
/**
* Generic table for table 'name' with 'num' entries:
*
* <pre>
* 0
* TABLE
* 2
* name
* 70
* num
* </pre>
*/
void table( const char* name, int num, int h = 0 ) const
{
dxfString( 0, "TABLE" );
dxfString( 2, name );
if( version>=DL_VERSION_2000 )
{
if( h==0 )
{
handle();
}
else
{
dxfHex( 5, h );
}
dxfString( 100, "AcDbSymbolTable" );
}
dxfInt( 70, num );
}
/** Table for layers.
*
* @param num Number of layers in total.
*
* <pre>
* 0
* TABLE
* 2
* LAYER
* 70
* num
* </pre>
*/
void tableLayers( int num ) const
{
table( "LAYER", num, 2 );
}
/** Table for line types.
*
* @param num Number of line types in total.
*
* <pre>
* 0
* TABLE
* 2
* LTYPE
* 70
* num
* </pre>
*/
void tableLinetypes( int num ) const
{
// linetypeHandle = 5;
table( "LTYPE", num, 5 );
}
/** Table for application id.
*
* @param num Number of registered applications in total.
*
* <pre>
* 0
* TABLE
* 2
* APPID
* 70
* num
* </pre>
*/
void tableAppid( int num ) const
{
table( "APPID", num, 9 );
}
/** Table for text style.
*
* @param num Number of text styles.
*
* <pre>
* 0
* TABLE
* 2
* STYLE
* 70
* num
* </pre>
*/
void tableStyle( int num ) const
{
table( "STYLE", num, 3 );
}
/**
* End of a table.
*
* <pre>
* 0
* ENDTAB
* </pre>
*/
void tableEnd() const
{
dxfString( 0, "ENDTAB" );
}
/**
* End of the DXF file.
*
* <pre>
* 0
* EOF
* </pre>
*/
void dxfEOF() const
{
dxfString( 0, "EOF" );
}
/**
* Comment.
*
* <pre>
* 999
* text
* </pre>
*/
void comment( const char* text ) const
{
dxfString( 999, text );
}
/**
* Entity.
*
* <pre>
* 0
* entTypeName
* </pre>
*
* @return Unique handle or 0.
*/
void entity( const char* entTypeName ) const
{
dxfString( 0, entTypeName );
if( version>=DL_VERSION_2000 )
{
handle();
}
}
/**
* Attributes of an entity.
*
* <pre>
* 8
* layer
* 62
* color
* 39
* width
* 6
* linetype
* </pre>
*/
void entityAttributes( const DL_Attributes& attrib ) const
{
// layer name:
dxfString( 8, attrib.getLayer() );
// R12 doesn't accept BYLAYER values. The value has to be missing
// in that case.
if( version>=DL_VERSION_2000 || attrib.getColor()!=256 )
{
dxfInt( 62, attrib.getColor() );
}
if( version>=DL_VERSION_2000 && attrib.getColor24()!=-1 )
{
dxfInt( 420, attrib.getColor24() );
}
if( version>=DL_VERSION_2000 )
{
dxfInt( 370, attrib.getWidth() );
}
if( version>=DL_VERSION_2000 )
{
dxfReal( 48, attrib.getLinetypeScale() );
}
std::string linetype = attrib.getLinetype();
std::transform( linetype.begin(), linetype.end(), linetype.begin(), ::toupper );
if( version>=DL_VERSION_2000 || linetype=="BYLAYER" )
{
dxfString( 6, attrib.getLinetype() );
}
}
/**
* Subclass.
*/
void subClass( const char* sub ) const
{
dxfString( 100, sub );
}
/**
* Layer (must be in the TABLES section LAYER).
*
* <pre>
* 0
* LAYER
* </pre>
*/
void tableLayerEntry( unsigned long int h = 0 ) const
{
dxfString( 0, "LAYER" );
if( version>=DL_VERSION_2000 )
{
if( h==0 )
{
handle();
}
else
{
dxfHex( 5, h );
}
dxfString( 100, "AcDbSymbolTableRecord" );
dxfString( 100, "AcDbLayerTableRecord" );
}
}
/**
* Line type (must be in the TABLES section LTYPE).
*
* <pre>
* 0
* LTYPE
* </pre>
*/
void tableLinetypeEntry( unsigned long int h = 0 ) const
{
dxfString( 0, "LTYPE" );
if( version>=DL_VERSION_2000 )
{
if( h==0 )
{
handle();
}
else
{
dxfHex( 5, h );
}
// dxfHex(330, 0x5);
dxfString( 100, "AcDbSymbolTableRecord" );
dxfString( 100, "AcDbLinetypeTableRecord" );
}
}
/**
* Appid (must be in the TABLES section APPID).
*
* <pre>
* 0
* APPID
* </pre>
*/
void tableAppidEntry( unsigned long int h = 0 ) const
{
dxfString( 0, "APPID" );
if( version>=DL_VERSION_2000 )
{
if( h==0 )
{
handle();
}
else
{
dxfHex( 5, h );
}
// dxfHex(330, 0x9);
dxfString( 100, "AcDbSymbolTableRecord" );
dxfString( 100, "AcDbRegAppTableRecord" );
}
}
/**
* Block (must be in the section BLOCKS).
*
* <pre>
* 0
* BLOCK
* </pre>
*/
void sectionBlockEntry( unsigned long int h = 0 ) const
{
dxfString( 0, "BLOCK" );
if( version>=DL_VERSION_2000 )
{
if( h==0 )
{
handle();
}
else
{
dxfHex( 5, h );
}
// dxfHex(330, blockHandle);
dxfString( 100, "AcDbEntity" );
if( h==0x1C )
{
dxfInt( 67, 1 );
}
dxfString( 8, "0" ); // TODO: Layer for block
dxfString( 100, "AcDbBlockBegin" );
}
}
/**
* End of Block (must be in the section BLOCKS).
*
* <pre>
* 0
* ENDBLK
* </pre>
*/
void sectionBlockEntryEnd( unsigned long int h = 0 ) const
{
dxfString( 0, "ENDBLK" );
if( version>=DL_VERSION_2000 )
{
if( h==0 )
{
handle();
}
else
{
dxfHex( 5, h );
}
// dxfHex(330, blockHandle);
dxfString( 100, "AcDbEntity" );
if( h==0x1D )
{
dxfInt( 67, 1 );
}
dxfString( 8, "0" ); // TODO: Layer for block
dxfString( 100, "AcDbBlockEnd" );
}
}
void color( int col = 256 ) const
{
dxfInt( 62, col );
}
void linetype( const char* lt ) const
{
dxfString( 6, lt );
}
void linetypeScale( double scale ) const
{
dxfReal( 48, scale );
}
void lineWeight( int lw ) const
{
dxfInt( 370, lw );
}
void coord( int gc, double x, double y, double z = 0 ) const
{
dxfReal( gc, x );
dxfReal( gc + 10, y );
dxfReal( gc + 20, z );
}
void coordTriplet( int gc, const double* value ) const
{
if( value )
{
dxfReal( gc, *value++ );
dxfReal( gc + 10, *value++ );
dxfReal( gc + 20, *value++ );
}
}
void resetHandle() const
{
m_handle = 1;
}
/**
* Writes a unique handle and returns it.
*/
unsigned long handle( int gc = 5 ) const
{
// handle has to be hex
dxfHex( gc, m_handle );
return m_handle++;
}
/**
* @return Next handle that will be written.
*/
unsigned long getNextHandle() const
{
return m_handle;
}
/**
* Increases handle, so that the handle returned remains available.
*/
unsigned long incHandle() const
{
return m_handle++;
}
/**
* Sets the handle of the model space. Entities refer to
* this handle.
*/
void setModelSpaceHandle( unsigned long h )
{
modelSpaceHandle = h;
}
unsigned long getModelSpaceHandle()
{
return modelSpaceHandle;
}
/**
* Sets the handle of the paper space. Some special blocks refer to
* this handle.
*/
void setPaperSpaceHandle( unsigned long h )
{
paperSpaceHandle = h;
}
unsigned long getPaperSpaceHandle()
{
return paperSpaceHandle;
}
/**
* Sets the handle of the paper space 0. Some special blocks refer to
* this handle.
*/
void setPaperSpace0Handle( unsigned long h )
{
paperSpace0Handle = h;
}
unsigned long getPaperSpace0Handle()
{
return paperSpace0Handle;
}
/**
* Must be overwritten by the implementing class to write a
* real value to the file.
*
* @param gc Group code.
* @param value The real value.
*/
virtual void dxfReal( int gc, double value ) const = 0;
/**
* Must be overwritten by the implementing class to write an
* int value to the file.
*
* @param gc Group code.
* @param value The int value.
*/
virtual void dxfInt( int gc, int value ) const = 0;
/**
* Can be overwritten by the implementing class to write a
* bool value to the file.
*
* @param gc Group code.
* @param value The bool value.
*/
virtual void dxfBool( int gc, bool value ) const
{
dxfInt( gc, (int) value );
}
/**
* Must be overwritten by the implementing class to write an
* int value (hex) to the file.
*
* @param gc Group code.
* @param value The int value.
*/
virtual void dxfHex( int gc, int value ) const = 0;
/**
* Must be overwritten by the implementing class to write a
* string to the file.
*
* @param gc Group code.
* @param value The string.
*/
virtual void dxfString( int gc, const char* value ) const = 0;
/**
* Must be overwritten by the implementing class to write a
* string to the file.
*
* @param gc Group code.
* @param value The string.
*/
virtual void dxfString( int gc, const std::string& value ) const = 0;
protected:
mutable unsigned long m_handle;
mutable unsigned long modelSpaceHandle;
mutable unsigned long paperSpaceHandle;
mutable unsigned long paperSpace0Handle;
/**
* DXF version to be created.
*/
DL_Codes::version version;
private:
};
#endif

View File

@ -0,0 +1,171 @@
/****************************************************************************
** Copyright (C) 2001-2013 RibbonSoft, GmbH. All rights reserved.
** Copyright (C) 2001 Robert J. Campbell Jr.
**
** This file is part of the dxflib project.
**
** This file is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** Licensees holding valid dxflib Professional Edition licenses may use
** this file in accordance with the dxflib 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.
**
** See http://www.ribbonsoft.com for further details.
**
** Contact info@ribbonsoft.com if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/
#include <stdio.h>
#include <string.h>
#include "dl_writer_ascii.h"
#include "dl_exception.h"
/**
* Closes the output file.
*/
void DL_WriterA::close() const
{
m_ofile.close();
}
/**
* @retval true Opening file has failed.
* @retval false Otherwise.
*/
bool DL_WriterA::openFailed() const
{
return m_ofile.fail();
}
/**
* Writes a real (double) variable to the DXF file.
*
* @param gc Group code.
* @param value Double value
*/
void DL_WriterA::dxfReal( int gc, double value ) const
{
char str[256];
if( version==DL_Codes::AC1009_MIN )
{
sprintf( str, "%.6lf", value );
}
else
{
sprintf( str, "%.16lf", value );
}
// fix for german locale:
strReplace( str, ',', '.' );
// Cut away those zeros at the end:
bool dot = false;
int end = -1;
for( unsigned int i = 0; i<strlen( str ); ++i )
{
if( str[i]=='.' )
{
dot = true;
end = i + 2;
continue;
}
else if( dot && str[i]!='0' )
{
end = i + 1;
}
}
if( end>0 && end<(int) strlen( str ) )
{
str[end] = '\0';
}
dxfString( gc, str );
m_ofile.flush();
}
/**
* Writes an int variable to the DXF file.
*
* @param gc Group code.
* @param value Int value
*/
void DL_WriterA::dxfInt( int gc, int value ) const
{
m_ofile << ( gc<10 ? " " : (gc<100 ? " " : "") ) << gc << "\n" << value << "\n";
}
/**
* Writes a hex int variable to the DXF file.
*
* @param gc Group code.
* @param value Int value
*/
void DL_WriterA::dxfHex( int gc, int value ) const
{
char str[12];
sprintf( str, "%0X", value );
dxfString( gc, str );
}
/**
* Writes a string variable to the DXF file.
*
* @param gc Group code.
* @param value String
*/
void DL_WriterA::dxfString( int gc, const char* value ) const
{
if( value==NULL )
{
#ifndef __GCC2x__
// throw DL_NullStrExc();
#endif
}
m_ofile << ( gc<10 ? " " : (gc<100 ? " " : "") ) << gc << "\n"
<< value << "\n";
}
void DL_WriterA::dxfString( int gc, const std::string& value ) const
{
m_ofile << ( gc<10 ? " " : (gc<100 ? " " : "") ) << gc << "\n"
<< value << "\n";
}
/**
* Replaces every occurence of src with dest in the null terminated str.
*/
void DL_WriterA::strReplace( char* str, char src, char dest )
{
size_t i;
for( i = 0; i<strlen( str ); i++ )
{
if( str[i]==src )
{
str[i] = dest;
}
}
}

View File

@ -0,0 +1,70 @@
/****************************************************************************
** Copyright (C) 2001-2013 RibbonSoft, GmbH. All rights reserved.
** Copyright (C) 2001 Robert J. Campbell Jr.
**
** This file is part of the dxflib project.
**
** This file is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** Licensees holding valid dxflib Professional Edition licenses may use
** this file in accordance with the dxflib 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.
**
** See http://www.ribbonsoft.com for further details.
**
** Contact info@ribbonsoft.com if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/
#ifndef DL_WRITER_ASCII_H
#define DL_WRITER_ASCII_H
#include "dl_global.h"
#include "dl_writer.h"
#include <fstream>
#include <string>
/**
* Implements functions defined in DL_Writer for writing low
* level DXF constructs to an ASCII format DXF file.
*
* @param fname File name of the file to be created.
* @param version DXF version. Defaults to DL_VERSION_2002.
*
* @todo What if \c fname is NULL? Or \c fname can't be opened for
* another reason?
*/
class DXFLIB_EXPORT DL_WriterA : public DL_Writer
{
public:
DL_WriterA( const char* afname, DL_Codes::version aversion = DL_VERSION_2000 )
: DL_Writer( aversion ), m_ofile( afname ) {}
virtual ~DL_WriterA() {}
bool openFailed() const;
void close() const;
void dxfReal( int gc, double value ) const override;
void dxfInt( int gc, int value ) const override;
void dxfHex( int gc, int value ) const override;
void dxfString( int gc, const char* value ) const override;
void dxfString( int gc, const std::string& value ) const override;
static void strReplace( char* str, char src, char dest );
private:
/**
* DXF file to be created.
*/
mutable std::ofstream m_ofile;
};
#endif

171
dxflib_qcad/dxflib.doxygen Normal file
View File

@ -0,0 +1,171 @@
PROJECT_NAME = dxflib
OUTPUT_DIRECTORY = doc/classref
CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = English
USE_WINDOWS_ENCODING = NO
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES
ABBREVIATE_BRIEF =
ALWAYS_DETAILED_SEC = NO
INLINE_INHERITED_MEMB = NO
FULL_PATH_NAMES = YES
STRIP_FROM_PATH =
STRIP_FROM_INC_PATH =
SHORT_NAMES = NO
JAVADOC_AUTOBRIEF = YES
MULTILINE_CPP_IS_BRIEF = NO
DETAILS_AT_TOP = NO
INHERIT_DOCS = YES
SEPARATE_MEMBER_PAGES = NO
TAB_SIZE = 8
ALIASES =
OPTIMIZE_OUTPUT_FOR_C = NO
OPTIMIZE_OUTPUT_JAVA = NO
BUILTIN_STL_SUPPORT = NO
DISTRIBUTE_GROUP_DOC = NO
SUBGROUPING = YES
EXTRACT_ALL = NO
EXTRACT_PRIVATE = NO
EXTRACT_STATIC = YES
EXTRACT_LOCAL_CLASSES = YES
EXTRACT_LOCAL_METHODS = NO
HIDE_UNDOC_MEMBERS = NO
HIDE_UNDOC_CLASSES = NO
HIDE_FRIEND_COMPOUNDS = NO
HIDE_IN_BODY_DOCS = NO
INTERNAL_DOCS = NO
CASE_SENSE_NAMES = YES
HIDE_SCOPE_NAMES = NO
SHOW_INCLUDE_FILES = YES
INLINE_INFO = YES
SORT_MEMBER_DOCS = YES
SORT_BRIEF_DOCS = NO
SORT_BY_SCOPE_NAME = NO
GENERATE_TODOLIST = YES
GENERATE_TESTLIST = YES
GENERATE_BUGLIST = YES
GENERATE_DEPRECATEDLIST= YES
ENABLED_SECTIONS =
MAX_INITIALIZER_LINES = 30
SHOW_USED_FILES = YES
SHOW_DIRECTORIES = NO
FILE_VERSION_FILTER =
QUIET = NO
WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
WARN_IF_DOC_ERROR = YES
WARN_NO_PARAMDOC = NO
WARN_FORMAT = "$file:$line: $text"
WARN_LOGFILE =
INPUT = ./src
FILE_PATTERNS = *.h *.cpp
RECURSIVE = YES
EXCLUDE =
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS =
EXAMPLE_PATH =
EXAMPLE_PATTERNS =
EXAMPLE_RECURSIVE = NO
IMAGE_PATH =
INPUT_FILTER =
FILTER_PATTERNS =
FILTER_SOURCE_FILES = NO
SOURCE_BROWSER = NO
INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = YES
REFERENCED_BY_RELATION = YES
REFERENCES_RELATION = YES
REFERENCES_LINK_SOURCE = YES
USE_HTAGS = NO
VERBATIM_HEADERS = YES
ALPHABETICAL_INDEX = NO
COLS_IN_ALPHA_INDEX = 5
IGNORE_PREFIX =
GENERATE_HTML = YES
HTML_OUTPUT = html
HTML_FILE_EXTENSION = .html
HTML_HEADER =
HTML_FOOTER =
HTML_STYLESHEET =
HTML_ALIGN_MEMBERS = YES
GENERATE_HTMLHELP = NO
CHM_FILE =
HHC_LOCATION =
GENERATE_CHI = NO
BINARY_TOC = NO
TOC_EXPAND = NO
DISABLE_INDEX = NO
ENUM_VALUES_PER_LINE = 4
GENERATE_TREEVIEW = NO
TREEVIEW_WIDTH = 250
GENERATE_LATEX = NO
LATEX_OUTPUT = latex
LATEX_CMD_NAME = latex
MAKEINDEX_CMD_NAME = makeindex
COMPACT_LATEX = NO
PAPER_TYPE = a4wide
EXTRA_PACKAGES =
LATEX_HEADER =
PDF_HYPERLINKS = NO
USE_PDFLATEX = NO
LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
GENERATE_RTF = NO
RTF_OUTPUT = rtf
COMPACT_RTF = NO
RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
GENERATE_MAN = NO
MAN_OUTPUT = man
MAN_EXTENSION = .3
MAN_LINKS = NO
GENERATE_XML = NO
XML_OUTPUT = xml
XML_SCHEMA =
XML_DTD =
XML_PROGRAMLISTING = YES
GENERATE_AUTOGEN_DEF = NO
GENERATE_PERLMOD = NO
PERLMOD_LATEX = NO
PERLMOD_PRETTY = YES
PERLMOD_MAKEVAR_PREFIX =
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = NO
EXPAND_ONLY_PREDEF = NO
SEARCH_INCLUDES = YES
INCLUDE_PATH =
INCLUDE_FILE_PATTERNS =
PREDEFINED =
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
TAGFILES =
GENERATE_TAGFILE =
ALLEXTERNALS = NO
EXTERNAL_GROUPS = YES
PERL_PATH = /usr/bin/perl
CLASS_DIAGRAMS = YES
HIDE_UNDOC_RELATIONS = YES
HAVE_DOT = NO
CLASS_GRAPH = YES
COLLABORATION_GRAPH = YES
GROUP_GRAPHS = YES
UML_LOOK = NO
TEMPLATE_RELATIONS = NO
INCLUDE_GRAPH = YES
INCLUDED_BY_GRAPH = YES
CALL_GRAPH = NO
CALLER_GRAPH = NO
GRAPHICAL_HIERARCHY = YES
DIRECTORY_GRAPH = YES
DOT_IMAGE_FORMAT = png
DOT_PATH =
DOTFILE_DIRS =
MAX_DOT_GRAPH_WIDTH = 1024
MAX_DOT_GRAPH_HEIGHT = 1024
MAX_DOT_GRAPH_DEPTH = 0
DOT_TRANSPARENT = NO
DOT_MULTI_TARGETS = NO
GENERATE_LEGEND = YES
DOT_CLEANUP = YES
SEARCHENGINE = NO

View File

@ -0,0 +1,3 @@
#!/bin/sh
uncrustify -c ../uncrustify.cfg --replace --no-backup *.h *.cpp *.c

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,912 @@
/** @file tinyspline.h */
/*
* The MIT License (MIT)
*
* Copyright (c) 2016 Marcel Steinbeck
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef TINYSPLINE_H
#define TINYSPLINE_H
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
/******************************************************************************
* *
* System Dependent Configuration *
* *
* The following configuration values must be adjusted to your system. Some of *
* them may be configured using preprocessor definitions. The default values *
* should be fine for most modern hardware, such as x86, x86_64, and arm. *
* *
******************************************************************************/
#ifdef TINYSPLINE_FLOAT_PRECISION
typedef float tsReal;
#else
typedef double tsReal;
#endif
#define FLT_MAX_ABS_ERROR 1e-5
#define FLT_MAX_REL_ERROR 1e-8
/******************************************************************************
* *
* Data Types *
* *
* The following section defines all data types available in TinySpline. *
* *
******************************************************************************/
/**
* Contains all error codes used by TinySpline. The following code snippet
* shows how to handle errors:
*
* tsError err = ... // any function call here
* if (err < 0) { // or use err != TS_SUCCESS
* printf("we got an error!");
*
* // you may want to reuse error codes
* return err;
* }
*/
typedef enum
{
/* No error. */
TS_SUCCESS = 0,
/* Unable to allocate memory (using malloc/realloc). */
TS_MALLOC = -1,
/* The dimension of the control points are 0. */
TS_DIM_ZERO = -2,
/* Degree of spline (deg) >= number of control points (n_ctrlp). */
TS_DEG_GE_NCTRLP = -3,
/* Spline is not defined at knot value u. */
TS_U_UNDEFINED = -4,
/* Multiplicity of a knot (s) > order of spline. */
TS_MULTIPLICITY = -5,
/* Decreasing knot vector. */
TS_KNOTS_DECR = -6,
/* Unexpected number of knots. */
TS_NUM_KNOTS = -7,
/* Spline is not derivable */
TS_UNDERIVABLE = -8
} tsError;
/**
* Describes how the knot vector of a spline is organized. If you don't know
* what an opened or clamped spline is, have a look at:
*
* www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/B-spline/bspline-curve.html
*/
typedef enum
{
/* Not available/Undefined. */
TS_NONE = 0,
/* Uniformly spaced knot vector. */
TS_OPENED = 1,
/* Uniformly spaced knot vector with clamped end knots. */
TS_CLAMPED = 2,
/* Uniformly spaced knot vector with s(u) = order of spline. */
TS_BEZIERS = 3
} tsBSplineType;
/**
* Represents a B-Spline which may also be used for NURBS, Bezier curves,
* lines, and points. NURBS are represented using homogeneous coordinates where
* the last component of a control point is its weight. Bezier curves are
* B-Splines with 'n_ctrlp == order' and clamped knot vector making the curve
* passing through the first and last control point. If a Bezier curve consists
* of two control points only, we call them a line. Points, ultimately, are
* just very short lines having only a single control point. Consequently, the
* degree of a point is zero.
*
* Two dimensional control points are organized as follows:
*
* [x_0, y_0, x_1, y_1, ..., x_n-1, y_n-1]
*
* Tree dimensional control points are organized as follows:
*
* [x_0, y_0, z_0, x_1, y_1, z_1, ..., x_n-1, y_n-1, z_n-1]
*
* ... and so on. NURBS are represented using homogeneous coordinates. For
* instance, let's say we have a NURBS in 2D consisting of 11 control points
* where 'w_i' is the weight of the i'th control point. Then the corresponding
* control points are organized as follows:
*
* [x_0, y_0, w_0, x_1, y_1, w_1, ..., x_10, y_10, w_10]
*
* Note: The fields 'ctrlp' and 'knots' share the same array (similar to the
* approach used in 'tsDeBoorNet'). That is, the first elements of this
* array contain the control points of a spline whereas the last elements
* contain its knots. Accordingly, you should never free 'knots'
* explicitly. Using 'ts_bspline_free()' to free dynamically allocated
* memory is to be preferred anyway. If 'ctrlp' and 'knots' do not share
* the same array, or at least a consistent block of data, functions
* provided by TinySpline my fail because values are copied block wise.
*/
typedef struct
{
/* Degree of B-Spline basis function. */
size_t deg;
/* A convenience field for deg+1. */
size_t order;
/* Dimension of a control points. */
size_t dim;
/* Number of control points. */
size_t n_ctrlp;
/* Number of knots (n_ctrlp + deg + 1). */
size_t n_knots;
/* Control points of a spline. */
tsReal* ctrlp;
/* Knot vector of a spline (ascending order). */
tsReal* knots;
} tsBSpline;
/**
* Represents the output of De Boor's algorithm. De Boor's algorithm is used to
* evaluate a spline at given knot value 'u' by iteratively computing a net of
* intermediate values until the result is available:
*
* https://en.wikipedia.org/wiki/De_Boor%27s_algorithm
* https://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/de-Boor.html
*
* All points of the net are stored in 'points'. The resulting point of an
* evaluation is the last point in 'points' and, for the sake of convenience,
* may be accessed using 'result':
*
* tsDeBoorNet net = ... // evaluate an arbitrary spline and store
* // resulting net of points in 'net'
*
* net.result ... // use 'result' to access resulting point
*
* Note: You should never free 'result' explicitly as it is just a convenient
* accessor for the last point in 'points'. Using 'ts_deboornet_free()'
* to free dynamically allocated memory is to be preferred anyway.
*
* Two dimensional points are organized as follows:
*
* [x_0, y_0, x_1, y_1, ..., x_n-1, y_n-1]
*
* Tree dimensional points are organized as follows:
*
* [x_0, y_0, z_0, x_1, y_1, z_1, ..., x_n-1, y_n-1, z_n-1]
*
* ... and so on.
*
* There is a special case in which the evaluation of a knot value 'u' returns
* two instead of one result. It occurs when the multiplicity of 'u' ( s(u) )
* is equals to a spline's order indicating that the spline is discontinuous at
* 'u'. This is common practice for B-Splines (or NURBS) consisting of
* connected Bezier curves where the endpoint of curve 'c_i' is equals to the
* start point of curve 'c_i+1'. The end point of 'c_i' and the start point of
* 'c_i+1' may still be completely different though, yielding to a spline
* having a (real and visible) gap at 'u'. Consequently, De Boor's algorithm
* must return two results if 's(u) == order' in order to give you access to
* the desired points. In such case, 'points' stores only the two resulting
* points (there is no net to create) and 'result' points to the *first* point
* in 'points' ('points' and 'result' store the same pointer). Since having
* (real) gaps in splines is unusual, both points in 'points' are generally
* equals making it easy to handle this special case by accessing 'result' as
* already shown above for regular cases:
*
* tsDeBoorNet net = ... // evaluate a spline which is discontinuous at
* // at given knot value yielding to a net with
* // two results
*
* net.result ... // use 'result' to access resulting point
*
* However, you can use both points if necessary:
*
* tsDeBoorNet net = ... // evaluate a spline which is discontinuous at
* // at given knot value yielding to a net with
* // two results
*
* net.result[0] ... // 'result[0]' stores the first component of
* // the first point
*
* net.result[net.dim] // 'result[net.dim]' stores the first component
* // of the second point
*
* As if this wasn't complicated enough, there is an exception for our special
* case yielding to exactly one result (just like the regular case) even if
* 's(u) == order'. It occurs when 'u' is the lower or upper bound of a
* spline's domain. For instance, if 'b' is a spline with domain [0, 1] and is
* evaluated at 'u = 0' or 'u = 1' then 'result' is *always* a single point
* regardless of the multiplicity of 'u'. Hence, handling this exception is
* straightforward:
*
* tsDeBoorNet net = ... // evaluate a spline at lower or upper bound of
* // its domain, for instance, 0 or 1
*
* net.result ... // use 'result' to access resulting point
*
* In summary, we have three different types of evaluation. 1) The regular case
* returning all points of the net we used to calculate the resulting point. 2)
* The special case returning exactly two points which is required for splines
* having (real) gaps. 3) The exception of 2) returning exactly one point even
* if 's(u) == order'. All in all this looks quite complex (and actually it is)
* but for most applications you don't need to bother with them. Just use
* 'result' to access your evaluation point.
*/
typedef struct
{
/* The evaluated knot value. */
tsReal u;
/* The index [u_k, u_k+1) */
size_t k;
/* Multiplicity of u_k. */
size_t s;
/* How many times u must be inserted to get the resulting point. */
size_t h;
/* Dimension of a control point. */
size_t dim;
/* Number of points in 'points'. */
size_t n_points;
/* Points of the net used to evaluate u_k. */
tsReal* points;
/* A convenient pointer to the result in 'points'. */
tsReal* result;
} tsDeBoorNet;
/******************************************************************************
* *
* Constructors, Destructors, Copy, and Move Functions *
* *
* The following section contains functions to create and delete instances of *
* the data types listed above. Additionally, each data type has a copy and *
* move function. *
* *
******************************************************************************/
/**
* The default constructor of tsBSpline.
*
* All values of \p \_spline\_ are set to 0/NULL.
*
* @param \_spline\_
* The spline whose values are set 0/NULL.
*/
void ts_bspline_default( tsBSpline* _spline_ );
/**
* A convenient constructor for tsBSpline.
*
* On error, all values of \p \_spline\_ are set to 0/NULL.
*
* @param n_ctrlp
* The number of control points of \p \_spline\_.
* @param dim
* The dimension of each control point in \p \_spline\_.
* @param deg
* The degree of \p \_spline\_.
* @param type
* How to setup the knot vector of \p \_spline\_.
* @param \_spline\_
* The output parameter storing the result of this function.
* @return TS_SUCCESS
* On success.
* @return TS_DIM_ZERO
* If \p deg == 0.
* @return TS_DEG_GE_NCTRLP
* If \p deg >= \p n_ctrlp.
* @return TS_NUM_KNOTS
* If \p type == ::TS_BEZIERS and (\p n_ctrlp % \p deg + 1) != 0.
* @return TS_MALLOC
* If allocating memory failed.
*/
tsError ts_bspline_new( size_t n_ctrlp, size_t dim, size_t deg,
tsBSplineType type, tsBSpline* _spline_ );
/**
* The copy constructor of tsBSpline.
*
* Creates a deep copy of \p original and stores the result in \p \_copy\_.
*
* On error, all values of \p \_copy\_ are set to 0/NULL. Does nothing, if
* \p original == \p \_copy\_.
*
* @param original
* The spline to deep copy.
* @param \_copy\_
* The output parameter storing the copied values of \p original.
* @return TS_SUCCESS
* On success.
* @return TS_MALLOC
* If allocating memory failed.
*/
tsError ts_bspline_copy( const tsBSpline* original, tsBSpline* _copy_ );
/**
* The move constructor of tsBSpline.
*
* Moves all values from \p from to \p \_to\_ and calls ::ts_bspline_default
* on \p from afterwards. Does nothing, if \p from == \p \_to\_.
*
* @param from
* The spline whose values are moved to \p \_to\_.
* @param \_to\_
* The output parameter storing the moved values of \p from.
*/
void ts_bspline_move( tsBSpline* from, tsBSpline* _to_ );
/**
* The destructor of tsBSpline.
*
* Frees all dynamically allocated memory in \p \_spline\_ and calls
* ::ts_bspline_default afterwards.
*
* @param \_spline\_
* The spline to free.
*/
void ts_bspline_free( tsBSpline* _spline_ );
/**
* The default constructor of tsDeBoorNet.
*
* All values of \p \_deBoorNet\_ are set to 0/NULL.
*
* @param \_deBoorNet\_
* The net whose values are set 0/NULL.
*/
void ts_deboornet_default( tsDeBoorNet* _deBoorNet_ );
/**
* The copy constructor of tsDeBoorNet.
*
* Creates a deep copy of \p original and stores the result in \p \_copy\_.
*
* On error, all values of \p _copy_ are set to 0/NULL. Does nothing, if
* \p original == \p \_copy\_.
*
* @param original
* The net to deep copy.
* @param \_copy\_
* The output parameter storing the copied values of \p original.
* @return TS_SUCCESS
* On success.
* @return TS_MALLOC
* If allocating memory failed.
*/
tsError ts_deboornet_copy( const tsDeBoorNet* original, tsDeBoorNet* _copy_ );
/**
* The move constructor of tsDeBoorNet.
*
* Moves all values from \p from to \p \_to\_ and calls ::ts_deboornet_default
* on \p from afterwards. Does nothing, if \p from == \p \_to\_.
*
* @param from
* The net whose values are moved to \p \_to\_.
* @param \_to\_
* The output parameter storing the moved values of \p from.
*/
void ts_deboornet_move( tsDeBoorNet* from, tsDeBoorNet* _to_ );
/**
* The destructor of tsDeBoorNet.
*
* Frees all dynamically allocated memory in \p \_deBoorNet\_ and calls
* ::ts_deboornet_default afterwards.
*
* @param \_deBoorNet\_
* The net to free.
*/
void ts_deboornet_free( tsDeBoorNet* _deBoorNet_ );
/******************************************************************************
* *
* Interpolation and Approximation Functions *
* *
* The following section contains functions to interpolate and approximate *
* arbitrary splines. *
* *
******************************************************************************/
/**
* Performs a cubic spline interpolation using the thomas algorithm, see:
*
* https://en.wikipedia.org/wiki/Tridiagonal_matrix_algorithm
* http://www.math.ucla.edu/~baker/149.1.02w/handouts/dd_splines.pdf
* http://www.bakoma-tex.com/doc/generic/pst-bspline/pst-bspline-doc.pdf
*
* The resulting spline is a sequence of bezier curves connecting each point
* in \p points. Each bezier curve _b_ is of degree 3 with \p dim being the
* dimension of the each control point in _b_. The total number of control
* points is (\p n - 1) * 4.
*
* On error, all values of \p \_spline\_ are set to 0/NULL.
*
* Note: \p n is the number of points in \p points and not the length of
* \p points. For instance, the follwing point vector yields to \p n = 4 and
* \p dim = 2:
*
* [x0, y0, x1, y1, x2, y2, x3, y3]
*
* @param points
* The points to interpolate.
* @param n
* The number of points in \p points.
* @param dim
* The dimension of each control point in \p \_spline\_.
* @param \_spline\_
* The output parameter storing the result of this function.
* @return TS_SUCCESS
* On success.
* @return TS_DIM_ZERO
* If \p dim == 0.
* @return TS_DEG_GE_NCTRLP
* If \p n < 2.
* @return TS_MALLOC
* If allocating memory failed.
*/
tsError ts_bspline_interpolate_cubic( const tsReal* points, size_t n,
size_t dim, tsBSpline* _spline_ );
/******************************************************************************
* *
* Query Functions *
* *
* The following section contains functions to query splines. *
* *
******************************************************************************/
/**
* Evaluates \p spline at knot value \p u and stores the result in
* \p \_deBoorNet\_.
*
* On error, all values of \p \_deBoorNet\_ are set to 0/NULL.
*
* @param spline
* The spline to evaluate.
* @param u
* The knot value to evaluate.
* @param \_deBoorNet\_
* The output parameter storing the evaluation result.
* @return TS_SUCCESS
* On success.
* @return TS_MULTIPLICITY
* If multiplicity s(\p u) > order of \p spline.
* @return TS_U_UNDEFINED
* If \p spline is not defined at knot value \p u.
* @return TS_MALLOC
* If allocating memory failed.
*/
tsError ts_bspline_evaluate( const tsBSpline* spline, tsReal u,
tsDeBoorNet* _deBoorNet_ );
/******************************************************************************
* *
* Transformation functions *
* *
* TinySpline is a library focusing on transformations. That is, most *
* functions are used to transform splines by modifying their state, e.g., *
* their number of control points, their degree, and so on. Accordingly, each *
* transformation functions specifies an input and output parameter (along *
* with the other parameters required to calculate the actual transformation). *
* By passing a different pointer to the output parameter, the transformation *
* result is calculated and stored without changing the state of the input. *
* This is in particular useful when dealing with errors as the original state *
* will never be modified. For instance, let's have a look at the following *
* code snippet: *
* *
* tsBSpline in = ... // an arbitrary spline *
* tsBSpline out; // result of transformation *
* *
* // Subdivide 'in' into sequence of bezier curves and store the result *
* // in 'out'. Does not change 'in' in any way. *
* tsError err = ts_bspline_to_beziers(&in, &out); *
* if (err != TS_SUCCESS) { *
* // fortunately, 'in' has not been changed *
* } *
* *
* Even if 'ts_bspline_to_beziers' fails, the state of 'in' has not been *
* changed allowing you to handle the error properly. *
* *
* Unless stated otherwise, the order of the parameters for transformation *
* functions is: *
* *
* function(input, [additional_input], output, [additional_output]) *
* *
* 'additional_input' are parameters required to calculate the actual *
* transformation. 'additional_output' are parameters storing further result. *
* *
* Note: None of TinySpline's transformation functions frees the memory of the *
* output parameter. Thus, when using the same output parameter multiple *
* times, make sure to free memory before each call. Otherwise, you will *
* have a bad time with memory leaks: *
* *
* tsBSpline in = ... // an arbitrary spline *
* tsBSpline out; // result of transformations *
* *
* ts_bspline_to_beziers(&in, &out); // first transformation *
* ... // some code *
* ts_bspline_free(&out); // avoid memory leak. *
* ts_bspline_buckle(&in, &out); // next transformation *
* *
* If you want to modify your input directly without having a separate output, *
* pass it as input and output at once: *
* *
* tsBSpline s = ... // an arbitrary spline *
* tsReal *knots = ... // a knot vector *
* *
* ts_bspline_set_knots(&s, knots, &s); // copy 'knots' into 's' *
* *
* Note: If a transformation function fails *and* input != output, all fields *
* of the output parameter are set to 0/NULL. If input == output, your *
* input may have an invalid state in case of errors. *
* *
******************************************************************************/
/**
* Computes the derivative of \p spline, see:
*
* http://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/B-spline/bspline-derv.html
*
* The derivative of a spline _s_ of degree _d_ with _m_ control points and
* _n_ knots is another spline _s'_ of degree _d-1_ with _m-1_ control points
* and _n-2_ knots, defined over _s_ as:
*
* \f{eqnarray*}{
* s'(u) &=& \sum_{i=0}^{n-1} N_{i+1,p-1}(u) *
* (P_{i+1} - P_{i}) * p / (u_{i+p+1}-u_{i+1}) \\
* &=& \sum_{i=1}^{n} N_{i,p-1}(u) *
* (P_{i} - P_{i-1}) * p / (u_{i+p}-u_{i})
* \f}
*
* If _s_ has a clamped knot vector, it can be shown that:
*
* \f{eqnarray*}{
* s'(u) &=& \sum_{i=0}^{n-1} N_{i,p-1}(u) *
* (P_{i+1} - P_{i}) * p / (u_{i+p+1}-u_{i+1})
* \f}
*
* where the multiplicity of the first and the last knot value _u_ is _p_
* rather than _p+1_.
*
* On error, (and if \p spline != \p \_derivative\_) all values of
* \p \_derivative\_ are set to 0/NULL.
*
* @param spline
* The spline to derive.
* @param \_derivative\_
* The output parameter storing the derivative of \p spline.
* @return TS_SUCCESS
* On success.
* @return TS_UNDERIVABLE
* If \p spline->deg < 1, \p spline->n_ctrlp < 2, or the multiplicity of
* an internal knot of \p spline is greater than the degree of \p spline.
* NOTE: This will be fixed in the future.
* @return TS_MALLOC
* If allocating memory failed.
*/
tsError ts_bspline_derive( const tsBSpline* spline, tsBSpline* _derivative_ );
/**
* Creates a deep copy of \p spline (only if \p spline != \p \_result\_) and
* copies the first \p spline->n_ctrlp * \p spline->dim values from \p ctrlp
* to \p \_result\_->ctrlp using memmove. The behaviour of this function is
* undefined, if the length of \p ctrlp is less than \p spline->n_ctrlp *
* \p spline->dim.
*
* On error, (and if \p spline != \p \_result\_) all values of \p \_result\_
* are set to 0/NULL.
*
* @param spline
* The spline to deep copy (if \p spline != \p \_result\_) and whose
* control points are replaced with \p ctrlp.
* @param ctrlp
* The control points to copy to \p \_result\_->ctrlp.
* @param \_result\_
* The output parameter storing the result of this function.
* @return TS_SUCCESS
* On success.
* @return TS_MALLOC
* If \p spline != \p \_result\_ and allocating memory failed.
*/
tsError ts_bspline_set_ctrlp( const tsBSpline* spline, const tsReal* ctrlp,
tsBSpline* _result_ );
/**
* Creates a deep copy of \p spline (only if \p spline != \p \_result\_) and
* copies the the first \p spline->n_knots from \p knots to \p \_result\_
* using memmove. The behaviour of this function is undefined, if the length
* of \p knots is less than \p spline->n_knots.
*
* On error, (and if \p spline != \p \_result\_) all values of \p \_result\_
* are set to 0/NULL.
*
* @param spline
* The spline to deep copy (if \p spline != \p \_result\_) and whose
* knots are replaced with \p knots.
* @param knots
* The knots to copy to \p \_result\_->knots.
* @param \_result\_
* The output parameter storing the result of this function.
* @return TS_SUCCESS
* On success.
* @return TS_MALLOC
* If \p spline != \p \_result\_ and allocating memory failed.
*/
tsError ts_bspline_set_knots( const tsBSpline* spline, const tsReal* knots,
tsBSpline* _result_ );
/**
* Fills the knot vector of \p spline according to \p type with minimum knot
* value \p min to maximum knot value \p max and stores the result in
* \p \_result\_. Creates a deep copy of \p spline, if
* \p spline != \p \_result\_.
*
* On error, (and if \p spline != \p \_result\_) all values of \p \_result\_
* are set to 0/NULL.
*
* @param spline
* The spline to deep copy (if \p spline != \p \_result\_) and whose knot
* vector is filled according to \p type with minimum knot value \p min
* and maximum knot value \p max.
* @param type
* How to fill the knot vector of \p \_result\_.
* @param min
* The minimum knot value of the knot vector of \p \_result\_.
* @param max
* The maximum knot value of the knot vector of \p \_result\_.
* @param \_result\_
* The output parameter storing the result of this function.
* @return TS_SUCCESS
* On success.
* @return TS_DEG_GE_NCTRLP
* If \p spline->n_knots < 2*(\p original->deg+1). We can reuse this
* error code because \p spline->n_knots < 2*(\p spline->deg+1) implies
* \p spline->deg >= \p spline->n_ctrlp. Furthermore, using
* TS_DEG_GE_NCTRLP instead of TS_NUM_KNOTS ensures that TS_NUM_KNOTS is
* not used twice for this function. To be more fail-safe,
* \p spline->deg+1 instead of \p spline->order is used, to make sure
* that \p spline->deg+1 >= 1.
* @return TS_NUM_KNOTS
* If \p type == TS_BEZIERS and
* \p spline->n_knots % \p spline->order != 0.
* @return TS_KNOTS_DECR
* If \p min >= \p max. (::ts_fequals is used to determine whether
* \p min == \p max).
* @return TS_MALLOC
* If \p spline != \p \_result\_ and allocating memory failed.
*/
tsError ts_bspline_fill_knots( const tsBSpline* spline, tsBSplineType type,
tsReal min, tsReal max, tsBSpline* _result_ );
/**
* Inserts the knot value \p u \p n times into \p spline and stores the result
* in \p \_result\_. Creates a deep copy of \p spline, if
* \p spline != \p \_result\_.
*
* On error, (and if \p spline != \p \_result\_) all values of \p \_result\_
* are set to 0/NULL.
*
* @param spline
* The spline to deep copy (if \p spline != \p \_result\_) and whose knot
* vector is extended with \p u \p n times.
* @param u
* The knot value to insert.
* @param n
* How many times \p u should be inserted.
* @param \_result\_
* The output parameter storing the updated knot vector.
* @param \_k\_
* The output parameter storing the last index of \p u in \p \_result\_.
* @return TS_SUCCESS
* On success.
* @return TS_MALLOC
* If \p spline != \p \_result\_ and allocating memory failed.
*/
tsError ts_bspline_insert_knot( const tsBSpline* spline, tsReal u, size_t n,
tsBSpline* _result_, size_t* _k_ );
/**
* Resizes \p spline by \p n (number of control points) and stores the result
* in \p \_resized\_. Creates a deep copy of \p spline, if
* \p spline != \p \_result\_. If \p back != 0 \p spline is resized at the
* end. If \p back == 0 \p spline is resized at front.
*
* On error, (and if \p spline != \p \_result\_) all values of \p \_result\_
* are set to 0/NULL.
*
* @return TS_SUCCESS
* On success.
* @return TS_DEG_GE_NCTRLP
* If the degree of \p \_resized\_ would be >= the number of the control
* points of \p \_resized\_.
* @return TS_DIM_ZERO
* If \p spline != \p \_result\_ and \p spline->dim == 0.
* @return TS_DEG_GE_NCTRLP
* If \p spline != \p \_result\_ and
* \p spline->deg >= \p spline->n_ctrlp.
* @return TS_MALLOC
* If \p spline != \p \_result\_ and allocating memory failed.
*/
tsError ts_bspline_resize( const tsBSpline* spline, int n, int back,
tsBSpline* _resized_ );
/**
* Splits \p spline at \p u and stores the result in \p \_split\_. That is,
* \p u is inserted _n_ times such that s(\p u) == \p \_split\_->order.
* Creates a deep copy of \p spline, if \p spline != \p \_split\_.
*
* On error, (and if \p spline != \p \_split\_) all values of \p \_split\_
* are set to 0/NULL.
*
* @param spline
* The spline to deep copy (if \p spline != \p \_result\_) and split.
* @param u
* The split point.
* @param \_split\_
* The output parameter storing the split spline.
* @param \_k\_
* The output parameter storing the last index of \p u in \p \_split\_.
* @return TS_SUCCESS
* On success.
* @return TS_MALLOC
* If \p spline != \p \_split\_ and allocating memory failed.
*/
tsError ts_bspline_split( const tsBSpline* spline, tsReal u,
tsBSpline* _split_, size_t* _k_ );
/**
* Buckles \p spline by \p b and stores the result in \p \_buckled\_. Creates
* a deep copy of \p spline, if \p spline != \p \_buckled\_.
*
* This function is based on:
*
* Holten, Danny. "Hierarchical edge bundles: Visualization of adjacency
* relations in hierarchical data." Visualization and Computer Graphics,
* IEEE Transactions on 12.5 (2006): 741-748.
*
* Holten calls it "straightening" (page 744, equation 1).
*
* Usually, the range of \p b is: 0.0 <= \p b <= 1.0 with 0 yielding to a line
* connecting the first and the last control point (no buckle) and 1 keeping
* the original shape (maximum buckle). If \b < 0 or \b > 1 the behaviour is
* undefined, though, it will not result in an error.
*
* On error, (and if \p spline != \p \_buckled\_) all values of \p \_buckled\_
* are set to 0/NULL.
*
* @param spline
* The spline to buckle by \p b.
* @param b
* The buckle factor (usually 0.0 <= \p b <= 1.0).
* @param \_buckled\_
* The output parameter storing the buckled spline.
* @return TS_SUCCESS
* On success.
* @return TS_MALLOC
* If \p spline != \p \_buckled\_ and allocating memory failed.
*/
tsError ts_bspline_buckle( const tsBSpline* original, tsReal b,
tsBSpline* _buckled_ );
/**
* Subdivides \p spline into a sequence of Bezier curvs by splitting it at
* each internal knot value. Creates a deep copy of \p spline, if
* \p spline != \p \_beziers\_.
*
* On error, (and if \p spline != \p \_beziers\_) all values of \p \_beziers\_
* are set to 0/NULL.
*
* @param spline
* The spline to subdivide into a sequence of Bezier curves.
* @param \_beziers\_
* The output parameter storing the sequence of Bezier curves.
* @return TS_SUCCESS
* On success.
* @return TS_MALLOC
* If \p spline != \p \_beizers\_ and allocating memory failed.
*/
tsError ts_bspline_to_beziers( const tsBSpline* spline, tsBSpline* _beziers_ );
/******************************************************************************
* *
* Utility Functions *
* *
* The following section contains utility functions used by TinySpline which *
* also may be helpful when working with this library. *
* *
******************************************************************************/
/**
* Compares the tsReal values \p x and \p y using an absolute and relative
* epsilon environment.
*
* @param x
* The x value to compare.
* @param y
* The y value to compare.
* @return 1
* If \p x is equals to \p y.
* @return 0
* Otherwise.
*/
int ts_fequals( tsReal x, tsReal y );
/**
* Returns the error message associated to \p err. Returns "unknown error" if
* \p err is no associated (indicating a bug) or is TS_SUCCESS (which is not
* an actual error).
*/
const char* ts_enum_str( tsError err );
/**
* Returns the error code associated to \p str or TS_SUCCESS if \p str is not
* associated. Keep in mind that by concept "unknown error" is not associated,
* though, TS_SUCCESS is returned.
*/
tsError ts_str_enum( const char* str );
/**
* Fills the given array \p arr with \p val from \p arr+0 to \p arr+ \p num
* (exclusive).
*/
void ts_arr_fill( tsReal* arr, size_t num, tsReal val );
/**
* Returns the euclidean distance of \p x and \p y consisting of \p dim
* components, respectively.
*
* @param x
* The x value.
* @param y
* The y value.
* @param dim
* The dimension of \p x and \p y.
* @return
* The euclidean distanc of \p x and \p y.
*/
tsReal ts_ctrlp_dist2( const tsReal* x, const tsReal* y, size_t dim );
#ifdef __cplusplus
}
#endif
#endif /* TINYSPLINE_H */

View File

@ -0,0 +1,493 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2016 Marcel Steinbeck
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "tinysplinecpp.h"
#include <stdexcept>
/********************************************************
* *
* DeBoorNet *
* *
********************************************************/
tinyspline::DeBoorNet::DeBoorNet()
{
ts_deboornet_default( &deBoorNet );
}
tinyspline::DeBoorNet::DeBoorNet( const tinyspline::DeBoorNet& other )
{
const tsError err = ts_deboornet_copy( &other.deBoorNet, &deBoorNet );
if( err < 0 )
throw std::runtime_error( ts_enum_str( err ) );
}
tinyspline::DeBoorNet::~DeBoorNet()
{
ts_deboornet_free( &deBoorNet );
}
tinyspline::DeBoorNet& tinyspline::DeBoorNet::operator=( const tinyspline::DeBoorNet& other )
{
if( &other != this )
{
const tsError err = ts_deboornet_copy(
&other.deBoorNet, &deBoorNet );
if( err < 0 )
throw std::runtime_error( ts_enum_str( err ) );
}
return *this;
}
tinyspline::real tinyspline::DeBoorNet::u() const
{
return deBoorNet.u;
}
size_t tinyspline::DeBoorNet::k() const
{
return deBoorNet.k;
}
size_t tinyspline::DeBoorNet::s() const
{
return deBoorNet.s;
}
size_t tinyspline::DeBoorNet::h() const
{
return deBoorNet.h;
}
size_t tinyspline::DeBoorNet::dim() const
{
return deBoorNet.dim;
}
size_t tinyspline::DeBoorNet::nPoints() const
{
return deBoorNet.n_points;
}
std::vector<tinyspline::real> tinyspline::DeBoorNet::points() const
{
const tinyspline::real* begin = deBoorNet.points;
const tinyspline::real* end = begin + deBoorNet.n_points * deBoorNet.dim;
return std::vector<tinyspline::real>( begin, end );
}
std::vector<tinyspline::real> tinyspline::DeBoorNet::result() const
{
const tinyspline::real* begin = deBoorNet.result;
const tinyspline::real* end = begin + deBoorNet.dim;
return std::vector<tinyspline::real>( begin, end );
}
tsDeBoorNet* tinyspline::DeBoorNet::data()
{
return &deBoorNet;
}
#ifndef TINYSPLINE_DISABLE_CXX11_FEATURES
tinyspline::DeBoorNet::DeBoorNet( tinyspline::DeBoorNet&& other ) noexcept
{
ts_deboornet_default( &deBoorNet );
swap( other );
}
tinyspline::DeBoorNet& tinyspline::DeBoorNet::operator=( tinyspline::DeBoorNet&& other ) noexcept
{
if( &other != this )
{
ts_deboornet_free( &deBoorNet );
swap( other );
}
return *this;
}
void tinyspline::DeBoorNet::swap( tinyspline::DeBoorNet& other )
{
if( &other != this )
{
std::swap( deBoorNet.u, other.deBoorNet.u );
std::swap( deBoorNet.k, other.deBoorNet.k );
std::swap( deBoorNet.s, other.deBoorNet.s );
std::swap( deBoorNet.h, other.deBoorNet.h );
std::swap( deBoorNet.dim, other.deBoorNet.dim );
std::swap( deBoorNet.n_points, other.deBoorNet.n_points );
std::swap( deBoorNet.points, other.deBoorNet.points );
std::swap( deBoorNet.result, other.deBoorNet.result );
}
}
#endif
/********************************************************
* *
* BSpline *
* *
********************************************************/
tinyspline::BSpline::BSpline()
{
ts_bspline_default( &bspline );
}
tinyspline::BSpline::BSpline( const tinyspline::BSpline& other )
{
const tsError err = ts_bspline_copy( &other.bspline, &bspline );
if( err < 0 )
throw std::runtime_error( ts_enum_str( err ) );
}
tinyspline::BSpline::BSpline( const size_t nCtrlp, const size_t dim,
const size_t deg, const tinyspline::BSpline::type type )
{
const tsError err = ts_bspline_new( nCtrlp, dim, deg, type, &bspline );
if( err < 0 )
throw std::runtime_error( ts_enum_str( err ) );
}
tinyspline::BSpline::~BSpline()
{
ts_bspline_free( &bspline );
}
tinyspline::BSpline& tinyspline::BSpline::operator=( const tinyspline::BSpline& other )
{
if( &other != this )
{
const tsError err = ts_bspline_copy( &other.bspline, &bspline );
if( err < 0 )
throw std::runtime_error( ts_enum_str( err ) );
}
return *this;
}
tinyspline::DeBoorNet tinyspline::BSpline::operator()( const tinyspline::real u ) const
{
return evaluate( u );
}
size_t tinyspline::BSpline::deg() const
{
return bspline.deg;
}
size_t tinyspline::BSpline::order() const
{
return bspline.order;
}
size_t tinyspline::BSpline::dim() const
{
return bspline.dim;
}
size_t tinyspline::BSpline::nCtrlp() const
{
return bspline.n_ctrlp;
}
size_t tinyspline::BSpline::nKnots() const
{
return bspline.n_knots;
}
std::vector<tinyspline::real> tinyspline::BSpline::ctrlp() const
{
const tinyspline::real* begin = bspline.ctrlp;
const tinyspline::real* end = begin + bspline.n_ctrlp * bspline.dim;
return std::vector<tinyspline::real>( begin, end );
}
std::vector<tinyspline::real> tinyspline::BSpline::knots() const
{
const tinyspline::real* begin = bspline.knots;
const tinyspline::real* end = begin + bspline.n_knots;
return std::vector<tinyspline::real>( begin, end );
}
tsBSpline* tinyspline::BSpline::data()
{
return &bspline;
}
tinyspline::DeBoorNet tinyspline::BSpline::evaluate( const tinyspline::real u ) const
{
tinyspline::DeBoorNet deBoorNet;
const tsError err = ts_bspline_evaluate( &bspline, u, deBoorNet.data() );
if( err < 0 )
throw std::runtime_error( ts_enum_str( err ) );
return deBoorNet;
}
void tinyspline::BSpline::setCtrlp( const std::vector<tinyspline::real>& ctrlp )
{
if( ctrlp.size() != nCtrlp() * dim() )
{
throw std::runtime_error( "The number of values must be equals"
"to the spline's number of control points multiplied"
"by the dimension of each control point." );
}
const tsError err = ts_bspline_set_ctrlp(
&bspline, ctrlp.data(), &bspline );
if( err < 0 )
throw std::runtime_error( ts_enum_str( err ) );
}
void tinyspline::BSpline::setKnots( const std::vector<tinyspline::real>& knots )
{
if( knots.size() != nKnots() )
{
throw std::runtime_error( "The number of values must be equals"
"to the spline's number of knots." );
}
const tsError err = ts_bspline_set_knots(
&bspline, knots.data(), &bspline );
if( err < 0 )
throw std::runtime_error( ts_enum_str( err ) );
}
tinyspline::BSpline tinyspline::BSpline::fillKnots( const tsBSplineType type,
const tinyspline::real min,
const tinyspline::real max ) const
{
tinyspline::BSpline bs;
const tsError err = ts_bspline_fill_knots(
&bspline, type, min, max, &bs.bspline );
if( err < 0 )
throw std::runtime_error( ts_enum_str( err ) );
return bs;
}
tinyspline::BSpline tinyspline::BSpline::insertKnot( const tinyspline::real u,
const size_t n ) const
{
tinyspline::BSpline bs;
size_t k;
const tsError err = ts_bspline_insert_knot(
&bspline, u, n, &bs.bspline, &k );
if( err < 0 )
throw std::runtime_error( ts_enum_str( err ) );
return bs;
}
tinyspline::BSpline tinyspline::BSpline::resize( const int n, const int back ) const
{
tinyspline::BSpline bs;
const tsError err = ts_bspline_resize( &bspline, n, back, &bs.bspline );
if( err < 0 )
throw std::runtime_error( ts_enum_str( err ) );
return bs;
}
tinyspline::BSpline tinyspline::BSpline::split( const tinyspline::real u ) const
{
tinyspline::BSpline bs;
size_t k;
const tsError err = ts_bspline_split( &bspline, u, &bs.bspline, &k );
if( err < 0 )
throw std::runtime_error( ts_enum_str( err ) );
return bs;
}
tinyspline::BSpline tinyspline::BSpline::buckle( const tinyspline::real b ) const
{
tinyspline::BSpline bs;
const tsError err = ts_bspline_buckle( &bspline, b, &bs.bspline );
if( err < 0 )
throw std::runtime_error( ts_enum_str( err ) );
return bs;
}
tinyspline::BSpline tinyspline::BSpline::toBeziers() const
{
tinyspline::BSpline bs;
const tsError err = ts_bspline_to_beziers( &bspline, &bs.bspline );
if( err < 0 )
throw std::runtime_error( ts_enum_str( err ) );
return bs;
}
tinyspline::BSpline tinyspline::BSpline::derive() const
{
tinyspline::BSpline bs;
const tsError err = ts_bspline_derive( &bspline, &bs.bspline );
if( err < 0 )
throw std::runtime_error( ts_enum_str( err ) );
return bs;
}
#ifndef TINYSPLINE_DISABLE_CXX11_FEATURES
tinyspline::BSpline::BSpline( tinyspline::BSpline&& other ) noexcept
{
ts_bspline_default( &bspline );
swap( other );
}
tinyspline::BSpline& tinyspline::BSpline::operator=( tinyspline::BSpline&& other ) noexcept
{
if( &other != this )
{
ts_bspline_free( &bspline );
swap( other );
}
return *this;
}
void tinyspline::BSpline::swap( tinyspline::BSpline& other )
{
if( &other != this )
{
std::swap( bspline.deg, other.bspline.deg );
std::swap( bspline.order, other.bspline.order );
std::swap( bspline.dim, other.bspline.dim );
std::swap( bspline.n_ctrlp, other.bspline.n_ctrlp );
std::swap( bspline.n_knots, other.bspline.n_knots );
std::swap( bspline.ctrlp, other.bspline.ctrlp );
std::swap( bspline.knots, other.bspline.knots );
}
}
#endif
/********************************************************
* *
* Utils *
* *
********************************************************/
tinyspline::BSpline tinyspline::Utils::interpolateCubic(
const std::vector<tinyspline::real>* points,
const size_t dim )
{
if( dim == 0 )
throw std::runtime_error( ts_enum_str( TS_DIM_ZERO ) );
if( points->size() % dim != 0 )
throw std::runtime_error( "#points % dim == 0 failed" );
tinyspline::BSpline bspline;
const tsError err = ts_bspline_interpolate_cubic(
points->data(), points->size() / dim, dim, bspline.data() );
if( err < 0 )
throw std::runtime_error( ts_enum_str( err ) );
return bspline;
}
bool tinyspline::Utils::fequals( const tinyspline::real x, const tinyspline::real y )
{
return ts_fequals( x, y ) == 1;
}
std::string tinyspline::Utils::enum_str( const tsError err )
{
return std::string( ts_enum_str( err ) );
}
tsError tinyspline::Utils::str_enum( const std::string str )
{
return ts_str_enum( str.c_str() );
}

View File

@ -0,0 +1,143 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2016 Marcel Steinbeck
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "tinyspline.h"
#include <vector>
#include <string>
namespace tinyspline {
typedef tsReal real;
class DeBoorNet
{
public:
/* Constructors & Destructors */
DeBoorNet();
DeBoorNet( const DeBoorNet& other );
~DeBoorNet();
/* Operators */
DeBoorNet& operator=( const DeBoorNet& other );
/* Getter */
real u() const;
size_t k() const;
size_t s() const;
size_t h() const;
size_t dim() const;
size_t nPoints() const;
std::vector<real> points() const;
std::vector<real> result() const;
tsDeBoorNet* data();
/* C++11 features */
#ifndef TINYSPLINE_DISABLE_CXX11_FEATURES
DeBoorNet( DeBoorNet&& other ) noexcept;
DeBoorNet& operator=( DeBoorNet&& other ) noexcept;
void swap( DeBoorNet& other );
friend void swap( DeBoorNet& left, DeBoorNet& right )
{
left.swap( right );
}
#endif
private:
tsDeBoorNet deBoorNet;
};
class BSpline
{
public:
typedef tsBSplineType type;
/* Constructors & Destructors */
BSpline();
BSpline( const BSpline& other );
explicit BSpline( size_t nCtrlp, size_t dim = 2, size_t deg = 3,
tinyspline::BSpline::type type = TS_CLAMPED );
~BSpline();
/* Operators */
BSpline& operator=( const BSpline& other );
DeBoorNet operator()( real u ) const;
/* Getter */
size_t deg() const;
size_t order() const;
size_t dim() const;
size_t nCtrlp() const;
size_t nKnots() const;
std::vector<real> ctrlp() const;
std::vector<real> knots() const;
tsBSpline* data();
DeBoorNet evaluate( real u ) const;
/* Modifications */
void setCtrlp( const std::vector<real>& ctrlp );
void setKnots( const std::vector<real>& knots );
/* Transformations */
BSpline fillKnots( tsBSplineType type, real min, real max ) const;
BSpline insertKnot( real u, size_t n ) const;
BSpline resize( int n, int back ) const;
BSpline split( real u ) const;
BSpline buckle( real b ) const;
BSpline toBeziers() const;
BSpline derive() const;
/* C++11 features */
#ifndef TINYSPLINE_DISABLE_CXX11_FEATURES
BSpline( BSpline&& other ) noexcept;
BSpline& operator=( BSpline&& other ) noexcept;
void swap( BSpline& other );
friend void swap( BSpline& left, BSpline& right )
{
left.swap( right );
}
#endif
private:
tsBSpline bspline;
};
class Utils
{
public:
static BSpline interpolateCubic( const std::vector<real>* points, size_t dim );
static bool fequals( real x, real y );
static std::string enum_str( tsError err );
static tsError str_enum( std::string str );
private:
Utils() {}
};
}

1
dxflib_qcad/version.txt Normal file
View File

@ -0,0 +1 @@
dxflib 3.17.0