diff --git a/bitmaps/makefile.g95 b/bitmaps/makefile.g95 index 5d903039c0..15d9cff467 100644 --- a/bitmaps/makefile.g95 +++ b/bitmaps/makefile.g95 @@ -8,3 +8,7 @@ include makefile.include libbitmaps.a: $(OBJECTS) ar ruv $@ $(OBJECTS) ranlib $@ + +clean: + rm -f *.o + rm -f *.a diff --git a/change_log.txt b/change_log.txt index 38ef9c23a1..3cfc9fc3ae 100644 --- a/change_log.txt +++ b/change_log.txt @@ -6,6 +6,17 @@ Please add newer entries at the top, list the date and your name with email address. +2008-Nov-14 UPDATE Jean-Pierre Charras +================================================================================ +kbool: + Using the last version (1.9) of kbool, downloaded from the wxArt2D project site + (see www.wxart2d.org) + But the version 1.8 bug still is here. + So using the workaround remains mandatory. + (this is not a problem because thermal shapes are better...) + + + 2008-Nov-14 UPDATE Dick Hollenbeck ================================================================================ +gerview diff --git a/include/build_version.h b/include/build_version.h index 2b7736c5b6..5b1a083436 100644 --- a/include/build_version.h +++ b/include/build_version.h @@ -9,7 +9,7 @@ COMMON_GLOBL wxString g_BuildVersion # include "config.h" (wxT(KICAD_SVN_VERSION)) # else - (wxT("(20081106-unstable)")) /* main program version */ + (wxT("(20081114-unstable)")) /* main program version */ # endif #endif ; @@ -20,7 +20,7 @@ COMMON_GLOBL wxString g_BuildAboutVersion # include "config.h" (wxT(KICAD_ABOUT_VERSION)) # else - (wxT("(20081106-unstable)")) /* svn date & rev (normally overridden) */ + (wxT("(20081114-unstable)")) /* svn date & rev (normally overridden) */ # endif #endif ; diff --git a/pcbnew/dialog_copper_zones.cpp b/pcbnew/dialog_copper_zones.cpp index 63a2fa4849..8e059bdaba 100644 --- a/pcbnew/dialog_copper_zones.cpp +++ b/pcbnew/dialog_copper_zones.cpp @@ -70,8 +70,8 @@ void dialog_copper_zone::OnInitDialog( wxInitDialogEvent& event ) m_GridCtrl->SetLabel( msg ); msg = ReturnStringFromValue( g_UnitMetric, - m_Zone_Setting->m_ZoneClearance, - m_Parent->m_InternalUnits ); + m_Zone_Setting->m_ZoneClearance, + m_Parent->m_InternalUnits ); m_ZoneClearanceCtrl->SetValue( msg ); if( g_Zone_45_Only ) @@ -85,8 +85,8 @@ void dialog_copper_zone::OnInitDialog( wxInitDialogEvent& event ) for( unsigned ii = 0; ii < 4; ii++ ) { msg = ReturnStringFromValue( g_UnitMetric, - GridList[ii], - m_Parent->m_InternalUnits ); + GridList[ii], + m_Parent->m_InternalUnits ); m_GridCtrl->SetString( ii, msg ); if( grid_routing == GridList[ii] ) selection = ii; @@ -98,8 +98,8 @@ void dialog_copper_zone::OnInitDialog( wxInitDialogEvent& event ) m_GridCtrl->SetSelection( selection ); msg = ReturnStringFromValue( g_UnitMetric, - m_Zone_Setting->m_ZoneClearance, - m_Parent->m_InternalUnits ); + m_Zone_Setting->m_ZoneClearance, + m_Parent->m_InternalUnits ); m_ZoneClearanceCtrl->SetValue( msg ); switch( m_Zone_Setting->m_Zone_Pad_Options ) @@ -135,11 +135,11 @@ void dialog_copper_zone::OnInitDialog( wxInitDialogEvent& event ) AddUnitSymbol( *m_AntipadSizeText, g_UnitMetric ); AddUnitSymbol( *m_CopperBridgeWidthText, g_UnitMetric ); PutValueInLocalUnits( *m_AntipadSizeValue, - m_Zone_Setting->m_ThermalReliefGapValue, - PCB_INTERNAL_UNIT ); + m_Zone_Setting->m_ThermalReliefGapValue, + PCB_INTERNAL_UNIT ); PutValueInLocalUnits( *m_CopperWidthValue, - m_Zone_Setting->m_ThermalReliefCopperBridgeValue, - PCB_INTERNAL_UNIT ); + m_Zone_Setting->m_ThermalReliefCopperBridgeValue, + PCB_INTERNAL_UNIT ); switch( m_Zone_Setting->m_Zone_HatchingStyle ) { @@ -189,8 +189,10 @@ void dialog_copper_zone::OnInitDialog( wxInitDialogEvent& event ) m_NetNameFilter->SetValue( NetNameFilter ); wxArrayString ListNetName; - m_Parent->m_Pcb->ReturnSortedNetnamesList( ListNetName, - m_NetSorting == 0 ? BOARD::ALPHA_SORT : BOARD::PAD_CNT_SORT ); + m_Parent->m_Pcb->ReturnSortedNetnamesList( + ListNetName, + m_NetSorting == + 0 ? BOARD::ALPHA_SORT : BOARD::PAD_CNT_SORT ); if( m_NetSorting != 0 ) { @@ -287,7 +289,7 @@ bool dialog_copper_zone::AcceptOptions( bool aPromptForErrors, bool aUseExportab if( m_Parent->m_Parent->m_EDA_Config ) { m_Parent->m_Parent->m_EDA_Config->Write( ZONE_NET_OUTLINES_HATCH_OPTION_KEY, - (long) m_Zone_Setting->m_Zone_HatchingStyle ); + (long) m_Zone_Setting->m_Zone_HatchingStyle ); } switch( m_GridCtrl->GetSelection() ) @@ -313,7 +315,7 @@ bool dialog_copper_zone::AcceptOptions( bool aPromptForErrors, bool aUseExportab m_Zone_Setting->m_GridFillValue = 0; #if 0 // I hope this feature works fine ( JP Charras) DisplayInfo( this, wxT( - "You are using No grid for filling zones\nThis is currently in development and for tests only.\n Do not use for production" ) ); + "You are using No grid for filling zones\nThis is currently in development and for tests only.\n Do not use for production" ) ); #endif break; } @@ -329,15 +331,17 @@ bool dialog_copper_zone::AcceptOptions( bool aPromptForErrors, bool aUseExportab m_Zone_Setting->m_FilledAreasShowMode = m_ShowFilledAreasInSketchOpt->IsChecked() ? 1 : 0; m_Zone_Setting->m_ThermalReliefGapValue = ReturnValueFromTextCtrl( *m_AntipadSizeValue, - PCB_INTERNAL_UNIT ); + PCB_INTERNAL_UNIT ); m_Zone_Setting->m_ThermalReliefCopperBridgeValue = ReturnValueFromTextCtrl( *m_CopperWidthValue, PCB_INTERNAL_UNIT ); m_Parent->m_Parent->m_EDA_Config->Write( ZONE_THERMAL_RELIEF_GAP_STRING_KEY, - (long) m_Zone_Setting->m_ThermalReliefGapValue ); - m_Parent->m_Parent->m_EDA_Config->Write( ZONE_THERMAL_RELIEF_COPPER_WIDTH_STRING_KEY, - (long) m_Zone_Setting->m_ThermalReliefCopperBridgeValue ); + (long) m_Zone_Setting->m_ThermalReliefGapValue ); + m_Parent->m_Parent->m_EDA_Config->Write( + ZONE_THERMAL_RELIEF_COPPER_WIDTH_STRING_KEY, + (long) m_Zone_Setting-> + m_ThermalReliefCopperBridgeValue ); // If we use only exportable to others zones parameters, exit here: if( aUseExportableSetupOnly ) @@ -388,8 +392,10 @@ void dialog_copper_zone::OnNetSortingOptionSelected( wxCommandEvent& event ) wxArrayString ListNetName; m_NetSorting = m_NetSortingOption->GetSelection(); - m_Parent->m_Pcb->ReturnSortedNetnamesList( ListNetName, - m_NetSorting == 0 ? BOARD::ALPHA_SORT : BOARD::PAD_CNT_SORT ); + m_Parent->m_Pcb->ReturnSortedNetnamesList( + ListNetName, + m_NetSorting == + 0 ? BOARD::ALPHA_SORT : BOARD::PAD_CNT_SORT ); if( m_NetSorting != 0 ) { wxString Filter = m_NetNameFilter->GetValue(); @@ -408,7 +414,7 @@ void dialog_copper_zone::OnNetSortingOptionSelected( wxCommandEvent& event ) { m_Parent->m_Parent->m_EDA_Config->Write( ZONE_NET_SORT_OPTION_KEY, (long) m_NetSorting ); m_Parent->m_Parent->m_EDA_Config->Write( ZONE_NET_FILTER_STRING_KEY, - m_NetNameFilter->GetValue() ); + m_NetNameFilter->GetValue() ); } // Select and isplay current zone net name in listbox: @@ -448,12 +454,14 @@ void dialog_copper_zone::ExportSetupToOtherCopperZones( wxCommandEvent& event ) if( !AcceptOptions( true, true ) ) return; - // Export to others zones: + // Export settings ( but layer ) to others zones: BOARD* pcb = m_Parent->m_Pcb; for( int ii = 0; ii < pcb->GetAreaCount(); ii++ ) { ZONE_CONTAINER* zone = pcb->GetArea( ii ); + int zone_layer = zone->GetLayer(); m_Zone_Setting->ExportSetting( *zone ); + zone->SetLayer( zone_layer ); m_Parent->GetScreen()->SetModify(); } } diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index 6d17001471..3b69ffe345 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -12,7 +12,7 @@ #include "protos.h" #include "id.h" #include "drc_stuff.h" -#include "kbool/include/booleng.h" +#include "kbool/include/kbool/booleng.h" /*******************************/ /* class WinEDA_PcbFrame */ diff --git a/pcbnew/zones_convert_brd_items_to_polygons.cpp b/pcbnew/zones_convert_brd_items_to_polygons.cpp index ee95fa5bd7..ad92fd21db 100644 --- a/pcbnew/zones_convert_brd_items_to_polygons.cpp +++ b/pcbnew/zones_convert_brd_items_to_polygons.cpp @@ -464,7 +464,7 @@ void AddThermalReliefPadPolygon( Bool_Engine* aBooleng, // Now, add the 4 holes ( each is the pattern, rotated by 0, 90, 180 and 270 deg // WARNING: problems with kbool if angle = 0 (in fact when angle < 200): // bad filled polygon on some cases, when pads are on a same vertical line - // this seems a bug in kbool polygon + // this seems a bug in kbool polygon (exists in 1.9 kbool version) // angle = 450 (45.0 degrees orientation) seems work fine. // angle = 0 with thermal shapes without angle < 90 deg seems works fine also angle = 0; diff --git a/polygon/PolyLine.h b/polygon/PolyLine.h index 29902cadf7..75e216cdb2 100644 --- a/polygon/PolyLine.h +++ b/polygon/PolyLine.h @@ -17,7 +17,7 @@ #include -#include "kbool/include/booleng.h" +#include "kbool/include/kbool/booleng.h" #include "pad_shapes.h" // inflection modes for DS_LINE and DS_LINE_VERTEX, used in math_for_graphics.cpp diff --git a/polygon/kbool/CMakeLists.txt b/polygon/kbool/CMakeLists.txt index 975d31fc25..bd20e13cf9 100644 --- a/polygon/kbool/CMakeLists.txt +++ b/polygon/kbool/CMakeLists.txt @@ -1,3 +1,3 @@ project(kbool) -subdirs(src samples) +subdirs(src) diff --git a/polygon/kbool/include/_dl_itr.h b/polygon/kbool/include/_dl_itr.h deleted file mode 100644 index 2908d9b97f..0000000000 --- a/polygon/kbool/include/_dl_itr.h +++ /dev/null @@ -1,405 +0,0 @@ -/*! \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 -#include "../include/booleng.h" - -#ifndef _STATUS_ENUM -#define _STATUS_ENUM - //!_root -#define HD _list->_root->_next -#define TL _list->_root->_prev -#define NB _list->_nbitems - -template class DL_List; -template class DL_Iter; -template class DL_SortIter; - -//! Template class DL_Node -template class DL_Node -{ - friend class DL_List; - friend class DL_Iter; - friend class DL_SortIter; - - //!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 DL_List -{ - friend class DL_Iter; - friend class DL_SortIter; - - 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* insend( Dtype n ); - - //!insert the object given at the begin of the list, before head - DL_Node* 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* 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* _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 DL_Iter -{ - public: - //!Construct an iterator object for a given list of type Dtype - DL_Iter(DL_List* 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* 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* insend(Dtype n); - - //!insert before head item - DL_Node* insbegin(Dtype n); - - //!insert before current iterator position - DL_Node* insbefore(Dtype n); - - //!insert after current iterator position - DL_Node* insafter(Dtype n); - - //!to move all objects in a list to the list of the iterator. - void takeover(DL_List* 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*); - - //!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* 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 *RT1,int n); - - //!sort list with mergesort - void mergetwo(int (*fcmp)(Dtype,Dtype), DL_Node *RT1,DL_Node *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 *_list; - - //!the current position of the iterator - DL_Node *_current; -}; - - -//! template class DL_StackIter class for stack iterator on DL_List -template -class DL_StackIter :protected DL_Iter -{ - public: - //!Constructor of stack iterator for given list - DL_StackIter(DL_List *); - //!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 DL_SortIter :public DL_Iter -{ - public: - //!Constructor of sort iterator for given list and sort function - DL_SortIter(DL_List* 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*){sortitererror();}; - //!Not allowed - void takeover (DL_Iter*){sortitererror();}; - //!Not allowed - void takeover (DL_Iter* 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 diff --git a/polygon/kbool/include/_lnk_itr.cpp b/polygon/kbool/include/_lnk_itr.cpp deleted file mode 100644 index 716de3093a..0000000000 --- a/polygon/kbool/include/_lnk_itr.cpp +++ /dev/null @@ -1,269 +0,0 @@ -/*! \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 "../include/_lnk_itr.h" -#endif - -//======================================================================= -// implementation class LinkBaseIter -//======================================================================= - -template -TDLI::TDLI(DL_List* newlist):DL_Iter(newlist) -{ -} - -template -TDLI::TDLI(DL_Iter* otheriter):DL_Iter(otheriter) -{ -} - -template -TDLI::TDLI():DL_Iter() -{ -} - -// destructor TDLI -template -TDLI::~TDLI() -{ -} - -template -void TDLI::delete_all() -{ - DL_Node* 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 -void TDLI::foreach_f(void (*fp) (Type* item) ) -{ - DL_Iter::foreach_f( (void (*)(void*))fp); //call fp for each item -} - -template -void TDLI::foreach_mf(void (Type::*mfp) ()) -{ - - DL_Node* 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 -void TDLI::takeover(DL_List* otherlist) -{ - DL_Iter::takeover( (DL_List*) otherlist); -} - -template -void TDLI::takeover(TDLI* otheriter) -{ - DL_Iter::takeover( (DL_Iter*) otheriter); -} - -template -void TDLI::takeover(TDLI* otheriter,int maxcount) -{ - DL_Iter::takeover( (DL_Iter*) otheriter,maxcount); -} - -// is item element of the list? -template -bool TDLI::has(Type* otheritem) -{ - return DL_Iter::has( (void*) otheritem); -} - -// goto to item -template -bool TDLI::toitem(Type* item) -{ - return DL_Iter::toitem( (void*) item); -} - -// get current item -template -Type* TDLI::item() -{ - return (Type*) DL_Iter::item(); -} - -template -void TDLI::insend(Type* newitem) -{ - DL_Iter::insend( (void*) newitem); -} - -template -void TDLI::insbegin(Type* newitem) -{ - DL_Iter::insbegin( (void*) newitem); -} - -template -void TDLI::insbefore(Type* newitem) -{ - DL_Iter::insbefore( (void*) newitem); -} - -template -void TDLI::insafter(Type* newitem) -{ - DL_Iter::insafter( (void*) newitem); -} - -template -void TDLI::insend_unsave(Type* newitem) -{ - short int iterbackup=_list->_iterlevel; - _list->_iterlevel=0; - DL_Iter::insend( (void*) newitem); - _list->_iterlevel=iterbackup; -} - -template -void TDLI::insbegin_unsave(Type* newitem) -{ - short int iterbackup=_list->_iterlevel; - _list->_iterlevel=0; - DL_Iter::insbegin( (void*) newitem); - _list->_iterlevel=iterbackup; -} - -template -void TDLI::insbefore_unsave(Type* newitem) -{ - short int iterbackup=_list->_iterlevel; - _list->_iterlevel=0; - DL_Iter::insbefore( (void*) newitem); - _list->_iterlevel=iterbackup; -} - -template -void TDLI::insafter_unsave(Type* newitem) -{ - short int iterbackup=_list->_iterlevel; - _list->_iterlevel=0; - DL_Iter::insafter( (void*) newitem); - _list->_iterlevel=iterbackup; -} - -template -void TDLI::mergesort(int (*f)(Type* a,Type* b)) -{ - DL_Iter::mergesort( (int (*)(void*,void*)) f); -} - -template -int TDLI::cocktailsort(int (*f)(Type* a,Type* b), bool (*f2)(Type* c,Type* d)) -{ - return DL_Iter::cocktailsort( (int (*)(void*,void*)) f,( bool(*)(void*,void*)) f2); -} - -template -TDLISort::TDLISort(DL_List* lista, int (*newfunc)(void*,void*)) - :DL_SortIter(lista, newfunc) -{ -} - -template -TDLISort::~TDLISort() -{ -} - -template -void TDLISort::delete_all() -{ - DL_Node* 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 -bool TDLISort::has(Type* otheritem) -{ - return DL_Iter::has( (void*) otheritem); -} - -// goto to item -template -bool TDLISort::toitem(Type* item) -{ - return DL_Iter::toitem( (void*) item); -} - -// get current item -template -Type* TDLISort::item() -{ - return (Type*) DL_Iter::item(); -} - -template -TDLIStack::TDLIStack(DL_List* newlist):DL_StackIter(newlist) -{ -} - -// destructor TDLI -template -TDLIStack::~TDLIStack() -{ -} - -// plaats nieuw item op stack -template -void TDLIStack::push(Type* newitem) -{ - DL_StackIter::push((Type*) newitem); -} - - -// haal bovenste item van stack -template -Type* TDLIStack::pop() -{ - return (Type*) DL_StackIter::pop(); -} - - diff --git a/polygon/kbool/include/_lnk_itr.h b/polygon/kbool/include/_lnk_itr.h deleted file mode 100644 index 85d01156aa..0000000000 --- a/polygon/kbool/include/_lnk_itr.h +++ /dev/null @@ -1,163 +0,0 @@ -/*! \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 -#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 that is type casted version of DL_Iter - \sa DL_Iter for further documentation -*/ -template class TDLI : public DL_Iter -{ - public: - //!constructor - /*! - \param list to iterate on. - */ - TDLI(DL_List* list); - - //!constructor - TDLI(DL_Iter* 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* 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 that is type casted version of DL_SortIter -// see also inhereted class DL_SortIter for further documentation -*/ -template class TDLISort : public DL_SortIter -{ - public: - - //!constructor givin a list and a sort function - TDLISort(DL_List* 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 that is type casted version of DL_StackIter - see also inhereted class DL_StackIter for further documentation -*/ -template class TDLIStack : public DL_StackIter -{ - public: - //constructor givin a list - TDLIStack(DL_List* list); - - ~TDLIStack(); - - void push(Type*); - Type* pop(); -}; - -#include"../include/_lnk_itr.cpp" - -#endif diff --git a/polygon/kbool/include/booleng.h b/polygon/kbool/include/booleng.h deleted file mode 100644 index ae4fcac2a7..0000000000 --- a/polygon/kbool/include/booleng.h +++ /dev/null @@ -1,544 +0,0 @@ -/*! \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 -#include - - -#ifdef A2DKBOOLMAKINGDLL -#define A2DKBOOLDLLEXP WXEXPORT -#define A2DKBOOLDLLEXP_DATA(type) WXEXPORT type -#define A2DKBOOLDLLEXP_CTORFN -#if 0 // Kicad does dot use wxWidgets lib when building the kbool library - // but uses wxWidgets. So WXUSINGDLL has no meaning here, but could be defined in makefiles - // but must not be used when building kbool -#elif defined(WXUSINGDLL) -#define A2DKBOOLDLLEXP WXIMPORT -#define A2DKBOOLDLLEXP_DATA(type) WXIMPORT type -#define A2DKBOOLDLLEXP_CTORFN -#endif -#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 - -//! 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 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* _linkiter; - - //! how many time run intersections fase. - unsigned int m_intersectionruns; - -}; - -#endif diff --git a/polygon/kbool/include/graph.h b/polygon/kbool/include/graph.h deleted file mode 100644 index 8f2332bb5b..0000000000 --- a/polygon/kbool/include/graph.h +++ /dev/null @@ -1,211 +0,0 @@ -/*! \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* _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* _linklist; - -}; - -#endif - - diff --git a/polygon/kbool/include/graphlst.h b/polygon/kbool/include/graphlst.h deleted file mode 100644 index fdec4029bc..0000000000 --- a/polygon/kbool/include/graphlst.h +++ /dev/null @@ -1,69 +0,0 @@ -/*! \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 -{ - 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 - diff --git a/polygon/kbool/include/_dl_itr.cpp b/polygon/kbool/include/kbool/_dl_itr.cpp similarity index 61% rename from polygon/kbool/include/_dl_itr.cpp rename to polygon/kbool/include/kbool/_dl_itr.cpp index 53f50151b6..894db9477e 100644 --- a/polygon/kbool/include/_dl_itr.cpp +++ b/polygon/kbool/include/kbool/_dl_itr.cpp @@ -1,4 +1,4 @@ -/*! \file kbool/include/kbool/_dl_itr.cpp +/*! \file kbool/_dl_itr.cpp \brief Double Linked list with Iterators on list \author Probably Klaas Holwerda @@ -6,15 +6,11 @@ Licence: wxWidgets Licence - RCS-ID: $Id: _dl_itr.cpp,v 1.1 2005/05/24 19:13:35 titato Exp $ + RCS-ID: $Id: _dl_itr.cpp,v 1.3 2006/12/13 21:43:33 titato Exp $ */ -#ifdef __GNUG__ -#pragma implementation -#endif - #ifdef __UNIX__ -#include "../include/_dl_itr.h" +#include "kbool/_dl_itr.h" #endif //======================================================================= @@ -34,8 +30,8 @@ Construct a node for a list object \param it Item the node will contain */ template -DL_Node::DL_Node(Dtype it) // + init nodeitem -:_item(it) +DL_Node::DL_Node( Dtype it ) // + init nodeitem + : _item( it ) {} /*! @@ -44,7 +40,7 @@ DL_Node::DL_Node(Dtype it) // + init nodeitem */ template DL_Node::DL_Node() -:_item(0) + : _item( 0 ) {} /*! @@ -52,8 +48,7 @@ Destruct a node object */ template DL_Node::~DL_Node() -{ -} +{} //======================================================================= @@ -73,16 +68,16 @@ Construct a node object \par Example: How to construct a list of type integer: \code - DL_List * a_list = new DL_List(); + DL_List * a_list = new DL_List(); \endcode */ template DL_List::DL_List() -:_nbitems(0), _iterlevel(0) + : _nbitems( 0 ), _iterlevel( 0 ) { - _root = new DL_Node(); - _root->_next=_root; - _root->_prev=_root; + _root = new DL_Node(); + _root->_next = _root; + _root->_prev = _root; } @@ -98,12 +93,12 @@ DL_List::DL_List() template DL_List::~DL_List() { - if (_iterlevel != 0) - throw Bool_Engine_Error("DL_List::~DL_List()\n_iterlevel > 0 ","list error", 0, 1); + if ( _iterlevel != 0 ) + throw Bool_Engine_Error( "DL_List::~DL_List()\n_iterlevel > 0 ", "list error", 0, 1 ); - remove_all(false); - delete _root; - _root=0;_nbitems=0; //reset memory used (no lost pointers) + remove_all( false ); + delete _root; + _root = 0;_nbitems = 0; //reset memory used (no lost pointers) } /*! @@ -121,23 +116,23 @@ Error("remove_all",ITER_GT_O); \param error code to generate a message for */ template -void DL_List::Error(const char* function,Lerror a_error) +void DL_List::Error( const char* function, Lerror a_error ) { - char buf[100]; - strcpy(buf,"DL_List::"); - strcat(buf,function); - switch (a_error) - { - case NO_MES: strcat(buf,""); break; - case EMPTY: strcat(buf,"list is empty"); break; - case ITER_GT_0: strcat(buf,"more then zero iter"); break; - case NO_LIST: strcat(buf,"no list attached"); break; - case SAME_LIST: strcat(buf,"same list not allowed"); break; - case AC_ITER_LIST_OTHER: strcat(buf,"iter not allowed on other list"); break; - default: strcat(buf,"unhandled error"); break; - } + char buf[100]; + strcpy( buf, "DL_List::" ); + strcat( buf, function ); + switch ( a_error ) + { + case NO_MES: strcat( buf, "" ); break; + case EMPTY: strcat( buf, "list is empty" ); break; + case ITER_GT_0: strcat( buf, "more then zero iter" ); break; + case NO_LIST: strcat( buf, "no list attached" ); break; + case SAME_LIST: strcat( buf, "same list not allowed" ); break; + case AC_ITER_LIST_OTHER: strcat( buf, "iter not allowed on other list" ); break; + default: strcat( buf, "unhandled error" ); break; + } - throw Bool_Engine_Error(buf,"list error", 0, 1); + throw Bool_Engine_Error( buf, "list error", 0, 1 ); } /*! @@ -157,7 +152,7 @@ DL_List _intlist; #create a list of integers template bool DL_List::empty() { - return(bool)(_nbitems==0); + return( bool )( _nbitems == 0 ); } /*! @@ -177,7 +172,7 @@ DL_List _intlist; #create a list of integers template int DL_List::count() { - return _nbitems; + return _nbitems; } /*! @@ -212,25 +207,25 @@ int DL_List::count() template void DL_List::remove_all( bool deleteObject ) { - if (_iterlevel > 0 ) - Error("remove_all()",ITER_GT_0); + if ( _iterlevel > 0 ) + Error( "remove_all()", ITER_GT_0 ); - Dtype* obj; + Dtype* obj; - DL_Node *node; - for (int i=0; i<_nbitems; i++) - { - node = _root->_next; - _root->_next = node->_next; - if ( deleteObject == true ) - { - obj=(Dtype*)(node->_item); - delete obj; - } - delete node; - } - _nbitems=0;_iterlevel=0; //reset memory used (no lost pointers) - _root->_prev=_root; + DL_Node *node; + for ( int i = 0; i < _nbitems; i++ ) + { + node = _root->_next; + _root->_next = node->_next; + if ( deleteObject == true ) + { + obj = ( Dtype* )( node->_item ); + delete obj; + } + delete node; + } + _nbitems = 0;_iterlevel = 0; //reset memory used (no lost pointers) + _root->_prev = _root; } /*! @@ -265,18 +260,18 @@ DL_List _intlist; #create a list of integers template void DL_List::removehead() { - if (_iterlevel > 0 ) - Error("removehead()",ITER_GT_0); - if(_nbitems==0) - Error("removehead()",EMPTY); + if ( _iterlevel > 0 ) + Error( "removehead()", ITER_GT_0 ); + if( _nbitems == 0 ) + Error( "removehead()", EMPTY ); - DL_Node* node=_root->_next; + DL_Node* node = _root->_next; - node->_prev->_next = node->_next; // update forward link - node->_next->_prev = node->_prev; // update backward link + node->_prev->_next = node->_next; // update forward link + node->_next->_prev = node->_prev; // update backward link - _nbitems--; - delete node; // delete list node + _nbitems--; + delete node; // delete list node } @@ -308,18 +303,18 @@ DL_List _intlist; #create a list of integers template void DL_List::removetail() { - if (_iterlevel > 0) - Error("removetail()",ITER_GT_0); - if (_nbitems==0) - Error("removehead()",EMPTY); + if ( _iterlevel > 0 ) + Error( "removetail()", ITER_GT_0 ); + if ( _nbitems == 0 ) + Error( "removehead()", EMPTY ); - DL_Node* node=_root->_prev; + DL_Node* node = _root->_prev; - node->_prev->_next = node->_next; // update forward link - node->_next->_prev = node->_prev; // update backward link + node->_prev->_next = node->_next; // update forward link + node->_next->_prev = node->_prev; // update backward link - _nbitems--; - delete node; // delete list node + _nbitems--; + delete node; // delete list node } /*! @@ -334,7 +329,7 @@ This will save time, since the iterator does not have to be created. \par Example: too insert integer a at end of list \code - DL_List _intlist; #create a list of integers + DL_List _intlist; #create a list of integers int a=123; @@ -343,20 +338,20 @@ too insert integer a at end of list \param newitem an object for which the template list was generated */ template -DL_Node* DL_List::insend(Dtype newitem) +DL_Node* DL_List::insend( Dtype newitem ) { - if (_iterlevel > 0) - Error("insend()",ITER_GT_0); + if ( _iterlevel > 0 ) + Error( "insend()", ITER_GT_0 ); - DL_Node* newnode = new DL_Node(newitem); + DL_Node* newnode = new DL_Node( newitem ); - newnode ->_next = _root; - newnode ->_prev = _root->_prev; - _root->_prev->_next = newnode; - _root->_prev = newnode; + newnode ->_next = _root; + newnode ->_prev = _root->_prev; + _root->_prev->_next = newnode; + _root->_prev = newnode; + + _nbitems++; - _nbitems++; - return newnode; } @@ -373,7 +368,7 @@ This will save time, since the iterator does not have to be created. \par Example: too insert integer a at begin of list \code - DL_List _intlist; #create a list of integers + DL_List _intlist; #create a list of integers int a=123; @@ -382,19 +377,19 @@ too insert integer a at begin of list \param newitem an object for which the template list was generated */ template -DL_Node* DL_List::insbegin(Dtype newitem) +DL_Node* DL_List::insbegin( Dtype newitem ) { - if (_iterlevel > 0) - Error("insbegin()",ITER_GT_0); + if ( _iterlevel > 0 ) + Error( "insbegin()", ITER_GT_0 ); - DL_Node* newnode = new DL_Node(newitem); + DL_Node* newnode = new DL_Node( newitem ); - newnode ->_prev = _root; - newnode ->_next = _root->_next; - _root->_next->_prev = newnode; - _root->_next = newnode; + newnode ->_prev = _root; + newnode ->_next = _root->_next; + _root->_next->_prev = newnode; + _root->_next = newnode; - _nbitems++; + _nbitems++; return newnode; } @@ -405,7 +400,7 @@ get head item too insert integer a and b into list and make c be the value of b which is at head of list| \code - DL_List _intlist; #create a list of integers + DL_List _intlist; #create a list of integers int a=123; @@ -422,7 +417,7 @@ get head item template Dtype DL_List::headitem() { - return _root->_next->_item; + return _root->_next->_item; } /*! @@ -432,7 +427,7 @@ get tail item too insert integer a and b into list and make c be the value of b which is at the tail of list \code - DL_List _intlist; #create a list of integers + DL_List _intlist; #create a list of integers int a=123; @@ -448,7 +443,7 @@ get tail item template Dtype DL_List::tailitem() { - return _root->_prev->_item; + return _root->_prev->_item; } /*! @@ -459,31 +454,31 @@ Dtype DL_List::tailitem() * \param otherlist the list to take the items from */ template -void DL_List::takeover(DL_List* otherlist) +void DL_List::takeover( DL_List* otherlist ) { - if (otherlist==0) - Error("takeover(DL_List*)",NO_LIST); - // no iterators allowed on otherlist - if (otherlist->_iterlevel > 0) - Error("takeover(DL_List*)",AC_ITER_LIST_OTHER); - // otherlist not this list - else if (otherlist == this) - Error("takeover(DL_List*)",SAME_LIST); + if ( otherlist == 0 ) + Error( "takeover(DL_List*)", NO_LIST ); + // no iterators allowed on otherlist + if ( otherlist->_iterlevel > 0 ) + Error( "takeover(DL_List*)", AC_ITER_LIST_OTHER ); + // otherlist not this list + else if ( otherlist == this ) + Error( "takeover(DL_List*)", SAME_LIST ); - if (otherlist->_nbitems == 0) - return; + if ( otherlist->_nbitems == 0 ) + return; - //link other list into this list at the end - _root->_prev->_next=otherlist->_root->_next; - otherlist->_root->_next->_prev=_root->_prev; - otherlist->_root->_prev->_next=_root; - _root->_prev=otherlist->_root->_prev; + //link other list into this list at the end + _root->_prev->_next = otherlist->_root->_next; + otherlist->_root->_next->_prev = _root->_prev; + otherlist->_root->_prev->_next = _root; + _root->_prev = otherlist->_root->_prev; - //empty other list - _nbitems+=otherlist->_nbitems; - otherlist->_nbitems=0; - otherlist->_root->_next=otherlist->_root; - otherlist->_root->_prev=otherlist->_root; + //empty other list + _nbitems += otherlist->_nbitems; + otherlist->_nbitems = 0; + otherlist->_root->_next = otherlist->_root; + otherlist->_root->_prev = otherlist->_root; } //======================================================================= @@ -537,30 +532,30 @@ void DL_List::takeover(DL_List* otherlist) \param a_error: error code to generate a message for */ template -void DL_Iter::Error(const char* function,Lerror a_error) +void DL_Iter::Error( const char* function, Lerror a_error ) { - char buf[100]; - strcpy(buf,"DL_Iter::"); - strcat(buf,function); - switch (a_error) - { - case NO_MES: strcat(buf,""); break; - case NO_LIST: strcat(buf,"no list attached"); break; - case NO_LIST_OTHER: strcat(buf,"no list on other iter"); break; - case AC_ITER_LIST_OTHER: strcat(buf,"iter not allowed on other list"); break; - case SAME_LIST: strcat(buf,"same list not allowed"); break; - case NOT_SAME_LIST: strcat(buf,"must be same list"); break; - case ITER_GT_1: strcat(buf,"more then one iter"); break; - case ITER_HITROOT: strcat(buf,"iter at root"); break; - case NO_ITEM: strcat(buf,"no item at current"); break; - case NO_NEXT: strcat(buf,"no next after current"); break; - case NO_PREV: strcat(buf,"no prev before current"); break; - case EMPTY: strcat(buf,"list is empty"); break; - case NOT_ALLOW: strcat(buf,"not allowed"); break; - case ITER_NEG: strcat(buf,"to much iters deleted"); break; - default: strcat(buf,"unhandled error"); break; - } - throw Bool_Engine_Error(buf,"list error", 0, 1); + char buf[100]; + strcpy( buf, "DL_Iter::" ); + strcat( buf, function ); + switch ( a_error ) + { + case NO_MES: strcat( buf, "" ); break; + case NO_LIST: strcat( buf, "no list attached" ); break; + case NO_LIST_OTHER: strcat( buf, "no list on other iter" ); break; + case AC_ITER_LIST_OTHER: strcat( buf, "iter not allowed on other list" ); break; + case SAME_LIST: strcat( buf, "same list not allowed" ); break; + case NOT_SAME_LIST: strcat( buf, "must be same list" ); break; + case ITER_GT_1: strcat( buf, "more then one iter" ); break; + case ITER_HITROOT: strcat( buf, "iter at root" ); break; + case NO_ITEM: strcat( buf, "no item at current" ); break; + case NO_NEXT: strcat( buf, "no next after current" ); break; + case NO_PREV: strcat( buf, "no prev before current" ); break; + case EMPTY: strcat( buf, "list is empty" ); break; + case NOT_ALLOW: strcat( buf, "not allowed" ); break; + case ITER_NEG: strcat( buf, "to much iters deleted" ); break; + default: strcat( buf, "unhandled error" ); break; + } + throw Bool_Engine_Error( buf, "list error", 0, 1 ); } /*! @@ -576,10 +571,10 @@ void DL_Iter::Error(const char* function,Lerror a_error) \param newlist: list for the iterator */ template -DL_Iter:: DL_Iter(DL_List* newlist) -:_list(newlist), _current(RT) +DL_Iter:: DL_Iter( DL_List* newlist ) + : _list( newlist ), _current( RT ) { - _list->_iterlevel++; // add 1 to DL_Iters on list + _list->_iterlevel++; // add 1 to DL_Iters on list } /*! @@ -589,7 +584,7 @@ tcarg: class | Dtype | list item object \par Example How to construct a list of type integer and a second iterator for it:| \code - DL_List* IntegerList; + DL_List* IntegerList; IntegerList = new DL_List(); @@ -600,13 +595,13 @@ tcarg: class | Dtype | list item object \param otheriter other iterator on same list */ template -DL_Iter:: DL_Iter(DL_Iter* otheriter) +DL_Iter:: DL_Iter( DL_Iter* otheriter ) { - if (otheriter->_current==0) - Error("DL_Iter(otheriter)",NO_LIST_OTHER); - _list=otheriter->_list; - _list->_iterlevel++; // add 1 to DL_Iters on List - _current=otheriter->_current; + if ( otheriter->_current == 0 ) + Error( "DL_Iter(otheriter)", NO_LIST_OTHER ); + _list = otheriter->_list; + _list->_iterlevel++; // add 1 to DL_Iters on List + _current = otheriter->_current; } /*! @@ -635,9 +630,8 @@ tcarg: class | Dtype | list item object */ template DL_Iter:: DL_Iter() -:_list(0), _current(0) -{ -} + : _list( 0 ), _current( 0 ) +{} /*! destruct an iterator for a list of a given type. @@ -645,11 +639,11 @@ destruct an iterator for a list of a given type. template DL_Iter::~DL_Iter() { - if (_current==0) - return; - _list->_iterlevel--; // decrease iterators - if (_list->_iterlevel < 0) - Error("~DL_Iter()",ITER_NEG); + if ( _current == 0 ) + return; + _list->_iterlevel--; // decrease iterators + if ( _list->_iterlevel < 0 ) + Error( "~DL_Iter()", ITER_NEG ); } /*! @@ -675,13 +669,13 @@ a_iter.Detach(); \param newlist the list to attached the iterator to */ template -void DL_Iter::Attach(DL_List* newlist) +void DL_Iter::Attach( DL_List* newlist ) { - if (_current!=0) - Error("Attach(list)",NOT_ALLOW); - _list=newlist; - _current=HD; - _list->_iterlevel++; // add 1 to DL_Iters on list + if ( _current != 0 ) + Error( "Attach(list)", NOT_ALLOW ); + _list = newlist; + _current = HD; + _list->_iterlevel++; // add 1 to DL_Iters on list } /*! @@ -709,23 +703,23 @@ a_iter.Detach(); template void DL_Iter::Detach() { - if (_current==0) - Error("Attach()",NO_LIST); - _list->_iterlevel--; // subtract 1 from DL_Iters on list - _list=0; - _current=0; + if ( _current == 0 ) + Error( "Attach()", NO_LIST ); + _list->_iterlevel--; // subtract 1 from DL_Iters on list + _list = 0; + _current = 0; } /* // copy pointers to items from other list template void DL_Iter::merge(DL_List* otherlist) { - DL_Node* node=otherlist->HD; //can be 0 if empty - for(int i=0; iNB; i++) - { - insend(node->new_item); // insert item at end - node=node->_next; // next item of otherlist - } + DL_Node* node=otherlist->HD; //can be 0 if empty + for(int i=0; iNB; i++) + { + insend(node->new_item); // insert item at end + node=node->_next; // next item of otherlist + } } */ /* @@ -733,7 +727,7 @@ template void DL_Iter::merge(DL_List* otherlist) template void DL_Iter::foreach_mf(void (Dtype::*mfp)()) { - DL_Node* node=HD; //can be 0 if empty + DL_Node* node=HD; //can be 0 if empty for(int i=0; i< NB; i++) { ((node->_item).*mfp)(); @@ -745,14 +739,14 @@ void DL_Iter::foreach_mf(void (Dtype::*mfp)()) /*! call given function for each item*/ template -void DL_Iter::foreach_f(void (*fp) (Dtype n) ) +void DL_Iter::foreach_f( void ( *fp ) ( Dtype n ) ) { - DL_Node* node=HD; //can be 0 if empty - for(int i=0; i< NB; i++) - { - fp (node->_item); - node=node->_next; - } + DL_Node* node = HD; //can be 0 if empty + for( int i = 0; i < NB; i++ ) + { + fp ( node->_item ); + node = node->_next; + } } @@ -782,31 +776,31 @@ a_listiter2->takeover(_intlist) \param otherlist the list to take the items from */ template -void DL_Iter::takeover(DL_List* otherlist) +void DL_Iter::takeover( DL_List* otherlist ) { - if (_current==0) - Error("takeover(DL_List*)",NO_LIST); - // no iterators allowed on otherlist - if (otherlist->_iterlevel > 0) - Error("takeover(DL_List*)",AC_ITER_LIST_OTHER); - // otherlist not this list - else if (otherlist == _list) - Error("takeover(DL_List*)",SAME_LIST); + if ( _current == 0 ) + Error( "takeover(DL_List*)", NO_LIST ); + // no iterators allowed on otherlist + if ( otherlist->_iterlevel > 0 ) + Error( "takeover(DL_List*)", AC_ITER_LIST_OTHER ); + // otherlist not this list + else if ( otherlist == _list ) + Error( "takeover(DL_List*)", SAME_LIST ); - if (otherlist->_nbitems == 0) - return; + if ( otherlist->_nbitems == 0 ) + return; - //link other list into this list at the end - TL->_next=otherlist->_root->_next; - otherlist->_root->_next->_prev=TL; - otherlist->_root->_prev->_next=RT; - TL=otherlist->_root->_prev; + //link other list into this list at the end + TL->_next = otherlist->_root->_next; + otherlist->_root->_next->_prev = TL; + otherlist->_root->_prev->_next = RT; + TL = otherlist->_root->_prev; - //empty other list - NB+=otherlist->_nbitems; - otherlist->_nbitems=0; - otherlist->_root->_next=otherlist->_root; - otherlist->_root->_prev=otherlist->_root; + //empty other list + NB += otherlist->_nbitems; + otherlist->_nbitems = 0; + otherlist->_root->_next = otherlist->_root; + otherlist->_root->_prev = otherlist->_root; } @@ -842,35 +836,35 @@ a_listiter2->takeover(a_listiter1) \param otheriter: the iterator to take the items from */ template -void DL_Iter::takeover(DL_Iter* otheriter) +void DL_Iter::takeover( DL_Iter* otheriter ) { - if (otheriter->_current==0) - Error(" DL_Iter",NO_LIST_OTHER); - if (_current==0) - Error(" DL_Iter",NO_LIST); + if ( otheriter->_current == 0 ) + Error( " DL_Iter", NO_LIST_OTHER ); + if ( _current == 0 ) + Error( " DL_Iter", NO_LIST ); - // only one iterator allowed on other list? - if (otheriter->_list->_iterlevel > 1) - Error("takeover(DL_Iter*)",AC_ITER_LIST_OTHER); - // otherlist not this list? - else if (otheriter->_list == _list) - Error("takeover(DL_Iter*)",SAME_LIST); + // only one iterator allowed on other list? + if ( otheriter->_list->_iterlevel > 1 ) + Error( "takeover(DL_Iter*)", AC_ITER_LIST_OTHER ); + // otherlist not this list? + else if ( otheriter->_list == _list ) + Error( "takeover(DL_Iter*)", SAME_LIST ); - if (otheriter->NB == 0) - return; + if ( otheriter->NB == 0 ) + return; - //link other list into this list at the end - TL->_next=otheriter->HD; - otheriter->HD->_prev=TL; - otheriter->TL->_next=RT; - TL=otheriter->TL; + //link other list into this list at the end + TL->_next = otheriter->HD; + otheriter->HD->_prev = TL; + otheriter->TL->_next = RT; + TL = otheriter->TL; - //empty other iter & list - NB+=otheriter->NB; - otheriter->NB=0; - otheriter->HD=otheriter->RT; - otheriter->TL=otheriter->RT; - otheriter->_current=otheriter->RT; + //empty other iter & list + NB += otheriter->NB; + otheriter->NB = 0; + otheriter->HD = otheriter->RT; + otheriter->TL = otheriter->RT; + otheriter->_current = otheriter->RT; } /*! @@ -906,85 +900,85 @@ a_listiter2->takeover(a_listiter1,1); \param maxcount maximum number of objects to take over */ template -void DL_Iter::takeover(DL_Iter* otheriter, int maxcount) +void DL_Iter::takeover( DL_Iter* otheriter, int maxcount ) { - if (otheriter->_current==0) - Error("takeover(DL_Iter*,int)",NO_LIST_OTHER); - if (_current==0) - Error("takeover(DL_Iter*,int)",NO_LIST); + if ( otheriter->_current == 0 ) + Error( "takeover(DL_Iter*,int)", NO_LIST_OTHER ); + if ( _current == 0 ) + Error( "takeover(DL_Iter*,int)", NO_LIST ); - if (otheriter->_list->_iterlevel > 1) - Error("takeover(DL_Iter*,int)",AC_ITER_LIST_OTHER); - else if (otheriter->_list == _list) - Error("takeover(DL_Iter*,int)",SAME_LIST); + if ( otheriter->_list->_iterlevel > 1 ) + Error( "takeover(DL_Iter*,int)", AC_ITER_LIST_OTHER ); + else if ( otheriter->_list == _list ) + Error( "takeover(DL_Iter*,int)", SAME_LIST ); - if (maxcount<0) - Error("takeover(DL_Iter*,int), maxcount < 0",NO_MES); + if ( maxcount < 0 ) + Error( "takeover(DL_Iter*,int), maxcount < 0", NO_MES ); - if (otheriter->NB == 0) - return; + if ( otheriter->NB == 0 ) + return; - if (otheriter->NB <= maxcount) - { //take it all - //link other list into this list at the end - TL->_next=otheriter->HD; - otheriter->HD->_prev=TL; - otheriter->TL->_next=RT; - TL=otheriter->TL; + if ( otheriter->NB <= maxcount ) + { //take it all + //link other list into this list at the end + TL->_next = otheriter->HD; + otheriter->HD->_prev = TL; + otheriter->TL->_next = RT; + TL = otheriter->TL; - //empty other iter & list - NB+=otheriter->NB; - otheriter->NB=0; - otheriter->HD=otheriter->RT; - otheriter->TL=otheriter->RT; - otheriter->_current=otheriter->RT; - } - else - { //take maxcount elements from otheriter - //set cursor in otherlist to element maxcount - DL_Node* node; + //empty other iter & list + NB += otheriter->NB; + otheriter->NB = 0; + otheriter->HD = otheriter->RT; + otheriter->TL = otheriter->RT; + otheriter->_current = otheriter->RT; + } + else + { //take maxcount elements from otheriter + //set cursor in otherlist to element maxcount + DL_Node* node; - if (NB/2 < maxcount) - { // this is faster (1st half) - node=otheriter->HD; - for(int i=1; i_next; - } - else - { // no, this is faster (2nd half) - node=otheriter->TL; - for(int i=NB; i>maxcount+1; i--) - node=node->_prev; - } + if ( NB / 2 < maxcount ) + { // this is faster (1st half) + node = otheriter->HD; + for( int i = 1; i < maxcount; i++ ) + node = node->_next; + } + else + { // no, this is faster (2nd half) + node = otheriter->TL; + for( int i = NB; i > maxcount + 1; i-- ) + node = node->_prev; + } - // link this->tail to other->head - if (NB>0) - { - TL->_next=otheriter->HD; - otheriter->HD->_prev=TL; - } - else // target is empty - { - HD=otheriter->HD; - otheriter->HD->_prev=RT; - } + // link this->tail to other->head + if ( NB > 0 ) + { + TL->_next = otheriter->HD; + otheriter->HD->_prev = TL; + } + else // target is empty + { + HD = otheriter->HD; + otheriter->HD->_prev = RT; + } - // set other root to node-> next (after last to copy) - otheriter->HD=node->_next; - otheriter->HD->_prev=otheriter->RT; + // set other root to node-> next (after last to copy) + otheriter->HD = node->_next; + otheriter->HD->_prev = otheriter->RT; - // set this->tail to other->item()->prev (last element to be copied) - TL=node; - node->_next=RT; + // set this->tail to other->item()->prev (last element to be copied) + TL = node; + node->_next = RT; - // still need to update element counter - NB+=maxcount; + // still need to update element counter + NB += maxcount; - // update other list - otheriter->NB-=maxcount; - otheriter->_current=otheriter->HD; // other->current is moved to this! - } + // update other list + otheriter->NB -= maxcount; + otheriter->_current = otheriter->HD; // other->current is moved to this! + } } @@ -1011,24 +1005,24 @@ a_listiter->tohead(); //the new head will be at object 3456 template void DL_Iter::reset_head() { - if (_current==0) - Error("reset_head()",NO_LIST); - if (_list->_iterlevel > 1 ) - Error("reset_head()",ITER_GT_1); + if ( _current == 0 ) + Error( "reset_head()", NO_LIST ); + if ( _list->_iterlevel > 1 ) + Error( "reset_head()", ITER_GT_1 ); - if(_current==RT) - Error("reset head()",ITER_HITROOT); + if( _current == RT ) + Error( "reset head()", ITER_HITROOT ); - //link out RT - HD->_prev=TL; - TL->_next=HD; + //link out RT + HD->_prev = TL; + TL->_next = HD; - //link in RT before current - HD=_current; - TL=_current->_prev; + //link in RT before current + HD = _current; + TL = _current->_prev; - TL->_next=RT; - HD->_prev=RT; + TL->_next = RT; + HD->_prev = RT; } /*! @@ -1054,24 +1048,24 @@ a_listiter->totail(); //the new tail will be at object 1234 template void DL_Iter::reset_tail() { - if (_current==0) - Error("reset_tail()",NO_LIST); - if (_list->_iterlevel > 1 ) - Error("reset_tail()",ITER_GT_1); + if ( _current == 0 ) + Error( "reset_tail()", NO_LIST ); + if ( _list->_iterlevel > 1 ) + Error( "reset_tail()", ITER_GT_1 ); - if(_current==RT) - Error("reset head()",ITER_HITROOT); + if( _current == RT ) + Error( "reset head()", ITER_HITROOT ); - //link out RT - HD->_prev=TL; - TL->_next=HD; + //link out RT + HD->_prev = TL; + TL->_next = HD; - //link in RT after current - TL=_current; - HD=_current->_next; + //link in RT after current + TL = _current; + HD = _current->_next; - HD->_prev=RT; - TL->_next=RT; + HD->_prev = RT; + TL->_next = RT; } /*! @@ -1090,10 +1084,10 @@ if (a_listiter->Empty()) template bool DL_Iter::empty() { - if (_current==0) - Error("empty()",NO_LIST); + if ( _current == 0 ) + Error( "empty()", NO_LIST ); - return(bool)(NB==0); + return( bool )( NB == 0 ); } /*! @@ -1111,26 +1105,26 @@ a_listiter->tohead(); //traverse forwards while ( ! a_listiter->hitroot()) { - cout << "The item =" << a_listiter->item(); - a_listiter++; //goto next object + cout << "The item =" << a_listiter->item(); + a_listiter++; //goto next object } a_listiter->totail(); //traverse backwards while ( ! a_listiter->hitroot()) { - cout << "The item =" << a_listiter->item(); - a_listiter--; //goto next object + cout << "The item =" << a_listiter->item(); + a_listiter--; //goto next object } \endcode */ template bool DL_Iter::hitroot() { - if (_current==0) - Error("hitroot()",NO_LIST); + if ( _current == 0 ) + Error( "hitroot()", NO_LIST ); - return(bool)(_current == RT); + return( bool )( _current == RT ); } /*! @@ -1150,10 +1144,10 @@ if (a_listiter->athead()) template bool DL_Iter::athead() { - if (_current==0) - Error("athead()",NO_LIST); + if ( _current == 0 ) + Error( "athead()", NO_LIST ); - return(bool)(_current == HD); + return( bool )( _current == HD ); } /*! @@ -1174,10 +1168,10 @@ if (a_listiter->attail()) template bool DL_Iter::attail() { - if (_current==0) - Error("attail()",NO_LIST); + if ( _current == 0 ) + Error( "attail()", NO_LIST ); - return(bool)(_current == TL); + return( bool )( _current == TL ); } /*! @@ -1196,18 +1190,19 @@ if (a_listiter->has(1234)) \param otheritem item to search for */ template -bool DL_Iter::has(Dtype otheritem) +bool DL_Iter::has( Dtype otheritem ) { - if (_current==0) - Error("has()",NO_LIST); + if ( _current == 0 ) + Error( "has()", NO_LIST ); - DL_Node* node=HD; //can be 0 if empty - for(int i=0; i_item == otheritem) - return true; - node=node->_next; - } - return false; + DL_Node* node = HD; //can be 0 if empty + for( int i = 0; i < NB; i++ ) + { + if ( node->_item == otheritem ) + return true; + node = node->_next; + } + return false; } /*! @@ -1225,10 +1220,10 @@ if (a_listiter->count() == 1) template int DL_Iter::count() { - if (_current==0) - Error("count()",NO_LIST); + if ( _current == 0 ) + Error( "count()", NO_LIST ); - return NB; + return NB; } /*! @@ -1246,10 +1241,10 @@ a_listiter->tohead(); template void DL_Iter::tohead() { - if (_current==0) - Error("tohead()",NO_LIST); + if ( _current == 0 ) + Error( "tohead()", NO_LIST ); - _current=HD; + _current = HD; } /*! @@ -1267,10 +1262,10 @@ a_listiter->totail(); template void DL_Iter::totail() { - if (_current==0) - Error("totail()",NO_LIST); + if ( _current == 0 ) + Error( "totail()", NO_LIST ); - _current=TL; + _current = TL; } /*! @@ -1290,10 +1285,10 @@ while (a_listiter->iterate()) template void DL_Iter::toroot() { - if (_current==0) - Error("toroot()",NO_LIST); + if ( _current == 0 ) + Error( "toroot()", NO_LIST ); - _current=RT; + _current = RT; } /*! @@ -1314,12 +1309,12 @@ while (!a_listiter->hitroot()) \endcode */ template -void DL_Iter::operator++(void) +void DL_Iter::operator++( void ) { - if (_current==0) - Error("operator++()",NO_LIST); + if ( _current == 0 ) + Error( "operator++()", NO_LIST ); - _current=_current->_next; + _current = _current->_next; } /*! @@ -1340,12 +1335,12 @@ while (!a_listiter->hitroot()) \endcode */ template -void DL_Iter::operator++(int) +void DL_Iter::operator++( int ) { - if (_current==0) - Error("operator++(int)",NO_LIST); + if ( _current == 0 ) + Error( "operator++(int)", NO_LIST ); - _current=_current->_next; + _current = _current->_next; } @@ -1367,12 +1362,12 @@ while (!a_listiter->hitroot()) \endcode */ template -void DL_Iter::operator--(void) +void DL_Iter::operator--( void ) { - if (_current==0) - Error("operator++()",NO_LIST); + if ( _current == 0 ) + Error( "operator++()", NO_LIST ); - _current=_current->_prev; + _current = _current->_prev; } @@ -1394,12 +1389,12 @@ while (!a_listiter->hitroot()) \endcode */ template -void DL_Iter::operator--(int) +void DL_Iter::operator--( int ) { - if (_current==0) - Error("operator++(int)",NO_LIST); + if ( _current == 0 ) + Error( "operator++(int)", NO_LIST ); - _current=_current->_prev; + _current = _current->_prev; } @@ -1417,13 +1412,13 @@ a_listiter>>2;//at root now \param n go n places forward */ template -void DL_Iter::operator>>(int n) +void DL_Iter::operator>>( int n ) { - if (_current==0) - Error("operator>>()",NO_LIST); + if ( _current == 0 ) + Error( "operator>>()", NO_LIST ); - for(int i=0; i_next; + for( int i = 0; i < n; i++ ) + _current = _current->_next; } @@ -1441,13 +1436,13 @@ a_listiter<<2;//at root now \param n go n places back */ template -void DL_Iter::operator<<(int n) +void DL_Iter::operator<<( int n ) { - if (_current==0) - Error("operator<<()",NO_LIST); + if ( _current == 0 ) + Error( "operator<<()", NO_LIST ); - for(int i=0; i_prev; + for( int i = 0; i < n; i++ ) + _current = _current->_prev; } @@ -1468,20 +1463,21 @@ a_listiter->toitem(2345); template \endcode */ template -bool DL_Iter::toitem(Dtype item) +bool DL_Iter::toitem( Dtype item ) { - if (_current==0) - Error("toitem(item)",NO_LIST); - DL_Node* node=HD; //can be 0 if empty - for(int i=0; i_item == item) - { - _current = node; - return true; - } - node=node->_next; - } - return false; + if ( _current == 0 ) + Error( "toitem(item)", NO_LIST ); + DL_Node* node = HD; //can be 0 if empty + for( int i = 0; i < NB; i++ ) + { + if ( node->_item == item ) + { + _current = node; + return true; + } + node = node->_next; + } + return false; } /*! @@ -1502,15 +1498,15 @@ a_listiter2->toiter(a_listiter2); \param otheriter other iterator to let this iterator point to. */ template -void DL_Iter::toiter(DL_Iter *otheriter) +void DL_Iter::toiter( DL_Iter *otheriter ) { - if (otheriter->_current==0) - Error("toiter(otheriter)",NO_LIST); - // both iters must have the same list - if (_list != otheriter->_list) - Error("toiter(otheriter)",NOT_SAME_LIST); + if ( otheriter->_current == 0 ) + Error( "toiter(otheriter)", NO_LIST ); + // both iters must have the same list + if ( _list != otheriter->_list ) + Error( "toiter(otheriter)", NOT_SAME_LIST ); - _current = otheriter->_current; + _current = otheriter->_current; } @@ -1521,18 +1517,19 @@ put the iterator at the position of the given object in the list. \param othernode a node to let this iterator point to. */ template -bool DL_Iter::tonode(DL_Node *othernode) +bool DL_Iter::tonode( DL_Node *othernode ) { - DL_Node* node=HD; //can be 0 if empty //node is a temporary cursor - for(int i=0; i_next; - } - return false; + DL_Node* node = HD; //can be 0 if empty //node is a temporary cursor + for( int i = 0; i < NB; i++ ) + { + if ( node == othernode ) + { + _current = othernode; + return true; + } + node = node->_next; + } + return false; } /*! @@ -1564,15 +1561,15 @@ while (a_listiter->iterate()) \endcode */ template -bool DL_Iter::iterate(void) +bool DL_Iter::iterate( void ) { - if (_current==0) - Error("iterate()",NO_LIST); + if ( _current == 0 ) + Error( "iterate()", NO_LIST ); - _current=_current->_next; - if (_current==RT) - return false; - return true; + _current = _current->_next; + if ( _current == RT ) + return false; + return true; } /*! @@ -1595,24 +1592,24 @@ int theitem=a_listiter->item(); template Dtype DL_Iter::item() { - if (_current==0) - Error("item()",NO_LIST); - if (_current==RT) - Error("item()",NO_ITEM); + if ( _current == 0 ) + Error( "item()", NO_LIST ); + if ( _current == RT ) + Error( "item()", NO_ITEM ); - return _current->_item; + return _current->_item; } //! get the node at iterater position template DL_Node* DL_Iter::node() { - if (_current==0) - Error("item()",NO_LIST); - if (_current==RT) - Error("item()",NO_ITEM); + if ( _current == 0 ) + Error( "item()", NO_LIST ); + if ( _current == RT ) + Error( "item()", NO_ITEM ); - return _current; + return _current; } /*! @@ -1622,10 +1619,10 @@ set the iterator position to next object in the list ( can be the root also). template void DL_Iter::next() { - if (_current==0) - Error("item()",NO_LIST); + if ( _current == 0 ) + Error( "item()", NO_LIST ); - _current=_current->_next; + _current = _current->_next; } @@ -1654,12 +1651,12 @@ while (count) template void DL_Iter::next_wrap() { - if (_current==0) - Error("item()",NO_LIST); + if ( _current == 0 ) + Error( "item()", NO_LIST ); - _current=_current->_next; - if (_current==RT) - _current=_current->_next; + _current = _current->_next; + if ( _current == RT ) + _current = _current->_next; } @@ -1670,10 +1667,10 @@ set the iterator position to previous object in the list ( can be the root also) template void DL_Iter::prev() { - if (_current==0) - Error("item()",NO_LIST); + if ( _current == 0 ) + Error( "item()", NO_LIST ); - _current=_current->_prev; + _current = _current->_prev; } /*! @@ -1701,26 +1698,26 @@ while (count) template void DL_Iter::prev_wrap() { - if (_current==0) - Error("item()",NO_LIST); + if ( _current == 0 ) + Error( "item()", NO_LIST ); - _current=_current->_prev; - if (_current==RT) - _current=_current->_prev; + _current = _current->_prev; + if ( _current == RT ) + _current = _current->_prev; } template void DL_Iter::remove_all() { - if (_current==0) - Error("remove_all()",NO_LIST); - if (_list->_iterlevel > 1 ) - Error("remove_all()",ITER_GT_1); + if ( _current == 0 ) + Error( "remove_all()", NO_LIST ); + if ( _list->_iterlevel > 1 ) + Error( "remove_all()", ITER_GT_1 ); - _list->_iterlevel--; - _list->remove_all(); - _list->_iterlevel++; - _current=RT; + _list->_iterlevel--; + _list->remove_all(); + _list->_iterlevel++; + _current = RT; } /*! @@ -1749,22 +1746,22 @@ a_listiter->remove(); template void DL_Iter::remove() { - if (_current==0) - Error("remove()",NO_LIST); - if (_list->_iterlevel > 1 ) - Error("remove()",ITER_GT_1); - if (_current==RT) - Error("remove()",ITER_HITROOT); + if ( _current == 0 ) + Error( "remove()", NO_LIST ); + if ( _list->_iterlevel > 1 ) + Error( "remove()", ITER_GT_1 ); + if ( _current == RT ) + Error( "remove()", ITER_HITROOT ); - DL_Node* node=_current; + DL_Node* node = _current; - _current=_current->_next; + _current = _current->_next; - node->_prev->_next = node->_next; // update forward link - node->_next->_prev = node->_prev; // update backward link + node->_prev->_next = node->_next; // update forward link + node->_next->_prev = node->_prev; // update backward link - NB--; - delete node; // delete list node + NB--; + delete node; // delete list node } /*! @@ -1792,19 +1789,19 @@ a_listiter->removehead(); template void DL_Iter::removehead() { - if (_current==0) - Error("removehead()",NO_LIST); - if (_list->_iterlevel > 1 ) - Error("removehead()",ITER_GT_1); - if(NB==0) - Error("removehead()",EMPTY); + if ( _current == 0 ) + Error( "removehead()", NO_LIST ); + if ( _list->_iterlevel > 1 ) + Error( "removehead()", ITER_GT_1 ); + if( NB == 0 ) + Error( "removehead()", EMPTY ); - if (_current==HD) - _current=_current->_next; + if ( _current == HD ) + _current = _current->_next; - _list->_iterlevel--; - _list->removehead(); - _list->_iterlevel++; + _list->_iterlevel--; + _list->removehead(); + _list->_iterlevel++; } @@ -1833,19 +1830,19 @@ a_listiter->removetail(); template void DL_Iter::removetail() { - if (_current==0) - Error("removetail()",NO_LIST); - if (_list->_iterlevel > 1 ) - Error("removetail()",ITER_GT_1); - if (NB==0) - Error("removehead()",EMPTY); + if ( _current == 0 ) + Error( "removetail()", NO_LIST ); + if ( _list->_iterlevel > 1 ) + Error( "removetail()", ITER_GT_1 ); + if ( NB == 0 ) + Error( "removehead()", EMPTY ); - if (_current==TL) - _current=_current->_prev; + if ( _current == TL ) + _current = _current->_prev; - _list->_iterlevel--; - _list->removetail(); - _list->_iterlevel++; + _list->_iterlevel--; + _list->removetail(); + _list->_iterlevel++; } @@ -1868,16 +1865,16 @@ a_listiter->insend(a); \endcode */ template -DL_Node* DL_Iter::insend(Dtype newitem) +DL_Node* DL_Iter::insend( Dtype newitem ) { - if (_current==0) - Error("insend()",NO_LIST); - if (_list->_iterlevel > 1) - Error("insend()",ITER_GT_1); + if ( _current == 0 ) + Error( "insend()", NO_LIST ); + if ( _list->_iterlevel > 1 ) + Error( "insend()", ITER_GT_1 ); - _list->_iterlevel--; - DL_Node* ret = _list->insend(newitem); - _list->_iterlevel++; + _list->_iterlevel--; + DL_Node* ret = _list->insend( newitem ); + _list->_iterlevel++; return ret; } @@ -1902,17 +1899,17 @@ a_listiter->insbegin(a); \param newitem an object for which the template list/iterator was generated */ template -DL_Node* DL_Iter::insbegin(Dtype newitem) +DL_Node* DL_Iter::insbegin( Dtype newitem ) { - if (_current==0) - Error("insbegin()",NO_LIST); - if (_list->_iterlevel > 1) - Error("insbegin()",ITER_GT_1); + if ( _current == 0 ) + Error( "insbegin()", NO_LIST ); + if ( _list->_iterlevel > 1 ) + Error( "insbegin()", ITER_GT_1 ); - _list->_iterlevel--; - DL_Node* ret = _list->insbegin(newitem); - _list->_iterlevel++; - return ret; + _list->_iterlevel--; + DL_Node* ret = _list->insbegin( newitem ); + _list->_iterlevel++; + return ret; } /*! @@ -1932,21 +1929,21 @@ a_listiter->insbefore(a); // insert before tail \param newitem an object for which the template list/iterator was generated */ template -DL_Node* DL_Iter::insbefore(Dtype newitem) +DL_Node* DL_Iter::insbefore( Dtype newitem ) { - if (_current==0) - Error("insbefore()",NO_LIST); - if (_list->_iterlevel > 1) - Error("insbefore()",ITER_GT_1); + if ( _current == 0 ) + Error( "insbefore()", NO_LIST ); + if ( _list->_iterlevel > 1 ) + Error( "insbefore()", ITER_GT_1 ); - DL_Node* newnode = new DL_Node(newitem); + DL_Node* newnode = new DL_Node( newitem ); - newnode ->_next = _current; - _current->_prev->_next = newnode; - newnode ->_prev = _current->_prev; - _current->_prev = newnode; + newnode ->_next = _current; + _current->_prev->_next = newnode; + newnode ->_prev = _current->_prev; + _current->_prev = newnode; - NB++; + NB++; return newnode; } @@ -1967,21 +1964,21 @@ a_listiter->insafter(a); // insert after head \param newitem an object for which the template list/iterator was generated */ template -DL_Node* DL_Iter::insafter(Dtype newitem) +DL_Node* DL_Iter::insafter( Dtype newitem ) { - if (_current==0) - Error("insafter()",NO_LIST); - if (_list->_iterlevel > 1) - Error("insafter()",ITER_GT_1); + if ( _current == 0 ) + Error( "insafter()", NO_LIST ); + if ( _list->_iterlevel > 1 ) + Error( "insafter()", ITER_GT_1 ); - DL_Node* newnode = new DL_Node(newitem); + DL_Node* newnode = new DL_Node( newitem ); - newnode ->_next = _current->_next; - newnode ->_prev = _current; - _current->_next->_prev = newnode; - _current->_next = newnode; + newnode ->_next = _current->_next; + newnode ->_prev = _current; + _current->_next->_prev = newnode; + _current->_next = newnode; - NB++; + NB++; return newnode; } @@ -2038,76 +2035,76 @@ a_listiter->cocktailsort(numbersorter,NULL); \param fswap swapfunction */ template -int DL_Iter::cocktailsort(int (*fcmp) (Dtype, Dtype), bool (*fswap)(Dtype, Dtype)) +int DL_Iter::cocktailsort( int ( *fcmp ) ( Dtype, Dtype ), bool ( *fswap )( Dtype, Dtype ) ) { - if (_current==0) - Error("cocktailsort()",NO_LIST); - if (NB <= 1) - return 0; + if ( _current == 0 ) + Error( "cocktailsort()", NO_LIST ); + if ( NB <= 1 ) + return 0; + + DL_Node* cursor; + Dtype swap; - DL_Node* cursor; - Dtype swap; - int swapResult = 0; - // boven/ondergrens setten - DL_Node *bg = TL, *bgold = TL; - DL_Node *og = HD, *ogold = HD; + // boven/ondergrens setten + DL_Node *bg = TL, *bgold = TL; + DL_Node *og = HD, *ogold = HD; - bool swapped = true; + bool swapped = true; - // while swaping is done & lowerborder upperborder don't touch - while (swapped && (og!=bg)) - { - swapped = false; + // while swaping is done & lowerborder upperborder don't touch + while ( swapped && ( og != bg ) ) + { + swapped = false; - // BUBBELSLAG lowerborder--->> upperborder - cursor=og; - while(!(cursor == bgold)) - { - // (current.next < current)? - if( fcmp(cursor->_next->_item, cursor->_item)==1) - { - // user function - if ( fswap != NULL ) - if ( fswap(cursor->_item, cursor->_next->_item) ) - swapResult++; - // update swap-flag en upperborder - swapped = true; - bg = cursor; - // swap the items of the nodes - swap = cursor->_item; - cursor->_item = cursor->_next->_item; - cursor->_next->_item = swap; - } - cursor=cursor->_next; - }// end bubbelslag - bgold = bg; - - // BRICKSLAG lowerborder <<---upperborder - cursor=bg; - while(!(cursor == ogold)) - { - // (current < current.next)? - if( fcmp(cursor->_item, cursor->_prev->_item)==1) - { - // user function - if ( fswap != NULL ) - if ( fswap(cursor->_item, cursor->_prev->_item) ) + // BUBBELSLAG lowerborder--->> upperborder + cursor = og; + while( !( cursor == bgold ) ) + { + // (current.next < current)? + if( fcmp( cursor->_next->_item, cursor->_item ) == 1 ) + { + // user function + if ( fswap != NULL ) + if ( fswap( cursor->_item, cursor->_next->_item ) ) swapResult++; - // update swap-flag and lowerborder - swapped = true; - og = cursor; - // swap de items van de nodes - swap = cursor->_item; - cursor->_item = cursor->_prev->_item; - cursor->_prev->_item = swap; - } - cursor=cursor->_prev; - }// end brickslag - ogold = og; - }// end while(ongesorteerd) - + // update swap-flag en upperborder + swapped = true; + bg = cursor; + // swap the items of the nodes + swap = cursor->_item; + cursor->_item = cursor->_next->_item; + cursor->_next->_item = swap; + } + cursor = cursor->_next; + }// end bubbelslag + bgold = bg; + + // BRICKSLAG lowerborder <<---upperborder + cursor = bg; + while( !( cursor == ogold ) ) + { + // (current < current.next)? + if( fcmp( cursor->_item, cursor->_prev->_item ) == 1 ) + { + // user function + if ( fswap != NULL ) + if ( fswap( cursor->_item, cursor->_prev->_item ) ) + swapResult++; + // update swap-flag and lowerborder + swapped = true; + og = cursor; + // swap de items van de nodes + swap = cursor->_item; + cursor->_item = cursor->_prev->_item; + cursor->_prev->_item = swap; + } + cursor = cursor->_prev; + }// end brickslag + ogold = og; + }// end while(ongesorteerd) + return swapResult; } @@ -2163,66 +2160,68 @@ a_listiter->mergesort(numbersorter); \endcode */ template -void DL_Iter::mergesort(int (*fcmp) (Dtype, Dtype)) +void DL_Iter::mergesort( int ( *fcmp ) ( Dtype, Dtype ) ) { - if (_current==0) - Error("mergesort()",NO_LIST); - mergesort_rec(fcmp, RT, NB); + if ( _current == 0 ) + Error( "mergesort()", NO_LIST ); + mergesort_rec( fcmp, RT, NB ); } template -void DL_Iter::mergesort_rec(int (*fcmp)(Dtype,Dtype), DL_Node *RT1, int n1) +void DL_Iter::mergesort_rec( int ( *fcmp )( Dtype, Dtype ), DL_Node *RT1, int n1 ) { - if (n1 > 1) //one element left then stop - { - DL_Node RT2; - int n2; + if ( n1 > 1 ) //one element left then stop + { + DL_Node RT2; + int n2; - RT2._prev=RT1->_prev; - RT2._next=RT1->_next; - // goto middle - n2=n1;n1>>=1;n2-=n1; - for (int i=0; i _next; + RT2._prev = RT1->_prev; + RT2._next = RT1->_next; + // goto middle + n2 = n1;n1 >>= 1;n2 -= n1; + for ( int i = 0; i < n1;i++ ) + RT2._next = RT2._next->_next; - //RT2 is at half - RT1->_prev->_next=&RT2; - RT2._prev=RT1->_prev; - RT1->_prev=RT2._next->_prev; - RT2._next->_prev->_next=RT1; + //RT2 is at half + RT1->_prev->_next = &RT2; + RT2._prev = RT1->_prev; + RT1->_prev = RT2._next->_prev; + RT2._next->_prev->_next = RT1; - mergesort_rec(fcmp,RT1,n1); - mergesort_rec(fcmp,&RT2,n2); - mergetwo(fcmp,RT1,&RT2); - } + mergesort_rec( fcmp, RT1, n1 ); + mergesort_rec( fcmp, &RT2, n2 ); + mergetwo( fcmp, RT1, &RT2 ); + } } template -void DL_Iter::mergetwo(int (*fcmp)(Dtype,Dtype), DL_Node *RT1,DL_Node *RT2) +void DL_Iter::mergetwo( int ( *fcmp )( Dtype, Dtype ), DL_Node *RT1, DL_Node *RT2 ) { - DL_Node *c,*a,*b; - a=RT1->_next;b=RT2->_next; - c=RT1; - do - { - if (fcmp(a->_item , b->_item) > -1) - { c->_next=a;a->_prev=c;c=a;a=a->_next;} - else - { c->_next=b;b->_prev=c;c=b;b=b->_next;} - if (a == RT1) - { c->_next= - b;b->_prev=c; //connect list b to the list made sofar - RT1->_prev=RT2->_prev; - RT1->_prev->_next=RT1; - break; - } - if (b == RT2) - { c->_next=a;a->_prev=c; //connect list a to the list made sofar - break; - } - } - while (true); + DL_Node *c, *a, *b; + a = RT1->_next;b = RT2->_next; + c = RT1; + do + { + if ( fcmp( a->_item , b->_item ) > -1 ) + { c->_next = a;a->_prev = c;c = a;a = a->_next;} + else + { c->_next = b;b->_prev = c;c = b;b = b->_next;} + if ( a == RT1 ) + { + c->_next = + b;b->_prev = c; //connect list b to the list made sofar + RT1->_prev = RT2->_prev; + RT1->_prev->_next = RT1; + break; + } + if ( b == RT2 ) + { + c->_next = a;a->_prev = c; //connect list a to the list made sofar + break; + } + } + while ( true ); } @@ -2266,55 +2265,54 @@ void DL_Iter::mergetwo(int (*fcmp)(Dtype,Dtype), DL_Node *RT1,DL_N // constructor template -DL_StackIter::DL_StackIter(DL_List *newlist) -:DL_Iter(newlist) // initialiseer BaseIter +DL_StackIter::DL_StackIter( DL_List *newlist ) + : DL_Iter( newlist ) // initialiseer BaseIter {} // destructor template DL_StackIter::~DL_StackIter() -{ -} +{} // plaats nieuw item op stack template -void DL_StackIter::push(Dtype newitem) +void DL_StackIter::push( Dtype newitem ) { - DL_Iter::insbegin(newitem); + DL_Iter::insbegin( newitem ); } // remove current item template void DL_StackIter::remove_all() { - DL_Iter::remove_all(); + DL_Iter::remove_all(); } // is stack leeg? template bool DL_StackIter::empty() { - return DL_Iter::empty(); + return DL_Iter::empty(); } // aantal items op stack template int DL_StackIter::count() { - return DL_Iter::count(); + return DL_Iter::count(); } // haal bovenste item van stack template Dtype DL_StackIter::pop() { - if(DL_Iter::empty()) - this->Error("pop()",EMPTY); + if( DL_Iter::empty() ) + this->Error( "pop()", EMPTY ); - DL_Iter::tohead(); - Dtype temp = DL_Iter::item(); - DL_Iter::removehead(); - return temp; + DL_Iter::tohead(); + Dtype temp = DL_Iter::item(); + DL_Iter::removehead(); + return temp; } //======================================================================= @@ -2331,8 +2329,8 @@ Dtype DL_StackIter::pop() // constructor template -DL_SortIter::DL_SortIter(DL_List* nw_list, int (*new_func)(DType ,DType )) -:DL_Iter(nw_list), comparef(new_func) +DL_SortIter::DL_SortIter( DL_List* nw_list, int ( *new_func )( DType , DType ) ) + : DL_Iter( nw_list ), comparef( new_func ) {} // destructor @@ -2342,37 +2340,37 @@ DL_SortIter::~DL_SortIter() // general function to insert item template -void DL_SortIter::insert(DType new_item) +void DL_SortIter::insert( DType new_item ) { - DL_Node* cursor=this->_current; //can be 0 if empty //node is a temporary cursor + DL_Node* cursor = this->_current; //can be 0 if empty //node is a temporary cursor - // if list is empty directly insert - if (DL_Iter::empty()) - { - DL_Iter::insend(new_item); - } - else - { - // put new item left of item - DL_Iter::tohead(); - while(!DL_Iter::hitroot()) - { - if (!(*comparef)(DL_Iter::item(), new_item)) - break; - DL_Iter::next(); - } + // if list is empty directly insert + if ( DL_Iter::empty() ) + { + DL_Iter::insend( new_item ); + } + else + { + // put new item left of item + DL_Iter::tohead(); + while( !DL_Iter::hitroot() ) + { + if ( !( *comparef )( DL_Iter::item(), new_item ) ) + break; + DL_Iter::next(); + } - //if at root - DL_Iter::insbefore(new_item); - } + //if at root + DL_Iter::insbefore( new_item ); + } - this->_current=cursor; //set to old cursor position + this->_current = cursor; //set to old cursor position } template void DL_SortIter::sortitererror() { - this->Error("sortiter()",NOT_ALLOW); + this->Error( "sortiter()", NOT_ALLOW ); } diff --git a/polygon/kbool/include/kbool/_dl_itr.h b/polygon/kbool/include/kbool/_dl_itr.h new file mode 100644 index 0000000000..f4a3c72aed --- /dev/null +++ b/polygon/kbool/include/kbool/_dl_itr.h @@ -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.3 2008/06/04 21:23:21 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 + +#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1 +#define _CRT_SECURE_NO_DEPRECATE 1 + +#include "kbool/booleng.h" +#include + + +#ifndef _STATUS_ENUM +#define _STATUS_ENUM +//!_root +#define HD _list->_root->_next +#define TL _list->_root->_prev +#define NB _list->_nbitems + +template class DL_List; +template class DL_Iter; +template class DL_SortIter; + +//! Template class DL_Node +template class DL_Node +{ + friend class DL_List; + friend class DL_Iter; + friend class DL_SortIter; + + //!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 DL_List +{ + friend class DL_Iter; + friend class DL_SortIter; + +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* insend( Dtype n ); + + //!insert the object given at the begin of the list, before head + DL_Node* 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* 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* _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 DL_Iter +{ +public: + //!Construct an iterator object for a given list of type Dtype + DL_Iter( DL_List* 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* 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* insend( Dtype n ); + + //!insert before head item + DL_Node* insbegin( Dtype n ); + + //!insert before current iterator position + DL_Node* insbefore( Dtype n ); + + //!insert after current iterator position + DL_Node* insafter( Dtype n ); + + //!to move all objects in a list to the list of the iterator. + void takeover( DL_List* 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* ); + + //!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* 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 *RT1, int n ); + + //!sort list with mergesort + void mergetwo( int ( *fcmp )( Dtype, Dtype ), DL_Node *RT1, DL_Node *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 *_list; + + //!the current position of the iterator + DL_Node *_current; +}; + + +//! template class DL_StackIter class for stack iterator on DL_List +template +class DL_StackIter : protected DL_Iter +{ +public: + //!Constructor of stack iterator for given list + DL_StackIter( DL_List * ); + //!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 DL_SortIter : public DL_Iter +{ +public: + //!Constructor of sort iterator for given list and sort function + DL_SortIter( DL_List* 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* ){sortitererror();}; + //!Not allowed + void takeover ( DL_Iter* ){sortitererror();}; + //!Not allowed + void takeover ( DL_Iter* 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 "kbool/_dl_itr.cpp" + +#endif diff --git a/polygon/kbool/include/kbool/_lnk_itr.cpp b/polygon/kbool/include/kbool/_lnk_itr.cpp new file mode 100644 index 0000000000..fef895e556 --- /dev/null +++ b/polygon/kbool/include/kbool/_lnk_itr.cpp @@ -0,0 +1,257 @@ +/*! \file 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.3 2006/12/13 21:43:33 titato Exp $ +*/ + +#ifdef __UNIX__ +#include "kbool/_lnk_itr.h" +#endif + +//======================================================================= +// implementation class LinkBaseIter +//======================================================================= + +template +TDLI::TDLI( DL_List* newlist ): DL_Iter( newlist ) +{} + +template +TDLI::TDLI( DL_Iter* otheriter ): DL_Iter( otheriter ) +{} + +template +TDLI::TDLI(): DL_Iter() +{} + +// destructor TDLI +template +TDLI::~TDLI() +{} + +template +void TDLI::delete_all() +{ + DL_Node* 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 +void TDLI::foreach_f( void ( *fp ) ( Type* item ) ) +{ + DL_Iter::foreach_f( ( void ( * )( void* ) )fp ); //call fp for each item +} + +template +void TDLI::foreach_mf( void ( Type::*mfp ) () ) +{ + + DL_Node* 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 +void TDLI::takeover( DL_List* otherlist ) +{ + DL_Iter::takeover( ( DL_List* ) otherlist ); +} + +template +void TDLI::takeover( TDLI* otheriter ) +{ + DL_Iter::takeover( ( DL_Iter* ) otheriter ); +} + +template +void TDLI::takeover( TDLI* otheriter, int maxcount ) +{ + DL_Iter::takeover( ( DL_Iter* ) otheriter, maxcount ); +} + +// is item element of the list? +template +bool TDLI::has( Type* otheritem ) +{ + return DL_Iter::has( ( void* ) otheritem ); +} + +// goto to item +template +bool TDLI::toitem( Type* item ) +{ + return DL_Iter::toitem( ( void* ) item ); +} + +// get current item +template +Type* TDLI::item() +{ + return ( Type* ) DL_Iter::item(); +} + +template +void TDLI::insend( Type* newitem ) +{ + DL_Iter::insend( ( void* ) newitem ); +} + +template +void TDLI::insbegin( Type* newitem ) +{ + DL_Iter::insbegin( ( void* ) newitem ); +} + +template +void TDLI::insbefore( Type* newitem ) +{ + DL_Iter::insbefore( ( void* ) newitem ); +} + +template +void TDLI::insafter( Type* newitem ) +{ + DL_Iter::insafter( ( void* ) newitem ); +} + +template +void TDLI::insend_unsave( Type* newitem ) +{ + short int iterbackup = _list->_iterlevel; + _list->_iterlevel = 0; + DL_Iter::insend( ( void* ) newitem ); + _list->_iterlevel = iterbackup; +} + +template +void TDLI::insbegin_unsave( Type* newitem ) +{ + short int iterbackup = _list->_iterlevel; + _list->_iterlevel = 0; + DL_Iter::insbegin( ( void* ) newitem ); + _list->_iterlevel = iterbackup; +} + +template +void TDLI::insbefore_unsave( Type* newitem ) +{ + short int iterbackup = _list->_iterlevel; + _list->_iterlevel = 0; + DL_Iter::insbefore( ( void* ) newitem ); + _list->_iterlevel = iterbackup; +} + +template +void TDLI::insafter_unsave( Type* newitem ) +{ + short int iterbackup = _list->_iterlevel; + _list->_iterlevel = 0; + DL_Iter::insafter( ( void* ) newitem ); + _list->_iterlevel = iterbackup; +} + +template +void TDLI::mergesort( int ( *f )( Type* a, Type* b ) ) +{ + DL_Iter::mergesort( ( int ( * )( void*, void* ) ) f ); +} + +template +int TDLI::cocktailsort( int ( *f )( Type* a, Type* b ), bool ( *f2 )( Type* c, Type* d ) ) +{ + return DL_Iter::cocktailsort( ( int ( * )( void*, void* ) ) f, ( bool( * )( void*, void* ) ) f2 ); +} + +template +TDLISort::TDLISort( DL_List* lista, int ( *newfunc )( void*, void* ) ) + : DL_SortIter( lista, newfunc ) +{} + +template +TDLISort::~TDLISort() +{} + +template +void TDLISort::delete_all() +{ + DL_Node* 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 +bool TDLISort::has( Type* otheritem ) +{ + return DL_Iter::has( ( void* ) otheritem ); +} + +// goto to item +template +bool TDLISort::toitem( Type* item ) +{ + return DL_Iter::toitem( ( void* ) item ); +} + +// get current item +template +Type* TDLISort::item() +{ + return ( Type* ) DL_Iter::item(); +} + +template +TDLIStack::TDLIStack( DL_List* newlist ): DL_StackIter( newlist ) +{} + +// destructor TDLI +template +TDLIStack::~TDLIStack() +{} + +// plaats nieuw item op stack +template +void TDLIStack::push( Type* newitem ) +{ + DL_StackIter::push( ( Type* ) newitem ); +} + + +// haal bovenste item van stack +template +Type* TDLIStack::pop() +{ + return ( Type* ) DL_StackIter::pop(); +} + + diff --git a/polygon/kbool/include/kbool/_lnk_itr.h b/polygon/kbool/include/kbool/_lnk_itr.h new file mode 100644 index 0000000000..901fd1597f --- /dev/null +++ b/polygon/kbool/include/kbool/_lnk_itr.h @@ -0,0 +1,159 @@ +/*! \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.2 2006/12/15 21:00:05 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 + +//! headerfiles="_dl_itr.h stdlib.h misc.h gdsmes.h" +#include +#include "kbool/booleng.h" + +#define SWAP(x,y,t)((t)=(x),(x)=(y),(y)=(t)) + +#include "kbool/_dl_itr.h" + +//! codefiles="_dl_itr.cpp" + +//! Template class TDLI +/*! + class for iterator on DL_List that is type casted version of DL_Iter + \sa DL_Iter for further documentation +*/ +template class TDLI : public DL_Iter +{ +public: + //!constructor + /*! + \param list to iterate on. + */ + TDLI( DL_List* list ); + + //!constructor + TDLI( DL_Iter* 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* 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 that is type casted version of DL_SortIter +// see also inhereted class DL_SortIter for further documentation +*/ +template class TDLISort : public DL_SortIter +{ +public: + + //!constructor givin a list and a sort function + TDLISort( DL_List* 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 that is type casted version of DL_StackIter + see also inhereted class DL_StackIter for further documentation +*/ +template class TDLIStack : public DL_StackIter +{ +public: + //constructor givin a list + TDLIStack( DL_List* list ); + + ~TDLIStack(); + + void push( Type* ); + Type* pop(); +}; + +#include"kbool/_lnk_itr.cpp" + +#endif diff --git a/polygon/kbool/include/kbool/booleng.h b/polygon/kbool/include/kbool/booleng.h new file mode 100644 index 0000000000..ee0c96d2f2 --- /dev/null +++ b/polygon/kbool/include/kbool/booleng.h @@ -0,0 +1,583 @@ +/*! \file include/booleng.h + \author Klaas Holwerda + + Copyright: 2001-2004 (C) Klaas Holwerda + + Licence: see kboollicense.txt + + RCS-ID: $Id: booleng.h,v 1.4 2008/09/05 19:01:14 titato Exp $ +*/ + +#ifndef BOOLENG_H +#define BOOLENG_H + +#undef _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES +#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1 +#define _CRT_SECURE_NO_DEPRECATE 1 + +#include +#include +#include +#include + + +#if 0 // Kicad does not use kbool in dll version +#if defined(__WXMSW__) + /* + __declspec works in BC++ 5 and later, Watcom C++ 11.0 and later as well + as VC++ and gcc + */ +# if defined(__VISUALC__) || defined(__BORLANDC__) || defined(__GNUC__) || defined(__WATCOMC__) +# define WXEXPORT __declspec(dllexport) +# define WXIMPORT __declspec(dllimport) +# else /* compiler doesn't support __declspec() */ +# define WXEXPORT +# define WXIMPORT +# endif +#elif defined(__WXPM__) +# if defined (__WATCOMC__) +# define WXEXPORT __declspec(dllexport) + /* + __declspec(dllimport) prepends __imp to imported symbols. We do NOT + want that! + */ +# define WXIMPORT +# elif defined(__EMX__) +# define WXEXPORT +# define WXIMPORT +# elif (!(defined(__VISAGECPP__) && (__IBMCPP__ < 400 || __IBMC__ < 400 ))) +# define WXEXPORT _Export +# define WXIMPORT _Export +# endif +#elif defined(__WXMAC__) || defined(__WXCOCOA__) +# ifdef __MWERKS__ +# define WXEXPORT __declspec(export) +# define WXIMPORT __declspec(import) +# endif +#elif defined(__CYGWIN__) +# define WXEXPORT __declspec(dllexport) +# define WXIMPORT __declspec(dllimport) +#endif +#endif // if 0 for kicad + +/* for other platforms/compilers we don't anything */ +#ifndef WXEXPORT +# define WXEXPORT +# define WXIMPORT +#endif + +#ifdef A2DKBOOLMAKINGDLL +#define A2DKBOOLDLLEXP WXEXPORT +#define A2DKBOOLDLLEXP_DATA(type) WXEXPORT type +#define A2DKBOOLDLLEXP_CTORFN +#elif defined(WXART2D_USINGDLL) +#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.9" + +#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 +const B_INT MAXB_INT = ( 0x7fffffffffffffffLL ); // 8 bytes integer +const B_INT MINB_INT = ( 0x8000000000000000LL ); + +#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; // 8 bytes integer +const B_INT MAXB_INT = ( 0x7fffffffL ); // 8 bytes integer +const B_INT MINB_INT = ( 0x80000000L ); +#else +typedef long B_INT; // 8 bytes integer +const B_INT MAXB_INT = ( 0x7fffffff ); // 8 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 + +//! 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 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* _linkiter; + + //! how many time run intersections fase. + unsigned int m_intersectionruns; + +}; + +#endif diff --git a/polygon/kbool/include/kbool/graph.h b/polygon/kbool/include/kbool/graph.h new file mode 100644 index 0000000000..8208e04318 --- /dev/null +++ b/polygon/kbool/include/kbool/graph.h @@ -0,0 +1,207 @@ +/*! \file include/graph.h + \author Klaas Holwerda + + Copyright: 2001-2004 (C) Klaas Holwerda + + Licence: see kboollicense.txt + + RCS-ID: $Id: graph.h,v 1.3 2008/06/04 21:23:21 titato Exp $ +*/ + +/* @@(#) $Source: /cvsroot/wxart2d/wxArt2D/thirdparty/kbool/include/kbool/graph.h,v $ $Revision: 1.3 $ $Date: 2008/06/04 21:23:21 $ */ + +/* +Program GRAPH.H +Purpose Used to Intercect and other process functions +Last Update 03-04-1996 +*/ + +#ifndef GRAPH_H +#define GRAPH_H + +#include "kbool/booleng.h" +#include "kbool/_lnk_itr.h" +#include "kbool/link.h" +#include "kbool/line.h" +#include "kbool/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* _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* _linklist; + +}; + +#endif + + diff --git a/polygon/kbool/include/kbool/graphlst.h b/polygon/kbool/include/kbool/graphlst.h new file mode 100644 index 0000000000..d7c559d4c7 --- /dev/null +++ b/polygon/kbool/include/kbool/graphlst.h @@ -0,0 +1,65 @@ +/*! \file include/graphlst.h + \author Klaas Holwerda + + Copyright: 2001-2004 (C) Klaas Holwerda + + Licence: see kboollicense.txt + + RCS-ID: $Id: graphlst.h,v 1.3 2008/06/04 21:23:21 titato Exp $ +*/ + +/* @@(#) $Source: /cvsroot/wxart2d/wxArt2D/thirdparty/kbool/include/kbool/graphlst.h,v $ $Revision: 1.3 $ $Date: 2008/06/04 21:23:21 $ */ + +/* +Program GRAPHLST.H +Purpose Implements a list of graphs (header) +Last Update 11-03-1996 +*/ + +#ifndef GRAPHLIST_H +#define GRAPHLIST_H + +#include "kbool/booleng.h" + +#include "kbool/_lnk_itr.h" + +#include "kbool/graph.h" + +class Debug_driver; + + +class A2DKBOOLDLLEXP GraphList: public DL_List +{ +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 + diff --git a/polygon/kbool/include/kbool/kboolmod.h b/polygon/kbool/include/kbool/kboolmod.h new file mode 100644 index 0000000000..fb3b9e682d --- /dev/null +++ b/polygon/kbool/include/kbool/kboolmod.h @@ -0,0 +1,15 @@ +#ifndef __A2D_KBOOLMOD_H__ +#define __A2D_KBOOLMOD_H__ + +#include "kbool/booleng.h" +#include "kbool/graph.h" +#include "kbool/graphlst.h" +#include "kbool/line.h" +#include "kbool/link.h" +#include "kbool/lpoint.h" +#include "kbool/node.h" +#include "kbool/record.h" +#include "kbool/scanbeam.h" + +#endif + diff --git a/polygon/kbool/include/kbool/line.h b/polygon/kbool/include/kbool/line.h new file mode 100644 index 0000000000..ad86c38071 --- /dev/null +++ b/polygon/kbool/include/kbool/line.h @@ -0,0 +1,107 @@ +/*! \file include/line.h + \brief Mainy used for calculating crossings + \author Klaas Holwerda + + Copyright: 2001-2004 (C) Klaas Holwerda + + Licence: see kboollicense.txt + + RCS-ID: $Id: line.h,v 1.3 2008/06/04 21:23:21 titato Exp $ +*/ + +#ifndef LINE_H +#define LINE_H + +#include "kbool/booleng.h" +#include "kbool/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* _LI ); + +// Linecrosslist + void SortLineCrossings(); + bool CrossListEmpty(); + DL_List* 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 *linecrosslist; +}; + +#endif diff --git a/polygon/kbool/include/kbool/link.h b/polygon/kbool/include/kbool/link.h new file mode 100644 index 0000000000..4871c8a4ff --- /dev/null +++ b/polygon/kbool/include/kbool/link.h @@ -0,0 +1,230 @@ +/*! \file include/link.h + \brief Part of a graph, connection between nodes (Header) + \author Klaas Holwerda or Julian Smart + + Copyright: 2001-2004 (C) Klaas Holwerda + + Licence: see kboollicense.txt + + RCS-ID: $Id: link.h,v 1.3 2008/06/04 21:23:22 titato Exp $ +*/ + +#ifndef LINK_H +#define LINK_H + +#include "kbool/booleng.h" +#include "kbool/_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* recordNode ) { m_record = recordNode; } + + DL_Node* 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* m_record; +}; + +#endif + diff --git a/polygon/kbool/include/kbool/lpoint.h b/polygon/kbool/include/kbool/lpoint.h new file mode 100644 index 0000000000..6800bef245 --- /dev/null +++ b/polygon/kbool/include/kbool/lpoint.h @@ -0,0 +1,60 @@ +/*! \file include/lpoint.h + \author Klaas Holwerda + + Copyright: 2001-2004 (C) Klaas Holwerda + + Licence: see kboollicense.txt + + RCS-ID: $Id: lpoint.h,v 1.3 2008/06/04 21:23:22 titato Exp $ +*/ + +/* @@(#) $Source: /cvsroot/wxart2d/wxArt2D/thirdparty/kbool/include/kbool/lpoint.h,v $ $Revision: 1.3 $ $Date: 2008/06/04 21:23:22 $ */ + +/* +Program LPOINT.H +Purpose Definition of GDSII pointtype structure +Last Update 12-12-1995 +*/ + +#ifndef LPOINT_H +#define LPOINT_H + +#include "kbool/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 diff --git a/polygon/kbool/include/kbool/node.h b/polygon/kbool/include/kbool/node.h new file mode 100644 index 0000000000..19d8f3346c --- /dev/null +++ b/polygon/kbool/include/kbool/node.h @@ -0,0 +1,85 @@ +/*! \file include/node.h + \brief Holds a GDSII node structure (Header) + \author Klaas Holwerda + + Copyright: 2001-2004 (C) Klaas Holwerda + + Licence: see kboollicense.txt + + RCS-ID: $Id: node.h,v 1.3 2008/06/04 21:23:22 titato Exp $ +*/ + +#ifndef NODE_H +#define NODE_H + +#include "kbool/booleng.h" + +#include "kbool/lpoint.h" + +#include "kbool/link.h" +#include "kbool/_lnk_itr.h" // LinkBaseIter +#include + +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* 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* _linklist; +}; + +#endif diff --git a/polygon/kbool/include/kbool/record.h b/polygon/kbool/include/kbool/record.h new file mode 100644 index 0000000000..aeb7f18b5e --- /dev/null +++ b/polygon/kbool/include/kbool/record.h @@ -0,0 +1,78 @@ +/*! \file include/record.h + \author Klaas Holwerda + + Copyright: 2001-2004 (C) Klaas Holwerda + + Licence: see kboollicense.txt + + RCS-ID: $Id: record.h,v 1.3 2008/06/04 21:23:22 titato Exp $ +*/ + +#ifndef RECORD_H +#define RECORD_H + +class Node; +#include "kbool/booleng.h" + +#include "kbool/link.h" +#include "kbool/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 diff --git a/polygon/kbool/include/kbool/scanbeam.h b/polygon/kbool/include/kbool/scanbeam.h new file mode 100644 index 0000000000..73794737e9 --- /dev/null +++ b/polygon/kbool/include/kbool/scanbeam.h @@ -0,0 +1,58 @@ +/*! \file include/scanbeam.h + \author Klaas Holwerda + + Copyright: 2001-2004 (C) Klaas Holwerda + + Licence: see kboollicense.txt + + RCS-ID: $Id: scanbeam.h,v 1.4 2008/09/05 19:01:14 titato Exp $ +*/ + +#ifndef SCANBEAM_H +#define SCANBEAM_H + +#include "kbool/booleng.h" +#include "kbool/_lnk_itr.h" + +#include "kbool/record.h" +#include "kbool/link.h" + +enum SCANTYPE{NODELINK, LINKLINK, GENLR, LINKHOLES, INOUT}; + +#if defined(WXART2D_USINGDLL) +template class A2DKBOOLDLLEXP DL_Iter; +#endif + +class A2DKBOOLDLLEXP ScanBeam : public DL_List +{ +protected: + Bool_Engine* _GC; + +public: + ScanBeam( Bool_Engine* GC ); + ~ScanBeam(); + void SetType( Node* low, Node* high ); + + bool FindNew( SCANTYPE scantype, TDLI* _I, bool& holes ); + bool RemoveOld( SCANTYPE scantype, TDLI* _I, bool& holes ); + +private: + + bool ProcessHoles( bool atinsert, TDLI* _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* _I,Node* _lowf); + void Generate_INOUT( int graphnumber ); + + Node* _low; + DL_Iter _BI; + int lastinserted; + BEAM_TYPE _type; +}; + +#endif diff --git a/polygon/kbool/include/kbool/statusb.h b/polygon/kbool/include/kbool/statusb.h new file mode 100644 index 0000000000..6eea40d337 --- /dev/null +++ b/polygon/kbool/include/kbool/statusb.h @@ -0,0 +1,54 @@ +/*! \file kbool/include/kbool/statusb.h + \author Probably Klaas Holwerda + + Copyright: 2001-2004 (C) Probably Klaas Holwerda + + Licence: wxWidgets Licence + + RCS-ID: $Id: statusb.h,v 1.2 2006/12/15 21:00:06 titato Exp $ +*/ + +/* @@(#) $Source: /cvsroot/wxart2d/wxArt2D/thirdparty/kbool/include/kbool/statusb.h,v $ $Revision: 1.2 $ $Date: 2006/12/15 21:00:06 $ */ + +/* +Program STATUSB.H +Purpose Controls the statusbar of the application (header) + This statusbar is a typical Windows statusbar + For porting to another platform there must be a StatusBar class + derived from this. + User interface element (See documentation for more details + about the functions needed in this class) +*/ + +#ifndef STATUSB_H +#define STATUSB_H +#include + +// abstract base class for own statusbar inherite from it +class A2DKBOOLDLLEXP StatusBar +{ +public: + // constructor & destructor + StatusBar(){}; + ~StatusBar(){}; + + virtual void SetXY( double = 0.0, double = 0.0 ) = 0; + virtual void ResetCoord() = 0; + virtual void SetFile( char* = 0 ) = 0; + virtual void SetProcess( char* = 0 ) = 0; + virtual void SetTime( time_t seconds = 0 ) = 0; + virtual void SetRecording( int status = 0 ) = 0; + virtual void SetZoom( float factor = 1 ) = 0; + virtual void Reset() = 0; + void StartDTimer(); + void EndDTimer(); + int GetDTimerOn(); + time_t GetDTimer(); + +protected: + int timer; + time_t oldtime; + time_t curtime; +}; + +#endif diff --git a/polygon/kbool/include/valuesvc.h b/polygon/kbool/include/kbool/valuesvc.h similarity index 70% rename from polygon/kbool/include/valuesvc.h rename to polygon/kbool/include/kbool/valuesvc.h index f6a4928ebb..a29af2bdfb 100644 --- a/polygon/kbool/include/valuesvc.h +++ b/polygon/kbool/include/kbool/valuesvc.h @@ -1,9 +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 $ + + RCS-ID: $Id: valuesvc.h,v 1.1 2006/11/04 21:49:01 titato Exp $ */ diff --git a/polygon/kbool/include/kboolmod.h b/polygon/kbool/include/kboolmod.h deleted file mode 100644 index c124ca7e36..0000000000 --- a/polygon/kbool/include/kboolmod.h +++ /dev/null @@ -1,15 +0,0 @@ -#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 - \ No newline at end of file diff --git a/polygon/kbool/include/line.h b/polygon/kbool/include/line.h deleted file mode 100644 index 6a7c687083..0000000000 --- a/polygon/kbool/include/line.h +++ /dev/null @@ -1,111 +0,0 @@ -/*! \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* _LI); - -// Linecrosslist - void SortLineCrossings(); - bool CrossListEmpty(); - DL_List* 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 *linecrosslist; -}; - -#endif diff --git a/polygon/kbool/include/link.h b/polygon/kbool/include/link.h deleted file mode 100644 index dab6dbdb59..0000000000 --- a/polygon/kbool/include/link.h +++ /dev/null @@ -1,234 +0,0 @@ -/*! \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* recordNode ) { m_record = recordNode; } - - DL_Node* 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* m_record; -}; - -#endif - diff --git a/polygon/kbool/include/lpoint.h b/polygon/kbool/include/lpoint.h deleted file mode 100644 index e264297552..0000000000 --- a/polygon/kbool/include/lpoint.h +++ /dev/null @@ -1,64 +0,0 @@ -/*! \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 diff --git a/polygon/kbool/include/node.h b/polygon/kbool/include/node.h deleted file mode 100644 index 9b818d7910..0000000000 --- a/polygon/kbool/include/node.h +++ /dev/null @@ -1,89 +0,0 @@ -/*! \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 -#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* 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* _linklist; -}; - -#endif diff --git a/polygon/kbool/include/record.h b/polygon/kbool/include/record.h deleted file mode 100644 index 8775d60014..0000000000 --- a/polygon/kbool/include/record.h +++ /dev/null @@ -1,82 +0,0 @@ -/*! \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 diff --git a/polygon/kbool/include/scanbeam.h b/polygon/kbool/include/scanbeam.h deleted file mode 100644 index b4f659fc6b..0000000000 --- a/polygon/kbool/include/scanbeam.h +++ /dev/null @@ -1,66 +0,0 @@ -/*! \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 0 // Kicad does dot use wxWidgets lib when building the kbool library - // but uses wxWidgets. So WXUSINGDLL could be defined in makefiles - // but must not be used when building kbool -#if defined(WXUSINGDLL) -template class A2DKBOOLDLLEXP DL_Iter; -#endif -#endif - -class A2DKBOOLDLLEXP ScanBeam : public DL_List -{ - protected: - Bool_Engine* _GC; - - public: - ScanBeam(Bool_Engine* GC); - ~ScanBeam(); - void SetType(Node* low,Node* high); - - bool FindNew(SCANTYPE scantype,TDLI* _I, bool& holes ); - bool RemoveOld(SCANTYPE scantype,TDLI* _I, bool& holes ); - - private: - - bool ProcessHoles(bool atinsert,TDLI* _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* _I,Node* _lowf); - void Generate_INOUT(int graphnumber); - - Node* _low; - DL_Iter _BI; - int lastinserted; - BEAM_TYPE _type; -}; - -#endif diff --git a/polygon/kbool/infos_and_license.txt b/polygon/kbool/infos_and_license.txt deleted file mode 100644 index 63e86db311..0000000000 --- a/polygon/kbool/infos_and_license.txt +++ /dev/null @@ -1,10 +0,0 @@ -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 diff --git a/polygon/kbool/infos_kbool.txt b/polygon/kbool/infos_kbool.txt new file mode 100644 index 0000000000..60763fef5f --- /dev/null +++ b/polygon/kbool/infos_kbool.txt @@ -0,0 +1,7 @@ +Boolean: GDSII viewer/editor + (boolean) operations on sets of 2d polygons. +Boolean Web Site: +http://boolean.klaasholwerda.nl/bool.html + +kbool is also used in wxArt2D +see www.wxart2d.org +the last version of kbool can be found on this site. diff --git a/polygon/kbool/kboollicense.txt b/polygon/kbool/kboollicense.txt new file mode 100644 index 0000000000..ba18bacda0 --- /dev/null +++ b/polygon/kbool/kboollicense.txt @@ -0,0 +1,684 @@ +The kbool library is dual licensed. +The GPL applies for open source, but for commercial use it is proprietary. +Contact copyright holder for more information on other licensing schemes. + +Software library is provided "AS IS" without warranty of any kind, conform point 16 and 17 down here. + +Next a copy of the GPL license text. + +========================================================================== + + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program 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, either version 3 of the License, or + (at your option) any later version. + + 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. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. \ No newline at end of file diff --git a/polygon/kbool/src/CMakeLists.txt b/polygon/kbool/src/CMakeLists.txt index 29853b81fb..f35d688bf8 100644 --- a/polygon/kbool/src/CMakeLists.txt +++ b/polygon/kbool/src/CMakeLists.txt @@ -1,10 +1,11 @@ -if(WIN32) - add_definitions(-D_MSWVC_) -else(WIN32) - add_definitions(-D__UNIX__) -endif(WIN32) +IF(WIN32) + ADD_DEFINITIONS( -D_MSWVC_ ) +ELSE(WIN32) + ADD_DEFINITIONS( -D__UNIX__ ) +ENDIF(WIN32) -include_directories(${kbool_SOURCE_DIR}/include) + +include_directories(../include) set(KBOOL_SRCS booleng.cpp diff --git a/polygon/kbool/src/booleng.cpp b/polygon/kbool/src/booleng.cpp index 0df202bb2c..0fc1b05ff0 100644 --- a/polygon/kbool/src/booleng.cpp +++ b/polygon/kbool/src/booleng.cpp @@ -1,111 +1,107 @@ -/*! \file kbool/src/booleng.cpp - \author Probably Klaas Holwerda +/*! \file src/booleng.cpp + \author Klaas Holwerda - Copyright: 2001-2004 (C) Probably Klaas Holwerda + Copyright: 2001-2004 (C) Klaas Holwerda - Licence: wxWidgets Licence + Licence: see kboollicense.txt - RCS-ID: $Id: booleng.cpp,v 1.11 2005/05/24 19:13:38 titato Exp $ + RCS-ID: $Id: booleng.cpp,v 1.3 2008/06/04 21:23:22 titato Exp $ */ -#ifdef __GNUG__ -#pragma implementation -#endif +#include "kbool/booleng.h" -#include #include -#include "../include/booleng.h" -#include "../include/link.h" -#include "../include/line.h" -#include "../include/node.h" -#include "../include/graph.h" -#include "../include/graphlst.h" +#include "kbool/link.h" +#include "kbool/line.h" +#include "kbool/node.h" +#include "kbool/graph.h" +#include "kbool/graphlst.h" -B_INT bmin(B_INT const value1, B_INT const value2) +B_INT bmin( B_INT const value1, B_INT const value2 ) { - return((value1 < value2) ? value1 : value2 ); + return( ( value1 < value2 ) ? value1 : value2 ); } -B_INT bmax(B_INT const value1, B_INT const value2) +B_INT bmax( B_INT const value1, B_INT const value2 ) { - return((value1 > value2) ? value1 : value2 ); + return( ( value1 > value2 ) ? value1 : value2 ); } -B_INT babs(B_INT a) +B_INT babs( B_INT a ) { - if (a < 0) a=-a; - return 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) +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"); + _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"); + if ( header ) + strcpy( _header, header ); + else + strcpy( _header, "non specified" ); - _degree = degree; - _fatal = fatal; + _degree = degree; + _fatal = fatal; } -Bool_Engine_Error::Bool_Engine_Error(const Bool_Engine_Error& a) +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"); + _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"); + if ( a._header ) + strcpy( _header, a._header ); + else + strcpy( _header, "non specified" ); - _degree = a._degree; - _fatal = a._fatal; + _degree = a._degree; + _fatal = a._fatal; } Bool_Engine_Error::~Bool_Engine_Error() { - strcpy(_message,""); - strcpy(_header,""); - delete _message; - delete _header; + strcpy( _message, "" ); + strcpy( _header, "" ); + delete _message; + delete _header; } char* Bool_Engine_Error::GetErrorMessage() { - return _message; + return _message; } char* Bool_Engine_Error::GetHeaderMessage() { - return _header; + return _header; } int Bool_Engine_Error::GetErrorDegree() { - return _degree; + return _degree; } int Bool_Engine_Error::GetFatal() { - return _fatal; + return _fatal; } //-------------------------------------------------------------------/ @@ -114,91 +110,91 @@ int Bool_Engine_Error::GetFatal() Bool_Engine::Bool_Engine() { - _linkiter=new TDLI(); - m_intersectionruns = 1; + _linkiter = new TDLI(); + 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_orientationEntryMode = false; + m_doLinkHoles = true; - m_logfile = NULL; + 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 ); + SetLog( true ); #else - SetLog( false ); + SetLog( false ); #endif } Bool_Engine::~Bool_Engine() { - if (m_logfile != NULL) - fclose (m_logfile); + if ( m_logfile != NULL ) + fclose ( m_logfile ); - delete _linkiter; - delete m_graphlist; + 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); + 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; - } - } + 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); + Write_Log( process ); } -void Bool_Engine::error(const char *text,const char *title) +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); + 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) +void Bool_Engine::info( const char *text, const char *title ) { - Write_Log("FATAL ERROR: ", title); - Write_Log("FATAL ERROR: ", text); + Write_Log( "FATAL ERROR: ", title ); + Write_Log( "FATAL ERROR: ", text ); }; -void Bool_Engine::SetMarge(double marge) +void Bool_Engine::SetMarge( double marge ) { m_MARGE = marge; - Write_Log("Bool_Engine::m_MARGE = %f\n", m_MARGE); + Write_Log( "Bool_Engine::m_MARGE = %f\n", m_MARGE ); } double Bool_Engine::GetAccur() @@ -206,10 +202,10 @@ double Bool_Engine::GetAccur() return m_ACCUR; } -void Bool_Engine::SetRoundfactor(double roundfac) +void Bool_Engine::SetRoundfactor( double roundfac ) { m_ROUNDFACTOR = roundfac; - Write_Log("Bool_Engine::m_ROUNDFACTOR = %f\n", m_ROUNDFACTOR); + Write_Log( "Bool_Engine::m_ROUNDFACTOR = %f\n", m_ROUNDFACTOR ); } double Bool_Engine::GetRoundfactor() @@ -222,10 +218,10 @@ double Bool_Engine::GetMarge() return m_MARGE; } -void Bool_Engine::SetDGrid(double dgrid) +void Bool_Engine::SetDGrid( double dgrid ) { m_DGRID = dgrid; - Write_Log("Bool_Engine::m_DGRID = %f\n", m_DGRID); + Write_Log( "Bool_Engine::m_DGRID = %f\n", m_DGRID ); } double Bool_Engine::GetDGrid() @@ -233,10 +229,10 @@ double Bool_Engine::GetDGrid() return m_DGRID; } -void Bool_Engine::SetGrid(B_INT grid) +void Bool_Engine::SetGrid( B_INT grid ) { m_GRID = grid; - Write_Log("Bool_Engine::m_GRID = %lld\n", m_GRID); + Write_Log( "Bool_Engine::m_GRID = %lld\n", m_GRID ); } B_INT Bool_Engine::GetGrid() @@ -244,10 +240,10 @@ B_INT Bool_Engine::GetGrid() return m_GRID; } -void Bool_Engine::SetCorrectionAber(double aber) +void Bool_Engine::SetCorrectionAber( double aber ) { m_CORRECTIONABER = aber; - Write_Log("Bool_Engine::m_CORRECTIONABER = %f\n", m_CORRECTIONABER); + Write_Log( "Bool_Engine::m_CORRECTIONABER = %f\n", m_CORRECTIONABER ); } double Bool_Engine::GetCorrectionAber() @@ -255,10 +251,10 @@ double Bool_Engine::GetCorrectionAber() return m_CORRECTIONABER; } -void Bool_Engine::SetCorrectionFactor(double aber) +void Bool_Engine::SetCorrectionFactor( double aber ) { m_CORRECTIONFACTOR = aber; - Write_Log("Bool_Engine::m_CORRECTIONFACTOR = %f\n", m_CORRECTIONFACTOR ); + Write_Log( "Bool_Engine::m_CORRECTIONFACTOR = %f\n", m_CORRECTIONFACTOR ); } double Bool_Engine::GetCorrectionFactor() @@ -266,10 +262,10 @@ double Bool_Engine::GetCorrectionFactor() return m_CORRECTIONFACTOR; } -void Bool_Engine::SetSmoothAber(double aber) +void Bool_Engine::SetSmoothAber( double aber ) { m_SMOOTHABER = aber; - Write_Log("Bool_Engine::m_SMOOTHABER = %f\n",m_SMOOTHABER ); + Write_Log( "Bool_Engine::m_SMOOTHABER = %f\n", m_SMOOTHABER ); } double Bool_Engine::GetSmoothAber() @@ -277,10 +273,10 @@ double Bool_Engine::GetSmoothAber() return m_SMOOTHABER; } -void Bool_Engine::SetMaxlinemerge(double maxline) +void Bool_Engine::SetMaxlinemerge( double maxline ) { m_MAXLINEMERGE = maxline; - Write_Log("Bool_Engine::m_MAXLINEMERGE = %f\n",m_MAXLINEMERGE ); + Write_Log( "Bool_Engine::m_MAXLINEMERGE = %f\n", m_MAXLINEMERGE ); } double Bool_Engine::GetMaxlinemerge() @@ -288,7 +284,7 @@ double Bool_Engine::GetMaxlinemerge() return m_MAXLINEMERGE; } -void Bool_Engine::SetWindingRule(bool rule) +void Bool_Engine::SetWindingRule( bool rule ) { m_WINDINGRULE = rule; } @@ -301,226 +297,226 @@ bool Bool_Engine::GetWindingRule() void Bool_Engine::SetInternalMarge( B_INT marge ) { - m_MARGE = (double)marge/m_GRID/m_DGRID; + m_MARGE = ( double )marge / m_GRID / m_DGRID; } B_INT Bool_Engine::GetInternalMarge() { - return (B_INT) ( m_MARGE*m_GRID*m_DGRID ); + return ( B_INT ) ( m_MARGE * m_GRID * m_DGRID ); } double Bool_Engine::GetInternalCorrectionAber() { - return m_CORRECTIONABER*m_GRID*m_DGRID; + return m_CORRECTIONABER * m_GRID * m_DGRID; } double Bool_Engine::GetInternalCorrectionFactor() { - return m_CORRECTIONFACTOR*m_GRID*m_DGRID; + return m_CORRECTIONFACTOR * m_GRID * m_DGRID; } double Bool_Engine::GetInternalSmoothAber() { - return m_SMOOTHABER*m_GRID*m_DGRID; + return m_SMOOTHABER * m_GRID * m_DGRID; } B_INT Bool_Engine::GetInternalMaxlinemerge() { - return (B_INT) ( m_MAXLINEMERGE*m_GRID*m_DGRID ); + return ( B_INT ) ( m_MAXLINEMERGE * m_GRID * m_DGRID ); } -#define TRIALS 30 +#define TRIALS 30 -bool Bool_Engine::Do_Operation(BOOL_OP operation) +bool Bool_Engine::Do_Operation( BOOL_OP operation ) { #if KBOOL_DEBUG - GraphList* saveme = new GraphList( m_graphlist ); + 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) - { + 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); + delete m_graphlist; + m_graphlist = new GraphList( saveme ); + m_graphlist->WriteGraphsKEY( this ); #endif - if (m_logfile != NULL) - { - fclose (m_logfile); - m_logfile = NULL; - } + if ( m_logfile != NULL ) + { + fclose ( m_logfile ); + m_logfile = NULL; + } - info(error.GetErrorMessage(), "error"); - throw error; - } - catch(...) - { + info( error.GetErrorMessage(), "error" ); + throw error; + } + catch( ... ) + { #if KBOOL_DEBUG - delete m_graphlist; - m_graphlist = new GraphList( saveme ); - m_graphlist->WriteGraphsKEY(this); + delete m_graphlist; + m_graphlist = new GraphList( saveme ); + m_graphlist->WriteGraphsKEY( this ); #endif - if (m_logfile != NULL) - { - fclose (m_logfile); - m_logfile = NULL; - } + if ( m_logfile != NULL ) + { + fclose ( m_logfile ); + m_logfile = NULL; + } - info("Unknown exception", "error"); - throw ; - } + info( "Unknown exception", "error" ); + throw ; + } #if KBOOL_DEBUG - delete saveme; + delete saveme; #endif - return true; + return true; } -bool Bool_Engine::StartPolygonAdd(GroupType A_or_B) +bool Bool_Engine::StartPolygonAdd( GroupType A_or_B ) { #if KBOOL_DEBUG - if (m_logfile != NULL) - fprintf(m_logfile, "-> StartPolygonAdd(%d)\n", A_or_B); + if ( m_logfile != NULL ) + fprintf( m_logfile, "-> StartPolygonAdd(%d)\n", A_or_B ); #endif - if (m_GraphToAdd != NULL) - return false; + if ( m_GraphToAdd != NULL ) + return false; - Graph *myGraph = new Graph(this); - m_graphlist->insbegin(myGraph); + 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) +bool Bool_Engine::AddPoint( double x, double y ) { - if (m_GraphToAdd == NULL){return false;} + if ( m_GraphToAdd == NULL ){return false;} - double scaledx = x * m_DGRID * m_GRID; - double scaledy = y * m_DGRID * m_GRID; + 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", "" ); + 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 ); + 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 ( 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) ; - } + 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 - { + 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) ; - } + 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; - } + m_GraphToAdd->AddLink( m_lastNodeToAdd, myNode ); + m_lastNodeToAdd = ( Node * ) myNode; + } - return true; + return true; } bool Bool_Engine::EndPolygonAdd() { - if (m_GraphToAdd == NULL) {return false;} + 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; + m_GraphToAdd->AddLink( m_lastNodeToAdd, m_firstNodeToAdd ); + m_GraphToAdd->SetGroup( m_groupType ); + m_GraphToAdd = NULL; + m_lastNodeToAdd = NULL; + m_firstNodeToAdd = NULL; - return true; + 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; - } + 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) + if ( m_numNodesVisited == 0 ) { // don't need to touch the m_getNode m_numNodesVisited++; return true; } - if (m_numNodesVisited < m_numPtsInPolygon) + 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_getNode = m_getLink->GetOther( m_getNode ); + m_getLink = m_getLink->Forth( m_getNode ); m_numNodesVisited++; return true; @@ -539,26 +535,26 @@ void Bool_Engine::EndPolygonGet() double Bool_Engine::GetPolygonXPoint() { - return m_getNode->GetX()/m_GRID/m_DGRID; + return m_getNode->GetX() / m_GRID / m_DGRID; } double Bool_Engine::GetPolygonYPoint() { - return m_getNode->GetY()/m_GRID/m_DGRID; + return m_getNode->GetY() / m_GRID / m_DGRID; } bool Bool_Engine::GetHoleSegment() { - if (m_getLink->GetHole()) - return true; - return false; + if ( m_getLink->GetHole() ) + return true; + return false; } bool Bool_Engine::GetHoleConnectionSegment() { - if (m_getLink->GetHoleLink()) - return true; - return false; + if ( m_getLink->GetHoleLink() ) + return true; + return false; } kbEdgeType Bool_Engine::GetPolygonPointEdgeType() @@ -575,34 +571,34 @@ kbEdgeType Bool_Engine::GetPolygonPointEdgeType() } -void Bool_Engine::Write_Log(const char *msg1) +void Bool_Engine::Write_Log( const char *msg1 ) { - if (m_logfile == NULL) - return; + if ( m_logfile == NULL ) + return; - fprintf(m_logfile,"%s \n",msg1); + fprintf( m_logfile, "%s \n", msg1 ); } -void Bool_Engine::Write_Log(const char *msg1, const char*msg2) +void Bool_Engine::Write_Log( const char *msg1, const char*msg2 ) { - if (m_logfile == NULL) - return; + if ( m_logfile == NULL ) + return; - fprintf(m_logfile,"%s %s\n",msg1, msg2); + fprintf( m_logfile, "%s %s\n", msg1, msg2 ); } -void Bool_Engine::Write_Log(const char *fmt, double dval) +void Bool_Engine::Write_Log( const char *fmt, double dval ) { - if (m_logfile == NULL) - return; + if ( m_logfile == NULL ) + return; - fprintf(m_logfile,fmt,dval); + fprintf( m_logfile, fmt, dval ); } -void Bool_Engine::Write_Log(const char *fmt, B_INT bval) +void Bool_Engine::Write_Log( const char *fmt, B_INT bval ) { - if (m_logfile == NULL) - return; + if ( m_logfile == NULL ) + return; - fprintf(m_logfile,fmt,bval); + fprintf( m_logfile, fmt, bval ); } diff --git a/polygon/kbool/src/graph.cpp b/polygon/kbool/src/graph.cpp index 7a4f4f2bb1..c93b0a0921 100644 --- a/polygon/kbool/src/graph.cpp +++ b/polygon/kbool/src/graph.cpp @@ -1,294 +1,287 @@ -/*! \file ../src/graph.cpp +/*! \file src/graph.cpp \brief Used to Intercect and other process functions - \author Probably Klaas Holwerda - - Copyright: 2001-2004 (C) Probably Klaas Holwerda - - Licence: wxWidgets Licence - - RCS-ID: $Id: graph.cpp,v 1.13 2005/06/17 22:42:58 kbluck Exp $ + \author Klaas Holwerda + + Copyright: 2001-2004 (C) Klaas Holwerda + + Licence: see kboollicense.txt + + RCS-ID: $Id: graph.cpp,v 1.3 2008/06/04 21:23:22 titato Exp $ */ // Grpah is the structure used to store polygons -#ifdef __GNUG__ -#pragma implementation -#endif - -#include -#include - -#include "../include/booleng.h" -#include "../include/graph.h" -#include "../include/graphlst.h" -#include "../include/node.h" +#include "kbool/booleng.h" +#include "kbool/graph.h" +#include "kbool/graphlst.h" +#include "kbool/node.h" // Prototype of function -int linkXYsorter(KBoolLink *, KBoolLink *); -int linkYXsorter(KBoolLink *, KBoolLink *); -int linkLsorter(KBoolLink *, KBoolLink *); -int linkYXtopsorter(KBoolLink *a, KBoolLink *b); -int linkGraphNumsorter(KBoolLink *_l1, KBoolLink* _l2); +int linkXYsorter( KBoolLink *, KBoolLink * ); +int linkYXsorter( KBoolLink *, KBoolLink * ); +int linkLsorter( KBoolLink *, KBoolLink * ); +int linkYXtopsorter( KBoolLink *a, KBoolLink *b ); +int linkGraphNumsorter( KBoolLink *_l1, KBoolLink* _l2 ); // constructor, initialize with one link // usage: Graph *a_graph = new Graph(a_link); -Graph::Graph(KBoolLink *a_link, Bool_Engine* GC ) +Graph::Graph( KBoolLink *a_link, Bool_Engine* GC ) { - _GC = GC; - _linklist=new DL_List(); + _GC = GC; + _linklist = new DL_List(); - _linklist->insbegin(a_link); - _bin = false; + _linklist->insbegin( a_link ); + _bin = false; } // constructor, initialize graph with no contents // usage: Graph *a_graph = new Graph(); -Graph::Graph(Bool_Engine* GC) +Graph::Graph( Bool_Engine* GC ) { - _GC = GC; - _linklist=new DL_List(); - _bin = false; + _GC = GC; + _linklist = new DL_List(); + _bin = false; } Graph::Graph( Graph* other ) { - _GC = other->_GC; - _linklist = new DL_List(); - _bin = false; + _GC = other->_GC; + _linklist = new DL_List(); + _bin = false; - int _nr_of_points = other->_linklist->count(); - KBoolLink* _current = other->GetFirstLink(); + int _nr_of_points = other->_linklist->count(); + KBoolLink* _current = other->GetFirstLink(); - Node* _last = _current->GetBeginNode(); - Node* node = new Node( _current->GetBeginNode()->GetX(), _current->GetBeginNode()->GetY(), _GC ); - Node* nodefirst = node; - for (int i = 0; i < _nr_of_points; i++) - { - // get the other node on the link - _last = _current->GetOther(_last); - // get the other link on the _last node - _current = _current->Forth(_last); + Node* _last = _current->GetBeginNode(); + Node* node = new Node( _current->GetBeginNode()->GetX(), _current->GetBeginNode()->GetY(), _GC ); + Node* nodefirst = node; + for ( int i = 0; i < _nr_of_points; i++ ) + { + // get the other node on the link + _last = _current->GetOther( _last ); + // get the other link on the _last node + _current = _current->Forth( _last ); - Node* node2 = new Node( _current->GetBeginNode()->GetX(), _current->GetBeginNode()->GetY(), _GC ); - _linklist->insend( new KBoolLink( node, node2, _GC ) ); - node = node2; - } - _linklist->insend( new KBoolLink( node, nodefirst, _GC ) ); + Node* node2 = new Node( _current->GetBeginNode()->GetX(), _current->GetBeginNode()->GetY(), _GC ); + _linklist->insend( new KBoolLink( node, node2, _GC ) ); + node = node2; + } + _linklist->insend( new KBoolLink( node, nodefirst, _GC ) ); } // destructor // deletes all object of the linklist Graph::~Graph() { - { - TDLI _LI=TDLI(_linklist); + { + TDLI _LI = TDLI( _linklist ); - //first empty the graph - _LI.delete_all(); - } + //first empty the graph + _LI.delete_all(); + } - delete _linklist; + delete _linklist; } -KBoolLink* Graph::GetFirstLink() +KBoolLink* Graph::GetFirstLink() { - return (KBoolLink*) _linklist->headitem(); + return ( KBoolLink* ) _linklist->headitem(); }; void Graph::Prepare( int intersectionruns ) { - _GC->SetState("Intersection"); + _GC->SetState( "Intersection" ); - bool found = true; - int run = 0; - while( run < intersectionruns && found ) - { - found = CalculateCrossings(_GC->GetInternalMarge()); - run++; - } + bool found = true; + int run = 0; + while( run < intersectionruns && found ) + { + found = CalculateCrossings( _GC->GetInternalMarge() ); + run++; + } //WHY -// Round(_GC->Get_Grid()); +// Round(_GC->Get_Grid()); - { - TDLI _LI=TDLI(_linklist); - _LI.foreach_mf(&KBoolLink::UnMark);// Reset Bin and Mark flag - } - _GC->SetState("Set group A/B Flags"); + { + TDLI _LI = TDLI( _linklist ); + _LI.foreach_mf( &KBoolLink::UnMark );// Reset Bin and Mark flag + } + _GC->SetState( "Set group A/B Flags" ); - bool dummy = false; + bool dummy = false; - if (_GC->GetWindingRule()) - ScanGraph2( INOUT, dummy ); + if ( _GC->GetWindingRule() ) + ScanGraph2( INOUT, dummy ); - ScanGraph2( GENLR, dummy ); + ScanGraph2( GENLR, dummy ); -// writegraph(); +// writegraph(); - _GC->SetState("Set operation Flags"); - Set_Operation_Flags(); + _GC->SetState( "Set operation Flags" ); + Set_Operation_Flags(); - _GC->SetState("Remove doubles"); - // Remove the marked links - { - TDLI _LI=TDLI(_linklist); - _LI.tohead(); - while(!_LI.hitroot()) - { - if (_LI.item()->IsMarked()) - { - delete _LI.item(); - _LI.remove(); - } - else - _LI++; - } - } + _GC->SetState( "Remove doubles" ); + // Remove the marked links + { + TDLI _LI = TDLI( _linklist ); + _LI.tohead(); + while( !_LI.hitroot() ) + { + if ( _LI.item()->IsMarked() ) + { + delete _LI.item(); + _LI.remove(); + } + else + _LI++; + } + } - _GC->SetState("Remove inlinks"); - Remove_IN_Links(); + _GC->SetState( "Remove inlinks" ); + Remove_IN_Links(); - _GC->SetState("Finished prepare graph"); + _GC->SetState( "Finished prepare graph" ); } // x and y of the point will be rounded to the nearest // xnew=N*grid and ynew=N*grid -void Graph::RoundInt(B_INT grid) +void Graph::RoundInt( B_INT grid ) { - TDLI _LI=TDLI(_linklist); - _LI.tohead(); - while (!_LI.hitroot()) - { - _LI.item()->GetBeginNode()->RoundInt(grid); - _LI.item()->GetEndNode()->RoundInt(grid); - _LI++; - } + TDLI _LI = TDLI( _linklist ); + _LI.tohead(); + while ( !_LI.hitroot() ) + { + _LI.item()->GetBeginNode()->RoundInt( grid ); + _LI.item()->GetEndNode()->RoundInt( grid ); + _LI++; + } } // rotate graph minus 90 degrees or plus 90 degrees -void Graph::Rotate(bool plus90) +void Graph::Rotate( bool plus90 ) { - B_INT swap; - Node* last=NULL; + B_INT swap; + Node* last = NULL; - B_INT neg=-1; - if (plus90) - neg=1; + B_INT neg = -1; + if ( plus90 ) + neg = 1; - TDLI _LI=TDLI(_linklist); - _LI.mergesort(linkXYsorter); + TDLI _LI = TDLI( _linklist ); + _LI.mergesort( linkXYsorter ); - _LI.tohead(); - while (!_LI.hitroot()) - { - if (_LI.item()->GetBeginNode() != last) - { - swap=_LI.item()->GetBeginNode()->GetX(); - _LI.item()->GetBeginNode()->SetX(-neg*(_LI.item()->GetBeginNode()->GetY())); - _LI.item()->GetBeginNode()->SetY(neg*swap); - last=_LI.item()->GetBeginNode(); - } - _LI++; - } + _LI.tohead(); + while ( !_LI.hitroot() ) + { + if ( _LI.item()->GetBeginNode() != last ) + { + swap = _LI.item()->GetBeginNode()->GetX(); + _LI.item()->GetBeginNode()->SetX( -neg * ( _LI.item()->GetBeginNode()->GetY() ) ); + _LI.item()->GetBeginNode()->SetY( neg * swap ); + last = _LI.item()->GetBeginNode(); + } + _LI++; + } } bool Graph::RemoveNullLinks() { - bool graph_is_modified = false; + bool graph_is_modified = false; - TDLI _LI=TDLI(_linklist); - _LI.tohead(); - while (!_LI.hitroot()) - { - if (_LI.item()->GetBeginNode() == _LI.item()->GetEndNode()) - { - _LI.item()->MergeNodes(_LI.item()->GetBeginNode()); - delete _LI.item(); - _LI.remove(); - graph_is_modified = true; - } - else - _LI++; - } - return (graph_is_modified); + TDLI _LI = TDLI( _linklist ); + _LI.tohead(); + while ( !_LI.hitroot() ) + { + if ( _LI.item()->GetBeginNode() == _LI.item()->GetEndNode() ) + { + _LI.item()->MergeNodes( _LI.item()->GetBeginNode() ); + delete _LI.item(); + _LI.remove(); + graph_is_modified = true; + } + else + _LI++; + } + return ( graph_is_modified ); } // Add a link to the graph connection with // other links is through the link his nodes -void Graph::AddLink(KBoolLink *a_link) +void Graph::AddLink( KBoolLink *a_link ) { - assert(a_link); + assert( a_link ); - _linklist->insend(a_link); + _linklist->insend( a_link ); } // Add a link to the graph, by giving it two nodes // the link is then made and added to the graph -void Graph::AddLink(Node *begin, Node *end) +void Graph::AddLink( Node *begin, Node *end ) { - assert(begin && end); - assert(begin != end); - AddLink(new KBoolLink(0, begin, end, _GC)); + assert( begin && end ); + assert( begin != end ); + AddLink( new KBoolLink( 0, begin, end, _GC ) ); } // Checks if there is a zeroline in the graph -bool Graph::AreZeroLines(B_INT Marge) +bool Graph::AreZeroLines( B_INT Marge ) { - bool Found_it = false; + bool Found_it = false; - TDLI _LI=TDLI(_linklist); - _LI.tohead(); - while (!_LI.hitroot()) - { - if (_LI.item()->IsZero(Marge)) - { - Found_it = true; - break; - } - _LI++; - } - return Found_it; + TDLI _LI = TDLI( _linklist ); + _LI.tohead(); + while ( !_LI.hitroot() ) + { + if ( _LI.item()->IsZero( Marge ) ) + { + Found_it = true; + break; + } + _LI++; + } + return Found_it; } // Delete links that do not fit the condition for given operation -void Graph::DeleteNonCond(BOOL_OP operation) +void Graph::DeleteNonCond( BOOL_OP operation ) { - TDLI _LI=TDLI(_linklist); - _LI.tohead(); - while(!_LI.hitroot()) - { - if ( !_LI.item()->IsMarked(operation)) - { - delete _LI.item(); - _LI.remove(); - } - else - _LI++; - } + TDLI _LI = TDLI( _linklist ); + _LI.tohead(); + while( !_LI.hitroot() ) + { + if ( !_LI.item()->IsMarked( operation ) ) + { + delete _LI.item(); + _LI.remove(); + } + else + _LI++; + } } -void Graph::HandleNonCond(BOOL_OP operation) +void Graph::HandleNonCond( BOOL_OP operation ) { - TDLI _LI=TDLI(_linklist); - _LI.tohead(); - while(!_LI.hitroot()) - { - if ( !_LI.item()->IsMarked(operation)) - { - _LI.item()->SetBeenHere(); - _LI.item()->SetGraphNum( -1 ); - } - _LI++; - } + TDLI _LI = TDLI( _linklist ); + _LI.tohead(); + while( !_LI.hitroot() ) + { + if ( !_LI.item()->IsMarked( operation ) ) + { + _LI.item()->SetBeenHere(); + _LI.item()->SetGraphNum( -1 ); + } + _LI++; + } } // All lines in the graph wich have a length < _GC->Get_Marge() will be deleted @@ -296,40 +289,40 @@ void Graph::HandleNonCond(BOOL_OP operation) // input : a marge, standard on _GC->Get_Marge() // return: true if lines in the graph are deleted // : false if no lines in the graph are deleted -bool Graph::DeleteZeroLines(B_INT Marge) +bool Graph::DeleteZeroLines( B_INT Marge ) { - // Is the graph modified ? - bool Is_Modified = false; - TDLI _LI=TDLI(_linklist); + // Is the graph modified ? + bool Is_Modified = false; + TDLI _LI = TDLI( _linklist ); - int Processed = _LI.count(); + int Processed = _LI.count(); - _LI.tohead(); - while (Processed > 0) - { - Processed--; - if (_LI.item()->IsZero(Marge)) - { - // the current link is zero, so make from both nodes one node - // and delete the current link from this graph - _LI.item()->MergeNodes(_LI.item()->GetBeginNode()); - // if an item is deleted the cursor of the list is set to the next - // so no explicit forth is needed - delete _LI.item(); - _LI.remove(); - // we have to set Processed, because if a zero line is deleted - // another can be made zero by this deletion - Processed = _LI.count(); - Is_Modified = true; - if (_LI.hitroot()) - _LI.tohead(); - } - else - _LI++; - if (_LI.hitroot()) - _LI.tohead(); - } - return Is_Modified; + _LI.tohead(); + while ( Processed > 0 ) + { + Processed--; + if ( _LI.item()->IsZero( Marge ) ) + { + // the current link is zero, so make from both nodes one node + // and delete the current link from this graph + _LI.item()->MergeNodes( _LI.item()->GetBeginNode() ); + // if an item is deleted the cursor of the list is set to the next + // so no explicit forth is needed + delete _LI.item(); + _LI.remove(); + // we have to set Processed, because if a zero line is deleted + // another can be made zero by this deletion + Processed = _LI.count(); + Is_Modified = true; + if ( _LI.hitroot() ) + _LI.tohead(); + } + else + _LI++; + if ( _LI.hitroot() ) + _LI.tohead(); + } + return Is_Modified; } @@ -340,487 +333,487 @@ bool Graph::DeleteZeroLines(B_INT Marge) // for instance a top link of a hole that is horizontal, always // is IN above the link and OUT underneath the link. // this for a non hole the opposite -void Graph::CollectGraph(Node *current_node,BOOL_OP operation, bool detecthole,int graphnumber, bool& foundholes ) +void Graph::CollectGraph( Node *current_node, BOOL_OP operation, bool detecthole, int graphnumber, bool& foundholes ) { - KBoolLink *currentlink; - KBoolLink *nextlink; - Node *next_node; - Node *MyFirst; - Node *Unlinked; - KBoolLink *MyFirstlink; + KBoolLink * currentlink; + KBoolLink *nextlink; + Node *next_node; + Node *MyFirst; + Node *Unlinked; + KBoolLink *MyFirstlink; - bool Hole; - LinkStatus whatside; + bool Hole; + LinkStatus whatside; - currentlink=current_node->GetNotFlat(); - if (!currentlink) - { - char buf[100]; - if (detecthole) - sprintf(buf,"no NON flat link Collectgraph for operation at %15.3lf , %15.3lf", - double(current_node->GetX()),double(current_node->GetY())); - else - sprintf(buf,"no NON flat link Collectgraph at %15.3lf , %15.3lf", - double(current_node->GetX()),double(current_node->GetY())); - throw Bool_Engine_Error(buf, "Error", 9, 0); - } + currentlink = current_node->GetNotFlat(); + if ( !currentlink ) + { + char buf[100]; + if ( detecthole ) + sprintf( buf, "no NON flat link Collectgraph for operation at %15.3lf , %15.3lf", + double( current_node->GetX() ), double( current_node->GetY() ) ); + else + sprintf( buf, "no NON flat link Collectgraph at %15.3lf , %15.3lf", + double( current_node->GetX() ), double( current_node->GetY() ) ); + throw Bool_Engine_Error( buf, "Error", 9, 0 ); + } - currentlink->SetBeenHere(); + currentlink->SetBeenHere(); - if (detecthole) - Hole = currentlink->IsHole(operation); - else - Hole = currentlink->GetHole(); //simple extract do not detect holes, but use hole flag. + if ( detecthole ) + Hole = currentlink->IsHole( operation ); + else + Hole = currentlink->GetHole(); //simple extract do not detect holes, but use hole flag. - currentlink->Redirect(current_node); + currentlink->Redirect( current_node ); - foundholes = Hole || foundholes; + foundholes = Hole || foundholes; - //depending if we have a hole or not - //we take the left node or right node from the selected link (currentlink) - //this MEANS for holes go left around and for non holes go right around - //since the currentlink is already set to binhere, it will not go in that direction - if (Hole) - { - whatside = IS_LEFT; - if ( currentlink->GetEndNode()->GetX() > current_node->GetX()) - current_node=currentlink->GetEndNode(); - } - else - { - whatside = IS_RIGHT; - if ( currentlink->GetEndNode()->GetX() < current_node->GetX()) - current_node=currentlink->GetEndNode(); - } - currentlink->Redirect(current_node); - MyFirst=current_node; //remember this as the start - MyFirstlink=currentlink; + //depending if we have a hole or not + //we take the left node or right node from the selected link (currentlink) + //this MEANS for holes go left around and for non holes go right around + //since the currentlink is already set to binhere, it will not go in that direction + if ( Hole ) + { + whatside = IS_LEFT; + if ( currentlink->GetEndNode()->GetX() > current_node->GetX() ) + current_node = currentlink->GetEndNode(); + } + else + { + whatside = IS_RIGHT; + if ( currentlink->GetEndNode()->GetX() < current_node->GetX() ) + current_node = currentlink->GetEndNode(); + } + currentlink->Redirect( current_node ); + MyFirst = current_node; //remember this as the start + MyFirstlink = currentlink; - next_node = currentlink->GetEndNode(); + next_node = currentlink->GetEndNode(); - // If this is a hole, Set as special link, this is the top link of this hole ! - // from this link we have to make links to the link above later on. - if (Hole) - currentlink->SetTopHole(true); - //set also the link as being part of a hole - if (detecthole) - currentlink->SetHole(Hole); - currentlink->SetGraphNum(graphnumber); + // If this is a hole, Set as special link, this is the top link of this hole ! + // from this link we have to make links to the link above later on. + if ( Hole ) + currentlink->SetTopHole( true ); + //set also the link as being part of a hole + if ( detecthole ) + currentlink->SetHole( Hole ); + currentlink->SetGraphNum( graphnumber ); - // Walk over links and redirect them. taking most right links around - while (currentlink != NULL) - { - if ( Hole ) - { - nextlink = next_node->GetMost(currentlink, IS_RIGHT, operation); - } - else - { - nextlink = next_node->GetMost(currentlink, IS_LEFT, operation); - // next works too if same is used in CollectGraphLast - //nextlink = next_node->GetMost(currentlink, IS_RIGHT, operation); - } - - if (nextlink == NULL) - { //END POINT MUST BE EQAUL TO BEGIN POINT - if (!next_node->Equal(MyFirst, 1)) - { - throw Bool_Engine_Error("no next (endpoint != beginpoint)","graph", 9, 0); - - //for god sake try this - //nextlink = next_node->GetMost(currentlink, whatside ,operation); - } - } - - current_node = next_node; - - if (nextlink!=NULL) - { - nextlink->Redirect(current_node); - nextlink->SetBeenHere(); - next_node = nextlink->GetEndNode(); - - if ( current_node->GetNumberOfLinks() > 2) - { // replace endnode of currentlink and beginnode of nextlink with new node - Unlinked = new Node(current_node, _GC); - currentlink->Replace(current_node,Unlinked); - nextlink->Replace(current_node,Unlinked); - } - - if (detecthole) - nextlink->SetHole(Hole); - nextlink->SetGraphNum(graphnumber); - } - else - { - //close the found graph properly - if ( current_node->GetNumberOfLinks() > 2) - { // replace endnode of currentlink and beginnode of nextlink with new node - Unlinked = new Node(current_node, _GC); - currentlink->Replace(current_node,Unlinked); - MyFirstlink->Replace(current_node,Unlinked); - } - } - - currentlink = nextlink; - } - - //END POINT MUST BE EQAUL TO BEGIN POINT - if (!current_node->Equal(MyFirst, 1)) - { - throw Bool_Engine_Error("in collect graph endpoint != beginpoint", "Error", 9, 0); - } -} - -void Graph::CollectGraphLast(Node *current_node,BOOL_OP operation, bool detecthole,int graphnumber, bool& foundholes ) -{ - KBoolLink *currentlink; - KBoolLink *nextlink; - Node *next_node; - Node *MyFirst; - Node *Unlinked; - KBoolLink *MyFirstlink; - - bool Hole; - LinkStatus whatside; - - currentlink=current_node->GetNotFlat(); - if (!currentlink) - { - char buf[100]; - if (detecthole) - sprintf(buf,"no NON flat link Collectgraph for operation at %15.3lf , %15.3lf", - double(current_node->GetX()),double(current_node->GetY())); - else - sprintf(buf,"no NON flat link Collectgraph at %15.3lf , %15.3lf", - double(current_node->GetX()),double(current_node->GetY())); - throw Bool_Engine_Error(buf, "Error", 9, 0); - } - - currentlink->SetBeenHere(); - - if (detecthole) - Hole = currentlink->IsHole(operation); - else - Hole = currentlink->GetHole(); //simple extract do not detect holes, but use hole flag. - - currentlink->Redirect(current_node); - - foundholes = Hole || foundholes; - - //depending if we have a hole or not - //we take the left node or right node from the selected link (currentlink) - //this MEANS for holes go left around and for non holes go right around - //since the currentlink is already set to binhere, it will not go in that direction - if (Hole) - { - whatside = IS_LEFT; - if ( currentlink->GetEndNode()->GetX() > current_node->GetX()) - current_node=currentlink->GetEndNode(); - } - else - { - whatside = IS_RIGHT; - if ( currentlink->GetEndNode()->GetX() < current_node->GetX()) - current_node=currentlink->GetEndNode(); - } - currentlink->Redirect(current_node); - MyFirst=current_node; //remember this as the start - MyFirstlink=currentlink; - - next_node = currentlink->GetEndNode(); - - // If this is a hole, Set as special link, this is the top link of this hole ! - // from this link we have to make links to the link above later on. - if (Hole) - currentlink->SetTopHole(true); - currentlink->SetGraphNum(graphnumber); - - // Walk over links and redirect them. taking most right links around - while (currentlink != NULL) - { - if ( Hole ) - { - if ( currentlink->GetHoleLink() ) - { - //in case we entered the hole via the hole link just now, we followe the hole. - //This is taking as many holes as possible ( most right around) - nextlink = next_node->GetMostHole(currentlink, IS_RIGHT ,operation ); - if ( !nextlink ) // hole done? - //if we did get to this hole via a holelink?, then we might now be on the return link. - //BTW it is also possible that holes are already found via a non linked hole path, - //in that case, we did go to the HoleLink here, and directly return on the other holelink. - nextlink = next_node->GetHoleLink(currentlink, true, operation ); - if ( !nextlink ) - { - //we did get to this hole via a holelink and we are on the returning holelink. - //So we left the hole collection, and continue with contours. - //Most Right is needed! - nextlink = next_node->GetMost(currentlink, IS_RIGHT, operation); - } - } - else - { - nextlink = next_node->GetHoleLink(currentlink, true, operation ); // other linked holes first - if ( !nextlink ) - nextlink = next_node->GetMostHole(currentlink, IS_RIGHT, operation ); // other holes first - if ( !nextlink ) - { - //We are leaving the hole. - //So we left the hole collection, and continue with contours. - //Most Right is needed! - nextlink = next_node->GetMost(currentlink, IS_RIGHT, operation); - } - } - } - else - { - - //a hole link is preferred above a normal link. If not no holes would be linked in anyway. - nextlink = next_node->GetHoleLink(currentlink, true, operation ); - if ( !nextlink ) - //also if we can get to a hole directly within a contour, that is better (get as much as possible) - nextlink = next_node->GetMostHole(currentlink, IS_RIGHT, operation); - if ( !nextlink ) - //if non of the above, we are still on the contour and take as must as possible to the left. - //Like that we take as many contour togethere as possible. - - nextlink = next_node->GetMost(currentlink, IS_LEFT, operation); + // Walk over links and redirect them. taking most right links around + while ( currentlink != NULL ) + { + if ( Hole ) + { + nextlink = next_node->GetMost( currentlink, IS_RIGHT, operation ); + } + else + { + nextlink = next_node->GetMost( currentlink, IS_LEFT, operation ); // next works too if same is used in CollectGraphLast //nextlink = next_node->GetMost(currentlink, IS_RIGHT, operation); - } + } - if (nextlink == NULL) - { //END POINT MUST BE EQAUL TO BEGIN POINT - if (!next_node->Equal(MyFirst, 1)) - { - throw Bool_Engine_Error("no next (endpoint != beginpoint)","graph", 9, 0); + if ( nextlink == NULL ) + { //END POINT MUST BE EQAUL TO BEGIN POINT + if ( !next_node->Equal( MyFirst, 1 ) ) + { + throw Bool_Engine_Error( "no next (endpoint != beginpoint)", "graph", 9, 0 ); - //for god sake try this - //nextlink = next_node->GetMost(currentlink, whatside, operation); - } - } - else - { - // when holes are already know, use the hole information to - // go left are right around. - Hole = nextlink->GetHole() || nextlink->GetHoleLink(); - } - current_node = next_node; + //for god sake try this + //nextlink = next_node->GetMost(currentlink, whatside ,operation); + } + } - if (nextlink!=NULL) - { - nextlink->Redirect(current_node); - nextlink->SetBeenHere(); - next_node = nextlink->GetEndNode(); + current_node = next_node; - if ( current_node->GetNumberOfLinks() > 2) - { // replace endnode of currentlink and beginnode of nextlink with new node - Unlinked = new Node(current_node, _GC); - currentlink->Replace(current_node,Unlinked); - nextlink->Replace(current_node,Unlinked); - } + if ( nextlink != NULL ) + { + nextlink->Redirect( current_node ); + nextlink->SetBeenHere(); + next_node = nextlink->GetEndNode(); - nextlink->SetGraphNum(graphnumber); - } - else - { - //close the found graph properly - if ( current_node->GetNumberOfLinks() > 2) - { // replace endnode of currentlink and beginnode of nextlink with new node - Unlinked = new Node(current_node, _GC); - currentlink->Replace(current_node,Unlinked); - MyFirstlink->Replace(current_node,Unlinked); - } - } + if ( current_node->GetNumberOfLinks() > 2 ) + { // replace endnode of currentlink and beginnode of nextlink with new node + Unlinked = new Node( current_node, _GC ); + currentlink->Replace( current_node, Unlinked ); + nextlink->Replace( current_node, Unlinked ); + } - currentlink = nextlink; - } + if ( detecthole ) + nextlink->SetHole( Hole ); + nextlink->SetGraphNum( graphnumber ); + } + else + { + //close the found graph properly + if ( current_node->GetNumberOfLinks() > 2 ) + { // replace endnode of currentlink and beginnode of nextlink with new node + Unlinked = new Node( current_node, _GC ); + currentlink->Replace( current_node, Unlinked ); + MyFirstlink->Replace( current_node, Unlinked ); + } + } - //END POINT MUST BE EQAUL TO BEGIN POINT - if (!current_node->Equal(MyFirst, 1)) - { - throw Bool_Engine_Error("in collect graph endpoint != beginpoint", "Error", 9, 0); - } + currentlink = nextlink; + } + + //END POINT MUST BE EQAUL TO BEGIN POINT + if ( !current_node->Equal( MyFirst, 1 ) ) + { + throw Bool_Engine_Error( "in collect graph endpoint != beginpoint", "Error", 9, 0 ); + } +} + +void Graph::CollectGraphLast( Node *current_node, BOOL_OP operation, bool detecthole, int graphnumber, bool& foundholes ) +{ + KBoolLink * currentlink; + KBoolLink *nextlink; + Node *next_node; + Node *MyFirst; + Node *Unlinked; + KBoolLink *MyFirstlink; + + bool Hole; + LinkStatus whatside; + + currentlink = current_node->GetNotFlat(); + if ( !currentlink ) + { + char buf[100]; + if ( detecthole ) + sprintf( buf, "no NON flat link Collectgraph for operation at %15.3lf , %15.3lf", + double( current_node->GetX() ), double( current_node->GetY() ) ); + else + sprintf( buf, "no NON flat link Collectgraph at %15.3lf , %15.3lf", + double( current_node->GetX() ), double( current_node->GetY() ) ); + throw Bool_Engine_Error( buf, "Error", 9, 0 ); + } + + currentlink->SetBeenHere(); + + if ( detecthole ) + Hole = currentlink->IsHole( operation ); + else + Hole = currentlink->GetHole(); //simple extract do not detect holes, but use hole flag. + + currentlink->Redirect( current_node ); + + foundholes = Hole || foundholes; + + //depending if we have a hole or not + //we take the left node or right node from the selected link (currentlink) + //this MEANS for holes go left around and for non holes go right around + //since the currentlink is already set to binhere, it will not go in that direction + if ( Hole ) + { + whatside = IS_LEFT; + if ( currentlink->GetEndNode()->GetX() > current_node->GetX() ) + current_node = currentlink->GetEndNode(); + } + else + { + whatside = IS_RIGHT; + if ( currentlink->GetEndNode()->GetX() < current_node->GetX() ) + current_node = currentlink->GetEndNode(); + } + currentlink->Redirect( current_node ); + MyFirst = current_node; //remember this as the start + MyFirstlink = currentlink; + + next_node = currentlink->GetEndNode(); + + // If this is a hole, Set as special link, this is the top link of this hole ! + // from this link we have to make links to the link above later on. + if ( Hole ) + currentlink->SetTopHole( true ); + currentlink->SetGraphNum( graphnumber ); + + // Walk over links and redirect them. taking most right links around + while ( currentlink != NULL ) + { + if ( Hole ) + { + if ( currentlink->GetHoleLink() ) + { + //in case we entered the hole via the hole link just now, we followe the hole. + //This is taking as many holes as possible ( most right around) + nextlink = next_node->GetMostHole( currentlink, IS_RIGHT , operation ); + if ( !nextlink ) // hole done? + //if we did get to this hole via a holelink?, then we might now be on the return link. + //BTW it is also possible that holes are already found via a non linked hole path, + //in that case, we did go to the HoleLink here, and directly return on the other holelink. + nextlink = next_node->GetHoleLink( currentlink, true, operation ); + if ( !nextlink ) + { + //we did get to this hole via a holelink and we are on the returning holelink. + //So we left the hole collection, and continue with contours. + //Most Right is needed! + nextlink = next_node->GetMost( currentlink, IS_RIGHT, operation ); + } + } + else + { + nextlink = next_node->GetHoleLink( currentlink, true, operation ); // other linked holes first + if ( !nextlink ) + nextlink = next_node->GetMostHole( currentlink, IS_RIGHT, operation ); // other holes first + if ( !nextlink ) + { + //We are leaving the hole. + //So we left the hole collection, and continue with contours. + //Most Right is needed! + nextlink = next_node->GetMost( currentlink, IS_RIGHT, operation ); + } + } + } + else + { + + //a hole link is preferred above a normal link. If not no holes would be linked in anyway. + nextlink = next_node->GetHoleLink( currentlink, true, operation ); + if ( !nextlink ) + //also if we can get to a hole directly within a contour, that is better (get as much as possible) + nextlink = next_node->GetMostHole( currentlink, IS_RIGHT, operation ); + if ( !nextlink ) + //if non of the above, we are still on the contour and take as must as possible to the left. + //Like that we take as many contour togethere as possible. + + nextlink = next_node->GetMost( currentlink, IS_LEFT, operation ); + // next works too if same is used in CollectGraphLast + //nextlink = next_node->GetMost(currentlink, IS_RIGHT, operation); + } + + if ( nextlink == NULL ) + { //END POINT MUST BE EQAUL TO BEGIN POINT + if ( !next_node->Equal( MyFirst, 1 ) ) + { + throw Bool_Engine_Error( "no next (endpoint != beginpoint)", "graph", 9, 0 ); + + //for god sake try this + //nextlink = next_node->GetMost(currentlink, whatside, operation); + } + } + else + { + // when holes are already know, use the hole information to + // go left are right around. + Hole = nextlink->GetHole() || nextlink->GetHoleLink(); + } + current_node = next_node; + + if ( nextlink != NULL ) + { + nextlink->Redirect( current_node ); + nextlink->SetBeenHere(); + next_node = nextlink->GetEndNode(); + + if ( current_node->GetNumberOfLinks() > 2 ) + { // replace endnode of currentlink and beginnode of nextlink with new node + Unlinked = new Node( current_node, _GC ); + currentlink->Replace( current_node, Unlinked ); + nextlink->Replace( current_node, Unlinked ); + } + + nextlink->SetGraphNum( graphnumber ); + } + else + { + //close the found graph properly + if ( current_node->GetNumberOfLinks() > 2 ) + { // replace endnode of currentlink and beginnode of nextlink with new node + Unlinked = new Node( current_node, _GC ); + currentlink->Replace( current_node, Unlinked ); + MyFirstlink->Replace( current_node, Unlinked ); + } + } + + currentlink = nextlink; + } + + //END POINT MUST BE EQAUL TO BEGIN POINT + if ( !current_node->Equal( MyFirst, 1 ) ) + { + throw Bool_Engine_Error( "in collect graph endpoint != beginpoint", "Error", 9, 0 ); + } } //============================================================================== //============================================================================== // Extract bi-directional graphs from this graph // Mark the graphs also as being a hole or not. -void Graph::Extract_Simples(BOOL_OP operation, bool detecthole, bool& foundholes ) +void Graph::Extract_Simples( BOOL_OP operation, bool detecthole, bool& foundholes ) { - TDLI _LI=TDLI(_linklist); - if (_LI.empty()) return; - Node *begin; - int graphnumber=1; + TDLI _LI = TDLI( _linklist ); + if ( _LI.empty() ) return; + Node *begin; + int graphnumber = 1; - _LI.mergesort(linkYXtopsorter); - _LI.tohead(); - while (true) - { - begin = GetMostTopLeft(&_LI); // from all the most Top nodes, - // take the most left one - // to most or not to most, that is the question - if (!begin) - break; + _LI.mergesort( linkYXtopsorter ); + _LI.tohead(); + while ( true ) + { + begin = GetMostTopLeft( &_LI ); // from all the most Top nodes, + // take the most left one + // to most or not to most, that is the question + if ( !begin ) + break; - try // collect the graph - { - if ( detecthole ) - CollectGraph( begin,operation,detecthole,graphnumber++, foundholes ); - else - //CollectGraph( begin,operation,detecthole,graphnumber++, foundholes ); - CollectGraphLast( begin,operation,detecthole,graphnumber++, foundholes ); - } - catch (Bool_Engine_Error& error) - { - _GC->info(error.GetErrorMessage(), "error"); - throw error; - } - } + try // collect the graph + { + if ( detecthole ) + CollectGraph( begin, operation, detecthole, graphnumber++, foundholes ); + else + //CollectGraph( begin,operation,detecthole,graphnumber++, foundholes ); + CollectGraphLast( begin, operation, detecthole, graphnumber++, foundholes ); + } + catch ( Bool_Engine_Error & error ) + { + _GC->info( error.GetErrorMessage(), "error" ); + throw error; + } + } } -void Graph::Split(GraphList* partlist) +void Graph::Split( GraphList* partlist ) { - TDLI _LI=TDLI(_linklist); - if (_LI.empty()) return; + TDLI _LI = TDLI( _linklist ); + if ( _LI.empty() ) return; - Graph *part = NULL; - int graphnumber=0; + Graph *part = NULL; + int graphnumber = 0; - //sort the graph on graphnumber - _LI.mergesort(linkGraphNumsorter); + //sort the graph on graphnumber + _LI.mergesort( linkGraphNumsorter ); - _LI.tohead(); - while (!_LI.hitroot()) - { - if ( _LI.item()->GetGraphNum() > 0 && graphnumber != _LI.item()->GetGraphNum()) + _LI.tohead(); + while ( !_LI.hitroot() ) { - graphnumber=_LI.item()->GetGraphNum(); - part = new Graph(_GC); - partlist->insend(part); + if ( _LI.item()->GetGraphNum() > 0 && graphnumber != _LI.item()->GetGraphNum() ) + { + graphnumber = _LI.item()->GetGraphNum(); + part = new Graph( _GC ); + partlist->insend( part ); + } + KBoolLink* tmp = _LI.item(); + if ( _LI.item()->GetGraphNum() > 0 ) + { + part->AddLink( tmp ); + } + else + { + delete tmp; + } + _LI.remove(); } - KBoolLink* tmp=_LI.item(); - if ( _LI.item()->GetGraphNum() > 0 ) - { - part->AddLink(tmp); - } - else - { - delete tmp; - } - _LI.remove(); - } } bool Graph::GetBeenHere() { - return _bin; + return _bin; } // return total number of links in this graph int Graph::GetNumberOfLinks() { - TDLI _LI=TDLI(_linklist); - return _LI.count(); + TDLI _LI = TDLI( _linklist ); + return _LI.count(); } //for all operations set the operation flags for the links //based on the Group_Left_Right values void Graph::Set_Operation_Flags() { - TDLI _LI=TDLI(_linklist); - _LI.tohead(); - while(!_LI.hitroot()) - { - _LI.item()->SetLineTypes(); - _LI++; - } + TDLI _LI = TDLI( _linklist ); + _LI.tohead(); + while( !_LI.hitroot() ) + { + _LI.item()->SetLineTypes(); + _LI++; + } } // Remove unused (those not used for any operation) links void Graph::Remove_IN_Links() { - TDLI _LI=TDLI(_linklist); - _LI.tohead(); - for (int t = _LI.count() ; t > 0; t--) - { - // Is this link not used for any operation? - if (_LI.item()->IsUnused()) - { - delete _LI.item(); - _LI.remove(); - } - else - _LI++; - } + TDLI _LI = TDLI( _linklist ); + _LI.tohead(); + for ( int t = _LI.count() ; t > 0; t-- ) + { + // Is this link not used for any operation? + if ( _LI.item()->IsUnused() ) + { + delete _LI.item(); + _LI.remove(); + } + else + _LI++; + } } void Graph::ResetBinMark() { - TDLI _LI=TDLI(_linklist); - if (_LI.empty()) return; - _LI.foreach_mf(&KBoolLink::UnMark);//reset bin and mark flag of each link + TDLI _LI = TDLI( _linklist ); + if ( _LI.empty() ) return; + _LI.foreach_mf( &KBoolLink::UnMark );//reset bin and mark flag of each link } void Graph::ReverseAllLinks() { - Node *dummy; - TDLI _LI=TDLI(_linklist); - _LI.tohead(); - while (!_LI.hitroot()) - { - // swap the begin- and endnode of the current link - dummy = _LI.item()->GetBeginNode(); - _LI.item()->SetBeginNode(_LI.item()->GetEndNode()); - _LI.item()->SetEndNode(dummy); - _LI++; - } + Node * dummy; + TDLI _LI = TDLI( _linklist ); + _LI.tohead(); + while ( !_LI.hitroot() ) + { + // swap the begin- and endnode of the current link + dummy = _LI.item()->GetBeginNode(); + _LI.item()->SetBeginNode( _LI.item()->GetEndNode() ); + _LI.item()->SetEndNode( dummy ); + _LI++; + } } -void Graph::SetBeenHere(bool value) +void Graph::SetBeenHere( bool value ) { - _bin=value; + _bin = value; } // ReSet the flags of the links void Graph::Reset_flags() { - TDLI _LI=TDLI(_linklist); - _LI.foreach_mf(&KBoolLink::Reset_flags); + TDLI _LI = TDLI( _linklist ); + _LI.foreach_mf( &KBoolLink::Reset_flags ); } // ReSet the bin and mark flag of the links void Graph::Reset_Mark_and_Bin() { - TDLI _LI=TDLI(_linklist); - _LI.foreach_mf(&KBoolLink::UnMark);//reset bin and mark flag of each link + TDLI _LI = TDLI( _linklist ); + _LI.foreach_mf( &KBoolLink::UnMark );//reset bin and mark flag of each link } // Set the group of the links to the same as newgroup -void Graph::SetGroup(GroupType newgroup) +void Graph::SetGroup( GroupType newgroup ) { - TDLI _LI=TDLI(_linklist); - _LI.tohead(); - while (!_LI.hitroot()) - { - _LI.item()->SetGroup(newgroup); - _LI++; - } + TDLI _LI = TDLI( _linklist ); + _LI.tohead(); + while ( !_LI.hitroot() ) + { + _LI.item()->SetGroup( newgroup ); + _LI++; + } } // Set the number of the links to the same as newnr -void Graph::SetNumber(const int newnr) +void Graph::SetNumber( const int newnr ) { - TDLI _LI=TDLI(_linklist); - _LI.tohead(); - while (!_LI.hitroot()) - { - _LI.item()->SetGraphNum(newnr); - _LI++; - } + TDLI _LI = TDLI( _linklist ); + _LI.tohead(); + while ( !_LI.hitroot() ) + { + _LI.item()->SetGraphNum( newnr ); + _LI++; + } } @@ -833,721 +826,722 @@ void Graph::SetNumber(const int newnr) // // input : a marge // return: true if graph is modified -// : false if graph is NOT simplified +// : false if graph is NOT simplified bool Graph::Simplify( B_INT Marge ) { - bool graph_is_modified = false; - TDLI _LI=TDLI(_linklist); - int Processed = _LI.count(); + bool graph_is_modified = false; + TDLI _LI = TDLI( _linklist ); + int Processed = _LI.count(); - _LI.foreach_mf(&KBoolLink::UnMark);//reset bin and mark flag of each link + _LI.foreach_mf( &KBoolLink::UnMark );//reset bin and mark flag of each link - _LI.tohead(); - GroupType mygroup=_LI.item()->Group(); + _LI.tohead(); + GroupType mygroup = _LI.item()->Group(); - // All items must be processed - while (Processed > 0) - { - // Gives the number of items to process - Processed--; - // Check if line is marked - // Links will be marked during the process - if (_LI.item()->IsMarked()) - { - delete _LI.item(); - _LI.remove(); - graph_is_modified = true; - Processed = _LI.count(); - if (_LI.hitroot()) - _LI.tohead(); - continue; - } + // All items must be processed + while ( Processed > 0 ) + { + // Gives the number of items to process + Processed--; + // Check if line is marked + // Links will be marked during the process + if ( _LI.item()->IsMarked() ) + { + delete _LI.item(); + _LI.remove(); + graph_is_modified = true; + Processed = _LI.count(); + if ( _LI.hitroot() ) + _LI.tohead(); + continue; + } - // Line is not marked, check if line is zero - if (_LI.item()->IsZero(Marge)) - { - _LI.item()->MergeNodes(_LI.item()->GetBeginNode()); - delete _LI.item(); - _LI.remove(); - graph_is_modified = true; - Processed = _LI.count(); - if (_LI.hitroot()) - _LI.tohead(); - continue; - } + // Line is not marked, check if line is zero + if ( _LI.item()->IsZero( Marge ) ) + { + _LI.item()->MergeNodes( _LI.item()->GetBeginNode() ); + delete _LI.item(); + _LI.remove(); + graph_is_modified = true; + Processed = _LI.count(); + if ( _LI.hitroot() ) + _LI.tohead(); + continue; + } - // begin with trying to simplify the link - { - // Line is not marked, not zero, so maybe it can be simplified - bool virtual_link_is_modified; - Node *new_begin, *new_end, *a_node; - KBoolLink *a_link; + // begin with trying to simplify the link + { + // Line is not marked, not zero, so maybe it can be simplified + bool virtual_link_is_modified; + Node *new_begin, *new_end, *a_node; + KBoolLink *a_link; - _LI.item()->Mark(); - new_begin = _LI.item()->GetBeginNode(); - new_end = _LI.item()->GetEndNode(); + _LI.item()->Mark(); + new_begin = _LI.item()->GetBeginNode(); + new_end = _LI.item()->GetEndNode(); - // while virtual link is modified - do - { - virtual_link_is_modified = false; - // look in the previous direction - if ((a_link = new_begin->GetPrevLink()) != NULL) - { - a_node = a_link->GetBeginNode(); - if (a_node->Simplify(new_begin,new_end,Marge)) - { - new_begin->GetPrevLink()->Mark(); - new_begin = a_node; - virtual_link_is_modified = true; - } - } - // look in the next direction - if ((a_link = new_end->GetNextLink()) != NULL) - { - a_node = a_link->GetEndNode(); - if (a_node->Simplify(new_begin,new_end,Marge)) - { - new_end->GetNextLink()->Mark(); - new_end = a_node; - virtual_link_is_modified = true; - } - } - graph_is_modified = (bool) (graph_is_modified || virtual_link_is_modified); - } while (virtual_link_is_modified); + // while virtual link is modified + do + { + virtual_link_is_modified = false; + // look in the previous direction + if ( ( a_link = new_begin->GetPrevLink() ) != NULL ) + { + a_node = a_link->GetBeginNode(); + if ( a_node->Simplify( new_begin, new_end, Marge ) ) + { + new_begin->GetPrevLink()->Mark(); + new_begin = a_node; + virtual_link_is_modified = true; + } + } + // look in the next direction + if ( ( a_link = new_end->GetNextLink() ) != NULL ) + { + a_node = a_link->GetEndNode(); + if ( a_node->Simplify( new_begin, new_end, Marge ) ) + { + new_end->GetNextLink()->Mark(); + new_end = a_node; + virtual_link_is_modified = true; + } + } + graph_is_modified = ( bool ) ( graph_is_modified || virtual_link_is_modified ); + } + while ( virtual_link_is_modified ); - // was the link simplified - if ((_LI.item()->GetBeginNode() != new_begin) || - (_LI.item()->GetEndNode() != new_end)) - { - // YES !!!!! - int number = _LI.item()->GetGraphNum(); - delete _LI.item(); - _LI.remove(); + // was the link simplified + if ( ( _LI.item()->GetBeginNode() != new_begin ) || + ( _LI.item()->GetEndNode() != new_end ) ) + { + // YES !!!!! + int number = _LI.item()->GetGraphNum(); + delete _LI.item(); + _LI.remove(); - if (_LI.hitroot()) - _LI.tohead(); + if ( _LI.hitroot() ) + _LI.tohead(); - KBoolLink *newlink = new KBoolLink(number, new_begin, new_end, _GC); - newlink->SetGroup(mygroup); + KBoolLink *newlink = new KBoolLink( number, new_begin, new_end, _GC ); + newlink->SetGroup( mygroup ); - _LI.insend(newlink); - Processed = _LI.count(); - graph_is_modified = true; - continue; - } - _LI.item()->UnMark(); - } // end of try to simplify - _LI++; - if (_LI.hitroot()) - _LI.tohead(); - }//end while all processed + _LI.insend( newlink ); + Processed = _LI.count(); + graph_is_modified = true; + continue; + } + _LI.item()->UnMark(); + } // end of try to simplify + _LI++; + if ( _LI.hitroot() ) + _LI.tohead(); + }//end while all processed - return graph_is_modified; + return graph_is_modified; } /* // This function will smoothen a graph with the following rules // -// 0. Process graphs with more than 3 links only. (while more than 3) -// Otherwise some objects may end-up as lines or disappear completely. +// 0. Process graphs with more than 3 links only. (while more than 3) +// Otherwise some objects may end-up as lines or disappear completely. // 1. -// a. ? Does begin-node lay on line(prevline.beginnode,endnode) -// -> merge beginnode to endnode -// b. ? Does end-node lay on line(beginnode,nextline.endnode) -// -> merge endnode to beginnode +// a. ? Does begin-node lay on line(prevline.beginnode,endnode) +// -> merge beginnode to endnode +// b. ? Does end-node lay on line(beginnode,nextline.endnode) +// -> merge endnode to beginnode // 2. -// a. ? Is distance between prevline.beginnode and endnode to short -// -> merge beginnode to endnode -// b. ? Is distance between beginnode and nextline.endnode to short -// -> merge endnode to beginnode +// a. ? Is distance between prevline.beginnode and endnode to short +// -> merge beginnode to endnode +// b. ? Is distance between beginnode and nextline.endnode to short +// -> merge endnode to beginnode // 3. -// a. ? Does (this)beginnode lay in area of nextline -// AND does cross-node lay on nextline -// -> move endnode to crossing of prevline and nextline -// b. ? Does (this)endnode lay in area of prevline -// AND does cross-node lay on prevline -// -> move beginnode to crossing of prevline and nextline +// a. ? Does (this)beginnode lay in area of nextline +// AND does cross-node lay on nextline +// -> move endnode to crossing of prevline and nextline +// b. ? Does (this)endnode lay in area of prevline +// AND does cross-node lay on prevline +// -> move beginnode to crossing of prevline and nextline // 4. -// ? Is this link too short -// ? Is prevline shorter than nextline -// Y -> ? Is prevlink shorter than maxlength -// -> merge endnode to beginnode -// N -> ? Is nextlink shorter than maxlength -// -> merge endnode to beginnode +// ? Is this link too short +// ? Is prevline shorter than nextline +// Y -> ? Is prevlink shorter than maxlength +// -> merge endnode to beginnode +// N -> ? Is nextlink shorter than maxlength +// -> merge endnode to beginnode // // -// Types of glitches / lines to remove : +// Types of glitches / lines to remove : // -// \ / \ / \ / -// Z---A---B OR Z-------B---A => Z-------B +// \ / \ / \ / +// Z---A---B OR Z-------B---A => Z-------B // -// (1) +// (1) // -// ----A C---- => ----A-----C---- -// \ / -// (2) \ / -// B +// ----A C---- => ----A-----C---- +// \ / +// (2) \ / +// B // -// ---Z ---Z -// \ \ -// (3) \ \ -// \ B----------C-- => A---B----------C-- +// ---Z ---Z +// \ \ +// (3) \ \ +// \ B----------C-- => A---B----------C-- // \ / // A // -// --Z---A --Z__ +// --Z---A --Z__ // \ -__ -// (4) B------------C-- => B------------C-- +// (4) B------------C-- => B------------C-- // -// linkLsorter(L1,L2) -// ret: -// +1 L1 < L2 -// 0 L1 == L2 -// -1 L1 > L2 +// linkLsorter(L1,L2) +// ret: +// +1 L1 < L2 +// 0 L1 == L2 +// -1 L1 > L2 // */ bool Graph::Smoothen( B_INT Marge ) { - TDLI _LI=TDLI(_linklist); - if (_LI.count()<=3) // Don't modify it - return false; + TDLI _LI = TDLI( _linklist ); + if ( _LI.count() <= 3 ) // Don't modify it + return false; - Node *Z, *A, *B, *C, *cross_node = new Node(_GC); - KBoolLink *prevlink, *nextlink, *thislink; - KBoolLine prevline(_GC), nextline(_GC), thisline(_GC); - KBoolLine prevhelp(_GC), nexthelp(_GC); + Node *Z, *A, *B, *C, *cross_node = new Node( _GC ); + KBoolLink *prevlink, *nextlink, *thislink; + KBoolLine prevline( _GC ), nextline( _GC ), thisline( _GC ); + KBoolLine prevhelp( _GC ), nexthelp( _GC ); - KBoolLink LZB(new Node(_GC), new Node(_GC), _GC), - LAC(new Node(_GC), new Node(_GC), _GC); + KBoolLink LZB( new Node( _GC ), new Node( _GC ), _GC ), + LAC( new Node( _GC ), new Node( _GC ), _GC ); - double distance=0; - double prevdist,nextdist; + double distance = 0; + double prevdist, nextdist; - bool doprev, donext; - bool graph_is_modified = false; - bool kill = false; // for first instance + bool doprev, donext; + bool graph_is_modified = false; + bool kill = false; // for first instance - _LI.tohead(); - int todo = _LI.count(); - thislink=_LI.item(); - B = thislink->GetEndNode(); - nextlink = thislink->Forth(B); + _LI.tohead(); + int todo = _LI.count(); + thislink = _LI.item(); + B = thislink->GetEndNode(); + nextlink = thislink->Forth( B ); - // Type 1 - while (todo>0) - { - if (kill==true) - { - // remove link from graph - _LI.toitem(thislink); - graph_is_modified = true; - delete _LI.item(); - _LI.remove(); - kill=false; - thislink=nextlink; - todo--; - if (_LI.count()<3) - break; - } + // Type 1 + while ( todo > 0 ) + { + if ( kill == true ) + { + // remove link from graph + _LI.toitem( thislink ); + graph_is_modified = true; + delete _LI.item(); + _LI.remove(); + kill = false; + thislink = nextlink; + todo--; + if ( _LI.count() < 3 ) + break; + } - A = thislink->GetBeginNode(); - B = thislink->GetEndNode(); + A = thislink->GetBeginNode(); + B = thislink->GetEndNode(); - if (A->ShorterThan(B,1)) - { - A->Merge(B); - kill = true; - continue; - } + if ( A->ShorterThan( B, 1 ) ) + { + A->Merge( B ); + kill = true; + continue; + } - Z = thislink->Forth(A)->GetBeginNode(); - C = thislink->Forth(B)->GetEndNode(); - thisline.Set(thislink); - thisline.CalculateLineParameters(); - nextlink = thislink->Forth(B); + Z = thislink->Forth( A )->GetBeginNode(); + C = thislink->Forth( B )->GetEndNode(); + thisline.Set( thislink ); + thisline.CalculateLineParameters(); + nextlink = thislink->Forth( B ); - if (thisline.PointInLine(Z,distance,0.0) == ON_AREA) - { // Z--A--B => Z--B Merge this to previous - thislink->MergeNodes(B); // remove A - kill = true; - continue; - } - else if (thisline.PointInLine(C,distance,0.0) == ON_AREA) - { // A--B--C => A--C Merge this to next - thislink->MergeNodes(A); // remove B - kill = true; - continue; - } + if ( thisline.PointInLine( Z, distance, 0.0 ) == ON_AREA ) + { // Z--A--B => Z--B Merge this to previous + thislink->MergeNodes( B ); // remove A + kill = true; + continue; + } + else if ( thisline.PointInLine( C, distance, 0.0 ) == ON_AREA ) + { // A--B--C => A--C Merge this to next + thislink->MergeNodes( A ); // remove B + kill = true; + continue; + } - thislink=nextlink; - todo--; - } + thislink = nextlink; + todo--; + } - kill=false; - todo = _LI.count(); - _LI.mergesort(linkLsorter); - _LI.tohead(); + kill = false; + todo = _LI.count(); + _LI.mergesort( linkLsorter ); + _LI.tohead(); - while (todo>0) - { - if (kill==true) - { - delete _LI.item(); - _LI.remove(); - graph_is_modified = true; - kill = false; - //mergesort(linkLsorter); - _LI.mergesort(linkLsorter); - _LI.tohead(); - todo = _LI.count(); - if (todo<3) // A polygon, at least, has 3 sides - break; - } + while ( todo > 0 ) + { + if ( kill == true ) + { + delete _LI.item(); + _LI.remove(); + graph_is_modified = true; + kill = false; + //mergesort(linkLsorter); + _LI.mergesort( linkLsorter ); + _LI.tohead(); + todo = _LI.count(); + if ( todo < 3 ) // A polygon, at least, has 3 sides + break; + } - // Keep this order! - thislink = _LI.item(); - A = thislink->GetBeginNode(); - B = thislink->GetEndNode(); - prevlink = thislink->Forth(A); - nextlink = thislink->Forth(B); - Z = prevlink->GetBeginNode(); - C = nextlink->GetEndNode(); + // Keep this order! + thislink = _LI.item(); + A = thislink->GetBeginNode(); + B = thislink->GetEndNode(); + prevlink = thislink->Forth( A ); + nextlink = thislink->Forth( B ); + Z = prevlink->GetBeginNode(); + C = nextlink->GetEndNode(); - if (A->ShorterThan(B,1)) - { - A->Merge(B); - kill = true; - continue; - } + if ( A->ShorterThan( B, 1 ) ) + { + A->Merge( B ); + kill = true; + continue; + } - prevline.Set(prevlink); - prevline.CalculateLineParameters(); - nextline.Set(nextlink); - nextline.CalculateLineParameters(); + prevline.Set( prevlink ); + prevline.CalculateLineParameters(); + nextline.Set( nextlink ); + nextline.CalculateLineParameters(); - // Type 2 - if (B->ShorterThan(Z,Marge)) - { // Z--A--B => Z--B Merge this to previous - thislink->MergeNodes(B); // remove A - kill = true; - continue; - } - else if (A->ShorterThan(C,Marge)) - { // A--B--C => A--C Merge this to next - thislink->MergeNodes(A); // remove B - kill = true; - continue; - } + // Type 2 + if ( B->ShorterThan( Z, Marge ) ) + { // Z--A--B => Z--B Merge this to previous + thislink->MergeNodes( B ); // remove A + kill = true; + continue; + } + else if ( A->ShorterThan( C, Marge ) ) + { // A--B--C => A--C Merge this to next + thislink->MergeNodes( A ); // remove B + kill = true; + continue; + } - *LZB.GetBeginNode()=*Z; - *LZB.GetEndNode()=*B; - *LAC.GetBeginNode()=*A; - *LAC.GetEndNode()=*C; - prevhelp.Set(&LZB); - nexthelp.Set(&LAC); - prevhelp.CalculateLineParameters(); - nexthelp.CalculateLineParameters(); + *LZB.GetBeginNode() = *Z; + *LZB.GetEndNode() = *B; + *LAC.GetBeginNode() = *A; + *LAC.GetEndNode() = *C; + prevhelp.Set( &LZB ); + nexthelp.Set( &LAC ); + prevhelp.CalculateLineParameters(); + nexthelp.CalculateLineParameters(); - // Type 4 - doprev = bool(prevhelp.PointInLine(A,prevdist,(double)Marge) == IN_AREA); - donext = bool(nexthelp.PointInLine(B,nextdist,(double)Marge) == IN_AREA); - doprev = bool(B->ShorterThan(Z,_GC->GetInternalMaxlinemerge()) && doprev); - donext = bool(A->ShorterThan(C,_GC->GetInternalMaxlinemerge()) && donext); + // Type 4 + doprev = bool( prevhelp.PointInLine( A, prevdist, ( double )Marge ) == IN_AREA ); + donext = bool( nexthelp.PointInLine( B, nextdist, ( double )Marge ) == IN_AREA ); + doprev = bool( B->ShorterThan( Z, _GC->GetInternalMaxlinemerge() ) && doprev ); + donext = bool( A->ShorterThan( C, _GC->GetInternalMaxlinemerge() ) && donext ); - if (doprev && donext) - { - if (fabs(prevdist)<=fabs(nextdist)) - thislink->MergeNodes(B); // remove A - else - thislink->MergeNodes(A); // remove B + if ( doprev && donext ) + { + if ( fabs( prevdist ) <= fabs( nextdist ) ) + thislink->MergeNodes( B ); // remove A + else + thislink->MergeNodes( A ); // remove B - kill = true; - continue; - } - else if (doprev) - { - thislink->MergeNodes(B); // remove A - kill = true; - continue; - } - else if (donext) - { - thislink->MergeNodes(A); // remove B - kill = true; - continue; - } + kill = true; + continue; + } + else if ( doprev ) + { + thislink->MergeNodes( B ); // remove A + kill = true; + continue; + } + else if ( donext ) + { + thislink->MergeNodes( A ); // remove B + kill = true; + continue; + } - thisline.Set(thislink); - thisline.CalculateLineParameters(); + thisline.Set( thislink ); + thisline.CalculateLineParameters(); - // Type 1 - if (thisline.PointInLine(Z,distance,0.0) == ON_AREA) - { // Z--A--B => Z--B Merge this to previous - thislink->MergeNodes(B); // remove A - kill = true; - continue; - } - else if (thisline.PointInLine(C,distance,0.0) == ON_AREA) - { // A--B--C => A--C Merge this to next - thislink->MergeNodes(A); // remove B - kill = true; - continue; - } + // Type 1 + if ( thisline.PointInLine( Z, distance, 0.0 ) == ON_AREA ) + { // Z--A--B => Z--B Merge this to previous + thislink->MergeNodes( B ); // remove A + kill = true; + continue; + } + else if ( thisline.PointInLine( C, distance, 0.0 ) == ON_AREA ) + { // A--B--C => A--C Merge this to next + thislink->MergeNodes( A ); // remove B + kill = true; + continue; + } - // Type 3 - if (nextline.PointInLine(A,distance, (double) Marge)==IN_AREA) - { - if (nextline.Intersect2(cross_node,&prevline)) - { - if (nextline.PointInLine(cross_node,distance,0.0)==IN_AREA) - { - B->Set(cross_node); - thislink->MergeNodes(B); // remove A - kill=true; - continue; - } - else - { - thislink->MergeNodes(A); // remove B - kill=true; - continue; - } - } - else - { - thislink->MergeNodes(A); // remove B - kill=true; - continue; - } - } + // Type 3 + if ( nextline.PointInLine( A, distance, ( double ) Marge ) == IN_AREA ) + { + if ( nextline.Intersect2( cross_node, &prevline ) ) + { + if ( nextline.PointInLine( cross_node, distance, 0.0 ) == IN_AREA ) + { + B->Set( cross_node ); + thislink->MergeNodes( B ); // remove A + kill = true; + continue; + } + else + { + thislink->MergeNodes( A ); // remove B + kill = true; + continue; + } + } + else + { + thislink->MergeNodes( A ); // remove B + kill = true; + continue; + } + } - // Type 3 - if (prevline.PointInLine(B,distance,(double)Marge)==IN_AREA) - { - if (prevline.Intersect2(cross_node,&nextline)) - { - if (prevline.PointInLine(cross_node,distance,0.0)==IN_AREA) - { - A->Set(cross_node); - thislink->MergeNodes(A); // remove B - kill=true; - continue; - } - else - { - thislink->MergeNodes(B); // remove A - kill=true; - continue; - } - } - else - { - thislink->MergeNodes(B); // remove A - kill=true; - continue; - } - } + // Type 3 + if ( prevline.PointInLine( B, distance, ( double )Marge ) == IN_AREA ) + { + if ( prevline.Intersect2( cross_node, &nextline ) ) + { + if ( prevline.PointInLine( cross_node, distance, 0.0 ) == IN_AREA ) + { + A->Set( cross_node ); + thislink->MergeNodes( A ); // remove B + kill = true; + continue; + } + else + { + thislink->MergeNodes( B ); // remove A + kill = true; + continue; + } + } + else + { + thislink->MergeNodes( B ); // remove A + kill = true; + continue; + } + } - todo--; - _LI++; - } // end: while all processed + todo--; + _LI++; + } // end: while all processed - delete cross_node; + delete cross_node; - return graph_is_modified; + return graph_is_modified; } // Give the graphnumber of the first link in the graphlist int Graph::GetGraphNum() { - return ((KBoolLink*)_linklist->headitem())->GetGraphNum(); + return ( ( KBoolLink* )_linklist->headitem() )->GetGraphNum(); } // get the node with the highest Y value Node* Graph::GetTopNode() { - B_INT max_Y = MAXB_INT; - Node* result; + B_INT max_Y = MAXB_INT; + Node* result; - TDLI _LI=TDLI(_linklist); + TDLI _LI = TDLI( _linklist ); - _LI.tohead(); - while (!_LI.hitroot()) - { - if (!(_LI.item()->GetBeginNode()->GetY() < max_Y)) - break; - _LI++; - } - result = _LI.item()->GetBeginNode(); + _LI.tohead(); + while ( !_LI.hitroot() ) + { + if ( !( _LI.item()->GetBeginNode()->GetY() < max_Y ) ) + break; + _LI++; + } + result = _LI.item()->GetBeginNode(); - return result; + return result; } // THE GRAPH MUST be SORTED before using this function -// mergesort(linkYXtopsorter); +// mergesort(linkYXtopsorter); // Get the mostleft top node from the graph for which the link flag is not set yet -Node* Graph::GetMostTopLeft(TDLI* _LI) +Node* Graph::GetMostTopLeft( TDLI* _LI ) { - while (!_LI->hitroot()) - { - if (!_LI->item()->BeenHere()) - { - KBoolLink* a=_LI->item(); - //find the top node of this link (sorted on top allready) - if (a->GetBeginNode()->GetY() > a->GetEndNode()->GetY()) - return(a->GetBeginNode()); - if (a->GetBeginNode()->GetY() < a->GetEndNode()->GetY()) - return(a->GetEndNode()); - else - return(a->GetBeginNode()); - } - (*_LI)++; - } - return NULL; + while ( !_LI->hitroot() ) + { + if ( !_LI->item()->BeenHere() ) + { + KBoolLink * a = _LI->item(); + //find the top node of this link (sorted on top allready) + if ( a->GetBeginNode()->GetY() > a->GetEndNode()->GetY() ) + return( a->GetBeginNode() ); + if ( a->GetBeginNode()->GetY() < a->GetEndNode()->GetY() ) + return( a->GetEndNode() ); + else + return( a->GetBeginNode() ); + } + ( *_LI )++; + } + return NULL; } // Take the linkslist over from a other graph // The linklist of the other graph will be empty afterwards -void Graph::TakeOver(Graph *other) +void Graph::TakeOver( Graph *other ) { - TDLI _LI=TDLI(_linklist); - _LI.takeover( other->_linklist); + TDLI _LI = TDLI( _linklist ); + _LI.takeover( other->_linklist ); } -// calculate crossing with scanbeams -bool Graph::CalculateCrossings(B_INT Marge) +// calculate crossing with scanbeams +bool Graph::CalculateCrossings( B_INT Marge ) { - // POINT <==> POINT - _GC->SetState("Node to Node"); + // POINT <==> POINT + _GC->SetState( "Node to Node" ); - bool found = false; - bool dummy = false; + bool found = false; + bool dummy = false; - found = Merge_NodeToNode(Marge) != 0; + found = Merge_NodeToNode( Marge ) != 0; - if (_linklist->count() < 3) - return found; + if ( _linklist->count() < 3 ) + return found; - // POINT <==> LINK - _GC->SetState("Node to KBoolLink 0"); + // POINT <==> LINK + _GC->SetState( "Node to KBoolLink 0" ); - found = ScanGraph2(NODELINK, dummy) != 0 || found; + found = ScanGraph2( NODELINK, dummy ) != 0 || found; - _GC->SetState("Rotate -90"); - Rotate(false); + _GC->SetState( "Rotate -90" ); + Rotate( false ); - _GC->SetState("Node to KBoolLink -90"); - found = ScanGraph2(NODELINK, dummy) != 0 || found; + _GC->SetState( "Node to KBoolLink -90" ); + found = ScanGraph2( NODELINK, dummy ) != 0 || found; - _GC->SetState("Rotate +90"); - Rotate(true); + _GC->SetState( "Rotate +90" ); + Rotate( true ); - // LINK <==> LINK - _GC->SetState("intersect"); + // LINK <==> LINK + _GC->SetState( "intersect" ); - found = ScanGraph2(LINKLINK, dummy) != 0 || found; + found = ScanGraph2( LINKLINK, dummy ) != 0 || found; -/* - if (!checksort()) - { { - TDLI _LI=TDLI(_linklist); - _LI.mergesort(linkXYsorter); - } - writeintersections(); - writegraph(true); - } -*/ - -// Rotate(false); -// _GC->SetState("KBoolLink to KBoolLink -90"); -// ScanGraph2(LINKLINK); -// Rotate(true); - - writegraph(true); - - _GC->Write_Log("Node to Node"); - _GC->SetState("Node to Node"); - - found = Merge_NodeToNode(Marge) != 0 || found; - writegraph(true); - - return found; -} - -// neem de nodes die binnen de margeafstand bij elkaar liggen samen RICHARD -int Graph::Merge_NodeToNode(B_INT Marge) -{ - //aantal punten dat verplaatst is - int merges = 0; - { - TDLI _LI=TDLI(_linklist); - - //unmark all links; markflag wordt gebruikt om aan te geven - //of een link (eigenlijk beginnode ervan) al verwerkt is - _LI.foreach_mf(&KBoolLink::UnMark); - - //sort links on x value of beginnode + /* + if (!checksort()) + { { + TDLI _LI=TDLI(_linklist); _LI.mergesort(linkXYsorter); + } + writeintersections(); + writegraph(true); + } + */ - //extra iterator voor doorlopen links in graph - { - TDLI links=TDLI(_linklist); +// Rotate(false); +// _GC->SetState("KBoolLink to KBoolLink -90"); +// ScanGraph2(LINKLINK); +// Rotate(true); - Node *nodeOne, *nodeTwo; - //verwerk alle links (alle (begin)nodes) - for(_LI.tohead(); !_LI.hitroot(); _LI++) - { - nodeOne = _LI.item()->GetBeginNode(); + writegraph( true ); - // link (beginnode) al verwerkt? - if(!_LI.item()->IsMarked()) - { - // wordt verwerkt dus markeer - _LI.item()->Mark(); + _GC->Write_Log( "Node to Node" ); + _GC->SetState( "Node to Node" ); - // doorloop alle links vanaf huidige tot link buiten marge - links.toiter(&_LI);links++; - while (!links.hitroot()) + found = Merge_NodeToNode( Marge ) != 0 || found; + writegraph( true ); + + return found; +} + +// neem de nodes die binnen de margeafstand bij elkaar liggen samen RICHARD +int Graph::Merge_NodeToNode( B_INT Marge ) +{ + //aantal punten dat verplaatst is + int merges = 0; + { + TDLI _LI = TDLI( _linklist ); + + //unmark all links; markflag wordt gebruikt om aan te geven + //of een link (eigenlijk beginnode ervan) al verwerkt is + _LI.foreach_mf( &KBoolLink::UnMark ); + + //sort links on x value of beginnode + _LI.mergesort( linkXYsorter ); + + //extra iterator voor doorlopen links in graph + { + TDLI links = TDLI( _linklist ); + + Node *nodeOne, *nodeTwo; + //verwerk alle links (alle (begin)nodes) + for( _LI.tohead(); !_LI.hitroot(); _LI++ ) { - nodeTwo = links.item()->GetBeginNode(); + nodeOne = _LI.item()->GetBeginNode(); - // marked? - if(!links.item()->IsMarked()) - { - // x van beginnode vd link binnen marge? - if(babs(nodeOne->GetX()-nodeTwo->GetX()) <= Marge ) - { - // y van beginnode vd link binnen marge? - // zijn twee node-object referenties wel verschillend? - if(babs(nodeOne->GetY()-nodeTwo->GetY()) <= Marge && - (!(nodeOne == nodeTwo)) - ) - { - links.item()->Mark(); - nodeOne->Merge(nodeTwo); - merges++; - }//y binnen marge en niet zelfde node - }//x binnen marge? - else - { - // link valt buiten marge; de rest vd links - // dus ook (omdat lijst gesorteerd is) - links.totail(); - } - }//marked? - links++; - }//current -> ongeldig - }//verwerkt? - }//all links + // link (beginnode) al verwerkt? + if( !_LI.item()->IsMarked() ) + { + // wordt verwerkt dus markeer + _LI.item()->Mark(); - }//om de extra iterator te verwijderen - } - RemoveNullLinks(); + // doorloop alle links vanaf huidige tot link buiten marge + links.toiter( &_LI );links++; + while ( !links.hitroot() ) + { + nodeTwo = links.item()->GetBeginNode(); - return merges; + // marked? + if( !links.item()->IsMarked() ) + { + // x van beginnode vd link binnen marge? + if( babs( nodeOne->GetX() - nodeTwo->GetX() ) <= Marge ) + { + // y van beginnode vd link binnen marge? + // zijn twee node-object referenties wel verschillend? + if( babs( nodeOne->GetY() - nodeTwo->GetY() ) <= Marge && + ( !( nodeOne == nodeTwo ) ) + ) + { + links.item()->Mark(); + nodeOne->Merge( nodeTwo ); + merges++; + }//y binnen marge en niet zelfde node + }//x binnen marge? + else + { + // link valt buiten marge; de rest vd links + // dus ook (omdat lijst gesorteerd is) + links.totail(); + } + }//marked? + links++; + }//current -> ongeldig + }//verwerkt? + }//all links + + }//om de extra iterator te verwijderen + } + RemoveNullLinks(); + + return merges; } -int Graph::ScanGraph2(SCANTYPE scantype, bool& holes ) +int Graph::ScanGraph2( SCANTYPE scantype, bool& holes ) { - TDLI _LI=TDLI(_linklist); - int found=0; + TDLI _LI = TDLI( _linklist ); + int found = 0; - //sort links on x and y value of beginnode - _LI.mergesort(linkXYsorter); + //sort links on x and y value of beginnode + _LI.mergesort( linkXYsorter ); - writegraph( false ); + writegraph( false ); - //bin flag is used in scanbeam so reset - _LI.foreach_mf(&KBoolLink::SetNotBeenHere); + //bin flag is used in scanbeam so reset + _LI.foreach_mf( &KBoolLink::SetNotBeenHere ); - ScanBeam* scanbeam = new ScanBeam(_GC); - Node* _low; - Node* _high; + ScanBeam* scanbeam = new ScanBeam( _GC ); + Node* _low; + Node* _high; - _LI.tohead(); - while (!_LI.attail()) - { - _low = _LI.item()->GetBeginNode(); - //find new links for the new beam and remove the old links - if ( scanbeam->FindNew(scantype,&_LI, holes ) ) + _LI.tohead(); + while ( !_LI.attail() ) + { + _low = _LI.item()->GetBeginNode(); + //find new links for the new beam and remove the old links + if ( scanbeam->FindNew( scantype, &_LI, holes ) ) found++; - //find a new low node, this should be a node not eqaul to the current _low - do - { _LI++;} - while (!_LI.hitroot() && (_low == _LI.item()->GetBeginNode())); - if (_LI.hitroot()) + //find a new low node, this should be a node not eqaul to the current _low + do + { _LI++;} + while ( !_LI.hitroot() && ( _low == _LI.item()->GetBeginNode() ) ); + if ( _LI.hitroot() ) //if the last few links share the same beginnode //we arive here break; - else - _high=_LI.item()->GetBeginNode(); + else + _high = _LI.item()->GetBeginNode(); - scanbeam->SetType(_low,_high); + scanbeam->SetType( _low, _high ); - if (scanbeam->RemoveOld(scantype,&_LI, holes ) ) + if ( scanbeam->RemoveOld( scantype, &_LI, holes ) ) found++; - } + } - delete scanbeam; - return found; + delete scanbeam; + return found; } /* - -// scanbeam->writebeam(); - + +// scanbeam->writebeam(); + if (j%100 ==0) { long x; long y; char buf[80]; - x=(long)_lowlink->GetBeginNode()->GetX(); - y=(long)_lowlink->GetBeginNode()->GetY(); + x=(long)_lowlink->GetBeginNode()->GetX(); + y=(long)_lowlink->GetBeginNode()->GetY(); sprintf(buf," x=%I64d , y=%I64d here %I64d",x,y,scanbeam->count()); - _GC->SetState(buf); - scanbeam->writebeam(); + _GC->SetState(buf); + scanbeam->writebeam(); } - - - + + + writegraph(false); if (!checksort()) { double x=_lowlink->GetBeginNode()->GetX(); checksort(); } - - - + + + _LI++; } } - - delete scanbeam; - return 0; + + delete scanbeam; + return 0; } - - + + if (!checksort()) { x=_lowlink->GetBeginNode()->GetX(); checksort(); } - + if (x >= -112200) { -// writegraph(true); -// scanbeam->writebeam(); +// writegraph(true); +// scanbeam->writebeam(); } */ @@ -1555,513 +1549,513 @@ int Graph::ScanGraph2(SCANTYPE scantype, bool& holes ) //=============================== Global Functions ============================= // Sorts the links on the X values -int linkXYsorter(KBoolLink *a, KBoolLink* b) +int linkXYsorter( KBoolLink *a, KBoolLink* b ) { - if ( a->GetBeginNode()->GetX() < b->GetBeginNode()->GetX()) - return(1); - if ( a->GetBeginNode()->GetX() > b->GetBeginNode()->GetX()) - return(-1); - //they are eqaul in x - if ( a->GetBeginNode()->GetY() < b->GetBeginNode()->GetY()) - return(-1); - if ( a->GetBeginNode()->GetY() > b->GetBeginNode()->GetY()) - return(1); - //they are eqaul in y - return(0); + if ( a->GetBeginNode()->GetX() < b->GetBeginNode()->GetX() ) + return( 1 ); + if ( a->GetBeginNode()->GetX() > b->GetBeginNode()->GetX() ) + return( -1 ); + //they are eqaul in x + if ( a->GetBeginNode()->GetY() < b->GetBeginNode()->GetY() ) + return( -1 ); + if ( a->GetBeginNode()->GetY() > b->GetBeginNode()->GetY() ) + return( 1 ); + //they are eqaul in y + return( 0 ); } // Sorts the links on the Y value of the beginnode -int linkYXsorter(KBoolLink *a, KBoolLink* b) +int linkYXsorter( KBoolLink *a, KBoolLink* b ) { - if ( a->GetBeginNode()->GetY() > b->GetBeginNode()->GetY()) - return(1); - if ( a->GetBeginNode()->GetY() < b->GetBeginNode()->GetY()) - return(-1); - if ( a->GetBeginNode()->GetX() > b->GetBeginNode()->GetX()) - return(-1); - if ( a->GetBeginNode()->GetX() < b->GetBeginNode()->GetX()) - return(1); - return(0); + if ( a->GetBeginNode()->GetY() > b->GetBeginNode()->GetY() ) + return( 1 ); + if ( a->GetBeginNode()->GetY() < b->GetBeginNode()->GetY() ) + return( -1 ); + if ( a->GetBeginNode()->GetX() > b->GetBeginNode()->GetX() ) + return( -1 ); + if ( a->GetBeginNode()->GetX() < b->GetBeginNode()->GetX() ) + return( 1 ); + return( 0 ); } // The sort function for sorting graph from shortest to longest (_l1 < _l2) -int linkLsorter(KBoolLink *_l1, KBoolLink* _l2) +int linkLsorter( KBoolLink *_l1, KBoolLink* _l2 ) { - B_INT dx1,dx2,dy1,dy2; - dx1 = (_l1->GetEndNode()->GetX() - _l1->GetBeginNode()->GetX()); - dx1*=dx1; - dy1 = (_l1->GetEndNode()->GetY() - _l1->GetBeginNode()->GetY()); - dy1*=dy1; - dx2 = (_l2->GetEndNode()->GetX() - _l2->GetBeginNode()->GetX()); - dx2*=dx2; - dy2 = (_l2->GetEndNode()->GetY() - _l2->GetBeginNode()->GetY()); - dy2*=dy2; + B_INT dx1, dx2, dy1, dy2; + dx1 = ( _l1->GetEndNode()->GetX() - _l1->GetBeginNode()->GetX() ); + dx1 *= dx1; + dy1 = ( _l1->GetEndNode()->GetY() - _l1->GetBeginNode()->GetY() ); + dy1 *= dy1; + dx2 = ( _l2->GetEndNode()->GetX() - _l2->GetBeginNode()->GetX() ); + dx2 *= dx2; + dy2 = ( _l2->GetEndNode()->GetY() - _l2->GetBeginNode()->GetY() ); + dy2 *= dy2; - dx1+=dy1; dx2+=dy2; + dx1 += dy1; dx2 += dy2; - if ( dx1 > dx2 ) - return(-1); - if ( dx1 < dx2 ) - return(1); - return(0); + if ( dx1 > dx2 ) + return( -1 ); + if ( dx1 < dx2 ) + return( 1 ); + return( 0 ); } // The sort function for the links in a graph (a.topnode < b.topnode) // if the two links lay with the top nodes on eachother the most left will be selected -int linkYXtopsorter(KBoolLink *a, KBoolLink *b) +int linkYXtopsorter( KBoolLink *a, KBoolLink *b ) { - if (bmax(a->GetBeginNode()->GetY(),a->GetEndNode()->GetY()) < bmax(b->GetBeginNode()->GetY(),b->GetEndNode()->GetY())) - return -1; + if ( bmax( a->GetBeginNode()->GetY(), a->GetEndNode()->GetY() ) < bmax( b->GetBeginNode()->GetY(), b->GetEndNode()->GetY() ) ) + return -1; - if (bmax(a->GetBeginNode()->GetY(),a->GetEndNode()->GetY()) > bmax(b->GetBeginNode()->GetY(),b->GetEndNode()->GetY())) - return 1; + if ( bmax( a->GetBeginNode()->GetY(), a->GetEndNode()->GetY() ) > bmax( b->GetBeginNode()->GetY(), b->GetEndNode()->GetY() ) ) + return 1; - //equal - if (bmin(a->GetBeginNode()->GetX(),a->GetEndNode()->GetX()) < bmin(b->GetBeginNode()->GetX(),b->GetEndNode()->GetX())) - return -1; + //equal + if ( bmin( a->GetBeginNode()->GetX(), a->GetEndNode()->GetX() ) < bmin( b->GetBeginNode()->GetX(), b->GetEndNode()->GetX() ) ) + return -1; - if (bmin(a->GetBeginNode()->GetX(),a->GetEndNode()->GetX()) > bmin(b->GetBeginNode()->GetX(),b->GetEndNode()->GetX())) - return 1; + if ( bmin( a->GetBeginNode()->GetX(), a->GetEndNode()->GetX() ) > bmin( b->GetBeginNode()->GetX(), b->GetEndNode()->GetX() ) ) + return 1; - return 0; + return 0; } // The sort function for sorting graph from shortest to longest (_l1 < _l2) -int linkGraphNumsorter(KBoolLink *_l1, KBoolLink* _l2) +int linkGraphNumsorter( KBoolLink *_l1, KBoolLink* _l2 ) { - if ( _l1->GetGraphNum() > _l2->GetGraphNum()) - return(-1); - if ( _l1->GetGraphNum() < _l2->GetGraphNum()) - return(1); - return(0); + if ( _l1->GetGraphNum() > _l2->GetGraphNum() ) + return( -1 ); + if ( _l1->GetGraphNum() < _l2->GetGraphNum() ) + return( 1 ); + return( 0 ); } // Perform an operation on the graph -void Graph::Boolean(BOOL_OP operation,GraphList* Result) +void Graph::Boolean( BOOL_OP operation, GraphList* Result ) { - _GC->SetState("Performing Operation"); + _GC->SetState( "Performing Operation" ); - // At this moment we have one graph - // step one, split it up in single graphs, and mark the holes - // step two, make one graph again and link the holes - // step three, split up again and dump the result in Result + // At this moment we have one graph + // step one, split it up in single graphs, and mark the holes + // step two, make one graph again and link the holes + // step three, split up again and dump the result in Result - _GC->SetState("Extract simples first "); + _GC->SetState( "Extract simples first " ); - ResetBinMark(); - DeleteNonCond(operation); - HandleNonCond(operation); + ResetBinMark(); + DeleteNonCond( operation ); + HandleNonCond( operation ); - bool foundholes = false; - try - { - WriteGraphKEY(_GC); - writegraph(true); + bool foundholes = false; + try + { + WriteGraphKEY( _GC ); + writegraph( true ); - Extract_Simples(operation,true, foundholes); - } - catch (Bool_Engine_Error& error) - { - throw error; - } + Extract_Simples( operation, true, foundholes ); + } + catch ( Bool_Engine_Error & error ) + { + throw error; + } - // now we will link all the holes in de graphlist - // By the scanbeam method we will search all the links that are marked - // as topleft link of a the hole polygon, when we find them we will get the - // closest link, being the one higher in the beam. - // Next we will create a link and nodes toceoonect the hole into it outside contour - // or other hole. - _GC->SetState("Linking Holes"); + // now we will link all the holes in de graphlist + // By the scanbeam method we will search all the links that are marked + // as topleft link of a the hole polygon, when we find them we will get the + // closest link, being the one higher in the beam. + // Next we will create a link and nodes toceoonect the hole into it outside contour + // or other hole. + _GC->SetState( "Linking Holes" ); - if (_linklist->count() == 0) - //extract simples did leaf an empty graph - //so we are ready - return; + if ( _linklist->count() == 0 ) + //extract simples did leaf an empty graph + //so we are ready + return; - if ( foundholes && _GC->GetLinkHoles() ) - { - //the first extract simples introduced nodes at the same location that are not merged. - //e.g. Butterfly polygons as two seperate polygons. - //The scanlines can not cope with this, so merge them, and later extract one more time. - Merge_NodeToNode(0); + if ( foundholes && _GC->GetLinkHoles() ) + { + //the first extract simples introduced nodes at the same location that are not merged. + //e.g. Butterfly polygons as two seperate polygons. + //The scanlines can not cope with this, so merge them, and later extract one more time. + Merge_NodeToNode( 0 ); - _GC->Write_Log("LINKHOLES\n"); - writegraph( false ); + _GC->Write_Log( "LINKHOLES\n" ); + writegraph( false ); - //link the holes into the non holes if there are any. - bool holes = false; - ScanGraph2(LINKHOLES, holes ); + //link the holes into the non holes if there are any. + bool holes = false; + ScanGraph2( LINKHOLES, holes ); - WriteGraphKEY(_GC); - writegraph(true); - if ( holes ) - { - //to delete extra points - //those extra points are caused by link holes - //and are eqaul - DeleteZeroLines(1); + WriteGraphKEY( _GC ); + writegraph( true ); + if ( holes ) + { + //to delete extra points + //those extra points are caused by link holes + //and are eqaul + DeleteZeroLines( 1 ); - _GC->SetState("extract simples last"); - ResetBinMark(); - HandleNonCond(operation); - DeleteNonCond(operation); - Extract_Simples(operation,false, foundholes); - } - } + _GC->SetState( "extract simples last" ); + ResetBinMark(); + HandleNonCond( operation ); + DeleteNonCond( operation ); + Extract_Simples( operation, false, foundholes ); + } + } - writegraph( true ); - Split(Result); + //writegraph( false ); + Split( Result ); } // Perform an correction on the graph void Graph::Correction( GraphList* Result, double factor ) { - // At this moment we have one graph - // step one, split it up in single graphs, and mark the holes - // step two, make one graph again and link the holes - // step three, split up again and dump the result in Result - _GC->SetState("Extract simple graphs"); + // At this moment we have one graph + // step one, split it up in single graphs, and mark the holes + // step two, make one graph again and link the holes + // step three, split up again and dump the result in Result + _GC->SetState( "Extract simple graphs" ); - //extract the (MERGE or OR) result from the graph - if (Simplify(_GC->GetGrid())) - if (GetNumberOfLinks() < 3) - return; + //extract the (MERGE or OR) result from the graph + if ( Simplify( _GC->GetGrid() ) ) + if ( GetNumberOfLinks() < 3 ) + return; - Graph* original=new Graph(_GC); + Graph* original = new Graph( _GC ); - { - if (_linklist->empty()) return; + { + if ( _linklist->empty() ) return; - KBoolLink* _current = GetFirstLink(); - Node *_first = new Node(_current->GetBeginNode(), _GC); - Node *_last = _current->GetBeginNode(); - Node *_begin = _first; - Node *_end = _first; + KBoolLink* _current = GetFirstLink(); + Node *_first = new Node( _current->GetBeginNode(), _GC ); + Node *_last = _current->GetBeginNode(); + Node *_begin = _first; + Node *_end = _first; - int _nr_of_points = GetNumberOfLinks(); - for (int i = 1; i < _nr_of_points; i++) - { - // get the other node on the link - _last = _current->GetOther(_last); - // make a node from this point - _end = new Node(_last, _GC); + int _nr_of_points = GetNumberOfLinks(); + for ( int i = 1; i < _nr_of_points; i++ ) + { + // get the other node on the link + _last = _current->GetOther( _last ); + // make a node from this point + _end = new Node( _last, _GC ); - // make a link between begin and end - original->AddLink(_begin, _end); + // make a link between begin and end + original->AddLink( _begin, _end ); - _begin=_end; - _current = _current->Forth(_last); - } + _begin = _end; + _current = _current->Forth( _last ); + } - // make a link between the _begin and the first to close the graph - original->AddLink(_begin, _first); - } + // make a link between the _begin and the first to close the graph + original->AddLink( _begin, _first ); + } - SetNumber(1); - SetGroup(GROUP_A); - Prepare(1); - ResetBinMark(); - //DeleteNonCond(BOOL_OR); - HandleNonCond(BOOL_OR); + SetNumber( 1 ); + SetGroup( GROUP_A ); + Prepare( 1 ); + ResetBinMark(); + //DeleteNonCond(BOOL_OR); + HandleNonCond( BOOL_OR ); - bool foundholes = false; - Extract_Simples( BOOL_OR, true, foundholes ); - Split(Result); + bool foundholes = false; + Extract_Simples( BOOL_OR, true, foundholes ); + Split( Result ); - //Result contains the separate boundaries and holes + //Result contains the separate boundaries and holes - //ring creation should never be alternate rule, since it overlaps. - //So temprarely modify it. - bool rule = _GC->GetWindingRule(); - _GC->SetWindingRule( true ); + //ring creation should never be alternate rule, since it overlaps. + //So temprarely modify it. + bool rule = _GC->GetWindingRule(); + _GC->SetWindingRule( true ); - _GC->SetState("Create rings"); - //first create a ring around all simple graphs - { - TDLI IResult=TDLI(Result); - GraphList *_ring = new GraphList(_GC); - { - //put into one graphlist - IResult.tohead(); - int i; - int n=IResult.count(); - for (i=0;iMakeClockWise(); - IResult.item()->CreateRing_fast(_ring,fabs(factor)); - // IResult.item()->CreateRing(_ring,fabs(factor)); - } - delete(IResult.item()); - IResult.remove(); - - //move ring graphlist to result - while (!_ring->empty()) + _GC->SetState( "Create rings" ); + //first create a ring around all simple graphs + { + TDLI IResult = TDLI( Result ); + GraphList *_ring = new GraphList( _GC ); + { + //put into one graphlist + IResult.tohead(); + int i; + int n = IResult.count(); + for ( i = 0;i < n;i++ ) { - //add to end - ((Graph*)_ring->headitem())->MakeClockWise(); - IResult.insend((Graph*)_ring->headitem()); - _ring->removehead(); + { + IResult.item()->MakeClockWise(); + IResult.item()->CreateRing_fast( _ring, fabs( factor ) ); + // IResult.item()->CreateRing(_ring,fabs(factor)); + } + delete( IResult.item() ); + IResult.remove(); + + //move ring graphlist to result + while ( !_ring->empty() ) + { + //add to end + ( ( Graph* )_ring->headitem() )->MakeClockWise(); + IResult.insend( ( Graph* )_ring->headitem() ); + _ring->removehead(); + } } - } - } - delete _ring; + } + delete _ring; - //IResult contains all rings - //prepare the graphs for extracting the links of a certain operation - //set original graphlist to groupA and ring to groupB - int i=2; - IResult.tohead(); - while (!IResult.hitroot()) - { - IResult.item()->Reset_flags(); - IResult.item()->SetGroup(GROUP_B); - IResult.item()->SetNumber(i); - i++; - IResult++; - } - } + //IResult contains all rings + //prepare the graphs for extracting the links of a certain operation + //set original graphlist to groupA and ring to groupB + int i = 2; + IResult.tohead(); + while ( !IResult.hitroot() ) + { + IResult.item()->Reset_flags(); + IResult.item()->SetGroup( GROUP_B ); + IResult.item()->SetNumber( i ); + i++; + IResult++; + } + } - //a ring shape can overlap itself, for alternate filling this is problem. - //doing a merge in winding rule makes this oke, since overlap is removed by it. - if ( !rule ) //alternate rule? - { - Prepare(1); - Boolean(BOOL_OR,Result); + //a ring shape can overlap itself, for alternate filling this is problem. + //doing a merge in winding rule makes this oke, since overlap is removed by it. + if ( !rule ) //alternate rule? + { + Prepare( 1 ); + Boolean( BOOL_OR, Result ); - TDLI IResult=TDLI(Result); - //IResult contains all rings - //prepare the graphs for extracting the links of a certain operation - //set original graphlist to groupA and ring to groupB - int i=2; - IResult.tohead(); - while (!IResult.hitroot()) - { - IResult.item()->Reset_flags(); - IResult.item()->SetGroup(GROUP_B); - IResult.item()->SetNumber(i); - i++; - IResult++; - } - } + TDLI IResult = TDLI( Result ); + //IResult contains all rings + //prepare the graphs for extracting the links of a certain operation + //set original graphlist to groupA and ring to groupB + int i = 2; + IResult.tohead(); + while ( !IResult.hitroot() ) + { + IResult.item()->Reset_flags(); + IResult.item()->SetGroup( GROUP_B ); + IResult.item()->SetNumber( i ); + i++; + IResult++; + } + } - //restore filling rule - _GC->SetWindingRule( rule ); + //restore filling rule + _GC->SetWindingRule( rule ); - TakeOver(original); - Reset_flags(); - SetNumber(1); - SetGroup(GROUP_A); - Result->MakeOneGraph(this); // adds all graph its links to original - // Result will be empty afterwords + TakeOver( original ); + Reset_flags(); + SetNumber( 1 ); + SetGroup( GROUP_A ); + Result->MakeOneGraph( this ); // adds all graph its links to original + // Result will be empty afterwords - //merge ring with original shapes for positive correction else subtract ring + //merge ring with original shapes for positive correction else subtract ring - //calculate intersections etc. - //SINCE correction will calculate intersections between - //ring and original _GC->Get_Marge() must be set a lot smaller then factor - //during the rest of this routine - //else wierd effects will be the result. - double Backup_Marge = _GC->GetMarge(); + //calculate intersections etc. + //SINCE correction will calculate intersections between + //ring and original _GC->Get_Marge() must be set a lot smaller then factor + //during the rest of this routine + //else wierd effects will be the result. + double Backup_Marge = _GC->GetMarge(); - if (_GC->GetInternalMarge() > fabs(factor/100)) - { - _GC->SetInternalMarge( (B_INT) fabs(factor/100)); - //less then 1 is usless since all coordinates are integers - if (_GC->GetInternalMarge() < 1) - _GC->SetInternalMarge(1); - } + if ( _GC->GetInternalMarge() > fabs( factor / 100 ) ) + { + _GC->SetInternalMarge( ( B_INT ) fabs( factor / 100 ) ); + //less then 1 is usless since all coordinates are integers + if ( _GC->GetInternalMarge() < 1 ) + _GC->SetInternalMarge( 1 ); + } - Prepare(1); + Prepare( 1 ); - _GC->SetState("Add/Substract rings"); + _GC->SetState( "Add/Substract rings" ); - if (factor > 0) - Boolean(BOOL_OR,Result); - else - Boolean(BOOL_A_SUB_B,Result); + if ( factor > 0 ) + Boolean( BOOL_OR, Result ); + else + Boolean( BOOL_A_SUB_B, Result ); - _GC->SetMarge( Backup_Marge); + _GC->SetMarge( Backup_Marge ); - //the result of the graph correction is in Result - delete original; + //the result of the graph correction is in Result + delete original; } // Perform an operation on the graph void Graph::MakeRing( GraphList* Result, double factor ) { - bool rule = _GC->GetWindingRule(); - _GC->SetWindingRule( true ); + bool rule = _GC->GetWindingRule(); + _GC->SetWindingRule( true ); - // At this moment we have one graph - // step one, split it up in single graphs, and mark the holes - // step two, make one graph again and link the holes - // step three, split up again and dump the result in Result - _GC->SetState("Extract simple graphs"); + // At this moment we have one graph + // step one, split it up in single graphs, and mark the holes + // step two, make one graph again and link the holes + // step three, split up again and dump the result in Result + _GC->SetState( "Extract simple graphs" ); - //extract the (MERGE or OR) result from the graph - SetNumber(1); - Prepare(1); + //extract the (MERGE or OR) result from the graph + SetNumber( 1 ); + Prepare( 1 ); - ResetBinMark(); - //DeleteNonCond(BOOL_OR); - HandleNonCond(BOOL_OR); + ResetBinMark(); + //DeleteNonCond(BOOL_OR); + HandleNonCond( BOOL_OR ); - bool foundholes = false; - Extract_Simples( BOOL_OR, true, foundholes ); - Split(Result); - //Iresult contains the separate boundaries and holes - //make a correction on the boundaries factor - //make a correction on the holes -factor + bool foundholes = false; + Extract_Simples( BOOL_OR, true, foundholes ); + Split( Result ); + //Iresult contains the separate boundaries and holes + //make a correction on the boundaries factor + //make a correction on the holes -factor - _GC->SetState("Create rings"); + _GC->SetState( "Create rings" ); - //first create a ring around all simple graphs - TDLI IResult=TDLI(Result); - GraphList *_ring = new GraphList(_GC); - { - IResult.tohead(); - int i; - int n=IResult.count(); - for (i=0;i IResult = TDLI( Result ); + GraphList *_ring = new GraphList( _GC ); + { + IResult.tohead(); + int i; + int n = IResult.count(); + for ( i = 0;i < n;i++ ) { - IResult.item()->MakeClockWise(); - IResult.item()->CreateRing_fast(_ring,fabs(factor)); - } - delete(IResult.item()); - IResult.remove(); + { + IResult.item()->MakeClockWise(); + IResult.item()->CreateRing_fast( _ring, fabs( factor ) ); + } + delete( IResult.item() ); + IResult.remove(); - //move ring graphlist to result - while (!_ring->empty()) - { - //add to end - ((Graph*)_ring->headitem())->MakeClockWise(); - IResult.insend((Graph*)_ring->headitem()); - _ring->removehead(); - } - } - } - delete _ring; - _GC->SetWindingRule( rule ); + //move ring graphlist to result + while ( !_ring->empty() ) + { + //add to end + ( ( Graph* )_ring->headitem() )->MakeClockWise(); + IResult.insend( ( Graph* )_ring->headitem() ); + _ring->removehead(); + } + } + } + delete _ring; + _GC->SetWindingRule( rule ); } //create a ring shapes on every edge of the graph void Graph::CreateRing( GraphList *ring, double factor ) { - TDLI _LI=TDLI(_linklist); - _LI.tohead(); - while( !_LI.hitroot()) - { - Graph *shape=new Graph(_GC); - //generate shape around link - shape->Make_Rounded_Shape(_LI.item(),factor); - ring->insbegin(shape); - _LI++; - } + TDLI _LI = TDLI( _linklist ); + _LI.tohead(); + while( !_LI.hitroot() ) + { + Graph * shape = new Graph( _GC ); + //generate shape around link + shape->Make_Rounded_Shape( _LI.item(), factor ); + ring->insbegin( shape ); + _LI++; + } } //create a ring shapes on every edge of the graph void Graph::CreateRing_fast( GraphList *ring, double factor ) { - Node* begin; - KBoolLink* currentlink; - KBoolLine currentline(_GC); + Node * begin; + KBoolLink* currentlink; + KBoolLine currentline( _GC ); - KBoolLine firstline(_GC); + KBoolLine firstline( _GC ); - KBoolLink* nextlink; - KBoolLine nextline(_GC); + KBoolLink* nextlink; + KBoolLine nextline( _GC ); - { - TDLI _LI=TDLI(_linklist); - _LI.foreach_mf(&KBoolLink::UnMark);//reset bin and mark flag of each link - _LI.mergesort(linkYXsorter); - _LI.tohead(); + { + TDLI _LI = TDLI( _linklist ); + _LI.foreach_mf( &KBoolLink::UnMark );//reset bin and mark flag of each link + _LI.mergesort( linkYXsorter ); + _LI.tohead(); - begin = GetMostTopLeft(&_LI); // from all the most Top nodes, - // take the most left one - } - if (!begin) - return; + begin = GetMostTopLeft( &_LI ); // from all the most Top nodes, + // take the most left one + } + if ( !begin ) + return; - currentlink=begin->GetIncomingLink(); - currentline.Set(currentlink); - currentline.CalculateLineParameters(); + currentlink = begin->GetIncomingLink(); + currentline.Set( currentlink ); + currentline.CalculateLineParameters(); - nextlink=begin->GetOutgoingLink(); - nextline.Set(nextlink); - nextline.CalculateLineParameters(); + nextlink = begin->GetOutgoingLink(); + nextline.Set( nextlink ); + nextline.CalculateLineParameters(); - firstline.Set(nextlink); - firstline.CalculateLineParameters(); + firstline.Set( nextlink ); + firstline.CalculateLineParameters(); - while (nextlink) - { - Graph *shape=new Graph(_GC); - { + while ( nextlink ) + { + Graph * shape = new Graph( _GC ); + { - Node* _last_ins_left =0; - Node* _last_ins_right =0; + Node* _last_ins_left = 0; + Node* _last_ins_right = 0; - currentline.Create_Begin_Shape(&nextline,&_last_ins_left,&_last_ins_right,factor,shape); + currentline.Create_Begin_Shape( &nextline, &_last_ins_left, &_last_ins_right, factor, shape ); - while(true) - { - currentline=nextline; - currentlink=nextlink; - currentlink->SetBeenHere(); + while( true ) + { + currentline = nextline; + currentlink = nextlink; + currentlink->SetBeenHere(); - nextlink=currentlink->GetEndNode()->Follow(currentlink); - if (nextlink) - { - nextline.Set(nextlink); - nextline.CalculateLineParameters(); - if (!currentline.Create_Ring_Shape(&nextline,&_last_ins_left,&_last_ins_right,factor,shape)) - break; - } - else - break; - } + nextlink = currentlink->GetEndNode()->Follow( currentlink ); + if ( nextlink ) + { + nextline.Set( nextlink ); + nextline.CalculateLineParameters(); + if ( !currentline.Create_Ring_Shape( &nextline, &_last_ins_left, &_last_ins_right, factor, shape ) ) + break; + } + else + break; + } - //finish this part - if (nextlink) - currentline.Create_End_Shape(&nextline,_last_ins_left,_last_ins_right,factor,shape); - else - currentline.Create_End_Shape(&firstline,_last_ins_left,_last_ins_right,factor,shape); + //finish this part + if ( nextlink ) + currentline.Create_End_Shape( &nextline, _last_ins_left, _last_ins_right, factor, shape ); + else + currentline.Create_End_Shape( &firstline, _last_ins_left, _last_ins_right, factor, shape ); - shape->MakeOneDirection(); - shape->MakeClockWise(); - } + shape->MakeOneDirection(); + shape->MakeClockWise(); + } - //if the shape is very small first merge it with the previous shape - if (!ring->empty() && shape->Small( (B_INT) fabs(factor*3))) - { - TDLI Iring = TDLI(ring); + //if the shape is very small first merge it with the previous shape + if ( !ring->empty() && shape->Small( ( B_INT ) fabs( factor * 3 ) ) ) + { + TDLI Iring = TDLI( ring ); - Iring.totail(); + Iring.totail(); - GraphList *_twoshapes=new GraphList(_GC); - _twoshapes->insbegin(shape); - _twoshapes->insbegin(Iring.item()); - Iring.remove(); - _twoshapes->Merge(); + GraphList *_twoshapes = new GraphList( _GC ); + _twoshapes->insbegin( shape ); + _twoshapes->insbegin( Iring.item() ); + Iring.remove(); + _twoshapes->Merge(); - //move merged graphlist to ring - Iring.takeover(_twoshapes); - delete _twoshapes; - } - else - ring->insend(shape); + //move merged graphlist to ring + Iring.takeover( _twoshapes ); + delete _twoshapes; + } + else + ring->insend( shape ); - currentlink->SetBeenHere(); - } + currentlink->SetBeenHere(); + } } //create an arc and add it to the graph @@ -2070,347 +2064,347 @@ void Graph::CreateRing_fast( GraphList *ring, double factor ) //end point of arc //radius of arc //aberation for generating the segments -void Graph::CreateArc(Node* center, Node* begin, Node* end,double radius,bool clock,double aber) +void Graph::CreateArc( Node* center, Node* begin, Node* end, double radius, bool clock, double aber ) { - double phi,dphi,dx,dy; - int Segments; - int i; - double ang1,ang2,phit; + double phi, dphi, dx, dy; + int Segments; + int i; + double ang1, ang2, phit; - Node* _last_ins; - Node* _current; + Node* _last_ins; + Node* _current; - _last_ins=begin; + _last_ins = begin; - dx = (double) _last_ins->GetX() - center->GetX(); - dy = (double) _last_ins->GetY() - center->GetY(); - ang1=atan2(dy,dx); - if (ang1<0) ang1+=2.0*M_PI; - dx = (double) end->GetX() - center->GetX(); - dy = (double) end->GetY() - center->GetY(); - ang2=atan2(dy,dx); - if (ang2<0) ang2+=2.0*M_PI; + dx = ( double ) _last_ins->GetX() - center->GetX(); + dy = ( double ) _last_ins->GetY() - center->GetY(); + ang1 = atan2( dy, dx ); + if ( ang1 < 0 ) ang1 += 2.0 * M_PI; + dx = ( double ) end->GetX() - center->GetX(); + dy = ( double ) end->GetY() - center->GetY(); + ang2 = atan2( dy, dx ); + if ( ang2 < 0 ) ang2 += 2.0 * M_PI; - if (clock) - { //clockwise - if (ang2 > ang1) - phit=2.0*M_PI-ang2+ ang1; - else - phit=ang1-ang2; - } - else - { //counter_clockwise - if (ang1 > ang2) - phit=-(2.0*M_PI-ang1+ ang2); - else - phit=-(ang2-ang1); - } + if ( clock ) + { //clockwise + if ( ang2 > ang1 ) + phit = 2.0 * M_PI - ang2 + ang1; + else + phit = ang1 - ang2; + } + else + { //counter_clockwise + if ( ang1 > ang2 ) + phit = -( 2.0 * M_PI - ang1 + ang2 ); + else + phit = -( ang2 - ang1 ); + } - //what is the delta phi to get an accurancy of aber - dphi=2*acos((radius-aber)/radius); + //what is the delta phi to get an accurancy of aber + dphi = 2 * acos( ( radius - aber ) / radius ); - //set the number of segments - if (phit > 0) - Segments=(int)ceil(phit/dphi); - else - Segments=(int)ceil(-phit/dphi); + //set the number of segments + if ( phit > 0 ) + Segments = ( int )ceil( phit / dphi ); + else + Segments = ( int )ceil( -phit / dphi ); - if (Segments <= 1) - Segments=1; - if (Segments > 6) - Segments=6; + if ( Segments <= 1 ) + Segments = 1; + if ( Segments > 6 ) + Segments = 6; - dphi=phit/(Segments); + dphi = phit / ( Segments ); - for (i=1; iGetX() - center->GetX(); - dy = (double) _last_ins->GetY() - center->GetY(); - phi=atan2(dy,dx); + for ( i = 1; i < Segments; i++ ) + { + dx = ( double ) _last_ins->GetX() - center->GetX(); + dy = ( double ) _last_ins->GetY() - center->GetY(); + phi = atan2( dy, dx ); - _current = new Node((B_INT) (center->GetX() + radius * cos(phi-dphi)), - (B_INT) (center->GetY() + radius * sin(phi-dphi)), _GC); - AddLink(_last_ins, _current); + _current = new Node( ( B_INT ) ( center->GetX() + radius * cos( phi - dphi ) ), + ( B_INT ) ( center->GetY() + radius * sin( phi - dphi ) ), _GC ); + AddLink( _last_ins, _current ); - _last_ins=_current; - } + _last_ins = _current; + } - // make a node from the endnode of link - AddLink(_last_ins, end); + // make a node from the endnode of link + AddLink( _last_ins, end ); } -void Graph::CreateArc(Node* center, KBoolLine* incoming, Node* end,double radius,double aber) +void Graph::CreateArc( Node* center, KBoolLine* incoming, Node* end, double radius, double aber ) { - double distance=0; - if (incoming->PointOnLine(center, distance, _GC->GetAccur()) == RIGHT_SIDE) - CreateArc(center,incoming->GetEndNode(),end,radius,true,aber); - else - CreateArc(center,incoming->GetEndNode(),end,radius,false,aber); + double distance = 0; + if ( incoming->PointOnLine( center, distance, _GC->GetAccur() ) == RIGHT_SIDE ) + CreateArc( center, incoming->GetEndNode(), end, radius, true, aber ); + else + CreateArc( center, incoming->GetEndNode(), end, radius, false, aber ); } void Graph::MakeOneDirection() { - int _nr_of_points = _linklist->count(); - KBoolLink* _current = (KBoolLink*)_linklist->headitem(); + int _nr_of_points = _linklist->count(); + KBoolLink* _current = ( KBoolLink* )_linklist->headitem(); - Node* _last = _current->GetBeginNode(); - Node* dummy; + Node* _last = _current->GetBeginNode(); + Node* dummy; - for (int i = 0; i < _nr_of_points; i++) - { - // get the other node on the link - _last = _current->GetOther(_last); - // get the other link on the node - _current = _current->Forth(_last); + for ( int i = 0; i < _nr_of_points; i++ ) + { + // get the other node on the link + _last = _current->GetOther( _last ); + // get the other link on the node + _current = _current->Forth( _last ); - if (_current->GetBeginNode() != _last) - { - // swap the begin- and endnode of the current link - dummy = _current->GetBeginNode(); - _current->SetBeginNode(_current->GetEndNode()); - _current->SetEndNode(dummy); - } - } + if ( _current->GetBeginNode() != _last ) + { + // swap the begin- and endnode of the current link + dummy = _current->GetBeginNode(); + _current->SetBeginNode( _current->GetEndNode() ); + _current->SetEndNode( dummy ); + } + } } -bool Graph::Small(B_INT howsmall) +bool Graph::Small( B_INT howsmall ) { - TDLI _LI=TDLI(_linklist); - _LI.tohead(); - Node* bg=_LI.item()->GetBeginNode(); - B_INT xmin=bg->GetX(); - B_INT xmax=bg->GetX(); - B_INT ymin=bg->GetY(); - B_INT ymax=bg ->GetY(); - while (!_LI.hitroot()) - { - bg=_LI.item()->GetBeginNode(); - // make _boundingbox bigger if the link makes the graph bigger - // Checking if point is in bounding-box with marge - xmin=bmin(xmin,bg->GetX()); - xmax=bmax(xmax,bg->GetX()); - ymin=bmin(ymin,bg->GetY()); - ymax=bmax(ymax,bg->GetY()); - _LI++; - } + TDLI _LI = TDLI( _linklist ); + _LI.tohead(); + Node* bg = _LI.item()->GetBeginNode(); + B_INT xmin = bg->GetX(); + B_INT xmax = bg->GetX(); + B_INT ymin = bg->GetY(); + B_INT ymax = bg ->GetY(); + while ( !_LI.hitroot() ) + { + bg = _LI.item()->GetBeginNode(); + // make _boundingbox bigger if the link makes the graph bigger + // Checking if point is in bounding-box with marge + xmin = bmin( xmin, bg->GetX() ); + xmax = bmax( xmax, bg->GetX() ); + ymin = bmin( ymin, bg->GetY() ); + ymax = bmax( ymax, bg->GetY() ); + _LI++; + } - B_INT dx=(xmax-xmin); - B_INT dy=(ymax-ymin); + B_INT dx = ( xmax - xmin ); + B_INT dy = ( ymax - ymin ); - if ((dx < howsmall) && (dy < howsmall) ) - return true; + if ( ( dx < howsmall ) && ( dy < howsmall ) ) + return true; - return false; + return false; } //create a circle at end and begin point // and block in between -void Graph::Make_Rounded_Shape( KBoolLink* a_link, double factor) +void Graph::Make_Rounded_Shape( KBoolLink* a_link, double factor ) { - double phi,dphi,dx,dy; - int Segments=6; - int i; + double phi, dphi, dx, dy; + int Segments = 6; + int i; - KBoolLine theline(a_link, _GC); - theline.CalculateLineParameters(); + KBoolLine theline( a_link, _GC ); + theline.CalculateLineParameters(); - Node* _current; - Node *_first = new Node(a_link->GetBeginNode(), _GC); - Node *_last_ins = _first; + Node* _current; + Node *_first = new Node( a_link->GetBeginNode(), _GC ); + Node *_last_ins = _first; - theline.Virtual_Point(_first,factor); + theline.Virtual_Point( _first, factor ); - // make a node from this point - _current = new Node(a_link->GetEndNode(), _GC); - theline.Virtual_Point(_current,factor); + // make a node from this point + _current = new Node( a_link->GetEndNode(), _GC ); + theline.Virtual_Point( _current, factor ); - // make a link between the current and the previous and add this to graph - AddLink(_last_ins, _current); - _last_ins=_current; + // make a link between the current and the previous and add this to graph + AddLink( _last_ins, _current ); + _last_ins = _current; - // make a half circle around the clock with the opposite point as - // the middle point of the circle - dphi=M_PI/(Segments); - for (i=1; iGetX() - a_link->GetEndNode()->GetX(); - dy = (double) _last_ins->GetY() - a_link->GetEndNode()->GetY(); - phi=atan2(dy,dx); + // make a half circle around the clock with the opposite point as + // the middle point of the circle + dphi = M_PI / ( Segments ); + for ( i = 1; i < Segments; i++ ) + { + dx = ( double ) _last_ins->GetX() - a_link->GetEndNode()->GetX(); + dy = ( double ) _last_ins->GetY() - a_link->GetEndNode()->GetY(); + phi = atan2( dy, dx ); - _current = new Node((B_INT) (a_link->GetEndNode()->GetX() + factor * cos(phi-dphi)), - (B_INT) (a_link->GetEndNode()->GetY() + factor * sin(phi-dphi)), _GC); + _current = new Node( ( B_INT ) ( a_link->GetEndNode()->GetX() + factor * cos( phi - dphi ) ), + ( B_INT ) ( a_link->GetEndNode()->GetY() + factor * sin( phi - dphi ) ), _GC ); - AddLink(_last_ins, _current); + AddLink( _last_ins, _current ); - _last_ins=_current; - } + _last_ins = _current; + } - // make a node from the endnode of link - _current = new Node(a_link->GetEndNode(), _GC); - theline.Virtual_Point(_current,-factor); - AddLink(_last_ins, _current); - _last_ins=_current; + // make a node from the endnode of link + _current = new Node( a_link->GetEndNode(), _GC ); + theline.Virtual_Point( _current, -factor ); + AddLink( _last_ins, _current ); + _last_ins = _current; - // make a node from this beginnode of link - _current = new Node(a_link->GetBeginNode(), _GC); - theline.Virtual_Point(_current,-factor); - AddLink(_last_ins, _current); - _last_ins=_current; + // make a node from this beginnode of link + _current = new Node( a_link->GetBeginNode(), _GC ); + theline.Virtual_Point( _current, -factor ); + AddLink( _last_ins, _current ); + _last_ins = _current; - for (i=1; iGetX() - a_link->GetBeginNode()->GetX(); - dy = (double) _last_ins->GetY() - a_link->GetBeginNode()->GetY(); - phi=atan2(dy,dx); + for ( i = 1; i < Segments; i++ ) + { + dx = ( double ) _last_ins->GetX() - a_link->GetBeginNode()->GetX(); + dy = ( double ) _last_ins->GetY() - a_link->GetBeginNode()->GetY(); + phi = atan2( dy, dx ); - _current = new Node((B_INT)(a_link->GetBeginNode()->GetX() + factor * cos(phi-dphi)), - (B_INT)(a_link->GetBeginNode()->GetY() + factor * sin(phi-dphi)), _GC); + _current = new Node( ( B_INT )( a_link->GetBeginNode()->GetX() + factor * cos( phi - dphi ) ), + ( B_INT )( a_link->GetBeginNode()->GetY() + factor * sin( phi - dphi ) ), _GC ); - AddLink(_last_ins, _current); + AddLink( _last_ins, _current ); - _last_ins=_current; - } + _last_ins = _current; + } - // make a link between the last and the first to close the graph - AddLink(_last_ins, _first); + // make a link between the last and the first to close the graph + AddLink( _last_ins, _first ); }; //make the graph clockwise orientation, //return if the graph needed redirection bool Graph::MakeClockWise() { - if ( _GC->GetOrientationEntryMode() ) - return false; + if ( _GC->GetOrientationEntryMode() ) + return false; - TDLI _LI=TDLI(_linklist); - if (_LI.empty()) return false; + TDLI _LI = TDLI( _linklist ); + if ( _LI.empty() ) return false; - KBoolLink *currentlink; - Node *begin; + KBoolLink *currentlink; + Node *begin; - _LI.foreach_mf(&KBoolLink::UnMark);//reset bin and mark flag of each link - _LI.mergesort(linkYXtopsorter); - _LI.tohead(); + _LI.foreach_mf( &KBoolLink::UnMark );//reset bin and mark flag of each link + _LI.mergesort( linkYXtopsorter ); + _LI.tohead(); - begin = GetMostTopLeft(&_LI); // from all the most Top nodes, - // take the most left one + begin = GetMostTopLeft( &_LI ); // from all the most Top nodes, + // take the most left one - currentlink=begin->GetNotFlat(); - if (!currentlink) - { - char buf[100]; - sprintf(buf,"no NON flat link MakeClockWise at %15.3lf , %15.3lf", - double(begin->GetX()),double(begin->GetY())); - throw Bool_Engine_Error(buf, "Error", 9, 0); - } + currentlink = begin->GetNotFlat(); + if ( !currentlink ) + { + char buf[100]; + sprintf( buf, "no NON flat link MakeClockWise at %15.3lf , %15.3lf", + double( begin->GetX() ), double( begin->GetY() ) ); + throw Bool_Engine_Error( buf, "Error", 9, 0 ); + } - //test to see if the orientation is right or left - if (currentlink->GetBeginNode() == begin) - { - if ( currentlink->GetEndNode()->GetX() < begin->GetX()) - { - //going left - //it needs redirection - ReverseAllLinks(); - return true; - } - } - else - { - if ( currentlink->GetBeginNode()->GetX() > begin->GetX()) - { //going left - //it needs redirection - ReverseAllLinks(); - return true; - } - } - return false; + //test to see if the orientation is right or left + if ( currentlink->GetBeginNode() == begin ) + { + if ( currentlink->GetEndNode()->GetX() < begin->GetX() ) + { + //going left + //it needs redirection + ReverseAllLinks(); + return true; + } + } + else + { + if ( currentlink->GetBeginNode()->GetX() > begin->GetX() ) + { //going left + //it needs redirection + ReverseAllLinks(); + return true; + } + } + return false; } -bool Graph::writegraph(bool linked ) +bool Graph::writegraph( bool linked ) { #if KBOOL_DEBUG == 1 - FILE* file = _GC->GetLogFile(); + FILE * file = _GC->GetLogFile(); - if (file == NULL) - return true; + if ( file == NULL ) + return true; - fprintf( file, "# graph\n" ); + fprintf( file, "# graph\n" ); - TDLI _LI=TDLI(_linklist); - if (_LI.empty()) - { - return true; - } + TDLI _LI = TDLI( _linklist ); + if ( _LI.empty() ) + { + return true; + } - _LI.tohead(); - while(!_LI.hitroot()) - { - KBoolLink* curl = _LI.item(); + _LI.tohead(); + while( !_LI.hitroot() ) + { + KBoolLink * curl = _LI.item(); - fprintf( file, " linkbegin %I64d %I64d \n", curl->GetBeginNode()->GetX() , curl->GetBeginNode()->GetY() ); + fprintf( file, " linkbegin %I64d %I64d \n", curl->GetBeginNode()->GetX() , curl->GetBeginNode()->GetY() ); - if (linked) - { - TDLI Inode(curl->GetBeginNode()->GetLinklist()); - Inode.tohead(); - while(!Inode.hitroot()) - { + if ( linked ) + { + TDLI Inode( curl->GetBeginNode()->GetLinklist() ); + Inode.tohead(); + while( !Inode.hitroot() ) + { - fprintf( file, " b %I64d %I64d \n", Inode.item()->GetBeginNode()->GetX() , Inode.item()->GetBeginNode()->GetY() ); + fprintf( file, " b %I64d %I64d \n", Inode.item()->GetBeginNode()->GetX() , Inode.item()->GetBeginNode()->GetY() ); - fprintf( file, " e %I64d %I64d \n", Inode.item()->GetEndNode()->GetX() , Inode.item()->GetEndNode()->GetY() ); + fprintf( file, " e %I64d %I64d \n", Inode.item()->GetEndNode()->GetX() , Inode.item()->GetEndNode()->GetY() ); - Inode++; - } - } - fprintf( file, " linkend %I64d %I64d \n", curl->GetEndNode()->GetX() , curl->GetEndNode()->GetY() ); + Inode++; + } + } + fprintf( file, " linkend %I64d %I64d \n", curl->GetEndNode()->GetX() , curl->GetEndNode()->GetY() ); - if (linked) - { - TDLI Inode(curl->GetEndNode()->GetLinklist()); - Inode.tohead(); - while(!Inode.hitroot()) - { + if ( linked ) + { + TDLI Inode( curl->GetEndNode()->GetLinklist() ); + Inode.tohead(); + while( !Inode.hitroot() ) + { - fprintf( file, " b %I64d %I64d \n", Inode.item()->GetBeginNode()->GetX() , Inode.item()->GetBeginNode()->GetY() ); + fprintf( file, " b %I64d %I64d \n", Inode.item()->GetBeginNode()->GetX() , Inode.item()->GetBeginNode()->GetY() ); - fprintf( file, " e %I64d %I64d \n", Inode.item()->GetEndNode()->GetX() , Inode.item()->GetEndNode()->GetY() ); + fprintf( file, " e %I64d %I64d \n", Inode.item()->GetEndNode()->GetX() , Inode.item()->GetEndNode()->GetY() ); - Inode++; - } + Inode++; + } - } + } - if ( curl->GetBeginNode() == curl->GetEndNode() ) - fprintf( file, " null_link \n" ); + if ( curl->GetBeginNode() == curl->GetEndNode() ) + fprintf( file, " null_link \n" ); - fprintf( file, " group %d ", curl->Group() ); - fprintf( file, " bin %d ", curl->BeenHere() ); - fprintf( file, " mark %d ", curl->IsMarked() ); - fprintf( file, " leftA %d ", curl->GetLeftA() ); - fprintf( file, " rightA %d ", curl->GetRightA() ); - fprintf( file, " leftB %d ", curl->GetLeftB() ); - fprintf( file, " rightB %d \n", curl->GetRightB() ); - fprintf( file, " or %d ", curl->IsMarked(BOOL_OR) ); - fprintf( file, " and %d " , curl->IsMarked(BOOL_AND) ); - fprintf( file, " exor %d " , curl->IsMarked(BOOL_EXOR) ); - fprintf( file, " a_sub_b %d " , curl->IsMarked(BOOL_A_SUB_B) ); - fprintf( file, " b_sub_a %d " , curl->IsMarked(BOOL_B_SUB_A) ); - fprintf( file, " hole %d " , curl->GetHole() ); - fprintf( file, " top_hole %d \n" , curl->IsTopHole() ); - - _LI++; - } + fprintf( file, " group %d ", curl->Group() ); + fprintf( file, " bin %d ", curl->BeenHere() ); + fprintf( file, " mark %d ", curl->IsMarked() ); + fprintf( file, " leftA %d ", curl->GetLeftA() ); + fprintf( file, " rightA %d ", curl->GetRightA() ); + fprintf( file, " leftB %d ", curl->GetLeftB() ); + fprintf( file, " rightB %d \n", curl->GetRightB() ); + fprintf( file, " or %d ", curl->IsMarked( BOOL_OR ) ); + fprintf( file, " and %d " , curl->IsMarked( BOOL_AND ) ); + fprintf( file, " exor %d " , curl->IsMarked( BOOL_EXOR ) ); + fprintf( file, " a_sub_b %d " , curl->IsMarked( BOOL_A_SUB_B ) ); + fprintf( file, " b_sub_a %d " , curl->IsMarked( BOOL_B_SUB_A ) ); + fprintf( file, " hole %d " , curl->GetHole() ); + fprintf( file, " top_hole %d \n" , curl->IsTopHole() ); + + _LI++; + } #endif - return true; + return true; } bool Graph::writeintersections() @@ -2418,212 +2412,209 @@ bool Graph::writeintersections() #if KBOOL_DEBUG == 1 - FILE* file = _GC->GetLogFile(); + FILE * file = _GC->GetLogFile(); - if (file == NULL) - return true; + if ( file == NULL ) + return true; - fprintf( file, "# graph\n" ); + fprintf( file, "# graph\n" ); - TDLI _LI=TDLI(_linklist); - if (_LI.empty()) - { - return true; - } + TDLI _LI = TDLI( _linklist ); + if ( _LI.empty() ) + { + return true; + } - _LI.tohead(); - while(!_LI.hitroot()) - { - KBoolLink* curl=_LI.item(); - TDLI Inode(curl->GetBeginNode()->GetLinklist()); - Inode.tohead(); - if (Inode.count() > 2) - { - fprintf( file, " count %I64d", Inode.count() ); - fprintf( file, " b %I64d %I64d \n\n", curl->GetBeginNode()->GetX() , curl->GetBeginNode()->GetY() ); - } - _LI++; - } + _LI.tohead(); + while( !_LI.hitroot() ) + { + KBoolLink * curl = _LI.item(); + TDLI Inode( curl->GetBeginNode()->GetLinklist() ); + Inode.tohead(); + if ( Inode.count() > 2 ) + { + fprintf( file, " count %I64d", Inode.count() ); + fprintf( file, " b %I64d %I64d \n\n", curl->GetBeginNode()->GetX() , curl->GetBeginNode()->GetY() ); + } + _LI++; + } #endif - return true; + return true; } bool Graph::checksort() { - // if empty then just insert - if (_linklist->empty()) - return true; + // if empty then just insert + if ( _linklist->empty() ) + return true; - TDLI _LI=TDLI(_linklist); - // put new item left of the one that is bigger - _LI.tohead(); - KBoolLink* prev=_LI.item(); - KBoolLink* cur=_LI.item(); - _LI++; - while(!_LI.hitroot()) - { - KBoolLink* aap=_LI.item(); - if (linkXYsorter(prev,_LI.item())==-1) - { - cur=aap; + TDLI _LI = TDLI( _linklist ); + // put new item left of the one that is bigger + _LI.tohead(); + KBoolLink* prev = _LI.item(); + KBoolLink* cur = _LI.item(); + _LI++; + while( !_LI.hitroot() ) + { + KBoolLink * aap = _LI.item(); + if ( linkXYsorter( prev, _LI.item() ) == -1 ) + { + cur = aap; - return false; - } - prev=_LI.item(); - _LI++; - } - return true; + return false; + } + prev = _LI.item(); + _LI++; + } + return true; } void Graph::WriteKEY( Bool_Engine* GC, FILE* file ) { - double scale = 1.0/GC->GetGrid()/GC->GetGrid(); + double scale = 1.0 / GC->GetGrid() / GC->GetGrid(); - bool ownfile = false; - if ( !file ) - { - file = fopen("keyfile.key", "w"); - ownfile = true; + bool ownfile = false; + if ( !file ) + { + file = fopen( "keyfile.key", "w" ); + ownfile = true; - 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; \ - "); - } + 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 _LI=TDLI(_linklist); - if (_LI.empty()) - { - if ( ownfile ) - { - fprintf(file,"\ - ENDSTR top; \ - ENDLIB; \ - "); - fclose (file); + TDLI _LI=TDLI(_linklist); + if (_LI.empty()) + { + if ( ownfile ) + { + fprintf(file,"\ + ENDSTR top; \ + ENDLIB; \ + "); + fclose (file); - } - return; - } + } + return; + } - _LI.tohead(); - KBoolLink* curl = _LI.item(); + _LI.tohead(); + KBoolLink* curl = _LI.item(); - if ( _LI.item()->Group() == GROUP_A ) - fprintf(file,"BOUNDARY; LAYER 0; DATATYPE 0;\n"); - else - fprintf(file,"BOUNDARY; LAYER 1; DATATYPE 0;\n"); - fprintf(file," XY %d; \n", _LI.count()+1 ); + if ( _LI.item()->Group() == GROUP_A ) + fprintf(file,"BOUNDARY; LAYER 0; DATATYPE 0;\n"); + else + fprintf(file,"BOUNDARY; LAYER 1; DATATYPE 0;\n"); + fprintf(file," XY % d; \n", _LI.count()+1 ); - double firstx = curl->GetBeginNode()->GetX()*scale; - double firsty = curl->GetBeginNode()->GetY()*scale; - fprintf(file,"X %f;\t", firstx); - fprintf(file,"Y %f; \n", firsty); - _LI++; + double firstx = curl->GetBeginNode()->GetX()*scale; + double firsty = curl->GetBeginNode()->GetY()*scale; + fprintf(file,"X % f;\t", firstx); + fprintf(file,"Y % f; \n", firsty); + _LI++; - while(!_LI.hitroot()) - { - KBoolLink* curl = _LI.item(); + while(!_LI.hitroot()) + { + KBoolLink* curl = _LI.item(); - fprintf(file,"X %f;\t", curl->GetBeginNode()->GetX()*scale); - fprintf(file,"Y %f; \n", curl->GetBeginNode()->GetY()*scale); - - _LI++; - } - fprintf(file,"X %f;\t", firstx); - fprintf(file,"Y %f; \n", firsty); - fprintf(file,"ENDEL;\n"); + fprintf(file,"X % f;\t", curl->GetBeginNode()->GetX()*scale); + fprintf(file,"Y % f; \n", curl->GetBeginNode()->GetY()*scale); - if ( ownfile ) - { - fprintf(file,"\ - ENDSTR top; \ - ENDLIB; \ - "); - fclose (file); + _LI++; + } + fprintf(file,"X % f;\t", firstx); + fprintf(file,"Y % f; \n", firsty); + fprintf(file,"ENDEL;\n"); - } + if ( ownfile ) + { + fprintf(file,"\ + ENDSTR top; \ + ENDLIB; \ + "); + fclose (file); + + } } - + void Graph::WriteGraphKEY(Bool_Engine* GC) { -#if KBOOL_DEBUG == 1 - double scale = 1.0/GC->GetGrid()/GC->GetGrid(); + double scale = 1.0/GC->GetGrid()/GC->GetGrid(); - FILE* file = fopen("keygraphfile.key", "w"); + FILE* file = fopen("keygraphfile.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 1; PHYSUNITS 1e-006; \ - \ - BGNSTR; \ - CREATION {2-11-15 15:39:21}; \ - LASTMOD {2-11-15 15:39:21}; \ - STRNAME top; \ - "); + fprintf(file,"\ + HEADER 5; \ + BGNLIB; \ + LASTMOD {2 - 11 - 15 15: 39: 21}; \ + LASTACC {2 - 11 - 15 15: 39: 21}; \ + LIBNAME trial; \ + UNITS; \ + USERUNITS 1; PHYSUNITS 1e-006; \ + \ + BGNSTR; \ + CREATION {2 - 11 - 15 15: 39: 21}; \ + LASTMOD {2 - 11 - 15 15: 39: 21}; \ + STRNAME top; \ + "); - TDLI _LI=TDLI(_linklist); - if (_LI.empty()) - { - fprintf(file,"\ - ENDSTR top; \ - ENDLIB; \ - "); - fclose (file); - return; - } + TDLI _LI=TDLI(_linklist); + if (_LI.empty()) + { + fprintf(file,"\ + ENDSTR top; \ + ENDLIB; \ + "); + fclose (file); + return; + } - _LI.tohead(); - KBoolLink* curl; + _LI.tohead(); + KBoolLink* curl; - int _nr_of_points = _linklist->count(); - for (int i = 0; i < _nr_of_points; i++) - { - curl = _LI.item(); + int _nr_of_points = _linklist->count(); + for (int i = 0; i < _nr_of_points; i++) + { + curl = _LI.item(); - if ( curl->Group() == GROUP_A ) - fprintf(file,"PATH; LAYER 0;\n"); - else - fprintf(file,"PATH; LAYER 1;\n"); + if ( curl->Group() == GROUP_A ) + fprintf(file,"PATH; LAYER 0;\n"); + else + fprintf(file,"PATH; LAYER 1;\n"); - fprintf(file," XY %d; \n", 2 ); - fprintf(file,"X %f;\t", curl->GetBeginNode()->GetX()*scale); - fprintf(file,"Y %f; \n", curl->GetBeginNode()->GetY()*scale); - fprintf(file,"X %f;\t", curl->GetEndNode()->GetX()*scale); - fprintf(file,"Y %f; \n", curl->GetEndNode()->GetY()*scale); - _LI++; - fprintf(file,"ENDEL;\n"); - } + fprintf(file," XY % d; \n", 2 ); + fprintf(file,"X % f;\t", curl->GetBeginNode()->GetX()*scale); + fprintf(file,"Y % f; \n", curl->GetBeginNode()->GetY()*scale); + fprintf(file,"X % f;\t", curl->GetEndNode()->GetX()*scale); + fprintf(file,"Y % f; \n", curl->GetEndNode()->GetY()*scale); + _LI++; + fprintf(file,"ENDEL;\n"); + } - fprintf(file,"\ - ENDSTR top; \ - ENDLIB; \ - "); + fprintf(file,"\ + ENDSTR top; \ + ENDLIB; \ + "); - fclose (file); - -#endif + fclose (file); } diff --git a/polygon/kbool/src/graphlst.cpp b/polygon/kbool/src/graphlst.cpp index 851f118684..e72a827f4c 100644 --- a/polygon/kbool/src/graphlst.cpp +++ b/polygon/kbool/src/graphlst.cpp @@ -1,97 +1,93 @@ -/*! \file ../src/graphlst.cpp +/*! \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 $ + \author Klaas Holwerda + + Copyright: 2001-2004 (C) Klaas Holwerda + + Licence: see kboollicense.txt + + RCS-ID: $Id: graphlst.cpp,v 1.3 2008/06/04 21:23:22 titato Exp $ */ -#ifdef __GNUG__ -#pragma implementation -#endif - //#include "debugdrv.h" -#include "../include/booleng.h" -#include "../include/graphlst.h" +#include "kbool/booleng.h" +#include "kbool/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 * ); +int graphsorterX( Graph *, Graph * ); +int graphsorterY( Graph *, Graph * ); -GraphList::GraphList(Bool_Engine* GC) +GraphList::GraphList( Bool_Engine* GC ) { - _GC=GC; + _GC = GC; } -GraphList::GraphList( GraphList* other ) +GraphList::GraphList( GraphList* other ) { - _GC = other->_GC; + _GC = other->_GC; - TDLI _LI = TDLI( other ); - _LI.tohead(); - while (!_LI.hitroot()) - { - insend( new Graph( _LI.item() ) ); - _LI++; - } + TDLI _LI = TDLI( other ); + _LI.tohead(); + while ( !_LI.hitroot() ) + { + insend( new Graph( _LI.item() ) ); + _LI++; + } } GraphList::~GraphList() { - TDLI _LI=TDLI(this); - //first empty the graph - _LI.delete_all(); + TDLI _LI = TDLI( 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) +void GraphList::Prepare( Graph* total ) { - if (empty()) - return; + if ( empty() ) + return; - //round to grid and put in one graph - _GC->SetState("Simplify"); + //round to grid and put in one graph + _GC->SetState( "Simplify" ); - // Simplify all graphs in the list - Simplify( (double) _GC->GetGrid() ); + // Simplify all graphs in the list + Simplify( ( double ) _GC->GetGrid() ); - if ( ! _GC->GetOrientationEntryMode() ) - { - TDLI _LI=TDLI(this); - _LI.tohead(); - while (!_LI.hitroot()) - { - _LI.item()->MakeClockWise(); - _LI++; - } - } + if ( ! _GC->GetOrientationEntryMode() ) + { + TDLI _LI = TDLI( this ); + _LI.tohead(); + while ( !_LI.hitroot() ) + { + _LI.item()->MakeClockWise(); + _LI++; + } + } - Renumber(); + Renumber(); - //the graplist contents will be transferred to one graph - MakeOneGraph(total); + //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) +void GraphList::MakeOneGraph( Graph* total ) { - TDLI _LI=TDLI(this); - _LI.tohead(); - while(!_LI.hitroot()) - { - total->TakeOver(_LI.item()); - delete _LI.item(); - _LI.remove(); - } + TDLI _LI = TDLI( this ); + _LI.tohead(); + while( !_LI.hitroot() ) + { + total->TakeOver( _LI.item() ); + delete _LI.item(); + _LI.remove(); + } } // @@ -99,85 +95,85 @@ void GraphList::MakeOneGraph(Graph* total) // void GraphList::Renumber() { - if ( _GC->GetOrientationEntryMode() ) - { - TDLI _LI=TDLI(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 _LI=TDLI(this); - _LI.tohead(); - while (!_LI.hitroot()) - { - _LI.item()->SetNumber(Number++); - _LI++; - } - } + if ( _GC->GetOrientationEntryMode() ) + { + TDLI _LI = TDLI( 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 _LI = TDLI( this ); + _LI.tohead(); + while ( !_LI.hitroot() ) + { + _LI.item()->SetNumber( Number++ ); + _LI++; + } + } } // Simplify the graphs -void GraphList::Simplify(double marge) +void GraphList::Simplify( double marge ) { - TDLI _LI=TDLI(this); - _LI.foreach_mf(&Graph::Reset_Mark_and_Bin); + TDLI _LI = TDLI( 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++; - } + _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) +void GraphList::Smoothen( double marge ) { - TDLI _LI=TDLI(this); - _LI.foreach_mf(&Graph::Reset_Mark_and_Bin); + TDLI _LI = TDLI( 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++; - } + _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 _LI=TDLI(this); - _LI.foreach_mf(&Graph::Reset_Mark_and_Bin); + TDLI _LI = TDLI( this ); + _LI.foreach_mf( &Graph::Reset_Mark_and_Bin ); } //============================================================================== @@ -188,209 +184,209 @@ void GraphList::UnMarkAll() void GraphList::Correction() { - TDLI _LI=TDLI(this); - int todo=_LI.count(); + TDLI _LI = TDLI( this ); + int todo = _LI.count(); - if ( _GC->GetInternalCorrectionFactor()) //not zero - { - _LI.tohead(); - for(int i=0; iGetInternalCorrectionFactor() ) //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 _LI = TDLI( 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()->Correction(_correct,_GC->GetInternalCorrectionFactor()); + _LI.item()->MakeRing( _ring, _GC->GetInternalCorrectionFactor() ); delete _LI.item(); _LI.remove(); - //move corrected graphlist to result - while (!_correct->empty()) + //move created rings graphs to this + while ( !_ring->empty() ) { - //add to end - _LI.insend((Graph*)_correct->headitem()); - _correct->removehead(); + //add to end + ( ( Graph* )_ring->headitem() )->MakeClockWise(); + _LI.insend( ( Graph* )_ring->headitem() ); + _ring->removehead(); } - } - delete _correct; - } - } - } - -void GraphList::MakeRings() -{ - TDLI _LI=TDLI(this); - int todo=_LI.count(); - - _LI.tohead(); - for(int i=0; iMakeClockWise(); - _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; - } + } + delete _ring; + } } //merge the graphs in the list and return the merged result void GraphList::Merge() { - if (count()<=1) - return; + if ( count() <= 1 ) + return; - { - TDLI _LI=TDLI(this); - _LI.tohead(); - while (!_LI.hitroot()) - { - _LI.item()->SetGroup(GROUP_A); - _LI++; - } - } + { + TDLI _LI = TDLI( this ); + _LI.tohead(); + while ( !_LI.hitroot() ) + { + _LI.item()->SetGroup( GROUP_A ); + _LI++; + } + } - Graph* _tomerge=new Graph(_GC); + Graph* _tomerge = new Graph( _GC ); - Renumber(); + Renumber(); - //the graplist contents will be transferred to one graph - MakeOneGraph(_tomerge); - //the original is empty now + //the graplist contents will be transferred to one graph + MakeOneGraph( _tomerge ); + //the original is empty now - _tomerge->Prepare(1); - _tomerge->Boolean(BOOL_OR,this); + _tomerge->Prepare( 1 ); + _tomerge->Boolean( BOOL_OR, this ); - delete _tomerge; + delete _tomerge; } -#define TRIALS 30 +#define TRIALS 30 #define SAVEME 1 //perform boolean operation on the graphs in the list -void GraphList::Boolean(BOOL_OP operation, int intersectionRunsMax ) +void GraphList::Boolean( BOOL_OP operation, int intersectionRunsMax ) { - _GC->SetState("Performing Boolean Operation"); + _GC->SetState( "Performing Boolean Operation" ); - if (count()==0) - return; + if ( count() == 0 ) + return; - Graph* _prepared = new Graph(_GC); + Graph* _prepared = new Graph( _GC ); - if (empty()) - return; - - //round to grid and put in one graph - _GC->SetState("Simplify"); + if ( empty() ) + return; - int intersectionruns = 1; + //round to grid and put in one graph + _GC->SetState( "Simplify" ); - while ( intersectionruns <= intersectionRunsMax ) - { - try - { - Prepare( _prepared ); + int intersectionruns = 1; - 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) - { + 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); + _prepared->WriteGraphKEY( _GC ); #endif - intersectionruns++; - if ( intersectionruns == intersectionRunsMax ) - { - _prepared->WriteGraphKEY(_GC); - _GC->info(error.GetErrorMessage(), "error"); - throw error; - } - } - catch(...) - { + intersectionruns++; + if ( intersectionruns == intersectionRunsMax ) + { + _prepared->WriteGraphKEY( _GC ); + _GC->info( error.GetErrorMessage(), "error" ); + throw error; + } + } + catch( ... ) + { #if KBOOL_DEBUG - _prepared->WriteGraphKEY(_GC); + _prepared->WriteGraphKEY( _GC ); #endif - intersectionruns++; - if ( intersectionruns == intersectionRunsMax ) - { - _prepared->WriteGraphKEY(_GC); - _GC->info("Unknown exception", "error"); - throw; - } - } - } + intersectionruns++; + if ( intersectionruns == intersectionRunsMax ) + { + _prepared->WriteGraphKEY( _GC ); + _GC->info( "Unknown exception", "error" ); + throw; + } + } + } - delete _prepared; + delete _prepared; } void GraphList::WriteGraphs() { - TDLI _LI=TDLI(this); - _LI.tohead(); - while(!_LI.hitroot()) - { + TDLI _LI = TDLI( this ); + _LI.tohead(); + while( !_LI.hitroot() ) + { _LI.item()->writegraph( false ); _LI++; - } + } } void GraphList::WriteGraphsKEY( Bool_Engine* GC ) { - FILE* file = fopen("graphkeyfile.key", "w"); + 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; \ - "); + 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 _LI=TDLI(this); - _LI.tohead(); - while(!_LI.hitroot()) - { + TDLI _LI=TDLI(this); + _LI.tohead(); + while(!_LI.hitroot()) + { _LI.item()->WriteKEY( GC, file ); _LI++; - } + } - fprintf(file,"\ - ENDSTR top; \ - ENDLIB; \ - "); + fprintf(file,"\ + ENDSTR top; \ + ENDLIB; \ + "); - fclose (file); + fclose (file); } diff --git a/polygon/kbool/src/instonly.cpp b/polygon/kbool/src/instonly.cpp index 0eb5e3782b..67edd2e4d9 100644 --- a/polygon/kbool/src/instonly.cpp +++ b/polygon/kbool/src/instonly.cpp @@ -1,25 +1,25 @@ -/*! \file ../src/instonly.cpp +/*! \file kbool/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 $ + + RCS-ID: $Id: instonly.cpp,v 1.2 2006/11/05 14:59:31 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" +#include "kbool/_dl_itr.h" +#include "kbool/node.h" +#include "kbool/record.h" +#include "kbool/link.h" +#include "kbool/_lnk_itr.h" +#include "kbool/scanbeam.h" +#include "kbool/graph.h" +#include "kbool/graphlst.h" +//#include "kbool/misc.h" template class DL_Node; template class DL_Iter; diff --git a/polygon/kbool/src/line.cpp b/polygon/kbool/src/line.cpp index 4272e631c2..b1d38e275a 100644 --- a/polygon/kbool/src/line.cpp +++ b/polygon/kbool/src/line.cpp @@ -1,72 +1,65 @@ -/*! \file ../src/line.cpp +/*! \file src/line.cpp \brief Mainly used for calculating crossings - \author Probably Klaas Holwerda - - Copyright: 2001-2004 (C) Probably Klaas Holwerda - - Licence: wxWidgets Licence - - RCS-ID: $Id: line.cpp,v 1.10 2005/06/17 22:48:46 kbluck Exp $ + \author Klaas Holwerda + + Copyright: 2001-2004 (C) Klaas Holwerda + + Licence: see kboollicense.txt + + RCS-ID: $Id: line.cpp,v 1.3 2008/06/04 21:23:22 titato Exp $ */ -#ifdef __GNUG__ -#pragma implementation -#endif - // Standard include files -#include -#include - -#include "../include/booleng.h" +#include "kbool/booleng.h" // Include files for forward declarations -#include "../include/link.h" -#include "../include/node.h" +#include "kbool/link.h" +#include "kbool/node.h" // header -#include "../include/line.h" +#include "kbool/line.h" -#include "../include/graph.h" -#include "../include/graphlst.h" +#include "kbool/graph.h" +#include "kbool/graphlst.h" // // The default constructor // -KBoolLine::KBoolLine(Bool_Engine* GC) +KBoolLine::KBoolLine( Bool_Engine* GC ) { - m_GC=GC; - m_AA = 0.0; - m_BB = 0.0; - m_CC = 0.0; - m_link = 0; - linecrosslist = NULL; - m_valid_parameters = false; + m_GC = GC; + m_AA = 0.0; + m_BB = 0.0; + m_CC = 0.0; + m_link = 0; + linecrosslist = NULL; + m_valid_parameters = false; } KBoolLine::~KBoolLine() { - if (linecrosslist) - delete linecrosslist; + if ( linecrosslist ) + delete linecrosslist; } // // constructor with a link // -KBoolLine::KBoolLine(KBoolLink *a_link,Bool_Engine* GC) +KBoolLine::KBoolLine( KBoolLink *a_link, Bool_Engine* GC ) { - m_GC=GC; - // a_link must exist - assert(a_link); - // points may not be equal - // must be an if statement because if an assert is used there will - // be a macro expansion error + m_GC = GC; + // a_link must exist + assert( a_link ); + // points may not be equal + // must be an if statement because if an assert is used there will + // be a macro expansion error - //if (a_link->GetBeginNode()->Equal(a_link->GetEndNode(), 1)) - // assert(!a_link); + //if (a_link->GetBeginNode()->Equal(a_link->GetEndNode(), 1)) + // assert(!a_link); - linecrosslist = NULL; - m_link = a_link; - m_valid_parameters = false; + linecrosslist = NULL; + m_link = a_link; + m_valid_parameters = false; } @@ -76,7 +69,7 @@ KBoolLine::KBoolLine(KBoolLink *a_link,Bool_Engine* GC) // has given the results of two points in relation to a line. See table 1 in the report // // input Result_beginnode: -// Result_endnode : +// Result_endnode : // The results can be LEFT_SIDE, RIGHT_SIDE, ON_AREA, IN_AREA // // return -1: Illegal combination @@ -84,106 +77,106 @@ KBoolLine::KBoolLine(KBoolLink *a_link,Bool_Engine* GC) // 1: Investigate results points in relation to the other line // 2: endnode is a crosspoint, no further investigation // 3: beginnode is a crosspoint, no further investigation -// 4: beginnode and endnode are crosspoints, no further investigation +// 4: beginnode and endnode are crosspoints, no further investigation // 5: beginnode is a crosspoint, need further investigation // 6: endnode is a crosspoint, need further investigation -int KBoolLine::ActionOnTable1(PointStatus Result_beginnode, PointStatus Result_endnode) +int KBoolLine::ActionOnTable1( PointStatus Result_beginnode, PointStatus Result_endnode ) { - // Action 1.5 beginnode and endnode are crosspoints, no further investigation needed - if ( - (Result_beginnode == IN_AREA) - && - (Result_endnode == IN_AREA) - ) - return 4; - // Action 1.1, there are no crosspoints, no action - if ( - ( - (Result_beginnode == LEFT_SIDE) - && - (Result_endnode == LEFT_SIDE) - ) - || - ( - (Result_beginnode == RIGHT_SIDE) - && - (Result_endnode == RIGHT_SIDE) - ) - ) - return 0; - // Action 1.2, maybe there is a crosspoint, further investigation needed - if ( - ( - (Result_beginnode == LEFT_SIDE) - && - ( - (Result_endnode == RIGHT_SIDE) - || - (Result_endnode == ON_AREA) - ) - ) - || - ( - (Result_beginnode == RIGHT_SIDE) - && - ( - (Result_endnode == LEFT_SIDE) - || - (Result_endnode == ON_AREA) - ) - ) - || - ( - (Result_beginnode == ON_AREA) - && - ( - (Result_endnode == LEFT_SIDE) - || - (Result_endnode == RIGHT_SIDE) - || - (Result_endnode == ON_AREA) - ) - ) - ) - return 1; - // Action 1.3, there is a crosspoint, no further investigation - if ( - ( - (Result_beginnode == LEFT_SIDE) - || - (Result_beginnode == RIGHT_SIDE) - ) - && - (Result_endnode == IN_AREA) - ) - return 2; - // Action 1.4 there is a crosspoint, no further investigation - if ( - (Result_beginnode == IN_AREA) - && - ( - (Result_endnode == LEFT_SIDE) - || - (Result_endnode == RIGHT_SIDE) - ) - ) - return 3; - // Action 1.6 beginnode is a crosspoint, further investigation needed - if ( - (Result_beginnode == IN_AREA) - && - (Result_endnode == ON_AREA) - ) - return 5; - // Action 1.7 endnode is a crosspoint, further investigation needed - if ( - (Result_beginnode == ON_AREA) - && - (Result_endnode == IN_AREA) - ) - return 6; - // All other combinations are illegal - return -1; + // Action 1.5 beginnode and endnode are crosspoints, no further investigation needed + if ( + ( Result_beginnode == IN_AREA ) + && + ( Result_endnode == IN_AREA ) + ) + return 4; + // Action 1.1, there are no crosspoints, no action + if ( + ( + ( Result_beginnode == LEFT_SIDE ) + && + ( Result_endnode == LEFT_SIDE ) + ) + || + ( + ( Result_beginnode == RIGHT_SIDE ) + && + ( Result_endnode == RIGHT_SIDE ) + ) + ) + return 0; + // Action 1.2, maybe there is a crosspoint, further investigation needed + if ( + ( + ( Result_beginnode == LEFT_SIDE ) + && + ( + ( Result_endnode == RIGHT_SIDE ) + || + ( Result_endnode == ON_AREA ) + ) + ) + || + ( + ( Result_beginnode == RIGHT_SIDE ) + && + ( + ( Result_endnode == LEFT_SIDE ) + || + ( Result_endnode == ON_AREA ) + ) + ) + || + ( + ( Result_beginnode == ON_AREA ) + && + ( + ( Result_endnode == LEFT_SIDE ) + || + ( Result_endnode == RIGHT_SIDE ) + || + ( Result_endnode == ON_AREA ) + ) + ) + ) + return 1; + // Action 1.3, there is a crosspoint, no further investigation + if ( + ( + ( Result_beginnode == LEFT_SIDE ) + || + ( Result_beginnode == RIGHT_SIDE ) + ) + && + ( Result_endnode == IN_AREA ) + ) + return 2; + // Action 1.4 there is a crosspoint, no further investigation + if ( + ( Result_beginnode == IN_AREA ) + && + ( + ( Result_endnode == LEFT_SIDE ) + || + ( Result_endnode == RIGHT_SIDE ) + ) + ) + return 3; + // Action 1.6 beginnode is a crosspoint, further investigation needed + if ( + ( Result_beginnode == IN_AREA ) + && + ( Result_endnode == ON_AREA ) + ) + return 5; + // Action 1.7 endnode is a crosspoint, further investigation needed + if ( + ( Result_beginnode == ON_AREA ) + && + ( Result_endnode == IN_AREA ) + ) + return 6; + // All other combinations are illegal + return -1; } @@ -194,7 +187,7 @@ int KBoolLine::ActionOnTable1(PointStatus Result_beginnode, PointStatus Result_e // are investigated in relation to the line wich can be constucted from the points. // // input Result_beginnode: -// Result_endnode : +// Result_endnode : // The results can be LEFT_SIDE, RIGHT_SIDE, ON_AREA, IN_AREA // // return -1: Illegal combination @@ -203,93 +196,93 @@ int KBoolLine::ActionOnTable1(PointStatus Result_beginnode, PointStatus Result_e // 2: endnode is a crosspoint // 3: beginnode is a crosspoint // 4: beginnode and endnode are crosspoints -int KBoolLine::ActionOnTable2(PointStatus Result_beginnode, PointStatus Result_endnode) +int KBoolLine::ActionOnTable2( PointStatus Result_beginnode, PointStatus Result_endnode ) { - // Action 2.5, beginnode and eindpoint are crosspoints - if ( - (Result_beginnode == IN_AREA) - && - (Result_endnode == IN_AREA) - ) - return 4; - // Action 2.1, there are no crosspoints - if ( - ( - (Result_beginnode == LEFT_SIDE) - && - ( - (Result_endnode == LEFT_SIDE) - || - (Result_endnode == ON_AREA) - ) - ) - || - ( - (Result_beginnode == RIGHT_SIDE) - && - ( - (Result_endnode == RIGHT_SIDE) - || - (Result_endnode == ON_AREA) - ) - ) - || - ( - (Result_beginnode == ON_AREA) - && - ( - (Result_endnode == LEFT_SIDE) - || - (Result_endnode == RIGHT_SIDE) - || - (Result_endnode == ON_AREA) - ) - ) - ) - return 0; - // Action 2.2, there is a real intersect ion, which must be calculated - if ( - ( - (Result_beginnode == LEFT_SIDE) - && - (Result_endnode == RIGHT_SIDE) - ) - || - ( - (Result_beginnode == RIGHT_SIDE) - && - (Result_endnode == LEFT_SIDE) - ) - ) - return 1; - // Action 2.3, endnode is a crosspoint - if ( - ( - (Result_beginnode == LEFT_SIDE) - || - (Result_beginnode == RIGHT_SIDE) - || - (Result_beginnode == ON_AREA) - ) - && - (Result_endnode == IN_AREA) - ) - return 2; - // Action 2.4, beginnode is a crosspoint - if ( - (Result_beginnode == IN_AREA) - && - ( - (Result_endnode == LEFT_SIDE) - || - (Result_endnode == RIGHT_SIDE) - || - (Result_endnode == ON_AREA) - ) - ) - return 3; - // All other combinations are illegal - return -1; + // Action 2.5, beginnode and eindpoint are crosspoints + if ( + ( Result_beginnode == IN_AREA ) + && + ( Result_endnode == IN_AREA ) + ) + return 4; + // Action 2.1, there are no crosspoints + if ( + ( + ( Result_beginnode == LEFT_SIDE ) + && + ( + ( Result_endnode == LEFT_SIDE ) + || + ( Result_endnode == ON_AREA ) + ) + ) + || + ( + ( Result_beginnode == RIGHT_SIDE ) + && + ( + ( Result_endnode == RIGHT_SIDE ) + || + ( Result_endnode == ON_AREA ) + ) + ) + || + ( + ( Result_beginnode == ON_AREA ) + && + ( + ( Result_endnode == LEFT_SIDE ) + || + ( Result_endnode == RIGHT_SIDE ) + || + ( Result_endnode == ON_AREA ) + ) + ) + ) + return 0; + // Action 2.2, there is a real intersection, which must be calculated + if ( + ( + ( Result_beginnode == LEFT_SIDE ) + && + ( Result_endnode == RIGHT_SIDE ) + ) + || + ( + ( Result_beginnode == RIGHT_SIDE ) + && + ( Result_endnode == LEFT_SIDE ) + ) + ) + return 1; + // Action 2.3, endnode is a crosspoint + if ( + ( + ( Result_beginnode == LEFT_SIDE ) + || + ( Result_beginnode == RIGHT_SIDE ) + || + ( Result_beginnode == ON_AREA ) + ) + && + ( Result_endnode == IN_AREA ) + ) + return 2; + // Action 2.4, beginnode is a crosspoint + if ( + ( Result_beginnode == IN_AREA ) + && + ( + ( Result_endnode == LEFT_SIDE ) + || + ( Result_endnode == RIGHT_SIDE ) + || + ( Result_endnode == ON_AREA ) + ) + ) + return 3; + // All other combinations are illegal + return -1; } // @@ -297,54 +290,54 @@ int KBoolLine::ActionOnTable2(PointStatus Result_beginnode, PointStatus Result_e // the crossing will be put in the link, because the line will be destructed // after use of the variable // -void KBoolLine::AddLineCrossing(B_INT X, B_INT Y, KBoolLine *other_line) +void KBoolLine::AddLineCrossing( B_INT X, B_INT Y, KBoolLine *other_line ) { - // the other line must exist - assert(other_line); - // the links of the lines must exist - assert(other_line->m_link && m_link); - other_line->AddCrossing(AddCrossing(X,Y)); + // the other line must exist + assert( other_line ); + // the links of the lines must exist + assert( other_line->m_link && m_link ); + other_line->AddCrossing( AddCrossing( X, Y ) ); } // Calculate the Y when the X is given // -B_INT KBoolLine::Calculate_Y(B_INT X) +B_INT KBoolLine::Calculate_Y( B_INT X ) { - // link must exist to get info about the nodes - assert(m_link); + // link must exist to get info about the nodes + assert( m_link ); - CalculateLineParameters(); - if (m_AA != 0) - return (B_INT)(-(m_AA * X + m_CC) / m_BB); - else - // horizontal line - return m_link->GetBeginNode()->GetY(); + CalculateLineParameters(); + if ( m_AA != 0 ) + return ( B_INT )( -( m_AA * X + m_CC ) / m_BB ); + else + // horizontal line + return m_link->GetBeginNode()->GetY(); } -B_INT KBoolLine::Calculate_Y_from_X(B_INT X) +B_INT KBoolLine::Calculate_Y_from_X( B_INT X ) { - // link must exist to get info about the nodes - assert(m_link); - assert(m_valid_parameters); + // link must exist to get info about the nodes + assert( m_link ); + assert( m_valid_parameters ); - if (m_AA != 0) - return (B_INT) ((-(m_AA * X + m_CC) / m_BB)+0.5); - else - // horizontal line - return m_link->GetBeginNode()->GetY(); + if ( m_AA != 0 ) + return ( B_INT ) ( ( -( m_AA * X + m_CC ) / m_BB ) + 0.5 ); + else + // horizontal line + return m_link->GetBeginNode()->GetY(); } -void KBoolLine::Virtual_Point(LPoint *a_point,double distance) +void KBoolLine::Virtual_Point( LPoint *a_point, double distance ) { - // link must exist to get info about the nodes - assert(m_link); - assert(m_valid_parameters); + // link must exist to get info about the nodes + assert( m_link ); + assert( m_valid_parameters ); - //calculate the distance using the slope of the line - //and rotate 90 degrees + //calculate the distance using the slope of the line + //and rotate 90 degrees - a_point->SetY((B_INT)(a_point->GetY() + (distance * -(m_BB)))); - a_point->SetX((B_INT)(a_point->GetX() - (distance * m_AA ))); + a_point->SetY( ( B_INT )( a_point->GetY() + ( distance * -( m_BB ) ) ) ); + a_point->SetX( ( B_INT )( a_point->GetX() - ( distance * m_AA ) ) ); } @@ -354,39 +347,39 @@ void KBoolLine::Virtual_Point(LPoint *a_point,double distance) // void KBoolLine::CalculateLineParameters() { - // linkmust exist to get beginnode AND endnode - assert(m_link); + // linkmust exist to get beginnode AND endnode + assert( m_link ); - // if not valid_parameters calculate the parameters - if (!m_valid_parameters) - { - Node *bp, *ep; - double length; + // if not valid_parameters calculate the parameters + if ( !m_valid_parameters ) + { + Node * bp, *ep; + double length; - // get the begin and endnode via the link - bp = m_link->GetBeginNode(); - ep = m_link->GetEndNode(); + // get the begin and endnode via the link + bp = m_link->GetBeginNode(); + ep = m_link->GetEndNode(); - // bp AND ep may not be the same - if (bp == ep) - assert (bp != ep); + // bp AND ep may not be the same + if ( bp == ep ) + assert ( bp != ep ); - m_AA = (double) (ep->GetY() - bp->GetY()); // A = (Y2-Y1) - m_BB = (double) (bp->GetX() - ep->GetX()); // B = (X1-X2) + m_AA = ( double ) ( ep->GetY() - bp->GetY() ); // A = (Y2-Y1) + m_BB = ( double ) ( bp->GetX() - ep->GetX() ); // B = (X1-X2) - // the parameters A end B can now be normalized - length = sqrt(m_AA*m_AA + m_BB*m_BB); + // the parameters A end B can now be normalized + length = sqrt( m_AA * m_AA + m_BB * m_BB ); - if(length ==0) - m_GC->error("length = 0","CalculateLineParameters"); + if( length == 0 ) + m_GC->error( "length = 0", "CalculateLineParameters" ); - m_AA = (m_AA / length); - m_BB = (m_BB / length); + m_AA = ( m_AA / length ); + m_BB = ( m_BB / length ); - m_CC = -((m_AA * bp->GetX()) + (bp->GetY() * m_BB)); + m_CC = -( ( m_AA * bp->GetX() ) + ( bp->GetY() * m_BB ) ); - m_valid_parameters = true; - } + m_valid_parameters = true; + } } @@ -394,52 +387,54 @@ void KBoolLine::CalculateLineParameters() // inout Line : another line // Marge: optional, standard on MARGE (declared in MISC.CPP) // -// return true : lines are crossing -// false: lines are not crossing +// return true : lines are crossing +// false: lines are not crossing // -int KBoolLine::CheckIntersect (KBoolLine * lijn, double Marge) +int KBoolLine::CheckIntersect ( KBoolLine * lijn, double Marge ) { - double distance=0; - // link must exist - assert(m_link); - // lijn must exist - assert(lijn); + double distance = 0; + // link must exist + assert( m_link ); + // lijn must exist + assert( lijn ); - // points may not be equal - // must be an if statement because if an assert is used there will - // be a macro expansion error - if (m_link->GetBeginNode() == m_link->GetEndNode()) - assert(!m_link); + // points may not be equal + // must be an if statement because if an assert is used there will + // be a macro expansion error + if ( m_link->GetBeginNode() == m_link->GetEndNode() ) + assert( !m_link ); - int Take_Action1, Take_Action2, Total_Result; - Node *bp, *ep; - PointStatus Result_beginnode,Result_endnode; + int Take_Action1, Take_Action2, Total_Result; + Node *bp, *ep; + PointStatus Result_beginnode, Result_endnode; - bp = lijn->m_link->GetBeginNode(); - ep = lijn->m_link->GetEndNode(); - Result_beginnode = PointInLine(bp,distance,Marge); - Result_endnode = PointInLine(ep,distance,Marge); - Take_Action1 = ActionOnTable1(Result_beginnode,Result_endnode); - switch (Take_Action1) - { - case 0: Total_Result = false ; break; - case 1: { - bp = m_link->GetBeginNode(); - ep = m_link->GetEndNode(); - Result_beginnode = lijn->PointInLine(bp,distance,Marge); - Result_endnode = lijn->PointInLine(ep,distance,Marge); - Take_Action2 = ActionOnTable2(Result_beginnode,Result_endnode); - switch (Take_Action2) - { - case 0: Total_Result = false; break; - case 1: case 2: case 3: case 4: Total_Result = true; break; - default: Total_Result = false; assert( Total_Result ); - } - }; break; // This break belongs to the switch(Take_Action1) - case 2: case 3: case 4: case 5: case 6: Total_Result = true; break; - default: Total_Result = false; assert( Total_Result ); - } - return Total_Result; //This is the final decision + bp = lijn->m_link->GetBeginNode(); + ep = lijn->m_link->GetEndNode(); + Result_beginnode = PointInLine( bp, distance, Marge ); + Result_endnode = PointInLine( ep, distance, Marge ); + Take_Action1 = ActionOnTable1( Result_beginnode, Result_endnode ); + switch ( Take_Action1 ) + { + case 0: Total_Result = false ; break; + case 1: + { + bp = m_link->GetBeginNode(); + ep = m_link->GetEndNode(); + Result_beginnode = lijn->PointInLine( bp, distance, Marge ); + Result_endnode = lijn->PointInLine( ep, distance, Marge ); + Take_Action2 = ActionOnTable2( Result_beginnode, Result_endnode ); + switch ( Take_Action2 ) + { + case 0: Total_Result = false; break; + case 1: case 2: case 3: case 4: Total_Result = true; break; + default: Total_Result = false; assert( Total_Result ); + } + } + ; break; // This break belongs to the switch(Take_Action1) + case 2: case 3: case 4: case 5: case 6: Total_Result = true; break; + default: Total_Result = false; assert( Total_Result ); + } + return Total_Result; //This is the final decision } @@ -449,9 +444,9 @@ int KBoolLine::CheckIntersect (KBoolLine * lijn, double Marge) // Node *KBoolLine::GetBeginNode() { - // link must exist - assert(m_link); - return m_link->GetBeginNode(); + // link must exist + assert( m_link ); + return m_link->GetBeginNode(); } @@ -461,142 +456,144 @@ Node *KBoolLine::GetBeginNode() // Node *KBoolLine::GetEndNode() { - // link must exist - assert(m_link); - return m_link->GetEndNode(); + // link must exist + assert( m_link ); + return m_link->GetEndNode(); } // Intersects two lines // input Line : another line // Marge: optional, standard on MARGE // -// return 0: If there are no crossings -// 1: If there is one crossing -// 2: If there are two crossings -int KBoolLine::Intersect(KBoolLine * lijn, double Marge) +// return 0: If there are no crossings +// 1: If there is one crossing +// 2: If there are two crossings +int KBoolLine::Intersect( KBoolLine * lijn, double Marge ) { - double distance=0; - // lijn must exist - assert(lijn); + double distance = 0; + // lijn must exist + assert( lijn ); - // points may not be equal - // must be an if statement because if an assert is used there will - // be a macro expansion error - if (m_link->GetBeginNode() == m_link->GetEndNode()) - assert(!m_link); + // points may not be equal + // must be an if statement because if an assert is used there will + // be a macro expansion error + if ( m_link->GetBeginNode() == m_link->GetEndNode() ) + assert( !m_link ); - Node *bp, *ep; - PointStatus Result_beginnode,Result_endnode; - int Take_Action1, Take_Action2, Number_of_Crossings = 0; + Node *bp, *ep; + PointStatus Result_beginnode, Result_endnode; + int Take_Action1, Take_Action2, Number_of_Crossings = 0; - // Get the nodes from lijn via the link - bp = lijn->m_link->GetBeginNode(); - ep = lijn->m_link->GetEndNode(); + // Get the nodes from lijn via the link + bp = lijn->m_link->GetBeginNode(); + ep = lijn->m_link->GetEndNode(); - Result_beginnode = PointInLine(bp,distance,Marge); - Result_endnode = PointInLine(ep,distance,Marge); + Result_beginnode = PointInLine( bp, distance, Marge ); + Result_endnode = PointInLine( ep, distance, Marge ); - Take_Action1 = ActionOnTable1(Result_beginnode,Result_endnode); + Take_Action1 = ActionOnTable1( Result_beginnode, Result_endnode ); - // The first switch will insert a crosspoint immediatly - switch (Take_Action1) - { - // for the cases see the returnvalue of ActionTable1 - case 2: case 6: AddCrossing(ep); - Number_of_Crossings = 1; - break; - case 3: case 5: AddCrossing(bp); - Number_of_Crossings = 1; - break; - case 4: AddCrossing(bp); - AddCrossing(ep); - Number_of_Crossings = 2; - break; - } - // This switch wil investigate the points of this line in relation to lijn - switch (Take_Action1) - { - // for the cases see the returnvalue of ActionTable1 - case 1: case 5: case 6: - { - // Get the nodes from this line via the link - bp = m_link->GetBeginNode(); - ep = m_link->GetEndNode(); - Result_beginnode = lijn->PointInLine(bp,distance,Marge); - Result_endnode = lijn->PointInLine(ep,distance,Marge); - Take_Action2 = ActionOnTable2(Result_beginnode,Result_endnode); - switch (Take_Action2) - { - // for the cases see the returnvalue of ActionTable2 - case 1: { // begin of scope to calculate the intersection - double X, Y, Denominator; - CalculateLineParameters(); - Denominator = (m_AA * lijn->m_BB) - (lijn->m_AA * m_BB); - // Denominator may not be 0 - assert(Denominator != 0.0); - // Calculate intersection of both linesegments - X = ((m_BB * lijn->m_CC) - (lijn->m_BB * m_CC)) / Denominator; - Y = ((lijn->m_AA * m_CC) - (m_AA * lijn->m_CC)) / Denominator; + // The first switch will insert a crosspoint immediatly + switch ( Take_Action1 ) + { + // for the cases see the returnvalue of ActionTable1 + case 2: case 6: AddCrossing( ep ); + Number_of_Crossings = 1; + break; + case 3: case 5: AddCrossing( bp ); + Number_of_Crossings = 1; + break; + case 4: AddCrossing( bp ); + AddCrossing( ep ); + Number_of_Crossings = 2; + break; + } + // This switch wil investigate the points of this line in relation to lijn + switch ( Take_Action1 ) + { + // for the cases see the returnvalue of ActionTable1 +case 1: case 5: case 6: + { + // Get the nodes from this line via the link + bp = m_link->GetBeginNode(); + ep = m_link->GetEndNode(); + Result_beginnode = lijn->PointInLine( bp, distance, Marge ); + Result_endnode = lijn->PointInLine( ep, distance, Marge ); + Take_Action2 = ActionOnTable2( Result_beginnode, Result_endnode ); + switch ( Take_Action2 ) + { + // for the cases see the returnvalue of ActionTable2 + case 1: + { // begin of scope to calculate the intersection + double X, Y, Denominator; + CalculateLineParameters(); + Denominator = ( m_AA * lijn->m_BB ) - ( lijn->m_AA * m_BB ); + // Denominator may not be 0 + assert( Denominator != 0.0 ); + // Calculate intersection of both linesegments + X = ( ( m_BB * lijn->m_CC ) - ( lijn->m_BB * m_CC ) ) / Denominator; + Y = ( ( lijn->m_AA * m_CC ) - ( m_AA * lijn->m_CC ) ) / Denominator; - //make a decent rounding to B_INT - AddLineCrossing((B_INT)X,(B_INT)Y,lijn); - } // end of scope to calculate the intersection - Number_of_Crossings++; - break; - case 2: lijn->AddCrossing(ep); - Number_of_Crossings++; - break; - case 3: lijn->AddCrossing(bp); - Number_of_Crossings++; - break; - case 4: lijn->AddCrossing(bp); - lijn->AddCrossing(ep); - Number_of_Crossings = 2; - break; - } - }; break; // This break belongs to the outer switch - } - return Number_of_Crossings; //This is de final number of crossings + //make a decent rounding to B_INT + AddLineCrossing( ( B_INT )X, ( B_INT )Y, lijn ); + } // end of scope to calculate the intersection + Number_of_Crossings++; + break; + case 2: lijn->AddCrossing( ep ); + Number_of_Crossings++; + break; + case 3: lijn->AddCrossing( bp ); + Number_of_Crossings++; + break; + case 4: lijn->AddCrossing( bp ); + lijn->AddCrossing( ep ); + Number_of_Crossings = 2; + break; + } + } + ; break; // This break belongs to the outer switch + } + return Number_of_Crossings; //This is de final number of crossings } // Intersects two lines there must be a crossing -int KBoolLine::Intersect_simple(KBoolLine * lijn) +int KBoolLine::Intersect_simple( KBoolLine * lijn ) { - // lijn must exist - assert(lijn); + // lijn must exist + assert( lijn ); - double X, Y, Denominator; - Denominator = (m_AA * lijn->m_BB) - (lijn->m_AA * m_BB); - // Denominator may not be 0 - if (Denominator == 0.0) - m_GC->error("colliniar lines","line"); - // Calculate intersection of both linesegments - X = ((m_BB * lijn->m_CC) - (lijn->m_BB * m_CC)) / Denominator; - Y = ((lijn->m_AA * m_CC) - (m_AA * lijn->m_CC)) / Denominator; - AddLineCrossing((B_INT)X,(B_INT)Y,lijn); + double X, Y, Denominator; + Denominator = ( m_AA * lijn->m_BB ) - ( lijn->m_AA * m_BB ); + // Denominator may not be 0 + if ( Denominator == 0.0 ) + m_GC->error( "colliniar lines", "line" ); + // Calculate intersection of both linesegments + X = ( ( m_BB * lijn->m_CC ) - ( lijn->m_BB * m_CC ) ) / Denominator; + Y = ( ( lijn->m_AA * m_CC ) - ( m_AA * lijn->m_CC ) ) / Denominator; + AddLineCrossing( ( B_INT )X, ( B_INT )Y, lijn ); - return(0); + return( 0 ); } // Intersects two lines there must be a crossing -bool KBoolLine::Intersect2(Node* crossing,KBoolLine * lijn) +bool KBoolLine::Intersect2( Node* crossing, KBoolLine * lijn ) { - // lijn must exist - assert(lijn); + // lijn must exist + assert( lijn ); - double X, Y, Denominator; - Denominator = (m_AA * lijn->m_BB) - (lijn->m_AA * m_BB); - // Denominator may not be 0 - if (Denominator == 0.0) - return false; - // Calculate intersection of both linesegments - X = ((m_BB * lijn->m_CC) - (lijn->m_BB * m_CC)) / Denominator; - Y = ((lijn->m_AA * m_CC) - (m_AA * lijn->m_CC)) / Denominator; + double X, Y, Denominator; + Denominator = ( m_AA * lijn->m_BB ) - ( lijn->m_AA * m_BB ); + // Denominator may not be 0 + if ( Denominator == 0.0 ) + return false; + // Calculate intersection of both linesegments + X = ( ( m_BB * lijn->m_CC ) - ( lijn->m_BB * m_CC ) ) / Denominator; + Y = ( ( lijn->m_AA * m_CC ) - ( m_AA * lijn->m_CC ) ) / Denominator; - crossing->SetX((B_INT)X); - crossing->SetY((B_INT)Y); - return true; + crossing->SetX( ( B_INT )X ); + crossing->SetY( ( B_INT )Y ); + return true; } // @@ -607,52 +604,52 @@ bool KBoolLine::Intersect2(Node* crossing,KBoolLine * lijn) // returns LEFT_SIDE, when point lies on the left side of the line // RIGHT_SIDE, when point lies on the right side of the line // ON_AREA, when point lies on the infinite line within a range -// IN_AREA, when point lies in the area of the linesegment -// the returnvalues are declared in (LINE.H) -PointStatus KBoolLine::PointInLine(Node *a_node, double& Distance, double Marge) +// IN_AREA, when point lies in the area of the linesegment +// the returnvalues are declared in (LINE.H) +PointStatus KBoolLine::PointInLine( Node *a_node, double& Distance, double Marge ) { - Distance=0; + Distance = 0; - //Punt must exist - assert(a_node); - // link must exist to get beginnode and endnode via link - assert(m_link); + //Punt must exist + assert( a_node ); + // link must exist to get beginnode and endnode via link + assert( m_link ); - // get the nodes form the line via the link - Node *bp, *ep; - bp = m_link->GetBeginNode(); - ep = m_link->GetEndNode(); + // get the nodes form the line via the link + Node *bp, *ep; + bp = m_link->GetBeginNode(); + ep = m_link->GetEndNode(); - // both node must exist - assert(bp && ep); - // node may not be the same - assert(bp != ep); + // both node must exist + assert( bp && ep ); + // node may not be the same + assert( bp != ep ); - //quick test if point is begin or endpoint - if (a_node == bp || a_node == ep) + //quick test if point is begin or endpoint + if ( a_node == bp || a_node == ep ) return IN_AREA; - int Result_of_BBox=false; - PointStatus Result_of_Online; + int Result_of_BBox = false; + PointStatus Result_of_Online; - // Checking if point is in bounding-box with marge - B_INT xmin=bmin(bp->GetX(),ep->GetX()); - B_INT xmax=bmax(bp->GetX(),ep->GetX()); - B_INT ymin=bmin(bp->GetY(),ep->GetY()); - B_INT ymax=bmax(bp->GetY(),ep->GetY()); + // Checking if point is in bounding-box with marge + B_INT xmin = bmin( bp->GetX(), ep->GetX() ); + B_INT xmax = bmax( bp->GetX(), ep->GetX() ); + B_INT ymin = bmin( bp->GetY(), ep->GetY() ); + B_INT ymax = bmax( bp->GetY(), ep->GetY() ); - if ( a_node->GetX() >= (xmin - Marge) && a_node->GetX() <= (xmax + Marge) && - a_node->GetY() >= (ymin - Marge) && a_node->GetY() <= (ymax + Marge) ) - Result_of_BBox=true; + if ( a_node->GetX() >= ( xmin - Marge ) && a_node->GetX() <= ( xmax + Marge ) && + a_node->GetY() >= ( ymin - Marge ) && a_node->GetY() <= ( ymax + Marge ) ) + Result_of_BBox = true; - // Checking if point is on the infinite line - Result_of_Online = PointOnLine(a_node, Distance, Marge); + // Checking if point is on the infinite line + Result_of_Online = PointOnLine( a_node, Distance, Marge ); - // point in boundingbox of the line and is on the line then the point is IN_AREA - if ((Result_of_BBox) && (Result_of_Online == ON_AREA)) - return IN_AREA; - else - return Result_of_Online; + // point in boundingbox of the line and is on the line then the point is IN_AREA + if ( ( Result_of_BBox ) && ( Result_of_Online == ON_AREA ) ) + return IN_AREA; + else + return Result_of_Online; } @@ -664,43 +661,43 @@ PointStatus KBoolLine::PointInLine(Node *a_node, double& Distance, double Marge) // returns LEFT_SIDE, when point lies on the left side of the line // ON_AREA, when point lies on the infinite line within a range // RIGHT_SIDE, when point lies on the right side of the line -// LEFT_SIDE , RIGHT_SIDE , ON_AREA -PointStatus KBoolLine::PointOnLine(Node *a_node, double& Distance, double Marge) +// LEFT_SIDE , RIGHT_SIDE , ON_AREA +PointStatus KBoolLine::PointOnLine( Node *a_node, double& Distance, double Marge ) { - Distance=0; + Distance = 0; - // a_node must exist - assert(a_node); - // link must exist to get beginnode and endnode - assert(m_link); + // a_node must exist + assert( a_node ); + // link must exist to get beginnode and endnode + assert( m_link ); - // get the nodes from the line via the link - Node *bp, *ep; - bp = m_link->GetBeginNode(); - ep = m_link->GetEndNode(); + // get the nodes from the line via the link + Node *bp, *ep; + bp = m_link->GetBeginNode(); + ep = m_link->GetEndNode(); - // both node must exist - assert(bp && ep); - // node may not be queal - assert(bp!=ep); + // both node must exist + assert( bp && ep ); + // node may not be queal + assert( bp != ep ); - //quick test if point is begin or endpoint - if (a_node == bp || a_node == ep) - return ON_AREA; + //quick test if point is begin or endpoint + if ( a_node == bp || a_node == ep ) + return ON_AREA; - CalculateLineParameters(); - // calculate the distance of a_node in relation to the line - Distance = (m_AA * a_node->GetX())+(m_BB * a_node->GetY()) + m_CC; + CalculateLineParameters(); + // calculate the distance of a_node in relation to the line + Distance = ( m_AA * a_node->GetX() ) + ( m_BB * a_node->GetY() ) + m_CC; - if (Distance < -Marge) - return LEFT_SIDE; - else - { - if (Distance > Marge) - return RIGHT_SIDE; - else - return ON_AREA; - } + if ( Distance < -Marge ) + return LEFT_SIDE; + else + { + if ( Distance > Marge ) + return RIGHT_SIDE; + else + return ON_AREA; + } } @@ -708,437 +705,439 @@ PointStatus KBoolLine::PointOnLine(Node *a_node, double& Distance, double Marge) // Sets lines parameters // usage: a_line.Set(a_pointer_to_a_link); // -void KBoolLine::Set(KBoolLink *a_link) +void KBoolLine::Set( KBoolLink *a_link ) { - // points must exist - assert(a_link); - // points may not be equal - // must be an if statement because if an assert is used there will - // be a macro expansion error -// if (a_link->GetBeginNode()->Equal(a_link->GetEndNode(),MARGE)) assert(!a_link); + // points must exist + assert( a_link ); + // points may not be equal + // must be an if statement because if an assert is used there will + // be a macro expansion error +// if (a_link->GetBeginNode()->Equal(a_link->GetEndNode(),MARGE)) assert(!a_link); - linecrosslist = NULL; - m_link = a_link; - m_valid_parameters = false; + linecrosslist = NULL; + m_link = a_link; + m_valid_parameters = false; } KBoolLink* KBoolLine::GetLink() { - return m_link; + return m_link; } // // makes a line same as these // usage : line1 = line2; // -KBoolLine& KBoolLine::operator=(const KBoolLine& a_line) +KBoolLine& KBoolLine::operator=( const KBoolLine& a_line ) { - m_AA = a_line.m_AA; - m_BB = a_line.m_BB; - m_CC = a_line.m_CC; - m_link = a_line.m_link; - linecrosslist = NULL; - m_valid_parameters = a_line.m_valid_parameters; - return *this; + m_AA = a_line.m_AA; + m_BB = a_line.m_BB; + m_CC = a_line.m_CC; + m_link = a_line.m_link; + linecrosslist = NULL; + m_valid_parameters = a_line.m_valid_parameters; + return *this; } -Node* KBoolLine::OffsetContour(KBoolLine* const nextline,Node* _last_ins, double factor,Graph *shape) +Node* KBoolLine::OffsetContour( KBoolLine* const nextline, Node* _last_ins, double factor, Graph *shape ) { - KBoolLink* offs_currentlink; - KBoolLine offs_currentline(m_GC); - KBoolLink* offs_nextlink; - KBoolLine offs_nextline(m_GC); - Node* offs_end; + KBoolLink * offs_currentlink; + KBoolLine offs_currentline( m_GC ); + KBoolLink* offs_nextlink; + KBoolLine offs_nextline( m_GC ); + Node* offs_end; - Node* offs_bgn_next; - Node* offs_end_next; + Node* offs_bgn_next; + Node* offs_end_next; - // make a node from this point - offs_end = new Node(GetEndNode(), m_GC); - Virtual_Point(offs_end,factor); - offs_currentlink=new KBoolLink(0, _last_ins,offs_end, m_GC); - offs_currentline.Set(offs_currentlink); + // make a node from this point + offs_end = new Node( GetEndNode(), m_GC ); + Virtual_Point( offs_end, factor ); + offs_currentlink = new KBoolLink( 0, _last_ins, offs_end, m_GC ); + offs_currentline.Set( offs_currentlink ); - offs_bgn_next = new Node(nextline->m_link->GetBeginNode(), m_GC); - nextline->Virtual_Point(offs_bgn_next,factor); + offs_bgn_next = new Node( nextline->m_link->GetBeginNode(), m_GC ); + nextline->Virtual_Point( offs_bgn_next, factor ); - offs_end_next = new Node(nextline->m_link->GetEndNode(), m_GC); - nextline->Virtual_Point(offs_end_next,factor); + offs_end_next = new Node( nextline->m_link->GetEndNode(), m_GC ); + nextline->Virtual_Point( offs_end_next, factor ); - offs_nextlink=new KBoolLink(0, offs_bgn_next, offs_end_next, m_GC); - offs_nextline.Set(offs_nextlink); + offs_nextlink = new KBoolLink( 0, offs_bgn_next, offs_end_next, m_GC ); + offs_nextline.Set( offs_nextlink ); - offs_currentline.CalculateLineParameters(); - offs_nextline.CalculateLineParameters(); - offs_currentline.Intersect2(offs_end,&offs_nextline); + offs_currentline.CalculateLineParameters(); + offs_nextline.CalculateLineParameters(); + offs_currentline.Intersect2( offs_end, &offs_nextline ); - // make a link between the current and the previous and add this to graph - shape->AddLink(offs_currentlink); + // make a link between the current and the previous and add this to graph + shape->AddLink( offs_currentlink ); - delete offs_nextlink; + delete offs_nextlink; - return(offs_end); + return( offs_end ); } -Node* KBoolLine::OffsetContour_rounded(KBoolLine* const nextline,Node* _last_ins, double factor,Graph *shape) +Node* KBoolLine::OffsetContour_rounded( KBoolLine* const nextline, Node* _last_ins, double factor, Graph *shape ) { - KBoolLink* offs_currentlink; - KBoolLine offs_currentline(m_GC); - KBoolLink* offs_nextlink; - KBoolLine offs_nextline(m_GC); - Node* offs_end; - Node* medial_axes_point= new Node(m_GC); - Node* bu_last_ins = new Node(_last_ins, m_GC); + KBoolLink * offs_currentlink; + KBoolLine offs_currentline( m_GC ); + KBoolLink* offs_nextlink; + KBoolLine offs_nextline( m_GC ); + Node* offs_end; + Node* medial_axes_point = new Node( m_GC ); + Node* bu_last_ins = new Node( _last_ins, m_GC ); - Node* offs_bgn_next; - Node* offs_end_next; + Node* offs_bgn_next; + Node* offs_end_next; - // make a node from this point - offs_end = new Node(GetEndNode(), m_GC); + // make a node from this point + offs_end = new Node( GetEndNode(), m_GC ); - *_last_ins = *GetBeginNode(); - Virtual_Point(_last_ins,factor); - Virtual_Point(offs_end,factor); - offs_currentlink=new KBoolLink(0, _last_ins,offs_end, m_GC); - offs_currentline.Set(offs_currentlink); + *_last_ins = *GetBeginNode(); + Virtual_Point( _last_ins, factor ); + Virtual_Point( offs_end, factor ); + offs_currentlink = new KBoolLink( 0, _last_ins, offs_end, m_GC ); + offs_currentline.Set( offs_currentlink ); - offs_bgn_next = new Node(nextline->m_link->GetBeginNode(), m_GC); - nextline->Virtual_Point(offs_bgn_next,factor); + offs_bgn_next = new Node( nextline->m_link->GetBeginNode(), m_GC ); + nextline->Virtual_Point( offs_bgn_next, factor ); - offs_end_next = new Node(nextline->m_link->GetEndNode(), m_GC); - nextline->Virtual_Point(offs_end_next,factor); + offs_end_next = new Node( nextline->m_link->GetEndNode(), m_GC ); + nextline->Virtual_Point( offs_end_next, factor ); - offs_nextlink=new KBoolLink(0, offs_bgn_next, offs_end_next, m_GC); - offs_nextline.Set(offs_nextlink); + offs_nextlink = new KBoolLink( 0, offs_bgn_next, offs_end_next, m_GC ); + offs_nextline.Set( offs_nextlink ); - offs_currentline.CalculateLineParameters(); - offs_nextline.CalculateLineParameters(); - offs_currentline.Intersect2(medial_axes_point,&offs_nextline); + offs_currentline.CalculateLineParameters(); + offs_nextline.CalculateLineParameters(); + offs_currentline.Intersect2( medial_axes_point, &offs_nextline ); - double result_offs=sqrt( pow((double)GetEndNode()->GetY()-medial_axes_point->GetY(),2) + - pow((double)GetEndNode()->GetX()-medial_axes_point->GetX(),2) ); + double result_offs = sqrt( pow( ( double )GetEndNode()->GetY() - medial_axes_point->GetY(), 2 ) + + pow( ( double )GetEndNode()->GetX() - medial_axes_point->GetX(), 2 ) ); - if ( result_offs < fabs(m_GC->GetRoundfactor()*factor)) - { - *_last_ins=*bu_last_ins; - *offs_end=*medial_axes_point; - delete medial_axes_point; - delete bu_last_ins; - // make a link between the current and the previous and add this to graph - delete offs_nextlink; - shape->AddLink(offs_currentlink); - return(offs_end); - } - else - { //let us create a circle - *_last_ins=*bu_last_ins; - delete medial_axes_point; - delete bu_last_ins; - Node* endarc= new Node(offs_bgn_next, m_GC); - shape->AddLink(offs_currentlink); - delete offs_nextlink; - shape->CreateArc(GetEndNode(), &offs_currentline, endarc,fabs(factor),m_GC->GetInternalCorrectionAber()); - return(endarc); - } + if ( result_offs < fabs( m_GC->GetRoundfactor() * factor ) ) + { + *_last_ins = *bu_last_ins; + *offs_end = *medial_axes_point; + delete medial_axes_point; + delete bu_last_ins; + // make a link between the current and the previous and add this to graph + delete offs_nextlink; + shape->AddLink( offs_currentlink ); + return( offs_end ); + } + else + { //let us create a circle + *_last_ins = *bu_last_ins; + delete medial_axes_point; + delete bu_last_ins; + Node* endarc = new Node( offs_bgn_next, m_GC ); + shape->AddLink( offs_currentlink ); + delete offs_nextlink; + shape->CreateArc( GetEndNode(), &offs_currentline, endarc, fabs( factor ), m_GC->GetInternalCorrectionAber() ); + return( endarc ); + } } -bool KBoolLine::OkeForContour(KBoolLine* const nextline,double factor,Node* LastLeft,Node* LastRight, LinkStatus& _outproduct) +bool KBoolLine::OkeForContour( KBoolLine* const nextline, double factor, Node* LastLeft, Node* LastRight, LinkStatus& _outproduct ) { - assert(m_link); - assert(m_valid_parameters); - assert(nextline->m_link); - assert(nextline->m_valid_parameters); + assert( m_link ); + assert( m_valid_parameters ); + assert( nextline->m_link ); + assert( nextline->m_valid_parameters ); - factor = fabs(factor); + factor = fabs( factor ); -// PointStatus status=ON_AREA; - double distance=0; +// PointStatus status=ON_AREA; + double distance = 0; - Node offs_end_next(nextline->m_link->GetEndNode(), m_GC); + Node offs_end_next( nextline->m_link->GetEndNode(), m_GC ); - _outproduct= m_link->OutProduct(nextline->m_link,m_GC->GetAccur()); + _outproduct = m_link->OutProduct( nextline->m_link, m_GC->GetAccur() ); - switch (_outproduct) - { - // current line lies on leftside of prev line - case IS_RIGHT : - { - nextline->Virtual_Point(&offs_end_next,-factor); + switch ( _outproduct ) + { + // current line lies on leftside of prev line + case IS_RIGHT : + { + nextline->Virtual_Point( &offs_end_next, -factor ); - // status= - nextline->PointOnLine(LastRight, distance, m_GC->GetAccur()); - if (distance > factor) - { PointOnLine(&offs_end_next, distance, m_GC->GetAccur()); - if (distance > factor) - return(true); - } - } - break; - // current line lies on rightside of prev line - case IS_LEFT : - { - nextline->Virtual_Point(&offs_end_next,factor); + // status= + nextline->PointOnLine( LastRight, distance, m_GC->GetAccur() ); + if ( distance > factor ) + { + PointOnLine( &offs_end_next, distance, m_GC->GetAccur() ); + if ( distance > factor ) + return( true ); + } + } + break; + // current line lies on rightside of prev line + case IS_LEFT : + { + nextline->Virtual_Point( &offs_end_next, factor ); - // status= - nextline->PointOnLine(LastLeft, distance, m_GC->GetAccur()); - if (distance < -factor) - { PointOnLine(&offs_end_next, distance, m_GC->GetAccur()); - if (distance <-factor) - return(true); - } - } - break; - // current line lies on prev line - case IS_ON : - { - return(true); - } - }//end switch + // status= + nextline->PointOnLine( LastLeft, distance, m_GC->GetAccur() ); + if ( distance < -factor ) + { + PointOnLine( &offs_end_next, distance, m_GC->GetAccur() ); + if ( distance < -factor ) + return( true ); + } + } + break; + // current line lies on prev line + case IS_ON : + { + return( true ); + } + }//end switch - return(false); + return( false ); } -bool KBoolLine::Create_Ring_Shape(KBoolLine* nextline,Node** _last_ins_left,Node** _last_ins_right,double factor,Graph *shape) +bool KBoolLine::Create_Ring_Shape( KBoolLine* nextline, Node** _last_ins_left, Node** _last_ins_right, double factor, Graph *shape ) { - Node* _current; - LinkStatus _outproduct=IS_ON; + Node * _current; + LinkStatus _outproduct = IS_ON; - if (OkeForContour(nextline,factor,*_last_ins_left,*_last_ins_right,_outproduct)) - { - switch (_outproduct) - { - // Line 2 lies on leftside of this line - case IS_RIGHT : - { - *_last_ins_left =OffsetContour_rounded(nextline,*_last_ins_left,factor,shape); - *_last_ins_right =OffsetContour(nextline,*_last_ins_right,-factor,shape); - } - break; - case IS_LEFT : - { - *_last_ins_left =OffsetContour(nextline,*_last_ins_left,factor,shape); - *_last_ins_right =OffsetContour_rounded(nextline,*_last_ins_right,-factor,shape); + if ( OkeForContour( nextline, factor, *_last_ins_left, *_last_ins_right, _outproduct ) ) + { + switch ( _outproduct ) + { + // Line 2 lies on leftside of this line + case IS_RIGHT : + { + *_last_ins_left = OffsetContour_rounded( nextline, *_last_ins_left, factor, shape ); + *_last_ins_right = OffsetContour( nextline, *_last_ins_right, -factor, shape ); + } + break; + case IS_LEFT : + { + *_last_ins_left = OffsetContour( nextline, *_last_ins_left, factor, shape ); + *_last_ins_right = OffsetContour_rounded( nextline, *_last_ins_right, -factor, shape ); - } - break; - // Line 2 lies on this line - case IS_ON : - { - // make a node from this point - _current = new Node(m_link->GetEndNode(), m_GC); - Virtual_Point(_current,factor); + } + break; + // Line 2 lies on this line + case IS_ON : + { + // make a node from this point + _current = new Node( m_link->GetEndNode(), m_GC ); + Virtual_Point( _current, factor ); - // make a link between the current and the previous and add this to graph - shape->AddLink(*_last_ins_left, _current); - *_last_ins_left=_current; + // make a link between the current and the previous and add this to graph + shape->AddLink( *_last_ins_left, _current ); + *_last_ins_left = _current; - _current = new Node(m_link->GetEndNode(), m_GC); - Virtual_Point(_current,-factor); + _current = new Node( m_link->GetEndNode(), m_GC ); + Virtual_Point( _current, -factor ); - shape->AddLink(*_last_ins_right, _current); - *_last_ins_right=_current; - } - break; - }//end switch - return(true); - } -/* else - { - switch (_outproduct) - { - // Line 2 lies on leftside of this line - case IS_RIGHT : - { - *_last_ins_left =OffsetContour_rounded(nextline,*_last_ins_left,factor,Ishape); - *_last_ins_right =OffsetContour(nextline,*_last_ins_right,-factor,Ishape); - } - break; - case IS_LEFT : - { - *_last_ins_left =OffsetContour(nextline,*_last_ins_left,factor,Ishape); - *_last_ins_right =OffsetContour_rounded(nextline,*_last_ins_right,-factor,Ishape); - - } - break; - // Line 2 lies on this line - case IS_ON : - { - // make a node from this point - _current = new Node(m_link->GetEndNode()); - Virtual_Point(_current,factor); - - // make a link between the current and the previous and add this to graph - Ishape->AddLink(*_last_ins_left, _current); - *_last_ins_left=_current; - - _current = new Node(m_link->GetEndNode()); - Virtual_Point(_current,-factor); - - Ishape->AddLink(*_last_ins_right, _current); - *_last_ins_right=_current; - } - break; - }//end switch - return(true); - } -*/ - return(false); + shape->AddLink( *_last_ins_right, _current ); + *_last_ins_right = _current; + } + break; + }//end switch + return( true ); + } + /* else + { + switch (_outproduct) + { + // Line 2 lies on leftside of this line + case IS_RIGHT : + { + *_last_ins_left =OffsetContour_rounded(nextline,*_last_ins_left,factor,Ishape); + *_last_ins_right =OffsetContour(nextline,*_last_ins_right,-factor,Ishape); + } + break; + case IS_LEFT : + { + *_last_ins_left =OffsetContour(nextline,*_last_ins_left,factor,Ishape); + *_last_ins_right =OffsetContour_rounded(nextline,*_last_ins_right,-factor,Ishape); + + } + break; + // Line 2 lies on this line + case IS_ON : + { + // make a node from this point + _current = new Node(m_link->GetEndNode()); + Virtual_Point(_current,factor); + + // make a link between the current and the previous and add this to graph + Ishape->AddLink(*_last_ins_left, _current); + *_last_ins_left=_current; + + _current = new Node(m_link->GetEndNode()); + Virtual_Point(_current,-factor); + + Ishape->AddLink(*_last_ins_right, _current); + *_last_ins_right=_current; + } + break; + }//end switch + return(true); + } + */ + return( false ); } -void KBoolLine::Create_Begin_Shape(KBoolLine* nextline,Node** _last_ins_left,Node** _last_ins_right,double factor,Graph *shape) +void KBoolLine::Create_Begin_Shape( KBoolLine* nextline, Node** _last_ins_left, Node** _last_ins_right, double factor, Graph *shape ) { - factor = fabs(factor); - LinkStatus _outproduct; - _outproduct= m_link->OutProduct(nextline->m_link,m_GC->GetAccur()); + factor = fabs( factor ); + LinkStatus _outproduct; + _outproduct = m_link->OutProduct( nextline->m_link, m_GC->GetAccur() ); - switch (_outproduct) - { - case IS_RIGHT : - { - *_last_ins_left = new Node(m_link->GetEndNode(), m_GC); + switch ( _outproduct ) + { + case IS_RIGHT : + { + *_last_ins_left = new Node( m_link->GetEndNode(), m_GC ); - Virtual_Point(*_last_ins_left,factor); + Virtual_Point( *_last_ins_left, factor ); - *_last_ins_right = new Node(nextline->m_link->GetBeginNode(), m_GC); - nextline->Virtual_Point(*_last_ins_right,-factor); + *_last_ins_right = new Node( nextline->m_link->GetBeginNode(), m_GC ); + nextline->Virtual_Point( *_last_ins_right, -factor ); - shape->AddLink(*_last_ins_left, *_last_ins_right); + shape->AddLink( *_last_ins_left, *_last_ins_right ); - *_last_ins_left=OffsetContour_rounded(nextline,*_last_ins_left,factor,shape); - } - break; - case IS_LEFT : - { - *_last_ins_left = new Node(nextline->m_link->GetBeginNode(), m_GC); - nextline->Virtual_Point(*_last_ins_left,factor); + *_last_ins_left = OffsetContour_rounded( nextline, *_last_ins_left, factor, shape ); + } + break; + case IS_LEFT : + { + *_last_ins_left = new Node( nextline->m_link->GetBeginNode(), m_GC ); + nextline->Virtual_Point( *_last_ins_left, factor ); - *_last_ins_right = new Node(m_link->GetEndNode(), m_GC); - Virtual_Point(*_last_ins_right,-factor); + *_last_ins_right = new Node( m_link->GetEndNode(), m_GC ); + Virtual_Point( *_last_ins_right, -factor ); - shape->AddLink(*_last_ins_left, *_last_ins_right); + shape->AddLink( *_last_ins_left, *_last_ins_right ); - *_last_ins_right=OffsetContour_rounded(nextline,*_last_ins_right,-factor,shape); - } - break; - // Line 2 lies on this line - case IS_ON : - { - *_last_ins_left = new Node(nextline->m_link->GetBeginNode(), m_GC); - Virtual_Point(*_last_ins_left,factor); + *_last_ins_right = OffsetContour_rounded( nextline, *_last_ins_right, -factor, shape ); + } + break; + // Line 2 lies on this line + case IS_ON : + { + *_last_ins_left = new Node( nextline->m_link->GetBeginNode(), m_GC ); + Virtual_Point( *_last_ins_left, factor ); - *_last_ins_right = new Node(nextline->m_link->GetBeginNode(), m_GC); - Virtual_Point(*_last_ins_right,-factor); + *_last_ins_right = new Node( nextline->m_link->GetBeginNode(), m_GC ); + Virtual_Point( *_last_ins_right, -factor ); - shape->AddLink(*_last_ins_left, *_last_ins_right); - } - break; - }//end switch + shape->AddLink( *_last_ins_left, *_last_ins_right ); + } + break; + }//end switch } -void KBoolLine::Create_End_Shape(KBoolLine* nextline,Node* _last_ins_left,Node* _last_ins_right,double factor,Graph *shape) +void KBoolLine::Create_End_Shape( KBoolLine* nextline, Node* _last_ins_left, Node* _last_ins_right, double factor, Graph *shape ) { - Node* _current; - factor = fabs(factor); - LinkStatus _outproduct; - _outproduct= m_link->OutProduct(nextline->m_link,m_GC->GetAccur()); + Node * _current; + factor = fabs( factor ); + LinkStatus _outproduct; + _outproduct = m_link->OutProduct( nextline->m_link, m_GC->GetAccur() ); - switch (_outproduct) - { - case IS_RIGHT : - { - _current = new Node(m_link->GetEndNode(), m_GC); - Virtual_Point(_current,-factor); - shape->AddLink(_last_ins_right, _current); - _last_ins_right=_current; + switch ( _outproduct ) + { + case IS_RIGHT : + { + _current = new Node( m_link->GetEndNode(), m_GC ); + Virtual_Point( _current, -factor ); + shape->AddLink( _last_ins_right, _current ); + _last_ins_right = _current; - _last_ins_left=OffsetContour_rounded(nextline,_last_ins_left,factor,shape); - shape->AddLink(_last_ins_left,_last_ins_right); - } - break; - case IS_LEFT : - { - _current = new Node(m_link->GetEndNode(), m_GC); - Virtual_Point(_current,factor); - shape->AddLink(_last_ins_left, _current); - _last_ins_left=_current; + _last_ins_left = OffsetContour_rounded( nextline, _last_ins_left, factor, shape ); + shape->AddLink( _last_ins_left, _last_ins_right ); + } + break; + case IS_LEFT : + { + _current = new Node( m_link->GetEndNode(), m_GC ); + Virtual_Point( _current, factor ); + shape->AddLink( _last_ins_left, _current ); + _last_ins_left = _current; - _last_ins_right=OffsetContour_rounded(nextline,_last_ins_right,-factor,shape); - shape->AddLink(_last_ins_right, _last_ins_left); - } - break; - // Line 2 lies on this line - case IS_ON : - { - _current = new Node(m_link->GetEndNode(), m_GC); - Virtual_Point(_current,factor); - shape->AddLink(_last_ins_left, _current); - _last_ins_left=_current; + _last_ins_right = OffsetContour_rounded( nextline, _last_ins_right, -factor, shape ); + shape->AddLink( _last_ins_right, _last_ins_left ); + } + break; + // Line 2 lies on this line + case IS_ON : + { + _current = new Node( m_link->GetEndNode(), m_GC ); + Virtual_Point( _current, factor ); + shape->AddLink( _last_ins_left, _current ); + _last_ins_left = _current; - _current = new Node(m_link->GetEndNode(), m_GC); - Virtual_Point(_current,-factor); - shape->AddLink(_last_ins_right, _current); - _last_ins_right=_current; + _current = new Node( m_link->GetEndNode(), m_GC ); + Virtual_Point( _current, -factor ); + shape->AddLink( _last_ins_right, _current ); + _last_ins_right = _current; - shape->AddLink(_last_ins_left, _last_ins_right); - } - break; - }//end switch + shape->AddLink( _last_ins_left, _last_ins_right ); + } + break; + }//end switch } // // Generate from the found crossings a part of the graph // -bool KBoolLine::ProcessCrossings(TDLI* _LI) +bool KBoolLine::ProcessCrossings( TDLI* _LI ) { - Node *last; KBoolLink *dummy; -// assert (beginnode && endnode); + Node * last; KBoolLink *dummy; +// assert (beginnode && endnode); - if (!linecrosslist) return false; + if ( !linecrosslist ) return false; - if (linecrosslist->empty()) return false; - if (linecrosslist->count()>1) SortLineCrossings(); - m_link->GetEndNode()->RemoveLink(m_link); - last=m_link->GetEndNode(); - // Make new links : - while (!linecrosslist->empty()) - { - dummy=new KBoolLink(m_link->GetGraphNum(),(Node*) linecrosslist->tailitem(),last, m_GC); - dummy->SetBeenHere(); - dummy->SetGroup(m_link->Group()); - _LI->insbegin(dummy); - last=(Node*)linecrosslist->tailitem(); - linecrosslist->removetail(); - } - // Recycle this link : - last->AddLink(m_link); - m_link->SetEndNode(last); - delete linecrosslist; - linecrosslist=NULL; - return true; + if ( linecrosslist->empty() ) return false; + if ( linecrosslist->count() > 1 ) SortLineCrossings(); + m_link->GetEndNode()->RemoveLink( m_link ); + last = m_link->GetEndNode(); + // Make new links : + while ( !linecrosslist->empty() ) + { + dummy = new KBoolLink( m_link->GetGraphNum(), ( Node* ) linecrosslist->tailitem(), last, m_GC ); + dummy->SetBeenHere(); + dummy->SetGroup( m_link->Group() ); + _LI->insbegin( dummy ); + last = ( Node* )linecrosslist->tailitem(); + linecrosslist->removetail(); + } + // Recycle this link : + last->AddLink( m_link ); + m_link->SetEndNode( last ); + delete linecrosslist; + linecrosslist = NULL; + return true; } /* // Sorts the links on the X values int NodeXYsorter(Node* a, Node* b) { - if ( a->GetX() < b->GetX()) - return(1); - if ( a->GetX() > b->GetX()) - return(-1); + if ( a->GetX() < b->GetX()) + return(1); + if ( a->GetX() > b->GetX()) + return(-1); //they are eqaul in x - if ( a->GetY() < b->GetY()) - return(-1); - if ( a->GetY() > b->GetY()) - return(1); + if ( a->GetY() < b->GetY()) + return(-1); + if ( a->GetY() > b->GetY()) + return(1); //they are eqaul in y - return(0); + return(0); } - + // // Generate from the found crossings a part of the graph // this routine is used in combination with the scanbeam class @@ -1153,16 +1152,16 @@ KBoolLink* KBoolLine::ProcessCrossingsSmart(TDLI* _LI) Node *lastinserted; KBoolLink *new_link; KBoolLink *returnlink; - assert (beginnode && endnode); - if (!linecrosslist) return this; - - if (linecrosslist->empty()) return this; - if (linecrosslist->count()>1) + assert (beginnode && endnode); + if (!linecrosslist) return this; + + if (linecrosslist->empty()) return this; + if (linecrosslist->count()>1) { - SortLineCrossings(); + SortLineCrossings(); } - int inbeam; - + int inbeam; + //most left at the beginnode or endnode if (NodeXYsorter(beginnode,endnode)==1) { @@ -1183,14 +1182,14 @@ KBoolLink* KBoolLine::ProcessCrossingsSmart(TDLI* _LI) break; } returnlink=this; - + lastinserted=endnode; linecrosslist->removehead(); // Make new links starting at endnode while (!linecrosslist->empty()) { new_link=new KBoolLink(graphnum,lastinserted,(Node*) linecrosslist->headitem()); - + new_link->group=group; int inbeam=NodeXYsorter(_LI->item()->beginnode,lastinserted); switch (inbeam) @@ -1201,26 +1200,26 @@ KBoolLink* KBoolLine::ProcessCrossingsSmart(TDLI* _LI) char buf[80]; x=((Node*)(linecrosslist->headitem()))->GetX(); y=((Node*)(linecrosslist->headitem()))->GetY(); - xl=_LI->item()->beginnode->GetX(); + xl=_LI->item()->beginnode->GetX(); yl=_LI->item()->beginnode->GetY(); sprintf(buf," x=%f , y=%f inserted before %f,%f",x,y,xl,yl); _messagehandler->info(buf,"scanbeam"); - new_link->bin=true; + new_link->bin=true; } break; case 0: - new_link->bin=true; - returnlink=new_link; + new_link->bin=true; + returnlink=new_link; break; case 1: - new_link->bin=false; + new_link->bin=false; break; } - + //insert a link into the graph that is already sorted on beginnodes of the links. //starting at a given position // if empty then just insert - + if (_LI->empty()) _LI->insend(new_link); else @@ -1235,19 +1234,19 @@ KBoolLink* KBoolLine::ProcessCrossingsSmart(TDLI* _LI) (*_LI)++; i++; } - + _LI->insbefore_unsave(new_link); if (insert==0 && _LI->item()->beginnode!=new_link->beginnode) //the begin nodes are equal but not the same merge them into one node { Node* todelete=_LI->item()->beginnode; - new_link->beginnode->Merge(todelete); - delete todelete; + new_link->beginnode->Merge(todelete); + delete todelete; } - + //set back iter (*_LI) << (i+1); } - + lastinserted=(Node*)linecrosslist->headitem(); linecrosslist->removehead(); } @@ -1271,25 +1270,25 @@ KBoolLink* KBoolLine::ProcessCrossingsSmart(TDLI* _LI) break; } returnlink=this; - + lastinserted=endnode; linecrosslist->removehead(); - + // Make new links starting at endnode while (!linecrosslist->empty()) { new_link=new KBoolLink(graphnum,lastinserted,(Node*) linecrosslist->headitem()); new_link->group=group; - + inbeam=NodeXYsorter(_LI->item()->beginnode,(Node*) linecrosslist->headitem()); switch (inbeam) { case -1: case 0: - new_link->bin=true; + new_link->bin=true; break; case 1: - new_link->bin=false; + new_link->bin=false; break; } inbeam=NodeXYsorter(_LI->item()->beginnode,lastinserted); @@ -1301,7 +1300,7 @@ KBoolLink* KBoolLine::ProcessCrossingsSmart(TDLI* _LI) char buf[80]; x=lastinserted->GetX(); y=lastinserted->GetY(); - xl=_LI->item()->beginnode->GetX(); + xl=_LI->item()->beginnode->GetX(); yl=_LI->item()->beginnode->GetY(); sprintf(buf," x=%f , y=%f inserted before %f,%f",x,y,xl,yl); _messagehandler->info(buf,"scanbeam"); @@ -1310,14 +1309,14 @@ KBoolLink* KBoolLine::ProcessCrossingsSmart(TDLI* _LI) case 0: break; case 1: - returnlink=new_link; + returnlink=new_link; break; } - + //insert a link into the graph that is already sorted on beginnodes of the links. //starting at a given position // if empty then just insert - + if (_LI->empty()) _LI->insend(new_link); else @@ -1332,62 +1331,62 @@ KBoolLink* KBoolLine::ProcessCrossingsSmart(TDLI* _LI) (*_LI)++; i++; } - + _LI->insbefore_unsave(new_link); if (insert==0 && _LI->item()->beginnode!=new_link->beginnode) //the begin nodes are equal but not the same merge them into one node { Node* todelete=_LI->item()->beginnode; - new_link->beginnode->Merge(todelete); - delete todelete; + new_link->beginnode->Merge(todelete); + delete todelete; } //set back iter (*_LI) << (i+1); } - + lastinserted=(Node*)linecrosslist->headitem(); linecrosslist->removehead(); } } - delete linecrosslist; - linecrosslist=NULL; - - return returnlink; + delete linecrosslist; + linecrosslist=NULL; + + return returnlink; } */ -static int NODE_X_ASCENDING_L (Node* a, Node* b) +static int NODE_X_ASCENDING_L ( Node* a, Node* b ) { - if(b->GetX() > a->GetX()) return(1); - else - if(b->GetX() == a->GetX()) return(0); + if( b->GetX() > a->GetX() ) return( 1 ); + else + if( b->GetX() == a->GetX() ) return( 0 ); - return(-1); + return( -1 ); } -static int NODE_X_DESCENDING_L(Node* a, Node* b) +static int NODE_X_DESCENDING_L( Node* a, Node* b ) { - if(a->GetX() > b->GetX()) return(1); - else - if(a->GetX() == b->GetX()) return(0); + if( a->GetX() > b->GetX() ) return( 1 ); + else + if( a->GetX() == b->GetX() ) return( 0 ); - return(-1); + return( -1 ); } -static int NODE_Y_ASCENDING_L (Node* a, Node* b) +static int NODE_Y_ASCENDING_L ( Node* a, Node* b ) { - if(b->GetY() > a->GetY()) return(1); - else - if(b->GetY() == a->GetY()) return(0); - return(-1); + if( b->GetY() > a->GetY() ) return( 1 ); + else + if( b->GetY() == a->GetY() ) return( 0 ); + return( -1 ); } -static int NODE_Y_DESCENDING_L(Node* a, Node* b) +static int NODE_Y_DESCENDING_L( Node* a, Node* b ) { - if(a->GetY() > b->GetY()) return(1); - else - if(a->GetY() == b->GetY()) return(0); + if( a->GetY() > b->GetY() ) return( 1 ); + else + if( a->GetY() == b->GetY() ) return( 0 ); - return(-1); + return( -1 ); } // @@ -1396,81 +1395,81 @@ static int NODE_Y_DESCENDING_L(Node* a, Node* b) // void KBoolLine::SortLineCrossings() { - TDLI I(linecrosslist); + TDLI I( linecrosslist ); - B_INT dx, dy; - dx=babs(m_link->GetEndNode()->GetX() - m_link->GetBeginNode()->GetX()); - dy=babs(m_link->GetEndNode()->GetY() - m_link->GetBeginNode()->GetY()); - if (dx > dy) - { // thislink is more horizontal then vertical - if (m_link->GetEndNode()->GetX() > m_link->GetBeginNode()->GetX()) - I.mergesort(NODE_X_ASCENDING_L); - else - I.mergesort(NODE_X_DESCENDING_L); - } - else - { // this link is more vertical then horizontal - if (m_link->GetEndNode()->GetY() > m_link->GetBeginNode()->GetY()) - I.mergesort(NODE_Y_ASCENDING_L); - else - I.mergesort(NODE_Y_DESCENDING_L); - } + B_INT dx, dy; + dx = babs( m_link->GetEndNode()->GetX() - m_link->GetBeginNode()->GetX() ); + dy = babs( m_link->GetEndNode()->GetY() - m_link->GetBeginNode()->GetY() ); + if ( dx > dy ) + { // thislink is more horizontal then vertical + if ( m_link->GetEndNode()->GetX() > m_link->GetBeginNode()->GetX() ) + I.mergesort( NODE_X_ASCENDING_L ); + else + I.mergesort( NODE_X_DESCENDING_L ); + } + else + { // this link is more vertical then horizontal + if ( m_link->GetEndNode()->GetY() > m_link->GetBeginNode()->GetY() ) + I.mergesort( NODE_Y_ASCENDING_L ); + else + I.mergesort( NODE_Y_DESCENDING_L ); + } } // // Adds a cross Node to this. a_node may not be deleted before processing the crossings // -void KBoolLine::AddCrossing(Node *a_node) +void KBoolLine::AddCrossing( Node *a_node ) { - if (a_node==m_link->GetBeginNode() || a_node==m_link->GetEndNode()) return; + if ( a_node == m_link->GetBeginNode() || a_node == m_link->GetEndNode() ) return; - if (!linecrosslist) - { - linecrosslist=new DL_List(); - linecrosslist->insend(a_node); - } - else - { - TDLI I(linecrosslist); - if (!I.has(a_node)) - I.insend(a_node); - } + if ( !linecrosslist ) + { + linecrosslist = new DL_List(); + linecrosslist->insend( a_node ); + } + else + { + TDLI I( linecrosslist ); + if ( !I.has( a_node ) ) + I.insend( a_node ); + } } // // see above // -Node* KBoolLine::AddCrossing(B_INT X, B_INT Y) +Node* KBoolLine::AddCrossing( B_INT X, B_INT Y ) { - Node* result=new Node(X,Y, m_GC); - AddCrossing(result); - return result; + Node * result = new Node( X, Y, m_GC ); + AddCrossing( result ); + return result; } DL_List* KBoolLine::GetCrossList() { - if (linecrosslist) - return linecrosslist; - return NULL; + if ( linecrosslist ) + return linecrosslist; + return NULL; } bool KBoolLine::CrossListEmpty() { - if (linecrosslist) - return linecrosslist->empty(); - return true; + if ( linecrosslist ) + return linecrosslist->empty(); + return true; } /* bool KBoolLine::HasInCrossList(Node *n) { - if(linecrosslist!=NULL) - { - TDLI I(linecrosslist); - return I.has(n); - } - return false; + if(linecrosslist!=NULL) + { + TDLI I(linecrosslist); + return I.has(n); + } + return false; } */ diff --git a/polygon/kbool/src/link.cpp b/polygon/kbool/src/link.cpp index 6f175f66d8..9e02f435c1 100644 --- a/polygon/kbool/src/link.cpp +++ b/polygon/kbool/src/link.cpp @@ -1,70 +1,66 @@ -/*! \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 $ +/*! \file src/link.cpp + \author Klaas Holwerda + + Copyright: 2001-2004 (C) Klaas Holwerda + + Licence: see kboollicense.txt + + RCS-ID: $Id: link.cpp,v 1.3 2008/06/04 21:23:22 titato Exp $ */ -#ifdef __GNUG__ -#pragma implementation -#endif +#include "kbool/booleng.h" -#include "../include/booleng.h" - -#include "../include/link.h" -#include "../include/line.h" +#include "kbool/link.h" +#include "kbool/line.h" #include #include -#include "../include/node.h" -#include "../include/graph.h" -#include "../include/graphlst.h" +#include "kbool/node.h" +#include "kbool/graph.h" +#include "kbool/graphlst.h" -int linkXYsorter(KBoolLink *, KBoolLink *); +int linkXYsorter( KBoolLink *, KBoolLink * ); // // Default constructor // -KBoolLink::KBoolLink(Bool_Engine* GC) +KBoolLink::KBoolLink( Bool_Engine* GC ) { - _GC=GC; - Reset(); + _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) +KBoolLink::KBoolLink( int graphnr, Node *begin, Node *end, Bool_Engine* GC ) { - _GC=GC; - Reset(); + _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; + // 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) +KBoolLink::KBoolLink( Node *begin, Node *end, Bool_Engine* GC ) { - _GC=GC; - Reset(); + _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; + // 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; } @@ -73,39 +69,39 @@ KBoolLink::KBoolLink(Node *begin, Node *end, Bool_Engine* GC) // KBoolLink::~KBoolLink() { - UnLink(); + UnLink(); } // -// Checks whether the current algorithm has been on this link +// Checks whether the current algorithm has been on this link // bool KBoolLink::BeenHere() { - if (m_bin) return true; - return false; + 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_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; + 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 +// Returns the next link from the argument // -KBoolLink* KBoolLink::Forth(Node *node) +KBoolLink* KBoolLink::Forth( Node *node ) { - assert(node==m_beginnode || node==m_endnode); - return node->GetOtherLink(this); + assert( node == m_beginnode || node == m_endnode ); + return node->GetOtherLink( this ); } // @@ -113,25 +109,25 @@ KBoolLink* KBoolLink::Forth(Node *node) // Node *KBoolLink::GetBeginNode() { - return m_beginnode; + return m_beginnode; } // // Returns the endnode // -Node* KBoolLink::GetEndNode() +Node* KBoolLink::GetEndNode() { - return m_endnode; + return m_endnode; } -Node* KBoolLink::GetLowNode() +Node* KBoolLink::GetLowNode() { - return ( ( m_beginnode->GetY() < m_endnode->GetY() ) ? m_beginnode : m_endnode ); + return ( ( m_beginnode->GetY() < m_endnode->GetY() ) ? m_beginnode : m_endnode ); } -Node* KBoolLink::GetHighNode() +Node* KBoolLink::GetHighNode() { - return ( ( m_beginnode->GetY() > m_endnode->GetY() ) ? m_beginnode : m_endnode ); + return ( ( m_beginnode->GetY() > m_endnode->GetY() ) ? m_beginnode : m_endnode ); } // @@ -139,137 +135,137 @@ Node* KBoolLink::GetHighNode() // int KBoolLink::GetGraphNum() { - return m_graphnum; + return m_graphnum; } bool KBoolLink::GetInc() { - return m_Inc; + return m_Inc; // if (Inc) return true; -// return false; +// return false; } -void KBoolLink::SetInc(bool inc) +void KBoolLink::SetInc( bool inc ) { - m_Inc = inc; + m_Inc = inc; // Inc=0; // if (inc) Inc=1; } bool KBoolLink::GetLeftA() { - return m_LeftA; + return m_LeftA; } -void KBoolLink::SetLeftA(bool la) +void KBoolLink::SetLeftA( bool la ) { - m_LeftA = la; + m_LeftA = la; } bool KBoolLink::GetLeftB() { - return m_LeftB; + return m_LeftB; } -void KBoolLink::SetLeftB(bool lb) +void KBoolLink::SetLeftB( bool lb ) { - m_LeftB = lb; + m_LeftB = lb; } bool KBoolLink::GetRightA() { - return m_RightA; + return m_RightA; } -void KBoolLink::SetRightA(bool ra) +void KBoolLink::SetRightA( bool ra ) { - m_RightA = ra; + m_RightA = ra; } bool KBoolLink::GetRightB() { - return m_RightB; + return m_RightB; } -void KBoolLink::SetRightB(bool rb) +void KBoolLink::SetRightB( bool rb ) { - m_RightB = rb; + m_RightB = rb; } // -// This function is very popular by GP-faults +// This function is very popular by GP-faults // It returns the node different from a // -Node* KBoolLink::GetOther(const Node *const a) +Node* KBoolLink::GetOther( const Node *const a ) { - return ( (a != m_beginnode) ? m_beginnode : m_endnode); + return ( ( a != m_beginnode ) ? m_beginnode : m_endnode ); } // -// Is this marked for given operation +// Is this marked for given operation // -bool KBoolLink::IsMarked(BOOL_OP 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; - } + 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) +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; - } + 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) +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; - } + 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 +// Is this a hole for given operation // beginnode must be to the left -bool KBoolLink::IsHole(BOOL_OP operation) +bool KBoolLink::IsHole( BOOL_OP operation ) { - bool topsideA,topsideB; + 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; } + 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; - } + 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; + } } // @@ -277,48 +273,48 @@ bool KBoolLink::IsHole(BOOL_OP operation) // bool KBoolLink::GetHole() { - return (m_hole); + return ( m_hole ); } -void KBoolLink::SetHole(bool h) +void KBoolLink::SetHole( bool h ) { - m_hole = h; + m_hole = h; } // -// Is this not marked at all +// 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 ); + 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) +bool KBoolLink::IsZero( B_INT marge ) { - return (m_beginnode->Equal(m_endnode,marge)) ; + return ( m_beginnode->Equal( m_endnode, marge ) ) ; } -bool KBoolLink::ShorterThan(B_INT marge) +bool KBoolLink::ShorterThan( B_INT marge ) { - return (m_beginnode->ShorterThan(m_endnode,marge)) ; + return ( m_beginnode->ShorterThan( m_endnode, marge ) ) ; } // -// Mark this link +// Mark this link // void KBoolLink::Mark() { - m_mark = true; + m_mark = true; } @@ -332,390 +328,394 @@ void KBoolLink::Mark() // 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) +void KBoolLink::MergeNodes( Node *const begin_or_end_node ) { -// assert(beginnode && endnode); -// assert ((begin_or_end_node == beginnode)||(begin_or_end_node == endnode)); +// assert(beginnode && endnode); +// assert ((begin_or_end_node == beginnode)||(begin_or_end_node == endnode)); - m_beginnode->RemoveLink(this); - m_endnode->RemoveLink(this); + 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; + 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 +// 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) +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); + 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); - } + //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); + //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; + 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;*/ + /*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; + //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 +// 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 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; + 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; +//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); +//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; + // 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; + // 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) +void KBoolLink::Remove( Node *a_node ) { - (m_beginnode == a_node) ? m_beginnode = NULL : m_endnode = NULL; + ( m_beginnode == a_node ) ? m_beginnode = NULL : m_endnode = NULL; } // -// Replace oldnode by newnode and correct the references +// 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; - } +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 +// Reset all values // void KBoolLink::Reset() { - m_beginnode = 0; - m_endnode = 0; - Reset_flags(); + m_beginnode = 0; + m_endnode = 0; + Reset_flags(); } // -// Reset all 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_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 + 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 +// Refill this link by the arguments // -void KBoolLink::Reset(Node *begin, Node *end,int graphnr) +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; + // 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) +void KBoolLink::Set( Node *begin, Node *end ) { - m_beginnode = begin; - m_endnode = end; + m_beginnode = begin; + m_endnode = end; } void KBoolLink::SetBeenHere() { - m_bin = true; + m_bin = true; } void KBoolLink::SetNotBeenHere() { - m_bin = false; + m_bin = false; } -void KBoolLink::SetBeginNode(Node* new_node) +void KBoolLink::SetBeginNode( Node* new_node ) { - m_beginnode = new_node; + m_beginnode = new_node; } -void KBoolLink::SetEndNode(Node* new_node) +void KBoolLink::SetEndNode( Node* new_node ) { - m_endnode = new_node; + m_endnode = new_node; } // -// Sets the graphnumber to argument num +// Sets the graphnumber to argument num // void KBoolLink::SetGraphNum( int num ) { - m_graphnum=num; + m_graphnum = num; } GroupType KBoolLink::Group() { - return m_group; + return m_group; } // // Reset the groupflag to argument groep // -void KBoolLink::SetGroup(GroupType groep) +void KBoolLink::SetGroup( GroupType groep ) { - m_group= groep; + m_group = groep; } // -// Remove all references to this link and from this link +// 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; + 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; + m_mark = false; + m_bin = false; } -void KBoolLink::SetMark(bool value) +void KBoolLink::SetMark( bool value ) { - m_mark = value; + m_mark = value; } // -// general purpose mark checker +// general purpose mark checker // bool KBoolLink::IsMarked() { return m_mark; } -void KBoolLink::SetTopHole(bool value) { m_hole_top = value; } +void KBoolLink::SetTopHole( bool value ) { m_hole_top = value; } -bool KBoolLink::IsTopHole() { return m_hole_top; } +bool KBoolLink::IsTopHole() { return m_hole_top; } // // Calculates the merge/substact/exor/intersect flags // -void KBoolLink::SetLineTypes() +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; + 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; + //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_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_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_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_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_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; + 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) +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; + 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; + 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_LeftB; + m_LeftB = m_RightB; + m_RightB = 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_merge_L ; + m_merge_L = m_merge_R; + m_merge_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_a_substract_b_L; + m_a_substract_b_L = m_a_substract_b_R; + m_a_substract_b_R = swap; - swap = m_intersect_L; - m_intersect_L = m_intersect_R; - m_intersect_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_exor_L; - m_exor_L = m_exor_R; - m_exor_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; + } } diff --git a/polygon/kbool/src/lpoint.cpp b/polygon/kbool/src/lpoint.cpp index cb1c7b29f2..3d1a1ef859 100644 --- a/polygon/kbool/src/lpoint.cpp +++ b/polygon/kbool/src/lpoint.cpp @@ -1,150 +1,146 @@ -/*! \file ../src/lpoint.cpp +/*! \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 $ + \author Klaas Holwerda + + Copyright: 2001-2004 (C) Klaas Holwerda + + Licence: see kboollicense.txt + + RCS-ID: $Id: lpoint.cpp,v 1.3 2008/06/04 21:23:22 titato Exp $ */ -#ifdef __GNUG__ -#pragma implementation -#endif - -#include "../include/lpoint.h" +#include "kbool/lpoint.h" #include // Constructors LPoint::LPoint() { - _x = 0; - _y = 0; + _x = 0; + _y = 0; } -LPoint::LPoint(B_INT const X, B_INT const Y) +LPoint::LPoint( B_INT const X, B_INT const Y ) { - _x = X; - _y = Y; + _x = X; + _y = Y; } -LPoint::LPoint(LPoint* const a_point) +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; + 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; + return _x; } B_INT LPoint::GetY() { - return _y; + return _y; } -void LPoint::SetX(B_INT a_point_x) +void LPoint::SetX( B_INT a_point_x ) { - _x = a_point_x; + _x = a_point_x; } -void LPoint::SetY(B_INT a_point_y) +void LPoint::SetY( B_INT a_point_y ) { - _y = a_point_y; + _y = a_point_y; } LPoint LPoint::GetPoint() { - return *this; + return * this; } -void LPoint::Set(const B_INT X,const B_INT Y) +void LPoint::Set( const B_INT X, const B_INT Y ) { - _x = X; - _y = Y; + _x = X; + _y = Y; } -void LPoint::Set(const LPoint &a_point) +void LPoint::Set( const LPoint &a_point ) { - _x = a_point._x; - _y =a_point._y; + _x = a_point._x; + _y = a_point._y; } -bool LPoint::Equal(const LPoint a_point, B_INT Marge) +bool LPoint::Equal( const LPoint a_point, B_INT Marge ) { - B_INT delta_x, delta_y; + B_INT delta_x, delta_y; - delta_x = babs((_x - a_point._x)); - delta_y = babs((_y - a_point._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; + 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) +bool LPoint::Equal( const B_INT X, const B_INT Y, B_INT Marge ) { - return (bool)((babs(_x - X) <= Marge) && (babs(_y - Y) <= Marge)); + return ( bool )( ( babs( _x - X ) <= Marge ) && ( babs( _y - Y ) <= Marge ) ); } -bool LPoint::ShorterThan(const LPoint a_point, B_INT 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; + 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 ) ; + return ( bool ) ( ( a + b ) <= Marge * Marge ? true : false ) ; } -bool LPoint::ShorterThan(const B_INT X, const B_INT Y, B_INT Marge) +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; + double a, b; + a = ( double ) ( X - _x ); + a *= a; + b = ( double ) ( Y - _y ); + b *= b; - return (bool) ( a+b <= Marge*Marge ? true : false ) ; + return ( bool ) ( a + b <= Marge * Marge ? true : false ) ; } // overload the assign (=) operator // usage : a_point = another_point; -LPoint &LPoint::operator=(const LPoint &other_point) +LPoint &LPoint::operator=( const LPoint &other_point ) { - _x = other_point._x; - _y = other_point._y; - return *this; + _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) +LPoint &LPoint::operator+( const LPoint &other_point ) { - _x += other_point._x; - _y += other_point._y; - return *this; + _x += other_point._x; + _y += other_point._y; + return *this; } @@ -152,51 +148,51 @@ LPoint &LPoint::operator+(const LPoint &other_point) // overload the - operator // usage : a_point = point1 - point2; -LPoint &LPoint::operator-(const LPoint &other_point) +LPoint &LPoint::operator-( const LPoint &other_point ) { - _x -= other_point._x; - _y -= other_point._y; - return *this; + _x -= other_point._x; + _y -= other_point._y; + return *this; } // overload the * operator // usage: a_point = point1 * 100; -LPoint &LPoint::operator*(int factor) +LPoint &LPoint::operator*( int factor ) { - _x *= factor; - _y *= factor; - return *this; + _x *= factor; + _y *= factor; + return *this; } // overload the / operator // usage: a_point = point1 / 100; -LPoint &LPoint::operator/(int factor) +LPoint &LPoint::operator/( int factor ) { - _x /= factor; - _y /= factor; - return *this; + _x /= factor; + _y /= factor; + return *this; } // overload the compare (==) operator // usage: if (point1 == point2) { }; -int LPoint::operator==(const LPoint &other_point) const +int LPoint::operator==( const LPoint &other_point ) const { - return ((other_point._x == _x) && (other_point._y == _y)); + 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 +int LPoint::operator!=( const LPoint &other_point ) const { - return ((other_point._x != _x) || (other_point._y != _y)); + return ( ( other_point._x != _x ) || ( other_point._y != _y ) ); } diff --git a/polygon/kbool/src/makefile.include b/polygon/kbool/src/makefile.include index 70047bb549..ff89ee729a 100644 --- a/polygon/kbool/src/makefile.include +++ b/polygon/kbool/src/makefile.include @@ -1,3 +1,7 @@ +# makefile.include for kbool +.cpp.o: + g++ -c -Wall -O2 -I../include -o $@ $*.cpp + OBJECTS =\ booleng.o\ graph.o\ diff --git a/polygon/kbool/src/node.cpp b/polygon/kbool/src/node.cpp index a75da4c9f1..007dec19e3 100644 --- a/polygon/kbool/src/node.cpp +++ b/polygon/kbool/src/node.cpp @@ -1,390 +1,387 @@ -/*! \file ../src/node.cpp +/*! \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 $ + \author Klaas Holwerda + + Copyright: 2001-2004 (C) Klaas Holwerda + + Licence: see kboollicense.txt + + RCS-ID: $Id: node.cpp,v 1.3 2008/06/04 21:23:22 titato Exp $ */ -#ifdef __GNUG__ -#pragma implementation -#endif -#include "../include/node.h" -#include "../include/link.h" -#include "../include/line.h" +#include "kbool/node.h" +#include "kbool/link.h" +#include "kbool/line.h" #include //this here is to initialize the static iterator of node //with NOLIST constructor -//TDLI Node::_linkiter=TDLI(_GC); +//TDLI Node::_linkiter=TDLI(_GC); -Node::Node(Bool_Engine* GC) : LPoint(0,0) +Node::Node( Bool_Engine* GC ) : LPoint( 0, 0 ) { - _GC=GC; - _linklist=new DL_List(); + _GC = GC; + _linklist = new DL_List(); } -Node::Node(B_INT const X, B_INT const Y, Bool_Engine* GC) : LPoint(X,Y) +Node::Node( B_INT const X, B_INT const Y, Bool_Engine* GC ) : LPoint( X, Y ) { - _GC=GC; - _linklist=new DL_List(); + _GC = GC; + _linklist = new DL_List(); } -Node::Node(LPoint* const a_point, Bool_Engine* GC) : LPoint(a_point) +Node::Node( LPoint* const a_point, Bool_Engine* GC ) : LPoint( a_point ) { - _GC=GC; - _linklist=new DL_List(); + _GC = GC; + _linklist = new DL_List(); } //Node::Node(Node * const other) : LPoint(other) -Node::Node(Node * const other, Bool_Engine* GC) +Node::Node( Node * const other, Bool_Engine* GC ) { - _GC=GC; - _x = other->_x; - _y = other->_y; - _linklist=new DL_List(); + _GC = GC; + _x = other->_x; + _y = other->_y; + _linklist = new DL_List(); } -Node& Node::operator=(const Node &other_node) +Node& Node::operator=( const Node &other_node ) { - _x = other_node._x; - _y = other_node._y; + _x = other_node._x; + _y = other_node._y; - return *this; + 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) +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; + _x = ( B_INT ) floor( ( _x + grid * 0.5 ) / grid ) * grid; + _y = ( B_INT ) floor( ( _y + grid * 0.5 ) / grid ) * grid; } Node::~Node() { - delete _linklist; + delete _linklist; } DL_List* Node::GetLinklist() { - return _linklist; + return _linklist; } -void Node::AddLink(KBoolLink *a_link) +void Node::AddLink( KBoolLink *a_link ) { -// assert(a_link); - _linklist->insbegin(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(); + 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(); + if ( ( ( KBoolLink* )_linklist->headitem() )->GetBeginNode() == this ) + return ( KBoolLink* )_linklist->headitem(); + else + return ( KBoolLink* )_linklist->tailitem(); } // // Returns the number of connected links // -int Node::GetNumberOfLinks() +int Node::GetNumberOfLinks() { - return _linklist->count(); + return _linklist->count(); } -KBoolLink* Node::GetOtherLink(KBoolLink* prev) +KBoolLink* Node::GetOtherLink( KBoolLink* prev ) { - if (prev==(KBoolLink*)_linklist->headitem()) - return (KBoolLink*)_linklist->tailitem(); - if (prev==(KBoolLink*)_linklist->tailitem()) - return (KBoolLink*)_linklist->headitem(); + if ( prev == ( KBoolLink* )_linklist->headitem() ) + return ( KBoolLink* )_linklist->tailitem(); + if ( prev == ( KBoolLink* )_linklist->tailitem() ) + return ( KBoolLink* )_linklist->headitem(); - return NULL; + return NULL; } -int Node::Merge(Node *other) +int Node::Merge( Node *other ) { - if (this==other) //they are already merged dummy - return 0; + 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 Iother(other->_linklist); - KBoolLink* temp; + _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 Iother( other->_linklist ); + KBoolLink* temp; - Counter = Iother.count(); + 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(); + 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; + //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) +void Node::RemoveLink( KBoolLink *a_link ) { -// assert(a_link); - _GC->_linkiter->Attach(_linklist); +// assert(a_link); + _GC->_linkiter->Attach( _linklist ); - if (_GC->_linkiter->toitem(a_link)) // find the link - _GC->_linkiter->remove(); - _GC->_linkiter->Detach(); + 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 +// 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) +// false if points can't be simplified +bool Node::Simplify( Node *First, Node *Second, B_INT Marge ) { - double distance=0; + 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; + // 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; + // 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); + // 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; + // 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(); + int Aantal = _linklist->count(); -// assert (Aantal != 0); +// 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; + // 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; - } + // 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; + int Aantal; + if ( !_linklist ) + return NULL; - Aantal = _linklist->count(); + Aantal = _linklist->count(); -// assert (Aantal != 0); +// assert (Aantal != 0); - // there is one link, so there is no previous link - if (Aantal == 1) - return NULL; + // there is one link, so there is no previous link + if ( Aantal == 1 ) + return NULL; - int Marked_Counter = 0; - KBoolLink *the_link = 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; - } + _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 ); - } + 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 ); - } + 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 ); + 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* Node::GetMost( KBoolLink* const prev , LinkStatus whatside, BOOL_OP operation ) { - KBoolLink *reserve=0; - KBoolLink *Result = NULL,*link; - Node* prevbegin = prev->GetOther(this); + 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); - } + 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)++; - } + _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); + // 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 @@ -392,221 +389,221 @@ KBoolLink* Node::GetMost( KBoolLink* const prev ,LinkStatus whatside, BOOL_OP op // 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); + 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); - } + 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)++; - } + _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); + // 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; + KBoolLink * Result = NULL, *link; - _GC->_linkiter->Attach(_linklist); + _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; - } - } + 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); + _GC->_linkiter->Detach(); + return ( Result ); } // this function gets the highest not flat link KBoolLink* Node::GetNotFlat() { - KBoolLink *Result=NULL,*link; + KBoolLink * Result = NULL, *link; - _GC->_linkiter->Attach(_linklist); + _GC->_linkiter->Attach( _linklist ); - double tangold = 0.0; - double tangnew = 0.0; + 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; - } + 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 ( !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); + // 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 *Node::Follow( KBoolLink* const prev ) { - KBoolLink *temp; - _GC->_linkiter->Attach(_linklist); + 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->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); + _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* Node::GetBinHighest( bool binset ) { - KBoolLink *Result=NULL,*link; - _GC->_linkiter->Attach(_linklist); + KBoolLink * Result = NULL, *link; + _GC->_linkiter->Attach( _linklist ); - double tangold = 0.0; - double tangnew = 0.0; + 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) + for( _GC->_linkiter->tohead();!_GC->_linkiter->hitroot();( *_GC->_linkiter )++ ) + { + link = _GC->_linkiter->item(); + if ( _GC->_linkiter->item()->BeenHere() == binset ) { - //this one is higher then the old Result - Result = link; - tangold = tangnew; - } - } - } - } + 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 there is a link found return it - // else return NULL - _GC->_linkiter->Detach(); - return (Result); + 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 ); } diff --git a/polygon/kbool/src/record.cpp b/polygon/kbool/src/record.cpp index 68e1920842..1ad4b591dc 100644 --- a/polygon/kbool/src/record.cpp +++ b/polygon/kbool/src/record.cpp @@ -1,20 +1,16 @@ -/*! \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 $ +/*! \file src/record.cpp + \author Klaas Holwerda or Julian Smart + + Copyright: 2001-2004 (C) Klaas Holwerda + + Licence: see kboollicense.txt + + RCS-ID: $Id: record.cpp,v 1.3 2008/06/04 21:23:22 titato Exp $ */ -#ifdef __GNUG__ -#pragma implementation -#endif - -#include "../include/booleng.h" -#include "../include/record.h" -#include "../include/node.h" +#include "kbool/booleng.h" +#include "kbool/record.h" +#include "kbool/node.h" #include #include @@ -33,8 +29,7 @@ //} Record::~Record() -{ -} +{} //void* Record::operator new(size_t size) @@ -57,7 +52,7 @@ Record::~Record() // return; // } // -// free (recordptr); +// free (recordptr); //} //void Record::deletepool() @@ -69,289 +64,289 @@ Record::~Record() // } //} -Record::Record(KBoolLink* link,Bool_Engine* GC) - :_line(GC) +Record::Record( KBoolLink* link, Bool_Engine* GC ) + : _line( GC ) { - _GC=GC; - _dir=GO_RIGHT; - _a=0; - _b=0; - _line.Set(link); - _line.CalculateLineParameters(); + _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) +void Record::SetNewLink( KBoolLink* link ) { - _line.Set(link); - _line.CalculateLineParameters(); + _line.Set( link ); + _line.CalculateLineParameters(); } //for beams calculate the ysp on the low scanline -void Record::Calc_Ysp(Node* low) +void Record::Calc_Ysp( Node* low ) { - if ((LNK->GetEndNode() == low) || (LNK->GetBeginNode() == low)) - { - _ysp=low->GetY(); - return; - } + 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()); + 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; - } + 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; + return LNK; } B_INT Record::Ysp() { - return _ysp; + return _ysp; } -void Record::SetYsp(B_INT ysp) +void Record::SetYsp( B_INT ysp ) { - _ysp=ysp; + _ysp = ysp; } DIRECTION Record::Direction() { - return DIRECTION(_dir); + return DIRECTION( _dir ); } -bool Record::Calc_Left_Right(Record* record_above_me) +bool Record::Calc_Left_Right( Record* record_above_me ) { - bool par=false; + 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; - } + 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)); + 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; - } + 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)); + 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; - } + 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)); + 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; - } + 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)); + 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; - } + 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; - } + 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; + /* + 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) +bool Record::Equal( Record *a ) { - return((bool)( ( LNK->GetOther(a->LNK->GetBeginNode()) == a->LNK->GetEndNode()) && - ( LNK->GetOther(a->LNK->GetEndNode()) == a->LNK->GetBeginNode()) )); + return( ( bool )( ( LNK->GetOther( a->LNK->GetBeginNode() ) == a->LNK->GetEndNode() ) && + ( LNK->GetOther( a->LNK->GetEndNode() ) == a->LNK->GetBeginNode() ) ) ); } KBoolLine* Record::GetLine() { - return &_line; + return & _line; } diff --git a/polygon/kbool/src/scanbeam.cpp b/polygon/kbool/src/scanbeam.cpp index c840c4c2cd..a761aaffa7 100644 --- a/polygon/kbool/src/scanbeam.cpp +++ b/polygon/kbool/src/scanbeam.cpp @@ -1,58 +1,54 @@ -/*! \file ../src/scanbeam.cpp - \author Probably Klaas Holwerda or Julian Smart - - Copyright: 2001-2004 (C) Probably Klaas Holwerda - - Licence: wxWidgets Licence - - RCS-ID: $Id: scanbeam.cpp,v 1.10 2005/06/17 23:05:18 kbluck Exp $ +/*! \file src/scanbeam.cpp + \author Klaas Holwerda or Julian Smart + + Copyright: 2001-2004 (C) Klaas Holwerda + + Licence: see kboollicense.txt + + RCS-ID: $Id: scanbeam.cpp,v 1.3 2008/06/04 21:23:22 titato Exp $ */ -#ifdef __GNUG__ -#pragma implementation -#endif - // class scanbeam // this class represents de space between two scanlines -#include "../include/scanbeam.h" +#include "kbool/scanbeam.h" #include #include -#include "../include/booleng.h" +#include "kbool/booleng.h" -#include "../include/graph.h" -#include "../include/node.h" +#include "kbool/graph.h" +#include "kbool/node.h" //this here is to initialize the static iterator of scanbeam //with NOLIST constructor -int recordsorter(Record* , Record* ); +int recordsorter( Record* , Record* ); -int recordsorter_ysp_angle(Record* , Record* ); -int recordsorter_ysp_angle_back(Record* rec1, Record* rec2); +int recordsorter_ysp_angle( Record* , Record* ); +int recordsorter_ysp_angle_back( Record* rec1, Record* rec2 ); -ScanBeam::ScanBeam(Bool_Engine* GC):DL_List() +ScanBeam::ScanBeam( Bool_Engine* GC ): DL_List() { - _GC = GC; - _type=NORMAL; - _BI.Attach(this); + _GC = GC; + _type = NORMAL; + _BI.Attach( this ); } ScanBeam::~ScanBeam() { - //first delete all record still in the beam - _BI.Detach(); - remove_all( true ); + //first delete all record still in the beam + _BI.Detach(); + remove_all( true ); - //DeleteRecordPool(); + //DeleteRecordPool(); } -void ScanBeam::SetType(Node* low,Node* high) +void ScanBeam::SetType( Node* low, Node* high ) { - if (low->GetX() < high->GetX()) - _type=NORMAL; - else - _type=FLAT; + if ( low->GetX() < high->GetX() ) + _type = NORMAL; + else + _type = FLAT; } /* @@ -60,41 +56,41 @@ void ScanBeam::SetType(Node* low,Node* high) // must be sorted on ysp int ScanBeam::FindCloseLinksAndCross(TDLI* _I,Node* _lowf) { - int merges = 0; - Record* record; - + int merges = 0; + Record* record; + TDLI _BBI=TDLI(this); - - if (_BI.count() > 1) - { - //first search a link towards this node - for(_BI.tohead(); !_BI.hitroot(); _BI++) - { - record=_BI.item(); - if( (record->GetLink()->GetBeginNode()==_lowf) || - (record->GetLink()->GetEndNode() ==_lowf) - ) - break; - } - - //NOTICE if the node "a_node" is not inside a record - //for instance to connected flat links (flatlinks not in beam) - //then IL will be at end (those will be catched at 90 degrees rotation) - if (_BI.hitroot()) + + if (_BI.count() > 1) + { + //first search a link towards this node + for(_BI.tohead(); !_BI.hitroot(); _BI++) + { + record=_BI.item(); + if( (record->GetLink()->GetBeginNode()==_lowf) || + (record->GetLink()->GetEndNode() ==_lowf) + ) + break; + } + + //NOTICE if the node "a_node" is not inside a record + //for instance to connected flat links (flatlinks not in beam) + //then IL will be at end (those will be catched at 90 degrees rotation) + if (_BI.hitroot()) { - return(merges); + return(merges); } - + //from IL search back for close links _BBI.toiter(&_BI); _BBI--; while(!_BBI.hitroot()) { record=_BBI.item(); - + if (record->Ysp() != _lowf->GetY()) break; - + // the distance to the low node is smaller then the MARGE if( (record->GetLink()->GetBeginNode()!=_lowf) && (record->GetLink()->GetEndNode() !=_lowf) @@ -106,18 +102,18 @@ int ScanBeam::FindCloseLinksAndCross(TDLI* _I,Node* _lowf) } _BBI--; } - + //from IL search forward for close links _BBI.toiter(&_BI); _BBI++; while(!_BBI.hitroot()) { record=_BBI.item(); - + if (record->Ysp() != _lowf->GetY()) // if (record->Ysp() < _lowf->GetY()-MARGE) break; - + // the distance to the low node is smaller then the MARGE if( (record->GetLink()->GetBeginNode()!=_lowf) && (record->GetLink()->GetEndNode() !=_lowf) @@ -130,34 +126,34 @@ int ScanBeam::FindCloseLinksAndCross(TDLI* _I,Node* _lowf) _BBI++; } } - return merges; + return merges; } */ /* bool ScanBeam::Update(TDLI* _I,Node* _lowf) { - bool found=false; - KBoolLink* link; - - _BI.tohead(); - while (!_BI.hitroot()) - { - - Record* record=_BI.item(); - record->Calc_Ysp(_type,_low); - _BI++; - } - + bool found=false; + KBoolLink* link; + + _BI.tohead(); + while (!_BI.hitroot()) + { + + Record* record=_BI.item(); + record->Calc_Ysp(_type,_low); + _BI++; + } + FindCloseLinksAndCross(_I,_lowf); - + _BI.tohead(); while (!_BI.hitroot()) { Record* record=_BI.item(); //records containing links towards the new low node //are links to be marked for removal - + if ((record->GetLink()->GetEndNode() == _lowf) || (record->GetLink()->GetBeginNode() == _lowf) ) @@ -165,7 +161,7 @@ bool ScanBeam::Update(TDLI* _I,Node* _lowf) //cross here the links that meat eachother now delete _BI.item(); _BI.remove(); - + //cross here the links that meat eachother now _BI--; if (!_BI.hitroot() && (_BI.count() > 1)) @@ -186,19 +182,19 @@ bool ScanBeam::Update(TDLI* _I,Node* _lowf) } } else - _BI++; + _BI++; } else _BI++; } - - //writebeam(); - + + //writebeam(); + //ONLY links towards the low node are possible to be added - //the bin flag will be set if it fits in the beam - //so for following beams it will not be checked again - while ( bool(link=_lowf->GetBinHighest(false)) ) - { + //the bin flag will be set if it fits in the beam + //so for following beams it will not be checked again + while ( bool(link=_lowf->GetBinHighest(false)) ) + { Record* record=new Record(link); // yp_new will always be the y of low node since all new links are // from this node @@ -208,7 +204,7 @@ bool ScanBeam::Update(TDLI* _I,Node* _lowf) //this is only used when the insert node is equal for both records // ins_smart and cross neighbour directly // if empty then just insert - + if (empty()) insend(record); else @@ -221,7 +217,7 @@ bool ScanBeam::Update(TDLI* _I,Node* _lowf) break; _BI++; } - + _BI.insbefore(record); _BI--;_BI--; //just before the new record inserted if (!_BI.hitroot()) @@ -241,12 +237,12 @@ bool ScanBeam::Update(TDLI* _I,Node* _lowf) } else _BI++; - + Record* prev=_BI.item(); //the new record _BI++; if (!_BI.hitroot() && !_BI.item()->Equal(prev)) // records NOT parallel { - Record* cur=_BI.item(); + Record* cur=_BI.item(); if (cur->GetLine()->Intersect(prev->GetLine(),MARGE)) { //this may modify the links already part of the record @@ -259,407 +255,407 @@ bool ScanBeam::Update(TDLI* _I,Node* _lowf) //remember this to calculate in/out values for each new link its polygon again. GNI->insend(record->GetLink()->GetGraphNum()); found=true; - record->GetLink()->SetBeenHere(); + record->GetLink()->SetBeenHere(); } - + FindCloseLinksAndCross(_I,_lowf); - //writebeam(); - return(found); + //writebeam(); + return(found); } */ -bool ScanBeam::FindNew(SCANTYPE scantype,TDLI* _I, bool& holes ) +bool ScanBeam::FindNew( SCANTYPE scantype, TDLI* _I, bool& holes ) { - bool foundnew = false; + bool foundnew = false; - _low = _I->item()->GetBeginNode(); + _low = _I->item()->GetBeginNode(); - KBoolLink* link; + KBoolLink* link; - //if (!checksort()) - // SortTheBeam(); + //if (!checksort()) + // SortTheBeam(); - lastinserted=0; - //ONLY links towards the low node are possible to be added - //the bin flag will be set if it fits in the beam - //so for following beams it will not be checked again - while ( (link = _low->GetBinHighest(false)) != NULL ) - { - if ( (link->GetEndNode()->GetX() == link->GetBeginNode()->GetX()) //flatlink in flatbeam - && ((scantype == NODELINK) || (scantype == LINKLINK) || (scantype == LINKHOLES)) - ) - { - switch(scantype) + lastinserted = 0; + //ONLY links towards the low node are possible to be added + //the bin flag will be set if it fits in the beam + //so for following beams it will not be checked again + while ( ( link = _low->GetBinHighest( false ) ) != NULL ) + { + if ( ( link->GetEndNode()->GetX() == link->GetBeginNode()->GetX() ) //flatlink in flatbeam + && ( ( scantype == NODELINK ) || ( scantype == LINKLINK ) || ( scantype == LINKHOLES ) ) + ) + { + switch( scantype ) { - case NODELINK: - { - //all vertical links in flatbeam are ignored - //normal link in beam - Record* record=new Record(link,_GC); - // yp_new will always be the y of low node since all new links are - // from this node - record->SetYsp(_low->GetY()); - record->Set_Flags(); - // put new item left of the one that is lower in the beam - // The last one inserted in this loop, is already left of the current - // iterator position. So the new links are inerted in proper order. - link->SetRecordNode( _BI.insbefore(record) ); - _BI--; - foundnew = Process_PointToLink_Crossings() !=0 || foundnew; - delete record; - _BI.remove(); - break; - } - case LINKLINK: - //is the new record a flat link - { - KBoolLine flatline = KBoolLine(link, _GC); - foundnew = Process_LinkToLink_Flat(&flatline) || foundnew; - //flatlinks are not part of the beams, still they are used to find new beams - //they can be processed now if the beginnode does not change, since this is used to - //to find new beams. and its position does not change - //ProcessCrossings does take care of this - flatline.ProcessCrossings(_I); - break; - } - case LINKHOLES : //holes are never to flatlinks - assert( true ); - default: - break; + case NODELINK: + { + //all vertical links in flatbeam are ignored + //normal link in beam + Record * record = new Record( link, _GC ); + // yp_new will always be the y of low node since all new links are + // from this node + record->SetYsp( _low->GetY() ); + record->Set_Flags(); + // put new item left of the one that is lower in the beam + // The last one inserted in this loop, is already left of the current + // iterator position. So the new links are inerted in proper order. + link->SetRecordNode( _BI.insbefore( record ) ); + _BI--; + foundnew = Process_PointToLink_Crossings() != 0 || foundnew; + delete record; + _BI.remove(); + break; + } + case LINKLINK: + //is the new record a flat link + { + KBoolLine flatline = KBoolLine( link, _GC ); + foundnew = Process_LinkToLink_Flat( &flatline ) || foundnew; + //flatlinks are not part of the beams, still they are used to find new beams + //they can be processed now if the beginnode does not change, since this is used to + //to find new beams. and its position does not change + //ProcessCrossings does take care of this + flatline.ProcessCrossings( _I ); + break; + } + case LINKHOLES : //holes are never to flatlinks + assert( true ); + default: + break; } - } - else - { - //normal link in beam - Record* record = new Record(link,_GC); - // yp_new will always be the y of low node since all new links are - // from this node - record->SetYsp(_low->GetY()); - record->Set_Flags(); - // put new item left of the one that is lower in the beam - // The last one inserted in this loop, is already left of the current - // iterator position. So the new links are inserted in proper order. - link->SetRecordNode( _BI.insbefore(record) ); - lastinserted++; + } + else + { + //normal link in beam + Record* record = new Record( link, _GC ); + // yp_new will always be the y of low node since all new links are + // from this node + record->SetYsp( _low->GetY() ); + record->Set_Flags(); + // put new item left of the one that is lower in the beam + // The last one inserted in this loop, is already left of the current + // iterator position. So the new links are inserted in proper order. + link->SetRecordNode( _BI.insbefore( record ) ); + lastinserted++; - //_GC->Write_Log( "after insert" ); - writebeam(); + //_GC->Write_Log( "after insert" ); + writebeam(); - switch(scantype) - { - case NODELINK: - _BI--; - foundnew = Process_PointToLink_Crossings() !=0 || foundnew; - _BI++; - break; - case INOUT: + switch( scantype ) { - _BI--; - //now we can set the _inc flag - Generate_INOUT(record->GetLink()->GetGraphNum()); - _BI++; + case NODELINK: + _BI--; + foundnew = Process_PointToLink_Crossings() != 0 || foundnew; + _BI++; + break; + case INOUT: + { + _BI--; + //now we can set the _inc flag + Generate_INOUT( record->GetLink()->GetGraphNum() ); + _BI++; + } + break; + case GENLR: + { + //now we can set the a/b group flags based on the above link + _BI--; + _BI--; + Record* above = 0; + if ( !_BI.hitroot() ) + above = _BI.item(); + _BI++; + + //something to do for winding rule + + if ( record->Calc_Left_Right( above ) ) + { + delete record; + _BI.remove(); + lastinserted--; + } + else + _BI++; + } + break; + case LINKHOLES: + _BI--; + holes = ProcessHoles( true, _I ) || holes; + _BI++; + break; + + default: + break; } - break; - case GENLR: - { - //now we can set the a/b group flags based on the above link - _BI--; - _BI--; - Record* above=0; - if (!_BI.hitroot()) - above=_BI.item(); - _BI++; + } + link->SetBeenHere(); + } - //something to do for winding rule + writebeam(); - if (record->Calc_Left_Right(above)) - { - delete record; - _BI.remove(); - lastinserted--; - } - else - _BI++; - } - break; - case LINKHOLES: - _BI--; - holes = ProcessHoles(true,_I) || holes; - _BI++; - break; - - default: - break; - } - } - link->SetBeenHere(); - } - - writebeam(); - - return foundnew; + return foundnew; } -bool ScanBeam::RemoveOld(SCANTYPE scantype,TDLI* _I, bool& holes ) +bool ScanBeam::RemoveOld( SCANTYPE scantype, TDLI* _I, bool& holes ) { - bool found = false; - bool foundnew = false; - DL_Iter _BBI=DL_Iter(); - bool attached=false; + bool found = false; + bool foundnew = false; + DL_Iter _BBI = DL_Iter(); + bool attached = false; - _low = _I->item()->GetBeginNode(); + _low = _I->item()->GetBeginNode(); - switch(scantype) - { - case INOUT: - case GENLR: - case LINKHOLES: - if (_type==NORMAL ) - { - if (_low->GetBinHighest(true)) //is there something to remove - { - if ( scantype == LINKHOLES ) + switch( scantype ) + { + case INOUT: + case GENLR: + case LINKHOLES: + if ( _type == NORMAL ) { - _BI.tohead(); - while (!_BI.hitroot()) - { - Record* record=_BI.item(); - //records containing links towards the new low node - //are links to be removed - if ((record->GetLink()->GetEndNode() == _low) || - (record->GetLink()->GetBeginNode() == _low) - ) - { - holes = ProcessHoles(false,_I) || holes; - } - _BI++; - } + if ( _low->GetBinHighest( true ) ) //is there something to remove + { + if ( scantype == LINKHOLES ) + { + _BI.tohead(); + while ( !_BI.hitroot() ) + { + Record * record = _BI.item(); + //records containing links towards the new low node + //are links to be removed + if ( ( record->GetLink()->GetEndNode() == _low ) || + ( record->GetLink()->GetBeginNode() == _low ) + ) + { + holes = ProcessHoles( false, _I ) || holes; + } + _BI++; + } + } + + _BI.tohead(); + while ( !_BI.hitroot() ) + { + Record * record = _BI.item(); + //records containing links towards the new low node + //are links to be removed + if ( ( record->GetLink()->GetEndNode() == _low ) || + ( record->GetLink()->GetBeginNode() == _low ) + ) + { + if ( attached ) //there is a bug + { + _BBI.Detach(); + if ( !checksort() ) + SortTheBeam( true ); + _BI.tohead(); + attached = false; + + } + delete _BI.item(); + _BI.remove(); + found = true; + } + else if ( found ) //only once in here + { + attached = true; + found = false; + _BBI.Attach( this ); + _BBI.toiter( &_BI ); //this is the position new records will be inserted + + //recalculate ysp for the new scanline + record->Calc_Ysp( _low ); + _BI++; + } + else + { + //recalculate ysp for the new scanline + record->Calc_Ysp( _low ); + _BI++; + } + } + + if ( attached ) + { + _BI.toiter( &_BBI ); + _BBI.Detach(); + } + + } + else + { + _BBI.Attach( this ); + _BBI.toroot(); + _BI.tohead(); + while ( !_BI.hitroot() ) + { + Record * record = _BI.item(); + + record->Calc_Ysp( _low ); + if ( !found && ( record->Ysp() < _low->GetY() ) ) + { + found = true; + _BBI.toiter( &_BI ); + } + _BI++; + } + _BI.toiter( &_BBI ); + _BBI.Detach(); + } } - - _BI.tohead(); - while (!_BI.hitroot()) - { - Record* record=_BI.item(); - //records containing links towards the new low node - //are links to be removed - if ((record->GetLink()->GetEndNode() == _low) || - (record->GetLink()->GetBeginNode() == _low) - ) - { - if (attached) //there is a bug - { - _BBI.Detach(); - if (!checksort()) - SortTheBeam( true ); - _BI.tohead(); - attached=false; - - } - delete _BI.item(); - _BI.remove(); - found=true; - } - else if (found) //only once in here - { - attached=true; - found=false; - _BBI.Attach(this); - _BBI.toiter(&_BI); //this is the position new records will be inserted - - //recalculate ysp for the new scanline - record->Calc_Ysp(_low); - _BI++; - } - else - { - //recalculate ysp for the new scanline - record->Calc_Ysp(_low); - _BI++; - } - } - - if (attached) - { - _BI.toiter(&_BBI); - _BBI.Detach(); - } - - } - else - { - _BBI.Attach(this); - _BBI.toroot(); - _BI.tohead(); - while (!_BI.hitroot()) - { - Record* record=_BI.item(); - - record->Calc_Ysp(_low); - if (!found && (record->Ysp() < _low->GetY())) - { - found=true; - _BBI.toiter(&_BI); - } - _BI++; - } - _BI.toiter(&_BBI); - _BBI.Detach(); - } - } - else - { //because the previous beam was flat the links to remove are - //below the last insert position - if (_low->GetBinHighest(true)) //is there something to remove - { - - if ( scantype == LINKHOLES ) - { - _BI.tohead(); - while (!_BI.hitroot()) - { - Record* record=_BI.item(); - //records containing links towards the new low node - //are links to be removed - if ((record->GetLink()->GetEndNode() == _low) || - (record->GetLink()->GetBeginNode() == _low) - ) - { - holes = ProcessHoles(false,_I) || holes; - } - _BI++; - } - } - - //on record back bring us to the last inserted record - //or if nothing was inserted the record before the last deleted record - //if there was no record before the last deleted record this means - //we where at the beginning of the beam, so at root - - //_BI << (lastinserted+1); - //_BI--; - //if (_BI.hitroot()) //only possible when at the begin of the beam - - _BI.tohead(); - while (!_BI.hitroot()) - { - Record* record=_BI.item(); - //records containing links towards the new low node - //are links to be removed - if ((record->GetLink()->GetEndNode() == _low) || - (record->GetLink()->GetBeginNode() == _low) - ) - { - delete _BI.item(); - _BI.remove(); - found=true; - } - else if (found) //only once in here - break; - else if (record->Ysp() < _low->GetY()) - //if flatlinks are not in the beam nothing will be found - //this will bring us to the right insertion point - break; - else - _BI++; - } - } - else - { - //on record back bring us to the last inserted record - //or if nothing was inserted the record before the last deleted record - //if there was no record before the last deleted record this means - //we where at the beginning of the beam, so at root - - //_BI << (lastinserted+ 1); - //_BI--; - //if (_BI.hitroot()) //only possible when at the begin of the beam - _BI.tohead(); - while (!_BI.hitroot()) - { - Record* record=_BI.item(); - if (record->Ysp() < _low->GetY()) - break; - _BI++; - } - } - } - break; - - case NODELINK: - case LINKLINK: - { - if (_type == NORMAL) - { - Calc_Ysp(); - if (scantype==LINKLINK) - foundnew = Process_LinkToLink_Crossings() !=0 || foundnew; else - SortTheBeam( false ); - } - //else beam is already sorted because the added/removed flat links - //do not change the ysp of links already there, new non flat links - //are inserted in order, as result the beam stays sorted + { //because the previous beam was flat the links to remove are + //below the last insert position + if ( _low->GetBinHighest( true ) ) //is there something to remove + { - if (_low->GetBinHighest(true)) //is there something to remove - { - _BI.tohead(); - while (!_BI.hitroot()) - { - Record* record=_BI.item(); - //records containing links towards the new low node - //are links to be removed - if ((record->GetLink()->GetEndNode() == _low) || - (record->GetLink()->GetBeginNode() == _low) - ) - { - KBoolLine* line=record->GetLine(); - if (scantype==NODELINK) - foundnew = Process_PointToLink_Crossings() !=0 || foundnew; - line->ProcessCrossings(_I); - delete _BI.item(); - _BI.remove(); - found=true; - } - //because the beam is sorted on ysp, stop when nothing can be there to remove - //and the right insertion point for new links has been found - else if ((record->Ysp() < _low->GetY())) - break; - else - _BI++; + if ( scantype == LINKHOLES ) + { + _BI.tohead(); + while ( !_BI.hitroot() ) + { + Record * record = _BI.item(); + //records containing links towards the new low node + //are links to be removed + if ( ( record->GetLink()->GetEndNode() == _low ) || + ( record->GetLink()->GetBeginNode() == _low ) + ) + { + holes = ProcessHoles( false, _I ) || holes; + } + _BI++; + } + } + + //on record back bring us to the last inserted record + //or if nothing was inserted the record before the last deleted record + //if there was no record before the last deleted record this means + //we where at the beginning of the beam, so at root + + //_BI << (lastinserted+1); + //_BI--; + //if (_BI.hitroot()) //only possible when at the begin of the beam + + _BI.tohead(); + while ( !_BI.hitroot() ) + { + Record * record = _BI.item(); + //records containing links towards the new low node + //are links to be removed + if ( ( record->GetLink()->GetEndNode() == _low ) || + ( record->GetLink()->GetBeginNode() == _low ) + ) + { + delete _BI.item(); + _BI.remove(); + found = true; + } + else if ( found ) //only once in here + break; + else if ( record->Ysp() < _low->GetY() ) + //if flatlinks are not in the beam nothing will be found + //this will bring us to the right insertion point + break; + else + _BI++; + } + } + else + { + //on record back bring us to the last inserted record + //or if nothing was inserted the record before the last deleted record + //if there was no record before the last deleted record this means + //we where at the beginning of the beam, so at root + + //_BI << (lastinserted+ 1); + //_BI--; + //if (_BI.hitroot()) //only possible when at the begin of the beam + _BI.tohead(); + while ( !_BI.hitroot() ) + { + Record * record = _BI.item(); + if ( record->Ysp() < _low->GetY() ) + break; + _BI++; + } + } } - } - else - { - _BI.tohead(); - while (!_BI.hitroot()) + break; + + case NODELINK: + case LINKLINK: + { + if ( _type == NORMAL ) { - Record* record=_BI.item(); - //because the beam is sorted on ysp, stop when - //the right insertion point for new links has been found - if ((record->Ysp() < _low->GetY())) - break; - _BI++; + Calc_Ysp(); + if ( scantype == LINKLINK ) + foundnew = Process_LinkToLink_Crossings() != 0 || foundnew; + else + SortTheBeam( false ); } - } - } - break; + //else beam is already sorted because the added/removed flat links + //do not change the ysp of links already there, new non flat links + //are inserted in order, as result the beam stays sorted - default: - break; - } + if ( _low->GetBinHighest( true ) ) //is there something to remove + { + _BI.tohead(); + while ( !_BI.hitroot() ) + { + Record * record = _BI.item(); + //records containing links towards the new low node + //are links to be removed + if ( ( record->GetLink()->GetEndNode() == _low ) || + ( record->GetLink()->GetBeginNode() == _low ) + ) + { + KBoolLine * line = record->GetLine(); + if ( scantype == NODELINK ) + foundnew = Process_PointToLink_Crossings() != 0 || foundnew; + line->ProcessCrossings( _I ); + delete _BI.item(); + _BI.remove(); + found = true; + } + //because the beam is sorted on ysp, stop when nothing can be there to remove + //and the right insertion point for new links has been found + else if ( ( record->Ysp() < _low->GetY() ) ) + break; + else + _BI++; + } + } + else + { + _BI.tohead(); + while ( !_BI.hitroot() ) + { + Record * record = _BI.item(); + //because the beam is sorted on ysp, stop when + //the right insertion point for new links has been found + if ( ( record->Ysp() < _low->GetY() ) ) + break; + _BI++; + } + } + } + break; - return foundnew; + default: + break; + } + + return foundnew; } /* bool ScanBeam::RemoveOld(SCANTYPE scantype,TDLI* _I, bool& holes ) { - bool found = false; - bool foundnew = false; + bool found = false; + bool foundnew = false; DL_Iter _BBI=DL_Iter(); - bool attached=false; - + bool attached=false; + _low = _I->item()->GetBeginNode(); - + switch(scantype) { case INOUT: @@ -671,7 +667,7 @@ bool ScanBeam::RemoveOld(SCANTYPE scantype,TDLI* _I, bool& holes ) if ( link ) //is there something to remove { link->SetRecordNode( NULL ); - + if ( scantype == LINKHOLES ) { _BI.tohead(); @@ -689,7 +685,7 @@ bool ScanBeam::RemoveOld(SCANTYPE scantype,TDLI* _I, bool& holes ) _BI++; } } - + _BI.tohead(); while (!_BI.hitroot()) { @@ -739,7 +735,7 @@ bool ScanBeam::RemoveOld(SCANTYPE scantype,TDLI* _I, bool& holes ) if( link )//is there something to remove { link->SetRecordNode( NULL ); - + bool linkf = false; _BI.tohead(); while (!_BI.hitroot()) @@ -749,11 +745,11 @@ bool ScanBeam::RemoveOld(SCANTYPE scantype,TDLI* _I, bool& holes ) linkf = true; _BI++; } - + if ( !linkf ) _BI.tohead(); - - + + if ( scantype == LINKHOLES ) { _BI.tohead(); @@ -771,22 +767,22 @@ bool ScanBeam::RemoveOld(SCANTYPE scantype,TDLI* _I, bool& holes ) _BI++; } } - + //_BI.tonode( link->GetRecordNode() ); //delete _BI.item(); //_BI.remove(); - + //on record back bring us to the last inserted record //or if nothing was inserted the record before the last deleted record //if there was no record before the last deleted record this means //we where at the beginning of the beam, so at root - + //_BI << (lastinserted+1); //_BI--; //if (_BI.hitroot()) //only possible when at the begin of the beam - + //found=false; - + _BI.tohead(); while (!_BI.hitroot()) { @@ -822,17 +818,17 @@ bool ScanBeam::RemoveOld(SCANTYPE scantype,TDLI* _I, bool& holes ) else _BI++; } - + } - + else { - + //on record back bring us to the last inserted record //or if nothing was inserted the record before the last deleted record //if there was no record before the last deleted record this means //we where at the beginning of the beam, so at root - + //_BI << (lastinserted+ 1); //_BI--; //if (_BI.hitroot()) //only possible when at the begin of the beam @@ -844,11 +840,11 @@ bool ScanBeam::RemoveOld(SCANTYPE scantype,TDLI* _I, bool& holes ) break; _BI++; } - + } } break; - + case NODELINK: case LINKLINK: { @@ -863,7 +859,7 @@ bool ScanBeam::RemoveOld(SCANTYPE scantype,TDLI* _I, bool& holes ) //else beam is already sorted because the added/removed flat links //do not change the ysp of links already there, new non flat links //are inserted in order, as result the beam stays sorted - + if (_low->GetBinHighest(true)) //is there something to remove { _BI.tohead(); @@ -878,7 +874,7 @@ bool ScanBeam::RemoveOld(SCANTYPE scantype,TDLI* _I, bool& holes ) { KBoolLine* line=record->GetLine(); if (scantype==NODELINK) - foundnew = Process_PointToLink_Crossings() !=0 || foundnew; + foundnew = Process_PointToLink_Crossings() !=0 || foundnew; line->ProcessCrossings(_I); delete _BI.item(); _BI.remove(); @@ -907,76 +903,76 @@ bool ScanBeam::RemoveOld(SCANTYPE scantype,TDLI* _I, bool& holes ) } } break; - + default: break; } - - return foundnew; + + return foundnew; } */ void ScanBeam::SortTheBeam( bool backangle ) { - if ( backangle ) - _BI.mergesort( recordsorter_ysp_angle_back ); - else - _BI.mergesort( recordsorter_ysp_angle ); + if ( backangle ) + _BI.mergesort( recordsorter_ysp_angle_back ); + else + _BI.mergesort( recordsorter_ysp_angle ); } -void ScanBeam::Calc_Ysp() +void ScanBeam::Calc_Ysp() { - _BI.tohead(); - while (!_BI.hitroot()) - { - Record* record=_BI.item(); -// KBoolLink* link=_BI.item()->GetLink(); - record->Calc_Ysp(_low); - _BI++; - } + _BI.tohead(); + while ( !_BI.hitroot() ) + { + Record * record = _BI.item(); +// KBoolLink* link=_BI.item()->GetLink(); + record->Calc_Ysp( _low ); + _BI++; + } } // this function will set for all the records which contain a link with the // corresponding graphnumber the inc flag. // The inc flag's function is to see in a beam if we go deeper in the graph or not -void ScanBeam::Generate_INOUT(int graphnumber) +void ScanBeam::Generate_INOUT( int graphnumber ) { - DIRECTION first_dir = GO_LEFT; - int diepte = 0; + DIRECTION first_dir = GO_LEFT; + int diepte = 0; - DL_Iter _BBI = DL_Iter(); - _BBI.Attach(this); - for( _BBI.tohead(); !_BBI.hitroot(); _BBI++ ) - { - // recalculate _inc again - if ( _BBI.item()->GetLink()->GetGraphNum()==graphnumber) - { //found a link that belongs to the graph - if (diepte==0) - { // first link found or at depth zero again - // the direction is important since this is used to find out - // if we go further in or out for coming links - first_dir=_BBI.item()->Direction(); - _BBI.item()->GetLink()->SetInc(true); - diepte=1; - } - else - { // according to depth=1 links set depth - // verhoog of verlaag diepte - if (_BBI.item()->Direction() == first_dir) - { - diepte++; - _BBI.item()->GetLink()->SetInc(true); - } - else - { - diepte--; - _BBI.item()->GetLink()->SetInc(false); - } - } - } - if ( _BBI.item() == _BI.item()) break; //not need to do the rest, will come in a later beam - } - _BBI.Detach(); + DL_Iter _BBI = DL_Iter(); + _BBI.Attach( this ); + for( _BBI.tohead(); !_BBI.hitroot(); _BBI++ ) + { + // recalculate _inc again + if ( _BBI.item()->GetLink()->GetGraphNum() == graphnumber ) + { //found a link that belongs to the graph + if ( diepte == 0 ) + { // first link found or at depth zero again + // the direction is important since this is used to find out + // if we go further in or out for coming links + first_dir = _BBI.item()->Direction(); + _BBI.item()->GetLink()->SetInc( true ); + diepte = 1; + } + else + { // according to depth=1 links set depth + // verhoog of verlaag diepte + if ( _BBI.item()->Direction() == first_dir ) + { + diepte++; + _BBI.item()->GetLink()->SetInc( true ); + } + else + { + diepte--; + _BBI.item()->GetLink()->SetInc( false ); + } + } + } + if ( _BBI.item() == _BI.item() ) break; //not need to do the rest, will come in a later beam + } + _BBI.Detach(); } @@ -985,390 +981,393 @@ void ScanBeam::Generate_INOUT(int graphnumber) // this function will search the closest link to a hole // step one, search for a link that is marked (this is a hole) // step two, this is tricky, the closest link is the previous link in -// the beam, but only in the beam that contains the highest node -// from the marked link. -// why ? : if the marked link has for the begin and end node different -// x,y values, see below as link C +// the beam, but only in the beam that contains the highest node +// from the marked link. +// why ? : if the marked link has for the begin and end node different +// x,y values, see below as link C // B // A +---------+ // +----------+ -// ___--+ -// ___--- -// +--- C +// ___--+ +// ___--- +// +--- C // -// when we at first detect link C we would link it to link A, should work he -// but; we always link a hole at its topleft node, so the highest node -// and then we can't link to A but we should link to B -// so when we found the link, we will look if the node that will come -// in a later beam will be higher than the current, if so we will wait -// till that node comes around otherwise we will link this node to the -// closest link (prev in beam) +// when we at first detect link C we would link it to link A, should work he +// but; we always link a hole at its topleft node, so the highest node +// and then we can't link to A but we should link to B +// so when we found the link, we will look if the node that will come +// in a later beam will be higher than the current, if so we will wait +// till that node comes around otherwise we will link this node to the +// closest link (prev in beam) bool ScanBeam::ProcessHoles( bool atinsert, TDLI* _LI ) { - // The scanbeam must already be sorted at this moment - Node *topnode; - bool foundholes = false; + // The scanbeam must already be sorted at this moment + Node * topnode; + bool foundholes = false; - Record* record = _BI.item(); - KBoolLink* link = record->GetLink(); + Record* record = _BI.item(); + KBoolLink* link = record->GetLink(); - if (!record->GetLine()->CrossListEmpty()) - { - SortTheBeam( atinsert ); + if ( !record->GetLine()->CrossListEmpty() ) + { + SortTheBeam( atinsert ); - // link the holes in the graph to a link above. - // a the link where the linecrosslist is not empty, means that - // there are links which refer to this link (must be linked to this link) - // make new nodes and links and set them, re-use the old link, so the links - // that still stand in the linecrosslist will not be lost. - // There is a hole that must be linked to this link ! - TDLI I(record->GetLine()->GetCrossList()); - I.tohead(); - while(!I.hitroot()) - { - topnode = I.item(); - I.remove(); + // link the holes in the graph to a link above. + // a the link where the linecrosslist is not empty, means that + // there are links which refer to this link (must be linked to this link) + // make new nodes and links and set them, re-use the old link, so the links + // that still stand in the linecrosslist will not be lost. + // There is a hole that must be linked to this link ! + TDLI I( record->GetLine()->GetCrossList() ); + I.tohead(); + while( !I.hitroot() ) + { + topnode = I.item(); + I.remove(); - KBoolLine line(_GC); - line.Set(link); + KBoolLine line( _GC ); + line.Set( link ); - B_INT Y = line.Calculate_Y(topnode->GetX()); + B_INT Y = line.Calculate_Y( topnode->GetX() ); - // Now we'll create new nodes and new links to make the link between - // the graphs. + // Now we'll create new nodes and new links to make the link between + // the graphs. - //holes are always linked in a non hole or hole - //for a non hole this link will be to the right - //because non holes are right around - //for holes this will be to the right also, - //because they are left around but the link is always on the - //bottom of the hole + //holes are always linked in a non hole or hole + //for a non hole this link will be to the right + //because non holes are right around + //for holes this will be to the right also, + //because they are left around but the link is always on the + //bottom of the hole - // linkA linkD - // o-------->--------NodeA------->------------o - // | | - // | | - // linkB v ^ linkBB - // | | - // | | - // outgoing* | | incoming* - // o------<---------topnode--------<----------o - // - // all holes are oriented left around + // linkA linkD + // o-------->--------NodeA------->------------o + // | | + // | | + // linkB v ^ linkBB + // | | + // | | + // outgoing* | | incoming* + // o------<---------topnode--------<----------o + // + // all holes are oriented left around - Node * leftnode; //left node of clossest link - (link->GetBeginNode()->GetX() < link->GetEndNode()->GetX()) ? - leftnode = link->GetBeginNode(): - leftnode = link->GetEndNode(); + Node * leftnode; //left node of clossest link + ( link->GetBeginNode()->GetX() < link->GetEndNode()->GetX() ) ? + leftnode = link->GetBeginNode() : + leftnode = link->GetEndNode(); - Node *node_A = new Node(topnode->GetX(),Y, _GC); - KBoolLink *link_A = new KBoolLink(0, leftnode, node_A, _GC); - KBoolLink *link_B = new KBoolLink(0, node_A, topnode, _GC); - KBoolLink *link_BB = new KBoolLink(0, topnode, node_A, _GC); - KBoolLink *link_D = _BI.item()->GetLink(); - link_D->Replace(leftnode,node_A); - _LI->insbegin(link_A); - _LI->insbegin(link_B); - _LI->insbegin(link_BB); + Node *node_A = new Node( topnode->GetX(), Y, _GC ); + KBoolLink *link_A = new KBoolLink( 0, leftnode, node_A, _GC ); + KBoolLink *link_B = new KBoolLink( 0, node_A, topnode, _GC ); + KBoolLink *link_BB = new KBoolLink( 0, topnode, node_A, _GC ); + KBoolLink *link_D = _BI.item()->GetLink(); + link_D->Replace( leftnode, node_A ); + _LI->insbegin( link_A ); + _LI->insbegin( link_B ); + _LI->insbegin( link_BB ); - //mark those two segments as hole linking segments - link_B->SetHoleLink(true); - link_BB->SetHoleLink(true); + //mark those two segments as hole linking segments + link_B->SetHoleLink( true ); + link_BB->SetHoleLink( true ); - //is where we come from/link to a hole - bool closest_is_hole = link->GetHole(); + //is where we come from/link to a hole + bool closest_is_hole = link->GetHole(); - // if the polygon linked to, is a hole, this hole here - // just gets bigger, so we take over the links its hole marking. - link_A->SetHole(closest_is_hole); - link_B->SetHole(closest_is_hole); - link_BB->SetHole(closest_is_hole); + // if the polygon linked to, is a hole, this hole here + // just gets bigger, so we take over the links its hole marking. + link_A->SetHole( closest_is_hole ); + link_B->SetHole( closest_is_hole ); + link_BB->SetHole( closest_is_hole ); - // we have only one operation at the time, taking - // over the operation flags is enough, since the linking segments will - // be part of that output for any operation done. - link_A->TakeOverOperationFlags( link ); - link_B->TakeOverOperationFlags( link ); - link_BB->TakeOverOperationFlags( link ); - } - } + // we have only one operation at the time, taking + // over the operation flags is enough, since the linking segments will + // be part of that output for any operation done. + link_A->TakeOverOperationFlags( link ); + link_B->TakeOverOperationFlags( link ); + link_BB->TakeOverOperationFlags( link ); + } + } - if (link->IsTopHole() ) - { - SortTheBeam( atinsert ); - writebeam(); - } - - if (link->IsTopHole() && !_BI.athead() ) - { - // now we check if this hole should now be linked, or later - // we always link on the node with the maximum y value, Why ? because i like it ! - // to link we put the node of the hole into the crosslist of the closest link ! + if ( link->IsTopHole() ) + { + SortTheBeam( atinsert ); + writebeam(); + } - assert( record->Direction() == GO_LEFT ); - // he goes to the left - if (atinsert) - { - if ( link->GetBeginNode()->GetY() <= link->GetEndNode()->GetY() ) - { - topnode = link->GetEndNode(); + if ( link->IsTopHole() && !_BI.athead() ) + { + // now we check if this hole should now be linked, or later + // we always link on the node with the maximum y value, Why ? because i like it ! + // to link we put the node of the hole into the crosslist of the closest link ! + + assert( record->Direction() == GO_LEFT ); + // he goes to the left + if ( atinsert ) + { + if ( link->GetBeginNode()->GetY() <= link->GetEndNode()->GetY() ) + { + topnode = link->GetEndNode(); + //the previous link in the scanbeam == the closest link to the hole in vertical + //direction PUT this node into this link + _BI--; + _BI.item()->GetLine()->AddCrossing( topnode ); + _BI++; + //reset tophole flag, hole has been processed + link->SetTopHole( false ); + foundholes = true; + } + } + else //remove stage of links from te beam + { + //the tophole link was NOT linked at the insert stage, so it most be linked now + topnode = _BI.item()->GetLink()->GetBeginNode(); //the previous link in the scanbeam == the closest link to the hole in vertical //direction PUT this node into this link _BI--; - _BI.item()->GetLine()->AddCrossing(topnode); + _BI.item()->GetLine()->AddCrossing( topnode ); _BI++; - //reset tophole flag, hole has been processed - link->SetTopHole(false); + //reset mark to flag that this hole has been processed + link->SetTopHole( false ); foundholes = true; - } - } - else //remove stage of links from te beam - { - //the tophole link was NOT linked at the insert stage, so it most be linked now - topnode = _BI.item()->GetLink()->GetBeginNode(); - //the previous link in the scanbeam == the closest link to the hole in vertical - //direction PUT this node into this link - _BI--; - _BI.item()->GetLine()->AddCrossing(topnode); - _BI++; - //reset mark to flag that this hole has been processed - link->SetTopHole(false); - foundholes = true; - } - } - return foundholes; + } + } + return foundholes; } //sort the records on Ysp if eqaul, sort on tangent at ysp -int recordsorter_ysp_angle(Record* rec1, Record* rec2) +int recordsorter_ysp_angle( Record* rec1, Record* rec2 ) { - if (rec1->Ysp() > rec2->Ysp() ) - return(1); - if (rec1->Ysp() < rec2->Ysp() ) - return(-1); - //it seems they are equal - B_INT rightY1; - if (rec1->Direction()==GO_LEFT) - rightY1 = rec1->GetLink()->GetBeginNode()->GetY(); - else - rightY1 = rec1->GetLink()->GetEndNode()->GetY(); - B_INT rightY2; - if (rec2->Direction()==GO_LEFT) - rightY2 = rec2->GetLink()->GetBeginNode()->GetY(); - else - rightY2 = rec2->GetLink()->GetEndNode()->GetY(); + if ( rec1->Ysp() > rec2->Ysp() ) + return( 1 ); + if ( rec1->Ysp() < rec2->Ysp() ) + return( -1 ); + //it seems they are equal + B_INT rightY1; + if ( rec1->Direction() == GO_LEFT ) + rightY1 = rec1->GetLink()->GetBeginNode()->GetY(); + else + rightY1 = rec1->GetLink()->GetEndNode()->GetY(); + B_INT rightY2; + if ( rec2->Direction() == GO_LEFT ) + rightY2 = rec2->GetLink()->GetBeginNode()->GetY(); + else + rightY2 = rec2->GetLink()->GetEndNode()->GetY(); - if ( rightY1 > rightY2 ) - return(1); - if ( rightY1 < rightY2 ) - return(-1); - return(0); + if ( rightY1 > rightY2 ) + return( 1 ); + if ( rightY1 < rightY2 ) + return( -1 ); + return( 0 ); } //sort the records on Ysp if eqaul, sort on tangent at ysp -int recordsorter_ysp_angle_back(Record* rec1, Record* rec2) +int recordsorter_ysp_angle_back( Record* rec1, Record* rec2 ) { - if (rec1->Ysp() > rec2->Ysp() ) - return(1); - if (rec1->Ysp() < rec2->Ysp() ) - return(-1); - //it seems they are equal - B_INT leftY1; - if ( rec1->Direction() == GO_RIGHT ) - leftY1 = rec1->GetLink()->GetBeginNode()->GetY(); - else - leftY1 = rec1->GetLink()->GetEndNode()->GetY(); - B_INT leftY2; - if ( rec2->Direction() == GO_RIGHT ) - leftY2 = rec2->GetLink()->GetBeginNode()->GetY(); - else - leftY2 = rec2->GetLink()->GetEndNode()->GetY(); + if ( rec1->Ysp() > rec2->Ysp() ) + return( 1 ); + if ( rec1->Ysp() < rec2->Ysp() ) + return( -1 ); + //it seems they are equal + B_INT leftY1; + if ( rec1->Direction() == GO_RIGHT ) + leftY1 = rec1->GetLink()->GetBeginNode()->GetY(); + else + leftY1 = rec1->GetLink()->GetEndNode()->GetY(); + B_INT leftY2; + if ( rec2->Direction() == GO_RIGHT ) + leftY2 = rec2->GetLink()->GetBeginNode()->GetY(); + else + leftY2 = rec2->GetLink()->GetEndNode()->GetY(); - if ( leftY1 > leftY2 ) - return(1); - if ( leftY1 < leftY2 ) - return(-1); - return(0); + if ( leftY1 > leftY2 ) + return( 1 ); + if ( leftY1 < leftY2 ) + return( -1 ); + return( 0 ); } // swap functie for cocktailsort ==> each swap means an intersection of links -bool swap_crossing_normal(Record *a, Record *b) +bool swap_crossing_normal( Record *a, Record *b ) { - if (!a->Equal(b)) // records NOT parallel - { - a->GetLine()->Intersect_simple( b->GetLine() ); - return true; - } - return false; + if ( !a->Equal( b ) ) // records NOT parallel + { + a->GetLine()->Intersect_simple( b->GetLine() ); + return true; + } + return false; } int ScanBeam::Process_LinkToLink_Crossings() { - // sort on y value of next intersection; and find the intersections - return _BI.cocktailsort( recordsorter_ysp_angle_back, swap_crossing_normal ); + // sort on y value of next intersection; and find the intersections + return _BI.cocktailsort( recordsorter_ysp_angle_back, swap_crossing_normal ); } //catch node to link crossings // must be sorted on ysp int ScanBeam::Process_PointToLink_Crossings() { - int merges = 0; - Record* record; + int merges = 0; + Record* record; - if (_BI.count() > 1) - { - DL_Iter IL = DL_Iter(this); - IL.toiter(&_BI); + if ( _BI.count() > 1 ) + { + DL_Iter IL = DL_Iter( this ); + IL.toiter( &_BI ); - //from IL search back for close links - IL--; - while(!IL.hitroot()) - { - record=IL.item(); + //from IL search back for close links + IL--; + while( !IL.hitroot() ) + { + record = IL.item(); - if (record->Ysp() > _low->GetY()+ _GC->GetInternalMarge()) - break; + if ( record->Ysp() > _low->GetY() + _GC->GetInternalMarge() ) + break; - // the distance to the lo/hi node is smaller then the _GC->GetInternalMarge() - if( (record->GetLink()->GetBeginNode()!= _low) && - (record->GetLink()->GetEndNode() != _low) - ) - { // the link is not towards the lohi node - record->GetLine()->AddCrossing(_low); - merges++; - } - IL--; - } + // the distance to the lo/hi node is smaller then the _GC->GetInternalMarge() + if( ( record->GetLink()->GetBeginNode() != _low ) && + ( record->GetLink()->GetEndNode() != _low ) + ) + { // the link is not towards the lohi node + record->GetLine()->AddCrossing( _low ); + merges++; + } + IL--; + } - //from IL search forward for close links - IL.toiter(&_BI); - IL++; - while(!IL.hitroot()) - { - record=IL.item(); + //from IL search forward for close links + IL.toiter( &_BI ); + IL++; + while( !IL.hitroot() ) + { + record = IL.item(); - if (record->Ysp() < _low->GetY()- _GC->GetInternalMarge()) - break; + if ( record->Ysp() < _low->GetY() - _GC->GetInternalMarge() ) + break; - // the distance to the lohi node is smaller then the booleng->Get_Marge() - if( (record->GetLink()->GetBeginNode()!=_low) && - (record->GetLink()->GetEndNode() !=_low) - ) - { // the link is not towards the low node - record->GetLine()->AddCrossing(_low); - merges++; - } - IL++; - } + // the distance to the lohi node is smaller then the booleng->Get_Marge() + if( ( record->GetLink()->GetBeginNode() != _low ) && + ( record->GetLink()->GetEndNode() != _low ) + ) + { // the link is not towards the low node + record->GetLine()->AddCrossing( _low ); + merges++; + } + IL++; + } - } + } - return merges; + return merges; } -int ScanBeam::Process_LinkToLink_Flat(KBoolLine* flatline) +int ScanBeam::Process_LinkToLink_Flat( KBoolLine* flatline ) { - int crossfound = 0; - Record* record; - DL_Iter _BBI = DL_Iter(); - _BBI.Attach(this); - _BBI.toiter(&_BI); + int crossfound = 0; + Record* record; + DL_Iter _BBI = DL_Iter(); + _BBI.Attach( this ); + _BBI.toiter( &_BI ); - for(_BI.tohead(); !_BI.hitroot(); _BI++) - { - record=_BI.item(); + for( _BI.tohead(); !_BI.hitroot(); _BI++ ) + { + record = _BI.item(); - if (record->Ysp() < (flatline->GetLink()->GetLowNode()->GetY() - _GC->GetInternalMarge())) - break;//they are sorted so no other can be there + if ( record->Ysp() < ( flatline->GetLink()->GetLowNode()->GetY() - _GC->GetInternalMarge() ) ) + break;//they are sorted so no other can be there - if ((record->Ysp() > (flatline->GetLink()->GetLowNode()->GetY() - _GC->GetInternalMarge())) - && - (record->Ysp() < (flatline->GetLink()->GetHighNode()->GetY() + _GC->GetInternalMarge())) - ) - { //it is in between the flat link region - //create a new node at ysp and insert it in both the flatlink and the crossing link + if ( ( record->Ysp() > ( flatline->GetLink()->GetLowNode()->GetY() - _GC->GetInternalMarge() ) ) + && + ( record->Ysp() < ( flatline->GetLink()->GetHighNode()->GetY() + _GC->GetInternalMarge() ) ) + ) + { //it is in between the flat link region + //create a new node at ysp and insert it in both the flatlink and the crossing link - if ( - (record->GetLink()->GetEndNode() != flatline->GetLink()->GetHighNode()) && - (record->GetLink()->GetEndNode() != flatline->GetLink()->GetLowNode() ) && - (record->GetLink()->GetBeginNode()!= flatline->GetLink()->GetHighNode()) && - (record->GetLink()->GetBeginNode()!= flatline->GetLink()->GetLowNode() ) - ) - { - Node *newnode = new Node(_low->GetX(),_BI.item()->Ysp(), _GC); - flatline->AddCrossing(newnode); - record->GetLine()->AddCrossing(newnode); - crossfound++; - } - } - } + if ( + ( record->GetLink()->GetEndNode() != flatline->GetLink()->GetHighNode() ) && + ( record->GetLink()->GetEndNode() != flatline->GetLink()->GetLowNode() ) && + ( record->GetLink()->GetBeginNode() != flatline->GetLink()->GetHighNode() ) && + ( record->GetLink()->GetBeginNode() != flatline->GetLink()->GetLowNode() ) + ) + { + Node * newnode = new Node( _low->GetX(), _BI.item()->Ysp(), _GC ); + flatline->AddCrossing( newnode ); + record->GetLine()->AddCrossing( newnode ); + crossfound++; + } + } + } - _BI.toiter(&_BBI); - _BBI.Detach(); - return crossfound; + _BI.toiter( &_BBI ); + _BBI.Detach(); + return crossfound; } bool ScanBeam::checksort() { - // if empty then just insert - if (empty()) - return true; + // if empty then just insert + if ( empty() ) + return true; - // put new item left of the one that is bigger - _BI.tohead(); - Record* prev=_BI.item(); - _BI++; - while(!_BI.hitroot()) - { - Record* curr=_BI.item(); - if (recordsorter_ysp_angle(prev,curr)==-1) - { - recordsorter_ysp_angle(prev,curr); - return false; - } - prev=_BI.item(); - _BI++; - } - return true; + // put new item left of the one that is bigger + _BI.tohead(); + Record* prev = _BI.item(); + _BI++; + while( !_BI.hitroot() ) + { + Record * curr = _BI.item(); + if ( recordsorter_ysp_angle( prev, curr ) == -1 ) + { + recordsorter_ysp_angle( prev, curr ); + return false; + } + prev = _BI.item(); + _BI++; + } + return true; } bool ScanBeam::writebeam() { #if KBOOL_DEBUG == 1 - FILE* file = _GC->GetLogFile(); + FILE * file = _GC->GetLogFile(); - if (file == NULL) - return true; + if ( file == NULL ) + return true; - fprintf( file, "# beam %d \n", count() ); - fprintf( file, " low %I64d %I64d \n", _low->GetX() , _low->GetY() ); - fprintf( file, " type %d \n", _type ); + fprintf( file, "# beam %d \n", count() ); + fprintf( file, " low %I64d %I64d \n", _low->GetX() , _low->GetY() ); + fprintf( file, " type %d \n", _type ); - if (empty()) - { - fprintf( file, " empty \n" ); - return true; - } + if ( empty() ) + { + fprintf( file, " empty \n" ); + return true; + } - DL_Iter _BI( this ); + DL_Iter _BI( this ); - // put new item left of the one that is bigger - _BI.tohead(); - while(!_BI.hitroot()) - { - Record* cur=_BI.item(); + // put new item left of the one that is bigger + _BI.tohead(); + while( !_BI.hitroot() ) + { + Record * cur = _BI.item(); - fprintf( file, " ysp %I64d \n", cur->Ysp() ); + fprintf( file, " ysp %I64d \n", cur->Ysp() ); - KBoolLink* curl=cur->GetLink(); + KBoolLink* curl = cur->GetLink(); - fprintf( file, " linkbegin %I64d %I64d \n", curl->GetBeginNode()->GetX(), curl->GetBeginNode()->GetY() ); - fprintf( file, " linkend %I64d %I64d \n", curl->GetEndNode()->GetX(), curl->GetEndNode()->GetY() ); + fprintf( file, " linkbegin %I64d %I64d \n", curl->GetBeginNode()->GetX(), curl->GetBeginNode()->GetY() ); + fprintf( file, " linkend %I64d %I64d \n", curl->GetEndNode()->GetX(), curl->GetEndNode()->GetY() ); - _BI++; - } + if ( curl->GetEndNode()->GetX() == -2459565876494606883 ) + fprintf( file, " linkend %I64d %I64d \n", curl->GetEndNode()->GetX(), curl->GetEndNode()->GetY() ); + + _BI++; + } #endif - return true; + return true; }