removed GPC library due to its unacceptable license. Using the great and powerfull kbool library insteed
This commit is contained in:
parent
e3b63f8380
commit
44743723d1
|
@ -101,6 +101,7 @@ add_subdirectory(gerbview)
|
|||
add_subdirectory(kicad)
|
||||
add_subdirectory(pcbnew)
|
||||
add_subdirectory(polygon)
|
||||
add_subdirectory(polygon/kbool/src)
|
||||
# Resources.
|
||||
add_subdirectory(demos)
|
||||
add_subdirectory(internat)
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
# Generate a static library target named "libbitmaps.a"
|
||||
|
||||
|
||||
# Copy the *.xmp files to *.cpp, on change only.
|
||||
# Compile those *.cpp files and put them into the library, then done.
|
||||
|
||||
|
||||
OBJECTS = \
|
||||
3d.o\
|
||||
Add_Arc.o\
|
||||
|
@ -287,5 +283,88 @@ OBJECTS = \
|
|||
Zoom_Page.o\
|
||||
Zoom_Selected.o\
|
||||
Zoom_Select.o\
|
||||
zoom.o
|
||||
|
||||
zoom.o\
|
||||
axis3d_back.o\
|
||||
axis3d_bottom.o\
|
||||
axis3d_front.o\
|
||||
axis3d_left.o\
|
||||
axis3d_right.o\
|
||||
axis3d_top.o\
|
||||
axis3d.o\
|
||||
import3d.o\
|
||||
rotate-x.o\
|
||||
rotate+x.o\
|
||||
rotate-y.o\
|
||||
rotate+y.o\
|
||||
rotate-z.o\
|
||||
rotate+z.o\
|
||||
zoomoins3d.o\
|
||||
zoompage3d.o\
|
||||
zoomplus3d.o\
|
||||
zoomrefr3d.o\
|
||||
Lang_Catalan.o\
|
||||
Lang_chinese.o\
|
||||
Lang_Default.o\
|
||||
Lang_De.o\
|
||||
Lang_En.o\
|
||||
Lang_Es.o\
|
||||
Lang_Fr.o\
|
||||
Lang_Hu.o\
|
||||
Lang_It.o\
|
||||
Lang_Ko.o\
|
||||
Lang_Nl.o\
|
||||
Lang_Pl.o\
|
||||
Lang_Pt.o\
|
||||
Lang_Ru.o\
|
||||
Lang_Sl.o\
|
||||
Language.o\
|
||||
delete_association.o\
|
||||
module_filtered_list.o\
|
||||
module_full_list.o\
|
||||
Break_Bus.o\
|
||||
cvpcb.o\
|
||||
Delete_Bus.o\
|
||||
Delete_Connection.o\
|
||||
Delete_GLabel.o\
|
||||
Delete_Pinsheet.o\
|
||||
Delete_Pin.o\
|
||||
Delete_Sheet.o\
|
||||
Edit_Comp_Footprint.o\
|
||||
Edit_Component.o\
|
||||
Edit_Comp_Ref.o\
|
||||
Edit_Comp_Value.o\
|
||||
Edit_Part.o\
|
||||
Edit_Sheet.o\
|
||||
Enter_Sheet.o\
|
||||
GLabel2Label.o\
|
||||
GLabel2Text.o\
|
||||
GL_Change.o\
|
||||
Hidden_Pin.o\
|
||||
Hierarchy_cursor.o\
|
||||
Hierarchy_Nav.o\
|
||||
Label2GLabel.o\
|
||||
Label2Text.o\
|
||||
Leave_Sheet.o\
|
||||
libedit_icon.o\
|
||||
libedit.o\
|
||||
Lib_next.o\
|
||||
Lib_previous.o\
|
||||
library_browse.o\
|
||||
Lines90.o\
|
||||
Move_GLabel.o\
|
||||
Move_Pinsheet.o\
|
||||
Move_Sheet.o\
|
||||
new_component.o\
|
||||
Normal.o\
|
||||
Options_Pinsheet.o\
|
||||
Options_Pin.o\
|
||||
part_properties.o\
|
||||
pin2pin.o\
|
||||
Pin_Name_to.o\
|
||||
Pin_Number_to.o\
|
||||
Pin_Size_to.o\
|
||||
Pin_to.o\
|
||||
Resize_Sheet.o\
|
||||
Rotate_GLabel.o\
|
||||
Rotate_Pin.o\
|
||||
viewlibs_icon.o
|
||||
|
|
|
@ -5,6 +5,14 @@ Started 2007-June-11
|
|||
Please add newer entries at the top, list the date and your name with
|
||||
email address.
|
||||
|
||||
2008-May-30 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
|
||||
================================================================================
|
||||
+pcbnew
|
||||
removed GPC library due to its unacceptable (and stupid) license
|
||||
using the powerfull kbool library insteed (see polygon/kbool)
|
||||
+all:
|
||||
minor changes
|
||||
|
||||
|
||||
2008-May-22 UPDATE Martin Kajdas <kajdas@cox.com>
|
||||
================================================================================
|
||||
|
|
|
@ -244,7 +244,7 @@ void WinEDA_BasicFrame::GetKicadHelp( wxCommandEvent& event )
|
|||
void WinEDA_BasicFrame::GetKicadAbout( wxCommandEvent& event )
|
||||
/**********************************************************/
|
||||
{
|
||||
Print_Kicad_Infos( this, m_AboutTitle );
|
||||
Print_Kicad_Infos( this, m_AboutTitle, wxEmptyString );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,106 +0,0 @@
|
|||
/************************************************************************/
|
||||
/* MODULE edamenu.cpp */
|
||||
/************************************************************************/
|
||||
|
||||
/****************************/
|
||||
/* INCLUDES SYSTEMES */
|
||||
/****************************/
|
||||
|
||||
#include "fctsys.h"
|
||||
|
||||
#include "wxstruct.h"
|
||||
#include "gr_basic.h"
|
||||
#include "macros.h"
|
||||
#include "common.h"
|
||||
|
||||
#include "worksheet.h"
|
||||
|
||||
/* Pour imprimer / lire en unites utilisateur ( INCHES / MM ) */
|
||||
|
||||
/* Retourne la valeur en inch ou mm de la valeur val en unités internes
|
||||
*/
|
||||
double To_User_Unit(bool is_metric, int val,int internal_unit_value)
|
||||
{
|
||||
double value;
|
||||
|
||||
if (is_metric)
|
||||
value = (double) (val) * 25.4 / internal_unit_value;
|
||||
else value = (double) (val) / internal_unit_value;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/* Retourne la valeur en unités internes de la valeur val exprimée en inch ou mm
|
||||
*/
|
||||
int From_User_Unit(bool is_metric, double val,int internal_unit_value)
|
||||
{
|
||||
double value;
|
||||
|
||||
if (is_metric) value = val * internal_unit_value / 25.4 ;
|
||||
else value = val * internal_unit_value;
|
||||
|
||||
return (int) round(value);
|
||||
}
|
||||
|
||||
/**********************/
|
||||
wxString GenDate()
|
||||
/**********************/
|
||||
/* Retourne la chaine de caractere donnant la date */
|
||||
{
|
||||
static char * mois[12] =
|
||||
{
|
||||
"jan", "feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec"
|
||||
};
|
||||
time_t buftime;
|
||||
struct tm * Date;
|
||||
wxString string_date;
|
||||
char Line[1024];
|
||||
|
||||
time(&buftime);
|
||||
Date = gmtime(&buftime);
|
||||
sprintf(Line,"%d %s %d", Date->tm_mday,
|
||||
mois[Date->tm_mon],
|
||||
Date->tm_year + 1900);
|
||||
string_date = Line;
|
||||
return(string_date);
|
||||
}
|
||||
|
||||
/***********************************/
|
||||
void * MyMalloc (size_t nb_octets)
|
||||
/***********************************/
|
||||
/* Routine d'allocation memoire */
|
||||
{
|
||||
void * pt_mem;
|
||||
char txt[60];
|
||||
|
||||
if (nb_octets == 0)
|
||||
{
|
||||
DisplayError(NULL, "Allocate 0 bytes !!");
|
||||
return(NULL);
|
||||
}
|
||||
pt_mem = malloc(nb_octets);
|
||||
if (pt_mem == NULL)
|
||||
{
|
||||
sprintf(txt,"Out of memory: allocation %d bytes", nb_octets);
|
||||
DisplayError(NULL, txt);
|
||||
}
|
||||
return(pt_mem);
|
||||
}
|
||||
|
||||
/************************************/
|
||||
void * MyZMalloc (size_t nb_octets)
|
||||
/************************************/
|
||||
/* Routine d'allocation memoire, avec remise a zero de la zone allouee */
|
||||
{
|
||||
void * pt_mem = MyMalloc (nb_octets);
|
||||
if ( pt_mem) memset(pt_mem, 0, nb_octets);
|
||||
return(pt_mem);
|
||||
}
|
||||
|
||||
/*******************************/
|
||||
void MyFree (void * pt_mem)
|
||||
/*******************************/
|
||||
{
|
||||
if( pt_mem ) free(pt_mem);
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
/****************************************************/
|
||||
/* Display a generic info about kikac (copyright..) */
|
||||
/* Common tp CVPCB, EESCHEMA, PCBNEW and GERBVIEW */
|
||||
/****************************************************/
|
||||
/****************************************************/
|
||||
/* Display a generic info about kikac (copyright..) */
|
||||
/* Common tp CVPCB, EESCHEMA, PCBNEW and GERBVIEW */
|
||||
/****************************************************/
|
||||
|
||||
#include "fctsys.h"
|
||||
#include "gr_basic.h"
|
||||
|
@ -14,53 +14,52 @@
|
|||
// Import:
|
||||
extern wxString g_Main_Title;
|
||||
|
||||
/* Program title strings used in about dialog. They are kept hear to make
|
||||
/* Program title strings used in about dialog. They are kept here to make
|
||||
* it easy to update the copyright dates. */
|
||||
wxString g_KicadAboutTitle = wxT("** KICAD (jul 2000 .. 2008) **");
|
||||
wxString g_CvpcbAboutTitle = wxT("** CVPCB (sept 1992 .. 2008) **");
|
||||
wxString g_EeschemaAboutTitle = wxT("** EESCHEMA (sept 1994 .. 2008) **");
|
||||
wxString g_PcbnewAboutTitle = wxT("** PCBNEW (sept 1992 .. 2008) **");
|
||||
wxString g_GerbviewAboutTitle = wxT("** GERBVIEW (jul 2001 .. 2008) **");
|
||||
wxString g_KicadAboutTitle = wxT( "** KICAD (jul 2000 .. 2008) **" );
|
||||
wxString g_CvpcbAboutTitle = wxT( "** CVPCB (sept 1992 .. 2008) **" );
|
||||
wxString g_EeschemaAboutTitle = wxT( "** EESCHEMA (sept 1994 .. 2008) **" );
|
||||
wxString g_PcbnewAboutTitle = wxT( "** PCBNEW (sept 1992 .. 2008) **" );
|
||||
wxString g_GerbviewAboutTitle = wxT( "** GERBVIEW (jul 2001 .. 2008) **" );
|
||||
|
||||
// Routines Locales
|
||||
|
||||
/*******************************************/
|
||||
void Print_Kicad_Infos(wxWindow * frame, const wxString& title)
|
||||
/*******************************************/
|
||||
/**************************************************************/
|
||||
void Print_Kicad_Infos( wxWindow* frame, const wxString& title,
|
||||
const wxString& aExtra_infos )
|
||||
/**************************************************************/
|
||||
{
|
||||
wxString AboutCaption = wxT("About ");
|
||||
wxString AboutCaption = wxT( "About " );
|
||||
wxString Msg = title;
|
||||
|
||||
Msg << wxT("\n\n") << _("Build Version:") << wxT("\n") ;
|
||||
Msg << wxT( "\n\n" ) << _( "Build Version:" ) << wxT( "\n" );
|
||||
|
||||
Msg << g_Main_Title << wxT(" ") << GetBuildVersion();
|
||||
Msg << g_Main_Title << wxT( " " ) << GetBuildVersion();
|
||||
#if wxUSE_UNICODE
|
||||
Msg << wxT(" - Unicode version");
|
||||
Msg << wxT( " - Unicode version" );
|
||||
#else
|
||||
Msg << wxT(" - Ansi version");
|
||||
Msg << wxT( " - Ansi version" );
|
||||
#endif
|
||||
|
||||
#ifdef KICAD_PYTHON
|
||||
Msg << wxT("\n");
|
||||
Msg << wxT( "python : " );
|
||||
Msg << wxString::FromAscii( PyHandler::GetInstance()->GetVersion() );
|
||||
Msg << wxT( "\n" );
|
||||
Msg << wxT( "python : " );
|
||||
Msg << wxString::FromAscii( PyHandler::GetInstance()->GetVersion() );
|
||||
#endif
|
||||
|
||||
Msg << wxT("\n\n") << _("Author:");
|
||||
Msg << wxT(" JP CHARRAS\n\n") << _("Based on wxWidgets ");
|
||||
Msg << wxMAJOR_VERSION << wxT(".") <<
|
||||
wxMINOR_VERSION << wxT(".") << wxRELEASE_NUMBER;
|
||||
if( wxSUBRELEASE_NUMBER )
|
||||
Msg << wxT(".") << wxSUBRELEASE_NUMBER;
|
||||
Msg << _("\n\nGPL License");
|
||||
Msg << _("\n\nAuthor's sites:\n");
|
||||
Msg << wxT("http://iut-tice.ujf-grenoble.fr/kicad/\n");
|
||||
Msg << wxT("http://www.gipsa-lab.inpg.fr/realise_au_lis/kicad/");
|
||||
Msg << _("\n\nInternational wiki:\n");
|
||||
Msg << wxT("http://kicad.sourceforge.net/\n");
|
||||
Msg << wxT( "\n\n" ) << _( "Author:" );
|
||||
Msg << wxT( " JP CHARRAS\n\n" ) << _( "Based on wxWidgets " );
|
||||
Msg << wxMAJOR_VERSION << wxT( "." ) <<
|
||||
wxMINOR_VERSION << wxT( "." ) << wxRELEASE_NUMBER;
|
||||
if( wxSUBRELEASE_NUMBER )
|
||||
Msg << wxT( "." ) << wxSUBRELEASE_NUMBER;
|
||||
Msg << _( "\n\nGPL License" );
|
||||
Msg << _( "\n\nAuthor's sites:\n" );
|
||||
Msg << wxT( "http://iut-tice.ujf-grenoble.fr/kicad/\n" );
|
||||
Msg << wxT( "http://www.gipsa-lab.inpg.fr/realise_au_lis/kicad/" );
|
||||
Msg << _( "\n\nInternational wiki:\n" );
|
||||
Msg << wxT( "http://kicad.sourceforge.net/\n" );
|
||||
Msg << aExtra_infos;
|
||||
|
||||
AboutCaption << g_Main_Title << wxT(" ") << GetBuildVersion();
|
||||
AboutCaption << g_Main_Title << wxT( " " ) << GetBuildVersion();
|
||||
|
||||
wxMessageBox(Msg, AboutCaption, wxICON_INFORMATION, frame);
|
||||
wxMessageBox( Msg, AboutCaption, wxICON_INFORMATION, frame );
|
||||
}
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ endif(APPLE)
|
|||
|
||||
add_executable(cvpcb WIN32 MACOSX_BUNDLE ${CVPCB_SRCS} ${CVPCB_EXTRA_SRCS} ${CVPCB_RESOURCES})
|
||||
|
||||
target_link_libraries(cvpcb 3d-viewer common polygon bitmaps ${wxWidgets_LIBRARIES} ${OPENGL_LIBRARIES})
|
||||
target_link_libraries(cvpcb 3d-viewer common polygon kbool bitmaps ${wxWidgets_LIBRARIES} ${OPENGL_LIBRARIES})
|
||||
|
||||
install(TARGETS cvpcb RUNTIME DESTINATION ${KICAD_BIN}
|
||||
COMPONENT binary)
|
||||
|
|
|
@ -3,10 +3,12 @@ OBJSUFF = o
|
|||
|
||||
EXTRACPPFLAGS += -DCVPCB -fno-strict-aliasing\
|
||||
-I./ -I../cvpcb -I../include -Ibitmaps\
|
||||
-I../pcbnew -I../3d-viewer\
|
||||
-I../polygon
|
||||
-I../pcbnew -I../3d-viewer -I ../polygon
|
||||
|
||||
EXTRALIBS = ../common/common.a ../bitmaps/libbitmaps.a\
|
||||
../polygon/lib_polygon.a\
|
||||
../polygon/kbool/src/libkbool.a
|
||||
|
||||
EXTRALIBS = ../common/common.a ../bitmaps/libbitmaps.a ../polygon/lib_polygon.a
|
||||
|
||||
LIBVIEWER3D = ../3d-viewer/3d-viewer.a
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ endif(APPLE)
|
|||
|
||||
add_executable(gerbview WIN32 MACOSX_BUNDLE ${GERBVIEW_SRCS} ${GERBVIEW_EXTRA_SRCS} ${GERBVIEW_RESOURCES})
|
||||
|
||||
target_link_libraries(gerbview 3d-viewer common polygon bitmaps ${wxWidgets_LIBRARIES})
|
||||
target_link_libraries(gerbview 3d-viewer common polygon kbool bitmaps ${wxWidgets_LIBRARIES})
|
||||
|
||||
install(TARGETS gerbview RUNTIME DESTINATION ${KICAD_BIN}
|
||||
COMPONENT binary)
|
||||
|
|
|
@ -9,7 +9,7 @@ COMMON_GLOBL wxString g_BuildVersion
|
|||
# include "config.h"
|
||||
(wxT(KICAD_SVN_VERSION))
|
||||
# else
|
||||
(wxT("(20080429-r1010)"))
|
||||
(wxT("(20080530-r1107)"))
|
||||
# endif
|
||||
#endif
|
||||
;
|
||||
|
|
204
include/common.h
204
include/common.h
|
@ -48,10 +48,10 @@ enum pseudokeys {
|
|||
#define EESCHEMA_EXE wxT( "eeschema" )
|
||||
#define GERBVIEW_EXE wxT( "gerbview" )
|
||||
#else
|
||||
#define CVPCB_EXE wxT("cvpcb.app/Contents/MacOS/cvpcb")
|
||||
#define PCBNEW_EXE wxT("pcbnew.app/Contents/MacOS/pcbnew")
|
||||
#define EESCHEMA_EXE wxT("eeschema.app/Contents/MacOS/eeschema")
|
||||
#define GERBVIEW_EXE wxT("gerbview.app/Contents/MacOS/gerbview")
|
||||
#define CVPCB_EXE wxT( "cvpcb.app/Contents/MacOS/cvpcb" )
|
||||
#define PCBNEW_EXE wxT( "pcbnew.app/Contents/MacOS/pcbnew" )
|
||||
#define EESCHEMA_EXE wxT( "eeschema.app/Contents/MacOS/eeschema" )
|
||||
#define GERBVIEW_EXE wxT( "gerbview.app/Contents/MacOS/gerbview" )
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -97,7 +97,7 @@ public:
|
|||
bool m_Setup; /* TRUE -> inscription en setup (registration base)*/
|
||||
|
||||
public:
|
||||
PARAM_CFG_BASE( const wxChar * ident, const paramcfg_id type, const wxChar * group = NULL );
|
||||
PARAM_CFG_BASE( const wxChar* ident, const paramcfg_id type, const wxChar* group = NULL );
|
||||
~PARAM_CFG_BASE() { };
|
||||
};
|
||||
|
||||
|
@ -109,12 +109,12 @@ public:
|
|||
int m_Default; /* valeur par defaut */
|
||||
|
||||
public:
|
||||
PARAM_CFG_INT( const wxChar * ident, int* ptparam,
|
||||
PARAM_CFG_INT( const wxChar* ident, int* ptparam,
|
||||
int default_val = 0, int min = INT_MINVAL, int max = INT_MAXVAL,
|
||||
const wxChar * group = NULL );
|
||||
PARAM_CFG_INT( bool Insetup, const wxChar * ident, int* ptparam,
|
||||
const wxChar* group = NULL );
|
||||
PARAM_CFG_INT( bool Insetup, const wxChar* ident, int* ptparam,
|
||||
int default_val = 0, int min = INT_MINVAL, int max = INT_MAXVAL,
|
||||
const wxChar * group = NULL );
|
||||
const wxChar* group = NULL );
|
||||
};
|
||||
|
||||
class PARAM_CFG_SETCOLOR : public PARAM_CFG_BASE
|
||||
|
@ -124,10 +124,10 @@ public:
|
|||
int m_Default; /* valeur par defaut */
|
||||
|
||||
public:
|
||||
PARAM_CFG_SETCOLOR( const wxChar * ident, int* ptparam,
|
||||
int default_val, const wxChar * group = NULL );
|
||||
PARAM_CFG_SETCOLOR( bool Insetup, const wxChar * ident, int* ptparam,
|
||||
int default_val, const wxChar * group = NULL );
|
||||
PARAM_CFG_SETCOLOR( const wxChar* ident, int* ptparam,
|
||||
int default_val, const wxChar* group = NULL );
|
||||
PARAM_CFG_SETCOLOR( bool Insetup, const wxChar* ident, int* ptparam,
|
||||
int default_val, const wxChar* group = NULL );
|
||||
};
|
||||
|
||||
class PARAM_CFG_DOUBLE : public PARAM_CFG_BASE
|
||||
|
@ -138,12 +138,12 @@ public:
|
|||
double m_Min, m_Max; /* valeurs extremes du parametre */
|
||||
|
||||
public:
|
||||
PARAM_CFG_DOUBLE( const wxChar * ident, double* ptparam,
|
||||
PARAM_CFG_DOUBLE( const wxChar* ident, double* ptparam,
|
||||
double default_val = 0.0, double min = 0.0, double max = 10000.0,
|
||||
const wxChar * group = NULL );
|
||||
PARAM_CFG_DOUBLE( bool Insetup, const wxChar * ident, double* ptparam,
|
||||
const wxChar* group = NULL );
|
||||
PARAM_CFG_DOUBLE( bool Insetup, const wxChar* ident, double* ptparam,
|
||||
double default_val = 0.0, double min = 0.0, double max = 10000.0,
|
||||
const wxChar * group = NULL );
|
||||
const wxChar* group = NULL );
|
||||
};
|
||||
|
||||
class PARAM_CFG_BOOL : public PARAM_CFG_BASE
|
||||
|
@ -153,10 +153,10 @@ public:
|
|||
int m_Default; /* valeur par defaut */
|
||||
|
||||
public:
|
||||
PARAM_CFG_BOOL( const wxChar * ident, bool * ptparam,
|
||||
int default_val = FALSE, const wxChar * group = NULL );
|
||||
PARAM_CFG_BOOL( bool Insetup, const wxChar * ident, bool * ptparam,
|
||||
int default_val = FALSE, const wxChar * group = NULL );
|
||||
PARAM_CFG_BOOL( const wxChar* ident, bool* ptparam,
|
||||
int default_val = FALSE, const wxChar* group = NULL );
|
||||
PARAM_CFG_BOOL( bool Insetup, const wxChar* ident, bool* ptparam,
|
||||
int default_val = FALSE, const wxChar* group = NULL );
|
||||
};
|
||||
|
||||
|
||||
|
@ -166,11 +166,11 @@ public:
|
|||
wxString* m_Pt_param; /* pointeur sur le parametre a configurer */
|
||||
|
||||
public:
|
||||
PARAM_CFG_WXSTRING( const wxChar * ident, wxString * ptparam, const wxChar * group = NULL );
|
||||
PARAM_CFG_WXSTRING( bool Insetup,
|
||||
const wxChar * ident,
|
||||
wxString * ptparam,
|
||||
const wxChar * group = NULL );
|
||||
PARAM_CFG_WXSTRING( const wxChar* ident, wxString* ptparam, const wxChar* group = NULL );
|
||||
PARAM_CFG_WXSTRING( bool Insetup,
|
||||
const wxChar* ident,
|
||||
wxString* ptparam,
|
||||
const wxChar* group = NULL );
|
||||
};
|
||||
|
||||
class PARAM_CFG_LIBNAME_LIST : public PARAM_CFG_BASE
|
||||
|
@ -179,9 +179,9 @@ public:
|
|||
wxArrayString* m_Pt_param; /* pointeur sur le parametre a configurer */
|
||||
|
||||
public:
|
||||
PARAM_CFG_LIBNAME_LIST( const wxChar * ident,
|
||||
wxArrayString * ptparam,
|
||||
const wxChar * group = NULL );
|
||||
PARAM_CFG_LIBNAME_LIST( const wxChar* ident,
|
||||
wxArrayString* ptparam,
|
||||
const wxChar* group = NULL );
|
||||
};
|
||||
|
||||
|
||||
|
@ -195,7 +195,7 @@ private:
|
|||
wxListBox* m_List;
|
||||
|
||||
public:
|
||||
WinEDA_TextFrame( wxWindow * parent, const wxString &title );
|
||||
WinEDA_TextFrame( wxWindow* parent, const wxString& title );
|
||||
void Append( const wxString& text );
|
||||
|
||||
private:
|
||||
|
@ -221,24 +221,24 @@ public:
|
|||
int m_BottomMargin;
|
||||
|
||||
public:
|
||||
Ki_PageDescr( const wxSize &size, const wxPoint &offset, const wxString &name );
|
||||
Ki_PageDescr( const wxSize& size, const wxPoint& offset, const wxString& name );
|
||||
};
|
||||
|
||||
|
||||
/* Standard page sizes in 1/1000 inch */
|
||||
#if defined EDA_BASE
|
||||
Ki_PageDescr g_Sheet_A4( wxSize( 11700, 8267 ), wxPoint( 0, 0 ), wxT( "A4" ) );
|
||||
Ki_PageDescr g_Sheet_A3( wxSize( 16535, 11700 ), wxPoint( 0, 0 ), wxT( "A3" ) );
|
||||
Ki_PageDescr g_Sheet_A2( wxSize( 23400, 16535 ), wxPoint( 0, 0 ), wxT( "A2" ) );
|
||||
Ki_PageDescr g_Sheet_A1( wxSize( 33070, 23400 ), wxPoint( 0, 0 ), wxT( "A1" ) );
|
||||
Ki_PageDescr g_Sheet_A0( wxSize( 46800, 33070 ), wxPoint( 0, 0 ), wxT( "A0" ) );
|
||||
Ki_PageDescr g_Sheet_A( wxSize( 11000, 8500 ), wxPoint( 0, 0 ), wxT( "A" ) );
|
||||
Ki_PageDescr g_Sheet_B( wxSize( 17000, 11000 ), wxPoint( 0, 0 ), wxT( "B" ) );
|
||||
Ki_PageDescr g_Sheet_C( wxSize( 22000, 17000 ), wxPoint( 0, 0 ), wxT( "C" ) );
|
||||
Ki_PageDescr g_Sheet_D( wxSize( 34000, 22000 ), wxPoint( 0, 0 ), wxT( "D" ) );
|
||||
Ki_PageDescr g_Sheet_E( wxSize( 44000, 34000 ), wxPoint( 0, 0 ), wxT( "E" ) );
|
||||
Ki_PageDescr g_Sheet_GERBER( wxSize( 32000, 32000 ), wxPoint( 0, 0 ), wxT( "GERBER" ) );
|
||||
Ki_PageDescr g_Sheet_user( wxSize( 17000, 11000 ), wxPoint( 0, 0 ), wxT( "User" ) );
|
||||
Ki_PageDescr g_Sheet_A4( wxSize( 11700, 8267 ), wxPoint( 0, 0 ), wxT( "A4" ) );
|
||||
Ki_PageDescr g_Sheet_A3( wxSize( 16535, 11700 ), wxPoint( 0, 0 ), wxT( "A3" ) );
|
||||
Ki_PageDescr g_Sheet_A2( wxSize( 23400, 16535 ), wxPoint( 0, 0 ), wxT( "A2" ) );
|
||||
Ki_PageDescr g_Sheet_A1( wxSize( 33070, 23400 ), wxPoint( 0, 0 ), wxT( "A1" ) );
|
||||
Ki_PageDescr g_Sheet_A0( wxSize( 46800, 33070 ), wxPoint( 0, 0 ), wxT( "A0" ) );
|
||||
Ki_PageDescr g_Sheet_A( wxSize( 11000, 8500 ), wxPoint( 0, 0 ), wxT( "A" ) );
|
||||
Ki_PageDescr g_Sheet_B( wxSize( 17000, 11000 ), wxPoint( 0, 0 ), wxT( "B" ) );
|
||||
Ki_PageDescr g_Sheet_C( wxSize( 22000, 17000 ), wxPoint( 0, 0 ), wxT( "C" ) );
|
||||
Ki_PageDescr g_Sheet_D( wxSize( 34000, 22000 ), wxPoint( 0, 0 ), wxT( "D" ) );
|
||||
Ki_PageDescr g_Sheet_E( wxSize( 44000, 34000 ), wxPoint( 0, 0 ), wxT( "E" ) );
|
||||
Ki_PageDescr g_Sheet_GERBER( wxSize( 32000, 32000 ), wxPoint( 0, 0 ), wxT( "GERBER" ) );
|
||||
Ki_PageDescr g_Sheet_user( wxSize( 17000, 11000 ), wxPoint( 0, 0 ), wxT( "User" ) );
|
||||
|
||||
#else
|
||||
extern Ki_PageDescr g_Sheet_A4;
|
||||
|
@ -316,7 +316,7 @@ COMMON_GLOBL wxString g_EditorName;
|
|||
|
||||
// Gestion de la grille "utilisateur" (User Grid)
|
||||
#ifdef EDA_BASE
|
||||
wxRealPoint g_UserGrid( 0.01, 0.01 );
|
||||
wxRealPoint g_UserGrid( 0.01, 0.01 );
|
||||
|
||||
int g_UserGrid_Unit = INCHES;
|
||||
#else
|
||||
|
@ -364,7 +364,7 @@ class WinEDA_DrawPanel;
|
|||
* @param aPoint The point to output.
|
||||
* @return wxString& - the input string
|
||||
*/
|
||||
wxString& operator << ( wxString& aString, const wxPoint& aPoint );
|
||||
wxString& operator <<( wxString& aString, const wxPoint& aPoint );
|
||||
|
||||
|
||||
/**
|
||||
|
@ -374,10 +374,10 @@ wxString& operator << ( wxString& aString, const wxPoint& aPoint );
|
|||
* @param aFlags The same args as allowed for wxExecute()
|
||||
* @return bool - true if success, else false
|
||||
*/
|
||||
bool ProcessExecute( const wxString& aCommandLine, int aFlags = wxEXEC_ASYNC );
|
||||
bool ProcessExecute( const wxString& aCommandLine, int aFlags = wxEXEC_ASYNC );
|
||||
|
||||
|
||||
wxString ReturnPcbLayerName( int layer_number, bool is_filename = FALSE );
|
||||
wxString ReturnPcbLayerName( int layer_number, bool is_filename = FALSE );
|
||||
|
||||
/* Return the name of the layer number "layer_number".
|
||||
* if "is_filename" == TRUE, the name can be used for a file name
|
||||
|
@ -431,19 +431,19 @@ void OpenFile( const wxString& file );
|
|||
|
||||
|
||||
bool EDA_DirectorySelector( const wxString& Title, /* Titre de la fenetre */
|
||||
wxString& Path, /* Chemin par defaut */
|
||||
int flag, /* reserve */
|
||||
wxWindow* Frame, /* parent frame */
|
||||
const wxPoint& Pos );
|
||||
wxString& Path, /* Chemin par defaut */
|
||||
int flag, /* reserve */
|
||||
wxWindow* Frame, /* parent frame */
|
||||
const wxPoint& Pos );
|
||||
|
||||
wxString EDA_FileSelector( const wxString& Title, /* Window title */
|
||||
const wxString& Path, /* default path */
|
||||
const wxString& FileName, /* default filename */
|
||||
const wxString& Ext, /* default extension */
|
||||
const wxString& Mask, /* Display filename mask */
|
||||
wxWindow* Frame, /* parent frame */
|
||||
int flag, /* wxSAVE, wxOPEN ..*/
|
||||
const bool keep_working_directory, /* true = do not change the C.W.D. */
|
||||
wxString EDA_FileSelector( const wxString &Title, /* Window title */
|
||||
const wxString &Path, /* default path */
|
||||
const wxString &FileName, /* default filename */
|
||||
const wxString &Ext, /* default extension */
|
||||
const wxString &Mask, /* Display filename mask */
|
||||
wxWindow * Frame, /* parent frame */
|
||||
int flag, /* wxSAVE, wxOPEN ..*/
|
||||
const bool keep_working_directory, /* true = do not change the C.W.D. */
|
||||
const wxPoint& Pos = wxPoint( -1, -1 )
|
||||
);
|
||||
|
||||
|
@ -461,8 +461,8 @@ wxString MakeFileName( const wxString& dir,
|
|||
* retourne la chaine calculee */
|
||||
|
||||
wxString MakeReducedFileName( const wxString& fullfilename,
|
||||
const wxString& default_path,
|
||||
const wxString& default_ext );
|
||||
const wxString& default_path,
|
||||
const wxString& default_ext );
|
||||
|
||||
/* Calcule le nom "reduit" d'un file d'apres les chaines
|
||||
* fullfilename = nom complet
|
||||
|
@ -488,14 +488,14 @@ int ExecuteFile( wxWindow* frame, const wxString& ExecFile,
|
|||
const wxString& param = wxEmptyString );
|
||||
void AddDelimiterString( wxString& string );
|
||||
|
||||
void SetRealLibraryPath( const wxString& shortlibname );/* met a jour
|
||||
* le chemin des librairies RealLibDirBuffer (global)
|
||||
* a partir de UserLibDirBuffer (global):
|
||||
* Si UserLibDirBuffer non vide RealLibDirBuffer = UserLibDirBuffer.
|
||||
* Sinon si variable d'environnement KICAD definie (KICAD = chemin pour kicad),
|
||||
* UserLibDirBuffer = <KICAD>/shortlibname;
|
||||
* Sinon UserLibDirBuffer = <Chemin des binaires>../shortlibname/
|
||||
*/
|
||||
void SetRealLibraryPath( const wxString& shortlibname ); /* met a jour
|
||||
* le chemin des librairies RealLibDirBuffer (global)
|
||||
* a partir de UserLibDirBuffer (global):
|
||||
* Si UserLibDirBuffer non vide RealLibDirBuffer = UserLibDirBuffer.
|
||||
* Sinon si variable d'environnement KICAD definie (KICAD = chemin pour kicad),
|
||||
* UserLibDirBuffer = <KICAD>/shortlibname;
|
||||
* Sinon UserLibDirBuffer = <Chemin des binaires>../shortlibname/
|
||||
*/
|
||||
wxString FindKicadHelpPath();
|
||||
|
||||
/* Find absolute path for kicad/help (or kicad/help/<language>) */
|
||||
|
@ -564,26 +564,28 @@ bool WildCompareString( const wxString& pattern, const wxString& string_t
|
|||
bool case_sensitive = TRUE );
|
||||
|
||||
/* compare 2 noms de composants, selon regles usuelles
|
||||
* ( Jokers * , ? , autoris<EFBFBD>s).
|
||||
* ( Jokers * , ? , autorises).
|
||||
* la chaine de reference est "pattern"
|
||||
* si case_sensitive == TRUE (default), comparaison exacte
|
||||
* retourne TRUE si match FALSE si differences */
|
||||
|
||||
char* to_point( char* Text );
|
||||
|
||||
/* convertit les , en . dans une chaine. utilis<EFBFBD> pour compenser la fct printf
|
||||
/* convertit les , en . dans une chaine. utilise pour compenser la fct printf
|
||||
* qui genere les flottants avec une virgule au lieu du point en mode international */
|
||||
|
||||
/****************/
|
||||
/* infospgm.cpp */
|
||||
/****************/
|
||||
extern wxString g_KicadAboutTitle;
|
||||
extern wxString g_CvpcbAboutTitle;
|
||||
extern wxString g_EeschemaAboutTitle;
|
||||
extern wxString g_PcbnewAboutTitle;
|
||||
extern wxString g_GerbviewAboutTitle;
|
||||
extern wxString g_KicadAboutTitle;
|
||||
extern wxString g_CvpcbAboutTitle;
|
||||
extern wxString g_EeschemaAboutTitle;
|
||||
extern wxString g_PcbnewAboutTitle;
|
||||
extern wxString g_GerbviewAboutTitle;
|
||||
|
||||
void Print_Kicad_Infos( wxWindow* frame, const wxString& title );
|
||||
void Print_Kicad_Infos( wxWindow* frame,
|
||||
const wxString& title,
|
||||
const wxString& aExtra_infos );
|
||||
|
||||
/**************/
|
||||
/* common.cpp */
|
||||
|
@ -591,10 +593,10 @@ void Print_Kicad_Infos( wxWindow* frame, const wxString& title );
|
|||
wxString GetBuildVersion(); /* Return the build date */
|
||||
|
||||
void Affiche_1_Parametre( WinEDA_DrawFrame* frame,
|
||||
int pos_X,
|
||||
const wxString& texte_H,
|
||||
const wxString& texte_L,
|
||||
int color );
|
||||
int pos_X,
|
||||
const wxString& texte_H,
|
||||
const wxString& texte_L,
|
||||
int color );
|
||||
|
||||
/*
|
||||
* Routine d'affichage d'un parametre.
|
||||
|
@ -608,16 +610,16 @@ void Affiche_1_Parametre( WinEDA_DrawFrame* frame,
|
|||
* color = couleur d'affichage
|
||||
*/
|
||||
|
||||
void AfficheDoc( WinEDA_DrawFrame* frame, const wxString& Doc, const wxString& KeyW );
|
||||
void AfficheDoc( WinEDA_DrawFrame* frame, const wxString& Doc, const wxString& KeyW );
|
||||
|
||||
/* Routine d'affichage de la documentation associee a un composant */
|
||||
|
||||
int GetTimeStamp();
|
||||
int GetTimeStamp();
|
||||
|
||||
/* Retoure une identification temporelle (Time stamp) differente a chaque appel */
|
||||
int DisplayColorFrame( wxWindow* parent, int OldColor );
|
||||
int GetCommandOptions( const int argc, const char** argv, const char* stringtst,
|
||||
const char** optarg, int* optind );
|
||||
int DisplayColorFrame( wxWindow* parent, int OldColor );
|
||||
int GetCommandOptions( const int argc, const char** argv, const char* stringtst,
|
||||
const char** optarg, int* optind );
|
||||
|
||||
|
||||
const wxString& valeur_param( int valeur, wxString& buf_texte );
|
||||
|
@ -628,28 +630,28 @@ const wxString& valeur_param( int valeur, wxString& buf_texte );
|
|||
* suivie de " ou mm
|
||||
*/
|
||||
|
||||
wxString ReturnUnitSymbol( int Units = g_UnitMetric );
|
||||
int ReturnValueFromString( int Units, const wxString& TextValue, int Internal_Unit );
|
||||
wxString ReturnStringFromValue( int Units, int Value, int Internal_Unit );
|
||||
void AddUnitSymbol( wxStaticText& Stext, int Units = g_UnitMetric );
|
||||
wxString ReturnUnitSymbol( int Units = g_UnitMetric );
|
||||
int ReturnValueFromString( int Units, const wxString& TextValue, int Internal_Unit );
|
||||
wxString ReturnStringFromValue( int Units, int Value, int Internal_Unit );
|
||||
void AddUnitSymbol( wxStaticText& Stext, int Units = g_UnitMetric );
|
||||
|
||||
/* Add string " (mm):" or " ("):" to the static text Stext.
|
||||
* Used in dialog boxes for entering values depending on selected units */
|
||||
void PutValueInLocalUnits( wxTextCtrl& TextCtr, int Value, int Internal_Unit );
|
||||
void PutValueInLocalUnits( wxTextCtrl& TextCtr, int Value, int Internal_Unit );
|
||||
|
||||
/* Convert the number Value in a string according to the internal units
|
||||
* and the selected unit (g_UnitMetric) and put it in the wxTextCtrl TextCtrl */
|
||||
int ReturnValueFromTextCtrl( const wxTextCtrl& TextCtr, int Internal_Unit );
|
||||
int ReturnValueFromTextCtrl( const wxTextCtrl& TextCtr, int Internal_Unit );
|
||||
|
||||
/* Convert the Value in the wxTextCtrl TextCtrl in an integer,
|
||||
* according to the internal units and the selected unit (g_UnitMetric) */
|
||||
|
||||
double To_User_Unit( bool is_metric, int val, int internal_unit_value );
|
||||
int From_User_Unit( bool is_metric, double val, int internal_unit_value );
|
||||
wxString GenDate();
|
||||
void MyFree( void* pt_mem );
|
||||
void* MyZMalloc( size_t nb_octets );
|
||||
void* MyMalloc( size_t nb_octets );
|
||||
double To_User_Unit( bool is_metric, int val, int internal_unit_value );
|
||||
int From_User_Unit( bool is_metric, double val, int internal_unit_value );
|
||||
wxString GenDate();
|
||||
void MyFree( void* pt_mem );
|
||||
void* MyZMalloc( size_t nb_octets );
|
||||
void* MyMalloc( size_t nb_octets );
|
||||
|
||||
|
||||
/****************/
|
||||
|
@ -671,9 +673,9 @@ bool GetAssociatedDocument( wxFrame* frame, const wxString& LibPath,
|
|||
/****************************/
|
||||
/* get_component_dialog.cpp */
|
||||
/****************************/
|
||||
wxString GetComponentName( WinEDA_DrawFrame* frame,
|
||||
wxArrayString& HistoryList, const wxString& Title,
|
||||
wxString (* AuxTool)(WinEDA_DrawFrame* parent) );
|
||||
wxString GetComponentName( WinEDA_DrawFrame * frame,
|
||||
wxArrayString & HistoryList, const wxString &Title,
|
||||
wxString (*AuxTool)( WinEDA_DrawFrame * parent ) );
|
||||
|
||||
/* Dialog frame to choose a component name */
|
||||
void AddHistoryComponentName( wxArrayString& HistoryList, const wxString& Name );
|
||||
|
|
|
@ -329,6 +329,8 @@ public:
|
|||
|
||||
~WinEDA_PcbFrame();
|
||||
|
||||
void GetKicadAbout( wxCommandEvent& event );
|
||||
|
||||
// Configurations:
|
||||
void InstallConfigFrame( const wxPoint& pos );
|
||||
void Process_Config( wxCommandEvent& event );
|
||||
|
|
Binary file not shown.
3743
internat/fr/kicad.po
3743
internat/fr/kicad.po
File diff suppressed because it is too large
Load Diff
|
@ -27,6 +27,24 @@
|
|||
// UnComment this to load subdirs files in the tree project
|
||||
#define ADD_FILES_IN_SUBDIRS
|
||||
|
||||
// list of files extensions listed in the tree project window
|
||||
// *.sch files are always allowed, do not add here
|
||||
// Add extensions in a compatible regex format to see others files types
|
||||
const wxChar * s_AllowedExtensionsToList[] =
|
||||
{
|
||||
wxT( "^.*\\.pro$" ),
|
||||
wxT( "^.*\\.pdf$" ),
|
||||
wxT( "^[^$].*\\.brd$" ),
|
||||
wxT( "^.*\\.net$" ),
|
||||
wxT( "^.*\\.txt$" ),
|
||||
wxT( "^.*\\.pho$" ),
|
||||
wxT( "^.*\\.odt$" ),
|
||||
wxT( "^.*\\.sxw$" ),
|
||||
wxT( "^.*\\.htm$" ),
|
||||
wxT( "^.*\\.html$" ),
|
||||
NULL // end of list
|
||||
};
|
||||
|
||||
/******************************************************************/
|
||||
WinEDA_PrjFrame::WinEDA_PrjFrame( WinEDA_MainFrame* parent,
|
||||
const wxPoint& pos,
|
||||
|
@ -44,12 +62,10 @@ WinEDA_PrjFrame::WinEDA_PrjFrame( WinEDA_MainFrame* parent,
|
|||
* for a given file type.
|
||||
*/
|
||||
m_Filters.push_back( wxT( "^.*\\.sch$" ) ); // note: sch filter must be first because of a test in AddFile() below
|
||||
m_Filters.push_back( wxT( "^.*\\.pro$" ) );
|
||||
m_Filters.push_back( wxT( "^.*\\.pdf$" ) );
|
||||
m_Filters.push_back( wxT( "^[^$].*\\.brd$" ) );
|
||||
m_Filters.push_back( wxT( "^.*\\.net$" ) );
|
||||
m_Filters.push_back( wxT( "^.*\\.txt$" ) );
|
||||
m_Filters.push_back( wxT( "^.*\\.pho$" ) );
|
||||
for ( int ii = 0; s_AllowedExtensionsToList[ii] != NULL; ii++ )
|
||||
{
|
||||
m_Filters.push_back( s_AllowedExtensionsToList[ii] );
|
||||
}
|
||||
m_Filters.push_back( wxT( "^no kicad files found" ) );
|
||||
|
||||
#ifdef KICAD_PYTHON
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
KICAD_SUBDIRS = common bitmaps 3d-viewer polygon eeschema eeschema/plugins pcbnew kicad cvpcb gerbview
|
||||
KICAD_SUBDIRS = common bitmaps 3d-viewer polygon polygon/kbool/src eeschema eeschema/plugins pcbnew kicad cvpcb gerbview
|
||||
KICAD_SUBDIRS_BIN = eeschema eeschema/plugins pcbnew cvpcb kicad gerbview
|
||||
# How to invoke make:
|
||||
MAKE = make -k -f makefile.g95
|
||||
|
|
|
@ -163,7 +163,7 @@ endif(APPLE)
|
|||
|
||||
add_executable(pcbnew WIN32 MACOSX_BUNDLE ${PCBNEW_SRCS} ${PCBNEW_EXTRA_SRCS} ${PCBNEW_RESOURCES})
|
||||
|
||||
target_link_libraries(pcbnew 3d-viewer common polygon bitmaps ${wxWidgets_LIBRARIES} ${OPENGL_LIBRARIES} )
|
||||
target_link_libraries(pcbnew 3d-viewer common polygon kbool bitmaps ${wxWidgets_LIBRARIES} ${OPENGL_LIBRARIES} )
|
||||
|
||||
install(TARGETS pcbnew RUNTIME DESTINATION ${KICAD_BIN}
|
||||
COMPONENT binary)
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
|
||||
EXTRALIBS = ../common/common.a ../bitmaps/libbitmaps.a ../polygon/lib_polygon.a
|
||||
EXTRALIBS = ../common/common.a ../bitmaps/libbitmaps.a\
|
||||
../polygon/lib_polygon.a\
|
||||
../polygon/kbool/src/libkbool.a
|
||||
|
||||
EXTRACPPFLAGS += -DPCBNEW -fno-strict-aliasing -I./ -Ibitmaps -I../include -I../share\
|
||||
-I../pcbnew -I../3d-viewer -I../polygon
|
||||
|
||||
|
|
|
@ -478,7 +478,7 @@ void WinEDA_PcbFrame::createPopupMenuForTracks( TRACK* Track, wxMenu* PopMenu )
|
|||
wxMenu* via_mnu = new wxMenu();
|
||||
|
||||
ADD_MENUITEM_WITH_SUBMENU( PopMenu, via_mnu,
|
||||
ID_POPUP_PCB_VIA_EDITING, _( "Edit Via" ), edit_xpm );
|
||||
ID_POPUP_PCB_VIA_EDITING, _( "Edit Via Drill" ), edit_xpm );
|
||||
ADD_MENUITEM( via_mnu, ID_POPUP_PCB_VIA_HOLE_TO_DEFAULT,
|
||||
_( "Set via hole to Default" ), apply_xpm );
|
||||
msg = _( "Set via hole to a specific value. This specfic value is currently" );
|
||||
|
@ -486,7 +486,7 @@ void WinEDA_PcbFrame::createPopupMenuForTracks( TRACK* Track, wxMenu* PopMenu )
|
|||
ADD_MENUITEM_WITH_HELP( via_mnu, ID_POPUP_PCB_VIA_HOLE_TO_VALUE,
|
||||
_( "Set via hole to alt value" ), msg,
|
||||
options_new_pad_xpm );
|
||||
msg = _( "Set alt via hole value. This value is currently" );
|
||||
msg = _( "Set a specific via hole value. This value is currently" );
|
||||
msg << wxT(" ") << ReturnStringFromValue( g_UnitMetric, g_DesignSettings.m_ViaDrillCustomValue, m_InternalUnits );
|
||||
ADD_MENUITEM_WITH_HELP( via_mnu, ID_POPUP_PCB_VIA_HOLE_ENTER_VALUE,
|
||||
_( "Set the via hole alt value" ), msg, edit_xpm );
|
||||
|
@ -559,18 +559,18 @@ void WinEDA_PcbFrame::createPopupMenuForTracks( TRACK* Track, wxMenu* PopMenu )
|
|||
ADD_MENUITEM_WITH_SUBMENU( PopMenu, track_mnu,
|
||||
ID_POPUP_PCB_EDIT_TRACK_MNU, _( "Change Width" ), width_track_xpm );
|
||||
ADD_MENUITEM( track_mnu, ID_POPUP_PCB_EDIT_TRACKSEG,
|
||||
Track->Type()==TYPEVIA ? _( "Edit Via" ) : _( "Edit Segment" ), width_segment_xpm );
|
||||
Track->Type()==TYPEVIA ? _( "Change Via Size" ) : _( "Change Segment Width" ), width_segment_xpm );
|
||||
|
||||
ADD_MENUITEM( track_mnu, ID_POPUP_PCB_EDIT_TRACK,
|
||||
_( "Edit Track" ), width_track_xpm );
|
||||
_( "Change Track Width" ), width_track_xpm );
|
||||
ADD_MENUITEM( track_mnu, ID_POPUP_PCB_EDIT_NET,
|
||||
_( "Edit Net" ), width_net_xpm );
|
||||
_( "Change Net" ), width_net_xpm );
|
||||
ADD_MENUITEM( track_mnu, ID_POPUP_PCB_EDIT_ALL_VIAS_AND_TRACK_SIZE,
|
||||
_( "Edit ALL Tracks and Vias" ), width_track_via_xpm );
|
||||
_( "Change ALL Tracks and Vias" ), width_track_via_xpm );
|
||||
ADD_MENUITEM( track_mnu, ID_POPUP_PCB_EDIT_ALL_VIAS_SIZE,
|
||||
_( "Edit ALL Vias (no track)" ), width_vias_xpm );
|
||||
_( "Change ALL Vias (no track)" ), width_vias_xpm );
|
||||
ADD_MENUITEM( track_mnu, ID_POPUP_PCB_EDIT_ALL_TRACK_SIZE,
|
||||
_( "Edit ALL Tracks (no via)" ), width_track_xpm );
|
||||
_( "Change ALL Tracks (no via)" ), width_track_xpm );
|
||||
}
|
||||
|
||||
// Delete control:
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include "protos.h"
|
||||
#include "id.h"
|
||||
#include "drc_stuff.h"
|
||||
|
||||
#include "kbool/include/booleng.h"
|
||||
|
||||
/*******************************/
|
||||
/* class WinEDA_PcbFrame */
|
||||
|
@ -99,7 +99,7 @@ BEGIN_EVENT_TABLE( WinEDA_PcbFrame, WinEDA_BasePcbFrame )
|
|||
|
||||
// Menu Help
|
||||
EVT_MENU( ID_GENERAL_HELP, WinEDA_DrawFrame::GetKicadHelp )
|
||||
EVT_MENU( ID_KICAD_ABOUT, WinEDA_DrawFrame::GetKicadAbout )
|
||||
EVT_MENU( ID_KICAD_ABOUT, WinEDA_PcbFrame::GetKicadAbout )
|
||||
|
||||
// Menu 3D Frame
|
||||
EVT_MENU( ID_MENU_PCB_SHOW_3D_FRAME, WinEDA_PcbFrame::Show3D_Frame )
|
||||
|
@ -245,8 +245,9 @@ WinEDA_PcbFrame::WinEDA_PcbFrame( wxWindow* father, WinEDA_App* parent,
|
|||
ReCreateOptToolbar();
|
||||
}
|
||||
|
||||
|
||||
/************************************/
|
||||
WinEDA_PcbFrame::~WinEDA_PcbFrame()
|
||||
/************************************/
|
||||
{
|
||||
m_Parent->m_PcbFrame = NULL;
|
||||
SetBaseScreen( ScreenPcb );
|
||||
|
@ -566,3 +567,15 @@ void WinEDA_PcbFrame::SetToolbars()
|
|||
DisplayUnitsMsg();
|
||||
}
|
||||
|
||||
/***********************************************************/
|
||||
void WinEDA_PcbFrame::GetKicadAbout( wxCommandEvent& event )
|
||||
/**********************************************************/
|
||||
{
|
||||
wxString extra_message =
|
||||
wxT("\nPcbnew uses the kbool library (boolean operations on sets of 2d polygons)\n");
|
||||
extra_message << wxT("version ") << wxT(KBOOL_VERSION)
|
||||
<< wxT("\nsee http://boolean.klaasholwerda.nl/bool.html\n");
|
||||
|
||||
Print_Kicad_Infos( this, m_AboutTitle, extra_message );
|
||||
}
|
||||
|
||||
|
|
|
@ -291,7 +291,7 @@ int BOARD::ClipAreaPolygon( ZONE_CONTAINER* CurrArea,
|
|||
NewArea = AddArea( CurrArea->GetNet(), CurrArea->GetLayer(), 0, 0, 0 );
|
||||
|
||||
// remove the poly that was automatically created for the new area
|
||||
// and replace it with a poly from NormalizeWithGpc
|
||||
// and replace it with a poly from NormalizeWithKbool
|
||||
delete NewArea->m_Poly;
|
||||
NewArea->m_Poly = new_p;
|
||||
NewArea->m_Poly->Draw();
|
||||
|
@ -694,183 +694,109 @@ int BOARD::CombineAreas( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_to_combi
|
|||
#endif
|
||||
|
||||
// polygons intersect, combine them
|
||||
CPolyLine* poly1 = area_ref->m_Poly;
|
||||
CPolyLine* poly2 = area_to_combine->m_Poly;
|
||||
std::vector<CArc> arc_array1;
|
||||
std::vector<CArc> arc_array2;
|
||||
bool keep_area_to_combine = false;
|
||||
|
||||
poly1->MakePolygonFromAreaOutlines( -1, &arc_array1 );
|
||||
poly2->MakePolygonFromAreaOutlines( -1, &arc_array2 );
|
||||
Bool_Engine* booleng = new Bool_Engine();
|
||||
ArmBoolEng( booleng );
|
||||
|
||||
#ifdef USE_GPC_POLY_LIB
|
||||
int n_ext_cont1 = 0;
|
||||
for( int ic = 0; ic<poly1->GetGpcPoly()->num_contours; ic++ )
|
||||
if( !( (poly1->GetGpcPoly()->hole)[ic] ) )
|
||||
n_ext_cont1++;
|
||||
area_ref->m_Poly->AddPolygonsToBoolEng( booleng, GROUP_A, -1, -1 );
|
||||
area_to_combine->m_Poly->AddPolygonsToBoolEng( booleng, GROUP_B, -1, -1 );
|
||||
booleng->Do_Operation( BOOL_OR );
|
||||
|
||||
int n_ext_cont2 = 0;
|
||||
for( int ic = 0; ic<poly2->GetGpcPoly()->num_contours; ic++ )
|
||||
if( !( (poly2->GetGpcPoly()->hole)[ic] ) )
|
||||
n_ext_cont2++;
|
||||
|
||||
gpc_polygon* union_gpc = new gpc_polygon;
|
||||
gpc_polygon_clip( GPC_UNION, poly1->GetGpcPoly(), poly2->GetGpcPoly(), union_gpc );
|
||||
|
||||
// get number of outside contours
|
||||
int n_union_ext_cont = 0;
|
||||
for( int ic = 0; ic<union_gpc->num_contours; ic++ )
|
||||
if( !( (union_gpc->hole)[ic] ) )
|
||||
n_union_ext_cont++;
|
||||
|
||||
// if no intersection, free new gpc and return
|
||||
if( n_union_ext_cont == n_ext_cont1 + n_ext_cont2 )
|
||||
// create area with external contour: Recreate only area edges, NOT holes
|
||||
if( booleng->StartPolygonGet() )
|
||||
{
|
||||
gpc_free_polygon( union_gpc );
|
||||
delete union_gpc;
|
||||
return 0;
|
||||
if( booleng->GetPolygonPointEdgeType() == KB_INSIDE_EDGE )
|
||||
{
|
||||
DisplayError( NULL, wxT( "BOARD::CombineAreas() error: unexpected hole descriptor" ) );
|
||||
}
|
||||
|
||||
area_ref->m_Poly->RemoveAllContours();
|
||||
|
||||
// foreach point in the polygon
|
||||
bool first = true;
|
||||
while( booleng->PolygonHasMorePoints() )
|
||||
{
|
||||
int x = booleng->GetPolygonXPoint();
|
||||
int y = booleng->GetPolygonYPoint();
|
||||
if( first )
|
||||
{
|
||||
first = false;
|
||||
area_ref->m_Poly->Start( area_ref->GetLayer(
|
||||
), x, y, area_ref->m_Poly->GetHatchStyle() );
|
||||
}
|
||||
else
|
||||
area_ref->m_Poly->AppendCorner( x, y );
|
||||
}
|
||||
|
||||
booleng->EndPolygonGet();
|
||||
area_ref->m_Poly->Close();
|
||||
}
|
||||
|
||||
// intersection, replace area_ref->m_Poly with combined areas and remove area_to_combine
|
||||
RemoveArea( area_to_combine );
|
||||
area_ref->m_Poly->RemoveAllContours();
|
||||
|
||||
// create area with external contour
|
||||
for( int ic = 0; ic<union_gpc->num_contours; ic++ )
|
||||
// Recreate the area_to_combine if a second polygon exists
|
||||
// if not exists , the first poly contains the 2 initial polygons
|
||||
#if 0 // TestAreaIntersection must be called before combine areas, so
|
||||
// 2 intersecting areas are expected, and only one outline contour after combining areas
|
||||
else
|
||||
{
|
||||
if( !(union_gpc->hole)[ic] )
|
||||
area_to_combine->m_Poly->RemoveAllContours();
|
||||
keep_area_to_combine = true;
|
||||
|
||||
// create area with external contour: Recreate only area edges, NOT holes (todo..)
|
||||
{
|
||||
// external contour, replace this poly
|
||||
for( int i = 0; i<union_gpc->contour[ic].num_vertices; i++ )
|
||||
// foreach point in the polygon
|
||||
bool first = true;
|
||||
while( booleng->PolygonHasMorePoints() )
|
||||
{
|
||||
int x = (int) ( (union_gpc->contour)[ic].vertex )[i].x;
|
||||
int y = (int) ( (union_gpc->contour)[ic].vertex )[i].y;
|
||||
if( i==0 )
|
||||
int x = booleng->GetPolygonXPoint();
|
||||
int y = booleng->GetPolygonYPoint();
|
||||
if( first )
|
||||
{
|
||||
area_ref->m_Poly->Start( area_ref->GetLayer(
|
||||
), x, y, area_ref->m_Poly->GetHatchStyle() );
|
||||
first = false;
|
||||
area_to_combine->m_Poly->Start( area_ref->GetLayer(
|
||||
), x, y, area_ref->m_Poly->GetHatchStyle() );
|
||||
}
|
||||
else
|
||||
area_ref->m_Poly->AppendCorner( x, y );
|
||||
area_to_combine->m_Poly->AppendCorner( x, y );
|
||||
}
|
||||
|
||||
area_ref->m_Poly->Close();
|
||||
booleng->EndPolygonGet();
|
||||
area_to_combine->m_Poly->Close();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// add holes
|
||||
for( int ic = 0; ic<union_gpc->num_contours; ic++ )
|
||||
while( booleng->StartPolygonGet() )
|
||||
{
|
||||
if( (union_gpc->hole)[ic] )
|
||||
if( booleng->GetPolygonPointEdgeType() != KB_INSIDE_EDGE )
|
||||
{
|
||||
// hole
|
||||
for( int i = 0; i<union_gpc->contour[ic].num_vertices; i++ )
|
||||
{
|
||||
int x = (int) ( (union_gpc->contour)[ic].vertex )[i].x;
|
||||
int y = (int) ( (union_gpc->contour)[ic].vertex )[i].y;
|
||||
area_ref->m_Poly->AppendCorner( x, y );
|
||||
}
|
||||
|
||||
area_ref->m_Poly->Close();
|
||||
DisplayError( NULL,
|
||||
wxT( "BOARD::CombineAreas() error: unexpected outside contour descriptor" ) );
|
||||
continue;
|
||||
}
|
||||
while( booleng->PolygonHasMorePoints() )
|
||||
{
|
||||
int x = booleng->GetPolygonXPoint();
|
||||
int y = booleng->GetPolygonYPoint();
|
||||
area_ref->m_Poly->AppendCorner( x, y );
|
||||
}
|
||||
|
||||
area_ref->m_Poly->Close();
|
||||
booleng->EndPolygonGet();
|
||||
}
|
||||
|
||||
if( !keep_area_to_combine )
|
||||
RemoveArea( area_to_combine );
|
||||
|
||||
area_ref->utility = 1;
|
||||
area_ref->m_Poly->RestoreArcs( &arc_array1 );
|
||||
area_ref->m_Poly->RestoreArcs( &arc_array2 );
|
||||
area_ref->m_Poly->Draw();
|
||||
gpc_free_polygon( union_gpc );
|
||||
delete union_gpc;
|
||||
|
||||
delete booleng;
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
#ifdef USE_GPL_POLY_LIB
|
||||
//@todo
|
||||
#warning work in progress
|
||||
wxString msg;
|
||||
int n_ext_cont1 = poly1->GetPhpPoly()->m_cnt;
|
||||
|
||||
int n_ext_cont2 = poly2->GetPhpPoly()->m_cnt;
|
||||
|
||||
polygon* union_polygon = NULL;
|
||||
union_polygon = poly1->GetPhpPoly()->boolean( poly2->GetPhpPoly(), A_OR_B );
|
||||
|
||||
if ( union_polygon == NULL )
|
||||
return 0;
|
||||
// get number of outside contours
|
||||
int n_union_ext_cont = union_polygon->m_cnt;
|
||||
msg.Printf(wxT("cnt res = %d, pts1,2 = %d,%d"), n_union_ext_cont , n_ext_cont1, n_ext_cont2);
|
||||
wxMessageBox(msg);
|
||||
|
||||
// if no intersection, free new gpc and return
|
||||
#if 0
|
||||
if( n_union_ext_cont == n_ext_cont1 + n_ext_cont2 )
|
||||
{
|
||||
wxMessageBox(wxT("no change polys"));
|
||||
delete union_polygon;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
wxMessageBox(wxT("merge areas"));
|
||||
// intersection, replace area_ref->m_Poly with combined areas and remove area_to_combine
|
||||
RemoveArea( area_to_combine );
|
||||
area_ref->m_Poly->RemoveAllContours();
|
||||
// create area with external contour
|
||||
// for( int ic = 0; ic < union_polygon->m_cnt; ic++ )
|
||||
{
|
||||
// if( !(union_gpc->hole)[ic] ) // Recreate only area edges, NOT holes (todo..)
|
||||
{
|
||||
// external contour, replace this poly
|
||||
vertex * curr_vertex = union_polygon->getFirst();
|
||||
for( int ii = 0; ii < union_polygon->m_cnt; ii++ )
|
||||
{
|
||||
int x = (int) curr_vertex->X();
|
||||
int y = (int) curr_vertex->Y();
|
||||
msg.Printf(wxT("ii = %d, pts = %d,%d, wid = %d"), ii , x, y, curr_vertex->id());
|
||||
wxMessageBox(msg);
|
||||
|
||||
if( ii==0 )
|
||||
{
|
||||
area_ref->m_Poly->Start( area_ref->GetLayer(
|
||||
), x, y, area_ref->m_Poly->GetHatchStyle() );
|
||||
}
|
||||
else
|
||||
area_ref->m_Poly->AppendCorner( x, y );
|
||||
|
||||
curr_vertex = curr_vertex->Next();
|
||||
// if( curr_vertex->id() == union_polygon->getFirst()->id() ) break;
|
||||
}
|
||||
area_ref->m_Poly->Close();
|
||||
}
|
||||
}
|
||||
|
||||
// add holes
|
||||
#if 0
|
||||
for( int ic = 0; ic<union_gpc->num_contours; ic++ )
|
||||
{
|
||||
if( (union_gpc->hole)[ic] )
|
||||
{
|
||||
// hole
|
||||
for( int i = 0; i<union_gpc->contour[ic].num_vertices; i++ )
|
||||
{
|
||||
int x = (int) ( (union_gpc->contour)[ic].vertex )[i].x;
|
||||
int y = (int) ( (union_gpc->contour)[ic].vertex )[i].y;
|
||||
area_ref->m_Poly->AppendCorner( x, y );
|
||||
}
|
||||
|
||||
area_ref->m_Poly->Close();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
area_ref->utility = 1;
|
||||
area_ref->m_Poly->RestoreArcs( &arc_array1 );
|
||||
area_ref->m_Poly->RestoreArcs( &arc_array2 );
|
||||
area_ref->m_Poly->Draw();
|
||||
delete union_polygon;
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -1098,31 +1024,32 @@ int BOARD::Test_Drc_Areas_Outlines_To_Areas_Outlines( ZONE_CONTAINER* aArea_To_E
|
|||
* @return bool - false if DRC error or true if OK
|
||||
*/
|
||||
|
||||
bool DRC::doEdgeZoneDrc( ZONE_CONTAINER * aArea, int aCornerIndex )
|
||||
bool DRC::doEdgeZoneDrc( ZONE_CONTAINER* aArea, int aCornerIndex )
|
||||
{
|
||||
wxString str;
|
||||
|
||||
wxPoint start = aArea->GetCornerPosition(aCornerIndex);
|
||||
wxPoint end;
|
||||
// Search the end point of the edge starting at aCornerIndex
|
||||
if( aArea->m_Poly->corner[aCornerIndex].end_contour == FALSE &&
|
||||
aCornerIndex < (aArea->GetNumCorners() - 1) )
|
||||
{
|
||||
end = aArea->GetCornerPosition(aCornerIndex+1);
|
||||
}
|
||||
else // aCornerIndex is the last corner of an outline.
|
||||
// the corresponding end point of the segment is the first corner of the outline
|
||||
{
|
||||
int ii = aCornerIndex-1;
|
||||
end = aArea->GetCornerPosition(ii);
|
||||
while ( ii >= 0 )
|
||||
{
|
||||
if ( aArea->m_Poly->corner[ii].end_contour )
|
||||
break;
|
||||
end = aArea->GetCornerPosition(ii);
|
||||
ii--;
|
||||
}
|
||||
}
|
||||
wxPoint start = aArea->GetCornerPosition( aCornerIndex );
|
||||
wxPoint end;
|
||||
|
||||
// Search the end point of the edge starting at aCornerIndex
|
||||
if( aArea->m_Poly->corner[aCornerIndex].end_contour == FALSE
|
||||
&& aCornerIndex < (aArea->GetNumCorners() - 1) )
|
||||
{
|
||||
end = aArea->GetCornerPosition( aCornerIndex + 1 );
|
||||
}
|
||||
else // aCornerIndex is the last corner of an outline.
|
||||
// the corresponding end point of the segment is the first corner of the outline
|
||||
{
|
||||
int ii = aCornerIndex - 1;
|
||||
end = aArea->GetCornerPosition( ii );
|
||||
while( ii >= 0 )
|
||||
{
|
||||
if( aArea->m_Poly->corner[ii].end_contour )
|
||||
break;
|
||||
end = aArea->GetCornerPosition( ii );
|
||||
ii--;
|
||||
}
|
||||
}
|
||||
|
||||
// iterate through all areas
|
||||
for( int ia2 = 0; ia2 < m_pcb->GetAreaCount(); ia2++ )
|
||||
|
@ -1134,7 +1061,7 @@ bool DRC::doEdgeZoneDrc( ZONE_CONTAINER * aArea, int aCornerIndex )
|
|||
continue;
|
||||
|
||||
// Test for same net
|
||||
if( (aArea->GetNet() == Area_To_Test->GetNet()) && (aArea->GetNet() > 0) )
|
||||
if( ( aArea->GetNet() == Area_To_Test->GetNet() ) && (aArea->GetNet() > 0) )
|
||||
continue;
|
||||
|
||||
// test for ending line inside Area_To_Test
|
||||
|
@ -1188,11 +1115,11 @@ bool DRC::doEdgeZoneDrc( ZONE_CONTAINER * aArea, int aCornerIndex )
|
|||
m_currentMarker = fillMarker( aArea, wxPoint( x, y ),
|
||||
COPPERAREA_CLOSE_TO_COPPERAREA,
|
||||
m_currentMarker );
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
set(POLYGON_SRCS
|
||||
GenericPolygonClipperLibrary.cpp
|
||||
math_for_graphics.cpp
|
||||
php_polygon.cpp
|
||||
php_polygon_vertex.cpp
|
||||
PolyLine.cpp)
|
||||
|
||||
add_library(polygon ${POLYGON_SRCS})
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,133 +0,0 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Project: Generic Polygon Clipper
|
||||
|
||||
A new algorithm for calculating the difference, intersection,
|
||||
exclusive-or or union of arbitrary polygon sets.
|
||||
|
||||
File: gpc.h
|
||||
Author: Alan Murta (email: gpc@cs.man.ac.uk)
|
||||
Version: 2.32
|
||||
Date: 17th December 2004
|
||||
|
||||
Copyright: (C) Advanced Interfaces Group,
|
||||
University of Manchester.
|
||||
|
||||
This software is free for non-commercial use. It may be copied,
|
||||
modified, and redistributed provided that this copyright notice
|
||||
is preserved on all copies. The intellectual property rights of
|
||||
the algorithms used reside with the University of Manchester
|
||||
Advanced Interfaces Group.
|
||||
|
||||
You may not use this software, in whole or in part, in support
|
||||
of any commercial product without the express consent of the
|
||||
author.
|
||||
|
||||
There is no warranty or other guarantee of fitness of this
|
||||
software for any purpose. It is provided solely "as is".
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __gpc_h
|
||||
#define __gpc_h
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
/*
|
||||
===========================================================================
|
||||
Constants
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/* Increase GPC_EPSILON to encourage merging of near coincident edges */
|
||||
|
||||
#define GPC_EPSILON (DBL_EPSILON)
|
||||
|
||||
#define GPC_VERSION "2.32"
|
||||
|
||||
|
||||
/*
|
||||
===========================================================================
|
||||
Public Data Types
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
typedef enum /* Set operation type */
|
||||
{
|
||||
GPC_DIFF, /* Difference */
|
||||
GPC_INT, /* Intersection */
|
||||
GPC_XOR, /* Exclusive or */
|
||||
GPC_UNION /* Union */
|
||||
} gpc_op;
|
||||
|
||||
typedef struct /* Polygon vertex structure */
|
||||
{
|
||||
double x; /* Vertex x component */
|
||||
double y; /* vertex y component */
|
||||
} gpc_vertex;
|
||||
|
||||
typedef struct /* Vertex list structure */
|
||||
{
|
||||
int num_vertices; /* Number of vertices in list */
|
||||
gpc_vertex *vertex; /* Vertex array pointer */
|
||||
} gpc_vertex_list;
|
||||
|
||||
typedef struct /* Polygon set structure */
|
||||
{
|
||||
int num_contours; /* Number of contours in polygon */
|
||||
int *hole; /* Hole / external contour flags */
|
||||
gpc_vertex_list *contour; /* Contour array pointer */
|
||||
} gpc_polygon;
|
||||
|
||||
typedef struct /* Tristrip set structure */
|
||||
{
|
||||
int num_strips; /* Number of tristrips */
|
||||
gpc_vertex_list *strip; /* Tristrip array pointer */
|
||||
} gpc_tristrip;
|
||||
|
||||
|
||||
/*
|
||||
===========================================================================
|
||||
Public Function Prototypes
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
void gpc_read_polygon (FILE *infile_ptr,
|
||||
int read_hole_flags,
|
||||
gpc_polygon *polygon);
|
||||
|
||||
void gpc_write_polygon (FILE *outfile_ptr,
|
||||
int write_hole_flags,
|
||||
gpc_polygon *polygon);
|
||||
|
||||
void gpc_add_contour (gpc_polygon *polygon,
|
||||
gpc_vertex_list *contour,
|
||||
int hole);
|
||||
|
||||
void gpc_polygon_clip (gpc_op set_operation,
|
||||
gpc_polygon *subject_polygon,
|
||||
gpc_polygon *clip_polygon,
|
||||
gpc_polygon *result_polygon);
|
||||
|
||||
void gpc_tristrip_clip (gpc_op set_operation,
|
||||
gpc_polygon *subject_polygon,
|
||||
gpc_polygon *clip_polygon,
|
||||
gpc_tristrip *result_tristrip);
|
||||
|
||||
void gpc_polygon_to_tristrip (gpc_polygon *polygon,
|
||||
gpc_tristrip *tristrip);
|
||||
|
||||
void gpc_free_polygon (gpc_polygon *polygon);
|
||||
|
||||
void gpc_free_tristrip (gpc_tristrip *tristrip);
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
===========================================================================
|
||||
End of file: gpc.h
|
||||
===========================================================================
|
||||
*/
|
Binary file not shown.
|
@ -1,123 +0,0 @@
|
|||
|
||||
Generic Polygon Clipper (gpc) Revision History
|
||||
==============================================
|
||||
|
||||
|
||||
v2.32 17th Dec 2004
|
||||
---------------------
|
||||
Fixed occasional memory leak occurring when processing some
|
||||
degenerate polygon arrangements.
|
||||
Added explicit type casting to memory allocator in support of
|
||||
increased code portability.
|
||||
|
||||
v2.31 4th Jun 1999
|
||||
---------------------
|
||||
Separated edge merging measure based on a user-defined GPC_EPSILON
|
||||
value from general numeric equality testing and ordering, which now
|
||||
uses direct arithmetic comparison rather an EPSILON based proximity
|
||||
test.
|
||||
Fixed problem with numerical equality test during construction of
|
||||
local minima and scanbeam tables, leading to occasional crash.
|
||||
Fixed hole array memory leak in gpc_add_contour.
|
||||
Fixed uninitialised hole field bug in gpc_polygon_clip result.
|
||||
|
||||
v2.30 11th Apr 1999
|
||||
---------------------
|
||||
Major re-write.
|
||||
Minor API change: additional 'hole' array field added to gpc_polygon
|
||||
datatype to indicate which constituent contours are internal holes,
|
||||
and which form external boundaries.
|
||||
Minor API change: additional 'hole' argument to gpc_add_contour
|
||||
to indicate whether the new contour is a hole or external contour.
|
||||
Minor API change: additional parameter to gpc_read_polygon and
|
||||
gpc_write_polygon to indicate whether or not to read or write
|
||||
contour hole flags.
|
||||
Fixed NULL pointer bug in add/merge left/right operations.
|
||||
Fixed numerical problem in intersection table generation.
|
||||
Fixed zero byte malloc problem.
|
||||
Fixed problem producing occasional 2 vertex contours.
|
||||
Added bounding box test optimisations.
|
||||
Simplified edge bundle creation, detection of scanbeam internal
|
||||
edge intersections and tristrip scanbeam boundary code.
|
||||
Renamed 'class' variable to be C++ friendly.
|
||||
|
||||
v2.22 17th Oct 1998
|
||||
---------------------
|
||||
Re-implemented edge interpolation and intersection calculations
|
||||
to improve numerical robustness.
|
||||
Simplified setting of GPC_EPSILON.
|
||||
|
||||
v2.21 19th Aug 1998
|
||||
---------------------
|
||||
Fixed problem causing occasional incorrect output when processing
|
||||
self-intersecting polygons (bow-ties etc).
|
||||
Removed bug which may lead to non-generation of uppermost triangle
|
||||
in tristrip output.
|
||||
|
||||
v2.20 26th May 1998
|
||||
---------------------
|
||||
Major re-write.
|
||||
Added exclusive-or polygon set operation.
|
||||
Replaced table-based processing of edge intersections with
|
||||
rule-based system.
|
||||
Replaced two-pass approach to scanbeam interior processing with
|
||||
single pass method.
|
||||
|
||||
v2.10a 14th May 1998
|
||||
---------------------
|
||||
Minor bug-fixes to counter some v2.10 reliability problems.
|
||||
|
||||
v2.10 11th May 1998
|
||||
---------------------
|
||||
Major re-write.
|
||||
Incorporated edge bundle processing of AET to overcome coincident
|
||||
edge problems present in previous releases.
|
||||
Replaced Vatti's method for processing scanbeam interior regions
|
||||
with an adapted version of the scanbeam boundary processing
|
||||
algorithm.
|
||||
|
||||
v2.02 16th Apr 1998 (unreleased)
|
||||
----------------------------------
|
||||
Fixed internal minimum vertex duplication in gpc_polygon_clip
|
||||
result.
|
||||
Improved line intersection code discourage superfluous
|
||||
intersections near line ends.
|
||||
Removed limited precision number formatting in gpc_write_polygon.
|
||||
Modification to allow subject or clip polygon to be reused as the
|
||||
result in gpc_polygon_clip without memory leakage.
|
||||
|
||||
v2.01 23rd Feb 1998
|
||||
---------------------
|
||||
Removed bug causing duplicated vertices in output polygon.
|
||||
Fixed scanbeam table index overrun problem.
|
||||
|
||||
v2.00 25th Nov 1997
|
||||
---------------------
|
||||
Major re-write.
|
||||
Replaced temporary horizontal edge work-around (using tilting)
|
||||
with true horizontal edge handling.
|
||||
Trapezoidal output replaced by tristrips.
|
||||
gpc_op constants now feature a `GPC_' prefix.
|
||||
Data structures now passed by reference to gpc functions.
|
||||
Replaced AET search by proxy addressing in polygon table.
|
||||
Eliminated most (all?) coincident vertex / edge crashes.
|
||||
|
||||
v1.02 18th Oct 1997 (unreleased)
|
||||
----------------------------------
|
||||
Significantly reduced number of mallocs in build_lmt.
|
||||
Scanbeam table now built using heapsort rather than insertion
|
||||
sort.
|
||||
|
||||
v1.01 12th Oct 1997
|
||||
---------------------
|
||||
Fixed memory leak during output polygon build in
|
||||
gpc_clip_polygon.
|
||||
Removed superfluous logfile debug code.
|
||||
Commented out malloc counts.
|
||||
Added missing horizontal edge tilt-correction code in
|
||||
gpc_clip_polygon.
|
||||
|
||||
v1.00 8th Oct 1997
|
||||
--------------------
|
||||
First release.
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
// PolyLine.cpp ... implementation of CPolyLine class from FreePCB.
|
||||
|
||||
//
|
||||
// implementation for kicad
|
||||
// implementation for kicad and kbool polygon clipping library
|
||||
//
|
||||
using namespace std;
|
||||
|
||||
|
@ -13,8 +13,6 @@ using namespace std;
|
|||
|
||||
#include "PolyLine.h"
|
||||
|
||||
#define to_int( x ) (int) round( (x) )
|
||||
|
||||
|
||||
#define pi 3.14159265359
|
||||
|
||||
|
@ -23,17 +21,7 @@ CPolyLine::CPolyLine()
|
|||
m_HatchStyle = 0;
|
||||
m_Width = 0;
|
||||
utility = 0;
|
||||
#ifdef USE_GPC_POLY_LIB
|
||||
m_gpc_poly = new gpc_polygon;
|
||||
m_gpc_poly->num_contours = 0;
|
||||
#else
|
||||
m_gpc_poly = NULL;
|
||||
#endif
|
||||
#ifdef USE_GPL_POLY_LIB
|
||||
m_php_poly = new polygon;
|
||||
#else
|
||||
m_php_poly = NULL;
|
||||
#endif
|
||||
m_Kbool_Poly_Engine = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
@ -42,288 +30,286 @@ CPolyLine::CPolyLine()
|
|||
CPolyLine::~CPolyLine()
|
||||
{
|
||||
Undraw();
|
||||
#ifdef USE_GPC_POLY_LIB
|
||||
FreeGpcPoly();
|
||||
delete m_gpc_poly;
|
||||
#endif
|
||||
#ifdef USE_GPL_POLY_LIB
|
||||
delete m_php_poly;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_GPC_POLY_LIB
|
||||
|
||||
// Use the General Polygon Clipping Library to clip contours
|
||||
// If this results in new polygons, return them as std::vector p
|
||||
// If bRetainArcs == TRUE, try to retain arcs in polys
|
||||
// Returns number of external contours, or -1 if error
|
||||
//
|
||||
int CPolyLine::NormalizeWithGpc( std::vector<CPolyLine*> * pa, bool bRetainArcs )
|
||||
/** Function NormalizeWithKbool
|
||||
* Use the Kbool Library to clip contours: if outlines are crossing, the self-crossing polygon
|
||||
* is converted to non self-crossing polygon by adding extra points at the crossing locations
|
||||
* if more than one outside contour are found, extra CPolyLines will be created
|
||||
* because copper areas have only one outside contour
|
||||
* Therefore, if this results in new CPolyLines, return them as std::vector pa
|
||||
* @param pa: pointer on a std::vector<CPolyLine*> to store extra CPolyLines
|
||||
* @param bRetainArcs == TRUE, try to retain arcs in polys
|
||||
* @return number of external contours, or -1 if error
|
||||
*/
|
||||
int CPolyLine::NormalizeWithKbool( std::vector<CPolyLine*> * pa, bool bRetainArcs )
|
||||
{
|
||||
std::vector<CArc> arc_array;
|
||||
std::vector<CArc> arc_array;
|
||||
std::vector <void*> hole_array; // list of holes
|
||||
std::vector<int> * hole; // used to store corners for a given hole
|
||||
CPolyLine* polyline;
|
||||
int n_ext_cont = 0; // CPolyLine count
|
||||
|
||||
/* Creates a bool engine from this CPolyLine.
|
||||
* Normalized outlines and holes will be in m_Kbool_Poly_Engine
|
||||
* If some polygons are self crossing, after running the Kbool Engine, self crossing polygons
|
||||
* will be converted in non self crossing polygons by inserting extra points at the crossing locations
|
||||
* True holes are combined if possible
|
||||
*/
|
||||
if( bRetainArcs )
|
||||
MakeGpcPoly( -1, &arc_array );
|
||||
MakeKboolPoly( -1, -1, &arc_array );
|
||||
else
|
||||
MakeGpcPoly( -1, NULL );
|
||||
MakeKboolPoly( -1, -1, NULL );
|
||||
|
||||
Undraw();
|
||||
|
||||
// now, recreate poly
|
||||
// first, find outside contours and create new CPolyLines if necessary
|
||||
int n_ext_cont = 0;
|
||||
for( int ic = 0; ic<m_gpc_poly->num_contours; ic++ )
|
||||
/* now, recreate polys
|
||||
* if more than one outside contour are found, extra CPolyLines will be created
|
||||
* because copper areas have only one outside contour
|
||||
* the first outside contour found is the new "this" outside contour
|
||||
* if others outside contours are found we create new CPolyLines
|
||||
* Note: if there are holes in polygons, we must store them
|
||||
* and when all outside contours are found, search the corresponding outside contour for each hole
|
||||
*/
|
||||
while( m_Kbool_Poly_Engine->StartPolygonGet() )
|
||||
{
|
||||
if( !(m_gpc_poly->hole)[ic] )
|
||||
// See if the current polygon is flagged as a hole
|
||||
if( m_Kbool_Poly_Engine->GetPolygonPointEdgeType() == KB_INSIDE_EDGE )
|
||||
{
|
||||
if( n_ext_cont == 0 )
|
||||
hole = new std::vector<int>;
|
||||
hole_array.push_back( hole );
|
||||
while( m_Kbool_Poly_Engine->PolygonHasMorePoints() ) // store hole
|
||||
{
|
||||
// first external contour, replace this poly
|
||||
corner.clear();
|
||||
side_style.clear();
|
||||
for( int i = 0; i<m_gpc_poly->contour[ic].num_vertices; i++ )
|
||||
{
|
||||
int x = to_int( ( (m_gpc_poly->contour)[ic].vertex )[i].x );
|
||||
int y = to_int( ( (m_gpc_poly->contour)[ic].vertex )[i].y );
|
||||
if( i==0 )
|
||||
Start( m_layer, x, y, m_HatchStyle );
|
||||
else
|
||||
AppendCorner( x, y, STRAIGHT, FALSE );
|
||||
}
|
||||
|
||||
Close();
|
||||
n_ext_cont++;
|
||||
int x = m_Kbool_Poly_Engine->GetPolygonXPoint();
|
||||
int y = m_Kbool_Poly_Engine->GetPolygonYPoint();
|
||||
hole->push_back( x );
|
||||
hole->push_back( y );
|
||||
}
|
||||
else if( pa )
|
||||
|
||||
m_Kbool_Poly_Engine->EndPolygonGet();
|
||||
}
|
||||
else if( n_ext_cont == 0 )
|
||||
{
|
||||
// first external contour, replace this poly
|
||||
corner.clear();
|
||||
side_style.clear();
|
||||
bool first = true;
|
||||
while( m_Kbool_Poly_Engine->PolygonHasMorePoints() )
|
||||
{ // foreach point in the polygon
|
||||
int x = m_Kbool_Poly_Engine->GetPolygonXPoint();
|
||||
int y = m_Kbool_Poly_Engine->GetPolygonYPoint();
|
||||
if( first )
|
||||
{
|
||||
first = false;
|
||||
Start( GetLayer(), x, y, GetHatchStyle() );
|
||||
}
|
||||
else
|
||||
AppendCorner( x, y );
|
||||
}
|
||||
|
||||
m_Kbool_Poly_Engine->EndPolygonGet();
|
||||
Close();
|
||||
n_ext_cont++;
|
||||
}
|
||||
else if( pa ) // a new outside contour is found: create a new CPolyLine
|
||||
{
|
||||
polyline = new CPolyLine; // create new poly
|
||||
pa->push_back( polyline ); // put it in array
|
||||
bool first = true;
|
||||
while( m_Kbool_Poly_Engine->PolygonHasMorePoints() ) // read next external contour
|
||||
{
|
||||
// next external contour, create new poly
|
||||
CPolyLine* poly = new CPolyLine;
|
||||
pa->push_back( poly ); // put in array
|
||||
for( int i = 0; i<m_gpc_poly->contour[ic].num_vertices; i++ )
|
||||
int x = m_Kbool_Poly_Engine->GetPolygonXPoint();
|
||||
int y = m_Kbool_Poly_Engine->GetPolygonYPoint();
|
||||
if( first )
|
||||
{
|
||||
int x = to_int( ( (m_gpc_poly->contour)[ic].vertex )[i].x );
|
||||
int y = to_int( ( (m_gpc_poly->contour)[ic].vertex )[i].y );
|
||||
if( i==0 )
|
||||
poly->Start( m_layer, x, y, m_HatchStyle );
|
||||
else
|
||||
poly->AppendCorner( x, y, STRAIGHT, FALSE );
|
||||
first = false;
|
||||
polyline->Start( GetLayer(), x, y, GetHatchStyle() );
|
||||
}
|
||||
|
||||
poly->Close( STRAIGHT, FALSE );
|
||||
n_ext_cont++;
|
||||
else
|
||||
polyline->AppendCorner( x, y );
|
||||
}
|
||||
|
||||
m_Kbool_Poly_Engine->EndPolygonGet();
|
||||
polyline->Close( STRAIGHT, FALSE );
|
||||
n_ext_cont++;
|
||||
}
|
||||
}
|
||||
|
||||
// now add cutouts to the CPolyLine(s)
|
||||
for( int ic = 0; ic<m_gpc_poly->num_contours; ic++ )
|
||||
// now add cutouts to the corresponding CPolyLine(s)
|
||||
for( unsigned ii = 0; ii < hole_array.size(); ii++ )
|
||||
{
|
||||
if( (m_gpc_poly->hole)[ic] )
|
||||
hole = (std::vector<int> *)hole_array[ii];
|
||||
polyline = NULL;
|
||||
if( n_ext_cont == 1 )
|
||||
{
|
||||
CPolyLine* ext_poly = NULL;
|
||||
if( n_ext_cont == 1 )
|
||||
polyline = this;
|
||||
}
|
||||
else
|
||||
{
|
||||
// find the polygon that contains this hole
|
||||
// testing one corner inside is enought because a hole is entirely inside the polygon
|
||||
// sowe test only the first corner
|
||||
int x = (*hole)[0];
|
||||
int y = (*hole)[1];
|
||||
if( TestPointInside( x, y ) )
|
||||
polyline = this;
|
||||
else if( pa )
|
||||
{
|
||||
ext_poly = this;
|
||||
}
|
||||
else
|
||||
{
|
||||
// find the polygon that contains this hole
|
||||
for( int i = 0; i<m_gpc_poly->contour[ic].num_vertices; i++ )
|
||||
for( int ext_ic = 0; ext_ic<n_ext_cont - 1; ext_ic++ )
|
||||
{
|
||||
int x = to_int( ( (m_gpc_poly->contour)[ic].vertex )[i].x );
|
||||
int y = to_int( ( (m_gpc_poly->contour)[ic].vertex )[i].y );
|
||||
if( TestPointInside( x, y ) )
|
||||
ext_poly = this;
|
||||
else
|
||||
if( (*pa)[ext_ic]->TestPointInside( x, y ) )
|
||||
{
|
||||
for( int ext_ic = 0; ext_ic<n_ext_cont - 1; ext_ic++ )
|
||||
{
|
||||
if( (*pa)[ext_ic]->TestPointInside( x, y ) )
|
||||
{
|
||||
ext_poly = (*pa)[ext_ic];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ext_poly )
|
||||
polyline = (*pa)[ext_ic];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( !ext_poly )
|
||||
wxASSERT( 0 );
|
||||
for( int i = 0; i<m_gpc_poly->contour[ic].num_vertices; i++ )
|
||||
}
|
||||
|
||||
if( !polyline )
|
||||
wxASSERT( 0 );
|
||||
else
|
||||
{
|
||||
for( unsigned ii = 0; ii< (*hole).size(); ii++ )
|
||||
{
|
||||
int x = to_int( ( (m_gpc_poly->contour)[ic].vertex )[i].x );
|
||||
int y = to_int( ( (m_gpc_poly->contour)[ic].vertex )[i].y );
|
||||
ext_poly->AppendCorner( x, y, STRAIGHT, FALSE );
|
||||
int x = (*hole)[ii]; ii++;
|
||||
int y = (*hole)[ii];
|
||||
polyline->AppendCorner( x, y, STRAIGHT, FALSE );
|
||||
}
|
||||
|
||||
ext_poly->Close( STRAIGHT, FALSE );
|
||||
polyline->Close( STRAIGHT, FALSE );
|
||||
}
|
||||
}
|
||||
|
||||
if( bRetainArcs )
|
||||
RestoreArcs( &arc_array, pa );
|
||||
FreeGpcPoly();
|
||||
|
||||
delete m_Kbool_Poly_Engine;
|
||||
m_Kbool_Poly_Engine = NULL;
|
||||
|
||||
// free hole list
|
||||
for( unsigned ii = 0; ii < hole_array.size(); ii++ )
|
||||
delete (std::vector<int> *)hole_array[ii];
|
||||
|
||||
return n_ext_cont;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef USE_GPL_POLY_LIB
|
||||
|
||||
// make a php_polygon from first contour
|
||||
int CPolyLine::MakePhpPoly()
|
||||
/** Function AddPolygonsToBoolEng
|
||||
* and edges contours to a kbool engine, preparing a boolean op between polygons
|
||||
* @param aStart_contour: starting contour number (-1 = all, 0 is the outlines of zone, > 1 = holes in zone
|
||||
* @param aEnd_contour: ending contour number (-1 = all after aStart_contour)
|
||||
* @param arc_array: arc converted to poly segments (NULL if not exists)
|
||||
* @param aBooleng : pointer on a bool engine (handle a set of polygons)
|
||||
* @param aGroup : group to fill (aGroup = GROUP_A or GROUP_B) operations are made between GROUP_A and GROUP_B
|
||||
*/
|
||||
int CPolyLine::AddPolygonsToBoolEng( Bool_Engine* aBooleng,
|
||||
GroupType aGroup,
|
||||
int aStart_contour,
|
||||
int aEnd_contour,
|
||||
std::vector<CArc> * arc_array )
|
||||
{
|
||||
FreePhpPoly();
|
||||
int nv = GetContourEnd( 0 );
|
||||
for( int iv = 0; iv <= nv; iv++ )
|
||||
m_php_poly->addv( GetX( iv ), GetY( iv ) );
|
||||
int count = 0;
|
||||
|
||||
m_php_poly->getFirst()->m_id = 1;
|
||||
return 0;
|
||||
}
|
||||
if( (aGroup != GROUP_A) && (aGroup != GROUP_B ) )
|
||||
return 0; //Error !
|
||||
|
||||
MakeKboolPoly( aStart_contour, aEnd_contour, arc_array );
|
||||
|
||||
void CPolyLine::FreePhpPoly()
|
||||
{
|
||||
// delete all vertices
|
||||
while( m_php_poly->m_cnt > 1 )
|
||||
while( m_Kbool_Poly_Engine->StartPolygonGet() )
|
||||
{
|
||||
vertex* fv = m_php_poly->getFirst();
|
||||
m_php_poly->del( fv->m_nextV );
|
||||
}
|
||||
|
||||
delete m_php_poly->m_first;
|
||||
m_php_poly->m_first = NULL;
|
||||
m_php_poly->m_cnt = 0;
|
||||
}
|
||||
|
||||
|
||||
// Use the php clipping lib to clip this poly against poly
|
||||
//
|
||||
void CPolyLine::ClipPhpPolygon( int php_op, CPolyLine* poly )
|
||||
{
|
||||
Undraw();
|
||||
poly->MakePhpPoly();
|
||||
MakePhpPoly();
|
||||
polygon* p = m_php_poly->boolean( poly->m_php_poly, php_op );
|
||||
poly->FreePhpPoly();
|
||||
FreePhpPoly();
|
||||
|
||||
if( p )
|
||||
{
|
||||
// now screw with the PolyLine
|
||||
corner.clear();
|
||||
side_style.clear();
|
||||
|
||||
do
|
||||
if( aBooleng->StartPolygonAdd( GROUP_A ) )
|
||||
{
|
||||
vertex* v = p->getFirst();
|
||||
Start( m_layer, to_int( v->X() ), to_int( v->Y() ), m_HatchStyle );
|
||||
|
||||
do
|
||||
while( m_Kbool_Poly_Engine->PolygonHasMorePoints() )
|
||||
{
|
||||
vertex* n = v->Next();
|
||||
AppendCorner( to_int( v->X() ), to_int( (v->Y()) ) );
|
||||
v = n;
|
||||
} while( v->id() != p->getFirst()->id() );
|
||||
int x = m_Kbool_Poly_Engine->GetPolygonXPoint();
|
||||
int y = m_Kbool_Poly_Engine->GetPolygonYPoint();
|
||||
aBooleng->AddPoint( x, y );
|
||||
count++;
|
||||
}
|
||||
|
||||
Close();
|
||||
|
||||
// p = p->NextPoly();
|
||||
delete p;
|
||||
p = NULL;
|
||||
} while( p );
|
||||
aBooleng->EndPolygonAdd();
|
||||
}
|
||||
m_Kbool_Poly_Engine->EndPolygonGet();
|
||||
}
|
||||
Draw();
|
||||
|
||||
delete m_Kbool_Poly_Engine;
|
||||
m_Kbool_Poly_Engine = NULL;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
int CPolyLine::MakePolygonFromAreaOutlines( int icontour, std::vector<CArc> * arc_array )
|
||||
{
|
||||
#ifdef USE_GPC_POLY_LIB
|
||||
return MakeGpcPoly( icontour, arc_array );
|
||||
#endif
|
||||
#ifdef USE_GPL_POLY_LIB
|
||||
return MakePhpPoly( );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void CPolyLine::FreePolygon()
|
||||
{
|
||||
#ifdef USE_GPC_POLY_LIB
|
||||
FreeGpcPoly();
|
||||
#endif
|
||||
#ifdef USE_GPL_POLY_LIB
|
||||
FreePhpPoly();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int CPolyLine::NormalizeAreaOutlines( std::vector<CPolyLine*> * pa, bool bRetainArcs )
|
||||
{
|
||||
#ifdef USE_GPC_POLY_LIB
|
||||
return NormalizeWithGpc( pa, bRetainArcs );
|
||||
#endif
|
||||
#ifdef USE_GPL_POLY_LIB
|
||||
#warning NormalizeAreaOutlines with GPL lib must be finished (TODO)
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_GPC_POLY_LIB
|
||||
|
||||
/** Function MakeGpcPoly
|
||||
* make a gpc_polygon for a closed polyline contour
|
||||
/** Function MakeKboolPoly
|
||||
* fill a kbool engine with a closed polyline contour
|
||||
* approximates arcs with multiple straight-line segments
|
||||
* @param icontour : if icontour = -1, make polygon with all contours,
|
||||
* @param aStart_contour: starting contour number (-1 = all, 0 is the outlines of zone, > 1 = holes in zone
|
||||
* @param aEnd_contour: ending contour number (-1 = all after aStart_contour)
|
||||
* combining intersecting contours if possible
|
||||
* @param arc_array : return data on arcs in arc_array
|
||||
* @param arc_array : return corners computed from arcs approximations in arc_array
|
||||
* @return error: 0 if Ok, 1 if error
|
||||
*/
|
||||
int CPolyLine::MakeGpcPoly( int icontour, std::vector<CArc> * arc_array )
|
||||
int CPolyLine::MakeKboolPoly( int aStart_contour, int aEnd_contour, std::vector<CArc> * arc_array )
|
||||
{
|
||||
if( m_gpc_poly->num_contours )
|
||||
FreeGpcPoly();
|
||||
if( !GetClosed() && (icontour == (GetNumContours() - 1) || icontour == -1) )
|
||||
if( m_Kbool_Poly_Engine )
|
||||
{
|
||||
delete m_Kbool_Poly_Engine;
|
||||
m_Kbool_Poly_Engine = NULL;
|
||||
}
|
||||
if( !GetClosed() && (aStart_contour == (GetNumContours() - 1) || aStart_contour == -1) )
|
||||
return 1; // error
|
||||
|
||||
// initialize m_gpc_poly
|
||||
m_gpc_poly->num_contours = 0;
|
||||
m_gpc_poly->hole = NULL;
|
||||
m_gpc_poly->contour = NULL;
|
||||
int n_arcs = 0;
|
||||
|
||||
int first_contour = icontour;
|
||||
int last_contour = icontour;
|
||||
if( icontour == -1 )
|
||||
int first_contour = aStart_contour;
|
||||
int last_contour = aEnd_contour;
|
||||
if( aStart_contour == -1 )
|
||||
{
|
||||
first_contour = 0;
|
||||
last_contour = GetNumContours() - 1;
|
||||
}
|
||||
if( aEnd_contour == -1 )
|
||||
{
|
||||
last_contour = GetNumContours() - 1;
|
||||
}
|
||||
if( arc_array )
|
||||
arc_array->clear();
|
||||
int iarc = 0;
|
||||
for( int icont = first_contour; icont<=last_contour; icont++ )
|
||||
{
|
||||
// make gpc_polygon for this contour
|
||||
gpc_polygon* gpc = new gpc_polygon;
|
||||
gpc->num_contours = 0;
|
||||
gpc->hole = NULL;
|
||||
gpc->contour = NULL;
|
||||
// Fill a kbool engine for this contour,
|
||||
// and combine it with previous contours
|
||||
Bool_Engine* booleng = new Bool_Engine();
|
||||
ArmBoolEng( booleng );
|
||||
|
||||
if( m_Kbool_Poly_Engine ) // a previous contour exists. Put it in new engine
|
||||
{
|
||||
while( m_Kbool_Poly_Engine->StartPolygonGet() )
|
||||
{
|
||||
if( booleng->StartPolygonAdd( GROUP_A ) )
|
||||
{
|
||||
while( m_Kbool_Poly_Engine->PolygonHasMorePoints() )
|
||||
{
|
||||
int x = m_Kbool_Poly_Engine->GetPolygonXPoint();
|
||||
int y = m_Kbool_Poly_Engine->GetPolygonYPoint();
|
||||
booleng->AddPoint( x, y );
|
||||
}
|
||||
|
||||
booleng->EndPolygonAdd();
|
||||
}
|
||||
m_Kbool_Poly_Engine->EndPolygonGet();
|
||||
}
|
||||
}
|
||||
|
||||
// first, calculate number of vertices in contour
|
||||
int n_vertices = 0;
|
||||
int ic_st = GetContourStart( icont );
|
||||
int ic_end = GetContourEnd( icont );
|
||||
if( !booleng->StartPolygonAdd( GROUP_B ) )
|
||||
{
|
||||
wxASSERT( 0 );
|
||||
return 1; //error
|
||||
}
|
||||
for( int ic = ic_st; ic<=ic_end; ic++ )
|
||||
{
|
||||
int style = side_style[ic];
|
||||
|
@ -353,10 +339,7 @@ int CPolyLine::MakeGpcPoly( int icontour, std::vector<CArc> * arc_array )
|
|||
}
|
||||
}
|
||||
|
||||
// now create gcp_vertex_list for this contour
|
||||
gpc_vertex_list* g_v_list = new gpc_vertex_list;
|
||||
g_v_list->vertex = (gpc_vertex*) calloc( sizeof(gpc_vertex), n_vertices );
|
||||
g_v_list->num_vertices = n_vertices;
|
||||
// now enter this contour to booleng
|
||||
int ivtx = 0;
|
||||
for( int ic = ic_st; ic<=ic_end; ic++ )
|
||||
{
|
||||
|
@ -376,8 +359,7 @@ int CPolyLine::MakeGpcPoly( int icontour, std::vector<CArc> * arc_array )
|
|||
}
|
||||
if( style == STRAIGHT )
|
||||
{
|
||||
g_v_list->vertex[ivtx].x = x1;
|
||||
g_v_list->vertex[ivtx].y = y1;
|
||||
booleng->AddPoint( x1, y1 );
|
||||
ivtx++;
|
||||
}
|
||||
else
|
||||
|
@ -480,8 +462,7 @@ int CPolyLine::MakeGpcPoly( int icontour, std::vector<CArc> * arc_array )
|
|||
x = x1;
|
||||
y = y1;
|
||||
}
|
||||
g_v_list->vertex[ivtx].x = x;
|
||||
g_v_list->vertex[ivtx].y = y;
|
||||
booleng->AddPoint( x1, y1 );
|
||||
ivtx++;
|
||||
}
|
||||
}
|
||||
|
@ -490,42 +471,93 @@ int CPolyLine::MakeGpcPoly( int icontour, std::vector<CArc> * arc_array )
|
|||
if( n_vertices != ivtx )
|
||||
wxASSERT( 0 );
|
||||
|
||||
// add vertex_list to gpc
|
||||
gpc_add_contour( gpc, g_v_list, 0 );
|
||||
// close list added to the bool engine
|
||||
booleng->EndPolygonAdd();
|
||||
|
||||
/* now combine polygon to the previous polygons.
|
||||
* note: the first polygon is the outline contour, and others are holes inside the first polygon
|
||||
* The first polygon is ORed with nothing, but is is a trick to sort corners (vertex)
|
||||
* clockwise with the kbool engine.
|
||||
* Others polygons are substract to the outline and corners will be ordered counter clockwise
|
||||
* by the kbool engine
|
||||
*/
|
||||
if( aStart_contour <= 0 && icont != 0 ) // substract hole to outside ( if the outline contour is take in account)
|
||||
{
|
||||
booleng->Do_Operation( BOOL_A_SUB_B );
|
||||
}
|
||||
else // add outside or add holes if we do not use the outline contour
|
||||
{
|
||||
booleng->Do_Operation( BOOL_OR );
|
||||
}
|
||||
|
||||
// now clip m_gpc_poly with gpc, put new poly into result
|
||||
gpc_polygon* result = new gpc_polygon;
|
||||
if( icontour == -1 && icont != 0 )
|
||||
gpc_polygon_clip( GPC_DIFF, m_gpc_poly, gpc, result ); // hole
|
||||
else
|
||||
gpc_polygon_clip( GPC_UNION, m_gpc_poly, gpc, result ); // outside
|
||||
// now copy result to m_gpc_poly
|
||||
gpc_free_polygon( m_gpc_poly );
|
||||
delete m_gpc_poly;
|
||||
m_gpc_poly = result;
|
||||
gpc_free_polygon( gpc );
|
||||
delete gpc;
|
||||
free( g_v_list->vertex );
|
||||
free( g_v_list );
|
||||
if( m_Kbool_Poly_Engine )
|
||||
delete m_Kbool_Poly_Engine;
|
||||
m_Kbool_Poly_Engine = booleng;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void CPolyLine::FreeGpcPoly()
|
||||
/** 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: holes are linked into outer contours by double overlapping segments
|
||||
* false: holes are not linked: in this mode contours are added clockwise
|
||||
* and polygons added counter clockwise are holes
|
||||
*/
|
||||
void ArmBoolEng( Bool_Engine* aBooleng, bool aConvertHoles )
|
||||
{
|
||||
if( m_gpc_poly->num_contours )
|
||||
// set some global vals to arm the boolean engine
|
||||
double DGRID = 1000; // round coordinate X or Y value in calculations to this
|
||||
double MARGE = 0.001; // snap with in this range points to lines in the intersection routines
|
||||
// should always be > DGRID a MARGE >= 10*DGRID is oke
|
||||
// this is also used to remove small segments and to decide when
|
||||
// two segments are in line.
|
||||
double CORRECTIONFACTOR = 500.0; // correct the polygons by this number
|
||||
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
|
||||
|
||||
|
||||
// DGRID is only meant to make fractional parts of input data which
|
||||
// are doubles, part of the integers used in vertexes within the boolean algorithm.
|
||||
// Within the algorithm all input data is multiplied with DGRID
|
||||
|
||||
// space for extra intersection inside the boolean algorithms
|
||||
// only change this if there are problems
|
||||
int GRID = 10000;
|
||||
|
||||
aBooleng->SetMarge( MARGE );
|
||||
aBooleng->SetGrid( GRID );
|
||||
aBooleng->SetDGrid( DGRID );
|
||||
aBooleng->SetCorrectionFactor( CORRECTIONFACTOR );
|
||||
aBooleng->SetCorrectionAber( CORRECTIONABER );
|
||||
aBooleng->SetSmoothAber( SMOOTHABER );
|
||||
aBooleng->SetMaxlinemerge( MAXLINEMERGE );
|
||||
aBooleng->SetRoundfactor( ROUNDFACTOR );
|
||||
|
||||
if( aConvertHoles )
|
||||
{
|
||||
delete m_gpc_poly->contour->vertex;
|
||||
delete m_gpc_poly->contour;
|
||||
delete m_gpc_poly->hole;
|
||||
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 ce connected by double overlapping segments
|
||||
aBooleng->SetOrientationEntryMode( true ); // holes are entered counter clockwise
|
||||
}
|
||||
m_gpc_poly->num_contours = 0;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
int CPolyLine::NormalizeAreaOutlines( std::vector<CPolyLine*> * pa, bool bRetainArcs )
|
||||
{
|
||||
return NormalizeWithKbool( pa, bRetainArcs );
|
||||
}
|
||||
|
||||
// Restore arcs to a polygon where they were replaced with steps
|
||||
// If pa != NULL, also use polygons in pa array
|
||||
|
@ -548,8 +580,9 @@ int CPolyLine::RestoreArcs( std::vector<CArc> * arc_array, std::vector<CPolyLine
|
|||
poly = (*pa)[ip - 1];
|
||||
poly->Undraw();
|
||||
for( int ic = 0; ic<poly->GetNumCorners(); ic++ )
|
||||
poly->SetUtility( ic, 0 ); // clear utility flag
|
||||
poly->SetUtility( ic, 0 );
|
||||
|
||||
// clear utility flag
|
||||
}
|
||||
|
||||
// find arcs and replace them
|
||||
|
@ -1181,19 +1214,20 @@ void CPolyLine::Hatch()
|
|||
if( corner[ic].end_contour || ( ic == (int) (corner.size() - 1) ) )
|
||||
{
|
||||
ok = FindLineSegmentIntersection( a, slope,
|
||||
corner[ic].x, corner[ic].y,
|
||||
corner[i_start_contour].x, corner[i_start_contour].y,
|
||||
side_style[ic],
|
||||
&x, &y, &x2, &y2 );
|
||||
corner[ic].x, corner[ic].y,
|
||||
corner[i_start_contour].x,
|
||||
corner[i_start_contour].y,
|
||||
side_style[ic],
|
||||
&x, &y, &x2, &y2 );
|
||||
i_start_contour = ic + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ok = FindLineSegmentIntersection( a, slope,
|
||||
corner[ic].x, corner[ic].y,
|
||||
corner[ic + 1].x, corner[ic + 1].y,
|
||||
side_style[ic],
|
||||
&x, &y, &x2, &y2 );
|
||||
corner[ic].x, corner[ic].y,
|
||||
corner[ic + 1].x, corner[ic + 1].y,
|
||||
side_style[ic],
|
||||
&x, &y, &x2, &y2 );
|
||||
}
|
||||
if( ok )
|
||||
{
|
||||
|
@ -1267,11 +1301,12 @@ void CPolyLine::Hatch()
|
|||
double y2 = yy[ip + 1] - dx * slope;
|
||||
m_HatchLines.push_back( CSegment( xx[ip], yy[ip], to_int( x1 ), to_int( y1 ) ) );
|
||||
m_HatchLines.push_back( CSegment( xx[ip + 1], yy[ip + 1], to_int( x2 ),
|
||||
to_int( y2 ) ) );
|
||||
to_int( y2 ) ) );
|
||||
}
|
||||
}
|
||||
} // end for
|
||||
}
|
||||
|
||||
// end for
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1309,16 +1344,16 @@ bool CPolyLine::TestPointInside( int x, int y )
|
|||
int ok;
|
||||
if( ic == istart )
|
||||
ok = FindLineSegmentIntersection( a, slope,
|
||||
corner[iend].x, corner[iend].y,
|
||||
corner[istart].x, corner[istart].y,
|
||||
side_style[corner.size() - 1],
|
||||
&x, &y, &x2, &y2 );
|
||||
corner[iend].x, corner[iend].y,
|
||||
corner[istart].x, corner[istart].y,
|
||||
side_style[corner.size() - 1],
|
||||
&x, &y, &x2, &y2 );
|
||||
else
|
||||
ok = FindLineSegmentIntersection( a, slope,
|
||||
corner[ic - 1].x, corner[ic - 1].y,
|
||||
corner[ic].x, corner[ic].y,
|
||||
side_style[ic - 1],
|
||||
&x, &y, &x2, &y2 );
|
||||
corner[ic - 1].x, corner[ic - 1].y,
|
||||
corner[ic].x, corner[ic].y,
|
||||
side_style[ic - 1],
|
||||
&x, &y, &x2, &y2 );
|
||||
if( ok )
|
||||
{
|
||||
xx[npts] = (int) x;
|
||||
|
@ -1393,16 +1428,16 @@ bool CPolyLine::TestPointInsideContour( int icont, int x, int y )
|
|||
int ok;
|
||||
if( ic == istart )
|
||||
ok = FindLineSegmentIntersection( a, slope,
|
||||
corner[iend].x, corner[iend].y,
|
||||
corner[istart].x, corner[istart].y,
|
||||
side_style[corner.size() - 1],
|
||||
&x, &y, &x2, &y2 );
|
||||
corner[iend].x, corner[iend].y,
|
||||
corner[istart].x, corner[istart].y,
|
||||
side_style[corner.size() - 1],
|
||||
&x, &y, &x2, &y2 );
|
||||
else
|
||||
ok = FindLineSegmentIntersection( a, slope,
|
||||
corner[ic - 1].x, corner[ic - 1].y,
|
||||
corner[ic].x, corner[ic].y,
|
||||
side_style[ic - 1],
|
||||
&x, &y, &x2, &y2 );
|
||||
corner[ic - 1].x, corner[ic - 1].y,
|
||||
corner[ic].x, corner[ic].y,
|
||||
side_style[ic - 1],
|
||||
&x, &y, &x2, &y2 );
|
||||
if( ok )
|
||||
{
|
||||
xx[npts] = (int) x;
|
||||
|
@ -1455,12 +1490,6 @@ void CPolyLine::Copy( CPolyLine* src )
|
|||
// copy side styles
|
||||
for( unsigned ii = 0; ii < src->side_style.size(); ii++ )
|
||||
side_style.push_back( src->side_style[ii] );
|
||||
|
||||
#ifdef USE_GPC_POLY_LIB
|
||||
|
||||
// don't copy the Gpc_poly, just clear the old one
|
||||
FreeGpcPoly();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -1632,9 +1661,9 @@ void CPolyLine::AddContourForPadClearance( int type,
|
|||
}
|
||||
AppendCorner( to_int( x + corner_x ), to_int( y + corner_y ), STRAIGHT, 0 );
|
||||
AppendCorner( to_int( x + r * cos( th1 ) ), to_int( y + r * sin(
|
||||
th1 ) ), STRAIGHT, 0 );
|
||||
th1 ) ), STRAIGHT, 0 );
|
||||
AppendCorner( to_int( x + r * cos( th2 ) ), to_int( y + r * sin(
|
||||
th2 ) ), ARC_CCW, 0 );
|
||||
th2 ) ), ARC_CCW, 0 );
|
||||
Close( STRAIGHT );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// PolyLine.h ... definition of CPolyLine class
|
||||
|
||||
//
|
||||
// A polyline contains one or more contours, where each contour
|
||||
// is defined by a list of corners and side-styles
|
||||
|
@ -16,150 +17,214 @@
|
|||
|
||||
#include <vector>
|
||||
|
||||
#define USE_GPC_POLY_LIB
|
||||
//#define USE_GPL_POLY_LIB
|
||||
|
||||
#include "defs-macros.h"
|
||||
|
||||
#include "GenericPolygonClipperLibrary.h"
|
||||
#include "php_polygon.h"
|
||||
#include "php_polygon_vertex.h"
|
||||
|
||||
#include "PolyLine2Kicad.h"
|
||||
|
||||
|
||||
#include "kbool/include/booleng.h"
|
||||
#include "freepcbDisplayList.h"
|
||||
#include "math_for_graphics.h"
|
||||
#include "pad_shapes.h"
|
||||
|
||||
class CSegment {
|
||||
|
||||
/** 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: holes are linked into outer contours by double overlapping segments
|
||||
* false: holes are not linked: in this mode contours are added clockwise
|
||||
* and polygons added counter clockwise are holes
|
||||
*/
|
||||
void ArmBoolEng( Bool_Engine* aBooleng, bool aConvertHoles = false);
|
||||
|
||||
|
||||
#define PCBU_PER_MIL 10
|
||||
#define NM_PER_MIL 10 // 25400
|
||||
|
||||
#define to_int( x ) (int) round( (x) )
|
||||
#ifndef min
|
||||
#define min( x1, x2 ) ( (x1) > (x2) ) ? (x2) : (x1)
|
||||
#endif
|
||||
#ifndef max
|
||||
#define max( x1, x2 ) ( (x1) > (x2) ) ? (x1) : (x2)
|
||||
#endif
|
||||
|
||||
class CRect
|
||||
{
|
||||
public:
|
||||
int xi, yi, xf, yf;
|
||||
CSegment() {};
|
||||
CSegment(int x0, int y0, int x1, int y1) {
|
||||
xi = x0; yi = y0; xf = x1; yf = y1; }
|
||||
int left, right, top, bottom;
|
||||
};
|
||||
|
||||
class CArc {
|
||||
class CPoint
|
||||
{
|
||||
public:
|
||||
enum{ MAX_STEP = 50*25400 }; // max step is 20 mils
|
||||
enum{ MIN_STEPS = 18 }; // min step is 5 degrees
|
||||
int style;
|
||||
int xi, yi, xf, yf;
|
||||
int n_steps; // number of straight-line segments in gpc_poly
|
||||
bool bFound;
|
||||
int x, y;
|
||||
public:
|
||||
CPoint( void ) { x = y = 0; };
|
||||
CPoint( int i, int j ) { x = i; y = j; };
|
||||
};
|
||||
|
||||
class CSegment
|
||||
{
|
||||
public:
|
||||
int xi, yi, xf, yf;
|
||||
CSegment() { };
|
||||
CSegment( int x0, int y0, int x1, int y1 )
|
||||
{
|
||||
xi = x0; yi = y0; xf = x1; yf = y1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#include "math_for_graphics.h"
|
||||
|
||||
class CArc
|
||||
{
|
||||
public:
|
||||
enum { MAX_STEP = 50 * 25400 }; // max step is 20 mils
|
||||
enum { MIN_STEPS = 18 }; // min step is 5 degrees
|
||||
int style;
|
||||
int xi, yi, xf, yf;
|
||||
int n_steps; // number of straight-line segments in gpc_poly
|
||||
bool bFound;
|
||||
};
|
||||
|
||||
class CPolyPt
|
||||
{
|
||||
public:
|
||||
CPolyPt( int qx=0, int qy=0, bool qf=FALSE )
|
||||
{ x=qx; y=qy; end_contour=qf; utility = 0; };
|
||||
int x;
|
||||
int y;
|
||||
bool end_contour;
|
||||
int utility;
|
||||
CPolyPt( int qx = 0, int qy = 0, bool qf = FALSE )
|
||||
{ x = qx; y = qy; end_contour = qf; utility = 0; };
|
||||
int x;
|
||||
int y;
|
||||
bool end_contour;
|
||||
int utility;
|
||||
};
|
||||
|
||||
class CPolyLine
|
||||
{
|
||||
public:
|
||||
enum { STRAIGHT, ARC_CW, ARC_CCW }; // side styles
|
||||
enum { NO_HATCH, DIAGONAL_FULL, DIAGONAL_EDGE }; // hatch styles
|
||||
enum { STRAIGHT, ARC_CW, ARC_CCW }; // side styles
|
||||
enum { NO_HATCH, DIAGONAL_FULL, DIAGONAL_EDGE }; // hatch styles
|
||||
|
||||
// constructors/destructor
|
||||
CPolyLine();
|
||||
~CPolyLine();
|
||||
// constructors/destructor
|
||||
CPolyLine();
|
||||
~CPolyLine();
|
||||
|
||||
// functions for modifying polyline
|
||||
void Start( int layer, int x, int y, int hatch );
|
||||
void AppendCorner( int x, int y, int style = STRAIGHT, bool bDraw=TRUE );
|
||||
void InsertCorner( int ic, int x, int y );
|
||||
void DeleteCorner( int ic, bool bDraw=TRUE );
|
||||
void MoveCorner( int ic, int x, int y );
|
||||
void Close( int style = STRAIGHT, bool bDraw=TRUE );
|
||||
void RemoveContour( int icont );
|
||||
void RemoveAllContours( void );
|
||||
// functions for modifying polyline
|
||||
void Start( int layer, int x, int y, int hatch );
|
||||
void AppendCorner( int x, int y, int style = STRAIGHT, bool bDraw = TRUE );
|
||||
void InsertCorner( int ic, int x, int y );
|
||||
void DeleteCorner( int ic, bool bDraw = TRUE );
|
||||
void MoveCorner( int ic, int x, int y );
|
||||
void Close( int style = STRAIGHT, bool bDraw = TRUE );
|
||||
void RemoveContour( int icont );
|
||||
|
||||
// drawing functions
|
||||
void Undraw();
|
||||
void Draw( );
|
||||
void Hatch();
|
||||
void MoveOrigin( int x_off, int y_off );
|
||||
void RemoveAllContours( void );
|
||||
|
||||
// misc. functions
|
||||
CRect GetBounds();
|
||||
CRect GetCornerBounds();
|
||||
CRect GetCornerBounds( int icont );
|
||||
void Copy( CPolyLine * src );
|
||||
bool TestPointInside( int x, int y );
|
||||
bool TestPointInsideContour( int icont, int x, int y );
|
||||
bool IsCutoutContour( int icont );
|
||||
void AppendArc( int xi, int yi, int xf, int yf, int xc, int yc, int num );
|
||||
// drawing functions
|
||||
void Undraw();
|
||||
void Draw();
|
||||
void Hatch();
|
||||
void MoveOrigin( int x_off, int y_off );
|
||||
|
||||
// misc. functions
|
||||
CRect GetBounds();
|
||||
CRect GetCornerBounds();
|
||||
CRect GetCornerBounds( int icont );
|
||||
void Copy( CPolyLine* src );
|
||||
bool TestPointInside( int x, int y );
|
||||
bool TestPointInsideContour( int icont, int x, int y );
|
||||
bool IsCutoutContour( int icont );
|
||||
void AppendArc( int xi, int yi, int xf, int yf, int xc, int yc, int num );
|
||||
|
||||
|
||||
// access functions
|
||||
int GetLayer() { return m_layer;}
|
||||
int GetNumCorners();
|
||||
int GetNumSides();
|
||||
int GetClosed();
|
||||
int GetNumContours();
|
||||
int GetContour( int ic );
|
||||
int GetContourStart( int icont );
|
||||
int GetContourEnd( int icont );
|
||||
int GetContourSize( int icont );
|
||||
int GetX( int ic );
|
||||
int GetY( int ic );
|
||||
int GetEndContour( int ic );
|
||||
int GetUtility( int ic ){ return corner[ic].utility; };
|
||||
void SetUtility( int ic, int utility ){ corner[ic].utility = utility; };
|
||||
int GetSideStyle( int is );
|
||||
int GetHatchStyle(){ return m_HatchStyle; }
|
||||
void SetHatch( int hatch ){ Undraw(); m_HatchStyle = hatch; Draw(); };
|
||||
void SetX( int ic, int x );
|
||||
void SetY( int ic, int y );
|
||||
void SetEndContour( int ic, bool end_contour );
|
||||
void SetSideStyle( int is, int style );
|
||||
// access functions
|
||||
int GetLayer() { return m_layer; }
|
||||
int GetNumCorners();
|
||||
int GetNumSides();
|
||||
int GetClosed();
|
||||
int GetNumContours();
|
||||
int GetContour( int ic );
|
||||
int GetContourStart( int icont );
|
||||
int GetContourEnd( int icont );
|
||||
int GetContourSize( int icont );
|
||||
int GetX( int ic );
|
||||
int GetY( int ic );
|
||||
int GetEndContour( int ic );
|
||||
|
||||
int RestoreArcs( std::vector<CArc> * arc_array, std::vector<CPolyLine*> * pa=NULL );
|
||||
CPolyLine * MakePolylineForPad( int type, int x, int y, int w, int l, int r, int angle );
|
||||
void AddContourForPadClearance( int type, int x, int y, int w,
|
||||
int l, int r, int angle, int fill_clearance,
|
||||
int hole_w, int hole_clearance, bool bThermal=FALSE, int spoke_w=0 );
|
||||
int GetUtility( int ic ) { return corner[ic].utility; };
|
||||
void SetUtility( int ic, int utility ) { corner[ic].utility = utility; };
|
||||
int GetSideStyle( int is );
|
||||
|
||||
int MakePolygonFromAreaOutlines( int icontour, std::vector<CArc> * arc_array );
|
||||
void FreePolygon();
|
||||
int NormalizeAreaOutlines( std::vector<CPolyLine*> * pa=NULL, bool bRetainArcs=FALSE );
|
||||
int GetHatchStyle() { return m_HatchStyle; }
|
||||
void SetHatch( int hatch ) { Undraw(); m_HatchStyle = hatch; Draw(); };
|
||||
void SetX( int ic, int x );
|
||||
void SetY( int ic, int y );
|
||||
void SetEndContour( int ic, bool end_contour );
|
||||
void SetSideStyle( int is, int style );
|
||||
|
||||
#ifdef USE_GPC_POLY_LIB
|
||||
// GPC functions
|
||||
int MakeGpcPoly( int icontour=0, std::vector<CArc> * arc_array=NULL );
|
||||
void FreeGpcPoly();
|
||||
gpc_polygon * GetGpcPoly(){ return m_gpc_poly; };
|
||||
int NormalizeWithGpc( std::vector<CPolyLine*> * pa=NULL, bool bRetainArcs=FALSE );
|
||||
#endif
|
||||
int RestoreArcs( std::vector<CArc> * arc_array, std::vector<CPolyLine*> * pa = NULL );
|
||||
CPolyLine* MakePolylineForPad( int type, int x, int y, int w, int l, int r, int angle );
|
||||
void AddContourForPadClearance( int type,
|
||||
int x,
|
||||
int y,
|
||||
int w,
|
||||
int l,
|
||||
int r,
|
||||
int angle,
|
||||
int fill_clearance,
|
||||
int hole_w,
|
||||
int hole_clearance,
|
||||
bool bThermal = FALSE,
|
||||
int spoke_w = 0 );
|
||||
|
||||
int NormalizeAreaOutlines( std::vector<CPolyLine*> * pa = NULL,
|
||||
bool bRetainArcs = FALSE );
|
||||
|
||||
// PHP functions
|
||||
#ifdef USE_GPL_POLY_LIB
|
||||
int MakePhpPoly();
|
||||
void FreePhpPoly();
|
||||
void ClipPhpPolygon( int php_op, CPolyLine * poly );
|
||||
polygon * GetPhpPoly(){ return m_php_poly; };
|
||||
#endif
|
||||
// KBOOL functions
|
||||
|
||||
/** Function AddPolygonsToBoolEng
|
||||
* and edges contours to a kbool engine, preparing a boolean op between polygons
|
||||
* @param aStart_contour: starting contour number (-1 = all, 0 is the outlines of zone, > 1 = holes in zone
|
||||
* @param aEnd_contour: ending contour number (-1 = all after aStart_contour)
|
||||
* @param arc_array: arc connverted to poly (NULL if not exists)
|
||||
* @param aBooleng : pointer on a bool engine (handle a set of polygons)
|
||||
* @param aGroup : group to fill (aGroup = GROUP_A or GROUP_B) operations are made between GROUP_A and GROUP_B
|
||||
*/
|
||||
int AddPolygonsToBoolEng( Bool_Engine* aBooleng,
|
||||
GroupType aGroup,
|
||||
int aStart_contour = -1,
|
||||
int aEnd_contour = -1,
|
||||
std::vector<CArc> * arc_array = NULL );
|
||||
|
||||
/** Function MakeKboolPoly
|
||||
* fill a kbool engine with a closed polyline contour
|
||||
* approximates arcs with multiple straight-line segments
|
||||
* @param aStart_contour: starting contour number (-1 = all, 0 is the outlines of zone, > 1 = holes in zone
|
||||
* @param aEnd_contour: ending contour number (-1 = all after aStart_contour)
|
||||
* combining intersecting contours if possible
|
||||
* @param arc_array : return data on arcs in arc_array
|
||||
* @return error: 0 if Ok, 1 if error
|
||||
*/
|
||||
int MakeKboolPoly( int aStart_contour = -1, int aEnd_contour = -1, std::vector<CArc> * arc_array = NULL );
|
||||
|
||||
/** Function NormalizeWithKbool
|
||||
* Use the Kbool Library to clip contours: if outlines are crossing, the self-crossing polygon
|
||||
* is converted in 2 or more non self-crossing polygons
|
||||
* If this results in new polygons, return them as std::vector pa
|
||||
* @param pa: pointer on a std::vector<CPolyLine*> to store extra polylines
|
||||
* @param bRetainArcs == TRUE, try to retain arcs in polys
|
||||
* @return number of external contours, or -1 if error
|
||||
*/
|
||||
int NormalizeWithKbool( std::vector<CPolyLine*> * pa, bool bRetainArcs );
|
||||
|
||||
private:
|
||||
int m_layer; // layer to draw on
|
||||
int m_Width; // lines width when drawing. Provided but not really used
|
||||
int utility;
|
||||
int m_layer; // layer to draw on
|
||||
int m_Width; // lines width when drawing. Provided but not really used
|
||||
int utility;
|
||||
public:
|
||||
std::vector <CPolyPt> corner; // array of points for corners
|
||||
std::vector <int> side_style; // array of styles for sides
|
||||
int m_HatchStyle; // hatch style, see enum above
|
||||
std::vector <CSegment> m_HatchLines; // hatch lines
|
||||
std::vector <CPolyPt> corner; // array of points for corners
|
||||
std::vector <int> side_style; // array of styles for sides
|
||||
int m_HatchStyle; // hatch style, see enum above
|
||||
std::vector <CSegment> m_HatchLines; // hatch lines
|
||||
private:
|
||||
gpc_polygon * m_gpc_poly; // polygon in gpc format
|
||||
polygon * m_php_poly;
|
||||
bool bDrawn;
|
||||
Bool_Engine * m_Kbool_Poly_Engine; // polygons set in kbool engine data
|
||||
bool bDrawn;
|
||||
};
|
||||
|
||||
#endif // #ifndef POLYLINE_H
|
||||
#endif // #ifndef POLYLINE_H
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
// PolyLine.h ... definition of CPolyLine class
|
||||
//
|
||||
// A polyline contains one or more contours, where each contour
|
||||
// is defined by a list of corners and side-styles
|
||||
// There may be multiple contours in a polyline.
|
||||
// The last contour may be open or closed, any others must be closed.
|
||||
// All of the corners and side-styles are concatenated into 2 arrays,
|
||||
// separated by setting the end_contour flag of the last corner of
|
||||
// each contour.
|
||||
//
|
||||
// When used for copper areas, the first contour is the outer edge
|
||||
// of the area, subsequent ones are "holes" in the copper.
|
||||
|
||||
#ifndef POLYLINE2KICAD_H
|
||||
#define POLYLINE2KICAD_H
|
||||
|
||||
#define PCBU_PER_MIL 10
|
||||
#define NM_PER_MIL 10 // 25400
|
||||
|
||||
|
||||
#include "pad_shapes.h"
|
||||
|
||||
|
||||
class CRect {
|
||||
public:
|
||||
int left, right, top, bottom;
|
||||
};
|
||||
|
||||
class CPoint {
|
||||
public:
|
||||
int x, y;
|
||||
public:
|
||||
CPoint(void) { x = y = 0;};
|
||||
CPoint(int i, int j) { x = i; y = j;};
|
||||
};
|
||||
|
||||
#endif // #ifndef POLYLINE2KICAD_H
|
|
@ -1,39 +0,0 @@
|
|||
/**********************/
|
||||
/* Some usual defines */
|
||||
/**********************/
|
||||
|
||||
#ifndef DEFS_MACROS_H
|
||||
#define DEFS_MACROS_H
|
||||
|
||||
#ifndef BOOL
|
||||
#define BOOL bool
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE false
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE true
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#ifndef abs
|
||||
#define abs(x) (((x) >=0) ? (x) : (-(x)))
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef min
|
||||
#define min(x,y) (((x) <= (y)) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
#ifndef max
|
||||
#define max(x,y) (((x) >= (y)) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
#define TRACE printf
|
||||
|
||||
#endif // ifndef DEFS_MACROS_H
|
|
@ -0,0 +1,4 @@
|
|||
PROJECT( kbool )
|
||||
|
||||
SUBDIRS( src samples )
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,405 @@
|
|||
/*! \file kbool/include/kbool/_dl_itr.h
|
||||
\author Probably Klaas Holwerda
|
||||
|
||||
Copyright: 2001-2004 (C) Probably Klaas Holwerda
|
||||
|
||||
Licence: wxWidgets Licence
|
||||
|
||||
RCS-ID: $Id: _dl_itr.h,v 1.1 2005/05/24 19:13:35 titato Exp $
|
||||
*/
|
||||
|
||||
//! author="Klaas Holwerda"
|
||||
/*
|
||||
* Definitions of classes, for list implementation
|
||||
* template list and iterator for any list node type
|
||||
*/
|
||||
|
||||
#ifndef _DL_Iter_H
|
||||
#define _DL_Iter_H
|
||||
|
||||
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
|
||||
#pragma interface
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "../include/booleng.h"
|
||||
|
||||
#ifndef _STATUS_ENUM
|
||||
#define _STATUS_ENUM
|
||||
//!<enum Error codes for List and iterator class
|
||||
enum Lerror {
|
||||
NO_MES, /*!<No Message will be generated */
|
||||
NO_LIST, /*!<List is not attached to the iterator*/
|
||||
NO_LIST_OTHER, /*!<no attached list on other iter*/
|
||||
AC_ITER_LIST_OTHER, /*!<iter not allowed on other list */
|
||||
SAME_LIST, /*!<same list not allowed*/
|
||||
NOT_SAME_LIST, /*!<must be same list*/
|
||||
ITER_GT_1, /*!<more then one iteriter at root*/
|
||||
ITER_GT_0, /*!<iter not allowed*/
|
||||
ITER_HITROOT, /*!<iter at root*/
|
||||
NO_ITEM, /*!<no item at current*/
|
||||
NO_NEXT, /*!<no next after current*/
|
||||
NO_PREV, /*!<no prev before current */
|
||||
EMPTY, /*!<list is empty*/
|
||||
NOT_ALLOW, /*!<not allowed*/
|
||||
ITER_NEG /*!<to much iters deleted*/
|
||||
};
|
||||
#endif
|
||||
|
||||
#define SWAP(x,y,t)((t)=(x),(x)=(y),(y)=(t))
|
||||
#define RT _list->_root
|
||||
#define HD _list->_root->_next
|
||||
#define TL _list->_root->_prev
|
||||
#define NB _list->_nbitems
|
||||
|
||||
template <class Dtype> class DL_List;
|
||||
template <class Dtype> class DL_Iter;
|
||||
template <class Dtype> class DL_SortIter;
|
||||
|
||||
//! Template class DL_Node
|
||||
template <class Dtype> class DL_Node
|
||||
{
|
||||
friend class DL_List<Dtype>;
|
||||
friend class DL_Iter<Dtype>;
|
||||
friend class DL_SortIter<Dtype>;
|
||||
|
||||
//!Public members
|
||||
public:
|
||||
//!Template constructor no contents
|
||||
//!Construct a node for a list object
|
||||
DL_Node();
|
||||
|
||||
//!constructor with init of Dtype
|
||||
DL_Node( Dtype n );
|
||||
|
||||
//!Destructor
|
||||
~DL_Node();
|
||||
|
||||
//!Public members
|
||||
public:
|
||||
//!data in node
|
||||
Dtype _item;
|
||||
|
||||
//!pointer to next node
|
||||
DL_Node* _next;
|
||||
|
||||
//!pointer to previous node
|
||||
DL_Node* _prev;
|
||||
};
|
||||
|
||||
//!Template class DL_List
|
||||
template <class Dtype> class DL_List
|
||||
{
|
||||
friend class DL_Iter<Dtype>;
|
||||
friend class DL_SortIter<Dtype>;
|
||||
|
||||
public:
|
||||
//!Constructor
|
||||
//!Construct a list object
|
||||
//!!tcarg class | Dtype | list object
|
||||
DL_List();
|
||||
|
||||
//!destructor
|
||||
~DL_List();
|
||||
|
||||
//!Report off List Errors
|
||||
void Error(const char* function,Lerror a_error);
|
||||
|
||||
//!Number of items in the list
|
||||
int count();
|
||||
|
||||
//!Empty List?
|
||||
bool empty();
|
||||
|
||||
//!insert the object given at the end of the list, after tail
|
||||
DL_Node<Dtype>* insend( Dtype n );
|
||||
|
||||
//!insert the object given at the begin of the list, before head
|
||||
DL_Node<Dtype>* insbegin( Dtype n );
|
||||
|
||||
//!remove the object at the begin of the list (head)
|
||||
void removehead();
|
||||
|
||||
//! remove the object at the end of the list (tail)
|
||||
void removetail();
|
||||
|
||||
//!remove all objects from the list
|
||||
void remove_all( bool deleteObject = false );
|
||||
|
||||
//!Get the item at the head of the list
|
||||
Dtype headitem();
|
||||
|
||||
//!Get the item at the tail of the list
|
||||
Dtype tailitem();
|
||||
|
||||
//! to move all objects in a list to this list.
|
||||
void takeover(DL_List<Dtype>* otherlist);
|
||||
|
||||
public:
|
||||
//!the root node pointer of the list, the first and last node
|
||||
//! in the list are connected to the root node. The root node is used
|
||||
//! to detect the end / beginning of the list while traversing it.
|
||||
DL_Node<Dtype>* _root;
|
||||
|
||||
//!the number of items in the list, if empty list it is 0
|
||||
int _nbitems;
|
||||
|
||||
//!number of iterators on the list, Attaching or instantiating an iterator to list,
|
||||
//! will increment this member, detaching and
|
||||
//! destruction of iterator for a list will decrement this number
|
||||
short int _iterlevel;
|
||||
};
|
||||
|
||||
//! Template class DL_Iter for iterator on DL_List
|
||||
template <class Dtype>
|
||||
class DL_Iter
|
||||
{
|
||||
public:
|
||||
//!Construct an iterator object for a given list of type Dtype
|
||||
DL_Iter(DL_List<Dtype>* newlist);
|
||||
|
||||
//!Constructor of iterator for the same list as another iterator
|
||||
DL_Iter(DL_Iter* otheriter);
|
||||
|
||||
//!Constructor without an attached list
|
||||
DL_Iter();
|
||||
|
||||
//!destructor
|
||||
~DL_Iter();
|
||||
|
||||
//!Report off Iterator Errors
|
||||
void Error(const char* function,Lerror a_error);
|
||||
|
||||
//!This attaches an iterator to a list of a given type.
|
||||
void Attach(DL_List<Dtype>* newlist);
|
||||
|
||||
//!This detaches an iterator from a list
|
||||
void Detach();
|
||||
|
||||
//!execute given function for each item in the list/iterator
|
||||
void foreach_f(void (*fp) (Dtype n) );
|
||||
|
||||
//! list mutations
|
||||
|
||||
//!insert after tail item
|
||||
DL_Node<Dtype>* insend(Dtype n);
|
||||
|
||||
//!insert before head item
|
||||
DL_Node<Dtype>* insbegin(Dtype n);
|
||||
|
||||
//!insert before current iterator position
|
||||
DL_Node<Dtype>* insbefore(Dtype n);
|
||||
|
||||
//!insert after current iterator position
|
||||
DL_Node<Dtype>* insafter(Dtype n);
|
||||
|
||||
//!to move all objects in a list to the list of the iterator.
|
||||
void takeover(DL_List<Dtype>* otherlist);
|
||||
|
||||
//!to move all objects in a list (using iterator of that list) to the list of the iterator
|
||||
void takeover(DL_Iter* otheriter);
|
||||
|
||||
//! to move maxcount objects in a list (using iterator of that list) to the list of the iterator
|
||||
void takeover(DL_Iter* otheriter, int maxcount);
|
||||
|
||||
//!remove object at current iterator position from the list.
|
||||
void remove();
|
||||
|
||||
//!Remove head item
|
||||
void removehead();
|
||||
|
||||
//!Remove tail item
|
||||
void removetail();
|
||||
|
||||
//!Remove all items
|
||||
void remove_all();
|
||||
|
||||
|
||||
/* void foreach_mf(void (Dtype::*mfp)() ); //call Dtype::mfp for each item */
|
||||
|
||||
//!is list empty (contains items or not)?
|
||||
bool empty();
|
||||
|
||||
//!is iterator at root node (begin or end)?
|
||||
bool hitroot();
|
||||
|
||||
//!is iterator at head/first node?
|
||||
bool athead();
|
||||
|
||||
//!is iterator at tail/last node?
|
||||
bool attail();
|
||||
|
||||
//!is given item member of the list
|
||||
bool has(Dtype otheritem);
|
||||
|
||||
//!Number of items in the list
|
||||
int count();
|
||||
|
||||
/* cursor movements */
|
||||
|
||||
//!go to last item, if list is empty goto hite
|
||||
void totail();
|
||||
|
||||
//!go to first item, if list is empty goto hite
|
||||
void tohead();
|
||||
|
||||
//!set the iterator position to the root (empty dummy) object in the list.
|
||||
void toroot();
|
||||
|
||||
//! set the iterator position to next object in the list ( can be the root also).
|
||||
void operator++ (void);
|
||||
|
||||
//!set iterator to next item (pre fix)
|
||||
void operator++ (int);
|
||||
|
||||
//!set the iterator position to previous object in the list ( can be the root also)(postfix).
|
||||
void operator-- (void);
|
||||
|
||||
//!set the iterator position to previous object in the list ( can be the root also)(pre fix).
|
||||
void operator-- (int);
|
||||
|
||||
//!set the iterator position n objects in the next direction ( can be the root also).
|
||||
void operator>> (int);
|
||||
|
||||
//!set the iterator position n objects in the previous direction ( can be the root also).
|
||||
void operator<< (int);
|
||||
|
||||
//!set the iterator position to next object in the list, if this would be the root object,
|
||||
//!then set the iterator at the head object
|
||||
void next_wrap();
|
||||
|
||||
//!set the iterator position to previous object in the list, if this would be the root object,
|
||||
//!then set the iterator at the tail object
|
||||
void prev_wrap();
|
||||
|
||||
//!move root in order to make the current node the tail
|
||||
void reset_tail();
|
||||
|
||||
//!move root in order to make the current node the head
|
||||
void reset_head();
|
||||
|
||||
//!put the iterator at the position of the given object in the list.
|
||||
bool toitem(Dtype);
|
||||
|
||||
//!put the iterator at the same position as the given iterator in the list.
|
||||
void toiter(DL_Iter* otheriter);
|
||||
|
||||
//!put the iterator at the position of the given node in the list.
|
||||
bool tonode(DL_Node<Dtype>*);
|
||||
|
||||
//!iterate through all items of the list
|
||||
bool iterate(void);
|
||||
|
||||
//!To get the item at the current iterator position
|
||||
Dtype item();
|
||||
|
||||
//! get node at iterator
|
||||
DL_Node<Dtype>* node();
|
||||
|
||||
//!sort list with mergesort
|
||||
void mergesort(int (*fcmp) (Dtype, Dtype));
|
||||
|
||||
//!sort list with cocktailsort
|
||||
/*!
|
||||
\return number of swaps done.
|
||||
*/
|
||||
int cocktailsort(int (*)(Dtype,Dtype), bool (*)(Dtype,Dtype)=NULL);
|
||||
|
||||
protected:
|
||||
|
||||
//!sort list with mergesort
|
||||
void mergesort_rec(int (*fcmp)(Dtype,Dtype), DL_Node<Dtype> *RT1,int n);
|
||||
|
||||
//!sort list with mergesort
|
||||
void mergetwo(int (*fcmp)(Dtype,Dtype), DL_Node<Dtype> *RT1,DL_Node<Dtype> *RT2);
|
||||
|
||||
//!set the iterator position to next object in the list ( can be the root also).
|
||||
void next();
|
||||
|
||||
//!set the iterator position to previous object in the list ( can be the root also).
|
||||
void prev();
|
||||
|
||||
//!the list for this iterator
|
||||
DL_List<Dtype> *_list;
|
||||
|
||||
//!the current position of the iterator
|
||||
DL_Node<Dtype> *_current;
|
||||
};
|
||||
|
||||
|
||||
//! template class DL_StackIter class for stack iterator on DL_List
|
||||
template <class Dtype>
|
||||
class DL_StackIter :protected DL_Iter<Dtype>
|
||||
{
|
||||
public:
|
||||
//!Constructor of stack iterator for given list
|
||||
DL_StackIter(DL_List<Dtype> *);
|
||||
//!Constructor of stack iterator no list attached
|
||||
DL_StackIter();
|
||||
|
||||
//!Destructor of stack iterator
|
||||
~DL_StackIter();
|
||||
|
||||
//!Remove all items from the stack
|
||||
void remove_all();
|
||||
//!push given item on the stack
|
||||
void push(Dtype n);
|
||||
//!get last inserted item from stack
|
||||
Dtype pop();
|
||||
//!is stack empty?
|
||||
bool empty();
|
||||
//!number of items on the stack
|
||||
int count();
|
||||
};
|
||||
|
||||
//!template class DL_SortIter
|
||||
template <class DType> class DL_SortIter :public DL_Iter<DType>
|
||||
{
|
||||
public:
|
||||
//!Constructor of sort iterator for given list and sort function
|
||||
DL_SortIter(DL_List<DType>* nw_list, int (*new_func)(DType ,DType ));
|
||||
|
||||
//!Constructor of sort iterator with sort function and no list attached
|
||||
DL_SortIter(int (*newfunc)(DType,DType));
|
||||
|
||||
//!Destructor of sort iterator
|
||||
~DL_SortIter();
|
||||
|
||||
//!insert item in sorted order
|
||||
void insert (DType new_item);
|
||||
|
||||
/*override following functions to give an error */
|
||||
//!Not allowed
|
||||
void insend (bool n){sortitererror();};
|
||||
//!Not allowed
|
||||
void insbegin (bool n){sortitererror();};
|
||||
//!Not allowed
|
||||
void insbefore (bool n){sortitererror();};
|
||||
//!Not allowed
|
||||
void insafter (bool n){sortitererror();};
|
||||
//!Not allowed
|
||||
void takeover (DL_List<DType>*){sortitererror();};
|
||||
//!Not allowed
|
||||
void takeover (DL_Iter<DType>*){sortitererror();};
|
||||
//!Not allowed
|
||||
void takeover (DL_Iter<DType>* otheriter, int maxcount){sortitererror();};
|
||||
//!Not allowed
|
||||
void next_wrap() {sortitererror();};
|
||||
//!Not allowed
|
||||
void prev_wrap() {sortitererror();};
|
||||
//!Not allowed
|
||||
void reset_tail() {sortitererror();};
|
||||
//!Not allowed
|
||||
void reset_head() {sortitererror();};
|
||||
|
||||
private:
|
||||
//!Report off Iterator Errors
|
||||
void sortitererror();
|
||||
|
||||
//!comparefunction used to insert items in sorted order
|
||||
int (*comparef)(DType, DType);
|
||||
};
|
||||
|
||||
#include "../include/_dl_itr.cpp"
|
||||
|
||||
#endif
|
|
@ -0,0 +1,269 @@
|
|||
/*! \file kbool/include/kbool/_lnk_itr.cpp
|
||||
\author Probably Klaas Holwerda
|
||||
|
||||
Copyright: 2001-2004 (C) Probably Klaas Holwerda
|
||||
|
||||
Licence: wxWidgets Licence
|
||||
|
||||
RCS-ID: $Id: _lnk_itr.cpp,v 1.1 2005/05/24 19:13:36 titato Exp $
|
||||
*/
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma implementation
|
||||
#endif
|
||||
|
||||
#ifdef __UNIX__
|
||||
#include "kbool/include/_lnk_itr.h"
|
||||
#endif
|
||||
|
||||
//=======================================================================
|
||||
// implementation class LinkBaseIter
|
||||
//=======================================================================
|
||||
|
||||
template<class Type>
|
||||
TDLI<Type>::TDLI(DL_List<void*>* newlist):DL_Iter<void*>(newlist)
|
||||
{
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
TDLI<Type>::TDLI(DL_Iter<void*>* otheriter):DL_Iter<void*>(otheriter)
|
||||
{
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
TDLI<Type>::TDLI():DL_Iter<void*>()
|
||||
{
|
||||
}
|
||||
|
||||
// destructor TDLI
|
||||
template<class Type>
|
||||
TDLI<Type>::~TDLI()
|
||||
{
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
void TDLI<Type>::delete_all()
|
||||
{
|
||||
DL_Node<void*>* node;
|
||||
Type* obj;
|
||||
for (int i=0; i< NB; i++)
|
||||
{
|
||||
node = HD;
|
||||
HD = node->_next;
|
||||
obj=(Type*)(node->_item);
|
||||
delete obj;
|
||||
delete node;
|
||||
}
|
||||
NB=0; //reset memory used (no lost pointers)
|
||||
TL=RT;
|
||||
_current=RT;
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
void TDLI<Type>::foreach_f(void (*fp) (Type* item) )
|
||||
{
|
||||
DL_Iter<void*>::foreach_f( (void (*)(void*))fp); //call fp for each item
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
void TDLI<Type>::foreach_mf(void (Type::*mfp) ())
|
||||
{
|
||||
|
||||
DL_Node<void*>* node=HD; //can be 0 if empty
|
||||
Type* obj;
|
||||
for(int i=0; i< NB; i++)
|
||||
{
|
||||
obj=(Type*)(node->_item);
|
||||
(obj->*mfp)();
|
||||
node=node->_next;
|
||||
}
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
void TDLI<Type>::takeover(DL_List<void*>* otherlist)
|
||||
{
|
||||
DL_Iter<void*>::takeover( (DL_List<void*>*) otherlist);
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
void TDLI<Type>::takeover(TDLI* otheriter)
|
||||
{
|
||||
DL_Iter<void*>::takeover( (DL_Iter<void*>*) otheriter);
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
void TDLI<Type>::takeover(TDLI* otheriter,int maxcount)
|
||||
{
|
||||
DL_Iter<void*>::takeover( (DL_Iter<void*>*) otheriter,maxcount);
|
||||
}
|
||||
|
||||
// is item element of the list?
|
||||
template<class Type>
|
||||
bool TDLI<Type>::has(Type* otheritem)
|
||||
{
|
||||
return DL_Iter<void*>::has( (void*) otheritem);
|
||||
}
|
||||
|
||||
// goto to item
|
||||
template<class Type>
|
||||
bool TDLI<Type>::toitem(Type* item)
|
||||
{
|
||||
return DL_Iter<void*>::toitem( (void*) item);
|
||||
}
|
||||
|
||||
// get current item
|
||||
template<class Type>
|
||||
Type* TDLI<Type>::item()
|
||||
{
|
||||
return (Type*) DL_Iter<void*>::item();
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
void TDLI<Type>::insend(Type* newitem)
|
||||
{
|
||||
DL_Iter<void*>::insend( (void*) newitem);
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
void TDLI<Type>::insbegin(Type* newitem)
|
||||
{
|
||||
DL_Iter<void*>::insbegin( (void*) newitem);
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
void TDLI<Type>::insbefore(Type* newitem)
|
||||
{
|
||||
DL_Iter<void*>::insbefore( (void*) newitem);
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
void TDLI<Type>::insafter(Type* newitem)
|
||||
{
|
||||
DL_Iter<void*>::insafter( (void*) newitem);
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
void TDLI<Type>::insend_unsave(Type* newitem)
|
||||
{
|
||||
short int iterbackup=_list->_iterlevel;
|
||||
_list->_iterlevel=0;
|
||||
DL_Iter<void*>::insend( (void*) newitem);
|
||||
_list->_iterlevel=iterbackup;
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
void TDLI<Type>::insbegin_unsave(Type* newitem)
|
||||
{
|
||||
short int iterbackup=_list->_iterlevel;
|
||||
_list->_iterlevel=0;
|
||||
DL_Iter<void*>::insbegin( (void*) newitem);
|
||||
_list->_iterlevel=iterbackup;
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
void TDLI<Type>::insbefore_unsave(Type* newitem)
|
||||
{
|
||||
short int iterbackup=_list->_iterlevel;
|
||||
_list->_iterlevel=0;
|
||||
DL_Iter<void*>::insbefore( (void*) newitem);
|
||||
_list->_iterlevel=iterbackup;
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
void TDLI<Type>::insafter_unsave(Type* newitem)
|
||||
{
|
||||
short int iterbackup=_list->_iterlevel;
|
||||
_list->_iterlevel=0;
|
||||
DL_Iter<void*>::insafter( (void*) newitem);
|
||||
_list->_iterlevel=iterbackup;
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
void TDLI<Type>::mergesort(int (*f)(Type* a,Type* b))
|
||||
{
|
||||
DL_Iter<void*>::mergesort( (int (*)(void*,void*)) f);
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
int TDLI<Type>::cocktailsort(int (*f)(Type* a,Type* b), bool (*f2)(Type* c,Type* d))
|
||||
{
|
||||
return DL_Iter<void*>::cocktailsort( (int (*)(void*,void*)) f,( bool(*)(void*,void*)) f2);
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
TDLISort<Type>::TDLISort(DL_List<void*>* lista, int (*newfunc)(void*,void*))
|
||||
:DL_SortIter<void*>(lista, newfunc)
|
||||
{
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
TDLISort<Type>::~TDLISort()
|
||||
{
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
void TDLISort<Type>::delete_all()
|
||||
{
|
||||
DL_Node<void*>* node;
|
||||
Type* obj;
|
||||
for (int i=0; i< NB; i++)
|
||||
{
|
||||
node = HD;
|
||||
HD = node->_next;
|
||||
obj=(Type*)(node->_item);
|
||||
delete obj;
|
||||
delete node;
|
||||
}
|
||||
NB=0; //reset memory used (no lost pointers)
|
||||
TL=RT;
|
||||
_current=RT;
|
||||
}
|
||||
|
||||
// is item element of the list?
|
||||
template<class Type>
|
||||
bool TDLISort<Type>::has(Type* otheritem)
|
||||
{
|
||||
return DL_Iter<void*>::has( (void*) otheritem);
|
||||
}
|
||||
|
||||
// goto to item
|
||||
template<class Type>
|
||||
bool TDLISort<Type>::toitem(Type* item)
|
||||
{
|
||||
return DL_Iter<void*>::toitem( (void*) item);
|
||||
}
|
||||
|
||||
// get current item
|
||||
template<class Type>
|
||||
Type* TDLISort<Type>::item()
|
||||
{
|
||||
return (Type*) DL_Iter<void*>::item();
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
TDLIStack<Type>::TDLIStack(DL_List<void*>* newlist):DL_StackIter<void*>(newlist)
|
||||
{
|
||||
}
|
||||
|
||||
// destructor TDLI
|
||||
template<class Type>
|
||||
TDLIStack<Type>::~TDLIStack()
|
||||
{
|
||||
}
|
||||
|
||||
// plaats nieuw item op stack
|
||||
template<class Type>
|
||||
void TDLIStack<Type>::push(Type* newitem)
|
||||
{
|
||||
DL_StackIter<void*>::push((Type*) newitem);
|
||||
}
|
||||
|
||||
|
||||
// haal bovenste item van stack
|
||||
template<class Type>
|
||||
Type* TDLIStack<Type>::pop()
|
||||
{
|
||||
return (Type*) DL_StackIter<void*>::pop();
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,163 @@
|
|||
/*! \file kbool/include/kbool/_lnk_itr.h
|
||||
\author Probably Klaas Holwerda
|
||||
|
||||
Copyright: 2001-2004 (C) Probably Klaas Holwerda
|
||||
|
||||
Licence: wxWidgets Licence
|
||||
|
||||
RCS-ID: $Id: _lnk_itr.h,v 1.1 2005/05/24 19:13:36 titato Exp $
|
||||
*/
|
||||
|
||||
//! author="Klaas Holwerda"
|
||||
//! version="1.0"
|
||||
/*
|
||||
* Definitions of classes, for list implementation
|
||||
* template list and iterator for any list node type
|
||||
*/
|
||||
#ifndef _LinkBaseIter_H
|
||||
#define _LinkBaseIter_H
|
||||
|
||||
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
|
||||
#pragma interface
|
||||
#endif
|
||||
|
||||
//! headerfiles="_dl_itr.h stdlib.h misc.h gdsmes.h"
|
||||
#include <stdlib.h>
|
||||
#include "../include/booleng.h"
|
||||
|
||||
#define SWAP(x,y,t)((t)=(x),(x)=(y),(y)=(t))
|
||||
|
||||
#include "../include/_dl_itr.h"
|
||||
|
||||
//! codefiles="_dl_itr.cpp"
|
||||
|
||||
//! Template class TDLI
|
||||
/*!
|
||||
class for iterator on DL_List<void*> that is type casted version of DL_Iter
|
||||
\sa DL_Iter for further documentation
|
||||
*/
|
||||
template<class Type> class TDLI : public DL_Iter<void*>
|
||||
{
|
||||
public:
|
||||
//!constructor
|
||||
/*!
|
||||
\param list to iterate on.
|
||||
*/
|
||||
TDLI(DL_List<void*>* list);
|
||||
|
||||
//!constructor
|
||||
TDLI(DL_Iter<void*>* otheriter);
|
||||
|
||||
//! nolist constructor
|
||||
TDLI();
|
||||
|
||||
//! destructor
|
||||
~TDLI();
|
||||
|
||||
//!call fp for each item
|
||||
void foreach_f(void (*fp) (Type* item) );
|
||||
|
||||
//!call fp for each item
|
||||
void foreach_mf(void (Type::*fp) () );
|
||||
|
||||
/* list mutations */
|
||||
|
||||
|
||||
//! delete all items
|
||||
void delete_all ();
|
||||
|
||||
|
||||
//! insert at end
|
||||
void insend (Type* n);
|
||||
|
||||
//! insert at begin
|
||||
void insbegin (Type* n);
|
||||
|
||||
//! insert before current
|
||||
void insbefore (Type* n);
|
||||
|
||||
//! insert after current
|
||||
void insafter (Type* n);
|
||||
|
||||
//! insert at end unsave (works even if more then one iterator is on the list
|
||||
//! the user must be sure not to delete/remove items where other iterators
|
||||
//! are pointing to.
|
||||
void insend_unsave (Type* n);
|
||||
|
||||
//! insert at begin unsave (works even if more then one iterator is on the list
|
||||
//! the user must be sure not to delete/remove items where other iterators
|
||||
//! are pointing to.
|
||||
void insbegin_unsave (Type* n);
|
||||
|
||||
//! insert before iterator position unsave (works even if more then one iterator is on the list
|
||||
//! the user must be sure not to delete/remove items where other iterators
|
||||
//! are pointing to.
|
||||
void insbefore_unsave (Type* n);
|
||||
|
||||
//! insert after iterator position unsave (works even if more then one iterator is on the list
|
||||
//! the user must be sure not to delete/remove items where other iterators
|
||||
//! are pointing to.
|
||||
void insafter_unsave (Type* n);
|
||||
|
||||
//! \sa DL_Iter::takeover(DL_List< Dtype >* otherlist )
|
||||
void takeover (DL_List<void*>* otherlist);
|
||||
//! \sa DL_Iter::takeover(DL_Iter* otheriter)
|
||||
void takeover (TDLI* otheriter);
|
||||
//! \sa DL_Iter::takeover(DL_Iter* otheriter, int maxcount)
|
||||
void takeover (TDLI* otheriter, int maxcount);
|
||||
|
||||
//! \sa DL_Iter::has
|
||||
bool has (Type*);
|
||||
//! \sa DL_Iter::toitem
|
||||
bool toitem (Type*);
|
||||
|
||||
//!get the item then iterator is pointing at
|
||||
Type* item ();
|
||||
|
||||
//! \sa DL_Iter::mergesort
|
||||
void mergesort (int (*f)(Type* a,Type* b));
|
||||
//! \sa DL_Iter::cocktailsort
|
||||
int cocktailsort( int (*) (Type* a,Type* b), bool (*) (Type* c,Type* d) = NULL);
|
||||
|
||||
};
|
||||
|
||||
//! Template class TDLIsort
|
||||
/*!
|
||||
// class for sort iterator on DL_List<void*> that is type casted version of DL_SortIter
|
||||
// see also inhereted class DL_SortIter for further documentation
|
||||
*/
|
||||
template<class Type> class TDLISort : public DL_SortIter<void*>
|
||||
{
|
||||
public:
|
||||
|
||||
//!constructor givin a list and a sort function
|
||||
TDLISort(DL_List<void*>* list, int (*newfunc)(void*,void*));
|
||||
~TDLISort();
|
||||
|
||||
//!delete all items from the list
|
||||
void delete_all();
|
||||
bool has (Type*);
|
||||
bool toitem (Type*);
|
||||
Type* item ();
|
||||
};
|
||||
|
||||
//! Template class TDLIStack
|
||||
/*!
|
||||
class for iterator on DL_List<void*> that is type casted version of DL_StackIter
|
||||
see also inhereted class DL_StackIter for further documentation
|
||||
*/
|
||||
template<class Type> class TDLIStack : public DL_StackIter<void*>
|
||||
{
|
||||
public:
|
||||
//constructor givin a list
|
||||
TDLIStack(DL_List<void*>* list);
|
||||
|
||||
~TDLIStack();
|
||||
|
||||
void push(Type*);
|
||||
Type* pop();
|
||||
};
|
||||
|
||||
#include"../include/_lnk_itr.cpp"
|
||||
|
||||
#endif
|
|
@ -0,0 +1,540 @@
|
|||
/*! \file kbool/include/kbool/booleng.h
|
||||
\author Probably Klaas Holwerda
|
||||
|
||||
Copyright: 2001-2004 (C) Probably Klaas Holwerda
|
||||
|
||||
Licence: wxWidgets Licence
|
||||
|
||||
RCS-ID: $Id: booleng.h,v 1.3 2005/06/11 19:25:12 frm Exp $
|
||||
*/
|
||||
|
||||
#ifndef BOOLENG_H
|
||||
#define BOOLENG_H
|
||||
|
||||
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
|
||||
#pragma interface
|
||||
#endif
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
|
||||
|
||||
#ifdef A2DKBOOLMAKINGDLL
|
||||
#define A2DKBOOLDLLEXP WXEXPORT
|
||||
#define A2DKBOOLDLLEXP_DATA(type) WXEXPORT type
|
||||
#define A2DKBOOLDLLEXP_CTORFN
|
||||
#elif defined(WXUSINGDLL)
|
||||
#define A2DKBOOLDLLEXP WXIMPORT
|
||||
#define A2DKBOOLDLLEXP_DATA(type) WXIMPORT type
|
||||
#define A2DKBOOLDLLEXP_CTORFN
|
||||
#else // not making nor using DLL
|
||||
#define A2DKBOOLDLLEXP
|
||||
#define A2DKBOOLDLLEXP_DATA(type) type
|
||||
#define A2DKBOOLDLLEXP_CTORFN
|
||||
#endif
|
||||
|
||||
#define KBOOL_VERSION "1.8"
|
||||
|
||||
#define KBOOL_DEBUG 0
|
||||
#define KBOOL_LOG 0
|
||||
#define KBOOL_INT64 1
|
||||
|
||||
class KBoolLink;
|
||||
|
||||
#define LINELENGTH 200
|
||||
|
||||
#ifdef MAXDOUBLE
|
||||
#undef MAXDOUBLE
|
||||
#endif
|
||||
#define MAXDOUBLE 1.7976931348623158e+308
|
||||
|
||||
#ifdef KBOOL_INT64
|
||||
|
||||
#if defined(__UNIX__) || defined(__GNUG__)
|
||||
|
||||
typedef long long B_INT; // 8 bytes integer
|
||||
//#define MAXB_INT LONG_LONG_MAX
|
||||
//#define MINB_INT LONG_LONG_MIN // 8 bytes integer
|
||||
#ifndef MAXB_INT
|
||||
const B_INT MAXB_INT = (0x7fffffffffffffffLL); // 8 bytes integer
|
||||
#endif
|
||||
#ifndef MINB_INT
|
||||
const B_INT MINB_INT = (0x8000000000000000LL);
|
||||
#endif
|
||||
|
||||
#else //defined(__UNIX__) || defined(__GNUG__)
|
||||
|
||||
typedef __int64 B_INT; // 8 bytes integer
|
||||
#undef MAXB_INT
|
||||
#undef MINB_INT
|
||||
|
||||
const B_INT MAXB_INT = (0x7fffffffffffffff); // 8 bytes integer
|
||||
const B_INT MINB_INT = (0x8000000000000000);
|
||||
|
||||
#endif //defined(__UNIX__) || defined(__GNUG__)
|
||||
|
||||
#else //KBOOL_INT64
|
||||
|
||||
#if defined(__UNIX__) || defined(__GNUG__)
|
||||
typedef long B_INT; // 4 bytes integer
|
||||
const B_INT MAXB_INT = (0x7fffffffL); // 4 bytes integer
|
||||
const B_INT MINB_INT = (0x80000000L);
|
||||
#else
|
||||
typedef long B_INT; // 4 bytes integer
|
||||
const B_INT MAXB_INT = (0x7fffffff); // 4 bytes integer
|
||||
const B_INT MINB_INT = (0x80000000);
|
||||
#endif
|
||||
|
||||
#endif //KBOOL_INT64
|
||||
|
||||
B_INT babs(B_INT);
|
||||
|
||||
#ifdef M_PI
|
||||
#undef M_PI
|
||||
#endif
|
||||
#define M_PI (3.1415926535897932384626433832795028841972)
|
||||
|
||||
#ifdef M_PI_2
|
||||
#undef M_PI_2
|
||||
#endif
|
||||
#define M_PI_2 1.57079632679489661923
|
||||
|
||||
#ifdef M_PI_4
|
||||
#undef M_PI_4
|
||||
#endif
|
||||
#define M_PI_4 0.785398163397448309616
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
B_INT bmin(B_INT const value1, B_INT const value2);
|
||||
B_INT bmax(B_INT const value1, B_INT const value2);
|
||||
|
||||
B_INT bmin(B_INT value1, B_INT value2);
|
||||
B_INT bmax(B_INT value1, B_INT value2);
|
||||
|
||||
#include <string.h>
|
||||
|
||||
//! errors in the boolean algorithm will be thrown using this class
|
||||
class A2DKBOOLDLLEXP Bool_Engine_Error
|
||||
{
|
||||
public:
|
||||
Bool_Engine_Error(const char* message, const char* header=0, int degree = 9, int fatal = 0);
|
||||
Bool_Engine_Error(const Bool_Engine_Error& a);
|
||||
~Bool_Engine_Error();
|
||||
char* GetErrorMessage();
|
||||
char* GetHeaderMessage();
|
||||
int GetErrorDegree();
|
||||
int GetFatal();
|
||||
|
||||
protected:
|
||||
char* _message;
|
||||
char* _header;
|
||||
int _degree;
|
||||
int _fatal;
|
||||
};
|
||||
|
||||
|
||||
#define KBOOL_LOGFILE "kbool.log"
|
||||
|
||||
enum kbEdgeType
|
||||
{
|
||||
KB_OUTSIDE_EDGE, /*!< edge of the outside contour of a polygon */
|
||||
KB_INSIDE_EDGE, /*!< edge of the inside hole a polygon */
|
||||
KB_FALSE_EDGE /*!< edge to connect holes into polygons */
|
||||
} ;
|
||||
|
||||
enum GroupType
|
||||
{
|
||||
GROUP_A, /*!< to set Group A for polygons */
|
||||
GROUP_B /*!< to set Group A for polygons */
|
||||
};
|
||||
|
||||
enum BOOL_OP
|
||||
{
|
||||
BOOL_NON, /*!< No operation */
|
||||
BOOL_OR, /*!< boolean OR operation */
|
||||
BOOL_AND, /*!< boolean AND operation */
|
||||
BOOL_EXOR, /*!< boolean EX_OR operation */
|
||||
BOOL_A_SUB_B, /*!< boolean Group A - Group B operation */
|
||||
BOOL_B_SUB_A, /*!< boolean Group B - Group A operation */
|
||||
BOOL_CORRECTION, /*!< polygon correction/offset operation */
|
||||
BOOL_SMOOTHEN, /*!< smooth operation */
|
||||
BOOL_MAKERING /*!< create a ring on all polygons */
|
||||
};
|
||||
|
||||
class GraphList;
|
||||
class Graph;
|
||||
class KBoolLink;
|
||||
class Node;
|
||||
template<class Type> class TDLI;
|
||||
|
||||
//! boolean engine to perform operation on two sets of polygons.
|
||||
/*
|
||||
First the engine needs to be filled with polygons.
|
||||
The first operand in the operation is called group A polygons, the second group B.
|
||||
The boolean operation ( BOOL_OR, BOOL_AND, BOOL_EXOR, BOOL_A_SUB_B, BOOL_B_SUB_A )
|
||||
are based on the two sets of polygons in group A and B.
|
||||
The other operation on group A only.
|
||||
|
||||
At the end of the operation the resulting polygons can be extracted.
|
||||
*/
|
||||
class A2DKBOOLDLLEXP Bool_Engine {
|
||||
|
||||
public:
|
||||
|
||||
//! constructor
|
||||
Bool_Engine();
|
||||
|
||||
//! destructor
|
||||
virtual ~Bool_Engine();
|
||||
|
||||
const char* GetVersion() { return KBOOL_VERSION; }
|
||||
|
||||
//! reports progress of algorithm.
|
||||
virtual void SetState( const char* = 0 );
|
||||
|
||||
//! called at an internal error.
|
||||
virtual void error(const char *text, const char *title);
|
||||
|
||||
//! called at an internal generated possible error.
|
||||
virtual void info(const char *text, const char *title);
|
||||
|
||||
bool Do_Operation(BOOL_OP operation);
|
||||
|
||||
|
||||
//! distance within which points and lines will be snapped towards lines and other points
|
||||
/*
|
||||
The algorithm takes into account gaps and inaccuracies caused by rounding to integer coordinates
|
||||
in the original data.
|
||||
Imagine two rectangles one with a side ( 0,0 ) ( 2.0, 17.0 )
|
||||
and the other has a side ( 0,0 ) ( 1.0, 8.5 )
|
||||
If for some reason those coordinates where round to ( 0,0 ) ( 2, 17 ) ( 0,0 ) ( 1, 9 ),
|
||||
there will be clearly a gap or overlap that was not intended.
|
||||
Even without rounding this effect takes place since there is always a minimum significant bit
|
||||
also when using doubles.
|
||||
|
||||
If the user used as minimum accuracy 0.001, you need to choose Marge > 0.001
|
||||
The boolean engine scales up the input data with GetDGrid() * GetGrid() and rounds the result to
|
||||
integer, So (assuming GRID = 100 DGRID = 1000) a vertex of 123.001 in the user data will
|
||||
become 12300100 internal.
|
||||
At the end of the algorithm the internal vertexes are scaled down again with GetDGrid() * GetGrid(),
|
||||
so 12300103 becomes 123.00103 eventually.
|
||||
So indeed the minimum accuracy might increase, you are free to round again if needed.
|
||||
*/
|
||||
void SetMarge(double marge);
|
||||
double GetMarge();
|
||||
|
||||
//! input points are scaled up with GetDGrid() * GetGrid()
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
void SetGrid(B_INT grid);
|
||||
|
||||
//! See SetGrid
|
||||
B_INT GetGrid();
|
||||
|
||||
//! input points are scaled up with GetDGrid() * GetGrid()
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
void SetDGrid(double dgrid);
|
||||
|
||||
//! See SetDGrid
|
||||
double GetDGrid();
|
||||
|
||||
//! When doing a correction operation ( also known as process offset )
|
||||
//! this defines the detail in the rounded corners.
|
||||
/*
|
||||
Depending on the round factor the corners of the polygon may be rounding within the correction
|
||||
algorithm. The detail within this rounded corner is set here.
|
||||
It defines the deviation the generated segments in arc like polygon may have towards the ideal
|
||||
rounded corner using a perfect arc.
|
||||
*/
|
||||
void SetCorrectionAber(double aber);
|
||||
|
||||
//! see SetCorrectionAber
|
||||
double GetCorrectionAber();
|
||||
|
||||
//! When doing a correction operation ( also known as process offset )
|
||||
//! this defines the amount of correction.
|
||||
/*
|
||||
The correction algorithm can apply positive and negative offset to polygons.
|
||||
It takes into account closed in areas within a polygon, caused by overlapping/selfintersecting
|
||||
polygons. So holes form that way are corrected proberly, but the overlapping parts itself
|
||||
are left alone. An often used trick to present polygons with holes by linking to the outside
|
||||
boundary, is therefore also handled properly.
|
||||
The algoritm first does a boolean OR operation on the polygon, and seperates holes and
|
||||
outside contours.
|
||||
After this it creates a ring shapes on the above holes and outside contours.
|
||||
This ring shape is added or subtracted from the holes and outside contours.
|
||||
The result is the corrected polygon.
|
||||
If the correction factor is > 0, the outside contours will become larger, while the hole contours
|
||||
will become smaller.
|
||||
*/
|
||||
void SetCorrectionFactor(double aber);
|
||||
|
||||
//! see SetCorrectionFactor
|
||||
double GetCorrectionFactor();
|
||||
|
||||
//! used within the smooth algorithm to define how much the smoothed curve may deviate
|
||||
//! from the original.
|
||||
void SetSmoothAber(double aber);
|
||||
|
||||
//! see SetSmoothAber
|
||||
double GetSmoothAber();
|
||||
|
||||
//! segments of this size will be left alone in the smooth algorithm.
|
||||
void SetMaxlinemerge(double maxline);
|
||||
|
||||
//! see SetMaxlinemerge
|
||||
double GetMaxlinemerge();
|
||||
|
||||
//! Polygon may be filled in different ways (alternate and winding rule).
|
||||
//! This here defines which method will be assumed within the algorithm.
|
||||
void SetWindingRule(bool rule);
|
||||
|
||||
//! see SetWindingRule
|
||||
bool GetWindingRule();
|
||||
|
||||
//! the smallest accuracy used within the algorithm for comparing two real numbers.
|
||||
double GetAccur();
|
||||
|
||||
//! Used with in correction/offset algorithm.
|
||||
/*
|
||||
When the polygon contains sharp angles ( < 90 ), after a positive correction the
|
||||
extended parrallel constructed offset lines may leed to extreme offsets on the angles.
|
||||
The length of the crossing generated by the parrallel constructed offset lines
|
||||
towards the original point in the polygon is compared to the offset which needs to be applied.
|
||||
The Roundfactor then decides if this corner will be rounded.
|
||||
A Roundfactor of 1 means that the resulting offset will not be bigger then the correction factor
|
||||
set in the algorithm. Meaning even straight 90 degrees corners will be rounded.
|
||||
A Roundfactor of > sqrt(2) is where 90 corners will be left alone, and smaller corners will be rounded.
|
||||
*/
|
||||
void SetRoundfactor(double roundfac);
|
||||
|
||||
//! see SetRoundfactor
|
||||
double GetRoundfactor();
|
||||
|
||||
// the following are only be used within the algorithm,
|
||||
// since they are scaled with m_DGRID
|
||||
|
||||
//! only used internal.
|
||||
void SetInternalMarge( B_INT marge );
|
||||
//! only used internal.
|
||||
B_INT GetInternalMarge();
|
||||
|
||||
//! only used internal.
|
||||
double GetInternalCorrectionAber();
|
||||
|
||||
//! only used internal.
|
||||
double GetInternalCorrectionFactor();
|
||||
|
||||
//! only used internal.
|
||||
double GetInternalSmoothAber();
|
||||
|
||||
//! only used internal.
|
||||
B_INT GetInternalMaxlinemerge();
|
||||
|
||||
//! in this mode polygons add clockwise, or contours,
|
||||
/*!
|
||||
and polygons added counter clockwise or holes.
|
||||
*/
|
||||
void SetOrientationEntryMode( bool orientationEntryMode ) { m_orientationEntryMode = orientationEntryMode; }
|
||||
|
||||
//! see SetOrientationEntryMode()
|
||||
bool GetOrientationEntryMode() { return m_orientationEntryMode; }
|
||||
|
||||
//! if set true holes are linked into outer contours by double overlapping segments.
|
||||
/*!
|
||||
This mode is needed when the software using the boolean algorithm does
|
||||
not understand hole polygons. In that case a contour and its holes form one
|
||||
polygon. In cases where software understands the concept of holes, contours
|
||||
are clockwise oriented, while holes are anticlockwise oriented.
|
||||
The output of the boolean operations, is following those rules also.
|
||||
But even if extracting the polygons from the engine, each segment is marked such
|
||||
that holes and non holes and linksegments to holes can be recognized.
|
||||
*/
|
||||
void SetLinkHoles( bool doLinkHoles ) { m_doLinkHoles = doLinkHoles; }
|
||||
|
||||
//! see SetLinkHoles()
|
||||
bool GetLinkHoles() { return m_doLinkHoles; }
|
||||
|
||||
//!lof file will be created when set True
|
||||
void SetLog( bool OnOff );
|
||||
|
||||
//! used to write to log file
|
||||
void Write_Log(const char *);
|
||||
//! used to write to log file
|
||||
void Write_Log(const char *, const char *);
|
||||
//! used to write to log file
|
||||
void Write_Log(const char *, double);
|
||||
//! used to write to log file
|
||||
void Write_Log(const char *, B_INT);
|
||||
|
||||
FILE* GetLogFile() { return m_logfile; }
|
||||
|
||||
// methods used to add polygons to the eng using points
|
||||
|
||||
//! Start adding a polygon to the engine
|
||||
/*
|
||||
The boolean operation work on two groups of polygons ( group A or B ),
|
||||
other algorithms are only using group A.
|
||||
|
||||
You add polygons like this to the engine.
|
||||
|
||||
// foreach point in a polygon ...
|
||||
if (booleng->StartPolygonAdd(GROUP_A))
|
||||
{
|
||||
booleng->AddPoint(100,100);
|
||||
booleng->AddPoint(-100,100);
|
||||
booleng->AddPoint(-100,-100);
|
||||
booleng->AddPoint(100,-100);
|
||||
}
|
||||
booleng->EndPolygonAdd();
|
||||
|
||||
\param A_or_B defines if the new polygon will be of group A or B
|
||||
|
||||
Holes or added by adding an inside polygons with opposite orientation compared
|
||||
to another polygon added.
|
||||
So the contour polygon ClockWise, then add counterclockwise polygons for holes, and visa versa.
|
||||
BUT only if m_orientationEntryMode is set true, else all polygons are redirected, and become
|
||||
individual areas without holes.
|
||||
Holes in such a case must be linked into the contour using two extra segments.
|
||||
*/
|
||||
bool StartPolygonAdd( GroupType A_or_B );
|
||||
|
||||
//! see StartPolygonAdd
|
||||
bool AddPoint(double x, double y);
|
||||
|
||||
//! see StartPolygonAdd
|
||||
bool EndPolygonAdd();
|
||||
|
||||
// methods used to extract polygons from the eng by getting its points
|
||||
|
||||
//! Use after StartPolygonGet()
|
||||
int GetNumPointsInPolygon() { return m_numPtsInPolygon ; }
|
||||
|
||||
//! get resulting polygons at end of an operation
|
||||
/*!
|
||||
// foreach resultant polygon in the booleng ...
|
||||
while ( booleng->StartPolygonGet() )
|
||||
{
|
||||
// foreach point in the polygon
|
||||
while ( booleng->PolygonHasMorePoints() )
|
||||
{
|
||||
fprintf(stdout,"x = %f\t", booleng->GetPolygonXPoint());
|
||||
fprintf(stdout,"y = %f\n", booleng->GetPolygonYPoint());
|
||||
}
|
||||
booleng->EndPolygonGet();
|
||||
}
|
||||
*/
|
||||
bool StartPolygonGet();
|
||||
|
||||
//! see StartPolygonGet
|
||||
/*!
|
||||
This iterates through the first graph in the graphlist.
|
||||
Setting the current Node properly by following the links in the graph
|
||||
through its nodes.
|
||||
*/
|
||||
bool PolygonHasMorePoints();
|
||||
|
||||
//! see StartPolygonGet
|
||||
double GetPolygonXPoint();
|
||||
|
||||
//! see StartPolygonGet
|
||||
double GetPolygonYPoint();
|
||||
|
||||
//! in the resulting polygons this tells if the current polygon segment is one
|
||||
//! used to link holes into the outer contour of the surrounding polygon
|
||||
bool GetHoleConnectionSegment();
|
||||
|
||||
//! in the resulting polygons this tells if the current polygon segment is part
|
||||
//! of a hole within a polygon.
|
||||
bool GetHoleSegment();
|
||||
|
||||
//! an other way to get the type of segment.
|
||||
kbEdgeType GetPolygonPointEdgeType();
|
||||
|
||||
//! see StartPolygonGet()
|
||||
/*!
|
||||
Removes a graph from the graphlist.
|
||||
Called after an extraction of an output polygon was done.
|
||||
*/
|
||||
void EndPolygonGet();
|
||||
|
||||
private:
|
||||
|
||||
bool m_doLog;
|
||||
|
||||
//! contains polygons in graph form
|
||||
GraphList* m_graphlist;
|
||||
|
||||
double m_MARGE;
|
||||
B_INT m_GRID;
|
||||
double m_DGRID;
|
||||
double m_CORRECTIONABER;
|
||||
double m_CORRECTIONFACTOR;
|
||||
double m_SMOOTHABER;
|
||||
double m_MAXLINEMERGE;
|
||||
bool m_WINDINGRULE;
|
||||
double m_ACCUR;
|
||||
double m_ROUNDFACTOR;
|
||||
|
||||
bool m_orientationEntryMode;
|
||||
|
||||
bool m_doLinkHoles;
|
||||
|
||||
//! used in the StartPolygonAdd, AddPt, EndPolygonAdd sequence
|
||||
Graph* m_GraphToAdd;
|
||||
//! used in the StartPolygonAdd, AddPt, EndPolygonAdd sequence
|
||||
Node* m_lastNodeToAdd;
|
||||
//! used in the StartPolygonAdd, AddPt, EndPolygonAdd sequence
|
||||
Node* m_firstNodeToAdd;
|
||||
|
||||
//! the current group type ( group A or B )
|
||||
GroupType m_groupType;
|
||||
|
||||
//! used in extracting the points from the resultant polygons
|
||||
Graph* m_getGraph;
|
||||
//! used in extracting the points from the resultant polygons
|
||||
KBoolLink* m_getLink;
|
||||
//! used in extracting the points from the resultant polygons
|
||||
Node* m_getNode;
|
||||
//! used in extracting the points from the resultant polygons
|
||||
double m_PolygonXPoint;
|
||||
//! used in extracting the points from the resultant polygons
|
||||
double m_PolygonYPoint;
|
||||
//! used in extracting the points from the resultant polygons
|
||||
int m_numPtsInPolygon;
|
||||
//! used in extracting the points from the resultant polygons
|
||||
int m_numNodesVisited;
|
||||
|
||||
FILE* m_logfile;
|
||||
|
||||
public:
|
||||
|
||||
//! use in Node to iterate links.
|
||||
TDLI<KBoolLink>* _linkiter;
|
||||
|
||||
//! how many time run intersections fase.
|
||||
unsigned int m_intersectionruns;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,211 @@
|
|||
/*! \file ../include/../graph.h
|
||||
\author Probably Klaas Holwerda
|
||||
|
||||
Copyright: 2001-2004 (C) Probably Klaas Holwerda
|
||||
|
||||
Licence: wxWidgets Licence
|
||||
|
||||
RCS-ID: $Id: graph.h,v 1.1 2005/05/24 19:13:37 titato Exp $
|
||||
*/
|
||||
|
||||
/* @@(#) $Source: /cvsroot/wxart2d/wxArt2D/modules/../include/graph.h,v $ $Revision: 1.1 $ $Date: 2005/05/24 19:13:37 $ */
|
||||
|
||||
/*
|
||||
Program GRAPH.H
|
||||
Purpose Used to Intercect and other process functions
|
||||
Last Update 03-04-1996
|
||||
*/
|
||||
|
||||
#ifndef GRAPH_H
|
||||
#define GRAPH_H
|
||||
|
||||
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
|
||||
#pragma interface
|
||||
#endif
|
||||
|
||||
#include "../include/booleng.h"
|
||||
#include "../include/_lnk_itr.h"
|
||||
#include "../include/link.h"
|
||||
#include "../include/line.h"
|
||||
#include "../include/scanbeam.h"
|
||||
|
||||
class Node;
|
||||
|
||||
class GraphList;
|
||||
|
||||
//! one graph containing links that cab be connected.
|
||||
class A2DKBOOLDLLEXP Graph
|
||||
{
|
||||
protected:
|
||||
Bool_Engine* _GC;
|
||||
public:
|
||||
|
||||
Graph(Bool_Engine* GC);
|
||||
Graph(KBoolLink*,Bool_Engine* GC);
|
||||
|
||||
Graph( Graph* other );
|
||||
|
||||
~Graph();
|
||||
|
||||
bool GetBin() { return _bin; };
|
||||
void SetBin(bool b) { _bin = b; };
|
||||
|
||||
void Prepare( int intersectionruns );
|
||||
void RoundInt(B_INT grid);
|
||||
void Rotate(bool plus90);
|
||||
|
||||
//! adds a link to the linklist
|
||||
void AddLink(Node *begin,Node *end);
|
||||
|
||||
//! adds a link to the linklist
|
||||
void AddLink(KBoolLink *a_link);
|
||||
|
||||
bool AreZeroLines(B_INT Marge);
|
||||
|
||||
//! Delete parallel lines
|
||||
void DeleteDoubles();
|
||||
|
||||
//! delete zerolines
|
||||
bool DeleteZeroLines(B_INT Marge);
|
||||
bool RemoveNullLinks();
|
||||
|
||||
//! Process found intersections
|
||||
void ProcessCrossings();
|
||||
//! set flags for operations based on group
|
||||
void Set_Operation_Flags();
|
||||
|
||||
//! Left Right values
|
||||
void Remove_IN_Links();
|
||||
|
||||
//! reset bin and mark flags in links.
|
||||
void ResetBinMark();
|
||||
|
||||
// Remove unused links
|
||||
void ReverseAllLinks();
|
||||
|
||||
//! Simplify the graph
|
||||
bool Simplify( B_INT Marge );
|
||||
|
||||
|
||||
//! Takes over all links of the argument
|
||||
bool Smoothen( B_INT Marge);
|
||||
|
||||
void TakeOver(Graph*);
|
||||
|
||||
//! function for maximum performance
|
||||
|
||||
//! Get the First link from the graph
|
||||
KBoolLink* GetFirstLink();
|
||||
Node* GetTopNode();
|
||||
void SetBeenHere(bool);
|
||||
void Reset_flags();
|
||||
|
||||
//! Set the group of a graph
|
||||
void SetGroup(GroupType);
|
||||
|
||||
//! Set the number of the graph
|
||||
void SetNumber(int);
|
||||
void Reset_Mark_and_Bin();
|
||||
bool GetBeenHere();
|
||||
int GetGraphNum();
|
||||
int GetNumberOfLinks();
|
||||
|
||||
void Boolean(BOOL_OP operation,GraphList* Result);
|
||||
void Correction(GraphList* Result,double factor);
|
||||
void MakeRing(GraphList* Result,double factor);
|
||||
void CreateRing(GraphList *ring,double factor);
|
||||
void CreateRing_fast(GraphList *ring,double factor);
|
||||
void CreateArc(Node* center, KBoolLine* incoming, Node* end,double radius,double aber);
|
||||
void CreateArc(Node* center, Node* begin, Node* end,double radius,bool clock,double aber);
|
||||
void MakeOneDirection();
|
||||
void Make_Rounded_Shape(KBoolLink* a_link, double factor);
|
||||
bool MakeClockWise();
|
||||
bool writegraph(bool linked);
|
||||
bool writeintersections();
|
||||
void WriteKEY( Bool_Engine* GC, FILE* file = NULL );
|
||||
void WriteGraphKEY( Bool_Engine* GC );
|
||||
|
||||
protected:
|
||||
|
||||
//! Extracts partical polygons from the graph
|
||||
/*
|
||||
Links are sorted in XY at beginpoint. Bin and mark flag are reset.
|
||||
Next start to collect subparts from the graph, setting the links bin for all found parts.
|
||||
The parts are searched starting at a topleft corner NON set bin flag link.
|
||||
Found parts are numbered, to be easily split into to real sperate graphs by Split()
|
||||
|
||||
\param operation operation to collect for.
|
||||
\param detecthole if you want holes detected, influences also way of extraction.
|
||||
\param foundholes when holes are found this flag is set true, but only if detecthole is set true.
|
||||
*/
|
||||
void Extract_Simples(BOOL_OP operation, bool detecthole, bool& foundholes );
|
||||
|
||||
//! split graph into small graph, using the numbers in links.
|
||||
void Split(GraphList* partlist);
|
||||
|
||||
//! Collect a graph by starting at argument link
|
||||
/*
|
||||
Called from Extract_Simples, and assumes sorted links with bin flag unset for non extarted piece
|
||||
|
||||
Collect graphs pieces from a total graph, by following links set to a given boolean operation.
|
||||
\param current_node start node to collect
|
||||
\param operation operation to collect for.
|
||||
\param detecthole if you want holes detected, influences also way of extraction.
|
||||
\param graphnumber number to be given to links in the extracted graph piece
|
||||
\param foundholes when holes are found this flag is set true.
|
||||
*/
|
||||
void CollectGraph(Node *current_node, BOOL_OP operation, bool detecthole,int graphnumber, bool& foundholes );
|
||||
|
||||
void CollectGraphLast(Node *current_node, BOOL_OP operation, bool detecthole,int graphnumber, bool& foundholes );
|
||||
|
||||
//! find a link not bin in the top left corner ( links should be sorted already )
|
||||
/*!
|
||||
Last found position is used to find it quickly.
|
||||
Used in ExtractSimples()
|
||||
*/
|
||||
Node* GetMostTopLeft(TDLI<KBoolLink>* _LI);
|
||||
|
||||
//! calculates crossing for all links in a graph, and add those as part of the graph.
|
||||
/*
|
||||
It is not just crossings calculation, snapping close nodes is part of it.
|
||||
This is not done at maximum stability in economic time.
|
||||
There are faster ways, but hardly ever they solve the problems, and they do not snap.
|
||||
Here it is on purpose split into separate steps, to get a better result in snapping, and
|
||||
to reach a better stability.
|
||||
|
||||
\param Marge nodes and lines closer to eachother then this, are merged.
|
||||
*/
|
||||
bool CalculateCrossings(B_INT Marge);
|
||||
|
||||
//! equal nodes in position are merged into one.
|
||||
int Merge_NodeToNode(B_INT Marge);
|
||||
|
||||
//! basic scan algorithm with a sweeping beam are line.
|
||||
/*!
|
||||
\param scantype a different face in the algorithm.
|
||||
\param holes to detect hole when needed.
|
||||
*/
|
||||
int ScanGraph2( SCANTYPE scantype, bool& holes );
|
||||
|
||||
//! links not used for a certain operation can be deleted, simplifying extraction
|
||||
void DeleteNonCond(BOOL_OP operation);
|
||||
|
||||
//! links not used for a certain operation can be set bin, simplifying extraction
|
||||
void HandleNonCond(BOOL_OP operation);
|
||||
|
||||
//! debug
|
||||
bool checksort();
|
||||
|
||||
//! used in correction/offset algorithm
|
||||
bool Small(B_INT howsmall);
|
||||
|
||||
|
||||
bool _bin;
|
||||
|
||||
DL_List<void*>* _linklist;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
/*! \file ../include/../graphlst.h
|
||||
\author Probably Klaas Holwerda
|
||||
|
||||
Copyright: 2001-2004 (C) Probably Klaas Holwerda
|
||||
|
||||
Licence: wxWidgets Licence
|
||||
|
||||
RCS-ID: $Id: graphlst.h,v 1.1 2005/05/24 19:13:37 titato Exp $
|
||||
*/
|
||||
|
||||
/* @@(#) $Source: /cvsroot/wxart2d/wxArt2D/modules/../include/graphlst.h,v $ $Revision: 1.1 $ $Date: 2005/05/24 19:13:37 $ */
|
||||
|
||||
/*
|
||||
Program GRAPHLST.H
|
||||
Purpose Implements a list of graphs (header)
|
||||
Last Update 11-03-1996
|
||||
*/
|
||||
|
||||
#ifndef GRAPHLIST_H
|
||||
#define GRAPHLIST_H
|
||||
|
||||
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
|
||||
#pragma interface
|
||||
#endif
|
||||
|
||||
#include "../include/booleng.h"
|
||||
|
||||
#include "../include/_lnk_itr.h"
|
||||
|
||||
#include "../include/graph.h"
|
||||
|
||||
class Debug_driver;
|
||||
|
||||
|
||||
class A2DKBOOLDLLEXP GraphList: public DL_List<void*>
|
||||
{
|
||||
protected:
|
||||
Bool_Engine* _GC;
|
||||
public:
|
||||
|
||||
GraphList(Bool_Engine* GC);
|
||||
|
||||
GraphList( GraphList* other );
|
||||
|
||||
~GraphList();
|
||||
|
||||
void MakeOneGraph(Graph *total);
|
||||
|
||||
void Prepare(Graph *total);
|
||||
void MakeRings();
|
||||
void Correction();
|
||||
|
||||
void Simplify( double marge);
|
||||
void Smoothen( double marge);
|
||||
void Merge();
|
||||
void Boolean(BOOL_OP operation, int intersectionRunsMax );
|
||||
|
||||
void WriteGraphs();
|
||||
void WriteGraphsKEY( Bool_Engine* GC );
|
||||
|
||||
protected:
|
||||
void Renumber();
|
||||
void UnMarkAll();
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
#ifndef __A2D_KBOOLMOD_H__
|
||||
#define __A2D_KBOOLMOD_H__
|
||||
|
||||
#include "../include/booleng.h"
|
||||
#include "../include/graph.h"
|
||||
#include "../include/graphlst.h"
|
||||
#include "../include/line.h"
|
||||
#include "../include/link.h"
|
||||
#include "../include/lpoint.h"
|
||||
#include "../include/node.h"
|
||||
#include "../include/record.h"
|
||||
#include "../include/scanbeam.h"
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
/*! \file ../include/../line.h
|
||||
\brief Mainy used for calculating crossings
|
||||
\author Probably Klaas Holwerda
|
||||
|
||||
Copyright: 2001-2004 (C) Probably Klaas Holwerda
|
||||
|
||||
Licence: wxWidgets Licence
|
||||
|
||||
RCS-ID: $Id: line.h,v 1.2 2005/06/12 00:03:11 kbluck Exp $
|
||||
*/
|
||||
|
||||
#ifndef LINE_H
|
||||
#define LINE_H
|
||||
|
||||
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
|
||||
#pragma interface
|
||||
#endif
|
||||
|
||||
#include "../include/booleng.h"
|
||||
#include "../include/link.h"
|
||||
|
||||
class A2DKBOOLDLLEXP Bool_Engine;
|
||||
|
||||
// Status of a point to a line
|
||||
enum PointStatus {LEFT_SIDE, RIGHT_SIDE, ON_AREA, IN_AREA};
|
||||
|
||||
class A2DKBOOLDLLEXP Graph;
|
||||
|
||||
class A2DKBOOLDLLEXP KBoolLine
|
||||
{
|
||||
protected:
|
||||
Bool_Engine* m_GC;
|
||||
public:
|
||||
|
||||
// constructors and destructor
|
||||
KBoolLine(Bool_Engine* GC);
|
||||
KBoolLine(KBoolLink*,Bool_Engine* GC);
|
||||
~KBoolLine();
|
||||
|
||||
void Set(KBoolLink *);
|
||||
KBoolLink* GetLink();
|
||||
|
||||
//! Get the beginnode from a line
|
||||
Node* GetBeginNode();
|
||||
|
||||
//! Get the endnode from a line
|
||||
Node* GetEndNode();
|
||||
|
||||
//! Check if two lines intersects
|
||||
int CheckIntersect(KBoolLine*, double Marge);
|
||||
|
||||
//! Intersects two lines
|
||||
int Intersect(KBoolLine*, double Marge);
|
||||
int Intersect_simple(KBoolLine * lijn);
|
||||
bool Intersect2(Node* crossing,KBoolLine * lijn);
|
||||
|
||||
//!For an infinite line
|
||||
PointStatus PointOnLine(Node* a_node, double& Distance, double Marge );
|
||||
|
||||
//!For a non-infinite line
|
||||
PointStatus PointInLine(Node* a_node, double& Distance, double Marge );
|
||||
|
||||
//! Caclulate Y if X is known
|
||||
B_INT Calculate_Y(B_INT X);
|
||||
B_INT Calculate_Y_from_X(B_INT X);
|
||||
void Virtual_Point( LPoint *a_point, double distance);
|
||||
|
||||
//! assignment operator
|
||||
KBoolLine& operator=(const KBoolLine&);
|
||||
|
||||
Node* OffsetContour(KBoolLine* const nextline,Node* last_ins, double factor,Graph *shape);
|
||||
Node* OffsetContour_rounded(KBoolLine* const nextline,Node* _last_ins, double factor,Graph *shape);
|
||||
bool OkeForContour(KBoolLine* const nextline,double factor,Node* LastLeft,Node* LastRight, LinkStatus& _outproduct);
|
||||
bool Create_Ring_Shape(KBoolLine* nextline,Node** _last_ins_left,Node** _last_ins_right,double factor,Graph *shape);
|
||||
void Create_Begin_Shape(KBoolLine* nextline,Node** _last_ins_left,Node** _last_ins_right,double factor,Graph *shape);
|
||||
void Create_End_Shape(KBoolLine* nextline,Node* _last_ins_left,Node* _last_ins_right,double factor,Graph *shape);
|
||||
|
||||
//! Calculate the parameters if nessecary
|
||||
void CalculateLineParameters();
|
||||
|
||||
//! Adds a crossing between the intersecting lines
|
||||
void AddLineCrossing(B_INT , B_INT , KBoolLine *);
|
||||
|
||||
void AddCrossing(Node *a_node);
|
||||
Node* AddCrossing(B_INT X, B_INT Y);
|
||||
bool ProcessCrossings(TDLI<KBoolLink>* _LI);
|
||||
|
||||
// Linecrosslist
|
||||
void SortLineCrossings();
|
||||
bool CrossListEmpty();
|
||||
DL_List<void*>* GetCrossList();
|
||||
// bool HasInCrossList(Node*);
|
||||
|
||||
private:
|
||||
|
||||
//! Function needed for Intersect
|
||||
int ActionOnTable1(PointStatus,PointStatus);
|
||||
//! Function needed for Intersect
|
||||
int ActionOnTable2(PointStatus,PointStatus);
|
||||
|
||||
double m_AA;
|
||||
double m_BB;
|
||||
double m_CC;
|
||||
KBoolLink* m_link;
|
||||
bool m_valid_parameters;
|
||||
|
||||
//! List with crossings through this link
|
||||
DL_List<void*> *linecrosslist;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,234 @@
|
|||
/*! \file kbool/include/kbool/link.h
|
||||
\brief Part of a graph, connection between nodes (Header)
|
||||
\author Probably Klaas Holwerda or Julian Smart
|
||||
|
||||
Copyright: 2001-2004 (C) Probably Klaas Holwerda
|
||||
|
||||
Licence: wxWidgets Licence
|
||||
|
||||
RCS-ID: $Id: link.h,v 1.1 2005/05/24 19:13:37 titato Exp $
|
||||
*/
|
||||
|
||||
#ifndef LINK_H
|
||||
#define LINK_H
|
||||
|
||||
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
|
||||
#pragma interface
|
||||
#endif
|
||||
|
||||
#include "../include/booleng.h"
|
||||
#include "../include/_lnk_itr.h"
|
||||
|
||||
enum LinkStatus {IS_LEFT,IS_ON,IS_RIGHT};
|
||||
|
||||
class LPoint;
|
||||
class Node;
|
||||
class Record;
|
||||
|
||||
//! segment within a graph
|
||||
/*
|
||||
A Graph contains a list of KBoolLink, the KBoolLink or connected by Node's.
|
||||
Several KBoolLink can be connected to one Node.
|
||||
A KBoolLink has a direction defined by its begin and end node.
|
||||
Node do have a list of connected KBoolLink's.
|
||||
So one can walk trough a graph in two ways:
|
||||
1- via its KBoolLink list
|
||||
2- via the node connected to the KBoolLink's
|
||||
*/
|
||||
class A2DKBOOLDLLEXP KBoolLink
|
||||
{
|
||||
protected:
|
||||
Bool_Engine* _GC;
|
||||
public:
|
||||
|
||||
//! contructors
|
||||
KBoolLink(Bool_Engine* GC);
|
||||
|
||||
//! contructors
|
||||
KBoolLink(int graphnr, Node* begin, Node* end, Bool_Engine* GC);
|
||||
|
||||
//! contructors
|
||||
KBoolLink(Node *begin, Node *end, Bool_Engine* GC);
|
||||
|
||||
//! destructors
|
||||
~KBoolLink();
|
||||
|
||||
|
||||
//! Merges the other node with argument
|
||||
void MergeNodes(Node* const);
|
||||
|
||||
//! outproduct of two links
|
||||
LinkStatus OutProduct(KBoolLink* const two,double accur);
|
||||
|
||||
//! link three compared to this and two
|
||||
LinkStatus PointOnCorner(KBoolLink* const, KBoolLink* const);
|
||||
|
||||
//! Removes argument from the link
|
||||
void Remove(Node*);
|
||||
|
||||
//! replaces olddone in the link by newnode
|
||||
void Replace(Node* oldnode, Node* newnode);
|
||||
|
||||
//!top hole marking
|
||||
void SetTopHole(bool value);
|
||||
|
||||
//!top hole marking
|
||||
bool IsTopHole();
|
||||
|
||||
//! Marking functions
|
||||
void UnMark();
|
||||
//! Marking functions
|
||||
void Mark();
|
||||
//! Marking functions
|
||||
void SetMark(bool);
|
||||
//! Marking functions
|
||||
bool IsMarked();
|
||||
|
||||
//! holelink Marking functions
|
||||
void SetHoleLink(bool val){ m_holelink = val;};
|
||||
|
||||
//! holelink Marking functions
|
||||
bool GetHoleLink(){ return m_holelink;};
|
||||
|
||||
//! Bin functions
|
||||
void SetNotBeenHere();
|
||||
//! Bin functions
|
||||
void SetBeenHere();
|
||||
//! Have you been here ??
|
||||
bool BeenHere();
|
||||
|
||||
//! Removes all the references to this
|
||||
void UnLink();
|
||||
|
||||
//! functions for maximum performance
|
||||
Node* GetBeginNode();
|
||||
|
||||
//! Datamember access functions
|
||||
Node* GetEndNode();
|
||||
Node* GetLowNode();
|
||||
Node* GetHighNode();
|
||||
|
||||
//! Returns a next link beginning with argument
|
||||
KBoolLink* Forth(Node*);
|
||||
|
||||
int GetGraphNum();
|
||||
bool GetInc();
|
||||
bool GetLeftA();
|
||||
bool GetLeftB();
|
||||
bool GetRightA();
|
||||
bool GetRightB();
|
||||
void GetLRO(LPoint*, int&, int&, double);
|
||||
|
||||
//! Return a node not equal to arg.
|
||||
Node* GetOther(const Node* const);
|
||||
//! Is this link unused ?
|
||||
bool IsUnused();
|
||||
|
||||
//! Used for given operation ?
|
||||
bool IsMarked(BOOL_OP operation);
|
||||
|
||||
//! return true if Left side is marked true for operation
|
||||
bool IsMarkedLeft(BOOL_OP operation);
|
||||
|
||||
//! return true if Right side is marked true for operation
|
||||
bool IsMarkedRight(BOOL_OP operation);
|
||||
|
||||
//! is this a hole link for given operation
|
||||
bool IsHole(BOOL_OP operation);
|
||||
|
||||
//! set the hole mark
|
||||
void SetHole(bool);
|
||||
|
||||
//! is the hole mark set?
|
||||
bool GetHole();
|
||||
|
||||
//! Are the nodes on about the same coordinates ?
|
||||
bool IsZero(B_INT marge );
|
||||
bool ShorterThan(B_INT marge );
|
||||
|
||||
//! Resets the link
|
||||
void Reset(Node* begin, Node* end, int graphnr = 0);
|
||||
void Set(Node* begin, Node* end);
|
||||
void SetBeginNode(Node*);
|
||||
void SetEndNode(Node*);
|
||||
void SetGraphNum(int);
|
||||
void SetInc(bool);
|
||||
void SetLeftA(bool);
|
||||
void SetLeftB(bool);
|
||||
void SetRightA(bool);
|
||||
void SetRightB(bool);
|
||||
void SetGroup(GroupType);
|
||||
GroupType Group();
|
||||
|
||||
//! Flag calculation (internal only)
|
||||
void SetLineTypes();
|
||||
void Reset();
|
||||
void Reset_flags();
|
||||
|
||||
//!put in this direction
|
||||
void Redirect(Node* a_node);
|
||||
|
||||
void TakeOverOperationFlags( KBoolLink* link );
|
||||
|
||||
void SetRecordNode( DL_Node<Record*>* recordNode ) { m_record = recordNode; }
|
||||
|
||||
DL_Node<Record*>* GetRecordNode() { return m_record; }
|
||||
|
||||
protected:
|
||||
|
||||
//! The mainitems of a link
|
||||
Node *m_beginnode, *m_endnode;
|
||||
//! Marker for walking over the graph
|
||||
bool m_bin : 1;
|
||||
//! Is this a part of hole ?
|
||||
bool m_hole : 1;
|
||||
//! link that is toplink of hole?
|
||||
bool m_hole_top : 1;
|
||||
//! going in one more time in this graph if true else going out one time
|
||||
bool m_Inc : 1;
|
||||
//! Is left in polygongroup A
|
||||
bool m_LeftA : 1;
|
||||
//! Is right in polygon group A
|
||||
bool m_RightA : 1;
|
||||
//! Is left in polygon group B
|
||||
bool m_LeftB : 1;
|
||||
//! Is right in polygongroup B
|
||||
bool m_RightB : 1;
|
||||
//! General purose marker, internally unused
|
||||
bool m_mark : 1;
|
||||
//! link for linking holes
|
||||
bool m_holelink : 1;
|
||||
|
||||
//! Marker for Merge Left
|
||||
bool m_merge_L : 1;
|
||||
//! Marker for substract a-b Left
|
||||
bool m_a_substract_b_L: 1;
|
||||
//! Marker for substract b-a Left
|
||||
bool m_b_substract_a_L: 1;
|
||||
//! Marker for intersect Left
|
||||
bool m_intersect_L: 1;
|
||||
//! Marker for X-OR Left
|
||||
bool m_exor_L: 1;
|
||||
|
||||
//! Marker for Merge Right
|
||||
bool m_merge_R : 1;
|
||||
//! Marker for substract a-b Right
|
||||
bool m_a_substract_b_R: 1;
|
||||
//! Marker for substract b-a Right
|
||||
bool m_b_substract_a_R: 1;
|
||||
//! Marker for intersect Right
|
||||
bool m_intersect_R: 1;
|
||||
//! Marker for X-OR Right
|
||||
bool m_exor_R: 1;
|
||||
|
||||
//! belongs to group A or B
|
||||
GroupType m_group : 1;
|
||||
|
||||
//! belongs to this polygon part in the graph.
|
||||
int m_graphnum;
|
||||
|
||||
DL_Node<Record*>* m_record;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
/*! \file ../include/../lpoint.h
|
||||
\author Probably Klaas Holwerda
|
||||
|
||||
Copyright: 2001-2004 (C) Probably Klaas Holwerda
|
||||
|
||||
Licence: wxWidgets Licence
|
||||
|
||||
RCS-ID: $Id: lpoint.h,v 1.1 2005/05/24 19:13:37 titato Exp $
|
||||
*/
|
||||
|
||||
/* @@(#) $Source: /cvsroot/wxart2d/wxArt2D/modules/../include/lpoint.h,v $ $Revision: 1.1 $ $Date: 2005/05/24 19:13:37 $ */
|
||||
|
||||
/*
|
||||
Program LPOINT.H
|
||||
Purpose Definition of GDSII pointtype structure
|
||||
Last Update 12-12-1995
|
||||
*/
|
||||
|
||||
#ifndef LPOINT_H
|
||||
#define LPOINT_H
|
||||
|
||||
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
|
||||
#pragma interface
|
||||
#endif
|
||||
|
||||
#include "../include/booleng.h"
|
||||
|
||||
class A2DKBOOLDLLEXP LPoint
|
||||
{
|
||||
public:
|
||||
LPoint();
|
||||
LPoint(B_INT const ,B_INT const);
|
||||
LPoint(LPoint* const);
|
||||
|
||||
void Set(const B_INT,const B_INT);
|
||||
void Set(const LPoint &);
|
||||
|
||||
LPoint GetPoint();
|
||||
B_INT GetX();
|
||||
B_INT GetY();
|
||||
void SetX(B_INT);
|
||||
void SetY(B_INT);
|
||||
bool Equal(const LPoint a_point, B_INT Marge );
|
||||
bool Equal(const B_INT,const B_INT , B_INT Marge);
|
||||
bool ShorterThan(const LPoint a_point, B_INT marge);
|
||||
bool ShorterThan(const B_INT X, const B_INT Y, B_INT);
|
||||
|
||||
LPoint &operator=(const LPoint &);
|
||||
LPoint &operator+(const LPoint &);
|
||||
LPoint &operator-(const LPoint &);
|
||||
|
||||
LPoint &operator*(int);
|
||||
LPoint &operator/(int);
|
||||
|
||||
int operator==(const LPoint &) const;
|
||||
int operator!=(const LPoint &) const;
|
||||
|
||||
protected:
|
||||
B_INT _x;
|
||||
B_INT _y;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,89 @@
|
|||
/*! \file ../include/../node.h
|
||||
\brief Holds a GDSII node structure (Header)
|
||||
\author Probably Klaas Holwerda
|
||||
|
||||
Copyright: 2001-2004 (C) Probably Klaas Holwerda
|
||||
|
||||
Licence: wxWidgets Licence
|
||||
|
||||
RCS-ID: $Id: node.h,v 1.1 2005/05/24 19:13:37 titato Exp $
|
||||
*/
|
||||
|
||||
#ifndef NODE_H
|
||||
#define NODE_H
|
||||
|
||||
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
|
||||
#pragma interface
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
#include "../include/booleng.h"
|
||||
|
||||
#include "../include/lpoint.h"
|
||||
|
||||
#include "../include/link.h"
|
||||
#include "../include/_lnk_itr.h" // LinkBaseIter
|
||||
|
||||
enum NodePosition { N_LEFT, N_ON, N_RIGHT};
|
||||
|
||||
class A2DKBOOLDLLEXP Node : public LPoint
|
||||
{
|
||||
protected:
|
||||
Bool_Engine* _GC;
|
||||
public:
|
||||
// friend must be deleted in the final version!
|
||||
friend class Debug_driver;
|
||||
|
||||
// constructors and destructors
|
||||
Node(Bool_Engine* GC);
|
||||
|
||||
Node(const B_INT, const B_INT, Bool_Engine* GC);
|
||||
|
||||
Node(LPoint* const a_point, Bool_Engine* GC);
|
||||
Node(Node * const, Bool_Engine* GC);
|
||||
Node& operator=(const Node &other_node);
|
||||
~Node();
|
||||
|
||||
//public member functions
|
||||
void AddLink(KBoolLink*);
|
||||
DL_List<void*>* GetLinklist();
|
||||
|
||||
//! check two link for its operation flags to be the same when coming from the prev link.
|
||||
bool SameSides( KBoolLink* const prev , KBoolLink* const link, BOOL_OP operation );
|
||||
|
||||
//! get the link most right or left to the current link, but with the specific operation
|
||||
/*! flags the same on the sides of the new link.
|
||||
*/
|
||||
KBoolLink* GetMost( KBoolLink* const prev ,LinkStatus whatside, BOOL_OP operation );
|
||||
|
||||
//! get link that is leading to a hole ( hole segment or linking segment )
|
||||
KBoolLink* GetMostHole( KBoolLink* const prev ,LinkStatus whatside, BOOL_OP operation );
|
||||
|
||||
//! get link that is not vertical.
|
||||
KBoolLink* GetNotFlat();
|
||||
|
||||
//! get a link to a hole or from a hole.
|
||||
KBoolLink* GetHoleLink( KBoolLink* const prev, bool checkbin, BOOL_OP operation );
|
||||
|
||||
int Merge(Node*);
|
||||
void RemoveLink(KBoolLink*);
|
||||
bool Simplify(Node* First, Node* Second, B_INT Marge );
|
||||
|
||||
// memberfunctions for maximum performance
|
||||
void RoundInt(B_INT grid);
|
||||
KBoolLink* GetIncomingLink();
|
||||
|
||||
int GetNumberOfLinks();
|
||||
KBoolLink* GetNextLink();
|
||||
KBoolLink* GetOtherLink(KBoolLink*);
|
||||
KBoolLink* GetOutgoingLink();
|
||||
KBoolLink* GetPrevLink();
|
||||
|
||||
KBoolLink* Follow(KBoolLink* const prev );
|
||||
KBoolLink* GetBinHighest(bool binset);
|
||||
|
||||
protected:
|
||||
DL_List<void*>* _linklist;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,82 @@
|
|||
/*! \file ../include/../record.h
|
||||
\author Probably Klaas Holwerda
|
||||
|
||||
Copyright: 2001-2004 (C) Probably Klaas Holwerda
|
||||
|
||||
Licence: wxWidgets Licence
|
||||
|
||||
RCS-ID: $Id: record.h,v 1.1 2005/05/24 19:13:37 titato Exp $
|
||||
*/
|
||||
|
||||
#ifndef RECORD_H
|
||||
#define RECORD_H
|
||||
|
||||
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
|
||||
#pragma interface
|
||||
#endif
|
||||
|
||||
class Node;
|
||||
#include "../include/booleng.h"
|
||||
|
||||
#include "../include/link.h"
|
||||
#include "../include/line.h"
|
||||
|
||||
enum BEAM_TYPE { NORMAL,FLAT};
|
||||
|
||||
enum DIRECTION {GO_LEFT,GO_RIGHT};
|
||||
|
||||
//extern void DeleteRecordPool();
|
||||
class A2DKBOOLDLLEXP Bool_Engine;
|
||||
|
||||
class A2DKBOOLDLLEXP Record
|
||||
{
|
||||
protected:
|
||||
Bool_Engine* _GC;
|
||||
public:
|
||||
// void deletepool();
|
||||
|
||||
Record(KBoolLink* link,Bool_Engine* GC);
|
||||
|
||||
~Record();
|
||||
|
||||
// void* operator new(size_t size);
|
||||
|
||||
// void operator delete(void* recordptr);
|
||||
|
||||
void SetNewLink(KBoolLink* link);
|
||||
|
||||
void Set_Flags();
|
||||
|
||||
void Calc_Ysp(Node* low);
|
||||
|
||||
KBoolLink* GetLink();
|
||||
|
||||
KBoolLine* GetLine();
|
||||
|
||||
B_INT Ysp();
|
||||
|
||||
void SetYsp(B_INT ysp);
|
||||
|
||||
DIRECTION Direction();
|
||||
|
||||
bool Calc_Left_Right(Record* record_above_me);
|
||||
|
||||
bool Equal(Record*);
|
||||
|
||||
private:
|
||||
KBoolLine _line;
|
||||
|
||||
B_INT _ysp;
|
||||
|
||||
//! going left are right in beam
|
||||
DIRECTION _dir;
|
||||
|
||||
//! how far in group_a
|
||||
int _a;
|
||||
|
||||
//! how far in group_b
|
||||
int _b;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,62 @@
|
|||
/*! \file ../include/../scanbeam.h
|
||||
\author Probably Klaas Holwerda
|
||||
|
||||
Copyright: 2001-2004 (C) Probably Klaas Holwerda
|
||||
|
||||
Licence: wxWidgets Licence
|
||||
|
||||
RCS-ID: $Id: scanbeam.h,v 1.2 2005/06/11 19:25:12 frm Exp $
|
||||
*/
|
||||
|
||||
#ifndef SCANBEAM_H
|
||||
#define SCANBEAM_H
|
||||
|
||||
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
|
||||
#pragma interface
|
||||
#endif
|
||||
|
||||
#include "../include/booleng.h"
|
||||
#include "../include/_lnk_itr.h"
|
||||
|
||||
#include "../include/record.h"
|
||||
#include "../include/link.h"
|
||||
|
||||
enum SCANTYPE{NODELINK,LINKLINK,GENLR,LINKHOLES,INOUT};
|
||||
|
||||
#if defined(WXUSINGDLL)
|
||||
template class A2DKBOOLDLLEXP DL_Iter<Record*>;
|
||||
#endif
|
||||
|
||||
class A2DKBOOLDLLEXP ScanBeam : public DL_List<Record*>
|
||||
{
|
||||
protected:
|
||||
Bool_Engine* _GC;
|
||||
|
||||
public:
|
||||
ScanBeam(Bool_Engine* GC);
|
||||
~ScanBeam();
|
||||
void SetType(Node* low,Node* high);
|
||||
|
||||
bool FindNew(SCANTYPE scantype,TDLI<KBoolLink>* _I, bool& holes );
|
||||
bool RemoveOld(SCANTYPE scantype,TDLI<KBoolLink>* _I, bool& holes );
|
||||
|
||||
private:
|
||||
|
||||
bool ProcessHoles(bool atinsert,TDLI<KBoolLink>* _LI);
|
||||
int Process_LinkToLink_Crossings(); // find crossings
|
||||
int Process_PointToLink_Crossings();
|
||||
int Process_LinkToLink_Flat(KBoolLine* flatline);
|
||||
void SortTheBeam( bool backangle );
|
||||
bool checksort();
|
||||
bool writebeam();
|
||||
void Calc_Ysp();
|
||||
//int FindCloseLinksAndCross(TDLI<KBoolLink>* _I,Node* _lowf);
|
||||
void Generate_INOUT(int graphnumber);
|
||||
|
||||
Node* _low;
|
||||
DL_Iter<Record*> _BI;
|
||||
int lastinserted;
|
||||
BEAM_TYPE _type;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,9 @@
|
|||
/*! \file kbool/include/kbool/valuesvc.h
|
||||
\author Probably Klaas Holwerda
|
||||
|
||||
Copyright: 2001-2004 (C) Probably Klaas Holwerda
|
||||
|
||||
Licence: wxWidgets Licence
|
||||
|
||||
RCS-ID: $Id: valuesvc.h,v 1.1 2005/05/24 19:13:37 titato Exp $
|
||||
*/
|
|
@ -0,0 +1,10 @@
|
|||
Boolean: GDSII viewer/editor + (boolean) operations on sets of 2d polygons.
|
||||
Boolean Web Site:
|
||||
http://boolean.klaasholwerda.nl/bool.html
|
||||
|
||||
Copyright section form the site:
|
||||
The code is written by Klaas Holwerda, it is free to use for non commercial open source projects licensed as GPL.
|
||||
|
||||
Note:
|
||||
License info in kbool files:
|
||||
files are under wxWidget license
|
|
@ -0,0 +1,11 @@
|
|||
ADD_EXECUTABLE(boolonly boolonly.cpp)
|
||||
|
||||
IF(WIN32)
|
||||
ADD_DEFINITIONS( -D_MSWVC_ )
|
||||
ELSE(WIN32)
|
||||
ADD_DEFINITIONS( -D__UNIX__ )
|
||||
ENDIF(WIN32)
|
||||
|
||||
INCLUDE_DIRECTORIES( ${kbool_SOURCE_DIR}/.. )
|
||||
|
||||
TARGET_LINK_LIBRARIES( boolonly kbool )
|
|
@ -0,0 +1,368 @@
|
|||
/*! \file kbool/samples/boolonly/boolonly.cpp
|
||||
\brief boolonly demonstrates the use of the boolean algorithm
|
||||
\author Probably Klaas Holwerda
|
||||
|
||||
Copyright: 2001-2004 (C) Probably Klaas Holwerda
|
||||
|
||||
Licence: wxWidgets Licence
|
||||
|
||||
RCS-ID: $Id: boolonly.cpp,v 1.9 2005/01/16 18:39:24 kire_putsje Exp $
|
||||
*/
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma implementation
|
||||
#endif
|
||||
|
||||
#include "boolonly.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
// Constructors
|
||||
KBoolPoint::KBoolPoint()
|
||||
{
|
||||
_x = 0.0;
|
||||
_y = 0.0;
|
||||
}
|
||||
|
||||
KBoolPoint::KBoolPoint(double const X, double const Y)
|
||||
{
|
||||
_x = X;
|
||||
_y = Y;
|
||||
}
|
||||
|
||||
double KBoolPoint::GetX()
|
||||
{
|
||||
return _x;
|
||||
}
|
||||
|
||||
double KBoolPoint::GetY()
|
||||
{
|
||||
return _y;
|
||||
}
|
||||
|
||||
template class TDLI<KBoolPoint>;
|
||||
|
||||
|
||||
void ArmBoolEng( Bool_Engine* booleng )
|
||||
{
|
||||
// set some global vals to arm the boolean engine
|
||||
double DGRID = 1000; // round coordinate X or Y value in calculations to this
|
||||
double MARGE = 0.001; // snap with in this range points to lines in the intersection routines
|
||||
// should always be > DGRID a MARGE >= 10*DGRID is oke
|
||||
// this is also used to remove small segments and to decide when
|
||||
// two segments are in line.
|
||||
double CORRECTIONFACTOR = 500.0; // correct the polygons by this number
|
||||
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
|
||||
|
||||
|
||||
// DGRID is only meant to make fractional parts of input data which
|
||||
// are doubles, part of the integers used in vertexes within the boolean algorithm.
|
||||
// Within the algorithm all input data is multiplied with DGRID
|
||||
|
||||
// space for extra intersection inside the boolean algorithms
|
||||
// only change this if there are problems
|
||||
int GRID =10000;
|
||||
|
||||
booleng->SetMarge( MARGE );
|
||||
booleng->SetGrid( GRID );
|
||||
booleng->SetDGrid( DGRID );
|
||||
booleng->SetCorrectionFactor( CORRECTIONFACTOR );
|
||||
booleng->SetCorrectionAber( CORRECTIONABER );
|
||||
booleng->SetSmoothAber( SMOOTHABER );
|
||||
booleng->SetMaxlinemerge( MAXLINEMERGE );
|
||||
booleng->SetRoundfactor( ROUNDFACTOR );
|
||||
|
||||
}
|
||||
|
||||
void AddPolygonsToBoolEng2( Bool_Engine* booleng )
|
||||
{
|
||||
int x1 = 100;
|
||||
int x2 = 200;
|
||||
int y1 = 100;
|
||||
int y2 = 200;
|
||||
int pitch1 = 200;
|
||||
int numRowsAndCols = 120;
|
||||
int i, j;
|
||||
|
||||
for ( i = 0; i < numRowsAndCols; i++) {
|
||||
for ( j = 0; j < numRowsAndCols; j++) {
|
||||
// foreach point in a polygon ...
|
||||
if (booleng->StartPolygonAdd(GROUP_A))
|
||||
{
|
||||
// Counter-Clockwise
|
||||
booleng->AddPoint(x1,y1);
|
||||
booleng->AddPoint(x2,y1);
|
||||
booleng->AddPoint(x2,y2);
|
||||
booleng->AddPoint(x1,y2);
|
||||
|
||||
}
|
||||
booleng->EndPolygonAdd();
|
||||
x1 += pitch1;
|
||||
x2 += pitch1;
|
||||
}
|
||||
x1 = 100;
|
||||
x2 = 200;
|
||||
|
||||
y1 += pitch1;
|
||||
y2 += pitch1;
|
||||
|
||||
}
|
||||
|
||||
x1 = 150;
|
||||
x2 = 250;
|
||||
y1 = 150;
|
||||
y2 = 250;
|
||||
|
||||
for ( i = 0; i < numRowsAndCols; i++) {
|
||||
for ( int j = 0; j < numRowsAndCols; j++) {
|
||||
// foreach point in a polygon ...
|
||||
if (booleng->StartPolygonAdd(GROUP_B))
|
||||
{
|
||||
// Counter Clockwise
|
||||
booleng->AddPoint(x1,y1);
|
||||
booleng->AddPoint(x2,y1);
|
||||
booleng->AddPoint(x2,y2);
|
||||
booleng->AddPoint(x1,y2);
|
||||
|
||||
}
|
||||
booleng->EndPolygonAdd();
|
||||
x1 += pitch1;
|
||||
x2 += pitch1;
|
||||
}
|
||||
x1 = 150;
|
||||
x2 = 250;
|
||||
|
||||
y1 += pitch1;
|
||||
y2 += pitch1;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void AddPolygonsToBoolEng( Bool_Engine* booleng )
|
||||
{
|
||||
// foreach point in a polygon ...
|
||||
if (booleng->StartPolygonAdd(GROUP_A))
|
||||
{
|
||||
booleng->AddPoint( 28237.480000, 396.364000 );
|
||||
booleng->AddPoint( 28237.980000, 394.121000 );
|
||||
booleng->AddPoint( 28242.000000, 395.699000 );
|
||||
booleng->AddPoint( 28240.830000, 397.679000 );
|
||||
}
|
||||
booleng->EndPolygonAdd();
|
||||
|
||||
// foreach point in a polygon ...
|
||||
if (booleng->StartPolygonAdd(GROUP_B))
|
||||
{
|
||||
booleng->AddPoint( 28242.100000, 398.491000 );
|
||||
booleng->AddPoint( 28240.580000, 397.485000 );
|
||||
booleng->AddPoint( 28237.910000, 394.381000 );
|
||||
}
|
||||
booleng->EndPolygonAdd();
|
||||
|
||||
if (booleng->StartPolygonAdd(GROUP_B))
|
||||
{
|
||||
booleng->AddPoint( 28243.440000, 399.709000 );
|
||||
booleng->AddPoint( 28237.910000, 394.381000 );
|
||||
booleng->AddPoint( 28239.290000, 394.763000 );
|
||||
}
|
||||
booleng->EndPolygonAdd();
|
||||
}
|
||||
|
||||
void AddPolygonsToBoolEng3( Bool_Engine* booleng )
|
||||
{
|
||||
// foreach point in a polygon ...
|
||||
if (booleng->StartPolygonAdd(GROUP_A))
|
||||
{
|
||||
booleng->AddPoint(100,100);
|
||||
booleng->AddPoint(-100,100);
|
||||
booleng->AddPoint(-100,-100);
|
||||
booleng->AddPoint(100,-100);
|
||||
}
|
||||
booleng->EndPolygonAdd();
|
||||
|
||||
// foreach point in a polygon ...
|
||||
if (booleng->StartPolygonAdd(GROUP_B))
|
||||
{
|
||||
booleng->AddPoint(50,50);
|
||||
booleng->AddPoint(-50,50);
|
||||
booleng->AddPoint(-50,-50);
|
||||
booleng->AddPoint(50,-50);
|
||||
booleng->EndPolygonAdd();
|
||||
}
|
||||
booleng->EndPolygonAdd();
|
||||
}
|
||||
|
||||
void AddPolygonsToBoolEng4( Bool_Engine* booleng )
|
||||
{
|
||||
// foreach point in a polygon ...
|
||||
if (booleng->StartPolygonAdd(GROUP_A))
|
||||
{
|
||||
booleng->AddPoint(0,0);
|
||||
booleng->AddPoint(0,1000);
|
||||
booleng->AddPoint(1000,1000);
|
||||
booleng->AddPoint(1000,0);
|
||||
}
|
||||
booleng->EndPolygonAdd();
|
||||
}
|
||||
|
||||
void GetPolygonsFromBoolEng( Bool_Engine* booleng )
|
||||
{
|
||||
// foreach resultant polygon in the booleng ...
|
||||
while ( booleng->StartPolygonGet() )
|
||||
{
|
||||
// foreach point in the polygon
|
||||
while ( booleng->PolygonHasMorePoints() )
|
||||
{
|
||||
fprintf(stderr,"x = %f\t", booleng->GetPolygonXPoint());
|
||||
fprintf(stderr,"y = %f\n", booleng->GetPolygonYPoint());
|
||||
}
|
||||
booleng->EndPolygonGet();
|
||||
}
|
||||
}
|
||||
|
||||
void GetPolygonsFromBoolEngKEY( Bool_Engine* booleng )
|
||||
{
|
||||
FILE* file = fopen("keyfile.key", "w");
|
||||
|
||||
fprintf(file,"\
|
||||
HEADER 5; \
|
||||
BGNLIB; \
|
||||
LASTMOD {2-11-15 15:39:21}; \
|
||||
LASTACC {2-11-15 15:39:21}; \
|
||||
LIBNAME trial; \
|
||||
UNITS; \
|
||||
USERUNITS 0.0001; PHYSUNITS 2.54e-009; \
|
||||
\
|
||||
BGNSTR; \
|
||||
CREATION {2-11-15 15:39:21}; \
|
||||
LASTMOD {2-11-15 15:39:21}; \
|
||||
STRNAME top; \
|
||||
");
|
||||
// foreach resultant polygon in the booleng ...
|
||||
while ( booleng->StartPolygonGet() )
|
||||
{
|
||||
fprintf(file,"BOUNDARY; LAYER 2; DATATYPE 0;\n");
|
||||
fprintf(file," XY %d; \n",booleng->GetNumPointsInPolygon()+1 );
|
||||
|
||||
booleng->PolygonHasMorePoints();
|
||||
double firstx = booleng->GetPolygonXPoint();
|
||||
double firsty = booleng->GetPolygonYPoint();
|
||||
fprintf(file,"X %f;\t", firstx);
|
||||
fprintf(file,"Y %f; \n", firsty);
|
||||
|
||||
// foreach point in the polygon
|
||||
while ( booleng->PolygonHasMorePoints() )
|
||||
{
|
||||
fprintf(file,"X %f;\t", booleng->GetPolygonXPoint());
|
||||
fprintf(file,"Y %f; \n", booleng->GetPolygonYPoint());
|
||||
}
|
||||
booleng->EndPolygonGet();
|
||||
fprintf(file,"X %f;\t", firstx);
|
||||
fprintf(file,"Y %f; \n", firsty);
|
||||
fprintf(file,"ENDEL;\n");
|
||||
}
|
||||
|
||||
fprintf(file,"\
|
||||
ENDSTR top; \
|
||||
ENDLIB; \
|
||||
");
|
||||
fclose (file);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
printf( "------------------------------------------------------\n" );
|
||||
printf( "| Unit test of the KBool Engine |\n" );
|
||||
printf( "------------------------------------------------------\n" );
|
||||
|
||||
float correction;
|
||||
char a = '1';
|
||||
while (a != '0')
|
||||
{
|
||||
Bool_Engine* booleng = new Bool_Engine();
|
||||
ArmBoolEng( booleng );
|
||||
|
||||
AddPolygonsToBoolEng( booleng );
|
||||
|
||||
printf( "\n***********************************\n" );
|
||||
printf( "*** version: %s \n", booleng->GetVersion() );
|
||||
printf( "***********************************\n" );
|
||||
printf( "1: OR operation\n" );
|
||||
printf( "2: AND operation\n" );
|
||||
printf( "3: EXOR operation\n" );
|
||||
printf( "4: A subtract B\n" );
|
||||
printf( "5: B subtract A\n" );
|
||||
printf( "6: Correct each polygon with a factor\n" );
|
||||
printf( "7: Smoothen each polygon\n" );
|
||||
printf( "8: Make a ring around each polygon\n" );
|
||||
printf( "9: No operation\n" );
|
||||
printf( "0: Quit\n" );
|
||||
printf( "***********************************\n" );
|
||||
|
||||
printf( "type a number and <return>" );
|
||||
scanf( "%c", &a );
|
||||
|
||||
switch (a)
|
||||
{
|
||||
case ('0'):
|
||||
break;
|
||||
case ('1'):
|
||||
booleng->Do_Operation(BOOL_OR);
|
||||
break;
|
||||
case ('2'):
|
||||
booleng->Do_Operation(BOOL_AND);
|
||||
break;
|
||||
case ('3'):
|
||||
booleng->Do_Operation(BOOL_EXOR);
|
||||
break;
|
||||
case ('4'):
|
||||
booleng->Do_Operation(BOOL_A_SUB_B);
|
||||
break;
|
||||
case ('5'):
|
||||
booleng->Do_Operation(BOOL_B_SUB_A);
|
||||
break;
|
||||
case ('6'):
|
||||
printf( "give correction factor (eg. 100.0 or -100.0)<return>:");
|
||||
scanf("%f", &correction ); // correct the polygons by this number
|
||||
booleng->SetCorrectionFactor( correction );
|
||||
booleng->Do_Operation(BOOL_CORRECTION);
|
||||
break;
|
||||
case ('7'):
|
||||
booleng->Do_Operation(BOOL_SMOOTHEN);
|
||||
break;
|
||||
case ('8'):
|
||||
printf("give width of ring <return>:");
|
||||
scanf("%f", &correction );
|
||||
// create a ring of this size
|
||||
booleng->SetCorrectionFactor( fabs( correction / 2.0) );
|
||||
booleng->Do_Operation(BOOL_MAKERING);
|
||||
break;
|
||||
case ('9'):
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if (a != '0')
|
||||
{
|
||||
printf("\nresulting polygons\n" );
|
||||
|
||||
GetPolygonsFromBoolEng( booleng );
|
||||
|
||||
//OR USE THIS
|
||||
//GetPolygonsFromBoolEngKEY( booleng );
|
||||
|
||||
printf( "\n\ntype a character and <return>");
|
||||
scanf( "%c", &a );
|
||||
}
|
||||
delete booleng;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/*! \file kbool/samples/boolonly/boolonly.h
|
||||
\author Probably Klaas Holwerda
|
||||
|
||||
Copyright: 2001-2004 (C) Probably Klaas Holwerda
|
||||
|
||||
Licence: wxWidgets Licence
|
||||
|
||||
RCS-ID: $Id: boolonly.h,v 1.5 2005/05/24 19:13:38 titato Exp $
|
||||
*/
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma implementation
|
||||
#endif
|
||||
|
||||
#include "kbool/include/_lnk_itr.h"
|
||||
#include "kbool/include/booleng.h"
|
||||
|
||||
class KBoolPoint
|
||||
{
|
||||
public:
|
||||
|
||||
KBoolPoint();
|
||||
KBoolPoint(double const ,double const);
|
||||
double GetX();
|
||||
double GetY();
|
||||
|
||||
private:
|
||||
double _x;
|
||||
double _y;
|
||||
|
||||
};
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
IF(WIN32)
|
||||
ADD_DEFINITIONS( -D_MSWVC_ )
|
||||
ELSE(WIN32)
|
||||
ADD_DEFINITIONS( -D__UNIX__ )
|
||||
ENDIF(WIN32)
|
||||
|
||||
include_directories(${kbool_SOURCE_DIR}/include)
|
||||
|
||||
set(KBOOL_SRCS
|
||||
booleng.cpp
|
||||
graph.cpp
|
||||
graphlst.cpp
|
||||
line.cpp
|
||||
link.cpp
|
||||
lpoint.cpp
|
||||
node.cpp
|
||||
record.cpp
|
||||
scanbeam.cpp)
|
||||
|
||||
ADD_LIBRARY( kbool ${KBOOL_SRCS})
|
||||
|
|
@ -0,0 +1,608 @@
|
|||
/*! \file kbool/src/booleng.cpp
|
||||
\author Probably Klaas Holwerda
|
||||
|
||||
Copyright: 2001-2004 (C) Probably Klaas Holwerda
|
||||
|
||||
Licence: wxWidgets Licence
|
||||
|
||||
RCS-ID: $Id: booleng.cpp,v 1.11 2005/05/24 19:13:38 titato Exp $
|
||||
*/
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma implementation
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "../include/booleng.h"
|
||||
#include "../include/link.h"
|
||||
#include "../include/line.h"
|
||||
#include "../include/node.h"
|
||||
#include "../include/graph.h"
|
||||
#include "../include/graphlst.h"
|
||||
|
||||
B_INT bmin(B_INT const value1, B_INT const value2)
|
||||
{
|
||||
return((value1 < value2) ? value1 : value2 );
|
||||
}
|
||||
|
||||
B_INT bmax(B_INT const value1, B_INT const value2)
|
||||
{
|
||||
return((value1 > value2) ? value1 : value2 );
|
||||
}
|
||||
|
||||
B_INT babs(B_INT a)
|
||||
{
|
||||
if (a < 0) a=-a;
|
||||
return a;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------/
|
||||
//----------------- Bool_Engine_Error -------------------------------/
|
||||
//-------------------------------------------------------------------/
|
||||
|
||||
Bool_Engine_Error::Bool_Engine_Error(const char* message, const char* header, int degree, int fatal)
|
||||
{
|
||||
_message = new char[LINELENGTH];
|
||||
_header = new char[LINELENGTH];
|
||||
if (message)
|
||||
strcpy(_message, message);
|
||||
else
|
||||
strcpy(_message,"non specified");
|
||||
|
||||
if (header)
|
||||
strcpy(_header, header);
|
||||
else
|
||||
strcpy(_header,"non specified");
|
||||
|
||||
_degree = degree;
|
||||
_fatal = fatal;
|
||||
|
||||
}
|
||||
|
||||
Bool_Engine_Error::Bool_Engine_Error(const Bool_Engine_Error& a)
|
||||
{
|
||||
_message = new char[LINELENGTH];
|
||||
_header = new char[LINELENGTH];
|
||||
if (a._message)
|
||||
strcpy(_message, a._message);
|
||||
else
|
||||
strcpy(_message,"non specified");
|
||||
|
||||
if (a._header)
|
||||
strcpy(_header, a._header);
|
||||
else
|
||||
strcpy(_header,"non specified");
|
||||
|
||||
_degree = a._degree;
|
||||
_fatal = a._fatal;
|
||||
|
||||
}
|
||||
|
||||
Bool_Engine_Error::~Bool_Engine_Error()
|
||||
{
|
||||
strcpy(_message,"");
|
||||
strcpy(_header,"");
|
||||
delete _message;
|
||||
delete _header;
|
||||
}
|
||||
|
||||
char* Bool_Engine_Error::GetErrorMessage()
|
||||
{
|
||||
return _message;
|
||||
}
|
||||
|
||||
char* Bool_Engine_Error::GetHeaderMessage()
|
||||
{
|
||||
return _header;
|
||||
}
|
||||
|
||||
int Bool_Engine_Error::GetErrorDegree()
|
||||
{
|
||||
return _degree;
|
||||
}
|
||||
|
||||
int Bool_Engine_Error::GetFatal()
|
||||
{
|
||||
return _fatal;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------/
|
||||
//----------------- Bool_Engine -------------------------------------/
|
||||
//-------------------------------------------------------------------/
|
||||
|
||||
Bool_Engine::Bool_Engine()
|
||||
{
|
||||
_linkiter=new TDLI<KBoolLink>();
|
||||
m_intersectionruns = 1;
|
||||
|
||||
m_orientationEntryMode = false;
|
||||
m_doLinkHoles = true;
|
||||
|
||||
m_graphlist = new GraphList(this);
|
||||
m_ACCUR = 1e-4;
|
||||
m_WINDINGRULE = true;
|
||||
m_GraphToAdd = NULL;
|
||||
m_firstNodeToAdd = NULL;
|
||||
m_lastNodeToAdd = NULL;
|
||||
|
||||
m_logfile = NULL;
|
||||
|
||||
#if KBOOL_LOG == 1
|
||||
SetLog( true );
|
||||
#else
|
||||
SetLog( false );
|
||||
#endif
|
||||
}
|
||||
|
||||
Bool_Engine::~Bool_Engine()
|
||||
{
|
||||
if (m_logfile != NULL)
|
||||
fclose (m_logfile);
|
||||
|
||||
delete _linkiter;
|
||||
delete m_graphlist;
|
||||
}
|
||||
|
||||
void Bool_Engine::SetLog( bool OnOff )
|
||||
{
|
||||
m_doLog = OnOff;
|
||||
if ( m_doLog )
|
||||
{
|
||||
if ( m_logfile == NULL )
|
||||
{
|
||||
// create a new logfile
|
||||
m_logfile = fopen(KBOOL_LOGFILE, "w");
|
||||
if (m_logfile == NULL)
|
||||
fprintf(stderr,"Bool_Engine: Unable to write to Boolean Engine logfile\n");
|
||||
else
|
||||
{
|
||||
time_t timer;
|
||||
struct tm * today;
|
||||
timer = time(NULL);
|
||||
today = localtime(&timer);
|
||||
|
||||
fprintf(m_logfile, "Logfile created on:\t\t\t%s", ctime( &timer ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_logfile != NULL)
|
||||
{
|
||||
fclose (m_logfile);
|
||||
m_logfile = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Bool_Engine::SetState( const char* process )
|
||||
{
|
||||
Write_Log(process);
|
||||
}
|
||||
|
||||
void Bool_Engine::error(const char *text,const char *title)
|
||||
{
|
||||
Write_Log("FATAL ERROR: ", title);
|
||||
Write_Log("FATAL ERROR: ", text);
|
||||
throw Bool_Engine_Error(" Fatal Error", "Fatal Error", 9, 1);
|
||||
};
|
||||
|
||||
void Bool_Engine::info(const char *text, const char *title)
|
||||
{
|
||||
Write_Log("FATAL ERROR: ", title);
|
||||
Write_Log("FATAL ERROR: ", text);
|
||||
};
|
||||
|
||||
void Bool_Engine::SetMarge(double marge)
|
||||
{
|
||||
m_MARGE = marge;
|
||||
Write_Log("Bool_Engine::m_MARGE = %f\n", m_MARGE);
|
||||
}
|
||||
|
||||
double Bool_Engine::GetAccur()
|
||||
{
|
||||
return m_ACCUR;
|
||||
}
|
||||
|
||||
void Bool_Engine::SetRoundfactor(double roundfac)
|
||||
{
|
||||
m_ROUNDFACTOR = roundfac;
|
||||
Write_Log("Bool_Engine::m_ROUNDFACTOR = %f\n", m_ROUNDFACTOR);
|
||||
}
|
||||
|
||||
double Bool_Engine::GetRoundfactor()
|
||||
{
|
||||
return m_ROUNDFACTOR;
|
||||
}
|
||||
|
||||
double Bool_Engine::GetMarge()
|
||||
{
|
||||
return m_MARGE;
|
||||
}
|
||||
|
||||
void Bool_Engine::SetDGrid(double dgrid)
|
||||
{
|
||||
m_DGRID = dgrid;
|
||||
Write_Log("Bool_Engine::m_DGRID = %f\n", m_DGRID);
|
||||
}
|
||||
|
||||
double Bool_Engine::GetDGrid()
|
||||
{
|
||||
return m_DGRID;
|
||||
}
|
||||
|
||||
void Bool_Engine::SetGrid(B_INT grid)
|
||||
{
|
||||
m_GRID = grid;
|
||||
Write_Log("Bool_Engine::m_GRID = %lld\n", m_GRID);
|
||||
}
|
||||
|
||||
B_INT Bool_Engine::GetGrid()
|
||||
{
|
||||
return m_GRID;
|
||||
}
|
||||
|
||||
void Bool_Engine::SetCorrectionAber(double aber)
|
||||
{
|
||||
m_CORRECTIONABER = aber;
|
||||
Write_Log("Bool_Engine::m_CORRECTIONABER = %f\n", m_CORRECTIONABER);
|
||||
}
|
||||
|
||||
double Bool_Engine::GetCorrectionAber()
|
||||
{
|
||||
return m_CORRECTIONABER;
|
||||
}
|
||||
|
||||
void Bool_Engine::SetCorrectionFactor(double aber)
|
||||
{
|
||||
m_CORRECTIONFACTOR = aber;
|
||||
Write_Log("Bool_Engine::m_CORRECTIONFACTOR = %f\n", m_CORRECTIONFACTOR );
|
||||
}
|
||||
|
||||
double Bool_Engine::GetCorrectionFactor()
|
||||
{
|
||||
return m_CORRECTIONFACTOR;
|
||||
}
|
||||
|
||||
void Bool_Engine::SetSmoothAber(double aber)
|
||||
{
|
||||
m_SMOOTHABER = aber;
|
||||
Write_Log("Bool_Engine::m_SMOOTHABER = %f\n",m_SMOOTHABER );
|
||||
}
|
||||
|
||||
double Bool_Engine::GetSmoothAber()
|
||||
{
|
||||
return m_SMOOTHABER;
|
||||
}
|
||||
|
||||
void Bool_Engine::SetMaxlinemerge(double maxline)
|
||||
{
|
||||
m_MAXLINEMERGE = maxline;
|
||||
Write_Log("Bool_Engine::m_MAXLINEMERGE = %f\n",m_MAXLINEMERGE );
|
||||
}
|
||||
|
||||
double Bool_Engine::GetMaxlinemerge()
|
||||
{
|
||||
return m_MAXLINEMERGE;
|
||||
}
|
||||
|
||||
void Bool_Engine::SetWindingRule(bool rule)
|
||||
{
|
||||
m_WINDINGRULE = rule;
|
||||
}
|
||||
|
||||
bool Bool_Engine::GetWindingRule()
|
||||
{
|
||||
return m_WINDINGRULE;
|
||||
}
|
||||
|
||||
|
||||
void Bool_Engine::SetInternalMarge( B_INT marge )
|
||||
{
|
||||
m_MARGE = (double)marge/m_GRID/m_DGRID;
|
||||
}
|
||||
|
||||
B_INT Bool_Engine::GetInternalMarge()
|
||||
{
|
||||
return (B_INT) ( m_MARGE*m_GRID*m_DGRID );
|
||||
}
|
||||
|
||||
double Bool_Engine::GetInternalCorrectionAber()
|
||||
{
|
||||
return m_CORRECTIONABER*m_GRID*m_DGRID;
|
||||
}
|
||||
|
||||
double Bool_Engine::GetInternalCorrectionFactor()
|
||||
{
|
||||
return m_CORRECTIONFACTOR*m_GRID*m_DGRID;
|
||||
}
|
||||
|
||||
double Bool_Engine::GetInternalSmoothAber()
|
||||
{
|
||||
return m_SMOOTHABER*m_GRID*m_DGRID;
|
||||
}
|
||||
|
||||
B_INT Bool_Engine::GetInternalMaxlinemerge()
|
||||
{
|
||||
return (B_INT) ( m_MAXLINEMERGE*m_GRID*m_DGRID );
|
||||
}
|
||||
|
||||
#define TRIALS 30
|
||||
|
||||
bool Bool_Engine::Do_Operation(BOOL_OP operation)
|
||||
{
|
||||
|
||||
#if KBOOL_DEBUG
|
||||
GraphList* saveme = new GraphList( m_graphlist );
|
||||
#endif
|
||||
|
||||
try
|
||||
{
|
||||
switch (operation)
|
||||
{
|
||||
case (BOOL_OR):
|
||||
case (BOOL_AND):
|
||||
case (BOOL_EXOR):
|
||||
case (BOOL_A_SUB_B):
|
||||
case (BOOL_B_SUB_A):
|
||||
m_graphlist->Boolean(operation, m_intersectionruns);
|
||||
break;
|
||||
case (BOOL_CORRECTION):
|
||||
m_graphlist->Correction();
|
||||
break;
|
||||
case (BOOL_MAKERING):
|
||||
m_graphlist->MakeRings();
|
||||
break;
|
||||
case (BOOL_SMOOTHEN):
|
||||
m_graphlist->Smoothen( GetInternalSmoothAber() );
|
||||
break;
|
||||
default:
|
||||
{
|
||||
error("Wrong operation","Command Error");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Bool_Engine_Error& error)
|
||||
{
|
||||
|
||||
#if KBOOL_DEBUG
|
||||
delete m_graphlist;
|
||||
m_graphlist = new GraphList( saveme );
|
||||
m_graphlist->WriteGraphsKEY(this);
|
||||
#endif
|
||||
|
||||
if (m_logfile != NULL)
|
||||
{
|
||||
fclose (m_logfile);
|
||||
m_logfile = NULL;
|
||||
}
|
||||
|
||||
info(error.GetErrorMessage(), "error");
|
||||
throw error;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
|
||||
#if KBOOL_DEBUG
|
||||
delete m_graphlist;
|
||||
m_graphlist = new GraphList( saveme );
|
||||
m_graphlist->WriteGraphsKEY(this);
|
||||
#endif
|
||||
|
||||
if (m_logfile != NULL)
|
||||
{
|
||||
fclose (m_logfile);
|
||||
m_logfile = NULL;
|
||||
}
|
||||
|
||||
info("Unknown exception", "error");
|
||||
throw ;
|
||||
}
|
||||
|
||||
#if KBOOL_DEBUG
|
||||
delete saveme;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Bool_Engine::StartPolygonAdd(GroupType A_or_B)
|
||||
{
|
||||
#if KBOOL_DEBUG
|
||||
if (m_logfile != NULL)
|
||||
fprintf(m_logfile, "-> StartPolygonAdd(%d)\n", A_or_B);
|
||||
#endif
|
||||
if (m_GraphToAdd != NULL)
|
||||
return false;
|
||||
|
||||
Graph *myGraph = new Graph(this);
|
||||
m_graphlist->insbegin(myGraph);
|
||||
m_GraphToAdd = myGraph;
|
||||
m_groupType = A_or_B;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Bool_Engine::AddPoint(double x, double y)
|
||||
{
|
||||
if (m_GraphToAdd == NULL){return false;}
|
||||
|
||||
double scaledx = x * m_DGRID * m_GRID;
|
||||
double scaledy = y * m_DGRID * m_GRID;
|
||||
|
||||
if ( scaledx > MAXB_INT || scaledx < MINB_INT )
|
||||
error("X coordinate of vertex to big", "" );
|
||||
if ( scaledy > MAXB_INT || scaledy < MINB_INT )
|
||||
error("Y coordinate of vertex to big", "" );
|
||||
|
||||
|
||||
B_INT rintx = ((B_INT) (x * m_DGRID)) * m_GRID;
|
||||
B_INT rinty = ((B_INT) (y * m_DGRID)) * m_GRID;
|
||||
Node *myNode = new Node( rintx, rinty, this );
|
||||
|
||||
// adding first point to graph
|
||||
if (m_firstNodeToAdd == NULL)
|
||||
{
|
||||
#if KBOOL_DEBUG
|
||||
if (m_logfile != NULL)
|
||||
{
|
||||
fprintf(m_logfile, "-> AddPt() *FIRST* :");
|
||||
fprintf(m_logfile, " input: x = %f, y = %f\n", x, y);
|
||||
fprintf(m_logfile, " input: x = %I64d, y = %I64d\n", rintx, rinty) ;
|
||||
}
|
||||
#endif
|
||||
|
||||
m_firstNodeToAdd = (Node *) myNode;
|
||||
m_lastNodeToAdd = (Node *) myNode;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if KBOOL_DEBUG
|
||||
if (m_logfile != NULL)
|
||||
{
|
||||
fprintf(m_logfile, "-> AddPt():");
|
||||
fprintf(m_logfile, " input: x = %f, y = %f\n", x, y);
|
||||
fprintf(m_logfile, " input: x = %I64d, y = %I64d\n", rintx, rinty) ;
|
||||
}
|
||||
#endif
|
||||
|
||||
m_GraphToAdd->AddLink(m_lastNodeToAdd, myNode);
|
||||
m_lastNodeToAdd = (Node *) myNode;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Bool_Engine::EndPolygonAdd()
|
||||
{
|
||||
if (m_GraphToAdd == NULL) {return false;}
|
||||
|
||||
m_GraphToAdd->AddLink(m_lastNodeToAdd, m_firstNodeToAdd);
|
||||
m_GraphToAdd->SetGroup(m_groupType);
|
||||
m_GraphToAdd = NULL;
|
||||
m_lastNodeToAdd = NULL;
|
||||
m_firstNodeToAdd = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Bool_Engine::StartPolygonGet()
|
||||
{
|
||||
if (!m_graphlist->empty())
|
||||
{
|
||||
m_getGraph = (Graph*) m_graphlist->headitem();
|
||||
m_getLink = m_getGraph->GetFirstLink();
|
||||
m_getNode = m_getLink->GetBeginNode();
|
||||
m_numPtsInPolygon = m_getGraph->GetNumberOfLinks();
|
||||
m_numNodesVisited = 0;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Bool_Engine::PolygonHasMorePoints()
|
||||
{
|
||||
// see if first point
|
||||
if (m_numNodesVisited == 0)
|
||||
{
|
||||
// don't need to touch the m_getNode
|
||||
m_numNodesVisited++;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (m_numNodesVisited < m_numPtsInPolygon)
|
||||
{
|
||||
// traverse to the next node
|
||||
m_getNode = m_getLink->GetOther(m_getNode);
|
||||
m_getLink = m_getLink->Forth(m_getNode);
|
||||
|
||||
m_numNodesVisited++;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void Bool_Engine::EndPolygonGet()
|
||||
{
|
||||
m_graphlist->removehead();
|
||||
delete m_getGraph;
|
||||
}
|
||||
|
||||
double Bool_Engine::GetPolygonXPoint()
|
||||
{
|
||||
return m_getNode->GetX()/m_GRID/m_DGRID;
|
||||
}
|
||||
|
||||
double Bool_Engine::GetPolygonYPoint()
|
||||
{
|
||||
return m_getNode->GetY()/m_GRID/m_DGRID;
|
||||
}
|
||||
|
||||
bool Bool_Engine::GetHoleSegment()
|
||||
{
|
||||
if (m_getLink->GetHole())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Bool_Engine::GetHoleConnectionSegment()
|
||||
{
|
||||
if (m_getLink->GetHoleLink())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
kbEdgeType Bool_Engine::GetPolygonPointEdgeType()
|
||||
{
|
||||
// see if the point is the beginning of a false edge
|
||||
if ( m_getLink->GetHoleLink() )
|
||||
return KB_FALSE_EDGE;
|
||||
else
|
||||
// it's either an outside or inside edge
|
||||
if ( m_getLink->GetHole() )
|
||||
return KB_INSIDE_EDGE;
|
||||
else
|
||||
return KB_OUTSIDE_EDGE;
|
||||
}
|
||||
|
||||
|
||||
void Bool_Engine::Write_Log(const char *msg1)
|
||||
{
|
||||
if (m_logfile == NULL)
|
||||
return;
|
||||
|
||||
fprintf(m_logfile,"%s \n",msg1);
|
||||
}
|
||||
|
||||
void Bool_Engine::Write_Log(const char *msg1, const char*msg2)
|
||||
{
|
||||
if (m_logfile == NULL)
|
||||
return;
|
||||
|
||||
fprintf(m_logfile,"%s %s\n",msg1, msg2);
|
||||
}
|
||||
|
||||
void Bool_Engine::Write_Log(const char *fmt, double dval)
|
||||
{
|
||||
if (m_logfile == NULL)
|
||||
return;
|
||||
|
||||
fprintf(m_logfile,fmt,dval);
|
||||
}
|
||||
|
||||
void Bool_Engine::Write_Log(const char *fmt, B_INT bval)
|
||||
{
|
||||
if (m_logfile == NULL)
|
||||
return;
|
||||
|
||||
fprintf(m_logfile,fmt,bval);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,396 @@
|
|||
/*! \file ../src/graphlst.cpp
|
||||
\brief Implements a list of graphs
|
||||
\author Probably Klaas Holwerda
|
||||
|
||||
Copyright: 2001-2004 (C) Probably Klaas Holwerda
|
||||
|
||||
Licence: wxWidgets Licence
|
||||
|
||||
RCS-ID: $Id: graphlst.cpp,v 1.8 2005/05/24 19:13:38 titato Exp $
|
||||
*/
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma implementation
|
||||
#endif
|
||||
|
||||
//#include "debugdrv.h"
|
||||
#include "../include/booleng.h"
|
||||
#include "../include/graphlst.h"
|
||||
|
||||
//extern Debug_driver* _debug_driver;
|
||||
//this here is to initialize the static iterator of graphlist
|
||||
//with NOLIST constructor
|
||||
|
||||
int graphsorterX( Graph *, Graph * );
|
||||
int graphsorterY( Graph *, Graph * );
|
||||
|
||||
GraphList::GraphList(Bool_Engine* GC)
|
||||
{
|
||||
_GC=GC;
|
||||
}
|
||||
|
||||
GraphList::GraphList( GraphList* other )
|
||||
{
|
||||
_GC = other->_GC;
|
||||
|
||||
TDLI<Graph> _LI = TDLI<Graph>( other );
|
||||
_LI.tohead();
|
||||
while (!_LI.hitroot())
|
||||
{
|
||||
insend( new Graph( _LI.item() ) );
|
||||
_LI++;
|
||||
}
|
||||
}
|
||||
|
||||
GraphList::~GraphList()
|
||||
{
|
||||
TDLI<Graph> _LI=TDLI<Graph>(this);
|
||||
//first empty the graph
|
||||
_LI.delete_all();
|
||||
}
|
||||
|
||||
//prepare the graphlist for the boolean operations
|
||||
//group all graphs into ONE graph
|
||||
void GraphList::Prepare(Graph* total)
|
||||
{
|
||||
if (empty())
|
||||
return;
|
||||
|
||||
//round to grid and put in one graph
|
||||
_GC->SetState("Simplify");
|
||||
|
||||
// Simplify all graphs in the list
|
||||
Simplify( (double) _GC->GetGrid() );
|
||||
|
||||
if ( ! _GC->GetOrientationEntryMode() )
|
||||
{
|
||||
TDLI<Graph> _LI=TDLI<Graph>(this);
|
||||
_LI.tohead();
|
||||
while (!_LI.hitroot())
|
||||
{
|
||||
_LI.item()->MakeClockWise();
|
||||
_LI++;
|
||||
}
|
||||
}
|
||||
|
||||
Renumber();
|
||||
|
||||
//the graplist contents will be transferred to one graph
|
||||
MakeOneGraph(total);
|
||||
}
|
||||
|
||||
// the function will make from all the graphs in the graphlist one graph,
|
||||
// simply by throwing all the links in one graph, the graphnumbers will
|
||||
// not be changed
|
||||
void GraphList::MakeOneGraph(Graph* total)
|
||||
{
|
||||
TDLI<Graph> _LI=TDLI<Graph>(this);
|
||||
_LI.tohead();
|
||||
while(!_LI.hitroot())
|
||||
{
|
||||
total->TakeOver(_LI.item());
|
||||
delete _LI.item();
|
||||
_LI.remove();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Renumber all the graphs
|
||||
//
|
||||
void GraphList::Renumber()
|
||||
{
|
||||
if ( _GC->GetOrientationEntryMode() )
|
||||
{
|
||||
TDLI<Graph> _LI=TDLI<Graph>(this);
|
||||
_LI.tohead();
|
||||
while (!_LI.hitroot())
|
||||
{
|
||||
if ( _LI.item()->GetFirstLink()->Group() == GROUP_A )
|
||||
_LI.item()->SetNumber(1);
|
||||
else
|
||||
_LI.item()->SetNumber(2);
|
||||
_LI++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int Number = 1;
|
||||
TDLI<Graph> _LI=TDLI<Graph>(this);
|
||||
_LI.tohead();
|
||||
while (!_LI.hitroot())
|
||||
{
|
||||
_LI.item()->SetNumber(Number++);
|
||||
_LI++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Simplify the graphs
|
||||
void GraphList::Simplify(double marge)
|
||||
{
|
||||
TDLI<Graph> _LI=TDLI<Graph>(this);
|
||||
_LI.foreach_mf(&Graph::Reset_Mark_and_Bin);
|
||||
|
||||
_LI.tohead();
|
||||
while (!_LI.hitroot())
|
||||
{
|
||||
if (_LI.item()->Simplify( (B_INT) marge))
|
||||
{
|
||||
if (_LI.item()->GetNumberOfLinks() < 3)
|
||||
// delete this graph from the graphlist
|
||||
{
|
||||
delete _LI.item();
|
||||
_LI.remove();
|
||||
}
|
||||
}
|
||||
else
|
||||
_LI++;
|
||||
}
|
||||
}
|
||||
|
||||
// Smoothen the graphs
|
||||
void GraphList::Smoothen(double marge)
|
||||
{
|
||||
TDLI<Graph> _LI=TDLI<Graph>(this);
|
||||
_LI.foreach_mf(&Graph::Reset_Mark_and_Bin);
|
||||
|
||||
_LI.tohead();
|
||||
while (!_LI.hitroot())
|
||||
{
|
||||
if (_LI.item()->Smoothen( (B_INT) marge))
|
||||
{
|
||||
if (_LI.item()->GetNumberOfLinks() < 3)
|
||||
// delete this graph from the graphlist
|
||||
{
|
||||
delete _LI.item();
|
||||
_LI.remove();
|
||||
}
|
||||
}
|
||||
else
|
||||
_LI++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Turn off all markers in all the graphs
|
||||
void GraphList::UnMarkAll()
|
||||
{
|
||||
TDLI<Graph> _LI=TDLI<Graph>(this);
|
||||
_LI.foreach_mf(&Graph::Reset_Mark_and_Bin);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
//
|
||||
//======================== BOOLEAN FUNCTIONS ===================================
|
||||
//
|
||||
//==============================================================================
|
||||
|
||||
void GraphList::Correction()
|
||||
{
|
||||
TDLI<Graph> _LI=TDLI<Graph>(this);
|
||||
int todo=_LI.count();
|
||||
|
||||
if ( _GC->GetInternalCorrectionFactor()) //not zero
|
||||
{
|
||||
_LI.tohead();
|
||||
for(int i=0; i<todo ; i++)
|
||||
{
|
||||
//the input graph will be empty in the end
|
||||
GraphList *_correct=new GraphList(_GC);
|
||||
{
|
||||
_LI.item()->MakeClockWise();
|
||||
_LI.item()->Correction(_correct,_GC->GetInternalCorrectionFactor());
|
||||
|
||||
delete _LI.item();
|
||||
_LI.remove();
|
||||
|
||||
//move corrected graphlist to result
|
||||
while (!_correct->empty())
|
||||
{
|
||||
//add to end
|
||||
_LI.insend((Graph*)_correct->headitem());
|
||||
_correct->removehead();
|
||||
}
|
||||
}
|
||||
delete _correct;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GraphList::MakeRings()
|
||||
{
|
||||
TDLI<Graph> _LI=TDLI<Graph>(this);
|
||||
int todo=_LI.count();
|
||||
|
||||
_LI.tohead();
|
||||
for(int i=0; i<todo ; i++)
|
||||
{
|
||||
//the input graph will be empty in the end
|
||||
GraphList *_ring=new GraphList(_GC);
|
||||
{
|
||||
_LI.item()->MakeClockWise();
|
||||
_LI.item()->MakeRing(_ring,_GC->GetInternalCorrectionFactor());
|
||||
|
||||
delete _LI.item();
|
||||
_LI.remove();
|
||||
|
||||
//move created rings graphs to this
|
||||
while (!_ring->empty())
|
||||
{
|
||||
//add to end
|
||||
((Graph*)_ring->headitem())->MakeClockWise();
|
||||
_LI.insend((Graph*)_ring->headitem());
|
||||
_ring->removehead();
|
||||
}
|
||||
}
|
||||
delete _ring;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//merge the graphs in the list and return the merged result
|
||||
void GraphList::Merge()
|
||||
{
|
||||
if (count()<=1)
|
||||
return;
|
||||
|
||||
{
|
||||
TDLI<Graph> _LI=TDLI<Graph>(this);
|
||||
_LI.tohead();
|
||||
while (!_LI.hitroot())
|
||||
{
|
||||
_LI.item()->SetGroup(GROUP_A);
|
||||
_LI++;
|
||||
}
|
||||
}
|
||||
|
||||
Graph* _tomerge=new Graph(_GC);
|
||||
|
||||
Renumber();
|
||||
|
||||
//the graplist contents will be transferred to one graph
|
||||
MakeOneGraph(_tomerge);
|
||||
//the original is empty now
|
||||
|
||||
_tomerge->Prepare(1);
|
||||
_tomerge->Boolean(BOOL_OR,this);
|
||||
|
||||
delete _tomerge;
|
||||
}
|
||||
|
||||
#define TRIALS 30
|
||||
#define SAVEME 1
|
||||
|
||||
//perform boolean operation on the graphs in the list
|
||||
void GraphList::Boolean(BOOL_OP operation, int intersectionRunsMax )
|
||||
{
|
||||
_GC->SetState("Performing Boolean Operation");
|
||||
|
||||
if (count()==0)
|
||||
return;
|
||||
|
||||
Graph* _prepared = new Graph(_GC);
|
||||
|
||||
if (empty())
|
||||
return;
|
||||
|
||||
//round to grid and put in one graph
|
||||
_GC->SetState("Simplify");
|
||||
|
||||
int intersectionruns = 1;
|
||||
|
||||
while ( intersectionruns <= intersectionRunsMax )
|
||||
{
|
||||
try
|
||||
{
|
||||
Prepare( _prepared );
|
||||
|
||||
if (_prepared->GetNumberOfLinks())
|
||||
{
|
||||
//calculate intersections etc.
|
||||
_GC->SetState("prepare");
|
||||
_prepared->Prepare( intersectionruns );
|
||||
//_prepared->writegraph(true);
|
||||
_prepared->Boolean(operation,this);
|
||||
}
|
||||
intersectionruns = intersectionRunsMax +1;
|
||||
}
|
||||
catch (Bool_Engine_Error& error)
|
||||
{
|
||||
#if KBOOL_DEBUG
|
||||
_prepared->WriteGraphKEY(_GC);
|
||||
#endif
|
||||
intersectionruns++;
|
||||
if ( intersectionruns == intersectionRunsMax )
|
||||
{
|
||||
_prepared->WriteGraphKEY(_GC);
|
||||
_GC->info(error.GetErrorMessage(), "error");
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
|
||||
#if KBOOL_DEBUG
|
||||
_prepared->WriteGraphKEY(_GC);
|
||||
#endif
|
||||
intersectionruns++;
|
||||
if ( intersectionruns == intersectionRunsMax )
|
||||
{
|
||||
_prepared->WriteGraphKEY(_GC);
|
||||
_GC->info("Unknown exception", "error");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete _prepared;
|
||||
}
|
||||
|
||||
|
||||
void GraphList::WriteGraphs()
|
||||
{
|
||||
TDLI<Graph> _LI=TDLI<Graph>(this);
|
||||
_LI.tohead();
|
||||
while(!_LI.hitroot())
|
||||
{
|
||||
_LI.item()->writegraph( false );
|
||||
_LI++;
|
||||
}
|
||||
}
|
||||
|
||||
void GraphList::WriteGraphsKEY( Bool_Engine* GC )
|
||||
{
|
||||
FILE* file = fopen("graphkeyfile.key", "w");
|
||||
|
||||
fprintf(file,"\
|
||||
HEADER 5; \
|
||||
BGNLIB; \
|
||||
LASTMOD {2-11-15 15:39:21}; \
|
||||
LASTACC {2-11-15 15:39:21}; \
|
||||
LIBNAME trial; \
|
||||
UNITS; \
|
||||
USERUNITS 0.0001; PHYSUNITS 1e-009; \
|
||||
\
|
||||
BGNSTR; \
|
||||
CREATION {2-11-15 15:39:21}; \
|
||||
LASTMOD {2-11-15 15:39:21}; \
|
||||
STRNAME top; \
|
||||
");
|
||||
|
||||
TDLI<Graph> _LI=TDLI<Graph>(this);
|
||||
_LI.tohead();
|
||||
while(!_LI.hitroot())
|
||||
{
|
||||
_LI.item()->WriteKEY( GC, file );
|
||||
_LI++;
|
||||
}
|
||||
|
||||
fprintf(file,"\
|
||||
ENDSTR top; \
|
||||
ENDLIB; \
|
||||
");
|
||||
|
||||
fclose (file);
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*! \file ../src/instonly.cpp
|
||||
\author Probably Klaas Holwerda
|
||||
|
||||
Copyright: 2001-2004 (C) Probably Klaas Holwerda
|
||||
|
||||
Licence: wxWidgets Licence
|
||||
|
||||
RCS-ID: $Id: instonly.cpp,v 1.5 2005/05/24 19:13:38 titato Exp $
|
||||
*/
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma option -Jgd
|
||||
|
||||
#include "../include/_dl_itr.h"
|
||||
#include "../include/node.h"
|
||||
#include "../include/record.h"
|
||||
#include "../include/link.h"
|
||||
#include "../include/_lnk_itr.h"
|
||||
#include "../include/scanbeam.h"
|
||||
#include "../include/graph.h"
|
||||
#include "../include/graphlst.h"
|
||||
//#include "../include/misc.h"
|
||||
|
||||
template class DL_Node<void *>;
|
||||
template class DL_Iter<void *>;
|
||||
template class DL_List<void *>;
|
||||
|
||||
template class DL_Node<int>;
|
||||
template class DL_Iter<int>;
|
||||
template class DL_List<int>;
|
||||
|
||||
template class TDLI<Node>;
|
||||
template class TDLI<LPoint>;
|
||||
template class TDLI<Record>;
|
||||
template class TDLI<KBoolLink>;
|
||||
template class TDLI<Graph>;
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,721 @@
|
|||
/*! \file ../src/link.cpp
|
||||
\author Probably Klaas Holwerda
|
||||
|
||||
Copyright: 2001-2004 (C) Probably Klaas Holwerda
|
||||
|
||||
Licence: wxWidgets Licence
|
||||
|
||||
RCS-ID: $Id: link.cpp,v 1.10 2005/06/17 22:54:37 kbluck Exp $
|
||||
*/
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma implementation
|
||||
#endif
|
||||
|
||||
#include "../include/booleng.h"
|
||||
|
||||
#include "../include/link.h"
|
||||
#include "../include/line.h"
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "../include/node.h"
|
||||
#include "../include/graph.h"
|
||||
#include "../include/graphlst.h"
|
||||
|
||||
int linkXYsorter(KBoolLink *, KBoolLink *);
|
||||
|
||||
//
|
||||
// Default constructor
|
||||
//
|
||||
KBoolLink::KBoolLink(Bool_Engine* GC)
|
||||
{
|
||||
_GC=GC;
|
||||
Reset();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// This constructor makes this link a valid part of a graph
|
||||
//
|
||||
KBoolLink::KBoolLink(int graphnr, Node *begin, Node *end, Bool_Engine* GC)
|
||||
{
|
||||
_GC=GC;
|
||||
Reset();
|
||||
|
||||
// Set the references of the node and of this link correct
|
||||
begin->AddLink(this);
|
||||
end->AddLink(this);
|
||||
m_beginnode = begin;
|
||||
m_endnode = end;
|
||||
m_graphnum = graphnr;
|
||||
}
|
||||
|
||||
//
|
||||
// This constructor makes this link a valid part of a graph
|
||||
//
|
||||
KBoolLink::KBoolLink(Node *begin, Node *end, Bool_Engine* GC)
|
||||
{
|
||||
_GC=GC;
|
||||
Reset();
|
||||
|
||||
// Set the references of the node and of this link correct
|
||||
begin->AddLink(this);
|
||||
end->AddLink(this);
|
||||
m_beginnode=begin;
|
||||
m_endnode=end;
|
||||
m_graphnum=0;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Destructor
|
||||
//
|
||||
KBoolLink::~KBoolLink()
|
||||
{
|
||||
UnLink();
|
||||
}
|
||||
|
||||
//
|
||||
// Checks whether the current algorithm has been on this link
|
||||
//
|
||||
bool KBoolLink::BeenHere()
|
||||
{
|
||||
if (m_bin) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void KBoolLink::TakeOverOperationFlags( KBoolLink* link )
|
||||
{
|
||||
m_merge_L = link->m_merge_L;
|
||||
m_a_substract_b_L = link->m_a_substract_b_L;
|
||||
m_b_substract_a_L = link->m_b_substract_a_L;
|
||||
m_intersect_L = link->m_intersect_L;
|
||||
m_exor_L = link->m_exor_L;
|
||||
|
||||
m_merge_R = link->m_merge_R;
|
||||
m_a_substract_b_R = link->m_a_substract_b_R;
|
||||
m_b_substract_a_R = link->m_b_substract_a_R;
|
||||
m_intersect_R = link->m_intersect_R;
|
||||
m_exor_R = link->m_exor_R;
|
||||
}
|
||||
//
|
||||
// Returns the next link from the argument
|
||||
//
|
||||
KBoolLink* KBoolLink::Forth(Node *node)
|
||||
{
|
||||
assert(node==m_beginnode || node==m_endnode);
|
||||
return node->GetOtherLink(this);
|
||||
}
|
||||
|
||||
//
|
||||
// Returns the Beginnode
|
||||
//
|
||||
Node *KBoolLink::GetBeginNode()
|
||||
{
|
||||
return m_beginnode;
|
||||
}
|
||||
|
||||
//
|
||||
// Returns the endnode
|
||||
//
|
||||
Node* KBoolLink::GetEndNode()
|
||||
{
|
||||
return m_endnode;
|
||||
}
|
||||
|
||||
Node* KBoolLink::GetLowNode()
|
||||
{
|
||||
return ( ( m_beginnode->GetY() < m_endnode->GetY() ) ? m_beginnode : m_endnode );
|
||||
}
|
||||
|
||||
Node* KBoolLink::GetHighNode()
|
||||
{
|
||||
return ( ( m_beginnode->GetY() > m_endnode->GetY() ) ? m_beginnode : m_endnode );
|
||||
}
|
||||
|
||||
//
|
||||
// Returns the graphnumber
|
||||
//
|
||||
int KBoolLink::GetGraphNum()
|
||||
{
|
||||
return m_graphnum;
|
||||
}
|
||||
|
||||
bool KBoolLink::GetInc()
|
||||
{
|
||||
return m_Inc;
|
||||
// if (Inc) return true;
|
||||
// return false;
|
||||
}
|
||||
|
||||
void KBoolLink::SetInc(bool inc)
|
||||
{
|
||||
m_Inc = inc;
|
||||
// Inc=0;
|
||||
// if (inc) Inc=1;
|
||||
}
|
||||
|
||||
bool KBoolLink::GetLeftA()
|
||||
{
|
||||
return m_LeftA;
|
||||
}
|
||||
|
||||
void KBoolLink::SetLeftA(bool la)
|
||||
{
|
||||
m_LeftA = la;
|
||||
}
|
||||
|
||||
bool KBoolLink::GetLeftB()
|
||||
{
|
||||
return m_LeftB;
|
||||
}
|
||||
|
||||
void KBoolLink::SetLeftB(bool lb)
|
||||
{
|
||||
m_LeftB = lb;
|
||||
}
|
||||
|
||||
bool KBoolLink::GetRightA()
|
||||
{
|
||||
return m_RightA;
|
||||
}
|
||||
|
||||
void KBoolLink::SetRightA(bool ra)
|
||||
{
|
||||
m_RightA = ra;
|
||||
}
|
||||
|
||||
bool KBoolLink::GetRightB()
|
||||
{
|
||||
return m_RightB;
|
||||
}
|
||||
|
||||
void KBoolLink::SetRightB(bool rb)
|
||||
{
|
||||
m_RightB = rb;
|
||||
}
|
||||
|
||||
//
|
||||
// This function is very popular by GP-faults
|
||||
// It returns the node different from a
|
||||
//
|
||||
Node* KBoolLink::GetOther(const Node *const a)
|
||||
{
|
||||
return ( (a != m_beginnode) ? m_beginnode : m_endnode);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Is this marked for given operation
|
||||
//
|
||||
bool KBoolLink::IsMarked(BOOL_OP operation)
|
||||
{
|
||||
switch (operation)
|
||||
{
|
||||
case(BOOL_OR): return m_merge_L || m_merge_R;
|
||||
case(BOOL_AND): return m_intersect_L || m_intersect_R;
|
||||
case(BOOL_A_SUB_B): return m_a_substract_b_L || m_a_substract_b_R;
|
||||
case(BOOL_B_SUB_A): return m_b_substract_a_L || m_b_substract_a_R;
|
||||
case(BOOL_EXOR): return m_exor_L || m_exor_R;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool KBoolLink::IsMarkedLeft(BOOL_OP operation)
|
||||
{
|
||||
switch (operation)
|
||||
{
|
||||
case(BOOL_OR): return m_merge_L;
|
||||
case(BOOL_AND): return m_intersect_L;
|
||||
case(BOOL_A_SUB_B): return m_a_substract_b_L;
|
||||
case(BOOL_B_SUB_A): return m_b_substract_a_L;
|
||||
case(BOOL_EXOR): return m_exor_L;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool KBoolLink::IsMarkedRight(BOOL_OP operation)
|
||||
{
|
||||
switch (operation)
|
||||
{
|
||||
case(BOOL_OR): return m_merge_R;
|
||||
case(BOOL_AND): return m_intersect_R;
|
||||
case(BOOL_A_SUB_B): return m_a_substract_b_R;
|
||||
case(BOOL_B_SUB_A): return m_b_substract_a_R;
|
||||
case(BOOL_EXOR): return m_exor_R;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Is this a hole for given operation
|
||||
// beginnode must be to the left
|
||||
bool KBoolLink::IsHole(BOOL_OP operation)
|
||||
{
|
||||
|
||||
bool topsideA,topsideB;
|
||||
|
||||
if (m_beginnode->GetX() < m_endnode->GetX()) //going to the right?
|
||||
{ topsideA = m_RightA; topsideB = m_RightB; }
|
||||
else
|
||||
{ topsideA = m_LeftA; topsideB = m_LeftB; }
|
||||
|
||||
switch (operation)
|
||||
{
|
||||
case(BOOL_OR): return ( !topsideB && !topsideA );
|
||||
case(BOOL_AND): return ( !topsideB || !topsideA );
|
||||
case(BOOL_A_SUB_B): return ( topsideB || !topsideA );
|
||||
case(BOOL_B_SUB_A): return ( topsideA || !topsideB );
|
||||
case(BOOL_EXOR): return !( (topsideB && !topsideA) || (!topsideB && topsideA) );
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Is this a part of a hole
|
||||
//
|
||||
bool KBoolLink::GetHole()
|
||||
{
|
||||
return (m_hole);
|
||||
}
|
||||
|
||||
|
||||
void KBoolLink::SetHole(bool h)
|
||||
{
|
||||
m_hole = h;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Is this not marked at all
|
||||
//
|
||||
bool KBoolLink::IsUnused()
|
||||
{
|
||||
return
|
||||
!(m_merge_L || m_merge_R ||
|
||||
m_a_substract_b_L || m_a_substract_b_R ||
|
||||
m_b_substract_a_L || m_b_substract_a_R ||
|
||||
m_intersect_L || m_intersect_R ||
|
||||
m_exor_L || m_exor_R );
|
||||
}
|
||||
|
||||
|
||||
bool KBoolLink::IsZero(B_INT marge)
|
||||
{
|
||||
return (m_beginnode->Equal(m_endnode,marge)) ;
|
||||
}
|
||||
|
||||
|
||||
bool KBoolLink::ShorterThan(B_INT marge)
|
||||
{
|
||||
return (m_beginnode->ShorterThan(m_endnode,marge)) ;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Mark this link
|
||||
//
|
||||
void KBoolLink::Mark()
|
||||
{
|
||||
m_mark = true;
|
||||
}
|
||||
|
||||
|
||||
#ifndef ABS
|
||||
#define ABS(a) (((a)<0) ? -(a) : (a))
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// This makes from the begin and endnode one node (argument begin_or_end_node)
|
||||
// The references to this link in the node will also be deleted
|
||||
// After doing that, link link can be deleted or be recycled.
|
||||
//
|
||||
void KBoolLink::MergeNodes(Node *const begin_or_end_node)
|
||||
{
|
||||
// assert(beginnode && endnode);
|
||||
// assert ((begin_or_end_node == beginnode)||(begin_or_end_node == endnode));
|
||||
|
||||
m_beginnode->RemoveLink(this);
|
||||
m_endnode->RemoveLink(this);
|
||||
|
||||
if (m_endnode != m_beginnode)
|
||||
{ // only if beginnode and endnode are different nodes
|
||||
begin_or_end_node->Merge(GetOther(begin_or_end_node));
|
||||
}
|
||||
m_endnode = NULL;
|
||||
m_beginnode=NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// Return the position of the second link compared to this link
|
||||
// Result = IS_ON | IS_LEFT | IS_RIGHT
|
||||
// Here Left and Right is defined as being left or right from
|
||||
// the this link towards the center (common) node
|
||||
//
|
||||
LinkStatus KBoolLink::OutProduct(KBoolLink* const two,double accur)
|
||||
{
|
||||
Node* center;
|
||||
double distance;
|
||||
if (two->GetBeginNode()->Equal(two->GetEndNode(), 1))
|
||||
assert(!two);
|
||||
if (GetBeginNode()->Equal(GetEndNode(), 1))
|
||||
assert(!this);
|
||||
KBoolLine* temp_line = new KBoolLine(this, _GC);
|
||||
|
||||
//the this link should connect to the other two link at at least one node
|
||||
if (m_endnode == two->m_endnode || m_endnode == two->m_beginnode)
|
||||
center = m_endnode;
|
||||
else
|
||||
{ center = m_beginnode;
|
||||
// assert(center==two->endnode || center==two->beginnode);
|
||||
}
|
||||
|
||||
//here something tricky
|
||||
// the factor 10000.0 is needed to asure that the pointonline
|
||||
// is more accurate in this case compared to the intersection for graphs
|
||||
int uitp = temp_line->PointOnLine(two->GetOther(center), distance, accur);
|
||||
|
||||
delete temp_line;
|
||||
|
||||
/*double uitp= (_x - first._x) * (third._y - _y) -
|
||||
(_y - first._y) * (third._x - _x);
|
||||
if (uitp>0) return IS_LEFT;
|
||||
if (uitp<0) return IS_RIGHT;
|
||||
return IS_ON;*/
|
||||
|
||||
//depending on direction of this link (going to or coming from centre)
|
||||
if (center == m_endnode)
|
||||
{
|
||||
if (uitp==LEFT_SIDE)
|
||||
return IS_LEFT;
|
||||
if (uitp==RIGHT_SIDE)
|
||||
return IS_RIGHT;
|
||||
}
|
||||
else //center=beginnode
|
||||
{
|
||||
if (uitp==LEFT_SIDE)
|
||||
return IS_RIGHT;
|
||||
if (uitp==RIGHT_SIDE)
|
||||
return IS_LEFT;
|
||||
}
|
||||
return IS_ON;
|
||||
}
|
||||
|
||||
//
|
||||
// Return the position of the third link compared to this link and
|
||||
// the second link
|
||||
// Result = IS_ON | IS_LEFT | IS_RIGHT
|
||||
//
|
||||
LinkStatus KBoolLink::PointOnCorner(KBoolLink* const two, KBoolLink* const third)
|
||||
{
|
||||
LinkStatus
|
||||
TwoToOne, // Position of two to this line
|
||||
ThirdToOne, // Position of third to this line
|
||||
ThirdToTwo, // Position of third to two
|
||||
Result;
|
||||
|
||||
//m Node* center;
|
||||
|
||||
//the this link should connect to the other two link at at least one node
|
||||
//m if (endnode==two->endnode || endnode==two->beginnode)
|
||||
//m center=endnode;
|
||||
//m else
|
||||
//m { center=beginnode;
|
||||
// assert(center==two->endnode || center==two->beginnode);
|
||||
//m }
|
||||
// assert(center==third->endnode || center==third->beginnode);
|
||||
|
||||
|
||||
|
||||
// Calculate the position of the links compared to eachother
|
||||
TwoToOne = OutProduct(two,_GC->GetAccur());
|
||||
ThirdToOne= OutProduct(third,_GC->GetAccur());
|
||||
//center is used in outproduct to give de direction of two
|
||||
// this is why the result should be swapped
|
||||
ThirdToTwo= two->OutProduct(third,_GC->GetAccur());
|
||||
if (ThirdToTwo==IS_RIGHT)
|
||||
ThirdToTwo=IS_LEFT;
|
||||
else if (ThirdToTwo==IS_LEFT)
|
||||
ThirdToTwo=IS_RIGHT;
|
||||
|
||||
// Select the result
|
||||
switch(TwoToOne)
|
||||
{
|
||||
// Line 2 lies on leftside of this line
|
||||
case IS_LEFT : if ((ThirdToOne==IS_RIGHT) || (ThirdToTwo==IS_RIGHT)) return IS_RIGHT;
|
||||
else if ((ThirdToOne==IS_LEFT) && (ThirdToTwo==IS_LEFT)) return IS_LEFT;
|
||||
else Result=IS_ON; break;
|
||||
// Line 2 lies on this line
|
||||
case IS_ON : if ((ThirdToOne==IS_RIGHT) && (ThirdToTwo==IS_RIGHT)) return IS_RIGHT;
|
||||
else if ((ThirdToOne==IS_LEFT) && (ThirdToTwo==IS_LEFT)) return IS_LEFT;
|
||||
// else if ((ThirdToOne==IS_RIGHT) && (ThirdToTwo==IS_LEFT)) return IS_RIGHT;
|
||||
// else if ((ThirdToOne==IS_LEFT) && (ThirdToTwo==IS_RIGHT)) return IS_LEFT;
|
||||
else Result=IS_ON; break;
|
||||
// Line 2 lies on right side of this line
|
||||
case IS_RIGHT :if ((ThirdToOne==IS_RIGHT) && (ThirdToTwo==IS_RIGHT)) return IS_RIGHT;
|
||||
else if ((ThirdToOne==IS_LEFT) || (ThirdToTwo==IS_LEFT)) return IS_LEFT;
|
||||
else Result=IS_ON; break;
|
||||
default: Result = IS_ON; assert( false );
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
//
|
||||
// Remove the reference from this link to a_node
|
||||
//
|
||||
void KBoolLink::Remove(Node *a_node)
|
||||
{
|
||||
(m_beginnode == a_node) ? m_beginnode = NULL : m_endnode = NULL;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Replace oldnode by newnode and correct the references
|
||||
//
|
||||
void KBoolLink::Replace(Node *oldnode, Node *newnode)
|
||||
{
|
||||
if (m_beginnode == oldnode)
|
||||
{ m_beginnode->RemoveLink(this); // remove the reference to this
|
||||
newnode->AddLink(this); // let newnode refer to this
|
||||
m_beginnode = newnode; // let this refer to newnode
|
||||
}
|
||||
else
|
||||
{ //assert(endnode==oldnode);
|
||||
m_endnode->RemoveLink(this);
|
||||
newnode->AddLink(this);
|
||||
m_endnode = newnode;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Reset all values
|
||||
//
|
||||
void KBoolLink::Reset()
|
||||
{
|
||||
m_beginnode = 0;
|
||||
m_endnode = 0;
|
||||
Reset_flags();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Reset all flags
|
||||
//
|
||||
void KBoolLink::Reset_flags()
|
||||
{
|
||||
m_bin = false; // Marker for walking over the graph
|
||||
m_hole = false; // Is this a part of hole ?
|
||||
m_hole_top = false; // link that is toplink of hole?
|
||||
m_group = GROUP_A; // Does this belong to group A or B ( o.a. for boolean operations between graphs)
|
||||
m_LeftA = false; // Is left in polygongroup A
|
||||
m_RightA= false; // Is right in polygon group A
|
||||
m_LeftB = false; // Is left in polygon group B
|
||||
m_RightB= false; // Is right in polygongroup B
|
||||
m_mark = false; // General purose marker, internally unused
|
||||
m_holelink=false;
|
||||
|
||||
m_merge_L = m_merge_R = false; // Marker for Merge
|
||||
m_a_substract_b_L = m_a_substract_b_R = false; // Marker for substract
|
||||
m_b_substract_a_L = m_b_substract_a_R = false; // Marker for substract
|
||||
m_intersect_L = m_intersect_R = false; // Marker for intersect
|
||||
m_exor_L = m_exor_R= false; // Marker for Exor
|
||||
}
|
||||
|
||||
//
|
||||
// Refill this link by the arguments
|
||||
//
|
||||
void KBoolLink::Reset(Node *begin, Node *end,int graphnr)
|
||||
{
|
||||
// Remove all the previous references
|
||||
UnLink();
|
||||
Reset();
|
||||
// Set the references of the node and of this link correct
|
||||
begin->AddLink(this);
|
||||
end->AddLink(this);
|
||||
m_beginnode = begin;
|
||||
m_endnode = end;
|
||||
if (graphnr!=0)
|
||||
m_graphnum = graphnr;
|
||||
}
|
||||
|
||||
|
||||
void KBoolLink::Set(Node *begin, Node *end)
|
||||
{
|
||||
m_beginnode = begin;
|
||||
m_endnode = end;
|
||||
}
|
||||
|
||||
void KBoolLink::SetBeenHere()
|
||||
{
|
||||
m_bin = true;
|
||||
}
|
||||
|
||||
void KBoolLink::SetNotBeenHere()
|
||||
{
|
||||
m_bin = false;
|
||||
}
|
||||
|
||||
void KBoolLink::SetBeginNode(Node* new_node)
|
||||
{
|
||||
m_beginnode = new_node;
|
||||
}
|
||||
|
||||
|
||||
void KBoolLink::SetEndNode(Node* new_node)
|
||||
{
|
||||
m_endnode = new_node;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Sets the graphnumber to argument num
|
||||
//
|
||||
void KBoolLink::SetGraphNum( int num )
|
||||
{
|
||||
m_graphnum=num;
|
||||
}
|
||||
|
||||
GroupType KBoolLink::Group()
|
||||
{
|
||||
return m_group;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Reset the groupflag to argument groep
|
||||
//
|
||||
void KBoolLink::SetGroup(GroupType groep)
|
||||
{
|
||||
m_group= groep;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Remove all references to this link and from this link
|
||||
//
|
||||
void KBoolLink::UnLink()
|
||||
{
|
||||
if (m_beginnode)
|
||||
{ m_beginnode->RemoveLink(this);
|
||||
if (!m_beginnode->GetNumberOfLinks()) delete m_beginnode;
|
||||
}
|
||||
m_beginnode=NULL;
|
||||
if (m_endnode)
|
||||
{ m_endnode->RemoveLink(this);
|
||||
if (!m_endnode->GetNumberOfLinks()) delete m_endnode;
|
||||
}
|
||||
m_endnode=NULL;
|
||||
}
|
||||
|
||||
|
||||
void KBoolLink::UnMark()
|
||||
{
|
||||
m_mark = false;
|
||||
m_bin = false;
|
||||
}
|
||||
|
||||
void KBoolLink::SetMark(bool value)
|
||||
{
|
||||
m_mark = value;
|
||||
}
|
||||
|
||||
//
|
||||
// general purpose mark checker
|
||||
//
|
||||
bool KBoolLink::IsMarked() { return m_mark; }
|
||||
|
||||
void KBoolLink::SetTopHole(bool value) { m_hole_top = value; }
|
||||
|
||||
bool KBoolLink::IsTopHole() { return m_hole_top; }
|
||||
|
||||
//
|
||||
// Calculates the merge/substact/exor/intersect flags
|
||||
//
|
||||
void KBoolLink::SetLineTypes()
|
||||
{
|
||||
m_merge_R =
|
||||
m_a_substract_b_R =
|
||||
m_b_substract_a_R =
|
||||
m_intersect_R =
|
||||
m_exor_R =
|
||||
m_merge_L =
|
||||
m_a_substract_b_L =
|
||||
m_b_substract_a_L =
|
||||
m_intersect_L =
|
||||
m_exor_L = false;
|
||||
|
||||
//if left side is in group A and B then it is for the merge
|
||||
m_merge_L = m_LeftA || m_LeftB;
|
||||
m_merge_R = m_RightA || m_RightB;
|
||||
//both in mean does not add to result.
|
||||
if (m_merge_L && m_merge_R)
|
||||
m_merge_L = m_merge_R = false;
|
||||
|
||||
m_a_substract_b_L = m_LeftA && !m_LeftB;
|
||||
m_a_substract_b_R = m_RightA && !m_RightB;
|
||||
//both in mean does not add to result.
|
||||
if (m_a_substract_b_L && m_a_substract_b_R)
|
||||
m_a_substract_b_L = m_a_substract_b_R = false;
|
||||
|
||||
m_b_substract_a_L = m_LeftB && !m_LeftA;
|
||||
m_b_substract_a_R = m_RightB && !m_RightA;
|
||||
//both in mean does not add to result.
|
||||
if (m_b_substract_a_L && m_b_substract_a_R)
|
||||
m_b_substract_a_L = m_b_substract_a_R = false;
|
||||
|
||||
m_intersect_L = m_LeftB && m_LeftA;
|
||||
m_intersect_R = m_RightB && m_RightA;
|
||||
//both in mean does not add to result.
|
||||
if (m_intersect_L && m_intersect_R)
|
||||
m_intersect_L = m_intersect_R = false;
|
||||
|
||||
m_exor_L = !( (m_LeftB && m_LeftA) || (!m_LeftB && !m_LeftA) );
|
||||
m_exor_R = !( (m_RightB && m_RightA) || (!m_RightB && !m_RightA) );
|
||||
//both in mean does not add to result.
|
||||
if (m_exor_L && m_exor_R)
|
||||
m_exor_L = m_exor_R = false;
|
||||
}
|
||||
|
||||
|
||||
//put in direction with a_node as beginnode
|
||||
void KBoolLink::Redirect(Node* a_node)
|
||||
{
|
||||
if (a_node != m_beginnode)
|
||||
{
|
||||
// swap the begin- and endnode of the current link
|
||||
Node* dummy = m_beginnode;
|
||||
m_beginnode = m_endnode;
|
||||
m_endnode = dummy;
|
||||
|
||||
bool swap = m_LeftA;
|
||||
m_LeftA = m_RightA;
|
||||
m_RightA= swap;
|
||||
|
||||
swap = m_LeftB;
|
||||
m_LeftB = m_RightB;
|
||||
m_RightB= swap;
|
||||
|
||||
swap = m_merge_L ;
|
||||
m_merge_L = m_merge_R;
|
||||
m_merge_R = swap;
|
||||
|
||||
swap = m_a_substract_b_L;
|
||||
m_a_substract_b_L = m_a_substract_b_R;
|
||||
m_a_substract_b_R = swap;
|
||||
|
||||
swap = m_b_substract_a_L;
|
||||
m_b_substract_a_L = m_b_substract_a_R;
|
||||
m_b_substract_a_R = swap;
|
||||
|
||||
swap = m_intersect_L;
|
||||
m_intersect_L = m_intersect_R;
|
||||
m_intersect_R = swap;
|
||||
|
||||
swap = m_exor_L;
|
||||
m_exor_L = m_exor_R;
|
||||
m_exor_R = swap;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,203 @@
|
|||
/*! \file ../src/lpoint.cpp
|
||||
\brief Definition of GDSII LPoint type structure
|
||||
\author Probably Klaas Holwerda
|
||||
|
||||
Copyright: 2001-2004 (C) Probably Klaas Holwerda
|
||||
|
||||
Licence: wxWidgets Licence
|
||||
|
||||
RCS-ID: $Id: lpoint.cpp,v 1.4 2005/05/24 19:13:39 titato Exp $
|
||||
*/
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma implementation
|
||||
#endif
|
||||
|
||||
#include "../include/lpoint.h"
|
||||
#include <math.h>
|
||||
|
||||
// Constructors
|
||||
LPoint::LPoint()
|
||||
{
|
||||
_x = 0;
|
||||
_y = 0;
|
||||
}
|
||||
|
||||
|
||||
LPoint::LPoint(B_INT const X, B_INT const Y)
|
||||
{
|
||||
_x = X;
|
||||
_y = Y;
|
||||
}
|
||||
|
||||
|
||||
LPoint::LPoint(LPoint* const a_point)
|
||||
{
|
||||
if (!a_point)
|
||||
throw Bool_Engine_Error("Cannot copy a NULL Point Object.\n\nCould not create a LPoint Object.",
|
||||
"Fatal Creation Error", 0, 1);
|
||||
_x = a_point->_x;
|
||||
_y = a_point->_y;
|
||||
}
|
||||
|
||||
|
||||
B_INT LPoint::GetX()
|
||||
{
|
||||
return _x;
|
||||
}
|
||||
|
||||
B_INT LPoint::GetY()
|
||||
{
|
||||
return _y;
|
||||
}
|
||||
|
||||
|
||||
void LPoint::SetX(B_INT a_point_x)
|
||||
{
|
||||
_x = a_point_x;
|
||||
}
|
||||
|
||||
|
||||
void LPoint::SetY(B_INT a_point_y)
|
||||
{
|
||||
_y = a_point_y;
|
||||
}
|
||||
|
||||
|
||||
LPoint LPoint::GetPoint()
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void LPoint::Set(const B_INT X,const B_INT Y)
|
||||
{
|
||||
_x = X;
|
||||
_y = Y;
|
||||
}
|
||||
|
||||
|
||||
void LPoint::Set(const LPoint &a_point)
|
||||
{
|
||||
_x = a_point._x;
|
||||
_y =a_point._y;
|
||||
}
|
||||
|
||||
bool LPoint::Equal(const LPoint a_point, B_INT Marge)
|
||||
{
|
||||
B_INT delta_x, delta_y;
|
||||
|
||||
delta_x = babs((_x - a_point._x));
|
||||
delta_y = babs((_y - a_point._y));
|
||||
|
||||
if ((delta_x <= Marge) && (delta_y <= Marge))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool LPoint::Equal(const B_INT X, const B_INT Y, B_INT Marge)
|
||||
{
|
||||
return (bool)((babs(_x - X) <= Marge) && (babs(_y - Y) <= Marge));
|
||||
}
|
||||
|
||||
bool LPoint::ShorterThan(const LPoint a_point, B_INT Marge)
|
||||
{
|
||||
double a,b;
|
||||
a = (double) (a_point._x - _x);
|
||||
a*= a;
|
||||
b = (double) (a_point._y - _y);
|
||||
b*= b;
|
||||
|
||||
return (bool) ( (a+b) <= Marge*Marge ? true : false ) ;
|
||||
}
|
||||
|
||||
|
||||
bool LPoint::ShorterThan(const B_INT X, const B_INT Y, B_INT Marge)
|
||||
{
|
||||
double a,b;
|
||||
a = (double) (X - _x);
|
||||
a*= a;
|
||||
b = (double) (Y - _y);
|
||||
b*= b;
|
||||
|
||||
return (bool) ( a+b <= Marge*Marge ? true : false ) ;
|
||||
}
|
||||
|
||||
|
||||
// overload the assign (=) operator
|
||||
// usage : a_point = another_point;
|
||||
|
||||
LPoint &LPoint::operator=(const LPoint &other_point)
|
||||
{
|
||||
_x = other_point._x;
|
||||
_y = other_point._y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
// overload the + operator
|
||||
// usage : a_point = point1 + point2;
|
||||
|
||||
LPoint &LPoint::operator+(const LPoint &other_point)
|
||||
{
|
||||
_x += other_point._x;
|
||||
_y += other_point._y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// overload the - operator
|
||||
// usage : a_point = point1 - point2;
|
||||
|
||||
LPoint &LPoint::operator-(const LPoint &other_point)
|
||||
{
|
||||
_x -= other_point._x;
|
||||
_y -= other_point._y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
// overload the * operator
|
||||
// usage: a_point = point1 * 100;
|
||||
|
||||
LPoint &LPoint::operator*(int factor)
|
||||
{
|
||||
_x *= factor;
|
||||
_y *= factor;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
// overload the / operator
|
||||
// usage: a_point = point1 / 100;
|
||||
|
||||
LPoint &LPoint::operator/(int factor)
|
||||
{
|
||||
_x /= factor;
|
||||
_y /= factor;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
// overload the compare (==) operator
|
||||
// usage: if (point1 == point2) { };
|
||||
|
||||
int LPoint::operator==(const LPoint &other_point) const
|
||||
{
|
||||
return ((other_point._x == _x) && (other_point._y == _y));
|
||||
}
|
||||
|
||||
|
||||
// overload the diffrent (!=) operator
|
||||
// usage: if (point1 != point2) { };
|
||||
|
||||
int LPoint::operator!=(const LPoint &other_point) const
|
||||
{
|
||||
return ((other_point._x != _x) || (other_point._y != _y));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
WXDIR = $(WXWIN)
|
||||
|
||||
TARGET = libkbool.a
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
include makefile.include
|
||||
|
||||
$(TARGET): $(OBJECTS) makefile.include
|
||||
ar ruv $@ $(OBJECTS)
|
||||
ranlib $@
|
||||
|
||||
clean:
|
||||
rm -f *.bak
|
||||
rm -f *.o
|
||||
rm -f $(TARGET)
|
|
@ -0,0 +1,16 @@
|
|||
WXDIR = $(WXWIN)
|
||||
|
||||
TARGET = libkbool.a
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
include makefile.include
|
||||
|
||||
$(TARGET): $(OBJECTS) makefile.include
|
||||
ar ruv $@ $(OBJECTS)
|
||||
ranlib $@
|
||||
|
||||
clean:
|
||||
rm -f *.bak
|
||||
rm -f *.o
|
||||
rm -f $(TARGET)
|
|
@ -0,0 +1,10 @@
|
|||
OBJECTS =\
|
||||
booleng.o\
|
||||
graph.o\
|
||||
graphlst.o\
|
||||
line.o\
|
||||
link.o\
|
||||
lpoint.o\
|
||||
node.o\
|
||||
record.o\
|
||||
scanbeam.o
|
|
@ -0,0 +1,16 @@
|
|||
WXDIR = $(WXWIN)
|
||||
|
||||
TARGET = libkbool.a
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
include makefile.include
|
||||
|
||||
$(TARGET): $(OBJECTS) makefile.include
|
||||
ar ruv $@ $(OBJECTS)
|
||||
ranlib $@
|
||||
|
||||
clean:
|
||||
rm -f *.bak
|
||||
rm -f *.o
|
||||
rm -f $(TARGET)
|
|
@ -0,0 +1,612 @@
|
|||
/*! \file ../src/node.cpp
|
||||
\brief Holds a GDSII node structure
|
||||
\author Probably Klaas Holwerda
|
||||
|
||||
Copyright: 2001-2004 (C) Probably Klaas Holwerda
|
||||
|
||||
Licence: wxWidgets Licence
|
||||
|
||||
RCS-ID: $Id: node.cpp,v 1.7 2005/06/17 23:01:03 kbluck Exp $
|
||||
*/
|
||||
#ifdef __GNUG__
|
||||
#pragma implementation
|
||||
#endif
|
||||
|
||||
#include "../include/node.h"
|
||||
#include "../include/link.h"
|
||||
#include "../include/line.h"
|
||||
#include <math.h>
|
||||
|
||||
//this here is to initialize the static iterator of node
|
||||
//with NOLIST constructor
|
||||
//TDLI<KBoolLink> Node::_linkiter=TDLI<KBoolLink>(_GC);
|
||||
|
||||
Node::Node(Bool_Engine* GC) : LPoint(0,0)
|
||||
{
|
||||
_GC=GC;
|
||||
_linklist=new DL_List<void*>();
|
||||
}
|
||||
|
||||
|
||||
Node::Node(B_INT const X, B_INT const Y, Bool_Engine* GC) : LPoint(X,Y)
|
||||
{
|
||||
_GC=GC;
|
||||
_linklist=new DL_List<void*>();
|
||||
}
|
||||
|
||||
|
||||
Node::Node(LPoint* const a_point, Bool_Engine* GC) : LPoint(a_point)
|
||||
{
|
||||
_GC=GC;
|
||||
_linklist=new DL_List<void*>();
|
||||
}
|
||||
|
||||
|
||||
//Node::Node(Node * const other) : LPoint(other)
|
||||
Node::Node(Node * const other, Bool_Engine* GC)
|
||||
{
|
||||
_GC=GC;
|
||||
_x = other->_x;
|
||||
_y = other->_y;
|
||||
_linklist=new DL_List<void*>();
|
||||
}
|
||||
|
||||
Node& Node::operator=(const Node &other_node)
|
||||
{
|
||||
_x = other_node._x;
|
||||
_y = other_node._y;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
// x and y of the point will be rounded to the nearest
|
||||
// xnew=N*grid and ynew=N*grid
|
||||
void Node::RoundInt(B_INT grid)
|
||||
{
|
||||
_x=(B_INT) floor((_x + grid * 0.5) / grid) * grid;
|
||||
_y=(B_INT) floor((_y + grid * 0.5) / grid) * grid;
|
||||
}
|
||||
|
||||
Node::~Node()
|
||||
{
|
||||
delete _linklist;
|
||||
}
|
||||
|
||||
DL_List<void*>* Node::GetLinklist()
|
||||
{
|
||||
return _linklist;
|
||||
}
|
||||
|
||||
void Node::AddLink(KBoolLink *a_link)
|
||||
{
|
||||
// assert(a_link);
|
||||
_linklist->insbegin(a_link);
|
||||
}
|
||||
|
||||
KBoolLink* Node::GetIncomingLink()
|
||||
{
|
||||
if (((KBoolLink*)_linklist->headitem())->GetEndNode() == this)
|
||||
return (KBoolLink*)_linklist->headitem();
|
||||
else
|
||||
return (KBoolLink*)_linklist->tailitem();
|
||||
}
|
||||
|
||||
KBoolLink* Node::GetOutgoingLink()
|
||||
{
|
||||
if (((KBoolLink*)_linklist->headitem())->GetBeginNode() == this)
|
||||
return (KBoolLink*)_linklist->headitem();
|
||||
else
|
||||
return (KBoolLink*)_linklist->tailitem();
|
||||
}
|
||||
|
||||
//
|
||||
// Returns the number of connected links
|
||||
//
|
||||
int Node::GetNumberOfLinks()
|
||||
{
|
||||
return _linklist->count();
|
||||
}
|
||||
|
||||
KBoolLink* Node::GetOtherLink(KBoolLink* prev)
|
||||
{
|
||||
if (prev==(KBoolLink*)_linklist->headitem())
|
||||
return (KBoolLink*)_linklist->tailitem();
|
||||
if (prev==(KBoolLink*)_linklist->tailitem())
|
||||
return (KBoolLink*)_linklist->headitem();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int Node::Merge(Node *other)
|
||||
{
|
||||
if (this==other) //they are already merged dummy
|
||||
return 0;
|
||||
|
||||
_GC->_linkiter->Attach(_linklist);
|
||||
int Counter;
|
||||
// used to delete Iterator on other->_linklist
|
||||
// otherwise there can't be a takeover, because for takeover there can't
|
||||
// be an iterator on other->_linklist;
|
||||
{
|
||||
TDLI<KBoolLink> Iother(other->_linklist);
|
||||
KBoolLink* temp;
|
||||
|
||||
Counter = Iother.count();
|
||||
|
||||
Iother.tohead();
|
||||
while (!Iother.hitroot())
|
||||
{
|
||||
temp=Iother.item();
|
||||
//need to test both nodes because it may be a zero length link
|
||||
if (temp->GetEndNode()==other)
|
||||
temp->SetEndNode(this);
|
||||
if (temp->GetBeginNode()==other)
|
||||
temp->SetBeginNode(this);
|
||||
Iother++;
|
||||
}
|
||||
_GC->_linkiter->takeover(&Iother);
|
||||
}
|
||||
_GC->_linkiter->Detach();
|
||||
|
||||
//at this moment the other nodes has no link pointing to it so it needs to be deleted
|
||||
delete other;
|
||||
return Counter;
|
||||
}
|
||||
|
||||
|
||||
void Node::RemoveLink(KBoolLink *a_link)
|
||||
{
|
||||
// assert(a_link);
|
||||
_GC->_linkiter->Attach(_linklist);
|
||||
|
||||
if (_GC->_linkiter->toitem(a_link)) // find the link
|
||||
_GC->_linkiter->remove();
|
||||
_GC->_linkiter->Detach();
|
||||
}
|
||||
|
||||
// This function will determinate if the given three points
|
||||
// can be simplified to two points
|
||||
//
|
||||
// input : three nodes, the first and the second must be points of
|
||||
// a line in correct order, the third point is a point of another
|
||||
// line.
|
||||
// output: -
|
||||
// return: true if points can be simplified
|
||||
// false if points can't be simplified
|
||||
bool Node::Simplify(Node *First, Node *Second, B_INT Marge)
|
||||
{
|
||||
double distance=0;
|
||||
|
||||
// The first and second point are a zero line, if so we can
|
||||
// make a line between the first and third point
|
||||
if (First->Equal(Second,Marge))
|
||||
return true;
|
||||
|
||||
// Are the first and third point equal, if so
|
||||
// we can delete the second point
|
||||
if (First->Equal(this, Marge))
|
||||
return true;
|
||||
|
||||
// Used tmp_link.set here, because the link may not be linked in the graph,
|
||||
// because the point of the graphs are used, after use of the line we have
|
||||
//to set the link to zero so the nodes will not be destructed by exit of the function
|
||||
KBoolLink tmp_link(_GC);
|
||||
tmp_link.Set(First,Second);
|
||||
KBoolLine tmp_line(_GC);
|
||||
tmp_line.Set(&tmp_link);
|
||||
|
||||
// If third point is on the same line which is made from the first
|
||||
// and second point then we can delete the second point
|
||||
if (tmp_line.PointOnLine(this,distance, (double) Marge) == ON_AREA)
|
||||
{
|
||||
tmp_link.Set(NULL,NULL);
|
||||
return true;
|
||||
}
|
||||
//
|
||||
//
|
||||
tmp_link.Set(Second,this);
|
||||
tmp_line.Set(&tmp_link);
|
||||
if (tmp_line.PointOnLine(First,distance, (double) Marge) == ON_AREA)
|
||||
{
|
||||
tmp_link.Set(NULL,NULL);
|
||||
return true;
|
||||
}
|
||||
tmp_link.Set(NULL,NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
KBoolLink* Node::GetNextLink()
|
||||
{
|
||||
int Aantal = _linklist->count();
|
||||
|
||||
// assert (Aantal != 0);
|
||||
|
||||
// there is one link, so there is no previous link
|
||||
if (Aantal == 1)
|
||||
return NULL;
|
||||
int Marked_Counter = 0;
|
||||
KBoolLink *the_link = NULL;
|
||||
|
||||
// count the marked links
|
||||
_GC->_linkiter->Attach(_linklist);
|
||||
_GC->_linkiter->tohead();
|
||||
while (!_GC->_linkiter->hitroot())
|
||||
{
|
||||
if (_GC->_linkiter->item()->IsMarked())
|
||||
Marked_Counter++;
|
||||
else
|
||||
{
|
||||
if (!the_link)
|
||||
the_link = _GC->_linkiter->item();
|
||||
}
|
||||
(*_GC->_linkiter)++;
|
||||
}
|
||||
_GC->_linkiter->Detach();
|
||||
if (Aantal - Marked_Counter != 1)
|
||||
// there arent two unmarked links
|
||||
return NULL;
|
||||
else
|
||||
{
|
||||
if (the_link->GetBeginNode() == this)
|
||||
return the_link;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
KBoolLink* Node::GetPrevLink()
|
||||
{
|
||||
int Aantal;
|
||||
if (!_linklist)
|
||||
return NULL;
|
||||
|
||||
Aantal = _linklist->count();
|
||||
|
||||
// assert (Aantal != 0);
|
||||
|
||||
// there is one link, so there is no previous link
|
||||
if (Aantal == 1)
|
||||
return NULL;
|
||||
|
||||
int Marked_Counter = 0;
|
||||
KBoolLink *the_link = NULL;
|
||||
|
||||
_GC->_linkiter->Attach(_linklist);
|
||||
// count the marked links
|
||||
_GC->_linkiter->tohead();
|
||||
while (!_GC->_linkiter->hitroot())
|
||||
{
|
||||
if (_GC->_linkiter->item()->IsMarked())
|
||||
Marked_Counter++;
|
||||
else
|
||||
{
|
||||
if (!the_link)
|
||||
the_link = _GC->_linkiter->item();
|
||||
}
|
||||
(*_GC->_linkiter)++;
|
||||
}
|
||||
_GC->_linkiter->Detach();
|
||||
if (Aantal - Marked_Counter != 1)
|
||||
// there arent two unmarked links
|
||||
return NULL;
|
||||
else
|
||||
{
|
||||
if (the_link->GetEndNode() == this)
|
||||
return the_link;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool Node::SameSides( KBoolLink* const prev , KBoolLink* const link, BOOL_OP operation )
|
||||
{
|
||||
bool directedLeft;
|
||||
bool directedRight;
|
||||
if ( prev->GetEndNode() == this ) //forward direction
|
||||
{
|
||||
directedLeft = prev->IsMarkedLeft( operation );
|
||||
directedRight = prev->IsMarkedRight( operation );
|
||||
if ( link->GetBeginNode() == this ) //forward direction
|
||||
{
|
||||
return directedLeft == link->IsMarkedLeft( operation ) &&
|
||||
directedRight == link->IsMarkedRight( operation );
|
||||
}
|
||||
|
||||
return directedLeft == link->IsMarkedRight( operation ) &&
|
||||
directedRight == link->IsMarkedLeft( operation );
|
||||
}
|
||||
|
||||
directedLeft = prev->IsMarkedRight( operation );
|
||||
directedRight = prev->IsMarkedLeft( operation );
|
||||
if ( link->GetBeginNode() == this ) //forward direction
|
||||
{
|
||||
return directedLeft == link->IsMarkedLeft( operation ) &&
|
||||
directedRight == link->IsMarkedRight( operation );
|
||||
}
|
||||
return directedLeft == link->IsMarkedRight( operation ) &&
|
||||
directedRight == link->IsMarkedLeft( operation );
|
||||
}
|
||||
|
||||
// on the node get the link
|
||||
// is the most right or left one
|
||||
// This function is used to collect the simple graphs from a graph
|
||||
KBoolLink* Node::GetMost( KBoolLink* const prev ,LinkStatus whatside, BOOL_OP operation )
|
||||
{
|
||||
KBoolLink *reserve=0;
|
||||
KBoolLink *Result = NULL,*link;
|
||||
Node* prevbegin = prev->GetOther(this);
|
||||
|
||||
if (_linklist->count() == 2) // only two links to this node take the one != prev
|
||||
{
|
||||
if ( (link = (KBoolLink*)_linklist->headitem()) == prev ) //this is NOT the one to go on
|
||||
link = (KBoolLink*)_linklist->tailitem();
|
||||
if (!link->BeenHere() && SameSides( prev, link, operation ) )
|
||||
//we are back where we started (bin is true) return Null
|
||||
return link;
|
||||
return(0);
|
||||
}
|
||||
|
||||
_GC->_linkiter->Attach(_linklist);
|
||||
_GC->_linkiter->tohead();
|
||||
//more then 2 links to the Node
|
||||
while(!_GC->_linkiter->hitroot())
|
||||
{
|
||||
link = _GC->_linkiter->item();
|
||||
if ( !link->BeenHere() &&
|
||||
SameSides( prev, link, operation ) &&
|
||||
link != prev //should be set to bin already
|
||||
)
|
||||
{
|
||||
if (prevbegin == link->GetOther(this) )//pointers equal
|
||||
//we are going back in the same direction on a parallel link
|
||||
//only take this possibility if nothing else is possible
|
||||
reserve = link;
|
||||
else
|
||||
{ //this link is in a different direction
|
||||
if (!Result)
|
||||
Result = link; //first one found sofar
|
||||
else
|
||||
{
|
||||
if (prev->PointOnCorner(Result, link) == whatside )
|
||||
//more to the whatside than take this one
|
||||
Result = link;
|
||||
}
|
||||
}
|
||||
}
|
||||
(*_GC->_linkiter)++;
|
||||
}
|
||||
|
||||
// if there is a next link found return it
|
||||
// else if a parallel link is found return that one
|
||||
// else return NULL
|
||||
_GC->_linkiter->Detach();
|
||||
return ((Result) ? Result : reserve);
|
||||
}
|
||||
|
||||
// on the node get the link
|
||||
// is the most right or left one
|
||||
// This function is used to collect the simple graphs from a graph
|
||||
KBoolLink* Node::GetMostHole( KBoolLink* const prev, LinkStatus whatside, BOOL_OP operation )
|
||||
{
|
||||
KBoolLink *reserve=0;
|
||||
KBoolLink *Result=NULL,*link;
|
||||
Node* prevbegin = prev->GetOther(this);
|
||||
|
||||
if (_linklist->count() == 2) // only two links to this node take the one != prev
|
||||
{
|
||||
if ( (link = (KBoolLink*)_linklist->headitem()) == prev ) //this is NOT the one to go on
|
||||
link = (KBoolLink*)_linklist->tailitem();
|
||||
if ( link->GetHole() && !link->GetHoleLink() && !link->BeenHere() && SameSides( prev, link, operation ) )
|
||||
//we are back where we started (bin is true) return Null
|
||||
return link;
|
||||
return(0);
|
||||
}
|
||||
|
||||
_GC->_linkiter->Attach(_linklist);
|
||||
_GC->_linkiter->tohead();
|
||||
//more then 2 links to the Node
|
||||
while(!_GC->_linkiter->hitroot())
|
||||
{
|
||||
link = _GC->_linkiter->item();
|
||||
if ( !link->BeenHere() &&
|
||||
link->GetHole() &&
|
||||
!link->GetHoleLink() &&
|
||||
SameSides( prev, link, operation ) &&
|
||||
link != prev //should be set to bin already
|
||||
)
|
||||
{
|
||||
if (prevbegin == link->GetOther(this) )//pointers equal
|
||||
//we are going back in the same direction on a parallel link
|
||||
//only take this possibility if nothing else is possible
|
||||
reserve = link;
|
||||
else
|
||||
{ //this link is in a different direction
|
||||
if (!Result)
|
||||
Result = link; //first one found sofar
|
||||
else
|
||||
{
|
||||
if (prev->PointOnCorner(Result, link) == whatside )
|
||||
//more to the whatside than take this one
|
||||
Result = link;
|
||||
}
|
||||
}
|
||||
}
|
||||
(*_GC->_linkiter)++;
|
||||
}
|
||||
|
||||
// if there is a next link found return it
|
||||
// else if a parallel link is found return that one
|
||||
// else return NULL
|
||||
_GC->_linkiter->Detach();
|
||||
return ((Result) ? Result : reserve);
|
||||
}
|
||||
|
||||
// this function gets the highest not flat link
|
||||
KBoolLink* Node::GetHoleLink( KBoolLink* const prev, bool checkbin, BOOL_OP operation )
|
||||
{
|
||||
KBoolLink *Result=NULL,*link;
|
||||
|
||||
_GC->_linkiter->Attach(_linklist);
|
||||
|
||||
for(_GC->_linkiter->tohead();!_GC->_linkiter->hitroot();(*_GC->_linkiter)++)
|
||||
{
|
||||
link=_GC->_linkiter->item();
|
||||
if ( link->GetHoleLink() &&
|
||||
( !checkbin || ( checkbin && !link->BeenHere()) ) &&
|
||||
SameSides( prev, link, operation )
|
||||
)
|
||||
{
|
||||
Result=link;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_GC->_linkiter->Detach();
|
||||
return (Result);
|
||||
}
|
||||
|
||||
// this function gets the highest not flat link
|
||||
KBoolLink* Node::GetNotFlat()
|
||||
{
|
||||
KBoolLink *Result=NULL,*link;
|
||||
|
||||
_GC->_linkiter->Attach(_linklist);
|
||||
|
||||
double tangold = 0.0;
|
||||
double tangnew = 0.0;
|
||||
|
||||
for(_GC->_linkiter->tohead();!_GC->_linkiter->hitroot();(*_GC->_linkiter)++)
|
||||
{
|
||||
link=_GC->_linkiter->item();
|
||||
if (!_GC->_linkiter->item()->BeenHere())
|
||||
{
|
||||
B_INT dx=link->GetOther(this)->GetX()-_x;
|
||||
B_INT dy=link->GetOther(this)->GetY()-_y;
|
||||
if (dx!=0)
|
||||
{
|
||||
tangnew=fabs( (double) dy / (double) dx );
|
||||
}
|
||||
else
|
||||
{
|
||||
tangnew=MAXDOUBLE;
|
||||
}
|
||||
|
||||
if (!Result)
|
||||
{
|
||||
//this link is in a different direction
|
||||
Result=link; //first one found sofar
|
||||
tangold=tangnew;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(tangnew < tangold)
|
||||
{
|
||||
//this one is higher (more horizontal) then the old Result
|
||||
Result=link;
|
||||
tangold=tangnew;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if there is a next link found return it
|
||||
// else if a parallel link is found return that one
|
||||
// else return NULL
|
||||
_GC->_linkiter->Detach();
|
||||
return (Result);
|
||||
}
|
||||
|
||||
// on the node get the link that is not BIN
|
||||
// and that has the same graphnumber and is in same direction
|
||||
KBoolLink *Node::Follow(KBoolLink* const prev )
|
||||
{
|
||||
KBoolLink *temp;
|
||||
_GC->_linkiter->Attach(_linklist);
|
||||
|
||||
_GC->_linkiter->tohead();
|
||||
while(!_GC->_linkiter->hitroot())
|
||||
{
|
||||
if (( _GC->_linkiter->item() != prev ) &&
|
||||
( !_GC->_linkiter->item()->BeenHere()) &&
|
||||
( _GC->_linkiter->item()->GetGraphNum() == prev->GetGraphNum()) &&
|
||||
(
|
||||
( (prev->GetEndNode() == this) &&
|
||||
(_GC->_linkiter->item()->GetEndNode() !=this)
|
||||
)
|
||||
||
|
||||
( (prev->GetBeginNode() == this) &&
|
||||
(_GC->_linkiter->item()->GetBeginNode() !=this)
|
||||
)
|
||||
)
|
||||
)
|
||||
{
|
||||
temp=_GC->_linkiter->item();
|
||||
_GC->_linkiter->Detach();
|
||||
return(temp);
|
||||
}
|
||||
(*_GC->_linkiter)++;
|
||||
}
|
||||
|
||||
_GC->_linkiter->Detach();
|
||||
return (0);
|
||||
}
|
||||
|
||||
// this function gets the highest (other node) link ascending from the node
|
||||
// that has the bin flag set as the argument binset
|
||||
// if no such link exists return 0
|
||||
KBoolLink* Node::GetBinHighest(bool binset)
|
||||
{
|
||||
KBoolLink *Result=NULL,*link;
|
||||
_GC->_linkiter->Attach(_linklist);
|
||||
|
||||
double tangold = 0.0;
|
||||
double tangnew = 0.0;
|
||||
|
||||
for(_GC->_linkiter->tohead();!_GC->_linkiter->hitroot();(*_GC->_linkiter)++)
|
||||
{
|
||||
link=_GC->_linkiter->item();
|
||||
if (_GC->_linkiter->item()->BeenHere() == binset)
|
||||
{
|
||||
B_INT dx=link->GetOther(this)->GetX()-_x;
|
||||
B_INT dy=link->GetOther(this)->GetY()-_y;
|
||||
if (dx!=0)
|
||||
{
|
||||
tangnew = (double) dy / (double) dx;
|
||||
}
|
||||
else if (dy > 0)
|
||||
{
|
||||
tangnew = MAXDOUBLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
tangnew = -MAXDOUBLE;
|
||||
}
|
||||
|
||||
if (!Result)
|
||||
{
|
||||
Result = link; //first one found sofar
|
||||
tangold = tangnew;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(tangnew > tangold)
|
||||
{
|
||||
//this one is higher then the old Result
|
||||
Result = link;
|
||||
tangold = tangnew;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if there is a link found return it
|
||||
// else return NULL
|
||||
_GC->_linkiter->Detach();
|
||||
return (Result);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,357 @@
|
|||
/*! \file ../src/record.cpp
|
||||
\author Probably Klaas Holwerda or Julian Smart
|
||||
|
||||
Copyright: 2001-2004 (C) Probably Klaas Holwerda
|
||||
|
||||
Licence: wxWidgets Licence
|
||||
|
||||
RCS-ID: $Id: record.cpp,v 1.5 2005/05/24 19:13:39 titato Exp $
|
||||
*/
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma implementation
|
||||
#endif
|
||||
|
||||
#include "../include/booleng.h"
|
||||
#include "../include/record.h"
|
||||
#include "../include/node.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#define LNK _line.GetLink()
|
||||
|
||||
//int r_index=-1;
|
||||
//void* _Record_Pool[30];
|
||||
|
||||
//void DeleteRecordPool()
|
||||
//{
|
||||
// while (r_index!=-1)
|
||||
// {
|
||||
// free( _Record_Pool[r_index--]);
|
||||
// }
|
||||
//}
|
||||
|
||||
Record::~Record()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//void* Record::operator new(size_t size)
|
||||
//{
|
||||
//
|
||||
// if (r_index!=-1)
|
||||
// {
|
||||
// return _Record_Pool[r_index--];
|
||||
// }
|
||||
//
|
||||
// return malloc(size);
|
||||
//}
|
||||
|
||||
//void Record::operator delete(void* recordptr)
|
||||
//{
|
||||
//
|
||||
// if (r_index < 28)
|
||||
// {
|
||||
// _Record_Pool[++r_index]= recordptr;
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// free (recordptr);
|
||||
//}
|
||||
|
||||
//void Record::deletepool()
|
||||
//{
|
||||
//
|
||||
// while (r_index!=-1)
|
||||
// {
|
||||
// free( _Record_Pool[r_index--]);
|
||||
// }
|
||||
//}
|
||||
|
||||
Record::Record(KBoolLink* link,Bool_Engine* GC)
|
||||
:_line(GC)
|
||||
{
|
||||
_GC=GC;
|
||||
_dir=GO_RIGHT;
|
||||
_a=0;
|
||||
_b=0;
|
||||
_line.Set(link);
|
||||
_line.CalculateLineParameters();
|
||||
}
|
||||
|
||||
|
||||
//when the dimensions of a link for a record changes, its line parameters need to be recalculated
|
||||
void Record::SetNewLink(KBoolLink* link)
|
||||
{
|
||||
_line.Set(link);
|
||||
_line.CalculateLineParameters();
|
||||
}
|
||||
|
||||
//for beams calculate the ysp on the low scanline
|
||||
void Record::Calc_Ysp(Node* low)
|
||||
{
|
||||
if ((LNK->GetEndNode() == low) || (LNK->GetBeginNode() == low))
|
||||
{
|
||||
_ysp=low->GetY();
|
||||
return;
|
||||
}
|
||||
|
||||
if (LNK->GetEndNode()->GetX() == LNK->GetBeginNode()->GetX())
|
||||
_ysp=low->GetY(); //flatlink only in flatbeams
|
||||
else if (LNK->GetEndNode()->GetX() == low->GetX())
|
||||
_ysp=LNK->GetEndNode()->GetY();
|
||||
else if (LNK->GetBeginNode()->GetX() == low->GetX())
|
||||
_ysp=LNK->GetBeginNode()->GetY();
|
||||
else
|
||||
_ysp=_line.Calculate_Y_from_X(low->GetX());
|
||||
}
|
||||
|
||||
//to set the _dir for new links in the beam
|
||||
void Record::Set_Flags()
|
||||
{
|
||||
if (LNK->GetEndNode()->GetX()==LNK->GetBeginNode()->GetX()) //flatlink ?
|
||||
{ //only happens in flat beams
|
||||
if (LNK->GetEndNode()->GetY() < LNK->GetBeginNode()->GetY())
|
||||
_dir=GO_RIGHT;
|
||||
else
|
||||
_dir=GO_LEFT;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (LNK->GetEndNode()->GetX() > LNK->GetBeginNode()->GetX())
|
||||
_dir=GO_RIGHT;
|
||||
else
|
||||
_dir=GO_LEFT;
|
||||
}
|
||||
}
|
||||
|
||||
KBoolLink* Record::GetLink()
|
||||
{
|
||||
return LNK;
|
||||
}
|
||||
|
||||
B_INT Record::Ysp()
|
||||
{
|
||||
return _ysp;
|
||||
}
|
||||
|
||||
void Record::SetYsp(B_INT ysp)
|
||||
{
|
||||
_ysp=ysp;
|
||||
}
|
||||
|
||||
DIRECTION Record::Direction()
|
||||
{
|
||||
return DIRECTION(_dir);
|
||||
}
|
||||
|
||||
bool Record::Calc_Left_Right(Record* record_above_me)
|
||||
{
|
||||
bool par=false;
|
||||
|
||||
if (!record_above_me) //null if no record above
|
||||
{ _a=0;_b=0; }
|
||||
else
|
||||
{
|
||||
_a=record_above_me->_a;
|
||||
_b=record_above_me->_b;
|
||||
}
|
||||
|
||||
switch (_dir&1)
|
||||
{
|
||||
case GO_LEFT : if (LNK->Group() == GROUP_A)
|
||||
{
|
||||
LNK->SetRightA((bool)(_a>0));
|
||||
|
||||
if (_GC->GetWindingRule())
|
||||
LNK->GetInc() ? _a++ : _a--;
|
||||
else
|
||||
{ //ALTERNATE
|
||||
if (_a)
|
||||
_a=0;
|
||||
else
|
||||
_a=1;
|
||||
}
|
||||
|
||||
LNK->SetLeftA((bool)(_a>0));
|
||||
LNK->SetLeftB((bool)(_b>0));
|
||||
LNK->SetRightB((bool)(_b>0));
|
||||
}
|
||||
else
|
||||
{
|
||||
LNK->SetRightA((bool)(_a > 0));
|
||||
LNK->SetLeftA((bool)(_a>0));
|
||||
LNK->SetRightB((bool)(_b>0));
|
||||
|
||||
if (_GC->GetWindingRule())
|
||||
LNK->GetInc() ? _b++ : _b--;
|
||||
else //ALTERNATE
|
||||
{
|
||||
if (_b)
|
||||
_b=0;
|
||||
else
|
||||
_b=1;
|
||||
}
|
||||
|
||||
LNK->SetLeftB((bool)(_b>0));
|
||||
}
|
||||
break;
|
||||
case GO_RIGHT : if (LNK->Group() == GROUP_A)
|
||||
{
|
||||
LNK->SetLeftA((bool)(_a>0));
|
||||
|
||||
if (_GC->GetWindingRule())
|
||||
LNK->GetInc() ? _a++ : _a--;
|
||||
else
|
||||
{ //ALTERNATE
|
||||
if (_a)
|
||||
_a=0;
|
||||
else
|
||||
_a=1;
|
||||
}
|
||||
|
||||
LNK->SetRightA((bool)(_a>0));
|
||||
LNK->SetLeftB((bool)(_b>0));
|
||||
LNK->SetRightB((bool)(_b>0));
|
||||
}
|
||||
else
|
||||
{
|
||||
LNK->SetRightA((bool)(_a>0));
|
||||
LNK->SetLeftA((bool)(_a>0));
|
||||
LNK->SetLeftB((bool)(_b>0));
|
||||
|
||||
if (_GC->GetWindingRule())
|
||||
LNK->GetInc() ? _b++ : _b--;
|
||||
else
|
||||
{ //ALTERNATE
|
||||
if (_b)
|
||||
_b=0;
|
||||
else
|
||||
_b=1;
|
||||
}
|
||||
|
||||
LNK->SetRightB((bool)(_b>0));
|
||||
}
|
||||
break;
|
||||
default : _GC->error("Undefined Direction of link","function IScanBeam::Calc_Set_Left_Right()");
|
||||
break;
|
||||
}
|
||||
|
||||
//THE NEXT WILL WORK for MOST windingrule polygons,
|
||||
//even when not taking into acount windingrule
|
||||
// not all
|
||||
/*
|
||||
switch (_dir&1)
|
||||
{
|
||||
case GO_LEFT : if (LNK->Group() == GROUP_A)
|
||||
{
|
||||
LNK->SetRightA((bool)(_a>0));
|
||||
|
||||
if (booleng->Get_WindingRule())
|
||||
LNK->GetInc() ? _a++ : _a--;
|
||||
else
|
||||
_a--;
|
||||
|
||||
LNK->SetLeftA((bool)(_a>0));
|
||||
LNK->SetLeftB((bool)(_b>0));
|
||||
LNK->SetRightB((bool)(_b>0));
|
||||
}
|
||||
else
|
||||
{
|
||||
LNK->SetRightA((bool)(_a > 0));
|
||||
LNK->SetLeftA((bool)(_a>0));
|
||||
LNK->SetRightB((bool)(_b>0));
|
||||
|
||||
if (booleng->Get_WindingRule())
|
||||
LNK->GetInc() ? _b++ : _b--;
|
||||
else
|
||||
_b--;
|
||||
|
||||
LNK->SetLeftB((bool)(_b>0));
|
||||
}
|
||||
break;
|
||||
case GO_RIGHT : if (LNK->Group() == GROUP_A)
|
||||
{
|
||||
LNK->SetLeftA((bool)(_a>0));
|
||||
|
||||
if (booleng->Get_WindingRule())
|
||||
LNK->GetInc() ? _a++ : _a--;
|
||||
else
|
||||
_a++;
|
||||
|
||||
LNK->SetRightA((bool)(_a>0));
|
||||
LNK->SetLeftB((bool)(_b>0));
|
||||
LNK->SetRightB((bool)(_b>0));
|
||||
}
|
||||
else
|
||||
{
|
||||
LNK->SetRightA((bool)(_a>0));
|
||||
LNK->SetLeftA((bool)(_a>0));
|
||||
LNK->SetLeftB((bool)(_b>0));
|
||||
|
||||
if (booleng->Get_WindingRule())
|
||||
LNK->GetInc() ? _b++ : _b--;
|
||||
else
|
||||
_b++;
|
||||
|
||||
LNK->SetRightB((bool)(_b>0));
|
||||
}
|
||||
break;
|
||||
default : _messagehandler->error("Undefined Direction of link","function IScanBeam::Calc_Set_Left_Right()");
|
||||
break;
|
||||
}
|
||||
*/
|
||||
//if the records are parallel (same begin/endnodes)
|
||||
//the above link a/b flag are adjusted to the current a/b depth
|
||||
if (record_above_me && Equal(record_above_me))
|
||||
{
|
||||
par=true;
|
||||
LNK->Mark();
|
||||
record_above_me->_a=_a;
|
||||
record_above_me->_b=_b;
|
||||
if (Direction()== GO_LEFT)
|
||||
{
|
||||
//set the bottom side of the above link
|
||||
if (record_above_me->Direction()== GO_LEFT)
|
||||
{
|
||||
record_above_me->LNK->SetLeftA(LNK->GetLeftA());
|
||||
record_above_me->LNK->SetLeftB(LNK->GetLeftB());
|
||||
}
|
||||
else
|
||||
{
|
||||
record_above_me->LNK->SetRightA(LNK->GetLeftA());
|
||||
record_above_me->LNK->SetRightB(LNK->GetLeftB());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//set the bottom side of the above link
|
||||
if (record_above_me->Direction()== GO_LEFT)
|
||||
{
|
||||
record_above_me->LNK->SetLeftA(LNK->GetRightA());
|
||||
record_above_me->LNK->SetLeftB(LNK->GetRightB());
|
||||
}
|
||||
else
|
||||
{
|
||||
record_above_me->LNK->SetRightA(LNK->GetRightA());
|
||||
record_above_me->LNK->SetRightB(LNK->GetRightB());
|
||||
}
|
||||
}
|
||||
}
|
||||
return par;
|
||||
}
|
||||
|
||||
bool Record::Equal(Record *a)
|
||||
{
|
||||
return((bool)( ( LNK->GetOther(a->LNK->GetBeginNode()) == a->LNK->GetEndNode()) &&
|
||||
( LNK->GetOther(a->LNK->GetEndNode()) == a->LNK->GetBeginNode()) ));
|
||||
}
|
||||
|
||||
|
||||
KBoolLine* Record::GetLine()
|
||||
{
|
||||
return &_line;
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -1,17 +0,0 @@
|
|||
links to software relative to polygons (clipping and and other operations)
|
||||
|
||||
used in freePCB (Written by Alan Wright)
|
||||
gpc (here: GenericPolygonClipperLibrary.cpp)
|
||||
http://www.cs.man.ac.uk/~toby/alan/software/gpc.html
|
||||
|
||||
polygon.php (ported in "C++" by Alan Wright)
|
||||
the c++ corresponding file is php_polygon.cpp
|
||||
http://www.phpclasses.org/browse/file/10683.html
|
||||
|
||||
used in gpcb:
|
||||
polygon1.c:
|
||||
http://www.koders.com/c/
|
||||
and for this file:
|
||||
http://www.koders.com/c/fidE26CF2236C2DF7E435D597390A05B982EDFB4C38.aspx
|
||||
|
||||
gpcb uses a modified file (integer coordinates)
|
|
@ -5,16 +5,9 @@ COMMON =
|
|||
|
||||
|
||||
OBJECTS= \
|
||||
GenericPolygonClipperLibrary.o \
|
||||
php_polygon.o\
|
||||
php_polygon_vertex.o\
|
||||
PolyLine.o\
|
||||
math_for_graphics.o
|
||||
|
||||
GenericPolygonClipperLibrary.o: GenericPolygonClipperLibrary.cpp GenericPolygonClipperLibrary.h
|
||||
|
||||
php_polygon.o: php_polygon.cpp php_polygon.h php_polygon_vertex.h defs-macros.h
|
||||
|
||||
#polygon1.o: polygon1.cpp polyarea.h vectmatr.h
|
||||
PolyLine.o: PolyLine.cpp PolyLine.h
|
||||
|
||||
math_for_graphics.o: math_for_graphics.cpp math_for_graphics.h
|
||||
|
|
|
@ -10,9 +10,6 @@ using namespace std;
|
|||
|
||||
#include "fctsys.h"
|
||||
|
||||
#include "defs-macros.h"
|
||||
|
||||
#include "PolyLine2Kicad.h"
|
||||
#include "PolyLine.h"
|
||||
|
||||
|
||||
|
@ -49,7 +46,7 @@ CPoint GetInflectionPoint( CPoint pi, CPoint pf, int mode )
|
|||
{
|
||||
int vert; // length of vertical line needed
|
||||
if( dy > 0 )
|
||||
vert = dy - abs(dx); // positive
|
||||
vert = dy - abs(dx); // positive
|
||||
else
|
||||
vert = dy + abs(dx); // negative
|
||||
if( mode == IM_90_45 )
|
||||
|
@ -75,7 +72,7 @@ CPoint GetInflectionPoint( CPoint pi, CPoint pf, int mode )
|
|||
{
|
||||
int hor; // length of horizontal line needed
|
||||
if( dx > 0 )
|
||||
hor = dx - abs(dy); // positive
|
||||
hor = dx - abs(dy); // positive
|
||||
else
|
||||
hor = dx + abs(dy); // negative
|
||||
if( mode == IM_90_45 )
|
||||
|
@ -93,11 +90,11 @@ CPoint GetInflectionPoint( CPoint pi, CPoint pf, int mode )
|
|||
return p;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// function to rotate a point clockwise about another point
|
||||
// currently, angle must be 0, 90, 180 or 270
|
||||
//
|
||||
void RotatePoint( CPoint *p, int angle, CPoint org )
|
||||
void RotatePoint( CPoint *p, int angle, CPoint org )
|
||||
{
|
||||
if( angle == 90 )
|
||||
{
|
||||
|
@ -204,7 +201,7 @@ int TestLineHit( int xi, int yi, int xf, int yf, int x, int y, double dist )
|
|||
if( dd<dist && ( (xf>xi && xp<xf && xp>xi) || (xf<xi && xp>xf && xp<xi) ) )
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0; // no hit
|
||||
}
|
||||
|
||||
|
@ -293,16 +290,16 @@ int MakeEllipseFromArc( int xi, int yi, int xf, int yf, int style, EllipseKH * e
|
|||
// returns number of intersections found (max of 2)
|
||||
// returns coords of intersections in arrays x[2], y[2]
|
||||
//
|
||||
int FindSegmentIntersections( int xi, int yi, int xf, int yf, int style,
|
||||
int FindSegmentIntersections( int xi, int yi, int xf, int yf, int style,
|
||||
int xi2, int yi2, int xf2, int yf2, int style2,
|
||||
double x[], double y[] )
|
||||
{
|
||||
double xr[12], yr[12];
|
||||
int iret = 0;
|
||||
|
||||
if( max(xi,xf) < min(xi2,xf2)
|
||||
|| min(xi,xf) > max(xi2,xf2)
|
||||
|| max(yi,yf) < min(yi2,yf2)
|
||||
if( max(xi,xf) < min(xi2,xf2)
|
||||
|| min(xi,xf) > max(xi2,xf2)
|
||||
|| max(yi,yf) < min(yi2,yf2)
|
||||
|| min(yi,yf) > max(yi2,yf2) )
|
||||
return 0;
|
||||
|
||||
|
@ -449,7 +446,7 @@ int FindSegmentIntersections( int xi, int yi, int xf, int yf, int style,
|
|||
// sets coords of intersections in *x1, *y1, *x2, *y2
|
||||
// if no intersection, returns min distance in dist
|
||||
//
|
||||
int FindLineSegmentIntersection( double a, double b, int xi, int yi, int xf, int yf, int style,
|
||||
int FindLineSegmentIntersection( double a, double b, int xi, int yi, int xf, int yf, int style,
|
||||
double * x1, double * y1, double * x2, double * y2,
|
||||
double * dist )
|
||||
{
|
||||
|
@ -505,7 +502,7 @@ int FindLineSegmentIntersection( double a, double b, int xi, int yi, int xf, int
|
|||
else
|
||||
{
|
||||
// oblique line
|
||||
if( (xx>=xi && xx>xf) || (xx<=xi && xx<xf)
|
||||
if( (xx>=xi && xx>xf) || (xx<=xi && xx<xf)
|
||||
|| (yy>yi && yy>yf) || (yy<yi && yy<yf) )
|
||||
return 0;
|
||||
}
|
||||
|
@ -637,7 +634,7 @@ int FindLineSegmentIntersection( double a, double b, int xi, int yi, int xf, int
|
|||
// if false, returns min. distance in dist (may be 0.0 if parallel)
|
||||
// and coords on nearest point in one of the segments in (x,y)
|
||||
//
|
||||
bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y1f,
|
||||
bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y1f,
|
||||
int x2i, int y2i, int x2f, int y2f,
|
||||
int * x, int * y, double * d )
|
||||
{
|
||||
|
@ -994,14 +991,14 @@ void DrawArc( CDC * pDC, int shape, int xxi, int yyi, int xxf, int yyf, bool bMe
|
|||
pDC->MoveTo( xxi, yyi );
|
||||
pDC->LineTo( xxf, yyf );
|
||||
}
|
||||
else if( shape == DL_ARC_CCW || shape == DL_ARC_CW )
|
||||
else if( shape == DL_ARC_CCW || shape == DL_ARC_CW )
|
||||
{
|
||||
// set endpoints so we can always draw counter-clockwise arc
|
||||
if( shape == DL_ARC_CW )
|
||||
{
|
||||
xi = xxf;
|
||||
yi = yyf;
|
||||
xf = xxi;
|
||||
xf = xxi;
|
||||
yf = yyi;
|
||||
}
|
||||
else
|
||||
|
@ -1043,7 +1040,7 @@ void DrawArc( CDC * pDC, int shape, int xxi, int yyi, int xxf, int yyf, bool bMe
|
|||
int h = -(yf-yi)*2;
|
||||
if( !bMeta )
|
||||
pDC->Arc( xf, yi, xf+w, yi-h,
|
||||
xi, yi, xf, yf );
|
||||
xi, yi, xf, yf );
|
||||
else
|
||||
pDC->Arc( xf, yi-h, xf+w, yi,
|
||||
xf, yf, xi, yi );
|
||||
|
@ -1117,7 +1114,7 @@ void GetPadElements( int type, int x, int y, int wid, int len, int radius, int a
|
|||
}
|
||||
return;
|
||||
}
|
||||
//
|
||||
//
|
||||
int h;
|
||||
int v;
|
||||
if( angle == 90 || angle == 270 )
|
||||
|
@ -1251,7 +1248,7 @@ int GetClearanceBetweenSegments( int x1i, int y1i, int x1f, int y1f, int style1,
|
|||
// both segments are straight lines
|
||||
int xx, yy;
|
||||
double dd;
|
||||
TestForIntersectionOfStraightLineSegments( x1i, y1i, x1f, y1f,
|
||||
TestForIntersectionOfStraightLineSegments( x1i, y1i, x1f, y1f,
|
||||
x2i, y2i, x2f, y2f, &xx, &yy, &dd );
|
||||
int d = max( 0, (int)dd - w1/2 - w2/2 );
|
||||
if( x )
|
||||
|
@ -1266,7 +1263,7 @@ int GetClearanceBetweenSegments( int x1i, int y1i, int x1f, int y1f, int style1,
|
|||
double xr[2];
|
||||
double yr[2];
|
||||
test = FindSegmentIntersections( x1i, y1i, x1f, y1f, style1, x2i, y2i, x2f, y2f, style2, xr, yr );
|
||||
if( test )
|
||||
if( test )
|
||||
{
|
||||
if( x )
|
||||
*x = (int) xr[0];
|
||||
|
@ -1341,7 +1338,7 @@ int GetClearanceBetweenSegments( int x1i, int y1i, int x1f, int y1f, int style1,
|
|||
int nsteps2 = NSTEPS;
|
||||
double step = (s_start-s_end)/(nsteps-1);
|
||||
double step2 = (s_start2-s_end2)/(nsteps2-1);
|
||||
while( (step * max(el1.xrad, el1.yrad)) > 0.1*NM_PER_MIL
|
||||
while( (step * max(el1.xrad, el1.yrad)) > 0.1*NM_PER_MIL
|
||||
&& (step2 * len2) > 0.1*NM_PER_MIL )
|
||||
{
|
||||
step = (s_start-s_end)/(nsteps-1);
|
||||
|
@ -1444,7 +1441,7 @@ int GetClearanceBetweenPads( int type1, int x1, int y1, int w1, int l1, int r1,
|
|||
}
|
||||
for( int iss=0; iss<nss; iss++ )
|
||||
{
|
||||
int d = (int) GetPointToLineSegmentDistance( c[ic].x, c[ic].y,
|
||||
int d = (int) GetPointToLineSegmentDistance( c[ic].x, c[ic].y,
|
||||
ss[iss].xi, ss[iss].yi, ss[iss].xf, ss[iss].yf ) - c[ic].r;
|
||||
dist = min(dist,d);
|
||||
}
|
||||
|
@ -1453,7 +1450,7 @@ int GetClearanceBetweenPads( int type1, int x1, int y1, int w1, int l1, int r1,
|
|||
{
|
||||
for( int icc=0; icc<ncc; icc++ )
|
||||
{
|
||||
int d = (int) GetPointToLineSegmentDistance( cc[icc].x, cc[icc].y,
|
||||
int d = (int) GetPointToLineSegmentDistance( cc[icc].x, cc[icc].y,
|
||||
s[is].xi, s[is].yi, s[is].xf, s[is].yf ) - cc[icc].r;
|
||||
dist = min(dist,d);
|
||||
}
|
||||
|
@ -1577,8 +1574,8 @@ double Distance( int x1, int y1, int x2, int y2 )
|
|||
// this finds approximate solutions
|
||||
// note: this works best if el2 is smaller than el1
|
||||
//
|
||||
int GetArcIntersections( EllipseKH * el1, EllipseKH * el2,
|
||||
double * x1, double * y1, double * x2, double * y2 )
|
||||
int GetArcIntersections( EllipseKH * el1, EllipseKH * el2,
|
||||
double * x1, double * y1, double * x2, double * y2 )
|
||||
{
|
||||
if( el1->theta2 > el1->theta1 )
|
||||
wxASSERT(0);
|
||||
|
@ -1591,7 +1588,7 @@ int GetArcIntersections( EllipseKH * el1, EllipseKH * el2,
|
|||
double xscale = 1.0/el1->xrad;
|
||||
double yscale = 1.0/el1->yrad;
|
||||
// now transform params of second ellipse into reference frame
|
||||
// with origin at center if first ellipse,
|
||||
// with origin at center if first ellipse,
|
||||
// scaled so the first ellipse is a circle of radius = 1.0
|
||||
double xo = (el2->Center.X - el1->Center.X)*xscale;
|
||||
double yo = (el2->Center.Y - el1->Center.Y)*yscale;
|
||||
|
@ -1657,9 +1654,9 @@ int GetArcIntersections( EllipseKH * el1, EllipseKH * el2,
|
|||
|
||||
// this finds approximate solution
|
||||
//
|
||||
//double GetSegmentClearance( EllipseKH * el1, EllipseKH * el2,
|
||||
double GetArcClearance( EllipseKH * el1, EllipseKH * el2,
|
||||
double * x1, double * y1 )
|
||||
//double GetSegmentClearance( EllipseKH * el1, EllipseKH * el2,
|
||||
double GetArcClearance( EllipseKH * el1, EllipseKH * el2,
|
||||
double * x1, double * y1 )
|
||||
{
|
||||
const int NSTEPS = 32;
|
||||
|
||||
|
@ -1680,7 +1677,7 @@ double GetArcClearance( EllipseKH * el1, EllipseKH * el2,
|
|||
int nsteps2 = NSTEPS;
|
||||
double step = (th_start-th_end)/(nsteps-1);
|
||||
double step2 = (th_start2-th_end2)/(nsteps2-1);
|
||||
while( (step * max(el1->xrad, el1->yrad)) > 1.0*NM_PER_MIL
|
||||
while( (step * max(el1->xrad, el1->yrad)) > 1.0*NM_PER_MIL
|
||||
&& (step2 * max(el2->xrad, el2->yrad)) > 1.0*NM_PER_MIL )
|
||||
{
|
||||
step = (th_start-th_end)/(nsteps-1);
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
// math stuff for graphics, from FreePCB
|
||||
|
||||
#ifndef abs
|
||||
#define abs(x) (((x) >=0) ? (x) : (-(x)))
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct PointTag
|
||||
{
|
||||
double X,Y;
|
||||
|
@ -11,7 +16,7 @@ typedef struct EllipseTag
|
|||
// double MaxRad,MinRad; /* major and minor axis */
|
||||
// double Phi; /* major axis rotation */
|
||||
double xrad, yrad; // radii on x and y
|
||||
double theta1, theta2; // start and end angle for arc
|
||||
double theta1, theta2; // start and end angle for arc
|
||||
} EllipseKH;
|
||||
|
||||
const CPoint zero(0,0);
|
||||
|
@ -25,7 +30,7 @@ public:
|
|||
y = yy;
|
||||
r = rr;
|
||||
};
|
||||
int x, y, r;
|
||||
int x, y, r;
|
||||
};
|
||||
|
||||
class my_rect {
|
||||
|
@ -38,10 +43,10 @@ public:
|
|||
ylo = min(yi,yf);
|
||||
yhi = max(yi,yf);
|
||||
};
|
||||
int xlo, ylo, xhi, yhi;
|
||||
int xlo, ylo, xhi, yhi;
|
||||
};
|
||||
|
||||
class my_seg {
|
||||
class my_seg {
|
||||
public:
|
||||
my_seg(){};
|
||||
my_seg( int xxi, int yyi, int xxf, int yyf )
|
||||
|
@ -51,27 +56,27 @@ public:
|
|||
xf = xxf;
|
||||
yf = yyf;
|
||||
};
|
||||
int xi, yi, xf, yf;
|
||||
int xi, yi, xf, yf;
|
||||
};
|
||||
|
||||
// math stuff for graphics
|
||||
#if 0
|
||||
void DrawArc( CDC * pDC, int shape, int xxi, int yyi, int xxf, int yyf, BOOL bMeta=FALSE );
|
||||
void DrawArc( CDC * pDC, int shape, int xxi, int yyi, int xxf, int yyf, bool bMeta=FALSE );
|
||||
#endif
|
||||
|
||||
BOOL Quadratic( double a, double b, double c, double *x1, double *x2 );
|
||||
bool Quadratic( double a, double b, double c, double *x1, double *x2 );
|
||||
void RotatePoint( CPoint *p, int angle, CPoint org );
|
||||
void RotateRect( CRect *r, int angle, CPoint org );
|
||||
int TestLineHit( int xi, int yi, int xf, int yf, int x, int y, double dist );
|
||||
int FindLineIntersection( double a, double b, double c, double d, double * x, double * y );
|
||||
int FindLineSegmentIntersection( double a, double b, int xi, int yi, int xf, int yf, int style,
|
||||
int FindLineSegmentIntersection( double a, double b, int xi, int yi, int xf, int yf, int style,
|
||||
double * x1, double * y1, double * x2, double * y2, double * dist=NULL );
|
||||
int FindSegmentIntersections( int xi, int yi, int xf, int yf, int style,
|
||||
int FindSegmentIntersections( int xi, int yi, int xf, int yf, int style,
|
||||
int xi2, int yi2, int xf2, int yf2, int style2,
|
||||
double x[]=NULL, double y[]=NULL );
|
||||
BOOL FindLineEllipseIntersections( double a, double b, double c, double d, double *x1, double *x2 );
|
||||
BOOL FindVerticalLineEllipseIntersections( double a, double b, double x, double *y1, double *y2 );
|
||||
BOOL TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y1f,
|
||||
bool FindLineEllipseIntersections( double a, double b, double c, double d, double *x1, double *x2 );
|
||||
bool FindVerticalLineEllipseIntersections( double a, double b, double x, double *y1, double *y2 );
|
||||
bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y1f,
|
||||
int x2i, int y2i, int x2f, int y2f,
|
||||
int * x=NULL, int * y=NULL, double * dist=NULL );
|
||||
void GetPadElements( int type, int x, int y, int wid, int len, int radius, int angle,
|
||||
|
@ -79,7 +84,7 @@ void GetPadElements( int type, int x, int y, int wid, int len, int radius, int a
|
|||
int GetClearanceBetweenPads( int type1, int x1, int y1, int w1, int l1, int r1, int angle1,
|
||||
int type2, int x2, int y2, int w2, int l2, int r2, int angle2 );
|
||||
int GetClearanceBetweenSegmentAndPad( int x1, int y1, int x2, int y2, int w,
|
||||
int type, int x, int y, int wid, int len,
|
||||
int type, int x, int y, int wid, int len,
|
||||
int radius, int angle );
|
||||
int GetClearanceBetweenSegments( int x1i, int y1i, int x1f, int y1f, int style1, int w1,
|
||||
int x2i, int y2i, int x2f, int y2f, int style2, int w2,
|
||||
|
@ -94,11 +99,11 @@ int GetClearanceBetweenSegments( int x1i, int y1i, int x1f, int y1f, int style1,
|
|||
double GetPointToLineSegmentDistance( int x, int y, int xi, int yi, int xf, int yf );
|
||||
|
||||
double GetPointToLineDistance( double a, double b, int x, int y, double * xp=NULL, double * yp=NULL );
|
||||
BOOL InRange( double x, double xi, double xf );
|
||||
bool InRange( double x, double xi, double xf );
|
||||
double Distance( int x1, int y1, int x2, int y2 );
|
||||
int GetArcIntersections( EllipseKH * el1, EllipseKH * el2,
|
||||
double * x1=NULL, double * y1=NULL,
|
||||
double * x2=NULL, double * y2=NULL );
|
||||
int GetArcIntersections( EllipseKH * el1, EllipseKH * el2,
|
||||
double * x1=NULL, double * y1=NULL,
|
||||
double * x2=NULL, double * y2=NULL );
|
||||
CPoint GetInflectionPoint( CPoint pi, CPoint pf, int mode );
|
||||
|
||||
// quicksort (2-way or 3-way)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,72 +0,0 @@
|
|||
// file php_polygon.h
|
||||
|
||||
// See comments in php_polygon.cpp
|
||||
|
||||
#ifndef PHP_POLYGON_H
|
||||
#define PHP_POLYGON_H
|
||||
|
||||
class vertex;
|
||||
class segment;
|
||||
|
||||
#define infinity 100000000 // for places that are far far away
|
||||
#define PI 3.14159265359
|
||||
|
||||
enum {
|
||||
A_OR_B,
|
||||
A_AND_B,
|
||||
A_MINUS_B,
|
||||
B_MINUS_A
|
||||
};
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
** This class manages a doubly linked list of vertex objects that represents
|
||||
** a polygon. The class consists of basic methods to manage the list
|
||||
** and methods to implement boolean operations between polygon objects.
|
||||
*/
|
||||
|
||||
|
||||
class polygon
|
||||
{
|
||||
public:
|
||||
vertex* m_first; // Reference to first vertex in the linked list
|
||||
int m_cnt; // Tracks number of vertices in the polygon
|
||||
|
||||
public:
|
||||
polygon( vertex* first = NULL );
|
||||
~polygon();
|
||||
vertex* getFirst();
|
||||
polygon* NextPoly();
|
||||
|
||||
void add( vertex* nv );
|
||||
void addv( double x, double y,
|
||||
double xc = 0, double yc = 0, int d = 0 );
|
||||
vertex* del( vertex* v );
|
||||
void res();
|
||||
polygon* copy_poly();
|
||||
void insertSort( vertex* nv, vertex* s, vertex* e );
|
||||
vertex* nxt( vertex* v );
|
||||
BOOL unckd_remain();
|
||||
vertex* first_unckd_intersect();
|
||||
double dist( double x1, double y1, double x2, double y2 );
|
||||
double angle( double xc, double yc, double x1, double y1 );
|
||||
double aAlpha( double x1, double y1, double x2, double y2,
|
||||
double xc, double yc, double xi, double yi, double d );
|
||||
void perturb( vertex* p1, vertex* p2, vertex* q1, vertex* q2,
|
||||
double aP, double aQ );
|
||||
|
||||
BOOL ints( vertex * p1, vertex * p2, vertex * q1, vertex * q2,
|
||||
int* n, double ix[], double iy[], double alphaP[], double alphaQ[] );
|
||||
BOOL isInside( vertex* v );
|
||||
polygon* boolean( polygon* polyB, int oper );
|
||||
|
||||
#if 0
|
||||
function isPolyInside( p );
|
||||
function move( dx, dy );
|
||||
function rotate( xr, yr, a );
|
||||
function& bRect();
|
||||
|
||||
#endif
|
||||
}; //end of class polygon
|
||||
|
||||
|
||||
#endif // ifndef PHP_POLYGON_H
|
|
@ -1,144 +0,0 @@
|
|||
// file php_polygon_vertex.cpp
|
||||
// This is a port of a php class written by Brenor Brophy (see below)
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
** File: vertex.php
|
||||
** Description: PHP class for a polygon vertex. Used as the base object to
|
||||
** build a class of polygons.
|
||||
** Version: 1.1
|
||||
** Author: Brenor Brophy
|
||||
** Email: brenor at sbcglobal dot net
|
||||
** Homepage: www.brenorbrophy.com
|
||||
**------------------------------------------------------------------------------
|
||||
** COPYRIGHT (c) 2005 BRENOR BROPHY
|
||||
**
|
||||
** The source code included in this package 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. This license can be
|
||||
** read at:
|
||||
**
|
||||
** http://www.opensource.org/licenses/gpl-license.php
|
||||
**
|
||||
** 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.
|
||||
**------------------------------------------------------------------------------
|
||||
**
|
||||
** Based on the paper "Efficient Clipping of Arbitary Polygons" by Gunther
|
||||
** Greiner (greiner at informatik dot uni-erlangen dot de) and Kai Hormann
|
||||
** (hormann at informatik dot tu-clausthal dot de), ACM Transactions on Graphics
|
||||
** 1998;17(2):71-83.
|
||||
**
|
||||
** Available at: www.in.tu-clausthal.de/~hormann/papers/clipping.pdf
|
||||
**
|
||||
** Another useful site describing the algorithm and with some example
|
||||
** C code by Ionel Daniel Stroe is at:
|
||||
**
|
||||
** http://davis.wpi.edu/~matt/courses/clipping/
|
||||
**
|
||||
** The algorithm is extended by Brenor Brophy to allow polygons with
|
||||
** arcs between vertices.
|
||||
**
|
||||
** Rev History
|
||||
** -----------------------------------------------------------------------------
|
||||
** 1.0 08/25/2005 Initial Release
|
||||
** 1.1 09/04/2005 Added software license language to header comments
|
||||
*/
|
||||
//#include "stdafx.h"
|
||||
#include <math.h>
|
||||
|
||||
#include "php_polygon_vertex.h"
|
||||
|
||||
segment::segment(double xc, double yc, int d )
|
||||
{
|
||||
m_xc = xc;
|
||||
m_yc = yc;
|
||||
m_d = d;
|
||||
}
|
||||
|
||||
vertex::vertex( double x, double y,
|
||||
double xc, double yc, double d,
|
||||
vertex * nextV, vertex * prevV,
|
||||
polygon * nextPoly,
|
||||
BOOL intersect,
|
||||
vertex * neighbor,
|
||||
double alpha,
|
||||
BOOL entry,
|
||||
BOOL checked )
|
||||
{
|
||||
m_x = x;
|
||||
m_y = y;
|
||||
m_nextV = nextV;
|
||||
m_prevV = prevV;
|
||||
m_nextPoly = nextPoly;
|
||||
m_intersect = intersect;
|
||||
m_neighbor = neighbor;
|
||||
m_alpha = alpha;
|
||||
m_entry = entry;
|
||||
m_checked = checked;
|
||||
m_id = 0;
|
||||
m_nSeg = new segment( xc, yc, (int) d );
|
||||
m_pSeg = NULL;
|
||||
}
|
||||
|
||||
vertex::~vertex()
|
||||
{
|
||||
if( m_nSeg )
|
||||
delete m_nSeg;
|
||||
}
|
||||
|
||||
double vertex::Xc ( BOOL g )
|
||||
{
|
||||
if ( isIntersect() )
|
||||
{
|
||||
if ( m_neighbor->isEntry() )
|
||||
return m_neighbor->m_nSeg->Xc();
|
||||
else
|
||||
return m_neighbor->m_pSeg->Xc();
|
||||
}
|
||||
else
|
||||
if (g)
|
||||
return m_nSeg->Xc();
|
||||
else
|
||||
return m_pSeg->Xc();
|
||||
}
|
||||
|
||||
double vertex::Yc ( BOOL g )
|
||||
{
|
||||
if ( isIntersect() )
|
||||
{
|
||||
if ( m_neighbor->isEntry() )
|
||||
return m_neighbor->m_nSeg->Yc();
|
||||
else
|
||||
return m_neighbor->m_pSeg->Yc();
|
||||
}
|
||||
else
|
||||
if (g)
|
||||
return m_nSeg->Yc();
|
||||
else
|
||||
return m_pSeg->Yc();
|
||||
}
|
||||
|
||||
double vertex::d ( BOOL g )
|
||||
{
|
||||
if ( isIntersect() )
|
||||
{
|
||||
if ( m_neighbor->isEntry() )
|
||||
return m_neighbor->m_nSeg->d();
|
||||
else
|
||||
return (-1*m_neighbor->m_pSeg->d());
|
||||
}
|
||||
else
|
||||
if (g)
|
||||
return m_nSeg->d();
|
||||
else
|
||||
return (-1*m_pSeg->d());
|
||||
}
|
||||
|
||||
void vertex::setChecked( BOOL check )
|
||||
{
|
||||
m_checked = check;
|
||||
if( m_neighbor )
|
||||
if( !m_neighbor->isChecked() )
|
||||
m_neighbor->setChecked();
|
||||
}
|
|
@ -1,81 +0,0 @@
|
|||
// file php_polygon_vertex.h
|
||||
// See comments in file php_polygon_vertex.cpp
|
||||
|
||||
#ifndef PHP_POLYGON_VERTEX_H
|
||||
#define PHP_POLYGON_VERTEX_H
|
||||
|
||||
#include "defs-macros.h"
|
||||
|
||||
class vertex;
|
||||
class polygon;
|
||||
|
||||
class segment
|
||||
{
|
||||
public:
|
||||
segment(double xc=0.0, double yc=0.0, int d=0 );
|
||||
double Xc(){ return m_xc; };
|
||||
double Yc(){ return m_yc; };
|
||||
int d(){ return m_d; };
|
||||
void setXc( double xc ){ m_xc = xc; };
|
||||
void setYc( double yc ){ m_yc = yc; };
|
||||
|
||||
double m_xc, m_yc; // center of arc
|
||||
int m_d; // direction (-1=CW, 0=LINE, 1=CCW)
|
||||
};
|
||||
|
||||
class vertex
|
||||
{
|
||||
public:
|
||||
vertex( double x, double y,
|
||||
double xc=0.0, double yc=0.0, double d=0.0,
|
||||
vertex * nextV=NULL, vertex * prevV=NULL,
|
||||
polygon * nextPoly=NULL,
|
||||
BOOL intersect=FALSE,
|
||||
vertex * neighbor=NULL,
|
||||
double alpha=0.0,
|
||||
BOOL entry=TRUE,
|
||||
BOOL checked=FALSE );
|
||||
~vertex();
|
||||
int id() { return m_id; };
|
||||
double X() { return m_x; };
|
||||
void setX( double x ) { m_x = x; };
|
||||
double Y() { return m_y; };
|
||||
void setY( double y ) { m_y = y; };
|
||||
double Xc ( BOOL g = TRUE );
|
||||
double Yc ( BOOL g = TRUE );
|
||||
double d ( BOOL g = TRUE );
|
||||
void setXc ( double xc ) { m_nSeg->setXc(xc); };
|
||||
void setYc ( double yc ) { m_nSeg->setYc(yc); };
|
||||
void setNext ( vertex* nextV ){ m_nextV = nextV; };
|
||||
vertex * Next (){ return m_nextV; };
|
||||
void setPrev ( vertex *prevV ){ m_prevV = prevV; };
|
||||
vertex * Prev (){ return m_prevV; };
|
||||
void setNseg ( segment * nSeg ){ m_nSeg = nSeg; };
|
||||
segment * Nseg (){ return m_nSeg; };
|
||||
void setPseg ( segment * pSeg ){ m_pSeg = pSeg; };
|
||||
segment * Pseg (){ return m_pSeg; };
|
||||
void setNextPoly ( polygon * nextPoly ){ m_nextPoly = nextPoly; };
|
||||
polygon * NextPoly (){ return m_nextPoly; };
|
||||
void setNeighbor ( vertex * neighbor ){ m_neighbor = neighbor; };
|
||||
vertex * Neighbor (){ return m_neighbor; };
|
||||
double Alpha (){ return m_alpha; };
|
||||
BOOL isIntersect (){ return m_intersect; };
|
||||
void setChecked( BOOL check = TRUE);
|
||||
BOOL isChecked () { return m_checked; };
|
||||
void setEntry ( BOOL entry = TRUE){ m_entry = entry; }
|
||||
BOOL isEntry (){ return m_entry; };
|
||||
|
||||
double m_x, m_y; // coords
|
||||
vertex * m_nextV; // links to next and prev vertices
|
||||
vertex * m_prevV; // links to next and prev vertices
|
||||
segment * m_nSeg, * m_pSeg; // links to next and prev segments
|
||||
polygon * m_nextPoly;
|
||||
BOOL m_intersect;
|
||||
vertex * m_neighbor;
|
||||
double m_alpha;
|
||||
BOOL m_entry;
|
||||
BOOL m_checked;
|
||||
int m_id;
|
||||
};
|
||||
|
||||
#endif // ifndef PHP_POLYGON_VERTEX_H
|
Loading…
Reference in New Issue