Commit 7776dd61 authored by charras's avatar charras

use kbool 2.1 in zones calculations. see CHANGELOG for others changes and more info

parent 3803b79a
...@@ -4,6 +4,25 @@ KiCad ChangeLog 2009 ...@@ -4,6 +4,25 @@ KiCad ChangeLog 2009
Please add newer entries at the top, list the date and your name with Please add newer entries at the top, list the date and your name with
email address. email address.
2009-sept-17 UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
================================================================================
++pcbnew
Speed up ZONE_CONTAINER::Copy method
Speed up NETINFO_ITEM* BOARD::FindNet( const wxString& aNetname ) by using afast binary search
Switch to kbool V2.1. This version solves others problems in zones calculations.
Adding an other way to generate thermal shape; DO NOT USE: this is for kbool tests only
(I am thinking some bugs are remaining, so i am always working on kbool tests.
Klaas Olwerda is supporting me)
2009-sept-14 UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
================================================================================
++pcbnew
moved copper layers properties (layers couns anf layers names) from Design rules
to a specific dialog.
This must be seen as a TEMPORARY work, until a volunteer creates a better dialog box,
because there is currently no other way to change copper layers names.
2009-Sep-10 UPDATE Dick Hollenbeck <dick@softplc.com> 2009-Sep-10 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================ ================================================================================
++pcbnew ++pcbnew
...@@ -22,7 +41,7 @@ email address. ...@@ -22,7 +41,7 @@ email address.
++pcbnew ++pcbnew
Work on undo/redo in pcbnew finished. Work on undo/redo in pcbnew finished.
Switch to kbool V2.0. This version solves some problems in zones calculations but not all. Switch to kbool V2.0. This version solves some problems in zones calculations but not all.
The Kbool's author, Klaas Holveda, is still working on these problems The Kbool's author, Klaas Holweda, is still working on these problems
Thanks to Klaas Thanks to Klaas
......
...@@ -64,6 +64,7 @@ set(BITMAP_SRCS ...@@ -64,6 +64,7 @@ set(BITMAP_SRCS
config.xpm config.xpm
CopyBlock.xpm CopyBlock.xpm
copy.xpm copy.xpm
copper_layers_setup.cpp
Cursor_Shape.xpm Cursor_Shape.xpm
cursor.xpm cursor.xpm
cut.xpm cut.xpm
......
/* XPM */
const char * copper_layers_setup_xpm[] = {
"16 16 4 1",
" c None",
". c #B70000",
"s c #606020",
"# c #008F00",
".......... ",
".......... ",
".......... ",
"...ssssssssss ",
"...ssssssssss ",
"...ssssssssss ",
"...sss##########",
"...sss##########",
"...sss##########",
"...sss##########",
" sss##########",
" sss##########",
" sss##########",
" ##########",
" ##########",
" ##########"};
...@@ -72,9 +72,9 @@ void InitKiCadAbout( wxAboutDialogInfo& info ) ...@@ -72,9 +72,9 @@ void InitKiCadAbout( wxAboutDialogInfo& info )
/* Show Unicode or Ansi version */ /* Show Unicode or Ansi version */
#if wxUSE_UNICODE #if wxUSE_UNICODE
<< ( wxT( " Unicode\n" ) ); << ( wxT( " Unicode " ) );
# else # else
<< ( wxT( " Ansi\n" ) ); << ( wxT( " Ansi " ) );
#endif #endif
...@@ -107,7 +107,7 @@ void InitKiCadAbout( wxAboutDialogInfo& info ) ...@@ -107,7 +107,7 @@ void InitKiCadAbout( wxAboutDialogInfo& info )
#endif #endif
/* Websites */ /* Websites */
description << wxT( "\n\nKiCad on the web\n\n" ); description << wxT( "\n\nKiCad on the web\n\n" );
description << wxT( "http://iut-tice.ujf-grenoble.fr/kicad \n" ); description << wxT( "http://iut-tice.ujf-grenoble.fr/kicad \n" );
description << wxT( "http://kicad.sourceforge.net \n" ); description << wxT( "http://kicad.sourceforge.net \n" );
......
...@@ -340,11 +340,14 @@ void EDA_LibComponentStruct::Draw( WinEDA_DrawPanel* panel, wxDC* dc, ...@@ -340,11 +340,14 @@ void EDA_LibComponentStruct::Draw( WinEDA_DrawPanel* panel, wxDC* dc,
} }
} }
/* Enable this to draw the anchor of the component. */
#if 0
int len = panel->GetScreen()->Unscale( 3 ); int len = panel->GetScreen()->Unscale( 3 );
GRLine( &panel->m_ClipBox, dc, offset.x, offset.y - len, offset.x, GRLine( &panel->m_ClipBox, dc, offset.x, offset.y - len, offset.x,
offset.y + len, 0, color ); offset.y + len, 0, color );
GRLine( &panel->m_ClipBox, dc, offset.x - len, offset.y, offset.x + len, GRLine( &panel->m_ClipBox, dc, offset.x - len, offset.y, offset.x + len,
offset.y, 0, color ); offset.y, 0, color );
#endif
/* Enable this to draw the bounding box around the component to validate /* Enable this to draw the bounding box around the component to validate
* the bounding box calculations. */ * the bounding box calculations. */
......
...@@ -67,7 +67,10 @@ void DrawLibPartAux( WinEDA_DrawPanel* panel, wxDC* DC, ...@@ -67,7 +67,10 @@ void DrawLibPartAux( WinEDA_DrawPanel* panel, wxDC* DC,
Entry->Draw( panel, DC, Pos, Multi, convert, DrawMode, Color, TransMat, Entry->Draw( panel, DC, Pos, Multi, convert, DrawMode, Color, TransMat,
DrawPinText, false ); DrawPinText, false );
if( g_DebugLevel > 4 ) /* Draw the component boundary box */ /* Enable this to draw the bounding box around the component to validate
* the bounding box calculations. */
#if 0
/* Draw the component boundary box */
{ {
EDA_Rect BoundaryBox; EDA_Rect BoundaryBox;
if( Component ) if( Component )
...@@ -92,6 +95,7 @@ void DrawLibPartAux( WinEDA_DrawPanel* panel, wxDC* DC, ...@@ -92,6 +95,7 @@ void DrawLibPartAux( WinEDA_DrawPanel* panel, wxDC* DC,
y2 = BoundaryBox.GetBottom(); y2 = BoundaryBox.GetBottom();
GRRect( &panel->m_ClipBox, DC, x1, y1, x2, y2, BROWN ); GRRect( &panel->m_ClipBox, DC, x1, y1, x2, y2, BROWN );
} }
#endif
} }
......
...@@ -309,7 +309,7 @@ void WinEDA_LibeditFrame::UpdatePartSelectList() ...@@ -309,7 +309,7 @@ void WinEDA_LibeditFrame::UpdatePartSelectList()
return; return;
if( !m_SelpartBox->IsEmpty() ) if( m_SelpartBox->GetCount() != 0 )
m_SelpartBox->Clear(); m_SelpartBox->Clear();
if( CurrentLibEntry == NULL || CurrentLibEntry->m_UnitCount <= 1 ) if( CurrentLibEntry == NULL || CurrentLibEntry->m_UnitCount <= 1 )
......
...@@ -59,6 +59,7 @@ extern const char* cancel_xpm[]; ...@@ -59,6 +59,7 @@ extern const char* cancel_xpm[];
extern const char* component_select_alternate_shape_xpm[]; extern const char* component_select_alternate_shape_xpm[];
extern const char* component_select_unit_xpm[]; extern const char* component_select_unit_xpm[];
extern const char* config_xpm[]; extern const char* config_xpm[];
extern const char* copper_layers_setup_xpm[];
extern const char* copyblock_xpm[]; extern const char* copyblock_xpm[];
extern const char* copy_button[]; extern const char* copy_button[];
extern const char* cursor_shape_xpm[]; extern const char* cursor_shape_xpm[];
......
...@@ -469,7 +469,7 @@ enum main_id { ...@@ -469,7 +469,7 @@ enum main_id {
ID_PCB_MIRE_BUTT, ID_PCB_MIRE_BUTT,
ID_PCB_SHOW_1_RATSNEST_BUTT, ID_PCB_SHOW_1_RATSNEST_BUTT,
ID_PCB_PLACE_OFFSET_COORD_BUTT, ID_PCB_PLACE_OFFSET_COORD_BUTT,
ID_PCB_UNUSED_BUTT0, ID_PCB_COPPER_LAYERS_SETUP,
ID_PCB_UNUSED_BUTT1, ID_PCB_UNUSED_BUTT1,
ID_PCB_UNUSED_BUTT2, ID_PCB_UNUSED_BUTT2,
ID_PCB_UNUSED_BUTT3, ID_PCB_UNUSED_BUTT3,
......
...@@ -25,6 +25,8 @@ set(PCBNEW_SRCS ...@@ -25,6 +25,8 @@ set(PCBNEW_SRCS
cross-probing.cpp cross-probing.cpp
debug_kbool_key_file_fct.cpp debug_kbool_key_file_fct.cpp
deltrack.cpp deltrack.cpp
dialog_copper_layers_setup_base.cpp
dialog_copper_layers_setup.cpp
dialog_copper_zones.cpp dialog_copper_zones.cpp
dialog_copper_zones_base.cpp dialog_copper_zones_base.cpp
dialog_design_rules.cpp dialog_design_rules.cpp
......
...@@ -827,7 +827,7 @@ SEARCH_RESULT BOARD::Visit( INSPECTOR* inspector, const void* testData, ...@@ -827,7 +827,7 @@ SEARCH_RESULT BOARD::Visit( INSPECTOR* inspector, const void* testData,
* Function FindNet * Function FindNet
* searches for a net with the given netcode. * searches for a net with the given netcode.
* @param anetcode The netcode to search for. * @param anetcode The netcode to search for.
* @return EQUIPOT* - the net or NULL if not found. * @return NETINFO_ITEM* - the net or NULL if not found.
*/ */
NETINFO_ITEM* BOARD::FindNet( int anetcode ) const NETINFO_ITEM* BOARD::FindNet( int anetcode ) const
{ {
...@@ -851,21 +851,66 @@ NETINFO_ITEM* BOARD::FindNet( int anetcode ) const ...@@ -851,21 +851,66 @@ NETINFO_ITEM* BOARD::FindNet( int anetcode ) const
* Function FindNet overlayed * Function FindNet overlayed
* searches for a net with the given name. * searches for a net with the given name.
* @param aNetname A Netname to search for. * @param aNetname A Netname to search for.
* @return EQUIPOT* - the net or NULL if not found. * @return NETINFO_ITEM* - the net or NULL if not found.
*/ */
NETINFO_ITEM* BOARD::FindNet( const wxString& aNetname ) const NETINFO_ITEM* BOARD::FindNet( const wxString& aNetname ) const
{ {
// the first valid netcode is 1. // the first valid netcode is 1.
// zero is reserved for "no connection" and is not used. // zero is reserved for "no connection" and is not used.
if( !aNetname.IsEmpty() ) if( aNetname.IsEmpty() )
return NULL;
int ncount = m_NetInfo->GetCount();
// Search for a netname = aNetname
#if 0
// Use a sequencial search: easy to understand, but slow
printf("\nsearch %s, nets %d\n", CONV_TO_UTF8(aNetname), ncount);
for( int ii = 1; ii < ncount; ii++ )
{ {
for( unsigned ii = 1; ii < m_NetInfo->GetCount(); ii++ ) NETINFO_ITEM* item = m_NetInfo->GetNetItem( ii );
if( item && item->GetNetname() == aNetname )
{ {
NETINFO_ITEM* item = m_NetInfo->GetNetItem( ii ); printf(" found\n");
if( item && item->GetNetname() == aNetname ) return item;
return item;
} }
} }
#else
// Use a fast binary search,
// this is possible because Nets are alphabetically ordered in list
// see NETINFO_LIST::BuildListOfNets() and NETINFO_LIST::Build_Pads_Full_List()
int imax = ncount-1;
int index = imax;
while( ncount > 0 )
{
int ii = ncount;
ncount >>= 1;
if( (ii & 1) && ( ii > 1 ) )
ncount++;
NETINFO_ITEM* item = m_NetInfo->GetNetItem( index );
if( item == NULL )
return NULL;
int icmp = item->GetNetname().Cmp(aNetname);
if (icmp == 0 ) // found !
{
printf(" found\n");
return item;
}
if( icmp < 0 ) // must search after item
{
index += ncount;
continue;
}
if( icmp > 0 ) // must search before item
{
index -= ncount;
continue;
}
}
#endif
return NULL; return NULL;
} }
......
...@@ -197,9 +197,9 @@ void BOARD::SynchronizeNetsAndNetClasses() ...@@ -197,9 +197,9 @@ void BOARD::SynchronizeNetsAndNetClasses()
{ {
const wxString& netname = *member; const wxString& netname = *member;
// @todo: although this overall function seems to be adequately fast, if you // although this overall function seems to be adequately fast,
// wanted to make an improvement it would be in FindNet( wxString ) which I // FindNet( wxString ) uses now a fast binary search and is fast
// think is a sequential search. // event for large net lists
NETINFO_ITEM* net = FindNet( netname ); NETINFO_ITEM* net = FindNet( netname );
if( net && net->GetClassName() == NETCLASS::Default ) if( net && net->GetClassName() == NETCLASS::Default )
......
...@@ -59,6 +59,10 @@ void NETINFO_LIST::AppendNet( NETINFO_ITEM* aNewElement ) ...@@ -59,6 +59,10 @@ void NETINFO_LIST::AppendNet( NETINFO_ITEM* aNewElement )
/* sort function, to sort pad list by netnames /* sort function, to sort pad list by netnames
* this is a case sensitive sort.
* DO NOT change it because NETINFO_ITEM* BOARD::FindNet( const wxString& aNetname )
* when search a net by its net name does a binary search
* and expects to have a nets list sorted by an alphabetic case sensitive sort
*/ */
static bool PadlistSortByNetnames( const D_PAD* a, const D_PAD* b ) static bool PadlistSortByNetnames( const D_PAD* a, const D_PAD* b )
...@@ -74,10 +78,14 @@ void NETINFO_LIST::BuildListOfNets() ...@@ -74,10 +78,14 @@ void NETINFO_LIST::BuildListOfNets()
/** /**
* Compute and update the net_codes for PADS et and equipots (.m_NetCode member) * Compute and update the net_codes for PADS et and equipots (.m_NetCode member)
* net_codes are >= 1 (net_code = 0 means not connected) * net_codes are >= 1 (net_code = 0 means not connected)
* Update the equipotents buffer * Update the net buffer
* Must be called after editing pads (netname, or deleting) or after read a netlist * Must be called after editing pads (netname, or deleting) or after read a netlist
* set to 1 flag NET_CODE_OK of m_Pcb->m_Status_Pcb; * set to 1 flag NET_CODE_OK of m_Pcb->m_Status_Pcb;
* m_Pcb->m_NbNodes and m_Pcb->m_NbNets are updated * m_Pcb->m_NbNodes and m_Pcb->m_NbNets are updated
* Be aware NETINFO_ITEM* BOARD::FindNet( const wxString& aNetname )
* when search a net by its net name does a binary search
* and expects to have a nets list sorted by an alphabetic case sensitive sort
* So do not change Build_Pads_Full_List() taht build a sorted list of pads
*/ */
{ {
D_PAD* pad; D_PAD* pad;
...@@ -139,12 +147,16 @@ void NETINFO_LIST::Build_Pads_Full_List() ...@@ -139,12 +147,16 @@ void NETINFO_LIST::Build_Pads_Full_List()
/*****************************************/ /*****************************************/
/** Function Build_Pads_Full_List /** Function Build_Pads_Full_List
* Create the pad list, sorted by net names * Create the pad list, sorted by net names (sorted by an alphabetic case sensitive sort)
* initialise: * initialise:
* m_Pads (list of pads) * m_Pads (list of pads)
* set m_Status_Pcb = LISTE_PAD_OK; * set m_Status_Pcb = LISTE_PAD_OK;
* also clear m_Pcb->m_FullRatsnest that could have bad data * also clear m_Pcb->m_FullRatsnest that could have bad data
* (m_Pcb->m_FullRatsnest uses pointer to pads) * (m_Pcb->m_FullRatsnest uses pointer to pads)
* Be aware NETINFO_ITEM* BOARD::FindNet( const wxString& aNetname )
* when search a net by its net name does a binary search
* and expects to have a nets list sorted by an alphabetic case sensitive sort
* So do not change the sort function used here
*/ */
{ {
if( m_Parent->m_Status_Pcb & LISTE_PAD_OK ) if( m_Parent->m_Status_Pcb & LISTE_PAD_OK )
...@@ -167,6 +179,7 @@ void NETINFO_LIST::Build_Pads_Full_List() ...@@ -167,6 +179,7 @@ void NETINFO_LIST::Build_Pads_Full_List()
} }
// Sort pad list per net // Sort pad list per net
//
sort( m_PadsFullList.begin(), m_PadsFullList.end(), PadlistSortByNetnames ); sort( m_PadsFullList.begin(), m_PadsFullList.end(), PadlistSortByNetnames );
m_Parent->m_Status_Pcb = LISTE_PAD_OK; m_Parent->m_Status_Pcb = LISTE_PAD_OK;
......
...@@ -1142,7 +1142,8 @@ void ZONE_CONTAINER::Copy( ZONE_CONTAINER* src ) ...@@ -1142,7 +1142,8 @@ void ZONE_CONTAINER::Copy( ZONE_CONTAINER* src )
m_PadOption = src->m_PadOption; m_PadOption = src->m_PadOption;
m_ThermalReliefGapValue = src->m_ThermalReliefGapValue; m_ThermalReliefGapValue = src->m_ThermalReliefGapValue;
m_ThermalReliefCopperBridgeValue = src->m_ThermalReliefCopperBridgeValue; m_ThermalReliefCopperBridgeValue = src->m_ThermalReliefCopperBridgeValue;
m_Poly->SetHatch( src->m_Poly->GetHatchStyle() ); m_Poly->m_HatchStyle = src->m_Poly->GetHatchStyle();
m_Poly->m_HatchLines = src->m_Poly->m_HatchLines; // Copy vector <CSegment>
m_FilledPolysList.clear(); m_FilledPolysList.clear();
m_FilledPolysList = src->m_FilledPolysList; m_FilledPolysList = src->m_FilledPolysList;
m_FillSegmList.clear(); m_FillSegmList.clear();
......
...@@ -11,6 +11,9 @@ ...@@ -11,6 +11,9 @@
#ifdef CREATE_KBOOL_KEY_FILES #ifdef CREATE_KBOOL_KEY_FILES
// Allows or not) 0 degree orientation thermal shapes, for kbool tests
//#define CREATE_KBOOL_KEY_FILES_WITH_0_DEG
#define KEYFILE_FILENAME "dbgfile.key" #define KEYFILE_FILENAME "dbgfile.key"
/** function CreateKeyFile /** function CreateKeyFile
......
/////////////////////////////////////////////////////////////////////////////
// Name: dialog_design_rules.cpp
// Author: jean-pierre Charras
/////////////////////////////////////////////////////////////////////////////
/* functions relatives to the design rules editor
*/
#include "fctsys.h"
#include "common.h"
#include "class_drawpanel.h"
#include "confirm.h"
#include "pcbnew.h"
#include "wxPcbStruct.h"
#include "id.h"
#include "dialog_copper_layers_setup.h"
#include "wx/generic/gridctrl.h"
// Fields Positions on layer grid
#define LAYERS_GRID_ROUTABLE_POSITION 0
#define LAYERS_GRID_STATUS_POSITION 1
#define LAYERS_GRID_NAME_POSITION 2
/***********************************************************************************/
DIALOG_COPPER_LAYERS_SETUP::DIALOG_COPPER_LAYERS_SETUP( WinEDA_PcbFrame* parent ) :
DIALOG_COPPER_LAYERS_SETUP_BASE( parent )
/***********************************************************************************/
{
m_Parent = parent;
Init();
SetAutoLayout( true );
GetSizer()->Fit( this );
GetSizer()->SetSizeHints( this );
}
/********************************************************************/
void DIALOG_COPPER_LAYERS_SETUP::Init()
/********************************************************************/
{
SetFocus();
SetReturnCode( 0 );
// Initialize the layers grid:
m_ActivesLayersCount = g_DesignSettings.m_CopperLayerCount;
m_Pcb = m_Parent->GetBoard();
m_LayersCountSelection->SetSelection( m_ActivesLayersCount / 2 );
// Initialize the Routable column
SetRoutableLayerStatus();
// Initialize the Status column (layers attribute)
LAYER_T typelist[4] = { LT_SIGNAL, LT_POWER, LT_MIXED, LT_JUMPER };
for( int ii = 0; ii < 4; ii++ )
{
m_LayersType[ii] = typelist[ii];
m_LayersTypeName[ii] = CONV_FROM_UTF8( LAYER::ShowType( typelist[ii] ) );
}
for( int ii = 0; ii < m_gridLayersProperties->GetNumberRows(); ii++ )
{
m_gridLayersProperties->SetCellEditor( ii, LAYERS_GRID_STATUS_POSITION,
new wxGridCellChoiceEditor( WXSIZEOF(
m_LayersTypeName ),
m_LayersTypeName ) );
int select = LT_SIGNAL;
for( int jj = 0; jj < 4; jj++ )
{
int layer = LAYER_CMP_N - ii;
if( m_Pcb->GetLayerType( layer ) == m_LayersType[jj] )
{
select = m_LayersType[jj];
break;
}
}
m_gridLayersProperties->SetCellValue( ii, LAYERS_GRID_STATUS_POSITION,
m_LayersTypeName[select] );
m_gridLayersProperties->SetCellOverflow( ii, LAYERS_GRID_STATUS_POSITION, false );
}
// Initialize the Name column
for( int ii = 0; ii < m_gridLayersProperties->GetNumberRows(); ii++ )
{
wxString layer_name = m_Pcb->GetLayerName( LAYER_CMP_N - ii );
m_gridLayersProperties->SetCellValue( ii, LAYERS_GRID_NAME_POSITION, layer_name );
}
}
/* Initialize the Routable column, and the R/W property of some cells
*/
void DIALOG_COPPER_LAYERS_SETUP::SetRoutableLayerStatus()
{
m_gridLayersProperties->SetColFormatBool( LAYERS_GRID_ROUTABLE_POSITION );
for( int ii = 0; ii < m_gridLayersProperties->GetNumberRows(); ii++ )
{
int layer = LAYER_CMP_N - ii;
wxString value = layer < (m_ActivesLayersCount - 1) ? wxT( "1" ) : wxT( "0" );
if( m_ActivesLayersCount > 1 && layer == LAYER_CMP_N )
value = wxT( "1" );
if( layer == COPPER_LAYER_N )
value = wxT( "1" );
m_gridLayersProperties->SetCellValue( ii, LAYERS_GRID_ROUTABLE_POSITION, value );
m_gridLayersProperties->SetReadOnly( ii, LAYERS_GRID_ROUTABLE_POSITION );
// Set to Read Only cell for non existing copper layers:
m_gridLayersProperties->SetReadOnly( ii, LAYERS_GRID_STATUS_POSITION, value != wxT( "1" ) );
m_gridLayersProperties->SetReadOnly( ii, LAYERS_GRID_NAME_POSITION, value != wxT( "1" ) );
}
}
/*****************************************************************/
void DIALOG_COPPER_LAYERS_SETUP::OnCancelButtonClick( wxCommandEvent& event )
/*****************************************************************/
{
EndModal( 0 );
}
/**************************************************************************/
void DIALOG_COPPER_LAYERS_SETUP::OnOkButtonClick( wxCommandEvent& event )
/**************************************************************************/
{
if( !TestDataValidity() )
{
DisplayError( this, _( "Errors detected, Abort" ) );
return;
}
g_DesignSettings.m_CopperLayerCount = m_ActivesLayersCount;
// Initialize the new layer name
for( int ii = 0; ii < m_gridLayersProperties->GetNumberRows(); ii++ )
{
wxString layer_name = m_gridLayersProperties->GetCellValue( ii, LAYERS_GRID_NAME_POSITION );
if( layer_name != m_Pcb->GetLayerName( LAYER_CMP_N - ii ) )
{
m_Pcb->SetLayerName( LAYER_CMP_N - ii, layer_name );
}
}
// Initialize the layer type
for( int ii = 0; ii < m_gridLayersProperties->GetNumberRows(); ii++ )
{
wxString txt = m_gridLayersProperties->GetCellValue( ii, LAYERS_GRID_STATUS_POSITION );
int layer = LAYER_CMP_N - ii;
for( int jj = 0; jj < 3; jj++ )
{
if( m_LayersTypeName[jj] == txt )
{
m_Pcb->SetLayerType( layer, m_LayersType[jj] );
break;
}
}
}
m_Parent->ReCreateLayerBox( NULL );
EndModal( wxID_OK );
}
/**************************************************************************/
void DIALOG_COPPER_LAYERS_SETUP::OnLayerCountClick( wxCommandEvent& event )
/**************************************************************************/
{
m_ActivesLayersCount = m_LayersCountSelection->GetSelection() * 2;
if( m_ActivesLayersCount <= 0 )
m_ActivesLayersCount = 1;
// Reinit the routable layers status
SetRoutableLayerStatus();
}
/* TestDataValidity
* Performs a control of data validity
* set the background of a bad cell in RED and display an info message
* @return true if Ok, false if error
*/
bool DIALOG_COPPER_LAYERS_SETUP::TestDataValidity()
{
bool success = true;
m_MessagesList->SetPage(wxEmptyString); // Clear message list
// Test duplicate layers names
for( int ii = 0; ii < m_gridLayersProperties->GetNumberRows() - 1; ii++ )
{
wxString value = m_gridLayersProperties->GetCellValue( ii, LAYERS_GRID_NAME_POSITION );
for( int jj = ii+1; jj < m_gridLayersProperties->GetNumberRows(); jj++ )
{
wxString othervalue = m_gridLayersProperties->GetCellValue( ii,
LAYERS_GRID_NAME_POSITION );
othervalue = m_gridLayersProperties->GetCellValue( jj, LAYERS_GRID_NAME_POSITION );
if( value.CmpNoCase( othervalue ) == 0 ) // Already exists!
{
wxString text;
text.Printf( _(
"<small>This layer name <b>%s</b> is already existing<br>" ),
value.GetData() );
m_MessagesList->AppendToPage( text );
success = false;
}
}
}
return success;
}
///////////////////////////////////////////////////////////////////////////////
/// Class DIALOG_COPPER_LAYERS_SETUP
///////////////////////////////////////////////////////////////////////////////
#ifndef __dialog_design_rules_h_
#define __dialog_design_rules_h_
#include "dialog_copper_layers_setup_base.h"
class DIALOG_COPPER_LAYERS_SETUP : public DIALOG_COPPER_LAYERS_SETUP_BASE
{
private:
WinEDA_PcbFrame * m_Parent;
int m_ActivesLayersCount;
BOARD * m_Pcb;
LAYER_T m_LayersType[4];
wxString m_LayersTypeName[4];
private:
void OnCancelButtonClick( wxCommandEvent& event );
void OnOkButtonClick( wxCommandEvent& event );
void OnLayerCountClick( wxCommandEvent& event );
void OnLayerGridLeftClick( wxGridEvent& event ){ event.Skip(); }
void OnLayerGridRighttClick( wxGridEvent& event ){ event.Skip(); }
void Init();
void SetRoutableLayerStatus( );
bool TestDataValidity();
public:
DIALOG_COPPER_LAYERS_SETUP( WinEDA_PcbFrame* parent );
~DIALOG_COPPER_LAYERS_SETUP( ) { };
};
#endif //__dialog_design_rules_h_
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Apr 16 2008)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#include "dialog_copper_layers_setup_base.h"
///////////////////////////////////////////////////////////////////////////
DIALOG_COPPER_LAYERS_SETUP_BASE::DIALOG_COPPER_LAYERS_SETUP_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style )
{
this->SetSizeHints( wxSize( -1,-1 ), wxDefaultSize );
wxBoxSizer* bMainSizer;
bMainSizer = new wxBoxSizer( wxVERTICAL );
wxBoxSizer* bMainSizerLayers;
bMainSizerLayers = new wxBoxSizer( wxHORIZONTAL );
wxString m_LayersCountSelectionChoices[] = { _("1"), _("2"), _("4"), _("6"), _("8"), _("10"), _("12"), _("14"), _("16") };
int m_LayersCountSelectionNChoices = sizeof( m_LayersCountSelectionChoices ) / sizeof( wxString );
m_LayersCountSelection = new wxRadioBox( this, ID_LAYERS_COUNT_SELECTION, _("Layers Count"), wxDefaultPosition, wxDefaultSize, m_LayersCountSelectionNChoices, m_LayersCountSelectionChoices, 1, wxRA_SPECIFY_COLS );
m_LayersCountSelection->SetSelection( 1 );
bMainSizerLayers->Add( m_LayersCountSelection, 0, wxALL, 5 );
m_gridLayersProperties = new wxGrid( this, ID_LAYERS_PROPERTIES, wxDefaultPosition, wxDefaultSize, 0 );
// Grid
m_gridLayersProperties->CreateGrid( 16, 3 );
m_gridLayersProperties->EnableEditing( true );
m_gridLayersProperties->EnableGridLines( true );
m_gridLayersProperties->EnableDragGridSize( false );
m_gridLayersProperties->SetMargins( 0, 0 );
// Columns
m_gridLayersProperties->SetColSize( 0, 100 );
m_gridLayersProperties->SetColSize( 1, 100 );
m_gridLayersProperties->SetColSize( 2, 150 );
m_gridLayersProperties->EnableDragColMove( false );
m_gridLayersProperties->EnableDragColSize( true );
m_gridLayersProperties->SetColLabelSize( 30 );
m_gridLayersProperties->SetColLabelValue( 0, _("Active") );
m_gridLayersProperties->SetColLabelValue( 1, _("Status") );
m_gridLayersProperties->SetColLabelValue( 2, _("Name") );
m_gridLayersProperties->SetColLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
// Rows
m_gridLayersProperties->AutoSizeRows();
m_gridLayersProperties->EnableDragRowSize( true );
m_gridLayersProperties->SetRowLabelSize( 80 );
m_gridLayersProperties->SetRowLabelValue( 0, _("Top Layer") );
m_gridLayersProperties->SetRowLabelValue( 1, _("Inner 14") );
m_gridLayersProperties->SetRowLabelValue( 2, _("Inner 13") );
m_gridLayersProperties->SetRowLabelValue( 3, _("Inner 12") );
m_gridLayersProperties->SetRowLabelValue( 4, _("Inner 11") );
m_gridLayersProperties->SetRowLabelValue( 5, _("Inner 10") );
m_gridLayersProperties->SetRowLabelValue( 6, _("Inner 9") );
m_gridLayersProperties->SetRowLabelValue( 7, _("Inner 8") );
m_gridLayersProperties->SetRowLabelValue( 8, _("Inner 7") );
m_gridLayersProperties->SetRowLabelValue( 9, _("Inner 6") );
m_gridLayersProperties->SetRowLabelValue( 10, _("Inner 5") );
m_gridLayersProperties->SetRowLabelValue( 11, _("Inner 4") );
m_gridLayersProperties->SetRowLabelValue( 12, _("Inner 3") );
m_gridLayersProperties->SetRowLabelValue( 13, _("Inner 2") );
m_gridLayersProperties->SetRowLabelValue( 14, _("Inner 1") );
m_gridLayersProperties->SetRowLabelValue( 15, _("Bottom Layer") );
m_gridLayersProperties->SetRowLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
// Label Appearance
// Cell Defaults
m_gridLayersProperties->SetDefaultCellAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
bMainSizerLayers->Add( m_gridLayersProperties, 1, wxALL|wxEXPAND, 5 );
bMainSizer->Add( bMainSizerLayers, 1, wxEXPAND, 5 );
wxStaticBoxSizer* sbSizer1;
sbSizer1 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Messages:") ), wxVERTICAL );
m_MessagesList = new wxHtmlWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO );
sbSizer1->Add( m_MessagesList, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
bMainSizer->Add( sbSizer1, 1, wxEXPAND, 5 );
m_sdbSizer1 = new wxStdDialogButtonSizer();
m_sdbSizer1OK = new wxButton( this, wxID_OK );
m_sdbSizer1->AddButton( m_sdbSizer1OK );
m_sdbSizer1Cancel = new wxButton( this, wxID_CANCEL );
m_sdbSizer1->AddButton( m_sdbSizer1Cancel );
m_sdbSizer1->Realize();
bMainSizer->Add( m_sdbSizer1, 0, wxALIGN_RIGHT, 5 );
this->SetSizer( bMainSizer );
this->Layout();
// Connect Events
m_LayersCountSelection->Connect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_COPPER_LAYERS_SETUP_BASE::OnLayerCountClick ), NULL, this );
m_gridLayersProperties->Connect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_COPPER_LAYERS_SETUP_BASE::OnLayerGridLeftClick ), NULL, this );
m_gridLayersProperties->Connect( wxEVT_GRID_CELL_RIGHT_CLICK, wxGridEventHandler( DIALOG_COPPER_LAYERS_SETUP_BASE::OnLayerGridRighttClick ), NULL, this );
m_sdbSizer1Cancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_COPPER_LAYERS_SETUP_BASE::OnCancelButtonClick ), NULL, this );
m_sdbSizer1OK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_COPPER_LAYERS_SETUP_BASE::OnOkButtonClick ), NULL, this );
}
DIALOG_COPPER_LAYERS_SETUP_BASE::~DIALOG_COPPER_LAYERS_SETUP_BASE()
{
// Disconnect Events
m_LayersCountSelection->Disconnect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_COPPER_LAYERS_SETUP_BASE::OnLayerCountClick ), NULL, this );
m_gridLayersProperties->Disconnect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_COPPER_LAYERS_SETUP_BASE::OnLayerGridLeftClick ), NULL, this );
m_gridLayersProperties->Disconnect( wxEVT_GRID_CELL_RIGHT_CLICK, wxGridEventHandler( DIALOG_COPPER_LAYERS_SETUP_BASE::OnLayerGridRighttClick ), NULL, this );
m_sdbSizer1Cancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_COPPER_LAYERS_SETUP_BASE::OnCancelButtonClick ), NULL, this );
m_sdbSizer1OK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_COPPER_LAYERS_SETUP_BASE::OnOkButtonClick ), NULL, this );
}
This diff is collapsed.
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Apr 16 2008)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#ifndef __dialog_copper_layers_setup_base__
#define __dialog_copper_layers_setup_base__
#include <wx/intl.h>
#include <wx/string.h>
#include <wx/radiobox.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/grid.h>
#include <wx/sizer.h>
#include <wx/html/htmlwin.h>
#include <wx/statbox.h>
#include <wx/button.h>
#include <wx/dialog.h>
///////////////////////////////////////////////////////////////////////////
#define ID_LAYERS_COUNT_SELECTION 1000
#define ID_LAYERS_PROPERTIES 1001
///////////////////////////////////////////////////////////////////////////////
/// Class DIALOG_COPPER_LAYERS_SETUP_BASE
///////////////////////////////////////////////////////////////////////////////
class DIALOG_COPPER_LAYERS_SETUP_BASE : public wxDialog
{
private:
protected:
wxRadioBox* m_LayersCountSelection;
wxGrid* m_gridLayersProperties;
wxHtmlWindow* m_MessagesList;
wxStdDialogButtonSizer* m_sdbSizer1;
wxButton* m_sdbSizer1OK;
wxButton* m_sdbSizer1Cancel;
// Virtual event handlers, overide them in your derived class
virtual void OnLayerCountClick( wxCommandEvent& event ){ event.Skip(); }
virtual void OnLayerGridLeftClick( wxGridEvent& event ){ event.Skip(); }
virtual void OnLayerGridRighttClick( wxGridEvent& event ){ event.Skip(); }
virtual void OnCancelButtonClick( wxCommandEvent& event ){ event.Skip(); }
virtual void OnOkButtonClick( wxCommandEvent& event ){ event.Skip(); }
public:
DIALOG_COPPER_LAYERS_SETUP_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Copper layers setup"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 558,479 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~DIALOG_COPPER_LAYERS_SETUP_BASE();
};
#endif //__dialog_copper_layers_setup_base__
...@@ -290,6 +290,9 @@ static void class2gridRow( wxGrid* grid, int row, NETCLASS* nc, int units ) ...@@ -290,6 +290,9 @@ static void class2gridRow( wxGrid* grid, int row, NETCLASS* nc, int units )
grid->SetCellValue( row, GRID_uVIADRILL, msg ); grid->SetCellValue( row, GRID_uVIADRILL, msg );
} }
/** Function InitRulesList()
* Fill the grid showing current rules with values
*/
void DIALOG_DESIGN_RULES::InitRulesList() void DIALOG_DESIGN_RULES::InitRulesList()
{ {
NETCLASSES& netclasses = m_Pcb->m_NetClasses; NETCLASSES& netclasses = m_Pcb->m_NetClasses;
...@@ -300,8 +303,10 @@ void DIALOG_DESIGN_RULES::InitRulesList() ...@@ -300,8 +303,10 @@ void DIALOG_DESIGN_RULES::InitRulesList()
m_grid->AppendRows( netclasses.GetCount()+1 - m_grid->GetNumberRows() ); m_grid->AppendRows( netclasses.GetCount()+1 - m_grid->GetNumberRows() );
} }
// enter the Default NETCLASS.
class2gridRow( m_grid, 0, netclasses.GetDefault(), m_Parent->m_InternalUnits ); class2gridRow( m_grid, 0, netclasses.GetDefault(), m_Parent->m_InternalUnits );
// enter others netclasses
int row = 1; int row = 1;
for( NETCLASSES::iterator i=netclasses.begin(); i!=netclasses.end(); ++i, ++row ) for( NETCLASSES::iterator i=netclasses.begin(); i!=netclasses.end(); ++i, ++row )
{ {
...@@ -326,7 +331,7 @@ static void gridRow2class( wxGrid* grid, int row, NETCLASS* nc, int units ) ...@@ -326,7 +331,7 @@ static void gridRow2class( wxGrid* grid, int row, NETCLASS* nc, int units )
} }
/* Copy the rules list to board /* Copy the rules list from grid to board
*/ */
void DIALOG_DESIGN_RULES::CopyRulesListToBoard() void DIALOG_DESIGN_RULES::CopyRulesListToBoard()
{ {
...@@ -452,6 +457,44 @@ void DIALOG_DESIGN_RULES::OnRemoveNetclassClick( wxCommandEvent& event ) ...@@ -452,6 +457,44 @@ void DIALOG_DESIGN_RULES::OnRemoveNetclassClick( wxCommandEvent& event )
InitializeRulesSelectionBoxes(); InitializeRulesSelectionBoxes();
} }
/*
* Called on "Move Up" button click
* the selected(s) rules are moved up
* The default netclass is always the first rule
*/
void DIALOG_DESIGN_RULES::OnMoveUpSelectedNetClass( wxCommandEvent& event )
{
// Cannot move up rules if we have 1 or 2 rules only
if( m_grid->GetNumberRows() < 3 )
return;
wxArrayInt select = m_grid->GetSelectedRows();
bool reinit = false;
for( unsigned irow = 0; irow < select.GetCount(); irow++ )
{
int ii = select[irow];
if( ii < 2 ) // The default netclass *must* be the first netclass
continue; // so we cannot move up line 0 and 1
// Swap the rule and the previous rule
wxString curr_value, previous_value;
for( int icol = 0; icol < m_grid->GetNumberCols(); icol++ )
{
reinit = true;
curr_value = m_grid->GetCellValue( ii, icol );
previous_value = m_grid->GetCellValue( ii-1, icol );
m_grid->SetCellValue( ii, icol, previous_value );
m_grid->SetCellValue( ii-1, icol, curr_value );
}
curr_value = m_grid->GetRowLabelValue( ii );
previous_value = m_grid->GetRowLabelValue( ii-1 );
m_grid->SetRowLabelValue(ii, previous_value );
m_grid->SetRowLabelValue(ii-1, curr_value );
}
if( reinit )
InitializeRulesSelectionBoxes();
}
/* /*
* Called on the left Choice Box selection * Called on the left Choice Box selection
......
...@@ -42,15 +42,16 @@ private: ...@@ -42,15 +42,16 @@ private:
NETCUPS m_AllNets; NETCUPS m_AllNets;
private: private:
void OnLayerCountClick( wxCommandEvent& event ); // void OnLayerCountClick( wxCommandEvent& event );
void OnLayerGridLeftClick( wxGridEvent& event ){ event.Skip(); } // void OnLayerGridLeftClick( wxGridEvent& event ){ event.Skip(); }
void OnLayerGridRighttClick( wxGridEvent& event ){ event.Skip(); } // void OnLayerGridRighttClick( wxGridEvent& event ){ event.Skip(); }
void OnNetClassesGridLeftClick( wxGridEvent& event ){ event.Skip(); } void OnNetClassesGridLeftClick( wxGridEvent& event ){ event.Skip(); }
void OnNetClassesGridRightClick( wxGridEvent& event ){ event.Skip(); } void OnNetClassesGridRightClick( wxGridEvent& event ){ event.Skip(); }
void OnCancelButtonClick( wxCommandEvent& event ); void OnCancelButtonClick( wxCommandEvent& event );
void OnOkButtonClick( wxCommandEvent& event ); void OnOkButtonClick( wxCommandEvent& event );
void OnAddNetclassClick( wxCommandEvent& event ); void OnAddNetclassClick( wxCommandEvent& event );
void OnRemoveNetclassClick( wxCommandEvent& event ); void OnRemoveNetclassClick( wxCommandEvent& event );
void OnMoveUpSelectedNetClass( wxCommandEvent& event );
void OnLeftCBSelection( wxCommandEvent& event ); void OnLeftCBSelection( wxCommandEvent& event );
void OnRightCBSelection( wxCommandEvent& event ); void OnRightCBSelection( wxCommandEvent& event );
void OnRightToLeftCopyButton( wxCommandEvent& event ); void OnRightToLeftCopyButton( wxCommandEvent& event );
......
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Sep 9 2009) // C++ code generated with wxFormBuilder (version Apr 16 2008)
// http://www.wxformbuilder.org/ // http://www.wxformbuilder.org/
// //
// PLEASE DO "NOT" EDIT THIS FILE! // PLEASE DO "NOT" EDIT THIS FILE!
...@@ -79,7 +79,7 @@ DIALOG_DESIGN_RULES_BASE::DIALOG_DESIGN_RULES_BASE( wxWindow* parent, wxWindowID ...@@ -79,7 +79,7 @@ DIALOG_DESIGN_RULES_BASE::DIALOG_DESIGN_RULES_BASE( wxWindow* parent, wxWindowID
buttonBoxSizer->Add( m_moveUpButton, 0, wxALL, 5 ); buttonBoxSizer->Add( m_moveUpButton, 0, wxALL, 5 );
sbSizer1->Add( buttonBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL|wxBOTTOM, 5 ); sbSizer1->Add( buttonBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL, 5 );
bMainSizer->Add( sbSizer1, 1, wxALL|wxEXPAND, 5 ); bMainSizer->Add( sbSizer1, 1, wxALL|wxEXPAND, 5 );
...@@ -138,7 +138,7 @@ DIALOG_DESIGN_RULES_BASE::DIALOG_DESIGN_RULES_BASE( wxWindow* parent, wxWindowID ...@@ -138,7 +138,7 @@ DIALOG_DESIGN_RULES_BASE::DIALOG_DESIGN_RULES_BASE( wxWindow* parent, wxWindowID
sbSizer4->Add( rghtNetSelectBoxSizer, 0, wxALL|wxEXPAND, 5 ); sbSizer4->Add( rghtNetSelectBoxSizer, 0, wxALL|wxEXPAND, 5 );
bMainSizer->Add( sbSizer4, 2, wxALL|wxEXPAND, 5 ); bMainSizer->Add( sbSizer4, 2, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
wxStaticBoxSizer* sbSizer2; wxStaticBoxSizer* sbSizer2;
sbSizer2 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Messages:") ), wxHORIZONTAL ); sbSizer2 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Messages:") ), wxHORIZONTAL );
...@@ -146,7 +146,7 @@ DIALOG_DESIGN_RULES_BASE::DIALOG_DESIGN_RULES_BASE( wxWindow* parent, wxWindowID ...@@ -146,7 +146,7 @@ DIALOG_DESIGN_RULES_BASE::DIALOG_DESIGN_RULES_BASE( wxWindow* parent, wxWindowID
m_MessagesList = new wxHtmlWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO|wxSUNKEN_BORDER ); m_MessagesList = new wxHtmlWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO|wxSUNKEN_BORDER );
m_MessagesList->SetMinSize( wxSize( -1,100 ) ); m_MessagesList->SetMinSize( wxSize( -1,100 ) );
sbSizer2->Add( m_MessagesList, 1, wxALL|wxEXPAND, 5 ); sbSizer2->Add( m_MessagesList, 1, wxEXPAND|wxRIGHT|wxLEFT, 5 );
bMainSizer->Add( sbSizer2, 0, wxALL|wxEXPAND, 5 ); bMainSizer->Add( sbSizer2, 0, wxALL|wxEXPAND, 5 );
...@@ -166,6 +166,7 @@ DIALOG_DESIGN_RULES_BASE::DIALOG_DESIGN_RULES_BASE( wxWindow* parent, wxWindowID ...@@ -166,6 +166,7 @@ DIALOG_DESIGN_RULES_BASE::DIALOG_DESIGN_RULES_BASE( wxWindow* parent, wxWindowID
m_grid->Connect( wxEVT_GRID_CELL_RIGHT_CLICK, wxGridEventHandler( DIALOG_DESIGN_RULES_BASE::OnNetClassesGridRightClick ), NULL, this ); m_grid->Connect( wxEVT_GRID_CELL_RIGHT_CLICK, wxGridEventHandler( DIALOG_DESIGN_RULES_BASE::OnNetClassesGridRightClick ), NULL, this );
m_addButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnAddNetclassClick ), NULL, this ); m_addButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnAddNetclassClick ), NULL, this );
m_removeButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnRemoveNetclassClick ), NULL, this ); m_removeButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnRemoveNetclassClick ), NULL, this );
m_moveUpButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnMoveUpSelectedNetClass ), NULL, this );
m_leftClassChoice->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnLeftCBSelection ), NULL, this ); m_leftClassChoice->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnLeftCBSelection ), NULL, this );
m_buttonRightToLeft->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnRightToLeftCopyButton ), NULL, this ); m_buttonRightToLeft->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnRightToLeftCopyButton ), NULL, this );
m_buttonLeftToRight->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnLeftToRightCopyButton ), NULL, this ); m_buttonLeftToRight->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnLeftToRightCopyButton ), NULL, this );
...@@ -183,6 +184,7 @@ DIALOG_DESIGN_RULES_BASE::~DIALOG_DESIGN_RULES_BASE() ...@@ -183,6 +184,7 @@ DIALOG_DESIGN_RULES_BASE::~DIALOG_DESIGN_RULES_BASE()
m_grid->Disconnect( wxEVT_GRID_CELL_RIGHT_CLICK, wxGridEventHandler( DIALOG_DESIGN_RULES_BASE::OnNetClassesGridRightClick ), NULL, this ); m_grid->Disconnect( wxEVT_GRID_CELL_RIGHT_CLICK, wxGridEventHandler( DIALOG_DESIGN_RULES_BASE::OnNetClassesGridRightClick ), NULL, this );
m_addButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnAddNetclassClick ), NULL, this ); m_addButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnAddNetclassClick ), NULL, this );
m_removeButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnRemoveNetclassClick ), NULL, this ); m_removeButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnRemoveNetclassClick ), NULL, this );
m_moveUpButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnMoveUpSelectedNetClass ), NULL, this );
m_leftClassChoice->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnLeftCBSelection ), NULL, this ); m_leftClassChoice->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnLeftCBSelection ), NULL, this );
m_buttonRightToLeft->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnRightToLeftCopyButton ), NULL, this ); m_buttonRightToLeft->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnRightToLeftCopyButton ), NULL, this );
m_buttonLeftToRight->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnLeftToRightCopyButton ), NULL, this ); m_buttonLeftToRight->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnLeftToRightCopyButton ), NULL, this );
...@@ -191,5 +193,4 @@ DIALOG_DESIGN_RULES_BASE::~DIALOG_DESIGN_RULES_BASE() ...@@ -191,5 +193,4 @@ DIALOG_DESIGN_RULES_BASE::~DIALOG_DESIGN_RULES_BASE()
m_rightClassChoice->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnRightCBSelection ), NULL, this ); m_rightClassChoice->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnRightCBSelection ), NULL, this );
m_sdbSizer1Cancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnCancelButtonClick ), NULL, this ); m_sdbSizer1Cancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnCancelButtonClick ), NULL, this );
m_sdbSizer1OK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnOkButtonClick ), NULL, this ); m_sdbSizer1OK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnOkButtonClick ), NULL, this );
} }
This diff is collapsed.
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Sep 9 2009) // C++ code generated with wxFormBuilder (version Apr 16 2008)
// http://www.wxformbuilder.org/ // http://www.wxformbuilder.org/
// //
// PLEASE DO "NOT" EDIT THIS FILE! // PLEASE DO "NOT" EDIT THIS FILE!
...@@ -59,23 +59,23 @@ class DIALOG_DESIGN_RULES_BASE : public wxDialog ...@@ -59,23 +59,23 @@ class DIALOG_DESIGN_RULES_BASE : public wxDialog
wxButton* m_sdbSizer1Cancel; wxButton* m_sdbSizer1Cancel;
// Virtual event handlers, overide them in your derived class // Virtual event handlers, overide them in your derived class
virtual void OnNetClassesGridLeftClick( wxGridEvent& event ) { event.Skip(); } virtual void OnNetClassesGridLeftClick( wxGridEvent& event ){ event.Skip(); }
virtual void OnNetClassesGridRightClick( wxGridEvent& event ) { event.Skip(); } virtual void OnNetClassesGridRightClick( wxGridEvent& event ){ event.Skip(); }
virtual void OnAddNetclassClick( wxCommandEvent& event ) { event.Skip(); } virtual void OnAddNetclassClick( wxCommandEvent& event ){ event.Skip(); }
virtual void OnRemoveNetclassClick( wxCommandEvent& event ) { event.Skip(); } virtual void OnRemoveNetclassClick( wxCommandEvent& event ){ event.Skip(); }
virtual void OnLeftCBSelection( wxCommandEvent& event ) { event.Skip(); } virtual void OnMoveUpSelectedNetClass( wxCommandEvent& event ){ event.Skip(); }
virtual void OnRightToLeftCopyButton( wxCommandEvent& event ) { event.Skip(); } virtual void OnLeftCBSelection( wxCommandEvent& event ){ event.Skip(); }
virtual void OnLeftToRightCopyButton( wxCommandEvent& event ) { event.Skip(); } virtual void OnRightToLeftCopyButton( wxCommandEvent& event ){ event.Skip(); }
virtual void OnLeftSelectAllButton( wxCommandEvent& event ) { event.Skip(); } virtual void OnLeftToRightCopyButton( wxCommandEvent& event ){ event.Skip(); }
virtual void OnRightSelectAllButton( wxCommandEvent& event ) { event.Skip(); } virtual void OnLeftSelectAllButton( wxCommandEvent& event ){ event.Skip(); }
virtual void OnRightCBSelection( wxCommandEvent& event ) { event.Skip(); } virtual void OnRightSelectAllButton( wxCommandEvent& event ){ event.Skip(); }
virtual void OnCancelButtonClick( wxCommandEvent& event ) { event.Skip(); } virtual void OnRightCBSelection( wxCommandEvent& event ){ event.Skip(); }
virtual void OnOkButtonClick( wxCommandEvent& event ) { event.Skip(); } virtual void OnCancelButtonClick( wxCommandEvent& event ){ event.Skip(); }
virtual void OnOkButtonClick( wxCommandEvent& event ){ event.Skip(); }
public: public:
DIALOG_DESIGN_RULES_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Design Rules Editor"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 750,692 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
DIALOG_DESIGN_RULES_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Design Rules Editor"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 750,520 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~DIALOG_DESIGN_RULES_BASE(); ~DIALOG_DESIGN_RULES_BASE();
}; };
......
...@@ -185,6 +185,11 @@ void WinEDA_PcbFrame::ReCreateMenuBar() ...@@ -185,6 +185,11 @@ void WinEDA_PcbFrame::ReCreateMenuBar()
item->SetBitmap( preference_xpm ); item->SetBitmap( preference_xpm );
configmenu->Append( item ); configmenu->Append( item );
item = new wxMenuItem( configmenu, ID_PCB_COPPER_LAYERS_SETUP, _( "Copper &Layers" ),
_( "Select copper layers count and layers names" ) );
item->SetBitmap( copper_layers_setup_xpm );
configmenu->Append( item );
item = new wxMenuItem( configmenu, ID_PCB_DISPLAY_OPTIONS_SETUP, _( "&Display" ), item = new wxMenuItem( configmenu, ID_PCB_DISPLAY_OPTIONS_SETUP, _( "&Display" ),
_( "Select how items (pads, tracks texts ... ) are displayed" ) ); _( "Select how items (pads, tracks texts ... ) are displayed" ) );
item->SetBitmap( display_options_xpm ); item->SetBitmap( display_options_xpm );
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "id.h" #include "id.h"
#include "hotkeys.h" #include "hotkeys.h"
#include "protos.h" #include "protos.h"
#include "dialog_copper_layers_setup.h"
/* Routines Locales */ /* Routines Locales */
...@@ -48,6 +49,13 @@ void WinEDA_PcbFrame::Process_Config( wxCommandEvent& event ) ...@@ -48,6 +49,13 @@ void WinEDA_PcbFrame::Process_Config( wxCommandEvent& event )
DisplayColorSetupFrame( this, pos ); DisplayColorSetupFrame( this, pos );
break; break;
case ID_PCB_COPPER_LAYERS_SETUP:
{
DIALOG_COPPER_LAYERS_SETUP dialog( this );
dialog.ShowModal();
}
break;
case ID_CONFIG_REQ: // Creation de la fenetre de configuration case ID_CONFIG_REQ: // Creation de la fenetre de configuration
InstallConfigFrame( pos ); InstallConfigFrame( pos );
break; break;
......
...@@ -85,6 +85,7 @@ BEGIN_EVENT_TABLE( WinEDA_PcbFrame, WinEDA_BasePcbFrame ) ...@@ -85,6 +85,7 @@ BEGIN_EVENT_TABLE( WinEDA_PcbFrame, WinEDA_BasePcbFrame )
EVT_MENU( ID_COLORS_SETUP, WinEDA_PcbFrame::Process_Config ) EVT_MENU( ID_COLORS_SETUP, WinEDA_PcbFrame::Process_Config )
EVT_MENU( ID_OPTIONS_SETUP, WinEDA_PcbFrame::Process_Config ) EVT_MENU( ID_OPTIONS_SETUP, WinEDA_PcbFrame::Process_Config )
EVT_MENU( ID_PCB_COPPER_LAYERS_SETUP, WinEDA_PcbFrame::Process_Config )
EVT_MENU( ID_PCB_TRACK_SIZE_SETUP, WinEDA_PcbFrame::Process_Config ) EVT_MENU( ID_PCB_TRACK_SIZE_SETUP, WinEDA_PcbFrame::Process_Config )
EVT_MENU( ID_PCB_DRAWINGS_WIDTHS_SETUP, WinEDA_PcbFrame::Process_Config ) EVT_MENU( ID_PCB_DRAWINGS_WIDTHS_SETUP, WinEDA_PcbFrame::Process_Config )
EVT_MENU( ID_PCB_PAD_SETUP, WinEDA_PcbFrame::Process_Config ) EVT_MENU( ID_PCB_PAD_SETUP, WinEDA_PcbFrame::Process_Config )
......
...@@ -181,13 +181,13 @@ void WinEDA_PcbFrame::PrepareLayerIndicator() ...@@ -181,13 +181,13 @@ void WinEDA_PcbFrame::PrepareLayerIndicator()
void WinEDA_PcbFrame::ReCreateHToolbar() void WinEDA_PcbFrame::ReCreateHToolbar()
/******************************************/ /******************************************/
/* Create the main horizontal toolbar for the board editor */ /* Creates or updates the main horizontal toolbar for the board editor
*/
{ {
wxString msg; wxString msg;
if( m_HToolBar != NULL ) if( m_HToolBar != NULL )
{ {
D(printf("ReCreateHToolbar\n");)
SetToolbars(); SetToolbars();
return; return;
} }
......
...@@ -538,15 +538,17 @@ void ArmBoolEng( Bool_Engine* aBooleng, bool aConvertHoles ) ...@@ -538,15 +538,17 @@ void ArmBoolEng( Bool_Engine* aBooleng, bool aConvertHoles )
Within the algorithm all input data is multiplied with DGRID, and the result Within the algorithm all input data is multiplied with DGRID, and the result
is rounded to an integer. is rounded to an integer.
*/ */
double DGRID = 10.0; // round coordinate X or Y value in calculations to this (initial value = 1000.0 in kbool example) double DGRID = 1.0; // round coordinate X or Y value in calculations to this (initial value = 1000.0 in kbool example)
// kbool uses DGRID to convert float user units to integer
// kbool unit = (int)(user unit * DGRID)
// Note: in kicad, coordinates are already integer so DGRID could be set to 1 // Note: in kicad, coordinates are already integer so DGRID could be set to 1
// we choose a DGRID = 10 to have a MARGE = 1.0 // we choose DGRID = 1.0
double MARGE = 1.0; // snap with in this range points to lines in the intersection routines double MARGE = 10.0; // snap with in this range points to lines in the intersection routines
// should always be > 1/DGRID a MARGE >= 10/DGRID is ok // should always be >= 1/DGRID a MARGE >= 10/DGRID is ok
// this is also used to remove small segments and to decide when // this is also used to remove small segments and to decide when
// two segments are in line. ( initial value = 0.001 ) // two segments are in line. ( initial value = 0.001 )
// For kicad we choose MARGE = 1, with DGRID = 10 // For kicad we choose MARGE = 10, with DGRID = 1.0
double CORRECTIONFACTOR = 0.0; // correct the polygons by this number: used in BOOL_CORRECTION operation double CORRECTIONFACTOR = 0.0; // correct the polygons by this number: used in BOOL_CORRECTION operation
// this operation shrinks a polygon if CORRECTIONFACTOR < 0 // this operation shrinks a polygon if CORRECTIONFACTOR < 0
...@@ -578,6 +580,10 @@ void ArmBoolEng( Bool_Engine* aBooleng, bool aConvertHoles ) ...@@ -578,6 +580,10 @@ void ArmBoolEng( Bool_Engine* aBooleng, bool aConvertHoles )
if( aConvertHoles ) if( aConvertHoles )
{ {
#if 1 // Can be set to 1 for kbool version >= 2.1, must be set to 0 for previous versions
// SetAllowNonTopHoleLinking() exists only in kbool >= 2.1
aBooleng->SetAllowNonTopHoleLinking( false ); // Default = true, but i have problems (filling errors) when true
#endif
aBooleng->SetLinkHoles( true ); // holes will be connected by double overlapping segments aBooleng->SetLinkHoles( true ); // holes will be connected by double overlapping segments
aBooleng->SetOrientationEntryMode( false ); // all polygons are contours, not holes aBooleng->SetOrientationEntryMode( false ); // all polygons are contours, not holes
} }
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
Licence: see kboollicense.txt Licence: see kboollicense.txt
RCS-ID: $Id: _dl_itr.h,v 1.5 2009/04/23 19:35:24 titato Exp $ RCS-ID: $Id: _dl_itr.h,v 1.6 2009/09/10 17:04:09 titato Exp $
*/ */
//! author="Klaas Holwerda" //! author="Klaas Holwerda"
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
Licence: see kboollicense.txt Licence: see kboollicense.txt
RCS-ID: $Id: _lnk_itr.h,v 1.3 2009/02/06 21:33:03 titato Exp $ RCS-ID: $Id: _lnk_itr.h,v 1.4 2009/09/10 17:04:09 titato Exp $
*/ */
//! author="Klaas Holwerda" //! author="Klaas Holwerda"
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
Licence: see kboollicense.txt Licence: see kboollicense.txt
RCS-ID: $Id: booleng.h,v 1.6 2009/09/07 19:23:28 titato Exp $ RCS-ID: $Id: booleng.h,v 1.9 2009/09/14 18:18:03 titato Exp $
*/ */
#ifndef BOOLENG_H #ifndef BOOLENG_H
...@@ -85,7 +85,7 @@ using namespace std; ...@@ -85,7 +85,7 @@ using namespace std;
#define A2DKBOOLDLLEXP_CTORFN #define A2DKBOOLDLLEXP_CTORFN
#endif #endif
#define KBOOL_VERSION "2.0" #define KBOOL_VERSION "2.1"
#define KBOOL_DEBUG 0 #define KBOOL_DEBUG 0
#define KBOOL_LOG 0 #define KBOOL_LOG 0
...@@ -360,6 +360,13 @@ public: ...@@ -360,6 +360,13 @@ public:
//! see SetWindingRule //! see SetWindingRule
bool GetWindingRule(); bool GetWindingRule();
//! when set not only the top vertex of a hole is linked to the other holes and contours,
//! but also vertex other vertexes close to a hole can be used.
void SetAllowNonTopHoleLinking( bool allow ) { m_allowNonTopHoleLinking = allow; }
//! see SetWindingRule
bool GetAllowNonTopHoleLinking() { return m_allowNonTopHoleLinking; }
//! the smallest accuracy used within the algorithm for comparing two real numbers. //! the smallest accuracy used within the algorithm for comparing two real numbers.
double GetAccur(); double GetAccur();
...@@ -547,6 +554,7 @@ private: ...@@ -547,6 +554,7 @@ private:
bool m_orientationEntryMode; bool m_orientationEntryMode;
bool m_doLinkHoles; bool m_doLinkHoles;
bool m_allowNonTopHoleLinking;
//! used in the StartPolygonAdd, AddPt, EndPolygonAdd sequence //! used in the StartPolygonAdd, AddPt, EndPolygonAdd sequence
kbGraph* m_GraphToAdd; kbGraph* m_GraphToAdd;
......
...@@ -5,10 +5,10 @@ ...@@ -5,10 +5,10 @@
Licence: see kboollicense.txt Licence: see kboollicense.txt
RCS-ID: $Id: graph.h,v 1.4 2009/09/07 19:23:28 titato Exp $ RCS-ID: $Id: graph.h,v 1.5 2009/09/10 17:04:09 titato Exp $
*/ */
/* @@(#) $Source: /cvsroot/wxart2d/wxArt2D/thirdparty/kbool/include/kbool/graph.h,v $ $Revision: 1.4 $ $Date: 2009/09/07 19:23:28 $ */ /* @@(#) $Source: /cvsroot/wxart2d/wxArt2D/thirdparty/kbool/include/kbool/graph.h,v $ $Revision: 1.5 $ $Date: 2009/09/10 17:04:09 $ */
/* /*
Program GRAPH.H Program GRAPH.H
......
...@@ -5,10 +5,10 @@ ...@@ -5,10 +5,10 @@
Licence: see kboollicense.txt Licence: see kboollicense.txt
RCS-ID: $Id: graphlst.h,v 1.3 2008/06/04 21:23:21 titato Exp $ RCS-ID: $Id: graphlst.h,v 1.4 2009/09/10 17:04:09 titato Exp $
*/ */
/* @@(#) $Source: /cvsroot/wxart2d/wxArt2D/thirdparty/kbool/include/kbool/graphlst.h,v $ $Revision: 1.3 $ $Date: 2008/06/04 21:23:21 $ */ /* @@(#) $Source: /cvsroot/wxart2d/wxArt2D/thirdparty/kbool/include/kbool/graphlst.h,v $ $Revision: 1.4 $ $Date: 2009/09/10 17:04:09 $ */
/* /*
Program GRAPHLST.H Program GRAPHLST.H
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
Licence: see kboollicense.txt Licence: see kboollicense.txt
RCS-ID: $Id: line.h,v 1.4 2009/09/07 19:23:28 titato Exp $ RCS-ID: $Id: line.h,v 1.5 2009/09/10 17:04:09 titato Exp $
*/ */
#ifndef LINE_H #ifndef LINE_H
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
Licence: see kboollicense.txt Licence: see kboollicense.txt
RCS-ID: $Id: link.h,v 1.4 2009/09/07 19:23:28 titato Exp $ RCS-ID: $Id: link.h,v 1.5 2009/09/10 17:04:09 titato Exp $
*/ */
#ifndef LINK_H #ifndef LINK_H
......
...@@ -5,10 +5,10 @@ ...@@ -5,10 +5,10 @@
Licence: see kboollicense.txt Licence: see kboollicense.txt
RCS-ID: $Id: lpoint.h,v 1.3 2008/06/04 21:23:22 titato Exp $ RCS-ID: $Id: lpoint.h,v 1.4 2009/09/10 17:04:09 titato Exp $
*/ */
/* @@(#) $Source: /cvsroot/wxart2d/wxArt2D/thirdparty/kbool/include/kbool/lpoint.h,v $ $Revision: 1.3 $ $Date: 2008/06/04 21:23:22 $ */ /* @@(#) $Source: /cvsroot/wxart2d/wxArt2D/thirdparty/kbool/include/kbool/lpoint.h,v $ $Revision: 1.4 $ $Date: 2009/09/10 17:04:09 $ */
/* /*
Program LPOINT.H Program LPOINT.H
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
Licence: see kboollicense.txt Licence: see kboollicense.txt
RCS-ID: $Id: node.h,v 1.4 2009/09/07 19:23:28 titato Exp $ RCS-ID: $Id: node.h,v 1.7 2009/09/14 16:50:12 titato Exp $
*/ */
#ifndef NODE_H #ifndef NODE_H
...@@ -53,13 +53,15 @@ public: ...@@ -53,13 +53,15 @@ public:
kbLink* GetMost( kbLink* const prev , LinkStatus whatside, BOOL_OP operation ); kbLink* GetMost( kbLink* const prev , LinkStatus whatside, BOOL_OP operation );
//! get link that is leading to a hole ( hole segment or linking segment ) //! get link that is leading to a hole ( hole segment or linking segment )
kbLink* GetMostHole( kbLink* const prev , LinkStatus whatside, BOOL_OP operation ); kbLink* GetMostHole( kbLink* const prev , LinkStatus whatside, BOOL_OP operation,
bool searchholelink = true );
//! get link that is not vertical. //! get link that is not vertical.
kbLink* GetNotFlat(); kbLink* GetNotFlat();
//! get a link to a hole or from a hole. //! get a link to a hole or from a hole.
kbLink* GetHoleLink( kbLink* const prev, bool checkbin, BOOL_OP operation ); kbLink* GetHoleLink( kbLink* const prev, LinkStatus whatside,
bool checkbin, BOOL_OP operation );
int Merge( kbNode* ); int Merge( kbNode* );
void RemoveLink( kbLink* ); void RemoveLink( kbLink* );
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
Licence: see kboollicense.txt Licence: see kboollicense.txt
RCS-ID: $Id: record.h,v 1.4 2009/09/07 19:23:28 titato Exp $ RCS-ID: $Id: record.h,v 1.5 2009/09/10 17:04:09 titato Exp $
*/ */
#ifndef RECORD_H #ifndef RECORD_H
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
Licence: see kboollicense.txt Licence: see kboollicense.txt
RCS-ID: $Id: scanbeam.h,v 1.5 2009/09/07 19:23:28 titato Exp $ RCS-ID: $Id: scanbeam.h,v 1.6 2009/09/10 17:04:09 titato Exp $
*/ */
#ifndef SCANBEAM_H #ifndef SCANBEAM_H
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
Licence: see kboollicense.txt Licence: see kboollicense.txt
RCS-ID: $Id: booleng.cpp,v 1.5 2009/09/07 19:23:28 titato Exp $ RCS-ID: $Id: booleng.cpp,v 1.7 2009/09/14 16:50:12 titato Exp $
*/ */
#include "kbool/booleng.h" #include "kbool/booleng.h"
...@@ -95,6 +95,7 @@ Bool_Engine::Bool_Engine() ...@@ -95,6 +95,7 @@ Bool_Engine::Bool_Engine()
m_orientationEntryMode = false; m_orientationEntryMode = false;
m_doLinkHoles = true; m_doLinkHoles = true;
m_allowNonTopHoleLinking = true;
m_graphlist = new kbGraphList( this ); m_graphlist = new kbGraphList( this );
m_ACCUR = 1e-4; m_ACCUR = 1e-4;
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
Licence: see kboollicense.txt Licence: see kboollicense.txt
RCS-ID: $Id: graph.cpp,v 1.4 2009/09/07 19:23:28 titato Exp $ RCS-ID: $Id: graph.cpp,v 1.7 2009/09/14 16:50:12 titato Exp $
*/ */
// Grpah is the structure used to store polygons // Grpah is the structure used to store polygons
...@@ -536,14 +536,14 @@ void kbGraph::CollectGraphLast( kbNode *current_node, BOOL_OP operation, bool de ...@@ -536,14 +536,14 @@ void kbGraph::CollectGraphLast( kbNode *current_node, BOOL_OP operation, bool de
{ {
if ( currentlink->GetHoleLink() ) if ( currentlink->GetHoleLink() )
{ {
//in case we entered the hole via the hole link just now, we followe the hole. //in case we entered the hole via the hole link just now, we follow the hole.
//This is taking as many holes as possible ( most right around) //This is taking as many holes as possible ( most right around)
nextlink = next_node->GetMostHole( currentlink, IS_RIGHT , operation ); nextlink = next_node->GetMostHole( currentlink, IS_RIGHT , operation, false );
if ( !nextlink ) // hole done? if ( !nextlink ) // hole done?
//if we did get to this hole via a holelink?, then we might now be on the return link. //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, //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. //in that case, we did go to the HoleLink here, and directly return on the other holelink.
nextlink = next_node->GetHoleLink( currentlink, true, operation ); nextlink = next_node->GetHoleLink( currentlink, IS_RIGHT, true, operation );
if ( !nextlink ) if ( !nextlink )
{ {
//we did get to this hole via a holelink and we are on the returning holelink. //we did get to this hole via a holelink and we are on the returning holelink.
...@@ -554,9 +554,9 @@ void kbGraph::CollectGraphLast( kbNode *current_node, BOOL_OP operation, bool de ...@@ -554,9 +554,9 @@ void kbGraph::CollectGraphLast( kbNode *current_node, BOOL_OP operation, bool de
} }
else else
{ {
nextlink = next_node->GetHoleLink( currentlink, true, operation ); // other linked holes first nextlink = next_node->GetMostHole( currentlink, IS_RIGHT, operation ); // other holes first
if ( !nextlink ) if ( !nextlink )
nextlink = next_node->GetMostHole( currentlink, IS_RIGHT, operation ); // other holes first nextlink = next_node->GetHoleLink( currentlink, IS_RIGHT, true, operation ); // other linked holes first
if ( !nextlink ) if ( !nextlink )
{ {
//We are leaving the hole. //We are leaving the hole.
...@@ -568,9 +568,11 @@ void kbGraph::CollectGraphLast( kbNode *current_node, BOOL_OP operation, bool de ...@@ -568,9 +568,11 @@ void kbGraph::CollectGraphLast( kbNode *current_node, BOOL_OP operation, bool de
} }
else else
{ {
//nextlink = next_node->GetMost( currentlink, IS_RIGHT, operation );
//if ( !nextlink )
//a hole link is preferred above a normal link. If not no holes would be linked in anyway. //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 ); nextlink = next_node->GetHoleLink( currentlink, IS_RIGHT, true, operation );
if ( !nextlink ) if ( !nextlink )
//also if we can get to a hole directly within a contour, that is better (get as much as possible) //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 ); nextlink = next_node->GetMostHole( currentlink, IS_RIGHT, operation );
...@@ -1683,7 +1685,7 @@ void kbGraph::Boolean( BOOL_OP operation, kbGraphList* Result ) ...@@ -1683,7 +1685,7 @@ void kbGraph::Boolean( BOOL_OP operation, kbGraphList* Result )
Merge_NodeToNode( 0 ); Merge_NodeToNode( 0 );
#if KBOOL_LOG == 1 #if KBOOL_LOG == 1
_GC->SetLog( true ); //_GC->SetLog( true );
_GC->Write_Log( "LINKHOLES\n" ); _GC->Write_Log( "LINKHOLES\n" );
#endif #endif
writegraph( false ); writegraph( false );
...@@ -1698,7 +1700,7 @@ void kbGraph::Boolean( BOOL_OP operation, kbGraphList* Result ) ...@@ -1698,7 +1700,7 @@ void kbGraph::Boolean( BOOL_OP operation, kbGraphList* Result )
{ {
//to delete extra points //to delete extra points
//those extra points are caused by link holes //those extra points are caused by link holes
//and are eqaul //and are eqaul ( the smallest number in integer is 1 )
DeleteZeroLines( 1 ); DeleteZeroLines( 1 );
_GC->SetState( "extract simples last" ); _GC->SetState( "extract simples last" );
...@@ -2559,6 +2561,7 @@ void kbGraph::WriteKEY( Bool_Engine* GC, FILE* file ) ...@@ -2559,6 +2561,7 @@ void kbGraph::WriteKEY( Bool_Engine* GC, FILE* file )
void kbGraph::WriteGraphKEY(Bool_Engine* GC) void kbGraph::WriteGraphKEY(Bool_Engine* GC)
{ {
#if KBOOL_DEBUG #if KBOOL_DEBUG
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");
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
Licence: see kboollicense.txt Licence: see kboollicense.txt
RCS-ID: $Id: graphlst.cpp,v 1.3 2008/06/04 21:23:22 titato Exp $ RCS-ID: $Id: graphlst.cpp,v 1.4 2009/09/10 17:04:09 titato Exp $
*/ */
//#include "debugdrv.h" //#include "debugdrv.h"
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
Licence: see kboollicense.txt Licence: see kboollicense.txt
RCS-ID: $Id: line.cpp,v 1.4 2009/09/07 19:23:28 titato Exp $ RCS-ID: $Id: line.cpp,v 1.6 2009/09/13 18:34:06 titato Exp $
*/ */
// Standard include files // Standard include files
...@@ -308,7 +308,11 @@ B_INT kbLine::Calculate_Y( B_INT X ) ...@@ -308,7 +308,11 @@ B_INT kbLine::Calculate_Y( B_INT X )
CalculateLineParameters(); CalculateLineParameters();
if ( m_AA != 0 ) if ( m_AA != 0 )
{
//vertical line is undefined
assert( m_BB );
return ( B_INT )( -( m_AA * X + m_CC ) / m_BB ); return ( B_INT )( -( m_AA * X + m_CC ) / m_BB );
}
else else
// horizontal line // horizontal line
return m_link->GetBeginNode()->GetY(); return m_link->GetBeginNode()->GetY();
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
Licence: see kboollicense.txt Licence: see kboollicense.txt
RCS-ID: $Id: lpoint.cpp,v 1.3 2008/06/04 21:23:22 titato Exp $ RCS-ID: $Id: lpoint.cpp,v 1.4 2009/09/10 17:04:09 titato Exp $
*/ */
#include "kbool/lpoint.h" #include "kbool/lpoint.h"
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
Licence: see kboollicense.txt Licence: see kboollicense.txt
RCS-ID: $Id: node.cpp,v 1.4 2009/09/07 19:23:28 titato Exp $ RCS-ID: $Id: node.cpp,v 1.7 2009/09/14 16:50:12 titato Exp $
*/ */
#include "kbool/node.h" #include "kbool/node.h"
...@@ -387,7 +387,7 @@ kbLink* kbNode::GetMost( kbLink* const prev , LinkStatus whatside, BOOL_OP opera ...@@ -387,7 +387,7 @@ kbLink* kbNode::GetMost( kbLink* const prev , LinkStatus whatside, BOOL_OP opera
// on the node get the link // on the node get the link
// is the most right or left one // is the most right or left one
// This function is used to collect the simple graphs from a graph // This function is used to collect the simple graphs from a graph
kbLink* kbNode::GetMostHole( kbLink* const prev, LinkStatus whatside, BOOL_OP operation ) kbLink* kbNode::GetMostHole( kbLink* const prev, LinkStatus whatside, BOOL_OP operation, bool searchholelink )
{ {
kbLink * reserve = 0; kbLink * reserve = 0;
kbLink *Result = NULL, *link; kbLink *Result = NULL, *link;
...@@ -397,7 +397,11 @@ kbLink* kbNode::GetMostHole( kbLink* const prev, LinkStatus whatside, BOOL_OP op ...@@ -397,7 +397,11 @@ kbLink* kbNode::GetMostHole( kbLink* const prev, LinkStatus whatside, BOOL_OP op
{ {
if ( ( link = ( kbLink* )_linklist->headitem() ) == prev ) //this is NOT the one to go on if ( ( link = ( kbLink* )_linklist->headitem() ) == prev ) //this is NOT the one to go on
link = ( kbLink* )_linklist->tailitem(); link = ( kbLink* )_linklist->tailitem();
if ( link->GetHole() && !link->GetHoleLink() && !link->BeenHere() && SameSides( prev, link, operation ) ) if (
!link->BeenHere() &&
link->GetHole() &&
( searchholelink && link->GetHoleLink() || !link->GetHoleLink() ) &&
SameSides( prev, link, operation ) )
//we are back where we started (bin is true) return Null //we are back where we started (bin is true) return Null
return link; return link;
return( 0 ); return( 0 );
...@@ -409,9 +413,10 @@ kbLink* kbNode::GetMostHole( kbLink* const prev, LinkStatus whatside, BOOL_OP op ...@@ -409,9 +413,10 @@ kbLink* kbNode::GetMostHole( kbLink* const prev, LinkStatus whatside, BOOL_OP op
while( !_GC->_linkiter->hitroot() ) while( !_GC->_linkiter->hitroot() )
{ {
link = _GC->_linkiter->item(); link = _GC->_linkiter->item();
if ( !link->BeenHere() && if (
link->GetHole() && !link->BeenHere() &&
!link->GetHoleLink() && link->GetHole() &&
( searchholelink && link->GetHoleLink() || !link->GetHoleLink() ) &&
SameSides( prev, link, operation ) && SameSides( prev, link, operation ) &&
link != prev //should be set to bin already link != prev //should be set to bin already
) )
...@@ -443,7 +448,7 @@ kbLink* kbNode::GetMostHole( kbLink* const prev, LinkStatus whatside, BOOL_OP op ...@@ -443,7 +448,7 @@ kbLink* kbNode::GetMostHole( kbLink* const prev, LinkStatus whatside, BOOL_OP op
} }
// this function gets the highest not flat link // this function gets the highest not flat link
kbLink* kbNode::GetHoleLink( kbLink* const prev, bool checkbin, BOOL_OP operation ) kbLink* kbNode::GetHoleLink( kbLink* const prev, LinkStatus whatside, bool checkbin, BOOL_OP operation )
{ {
kbLink * Result = NULL, *link; kbLink * Result = NULL, *link;
...@@ -457,8 +462,14 @@ kbLink* kbNode::GetHoleLink( kbLink* const prev, bool checkbin, BOOL_OP operatio ...@@ -457,8 +462,14 @@ kbLink* kbNode::GetHoleLink( kbLink* const prev, bool checkbin, BOOL_OP operatio
SameSides( prev, link, operation ) SameSides( prev, link, operation )
) )
{ {
Result = link; if ( !Result )
break; Result = link; //first one found sofar
else
{
if ( prev->PointOnCorner( Result, link ) == whatside )
//more to the whatside than take this one
Result = link;
}
} }
} }
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
Licence: see kboollicense.txt Licence: see kboollicense.txt
RCS-ID: $Id: record.cpp,v 1.4 2009/09/07 19:23:28 titato Exp $ RCS-ID: $Id: record.cpp,v 1.5 2009/09/10 17:04:09 titato Exp $
*/ */
#include "kbool/booleng.h" #include "kbool/booleng.h"
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
Licence: see kboollicense.txt Licence: see kboollicense.txt
RCS-ID: $Id: scanbeam.cpp,v 1.4 2009/09/07 19:23:28 titato Exp $ RCS-ID: $Id: scanbeam.cpp,v 1.7 2009/09/14 16:50:12 titato Exp $
*/ */
// class scanbeam // class scanbeam
...@@ -401,7 +401,6 @@ bool ScanBeam::RemoveOld( SCANTYPE scantype, TDLI<kbLink>* _I, bool& holes ) ...@@ -401,7 +401,6 @@ bool ScanBeam::RemoveOld( SCANTYPE scantype, TDLI<kbLink>* _I, bool& holes )
bool found = false; bool found = false;
bool foundnew = false; bool foundnew = false;
DL_Iter<kbRecord*> _BBI = DL_Iter<kbRecord*>(); DL_Iter<kbRecord*> _BBI = DL_Iter<kbRecord*>();
bool attached = false;
_low = _I->item()->GetBeginNode(); _low = _I->item()->GetBeginNode();
...@@ -971,7 +970,7 @@ void ScanBeam::Generate_INOUT( int graphnumber ) ...@@ -971,7 +970,7 @@ void ScanBeam::Generate_INOUT( int graphnumber )
// //
// this function will search the closest link to a hole // this function will search the closest link to a hole
// step one, search for a link that is marked (this is 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 // step two, the closest link is the previous link in
// the beam, but only in the beam that contains the highest node // the beam, but only in the beam that contains the highest node
// from the marked link. // from the marked link.
// why ? : if the marked link has for the begin and end node different // why ? : if the marked link has for the begin and end node different
...@@ -998,6 +997,70 @@ bool ScanBeam::ProcessHoles( bool atinsert, TDLI<kbLink>* _LI ) ...@@ -998,6 +997,70 @@ bool ScanBeam::ProcessHoles( bool atinsert, TDLI<kbLink>* _LI )
kbRecord* record = _BI.item(); kbRecord* record = _BI.item();
kbLink* link = record->GetLink(); kbLink* link = record->GetLink();
kbNode* _low = _LI->item()->GetBeginNode();
if( _GC->GetAllowNonTopHoleLinking() )
{
_BI++;
if ( !_BI.hitroot() && _BI.item()->GetLink()->IsTopHole() )
{
kbLink* linkToThis = _BI.item()->GetLink();
//calculate linkToThis its Y at X of topnode.
kbLine line( _GC );
line.Set( linkToThis );
B_INT Y;
kbNode * leftnode; //left node of clossest link
//link right now
if ( linkToThis->GetEndNode()->GetX() == _low->GetX() )
Y = linkToThis->GetEndNode()->GetY();
else if ( linkToThis->GetBeginNode()->GetX() == _low->GetX() )
Y = linkToThis->GetBeginNode()->GetY();
else
Y = line.Calculate_Y( _low->GetX() );
if ( linkToThis->GetBeginNode()->GetX() < linkToThis->GetEndNode()->GetX() )
leftnode = linkToThis->GetBeginNode();
else
leftnode = linkToThis->GetEndNode();
kbNode *topnode = new kbNode( _low->GetX(), Y, _GC );
kbLink *link_A = new kbLink( 0, topnode, leftnode, _GC );
// the orginal linkToThis
linkToThis->Replace( leftnode, topnode );
_LI->insbegin( link_A );
//reset mark to flag that this hole has been processed
linkToThis->SetTopHole( false );
kbLink *link_B = new kbLink( 0, _low, topnode, _GC );
kbLink *link_BB = new kbLink( 0, topnode, _low, _GC );
_LI->insbegin( link_B );
_LI->insbegin( link_BB );
//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 = linkToThis->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 );
// 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( linkToThis );
link_B->TakeOverOperationFlags( linkToThis );
link_BB->TakeOverOperationFlags( linkToThis );
foundholes = true;
SortTheBeam( atinsert );
}
_BI--;
}
if ( !record->GetLine()->CrossListEmpty() ) if ( !record->GetLine()->CrossListEmpty() )
{ {
...@@ -1009,6 +1072,9 @@ bool ScanBeam::ProcessHoles( bool atinsert, TDLI<kbLink>* _LI ) ...@@ -1009,6 +1072,9 @@ bool ScanBeam::ProcessHoles( bool atinsert, TDLI<kbLink>* _LI )
// make new nodes and links and set them, re-use the old link, so the links // 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. // that still stand in the linecrosslist will not be lost.
// There is a hole that must be linked to this link ! // There is a hole that must be linked to this link !
kbLink* linkToThis = link;
TDLI<kbNode> I( record->GetLine()->GetCrossList() ); TDLI<kbNode> I( record->GetLine()->GetCrossList() );
I.tohead(); I.tohead();
while( !I.hitroot() ) while( !I.hitroot() )
...@@ -1016,11 +1082,43 @@ bool ScanBeam::ProcessHoles( bool atinsert, TDLI<kbLink>* _LI ) ...@@ -1016,11 +1082,43 @@ bool ScanBeam::ProcessHoles( bool atinsert, TDLI<kbLink>* _LI )
topnode = I.item(); topnode = I.item();
I.remove(); I.remove();
//calculate linkToThis its Y at X of topnode.
kbLine line( _GC ); kbLine line( _GC );
line.Set( link ); line.Set( linkToThis );
B_INT Y = line.Calculate_Y( topnode->GetX() ); kbNode * leftnode; //left node of clossest link
B_INT Y;
//check if flatlink ( i think is always linkBB from a topnode at same X coordinate.
//but lets accept all flatlinks
if ( linkToThis->GetEndNode()->GetX() == linkToThis->GetBeginNode()->GetX() )
{
//we take the lowest of the flatlink nodes, which is right for
// a second hole at same X
if ( linkToThis->GetEndNode()->GetY() >= linkToThis->GetBeginNode()->GetY() )
{
Y = linkToThis->GetBeginNode()->GetY();
leftnode = linkToThis->GetBeginNode();
}
else
{
Y = linkToThis->GetEndNode()->GetY();
leftnode = linkToThis->GetEndNode();
}
}
else
{
if ( linkToThis->GetEndNode()->GetX() == topnode->GetX() )
Y = linkToThis->GetEndNode()->GetY();
else if ( linkToThis->GetBeginNode()->GetX() == topnode->GetX() )
Y = linkToThis->GetBeginNode()->GetY();
else
Y = line.Calculate_Y( topnode->GetX() );
if ( linkToThis->GetBeginNode()->GetX() < linkToThis->GetEndNode()->GetX() )
leftnode = linkToThis->GetBeginNode();
else
leftnode = linkToThis->GetEndNode();
}
// Now we'll create new nodes and new links to make the link between // Now we'll create new nodes and new links to make the link between
// the graphs. // the graphs.
...@@ -1031,30 +1129,25 @@ bool ScanBeam::ProcessHoles( bool atinsert, TDLI<kbLink>* _LI ) ...@@ -1031,30 +1129,25 @@ bool ScanBeam::ProcessHoles( bool atinsert, TDLI<kbLink>* _LI )
//because they are left around but the link is always on the //because they are left around but the link is always on the
//bottom of the hole //bottom of the hole
// linkA linkD // linkA linkToThis
// o-------->--------NodeA------->------------o // o-------->--------NodeA------->------------o
// | | // leftnode | |
// | | // | |
// linkB v ^ linkBB // linkB v ^ linkBB
// | | // | |
// | | // | |
// outgoing* | | incoming* // outgoing* | | incoming*
// o------<---------topnode--------<----------o // o------<---------topnode--------<----------o
// //
// all holes are oriented left around // all holes are oriented left around
kbNode * leftnode; //left node of clossest link
( link->GetBeginNode()->GetX() < link->GetEndNode()->GetX() ) ?
leftnode = link->GetBeginNode() :
leftnode = link->GetEndNode();
kbNode *node_A = new kbNode( topnode->GetX(), Y, _GC ); kbNode *node_A = new kbNode( topnode->GetX(), Y, _GC );
kbLink *link_A = new kbLink( 0, leftnode, node_A, _GC ); kbLink *link_A = new kbLink( 0, leftnode, node_A, _GC );
kbLink *link_B = new kbLink( 0, node_A, topnode, _GC ); kbLink *link_B = new kbLink( 0, node_A, topnode, _GC );
kbLink *link_BB = new kbLink( 0, topnode, node_A, _GC ); kbLink *link_BB = new kbLink( 0, topnode, node_A, _GC );
kbLink *link_D = _BI.item()->GetLink(); // the orginal linkToThis
link_D->Replace( leftnode, node_A ); linkToThis->Replace( leftnode, node_A );
_LI->insbegin( link_A ); _LI->insbegin( link_A );
_LI->insbegin( link_B ); _LI->insbegin( link_B );
_LI->insbegin( link_BB ); _LI->insbegin( link_BB );
...@@ -1064,7 +1157,7 @@ bool ScanBeam::ProcessHoles( bool atinsert, TDLI<kbLink>* _LI ) ...@@ -1064,7 +1157,7 @@ bool ScanBeam::ProcessHoles( bool atinsert, TDLI<kbLink>* _LI )
link_BB->SetHoleLink( true ); link_BB->SetHoleLink( true );
//is where we come from/link to a hole //is where we come from/link to a hole
bool closest_is_hole = link->GetHole(); bool closest_is_hole = linkToThis->GetHole();
// if the polygon linked to, is a hole, this hole here // if the polygon linked to, is a hole, this hole here
// just gets bigger, so we take over the links its hole marking. // just gets bigger, so we take over the links its hole marking.
...@@ -1075,9 +1168,19 @@ bool ScanBeam::ProcessHoles( bool atinsert, TDLI<kbLink>* _LI ) ...@@ -1075,9 +1168,19 @@ bool ScanBeam::ProcessHoles( bool atinsert, TDLI<kbLink>* _LI )
// we have only one operation at the time, taking // we have only one operation at the time, taking
// over the operation flags is enough, since the linking segments will // over the operation flags is enough, since the linking segments will
// be part of that output for any operation done. // be part of that output for any operation done.
link_A->TakeOverOperationFlags( link ); link_A->TakeOverOperationFlags( linkToThis );
link_B->TakeOverOperationFlags( link ); link_B->TakeOverOperationFlags( linkToThis );
link_BB->TakeOverOperationFlags( link ); link_BB->TakeOverOperationFlags( linkToThis );
// check next top node is at same X
if ( !I.hitroot() )
{
kbNode *newtopnode = I.item();
if ( topnode->GetX() == newtopnode->GetX() )
linkToThis = link_BB;
else
linkToThis = link;
}
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment