bitmap2component: use BOOST:POLYGON instead of KBool, and minor enhancements.
This commit is contained in:
parent
4cbcf56cee
commit
51a845470b
|
@ -45,6 +45,8 @@
|
|||
#define KEYWORD_FRAME_SIZEY wxT( "Bmconverter_Size_y" )
|
||||
#define KEYWORD_LAST_INPUT_FILE wxT( "Last_input" )
|
||||
#define KEYWORD_LAST_OUTPUT_FILE wxT( "Last_output" )
|
||||
#define KEYWORD_BINARY_THRESHOLD wxT( "Threshold" )
|
||||
#define KEYWORD_BW_NEGATIVE wxT( "Negative_choice" )
|
||||
|
||||
extern int bitmap2component( potrace_bitmap_t* aPotrace_bitmap, FILE* aOutfile, int aFormat );
|
||||
|
||||
|
@ -88,6 +90,7 @@ private:
|
|||
|
||||
BM2CMP_FRAME::BM2CMP_FRAME() : BM2CMP_FRAME_BASE( NULL )
|
||||
{
|
||||
int tmp;
|
||||
m_Config = new wxConfig();
|
||||
m_Config->Read( KEYWORD_FRAME_POSX, & m_FramePos.x, -1 );
|
||||
m_Config->Read( KEYWORD_FRAME_POSY, & m_FramePos.y, -1 );
|
||||
|
@ -95,6 +98,11 @@ BM2CMP_FRAME::BM2CMP_FRAME() : BM2CMP_FRAME_BASE( NULL )
|
|||
m_Config->Read( KEYWORD_FRAME_SIZEY, & m_FrameSize.y, -1 );
|
||||
m_Config->Read( KEYWORD_LAST_INPUT_FILE, &m_BitmapFileName );
|
||||
m_Config->Read( KEYWORD_LAST_OUTPUT_FILE, &m_ConvertedFileName );
|
||||
if( m_Config->Read( KEYWORD_BINARY_THRESHOLD, &tmp ) )
|
||||
m_sliderThreshold->SetValue( tmp );
|
||||
if( m_Config->Read( KEYWORD_BW_NEGATIVE, &tmp ) )
|
||||
m_rbOptions->SetSelection( tmp ? 1 : 0 );
|
||||
|
||||
|
||||
// Give an icon
|
||||
wxIcon icon;
|
||||
|
@ -127,6 +135,8 @@ BM2CMP_FRAME::~BM2CMP_FRAME()
|
|||
m_Config->Write( KEYWORD_FRAME_SIZEY, (long) m_FrameSize.y );
|
||||
m_Config->Write( KEYWORD_LAST_INPUT_FILE, m_BitmapFileName );
|
||||
m_Config->Write( KEYWORD_LAST_OUTPUT_FILE, m_ConvertedFileName );
|
||||
m_Config->Write( KEYWORD_BINARY_THRESHOLD, m_sliderThreshold->GetValue() );
|
||||
m_Config->Write( KEYWORD_BW_NEGATIVE, m_rbOptions->GetSelection() );
|
||||
|
||||
delete m_Config;
|
||||
|
||||
|
@ -390,16 +400,12 @@ void BM2CMP_FRAME::ExportFile( FILE* aOutfile, int aFormat )
|
|||
}
|
||||
|
||||
|
||||
// BM_TO_CMP_APP
|
||||
|
||||
void EDA_APP::MacOpenFile(const wxString &fileName)
|
||||
{
|
||||
}
|
||||
// EDA_APP
|
||||
|
||||
IMPLEMENT_APP( EDA_APP )
|
||||
|
||||
///-----------------------------------------------------------------------------
|
||||
// BM_TO_CMP_APP
|
||||
// EDA_APP
|
||||
// main program
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
@ -415,3 +421,8 @@ bool EDA_APP::OnInit()
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void EDA_APP::MacOpenFile(const wxString &fileName)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -21,8 +21,10 @@
|
|||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
#include <math.h>
|
||||
|
||||
#include "kbool/booleng.h"
|
||||
// For some unknown reasons, polygon.hpp shoul be included first
|
||||
#include "boost/polygon/polygon.hpp"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
@ -34,13 +36,24 @@
|
|||
#include "potracelib.h"
|
||||
#include "auxiliary.h"
|
||||
|
||||
|
||||
#ifndef max
|
||||
#define max( a, b ) ( ( (a) > (b) ) ? (a) : (b) )
|
||||
#endif
|
||||
#ifndef min
|
||||
#endif
|
||||
#ifndef min
|
||||
#define min( a, b ) ( ( (a) < (b) ) ? (a) : (b) )
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Define some types used here from boost::polygon
|
||||
namespace bpl = boost::polygon; // bpl = boost polygon library
|
||||
using namespace bpl::operators; // +, -, =, ...
|
||||
|
||||
typedef int coordinate_type;
|
||||
|
||||
typedef bpl::polygon_data<coordinate_type> KPolygon; // define a basic polygon
|
||||
typedef std::vector<KPolygon> KPolygonSet; // define a set of polygons
|
||||
|
||||
typedef bpl::point_data<coordinate_type> KPolyPoint; // define a corner of a polygon
|
||||
|
||||
enum output_format {
|
||||
POSTSCRIPT_FMT = 1,
|
||||
|
@ -48,11 +61,13 @@ enum output_format {
|
|||
EESCHEMA_FMT
|
||||
};
|
||||
/* free a potrace bitmap */
|
||||
static void bm_free(potrace_bitmap_t *bm) {
|
||||
if (bm != NULL) {
|
||||
free(bm->map);
|
||||
static void bm_free( potrace_bitmap_t* bm )
|
||||
{
|
||||
if( bm != NULL )
|
||||
{
|
||||
free( bm->map );
|
||||
}
|
||||
free(bm);
|
||||
free( bm );
|
||||
}
|
||||
|
||||
|
||||
|
@ -69,8 +84,7 @@ public:
|
|||
double m_ScaleY; // the conversion scale
|
||||
potrace_path_t* m_Paths; // the list of paths, from potrace (list of lines and bezier curves)
|
||||
FILE* m_Outfile;
|
||||
public:
|
||||
BITMAPCONV_INFO();
|
||||
public: BITMAPCONV_INFO();
|
||||
};
|
||||
|
||||
static void BezierToPolyline( std::vector <potrace_dpoint_t>& aCornersBuffer,
|
||||
|
@ -96,102 +110,7 @@ BITMAPCONV_INFO::BITMAPCONV_INFO()
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function ArmBoolEng
|
||||
* Initialise parameters used in kbool
|
||||
* @param aBooleng = pointer to the Bool_Engine to initialise
|
||||
* @param aConvertHoles = mode for holes when a boolean operation is made
|
||||
* true: in resulting polygon, holes are linked into outer contours by double overlapping segments
|
||||
* false: in resulting polygons, holes are not linked: they are separate polygons
|
||||
*/
|
||||
void ArmBoolEng( Bool_Engine* aBooleng, bool aConvertHoles )
|
||||
{
|
||||
// set some global vals to arm the boolean engine
|
||||
|
||||
// input points are scaled up with GetDGrid() * GetGrid()
|
||||
|
||||
// DGRID is only meant to make fractional parts of input data which
|
||||
|
||||
/*
|
||||
* The input data scaled up with DGrid is related to the accuracy the user has in his input data.
|
||||
* User data with a minimum accuracy of 0.001, means set the DGrid to 1000.
|
||||
* The input data may contain data with a minimum accuracy much smaller, but by setting the DGrid
|
||||
* everything smaller than 1/DGrid is rounded.
|
||||
*
|
||||
* DGRID is only meant to make fractional parts of input data which can be
|
||||
* doubles, part of the integers used in vertexes within the boolean algorithm.
|
||||
* And therefore DGRID bigger than 1 is not usefull, you would only loose accuracy.
|
||||
* Within the algorithm all input data is multiplied with DGRID, and the result
|
||||
* is rounded to an integer.
|
||||
*/
|
||||
double DGRID = 1000.0; // round coordinate X or Y value in calculations to this (initial value = 1000.0 in kbool example)
|
||||
// kbool uses DGRID to convert float user units to integer
|
||||
// kbool unit = (int)(user unit * DGRID)
|
||||
// Note: in kicad, coordinates are already integer so DGRID could be set to 1
|
||||
// we can choose 1.0,
|
||||
// but choose DGRID = 1000.0 solves some filling problems
|
||||
// (perhaps because this allows a better precision in kbool internal calculations
|
||||
|
||||
double MARGE = 1.0 / DGRID; // snap with in this range points to lines in the intersection routines
|
||||
// should always be >= 1/DGRID a MARGE >= 10/DGRID is ok
|
||||
// this is also used to remove small segments and to decide when
|
||||
// two segments are in line. ( initial value = 0.001 )
|
||||
// For kicad we choose MARGE = 1/DGRID
|
||||
|
||||
double CORRECTIONFACTOR = 0.0; // correct the polygons by this number: used in BOOL_CORRECTION operation
|
||||
// this operation shrinks a polygon if CORRECTIONFACTOR < 0
|
||||
// or stretch it if CORRECTIONFACTOR > 0
|
||||
// the size change is CORRECTIONFACTOR (holes are correctly handled)
|
||||
double CORRECTIONABER = 1.0; // the accuracy for the rounded shapes used in correction
|
||||
double ROUNDFACTOR = 1.5; // when will we round the correction shape to a circle
|
||||
double SMOOTHABER = 10.0; // accuracy when smoothing a polygon
|
||||
double MAXLINEMERGE = 1000.0; // leave as is, segments of this length in smoothen
|
||||
|
||||
|
||||
/*
|
||||
* Grid makes sure that the integer data used within the algorithm has room for extra intersections
|
||||
* smaller than the smallest number within the input data.
|
||||
* The input data scaled up with DGrid is related to the accuracy the user has in his input data.
|
||||
* Another scaling with Grid is applied on top of it to create space in the integer number for
|
||||
* even smaller numbers.
|
||||
*/
|
||||
int GRID = (int) ( 10000 / DGRID ); // initial value = 10000 in kbool example
|
||||
|
||||
// But we use 10000/DGRID because the scalling is made
|
||||
// by DGRID on integer pcbnew units and
|
||||
// the global scalling ( GRID*DGRID) must be < 30000 to avoid
|
||||
// overflow in calculations (made in long long in kbool)
|
||||
if( GRID <= 1 ) // Cannot be null!
|
||||
GRID = 1;
|
||||
|
||||
aBooleng->SetMarge( MARGE );
|
||||
aBooleng->SetGrid( GRID );
|
||||
aBooleng->SetDGrid( DGRID );
|
||||
aBooleng->SetCorrectionFactor( CORRECTIONFACTOR );
|
||||
aBooleng->SetCorrectionAber( CORRECTIONABER );
|
||||
aBooleng->SetSmoothAber( SMOOTHABER );
|
||||
aBooleng->SetMaxlinemerge( MAXLINEMERGE );
|
||||
aBooleng->SetRoundfactor( ROUNDFACTOR );
|
||||
aBooleng->SetWindingRule( true ); // This is the default kbool value
|
||||
|
||||
if( aConvertHoles )
|
||||
{
|
||||
#if 1 // Can be set to 1 for kbool version >= 2.1, must be set to 0 for previous versions
|
||||
// SetAllowNonTopHoleLinking() exists only in kbool >= 2.1
|
||||
aBooleng->SetAllowNonTopHoleLinking( false ); // Default = , but i have problems (filling errors) when true
|
||||
#endif
|
||||
aBooleng->SetLinkHoles( true ); // holes will be connected by double overlapping segments
|
||||
aBooleng->SetOrientationEntryMode( false ); // all polygons are contours, not holes
|
||||
}
|
||||
else
|
||||
{
|
||||
aBooleng->SetLinkHoles( false ); // holes will not be connected by double overlapping segments
|
||||
aBooleng->SetOrientationEntryMode( true ); // holes are entered counter clockwise
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int bitmap2component( potrace_bitmap_t* aPotrace_bitmap, FILE * aOutfile, int aFormat )
|
||||
int bitmap2component( potrace_bitmap_t* aPotrace_bitmap, FILE* aOutfile, int aFormat )
|
||||
{
|
||||
potrace_param_t* param;
|
||||
potrace_state_t* st;
|
||||
|
@ -232,7 +151,7 @@ int bitmap2component( potrace_bitmap_t* aPotrace_bitmap, FILE * aOutfile, int aF
|
|||
case 1:
|
||||
info.m_Format = EESCHEMA_FMT;
|
||||
info.m_ScaleX = 1000.0 / 300; // the conversion scale
|
||||
info.m_ScaleY = - info.m_ScaleX; // Y axis is bottom to Top for components in libs
|
||||
info.m_ScaleY = -info.m_ScaleX; // Y axis is bottom to Top for components in libs
|
||||
CreateOutputFile( info );
|
||||
break;
|
||||
|
||||
|
@ -282,12 +201,12 @@ static void OuputHeader( BITMAPCONV_INFO& aInfo )
|
|||
fprintf( aInfo.m_Outfile, "# pixmap w = %d, h = %d\n#\n",
|
||||
aInfo.m_PixmapWidth, aInfo.m_PixmapHeight );
|
||||
fprintf( aInfo.m_Outfile, "$MODULE %s\n", CmpName );
|
||||
fprintf( aInfo.m_Outfile, "Po 0 0 0 15 00000000 00000000 ~~\n");
|
||||
fprintf( aInfo.m_Outfile, "Po 0 0 0 15 00000000 00000000 ~~\n" );
|
||||
fprintf( aInfo.m_Outfile, "Li %s\n", CmpName );
|
||||
fprintf( aInfo.m_Outfile, "T0 0 %d %d %d 0 %d N I %d \"G***\"\n",
|
||||
Ypos, fieldSize, fieldSize, fieldSize/5, FIELD_LAYER );
|
||||
Ypos, fieldSize, fieldSize, fieldSize / 5, FIELD_LAYER );
|
||||
fprintf( aInfo.m_Outfile, "T1 0 %d %d %d 0 %d N I %d \"%s\"\n",
|
||||
-Ypos, fieldSize, fieldSize, fieldSize/5, FIELD_LAYER, CmpName );
|
||||
-Ypos, fieldSize, fieldSize, fieldSize / 5, FIELD_LAYER, CmpName );
|
||||
break;
|
||||
|
||||
case EESCHEMA_FMT:
|
||||
|
@ -329,25 +248,32 @@ static void OuputEnd( BITMAPCONV_INFO& aInfo )
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static void OuputOnePolygon( BITMAPCONV_INFO& aInfo,
|
||||
std::vector <potrace_dpoint_t>& aPolygonBuffer )
|
||||
/**
|
||||
* Function OuputOnePolygon
|
||||
* write one polygon to output file.
|
||||
* Polygon coordinates are expected scaled by the polugon extraction function
|
||||
*/
|
||||
static void OuputOnePolygon( BITMAPCONV_INFO& aInfo, KPolygon & aPolygon )
|
||||
{
|
||||
unsigned ii;
|
||||
KPolyPoint currpoint;
|
||||
|
||||
double offsetX = aInfo.m_PixmapWidth / 2 * aInfo.m_ScaleX;
|
||||
double offsetY = aInfo.m_PixmapHeight / 2 * aInfo.m_ScaleY;
|
||||
int offsetX = (int)( aInfo.m_PixmapWidth / 2 * aInfo.m_ScaleX );
|
||||
int offsetY = (int)( aInfo.m_PixmapHeight / 2 * aInfo.m_ScaleY );
|
||||
|
||||
KPolyPoint startpoint = *aPolygon.begin();
|
||||
|
||||
switch( aInfo.m_Format )
|
||||
{
|
||||
case POSTSCRIPT_FMT:
|
||||
fprintf( aInfo.m_Outfile, "%f %f moveto\n",
|
||||
aPolygonBuffer[0].x * aInfo.m_ScaleX,
|
||||
aPolygonBuffer[0].y * aInfo.m_ScaleY );
|
||||
for( ii = 1; ii < aPolygonBuffer.size(); ii++ )
|
||||
fprintf( aInfo.m_Outfile, "%f %f lineto\n",
|
||||
aPolygonBuffer[ii].x * aInfo.m_ScaleX,
|
||||
aPolygonBuffer[ii].y * aInfo.m_ScaleY );
|
||||
fprintf( aInfo.m_Outfile, "%d %d moveto\n",
|
||||
startpoint.x(), startpoint.y() );
|
||||
for( ii = 1; ii < aPolygon.size(); ii++ )
|
||||
{
|
||||
currpoint = *(aPolygon.begin() + ii);
|
||||
fprintf( aInfo.m_Outfile, "%d %d lineto\n",
|
||||
currpoint.x(), currpoint.y() );
|
||||
}
|
||||
|
||||
fprintf( aInfo.m_Outfile, "0 setgray fill\n" );
|
||||
break;
|
||||
|
@ -359,30 +285,33 @@ static void OuputOnePolygon( BITMAPCONV_INFO& aInfo,
|
|||
int width = 1;
|
||||
fprintf( aInfo.m_Outfile, "DP %d %d %d %d %d %d %d\n",
|
||||
0, 0, 0, 0,
|
||||
int(aPolygonBuffer.size()+1),
|
||||
width, layer );
|
||||
aPolygon.size() + 1, width, layer );
|
||||
|
||||
for( ii = 0; ii < aPolygonBuffer.size(); ii++ )
|
||||
for( ii = 0; ii < aPolygon.size(); ii++ )
|
||||
{
|
||||
currpoint = *( aPolygon.begin() + ii );
|
||||
fprintf( aInfo.m_Outfile, "Dl %d %d\n",
|
||||
(int) ( aPolygonBuffer[ii].x * aInfo.m_ScaleX - offsetX ),
|
||||
(int) ( aPolygonBuffer[ii].y * aInfo.m_ScaleY - offsetY ) );
|
||||
currpoint.x() - offsetX, currpoint.y() - offsetY );
|
||||
}
|
||||
|
||||
// Close polygon
|
||||
fprintf( aInfo.m_Outfile, "Dl %d %d\n",
|
||||
(int) ( aPolygonBuffer[0].x * aInfo.m_ScaleX - offsetX ),
|
||||
(int) ( aPolygonBuffer[0].y * aInfo.m_ScaleY - offsetY ) );
|
||||
startpoint.x() - offsetX, startpoint.y() - offsetY );
|
||||
}
|
||||
break;
|
||||
|
||||
case EESCHEMA_FMT:
|
||||
fprintf( aInfo.m_Outfile, "P %d 0 0 1", int(aPolygonBuffer.size()+1) );
|
||||
for( ii = 0; ii < aPolygonBuffer.size(); ii++ )
|
||||
fprintf( aInfo.m_Outfile, "P %d 0 0 1", aPolygon.size() + 1 );
|
||||
for( ii = 0; ii < aPolygon.size(); ii++ )
|
||||
{
|
||||
currpoint = *(aPolygon.begin() + ii);
|
||||
fprintf( aInfo.m_Outfile, " %d %d",
|
||||
(int) ( aPolygonBuffer[ii].x * aInfo.m_ScaleX - offsetX ),
|
||||
(int) ( aPolygonBuffer[ii].y * aInfo.m_ScaleY - offsetY ) );
|
||||
currpoint.x() - offsetX, currpoint.y() - offsetY );
|
||||
}
|
||||
|
||||
// Close polygon
|
||||
fprintf( aInfo.m_Outfile, " %d %d",
|
||||
(int) ( aPolygonBuffer[0].x * aInfo.m_ScaleX - offsetX ),
|
||||
(int) ( aPolygonBuffer[0].y * aInfo.m_ScaleY - offsetY ) );
|
||||
startpoint.x() - offsetX, startpoint.y() - offsetY );
|
||||
|
||||
fprintf( aInfo.m_Outfile, " F\n" );
|
||||
break;
|
||||
|
@ -392,16 +321,21 @@ static void OuputOnePolygon( BITMAPCONV_INFO& aInfo,
|
|||
|
||||
static void CreateOutputFile( BITMAPCONV_INFO& aInfo )
|
||||
{
|
||||
unsigned int i, n;
|
||||
int* tag;
|
||||
KPolyPoint currpoint;
|
||||
|
||||
std::vector <potrace_dpoint_t> cornersBuffer;
|
||||
|
||||
// This KPolygonSet polyset_areas is a complex polygon to draw
|
||||
// and can be complex depending on holes inside this polygon
|
||||
KPolygonSet polyset_areas;
|
||||
|
||||
// This KPolygonSet polyset_holes is the set of holes inside polyset_areas
|
||||
KPolygonSet polyset_holes;
|
||||
|
||||
potrace_dpoint_t( *c )[3];
|
||||
OuputHeader( aInfo );
|
||||
|
||||
bool main_outline = true;
|
||||
Bool_Engine* booleng = NULL;
|
||||
|
||||
/* draw each as a polygon with no hole.
|
||||
* Bezier curves are approximated by a polyline
|
||||
|
@ -409,17 +343,11 @@ static void CreateOutputFile( BITMAPCONV_INFO& aInfo )
|
|||
potrace_path_t* paths = aInfo.m_Paths; // the list of paths
|
||||
while( paths != NULL )
|
||||
{
|
||||
n = paths->curve.n;
|
||||
tag = paths->curve.tag;
|
||||
int cnt = paths->curve.n;
|
||||
int* tag = paths->curve.tag;
|
||||
c = paths->curve.c;
|
||||
potrace_dpoint_t startpoint = c[n - 1][2];
|
||||
cornersBuffer.push_back( startpoint );
|
||||
if( booleng == NULL )
|
||||
{
|
||||
booleng = new Bool_Engine();
|
||||
ArmBoolEng( booleng, true );
|
||||
}
|
||||
for( i = 0; i < n; i++ )
|
||||
potrace_dpoint_t startpoint = c[cnt - 1][2];
|
||||
for( int i = 0; i < cnt; i++ )
|
||||
{
|
||||
switch( tag[i] )
|
||||
{
|
||||
|
@ -440,46 +368,53 @@ static void CreateOutputFile( BITMAPCONV_INFO& aInfo )
|
|||
if( main_outline )
|
||||
{
|
||||
main_outline = false;
|
||||
booleng->StartPolygonAdd( GROUP_A );
|
||||
for( i = 1; i < cornersBuffer.size(); i++ )
|
||||
booleng->AddPoint( cornersBuffer[i].x, cornersBuffer[i].y );
|
||||
|
||||
booleng->EndPolygonAdd();
|
||||
// build the current main polygon
|
||||
std::vector<KPolyPoint> cornerslist; // a simple boost polygon
|
||||
for( unsigned int i = 0; i < cornersBuffer.size(); i++ )
|
||||
{
|
||||
currpoint.x( (coordinate_type) (cornersBuffer[i].x * aInfo.m_ScaleX) );
|
||||
currpoint.y( (coordinate_type) (cornersBuffer[i].y * aInfo.m_ScaleY) );
|
||||
cornerslist.push_back( currpoint );
|
||||
}
|
||||
|
||||
KPolygon poly;
|
||||
bpl::set_points( poly, cornerslist.begin(), cornerslist.end() );
|
||||
polyset_areas.push_back( poly );
|
||||
}
|
||||
else
|
||||
{
|
||||
booleng->StartPolygonAdd( GROUP_B );
|
||||
for( i = 1; i < cornersBuffer.size(); i++ )
|
||||
booleng->AddPoint( cornersBuffer[i].x, cornersBuffer[i].y );
|
||||
// Add current hole in polyset_holes
|
||||
std::vector<KPolyPoint> cornerslist; // a simple boost polygon
|
||||
for( unsigned int i = 0; i < cornersBuffer.size(); i++ )
|
||||
{
|
||||
currpoint.x( (coordinate_type) (cornersBuffer[i].x * aInfo.m_ScaleX) );
|
||||
currpoint.y( (coordinate_type) (cornersBuffer[i].y * aInfo.m_ScaleY) );
|
||||
cornerslist.push_back( currpoint );
|
||||
}
|
||||
|
||||
booleng->EndPolygonAdd();
|
||||
KPolygon poly;
|
||||
bpl::set_points( poly, cornerslist.begin(), cornerslist.end() );
|
||||
polyset_holes.push_back( poly );
|
||||
}
|
||||
cornersBuffer.clear();
|
||||
|
||||
/* at the end of a group of a positive path and its negative
|
||||
* children, fill. */
|
||||
/* at the end of a group of a positive path and its negative children, fill.
|
||||
*/
|
||||
if( paths->next == NULL || paths->next->sign == '+' )
|
||||
{
|
||||
booleng->Do_Operation( BOOL_A_SUB_B );
|
||||
std::vector <potrace_dpoint_t> PolygonBuffer;
|
||||
while( booleng->StartPolygonGet() )
|
||||
// Substract holes to main polygon:
|
||||
polyset_areas -= polyset_holes;
|
||||
|
||||
// Output current resulting polygon(s)
|
||||
for( unsigned ii = 0; ii < polyset_areas.size(); ii++ )
|
||||
{
|
||||
potrace_dpoint_t corner;
|
||||
PolygonBuffer.clear();
|
||||
while( booleng->PolygonHasMorePoints() )
|
||||
{
|
||||
corner.x = booleng->GetPolygonXPoint();
|
||||
corner.y = booleng->GetPolygonYPoint();
|
||||
PolygonBuffer.push_back( corner );
|
||||
KPolygon& poly = polyset_areas[ii];
|
||||
OuputOnePolygon( aInfo, poly );
|
||||
}
|
||||
|
||||
booleng->EndPolygonGet();
|
||||
OuputOnePolygon( aInfo, PolygonBuffer );
|
||||
PolygonBuffer.clear();
|
||||
}
|
||||
|
||||
delete booleng;
|
||||
booleng = NULL;
|
||||
polyset_areas.clear();
|
||||
polyset_holes.clear();
|
||||
main_outline = true;
|
||||
}
|
||||
paths = paths->next;
|
||||
|
@ -505,7 +440,7 @@ void BezierToPolyline( std::vector <potrace_dpoint_t>& aCornersBuffer,
|
|||
* between the true curve and its approximation does not exceed the
|
||||
* desired accuracy delta. */
|
||||
|
||||
delta = 0.5; /* desired accuracy, in pixels */
|
||||
delta = 0.25; /* desired accuracy, in pixels */
|
||||
|
||||
/* let dd = maximal value of 2nd derivative over curve - this must
|
||||
* occur at an endpoint. */
|
||||
|
|
|
@ -77,10 +77,11 @@ typedef struct potrace_dpoint_s potrace_dpoint_t;
|
|||
/* closed curve segment */
|
||||
struct potrace_curve_s
|
||||
{
|
||||
int n; /* number of segments */
|
||||
int* tag; /* tag[n]: POTRACE_CURVETO or POTRACE_CORNER */
|
||||
int n; // number of segments
|
||||
int* tag; // tag[n]: POTRACE_CURVETO or POTRACE_CORNER
|
||||
potrace_dpoint_t( * c )[3]; /* c[n][3]: control points.
|
||||
* c[n][0] is unused for tag[n]=POTRACE_CORNER */
|
||||
* c[n][0] is unused for tag[n]=POTRACE_CORNER
|
||||
*/
|
||||
};
|
||||
typedef struct potrace_curve_s potrace_curve_t;
|
||||
|
||||
|
|
Loading…
Reference in New Issue