Browse Source
removed GPC library due to its unacceptable license. Using the great and powerfull kbool library insteed
pull/1/head
removed GPC library due to its unacceptable license. Using the great and powerfull kbool library insteed
pull/1/head
75 changed files with 16715 additions and 6747 deletions
-
1CMakeLists.txt
-
91bitmaps/makefile.include
-
8change_log.txt
-
2common/basicframe.cpp
-
106common/edamenu.cpp
-
75common/infospgm.cpp
-
2cvpcb/CMakeLists.txt
-
8cvpcb/makefile.include
-
2gerbview/CMakeLists.txt
-
2include/build_version.h
-
206include/common.h
-
2include/wxPcbStruct.h
-
BINinternat/fr/kicad.mo
-
3639internat/fr/kicad.po
-
28kicad/treeprj_frame.cpp
-
2makefile.g95
-
2pcbnew/CMakeLists.txt
-
5pcbnew/makefile.include
-
16pcbnew/onrightclick.cpp
-
19pcbnew/pcbframe.cpp
-
263pcbnew/zones_test_and_combine_areas.cpp
-
3polygon/CMakeLists.txt
-
2479polygon/GenericPolygonClipperLibrary.cpp
-
133polygon/GenericPolygonClipperLibrary.h
-
BINpolygon/GenericPolygonClipperLibrary.odt
-
123polygon/GenericPolygonClipperLibraryVERSIONS.TXT
-
591polygon/PolyLine.cpp
-
307polygon/PolyLine.h
-
37polygon/PolyLine2Kicad.h
-
39polygon/defs-macros.h
-
4polygon/kbool/CMakeLists.txt
-
2378polygon/kbool/include/_dl_itr.cpp
-
405polygon/kbool/include/_dl_itr.h
-
269polygon/kbool/include/_lnk_itr.cpp
-
163polygon/kbool/include/_lnk_itr.h
-
540polygon/kbool/include/booleng.h
-
211polygon/kbool/include/graph.h
-
69polygon/kbool/include/graphlst.h
-
15polygon/kbool/include/kboolmod.h
-
111polygon/kbool/include/line.h
-
234polygon/kbool/include/link.h
-
64polygon/kbool/include/lpoint.h
-
89polygon/kbool/include/node.h
-
82polygon/kbool/include/record.h
-
62polygon/kbool/include/scanbeam.h
-
9polygon/kbool/include/valuesvc.h
-
10polygon/kbool/infos_and_license.txt
-
11polygon/kbool/samples/boolonly/CMakeLists.txt
-
368polygon/kbool/samples/boolonly/boolonly.cpp
-
32polygon/kbool/samples/boolonly/boolonly.h
-
0polygon/kbool/samples/boolonly/boolonly.rc
-
21polygon/kbool/src/CMakeLists.txt
-
608polygon/kbool/src/booleng.cpp
-
2631polygon/kbool/src/graph.cpp
-
396polygon/kbool/src/graphlst.cpp
-
38polygon/kbool/src/instonly.cpp
-
1476polygon/kbool/src/line.cpp
-
721polygon/kbool/src/link.cpp
-
203polygon/kbool/src/lpoint.cpp
-
16polygon/kbool/src/makefile.g95
-
16polygon/kbool/src/makefile.gtk
-
10polygon/kbool/src/makefile.include
-
16polygon/kbool/src/makefile.macosx
-
612polygon/kbool/src/node.cpp
-
357polygon/kbool/src/record.cpp
-
1374polygon/kbool/src/scanbeam.cpp
-
17polygon/links.txt
-
9polygon/makefile.include
-
59polygon/math_for_graphics.cpp
-
39polygon/math_for_graphics.h
-
1226polygon/php_polygon.cpp
-
72polygon/php_polygon.h
-
144polygon/php_polygon_vertex.cpp
-
81polygon/php_polygon_vertex.h
-
3todo.txt
@ -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); |
|||
} |
|||
|
|||
3639
internat/fr/kicad.po
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -1,8 +1,5 @@ |
|||
set(POLYGON_SRCS |
|||
GenericPolygonClipperLibrary.cpp |
|||
math_for_graphics.cpp |
|||
php_polygon.cpp |
|||
php_polygon_vertex.cpp |
|||
PolyLine.cpp) |
|||
|
|||
add_library(polygon ${POLYGON_SRCS}) |
|||
2479
polygon/GenericPolygonClipperLibrary.cpp
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -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 |
|||
=========================================================================== |
|||
*/ |
|||
@ -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,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 ) |
|||
|
|||
2378
polygon/kbool/include/_dl_itr.cpp
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -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); |
|||
} |
|||
2631
polygon/kbool/src/graph.cpp
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -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
|
|||
1476
polygon/kbool/src/line.cpp
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -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; |
|||
} |
|||
|
|||
|
|||
1374
polygon/kbool/src/scanbeam.cpp
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -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) |
|||
1226
polygon/php_polygon.cpp
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -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 |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue