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(kicad)
|
||||||
add_subdirectory(pcbnew)
|
add_subdirectory(pcbnew)
|
||||||
add_subdirectory(polygon)
|
add_subdirectory(polygon)
|
||||||
|
add_subdirectory(polygon/kbool/src)
|
||||||
# Resources.
|
# Resources.
|
||||||
add_subdirectory(demos)
|
add_subdirectory(demos)
|
||||||
add_subdirectory(internat)
|
add_subdirectory(internat)
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
# Generate a static library target named "libbitmaps.a"
|
# 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 = \
|
OBJECTS = \
|
||||||
3d.o\
|
3d.o\
|
||||||
Add_Arc.o\
|
Add_Arc.o\
|
||||||
|
@ -287,5 +283,88 @@ OBJECTS = \
|
||||||
Zoom_Page.o\
|
Zoom_Page.o\
|
||||||
Zoom_Selected.o\
|
Zoom_Selected.o\
|
||||||
Zoom_Select.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
|
Please add newer entries at the top, list the date and your name with
|
||||||
email address.
|
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>
|
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 )
|
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..) */
|
/* Display a generic info about kikac (copyright..) */
|
||||||
/* Common tp CVPCB, EESCHEMA, PCBNEW and GERBVIEW */
|
/* Common tp CVPCB, EESCHEMA, PCBNEW and GERBVIEW */
|
||||||
/****************************************************/
|
/****************************************************/
|
||||||
|
|
||||||
#include "fctsys.h"
|
#include "fctsys.h"
|
||||||
#include "gr_basic.h"
|
#include "gr_basic.h"
|
||||||
|
@ -14,53 +14,52 @@
|
||||||
// Import:
|
// Import:
|
||||||
extern wxString g_Main_Title;
|
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. */
|
* it easy to update the copyright dates. */
|
||||||
wxString g_KicadAboutTitle = wxT("** KICAD (jul 2000 .. 2008) **");
|
wxString g_KicadAboutTitle = wxT( "** KICAD (jul 2000 .. 2008) **" );
|
||||||
wxString g_CvpcbAboutTitle = wxT("** CVPCB (sept 1992 .. 2008) **");
|
wxString g_CvpcbAboutTitle = wxT( "** CVPCB (sept 1992 .. 2008) **" );
|
||||||
wxString g_EeschemaAboutTitle = wxT("** EESCHEMA (sept 1994 .. 2008) **");
|
wxString g_EeschemaAboutTitle = wxT( "** EESCHEMA (sept 1994 .. 2008) **" );
|
||||||
wxString g_PcbnewAboutTitle = wxT("** PCBNEW (sept 1992 .. 2008) **");
|
wxString g_PcbnewAboutTitle = wxT( "** PCBNEW (sept 1992 .. 2008) **" );
|
||||||
wxString g_GerbviewAboutTitle = wxT("** GERBVIEW (jul 2001 .. 2008) **");
|
wxString g_GerbviewAboutTitle = wxT( "** GERBVIEW (jul 2001 .. 2008) **" );
|
||||||
|
|
||||||
// Routines Locales
|
/**************************************************************/
|
||||||
|
void Print_Kicad_Infos( wxWindow* frame, const wxString& title,
|
||||||
/*******************************************/
|
const wxString& aExtra_infos )
|
||||||
void Print_Kicad_Infos(wxWindow * frame, const wxString& title)
|
/**************************************************************/
|
||||||
/*******************************************/
|
|
||||||
{
|
{
|
||||||
wxString AboutCaption = wxT("About ");
|
wxString AboutCaption = wxT( "About " );
|
||||||
wxString Msg = title;
|
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
|
#if wxUSE_UNICODE
|
||||||
Msg << wxT(" - Unicode version");
|
Msg << wxT( " - Unicode version" );
|
||||||
#else
|
#else
|
||||||
Msg << wxT(" - Ansi version");
|
Msg << wxT( " - Ansi version" );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef KICAD_PYTHON
|
#ifdef KICAD_PYTHON
|
||||||
Msg << wxT("\n");
|
Msg << wxT( "\n" );
|
||||||
Msg << wxT( "python : " );
|
Msg << wxT( "python : " );
|
||||||
Msg << wxString::FromAscii( PyHandler::GetInstance()->GetVersion() );
|
Msg << wxString::FromAscii( PyHandler::GetInstance()->GetVersion() );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Msg << wxT("\n\n") << _("Author:");
|
Msg << wxT( "\n\n" ) << _( "Author:" );
|
||||||
Msg << wxT(" JP CHARRAS\n\n") << _("Based on wxWidgets ");
|
Msg << wxT( " JP CHARRAS\n\n" ) << _( "Based on wxWidgets " );
|
||||||
Msg << wxMAJOR_VERSION << wxT(".") <<
|
Msg << wxMAJOR_VERSION << wxT( "." ) <<
|
||||||
wxMINOR_VERSION << wxT(".") << wxRELEASE_NUMBER;
|
wxMINOR_VERSION << wxT( "." ) << wxRELEASE_NUMBER;
|
||||||
if( wxSUBRELEASE_NUMBER )
|
if( wxSUBRELEASE_NUMBER )
|
||||||
Msg << wxT(".") << wxSUBRELEASE_NUMBER;
|
Msg << wxT( "." ) << wxSUBRELEASE_NUMBER;
|
||||||
Msg << _("\n\nGPL License");
|
Msg << _( "\n\nGPL License" );
|
||||||
Msg << _("\n\nAuthor's sites:\n");
|
Msg << _( "\n\nAuthor's sites:\n" );
|
||||||
Msg << wxT("http://iut-tice.ujf-grenoble.fr/kicad/\n");
|
Msg << wxT( "http://iut-tice.ujf-grenoble.fr/kicad/\n" );
|
||||||
Msg << wxT("http://www.gipsa-lab.inpg.fr/realise_au_lis/kicad/");
|
Msg << wxT( "http://www.gipsa-lab.inpg.fr/realise_au_lis/kicad/" );
|
||||||
Msg << _("\n\nInternational wiki:\n");
|
Msg << _( "\n\nInternational wiki:\n" );
|
||||||
Msg << wxT("http://kicad.sourceforge.net/\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})
|
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}
|
install(TARGETS cvpcb RUNTIME DESTINATION ${KICAD_BIN}
|
||||||
COMPONENT binary)
|
COMPONENT binary)
|
||||||
|
|
|
@ -3,10 +3,12 @@ OBJSUFF = o
|
||||||
|
|
||||||
EXTRACPPFLAGS += -DCVPCB -fno-strict-aliasing\
|
EXTRACPPFLAGS += -DCVPCB -fno-strict-aliasing\
|
||||||
-I./ -I../cvpcb -I../include -Ibitmaps\
|
-I./ -I../cvpcb -I../include -Ibitmaps\
|
||||||
-I../pcbnew -I../3d-viewer\
|
-I../pcbnew -I../3d-viewer -I ../polygon
|
||||||
-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
|
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})
|
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}
|
install(TARGETS gerbview RUNTIME DESTINATION ${KICAD_BIN}
|
||||||
COMPONENT binary)
|
COMPONENT binary)
|
||||||
|
|
|
@ -9,7 +9,7 @@ COMMON_GLOBL wxString g_BuildVersion
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
(wxT(KICAD_SVN_VERSION))
|
(wxT(KICAD_SVN_VERSION))
|
||||||
# else
|
# else
|
||||||
(wxT("(20080429-r1010)"))
|
(wxT("(20080530-r1107)"))
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
;
|
;
|
||||||
|
|
204
include/common.h
204
include/common.h
|
@ -48,10 +48,10 @@ enum pseudokeys {
|
||||||
#define EESCHEMA_EXE wxT( "eeschema" )
|
#define EESCHEMA_EXE wxT( "eeschema" )
|
||||||
#define GERBVIEW_EXE wxT( "gerbview" )
|
#define GERBVIEW_EXE wxT( "gerbview" )
|
||||||
#else
|
#else
|
||||||
#define CVPCB_EXE wxT("cvpcb.app/Contents/MacOS/cvpcb")
|
#define CVPCB_EXE wxT( "cvpcb.app/Contents/MacOS/cvpcb" )
|
||||||
#define PCBNEW_EXE wxT("pcbnew.app/Contents/MacOS/pcbnew")
|
#define PCBNEW_EXE wxT( "pcbnew.app/Contents/MacOS/pcbnew" )
|
||||||
#define EESCHEMA_EXE wxT("eeschema.app/Contents/MacOS/eeschema")
|
#define EESCHEMA_EXE wxT( "eeschema.app/Contents/MacOS/eeschema" )
|
||||||
#define GERBVIEW_EXE wxT("gerbview.app/Contents/MacOS/gerbview")
|
#define GERBVIEW_EXE wxT( "gerbview.app/Contents/MacOS/gerbview" )
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ public:
|
||||||
bool m_Setup; /* TRUE -> inscription en setup (registration base)*/
|
bool m_Setup; /* TRUE -> inscription en setup (registration base)*/
|
||||||
|
|
||||||
public:
|
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() { };
|
~PARAM_CFG_BASE() { };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -109,12 +109,12 @@ public:
|
||||||
int m_Default; /* valeur par defaut */
|
int m_Default; /* valeur par defaut */
|
||||||
|
|
||||||
public:
|
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,
|
int default_val = 0, int min = INT_MINVAL, int max = INT_MAXVAL,
|
||||||
const wxChar * group = NULL );
|
const wxChar* group = NULL );
|
||||||
PARAM_CFG_INT( bool Insetup, const wxChar * ident, int* ptparam,
|
PARAM_CFG_INT( bool Insetup, const wxChar* ident, int* ptparam,
|
||||||
int default_val = 0, int min = INT_MINVAL, int max = INT_MAXVAL,
|
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
|
class PARAM_CFG_SETCOLOR : public PARAM_CFG_BASE
|
||||||
|
@ -124,10 +124,10 @@ public:
|
||||||
int m_Default; /* valeur par defaut */
|
int m_Default; /* valeur par defaut */
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PARAM_CFG_SETCOLOR( const wxChar * ident, int* ptparam,
|
PARAM_CFG_SETCOLOR( const wxChar* ident, int* ptparam,
|
||||||
int default_val, const wxChar * group = NULL );
|
int default_val, const wxChar* group = NULL );
|
||||||
PARAM_CFG_SETCOLOR( bool Insetup, const wxChar * ident, int* ptparam,
|
PARAM_CFG_SETCOLOR( bool Insetup, const wxChar* ident, int* ptparam,
|
||||||
int default_val, const wxChar * group = NULL );
|
int default_val, const wxChar* group = NULL );
|
||||||
};
|
};
|
||||||
|
|
||||||
class PARAM_CFG_DOUBLE : public PARAM_CFG_BASE
|
class PARAM_CFG_DOUBLE : public PARAM_CFG_BASE
|
||||||
|
@ -138,12 +138,12 @@ public:
|
||||||
double m_Min, m_Max; /* valeurs extremes du parametre */
|
double m_Min, m_Max; /* valeurs extremes du parametre */
|
||||||
|
|
||||||
public:
|
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,
|
double default_val = 0.0, double min = 0.0, double max = 10000.0,
|
||||||
const wxChar * group = NULL );
|
const wxChar* group = NULL );
|
||||||
PARAM_CFG_DOUBLE( bool Insetup, const wxChar * ident, double* ptparam,
|
PARAM_CFG_DOUBLE( bool Insetup, const wxChar* ident, double* ptparam,
|
||||||
double default_val = 0.0, double min = 0.0, double max = 10000.0,
|
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
|
class PARAM_CFG_BOOL : public PARAM_CFG_BASE
|
||||||
|
@ -153,10 +153,10 @@ public:
|
||||||
int m_Default; /* valeur par defaut */
|
int m_Default; /* valeur par defaut */
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PARAM_CFG_BOOL( const wxChar * ident, bool * ptparam,
|
PARAM_CFG_BOOL( const wxChar* ident, bool* ptparam,
|
||||||
int default_val = FALSE, const wxChar * group = NULL );
|
int default_val = FALSE, const wxChar* group = NULL );
|
||||||
PARAM_CFG_BOOL( bool Insetup, const wxChar * ident, bool * ptparam,
|
PARAM_CFG_BOOL( bool Insetup, const wxChar* ident, bool* ptparam,
|
||||||
int default_val = FALSE, const wxChar * group = NULL );
|
int default_val = FALSE, const wxChar* group = NULL );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -166,11 +166,11 @@ public:
|
||||||
wxString* m_Pt_param; /* pointeur sur le parametre a configurer */
|
wxString* m_Pt_param; /* pointeur sur le parametre a configurer */
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PARAM_CFG_WXSTRING( 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,
|
PARAM_CFG_WXSTRING( bool Insetup,
|
||||||
const wxChar * ident,
|
const wxChar* ident,
|
||||||
wxString * ptparam,
|
wxString* ptparam,
|
||||||
const wxChar * group = NULL );
|
const wxChar* group = NULL );
|
||||||
};
|
};
|
||||||
|
|
||||||
class PARAM_CFG_LIBNAME_LIST : public PARAM_CFG_BASE
|
class PARAM_CFG_LIBNAME_LIST : public PARAM_CFG_BASE
|
||||||
|
@ -179,9 +179,9 @@ public:
|
||||||
wxArrayString* m_Pt_param; /* pointeur sur le parametre a configurer */
|
wxArrayString* m_Pt_param; /* pointeur sur le parametre a configurer */
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PARAM_CFG_LIBNAME_LIST( const wxChar * ident,
|
PARAM_CFG_LIBNAME_LIST( const wxChar* ident,
|
||||||
wxArrayString * ptparam,
|
wxArrayString* ptparam,
|
||||||
const wxChar * group = NULL );
|
const wxChar* group = NULL );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -195,7 +195,7 @@ private:
|
||||||
wxListBox* m_List;
|
wxListBox* m_List;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
WinEDA_TextFrame( wxWindow * parent, const wxString &title );
|
WinEDA_TextFrame( wxWindow* parent, const wxString& title );
|
||||||
void Append( const wxString& text );
|
void Append( const wxString& text );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -221,24 +221,24 @@ public:
|
||||||
int m_BottomMargin;
|
int m_BottomMargin;
|
||||||
|
|
||||||
public:
|
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 */
|
/* Standard page sizes in 1/1000 inch */
|
||||||
#if defined EDA_BASE
|
#if defined EDA_BASE
|
||||||
Ki_PageDescr g_Sheet_A4( wxSize( 11700, 8267 ), wxPoint( 0, 0 ), wxT( "A4" ) );
|
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_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_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_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_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_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_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_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_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_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_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_user( wxSize( 17000, 11000 ), wxPoint( 0, 0 ), wxT( "User" ) );
|
||||||
|
|
||||||
#else
|
#else
|
||||||
extern Ki_PageDescr g_Sheet_A4;
|
extern Ki_PageDescr g_Sheet_A4;
|
||||||
|
@ -316,7 +316,7 @@ COMMON_GLOBL wxString g_EditorName;
|
||||||
|
|
||||||
// Gestion de la grille "utilisateur" (User Grid)
|
// Gestion de la grille "utilisateur" (User Grid)
|
||||||
#ifdef EDA_BASE
|
#ifdef EDA_BASE
|
||||||
wxRealPoint g_UserGrid( 0.01, 0.01 );
|
wxRealPoint g_UserGrid( 0.01, 0.01 );
|
||||||
|
|
||||||
int g_UserGrid_Unit = INCHES;
|
int g_UserGrid_Unit = INCHES;
|
||||||
#else
|
#else
|
||||||
|
@ -364,7 +364,7 @@ class WinEDA_DrawPanel;
|
||||||
* @param aPoint The point to output.
|
* @param aPoint The point to output.
|
||||||
* @return wxString& - the input string
|
* @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()
|
* @param aFlags The same args as allowed for wxExecute()
|
||||||
* @return bool - true if success, else false
|
* @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".
|
/* Return the name of the layer number "layer_number".
|
||||||
* if "is_filename" == TRUE, the name can be used for a file name
|
* 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 */
|
bool EDA_DirectorySelector( const wxString& Title, /* Titre de la fenetre */
|
||||||
wxString& Path, /* Chemin par defaut */
|
wxString& Path, /* Chemin par defaut */
|
||||||
int flag, /* reserve */
|
int flag, /* reserve */
|
||||||
wxWindow* Frame, /* parent frame */
|
wxWindow* Frame, /* parent frame */
|
||||||
const wxPoint& Pos );
|
const wxPoint& Pos );
|
||||||
|
|
||||||
wxString EDA_FileSelector( const wxString& Title, /* Window title */
|
wxString EDA_FileSelector( const wxString &Title, /* Window title */
|
||||||
const wxString& Path, /* default path */
|
const wxString &Path, /* default path */
|
||||||
const wxString& FileName, /* default filename */
|
const wxString &FileName, /* default filename */
|
||||||
const wxString& Ext, /* default extension */
|
const wxString &Ext, /* default extension */
|
||||||
const wxString& Mask, /* Display filename mask */
|
const wxString &Mask, /* Display filename mask */
|
||||||
wxWindow* Frame, /* parent frame */
|
wxWindow * Frame, /* parent frame */
|
||||||
int flag, /* wxSAVE, wxOPEN ..*/
|
int flag, /* wxSAVE, wxOPEN ..*/
|
||||||
const bool keep_working_directory, /* true = do not change the C.W.D. */
|
const bool keep_working_directory, /* true = do not change the C.W.D. */
|
||||||
const wxPoint& Pos = wxPoint( -1, -1 )
|
const wxPoint& Pos = wxPoint( -1, -1 )
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -461,8 +461,8 @@ wxString MakeFileName( const wxString& dir,
|
||||||
* retourne la chaine calculee */
|
* retourne la chaine calculee */
|
||||||
|
|
||||||
wxString MakeReducedFileName( const wxString& fullfilename,
|
wxString MakeReducedFileName( const wxString& fullfilename,
|
||||||
const wxString& default_path,
|
const wxString& default_path,
|
||||||
const wxString& default_ext );
|
const wxString& default_ext );
|
||||||
|
|
||||||
/* Calcule le nom "reduit" d'un file d'apres les chaines
|
/* Calcule le nom "reduit" d'un file d'apres les chaines
|
||||||
* fullfilename = nom complet
|
* fullfilename = nom complet
|
||||||
|
@ -488,14 +488,14 @@ int ExecuteFile( wxWindow* frame, const wxString& ExecFile,
|
||||||
const wxString& param = wxEmptyString );
|
const wxString& param = wxEmptyString );
|
||||||
void AddDelimiterString( wxString& string );
|
void AddDelimiterString( wxString& string );
|
||||||
|
|
||||||
void SetRealLibraryPath( const wxString& shortlibname );/* met a jour
|
void SetRealLibraryPath( const wxString& shortlibname ); /* met a jour
|
||||||
* le chemin des librairies RealLibDirBuffer (global)
|
* le chemin des librairies RealLibDirBuffer (global)
|
||||||
* a partir de UserLibDirBuffer (global):
|
* a partir de UserLibDirBuffer (global):
|
||||||
* Si UserLibDirBuffer non vide RealLibDirBuffer = UserLibDirBuffer.
|
* Si UserLibDirBuffer non vide RealLibDirBuffer = UserLibDirBuffer.
|
||||||
* Sinon si variable d'environnement KICAD definie (KICAD = chemin pour kicad),
|
* Sinon si variable d'environnement KICAD definie (KICAD = chemin pour kicad),
|
||||||
* UserLibDirBuffer = <KICAD>/shortlibname;
|
* UserLibDirBuffer = <KICAD>/shortlibname;
|
||||||
* Sinon UserLibDirBuffer = <Chemin des binaires>../shortlibname/
|
* Sinon UserLibDirBuffer = <Chemin des binaires>../shortlibname/
|
||||||
*/
|
*/
|
||||||
wxString FindKicadHelpPath();
|
wxString FindKicadHelpPath();
|
||||||
|
|
||||||
/* Find absolute path for kicad/help (or kicad/help/<language>) */
|
/* 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 );
|
bool case_sensitive = TRUE );
|
||||||
|
|
||||||
/* compare 2 noms de composants, selon regles usuelles
|
/* compare 2 noms de composants, selon regles usuelles
|
||||||
* ( Jokers * , ? , autoris<EFBFBD>s).
|
* ( Jokers * , ? , autorises).
|
||||||
* la chaine de reference est "pattern"
|
* la chaine de reference est "pattern"
|
||||||
* si case_sensitive == TRUE (default), comparaison exacte
|
* si case_sensitive == TRUE (default), comparaison exacte
|
||||||
* retourne TRUE si match FALSE si differences */
|
* retourne TRUE si match FALSE si differences */
|
||||||
|
|
||||||
char* to_point( char* Text );
|
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 */
|
* qui genere les flottants avec une virgule au lieu du point en mode international */
|
||||||
|
|
||||||
/****************/
|
/****************/
|
||||||
/* infospgm.cpp */
|
/* infospgm.cpp */
|
||||||
/****************/
|
/****************/
|
||||||
extern wxString g_KicadAboutTitle;
|
extern wxString g_KicadAboutTitle;
|
||||||
extern wxString g_CvpcbAboutTitle;
|
extern wxString g_CvpcbAboutTitle;
|
||||||
extern wxString g_EeschemaAboutTitle;
|
extern wxString g_EeschemaAboutTitle;
|
||||||
extern wxString g_PcbnewAboutTitle;
|
extern wxString g_PcbnewAboutTitle;
|
||||||
extern wxString g_GerbviewAboutTitle;
|
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 */
|
/* common.cpp */
|
||||||
|
@ -591,10 +593,10 @@ void Print_Kicad_Infos( wxWindow* frame, const wxString& title );
|
||||||
wxString GetBuildVersion(); /* Return the build date */
|
wxString GetBuildVersion(); /* Return the build date */
|
||||||
|
|
||||||
void Affiche_1_Parametre( WinEDA_DrawFrame* frame,
|
void Affiche_1_Parametre( WinEDA_DrawFrame* frame,
|
||||||
int pos_X,
|
int pos_X,
|
||||||
const wxString& texte_H,
|
const wxString& texte_H,
|
||||||
const wxString& texte_L,
|
const wxString& texte_L,
|
||||||
int color );
|
int color );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Routine d'affichage d'un parametre.
|
* Routine d'affichage d'un parametre.
|
||||||
|
@ -608,16 +610,16 @@ void Affiche_1_Parametre( WinEDA_DrawFrame* frame,
|
||||||
* color = couleur d'affichage
|
* 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 */
|
/* Routine d'affichage de la documentation associee a un composant */
|
||||||
|
|
||||||
int GetTimeStamp();
|
int GetTimeStamp();
|
||||||
|
|
||||||
/* Retoure une identification temporelle (Time stamp) differente a chaque appel */
|
/* Retoure une identification temporelle (Time stamp) differente a chaque appel */
|
||||||
int DisplayColorFrame( wxWindow* parent, int OldColor );
|
int DisplayColorFrame( wxWindow* parent, int OldColor );
|
||||||
int GetCommandOptions( const int argc, const char** argv, const char* stringtst,
|
int GetCommandOptions( const int argc, const char** argv, const char* stringtst,
|
||||||
const char** optarg, int* optind );
|
const char** optarg, int* optind );
|
||||||
|
|
||||||
|
|
||||||
const wxString& valeur_param( int valeur, wxString& buf_texte );
|
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
|
* suivie de " ou mm
|
||||||
*/
|
*/
|
||||||
|
|
||||||
wxString ReturnUnitSymbol( int Units = g_UnitMetric );
|
wxString ReturnUnitSymbol( int Units = g_UnitMetric );
|
||||||
int ReturnValueFromString( int Units, const wxString& TextValue, int Internal_Unit );
|
int ReturnValueFromString( int Units, const wxString& TextValue, int Internal_Unit );
|
||||||
wxString ReturnStringFromValue( int Units, int Value, int Internal_Unit );
|
wxString ReturnStringFromValue( int Units, int Value, int Internal_Unit );
|
||||||
void AddUnitSymbol( wxStaticText& Stext, int Units = g_UnitMetric );
|
void AddUnitSymbol( wxStaticText& Stext, int Units = g_UnitMetric );
|
||||||
|
|
||||||
/* Add string " (mm):" or " ("):" to the static text Stext.
|
/* Add string " (mm):" or " ("):" to the static text Stext.
|
||||||
* Used in dialog boxes for entering values depending on selected units */
|
* 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
|
/* 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 */
|
* 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,
|
/* Convert the Value in the wxTextCtrl TextCtrl in an integer,
|
||||||
* according to the internal units and the selected unit (g_UnitMetric) */
|
* according to the internal units and the selected unit (g_UnitMetric) */
|
||||||
|
|
||||||
double To_User_Unit( bool is_metric, int val, int internal_unit_value );
|
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 );
|
int From_User_Unit( bool is_metric, double val, int internal_unit_value );
|
||||||
wxString GenDate();
|
wxString GenDate();
|
||||||
void MyFree( void* pt_mem );
|
void MyFree( void* pt_mem );
|
||||||
void* MyZMalloc( size_t nb_octets );
|
void* MyZMalloc( size_t nb_octets );
|
||||||
void* MyMalloc( 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 */
|
/* get_component_dialog.cpp */
|
||||||
/****************************/
|
/****************************/
|
||||||
wxString GetComponentName( WinEDA_DrawFrame* frame,
|
wxString GetComponentName( WinEDA_DrawFrame * frame,
|
||||||
wxArrayString& HistoryList, const wxString& Title,
|
wxArrayString & HistoryList, const wxString &Title,
|
||||||
wxString (* AuxTool)(WinEDA_DrawFrame* parent) );
|
wxString (*AuxTool)( WinEDA_DrawFrame * parent ) );
|
||||||
|
|
||||||
/* Dialog frame to choose a component name */
|
/* Dialog frame to choose a component name */
|
||||||
void AddHistoryComponentName( wxArrayString& HistoryList, const wxString& Name );
|
void AddHistoryComponentName( wxArrayString& HistoryList, const wxString& Name );
|
||||||
|
|
|
@ -329,6 +329,8 @@ public:
|
||||||
|
|
||||||
~WinEDA_PcbFrame();
|
~WinEDA_PcbFrame();
|
||||||
|
|
||||||
|
void GetKicadAbout( wxCommandEvent& event );
|
||||||
|
|
||||||
// Configurations:
|
// Configurations:
|
||||||
void InstallConfigFrame( const wxPoint& pos );
|
void InstallConfigFrame( const wxPoint& pos );
|
||||||
void Process_Config( wxCommandEvent& event );
|
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
|
// UnComment this to load subdirs files in the tree project
|
||||||
#define ADD_FILES_IN_SUBDIRS
|
#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,
|
WinEDA_PrjFrame::WinEDA_PrjFrame( WinEDA_MainFrame* parent,
|
||||||
const wxPoint& pos,
|
const wxPoint& pos,
|
||||||
|
@ -44,12 +62,10 @@ WinEDA_PrjFrame::WinEDA_PrjFrame( WinEDA_MainFrame* parent,
|
||||||
* for a given file type.
|
* 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( "^.*\\.sch$" ) ); // note: sch filter must be first because of a test in AddFile() below
|
||||||
m_Filters.push_back( wxT( "^.*\\.pro$" ) );
|
for ( int ii = 0; s_AllowedExtensionsToList[ii] != NULL; ii++ )
|
||||||
m_Filters.push_back( wxT( "^.*\\.pdf$" ) );
|
{
|
||||||
m_Filters.push_back( wxT( "^[^$].*\\.brd$" ) );
|
m_Filters.push_back( s_AllowedExtensionsToList[ii] );
|
||||||
m_Filters.push_back( wxT( "^.*\\.net$" ) );
|
}
|
||||||
m_Filters.push_back( wxT( "^.*\\.txt$" ) );
|
|
||||||
m_Filters.push_back( wxT( "^.*\\.pho$" ) );
|
|
||||||
m_Filters.push_back( wxT( "^no kicad files found" ) );
|
m_Filters.push_back( wxT( "^no kicad files found" ) );
|
||||||
|
|
||||||
#ifdef KICAD_PYTHON
|
#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
|
KICAD_SUBDIRS_BIN = eeschema eeschema/plugins pcbnew cvpcb kicad gerbview
|
||||||
# How to invoke make:
|
# How to invoke make:
|
||||||
MAKE = make -k -f makefile.g95
|
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})
|
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}
|
install(TARGETS pcbnew RUNTIME DESTINATION ${KICAD_BIN}
|
||||||
COMPONENT binary)
|
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\
|
EXTRACPPFLAGS += -DPCBNEW -fno-strict-aliasing -I./ -Ibitmaps -I../include -I../share\
|
||||||
-I../pcbnew -I../3d-viewer -I../polygon
|
-I../pcbnew -I../3d-viewer -I../polygon
|
||||||
|
|
||||||
|
|
|
@ -478,7 +478,7 @@ void WinEDA_PcbFrame::createPopupMenuForTracks( TRACK* Track, wxMenu* PopMenu )
|
||||||
wxMenu* via_mnu = new wxMenu();
|
wxMenu* via_mnu = new wxMenu();
|
||||||
|
|
||||||
ADD_MENUITEM_WITH_SUBMENU( PopMenu, via_mnu,
|
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,
|
ADD_MENUITEM( via_mnu, ID_POPUP_PCB_VIA_HOLE_TO_DEFAULT,
|
||||||
_( "Set via hole to Default" ), apply_xpm );
|
_( "Set via hole to Default" ), apply_xpm );
|
||||||
msg = _( "Set via hole to a specific value. This specfic value is currently" );
|
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,
|
ADD_MENUITEM_WITH_HELP( via_mnu, ID_POPUP_PCB_VIA_HOLE_TO_VALUE,
|
||||||
_( "Set via hole to alt value" ), msg,
|
_( "Set via hole to alt value" ), msg,
|
||||||
options_new_pad_xpm );
|
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 );
|
msg << wxT(" ") << ReturnStringFromValue( g_UnitMetric, g_DesignSettings.m_ViaDrillCustomValue, m_InternalUnits );
|
||||||
ADD_MENUITEM_WITH_HELP( via_mnu, ID_POPUP_PCB_VIA_HOLE_ENTER_VALUE,
|
ADD_MENUITEM_WITH_HELP( via_mnu, ID_POPUP_PCB_VIA_HOLE_ENTER_VALUE,
|
||||||
_( "Set the via hole alt value" ), msg, edit_xpm );
|
_( "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,
|
ADD_MENUITEM_WITH_SUBMENU( PopMenu, track_mnu,
|
||||||
ID_POPUP_PCB_EDIT_TRACK_MNU, _( "Change Width" ), width_track_xpm );
|
ID_POPUP_PCB_EDIT_TRACK_MNU, _( "Change Width" ), width_track_xpm );
|
||||||
ADD_MENUITEM( track_mnu, ID_POPUP_PCB_EDIT_TRACKSEG,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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:
|
// Delete control:
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#include "protos.h"
|
#include "protos.h"
|
||||||
#include "id.h"
|
#include "id.h"
|
||||||
#include "drc_stuff.h"
|
#include "drc_stuff.h"
|
||||||
|
#include "kbool/include/booleng.h"
|
||||||
|
|
||||||
/*******************************/
|
/*******************************/
|
||||||
/* class WinEDA_PcbFrame */
|
/* class WinEDA_PcbFrame */
|
||||||
|
@ -99,7 +99,7 @@ BEGIN_EVENT_TABLE( WinEDA_PcbFrame, WinEDA_BasePcbFrame )
|
||||||
|
|
||||||
// Menu Help
|
// Menu Help
|
||||||
EVT_MENU( ID_GENERAL_HELP, WinEDA_DrawFrame::GetKicadHelp )
|
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
|
// Menu 3D Frame
|
||||||
EVT_MENU( ID_MENU_PCB_SHOW_3D_FRAME, WinEDA_PcbFrame::Show3D_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();
|
ReCreateOptToolbar();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/************************************/
|
||||||
WinEDA_PcbFrame::~WinEDA_PcbFrame()
|
WinEDA_PcbFrame::~WinEDA_PcbFrame()
|
||||||
|
/************************************/
|
||||||
{
|
{
|
||||||
m_Parent->m_PcbFrame = NULL;
|
m_Parent->m_PcbFrame = NULL;
|
||||||
SetBaseScreen( ScreenPcb );
|
SetBaseScreen( ScreenPcb );
|
||||||
|
@ -566,3 +567,15 @@ void WinEDA_PcbFrame::SetToolbars()
|
||||||
DisplayUnitsMsg();
|
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 );
|
NewArea = AddArea( CurrArea->GetNet(), CurrArea->GetLayer(), 0, 0, 0 );
|
||||||
|
|
||||||
// remove the poly that was automatically created for the new area
|
// 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;
|
delete NewArea->m_Poly;
|
||||||
NewArea->m_Poly = new_p;
|
NewArea->m_Poly = new_p;
|
||||||
NewArea->m_Poly->Draw();
|
NewArea->m_Poly->Draw();
|
||||||
|
@ -694,183 +694,109 @@ int BOARD::CombineAreas( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_to_combi
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// polygons intersect, combine them
|
// 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_array1;
|
||||||
std::vector<CArc> arc_array2;
|
std::vector<CArc> arc_array2;
|
||||||
|
bool keep_area_to_combine = false;
|
||||||
|
|
||||||
poly1->MakePolygonFromAreaOutlines( -1, &arc_array1 );
|
Bool_Engine* booleng = new Bool_Engine();
|
||||||
poly2->MakePolygonFromAreaOutlines( -1, &arc_array2 );
|
ArmBoolEng( booleng );
|
||||||
|
|
||||||
#ifdef USE_GPC_POLY_LIB
|
area_ref->m_Poly->AddPolygonsToBoolEng( booleng, GROUP_A, -1, -1 );
|
||||||
int n_ext_cont1 = 0;
|
area_to_combine->m_Poly->AddPolygonsToBoolEng( booleng, GROUP_B, -1, -1 );
|
||||||
for( int ic = 0; ic<poly1->GetGpcPoly()->num_contours; ic++ )
|
booleng->Do_Operation( BOOL_OR );
|
||||||
if( !( (poly1->GetGpcPoly()->hole)[ic] ) )
|
|
||||||
n_ext_cont1++;
|
|
||||||
|
|
||||||
int n_ext_cont2 = 0;
|
// create area with external contour: Recreate only area edges, NOT holes
|
||||||
for( int ic = 0; ic<poly2->GetGpcPoly()->num_contours; ic++ )
|
if( booleng->StartPolygonGet() )
|
||||||
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 )
|
|
||||||
{
|
{
|
||||||
gpc_free_polygon( union_gpc );
|
if( booleng->GetPolygonPointEdgeType() == KB_INSIDE_EDGE )
|
||||||
delete union_gpc;
|
{
|
||||||
return 0;
|
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
|
// Recreate the area_to_combine if a second polygon exists
|
||||||
RemoveArea( area_to_combine );
|
// if not exists , the first poly contains the 2 initial polygons
|
||||||
area_ref->m_Poly->RemoveAllContours();
|
#if 0 // TestAreaIntersection must be called before combine areas, so
|
||||||
|
// 2 intersecting areas are expected, and only one outline contour after combining areas
|
||||||
// create area with external contour
|
else
|
||||||
for( int ic = 0; ic<union_gpc->num_contours; ic++ )
|
|
||||||
{
|
{
|
||||||
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
|
// foreach point in the polygon
|
||||||
for( int i = 0; i<union_gpc->contour[ic].num_vertices; i++ )
|
bool first = true;
|
||||||
|
while( booleng->PolygonHasMorePoints() )
|
||||||
{
|
{
|
||||||
int x = (int) ( (union_gpc->contour)[ic].vertex )[i].x;
|
int x = booleng->GetPolygonXPoint();
|
||||||
int y = (int) ( (union_gpc->contour)[ic].vertex )[i].y;
|
int y = booleng->GetPolygonYPoint();
|
||||||
if( i==0 )
|
if( first )
|
||||||
{
|
{
|
||||||
area_ref->m_Poly->Start( area_ref->GetLayer(
|
first = false;
|
||||||
), x, y, area_ref->m_Poly->GetHatchStyle() );
|
area_to_combine->m_Poly->Start( area_ref->GetLayer(
|
||||||
|
), x, y, area_ref->m_Poly->GetHatchStyle() );
|
||||||
}
|
}
|
||||||
else
|
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
|
// 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
|
DisplayError( NULL,
|
||||||
for( int i = 0; i<union_gpc->contour[ic].num_vertices; i++ )
|
wxT( "BOARD::CombineAreas() error: unexpected outside contour descriptor" ) );
|
||||||
{
|
continue;
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
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->utility = 1;
|
||||||
area_ref->m_Poly->RestoreArcs( &arc_array1 );
|
area_ref->m_Poly->RestoreArcs( &arc_array1 );
|
||||||
area_ref->m_Poly->RestoreArcs( &arc_array2 );
|
area_ref->m_Poly->RestoreArcs( &arc_array2 );
|
||||||
area_ref->m_Poly->Draw();
|
area_ref->m_Poly->Draw();
|
||||||
gpc_free_polygon( union_gpc );
|
delete booleng;
|
||||||
delete union_gpc;
|
|
||||||
|
|
||||||
return 1;
|
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
|
* @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;
|
wxString str;
|
||||||
|
|
||||||
wxPoint start = aArea->GetCornerPosition(aCornerIndex);
|
wxPoint start = aArea->GetCornerPosition( aCornerIndex );
|
||||||
wxPoint end;
|
wxPoint end;
|
||||||
// Search the end point of the edge starting at aCornerIndex
|
|
||||||
if( aArea->m_Poly->corner[aCornerIndex].end_contour == FALSE &&
|
// Search the end point of the edge starting at aCornerIndex
|
||||||
aCornerIndex < (aArea->GetNumCorners() - 1) )
|
if( aArea->m_Poly->corner[aCornerIndex].end_contour == FALSE
|
||||||
{
|
&& aCornerIndex < (aArea->GetNumCorners() - 1) )
|
||||||
end = aArea->GetCornerPosition(aCornerIndex+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
|
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);
|
int ii = aCornerIndex - 1;
|
||||||
while ( ii >= 0 )
|
end = aArea->GetCornerPosition( ii );
|
||||||
{
|
while( ii >= 0 )
|
||||||
if ( aArea->m_Poly->corner[ii].end_contour )
|
{
|
||||||
break;
|
if( aArea->m_Poly->corner[ii].end_contour )
|
||||||
end = aArea->GetCornerPosition(ii);
|
break;
|
||||||
ii--;
|
end = aArea->GetCornerPosition( ii );
|
||||||
}
|
ii--;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// iterate through all areas
|
// iterate through all areas
|
||||||
for( int ia2 = 0; ia2 < m_pcb->GetAreaCount(); ia2++ )
|
for( int ia2 = 0; ia2 < m_pcb->GetAreaCount(); ia2++ )
|
||||||
|
@ -1134,7 +1061,7 @@ bool DRC::doEdgeZoneDrc( ZONE_CONTAINER * aArea, int aCornerIndex )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Test for same net
|
// 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;
|
continue;
|
||||||
|
|
||||||
// test for ending line inside Area_To_Test
|
// 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 ),
|
m_currentMarker = fillMarker( aArea, wxPoint( x, y ),
|
||||||
COPPERAREA_CLOSE_TO_COPPERAREA,
|
COPPERAREA_CLOSE_TO_COPPERAREA,
|
||||||
m_currentMarker );
|
m_currentMarker );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
set(POLYGON_SRCS
|
set(POLYGON_SRCS
|
||||||
GenericPolygonClipperLibrary.cpp
|
|
||||||
math_for_graphics.cpp
|
math_for_graphics.cpp
|
||||||
php_polygon.cpp
|
|
||||||
php_polygon_vertex.cpp
|
|
||||||
PolyLine.cpp)
|
PolyLine.cpp)
|
||||||
|
|
||||||
add_library(polygon ${POLYGON_SRCS})
|
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.
|
// PolyLine.cpp ... implementation of CPolyLine class from FreePCB.
|
||||||
|
|
||||||
//
|
//
|
||||||
// implementation for kicad
|
// implementation for kicad and kbool polygon clipping library
|
||||||
//
|
//
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
@ -13,8 +13,6 @@ using namespace std;
|
||||||
|
|
||||||
#include "PolyLine.h"
|
#include "PolyLine.h"
|
||||||
|
|
||||||
#define to_int( x ) (int) round( (x) )
|
|
||||||
|
|
||||||
|
|
||||||
#define pi 3.14159265359
|
#define pi 3.14159265359
|
||||||
|
|
||||||
|
@ -23,17 +21,7 @@ CPolyLine::CPolyLine()
|
||||||
m_HatchStyle = 0;
|
m_HatchStyle = 0;
|
||||||
m_Width = 0;
|
m_Width = 0;
|
||||||
utility = 0;
|
utility = 0;
|
||||||
#ifdef USE_GPC_POLY_LIB
|
m_Kbool_Poly_Engine = NULL;
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -42,288 +30,286 @@ CPolyLine::CPolyLine()
|
||||||
CPolyLine::~CPolyLine()
|
CPolyLine::~CPolyLine()
|
||||||
{
|
{
|
||||||
Undraw();
|
Undraw();
|
||||||
#ifdef USE_GPC_POLY_LIB
|
|
||||||
FreeGpcPoly();
|
|
||||||
delete m_gpc_poly;
|
|
||||||
#endif
|
|
||||||
#ifdef USE_GPL_POLY_LIB
|
|
||||||
delete m_php_poly;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Function NormalizeWithKbool
|
||||||
#ifdef USE_GPC_POLY_LIB
|
* 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
|
||||||
// Use the General Polygon Clipping Library to clip contours
|
* if more than one outside contour are found, extra CPolyLines will be created
|
||||||
// If this results in new polygons, return them as std::vector p
|
* because copper areas have only one outside contour
|
||||||
// If bRetainArcs == TRUE, try to retain arcs in polys
|
* Therefore, if this results in new CPolyLines, return them as std::vector pa
|
||||||
// Returns number of external contours, or -1 if error
|
* @param pa: pointer on a std::vector<CPolyLine*> to store extra CPolyLines
|
||||||
//
|
* @param bRetainArcs == TRUE, try to retain arcs in polys
|
||||||
int CPolyLine::NormalizeWithGpc( std::vector<CPolyLine*> * pa, bool bRetainArcs )
|
* @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 )
|
if( bRetainArcs )
|
||||||
MakeGpcPoly( -1, &arc_array );
|
MakeKboolPoly( -1, -1, &arc_array );
|
||||||
else
|
else
|
||||||
MakeGpcPoly( -1, NULL );
|
MakeKboolPoly( -1, -1, NULL );
|
||||||
|
|
||||||
Undraw();
|
Undraw();
|
||||||
|
|
||||||
// now, recreate poly
|
/* now, recreate polys
|
||||||
// first, find outside contours and create new CPolyLines if necessary
|
* if more than one outside contour are found, extra CPolyLines will be created
|
||||||
int n_ext_cont = 0;
|
* because copper areas have only one outside contour
|
||||||
for( int ic = 0; ic<m_gpc_poly->num_contours; ic++ )
|
* 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
|
int x = m_Kbool_Poly_Engine->GetPolygonXPoint();
|
||||||
corner.clear();
|
int y = m_Kbool_Poly_Engine->GetPolygonYPoint();
|
||||||
side_style.clear();
|
hole->push_back( x );
|
||||||
for( int i = 0; i<m_gpc_poly->contour[ic].num_vertices; i++ )
|
hole->push_back( y );
|
||||||
{
|
|
||||||
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++;
|
|
||||||
}
|
}
|
||||||
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
|
int x = m_Kbool_Poly_Engine->GetPolygonXPoint();
|
||||||
CPolyLine* poly = new CPolyLine;
|
int y = m_Kbool_Poly_Engine->GetPolygonYPoint();
|
||||||
pa->push_back( poly ); // put in array
|
if( first )
|
||||||
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 );
|
first = false;
|
||||||
int y = to_int( ( (m_gpc_poly->contour)[ic].vertex )[i].y );
|
polyline->Start( GetLayer(), x, y, GetHatchStyle() );
|
||||||
if( i==0 )
|
|
||||||
poly->Start( m_layer, x, y, m_HatchStyle );
|
|
||||||
else
|
|
||||||
poly->AppendCorner( x, y, STRAIGHT, FALSE );
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
poly->Close( STRAIGHT, FALSE );
|
polyline->AppendCorner( x, y );
|
||||||
n_ext_cont++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_Kbool_Poly_Engine->EndPolygonGet();
|
||||||
|
polyline->Close( STRAIGHT, FALSE );
|
||||||
|
n_ext_cont++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// now add cutouts to the CPolyLine(s)
|
// now add cutouts to the corresponding CPolyLine(s)
|
||||||
for( int ic = 0; ic<m_gpc_poly->num_contours; ic++ )
|
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;
|
polyline = this;
|
||||||
if( n_ext_cont == 1 )
|
}
|
||||||
|
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;
|
for( int ext_ic = 0; ext_ic<n_ext_cont - 1; ext_ic++ )
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// find the polygon that contains this hole
|
|
||||||
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 );
|
if( (*pa)[ext_ic]->TestPointInside( x, y ) )
|
||||||
int y = to_int( ( (m_gpc_poly->contour)[ic].vertex )[i].y );
|
|
||||||
if( TestPointInside( x, y ) )
|
|
||||||
ext_poly = this;
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
for( int ext_ic = 0; ext_ic<n_ext_cont - 1; ext_ic++ )
|
polyline = (*pa)[ext_ic];
|
||||||
{
|
|
||||||
if( (*pa)[ext_ic]->TestPointInside( x, y ) )
|
|
||||||
{
|
|
||||||
ext_poly = (*pa)[ext_ic];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if( ext_poly )
|
|
||||||
break;
|
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 x = (*hole)[ii]; ii++;
|
||||||
int y = to_int( ( (m_gpc_poly->contour)[ic].vertex )[i].y );
|
int y = (*hole)[ii];
|
||||||
ext_poly->AppendCorner( x, y, STRAIGHT, FALSE );
|
polyline->AppendCorner( x, y, STRAIGHT, FALSE );
|
||||||
}
|
}
|
||||||
|
|
||||||
ext_poly->Close( STRAIGHT, FALSE );
|
polyline->Close( STRAIGHT, FALSE );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( bRetainArcs )
|
if( bRetainArcs )
|
||||||
RestoreArcs( &arc_array, pa );
|
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;
|
return n_ext_cont;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
/** Function AddPolygonsToBoolEng
|
||||||
|
* and edges contours to a kbool engine, preparing a boolean op between polygons
|
||||||
#ifdef USE_GPL_POLY_LIB
|
* @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)
|
||||||
// make a php_polygon from first contour
|
* @param arc_array: arc converted to poly segments (NULL if not exists)
|
||||||
int CPolyLine::MakePhpPoly()
|
* @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 count = 0;
|
||||||
int nv = GetContourEnd( 0 );
|
|
||||||
for( int iv = 0; iv <= nv; iv++ )
|
|
||||||
m_php_poly->addv( GetX( iv ), GetY( iv ) );
|
|
||||||
|
|
||||||
m_php_poly->getFirst()->m_id = 1;
|
if( (aGroup != GROUP_A) && (aGroup != GROUP_B ) )
|
||||||
return 0;
|
return 0; //Error !
|
||||||
}
|
|
||||||
|
|
||||||
|
MakeKboolPoly( aStart_contour, aEnd_contour, arc_array );
|
||||||
|
|
||||||
void CPolyLine::FreePhpPoly()
|
while( m_Kbool_Poly_Engine->StartPolygonGet() )
|
||||||
{
|
|
||||||
// delete all vertices
|
|
||||||
while( m_php_poly->m_cnt > 1 )
|
|
||||||
{
|
{
|
||||||
vertex* fv = m_php_poly->getFirst();
|
if( aBooleng->StartPolygonAdd( GROUP_A ) )
|
||||||
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
|
|
||||||
{
|
{
|
||||||
vertex* v = p->getFirst();
|
while( m_Kbool_Poly_Engine->PolygonHasMorePoints() )
|
||||||
Start( m_layer, to_int( v->X() ), to_int( v->Y() ), m_HatchStyle );
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
vertex* n = v->Next();
|
int x = m_Kbool_Poly_Engine->GetPolygonXPoint();
|
||||||
AppendCorner( to_int( v->X() ), to_int( (v->Y()) ) );
|
int y = m_Kbool_Poly_Engine->GetPolygonYPoint();
|
||||||
v = n;
|
aBooleng->AddPoint( x, y );
|
||||||
} while( v->id() != p->getFirst()->id() );
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
Close();
|
aBooleng->EndPolygonAdd();
|
||||||
|
}
|
||||||
// p = p->NextPoly();
|
m_Kbool_Poly_Engine->EndPolygonGet();
|
||||||
delete p;
|
|
||||||
p = NULL;
|
|
||||||
} while( p );
|
|
||||||
}
|
}
|
||||||
Draw();
|
|
||||||
|
delete m_Kbool_Poly_Engine;
|
||||||
|
m_Kbool_Poly_Engine = NULL;
|
||||||
|
|
||||||
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
/** Function MakeKboolPoly
|
||||||
|
* fill a kbool engine with a closed polyline contour
|
||||||
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
|
|
||||||
* approximates arcs with multiple straight-line segments
|
* 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
|
* 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
|
* @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 )
|
if( m_Kbool_Poly_Engine )
|
||||||
FreeGpcPoly();
|
{
|
||||||
if( !GetClosed() && (icontour == (GetNumContours() - 1) || icontour == -1) )
|
delete m_Kbool_Poly_Engine;
|
||||||
|
m_Kbool_Poly_Engine = NULL;
|
||||||
|
}
|
||||||
|
if( !GetClosed() && (aStart_contour == (GetNumContours() - 1) || aStart_contour == -1) )
|
||||||
return 1; // error
|
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 n_arcs = 0;
|
||||||
|
|
||||||
int first_contour = icontour;
|
int first_contour = aStart_contour;
|
||||||
int last_contour = icontour;
|
int last_contour = aEnd_contour;
|
||||||
if( icontour == -1 )
|
if( aStart_contour == -1 )
|
||||||
{
|
{
|
||||||
first_contour = 0;
|
first_contour = 0;
|
||||||
last_contour = GetNumContours() - 1;
|
last_contour = GetNumContours() - 1;
|
||||||
}
|
}
|
||||||
|
if( aEnd_contour == -1 )
|
||||||
|
{
|
||||||
|
last_contour = GetNumContours() - 1;
|
||||||
|
}
|
||||||
if( arc_array )
|
if( arc_array )
|
||||||
arc_array->clear();
|
arc_array->clear();
|
||||||
int iarc = 0;
|
int iarc = 0;
|
||||||
for( int icont = first_contour; icont<=last_contour; icont++ )
|
for( int icont = first_contour; icont<=last_contour; icont++ )
|
||||||
{
|
{
|
||||||
// make gpc_polygon for this contour
|
// Fill a kbool engine for this contour,
|
||||||
gpc_polygon* gpc = new gpc_polygon;
|
// and combine it with previous contours
|
||||||
gpc->num_contours = 0;
|
Bool_Engine* booleng = new Bool_Engine();
|
||||||
gpc->hole = NULL;
|
ArmBoolEng( booleng );
|
||||||
gpc->contour = NULL;
|
|
||||||
|
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
|
// first, calculate number of vertices in contour
|
||||||
int n_vertices = 0;
|
int n_vertices = 0;
|
||||||
int ic_st = GetContourStart( icont );
|
int ic_st = GetContourStart( icont );
|
||||||
int ic_end = GetContourEnd( 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++ )
|
for( int ic = ic_st; ic<=ic_end; ic++ )
|
||||||
{
|
{
|
||||||
int style = side_style[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
|
// now enter this contour to booleng
|
||||||
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;
|
|
||||||
int ivtx = 0;
|
int ivtx = 0;
|
||||||
for( int ic = ic_st; ic<=ic_end; ic++ )
|
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 )
|
if( style == STRAIGHT )
|
||||||
{
|
{
|
||||||
g_v_list->vertex[ivtx].x = x1;
|
booleng->AddPoint( x1, y1 );
|
||||||
g_v_list->vertex[ivtx].y = y1;
|
|
||||||
ivtx++;
|
ivtx++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -480,8 +462,7 @@ int CPolyLine::MakeGpcPoly( int icontour, std::vector<CArc> * arc_array )
|
||||||
x = x1;
|
x = x1;
|
||||||
y = y1;
|
y = y1;
|
||||||
}
|
}
|
||||||
g_v_list->vertex[ivtx].x = x;
|
booleng->AddPoint( x1, y1 );
|
||||||
g_v_list->vertex[ivtx].y = y;
|
|
||||||
ivtx++;
|
ivtx++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -490,42 +471,93 @@ int CPolyLine::MakeGpcPoly( int icontour, std::vector<CArc> * arc_array )
|
||||||
if( n_vertices != ivtx )
|
if( n_vertices != ivtx )
|
||||||
wxASSERT( 0 );
|
wxASSERT( 0 );
|
||||||
|
|
||||||
// add vertex_list to gpc
|
// close list added to the bool engine
|
||||||
gpc_add_contour( gpc, g_v_list, 0 );
|
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
|
// now copy result to m_gpc_poly
|
||||||
gpc_free_polygon( m_gpc_poly );
|
if( m_Kbool_Poly_Engine )
|
||||||
delete m_gpc_poly;
|
delete m_Kbool_Poly_Engine;
|
||||||
m_gpc_poly = result;
|
m_Kbool_Poly_Engine = booleng;
|
||||||
gpc_free_polygon( gpc );
|
|
||||||
delete gpc;
|
|
||||||
free( g_v_list->vertex );
|
|
||||||
free( g_v_list );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
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;
|
aBooleng->SetLinkHoles( true ); // holes will be connected by double overlapping segments
|
||||||
delete m_gpc_poly->contour;
|
aBooleng->SetOrientationEntryMode( false ); // all polygons are contours, not holes
|
||||||
delete m_gpc_poly->hole;
|
}
|
||||||
|
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
|
// Restore arcs to a polygon where they were replaced with steps
|
||||||
// If pa != NULL, also use polygons in pa array
|
// 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 = (*pa)[ip - 1];
|
||||||
poly->Undraw();
|
poly->Undraw();
|
||||||
for( int ic = 0; ic<poly->GetNumCorners(); ic++ )
|
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
|
// find arcs and replace them
|
||||||
|
@ -1181,19 +1214,20 @@ void CPolyLine::Hatch()
|
||||||
if( corner[ic].end_contour || ( ic == (int) (corner.size() - 1) ) )
|
if( corner[ic].end_contour || ( ic == (int) (corner.size() - 1) ) )
|
||||||
{
|
{
|
||||||
ok = FindLineSegmentIntersection( a, slope,
|
ok = FindLineSegmentIntersection( a, slope,
|
||||||
corner[ic].x, corner[ic].y,
|
corner[ic].x, corner[ic].y,
|
||||||
corner[i_start_contour].x, corner[i_start_contour].y,
|
corner[i_start_contour].x,
|
||||||
side_style[ic],
|
corner[i_start_contour].y,
|
||||||
&x, &y, &x2, &y2 );
|
side_style[ic],
|
||||||
|
&x, &y, &x2, &y2 );
|
||||||
i_start_contour = ic + 1;
|
i_start_contour = ic + 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ok = FindLineSegmentIntersection( a, slope,
|
ok = FindLineSegmentIntersection( a, slope,
|
||||||
corner[ic].x, corner[ic].y,
|
corner[ic].x, corner[ic].y,
|
||||||
corner[ic + 1].x, corner[ic + 1].y,
|
corner[ic + 1].x, corner[ic + 1].y,
|
||||||
side_style[ic],
|
side_style[ic],
|
||||||
&x, &y, &x2, &y2 );
|
&x, &y, &x2, &y2 );
|
||||||
}
|
}
|
||||||
if( ok )
|
if( ok )
|
||||||
{
|
{
|
||||||
|
@ -1267,11 +1301,12 @@ void CPolyLine::Hatch()
|
||||||
double y2 = yy[ip + 1] - dx * slope;
|
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], yy[ip], to_int( x1 ), to_int( y1 ) ) );
|
||||||
m_HatchLines.push_back( CSegment( xx[ip + 1], yy[ip + 1], to_int( x2 ),
|
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;
|
int ok;
|
||||||
if( ic == istart )
|
if( ic == istart )
|
||||||
ok = FindLineSegmentIntersection( a, slope,
|
ok = FindLineSegmentIntersection( a, slope,
|
||||||
corner[iend].x, corner[iend].y,
|
corner[iend].x, corner[iend].y,
|
||||||
corner[istart].x, corner[istart].y,
|
corner[istart].x, corner[istart].y,
|
||||||
side_style[corner.size() - 1],
|
side_style[corner.size() - 1],
|
||||||
&x, &y, &x2, &y2 );
|
&x, &y, &x2, &y2 );
|
||||||
else
|
else
|
||||||
ok = FindLineSegmentIntersection( a, slope,
|
ok = FindLineSegmentIntersection( a, slope,
|
||||||
corner[ic - 1].x, corner[ic - 1].y,
|
corner[ic - 1].x, corner[ic - 1].y,
|
||||||
corner[ic].x, corner[ic].y,
|
corner[ic].x, corner[ic].y,
|
||||||
side_style[ic - 1],
|
side_style[ic - 1],
|
||||||
&x, &y, &x2, &y2 );
|
&x, &y, &x2, &y2 );
|
||||||
if( ok )
|
if( ok )
|
||||||
{
|
{
|
||||||
xx[npts] = (int) x;
|
xx[npts] = (int) x;
|
||||||
|
@ -1393,16 +1428,16 @@ bool CPolyLine::TestPointInsideContour( int icont, int x, int y )
|
||||||
int ok;
|
int ok;
|
||||||
if( ic == istart )
|
if( ic == istart )
|
||||||
ok = FindLineSegmentIntersection( a, slope,
|
ok = FindLineSegmentIntersection( a, slope,
|
||||||
corner[iend].x, corner[iend].y,
|
corner[iend].x, corner[iend].y,
|
||||||
corner[istart].x, corner[istart].y,
|
corner[istart].x, corner[istart].y,
|
||||||
side_style[corner.size() - 1],
|
side_style[corner.size() - 1],
|
||||||
&x, &y, &x2, &y2 );
|
&x, &y, &x2, &y2 );
|
||||||
else
|
else
|
||||||
ok = FindLineSegmentIntersection( a, slope,
|
ok = FindLineSegmentIntersection( a, slope,
|
||||||
corner[ic - 1].x, corner[ic - 1].y,
|
corner[ic - 1].x, corner[ic - 1].y,
|
||||||
corner[ic].x, corner[ic].y,
|
corner[ic].x, corner[ic].y,
|
||||||
side_style[ic - 1],
|
side_style[ic - 1],
|
||||||
&x, &y, &x2, &y2 );
|
&x, &y, &x2, &y2 );
|
||||||
if( ok )
|
if( ok )
|
||||||
{
|
{
|
||||||
xx[npts] = (int) x;
|
xx[npts] = (int) x;
|
||||||
|
@ -1455,12 +1490,6 @@ void CPolyLine::Copy( CPolyLine* src )
|
||||||
// copy side styles
|
// copy side styles
|
||||||
for( unsigned ii = 0; ii < src->side_style.size(); ii++ )
|
for( unsigned ii = 0; ii < src->side_style.size(); ii++ )
|
||||||
side_style.push_back( src->side_style[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 + corner_x ), to_int( y + corner_y ), STRAIGHT, 0 );
|
||||||
AppendCorner( to_int( x + r * cos( th1 ) ), to_int( y + r * sin(
|
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(
|
AppendCorner( to_int( x + r * cos( th2 ) ), to_int( y + r * sin(
|
||||||
th2 ) ), ARC_CCW, 0 );
|
th2 ) ), ARC_CCW, 0 );
|
||||||
Close( STRAIGHT );
|
Close( STRAIGHT );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
// PolyLine.h ... definition of CPolyLine class
|
// PolyLine.h ... definition of CPolyLine class
|
||||||
|
|
||||||
//
|
//
|
||||||
// A polyline contains one or more contours, where each contour
|
// A polyline contains one or more contours, where each contour
|
||||||
// is defined by a list of corners and side-styles
|
// is defined by a list of corners and side-styles
|
||||||
|
@ -16,150 +17,214 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#define USE_GPC_POLY_LIB
|
#include "kbool/include/booleng.h"
|
||||||
//#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 "freepcbDisplayList.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:
|
public:
|
||||||
int xi, yi, xf, yf;
|
int left, right, top, bottom;
|
||||||
CSegment() {};
|
|
||||||
CSegment(int x0, int y0, int x1, int y1) {
|
|
||||||
xi = x0; yi = y0; xf = x1; yf = y1; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class CArc {
|
class CPoint
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
enum{ MAX_STEP = 50*25400 }; // max step is 20 mils
|
int x, y;
|
||||||
enum{ MIN_STEPS = 18 }; // min step is 5 degrees
|
public:
|
||||||
int style;
|
CPoint( void ) { x = y = 0; };
|
||||||
int xi, yi, xf, yf;
|
CPoint( int i, int j ) { x = i; y = j; };
|
||||||
int n_steps; // number of straight-line segments in gpc_poly
|
};
|
||||||
bool bFound;
|
|
||||||
|
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
|
class CPolyPt
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CPolyPt( int qx=0, int qy=0, bool qf=FALSE )
|
CPolyPt( int qx = 0, int qy = 0, bool qf = FALSE )
|
||||||
{ x=qx; y=qy; end_contour=qf; utility = 0; };
|
{ x = qx; y = qy; end_contour = qf; utility = 0; };
|
||||||
int x;
|
int x;
|
||||||
int y;
|
int y;
|
||||||
bool end_contour;
|
bool end_contour;
|
||||||
int utility;
|
int utility;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CPolyLine
|
class CPolyLine
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum { STRAIGHT, ARC_CW, ARC_CCW }; // side styles
|
enum { STRAIGHT, ARC_CW, ARC_CCW }; // side styles
|
||||||
enum { NO_HATCH, DIAGONAL_FULL, DIAGONAL_EDGE }; // hatch styles
|
enum { NO_HATCH, DIAGONAL_FULL, DIAGONAL_EDGE }; // hatch styles
|
||||||
|
|
||||||
// constructors/destructor
|
// constructors/destructor
|
||||||
CPolyLine();
|
CPolyLine();
|
||||||
~CPolyLine();
|
~CPolyLine();
|
||||||
|
|
||||||
// functions for modifying polyline
|
// functions for modifying polyline
|
||||||
void Start( int layer, int x, int y, int hatch );
|
void Start( int layer, int x, int y, int hatch );
|
||||||
void AppendCorner( int x, int y, int style = STRAIGHT, bool bDraw=TRUE );
|
void AppendCorner( int x, int y, int style = STRAIGHT, bool bDraw = TRUE );
|
||||||
void InsertCorner( int ic, int x, int y );
|
void InsertCorner( int ic, int x, int y );
|
||||||
void DeleteCorner( int ic, bool bDraw=TRUE );
|
void DeleteCorner( int ic, bool bDraw = TRUE );
|
||||||
void MoveCorner( int ic, int x, int y );
|
void MoveCorner( int ic, int x, int y );
|
||||||
void Close( int style = STRAIGHT, bool bDraw=TRUE );
|
void Close( int style = STRAIGHT, bool bDraw = TRUE );
|
||||||
void RemoveContour( int icont );
|
void RemoveContour( int icont );
|
||||||
void RemoveAllContours( void );
|
|
||||||
|
|
||||||
// drawing functions
|
void RemoveAllContours( void );
|
||||||
void Undraw();
|
|
||||||
void Draw( );
|
|
||||||
void Hatch();
|
|
||||||
void MoveOrigin( int x_off, int y_off );
|
|
||||||
|
|
||||||
// misc. functions
|
// drawing functions
|
||||||
CRect GetBounds();
|
void Undraw();
|
||||||
CRect GetCornerBounds();
|
void Draw();
|
||||||
CRect GetCornerBounds( int icont );
|
void Hatch();
|
||||||
void Copy( CPolyLine * src );
|
void MoveOrigin( int x_off, int y_off );
|
||||||
bool TestPointInside( int x, int y );
|
|
||||||
bool TestPointInsideContour( int icont, int x, int y );
|
// misc. functions
|
||||||
bool IsCutoutContour( int icont );
|
CRect GetBounds();
|
||||||
void AppendArc( int xi, int yi, int xf, int yf, int xc, int yc, int num );
|
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
|
// access functions
|
||||||
int GetLayer() { return m_layer;}
|
int GetLayer() { return m_layer; }
|
||||||
int GetNumCorners();
|
int GetNumCorners();
|
||||||
int GetNumSides();
|
int GetNumSides();
|
||||||
int GetClosed();
|
int GetClosed();
|
||||||
int GetNumContours();
|
int GetNumContours();
|
||||||
int GetContour( int ic );
|
int GetContour( int ic );
|
||||||
int GetContourStart( int icont );
|
int GetContourStart( int icont );
|
||||||
int GetContourEnd( int icont );
|
int GetContourEnd( int icont );
|
||||||
int GetContourSize( int icont );
|
int GetContourSize( int icont );
|
||||||
int GetX( int ic );
|
int GetX( int ic );
|
||||||
int GetY( int ic );
|
int GetY( int ic );
|
||||||
int GetEndContour( 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 );
|
|
||||||
|
|
||||||
int RestoreArcs( std::vector<CArc> * arc_array, std::vector<CPolyLine*> * pa=NULL );
|
int GetUtility( int ic ) { return corner[ic].utility; };
|
||||||
CPolyLine * MakePolylineForPad( int type, int x, int y, int w, int l, int r, int angle );
|
void SetUtility( int ic, int utility ) { corner[ic].utility = utility; };
|
||||||
void AddContourForPadClearance( int type, int x, int y, int w,
|
int GetSideStyle( int is );
|
||||||
int l, int r, int angle, int fill_clearance,
|
|
||||||
int hole_w, int hole_clearance, bool bThermal=FALSE, int spoke_w=0 );
|
|
||||||
|
|
||||||
int MakePolygonFromAreaOutlines( int icontour, std::vector<CArc> * arc_array );
|
int GetHatchStyle() { return m_HatchStyle; }
|
||||||
void FreePolygon();
|
void SetHatch( int hatch ) { Undraw(); m_HatchStyle = hatch; Draw(); };
|
||||||
int NormalizeAreaOutlines( std::vector<CPolyLine*> * pa=NULL, bool bRetainArcs=FALSE );
|
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
|
int RestoreArcs( std::vector<CArc> * arc_array, std::vector<CPolyLine*> * pa = NULL );
|
||||||
// GPC functions
|
CPolyLine* MakePolylineForPad( int type, int x, int y, int w, int l, int r, int angle );
|
||||||
int MakeGpcPoly( int icontour=0, std::vector<CArc> * arc_array=NULL );
|
void AddContourForPadClearance( int type,
|
||||||
void FreeGpcPoly();
|
int x,
|
||||||
gpc_polygon * GetGpcPoly(){ return m_gpc_poly; };
|
int y,
|
||||||
int NormalizeWithGpc( std::vector<CPolyLine*> * pa=NULL, bool bRetainArcs=FALSE );
|
int w,
|
||||||
#endif
|
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
|
// KBOOL functions
|
||||||
#ifdef USE_GPL_POLY_LIB
|
|
||||||
int MakePhpPoly();
|
/** Function AddPolygonsToBoolEng
|
||||||
void FreePhpPoly();
|
* and edges contours to a kbool engine, preparing a boolean op between polygons
|
||||||
void ClipPhpPolygon( int php_op, CPolyLine * poly );
|
* @param aStart_contour: starting contour number (-1 = all, 0 is the outlines of zone, > 1 = holes in zone
|
||||||
polygon * GetPhpPoly(){ return m_php_poly; };
|
* @param aEnd_contour: ending contour number (-1 = all after aStart_contour)
|
||||||
#endif
|
* @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:
|
private:
|
||||||
int m_layer; // layer to draw on
|
int m_layer; // layer to draw on
|
||||||
int m_Width; // lines width when drawing. Provided but not really used
|
int m_Width; // lines width when drawing. Provided but not really used
|
||||||
int utility;
|
int utility;
|
||||||
public:
|
public:
|
||||||
std::vector <CPolyPt> corner; // array of points for corners
|
std::vector <CPolyPt> corner; // array of points for corners
|
||||||
std::vector <int> side_style; // array of styles for sides
|
std::vector <int> side_style; // array of styles for sides
|
||||||
int m_HatchStyle; // hatch style, see enum above
|
int m_HatchStyle; // hatch style, see enum above
|
||||||
std::vector <CSegment> m_HatchLines; // hatch lines
|
std::vector <CSegment> m_HatchLines; // hatch lines
|
||||||
private:
|
private:
|
||||||
gpc_polygon * m_gpc_poly; // polygon in gpc format
|
Bool_Engine * m_Kbool_Poly_Engine; // polygons set in kbool engine data
|
||||||
polygon * m_php_poly;
|
bool bDrawn;
|
||||||
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= \
|
OBJECTS= \
|
||||||
GenericPolygonClipperLibrary.o \
|
|
||||||
php_polygon.o\
|
|
||||||
php_polygon_vertex.o\
|
|
||||||
PolyLine.o\
|
PolyLine.o\
|
||||||
math_for_graphics.o
|
math_for_graphics.o
|
||||||
|
|
||||||
GenericPolygonClipperLibrary.o: GenericPolygonClipperLibrary.cpp GenericPolygonClipperLibrary.h
|
PolyLine.o: PolyLine.cpp PolyLine.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
|
|
||||||
|
|
||||||
math_for_graphics.o: math_for_graphics.cpp math_for_graphics.h
|
math_for_graphics.o: math_for_graphics.cpp math_for_graphics.h
|
||||||
|
|
|
@ -10,9 +10,6 @@ using namespace std;
|
||||||
|
|
||||||
#include "fctsys.h"
|
#include "fctsys.h"
|
||||||
|
|
||||||
#include "defs-macros.h"
|
|
||||||
|
|
||||||
#include "PolyLine2Kicad.h"
|
|
||||||
#include "PolyLine.h"
|
#include "PolyLine.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -49,7 +46,7 @@ CPoint GetInflectionPoint( CPoint pi, CPoint pf, int mode )
|
||||||
{
|
{
|
||||||
int vert; // length of vertical line needed
|
int vert; // length of vertical line needed
|
||||||
if( dy > 0 )
|
if( dy > 0 )
|
||||||
vert = dy - abs(dx); // positive
|
vert = dy - abs(dx); // positive
|
||||||
else
|
else
|
||||||
vert = dy + abs(dx); // negative
|
vert = dy + abs(dx); // negative
|
||||||
if( mode == IM_90_45 )
|
if( mode == IM_90_45 )
|
||||||
|
@ -75,7 +72,7 @@ CPoint GetInflectionPoint( CPoint pi, CPoint pf, int mode )
|
||||||
{
|
{
|
||||||
int hor; // length of horizontal line needed
|
int hor; // length of horizontal line needed
|
||||||
if( dx > 0 )
|
if( dx > 0 )
|
||||||
hor = dx - abs(dy); // positive
|
hor = dx - abs(dy); // positive
|
||||||
else
|
else
|
||||||
hor = dx + abs(dy); // negative
|
hor = dx + abs(dy); // negative
|
||||||
if( mode == IM_90_45 )
|
if( mode == IM_90_45 )
|
||||||
|
@ -93,11 +90,11 @@ CPoint GetInflectionPoint( CPoint pi, CPoint pf, int mode )
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// function to rotate a point clockwise about another point
|
// function to rotate a point clockwise about another point
|
||||||
// currently, angle must be 0, 90, 180 or 270
|
// 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 )
|
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) ) )
|
if( dd<dist && ( (xf>xi && xp<xf && xp>xi) || (xf<xi && xp>xf && xp<xi) ) )
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0; // no hit
|
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 number of intersections found (max of 2)
|
||||||
// returns coords of intersections in arrays x[2], y[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,
|
int xi2, int yi2, int xf2, int yf2, int style2,
|
||||||
double x[], double y[] )
|
double x[], double y[] )
|
||||||
{
|
{
|
||||||
double xr[12], yr[12];
|
double xr[12], yr[12];
|
||||||
int iret = 0;
|
int iret = 0;
|
||||||
|
|
||||||
if( max(xi,xf) < min(xi2,xf2)
|
if( max(xi,xf) < min(xi2,xf2)
|
||||||
|| min(xi,xf) > max(xi2,xf2)
|
|| min(xi,xf) > max(xi2,xf2)
|
||||||
|| max(yi,yf) < min(yi2,yf2)
|
|| max(yi,yf) < min(yi2,yf2)
|
||||||
|| min(yi,yf) > max(yi2,yf2) )
|
|| min(yi,yf) > max(yi2,yf2) )
|
||||||
return 0;
|
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
|
// sets coords of intersections in *x1, *y1, *x2, *y2
|
||||||
// if no intersection, returns min distance in dist
|
// 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 * x1, double * y1, double * x2, double * y2,
|
||||||
double * dist )
|
double * dist )
|
||||||
{
|
{
|
||||||
|
@ -505,7 +502,7 @@ int FindLineSegmentIntersection( double a, double b, int xi, int yi, int xf, int
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// oblique line
|
// 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) )
|
|| (yy>yi && yy>yf) || (yy<yi && yy<yf) )
|
||||||
return 0;
|
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)
|
// 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)
|
// 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 x2i, int y2i, int x2f, int y2f,
|
||||||
int * x, int * y, double * d )
|
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->MoveTo( xxi, yyi );
|
||||||
pDC->LineTo( xxf, yyf );
|
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
|
// set endpoints so we can always draw counter-clockwise arc
|
||||||
if( shape == DL_ARC_CW )
|
if( shape == DL_ARC_CW )
|
||||||
{
|
{
|
||||||
xi = xxf;
|
xi = xxf;
|
||||||
yi = yyf;
|
yi = yyf;
|
||||||
xf = xxi;
|
xf = xxi;
|
||||||
yf = yyi;
|
yf = yyi;
|
||||||
}
|
}
|
||||||
else
|
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;
|
int h = -(yf-yi)*2;
|
||||||
if( !bMeta )
|
if( !bMeta )
|
||||||
pDC->Arc( xf, yi, xf+w, yi-h,
|
pDC->Arc( xf, yi, xf+w, yi-h,
|
||||||
xi, yi, xf, yf );
|
xi, yi, xf, yf );
|
||||||
else
|
else
|
||||||
pDC->Arc( xf, yi-h, xf+w, yi,
|
pDC->Arc( xf, yi-h, xf+w, yi,
|
||||||
xf, yf, xi, 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;
|
return;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
int h;
|
int h;
|
||||||
int v;
|
int v;
|
||||||
if( angle == 90 || angle == 270 )
|
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
|
// both segments are straight lines
|
||||||
int xx, yy;
|
int xx, yy;
|
||||||
double dd;
|
double dd;
|
||||||
TestForIntersectionOfStraightLineSegments( x1i, y1i, x1f, y1f,
|
TestForIntersectionOfStraightLineSegments( x1i, y1i, x1f, y1f,
|
||||||
x2i, y2i, x2f, y2f, &xx, &yy, &dd );
|
x2i, y2i, x2f, y2f, &xx, &yy, &dd );
|
||||||
int d = max( 0, (int)dd - w1/2 - w2/2 );
|
int d = max( 0, (int)dd - w1/2 - w2/2 );
|
||||||
if( x )
|
if( x )
|
||||||
|
@ -1266,7 +1263,7 @@ int GetClearanceBetweenSegments( int x1i, int y1i, int x1f, int y1f, int style1,
|
||||||
double xr[2];
|
double xr[2];
|
||||||
double yr[2];
|
double yr[2];
|
||||||
test = FindSegmentIntersections( x1i, y1i, x1f, y1f, style1, x2i, y2i, x2f, y2f, style2, xr, yr );
|
test = FindSegmentIntersections( x1i, y1i, x1f, y1f, style1, x2i, y2i, x2f, y2f, style2, xr, yr );
|
||||||
if( test )
|
if( test )
|
||||||
{
|
{
|
||||||
if( x )
|
if( x )
|
||||||
*x = (int) xr[0];
|
*x = (int) xr[0];
|
||||||
|
@ -1341,7 +1338,7 @@ int GetClearanceBetweenSegments( int x1i, int y1i, int x1f, int y1f, int style1,
|
||||||
int nsteps2 = NSTEPS;
|
int nsteps2 = NSTEPS;
|
||||||
double step = (s_start-s_end)/(nsteps-1);
|
double step = (s_start-s_end)/(nsteps-1);
|
||||||
double step2 = (s_start2-s_end2)/(nsteps2-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 )
|
&& (step2 * len2) > 0.1*NM_PER_MIL )
|
||||||
{
|
{
|
||||||
step = (s_start-s_end)/(nsteps-1);
|
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++ )
|
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;
|
ss[iss].xi, ss[iss].yi, ss[iss].xf, ss[iss].yf ) - c[ic].r;
|
||||||
dist = min(dist,d);
|
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++ )
|
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;
|
s[is].xi, s[is].yi, s[is].xf, s[is].yf ) - cc[icc].r;
|
||||||
dist = min(dist,d);
|
dist = min(dist,d);
|
||||||
}
|
}
|
||||||
|
@ -1577,8 +1574,8 @@ double Distance( int x1, int y1, int x2, int y2 )
|
||||||
// this finds approximate solutions
|
// this finds approximate solutions
|
||||||
// note: this works best if el2 is smaller than el1
|
// note: this works best if el2 is smaller than el1
|
||||||
//
|
//
|
||||||
int GetArcIntersections( EllipseKH * el1, EllipseKH * el2,
|
int GetArcIntersections( EllipseKH * el1, EllipseKH * el2,
|
||||||
double * x1, double * y1, double * x2, double * y2 )
|
double * x1, double * y1, double * x2, double * y2 )
|
||||||
{
|
{
|
||||||
if( el1->theta2 > el1->theta1 )
|
if( el1->theta2 > el1->theta1 )
|
||||||
wxASSERT(0);
|
wxASSERT(0);
|
||||||
|
@ -1591,7 +1588,7 @@ int GetArcIntersections( EllipseKH * el1, EllipseKH * el2,
|
||||||
double xscale = 1.0/el1->xrad;
|
double xscale = 1.0/el1->xrad;
|
||||||
double yscale = 1.0/el1->yrad;
|
double yscale = 1.0/el1->yrad;
|
||||||
// now transform params of second ellipse into reference frame
|
// 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
|
// scaled so the first ellipse is a circle of radius = 1.0
|
||||||
double xo = (el2->Center.X - el1->Center.X)*xscale;
|
double xo = (el2->Center.X - el1->Center.X)*xscale;
|
||||||
double yo = (el2->Center.Y - el1->Center.Y)*yscale;
|
double yo = (el2->Center.Y - el1->Center.Y)*yscale;
|
||||||
|
@ -1657,9 +1654,9 @@ int GetArcIntersections( EllipseKH * el1, EllipseKH * el2,
|
||||||
|
|
||||||
// this finds approximate solution
|
// this finds approximate solution
|
||||||
//
|
//
|
||||||
//double GetSegmentClearance( EllipseKH * el1, EllipseKH * el2,
|
//double GetSegmentClearance( EllipseKH * el1, EllipseKH * el2,
|
||||||
double GetArcClearance( EllipseKH * el1, EllipseKH * el2,
|
double GetArcClearance( EllipseKH * el1, EllipseKH * el2,
|
||||||
double * x1, double * y1 )
|
double * x1, double * y1 )
|
||||||
{
|
{
|
||||||
const int NSTEPS = 32;
|
const int NSTEPS = 32;
|
||||||
|
|
||||||
|
@ -1680,7 +1677,7 @@ double GetArcClearance( EllipseKH * el1, EllipseKH * el2,
|
||||||
int nsteps2 = NSTEPS;
|
int nsteps2 = NSTEPS;
|
||||||
double step = (th_start-th_end)/(nsteps-1);
|
double step = (th_start-th_end)/(nsteps-1);
|
||||||
double step2 = (th_start2-th_end2)/(nsteps2-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 )
|
&& (step2 * max(el2->xrad, el2->yrad)) > 1.0*NM_PER_MIL )
|
||||||
{
|
{
|
||||||
step = (th_start-th_end)/(nsteps-1);
|
step = (th_start-th_end)/(nsteps-1);
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
// math stuff for graphics, from FreePCB
|
// math stuff for graphics, from FreePCB
|
||||||
|
|
||||||
|
#ifndef abs
|
||||||
|
#define abs(x) (((x) >=0) ? (x) : (-(x)))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
typedef struct PointTag
|
typedef struct PointTag
|
||||||
{
|
{
|
||||||
double X,Y;
|
double X,Y;
|
||||||
|
@ -11,7 +16,7 @@ typedef struct EllipseTag
|
||||||
// double MaxRad,MinRad; /* major and minor axis */
|
// double MaxRad,MinRad; /* major and minor axis */
|
||||||
// double Phi; /* major axis rotation */
|
// double Phi; /* major axis rotation */
|
||||||
double xrad, yrad; // radii on x and y
|
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;
|
} EllipseKH;
|
||||||
|
|
||||||
const CPoint zero(0,0);
|
const CPoint zero(0,0);
|
||||||
|
@ -25,7 +30,7 @@ public:
|
||||||
y = yy;
|
y = yy;
|
||||||
r = rr;
|
r = rr;
|
||||||
};
|
};
|
||||||
int x, y, r;
|
int x, y, r;
|
||||||
};
|
};
|
||||||
|
|
||||||
class my_rect {
|
class my_rect {
|
||||||
|
@ -38,10 +43,10 @@ public:
|
||||||
ylo = min(yi,yf);
|
ylo = min(yi,yf);
|
||||||
yhi = max(yi,yf);
|
yhi = max(yi,yf);
|
||||||
};
|
};
|
||||||
int xlo, ylo, xhi, yhi;
|
int xlo, ylo, xhi, yhi;
|
||||||
};
|
};
|
||||||
|
|
||||||
class my_seg {
|
class my_seg {
|
||||||
public:
|
public:
|
||||||
my_seg(){};
|
my_seg(){};
|
||||||
my_seg( int xxi, int yyi, int xxf, int yyf )
|
my_seg( int xxi, int yyi, int xxf, int yyf )
|
||||||
|
@ -51,27 +56,27 @@ public:
|
||||||
xf = xxf;
|
xf = xxf;
|
||||||
yf = yyf;
|
yf = yyf;
|
||||||
};
|
};
|
||||||
int xi, yi, xf, yf;
|
int xi, yi, xf, yf;
|
||||||
};
|
};
|
||||||
|
|
||||||
// math stuff for graphics
|
// math stuff for graphics
|
||||||
#if 0
|
#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
|
#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 RotatePoint( CPoint *p, int angle, CPoint org );
|
||||||
void RotateRect( CRect *r, 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 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 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 );
|
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,
|
int xi2, int yi2, int xf2, int yf2, int style2,
|
||||||
double x[]=NULL, double y[]=NULL );
|
double x[]=NULL, double y[]=NULL );
|
||||||
BOOL FindLineEllipseIntersections( double a, double b, double c, double d, double *x1, double *x2 );
|
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 FindVerticalLineEllipseIntersections( double a, double b, double x, double *y1, double *y2 );
|
||||||
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 x2i, int y2i, int x2f, int y2f,
|
||||||
int * x=NULL, int * y=NULL, double * dist=NULL );
|
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,
|
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 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 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 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 radius, int angle );
|
||||||
int GetClearanceBetweenSegments( int x1i, int y1i, int x1f, int y1f, int style1, int w1,
|
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,
|
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 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 );
|
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 );
|
double Distance( int x1, int y1, int x2, int y2 );
|
||||||
int GetArcIntersections( EllipseKH * el1, EllipseKH * el2,
|
int GetArcIntersections( EllipseKH * el1, EllipseKH * el2,
|
||||||
double * x1=NULL, double * y1=NULL,
|
double * x1=NULL, double * y1=NULL,
|
||||||
double * x2=NULL, double * y2=NULL );
|
double * x2=NULL, double * y2=NULL );
|
||||||
CPoint GetInflectionPoint( CPoint pi, CPoint pf, int mode );
|
CPoint GetInflectionPoint( CPoint pi, CPoint pf, int mode );
|
||||||
|
|
||||||
// quicksort (2-way or 3-way)
|
// 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
|
|
3
todo.txt
3
todo.txt
|
@ -26,9 +26,6 @@ Need to do this using DialogBlocks.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
** Switch to a free polygon library.
|
|
||||||
|
|
||||||
|
|
||||||
2008-Feb-8 Assigned To: Jean-Pierre, per his email
|
2008-Feb-8 Assigned To: Jean-Pierre, per his email
|
||||||
asked by: Dick Hollenbeck
|
asked by: Dick Hollenbeck
|
||||||
================================================================================
|
================================================================================
|
||||||
|
|
Loading…
Reference in New Issue