33 #include <wx/arrstr.h> 85 #define MIN_BULGE 0.0218 88 #define SCALE_FACTOR(x) (x) 106 std::unique_ptr<DXF_IMPORT_LAYER> layer0 =
108 m_layers.push_back( std::move( layer0 ) );
125 catch(
const std::bad_alloc& )
133 reportMsg(
_(
"Memory was exhausted trying to load the DXF, it may be too large." ) );
192 FILE* fp = wxFopen( aFile, wxT(
"rt" ) );
199 bool success = dxf_reader.in( fp,
this );
256 wxString
name = wxString::FromUTF8( aData.name.c_str() );
258 int lw = attributes.getWidth();
265 std::unique_ptr<DXF_IMPORT_LAYER> layer = std::make_unique<DXF_IMPORT_LAYER>(
name, lw );
267 m_layers.push_back( std::move( layer ) );
275 wxString description =
FROM_UTF8( data.description.c_str() );
302 wxString layerName = wxString::FromUTF8( aLayerName.c_str() );
304 if( !layerName.IsEmpty() )
307 [layerName](
const auto& it )
309 return it->m_layerName == layerName;
313 layer = resultIt->get();
323 wxString blockName = wxString::FromUTF8( aBlockName.c_str() );
325 if( !blockName.IsEmpty() )
328 [blockName](
const auto& it )
330 return it->m_name == blockName;
334 block = resultIt->get();
344 wxString styleName = wxString::FromUTF8( aStyleName.c_str() );
346 if( !styleName.IsEmpty() )
349 [styleName](
const auto& it ) {
return it->m_name == styleName; } );
352 style = resultIt->get();
369 bufferToUse->
AddLine( start, end, lineWidth );
401 if( aData.startWidth > 0.0 )
402 lineWidth = aData.startWidth / 100.0;
403 else if ( aData.endWidth > 0.0 )
404 lineWidth = aData.endWidth / 100.0;
406 const DL_VertexData* vertex = &aData;
465 wxString
name = wxString::FromUTF8( aData.name.c_str() );
467 std::unique_ptr<DXF_IMPORT_BLOCK> block =
468 std::make_unique<DXF_IMPORT_BLOCK>(
name, aData.bpx, aData.bpy );
470 m_blocks.push_back( std::move( block ) );
485 if( block ==
nullptr )
497 std::unique_ptr<IMPORTED_SHAPE> newShape = shape->clone();
499 newShape->Translate( translation );
500 newShape->Scale( aData.sx, aData.sy );
518 bufferToUse->
AddCircle( center,
mapDim( aData.radius ), lineWidth,
false );
536 double startangle = aData.angle1;
537 double endangle = aData.angle2;
540 VECTOR2D startPoint( aData.radius, 0.0 );
541 startPoint = startPoint.
Rotate( startangle * M_PI / 180.0 );
543 mapX( startPoint.
x + centerCoords.
x ),
mapY( startPoint.
y + centerCoords.
y ) );
546 double angle = -( endangle - startangle );
556 bufferToUse->
AddArc( center, arcStart,
angle, lineWidth );
570 std::isnan( aData.apy ) ? 0 : aData.apy,
571 std::isnan( aData.apz ) ? 0 : aData.apz ) );
576 if( aData.vJustification != 0 || aData.hJustification != 0 || aData.hJustification == 4 )
578 if( aData.hJustification != 3 && aData.hJustification != 5 )
590 double textHeight =
mapDim( aData.height );
592 double charWidth = textHeight * 0.9;
594 if( style !=
nullptr )
597 double textWidth = charWidth *
text.length();
598 double textThickness = textHeight/8.0;
608 switch( aData.vJustification )
614 topLeft.
y = textHeight;
615 topRight.
y = textHeight;
621 bottomRight.
y = -textHeight / 2.0;
622 bottomLeft.
y = -textHeight / 2.0;
623 topLeft.
y = textHeight / 2.0;
624 topRight.
y = textHeight / 2.0;
630 bottomLeft.
y = -textHeight;
631 bottomRight.
y = -textHeight;
635 switch( aData.hJustification )
642 bottomRight.
x = textWidth;
643 topRight.
x = textWidth;
650 bottomLeft.
x = -textWidth / 2.0;
651 topLeft.
x = -textWidth / 2.0;
652 bottomRight.
x = textWidth / 2.0;
653 topRight.
x = textWidth / 2.0;
659 bottomLeft.
x = -textWidth;
660 topLeft.
x = -textWidth;
665 wxString sty = wxString::FromUTF8( aData.style.c_str() );
668 if( aData.textgen == 2 )
671 }
else if( aData.textgen == 4 )
681 double angle_degree = aData.angle * 180 / M_PI;
684 double angleInRads = angle_degree * M_PI / 180.0;
685 double cosine = cos(angleInRads);
686 double sine = sin(angleInRads);
690 bufferToUse->
AddText( refPoint,
text, textHeight, charWidth, textThickness, angle_degree,
691 hJustify, vJustify );
694 bottomLeft.
x = bottomLeft.
x * cosine - bottomLeft.
y * sine;
695 bottomLeft.
y = bottomLeft.
x * sine + bottomLeft.
y * cosine;
697 bottomRight.
x = bottomRight.
x * cosine - bottomRight.
y * sine;
698 bottomRight.
y = bottomRight.
x * sine + bottomRight.
y * cosine;
700 topLeft.
x = topLeft.
x * cosine - topLeft.
y * sine;
701 topLeft.
y = topLeft.
x * sine + topLeft.
y * cosine;
703 topRight.
x = topRight.
x * cosine - topRight.
y * sine;
704 topRight.
y = topRight.
x * sine + topRight.
y * cosine;
706 bottomLeft += refPoint;
707 bottomRight += refPoint;
709 topRight += refPoint;
722 wxString attrib, tmp;
726 double textHeight =
mapDim( aData.height );
729 double charWidth = textHeight * 0.9;
730 if( style !=
nullptr )
733 double textWidth = charWidth *
text.length();
734 double textThickness = textHeight/8.0;
759 while(
text.StartsWith( wxT(
"\\" ) ) )
761 attrib <<
text.BeforeFirst(
';' );
762 tmp =
text.AfterFirst(
';' );
775 if( aData.attachmentPoint <= 3 )
779 bottomLeft.
y = -textHeight;
780 bottomRight.
y = -textHeight;
782 else if( aData.attachmentPoint <= 6 )
786 bottomRight.
y = -textHeight / 2.0;
787 bottomLeft.
y = -textHeight / 2.0;
788 topLeft.
y = textHeight / 2.0;
789 topRight.
y = textHeight / 2.0;
795 topLeft.
y = textHeight;
796 topRight.
y = textHeight;
799 if( aData.attachmentPoint % 3 == 1 )
803 bottomRight.
x = textWidth;
804 topRight.
x = textWidth;
806 else if( aData.attachmentPoint % 3 == 2 )
810 bottomLeft.
x = -textWidth / 2.0;
811 topLeft.
x = -textWidth / 2.0;
812 bottomRight.
x = textWidth / 2.0;
813 topRight.
x = textWidth / 2.0;
819 bottomLeft.
x = -textWidth;
820 topLeft.
x = -textWidth;
823 #if 0 // These setting have no meaning in Pcbnew 824 if( data.alignH == 1 )
828 else if( data.alignH == 3 )
837 if( aData.alignV == 1 )
849 double angle_degree = aData.angle * 180/M_PI;
852 double angleInRads = angle_degree * M_PI / 180.0;
853 double cosine = cos(angleInRads);
854 double sine = sin(angleInRads);
859 bufferToUse->
AddText( textpos,
text, textHeight, charWidth,
860 textThickness, angle_degree, hJustify, vJustify );
862 bottomLeft.
x = bottomLeft.
x * cosine - bottomLeft.
y * sine;
863 bottomLeft.
y = bottomLeft.
x * sine + bottomLeft.
y * cosine;
865 bottomRight.
x = bottomRight.
x * cosine - bottomRight.
y * sine;
866 bottomRight.
y = bottomRight.
x * sine + bottomRight.
y * cosine;
868 topLeft.
x = topLeft.
x * cosine - topLeft.
y * sine;
869 topLeft.
y = topLeft.
x * sine + topLeft.
y * cosine;
871 topRight.
x = topRight.
x * cosine - topRight.
y * sine;
872 topRight.
y = topRight.
x * sine + topRight.
y * cosine;
874 bottomLeft += textpos;
875 bottomRight += textpos;
964 if( key ==
"$DWGCODEPAGE" )
970 if( key ==
"$AUPREC" )
976 if( key ==
"$LUPREC" )
982 if( key ==
"$INSUNITS" )
1066 for(
unsigned i = 0; i<aStr.length(); ++i )
1070 if( c > 175 || c < 11 )
1072 res.append( aStr.Mid( j, i - j ) );
1078 res += wxT(
"\\P" );
1088 res += wxT(
"%%C" );
1093 res += wxT(
"%%D" );
1098 res += wxT(
"%%P" );
1110 res.append( aStr.Mid( j ) );
1122 for(
unsigned i = 0; i < aData.length(); ++i )
1124 if( aData[ i ] == 0x7B )
1126 if( aData[ i + 1 ] == 0x5c && aData[ i + 2 ] == 0x66 )
1129 res.append( aData.Mid( j, i - j ) );
1132 for(
unsigned k = i + 3; k < aData.length(); ++k )
1134 if( aData[ k ] == 0x3B )
1142 for(
unsigned k = i; k < aData.length(); ++k )
1144 if( aData[ k ] == 0x7D )
1146 res.append( aData.Mid( i, k - i ) );
1155 res.append( aData.Mid( j ) );
1160 regexp.Compile( wxT(
"\\\\P" ) );
1161 regexp.Replace( &res, wxT(
"\n" ) );
1164 regexp.Compile( wxT(
"\\\\~" ) );
1165 regexp.Replace( &res, wxT(
" " ) );
1168 regexp.Compile( wxT(
"%%[cC]" ) );
1171 regexp.Replace( &res, wxChar( 0xD8 ) );
1174 regexp.Replace( &res, wxChar( 0x2205 ) );
1178 regexp.Compile( wxT(
"%%[dD]" ) );
1179 regexp.Replace( &res, wxChar( 0x00B0 ) );
1181 regexp.Compile( wxT(
"%%[pP]" ) );
1182 regexp.Replace( &res, wxChar( 0x00B1 ) );
1191 wxString
name = wxString::FromUTF8( aData.name.c_str() );
1193 std::unique_ptr<DXF_IMPORT_STYLE> style =
1194 std::make_unique<DXF_IMPORT_STYLE>(
name, aData.fixedTextHeight, aData.widthFactor, aData.bold, aData.italic );
1196 m_styles.push_back( std::move( style ) );
1211 double lineWidth = 0.0001;
1212 double thickness =
mapDim( std::max( aData.thickness, 0.01 ) );
1216 bufferToUse->
AddCircle( center, thickness, lineWidth,
true );
1226 const VECTOR2D& aSegEnd,
double aWidth )
1233 bufferToUse->
AddLine( origin, end, aWidth );
1241 double aBulge,
double aWidth )
1247 if( aBulge < -2000.0 )
1249 else if( aBulge > 2000.0 )
1252 double ang = 4.0 * atan( aBulge );
1258 double offAng = atan2( ep.
y - sp.
y, ep.
x - sp.
x );
1260 double d = 0.5 * sqrt( (sp.
x - ep.
x) * (sp.
x - ep.
x) + (sp.
y - ep.
y) * (sp.
y - ep.
y) );
1262 double xm = ( sp.
x + ep.
x ) * 0.5;
1263 double ym = ( sp.
y + ep.
y ) * 0.5;
1264 double radius = d / sin( ang * 0.5 );
1270 double dh2 = radius * radius - d * d;
1276 double h = sqrt( dh2 );
1288 else if( ang > M_PI )
1292 double cx = h * cos( offAng ) + xm;
1293 double cy = h * sin( offAng ) + ym;
1310 bufferToUse->
AddArc( center, arc_start,
angle, aWidth );
1320 #include "tinysplinecpp.h" 1325 wxLogMessage(
"spl deg %d kn %d ctr %d fit %d",
1337 #if 0 // set to 1 to approximate the spline by segments between 2 control points 1341 for(
unsigned int ii = 1; ii < imax; ++ii )
1346 if( startpoint != endpoint )
1353 startpoint = endpoint;
1356 #else // Use bezier curves, supported by pcbnew, to approximate the spline 1357 std::vector<double> ctrlp;
1359 for(
unsigned ii = 0; ii < imax; ++ii )
1365 std::vector<double> coords;
1371 dxfspline.setCtrlp( ctrlp );
1373 tinyspline::BSpline beziers( dxfspline.toBeziers() );
1375 coords = beziers.ctrlp();
1377 catch(
const std::runtime_error& )
1380 reportMsg(
_(
"Invalid spline definition encountered" ) );
1384 if( coords.size() % 8 != 0 )
1387 reportMsg(
_(
"Invalid Bezier curve created" ) );
1395 for(
unsigned ii = 0; ii < coords.size(); ii += 8 )
1402 if( ii+7 < coords.size() )
1405 end = bezierControl2;
1409 bufferToUse->
AddSpline( start, bezierControl1, bezierControl2, end, aWidth );
1429 double direction[3];
1430 aData->getDirection( direction );
1434 if( ( abs( arbZ.
x ) < ( 1.0 / 64.0 ) ) && ( abs( arbZ.
y ) < ( 1.0 / 64.0 ) ) )
1452 x = point.
x * arbitraryAxis.
vecX.
x + point.
y * arbitraryAxis.
vecX.
y 1453 + point.
z * arbitraryAxis.
vecX.
z;
1454 y = point.
x * arbitraryAxis.
vecY.
x + point.
y * arbitraryAxis.
vecY.
y 1455 + point.
z * arbitraryAxis.
vecY.
z;
1456 z = point.
x * arbitraryAxis.
vecZ.
x + point.
y * arbitraryAxis.
vecZ.
y 1457 + point.
z * arbitraryAxis.
vecZ.
z;
1470 x = point.
x * worldX.
x + point.
y * worldX.
y + point.
z * worldX.
z;
1471 y = point.
x * worldY.
x + point.
y * worldY.
y + point.
z * worldY.
z;
1472 z = point.
x * worldZ.
x + point.
y * worldZ.
y + point.
z * worldZ.
z;
Interface that creates objects representing shapes for a given data model.
DXF2BRD_ENTITY_DATA m_curr_entity
std::vector< std::unique_ptr< DXF_IMPORT_STYLE > > m_styles
#define DXF_IMPORT_LINEWEIGHT_BY_LW_DEFAULT
virtual void addInsert(const DL_InsertData &aData) override
void AddLine(const VECTOR2D &aStart, const VECTOR2D &aEnd, double aWidth) override
Create an object representing a line segment.
VECTOR3< T > Normalize()
Compute the normalized vector.
static wxString FROM_UTF8(const char *cstring)
Convert a UTF8 encoded C string to a wxString for all wxWidgets build modes.
double GetImageHeight() const override
Return image height from original imported file.
virtual void addTextStyle(const DL_StyleData &aData) override
virtual void addLine(const DL_LineData &aData) override
virtual void addPolyline(const DL_PolylineData &aData) override
virtual void endBlock() override
A helper class to hold layer settings temporarily during import.
DXF_IMPORT_LAYER * getImportLayer(const std::string &aLayerName)
Return the import layer data.
virtual void addBlock(const DL_BlockData &) override
Called for each BLOCK in the DXF file.
static wxString toDxfString(const wxString &aStr)
Convert a native Unicode string into a DXF encoded string.
VECTOR3D ocsToWcs(const DXF_ARBITRARY_AXIS &arbitraryAxis, VECTOR3D point)
Converts a given object coordinate point to world coordinate using the given arbitrary axis vectors.
unsigned int m_SplineFitCount
double GetImageWidth() const override
Return image width from original imported file.
void AddArc(const VECTOR2D &aCenter, const VECTOR2D &aStart, double aAngle, double aWidth) override
Create an object representing an arc.
bool Load(const wxString &aFileName) override
Load file for import.
unsigned int m_SplineControlCount
double RAD2DEG(double rad)
double mapX(double aDxfCoordX)
virtual void addFitPoint(const DL_FitPointData &aData) override
Called for every spline fit point.
virtual void addLinetype(const DL_LinetypeData &data) override
DXF_IMPORT_UNITS m_currentUnit
virtual void addSpline(const DL_SplineData &aData) override
Called for every spline.
std::vector< VECTOR2D > m_SplineFitPointList
DXF_IMPORT_BLOCK * getImportBlock(const std::string &aBlockName)
Return the import layer block.
double m_SplineTangentEndY
void reportMsg(const wxString &aMessage)
#define DXF_IMPORT_LINEWEIGHT_BY_LAYER
void updateImageLimits(const VECTOR2D &aPoint)
void SetDefaultLineWidthMM(double aWidth)
Set the default line width when importing dxf items like lines to Pcbnew.
A helper class to hold style settings temporarily during import.
DXF_IMPORT_BLOCK * m_currentBlock
DXF_IMPORT_STYLE * getImportStyle(const std::string &aStyleName)
Return the import style.
int m_importAnglePrecision
This file contains miscellaneous commonly used macros and functions.
void AddShape(std::unique_ptr< IMPORTED_SHAPE > &aShape)
DXF_ARBITRARY_AXIS getArbitraryAxis(DL_Extrusion *aData)
virtual void endEntity() override
virtual void setVariableInt(const std::string &key, int value, int code) override
Called for every int variable in the DXF file (e.g.
bool Import() override
Actually imports the file.
VECTOR3< T > Cross(const VECTOR3< T > &aVector) const
Compute cross product of self with aVector.
void AddSpline(const VECTOR2D &aStart, const VECTOR2D &BezierControl1, const VECTOR2D &BezierControl2, const VECTOR2D &aEnd, double aWidth) override
Create an object representing an arc.
VECTOR2< double > VECTOR2D
virtual void addVertex(const DL_VertexData &aData) override
Called for every polyline vertex.
double m_SplineTangentEndX
unsigned int m_SplineKnotsCount
unsigned int m_SplineDegree
double getCurrentUnitScale()
virtual void addKnot(const DL_KnotData &aData) override
Called for every spline knot value.
double lineWeightToWidth(int lw, DXF_IMPORT_LAYER *aLayer)
static wxString toNativeString(const wxString &aData)
Convert a DXF encoded string into a native Unicode string.
std::vector< std::unique_ptr< DXF_IMPORT_LAYER > > m_layers
VECTOR3D wcsToOcs(const DXF_ARBITRARY_AXIS &arbitraryAxis, VECTOR3D point)
Converts a given world coordinate point to object coordinate using the given arbitrary axis vectors.
double mapDim(double aDxfValue)
void AddCircle(const VECTOR2D &aCenter, double aRadius, double aWidth, bool aFilled) override
Create an object representing a circle.
GRAPHICS_IMPORTER_BUFFER m_buffer
double m_SplineTangentStartX
int m_importCoordinatePrecision
void AddText(const VECTOR2D &aOrigin, const wxString &aText, double aHeight, double aWidth, double aThickness, double aOrientation, EDA_TEXT_HJUSTIFY_T aHJustify, EDA_TEXT_VJUSTIFY_T aVJustify) override
Create an object representing a text.
virtual void addControlPoint(const DL_ControlPointData &aData) override
Called for every spline control point.
std::vector< std::unique_ptr< DXF_IMPORT_BLOCK > > m_blocks
virtual void SetImporter(GRAPHICS_IMPORTER *aImporter) override
Set the receiver of the imported shapes.
VECTOR2< T > Rotate(double aAngle) const
Rotate the vector by a given angle.
void insertLine(const VECTOR2D &aSegStart, const VECTOR2D &aSegEnd, double aWidth)
virtual void addMText(const DL_MTextData &aData) override
double GetLineWidthMM() const
Return the line width used for importing the outlines (in mm).
bool ImportDxfFile(const wxString &aFile)
Implementation of the method used for communicate with this filter.
virtual void SetImporter(GRAPHICS_IMPORTER *aImporter)
Set the receiver of the imported shapes.
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
double m_defaultThickness
GRAPHICS_IMPORTER * m_importer
< Importer used to create objects representing the imported shapes.
Helper class representing the DXF specification's "arbitrary axis".
std::list< std::unique_ptr< IMPORTED_SHAPE > > & GetShapes()
virtual void addLayer(const DL_LayerData &aData) override
virtual void addArc(const DL_ArcData &aData) override
double mapY(double aDxfCoordY)
virtual void addText(const DL_TextData &aData) override
GRAPHICS_IMPORTER_BUFFER m_internalImporter
std::vector< double > m_SplineKnotsList
VECTOR2D m_LastCoordinate
virtual void addPoint(const DL_PointData &aData) override
void ImportTo(GRAPHICS_IMPORTER &aImporter)
virtual void setVariableString(const std::string &key, const std::string &value, int code) override
Called for every string variable in the DXF file (e.g.
std::vector< SPLINE_CTRL_POINT > m_SplineControlPointList
void insertArc(const VECTOR2D &aSegStart, const VECTOR2D &aSegEnd, double aBulge, double aWidth)
A helper class to hold layer settings temporarily during import.
double m_SplineTangentStartY
void insertSpline(double aWidth)
VECTOR3< double > VECTOR3D
virtual void addCircle(const DL_CircleData &aData) override