36#include <io/kicad/sexpr_file_versions.h>
39#include <potracelib.h>
41#include <fmt/format.h>
42#include <wx/translation.h>
48static void bm_free( potrace_bitmap_t* bm )
58 potrace_dpoint_t p1, potrace_dpoint_t p2,
59 potrace_dpoint_t p3, potrace_dpoint_t p4 );
77 int aDpi_X,
int aDpi_Y,
const wxString& aLayer )
79 potrace_param_t* param;
83 param = potrace_param_default();
87 m_reporter.Report( fmt::format(
"Error allocating parameters: {}\n", strerror( errno ) ),
95 param->opttolerance = 0.2;
98 st = potrace_trace( param, aPotrace_bitmap );
100 if( !st || st->status != POTRACE_STATUS_OK )
103 potrace_state_free( st );
105 potrace_param_free( param );
107 m_reporter.Report( fmt::format(
"Error tracing bitmap: {}\n", strerror( errno ) ),
146 potrace_state_free( st );
147 potrace_param_free( param );
161 m_Data +=
"%!PS-Adobe-3.0 EPSF-3.0\n";
169 m_Data += fmt::format(
"(footprint \"{}\" (version {}) (generator \"bitmap2component\") (generator_version \"{}\")\n"
170 " (layer \"F.Cu\")\n",
172 SEXPR_FOOTPRINT_FILE_VERSION,
175 m_Data += fmt::format(
" (attr board_only exclude_from_pos_files exclude_from_bom)\n" );
176 m_Data += fmt::format(
" (fp_text reference \"G***\" (at 0 0) (layer \"{}\")\n"
177 " (effects (font (size 1.5 1.5) (thickness 0.3)))\n"
179 aBrdLayerName.ToStdString().c_str(),
180 KIID().AsString().ToStdString().c_str() );
182 m_Data += fmt::format(
" (fp_text value \"{}\" (at 0.75 0) (layer \"{}\") hide\n"
183 " (effects (font (size 1.5 1.5) (thickness 0.3)))\n"
186 aBrdLayerName.ToStdString().c_str(),
187 KIID().AsString().ToStdString().c_str() );
194 m_Data += fmt::format(
"(kicad_symbol_lib (version {}) (generator \"bitmap2component\") (generator_version \"{}\")\n",
202 Ypos += fieldSize / 2;
203 m_Data += fmt::format(
" (symbol \"{}\" (pin_names (offset 1.016)) (in_bom yes) (on_board yes)\n",
206 m_Data += fmt::format(
" (property \"Reference\" \"#G\" (at 0 {:g} 0)\n"
207 " (effects (font (size {:g} {:g})) hide)\n )\n",
212 m_Data += fmt::format(
" (property \"Value\" \"{}\" (at 0 {:g} 0)\n"
213 " (effects (font (size {:g} {:g})) hide)\n )\n",
219 m_Data += fmt::format(
" (property \"Footprint\" \"\" (at 0 0 0)\n"
220 " (effects (font (size {:g} {:g})) hide)\n )\n",
224 m_Data += fmt::format(
" (property \"Datasheet\" \"\" (at 0 0 0)\n"
225 " (effects (font (size {:g} {:g})) hide)\n )\n",
280 m_Data += fmt::format(
"newpath\n{} {} moveto\n", startpoint.
x, offsetY - startpoint.
y );
283 for( ii = 1; ii < aPolygon.
PointCount(); ii++ )
285 currpoint = aPolygon.
CPoint( ii );
286 m_Data += fmt::format(
" {} {} lineto", currpoint.
x, offsetY - currpoint.
y );
295 m_Data +=
"\nclosepath fill\n";
299 m_Data +=
" (fp_poly\n (pts\n";
303 for( ii = 0; ii < aPolygon.
PointCount(); ii++ )
305 currpoint = aPolygon.
CPoint( ii );
306 m_Data += fmt::format(
" (xy {} {})\n",
313 m_Data += fmt::format(
" (stroke (width {:f}) (type solid)) (fill solid) (layer \"{}\") (uuid {}))\n",
315 aBrdLayerName.ToStdString().c_str(),
316 KIID().AsString().ToStdString().c_str() );
325#define SCH_LINE_THICKNESS_MM 0.01
327 m_Data +=
" (polyline\n (pts\n";
329 for( ii = 0; ii < aPolygon.
PointCount(); ii++ )
331 currpoint = aPolygon.
CPoint( ii );
332 m_Data += fmt::format(
" (xy {:f} {:f})\n",
338 m_Data += fmt::format(
" (xy {:f} {:f})\n",
343 m_Data += fmt::format(
" (stroke (width {:g}) (type default))\n"
344 " (fill (type outline))\n",
354 std::vector <potrace_dpoint_t> cornersBuffer;
366 potrace_dpoint_t( *c )[3];
376 bool main_outline =
true;
381 potrace_path_t* paths =
m_Paths;
385 m_reporter.Report(
_(
"No shape in black and white image to convert: no outline created." ),
389 while( paths !=
nullptr )
391 int cnt = paths->curve.n;
392 int* tag = paths->curve.tag;
394 potrace_dpoint_t startpoint = c[cnt - 1][2];
396 for(
int i = 0; i < cnt; i++ )
401 cornersBuffer.push_back( c[i][1] );
402 cornersBuffer.push_back( c[i][2] );
403 startpoint = c[i][2];
406 case POTRACE_CURVETO:
408 startpoint = c[i][2];
416 main_outline =
false;
421 for(
const potrace_dpoint_s& pt : cornersBuffer )
432 for(
const potrace_dpoint_s& pt : cornersBuffer )
439 cornersBuffer.clear();
442 if( paths->next ==
nullptr || paths->next->sign ==
'+' )
457 for(
int ii = 0; ii < polyset_areas.
OutlineCount(); ii++ )
462 for(
int ii = 0; ii < polyset_areas.
OutlineCount(); ii++ )
492 model.SetGenerator( wxT(
"bitmap2component" ) );
493 model.SetLeftMargin( 10 );
494 model.SetRightMargin( 10 );
495 model.SetTopMargin( 10 );
496 model.SetBottomMargin( 10 );
498 model.m_DefaultLineWidth = 0.15;
499 model.m_DefaultTextThickness = 0.15;
501 auto polyItem = std::make_unique<DS_DATA_ITEM_POLYGONS>();
502 polyItem->m_Name = wxEmptyString;
504 polyItem->m_LineWidth = 0.01;
516 for(
int jj = 0; jj < poly.
PointCount(); jj++ )
527 polyItem->CloseContour();
530 if( polyItem->GetPolyCount() > 0 )
531 model.Append( polyItem.release() );
561 potrace_dpoint_t p4 )
576 dd0 =
square( p1.x - 2 * p2.x + p3.x ) +
square( p1.y - 2 * p2.y + p3.y );
577 dd1 =
square( p2.x - 2 * p3.x + p4.x ) +
square( p2.y - 2 * p3.y + p4.y );
578 dd = 6 * sqrt( std::max( dd0, dd1 ) );
584 potrace_dpoint_t intermediate_point;
585 intermediate_point.x = p1.x *
cube( 1 - t ) +
586 3* p2.x*
square( 1 - t ) * t +
587 3 * p3.x * (1 - t) *
square( t ) +
590 intermediate_point.y = p1.y *
cube( 1 - t ) +
591 3* p2.y*
square( 1 - t ) * t +
592 3 * p3.y * (1 - t) *
square( t ) + p4.y*
cube( t );
594 aCornersBuffer.push_back( intermediate_point );
597 aCornersBuffer.push_back( p4 );
constexpr double SCH_IU_PER_MM
Schematic internal units 1=100nm.
constexpr double PCB_IU_PER_MM
Pcbnew IU is 1 nanometer.
constexpr double PL_IU_PER_MM
Internal units in micron (should be enough).
static void BezierToPolyline(std::vector< potrace_dpoint_t > &aCornersBuffer, potrace_dpoint_t p1, potrace_dpoint_t p2, potrace_dpoint_t p3, potrace_dpoint_t p4)
static void bm_free(potrace_bitmap_t *bm)
#define SCH_LINE_THICKNESS_MM
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
wxString GetMajorMinorVersion()
Get only the major and minor version in a string major.minor.
void outputDataEnd()
Function outputDataEnd write to file the last strings depending on file format.
BITMAPCONV_INFO(std::string &aData, REPORTER &aReporter)
void outputOnePolygon(SHAPE_LINE_CHAIN &aPolygon, const wxString &aBrdLayerName)
Function outputOnePolygon write one polygon to output file.
void outputDataHeader(const wxString &aBrdLayerName)
Function outputDataHeader write to file the header depending on file format.
enum OUTPUT_FMT_ID m_Format
int ConvertBitmap(potrace_bitmap_t *aPotrace_bitmap, OUTPUT_FMT_ID aFormat, int aDpi_X, int aDpi_Y, const wxString &aLayer)
Run the conversion of the bitmap.
void createDrawingSheetData(SHAPE_POLY_SET &aPolyset)
Generate drawing sheet output using the DS_DATA_MODEL serialization instead of hardcoded S-expression...
void createOutputData(const wxString &aBrdLayerName=wxT("F.SilkS"))
Creates the data specified by m_Format.
Handle the graphic items list to draw/plot the frame and title block.
A pure virtual class used to derive REPORTER objects from.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
int PointCount() const
Return the number of points (vertices) in this line chain.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
Represent a set of closed polygons.
void RemoveAllContours()
Remove all outlines & holes (clears) the polygon set.
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new outline to the set and returns its index.
int NormalizeAreaOutlines()
Convert a self-intersecting polygon to one (or more) non self-intersecting polygon(s).
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline)
void Simplify()
Simplify the polyset (merges overlapping polys, eliminates degeneracy/self-intersections)
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
int NewOutline()
Creates a new empty polygon in the set and returns its index.
int OutlineCount() const
Return the number of outlines in the set.
void Fracture(bool aSimplify=true)
Convert a set of polygons with holes to a single outline with "slits"/"fractures" connecting the oute...
void BooleanSubtract(const SHAPE_POLY_SET &b)
Perform boolean polyset difference.
This file contains miscellaneous commonly used macros and functions.
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
#define SEXPR_SYMBOL_LIB_FILE_VERSION
This file contains the file format version information for the s-expression schematic and symbol libr...
wxString result
Test unit parsing edge cases and error handling.
VECTOR2< int32_t > VECTOR2I
VECTOR2< double > VECTOR2D