/* * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2019 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors. * * This program 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. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, you may find one here: * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html * or you may search the http://www.gnu.org website for the version 2 license, * or you may write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef DXF2BRD_ITEMS_H #define DXF2BRD_ITEMS_H #include "graphics_import_plugin.h" #include "graphics_importer_buffer.h" #include #include #include #include #include class BOARD; class BOARD_ITEM; /** * A helper class to store a spline control point (in X,Y plane only) */ struct SPLINE_CTRL_POINT { double m_x; double m_y; double m_weight; SPLINE_CTRL_POINT( double a_x, double a_y, double a_weight ) : m_x( a_x ), m_y( a_y ), m_weight( a_weight ) {} }; /** * A helper class to parse a DXF entity (polyline and spline) */ class DXF2BRD_ENTITY_DATA { public: int m_EntityType; // the DXF type of entity int m_EntityParseStatus; // Inside a entity: status of parsing: // 0 = no entity // 1 = first item of entity // 2 = entity in progress int m_EntityFlag; // a info flag to parse entities VECTOR2D m_LastCoordinate; // the last vertex coordinate read (unit = mm) VECTOR2D m_PolylineStart; // The first point of the polyline entity, when reading a // polyline (unit = mm) double m_BulgeVertex; // the last vertex bulge value read // for spline parsing: parameters unsigned int m_SplineDegree; unsigned int m_SplineKnotsCount; unsigned int m_SplineControlCount; unsigned int m_SplineFitCount; double m_SplineTangentStartX; // tangent dir X for the start point double m_SplineTangentStartY; // tangent dir Y for the start point double m_SplineTangentEndX; // tangent dir X for the end point double m_SplineTangentEndY; // tangent dir Y for the end point // for spline parsing: buffers to store control points, fit points and knot std::vector m_SplineKnotsList; // knots list, code 40 // control points list coordinates, code 10, 20 & 30 (only X and Y cood and Weight) std::vector m_SplineControlPointList; // fit points list, code 11, 21 & 31 (only X and Y cood) std::vector m_SplineFitPointList; DXF2BRD_ENTITY_DATA() { Clear(); }; // Reset the entity parameters void Clear() { m_EntityType = DL_UNKNOWN; m_EntityParseStatus = 0; m_EntityFlag = 0; m_SplineDegree = 1; m_SplineKnotsCount = 0; m_SplineControlCount = 0; m_SplineFitCount = 0; m_SplineTangentStartX = 0.0; m_SplineTangentStartY = 0.0; m_SplineTangentEndX = 0.0; m_SplineTangentEndY = 0.0; m_BulgeVertex = 0.0; m_SplineKnotsList.clear(); m_SplineControlPointList.clear(); m_SplineFitPointList.clear(); } }; /** * This class import DXF ASCII files and convert basic entities to board entities. * It depends on the dxflib library. */ class DXF_IMPORT_PLUGIN : public GRAPHICS_IMPORT_PLUGIN, public DL_CreationAdapter { private: double m_xOffset; // X coord offset for conversion (in mm) double m_yOffset; // Y coord offset for conversion (in mm) double m_defaultThickness; // default line thickness for conversion (in mm) double m_DXF2mm; // The scale factor to convert DXF units to mm int m_brdLayer; // The board layer to place imported DXF items int m_version; // the dxf version, not used here std::string m_codePage; // The code page, not used here bool m_importAsfootprintGraphicItems; // Use module items instead of board items when true. // true when the items are imported in the footprint editor std::string m_messages; // messages generated during dxf file parsing. // Each message ends by '\n' DXF2BRD_ENTITY_DATA m_curr_entity; // the current entity parameters when parsing a DXF entity double m_minX, m_maxX; // handles image size in mm double m_minY, m_maxY; // handles image size in mm GRAPHICS_IMPORTER_BUFFER m_internalImporter; public: DXF_IMPORT_PLUGIN(); ~DXF_IMPORT_PLUGIN(); const wxString GetName() const override { return "AutoCAD DXF"; } const wxArrayString GetFileExtensions() const override { static wxString wildcardExt = formatWildcardExt( "dxf" ); return wxArrayString( 1, &wildcardExt ); } bool Load( const wxString& aFileName ) override; bool Import() override; double GetImageWidth() const override; double GetImageHeight() const override; void updateImageLimits( const VECTOR2D& aPoint ); virtual void SetImporter( GRAPHICS_IMPORTER* aImporter ) override; /** * Allows the import DXF items converted to board graphic items or footprint * graphic items. * @param aImportAsFootprintGraphic = true to import in a footprint, false to import on a board */ void ImportAsFootprintGraphic( bool aImportAsFootprintGraphic ) { m_importAsfootprintGraphicItems = aImportAsFootprintGraphic; } /** * Set the default line width when importing dxf items like lines to Pcbnew. * because dxf files have no line width explicit parameter, it will be most * of time the line width of imported lines * @param aWidth = line width in mm */ void SetDefaultLineWidthMM( double aWidth ) { m_defaultThickness = aWidth; } void SetLineWidthMM( double aWidth ) override { SetDefaultLineWidthMM( aWidth ); } /** * Set the coordinate offset between the imported dxf items and Pcbnew. * because dxf files have the Y axis from bottom to top; * aOffsetX = 0, and aOffsetY = - vertical page size to import a full page * @param aOffsetX = the X offset in mm * @param aOffsetY = the Y offset in mm */ void SetOffset( double aOffsetX, double aOffsetY ) { m_xOffset = aOffsetX; m_yOffset = aOffsetY; } /** * Set the layer number to import dxf items. * the layer should be a technical layer, not a copper layer */ void SetBrdLayer( int aBrdLayer ) { m_brdLayer = aBrdLayer; } /** * Implementation of the method used for communicate * with this filter. * * @param aFile = the full filename. */ bool ImportDxfFile( const wxString& aFile ); /** * @return the list of messages in one string. Each message ends by '\n' */ const std::string& GetMessages() const override { return m_messages; } private: // report message to keep trace of not supported dxf entities: void reportMsg( const char* aMessage ); // coordinate conversions from dxf file to mm double mapX( double aDxfCoordX ); double mapY( double aDxfCoordY ); double mapDim( double aDxfValue ); // mapWidth returns ( in mm) the aDxfValue if aDxfWidth > 0 // or m_defaultThickness double mapWidth( double aDxfWidth ); // Functions to aid in the creation of a Polyline void insertLine( const VECTOR2D& aSegStart, const VECTOR2D& aSegEnd, int aWidth ); void insertArc( const VECTOR2D& aSegStart, const VECTOR2D& aSegEnd, double aBulge, int aWidth ); // Add a dxf spline (stored in m_curr_entity) to the board, after conversion to segments void insertSpline( int aWidth ); // Methods from DL_CreationAdapter: // They are something like"call back" functions, // called when the corresponding object is read in dxf file /** * 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 ) override; /** * Called for every int variable in the DXF file (e.g. "$ACADMAINTVER"). */ virtual void setVariableInt( const std::string& key, int value, int code ) override; /** * Called for every double variable in the DXF file (e.g. "$DIMEXO"). */ virtual void setVariableDouble( const std::string& key, double value, int code ) override {} virtual void addLayer( const DL_LayerData& aData ) override; virtual void addLine( const DL_LineData& aData) override; virtual void addCircle( const DL_CircleData& aData ) override; virtual void addArc( const DL_ArcData& aData ) override; //virtual void addLWPolyline( const DRW_LWPolyline& aData ) override; virtual void addText( const DL_TextData& aData ) override; virtual void addPolyline( const DL_PolylineData& aData ) override; /** Called for every polyline vertex */ virtual void addVertex( const DL_VertexData& aData ) override; virtual void addMText( const DL_MTextData& aData) override; virtual void addTextStyle( const DL_StyleData& aData ) override; virtual void endEntity() override; /** Called for every spline */ virtual void addSpline( const DL_SplineData& aData ) override; /** Called for every spline control point */ virtual void addControlPoint( const DL_ControlPointData& aData ) override; /** Called for every spline fit point */ virtual void addFitPoint( const DL_FitPointData& aData ) override; /** Called for every spline knot value */ virtual void addKnot( const DL_KnotData& aData ) override; // Not yet handled DXF entities: virtual void addDimAlign( const DL_DimensionData&, const DL_DimAlignedData& ) override { reportMsg( "DL_Dimension not managed" ); } virtual void addDimLinear( const DL_DimensionData&, const DL_DimLinearData& ) override { reportMsg( "DL_Dimension not managed" ); } virtual void addDimRadial( const DL_DimensionData&, const DL_DimRadialData& ) override { reportMsg( "DL_Dimension not managed" ); } virtual void addDimDiametric( const DL_DimensionData&, const DL_DimDiametricData& ) override { reportMsg( "DL_Dimension not managed" ); } virtual void addDimAngular( const DL_DimensionData&, const DL_DimAngularData& ) override { reportMsg( "DL_Dimension not managed" ); } virtual void addDimAngular3P( const DL_DimensionData&, const DL_DimAngular3PData& ) override { reportMsg( "DL_Dimension not managed" ); } virtual void addDimOrdinate( const DL_DimensionData&, const DL_DimOrdinateData& ) override { reportMsg( "DL_Dimension not managed" ); } virtual void addLeader( const DL_LeaderData& ) override { reportMsg( "DL_Leader not managed" ); } virtual void addLeaderVertex( const DL_LeaderVertexData& ) override { reportMsg( "DL_LeaderVertex not managed" ); } virtual void addHatch( const DL_HatchData& ) override { reportMsg( "DL_Hatch not managed" ); } virtual void addTrace( const DL_TraceData& ) override { reportMsg( "DL_Trace not managed" ); } virtual void add3dFace( const DL_3dFaceData& ) override { reportMsg( "DL_3dFace not managed" ); } virtual void addSolid( const DL_SolidData& ) override { reportMsg( "DL_Solid not managed" ); } virtual void addImage( const DL_ImageData& ) override { reportMsg( "DL_ImageDa not managed" ); } virtual void linkImage( const DL_ImageDefData& ) override { reportMsg( "DL_ImageDef not managed" ); } virtual void addHatchLoop( const DL_HatchLoopData& ) override { reportMsg( "DL_HatchLoop not managed" ); } virtual void addHatchEdge( const DL_HatchEdgeData& ) override { reportMsg( "DL_HatchEdge not managed" ); } /** * Convert a native unicode string into a DXF encoded string. * * DXF encoding includes the following special sequences: * - %%%c for a diameter sign * - %%%d for a degree sign * - %%%p for a plus/minus sign */ static wxString toDxfString( const wxString& aStr ); /** * Converts a DXF encoded string into a native Unicode string. */ static wxString toNativeString( const wxString& aData ); void writeLine(); void writeMtext(); }; #endif // DXF2BRD_ITEMS_H