Updated boost to version 1.34. Added boost::polygon (experimental).
Fixed some issues with wxWidgets 2.9.1 (fixed Gerbview and Pcbnew crashes under Linux when starting. Could explain also crashes under MACOSX) Code cleaning. pcbnew: Added experimental zone fill calculations with boost::polygon old file zones_convert_brd_items_to_polygons.cpp has now 2 versions: zones_convert_brd_items_to_polygons_with_Boost.cpp use boost::polygon to calculate filled areas zones_convert_brd_items_to_polygons_with_BKbool.cpp use kbool (code cleaned). >>> to use boost polygon version: call cmake with option: -DUSE_BOOST_POLYGON_LIBRARY=ON Eeschema: added patches from Yuri Khalyavin
This commit is contained in:
commit
1794a2ae73
|
@ -4,6 +4,20 @@ KiCad ChangeLog 2010
|
|||
Please add newer entries at the top, list the date and your name with
|
||||
email address.
|
||||
|
||||
2010-jul-27, UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
|
||||
================================================================================
|
||||
++all:
|
||||
Updated boost to version 1.34
|
||||
Added boost::polygon (experimental)
|
||||
++pcbnew:
|
||||
Added experimental zone fill calculations with boost::polygon
|
||||
old file zones_convert_brd_items_to_polygons.cpp has now 2 versions:
|
||||
zones_convert_brd_items_to_polygons_with_Boost.cpp use boost::polygon to calculate filled areas
|
||||
zones_convert_brd_items_to_polygons_with_BKbool.cpp use kbool (code cleaned).
|
||||
|
||||
>>> to use boost polygon version:
|
||||
call cmake with option: -DUSE_BOOST_POLYGON_LIBRARY=ON
|
||||
|
||||
2010-jul-12, UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
|
||||
================================================================================
|
||||
++pcbnew:
|
||||
|
|
|
@ -24,6 +24,8 @@ option(USE_WX_ZOOM "Use wxDC to perform zooming (default OFF). Warning, this is
|
|||
option(USE_WX_GRAPHICS_CONTEXT
|
||||
"Use wxGraphicsContext for rendering (default OFF). Warning, this is experimental")
|
||||
|
||||
option(USE_BOOST_POLYGON_LIBRARY
|
||||
"Use boost polygon library instead of Kbool to calculate filled areas in zones (default OFF). Warning, this is experimental")
|
||||
|
||||
#================================================
|
||||
# Set flags for GCC.
|
||||
|
@ -58,6 +60,11 @@ if(USE_WX_GRAPHICS_CONTEXT)
|
|||
add_definitions(-DUSE_WX_GRAPHICS_CONTEXT)
|
||||
endif(USE_WX_GRAPHICS_CONTEXT)
|
||||
|
||||
if(USE_BOOST_POLYGON_LIBRARY)
|
||||
set( USE_BOOST_POLYGON_LIBRARY ON )
|
||||
add_definitions(-DUSE_BOOST_POLYGON_LIBRARY)
|
||||
endif(USE_WX_GRAPHICS_CONTEXT)
|
||||
|
||||
# Locations for install targets.
|
||||
set(KICAD_BIN bin
|
||||
CACHE PATH "Location of KiCad binaries.")
|
||||
|
|
|
@ -88,12 +88,12 @@ BM2CMP_FRAME_BASE::BM2CMP_FRAME_BASE( wxWindow* parent, wxWindowID id, const wxS
|
|||
brightSizer->Add( m_buttonLoad, 0, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL, 5 );
|
||||
|
||||
m_buttonExportEeschema = new wxButton( this, wxID_ANY, _("Export to eeschema"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_buttonExportEeschema->SetToolTip( _("Create a lib file for Eeschema") );
|
||||
m_buttonExportEeschema->SetToolTip( _("Create a library file for Eeschema\nThis library contains only one component: logo") );
|
||||
|
||||
brightSizer->Add( m_buttonExportEeschema, 0, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL, 5 );
|
||||
|
||||
m_buttonExportPcbnew = new wxButton( this, wxID_ANY, _("Export to Pcbnew"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_buttonExportPcbnew->SetToolTip( _("Create a footprint file for PcbNew") );
|
||||
m_buttonExportPcbnew->SetToolTip( _("Create a footprint file for PcbNew\nThis footprint contains only one footprint: logo") );
|
||||
|
||||
brightSizer->Add( m_buttonExportPcbnew, 0, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL, 5 );
|
||||
|
||||
|
@ -108,6 +108,8 @@ BM2CMP_FRAME_BASE::BM2CMP_FRAME_BASE( wxWindow* parent, wxWindowID id, const wxS
|
|||
brightSizer->Add( m_ThresholdText, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
m_sliderThreshold = new wxSlider( this, wxID_ANY, 25, 0, 50, wxDefaultPosition, wxDefaultSize, wxSL_AUTOTICKS|wxSL_HORIZONTAL|wxSL_TOP );
|
||||
m_sliderThreshold->SetToolTip( _("Adjust the level to convert the greysvale picture to the binary picture.") );
|
||||
|
||||
brightSizer->Add( m_sliderThreshold, 0, wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
bMainSizer->Add( brightSizer, 0, wxEXPAND, 5 );
|
||||
|
|
|
@ -851,7 +851,7 @@
|
|||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass"></property>
|
||||
<property name="tooltip">Create a lib file for Eeschema</property>
|
||||
<property name="tooltip">Create a library file for Eeschema
This library contains only one component: logo</property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
|
@ -903,7 +903,7 @@
|
|||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass"></property>
|
||||
<property name="tooltip">Create a footprint file for PcbNew</property>
|
||||
<property name="tooltip">Create a footprint file for PcbNew
This footprint contains only one footprint: logo</property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
|
@ -1060,7 +1060,7 @@
|
|||
<property name="size"></property>
|
||||
<property name="style">wxSL_AUTOTICKS|wxSL_HORIZONTAL|wxSL_TOP</property>
|
||||
<property name="subclass"></property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="tooltip">Adjust the level to convert the greysvale picture to the binary picture.</property>
|
||||
<property name="value">25</property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
|
|
|
@ -364,28 +364,33 @@ void WinEDA_DrawFrame::OnSize( wxSizeEvent& SizeEv )
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/** Function SetToolID
|
||||
* Enables the icon of the selected tool in the vertical toolbar.
|
||||
* (Or tool ID_NO_SELECT_BUTT default if no new selection)
|
||||
* if (id >= 0)
|
||||
* @param aId = new m_ID_current_state value (if aId >= 0)
|
||||
* @param aCursor = the new cursor shape (0 = default cursor)
|
||||
* @param aTitle = tool message in status bar
|
||||
* if (aId >= 0)
|
||||
* Updates all variables related:
|
||||
* Message m_ID_current_state, cursor
|
||||
* If (id < 0)
|
||||
* Only updates the variables message and cursor
|
||||
* m_ID_current_state, cursor shape and message in status bar
|
||||
* If (aId < 0)
|
||||
* Only updates the cursor shape and message in status bar
|
||||
* (does not the current m_ID_current_state value
|
||||
*/
|
||||
void WinEDA_DrawFrame::SetToolID( int id, int new_cursor_id,
|
||||
const wxString& title )
|
||||
void WinEDA_DrawFrame::SetToolID( int aId, int aCursor,
|
||||
const wxString& aToolMsg )
|
||||
{
|
||||
// Change Cursor
|
||||
// Keep default cursor in toolbars
|
||||
SetCursor( wxNullCursor );
|
||||
// Change Cursor in DrawPanel only
|
||||
if( DrawPanel )
|
||||
{
|
||||
DrawPanel->m_PanelDefaultCursor = new_cursor_id;
|
||||
DrawPanel->SetCursor( new_cursor_id );
|
||||
DrawPanel->m_PanelDefaultCursor = aCursor;
|
||||
DrawPanel->SetCursor( aCursor );
|
||||
}
|
||||
SetCursor( wxCURSOR_ARROW );
|
||||
DisplayToolMsg( title );
|
||||
DisplayToolMsg( aToolMsg );
|
||||
|
||||
if( id < 0 )
|
||||
if( aId < 0 )
|
||||
return;
|
||||
|
||||
// Old Tool ID_NO_SELECT_BUTT active or inactive if no new tool.
|
||||
|
@ -399,7 +404,7 @@ void WinEDA_DrawFrame::SetToolID( int id, int new_cursor_id,
|
|||
}
|
||||
else
|
||||
{
|
||||
if( id )
|
||||
if( aId )
|
||||
{
|
||||
if( m_VToolBar )
|
||||
m_VToolBar->ToggleTool( ID_NO_SELECT_BUTT, FALSE );
|
||||
|
@ -411,18 +416,18 @@ void WinEDA_DrawFrame::SetToolID( int id, int new_cursor_id,
|
|||
m_VToolBar->ToggleTool( ID_NO_SELECT_BUTT, TRUE );
|
||||
}
|
||||
|
||||
if( id )
|
||||
if( aId )
|
||||
{
|
||||
if( m_VToolBar )
|
||||
m_VToolBar->ToggleTool( id, TRUE );
|
||||
m_VToolBar->ToggleTool( aId, TRUE );
|
||||
|
||||
if( m_AuxVToolBar )
|
||||
m_AuxVToolBar->ToggleTool( id, TRUE );
|
||||
m_AuxVToolBar->ToggleTool( aId, TRUE );
|
||||
}
|
||||
else if( m_VToolBar )
|
||||
m_VToolBar->ToggleTool( ID_NO_SELECT_BUTT, TRUE );
|
||||
|
||||
m_ID_current_state = id;
|
||||
m_ID_current_state = aId;
|
||||
if( m_VToolBar )
|
||||
m_VToolBar->Refresh( );
|
||||
}
|
||||
|
|
|
@ -164,7 +164,7 @@ void WinEDA_SelColorFrame::Init_Dialog( int aOldColor )
|
|||
iconDC.DrawRoundedRectangle( 0, 0, w, h, (double) h / 3 );
|
||||
|
||||
BitmapButton = new wxBitmapButton( this, butt_ID, ButtBitmap,
|
||||
wxDefaultPosition, wxSize( w, h ) );
|
||||
wxDefaultPosition, wxSize( w+8, h+6 ) );
|
||||
FlexColumnBoxSizer->Add( BitmapButton, 0,
|
||||
wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
|
||||
wxLEFT | wxBOTTOM, 5 );
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
update=05/07/2010 19:03:21
|
||||
update=22/07/2010 13:46:39
|
||||
version=1
|
||||
last_client=pcbnew
|
||||
[common]
|
||||
|
|
|
@ -199,7 +199,7 @@ void WinEDA_SetColorsFrame::CreateControls()
|
|||
|
||||
BitmapButton =
|
||||
new wxBitmapButton( this, butt_ID, ButtBitmap, wxDefaultPosition,
|
||||
wxSize( BUTT_SIZE_X, BUTT_SIZE_Y ) );
|
||||
wxSize( BUTT_SIZE_X+8, BUTT_SIZE_Y+6 ) );
|
||||
RowBoxSizer->Add( BitmapButton,
|
||||
0,
|
||||
wxALIGN_CENTER_VERTICAL | wxRIGHT | wxBOTTOM,
|
||||
|
|
|
@ -38,8 +38,8 @@ enum col_sel_id {
|
|||
#endif
|
||||
|
||||
// Specify the width and height of every (color-displaying / bitmap) button
|
||||
const int BUTT_SIZE_X = 30;
|
||||
const int BUTT_SIZE_Y = 20;
|
||||
const int BUTT_SIZE_X = 16;
|
||||
const int BUTT_SIZE_Y = 16;
|
||||
|
||||
// Macro utile :
|
||||
#define ADR( numlayer ) & (g_LayerDescr.LayerColor[numlayer])
|
||||
|
|
|
@ -106,6 +106,8 @@ static Ki_HotkeyInfo HkAddLabel( wxT( "add Label" ), HK_ADD_LABEL, 'L' );
|
|||
static Ki_HotkeyInfo HkBeginWire( wxT( "begin Wire" ), HK_BEGIN_WIRE, 'W' );
|
||||
static Ki_HotkeyInfo HkAddComponent( wxT( "Add Component" ),
|
||||
HK_ADD_NEW_COMPONENT, 'A' );
|
||||
static Ki_HotkeyInfo HkAddNoConn( wxT( "Add NoConnected Flag" ),
|
||||
HK_ADD_NOCONN_FLAG, 'Q' );
|
||||
static Ki_HotkeyInfo HkMirrorYComponent( wxT( "Mirror Y Component" ),
|
||||
HK_MIRROR_Y_COMPONENT, 'Y' );
|
||||
static Ki_HotkeyInfo HkMirrorXComponent( wxT( "Mirror X Component" ),
|
||||
|
@ -146,11 +148,11 @@ static Ki_HotkeyInfo HkFindNextDrcMarker( wxT( "Find next DRC marker" ), HK_FIND
|
|||
WXK_F5 + GR_KB_SHIFT );
|
||||
|
||||
// Special keys for library editor:
|
||||
static Ki_HotkeyInfo HkCreatePin( wxT( "Create Pin" ),
|
||||
HK_LIBEDIT_CREATE_PIN, 'P' );
|
||||
static Ki_HotkeyInfo HkInsertPin( wxT( "Repeat Pin" ), HK_REPEAT_LAST,
|
||||
WXK_INSERT );
|
||||
static Ki_HotkeyInfo HkMovePin( wxT( "Move Pin" ), HK_LIBEDIT_MOVE_GRAPHIC_ITEM, 'M' );
|
||||
static Ki_HotkeyInfo HkDeletePin( wxT( "Delete Pin" ), HK_DELETE_PIN,
|
||||
WXK_DELETE );
|
||||
|
||||
|
||||
// List of common hotkey descriptors
|
||||
|
@ -190,16 +192,18 @@ Ki_HotkeyInfo* s_Schematic_Hotkey_List[] =
|
|||
&HkEditComponentFootprint,
|
||||
&HkBeginWire,
|
||||
&HkAddLabel,
|
||||
&HkAddNoConn,
|
||||
NULL
|
||||
};
|
||||
|
||||
// List of hotkey descriptors for library editor
|
||||
Ki_HotkeyInfo* s_LibEdit_Hotkey_List[] =
|
||||
{
|
||||
&HkCreatePin,
|
||||
&HkInsertPin,
|
||||
&HkEdit,
|
||||
&HkMovePin,
|
||||
&HkDeletePin,
|
||||
&HkDelete,
|
||||
&HkRotate,
|
||||
&HkDrag,
|
||||
NULL
|
||||
|
@ -332,7 +336,7 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey,
|
|||
if( !ItemInEdit && screen->m_BlockLocate.m_State == STATE_NO_BLOCK )
|
||||
{
|
||||
RefreshToolBar = LocateAndDeleteItem( this, DC );
|
||||
OnModify( );
|
||||
OnModify();
|
||||
GetScreen()->SetCurItem( NULL );
|
||||
TestDanglingEnds( GetScreen()->EEDrawList, DC );
|
||||
}
|
||||
|
@ -393,9 +397,10 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey,
|
|||
SetToolID( ID_LABEL_BUTT, wxCURSOR_PENCIL, _( "Add Label" ) );
|
||||
OnLeftClick( DC, MousePos );
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case HK_BEGIN_WIRE:
|
||||
|
||||
/* An item is selected. If edited and not a wire, a new command is not
|
||||
* possible */
|
||||
if( !ItemInEdit && screen->m_BlockLocate.m_State == STATE_NO_BLOCK )
|
||||
|
@ -419,6 +424,16 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey,
|
|||
}
|
||||
break;
|
||||
|
||||
case HK_ADD_NOCONN_FLAG: // Add a no connected flag
|
||||
if( !ItemInEdit )
|
||||
{
|
||||
if( m_ID_current_state != ID_NOCONN_BUTT )
|
||||
SetToolID( ID_NOCONN_BUTT, wxCURSOR_PENCIL,
|
||||
_( "Add a no connected flag" ) );
|
||||
OnLeftClick( DC, MousePos );
|
||||
}
|
||||
break;
|
||||
|
||||
case HK_ROTATE: // Component or other schematic item rotation
|
||||
|
||||
if( DrawStruct == NULL )
|
||||
|
@ -563,7 +578,7 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey,
|
|||
|
||||
// Create the events for moving a component or other schematic item
|
||||
wxCommandEvent eventMoveOrDragComponent( wxEVT_COMMAND_TOOL_CLICKED,
|
||||
HK_Descr->m_IdMenuEvent );
|
||||
HK_Descr->m_IdMenuEvent );
|
||||
wxCommandEvent eventMoveItem( wxEVT_COMMAND_TOOL_CLICKED,
|
||||
ID_POPUP_SCH_MOVE_ITEM_REQUEST );
|
||||
wxCommandEvent eventMovePinsheet( wxEVT_COMMAND_TOOL_CLICKED,
|
||||
|
@ -584,7 +599,7 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey,
|
|||
case TYPE_SCH_GLOBALLABEL:
|
||||
case TYPE_SCH_HIERLABEL:
|
||||
wxPostEvent( this, eventMoveOrDragComponent );
|
||||
break;
|
||||
break;
|
||||
|
||||
case TYPE_SCH_TEXT:
|
||||
case DRAW_PART_TEXT_STRUCT_TYPE:
|
||||
|
@ -831,8 +846,16 @@ void WinEDA_LibeditFrame::OnHotKey( wxDC* DC, int hotkey,
|
|||
}
|
||||
break;
|
||||
|
||||
case HK_LIBEDIT_CREATE_PIN:
|
||||
{
|
||||
wxCommandEvent evt;
|
||||
evt.SetId( ID_LIBEDIT_PIN_BUTT );
|
||||
Process_Special_Functions( evt );
|
||||
break;
|
||||
}
|
||||
|
||||
case HK_DELETE_PIN:
|
||||
|
||||
case HK_DELETE:
|
||||
m_drawItem = LocateItemUsingCursor();
|
||||
|
||||
if( m_drawItem )
|
||||
|
|
|
@ -15,15 +15,14 @@ enum hotkey_id_commnand {
|
|||
HK_FIND_ITEM,
|
||||
HK_DELETE,
|
||||
HK_REPEAT_LAST,
|
||||
HK_EDIT_PIN,
|
||||
HK_LIBEDIT_MOVE_GRAPHIC_ITEM,
|
||||
HK_LIBEDIT_ROTATE_PIN,
|
||||
HK_DELETE_PIN,
|
||||
HK_LIBEDIT_MOVE_GRAPHIC_ITEM,
|
||||
HK_MOVEBLOCK_TO_DRAGBLOCK,
|
||||
HK_LIBEDIT_CREATE_PIN,
|
||||
HK_DELETE_PIN,
|
||||
HK_ROTATE,
|
||||
HK_EDIT,
|
||||
HK_EDIT_COMPONENT_VALUE,
|
||||
HK_EDIT_COMPONENT_FOOTPRINT,
|
||||
HK_EDIT,
|
||||
HK_EDIT_COMPONENT_VALUE,
|
||||
HK_EDIT_COMPONENT_FOOTPRINT,
|
||||
HK_MIRROR_X_COMPONENT,
|
||||
HK_MIRROR_Y_COMPONENT,
|
||||
HK_ORIENT_NORMAL_COMPONENT,
|
||||
|
@ -32,16 +31,20 @@ enum hotkey_id_commnand {
|
|||
HK_DRAG,
|
||||
HK_ADD_NEW_COMPONENT,
|
||||
HK_BEGIN_WIRE,
|
||||
HK_ADD_LABEL
|
||||
HK_ADD_LABEL,
|
||||
HK_ADD_NOCONN_FLAG
|
||||
};
|
||||
|
||||
// List of hotkey descriptors for eeschema
|
||||
extern struct Ki_HotkeyInfoSectionDescriptor s_Eeschema_Hokeys_Descr[];
|
||||
|
||||
// List of hotkey descriptors for the schematic editor only
|
||||
extern struct Ki_HotkeyInfoSectionDescriptor s_Schematic_Hokeys_Descr[];
|
||||
|
||||
// List of hotkey descriptors for the lib editor only
|
||||
extern struct Ki_HotkeyInfoSectionDescriptor s_Libedit_Hokeys_Descr[];
|
||||
|
||||
// List of hotkey descriptors for the lib browser only
|
||||
extern struct Ki_HotkeyInfoSectionDescriptor s_Viewlib_Hokeys_Descr[];
|
||||
|
||||
#endif // KOTKEYS_H
|
||||
#endif // KOTKEYS_H
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/****************************/
|
||||
/* EESchema - libedit_onrightclick.cpp */
|
||||
/* EESchema - libedit_onrightclick.cpp */
|
||||
/****************************/
|
||||
|
||||
/* , In library editor, create the pop menu when clicking on mouse right button
|
||||
|
@ -85,21 +85,21 @@ bool WinEDA_LibeditFrame::OnRightClick( const wxPoint& MousePos,
|
|||
HK_LIBEDIT_MOVE_GRAPHIC_ITEM );
|
||||
ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_MOVE_ITEM_REQUEST,
|
||||
msg, move_arc_xpm );
|
||||
msg = AddHotkeyName( _( "Drag Arc Size" ), s_Libedit_Hokeys_Descr,
|
||||
HK_DRAG );
|
||||
ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_MODIFY_ITEM,
|
||||
msg = AddHotkeyName( _( "Drag Arc Size" ), s_Libedit_Hokeys_Descr,
|
||||
HK_DRAG );
|
||||
ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_MODIFY_ITEM,
|
||||
msg, move_arc_xpm );
|
||||
}
|
||||
|
||||
msg = AddHotkeyName( _( "Edit Arc Options" ), s_Libedit_Hokeys_Descr,
|
||||
HK_EDIT );
|
||||
HK_EDIT );
|
||||
ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_BODY_EDIT_ITEM,
|
||||
msg, options_arc_xpm );
|
||||
|
||||
if( DrawEntry->m_Flags == 0 )
|
||||
{
|
||||
msg = AddHotkeyName( _( "Delete Arc " ), s_Libedit_Hokeys_Descr,
|
||||
HK_DELETE_PIN );
|
||||
HK_DELETE );
|
||||
ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_DELETE_ITEM,
|
||||
msg, delete_arc_xpm );
|
||||
}
|
||||
|
@ -115,22 +115,22 @@ bool WinEDA_LibeditFrame::OnRightClick( const wxPoint& MousePos,
|
|||
}
|
||||
|
||||
if( DrawEntry->m_Flags == 0 )
|
||||
{
|
||||
msg = AddHotkeyName( _( "Drag Circle Outline" ), s_Libedit_Hokeys_Descr,
|
||||
HK_DRAG );
|
||||
ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_MODIFY_ITEM,
|
||||
msg, move_rectangle_xpm );
|
||||
}
|
||||
{
|
||||
msg = AddHotkeyName( _( "Drag Circle Outline" ), s_Libedit_Hokeys_Descr,
|
||||
HK_DRAG );
|
||||
ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_MODIFY_ITEM,
|
||||
msg, move_rectangle_xpm );
|
||||
}
|
||||
|
||||
msg = AddHotkeyName( _( "Edit Circle Options" ), s_Libedit_Hokeys_Descr,
|
||||
HK_EDIT );
|
||||
HK_EDIT );
|
||||
ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_BODY_EDIT_ITEM,
|
||||
msg, options_circle_xpm );
|
||||
|
||||
if( DrawEntry->m_Flags == 0 )
|
||||
{
|
||||
msg = AddHotkeyName( _( "Delete Circle " ),
|
||||
s_Libedit_Hokeys_Descr, HK_DELETE_PIN );
|
||||
s_Libedit_Hokeys_Descr, HK_DELETE );
|
||||
ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_DELETE_ITEM,
|
||||
msg, delete_circle_xpm );
|
||||
}
|
||||
|
@ -146,22 +146,22 @@ bool WinEDA_LibeditFrame::OnRightClick( const wxPoint& MousePos,
|
|||
}
|
||||
|
||||
msg = AddHotkeyName( _( "Edit Rectangle Options" ), s_Libedit_Hokeys_Descr,
|
||||
HK_EDIT );
|
||||
HK_EDIT );
|
||||
ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_BODY_EDIT_ITEM,
|
||||
msg, options_rectangle_xpm );
|
||||
|
||||
if( DrawEntry->m_Flags == 0 )
|
||||
{
|
||||
msg = AddHotkeyName( _( "Drag Rectangle Edge" ), s_Libedit_Hokeys_Descr,
|
||||
HK_DRAG );
|
||||
ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_MODIFY_ITEM,
|
||||
msg, move_rectangle_xpm );
|
||||
}
|
||||
{
|
||||
msg = AddHotkeyName( _( "Drag Rectangle Edge" ), s_Libedit_Hokeys_Descr,
|
||||
HK_DRAG );
|
||||
ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_MODIFY_ITEM,
|
||||
msg, move_rectangle_xpm );
|
||||
}
|
||||
|
||||
if( DrawEntry->m_Flags == 0 )
|
||||
{
|
||||
msg = AddHotkeyName( _( "Delete Rectangle " ), s_Libedit_Hokeys_Descr,
|
||||
HK_DELETE_PIN );
|
||||
HK_DELETE );
|
||||
ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_DELETE_ITEM,
|
||||
msg, delete_rectangle_xpm );
|
||||
}
|
||||
|
@ -178,19 +178,19 @@ bool WinEDA_LibeditFrame::OnRightClick( const wxPoint& MousePos,
|
|||
}
|
||||
|
||||
msg = AddHotkeyName( _( "Edit Text " ), s_Libedit_Hokeys_Descr,
|
||||
HK_EDIT );
|
||||
HK_EDIT );
|
||||
ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_BODY_EDIT_ITEM,
|
||||
msg, edit_text_xpm );
|
||||
|
||||
msg = AddHotkeyName( _( "Rotate Text " ), s_Libedit_Hokeys_Descr,
|
||||
HK_ROTATE );
|
||||
HK_ROTATE );
|
||||
ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_ROTATE_GRAPHIC_TEXT,
|
||||
msg, edit_text_xpm );
|
||||
|
||||
if( DrawEntry->m_Flags == 0 )
|
||||
{
|
||||
msg = AddHotkeyName( _( "Delete Text " ), s_Libedit_Hokeys_Descr,
|
||||
HK_DELETE_PIN );
|
||||
HK_DELETE );
|
||||
ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_DELETE_ITEM,
|
||||
msg, delete_text_xpm );
|
||||
}
|
||||
|
@ -203,9 +203,9 @@ bool WinEDA_LibeditFrame::OnRightClick( const wxPoint& MousePos,
|
|||
HK_LIBEDIT_MOVE_GRAPHIC_ITEM );
|
||||
ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_MOVE_ITEM_REQUEST,
|
||||
msg, move_line_xpm );
|
||||
msg = AddHotkeyName( _( "Drag Edge Point" ), s_Libedit_Hokeys_Descr,
|
||||
HK_DRAG );
|
||||
ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_MODIFY_ITEM,
|
||||
msg = AddHotkeyName( _( "Drag Edge Point" ), s_Libedit_Hokeys_Descr,
|
||||
HK_DRAG );
|
||||
ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_MODIFY_ITEM,
|
||||
msg, move_line_xpm );
|
||||
}
|
||||
|
||||
|
@ -216,14 +216,14 @@ bool WinEDA_LibeditFrame::OnRightClick( const wxPoint& MousePos,
|
|||
}
|
||||
|
||||
msg = AddHotkeyName( _( "Edit Line Options" ), s_Libedit_Hokeys_Descr,
|
||||
HK_EDIT );
|
||||
HK_EDIT );
|
||||
ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_BODY_EDIT_ITEM,
|
||||
msg, options_segment_xpm );
|
||||
|
||||
if( DrawEntry->m_Flags == 0 )
|
||||
{
|
||||
msg = AddHotkeyName( _( "Delete Line " ), s_Libedit_Hokeys_Descr,
|
||||
HK_DELETE_PIN );
|
||||
HK_DELETE );
|
||||
ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_DELETE_ITEM,
|
||||
msg, delete_segment_xpm );
|
||||
}
|
||||
|
@ -232,7 +232,7 @@ bool WinEDA_LibeditFrame::OnRightClick( const wxPoint& MousePos,
|
|||
if( ( (LIB_POLYLINE*) DrawEntry )->GetCornerCount() > 2 )
|
||||
{
|
||||
msg = AddHotkeyName( _( "Delete Segment " ),
|
||||
s_Libedit_Hokeys_Descr, HK_DELETE_PIN );
|
||||
s_Libedit_Hokeys_Descr, HK_DELETE );
|
||||
ADD_MENUITEM( PopMenu,
|
||||
ID_POPUP_LIBEDIT_DELETE_CURRENT_POLY_SEGMENT,
|
||||
msg, delete_segment_xpm );
|
||||
|
@ -296,7 +296,7 @@ void AddMenusForPin( wxMenu* PopMenu,
|
|||
if( not_in_move )
|
||||
{
|
||||
msg = AddHotkeyName( _( "Delete Pin " ), s_Libedit_Hokeys_Descr,
|
||||
HK_DELETE_PIN );
|
||||
HK_DELETE );
|
||||
ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_DELETE_ITEM,
|
||||
msg, delete_pin_xpm );
|
||||
}
|
||||
|
|
|
@ -24,9 +24,9 @@
|
|||
*/
|
||||
void WinEDA_SchematicFrame::ReCreateMenuBar()
|
||||
{
|
||||
wxString text;
|
||||
wxMenuItem *item;
|
||||
wxMenuBar *menuBar = GetMenuBar();
|
||||
wxString text;
|
||||
wxMenuItem* item;
|
||||
wxMenuBar* menuBar = GetMenuBar();
|
||||
|
||||
/**
|
||||
* Destroy the existing menu bar so it can be rebuilt. This allows
|
||||
|
@ -44,14 +44,14 @@ void WinEDA_SchematicFrame::ReCreateMenuBar()
|
|||
|
||||
/* New */
|
||||
item = new wxMenuItem( filesMenu, ID_NEW_PROJECT, _( "&New\tCtrl+N" ),
|
||||
_( "New schematic project" ) );
|
||||
_( "New schematic project" ) );
|
||||
|
||||
item->SetBitmap( new_xpm );
|
||||
filesMenu->Append( item );
|
||||
|
||||
/* Open */
|
||||
/* Open */
|
||||
item = new wxMenuItem( filesMenu, ID_LOAD_PROJECT, _( "&Open\tCtrl+O" ),
|
||||
_( "Open an existing schematic project" ) );
|
||||
_( "Open an existing schematic project" ) );
|
||||
item->SetBitmap( open_xpm );
|
||||
filesMenu->Append( item );
|
||||
|
||||
|
@ -60,7 +60,7 @@ void WinEDA_SchematicFrame::ReCreateMenuBar()
|
|||
wxGetApp().m_fileHistory.AddFilesToMenu( openRecentMenu );
|
||||
ADD_MENUITEM_WITH_HELP_AND_SUBMENU( filesMenu, openRecentMenu,
|
||||
-1, _( "Open &Recent" ),
|
||||
_("Open a recent opened schematic project" ),
|
||||
_( "Open a recent opened schematic project" ),
|
||||
open_project_xpm );
|
||||
|
||||
/* Separator */
|
||||
|
@ -69,20 +69,20 @@ void WinEDA_SchematicFrame::ReCreateMenuBar()
|
|||
/* Save */
|
||||
/* Save Project */
|
||||
item = new wxMenuItem( filesMenu, ID_SAVE_PROJECT,
|
||||
_( "&Save Whole Schematic Project\tCtrl+S" ),
|
||||
_( "Save all sheets in the schematic project" ) );
|
||||
_( "&Save Whole Schematic Project\tCtrl+S" ),
|
||||
_( "Save all sheets in the schematic project" ) );
|
||||
item->SetBitmap( save_project_xpm );
|
||||
filesMenu->Append( item );
|
||||
|
||||
item = new wxMenuItem( filesMenu, ID_SAVE_ONE_SHEET, _( "Save &Current Sheet Only" ),
|
||||
_( "Save only current schematic sheet" ) );
|
||||
_( "Save only current schematic sheet" ) );
|
||||
item->SetBitmap( save_xpm );
|
||||
filesMenu->Append( item );
|
||||
|
||||
/* Save as... */
|
||||
item = new wxMenuItem( filesMenu, ID_SAVE_ONE_SHEET_AS,
|
||||
_( "Save Current Sheet &as" ),
|
||||
_( "Save current schematic sheet as..." ) );
|
||||
_( "Save Current Sheet &as" ),
|
||||
_( "Save current schematic sheet as..." ) );
|
||||
item->SetBitmap( save_as_xpm );
|
||||
filesMenu->Append( item );
|
||||
|
||||
|
@ -91,33 +91,33 @@ void WinEDA_SchematicFrame::ReCreateMenuBar()
|
|||
|
||||
/* Print */
|
||||
item = new wxMenuItem( filesMenu, wxID_PRINT, _( "P&rint" ),
|
||||
_( "Print schematic" ) );
|
||||
_( "Print schematic" ) );
|
||||
item->SetBitmap( print_button );
|
||||
filesMenu->Append( item );
|
||||
|
||||
/* Plot submenu */
|
||||
wxMenu* choice_plot_fmt = new wxMenu;
|
||||
item = new wxMenuItem( choice_plot_fmt, ID_GEN_PLOT_PS,
|
||||
_( "Plot PostScript" ),
|
||||
_( "Plot schematic sheet in PostScript format" ) );
|
||||
_( "Plot PostScript" ),
|
||||
_( "Plot schematic sheet in PostScript format" ) );
|
||||
item->SetBitmap( plot_PS_xpm );
|
||||
choice_plot_fmt->Append( item );
|
||||
|
||||
/* Plot HPGL */
|
||||
item = new wxMenuItem( choice_plot_fmt, ID_GEN_PLOT_HPGL, _( "Plot HPGL" ),
|
||||
_( "Plot schematic sheet in HPGL format" ) );
|
||||
_( "Plot schematic sheet in HPGL format" ) );
|
||||
item->SetBitmap( plot_HPG_xpm );
|
||||
choice_plot_fmt->Append( item );
|
||||
|
||||
/* Plot SVG */
|
||||
item = new wxMenuItem( choice_plot_fmt, ID_GEN_PLOT_SVG, _( "Plot SVG" ),
|
||||
_( "Plot schematic sheet in SVG format" ) );
|
||||
_( "Plot schematic sheet in SVG format" ) );
|
||||
item->SetBitmap( plot_xpm );
|
||||
choice_plot_fmt->Append( item );
|
||||
|
||||
/* Plot DXF */
|
||||
item = new wxMenuItem( choice_plot_fmt, ID_GEN_PLOT_DXF, _( "Plot DXF" ),
|
||||
_( "Plot schematic sheet in DXF format" ) );
|
||||
_( "Plot schematic sheet in DXF format" ) );
|
||||
item->SetBitmap( plot_xpm );
|
||||
choice_plot_fmt->Append( item );
|
||||
|
||||
|
@ -125,8 +125,8 @@ void WinEDA_SchematicFrame::ReCreateMenuBar()
|
|||
#ifdef __WINDOWS__
|
||||
|
||||
item = new wxMenuItem( choice_plot_fmt, ID_GEN_COPY_SHEET_TO_CLIPBOARD,
|
||||
_( "Plot to Clipboard" ),
|
||||
_( "Export drawings to clipboard" ) );
|
||||
_( "Plot to Clipboard" ),
|
||||
_( "Export drawings to clipboard" ) );
|
||||
item->SetBitmap( copy_button );
|
||||
choice_plot_fmt->Append( item );
|
||||
|
||||
|
@ -134,7 +134,8 @@ void WinEDA_SchematicFrame::ReCreateMenuBar()
|
|||
|
||||
ADD_MENUITEM_WITH_HELP_AND_SUBMENU( filesMenu, choice_plot_fmt,
|
||||
ID_GEN_PLOT, _( "&Plot" ),
|
||||
_( "Plot schematic sheet in HPGL, PostScript or SVG format" ),
|
||||
_(
|
||||
"Plot schematic sheet in HPGL, PostScript or SVG format" ),
|
||||
plot_xpm );
|
||||
|
||||
/* Quit on all platforms except WXMAC */
|
||||
|
@ -142,20 +143,19 @@ void WinEDA_SchematicFrame::ReCreateMenuBar()
|
|||
|
||||
filesMenu->AppendSeparator();
|
||||
item = new wxMenuItem( filesMenu, wxID_EXIT, _( "&Quit" ),
|
||||
_( "Quit EESchema" ) );
|
||||
_( "Quit EESchema" ) );
|
||||
filesMenu->Append( item );
|
||||
|
||||
#endif /* !defined( __WXMAC__) */
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Edit menu
|
||||
*/
|
||||
wxMenu* editMenu = new wxMenu;
|
||||
|
||||
/* Undo */
|
||||
text = AddHotkeyName( _( "Undo" ), s_Schematic_Hokeys_Descr, HK_UNDO);
|
||||
text = AddHotkeyName( _( "Undo" ), s_Schematic_Hokeys_Descr, HK_UNDO );
|
||||
|
||||
item = new wxMenuItem( editMenu, wxID_UNDO, text,
|
||||
HELP_UNDO, wxITEM_NORMAL );
|
||||
|
@ -163,7 +163,7 @@ void WinEDA_SchematicFrame::ReCreateMenuBar()
|
|||
editMenu->Append( item );
|
||||
|
||||
/* Redo */
|
||||
text = AddHotkeyName( _( "Redo" ), s_Schematic_Hokeys_Descr, HK_REDO);
|
||||
text = AddHotkeyName( _( "Redo" ), s_Schematic_Hokeys_Descr, HK_REDO );
|
||||
|
||||
item = new wxMenuItem( editMenu, wxID_REDO, text,
|
||||
HELP_REDO, wxITEM_NORMAL );
|
||||
|
@ -200,14 +200,13 @@ void WinEDA_SchematicFrame::ReCreateMenuBar()
|
|||
editMenu->Append( item );
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* View menu
|
||||
*/
|
||||
wxMenu* viewMenu = new wxMenu;
|
||||
|
||||
/* Important Note for ZOOM IN and ZOOM OUT commands from menubar:
|
||||
* we cannot add hotkey info here, because the hotkey HK_ZOOM_IN and HK_ZOOM_OUT
|
||||
* we cannot add hotkey shortcut here, because the hotkey HK_ZOOM_IN and HK_ZOOM_OUT
|
||||
* events(default = WXK_F1 and WXK_F2) are *NOT* equivalent to this menu command:
|
||||
* zoom in and out from hotkeys are equivalent to the pop up menu zoom
|
||||
* From here, zoomming is made around the screen center
|
||||
|
@ -216,16 +215,20 @@ void WinEDA_SchematicFrame::ReCreateMenuBar()
|
|||
*
|
||||
* in others words HK_ZOOM_IN and HK_ZOOM_OUT *are NOT* accelerators
|
||||
* for Zoom in and Zoom out sub menus
|
||||
* SO WE ADD THE NAME OF THE CORRESPONDING HOTKEY AS A COMMENT, NOT AS A SHORTCUT
|
||||
* using in AddHotkeyName call the option "false" (not a shortcut)
|
||||
*/
|
||||
/* Zoom in */
|
||||
text =_( "Zoom In" );
|
||||
text = AddHotkeyName( _( "Zoom In" ), s_Schematic_Hokeys_Descr,
|
||||
ID_ZOOM_IN, false ); // add comment, not a shortcut
|
||||
item = new wxMenuItem( viewMenu, ID_ZOOM_IN, text, HELP_ZOOM_IN,
|
||||
wxITEM_NORMAL );
|
||||
item->SetBitmap( zoom_in_xpm );
|
||||
viewMenu->Append( item );
|
||||
|
||||
/* Zoom out */
|
||||
text = _( "Zoom Out" );
|
||||
text = AddHotkeyName( _( "Zoom Out" ), s_Schematic_Hokeys_Descr,
|
||||
ID_ZOOM_OUT, false ); // add comment, not a shortcut
|
||||
item = new wxMenuItem( viewMenu, ID_ZOOM_OUT, text, HELP_ZOOM_OUT,
|
||||
wxITEM_NORMAL );
|
||||
item->SetBitmap( zoom_out_xpm );
|
||||
|
@ -252,7 +255,6 @@ void WinEDA_SchematicFrame::ReCreateMenuBar()
|
|||
viewMenu->Append( item );
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Place menu
|
||||
* TODO: Unify the ID names!
|
||||
|
@ -260,7 +262,9 @@ void WinEDA_SchematicFrame::ReCreateMenuBar()
|
|||
wxMenu* placeMenu = new wxMenu;
|
||||
|
||||
/* Component */
|
||||
item = new wxMenuItem( placeMenu, ID_COMPONENT_BUTT, _( "&Component" ),
|
||||
text = AddHotkeyName( _( "&Component" ), s_Schematic_Hokeys_Descr,
|
||||
HK_ADD_NEW_COMPONENT, false ); // add comment, not a shortcut
|
||||
item = new wxMenuItem( placeMenu, ID_COMPONENT_BUTT, text,
|
||||
HELP_PLACE_COMPONENTS, wxITEM_NORMAL );
|
||||
item->SetBitmap( add_component_xpm );
|
||||
placeMenu->Append( item );
|
||||
|
@ -272,13 +276,15 @@ void WinEDA_SchematicFrame::ReCreateMenuBar()
|
|||
placeMenu->Append( item );
|
||||
|
||||
/* Wire */
|
||||
item = new wxMenuItem( placeMenu, ID_WIRE_BUTT, _( "&Wire" ),
|
||||
text = AddHotkeyName( _( "&Wire" ), s_Schematic_Hokeys_Descr,
|
||||
HK_BEGIN_WIRE, false ); // add comment, not a shortcut
|
||||
item = new wxMenuItem( placeMenu, ID_WIRE_BUTT, text,
|
||||
HELP_PLACE_WIRE, wxITEM_NORMAL );
|
||||
item->SetBitmap( add_line_xpm );
|
||||
placeMenu->Append( item );
|
||||
|
||||
/* Bus */
|
||||
item = new wxMenuItem( placeMenu, ID_BUS_BUTT, _( "&Bus" ),
|
||||
item = new wxMenuItem( placeMenu, ID_BUS_BUTT, _( "&Bus" ),
|
||||
HELP_PLACE_BUS, wxITEM_NORMAL );
|
||||
item->SetBitmap( add_bus_xpm );
|
||||
placeMenu->Append( item );
|
||||
|
@ -298,20 +304,25 @@ void WinEDA_SchematicFrame::ReCreateMenuBar()
|
|||
placeMenu->Append( item );
|
||||
|
||||
/* No connect flag */
|
||||
item = new wxMenuItem( placeMenu, ID_NOCONN_BUTT, _( "No connect flag" ),
|
||||
text = AddHotkeyName( _( "No connect flag" ), s_Schematic_Hokeys_Descr,
|
||||
HK_ADD_NOCONN_FLAG, false ); // add comment, not a shortcut
|
||||
item = new wxMenuItem( placeMenu, ID_NOCONN_BUTT, text,
|
||||
HELP_PLACE_NC_FLAG, wxITEM_NORMAL );
|
||||
item->SetBitmap( noconn_button );
|
||||
placeMenu->Append( item );
|
||||
|
||||
/* Net name */
|
||||
item = new wxMenuItem( placeMenu, ID_LABEL_BUTT, _( "Label" ),
|
||||
text = AddHotkeyName( _( "Label" ), s_Schematic_Hokeys_Descr,
|
||||
HK_ADD_LABEL, false ); // add comment, not a shortcut
|
||||
item = new wxMenuItem( placeMenu, ID_LABEL_BUTT, text,
|
||||
HELP_PLACE_NETLABEL, wxITEM_NORMAL );
|
||||
item->SetBitmap( add_line_label_xpm );
|
||||
placeMenu->Append( item );
|
||||
|
||||
/* Global label */
|
||||
item = new wxMenuItem( placeMenu, ID_GLABEL_BUTT, _( "Global label" ),
|
||||
_( "Place a global label. Warning: all global labels with the same name are connected in whole hierarchy" ),
|
||||
_(
|
||||
"Place a global label. Warning: all global labels with the same name are connected in whole hierarchy" ),
|
||||
wxITEM_NORMAL );
|
||||
item->SetBitmap( add_glabel_xpm );
|
||||
placeMenu->Append( item );
|
||||
|
@ -371,7 +382,6 @@ void WinEDA_SchematicFrame::ReCreateMenuBar()
|
|||
placeMenu->Append( item );
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Preferences Menu
|
||||
*/
|
||||
|
@ -379,19 +389,19 @@ void WinEDA_SchematicFrame::ReCreateMenuBar()
|
|||
|
||||
/* Library */
|
||||
item = new wxMenuItem( configmenu, ID_CONFIG_REQ, _( "&Library" ),
|
||||
_( "Library preferences" ) );
|
||||
_( "Library preferences" ) );
|
||||
item->SetBitmap( library_xpm );
|
||||
configmenu->Append( item );
|
||||
|
||||
/* Colors */
|
||||
item = new wxMenuItem( configmenu, ID_COLORS_SETUP, _( "&Colors" ),
|
||||
_( "Color preferences" ) );
|
||||
_( "Color preferences" ) );
|
||||
item->SetBitmap( palette_xpm );
|
||||
configmenu->Append( item );
|
||||
|
||||
/* Options */
|
||||
item = new wxMenuItem( configmenu, ID_OPTIONS_SETUP, _( "&Options" ),
|
||||
_( "Eeschema general options and preferences" ) );
|
||||
_( "Eeschema general options and preferences" ) );
|
||||
item->SetBitmap( preference_xpm );
|
||||
configmenu->Append( item );
|
||||
|
||||
|
@ -406,24 +416,23 @@ void WinEDA_SchematicFrame::ReCreateMenuBar()
|
|||
|
||||
/* Save preferences */
|
||||
item = new wxMenuItem( configmenu, ID_CONFIG_SAVE, _( "&Save preferences" ),
|
||||
_( "Save application preferences" ) );
|
||||
_( "Save application preferences" ) );
|
||||
item->SetBitmap( save_setup_xpm );
|
||||
configmenu->Append( item );
|
||||
|
||||
/* Read preferences */
|
||||
item = new wxMenuItem( configmenu, ID_CONFIG_READ, _( "&Read preferences" ),
|
||||
_( "Read application preferences" ) );
|
||||
_( "Read application preferences" ) );
|
||||
item->SetBitmap( read_setup_xpm );
|
||||
configmenu->Append( item );
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Help Menu
|
||||
*/
|
||||
wxMenu* helpMenu = new wxMenu;
|
||||
item = new wxMenuItem( helpMenu, ID_GENERAL_HELP, _( "&Contents" ),
|
||||
_( "Open the eeschema manual" ) );
|
||||
_( "Open the eeschema manual" ) );
|
||||
item->SetBitmap( online_help_xpm );
|
||||
helpMenu->Append( item );
|
||||
|
||||
|
@ -431,7 +440,7 @@ void WinEDA_SchematicFrame::ReCreateMenuBar()
|
|||
#if !defined(__WXMAC__)
|
||||
|
||||
item = new wxMenuItem( helpMenu, ID_KICAD_ABOUT, _( "&About" ),
|
||||
_( "About eeschema schematic designer" ) );
|
||||
_( "About eeschema schematic designer" ) );
|
||||
item->SetBitmap( info_xpm );
|
||||
helpMenu->Append( item );
|
||||
|
||||
|
|
|
@ -104,13 +104,13 @@ void WinEDA_GerberFrame::Process_Special_Functions( wxCommandEvent& event )
|
|||
GetScreen()->m_BlockLocate.ClearItemsList();
|
||||
}
|
||||
if( m_ID_current_state == 0 )
|
||||
SetToolID( 0, wxCURSOR_ARROW, wxEmptyString );
|
||||
SetToolID( 0, 0, wxEmptyString );
|
||||
else
|
||||
SetCursor( DrawPanel->m_PanelCursor = DrawPanel->m_PanelDefaultCursor );
|
||||
DrawPanel->SetCursor( DrawPanel->m_PanelCursor = DrawPanel->m_PanelDefaultCursor );
|
||||
break;
|
||||
|
||||
default:
|
||||
DrawPanel->UnManageCursor( 0, wxCURSOR_ARROW, wxEmptyString );
|
||||
DrawPanel->UnManageCursor( 0, 0, wxEmptyString );
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -146,7 +146,7 @@ void WinEDA_GerberFrame::Process_Special_Functions( wxCommandEvent& event )
|
|||
break;
|
||||
|
||||
case ID_POPUP_CLOSE_CURRENT_TOOL:
|
||||
SetToolID( 0, wxCURSOR_ARROW, wxEmptyString );
|
||||
SetToolID( 0, 0, wxEmptyString );
|
||||
break;
|
||||
|
||||
case ID_POPUP_CANCEL_CURRENT_COMMAND:
|
||||
|
@ -172,8 +172,6 @@ void WinEDA_GerberFrame::Process_Special_Functions( wxCommandEvent& event )
|
|||
gerber_layer->m_Selected_Tool = tool;
|
||||
DrawPanel->Refresh( TRUE );
|
||||
}
|
||||
else
|
||||
DisplayError( this, _( "No layer selected" ) );
|
||||
break;
|
||||
|
||||
case ID_GERBVIEW_SHOW_LIST_DCODES:
|
||||
|
|
|
@ -131,10 +131,13 @@ WinEDA_GerberFrame::WinEDA_GerberFrame( wxWindow* father,
|
|||
m_show_layer_manager_tools = true;
|
||||
|
||||
m_Draw_Axis = true; // true to show X and Y axis on screen
|
||||
m_Draw_Sheet_Ref = FALSE; // TRUE for reference drawings.
|
||||
m_Draw_Sheet_Ref = false; // true for reference drawings.
|
||||
m_HotkeysZoomAndGridList = s_Gerbview_Hokeys_Descr;
|
||||
m_SelLayerBox = NULL;
|
||||
m_SelLayerTool = NULL;
|
||||
|
||||
if( DrawPanel )
|
||||
DrawPanel->m_Block_Enable = TRUE;
|
||||
DrawPanel->m_Block_Enable = true;
|
||||
|
||||
// Give an icon
|
||||
#ifdef __WINDOWS__
|
||||
|
@ -238,7 +241,8 @@ void WinEDA_GerberFrame::OnCloseWindow( wxCloseEvent& Event )
|
|||
*/
|
||||
void WinEDA_GerberFrame::SetToolbars()
|
||||
{
|
||||
int layer = ( (PCB_SCREEN*) GetScreen() )->m_Active_Layer;
|
||||
PCB_SCREEN* screen = (PCB_SCREEN*) GetScreen();
|
||||
int layer = screen->m_Active_Layer;
|
||||
GERBER* gerber = g_GERBER_List[layer];
|
||||
|
||||
if( m_HToolBar == NULL )
|
||||
|
@ -246,40 +250,41 @@ void WinEDA_GerberFrame::SetToolbars()
|
|||
|
||||
if( GetScreen()->m_BlockLocate.m_Command == BLOCK_MOVE )
|
||||
{
|
||||
m_HToolBar->EnableTool( wxID_CUT, TRUE );
|
||||
m_HToolBar->EnableTool( wxID_COPY, TRUE );
|
||||
m_HToolBar->EnableTool( wxID_CUT, true );
|
||||
m_HToolBar->EnableTool( wxID_COPY, true );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_HToolBar->EnableTool( wxID_CUT, FALSE );
|
||||
m_HToolBar->EnableTool( wxID_COPY, FALSE );
|
||||
m_HToolBar->EnableTool( wxID_CUT, false );
|
||||
m_HToolBar->EnableTool( wxID_COPY, false );
|
||||
}
|
||||
|
||||
if( m_SelLayerBox->GetSelection() !=
|
||||
( (PCB_SCREEN*) GetScreen() )->m_Active_Layer )
|
||||
if( m_SelLayerBox && (m_SelLayerBox->GetSelection() != screen->m_Active_Layer) )
|
||||
{
|
||||
m_SelLayerBox->SetSelection(
|
||||
( (PCB_SCREEN*) GetScreen() )->m_Active_Layer );
|
||||
m_SelLayerBox->SetSelection( screen->m_Active_Layer );
|
||||
}
|
||||
|
||||
if( gerber )
|
||||
if( m_SelLayerTool )
|
||||
{
|
||||
int sel_index;
|
||||
m_SelLayerTool->Enable( TRUE );
|
||||
if( gerber->m_Selected_Tool < FIRST_DCODE ) // No tool selected
|
||||
sel_index = 0;
|
||||
else
|
||||
sel_index = gerber->m_Selected_Tool - FIRST_DCODE + 1;
|
||||
|
||||
if( sel_index != m_SelLayerTool->GetSelection() )
|
||||
if( gerber )
|
||||
{
|
||||
m_SelLayerTool->SetSelection( sel_index );
|
||||
int sel_index;
|
||||
m_SelLayerTool->Enable( true );
|
||||
if( gerber->m_Selected_Tool < FIRST_DCODE ) // No tool selected
|
||||
sel_index = 0;
|
||||
else
|
||||
sel_index = gerber->m_Selected_Tool - FIRST_DCODE + 1;
|
||||
|
||||
if( sel_index != m_SelLayerTool->GetSelection() )
|
||||
{
|
||||
m_SelLayerTool->SetSelection( sel_index );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_SelLayerTool->SetSelection( 0 );
|
||||
m_SelLayerTool->Enable( false );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_SelLayerTool->SetSelection( 0 );
|
||||
m_SelLayerTool->Enable( FALSE );
|
||||
}
|
||||
|
||||
if( m_OptionsToolBar )
|
||||
|
@ -287,9 +292,9 @@ void WinEDA_GerberFrame::SetToolbars()
|
|||
m_OptionsToolBar->ToggleTool(
|
||||
ID_TB_OPTIONS_SELECT_UNIT_MM,
|
||||
g_UserUnit ==
|
||||
MILLIMETRES ? TRUE : FALSE );
|
||||
MILLIMETRES ? true : false );
|
||||
m_OptionsToolBar->ToggleTool( ID_TB_OPTIONS_SELECT_UNIT_INCH,
|
||||
g_UserUnit == INCHES ? TRUE : FALSE );
|
||||
g_UserUnit == INCHES ? true : false );
|
||||
|
||||
m_OptionsToolBar->ToggleTool( ID_TB_OPTIONS_SHOW_POLAR_COORD,
|
||||
DisplayOpt.DisplayPolarCood );
|
||||
|
|
|
@ -105,7 +105,6 @@ bool WinEDA_App::OnInit()
|
|||
* main frame in order to display the
|
||||
* real hotkeys in menus or tool tips
|
||||
*/
|
||||
|
||||
frame = new WinEDA_GerberFrame( NULL, wxT( "GerbView" ),
|
||||
wxPoint( 0, 0 ),
|
||||
wxSize( 600, 400 ) );
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
/***************************************************/
|
||||
|
||||
#include "fctsys.h"
|
||||
#include "wx/wupdlock.h"
|
||||
|
||||
#include "appl_wxstruct.h"
|
||||
#include "common.h"
|
||||
#include "macros.h"
|
||||
|
@ -16,6 +18,8 @@
|
|||
|
||||
void WinEDA_GerberFrame::ReCreateMenuBar( void )
|
||||
{
|
||||
wxWindowUpdateLocker dummy(this);
|
||||
|
||||
wxMenuBar *menuBar = GetMenuBar();
|
||||
|
||||
/* Destroy the existing menu bar so it can be rebuilt. This allows
|
||||
|
@ -143,6 +147,10 @@ void WinEDA_GerberFrame::ReCreateHToolbar( void )
|
|||
if( m_HToolBar != NULL )
|
||||
return;
|
||||
|
||||
// we create m_SelLayerTool that have a lot of items,
|
||||
// so create a wxWindowUpdateLocker is a good idea
|
||||
wxWindowUpdateLocker dummy(this);
|
||||
|
||||
if( GetScreen() )
|
||||
{
|
||||
layer = GetScreen()->m_Active_Layer;
|
||||
|
@ -214,11 +222,12 @@ void WinEDA_GerberFrame::ReCreateHToolbar( void )
|
|||
ID_TOOLBARH_GERBVIEW_SELECT_LAYER,
|
||||
wxDefaultPosition, wxSize( 150, -1 ),
|
||||
choices );
|
||||
m_SelLayerBox->SetSelection( getActiveLayer() );
|
||||
m_HToolBar->AddControl( m_SelLayerBox );
|
||||
|
||||
m_HToolBar->AddSeparator();
|
||||
choices.Clear();
|
||||
|
||||
choices.Alloc(MAX_TOOLS+1);
|
||||
choices.Add( _( "No tool" ) );
|
||||
|
||||
for( ii = 0; ii < MAX_TOOLS; ii++ )
|
||||
|
@ -227,7 +236,6 @@ void WinEDA_GerberFrame::ReCreateHToolbar( void )
|
|||
msg = _( "Tool " ); msg << ii + FIRST_DCODE;
|
||||
choices.Add( msg );
|
||||
}
|
||||
|
||||
m_SelLayerTool = new WinEDAChoiceBox( m_HToolBar,
|
||||
ID_TOOLBARH_GERBER_SELECT_TOOL,
|
||||
wxDefaultPosition, wxSize( 150, -1 ),
|
||||
|
@ -238,7 +246,6 @@ void WinEDA_GerberFrame::ReCreateHToolbar( void )
|
|||
// after adding the buttons to the toolbar, must call Realize() to reflect
|
||||
// the changes
|
||||
m_HToolBar->Realize();
|
||||
SetToolbars();
|
||||
}
|
||||
|
||||
|
||||
|
@ -250,6 +257,8 @@ void WinEDA_GerberFrame::ReCreateVToolbar( void )
|
|||
if( m_VToolBar )
|
||||
return;
|
||||
|
||||
wxWindowUpdateLocker dummy(this);
|
||||
|
||||
m_VToolBar = new WinEDA_Toolbar( TOOLBAR_TOOL, this, ID_V_TOOLBAR, FALSE );
|
||||
|
||||
// Set up toolbar
|
||||
|
@ -262,7 +271,6 @@ void WinEDA_GerberFrame::ReCreateVToolbar( void )
|
|||
_( "Delete items" ) );
|
||||
|
||||
m_VToolBar->Realize();
|
||||
SetToolbars();
|
||||
}
|
||||
|
||||
|
||||
|
@ -274,6 +282,8 @@ void WinEDA_GerberFrame::ReCreateOptToolbar( void )
|
|||
if( m_OptionsToolBar )
|
||||
return;
|
||||
|
||||
wxWindowUpdateLocker dummy(this);
|
||||
|
||||
// creation of tool bar options
|
||||
m_OptionsToolBar = new WinEDA_Toolbar( TOOLBAR_OPTION, this,
|
||||
ID_OPT_TOOLBAR, FALSE );
|
||||
|
@ -327,5 +337,4 @@ void WinEDA_GerberFrame::ReCreateOptToolbar( void )
|
|||
|
||||
|
||||
m_OptionsToolBar->Realize();
|
||||
SetToolbars();
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
boost version: 1_40_0
|
||||
boost version: 1_43_0
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
// Copyright David Abrahams 2006. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_CONCEPT_ASSERT_DWA2006430_HPP
|
||||
# define BOOST_CONCEPT_ASSERT_DWA2006430_HPP
|
||||
|
||||
# include <boost/config.hpp>
|
||||
# include <boost/detail/workaround.hpp>
|
||||
|
||||
// The old protocol used a constraints() member function in concept
|
||||
// checking classes. If the compiler supports SFINAE, we can detect
|
||||
// that function and seamlessly support the old concept checking
|
||||
// classes. In this release, backward compatibility with the old
|
||||
// concept checking classes is enabled by default, where available.
|
||||
// The old protocol is deprecated, though, and backward compatibility
|
||||
// will no longer be the default in the next release.
|
||||
|
||||
# if !defined(BOOST_NO_OLD_CONCEPT_SUPPORT) \
|
||||
&& !defined(BOOST_NO_SFINAE) \
|
||||
\
|
||||
&& !(BOOST_WORKAROUND(__GNUC__, == 3) && BOOST_WORKAROUND(__GNUC_MINOR__, < 4)) \
|
||||
&& !(BOOST_WORKAROUND(__GNUC__, == 2))
|
||||
|
||||
// Note: gcc-2.96 through 3.3.x have some SFINAE, but no ability to
|
||||
// check for the presence of particularmember functions.
|
||||
|
||||
# define BOOST_OLD_CONCEPT_SUPPORT
|
||||
|
||||
# endif
|
||||
|
||||
# ifdef BOOST_MSVC
|
||||
# include <boost/concept/detail/msvc.hpp>
|
||||
# elif BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||
# include <boost/concept/detail/borland.hpp>
|
||||
# else
|
||||
# include <boost/concept/detail/general.hpp>
|
||||
# endif
|
||||
|
||||
// Usage, in class or function context:
|
||||
//
|
||||
// BOOST_CONCEPT_ASSERT((UnaryFunctionConcept<F,bool,int>));
|
||||
//
|
||||
# define BOOST_CONCEPT_ASSERT(ModelInParens) \
|
||||
BOOST_CONCEPT_ASSERT_FN(void(*)ModelInParens)
|
||||
|
||||
#endif // BOOST_CONCEPT_ASSERT_DWA2006430_HPP
|
|
@ -0,0 +1,29 @@
|
|||
// Copyright David Abrahams 2006. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_CONCEPT_DETAIL_BORLAND_DWA2006429_HPP
|
||||
# define BOOST_CONCEPT_DETAIL_BORLAND_DWA2006429_HPP
|
||||
|
||||
# include <boost/preprocessor/cat.hpp>
|
||||
|
||||
namespace boost { namespace concept {
|
||||
|
||||
template <class ModelFnPtr>
|
||||
struct require;
|
||||
|
||||
template <class Model>
|
||||
struct require<void(*)(Model)>
|
||||
{
|
||||
enum { instantiate = sizeof((((Model*)0)->~Model()), 3) };
|
||||
};
|
||||
|
||||
# define BOOST_CONCEPT_ASSERT_FN( ModelFnPtr ) \
|
||||
enum \
|
||||
{ \
|
||||
BOOST_PP_CAT(boost_concept_check,__LINE__) = \
|
||||
boost::concept::require<ModelFnPtr>::instantiate \
|
||||
}
|
||||
|
||||
}} // namespace boost::concept
|
||||
|
||||
#endif // BOOST_CONCEPT_DETAIL_BORLAND_DWA2006429_HPP
|
|
@ -0,0 +1,51 @@
|
|||
// Copyright David Abrahams 2006. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_CONCEPT_DETAIL_CONCEPT_DEF_DWA200651_HPP
|
||||
# define BOOST_CONCEPT_DETAIL_CONCEPT_DEF_DWA200651_HPP
|
||||
# include <boost/preprocessor/seq/for_each_i.hpp>
|
||||
# include <boost/preprocessor/seq/enum.hpp>
|
||||
# include <boost/preprocessor/comma_if.hpp>
|
||||
# include <boost/preprocessor/cat.hpp>
|
||||
#endif // BOOST_CONCEPT_DETAIL_CONCEPT_DEF_DWA200651_HPP
|
||||
|
||||
// BOOST_concept(SomeName, (p1)(p2)...(pN))
|
||||
//
|
||||
// Expands to "template <class p1, class p2, ...class pN> struct SomeName"
|
||||
//
|
||||
// Also defines an equivalent SomeNameConcept for backward compatibility.
|
||||
// Maybe in the next release we can kill off the "Concept" suffix for good.
|
||||
#if BOOST_WORKAROUND(__GNUC__, <= 3)
|
||||
# define BOOST_concept(name, params) \
|
||||
template < BOOST_PP_SEQ_FOR_EACH_I(BOOST_CONCEPT_typename,~,params) > \
|
||||
struct name; /* forward declaration */ \
|
||||
\
|
||||
template < BOOST_PP_SEQ_FOR_EACH_I(BOOST_CONCEPT_typename,~,params) > \
|
||||
struct BOOST_PP_CAT(name,Concept) \
|
||||
: name< BOOST_PP_SEQ_ENUM(params) > \
|
||||
{ \
|
||||
/* at least 2.96 and 3.4.3 both need this */ \
|
||||
BOOST_PP_CAT(name,Concept)(); \
|
||||
}; \
|
||||
\
|
||||
template < BOOST_PP_SEQ_FOR_EACH_I(BOOST_CONCEPT_typename,~,params) > \
|
||||
struct name
|
||||
#else
|
||||
# define BOOST_concept(name, params) \
|
||||
template < BOOST_PP_SEQ_FOR_EACH_I(BOOST_CONCEPT_typename,~,params) > \
|
||||
struct name; /* forward declaration */ \
|
||||
\
|
||||
template < BOOST_PP_SEQ_FOR_EACH_I(BOOST_CONCEPT_typename,~,params) > \
|
||||
struct BOOST_PP_CAT(name,Concept) \
|
||||
: name< BOOST_PP_SEQ_ENUM(params) > \
|
||||
{ \
|
||||
}; \
|
||||
\
|
||||
template < BOOST_PP_SEQ_FOR_EACH_I(BOOST_CONCEPT_typename,~,params) > \
|
||||
struct name
|
||||
#endif
|
||||
|
||||
// Helper for BOOST_concept, above.
|
||||
# define BOOST_CONCEPT_typename(r, ignored, index, t) \
|
||||
BOOST_PP_COMMA_IF(index) typename t
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
// Copyright David Abrahams 2006. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
# undef BOOST_concept_typename
|
||||
# undef BOOST_concept
|
|
@ -0,0 +1,66 @@
|
|||
// Copyright David Abrahams 2006. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_CONCEPT_DETAIL_GENERAL_DWA2006429_HPP
|
||||
# define BOOST_CONCEPT_DETAIL_GENERAL_DWA2006429_HPP
|
||||
|
||||
# include <boost/preprocessor/cat.hpp>
|
||||
|
||||
# ifdef BOOST_OLD_CONCEPT_SUPPORT
|
||||
# include <boost/concept/detail/has_constraints.hpp>
|
||||
# include <boost/mpl/if.hpp>
|
||||
# endif
|
||||
|
||||
// This implementation works on Comeau and GCC, all the way back to
|
||||
// 2.95
|
||||
namespace boost { namespace concept {
|
||||
|
||||
template <class ModelFn>
|
||||
struct requirement_;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <void(*)()> struct instantiate {};
|
||||
}
|
||||
|
||||
template <class Model>
|
||||
struct requirement
|
||||
{
|
||||
static void failed() { ((Model*)0)->~Model(); }
|
||||
};
|
||||
|
||||
# ifdef BOOST_OLD_CONCEPT_SUPPORT
|
||||
|
||||
template <class Model>
|
||||
struct constraint
|
||||
{
|
||||
static void failed() { ((Model*)0)->constraints(); }
|
||||
};
|
||||
|
||||
template <class Model>
|
||||
struct requirement_<void(*)(Model)>
|
||||
: mpl::if_<
|
||||
concept::not_satisfied<Model>
|
||||
, constraint<Model>
|
||||
, requirement<Model>
|
||||
>::type
|
||||
{};
|
||||
|
||||
# else
|
||||
|
||||
// For GCC-2.x, these can't have exactly the same name
|
||||
template <class Model>
|
||||
struct requirement_<void(*)(Model)>
|
||||
: requirement<Model>
|
||||
{};
|
||||
|
||||
# endif
|
||||
|
||||
# define BOOST_CONCEPT_ASSERT_FN( ModelFnPtr ) \
|
||||
typedef ::boost::concept::detail::instantiate< \
|
||||
&::boost::concept::requirement_<ModelFnPtr>::failed> \
|
||||
BOOST_PP_CAT(boost_concept_check,__LINE__)
|
||||
|
||||
}}
|
||||
|
||||
#endif // BOOST_CONCEPT_DETAIL_GENERAL_DWA2006429_HPP
|
|
@ -0,0 +1,48 @@
|
|||
// Copyright David Abrahams 2006. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_CONCEPT_DETAIL_HAS_CONSTRAINTS_DWA2006429_HPP
|
||||
# define BOOST_CONCEPT_DETAIL_HAS_CONSTRAINTS_DWA2006429_HPP
|
||||
|
||||
# include <boost/mpl/bool.hpp>
|
||||
# include <boost/detail/workaround.hpp>
|
||||
namespace boost { namespace concept {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// Here we implement the metafunction that detects whether a
|
||||
// constraints metafunction exists
|
||||
typedef char yes;
|
||||
typedef char (&no)[2];
|
||||
|
||||
template <class Model, void (Model::*)()>
|
||||
struct wrap_constraints {};
|
||||
|
||||
#if BOOST_WORKAROUND(__SUNPRO_CC, <= 0x580) || defined(__CUDACC__)
|
||||
// Work around the following bogus error in Sun Studio 11, by
|
||||
// turning off the has_constraints function entirely:
|
||||
// Error: complex expression not allowed in dependent template
|
||||
// argument expression
|
||||
inline no has_constraints_(...);
|
||||
#else
|
||||
template <class Model>
|
||||
inline yes has_constraints_(Model*, wrap_constraints<Model,&Model::constraints>* = 0);
|
||||
inline no has_constraints_(...);
|
||||
#endif
|
||||
}
|
||||
|
||||
// This would be called "detail::has_constraints," but it has a strong
|
||||
// tendency to show up in error messages.
|
||||
template <class Model>
|
||||
struct not_satisfied
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool
|
||||
, value = sizeof( detail::has_constraints_((Model*)0) ) == sizeof(detail::yes) );
|
||||
typedef mpl::bool_<value> type;
|
||||
};
|
||||
|
||||
}} // namespace boost::concept::detail
|
||||
|
||||
#endif // BOOST_CONCEPT_DETAIL_HAS_CONSTRAINTS_DWA2006429_HPP
|
|
@ -0,0 +1,92 @@
|
|||
// Copyright David Abrahams 2006. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP
|
||||
# define BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP
|
||||
|
||||
# include <boost/preprocessor/cat.hpp>
|
||||
|
||||
# ifdef BOOST_OLD_CONCEPT_SUPPORT
|
||||
# include <boost/concept/detail/has_constraints.hpp>
|
||||
# include <boost/mpl/if.hpp>
|
||||
# endif
|
||||
|
||||
|
||||
namespace boost { namespace concept {
|
||||
|
||||
template <class Model>
|
||||
struct check
|
||||
{
|
||||
virtual void failed(Model* x)
|
||||
{
|
||||
x->~Model();
|
||||
}
|
||||
};
|
||||
|
||||
# ifdef BOOST_OLD_CONCEPT_SUPPORT
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// No need for a virtual function here, since evaluating
|
||||
// not_satisfied below will have already instantiated the
|
||||
// constraints() member.
|
||||
struct constraint {};
|
||||
}
|
||||
|
||||
template <class Model>
|
||||
struct require
|
||||
: mpl::if_c<
|
||||
not_satisfied<Model>::value
|
||||
, detail::constraint
|
||||
, check<Model>
|
||||
>::type
|
||||
{};
|
||||
|
||||
# else
|
||||
|
||||
template <class Model>
|
||||
struct require
|
||||
: check<Model>
|
||||
{};
|
||||
|
||||
# endif
|
||||
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
|
||||
|
||||
//
|
||||
// The iterator library sees some really strange errors unless we
|
||||
// do things this way.
|
||||
//
|
||||
template <class Model>
|
||||
struct require<void(*)(Model)>
|
||||
{
|
||||
virtual void failed(Model*)
|
||||
{
|
||||
require<Model>();
|
||||
}
|
||||
};
|
||||
|
||||
# define BOOST_CONCEPT_ASSERT_FN( ModelFnPtr ) \
|
||||
enum \
|
||||
{ \
|
||||
BOOST_PP_CAT(boost_concept_check,__LINE__) = \
|
||||
sizeof(::boost::concept::require<ModelFnPtr>) \
|
||||
}
|
||||
|
||||
# else // Not vc-7.1
|
||||
|
||||
template <class Model>
|
||||
require<Model>
|
||||
require_(void(*)(Model));
|
||||
|
||||
# define BOOST_CONCEPT_ASSERT_FN( ModelFnPtr ) \
|
||||
enum \
|
||||
{ \
|
||||
BOOST_PP_CAT(boost_concept_check,__LINE__) = \
|
||||
sizeof(::boost::concept::require_((ModelFnPtr)0)) \
|
||||
}
|
||||
|
||||
# endif
|
||||
}}
|
||||
|
||||
#endif // BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP
|
|
@ -0,0 +1,78 @@
|
|||
// Copyright David Abrahams 2006. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_CONCEPT_REQUIRES_DWA2006430_HPP
|
||||
# define BOOST_CONCEPT_REQUIRES_DWA2006430_HPP
|
||||
|
||||
# include <boost/config.hpp>
|
||||
# include <boost/parameter/aux_/parenthesized_type.hpp>
|
||||
# include <boost/concept/assert.hpp>
|
||||
# include <boost/preprocessor/seq/for_each.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
// Template for use in handwritten assertions
|
||||
template <class Model, class More>
|
||||
struct requires_ : More
|
||||
{
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
typedef typename More::type type;
|
||||
# endif
|
||||
BOOST_CONCEPT_ASSERT((Model));
|
||||
};
|
||||
|
||||
// Template for use by macros, where models must be wrapped in parens.
|
||||
// This isn't in namespace detail to keep extra cruft out of resulting
|
||||
// error messages.
|
||||
template <class ModelFn>
|
||||
struct _requires_
|
||||
{
|
||||
enum { value = 0 };
|
||||
BOOST_CONCEPT_ASSERT_FN(ModelFn);
|
||||
};
|
||||
|
||||
template <int check, class Result>
|
||||
struct Requires_ : ::boost::parameter::aux::unaryfunptr_arg_type<Result>
|
||||
{
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
typedef typename ::boost::parameter::aux::unaryfunptr_arg_type<Result>::type type;
|
||||
# endif
|
||||
};
|
||||
|
||||
# if BOOST_WORKAROUND(BOOST_INTEL_WIN, BOOST_TESTED_AT(1010))
|
||||
# define BOOST_CONCEPT_REQUIRES_(r,data,t) | (::boost::_requires_<void(*)t>::value)
|
||||
# else
|
||||
# define BOOST_CONCEPT_REQUIRES_(r,data,t) + (::boost::_requires_<void(*)t>::value)
|
||||
# endif
|
||||
|
||||
#if defined(NDEBUG) || BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
|
||||
# define BOOST_CONCEPT_REQUIRES(models, result) \
|
||||
typename ::boost::parameter::aux::unaryfunptr_arg_type<void(*)result>::type
|
||||
|
||||
#elif BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||
|
||||
// Same thing as below without the initial typename
|
||||
# define BOOST_CONCEPT_REQUIRES(models, result) \
|
||||
::boost::Requires_< \
|
||||
(0 BOOST_PP_SEQ_FOR_EACH(BOOST_CONCEPT_REQUIRES_, ~, models)), \
|
||||
::boost::parameter::aux::unaryfunptr_arg_type<void(*)result> \
|
||||
>::type
|
||||
|
||||
#else
|
||||
|
||||
// This just ICEs on MSVC6 :(
|
||||
# define BOOST_CONCEPT_REQUIRES(models, result) \
|
||||
typename ::boost::Requires_< \
|
||||
(0 BOOST_PP_SEQ_FOR_EACH(BOOST_CONCEPT_REQUIRES_, ~, models)), \
|
||||
void(*)result \
|
||||
>::type
|
||||
|
||||
#endif
|
||||
|
||||
// C++0x proposed syntax changed. This supports an older usage
|
||||
#define BOOST_CONCEPT_WHERE(models,result) BOOST_CONCEPT_REQUIRES(models,result)
|
||||
|
||||
} // namespace boost::concept_check
|
||||
|
||||
#endif // BOOST_CONCEPT_REQUIRES_DWA2006430_HPP
|
|
@ -0,0 +1,43 @@
|
|||
// Copyright David Abrahams 2006. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_CONCEPT_USAGE_DWA2006919_HPP
|
||||
# define BOOST_CONCEPT_USAGE_DWA2006919_HPP
|
||||
|
||||
# include <boost/concept/assert.hpp>
|
||||
# include <boost/detail/workaround.hpp>
|
||||
|
||||
namespace boost { namespace concept {
|
||||
|
||||
# if BOOST_WORKAROUND(__GNUC__, == 2)
|
||||
|
||||
# define BOOST_CONCEPT_USAGE(model) ~model()
|
||||
|
||||
# else
|
||||
|
||||
template <class Model>
|
||||
struct usage_requirements
|
||||
{
|
||||
~usage_requirements() { ((Model*)0)->~Model(); }
|
||||
};
|
||||
|
||||
# if BOOST_WORKAROUND(__GNUC__, <= 3)
|
||||
|
||||
# define BOOST_CONCEPT_USAGE(model) \
|
||||
model(); /* at least 2.96 and 3.4.3 both need this :( */ \
|
||||
BOOST_CONCEPT_ASSERT((boost::concept::usage_requirements<model>)); \
|
||||
~model()
|
||||
|
||||
# else
|
||||
|
||||
# define BOOST_CONCEPT_USAGE(model) \
|
||||
BOOST_CONCEPT_ASSERT((boost::concept::usage_requirements<model>)); \
|
||||
~model()
|
||||
|
||||
# endif
|
||||
|
||||
# endif
|
||||
|
||||
}} // namespace boost::concept
|
||||
|
||||
#endif // BOOST_CONCEPT_USAGE_DWA2006919_HPP
|
File diff suppressed because it is too large
Load Diff
|
@ -66,7 +66,6 @@
|
|||
|
||||
// Borland C++ Builder 6 and below:
|
||||
#if (__BORLANDC__ <= 0x564)
|
||||
# define BOOST_NO_INTEGRAL_INT64_T
|
||||
|
||||
# ifdef NDEBUG
|
||||
// fix broken <cstring> so that Boost.test works:
|
||||
|
@ -121,6 +120,7 @@
|
|||
#endif
|
||||
|
||||
// Borland C++ Builder 2008 and below:
|
||||
# define BOOST_NO_INTEGRAL_INT64_T
|
||||
# define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL
|
||||
# define BOOST_NO_DEPENDENT_NESTED_DERIVATIONS
|
||||
# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS
|
||||
|
|
|
@ -19,8 +19,8 @@
|
|||
#endif
|
||||
//
|
||||
// versions check:
|
||||
// last known and checked version is 0x610
|
||||
#if (__CODEGEARC__ > 0x613)
|
||||
// last known and checked version is 0x620
|
||||
#if (__CODEGEARC__ > 0x620)
|
||||
# if defined(BOOST_ASSERT_CONFIG)
|
||||
# error "Unknown compiler version - please run the configure tests and report the results"
|
||||
# else
|
||||
|
@ -30,20 +30,24 @@
|
|||
|
||||
// CodeGear C++ Builder 2009
|
||||
#if (__CODEGEARC__ <= 0x613)
|
||||
# define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL
|
||||
# define BOOST_NO_INTEGRAL_INT64_T
|
||||
# define BOOST_NO_DEPENDENT_NESTED_DERIVATIONS
|
||||
# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS
|
||||
# define BOOST_NO_PRIVATE_IN_AGGREGATE
|
||||
# define BOOST_NO_TWO_PHASE_NAME_LOOKUP
|
||||
# define BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE
|
||||
# define BOOST_NO_USING_TEMPLATE
|
||||
// we shouldn't really need this - but too many things choke
|
||||
// without it, this needs more investigation:
|
||||
# define BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
||||
# define BOOST_NO_TYPENAME_WITH_CTOR // Cannot use typename keyword when making temporaries of a dependant type
|
||||
# define BOOST_NO_NESTED_FRIENDSHIP // TC1 gives nested classes access rights as any other member
|
||||
# define BOOST_SP_NO_SP_CONVERTIBLE
|
||||
#endif
|
||||
|
||||
// CodeGear C++ Builder 2010
|
||||
#if (__CODEGEARC__ <= 0x620)
|
||||
# define BOOST_NO_TYPENAME_WITH_CTOR // Cannot use typename keyword when making temporaries of a dependant type
|
||||
# define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL
|
||||
# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS
|
||||
# define BOOST_NO_NESTED_FRIENDSHIP // TC1 gives nested classes access rights as any other member
|
||||
# define BOOST_NO_USING_TEMPLATE
|
||||
# define BOOST_NO_TWO_PHASE_NAME_LOOKUP
|
||||
// Temporary hack, until specific MPL preprocessed headers are generated
|
||||
# define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
|
||||
|
||||
|
@ -59,7 +63,6 @@
|
|||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
// C++0x macros:
|
||||
//
|
||||
|
|
|
@ -108,11 +108,8 @@
|
|||
//
|
||||
#define BOOST_NO_CONSTEXPR
|
||||
#define BOOST_NO_EXTERN_TEMPLATE
|
||||
#define BOOST_NO_LAMBDAS
|
||||
#define BOOST_NO_NULLPTR
|
||||
#define BOOST_NO_RAW_LITERALS
|
||||
#define BOOST_NO_TEMPLATE_ALIASES
|
||||
#define BOOST_NO_UNICODE_LITERALS
|
||||
|
||||
// C++0x features in 4.3.n and later
|
||||
//
|
||||
|
@ -168,6 +165,9 @@
|
|||
//
|
||||
#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5) || !defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
# define BOOST_NO_EXPLICIT_CONVERSION_OPERATORS
|
||||
# define BOOST_NO_LAMBDAS
|
||||
# define BOOST_NO_RAW_LITERALS
|
||||
# define BOOST_NO_UNICODE_LITERALS
|
||||
#endif
|
||||
|
||||
// ConceptGCC compiler:
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
// (C) Copyright Eric Jourdanneau, Joel Falcou 2010
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
|
||||
// NVIDIA CUDA C++ compiler setup
|
||||
|
||||
#ifndef BOOST_COMPILER
|
||||
# define BOOST_COMPILER "NVIDIA CUDA C++ Compiler"
|
||||
#endif
|
||||
|
||||
// NVIDIA Specific support
|
||||
// BOOST_GPU_ENABLED : Flag a function or a method as being enabled on the host and device
|
||||
#define BOOST_GPU_ENABLED __host__ __device__
|
||||
|
||||
// Boost support macro for NVCC
|
||||
// NVCC Basically behaves like some flavor of MSVC6 + some specific quirks
|
||||
#define BOOST_NO_INCLASS_MEMBER_INITIALIZATION
|
||||
#define BOOST_MSVC6_MEMBER_TEMPLATES
|
||||
#define BOOST_HAS_UNISTD_H
|
||||
#define BOOST_HAS_STDINT_H
|
||||
#define BOOST_HAS_SIGACTION
|
||||
#define BOOST_HAS_SCHED_YIELD
|
||||
#define BOOST_HAS_PTHREADS
|
||||
#define BOOST_HAS_PTHREAD_YIELD
|
||||
#define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE
|
||||
#define BOOST_HAS_PARTIAL_STD_ALLOCATOR
|
||||
#define BOOST_HAS_NRVO
|
||||
#define BOOST_HAS_NL_TYPES_H
|
||||
#define BOOST_HAS_NANOSLEEP
|
||||
#define BOOST_HAS_LONG_LONG
|
||||
#define BOOST_HAS_LOG1P
|
||||
#define BOOST_HAS_GETTIMEOFDAY
|
||||
#define BOOST_HAS_EXPM1
|
||||
#define BOOST_HAS_DIRENT_H
|
||||
#define BOOST_HAS_CLOCK_GETTIME
|
||||
#define BOOST_NO_VARIADIC_TEMPLATES
|
||||
#define BOOST_NO_UNICODE_LITERALS
|
||||
#define BOOST_NO_TEMPLATE_ALIASES
|
||||
#define BOOST_NO_STD_UNORDERED
|
||||
#define BOOST_NO_STATIC_ASSERT
|
||||
#define BOOST_NO_SFINAE_EXPR
|
||||
#define BOOST_NO_SCOPED_ENUMS
|
||||
#define BOOST_NO_RVALUE_REFERENCES
|
||||
#define BOOST_NO_RAW_LITERALS
|
||||
#define BOOST_NO_NULLPTR
|
||||
#define BOOST_NO_LAMBDAS
|
||||
#define BOOST_NO_INITIALIZER_LISTS
|
||||
#define BOOST_NO_MS_INT64_NUMERIC_LIMITS
|
||||
#define BOOST_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS
|
||||
#define BOOST_NO_EXTERN_TEMPLATE
|
||||
#define BOOST_NO_EXPLICIT_CONVERSION_OPERATORS
|
||||
#define BOOST_NO_DELETED_FUNCTIONS
|
||||
#define BOOST_NO_DEFAULTED_FUNCTIONS
|
||||
#define BOOST_NO_DECLTYPE
|
||||
#define BOOST_NO_CONSTEXPR
|
||||
#define BOOST_NO_CONCEPTS
|
||||
#define BOOST_NO_CHAR32_T
|
||||
#define BOOST_NO_CHAR16_T
|
||||
#define BOOST_NO_AUTO_MULTIDECLARATIONS
|
||||
#define BOOST_NO_AUTO_DECLARATIONS
|
||||
#define BOOST_NO_0X_HDR_UNORDERED_SET
|
||||
#define BOOST_NO_0X_HDR_UNORDERED_MAP
|
||||
#define BOOST_NO_0X_HDR_TYPE_TRAITS
|
||||
#define BOOST_NO_0X_HDR_TUPLE
|
||||
#define BOOST_NO_0X_HDR_THREAD
|
||||
#define BOOST_NO_0X_HDR_SYSTEM_ERROR
|
||||
#define BOOST_NO_0X_HDR_REGEX
|
||||
#define BOOST_NO_0X_HDR_RATIO
|
||||
#define BOOST_NO_0X_HDR_RANDOM
|
||||
#define BOOST_NO_0X_HDR_MUTEX
|
||||
#define BOOST_NO_0X_HDR_MEMORY_CONCEPTS
|
||||
#define BOOST_NO_0X_HDR_ITERATOR_CONCEPTS
|
||||
#define BOOST_NO_0X_HDR_INITIALIZER_LIST
|
||||
#define BOOST_NO_0X_HDR_FUTURE
|
||||
#define BOOST_NO_0X_HDR_FORWARD_LIST
|
||||
#define BOOST_NO_0X_HDR_CONTAINER_CONCEPTS
|
||||
#define BOOST_NO_0X_HDR_CONDITION_VARIABLE
|
||||
#define BOOST_NO_0X_HDR_CONCEPTS
|
||||
#define BOOST_NO_0X_HDR_CODECVT
|
||||
#define BOOST_NO_0X_HDR_CHRONO
|
||||
#define BOOST_NO_0X_HDR_ARRAY
|
||||
|
|
@ -16,11 +16,28 @@
|
|||
// if no threading API is detected.
|
||||
//
|
||||
|
||||
#if (__PGIC__ >= 7)
|
||||
// PGI 10.x doesn't seem to define __PGIC__
|
||||
|
||||
// versions earlier than 10.x do define __PGIC__
|
||||
#if __PGIC__ >= 10
|
||||
|
||||
// options requested by configure --enable-test
|
||||
#define BOOST_HAS_PTHREADS
|
||||
#define BOOST_HAS_NRVO
|
||||
#define BOOST_HAS_LONG_LONG
|
||||
|
||||
// options --enable-test wants undefined
|
||||
#undef BOOST_NO_STDC_NAMESPACE
|
||||
#undef BOOST_NO_EXCEPTION_STD_NAMESPACE
|
||||
#undef BOOST_DEDUCED_TYPENAME
|
||||
|
||||
#elif __PGIC__ >= 7
|
||||
|
||||
#define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL
|
||||
#define BOOST_NO_TWO_PHASE_NAME_LOOKUP
|
||||
#define BOOST_NO_SWPRINTF
|
||||
#define BOOST_NO_AUTO_MULTIDECLARATIONS
|
||||
#define BOOST_NO_AUTO_DECLARATIONS
|
||||
|
||||
#else
|
||||
|
||||
|
@ -32,8 +49,6 @@
|
|||
//
|
||||
// See boost\config\suffix.hpp for BOOST_NO_LONG_LONG
|
||||
//
|
||||
#define BOOST_NO_AUTO_DECLARATIONS
|
||||
#define BOOST_NO_AUTO_MULTIDECLARATIONS
|
||||
#define BOOST_NO_CHAR16_T
|
||||
#define BOOST_NO_CHAR32_T
|
||||
#define BOOST_NO_CONCEPTS
|
||||
|
|
|
@ -125,7 +125,7 @@
|
|||
#if (_MSC_VER >= 1200)
|
||||
# define BOOST_HAS_MS_INT64
|
||||
#endif
|
||||
#if (_MSC_VER >= 1310) && defined(_MSC_EXTENSIONS)
|
||||
#if (_MSC_VER >= 1310) && (defined(_MSC_EXTENSIONS) || (_MSC_VER >= 1400))
|
||||
# define BOOST_HAS_LONG_LONG
|
||||
#else
|
||||
# define BOOST_NO_LONG_LONG
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
// (C) Copyright Yuriy Krasnoschek 2009.
|
||||
// (C) Copyright John Maddock 2001 - 2003.
|
||||
// (C) Copyright Jens Maurer 2001 - 2003.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
|
||||
// symbian specific config options:
|
||||
|
||||
|
||||
#define BOOST_PLATFORM "Symbian"
|
||||
#define BOOST_SYMBIAN 1
|
||||
|
||||
|
||||
#if defined(__S60_3X__)
|
||||
// Open C / C++ plugin was introdused in this SDK, earlier versions don't have CRT / STL
|
||||
# define BOOST_S60_3rd_EDITION_FP2_OR_LATER_SDK
|
||||
// make sure we have __GLIBC_PREREQ if available at all
|
||||
# include <cstdlib>
|
||||
// boilerplate code:
|
||||
# define BOOST_HAS_UNISTD_H
|
||||
# include <boost/config/posix_features.hpp>
|
||||
// S60 SDK defines _POSIX_VERSION as POSIX.1
|
||||
# ifndef BOOST_HAS_STDINT_H
|
||||
# define BOOST_HAS_STDINT_H
|
||||
# endif
|
||||
# ifndef BOOST_HAS_GETTIMEOFDAY
|
||||
# define BOOST_HAS_GETTIMEOFDAY
|
||||
# endif
|
||||
# ifndef BOOST_HAS_DIRENT_H
|
||||
# define BOOST_HAS_DIRENT_H
|
||||
# endif
|
||||
# ifndef BOOST_HAS_SIGACTION
|
||||
# define BOOST_HAS_SIGACTION
|
||||
# endif
|
||||
# ifndef BOOST_HAS_PTHREADS
|
||||
# define BOOST_HAS_PTHREADS
|
||||
# endif
|
||||
# ifndef BOOST_HAS_NANOSLEEP
|
||||
# define BOOST_HAS_NANOSLEEP
|
||||
# endif
|
||||
# ifndef BOOST_HAS_SCHED_YIELD
|
||||
# define BOOST_HAS_SCHED_YIELD
|
||||
# endif
|
||||
# ifndef BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE
|
||||
# define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE
|
||||
# endif
|
||||
# ifndef BOOST_HAS_LOG1P
|
||||
# define BOOST_HAS_LOG1P
|
||||
# endif
|
||||
# ifndef BOOST_HAS_EXPM1
|
||||
# define BOOST_HAS_EXPM1
|
||||
# endif
|
||||
# ifndef BOOST_POSIX_API
|
||||
# define BOOST_POSIX_API
|
||||
# endif
|
||||
// endianess support
|
||||
# include <sys/endian.h>
|
||||
// Symbian SDK provides _BYTE_ORDER instead of __BYTE_ORDER
|
||||
# ifndef __LITTLE_ENDIAN
|
||||
# ifdef _LITTLE_ENDIAN
|
||||
# define __LITTLE_ENDIAN _LITTLE_ENDIAN
|
||||
# else
|
||||
# define __LITTLE_ENDIAN 1234
|
||||
# endif
|
||||
# endif
|
||||
# ifndef __BIG_ENDIAN
|
||||
# ifdef _BIG_ENDIAN
|
||||
# define __BIG_ENDIAN _BIG_ENDIAN
|
||||
# else
|
||||
# define __BIG_ENDIAN 4321
|
||||
# endif
|
||||
# endif
|
||||
# ifndef __BYTE_ORDER
|
||||
# define __BYTE_ORDER __LITTLE_ENDIAN // Symbian is LE
|
||||
# endif
|
||||
// Known limitations
|
||||
# define BOOST_ASIO_DISABLE_SERIAL_PORT
|
||||
# define BOOST_DATE_TIME_NO_LOCALE
|
||||
# define BOOST_NO_STD_WSTRING
|
||||
# define BOOST_EXCEPTION_DISABLE
|
||||
# define BOOST_NO_EXCEPTIONS
|
||||
|
||||
#else // TODO: More platform support e.g. UIQ
|
||||
# error "Unsuppoted Symbian SDK"
|
||||
#endif
|
||||
|
||||
#if defined(__WINSCW__) && !defined(BOOST_DISABLE_WIN32)
|
||||
# define BOOST_DISABLE_WIN32 // winscw defines WIN32 macro
|
||||
#endif
|
||||
|
||||
|
|
@ -31,6 +31,7 @@
|
|||
# define BOOST_CXX_IBMCPP 0
|
||||
# define BOOST_CXX_MSVC 0
|
||||
# define BOOST_CXX_PGI 0
|
||||
# define BOOST_CXX_NVCC 0
|
||||
|
||||
|
||||
// locate which compiler we are using and define
|
||||
|
@ -40,6 +41,10 @@
|
|||
// GCC-XML emulates other compilers, it has to appear first here!
|
||||
# define BOOST_COMPILER_CONFIG "boost/config/compiler/gcc_xml.hpp"
|
||||
|
||||
#elif defined __CUDACC__
|
||||
// NVIDIA CUDA C++ compiler for GPU
|
||||
# define BOOST_COMPILER_CONFIG "boost/config/compiler/nvcc.hpp"
|
||||
|
||||
#elif defined __COMO__
|
||||
// Comeau C++
|
||||
# define BOOST_COMPILER_CONFIG "boost/config/compiler/comeau.hpp"
|
||||
|
|
|
@ -65,6 +65,10 @@
|
|||
// vxWorks:
|
||||
# define BOOST_PLATFORM_CONFIG "boost/config/platform/vxworks.hpp"
|
||||
|
||||
#elif defined(__SYMBIAN32__)
|
||||
// Symbian:
|
||||
# define BOOST_PLATFORM_CONFIG "boost/config/platform/symbian.hpp"
|
||||
|
||||
#else
|
||||
|
||||
# if defined(unix) \
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
// Copyright (c) 2002-2003 David Abrahams
|
||||
// Copyright (c) 2003 Gennaro Prota
|
||||
// Copyright (c) 2003 Eric Friedman
|
||||
//
|
||||
// Copyright (c) 2010 Eric Jourdanneau, Joel Falcou
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
@ -596,6 +596,11 @@ namespace boost{
|
|||
# endif
|
||||
# endif
|
||||
|
||||
//
|
||||
// Set some default values GPU support
|
||||
//
|
||||
# ifndef BOOST_GPU_ENABLED
|
||||
# define BOOST_GPU_ENABLED
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -40,115 +40,30 @@
|
|||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/range/algorithm/copy.hpp>
|
||||
#include <boost/range/algorithm/equal.hpp>
|
||||
#include <boost/range/algorithm/sort.hpp>
|
||||
#include <boost/range/algorithm/stable_sort.hpp>
|
||||
#include <boost/range/algorithm/find_if.hpp>
|
||||
#include <boost/range/algorithm/count.hpp>
|
||||
#include <boost/range/algorithm/count_if.hpp>
|
||||
#include <boost/range/algorithm_ext/is_sorted.hpp>
|
||||
#include <boost/range/algorithm_ext/iota.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
template <typename Iter1, typename Iter2>
|
||||
Iter1 begin(const std::pair<Iter1, Iter2>& p) { return p.first; }
|
||||
|
||||
template <typename Iter1, typename Iter2>
|
||||
Iter2 end(const std::pair<Iter1, Iter2>& p) { return p.second; }
|
||||
|
||||
template <typename Iter1, typename Iter2>
|
||||
typename boost::detail::iterator_traits<Iter1>::difference_type
|
||||
size(const std::pair<Iter1, Iter2>& p) {
|
||||
return std::distance(p.first, p.second);
|
||||
}
|
||||
|
||||
#if 0
|
||||
// These seem to interfere with the std::pair overloads :(
|
||||
template <typename Container>
|
||||
typename Container::iterator
|
||||
begin(Container& c) { return c.begin(); }
|
||||
|
||||
template <typename Container>
|
||||
typename Container::const_iterator
|
||||
begin(const Container& c) { return c.begin(); }
|
||||
|
||||
template <typename Container>
|
||||
typename Container::iterator
|
||||
end(Container& c) { return c.end(); }
|
||||
|
||||
template <typename Container>
|
||||
typename Container::const_iterator
|
||||
end(const Container& c) { return c.end(); }
|
||||
|
||||
template <typename Container>
|
||||
typename Container::size_type
|
||||
size(const Container& c) { return c.size(); }
|
||||
#else
|
||||
template <typename T>
|
||||
typename std::vector<T>::iterator
|
||||
begin(std::vector<T>& c) { return c.begin(); }
|
||||
|
||||
template <typename T>
|
||||
typename std::vector<T>::const_iterator
|
||||
begin(const std::vector<T>& c) { return c.begin(); }
|
||||
|
||||
template <typename T>
|
||||
typename std::vector<T>::iterator
|
||||
end(std::vector<T>& c) { return c.end(); }
|
||||
|
||||
template <typename T>
|
||||
typename std::vector<T>::const_iterator
|
||||
end(const std::vector<T>& c) { return c.end(); }
|
||||
|
||||
template <typename T>
|
||||
typename std::vector<T>::size_type
|
||||
size(const std::vector<T>& c) { return c.size(); }
|
||||
#endif
|
||||
|
||||
template <class ForwardIterator, class T>
|
||||
void iota(ForwardIterator first, ForwardIterator last, T value)
|
||||
{
|
||||
for (; first != last; ++first, ++value)
|
||||
*first = value;
|
||||
}
|
||||
template <typename Container, typename T>
|
||||
void iota(Container& c, const T& value)
|
||||
{
|
||||
iota(begin(c), end(c), value);
|
||||
}
|
||||
|
||||
// Also do version with 2nd container?
|
||||
template <typename Container, typename OutIter>
|
||||
OutIter copy(const Container& c, OutIter result) {
|
||||
return std::copy(begin(c), end(c), result);
|
||||
}
|
||||
|
||||
template <typename Container1, typename Container2>
|
||||
bool equal(const Container1& c1, const Container2& c2)
|
||||
{
|
||||
if (size(c1) != size(c2))
|
||||
return false;
|
||||
return std::equal(begin(c1), end(c1), begin(c2));
|
||||
}
|
||||
|
||||
template <typename Container>
|
||||
void sort(Container& c) { std::sort(begin(c), end(c)); }
|
||||
|
||||
template <typename Container, typename Predicate>
|
||||
void sort(Container& c, const Predicate& p) {
|
||||
std::sort(begin(c), end(c), p);
|
||||
}
|
||||
|
||||
template <typename Container>
|
||||
void stable_sort(Container& c) { std::stable_sort(begin(c), end(c)); }
|
||||
|
||||
template <typename Container, typename Predicate>
|
||||
void stable_sort(Container& c, const Predicate& p) {
|
||||
std::stable_sort(begin(c), end(c), p);
|
||||
}
|
||||
|
||||
template <typename InputIterator, typename Predicate>
|
||||
bool any_if(InputIterator first, InputIterator last, Predicate p)
|
||||
{
|
||||
return std::find_if(first, last, p) != last;
|
||||
}
|
||||
|
||||
template <typename Container, typename Predicate>
|
||||
bool any_if(const Container& c, Predicate p)
|
||||
{
|
||||
return any_if(begin(c), end(c), p);
|
||||
return any_if(boost::begin(c), boost::end(c), p);
|
||||
}
|
||||
|
||||
template <typename InputIterator, typename T>
|
||||
|
@ -159,62 +74,7 @@ namespace boost {
|
|||
template <typename Container, typename T>
|
||||
bool container_contains(const Container& c, const T& value)
|
||||
{
|
||||
return container_contains(begin(c), end(c), value);
|
||||
}
|
||||
|
||||
template <typename Container, typename T>
|
||||
std::size_t count(const Container& c, const T& value)
|
||||
{
|
||||
return std::count(begin(c), end(c), value);
|
||||
}
|
||||
|
||||
template <typename Container, typename Predicate>
|
||||
std::size_t count_if(const Container& c, Predicate p)
|
||||
{
|
||||
return std::count_if(begin(c), end(c), p);
|
||||
}
|
||||
|
||||
template <typename ForwardIterator>
|
||||
bool is_sorted(ForwardIterator first, ForwardIterator last)
|
||||
{
|
||||
if (first == last)
|
||||
return true;
|
||||
|
||||
ForwardIterator next = first;
|
||||
for (++next; next != last; first = next, ++next) {
|
||||
if (*next < *first)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename ForwardIterator, typename StrictWeakOrdering>
|
||||
bool is_sorted(ForwardIterator first, ForwardIterator last,
|
||||
StrictWeakOrdering comp)
|
||||
{
|
||||
if (first == last)
|
||||
return true;
|
||||
|
||||
ForwardIterator next = first;
|
||||
for (++next; next != last; first = next, ++next) {
|
||||
if (comp(*next, *first))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Container>
|
||||
bool is_sorted(const Container& c)
|
||||
{
|
||||
return is_sorted(begin(c), end(c));
|
||||
}
|
||||
|
||||
template <typename Container, typename StrictWeakOrdering>
|
||||
bool is_sorted(const Container& c, StrictWeakOrdering comp)
|
||||
{
|
||||
return is_sorted(begin(c), end(c), comp);
|
||||
return container_contains(boost::begin(c), boost::end(c), value);
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
|
|
@ -13,7 +13,9 @@
|
|||
#include <boost/config.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#if ((defined(__GLIBCPP__) || defined(__GLIBCXX__)) && defined(_GLIBCXX_DEBUG)) \
|
||||
#if defined(BOOST_DETAIL_NO_CONTAINER_FWD) \
|
||||
|| ((defined(__GLIBCPP__) || defined(__GLIBCXX__)) \
|
||||
&& (defined(_GLIBCXX_DEBUG) || defined(_GLIBCXX_PARALLEL))) \
|
||||
|| BOOST_WORKAROUND(__BORLANDC__, > 0x551) \
|
||||
|| BOOST_WORKAROUND(__DMC__, BOOST_TESTED_AT(0x842)) \
|
||||
|| (defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION))
|
||||
|
|
|
@ -54,11 +54,23 @@ extern "C" long __cdecl InterlockedExchangeAdd( long*, long );
|
|||
|
||||
#elif defined( BOOST_MSVC ) || defined( BOOST_INTEL_WIN )
|
||||
|
||||
#if defined( __CLRCALL_PURE_OR_CDECL )
|
||||
|
||||
extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedIncrement( long volatile * );
|
||||
extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedDecrement( long volatile * );
|
||||
extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedCompareExchange( long volatile *, long, long );
|
||||
extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedExchange( long volatile *, long );
|
||||
extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedExchangeAdd( long volatile *, long );
|
||||
|
||||
#else
|
||||
|
||||
extern "C" long __cdecl _InterlockedIncrement( long volatile * );
|
||||
extern "C" long __cdecl _InterlockedDecrement( long volatile * );
|
||||
extern "C" long __cdecl _InterlockedCompareExchange( long volatile *, long, long );
|
||||
extern "C" long __cdecl _InterlockedExchange( long volatile *, long);
|
||||
extern "C" long __cdecl _InterlockedExchangeAdd( long volatile *, long);
|
||||
extern "C" long __cdecl _InterlockedExchange( long volatile *, long );
|
||||
extern "C" long __cdecl _InterlockedExchangeAdd( long volatile *, long );
|
||||
|
||||
#endif
|
||||
|
||||
# pragma intrinsic( _InterlockedIncrement )
|
||||
# pragma intrinsic( _InterlockedDecrement )
|
||||
|
|
|
@ -173,8 +173,8 @@ inline void lcast_set_precision(std::ios_base& stream, T*)
|
|||
template<class Source, class Target>
|
||||
inline void lcast_set_precision(std::ios_base& stream, Source*, Target*)
|
||||
{
|
||||
std::streamsize const s = lcast_get_precision((Source*)0);
|
||||
std::streamsize const t = lcast_get_precision((Target*)0);
|
||||
std::streamsize const s = lcast_get_precision(static_cast<Source*>(0));
|
||||
std::streamsize const t = lcast_get_precision(static_cast<Target*>(0));
|
||||
stream.precision(s > t ? s : t);
|
||||
}
|
||||
|
||||
|
|
|
@ -41,9 +41,9 @@
|
|||
|
||||
#ifdef BOOST_NO_SCOPED_ENUMS
|
||||
|
||||
# define BOOST_SCOPED_ENUM_START(name) struct name { enum enum_t
|
||||
# define BOOST_SCOPED_ENUM_START(name) struct name { enum enum_type
|
||||
# define BOOST_SCOPED_ENUM_END };
|
||||
# define BOOST_SCOPED_ENUM(name) name::enum_t
|
||||
# define BOOST_SCOPED_ENUM(name) name::enum_type
|
||||
|
||||
#else
|
||||
|
||||
|
|
|
@ -19,20 +19,66 @@
|
|||
|
||||
#if defined( BOOST_NO_TYPEID )
|
||||
|
||||
#include <boost/current_function.hpp>
|
||||
#include <functional>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
typedef void* sp_typeinfo;
|
||||
class sp_typeinfo
|
||||
{
|
||||
private:
|
||||
|
||||
sp_typeinfo( sp_typeinfo const& );
|
||||
sp_typeinfo& operator=( sp_typeinfo const& );
|
||||
|
||||
char const * name_;
|
||||
|
||||
public:
|
||||
|
||||
explicit sp_typeinfo( char const * name ): name_( name )
|
||||
{
|
||||
}
|
||||
|
||||
bool operator==( sp_typeinfo const& rhs ) const
|
||||
{
|
||||
return this == &rhs;
|
||||
}
|
||||
|
||||
bool operator!=( sp_typeinfo const& rhs ) const
|
||||
{
|
||||
return this != &rhs;
|
||||
}
|
||||
|
||||
bool before( sp_typeinfo const& rhs ) const
|
||||
{
|
||||
return std::less< sp_typeinfo const* >()( this, &rhs );
|
||||
}
|
||||
|
||||
char const* name() const
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
};
|
||||
|
||||
template<class T> struct sp_typeid_
|
||||
{
|
||||
static char v_;
|
||||
static sp_typeinfo ti_;
|
||||
|
||||
static char const * name()
|
||||
{
|
||||
return BOOST_CURRENT_FUNCTION;
|
||||
}
|
||||
};
|
||||
|
||||
template<class T> char sp_typeid_< T >::v_;
|
||||
template<class T> sp_typeinfo sp_typeid_< T >::ti_( sp_typeid_< T >::name() );
|
||||
|
||||
template<class T> struct sp_typeid_< T & >: sp_typeid_< T >
|
||||
{
|
||||
};
|
||||
|
||||
template<class T> struct sp_typeid_< T const >: sp_typeid_< T >
|
||||
{
|
||||
|
@ -50,7 +96,7 @@ template<class T> struct sp_typeid_< T const volatile >: sp_typeid_< T >
|
|||
|
||||
} // namespace boost
|
||||
|
||||
#define BOOST_SP_TYPEID(T) (&boost::detail::sp_typeid_<T>::v_)
|
||||
#define BOOST_SP_TYPEID(T) (boost::detail::sp_typeid_<T>::ti_)
|
||||
|
||||
#else
|
||||
|
||||
|
|
|
@ -0,0 +1,146 @@
|
|||
|
||||
// (C) Copyright John maddock 1999.
|
||||
// (C) David Abrahams 2002. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// use this header as a workaround for missing <limits>
|
||||
|
||||
// See http://www.boost.org/libs/compatibility/index.html for documentation.
|
||||
|
||||
#ifndef BOOST_LIMITS
|
||||
#define BOOST_LIMITS
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#ifdef BOOST_NO_LIMITS
|
||||
# include <boost/detail/limits.hpp>
|
||||
#else
|
||||
# include <limits>
|
||||
#endif
|
||||
|
||||
#if (defined(BOOST_HAS_LONG_LONG) && defined(BOOST_NO_LONG_LONG_NUMERIC_LIMITS)) \
|
||||
|| (defined(BOOST_HAS_MS_INT64) && defined(BOOST_NO_MS_INT64_NUMERIC_LIMITS))
|
||||
// Add missing specializations for numeric_limits:
|
||||
#ifdef BOOST_HAS_MS_INT64
|
||||
# define BOOST_LLT __int64
|
||||
# define BOOST_ULLT unsigned __int64
|
||||
#else
|
||||
# define BOOST_LLT ::boost::long_long_type
|
||||
# define BOOST_ULLT ::boost::ulong_long_type
|
||||
#endif
|
||||
|
||||
#include <climits> // for CHAR_BIT
|
||||
|
||||
namespace std
|
||||
{
|
||||
template<>
|
||||
class numeric_limits<BOOST_LLT>
|
||||
{
|
||||
public:
|
||||
|
||||
BOOST_STATIC_CONSTANT(bool, is_specialized = true);
|
||||
#ifdef BOOST_HAS_MS_INT64
|
||||
static BOOST_LLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return 0x8000000000000000i64; }
|
||||
static BOOST_LLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return 0x7FFFFFFFFFFFFFFFi64; }
|
||||
#elif defined(LLONG_MAX)
|
||||
static BOOST_LLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return LLONG_MIN; }
|
||||
static BOOST_LLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return LLONG_MAX; }
|
||||
#elif defined(LONGLONG_MAX)
|
||||
static BOOST_LLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return LONGLONG_MIN; }
|
||||
static BOOST_LLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return LONGLONG_MAX; }
|
||||
#else
|
||||
static BOOST_LLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return 1LL << (sizeof(BOOST_LLT) * CHAR_BIT - 1); }
|
||||
static BOOST_LLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return ~(min)(); }
|
||||
#endif
|
||||
BOOST_STATIC_CONSTANT(int, digits = sizeof(BOOST_LLT) * CHAR_BIT -1);
|
||||
BOOST_STATIC_CONSTANT(int, digits10 = (CHAR_BIT * sizeof (BOOST_LLT) - 1) * 301L / 1000);
|
||||
BOOST_STATIC_CONSTANT(bool, is_signed = true);
|
||||
BOOST_STATIC_CONSTANT(bool, is_integer = true);
|
||||
BOOST_STATIC_CONSTANT(bool, is_exact = true);
|
||||
BOOST_STATIC_CONSTANT(int, radix = 2);
|
||||
static BOOST_LLT epsilon() throw() { return 0; };
|
||||
static BOOST_LLT round_error() throw() { return 0; };
|
||||
|
||||
BOOST_STATIC_CONSTANT(int, min_exponent = 0);
|
||||
BOOST_STATIC_CONSTANT(int, min_exponent10 = 0);
|
||||
BOOST_STATIC_CONSTANT(int, max_exponent = 0);
|
||||
BOOST_STATIC_CONSTANT(int, max_exponent10 = 0);
|
||||
|
||||
BOOST_STATIC_CONSTANT(bool, has_infinity = false);
|
||||
BOOST_STATIC_CONSTANT(bool, has_quiet_NaN = false);
|
||||
BOOST_STATIC_CONSTANT(bool, has_signaling_NaN = false);
|
||||
BOOST_STATIC_CONSTANT(bool, has_denorm = false);
|
||||
BOOST_STATIC_CONSTANT(bool, has_denorm_loss = false);
|
||||
static BOOST_LLT infinity() throw() { return 0; };
|
||||
static BOOST_LLT quiet_NaN() throw() { return 0; };
|
||||
static BOOST_LLT signaling_NaN() throw() { return 0; };
|
||||
static BOOST_LLT denorm_min() throw() { return 0; };
|
||||
|
||||
BOOST_STATIC_CONSTANT(bool, is_iec559 = false);
|
||||
BOOST_STATIC_CONSTANT(bool, is_bounded = true);
|
||||
BOOST_STATIC_CONSTANT(bool, is_modulo = true);
|
||||
|
||||
BOOST_STATIC_CONSTANT(bool, traps = false);
|
||||
BOOST_STATIC_CONSTANT(bool, tinyness_before = false);
|
||||
BOOST_STATIC_CONSTANT(float_round_style, round_style = round_toward_zero);
|
||||
|
||||
};
|
||||
|
||||
template<>
|
||||
class numeric_limits<BOOST_ULLT>
|
||||
{
|
||||
public:
|
||||
|
||||
BOOST_STATIC_CONSTANT(bool, is_specialized = true);
|
||||
#ifdef BOOST_HAS_MS_INT64
|
||||
static BOOST_ULLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return 0ui64; }
|
||||
static BOOST_ULLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return 0xFFFFFFFFFFFFFFFFui64; }
|
||||
#elif defined(ULLONG_MAX) && defined(ULLONG_MIN)
|
||||
static BOOST_ULLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return ULLONG_MIN; }
|
||||
static BOOST_ULLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return ULLONG_MAX; }
|
||||
#elif defined(ULONGLONG_MAX) && defined(ULONGLONG_MIN)
|
||||
static BOOST_ULLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return ULONGLONG_MIN; }
|
||||
static BOOST_ULLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return ULONGLONG_MAX; }
|
||||
#else
|
||||
static BOOST_ULLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return 0uLL; }
|
||||
static BOOST_ULLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return ~0uLL; }
|
||||
#endif
|
||||
BOOST_STATIC_CONSTANT(int, digits = sizeof(BOOST_LLT) * CHAR_BIT);
|
||||
BOOST_STATIC_CONSTANT(int, digits10 = (CHAR_BIT * sizeof (BOOST_LLT)) * 301L / 1000);
|
||||
BOOST_STATIC_CONSTANT(bool, is_signed = false);
|
||||
BOOST_STATIC_CONSTANT(bool, is_integer = true);
|
||||
BOOST_STATIC_CONSTANT(bool, is_exact = true);
|
||||
BOOST_STATIC_CONSTANT(int, radix = 2);
|
||||
static BOOST_ULLT epsilon() throw() { return 0; };
|
||||
static BOOST_ULLT round_error() throw() { return 0; };
|
||||
|
||||
BOOST_STATIC_CONSTANT(int, min_exponent = 0);
|
||||
BOOST_STATIC_CONSTANT(int, min_exponent10 = 0);
|
||||
BOOST_STATIC_CONSTANT(int, max_exponent = 0);
|
||||
BOOST_STATIC_CONSTANT(int, max_exponent10 = 0);
|
||||
|
||||
BOOST_STATIC_CONSTANT(bool, has_infinity = false);
|
||||
BOOST_STATIC_CONSTANT(bool, has_quiet_NaN = false);
|
||||
BOOST_STATIC_CONSTANT(bool, has_signaling_NaN = false);
|
||||
BOOST_STATIC_CONSTANT(bool, has_denorm = false);
|
||||
BOOST_STATIC_CONSTANT(bool, has_denorm_loss = false);
|
||||
static BOOST_ULLT infinity() throw() { return 0; };
|
||||
static BOOST_ULLT quiet_NaN() throw() { return 0; };
|
||||
static BOOST_ULLT signaling_NaN() throw() { return 0; };
|
||||
static BOOST_ULLT denorm_min() throw() { return 0; };
|
||||
|
||||
BOOST_STATIC_CONSTANT(bool, is_iec559 = false);
|
||||
BOOST_STATIC_CONSTANT(bool, is_bounded = true);
|
||||
BOOST_STATIC_CONSTANT(bool, is_modulo = true);
|
||||
|
||||
BOOST_STATIC_CONSTANT(bool, traps = false);
|
||||
BOOST_STATIC_CONSTANT(bool, tinyness_before = false);
|
||||
BOOST_STATIC_CONSTANT(float_round_style, round_style = round_toward_zero);
|
||||
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -6,11 +6,10 @@
|
|||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
// Preprocessed version of "boost/mpl/aux_/template_arity.hpp" header
|
||||
// *Preprocessed* version of the main "template_arity.hpp" header
|
||||
// -- DO NOT modify by hand!
|
||||
|
||||
namespace boost { namespace mpl { namespace aux {
|
||||
|
||||
template< int N > struct arity_tag
|
||||
{
|
||||
typedef char (&type)[N + 1];
|
||||
|
@ -23,7 +22,6 @@ struct max_arity
|
|||
{
|
||||
BOOST_STATIC_CONSTANT(int, value =
|
||||
( C6 > 0 ? C6 : ( C5 > 0 ? C5 : ( C4 > 0 ? C4 : ( C3 > 0 ? C3 : ( C2 > 0 ? C2 : ( C1 > 0 ? C1 : -1 ) ) ) ) ) )
|
||||
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -83,7 +81,7 @@ template< typename F, int N >
|
|||
struct template_arity_impl
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(int, value =
|
||||
sizeof(arity_helper(type_wrapper<F>(), arity_tag<N>())) - 1
|
||||
sizeof(::boost::mpl::aux::arity_helper(type_wrapper<F>(), arity_tag<N>())) - 1
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -92,9 +90,7 @@ struct template_arity
|
|||
{
|
||||
BOOST_STATIC_CONSTANT(int, value = (
|
||||
max_arity< template_arity_impl< F,1 >::value, template_arity_impl< F,2 >::value, template_arity_impl< F,3 >::value, template_arity_impl< F,4 >::value, template_arity_impl< F,5 >::value, template_arity_impl< F,6 >::value >::value
|
||||
|
||||
));
|
||||
|
||||
typedef mpl::int_<value> type;
|
||||
};
|
||||
|
||||
|
|
|
@ -14,9 +14,9 @@
|
|||
//
|
||||
// See http://www.boost.org/libs/mpl for documentation.
|
||||
|
||||
// $Id: template_arity.hpp 49267 2008-10-11 06:19:02Z agurtovoy $
|
||||
// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $
|
||||
// $Revision: 49267 $
|
||||
// $Id: template_arity.hpp 61584 2010-04-26 18:48:26Z agurtovoy $
|
||||
// $Date: 2010-04-26 14:48:26 -0400 (Mon, 26 Apr 2010) $
|
||||
// $Revision: 61584 $
|
||||
|
||||
#include <boost/mpl/aux_/config/ttp.hpp>
|
||||
#include <boost/mpl/aux_/config/lambda.hpp>
|
||||
|
@ -98,7 +98,7 @@ template< typename F, BOOST_MPL_AUX_NTTP_DECL(int, N) >
|
|||
struct template_arity_impl
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(int, value =
|
||||
sizeof(arity_helper(type_wrapper<F>(),arity_tag<N>())) - 1
|
||||
sizeof(::boost::mpl::aux::arity_helper(type_wrapper<F>(),arity_tag<N>())) - 1
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#ifndef BOOST_MPL_ZIP_VIEW_HPP_INCLUDED
|
||||
#define BOOST_MPL_ZIP_VIEW_HPP_INCLUDED
|
||||
|
||||
// Copyright Aleksey Gurtovoy 2000-2002
|
||||
// Copyright Aleksey Gurtovoy 2000-2010
|
||||
// Copyright David Abrahams 2000-2002
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
|
@ -11,9 +11,9 @@
|
|||
//
|
||||
// See http://www.boost.org/libs/mpl for documentation.
|
||||
|
||||
// $Id: zip_view.hpp 49267 2008-10-11 06:19:02Z agurtovoy $
|
||||
// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $
|
||||
// $Revision: 49267 $
|
||||
// $Id: zip_view.hpp 61591 2010-04-26 21:31:09Z agurtovoy $
|
||||
// $Date: 2010-04-26 17:31:09 -0400 (Mon, 26 Apr 2010) $
|
||||
// $Revision: 61591 $
|
||||
|
||||
#include <boost/mpl/transform.hpp>
|
||||
#include <boost/mpl/begin_end.hpp>
|
||||
|
@ -53,6 +53,7 @@ struct zip_view
|
|||
|
||||
public:
|
||||
typedef nested_begin_end_tag tag;
|
||||
typedef zip_view type;
|
||||
typedef zip_iterator<first_ones_> begin;
|
||||
typedef zip_iterator<last_ones_> end;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,448 @@
|
|||
/*
|
||||
Copyright 2008 Intel Corporation
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
*/
|
||||
#ifndef BOOST_POLYGON_BOOLEAN_OP_HPP
|
||||
#define BOOST_POLYGON_BOOLEAN_OP_HPP
|
||||
namespace boost { namespace polygon{
|
||||
namespace boolean_op {
|
||||
|
||||
//BooleanOp is the generic boolean operation scanline algorithm that provides
|
||||
//all the simple boolean set operations on manhattan data. By templatizing
|
||||
//the intersection count of the input and algorithm internals it is extensible
|
||||
//to multi-layer scans, properties and other advanced scanline operations above
|
||||
//and beyond simple booleans.
|
||||
//T must cast to int
|
||||
template <class T, typename Unit>
|
||||
class BooleanOp {
|
||||
public:
|
||||
typedef std::map<Unit, T> ScanData;
|
||||
typedef std::pair<Unit, T> ElementType;
|
||||
protected:
|
||||
ScanData scanData_;
|
||||
typename ScanData::iterator nextItr_;
|
||||
T nullT_;
|
||||
public:
|
||||
inline BooleanOp () : scanData_(), nextItr_(), nullT_() { nextItr_ = scanData_.end(); nullT_ = 0; }
|
||||
inline BooleanOp (T nullT) : scanData_(), nextItr_(), nullT_(nullT) { nextItr_ = scanData_.end(); }
|
||||
inline BooleanOp (const BooleanOp& that) : scanData_(that.scanData_), nextItr_(),
|
||||
nullT_(that.nullT_) { nextItr_ = scanData_.begin(); }
|
||||
inline BooleanOp& operator=(const BooleanOp& that);
|
||||
|
||||
//moves scanline forward
|
||||
inline void advanceScan() { nextItr_ = scanData_.begin(); }
|
||||
|
||||
//proceses the given interval and T data
|
||||
//appends output edges to cT
|
||||
template <class cT>
|
||||
inline void processInterval(cT& outputContainer, interval_data<Unit> ivl, T deltaCount);
|
||||
|
||||
private:
|
||||
inline typename ScanData::iterator lookup_(Unit pos){
|
||||
if(nextItr_ != scanData_.end() && nextItr_->first >= pos) {
|
||||
return nextItr_;
|
||||
}
|
||||
return nextItr_ = scanData_.lower_bound(pos);
|
||||
}
|
||||
inline typename ScanData::iterator insert_(Unit pos, T count){
|
||||
return nextItr_ = scanData_.insert(nextItr_, ElementType(pos, count));
|
||||
}
|
||||
template <class cT>
|
||||
inline void evaluateInterval_(cT& outputContainer, interval_data<Unit> ivl, T beforeCount, T afterCount);
|
||||
};
|
||||
|
||||
class BinaryAnd {
|
||||
public:
|
||||
inline BinaryAnd() {}
|
||||
inline bool operator()(int a, int b) { return (a > 0) & (b > 0); }
|
||||
};
|
||||
class BinaryOr {
|
||||
public:
|
||||
inline BinaryOr() {}
|
||||
inline bool operator()(int a, int b) { return (a > 0) | (b > 0); }
|
||||
};
|
||||
class BinaryNot {
|
||||
public:
|
||||
inline BinaryNot() {}
|
||||
inline bool operator()(int a, int b) { return (a > 0) & !(b > 0); }
|
||||
};
|
||||
class BinaryXor {
|
||||
public:
|
||||
inline BinaryXor() {}
|
||||
inline bool operator()(int a, int b) { return (a > 0) ^ (b > 0); }
|
||||
};
|
||||
|
||||
//BinaryCount is an array of two deltaCounts coming from two different layers
|
||||
//of scan event data. It is the merged count of the two suitable for consumption
|
||||
//as the template argument of the BooleanOp algorithm because BinaryCount casts to int.
|
||||
//T is a binary functor object that evaluates the array of counts and returns a logical
|
||||
//result of some operation on those values.
|
||||
//BinaryCount supports many of the operators that work with int, particularly the
|
||||
//binary operators, but cannot support less than or increment.
|
||||
template <class T>
|
||||
class BinaryCount {
|
||||
public:
|
||||
inline BinaryCount()
|
||||
#ifndef BOOST_POLYGON_MSVC
|
||||
: counts_()
|
||||
#endif
|
||||
{ counts_[0] = counts_[1] = 0; }
|
||||
// constructs from two integers
|
||||
inline BinaryCount(int countL, int countR)
|
||||
#ifndef BOOST_POLYGON_MSVC
|
||||
: counts_()
|
||||
#endif
|
||||
{ counts_[0] = countL, counts_[1] = countR; }
|
||||
inline BinaryCount& operator=(int count) { counts_[0] = count, counts_[1] = count; return *this; }
|
||||
inline BinaryCount& operator=(const BinaryCount& that);
|
||||
inline BinaryCount(const BinaryCount& that)
|
||||
#ifndef BOOST_POLYGON_MSVC
|
||||
: counts_()
|
||||
#endif
|
||||
{ *this = that; }
|
||||
inline bool operator==(const BinaryCount& that) const;
|
||||
inline bool operator!=(const BinaryCount& that) const { return !((*this) == that);}
|
||||
inline BinaryCount& operator+=(const BinaryCount& that);
|
||||
inline BinaryCount& operator-=(const BinaryCount& that);
|
||||
inline BinaryCount operator+(const BinaryCount& that) const;
|
||||
inline BinaryCount operator-(const BinaryCount& that) const;
|
||||
inline BinaryCount operator-() const;
|
||||
inline int& operator[](bool index) { return counts_[index]; }
|
||||
|
||||
//cast to int operator evaluates data using T binary functor
|
||||
inline operator int() const { return T()(counts_[0], counts_[1]); }
|
||||
private:
|
||||
int counts_[2];
|
||||
};
|
||||
|
||||
class UnaryCount {
|
||||
public:
|
||||
inline UnaryCount() : count_(0) {}
|
||||
// constructs from two integers
|
||||
inline explicit UnaryCount(int count) : count_(count) {}
|
||||
inline UnaryCount& operator=(int count) { count_ = count; return *this; }
|
||||
inline UnaryCount& operator=(const UnaryCount& that) { count_ = that.count_; return *this; }
|
||||
inline UnaryCount(const UnaryCount& that) : count_(that.count_) {}
|
||||
inline bool operator==(const UnaryCount& that) const { return count_ == that.count_; }
|
||||
inline bool operator!=(const UnaryCount& that) const { return !((*this) == that);}
|
||||
inline UnaryCount& operator+=(const UnaryCount& that) { count_ += that.count_; return *this; }
|
||||
inline UnaryCount& operator-=(const UnaryCount& that) { count_ -= that.count_; return *this; }
|
||||
inline UnaryCount operator+(const UnaryCount& that) const { UnaryCount tmp(*this); tmp += that; return tmp; }
|
||||
inline UnaryCount operator-(const UnaryCount& that) const { UnaryCount tmp(*this); tmp -= that; return tmp; }
|
||||
inline UnaryCount operator-() const { UnaryCount tmp; return tmp - *this; }
|
||||
|
||||
//cast to int operator evaluates data using T binary functor
|
||||
inline operator int() const { return count_ % 2; }
|
||||
private:
|
||||
int count_;
|
||||
};
|
||||
|
||||
template <class T, typename Unit>
|
||||
inline BooleanOp<T, Unit>& BooleanOp<T, Unit>::operator=(const BooleanOp& that) {
|
||||
scanData_ = that.scanData_;
|
||||
nextItr_ = scanData_.begin();
|
||||
nullT_ = that.nullT_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//appends output edges to cT
|
||||
template <class T, typename Unit>
|
||||
template <class cT>
|
||||
inline void BooleanOp<T, Unit>::processInterval(cT& outputContainer, interval_data<Unit> ivl, T deltaCount) {
|
||||
typename ScanData::iterator lowItr = lookup_(ivl.low());
|
||||
typename ScanData::iterator highItr = lookup_(ivl.high());
|
||||
//add interval to scan data if it is past the end
|
||||
if(lowItr == scanData_.end()) {
|
||||
lowItr = insert_(ivl.low(), deltaCount);
|
||||
highItr = insert_(ivl.high(), nullT_);
|
||||
evaluateInterval_(outputContainer, ivl, nullT_, deltaCount);
|
||||
return;
|
||||
}
|
||||
//ensure that highItr points to the end of the ivl
|
||||
if(highItr == scanData_.end() || (*highItr).first > ivl.high()) {
|
||||
T value = nullT_;
|
||||
if(highItr != scanData_.begin()) {
|
||||
--highItr;
|
||||
value = highItr->second;
|
||||
}
|
||||
nextItr_ = highItr;
|
||||
highItr = insert_(ivl.high(), value);
|
||||
}
|
||||
//split the low interval if needed
|
||||
if(lowItr->first > ivl.low()) {
|
||||
if(lowItr != scanData_.begin()) {
|
||||
--lowItr;
|
||||
nextItr_ = lowItr;
|
||||
lowItr = insert_(ivl.low(), lowItr->second);
|
||||
} else {
|
||||
nextItr_ = lowItr;
|
||||
lowItr = insert_(ivl.low(), nullT_);
|
||||
}
|
||||
}
|
||||
//process scan data intersecting interval
|
||||
for(typename ScanData::iterator itr = lowItr; itr != highItr; ){
|
||||
T beforeCount = itr->second;
|
||||
T afterCount = itr->second += deltaCount;
|
||||
Unit low = itr->first;
|
||||
++itr;
|
||||
Unit high = itr->first;
|
||||
evaluateInterval_(outputContainer, interval_data<Unit>(low, high), beforeCount, afterCount);
|
||||
}
|
||||
//merge the bottom interval with the one below if they have the same count
|
||||
if(lowItr != scanData_.begin()){
|
||||
typename ScanData::iterator belowLowItr = lowItr;
|
||||
--belowLowItr;
|
||||
if(belowLowItr->second == lowItr->second) {
|
||||
scanData_.erase(lowItr);
|
||||
}
|
||||
}
|
||||
//merge the top interval with the one above if they have the same count
|
||||
if(highItr != scanData_.begin()) {
|
||||
typename ScanData::iterator beforeHighItr = highItr;
|
||||
--beforeHighItr;
|
||||
if(beforeHighItr->second == highItr->second) {
|
||||
scanData_.erase(highItr);
|
||||
highItr = beforeHighItr;
|
||||
++highItr;
|
||||
}
|
||||
}
|
||||
nextItr_ = highItr;
|
||||
}
|
||||
|
||||
template <class T, typename Unit>
|
||||
template <class cT>
|
||||
inline void BooleanOp<T, Unit>::evaluateInterval_(cT& outputContainer, interval_data<Unit> ivl,
|
||||
T beforeCount, T afterCount) {
|
||||
bool before = (int)beforeCount > 0;
|
||||
bool after = (int)afterCount > 0;
|
||||
int value = (!before & after) - (before & !after);
|
||||
if(value) {
|
||||
outputContainer.insert(outputContainer.end(), std::pair<interval_data<Unit>, int>(ivl, value));
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline BinaryCount<T>& BinaryCount<T>::operator=(const BinaryCount<T>& that) {
|
||||
counts_[0] = that.counts_[0];
|
||||
counts_[1] = that.counts_[1];
|
||||
return *this;
|
||||
}
|
||||
template <class T>
|
||||
inline bool BinaryCount<T>::operator==(const BinaryCount<T>& that) const {
|
||||
return counts_[0] == that.counts_[0] &&
|
||||
counts_[1] == that.counts_[1];
|
||||
}
|
||||
template <class T>
|
||||
inline BinaryCount<T>& BinaryCount<T>::operator+=(const BinaryCount<T>& that) {
|
||||
counts_[0] += that.counts_[0];
|
||||
counts_[1] += that.counts_[1];
|
||||
return *this;
|
||||
}
|
||||
template <class T>
|
||||
inline BinaryCount<T>& BinaryCount<T>::operator-=(const BinaryCount<T>& that) {
|
||||
counts_[0] += that.counts_[0];
|
||||
counts_[1] += that.counts_[1];
|
||||
return *this;
|
||||
}
|
||||
template <class T>
|
||||
inline BinaryCount<T> BinaryCount<T>::operator+(const BinaryCount<T>& that) const {
|
||||
BinaryCount retVal(*this);
|
||||
retVal += that;
|
||||
return retVal;
|
||||
}
|
||||
template <class T>
|
||||
inline BinaryCount<T> BinaryCount<T>::operator-(const BinaryCount<T>& that) const {
|
||||
BinaryCount retVal(*this);
|
||||
retVal -= that;
|
||||
return retVal;
|
||||
}
|
||||
template <class T>
|
||||
inline BinaryCount<T> BinaryCount<T>::operator-() const {
|
||||
return BinaryCount<T>() - *this;
|
||||
}
|
||||
|
||||
|
||||
template <class T, typename Unit, typename iterator_type_1, typename iterator_type_2>
|
||||
inline void applyBooleanBinaryOp(std::vector<std::pair<Unit, std::pair<Unit, int> > >& output,
|
||||
//const std::vector<std::pair<Unit, std::pair<Unit, int> > >& input1,
|
||||
//const std::vector<std::pair<Unit, std::pair<Unit, int> > >& input2,
|
||||
iterator_type_1 itr1, iterator_type_1 itr1_end,
|
||||
iterator_type_2 itr2, iterator_type_2 itr2_end,
|
||||
T defaultCount) {
|
||||
BooleanOp<T, Unit> boolean(defaultCount);
|
||||
//typename std::vector<std::pair<Unit, std::pair<Unit, int> > >::const_iterator itr1 = input1.begin();
|
||||
//typename std::vector<std::pair<Unit, std::pair<Unit, int> > >::const_iterator itr2 = input2.begin();
|
||||
std::vector<std::pair<interval_data<Unit>, int> > container;
|
||||
//output.reserve((std::max)(input1.size(), input2.size()));
|
||||
|
||||
//consider eliminating dependecy on limits with bool flag for initial state
|
||||
Unit UnitMax = (std::numeric_limits<Unit>::max)();
|
||||
Unit prevCoord = UnitMax;
|
||||
Unit prevPosition = UnitMax;
|
||||
T count(defaultCount);
|
||||
//define the starting point
|
||||
if(itr1 != itr1_end) {
|
||||
prevCoord = (*itr1).first;
|
||||
prevPosition = (*itr1).second.first;
|
||||
count[0] += (*itr1).second.second;
|
||||
}
|
||||
if(itr2 != itr2_end) {
|
||||
if((*itr2).first < prevCoord ||
|
||||
((*itr2).first == prevCoord && (*itr2).second.first < prevPosition)) {
|
||||
prevCoord = (*itr2).first;
|
||||
prevPosition = (*itr2).second.first;
|
||||
count = defaultCount;
|
||||
count[1] += (*itr2).second.second;
|
||||
++itr2;
|
||||
} else if((*itr2).first == prevCoord && (*itr2).second.first == prevPosition) {
|
||||
count[1] += (*itr2).second.second;
|
||||
++itr2;
|
||||
if(itr1 != itr1_end) ++itr1;
|
||||
} else {
|
||||
if(itr1 != itr1_end) ++itr1;
|
||||
}
|
||||
} else {
|
||||
if(itr1 != itr1_end) ++itr1;
|
||||
}
|
||||
|
||||
while(itr1 != itr1_end || itr2 != itr2_end) {
|
||||
Unit curCoord = UnitMax;
|
||||
Unit curPosition = UnitMax;
|
||||
T curCount(defaultCount);
|
||||
if(itr1 != itr1_end) {
|
||||
curCoord = (*itr1).first;
|
||||
curPosition = (*itr1).second.first;
|
||||
curCount[0] += (*itr1).second.second;
|
||||
}
|
||||
if(itr2 != itr2_end) {
|
||||
if((*itr2).first < curCoord ||
|
||||
((*itr2).first == curCoord && (*itr2).second.first < curPosition)) {
|
||||
curCoord = (*itr2).first;
|
||||
curPosition = (*itr2).second.first;
|
||||
curCount = defaultCount;
|
||||
curCount[1] += (*itr2).second.second;
|
||||
++itr2;
|
||||
} else if((*itr2).first == curCoord && (*itr2).second.first == curPosition) {
|
||||
curCount[1] += (*itr2).second.second;
|
||||
++itr2;
|
||||
if(itr1 != itr1_end) ++itr1;
|
||||
} else {
|
||||
if(itr1 != itr1_end) ++itr1;
|
||||
}
|
||||
} else {
|
||||
++itr1;
|
||||
}
|
||||
|
||||
if(prevCoord != curCoord) {
|
||||
boolean.advanceScan();
|
||||
prevCoord = curCoord;
|
||||
prevPosition = curPosition;
|
||||
count = curCount;
|
||||
continue;
|
||||
}
|
||||
if(curPosition != prevPosition && count != defaultCount) {
|
||||
interval_data<Unit> ivl(prevPosition, curPosition);
|
||||
container.clear();
|
||||
boolean.processInterval(container, ivl, count);
|
||||
for(std::size_t i = 0; i < container.size(); ++i) {
|
||||
std::pair<interval_data<Unit>, int>& element = container[i];
|
||||
if(!output.empty() && output.back().first == prevCoord &&
|
||||
output.back().second.first == element.first.low() &&
|
||||
output.back().second.second == element.second * -1) {
|
||||
output.pop_back();
|
||||
} else {
|
||||
output.push_back(std::pair<Unit, std::pair<Unit, int> >(prevCoord, std::pair<Unit, int>(element.first.low(),
|
||||
element.second)));
|
||||
}
|
||||
output.push_back(std::pair<Unit, std::pair<Unit, int> >(prevCoord, std::pair<Unit, int>(element.first.high(),
|
||||
element.second * -1)));
|
||||
}
|
||||
}
|
||||
prevPosition = curPosition;
|
||||
count += curCount;
|
||||
}
|
||||
}
|
||||
|
||||
template <class T, typename Unit>
|
||||
inline void applyBooleanBinaryOp(std::vector<std::pair<Unit, std::pair<Unit, int> > >& inputOutput,
|
||||
const std::vector<std::pair<Unit, std::pair<Unit, int> > >& input2,
|
||||
T defaultCount) {
|
||||
std::vector<std::pair<Unit, std::pair<Unit, int> > > output;
|
||||
applyBooleanBinaryOp(output, inputOutput, input2, defaultCount);
|
||||
if(output.size() < inputOutput.size() / 2) {
|
||||
inputOutput = std::vector<std::pair<Unit, std::pair<Unit, int> > >();
|
||||
} else {
|
||||
inputOutput.clear();
|
||||
}
|
||||
inputOutput.insert(inputOutput.end(), output.begin(), output.end());
|
||||
}
|
||||
|
||||
template <typename Unit>
|
||||
inline void applyUnaryXOr(std::vector<std::pair<Unit, std::pair<Unit, int> > >& input) {
|
||||
BooleanOp<UnaryCount, Unit> booleanXOr;
|
||||
|
||||
}
|
||||
|
||||
template <typename count_type = int>
|
||||
struct default_arg_workaround {
|
||||
template <typename Unit>
|
||||
static inline void applyBooleanOr(std::vector<std::pair<Unit, std::pair<Unit, int> > >& input) {
|
||||
BooleanOp<count_type, Unit> booleanOr;
|
||||
std::vector<std::pair<interval_data<Unit>, int> > container;
|
||||
std::vector<std::pair<Unit, std::pair<Unit, int> > > output;
|
||||
output.reserve(input.size());
|
||||
//consider eliminating dependecy on limits with bool flag for initial state
|
||||
Unit UnitMax = (std::numeric_limits<Unit>::max)();
|
||||
Unit prevPos = UnitMax;
|
||||
Unit prevY = UnitMax;
|
||||
int count = 0;
|
||||
for(typename std::vector<std::pair<Unit, std::pair<Unit, int> > >::iterator itr = input.begin();
|
||||
itr != input.end(); ++itr) {
|
||||
Unit pos = (*itr).first;
|
||||
Unit y = (*itr).second.first;
|
||||
if(pos != prevPos) {
|
||||
booleanOr.advanceScan();
|
||||
prevPos = pos;
|
||||
prevY = y;
|
||||
count = (*itr).second.second;
|
||||
continue;
|
||||
}
|
||||
if(y != prevY && count != 0) {
|
||||
interval_data<Unit> ivl(prevY, y);
|
||||
container.clear();
|
||||
booleanOr.processInterval(container, ivl, count_type(count));
|
||||
for(std::size_t i = 0; i < container.size(); ++i) {
|
||||
std::pair<interval_data<Unit>, int>& element = container[i];
|
||||
if(!output.empty() && output.back().first == prevPos &&
|
||||
output.back().second.first == element.first.low() &&
|
||||
output.back().second.second == element.second * -1) {
|
||||
output.pop_back();
|
||||
} else {
|
||||
output.push_back(std::pair<Unit, std::pair<Unit, int> >(prevPos, std::pair<Unit, int>(element.first.low(),
|
||||
element.second)));
|
||||
}
|
||||
output.push_back(std::pair<Unit, std::pair<Unit, int> >(prevPos, std::pair<Unit, int>(element.first.high(),
|
||||
element.second * -1)));
|
||||
}
|
||||
}
|
||||
prevY = y;
|
||||
count += (*itr).second.second;
|
||||
}
|
||||
if(output.size() < input.size() / 2) {
|
||||
input = std::vector<std::pair<Unit, std::pair<Unit, int> > >();
|
||||
} else {
|
||||
input.clear();
|
||||
}
|
||||
input.insert(input.end(), output.begin(), output.end());
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
Copyright 2008 Intel Corporation
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
*/
|
||||
#ifndef BOOST_POLYGON_ITERATOR_COMPACT_TO_POINTS_HPP
|
||||
#define BOOST_POLYGON_ITERATOR_COMPACT_TO_POINTS_HPP
|
||||
namespace boost { namespace polygon{
|
||||
template <typename iterator_type, typename point_type>
|
||||
class iterator_compact_to_points {
|
||||
private:
|
||||
iterator_type iter_;
|
||||
iterator_type iter_end_;
|
||||
point_type pt_;
|
||||
typename point_traits<point_type>::coordinate_type firstX_;
|
||||
orientation_2d orient_;
|
||||
public:
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
typedef point_type value_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef const point_type* pointer; //immutable
|
||||
typedef const point_type& reference; //immutable
|
||||
|
||||
inline iterator_compact_to_points() : iter_(), iter_end_(), pt_(), firstX_(), orient_() {}
|
||||
inline iterator_compact_to_points(iterator_type iter, iterator_type iter_end) :
|
||||
iter_(iter), iter_end_(iter_end), pt_(), firstX_(), orient_(HORIZONTAL) {
|
||||
if(iter_ != iter_end_) {
|
||||
firstX_ = *iter_;
|
||||
x(pt_, firstX_);
|
||||
++iter_;
|
||||
if(iter_ != iter_end_) {
|
||||
y(pt_, *iter_);
|
||||
}
|
||||
}
|
||||
}
|
||||
//use bitwise copy and assign provided by the compiler
|
||||
inline iterator_compact_to_points& operator++() {
|
||||
iterator_type prev_iter = iter_;
|
||||
++iter_;
|
||||
if(iter_ == iter_end_) {
|
||||
if(x(pt_) != firstX_) {
|
||||
iter_ = prev_iter;
|
||||
x(pt_, firstX_);
|
||||
}
|
||||
} else {
|
||||
set(pt_, orient_, *iter_);
|
||||
orient_.turn_90();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
inline const iterator_compact_to_points operator++(int) {
|
||||
iterator_compact_to_points tmp(*this);
|
||||
++(*this);
|
||||
return tmp;
|
||||
}
|
||||
inline bool operator==(const iterator_compact_to_points& that) const {
|
||||
return (iter_ == that.iter_);
|
||||
}
|
||||
inline bool operator!=(const iterator_compact_to_points& that) const {
|
||||
return (iter_ != that.iter_);
|
||||
}
|
||||
inline reference operator*() const { return pt_; }
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,309 @@
|
|||
/*
|
||||
Copyright 2008 Intel Corporation
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
*/
|
||||
#ifndef BOOST_POLYGON_ITERATOR_GEOMETRY_TO_SET_HPP
|
||||
#define BOOST_POLYGON_ITERATOR_GEOMETRY_TO_SET_HPP
|
||||
namespace boost { namespace polygon{
|
||||
template <typename concept_type, typename geometry_type>
|
||||
class iterator_geometry_to_set {};
|
||||
|
||||
template <typename rectangle_type>
|
||||
class iterator_geometry_to_set<rectangle_concept, rectangle_type> {
|
||||
public:
|
||||
typedef typename rectangle_traits<rectangle_type>::coordinate_type coordinate_type;
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
typedef std::pair<coordinate_type, std::pair<coordinate_type, int> > value_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef const value_type* pointer; //immutable
|
||||
typedef const value_type& reference; //immutable
|
||||
private:
|
||||
rectangle_data<coordinate_type> rectangle_;
|
||||
mutable value_type vertex_;
|
||||
unsigned int corner_;
|
||||
orientation_2d orient_;
|
||||
bool is_hole_;
|
||||
public:
|
||||
iterator_geometry_to_set() : rectangle_(), vertex_(), corner_(4), orient_(), is_hole_() {}
|
||||
iterator_geometry_to_set(const rectangle_type& rectangle, direction_1d dir,
|
||||
orientation_2d orient = HORIZONTAL, bool is_hole = false) :
|
||||
rectangle_(), vertex_(), corner_(0), orient_(orient), is_hole_(is_hole) {
|
||||
assign(rectangle_, rectangle);
|
||||
if(dir == HIGH) corner_ = 4;
|
||||
}
|
||||
inline iterator_geometry_to_set& operator++() {
|
||||
++corner_;
|
||||
return *this;
|
||||
}
|
||||
inline const iterator_geometry_to_set operator++(int) {
|
||||
iterator_geometry_to_set tmp(*this);
|
||||
++(*this);
|
||||
return tmp;
|
||||
}
|
||||
inline bool operator==(const iterator_geometry_to_set& that) const {
|
||||
return corner_ == that.corner_;
|
||||
}
|
||||
inline bool operator!=(const iterator_geometry_to_set& that) const {
|
||||
return !(*this == that);
|
||||
}
|
||||
inline reference operator*() const {
|
||||
if(corner_ == 0) {
|
||||
vertex_.first = get(get(rectangle_, orient_.get_perpendicular()), LOW);
|
||||
vertex_.second.first = get(get(rectangle_, orient_), LOW);
|
||||
vertex_.second.second = 1;
|
||||
if(is_hole_) vertex_.second.second *= -1;
|
||||
} else if(corner_ == 1) {
|
||||
vertex_.second.first = get(get(rectangle_, orient_), HIGH);
|
||||
vertex_.second.second = -1;
|
||||
if(is_hole_) vertex_.second.second *= -1;
|
||||
} else if(corner_ == 2) {
|
||||
vertex_.first = get(get(rectangle_, orient_.get_perpendicular()), HIGH);
|
||||
vertex_.second.first = get(get(rectangle_, orient_), LOW);
|
||||
} else {
|
||||
vertex_.second.first = get(get(rectangle_, orient_), HIGH);
|
||||
vertex_.second.second = 1;
|
||||
if(is_hole_) vertex_.second.second *= -1;
|
||||
}
|
||||
return vertex_;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename polygon_type>
|
||||
class iterator_geometry_to_set<polygon_90_concept, polygon_type> {
|
||||
public:
|
||||
typedef typename polygon_traits<polygon_type>::coordinate_type coordinate_type;
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
typedef std::pair<coordinate_type, std::pair<coordinate_type, int> > value_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef const value_type* pointer; //immutable
|
||||
typedef const value_type& reference; //immutable
|
||||
typedef typename polygon_traits<polygon_type>::iterator_type coord_iterator_type;
|
||||
private:
|
||||
value_type vertex_;
|
||||
typename polygon_traits<polygon_type>::iterator_type itrb, itre;
|
||||
bool last_vertex_;
|
||||
bool is_hole_;
|
||||
int multiplier_;
|
||||
point_data<coordinate_type> first_pt, second_pt, pts[3];
|
||||
bool use_wrap;
|
||||
orientation_2d orient_;
|
||||
int polygon_index;
|
||||
public:
|
||||
iterator_geometry_to_set() : vertex_(), itrb(), itre(), last_vertex_(), is_hole_(), multiplier_(), first_pt(), second_pt(), pts(), use_wrap(), orient_(), polygon_index(-1) {}
|
||||
iterator_geometry_to_set(const polygon_type& polygon, direction_1d dir, orientation_2d orient = HORIZONTAL, bool is_hole = false) :
|
||||
vertex_(), itrb(), itre(), last_vertex_(),
|
||||
is_hole_(is_hole), multiplier_(), first_pt(), second_pt(), pts(), use_wrap(),
|
||||
orient_(orient), polygon_index(0) {
|
||||
itrb = begin_points(polygon);
|
||||
itre = end_points(polygon);
|
||||
use_wrap = false;
|
||||
if(itrb == itre || dir == HIGH || size(polygon) < 4) {
|
||||
polygon_index = -1;
|
||||
} else {
|
||||
direction_1d wdir = winding(polygon);
|
||||
multiplier_ = wdir == LOW ? -1 : 1;
|
||||
if(is_hole_) multiplier_ *= -1;
|
||||
first_pt = pts[0] = *itrb;
|
||||
++itrb;
|
||||
second_pt = pts[1] = *itrb;
|
||||
++itrb;
|
||||
pts[2] = *itrb;
|
||||
evaluate_();
|
||||
}
|
||||
}
|
||||
iterator_geometry_to_set(const iterator_geometry_to_set& that) :
|
||||
vertex_(), itrb(), itre(), last_vertex_(), is_hole_(), multiplier_(), first_pt(),
|
||||
second_pt(), pts(), use_wrap(), orient_(), polygon_index(-1) {
|
||||
vertex_ = that.vertex_;
|
||||
itrb = that.itrb;
|
||||
itre = that.itre;
|
||||
last_vertex_ = that.last_vertex_;
|
||||
is_hole_ = that.is_hole_;
|
||||
multiplier_ = that.multiplier_;
|
||||
first_pt = that.first_pt;
|
||||
second_pt = that.second_pt;
|
||||
pts[0] = that.pts[0];
|
||||
pts[1] = that.pts[1];
|
||||
pts[2] = that.pts[2];
|
||||
use_wrap = that.use_wrap;
|
||||
orient_ = that.orient_;
|
||||
polygon_index = that.polygon_index;
|
||||
}
|
||||
inline iterator_geometry_to_set& operator++() {
|
||||
++polygon_index;
|
||||
if(itrb == itre) {
|
||||
if(first_pt == pts[1]) polygon_index = -1;
|
||||
else {
|
||||
pts[0] = pts[1];
|
||||
pts[1] = pts[2];
|
||||
if(first_pt == pts[2]) {
|
||||
pts[2] = second_pt;
|
||||
} else {
|
||||
pts[2] = first_pt;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
++itrb;
|
||||
pts[0] = pts[1];
|
||||
pts[1] = pts[2];
|
||||
if(itrb == itre) {
|
||||
if(first_pt == pts[2]) {
|
||||
pts[2] = second_pt;
|
||||
} else {
|
||||
pts[2] = first_pt;
|
||||
}
|
||||
} else {
|
||||
pts[2] = *itrb;
|
||||
}
|
||||
}
|
||||
evaluate_();
|
||||
return *this;
|
||||
}
|
||||
inline const iterator_geometry_to_set operator++(int) {
|
||||
iterator_geometry_to_set tmp(*this);
|
||||
++(*this);
|
||||
return tmp;
|
||||
}
|
||||
inline bool operator==(const iterator_geometry_to_set& that) const {
|
||||
return polygon_index == that.polygon_index;
|
||||
}
|
||||
inline bool operator!=(const iterator_geometry_to_set& that) const {
|
||||
return !(*this == that);
|
||||
}
|
||||
inline reference operator*() const {
|
||||
return vertex_;
|
||||
}
|
||||
|
||||
inline void evaluate_() {
|
||||
vertex_.first = pts[1].get(orient_.get_perpendicular());
|
||||
vertex_.second.first =pts[1].get(orient_);
|
||||
if(pts[1] == pts[2]) {
|
||||
vertex_.second.second = 0;
|
||||
return;
|
||||
}
|
||||
if(pts[0].get(HORIZONTAL) != pts[1].get(HORIZONTAL)) {
|
||||
vertex_.second.second = -1;
|
||||
} else if(pts[0].get(VERTICAL) != pts[1].get(VERTICAL)) {
|
||||
vertex_.second.second = 1;
|
||||
} else {
|
||||
vertex_.second.second = 0;
|
||||
}
|
||||
vertex_.second.second *= multiplier_;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename polygon_with_holes_type>
|
||||
class iterator_geometry_to_set<polygon_90_with_holes_concept, polygon_with_holes_type> {
|
||||
public:
|
||||
typedef typename polygon_90_traits<polygon_with_holes_type>::coordinate_type coordinate_type;
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
typedef std::pair<coordinate_type, std::pair<coordinate_type, int> > value_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef const value_type* pointer; //immutable
|
||||
typedef const value_type& reference; //immutable
|
||||
private:
|
||||
iterator_geometry_to_set<polygon_90_concept, polygon_with_holes_type> itrb, itre;
|
||||
iterator_geometry_to_set<polygon_90_concept, typename polygon_with_holes_traits<polygon_with_holes_type>::hole_type> itrhib, itrhie;
|
||||
typename polygon_with_holes_traits<polygon_with_holes_type>::iterator_holes_type itrhb, itrhe;
|
||||
orientation_2d orient_;
|
||||
bool is_hole_;
|
||||
bool started_holes;
|
||||
public:
|
||||
iterator_geometry_to_set() : itrb(), itre(), itrhib(), itrhie(), itrhb(), itrhe(), orient_(), is_hole_(), started_holes() {}
|
||||
iterator_geometry_to_set(const polygon_with_holes_type& polygon, direction_1d dir,
|
||||
orientation_2d orient = HORIZONTAL, bool is_hole = false) :
|
||||
itrb(), itre(), itrhib(), itrhie(), itrhb(), itrhe(), orient_(orient), is_hole_(is_hole), started_holes() {
|
||||
itre = iterator_geometry_to_set<polygon_90_concept, polygon_with_holes_type>(polygon, HIGH, orient, is_hole_);
|
||||
itrhe = end_holes(polygon);
|
||||
if(dir == HIGH) {
|
||||
itrb = itre;
|
||||
itrhb = itrhe;
|
||||
started_holes = true;
|
||||
} else {
|
||||
itrb = iterator_geometry_to_set<polygon_90_concept, polygon_with_holes_type>(polygon, LOW, orient, is_hole_);
|
||||
itrhb = begin_holes(polygon);
|
||||
started_holes = false;
|
||||
}
|
||||
}
|
||||
iterator_geometry_to_set(const iterator_geometry_to_set& that) :
|
||||
itrb(), itre(), itrhib(), itrhie(), itrhb(), itrhe(), orient_(), is_hole_(), started_holes() {
|
||||
itrb = that.itrb;
|
||||
itre = that.itre;
|
||||
if(that.itrhib != that.itrhie) {
|
||||
itrhib = that.itrhib;
|
||||
itrhie = that.itrhie;
|
||||
}
|
||||
itrhb = that.itrhb;
|
||||
itrhe = that.itrhe;
|
||||
orient_ = that.orient_;
|
||||
is_hole_ = that.is_hole_;
|
||||
started_holes = that.started_holes;
|
||||
}
|
||||
inline iterator_geometry_to_set& operator++() {
|
||||
//this code can be folded with flow control factoring
|
||||
if(itrb == itre) {
|
||||
if(itrhib == itrhie) {
|
||||
if(itrhb != itrhe) {
|
||||
itrhib = iterator_geometry_to_set<polygon_90_concept,
|
||||
typename polygon_with_holes_traits<polygon_with_holes_type>::hole_type>(*itrhb, LOW, orient_, !is_hole_);
|
||||
itrhie = iterator_geometry_to_set<polygon_90_concept,
|
||||
typename polygon_with_holes_traits<polygon_with_holes_type>::hole_type>(*itrhb, HIGH, orient_, !is_hole_);
|
||||
++itrhb;
|
||||
} else {
|
||||
itrhib = itrhie = iterator_geometry_to_set<polygon_90_concept,
|
||||
typename polygon_with_holes_traits<polygon_with_holes_type>::hole_type>();
|
||||
}
|
||||
} else {
|
||||
++itrhib;
|
||||
if(itrhib == itrhie) {
|
||||
if(itrhb != itrhe) {
|
||||
itrhib = iterator_geometry_to_set<polygon_90_concept,
|
||||
typename polygon_with_holes_traits<polygon_with_holes_type>::hole_type>(*itrhb, LOW, orient_, !is_hole_);
|
||||
itrhie = iterator_geometry_to_set<polygon_90_concept,
|
||||
typename polygon_with_holes_traits<polygon_with_holes_type>::hole_type>(*itrhb, HIGH, orient_, !is_hole_);
|
||||
++itrhb;
|
||||
} else {
|
||||
itrhib = itrhie = iterator_geometry_to_set<polygon_90_concept,
|
||||
typename polygon_with_holes_traits<polygon_with_holes_type>::hole_type>();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
++itrb;
|
||||
if(itrb == itre) {
|
||||
if(itrhb != itrhe) {
|
||||
itrhib = iterator_geometry_to_set<polygon_90_concept,
|
||||
typename polygon_with_holes_traits<polygon_with_holes_type>::hole_type>(*itrhb, LOW, orient_, !is_hole_);
|
||||
itrhie = iterator_geometry_to_set<polygon_90_concept,
|
||||
typename polygon_with_holes_traits<polygon_with_holes_type>::hole_type>(*itrhb, HIGH, orient_, !is_hole_);
|
||||
++itrhb;
|
||||
}
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
inline const iterator_geometry_to_set operator++(int) {
|
||||
iterator_geometry_to_set tmp(*this);
|
||||
++(*this);
|
||||
return tmp;
|
||||
}
|
||||
inline bool operator==(const iterator_geometry_to_set& that) const {
|
||||
return itrb == that.itrb && itrhb == that.itrhb && itrhib == that.itrhib;
|
||||
}
|
||||
inline bool operator!=(const iterator_geometry_to_set& that) const {
|
||||
return !(*this == that);
|
||||
}
|
||||
inline reference operator*() const {
|
||||
if(itrb != itre) return *itrb;
|
||||
return *itrhib;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
Copyright 2008 Intel Corporation
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
*/
|
||||
#ifndef BOOST_POLYGON_ITERATOR_POINTS_TO_COMPACT_HPP
|
||||
#define BOOST_POLYGON_ITERATOR_POINTS_TO_COMPACT_HPP
|
||||
namespace boost { namespace polygon{
|
||||
template <typename iT, typename point_type>
|
||||
class iterator_points_to_compact {
|
||||
private:
|
||||
iT iter_, iterEnd_;
|
||||
orientation_2d orient_;
|
||||
mutable typename point_traits<point_type>::coordinate_type coord_;
|
||||
public:
|
||||
typedef typename point_traits<point_type>::coordinate_type coordinate_type;
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
typedef coordinate_type value_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef const coordinate_type* pointer; //immutable
|
||||
typedef const coordinate_type& reference; //immutable
|
||||
|
||||
inline iterator_points_to_compact() : iter_(), iterEnd_(), orient_(), coord_() {}
|
||||
inline iterator_points_to_compact(iT iter, iT iterEnd) :
|
||||
iter_(iter), iterEnd_(iterEnd), orient_(HORIZONTAL), coord_() {}
|
||||
inline iterator_points_to_compact(const iterator_points_to_compact& that) :
|
||||
iter_(that.iter_), iterEnd_(that.iterEnd_), orient_(that.orient_), coord_(that.coord_) {}
|
||||
//use bitwise copy and assign provided by the compiler
|
||||
inline iterator_points_to_compact& operator++() {
|
||||
//iT tmp = iter_;
|
||||
++iter_;
|
||||
//iT tmp2 = iter_;
|
||||
orient_.turn_90();
|
||||
//while(tmp2 != iterEnd_ && get(*tmp2, orient_) == get(*tmp, orient_)) {
|
||||
// iter_ = tmp2;
|
||||
// ++tmp2;
|
||||
//}
|
||||
return *this;
|
||||
}
|
||||
inline const iterator_points_to_compact operator++(int) {
|
||||
iT tmp(*this);
|
||||
++(*this);
|
||||
return tmp;
|
||||
}
|
||||
inline bool operator==(const iterator_points_to_compact& that) const {
|
||||
return (iter_ == that.iter_);
|
||||
}
|
||||
inline bool operator!=(const iterator_points_to_compact& that) const {
|
||||
return (iter_ != that.iter_);
|
||||
}
|
||||
inline reference operator*() const { coord_ = get(*iter_, orient_);
|
||||
return coord_;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,278 @@
|
|||
/*
|
||||
Copyright 2008 Intel Corporation
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
*/
|
||||
#ifndef BOOST_POLYGON_MAX_COVER_HPP
|
||||
#define BOOST_POLYGON_MAX_COVER_HPP
|
||||
namespace boost { namespace polygon{
|
||||
|
||||
template <typename Unit>
|
||||
struct MaxCover {
|
||||
typedef interval_data<Unit> Interval;
|
||||
typedef rectangle_data<Unit> Rectangle;
|
||||
|
||||
class Node {
|
||||
private:
|
||||
std::vector<Node*> children_;
|
||||
std::set<Interval> tracedPaths_;
|
||||
public:
|
||||
Rectangle rect;
|
||||
Node() : children_(), tracedPaths_(), rect() {}
|
||||
Node(const Rectangle rectIn) : children_(), tracedPaths_(), rect(rectIn) {}
|
||||
typedef typename std::vector<Node*>::iterator iterator;
|
||||
inline iterator begin() { return children_.begin(); }
|
||||
inline iterator end() { return children_.end(); }
|
||||
inline void add(Node* child) { children_.push_back(child); }
|
||||
inline bool tracedPath(const Interval& ivl) const {
|
||||
return tracedPaths_.find(ivl) != tracedPaths_.end();
|
||||
}
|
||||
inline void addPath(const Interval& ivl) {
|
||||
tracedPaths_.insert(tracedPaths_.end(), ivl);
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::pair<std::pair<Unit, Interval>, Node* > EdgeAssociation;
|
||||
|
||||
class lessEdgeAssociation : public std::binary_function<const EdgeAssociation&, const EdgeAssociation&, bool> {
|
||||
public:
|
||||
inline lessEdgeAssociation() {}
|
||||
inline bool operator () (const EdgeAssociation& elem1, const EdgeAssociation& elem2) const {
|
||||
if(elem1.first.first < elem2.first.first) return true;
|
||||
if(elem1.first.first > elem2.first.first) return false;
|
||||
return elem1.first.second < elem2.first.second;
|
||||
}
|
||||
};
|
||||
|
||||
template <class cT>
|
||||
static inline void getMaxCover(cT& outputContainer, Node* node, orientation_2d orient) {
|
||||
Interval rectIvl = node->rect.get(orient);
|
||||
if(node->tracedPath(rectIvl)) {
|
||||
return;
|
||||
}
|
||||
node->addPath(rectIvl);
|
||||
if(node->begin() == node->end()) {
|
||||
//std::cout << "WRITE OUT 3: " << node->rect << std::endl;
|
||||
outputContainer.push_back(copy_construct<typename cT::value_type, Rectangle>(node->rect));
|
||||
return;
|
||||
}
|
||||
bool writeOut = true;
|
||||
for(typename Node::iterator itr = node->begin(); itr != node->end(); ++itr) {
|
||||
getMaxCover(outputContainer, *itr, orient, node->rect); //get rectangles down path
|
||||
Interval nodeIvl = (*itr)->rect.get(orient);
|
||||
if(contains(nodeIvl, rectIvl, true)) writeOut = false;
|
||||
}
|
||||
if(writeOut) {
|
||||
//std::cout << "WRITE OUT 2: " << node->rect << std::endl;
|
||||
outputContainer.push_back(copy_construct<typename cT::value_type, Rectangle>(node->rect));
|
||||
}
|
||||
}
|
||||
|
||||
struct stack_element {
|
||||
inline stack_element() :
|
||||
node(), rect(), itr() {}
|
||||
inline stack_element(Node* n,
|
||||
const Rectangle& r,
|
||||
typename Node::iterator i) :
|
||||
node(n), rect(r), itr(i) {}
|
||||
Node* node;
|
||||
Rectangle rect;
|
||||
typename Node::iterator itr;
|
||||
};
|
||||
|
||||
template <class cT>
|
||||
static inline void getMaxCover(cT& outputContainer, Node* node, orientation_2d orient,
|
||||
Rectangle rect) {
|
||||
//std::cout << "New Root\n";
|
||||
std::vector<stack_element> stack;
|
||||
typename Node::iterator itr = node->begin();
|
||||
do {
|
||||
//std::cout << "LOOP\n";
|
||||
//std::cout << node->rect << std::endl;
|
||||
Interval rectIvl = rect.get(orient);
|
||||
Interval nodeIvl = node->rect.get(orient);
|
||||
bool iresult = intersect(rectIvl, nodeIvl, false);
|
||||
bool tresult = !node->tracedPath(rectIvl);
|
||||
//std::cout << (itr != node->end()) << " " << iresult << " " << tresult << std::endl;
|
||||
Rectangle nextRect1 = Rectangle(rectIvl, rectIvl);
|
||||
Unit low = rect.get(orient.get_perpendicular()).low();
|
||||
Unit high = node->rect.get(orient.get_perpendicular()).high();
|
||||
nextRect1.set(orient.get_perpendicular(), Interval(low, high));
|
||||
if(iresult && tresult) {
|
||||
node->addPath(rectIvl);
|
||||
bool writeOut = true;
|
||||
//check further visibility beyond this node
|
||||
for(typename Node::iterator itr2 = node->begin(); itr2 != node->end(); ++itr2) {
|
||||
Interval nodeIvl3 = (*itr2)->rect.get(orient);
|
||||
//if a child of this node can contain the interval then we can extend through
|
||||
if(contains(nodeIvl3, rectIvl, true)) writeOut = false;
|
||||
//std::cout << "child " << (*itr2)->rect << std::endl;
|
||||
}
|
||||
Rectangle nextRect2 = Rectangle(rectIvl, rectIvl);
|
||||
Unit low2 = rect.get(orient.get_perpendicular()).low();
|
||||
Unit high2 = node->rect.get(orient.get_perpendicular()).high();
|
||||
nextRect2.set(orient.get_perpendicular(), Interval(low2, high2));
|
||||
if(writeOut) {
|
||||
//std::cout << "write out " << nextRect << std::endl;
|
||||
outputContainer.push_back(copy_construct<typename cT::value_type, Rectangle>(nextRect2));
|
||||
} else {
|
||||
//std::cout << "supress " << nextRect << std::endl;
|
||||
}
|
||||
}
|
||||
if(itr != node->end() && iresult && tresult) {
|
||||
//std::cout << "recurse into child\n";
|
||||
stack.push_back(stack_element(node, rect, itr));
|
||||
rect = nextRect1;
|
||||
node = *itr;
|
||||
itr = node->begin();
|
||||
} else {
|
||||
if(!stack.empty()) {
|
||||
//std::cout << "recurse out of child\n";
|
||||
node = stack.back().node;
|
||||
rect = stack.back().rect;
|
||||
itr = stack.back().itr;
|
||||
stack.pop_back();
|
||||
} else {
|
||||
//std::cout << "empty stack\n";
|
||||
//if there were no children of the root node
|
||||
// Rectangle nextRect = Rectangle(rectIvl, rectIvl);
|
||||
// Unit low = rect.get(orient.get_perpendicular()).low();
|
||||
// Unit high = node->rect.get(orient.get_perpendicular()).high();
|
||||
// nextRect.set(orient.get_perpendicular(), Interval(low, high));
|
||||
// outputContainer.push_back(copy_construct<typename cT::value_type, Rectangle>(nextRect));
|
||||
}
|
||||
//std::cout << "increment " << (itr != node->end()) << std::endl;
|
||||
if(itr != node->end()) {
|
||||
++itr;
|
||||
if(itr != node->end()) {
|
||||
//std::cout << "recurse into next child.\n";
|
||||
stack.push_back(stack_element(node, rect, itr));
|
||||
Interval rectIvl2 = rect.get(orient);
|
||||
Interval nodeIvl2 = node->rect.get(orient);
|
||||
/*bool iresult =*/ intersect(rectIvl2, nodeIvl2, false);
|
||||
Rectangle nextRect2 = Rectangle(rectIvl2, rectIvl2);
|
||||
Unit low2 = rect.get(orient.get_perpendicular()).low();
|
||||
Unit high2 = node->rect.get(orient.get_perpendicular()).high();
|
||||
nextRect2.set(orient.get_perpendicular(), Interval(low2, high2));
|
||||
rect = nextRect2;
|
||||
//std::cout << "rect for next child" << rect << std::endl;
|
||||
node = *itr;
|
||||
itr = node->begin();
|
||||
}
|
||||
}
|
||||
}
|
||||
} while(!stack.empty() || itr != node->end());
|
||||
}
|
||||
|
||||
/* Function recursive version of getMaxCover
|
||||
Because the code is so much simpler than the loop algorithm I retain it for clarity
|
||||
|
||||
template <class cT>
|
||||
static inline void getMaxCover(cT& outputContainer, Node* node, orientation_2d orient,
|
||||
const Rectangle& rect) {
|
||||
Interval rectIvl = rect.get(orient);
|
||||
Interval nodeIvl = node->rect.get(orient);
|
||||
if(!intersect(rectIvl, nodeIvl, false)) {
|
||||
return;
|
||||
}
|
||||
if(node->tracedPath(rectIvl)) {
|
||||
return;
|
||||
}
|
||||
node->addPath(rectIvl);
|
||||
Rectangle nextRect(rectIvl, rectIvl);
|
||||
Unit low = rect.get(orient.get_perpendicular()).low();
|
||||
Unit high = node->rect.get(orient.get_perpendicular()).high();
|
||||
nextRect.set(orient.get_perpendicular(), Interval(low, high));
|
||||
bool writeOut = true;
|
||||
rectIvl = nextRect.get(orient);
|
||||
for(typename Node::iterator itr = node->begin(); itr != node->end(); ++itr) {
|
||||
nodeIvl = (*itr)->rect.get(orient);
|
||||
if(contains(nodeIvl, rectIvl, true)) writeOut = false;
|
||||
}
|
||||
if(writeOut) {
|
||||
outputContainer.push_back(copy_construct<typename cT::value_type, Rectangle>(nextRect));
|
||||
}
|
||||
for(typename Node::iterator itr = node->begin(); itr != node->end(); ++itr) {
|
||||
getMaxCover(outputContainer, *itr, orient, nextRect);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
//iterator range is assummed to be in topological order meaning all node's trailing
|
||||
//edges are in sorted order
|
||||
template <class iT>
|
||||
static inline void computeDag(iT beginNode, iT endNode, orientation_2d orient,
|
||||
std::size_t size) {
|
||||
std::vector<EdgeAssociation> leadingEdges;
|
||||
leadingEdges.reserve(size);
|
||||
for(iT iter = beginNode; iter != endNode; ++iter) {
|
||||
Node* nodep = &(*iter);
|
||||
Unit leading = nodep->rect.get(orient.get_perpendicular()).low();
|
||||
Interval rectIvl = nodep->rect.get(orient);
|
||||
leadingEdges.push_back(EdgeAssociation(std::pair<Unit, Interval>(leading, rectIvl), nodep));
|
||||
}
|
||||
std::sort(leadingEdges.begin(), leadingEdges.end(), lessEdgeAssociation());
|
||||
typename std::vector<EdgeAssociation>::iterator leadingBegin = leadingEdges.begin();
|
||||
iT trailingBegin = beginNode;
|
||||
while(leadingBegin != leadingEdges.end()) {
|
||||
EdgeAssociation& leadingSegment = (*leadingBegin);
|
||||
Unit trailing = (*trailingBegin).rect.get(orient.get_perpendicular()).high();
|
||||
Interval ivl = (*trailingBegin).rect.get(orient);
|
||||
std::pair<Unit, Interval> trailingSegment(trailing, ivl);
|
||||
if(leadingSegment.first.first < trailingSegment.first) {
|
||||
++leadingBegin;
|
||||
continue;
|
||||
}
|
||||
if(leadingSegment.first.first > trailingSegment.first) {
|
||||
++trailingBegin;
|
||||
continue;
|
||||
}
|
||||
if(leadingSegment.first.second.high() <= trailingSegment.second.low()) {
|
||||
++leadingBegin;
|
||||
continue;
|
||||
}
|
||||
if(trailingSegment.second.high() <= leadingSegment.first.second.low()) {
|
||||
++trailingBegin;
|
||||
continue;
|
||||
}
|
||||
//leading segment intersects trailing segment
|
||||
(*trailingBegin).add((*leadingBegin).second);
|
||||
if(leadingSegment.first.second.high() > trailingSegment.second.high()) {
|
||||
++trailingBegin;
|
||||
continue;
|
||||
}
|
||||
if(trailingSegment.second.high() > leadingSegment.first.second.high()) {
|
||||
++leadingBegin;
|
||||
continue;
|
||||
}
|
||||
++leadingBegin;
|
||||
++trailingBegin;
|
||||
}
|
||||
}
|
||||
|
||||
template <class cT>
|
||||
static inline void getMaxCover(cT& outputContainer,
|
||||
const std::vector<Rectangle>& rects, orientation_2d orient) {
|
||||
if(rects.empty()) return;
|
||||
std::vector<Node> nodes;
|
||||
{
|
||||
if(rects.size() == 1) {
|
||||
outputContainer.push_back(copy_construct<typename cT::value_type, Rectangle>(rects[0]));
|
||||
return;
|
||||
}
|
||||
nodes.reserve(rects.size());
|
||||
for(std::size_t i = 0; i < rects.size(); ++i) { nodes.push_back(Node(rects[i])); }
|
||||
}
|
||||
computeDag(nodes.begin(), nodes.end(), orient, nodes.size());
|
||||
for(std::size_t i = 0; i < nodes.size(); ++i) {
|
||||
getMaxCover(outputContainer, &(nodes[i]), orient);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,378 @@
|
|||
/*
|
||||
Copyright 2008 Intel Corporation
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
*/
|
||||
#ifndef BOOST_POLYGON_POLYGON_45_SET_VIEW_HPP
|
||||
#define BOOST_POLYGON_POLYGON_45_SET_VIEW_HPP
|
||||
namespace boost { namespace polygon{
|
||||
|
||||
template <typename ltype, typename rtype, int op_type>
|
||||
class polygon_45_set_view;
|
||||
|
||||
template <typename ltype, typename rtype, int op_type>
|
||||
struct polygon_45_set_traits<polygon_45_set_view<ltype, rtype, op_type> > {
|
||||
typedef typename polygon_45_set_view<ltype, rtype, op_type>::coordinate_type coordinate_type;
|
||||
typedef typename polygon_45_set_view<ltype, rtype, op_type>::iterator_type iterator_type;
|
||||
typedef typename polygon_45_set_view<ltype, rtype, op_type>::operator_arg_type operator_arg_type;
|
||||
|
||||
static inline iterator_type begin(const polygon_45_set_view<ltype, rtype, op_type>& polygon_45_set);
|
||||
static inline iterator_type end(const polygon_45_set_view<ltype, rtype, op_type>& polygon_45_set);
|
||||
|
||||
template <typename input_iterator_type>
|
||||
static inline void set(polygon_45_set_view<ltype, rtype, op_type>& polygon_45_set,
|
||||
input_iterator_type input_begin, input_iterator_type input_end);
|
||||
|
||||
static inline bool clean(const polygon_45_set_view<ltype, rtype, op_type>& polygon_45_set);
|
||||
|
||||
};
|
||||
|
||||
template <typename value_type, typename ltype, typename rtype, int op_type>
|
||||
struct compute_45_set_value {
|
||||
static
|
||||
void value(value_type& output_, const ltype& lvalue_, const rtype& rvalue_) {
|
||||
output_.set(polygon_45_set_traits<ltype>::begin(lvalue_),
|
||||
polygon_45_set_traits<ltype>::end(lvalue_));
|
||||
value_type rinput_;
|
||||
rinput_.set(polygon_45_set_traits<rtype>::begin(rvalue_),
|
||||
polygon_45_set_traits<rtype>::end(rvalue_));
|
||||
#ifdef BOOST_POLYGON_MSVC
|
||||
#pragma warning (disable: 4127)
|
||||
#endif
|
||||
if(op_type == 0)
|
||||
output_ |= rinput_;
|
||||
else if(op_type == 1)
|
||||
output_ &= rinput_;
|
||||
else if(op_type == 2)
|
||||
output_ ^= rinput_;
|
||||
else
|
||||
output_ -= rinput_;
|
||||
#ifdef BOOST_POLYGON_MSVC
|
||||
#pragma warning (default: 4127)
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
template <typename value_type, typename ltype, typename rcoord, int op_type>
|
||||
struct compute_45_set_value<value_type, ltype, polygon_45_set_data<rcoord>, op_type> {
|
||||
static
|
||||
void value(value_type& output_, const ltype& lvalue_, const polygon_45_set_data<rcoord>& rvalue_) {
|
||||
output_.set(polygon_45_set_traits<ltype>::begin(lvalue_),
|
||||
polygon_45_set_traits<ltype>::end(lvalue_));
|
||||
#ifdef BOOST_POLYGON_MSVC
|
||||
#pragma warning (disable: 4127)
|
||||
#endif
|
||||
if(op_type == 0)
|
||||
output_ |= rvalue_;
|
||||
else if(op_type == 1)
|
||||
output_ &= rvalue_;
|
||||
else if(op_type == 2)
|
||||
output_ ^= rvalue_;
|
||||
else
|
||||
output_ -= rvalue_;
|
||||
#ifdef BOOST_POLYGON_MSVC
|
||||
#pragma warning (default: 4127)
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ltype, typename rtype, int op_type>
|
||||
class polygon_45_set_view {
|
||||
public:
|
||||
typedef typename polygon_45_set_traits<ltype>::coordinate_type coordinate_type;
|
||||
typedef polygon_45_set_data<coordinate_type> value_type;
|
||||
typedef typename value_type::iterator_type iterator_type;
|
||||
typedef polygon_45_set_view operator_arg_type;
|
||||
private:
|
||||
const ltype& lvalue_;
|
||||
const rtype& rvalue_;
|
||||
mutable value_type output_;
|
||||
mutable bool evaluated_;
|
||||
|
||||
polygon_45_set_view& operator=(const polygon_45_set_view&);
|
||||
public:
|
||||
polygon_45_set_view(const ltype& lvalue,
|
||||
const rtype& rvalue ) :
|
||||
lvalue_(lvalue), rvalue_(rvalue), output_(), evaluated_(false) {}
|
||||
|
||||
// get iterator to begin vertex data
|
||||
public:
|
||||
const value_type& value() const {
|
||||
if(!evaluated_) {
|
||||
evaluated_ = true;
|
||||
compute_45_set_value<value_type, ltype, rtype, op_type>::value(output_, lvalue_, rvalue_);
|
||||
}
|
||||
return output_;
|
||||
}
|
||||
public:
|
||||
iterator_type begin() const { return value().begin(); }
|
||||
iterator_type end() const { return value().end(); }
|
||||
|
||||
bool dirty() const { return value().dirty(); } //result of a boolean is clean
|
||||
bool sorted() const { return value().sorted(); } //result of a boolean is sorted
|
||||
|
||||
// template <typename input_iterator_type>
|
||||
// void set(input_iterator_type input_begin, input_iterator_type input_end,
|
||||
// orientation_2d orient) const {
|
||||
// orient_ = orient;
|
||||
// output_.clear();
|
||||
// output_.insert(output_.end(), input_begin, input_end);
|
||||
// std::sort(output_.begin(), output_.end());
|
||||
// }
|
||||
};
|
||||
|
||||
template <typename ltype, typename rtype, int op_type>
|
||||
typename polygon_45_set_view<ltype, rtype, op_type>::iterator_type
|
||||
polygon_45_set_traits<polygon_45_set_view<ltype, rtype, op_type> >::
|
||||
begin(const polygon_45_set_view<ltype, rtype, op_type>& polygon_45_set) {
|
||||
return polygon_45_set.begin();
|
||||
}
|
||||
template <typename ltype, typename rtype, int op_type>
|
||||
typename polygon_45_set_view<ltype, rtype, op_type>::iterator_type
|
||||
polygon_45_set_traits<polygon_45_set_view<ltype, rtype, op_type> >::
|
||||
end(const polygon_45_set_view<ltype, rtype, op_type>& polygon_45_set) {
|
||||
return polygon_45_set.end();
|
||||
}
|
||||
template <typename ltype, typename rtype, int op_type>
|
||||
bool polygon_45_set_traits<polygon_45_set_view<ltype, rtype, op_type> >::
|
||||
clean(const polygon_45_set_view<ltype, rtype, op_type>& polygon_45_set) {
|
||||
return polygon_45_set.value().clean(); }
|
||||
|
||||
template <typename geometry_type_1, typename geometry_type_2, int op_type>
|
||||
geometry_type_1& self_assignment_boolean_op_45(geometry_type_1& lvalue_, const geometry_type_2& rvalue_) {
|
||||
typedef geometry_type_1 ltype;
|
||||
typedef geometry_type_2 rtype;
|
||||
typedef typename polygon_45_set_traits<ltype>::coordinate_type coordinate_type;
|
||||
typedef polygon_45_set_data<coordinate_type> value_type;
|
||||
value_type output_;
|
||||
value_type rinput_;
|
||||
output_.set(polygon_45_set_traits<ltype>::begin(lvalue_),
|
||||
polygon_45_set_traits<ltype>::end(lvalue_));
|
||||
rinput_.set(polygon_45_set_traits<rtype>::begin(rvalue_),
|
||||
polygon_45_set_traits<rtype>::end(rvalue_));
|
||||
#ifdef BOOST_POLYGON_MSVC
|
||||
#pragma warning (disable: 4127)
|
||||
#endif
|
||||
if(op_type == 0)
|
||||
output_ |= rinput_;
|
||||
else if(op_type == 1)
|
||||
output_ &= rinput_;
|
||||
else if(op_type == 2)
|
||||
output_ ^= rinput_;
|
||||
else
|
||||
output_ -= rinput_;
|
||||
#ifdef BOOST_POLYGON_MSVC
|
||||
#pragma warning (default: 4127)
|
||||
#endif
|
||||
polygon_45_set_mutable_traits<geometry_type_1>::set(lvalue_, output_.begin(), output_.end());
|
||||
return lvalue_;
|
||||
}
|
||||
|
||||
template <typename concept_type>
|
||||
struct fracture_holes_option_by_type {
|
||||
static const bool value = true;
|
||||
};
|
||||
template <>
|
||||
struct fracture_holes_option_by_type<polygon_45_with_holes_concept> {
|
||||
static const bool value = false;
|
||||
};
|
||||
template <>
|
||||
struct fracture_holes_option_by_type<polygon_with_holes_concept> {
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template <typename ltype, typename rtype, int op_type>
|
||||
struct geometry_concept<polygon_45_set_view<ltype, rtype, op_type> > { typedef polygon_45_set_concept type; };
|
||||
|
||||
namespace operators {
|
||||
struct y_ps45_b : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename geometry_type_2>
|
||||
typename enable_if< typename gtl_and_4< y_ps45_b,
|
||||
typename is_polygon_45_or_90_set_type<geometry_type_1>::type,
|
||||
typename is_polygon_45_or_90_set_type<geometry_type_2>::type,
|
||||
typename is_either_polygon_45_set_type<geometry_type_1, geometry_type_2>::type>::type,
|
||||
polygon_45_set_view<geometry_type_1, geometry_type_2, 0> >::type
|
||||
operator|(const geometry_type_1& lvalue, const geometry_type_2& rvalue) {
|
||||
return polygon_45_set_view<geometry_type_1, geometry_type_2, 0>
|
||||
(lvalue, rvalue);
|
||||
}
|
||||
|
||||
struct y_ps45_p : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename geometry_type_2>
|
||||
typename enable_if< typename gtl_and_4< y_ps45_p,
|
||||
typename gtl_if<typename is_polygon_45_or_90_set_type<geometry_type_1>::type>::type,
|
||||
typename gtl_if<typename is_polygon_45_or_90_set_type<geometry_type_2>::type>::type,
|
||||
typename gtl_if<typename is_either_polygon_45_set_type<geometry_type_1, geometry_type_2>::type>::type>::type,
|
||||
polygon_45_set_view<geometry_type_1, geometry_type_2, 0> >::type
|
||||
operator+(const geometry_type_1& lvalue, const geometry_type_2& rvalue) {
|
||||
return polygon_45_set_view<geometry_type_1, geometry_type_2, 0>
|
||||
(lvalue, rvalue);
|
||||
}
|
||||
|
||||
struct y_ps45_s : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename geometry_type_2>
|
||||
typename enable_if< typename gtl_and_4< y_ps45_s, typename is_polygon_45_or_90_set_type<geometry_type_1>::type,
|
||||
typename is_polygon_45_or_90_set_type<geometry_type_2>::type,
|
||||
typename is_either_polygon_45_set_type<geometry_type_1, geometry_type_2>::type>::type,
|
||||
polygon_45_set_view<geometry_type_1, geometry_type_2, 1> >::type
|
||||
operator*(const geometry_type_1& lvalue, const geometry_type_2& rvalue) {
|
||||
return polygon_45_set_view<geometry_type_1, geometry_type_2, 1>
|
||||
(lvalue, rvalue);
|
||||
}
|
||||
|
||||
struct y_ps45_a : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename geometry_type_2>
|
||||
typename enable_if< typename gtl_and_4< y_ps45_a, typename is_polygon_45_or_90_set_type<geometry_type_1>::type,
|
||||
typename is_polygon_45_or_90_set_type<geometry_type_2>::type,
|
||||
typename is_either_polygon_45_set_type<geometry_type_1, geometry_type_2>::type>::type,
|
||||
polygon_45_set_view<geometry_type_1, geometry_type_2, 1> >::type
|
||||
operator&(const geometry_type_1& lvalue, const geometry_type_2& rvalue) {
|
||||
return polygon_45_set_view<geometry_type_1, geometry_type_2, 1>
|
||||
(lvalue, rvalue);
|
||||
}
|
||||
|
||||
struct y_ps45_x : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename geometry_type_2>
|
||||
typename enable_if< typename gtl_and_4< y_ps45_x, typename is_polygon_45_or_90_set_type<geometry_type_1>::type,
|
||||
typename is_polygon_45_or_90_set_type<geometry_type_2>::type,
|
||||
typename is_either_polygon_45_set_type<geometry_type_1, geometry_type_2>::type>::type,
|
||||
polygon_45_set_view<geometry_type_1, geometry_type_2, 2> >::type
|
||||
operator^(const geometry_type_1& lvalue, const geometry_type_2& rvalue) {
|
||||
return polygon_45_set_view<geometry_type_1, geometry_type_2, 2>
|
||||
(lvalue, rvalue);
|
||||
}
|
||||
|
||||
struct y_ps45_m : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename geometry_type_2>
|
||||
typename enable_if< typename gtl_and_4< y_ps45_m,
|
||||
typename gtl_if<typename is_polygon_45_or_90_set_type<geometry_type_1>::type>::type,
|
||||
typename gtl_if<typename is_polygon_45_or_90_set_type<geometry_type_2>::type>::type,
|
||||
typename gtl_if<typename is_either_polygon_45_set_type<geometry_type_1, geometry_type_2>::type>::type>::type,
|
||||
polygon_45_set_view<geometry_type_1, geometry_type_2, 3> >::type
|
||||
operator-(const geometry_type_1& lvalue, const geometry_type_2& rvalue) {
|
||||
return polygon_45_set_view<geometry_type_1, geometry_type_2, 3>
|
||||
(lvalue, rvalue);
|
||||
}
|
||||
|
||||
struct y_ps45_pe : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename geometry_type_2>
|
||||
typename enable_if< typename gtl_and_4<y_ps45_pe, typename is_mutable_polygon_45_set_type<geometry_type_1>::type, gtl_yes,
|
||||
typename is_polygon_45_or_90_set_type<geometry_type_2>::type>::type,
|
||||
geometry_type_1>::type &
|
||||
operator+=(geometry_type_1& lvalue, const geometry_type_2& rvalue) {
|
||||
return self_assignment_boolean_op_45<geometry_type_1, geometry_type_2, 0>(lvalue, rvalue);
|
||||
}
|
||||
|
||||
struct y_ps45_be : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename geometry_type_2>
|
||||
typename enable_if< typename gtl_and_3<y_ps45_be, typename is_mutable_polygon_45_set_type<geometry_type_1>::type,
|
||||
typename is_polygon_45_or_90_set_type<geometry_type_2>::type>::type,
|
||||
geometry_type_1>::type &
|
||||
operator|=(geometry_type_1& lvalue, const geometry_type_2& rvalue) {
|
||||
return self_assignment_boolean_op_45<geometry_type_1, geometry_type_2, 0>(lvalue, rvalue);
|
||||
}
|
||||
|
||||
struct y_ps45_se : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename geometry_type_2>
|
||||
typename enable_if< typename gtl_and_3< y_ps45_se,
|
||||
typename is_mutable_polygon_45_set_type<geometry_type_1>::type,
|
||||
typename is_polygon_45_or_90_set_type<geometry_type_2>::type>::type,
|
||||
geometry_type_1>::type &
|
||||
operator*=(geometry_type_1& lvalue, const geometry_type_2& rvalue) {
|
||||
return self_assignment_boolean_op_45<geometry_type_1, geometry_type_2, 1>(lvalue, rvalue);
|
||||
}
|
||||
|
||||
struct y_ps45_ae : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename geometry_type_2>
|
||||
typename enable_if< typename gtl_and_3<y_ps45_ae, typename is_mutable_polygon_45_set_type<geometry_type_1>::type,
|
||||
typename is_polygon_45_or_90_set_type<geometry_type_2>::type>::type,
|
||||
geometry_type_1>::type &
|
||||
operator&=(geometry_type_1& lvalue, const geometry_type_2& rvalue) {
|
||||
return self_assignment_boolean_op_45<geometry_type_1, geometry_type_2, 1>(lvalue, rvalue);
|
||||
}
|
||||
|
||||
struct y_ps45_xe : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename geometry_type_2>
|
||||
typename enable_if<
|
||||
typename gtl_and_3<y_ps45_xe, typename is_mutable_polygon_45_set_type<geometry_type_1>::type,
|
||||
typename is_polygon_45_or_90_set_type<geometry_type_2>::type>::type,
|
||||
geometry_type_1>::type &
|
||||
operator^=(geometry_type_1& lvalue, const geometry_type_2& rvalue) {
|
||||
return self_assignment_boolean_op_45<geometry_type_1, geometry_type_2, 2>(lvalue, rvalue);
|
||||
}
|
||||
|
||||
struct y_ps45_me : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename geometry_type_2>
|
||||
typename enable_if< typename gtl_and_3<y_ps45_me, typename is_mutable_polygon_45_set_type<geometry_type_1>::type,
|
||||
typename is_polygon_45_or_90_set_type<geometry_type_2>::type>::type,
|
||||
geometry_type_1>::type &
|
||||
operator-=(geometry_type_1& lvalue, const geometry_type_2& rvalue) {
|
||||
return self_assignment_boolean_op_45<geometry_type_1, geometry_type_2, 3>(lvalue, rvalue);
|
||||
}
|
||||
|
||||
struct y_ps45_rpe : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename coordinate_type_1>
|
||||
typename enable_if< typename gtl_and_3< y_ps45_rpe, typename is_mutable_polygon_45_set_type<geometry_type_1>::type,
|
||||
typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type,
|
||||
coordinate_concept>::type>::type,
|
||||
geometry_type_1>::type &
|
||||
operator+=(geometry_type_1& lvalue, coordinate_type_1 rvalue) {
|
||||
return resize(lvalue, rvalue);
|
||||
}
|
||||
|
||||
struct y_ps45_rme : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename coordinate_type_1>
|
||||
typename enable_if< typename gtl_and_3<y_ps45_rme, typename gtl_if<typename is_mutable_polygon_45_set_type<geometry_type_1>::type>::type,
|
||||
typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type,
|
||||
coordinate_concept>::type>::type,
|
||||
geometry_type_1>::type &
|
||||
operator-=(geometry_type_1& lvalue, coordinate_type_1 rvalue) {
|
||||
return resize(lvalue, -rvalue);
|
||||
}
|
||||
|
||||
struct y_ps45_rp : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename coordinate_type_1>
|
||||
typename enable_if< typename gtl_and_3<y_ps45_rp, typename gtl_if<typename is_mutable_polygon_45_set_type<geometry_type_1>::type>::type,
|
||||
typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type,
|
||||
coordinate_concept>::type>
|
||||
::type, geometry_type_1>::type
|
||||
operator+(const geometry_type_1& lvalue, coordinate_type_1 rvalue) {
|
||||
geometry_type_1 retval(lvalue);
|
||||
retval += rvalue;
|
||||
return retval;
|
||||
}
|
||||
|
||||
struct y_ps45_rm : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename coordinate_type_1>
|
||||
typename enable_if< typename gtl_and_3<y_ps45_rm, typename gtl_if<typename is_mutable_polygon_45_set_type<geometry_type_1>::type>::type,
|
||||
typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type,
|
||||
coordinate_concept>::type>
|
||||
::type, geometry_type_1>::type
|
||||
operator-(const geometry_type_1& lvalue, coordinate_type_1 rvalue) {
|
||||
geometry_type_1 retval(lvalue);
|
||||
retval -= rvalue;
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,236 @@
|
|||
/*
|
||||
Copyright 2008 Intel Corporation
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
*/
|
||||
#ifndef BOOST_POLYGON_POLYGON_45_TOUCH_HPP
|
||||
#define BOOST_POLYGON_POLYGON_45_TOUCH_HPP
|
||||
namespace boost { namespace polygon{
|
||||
|
||||
template <typename Unit>
|
||||
struct polygon_45_touch {
|
||||
|
||||
typedef point_data<Unit> Point;
|
||||
typedef typename coordinate_traits<Unit>::manhattan_area_type LongUnit;
|
||||
|
||||
template <typename property_map>
|
||||
static inline void merge_property_maps(property_map& mp, const property_map& mp2, bool subtract = false) {
|
||||
property_map newmp;
|
||||
newmp.reserve(mp.size() + mp2.size());
|
||||
std::size_t i = 0;
|
||||
std::size_t j = 0;
|
||||
while(i != mp.size() && j != mp2.size()) {
|
||||
if(mp[i].first < mp2[j].first) {
|
||||
newmp.push_back(mp[i]);
|
||||
++i;
|
||||
} else if(mp[i].first > mp2[j].first) {
|
||||
newmp.push_back(mp2[j]);
|
||||
if(subtract) newmp.back().second *= -1;
|
||||
++j;
|
||||
} else {
|
||||
int count = mp[i].second;
|
||||
if(subtract) count -= mp2[j].second;
|
||||
else count += mp2[j].second;
|
||||
if(count) {
|
||||
newmp.push_back(mp[i]);
|
||||
newmp.back().second = count;
|
||||
}
|
||||
++i;
|
||||
++j;
|
||||
}
|
||||
}
|
||||
while(i != mp.size()) {
|
||||
newmp.push_back(mp[i]);
|
||||
++i;
|
||||
}
|
||||
while(j != mp2.size()) {
|
||||
newmp.push_back(mp2[j]);
|
||||
if(subtract) newmp.back().second *= -1;
|
||||
++j;
|
||||
}
|
||||
mp.swap(newmp);
|
||||
}
|
||||
|
||||
class CountTouch {
|
||||
public:
|
||||
inline CountTouch() : counts() {}
|
||||
//inline CountTouch(int count) { counts[0] = counts[1] = count; }
|
||||
//inline CountTouch(int count1, int count2) { counts[0] = count1; counts[1] = count2; }
|
||||
inline CountTouch(const CountTouch& count) : counts(count.counts) {}
|
||||
inline bool operator==(const CountTouch& count) const { return counts == count.counts; }
|
||||
inline bool operator!=(const CountTouch& count) const { return !((*this) == count); }
|
||||
//inline CountTouch& operator=(int count) { counts[0] = counts[1] = count; return *this; }
|
||||
inline CountTouch& operator=(const CountTouch& count) { counts = count.counts; return *this; }
|
||||
inline int& operator[](int index) {
|
||||
std::vector<std::pair<int, int> >::iterator itr = lower_bound(counts.begin(), counts.end(), std::make_pair(index, int(0)));
|
||||
if(itr != counts.end() && itr->first == index) {
|
||||
return itr->second;
|
||||
}
|
||||
itr = counts.insert(itr, std::make_pair(index, int(0)));
|
||||
return itr->second;
|
||||
}
|
||||
// inline int operator[](int index) const {
|
||||
// std::vector<std::pair<int, int> >::const_iterator itr = counts.begin();
|
||||
// for( ; itr != counts.end() && itr->first <= index; ++itr) {
|
||||
// if(itr->first == index) {
|
||||
// return itr->second;
|
||||
// }
|
||||
// }
|
||||
// return 0;
|
||||
// }
|
||||
inline CountTouch& operator+=(const CountTouch& count){
|
||||
merge_property_maps(counts, count.counts, false);
|
||||
return *this;
|
||||
}
|
||||
inline CountTouch& operator-=(const CountTouch& count){
|
||||
merge_property_maps(counts, count.counts, true);
|
||||
return *this;
|
||||
}
|
||||
inline CountTouch operator+(const CountTouch& count) const {
|
||||
return CountTouch(*this)+=count;
|
||||
}
|
||||
inline CountTouch operator-(const CountTouch& count) const {
|
||||
return CountTouch(*this)-=count;
|
||||
}
|
||||
inline CountTouch invert() const {
|
||||
CountTouch retval;
|
||||
retval -= *this;
|
||||
return retval;
|
||||
}
|
||||
std::vector<std::pair<int, int> > counts;
|
||||
};
|
||||
|
||||
typedef std::pair<std::pair<Unit, std::map<Unit, std::set<int> > >, std::map<int, std::set<int> > > map_graph_o;
|
||||
typedef std::pair<std::pair<Unit, std::map<Unit, std::set<int> > >, std::vector<std::set<int> > > vector_graph_o;
|
||||
|
||||
template <typename cT>
|
||||
static void process_previous_x(cT& output) {
|
||||
std::map<Unit, std::set<int> >& y_prop_map = output.first.second;
|
||||
for(typename std::map<Unit, std::set<int> >::iterator itr = y_prop_map.begin();
|
||||
itr != y_prop_map.end(); ++itr) {
|
||||
for(std::set<int>::iterator inner_itr = itr->second.begin();
|
||||
inner_itr != itr->second.end(); ++inner_itr) {
|
||||
std::set<int>& output_edges = (*(output.second))[*inner_itr];
|
||||
std::set<int>::iterator inner_inner_itr = inner_itr;
|
||||
++inner_inner_itr;
|
||||
for( ; inner_inner_itr != itr->second.end(); ++inner_inner_itr) {
|
||||
output_edges.insert(output_edges.end(), *inner_inner_itr);
|
||||
std::set<int>& output_edges_2 = (*(output.second))[*inner_inner_itr];
|
||||
output_edges_2.insert(output_edges_2.end(), *inner_itr);
|
||||
}
|
||||
}
|
||||
}
|
||||
y_prop_map.clear();
|
||||
}
|
||||
|
||||
struct touch_45_output_functor {
|
||||
template <typename cT>
|
||||
void operator()(cT& output, const CountTouch& count1, const CountTouch& count2,
|
||||
const Point& pt, int , direction_1d ) {
|
||||
Unit& x = output.first.first;
|
||||
std::map<Unit, std::set<int> >& y_prop_map = output.first.second;
|
||||
if(pt.x() != x) process_previous_x(output);
|
||||
x = pt.x();
|
||||
std::set<int>& output_set = y_prop_map[pt.y()];
|
||||
for(std::vector<std::pair<int, int> >::const_iterator itr1 = count1.counts.begin();
|
||||
itr1 != count1.counts.end(); ++itr1) {
|
||||
if(itr1->second > 0) {
|
||||
output_set.insert(output_set.end(), itr1->first);
|
||||
}
|
||||
}
|
||||
for(std::vector<std::pair<int, int> >::const_iterator itr2 = count2.counts.begin();
|
||||
itr2 != count2.counts.end(); ++itr2) {
|
||||
if(itr2->second > 0) {
|
||||
output_set.insert(output_set.end(), itr2->first);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
typedef typename std::pair<Point,
|
||||
typename boolean_op_45<Unit>::template Scan45CountT<CountTouch> > Vertex45Compact;
|
||||
typedef std::vector<Vertex45Compact> TouchSetData;
|
||||
|
||||
struct lessVertex45Compact {
|
||||
bool operator()(const Vertex45Compact& l, const Vertex45Compact& r) {
|
||||
return l.first < r.first;
|
||||
}
|
||||
};
|
||||
|
||||
// template <typename TSD>
|
||||
// static void print_tsd(TSD& tsd) {
|
||||
// for(std::size_t i = 0; i < tsd.size(); ++i) {
|
||||
// std::cout << tsd[i].first << ": ";
|
||||
// for(unsigned int r = 0; r < 4; ++r) {
|
||||
// std::cout << r << " { ";
|
||||
// for(std::vector<std::pair<int, int> >::iterator itr = tsd[i].second[r].counts.begin();
|
||||
// itr != tsd[i].second[r].counts.end(); ++itr) {
|
||||
// std::cout << itr->first << "," << itr->second << " ";
|
||||
// } std::cout << "} ";
|
||||
// }
|
||||
// } std::cout << std::endl;
|
||||
// }
|
||||
|
||||
// template <typename T>
|
||||
// static void print_scanline(T& t) {
|
||||
// for(typename T::iterator itr = t.begin(); itr != t.end(); ++itr) {
|
||||
// std::cout << itr->x << "," << itr->y << " " << itr->rise << " ";
|
||||
// for(std::vector<std::pair<int, int> >::iterator itr2 = itr->count.counts.begin();
|
||||
// itr2 != itr->count.counts.end(); ++itr2) {
|
||||
// std::cout << itr2->first << ":" << itr2->second << " ";
|
||||
// } std::cout << std::endl;
|
||||
// }
|
||||
// }
|
||||
|
||||
template <typename graph_type>
|
||||
static void performTouch(graph_type& graph, TouchSetData& tsd) {
|
||||
|
||||
std::sort(tsd.begin(), tsd.end(), lessVertex45Compact());
|
||||
typedef std::vector<std::pair<Point, typename boolean_op_45<Unit>::template Scan45CountT<CountTouch> > > TSD;
|
||||
TSD tsd_;
|
||||
tsd_.reserve(tsd.size());
|
||||
for(typename TouchSetData::iterator itr = tsd.begin(); itr != tsd.end(); ) {
|
||||
typename TouchSetData::iterator itr2 = itr;
|
||||
++itr2;
|
||||
for(; itr2 != tsd.end() && itr2->first == itr->first; ++itr2) {
|
||||
(itr->second) += (itr2->second); //accumulate
|
||||
}
|
||||
tsd_.push_back(std::make_pair(itr->first, itr->second));
|
||||
itr = itr2;
|
||||
}
|
||||
std::pair<std::pair<Unit, std::map<Unit, std::set<int> > >, graph_type*> output
|
||||
(std::make_pair(std::make_pair((std::numeric_limits<Unit>::max)(), std::map<Unit, std::set<int> >()), &graph));
|
||||
typename boolean_op_45<Unit>::template Scan45<CountTouch, touch_45_output_functor> scanline;
|
||||
for(typename TSD::iterator itr = tsd_.begin(); itr != tsd_.end(); ) {
|
||||
typename TSD::iterator itr2 = itr;
|
||||
++itr2;
|
||||
while(itr2 != tsd_.end() && itr2->first.x() == itr->first.x()) {
|
||||
++itr2;
|
||||
}
|
||||
scanline.scan(output, itr, itr2);
|
||||
itr = itr2;
|
||||
}
|
||||
process_previous_x(output);
|
||||
}
|
||||
|
||||
template <typename iT>
|
||||
static void populateTouchSetData(TouchSetData& tsd, iT begin, iT end, int nodeCount) {
|
||||
for( ; begin != end; ++begin) {
|
||||
Vertex45Compact vertex;
|
||||
vertex.first = typename Vertex45Compact::first_type(begin->pt.x() * 2, begin->pt.y() * 2);
|
||||
tsd.push_back(vertex);
|
||||
for(unsigned int i = 0; i < 4; ++i) {
|
||||
if(begin->count[i]) {
|
||||
tsd.back().second[i][nodeCount] += begin->count[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,445 @@
|
|||
/*
|
||||
Copyright 2008 Intel Corporation
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
*/
|
||||
#ifndef BOOST_POLYGON_POLYGON_90_SET_VIEW_HPP
|
||||
#define BOOST_POLYGON_POLYGON_90_SET_VIEW_HPP
|
||||
namespace boost { namespace polygon{
|
||||
struct operator_provides_storage {};
|
||||
struct operator_requires_copy {};
|
||||
|
||||
template <typename value_type, typename arg_type>
|
||||
inline void insert_into_view_arg(value_type& dest, const arg_type& arg, orientation_2d orient);
|
||||
|
||||
template <typename ltype, typename rtype, typename op_type>
|
||||
class polygon_90_set_view;
|
||||
|
||||
template <typename ltype, typename rtype, typename op_type>
|
||||
struct polygon_90_set_traits<polygon_90_set_view<ltype, rtype, op_type> > {
|
||||
typedef typename polygon_90_set_view<ltype, rtype, op_type>::coordinate_type coordinate_type;
|
||||
typedef typename polygon_90_set_view<ltype, rtype, op_type>::iterator_type iterator_type;
|
||||
typedef typename polygon_90_set_view<ltype, rtype, op_type>::operator_arg_type operator_arg_type;
|
||||
|
||||
static inline iterator_type begin(const polygon_90_set_view<ltype, rtype, op_type>& polygon_set);
|
||||
static inline iterator_type end(const polygon_90_set_view<ltype, rtype, op_type>& polygon_set);
|
||||
|
||||
static inline orientation_2d orient(const polygon_90_set_view<ltype, rtype, op_type>& polygon_set);
|
||||
|
||||
static inline bool clean(const polygon_90_set_view<ltype, rtype, op_type>& polygon_set);
|
||||
|
||||
static inline bool sorted(const polygon_90_set_view<ltype, rtype, op_type>& polygon_set);
|
||||
};
|
||||
|
||||
template <typename value_type, typename ltype, typename rtype, typename op_type>
|
||||
struct compute_90_set_value {
|
||||
static
|
||||
void value(value_type& output_, const ltype& lvalue_, const rtype& rvalue_, orientation_2d orient_) {
|
||||
value_type linput_(orient_);
|
||||
value_type rinput_(orient_);
|
||||
insert_into_view_arg(linput_, lvalue_, orient_);
|
||||
insert_into_view_arg(rinput_, rvalue_, orient_);
|
||||
output_.applyBooleanBinaryOp(linput_.begin(), linput_.end(),
|
||||
rinput_.begin(), rinput_.end(), boolean_op::BinaryCount<op_type>());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename value_type, typename lcoord, typename rcoord, typename op_type>
|
||||
struct compute_90_set_value<value_type, polygon_90_set_data<lcoord>, polygon_90_set_data<rcoord>, op_type> {
|
||||
static
|
||||
void value(value_type& output_, const polygon_90_set_data<lcoord>& lvalue_,
|
||||
const polygon_90_set_data<rcoord>& rvalue_, orientation_2d) {
|
||||
lvalue_.sort();
|
||||
rvalue_.sort();
|
||||
output_.applyBooleanBinaryOp(lvalue_.begin(), lvalue_.end(),
|
||||
rvalue_.begin(), rvalue_.end(), boolean_op::BinaryCount<op_type>());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename value_type, typename lcoord, typename rtype, typename op_type>
|
||||
struct compute_90_set_value<value_type, polygon_90_set_data<lcoord>, rtype, op_type> {
|
||||
static
|
||||
void value(value_type& output_, const polygon_90_set_data<lcoord>& lvalue_,
|
||||
const rtype& rvalue_, orientation_2d orient_) {
|
||||
value_type rinput_(orient_);
|
||||
lvalue_.sort();
|
||||
insert_into_view_arg(rinput_, rvalue_, orient_);
|
||||
output_.applyBooleanBinaryOp(lvalue_.begin(), lvalue_.end(),
|
||||
rinput_.begin(), rinput_.end(), boolean_op::BinaryCount<op_type>());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename value_type, typename ltype, typename rcoord, typename op_type>
|
||||
struct compute_90_set_value<value_type, ltype, polygon_90_set_data<rcoord>, op_type> {
|
||||
static
|
||||
void value(value_type& output_, const ltype& lvalue_,
|
||||
const polygon_90_set_data<rcoord>& rvalue_, orientation_2d orient_) {
|
||||
value_type linput_(orient_);
|
||||
insert_into_view_arg(linput_, lvalue_, orient_);
|
||||
rvalue_.sort();
|
||||
output_.applyBooleanBinaryOp(linput_.begin(), linput_.end(),
|
||||
rvalue_.begin(), rvalue_.end(), boolean_op::BinaryCount<op_type>());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ltype, typename rtype, typename op_type>
|
||||
class polygon_90_set_view {
|
||||
public:
|
||||
typedef typename polygon_90_set_traits<ltype>::coordinate_type coordinate_type;
|
||||
typedef polygon_90_set_data<coordinate_type> value_type;
|
||||
typedef typename value_type::iterator_type iterator_type;
|
||||
typedef polygon_90_set_view operator_arg_type;
|
||||
private:
|
||||
const ltype& lvalue_;
|
||||
const rtype& rvalue_;
|
||||
orientation_2d orient_;
|
||||
op_type op_;
|
||||
mutable value_type output_;
|
||||
mutable bool evaluated_;
|
||||
polygon_90_set_view& operator=(const polygon_90_set_view&);
|
||||
public:
|
||||
polygon_90_set_view(const ltype& lvalue,
|
||||
const rtype& rvalue,
|
||||
orientation_2d orient,
|
||||
op_type op) :
|
||||
lvalue_(lvalue), rvalue_(rvalue), orient_(orient), op_(op), output_(orient), evaluated_(false) {}
|
||||
|
||||
// get iterator to begin vertex data
|
||||
private:
|
||||
const value_type& value() const {
|
||||
if(!evaluated_) {
|
||||
evaluated_ = true;
|
||||
compute_90_set_value<value_type, ltype, rtype, op_type>::value(output_, lvalue_, rvalue_, orient_);
|
||||
}
|
||||
return output_;
|
||||
}
|
||||
public:
|
||||
iterator_type begin() const { return value().begin(); }
|
||||
iterator_type end() const { return value().end(); }
|
||||
|
||||
orientation_2d orient() const { return orient_; }
|
||||
bool dirty() const { return false; } //result of a boolean is clean
|
||||
bool sorted() const { return true; } //result of a boolean is sorted
|
||||
|
||||
// template <typename input_iterator_type>
|
||||
// void set(input_iterator_type input_begin, input_iterator_type input_end,
|
||||
// orientation_2d orient) const {
|
||||
// orient_ = orient;
|
||||
// output_.clear();
|
||||
// output_.insert(output_.end(), input_begin, input_end);
|
||||
// std::sort(output_.begin(), output_.end());
|
||||
// }
|
||||
void sort() const {} //is always sorted
|
||||
};
|
||||
|
||||
template <typename ltype, typename rtype, typename op_type>
|
||||
struct geometry_concept<polygon_90_set_view<ltype, rtype, op_type> > {
|
||||
typedef polygon_90_set_concept type;
|
||||
};
|
||||
|
||||
template <typename ltype, typename rtype, typename op_type>
|
||||
typename polygon_90_set_view<ltype, rtype, op_type>::iterator_type
|
||||
polygon_90_set_traits<polygon_90_set_view<ltype, rtype, op_type> >::
|
||||
begin(const polygon_90_set_view<ltype, rtype, op_type>& polygon_set) {
|
||||
return polygon_set.begin();
|
||||
}
|
||||
template <typename ltype, typename rtype, typename op_type>
|
||||
typename polygon_90_set_view<ltype, rtype, op_type>::iterator_type
|
||||
polygon_90_set_traits<polygon_90_set_view<ltype, rtype, op_type> >::
|
||||
end(const polygon_90_set_view<ltype, rtype, op_type>& polygon_set) {
|
||||
return polygon_set.end();
|
||||
}
|
||||
// template <typename ltype, typename rtype, typename op_type>
|
||||
// template <typename input_iterator_type>
|
||||
// void polygon_90_set_traits<polygon_90_set_view<ltype, rtype, op_type> >::
|
||||
// set(polygon_90_set_view<ltype, rtype, op_type>& polygon_set,
|
||||
// input_iterator_type input_begin, input_iterator_type input_end,
|
||||
// orientation_2d orient) {
|
||||
// polygon_set.set(input_begin, input_end, orient);
|
||||
// }
|
||||
template <typename ltype, typename rtype, typename op_type>
|
||||
orientation_2d polygon_90_set_traits<polygon_90_set_view<ltype, rtype, op_type> >::
|
||||
orient(const polygon_90_set_view<ltype, rtype, op_type>& polygon_set) {
|
||||
return polygon_set.orient(); }
|
||||
template <typename ltype, typename rtype, typename op_type>
|
||||
bool polygon_90_set_traits<polygon_90_set_view<ltype, rtype, op_type> >::
|
||||
clean(const polygon_90_set_view<ltype, rtype, op_type>& polygon_set) {
|
||||
return true; }
|
||||
template <typename ltype, typename rtype, typename op_type>
|
||||
bool polygon_90_set_traits<polygon_90_set_view<ltype, rtype, op_type> >::
|
||||
sorted(const polygon_90_set_view<ltype, rtype, op_type>& polygon_set) {
|
||||
return true; }
|
||||
|
||||
template <typename value_type, typename arg_type>
|
||||
inline void insert_into_view_arg(value_type& dest, const arg_type& arg, orientation_2d orient) {
|
||||
typedef typename polygon_90_set_traits<arg_type>::iterator_type literator;
|
||||
literator itr1, itr2;
|
||||
itr1 = polygon_90_set_traits<arg_type>::begin(arg);
|
||||
itr2 = polygon_90_set_traits<arg_type>::end(arg);
|
||||
dest.insert(itr1, itr2, orient);
|
||||
dest.sort();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename ltype, typename rtype, typename op_type>
|
||||
inline polygon_90_set_data<T>& polygon_90_set_data<T>::operator=(const polygon_90_set_view<ltype, rtype, op_type>& that) {
|
||||
set(that.begin(), that.end(), that.orient());
|
||||
dirty_ = false;
|
||||
unsorted_ = false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename ltype, typename rtype, typename op_type>
|
||||
inline polygon_90_set_data<T>::polygon_90_set_data(const polygon_90_set_view<ltype, rtype, op_type>& that) :
|
||||
orient_(that.orient()), data_(that.begin(), that.end()), dirty_(false), unsorted_(false) {}
|
||||
|
||||
template <typename geometry_type_1, typename geometry_type_2>
|
||||
struct self_assign_operator_lvalue {
|
||||
typedef geometry_type_1& type;
|
||||
};
|
||||
|
||||
template <typename type_1, typename type_2>
|
||||
struct by_value_binary_operator {
|
||||
typedef type_1 type;
|
||||
};
|
||||
|
||||
template <typename geometry_type_1, typename geometry_type_2, typename op_type>
|
||||
geometry_type_1& self_assignment_boolean_op(geometry_type_1& lvalue_, const geometry_type_2& rvalue_) {
|
||||
typedef geometry_type_1 ltype;
|
||||
typedef geometry_type_2 rtype;
|
||||
typedef typename polygon_90_set_traits<ltype>::coordinate_type coordinate_type;
|
||||
typedef polygon_90_set_data<coordinate_type> value_type;
|
||||
orientation_2d orient_ = polygon_90_set_traits<ltype>::orient(lvalue_);
|
||||
value_type linput_(orient_);
|
||||
value_type rinput_(orient_);
|
||||
value_type output_(orient_);
|
||||
insert_into_view_arg(linput_, lvalue_, orient_);
|
||||
insert_into_view_arg(rinput_, rvalue_, orient_);
|
||||
output_.applyBooleanBinaryOp(linput_.begin(), linput_.end(),
|
||||
rinput_.begin(), rinput_.end(), boolean_op::BinaryCount<op_type>());
|
||||
polygon_90_set_mutable_traits<geometry_type_1>::set(lvalue_, output_.begin(), output_.end(), orient_);
|
||||
return lvalue_;
|
||||
}
|
||||
|
||||
namespace operators {
|
||||
struct y_ps90_b : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename geometry_type_2>
|
||||
typename enable_if< typename gtl_and_3< y_ps90_b,
|
||||
typename is_polygon_90_set_type<geometry_type_1>::type,
|
||||
typename is_polygon_90_set_type<geometry_type_2>::type>::type,
|
||||
polygon_90_set_view<geometry_type_1, geometry_type_2, boolean_op::BinaryOr> >::type
|
||||
operator|(const geometry_type_1& lvalue, const geometry_type_2& rvalue) {
|
||||
return polygon_90_set_view<geometry_type_1, geometry_type_2, boolean_op::BinaryOr>
|
||||
(lvalue, rvalue,
|
||||
polygon_90_set_traits<geometry_type_1>::orient(lvalue),
|
||||
boolean_op::BinaryOr());
|
||||
}
|
||||
|
||||
struct y_ps90_p : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename geometry_type_2>
|
||||
typename enable_if<
|
||||
typename gtl_and_3< y_ps90_p,
|
||||
typename gtl_if<typename is_polygon_90_set_type<geometry_type_1>::type>::type,
|
||||
typename gtl_if<typename is_polygon_90_set_type<geometry_type_2>::type>::type>::type,
|
||||
polygon_90_set_view<geometry_type_1, geometry_type_2, boolean_op::BinaryOr> >::type
|
||||
operator+(const geometry_type_1& lvalue, const geometry_type_2& rvalue) {
|
||||
return polygon_90_set_view<geometry_type_1, geometry_type_2, boolean_op::BinaryOr>
|
||||
(lvalue, rvalue,
|
||||
polygon_90_set_traits<geometry_type_1>::orient(lvalue),
|
||||
boolean_op::BinaryOr());
|
||||
}
|
||||
|
||||
struct y_ps90_s : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename geometry_type_2>
|
||||
typename enable_if< typename gtl_and_3< y_ps90_s,
|
||||
typename is_polygon_90_set_type<geometry_type_1>::type,
|
||||
typename is_polygon_90_set_type<geometry_type_2>::type>::type,
|
||||
polygon_90_set_view<geometry_type_1, geometry_type_2, boolean_op::BinaryAnd> >::type
|
||||
operator*(const geometry_type_1& lvalue, const geometry_type_2& rvalue) {
|
||||
return polygon_90_set_view<geometry_type_1, geometry_type_2, boolean_op::BinaryAnd>
|
||||
(lvalue, rvalue,
|
||||
polygon_90_set_traits<geometry_type_1>::orient(lvalue),
|
||||
boolean_op::BinaryAnd());
|
||||
}
|
||||
|
||||
struct y_ps90_a : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename geometry_type_2>
|
||||
typename enable_if< typename gtl_and_3< y_ps90_a,
|
||||
typename is_polygon_90_set_type<geometry_type_1>::type,
|
||||
typename is_polygon_90_set_type<geometry_type_2>::type>::type,
|
||||
polygon_90_set_view<geometry_type_1, geometry_type_2, boolean_op::BinaryAnd> >::type
|
||||
operator&(const geometry_type_1& lvalue, const geometry_type_2& rvalue) {
|
||||
return polygon_90_set_view<geometry_type_1, geometry_type_2, boolean_op::BinaryAnd>
|
||||
(lvalue, rvalue,
|
||||
polygon_90_set_traits<geometry_type_1>::orient(lvalue),
|
||||
boolean_op::BinaryAnd());
|
||||
}
|
||||
|
||||
struct y_ps90_x : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename geometry_type_2>
|
||||
typename enable_if< typename gtl_and_3< y_ps90_x,
|
||||
typename is_polygon_90_set_type<geometry_type_1>::type,
|
||||
typename is_polygon_90_set_type<geometry_type_2>::type>::type,
|
||||
polygon_90_set_view<geometry_type_1, geometry_type_2, boolean_op::BinaryXor> >::type
|
||||
operator^(const geometry_type_1& lvalue, const geometry_type_2& rvalue) {
|
||||
return polygon_90_set_view<geometry_type_1, geometry_type_2, boolean_op::BinaryXor>
|
||||
(lvalue, rvalue,
|
||||
polygon_90_set_traits<geometry_type_1>::orient(lvalue),
|
||||
boolean_op::BinaryXor());
|
||||
}
|
||||
|
||||
struct y_ps90_m : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename geometry_type_2>
|
||||
typename enable_if< typename gtl_and_3< y_ps90_m,
|
||||
typename gtl_if<typename is_polygon_90_set_type<geometry_type_1>::type>::type,
|
||||
typename gtl_if<typename is_polygon_90_set_type<geometry_type_2>::type>::type>::type,
|
||||
polygon_90_set_view<geometry_type_1, geometry_type_2, boolean_op::BinaryNot> >::type
|
||||
operator-(const geometry_type_1& lvalue, const geometry_type_2& rvalue) {
|
||||
return polygon_90_set_view<geometry_type_1, geometry_type_2, boolean_op::BinaryNot>
|
||||
(lvalue, rvalue,
|
||||
polygon_90_set_traits<geometry_type_1>::orient(lvalue),
|
||||
boolean_op::BinaryNot());
|
||||
}
|
||||
|
||||
struct y_ps90_pe : gtl_yes {};
|
||||
|
||||
template <typename coordinate_type_1, typename geometry_type_2>
|
||||
typename enable_if< typename gtl_and< y_ps90_pe, typename is_polygon_90_set_type<geometry_type_2>::type>::type,
|
||||
polygon_90_set_data<coordinate_type_1> >::type &
|
||||
operator+=(polygon_90_set_data<coordinate_type_1>& lvalue, const geometry_type_2& rvalue) {
|
||||
lvalue.insert(polygon_90_set_traits<geometry_type_2>::begin(rvalue), polygon_90_set_traits<geometry_type_2>::end(rvalue),
|
||||
polygon_90_set_traits<geometry_type_2>::orient(rvalue));
|
||||
return lvalue;
|
||||
}
|
||||
|
||||
struct y_ps90_be : gtl_yes {};
|
||||
//
|
||||
template <typename coordinate_type_1, typename geometry_type_2>
|
||||
typename enable_if< typename gtl_and< y_ps90_be, typename is_polygon_90_set_type<geometry_type_2>::type>::type,
|
||||
polygon_90_set_data<coordinate_type_1> >::type &
|
||||
operator|=(polygon_90_set_data<coordinate_type_1>& lvalue, const geometry_type_2& rvalue) {
|
||||
return lvalue += rvalue;
|
||||
}
|
||||
|
||||
struct y_ps90_pe2 : gtl_yes {};
|
||||
|
||||
//normal self assignment boolean operations
|
||||
template <typename geometry_type_1, typename geometry_type_2>
|
||||
typename enable_if< typename gtl_and_3< y_ps90_pe2, typename is_mutable_polygon_90_set_type<geometry_type_1>::type,
|
||||
typename is_polygon_90_set_type<geometry_type_2>::type>::type,
|
||||
geometry_type_1>::type &
|
||||
operator+=(geometry_type_1& lvalue, const geometry_type_2& rvalue) {
|
||||
return self_assignment_boolean_op<geometry_type_1, geometry_type_2, boolean_op::BinaryOr>(lvalue, rvalue);
|
||||
}
|
||||
|
||||
struct y_ps90_be2 : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename geometry_type_2>
|
||||
typename enable_if< typename gtl_and_3<y_ps90_be2, typename is_mutable_polygon_90_set_type<geometry_type_1>::type,
|
||||
typename is_polygon_90_set_type<geometry_type_2>::type>::type,
|
||||
geometry_type_1>::type &
|
||||
operator|=(geometry_type_1& lvalue, const geometry_type_2& rvalue) {
|
||||
return self_assignment_boolean_op<geometry_type_1, geometry_type_2, boolean_op::BinaryOr>(lvalue, rvalue);
|
||||
}
|
||||
|
||||
struct y_ps90_se : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename geometry_type_2>
|
||||
typename enable_if< typename gtl_and_3<y_ps90_se, typename is_mutable_polygon_90_set_type<geometry_type_1>::type,
|
||||
typename is_polygon_90_set_type<geometry_type_2>::type>::type,
|
||||
geometry_type_1>::type &
|
||||
operator*=(geometry_type_1& lvalue, const geometry_type_2& rvalue) {
|
||||
return self_assignment_boolean_op<geometry_type_1, geometry_type_2, boolean_op::BinaryAnd>(lvalue, rvalue);
|
||||
}
|
||||
|
||||
struct y_ps90_ae : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename geometry_type_2>
|
||||
typename enable_if< typename gtl_and_3<y_ps90_ae, typename is_mutable_polygon_90_set_type<geometry_type_1>::type,
|
||||
typename is_polygon_90_set_type<geometry_type_2>::type>::type,
|
||||
geometry_type_1>::type &
|
||||
operator&=(geometry_type_1& lvalue, const geometry_type_2& rvalue) {
|
||||
return self_assignment_boolean_op<geometry_type_1, geometry_type_2, boolean_op::BinaryAnd>(lvalue, rvalue);
|
||||
}
|
||||
|
||||
struct y_ps90_xe : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename geometry_type_2>
|
||||
typename enable_if< typename gtl_and_3<y_ps90_xe, typename is_mutable_polygon_90_set_type<geometry_type_1>::type,
|
||||
typename is_polygon_90_set_type<geometry_type_2>::type>::type,
|
||||
geometry_type_1>::type &
|
||||
operator^=(geometry_type_1& lvalue, const geometry_type_2& rvalue) {
|
||||
return self_assignment_boolean_op<geometry_type_1, geometry_type_2, boolean_op::BinaryXor>(lvalue, rvalue);
|
||||
}
|
||||
|
||||
struct y_ps90_me : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename geometry_type_2>
|
||||
typename enable_if< typename gtl_and_3< y_ps90_me, typename is_mutable_polygon_90_set_type<geometry_type_1>::type,
|
||||
typename is_polygon_90_set_type<geometry_type_2>::type>::type,
|
||||
geometry_type_1>::type &
|
||||
operator-=(geometry_type_1& lvalue, const geometry_type_2& rvalue) {
|
||||
return self_assignment_boolean_op<geometry_type_1, geometry_type_2, boolean_op::BinaryNot>(lvalue, rvalue);
|
||||
}
|
||||
|
||||
struct y_ps90_rpe : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename coordinate_type_1>
|
||||
typename enable_if< typename gtl_and_3<y_ps90_rpe,
|
||||
typename is_mutable_polygon_90_set_type<geometry_type_1>::type,
|
||||
typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type, coordinate_concept>::type>::type,
|
||||
geometry_type_1>::type &
|
||||
operator+=(geometry_type_1& lvalue, coordinate_type_1 rvalue) {
|
||||
return resize(lvalue, rvalue);
|
||||
}
|
||||
|
||||
struct y_ps90_rme : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename coordinate_type_1>
|
||||
typename enable_if< typename gtl_and_3<y_ps90_rme,
|
||||
typename is_mutable_polygon_90_set_type<geometry_type_1>::type,
|
||||
typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type, coordinate_concept>::type>::type,
|
||||
geometry_type_1>::type &
|
||||
operator-=(geometry_type_1& lvalue, coordinate_type_1 rvalue) {
|
||||
return resize(lvalue, -rvalue);
|
||||
}
|
||||
|
||||
struct y_ps90_rp : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename coordinate_type_1>
|
||||
typename enable_if< typename gtl_and_3<y_ps90_rp,
|
||||
typename gtl_if<typename is_mutable_polygon_90_set_type<geometry_type_1>::type>::type,
|
||||
typename gtl_if<typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type, coordinate_concept>::type>::type>::type,
|
||||
geometry_type_1>::type
|
||||
operator+(const geometry_type_1& lvalue, coordinate_type_1 rvalue) {
|
||||
geometry_type_1 retval(lvalue);
|
||||
retval += rvalue;
|
||||
return retval;
|
||||
}
|
||||
|
||||
struct y_ps90_rm : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename coordinate_type_1>
|
||||
typename enable_if< typename gtl_and_3<y_ps90_rm,
|
||||
typename gtl_if<typename is_mutable_polygon_90_set_type<geometry_type_1>::type>::type,
|
||||
typename gtl_if<typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type, coordinate_concept>::type>::type>::type,
|
||||
geometry_type_1>::type
|
||||
operator-(const geometry_type_1& lvalue, coordinate_type_1 rvalue) {
|
||||
geometry_type_1 retval(lvalue);
|
||||
retval -= rvalue;
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,418 @@
|
|||
/*
|
||||
Copyright 2008 Intel Corporation
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
*/
|
||||
#ifndef BOOST_POLYGON_POLYGON_90_TOUCH_HPP
|
||||
#define BOOST_POLYGON_POLYGON_90_TOUCH_HPP
|
||||
namespace boost { namespace polygon{
|
||||
|
||||
template <typename Unit>
|
||||
struct touch_90_operation {
|
||||
typedef interval_data<Unit> Interval;
|
||||
|
||||
class TouchScanEvent {
|
||||
private:
|
||||
typedef std::map<Unit, std::set<int> > EventData;
|
||||
EventData eventData_;
|
||||
public:
|
||||
|
||||
// The TouchScanEvent::iterator is a lazy algorithm that accumulates
|
||||
// polygon ids in a set as it is incremented through the
|
||||
// scan event data structure.
|
||||
// The iterator provides a forward iterator semantic only.
|
||||
class iterator {
|
||||
private:
|
||||
typename EventData::const_iterator itr_;
|
||||
std::pair<Interval, std::set<int> > ivlIds_;
|
||||
bool incremented_;
|
||||
public:
|
||||
inline iterator() : itr_(), ivlIds_(), incremented_(false) {}
|
||||
inline iterator(typename EventData::const_iterator itr,
|
||||
Unit prevPos, Unit curPos, const std::set<int>& ivlIds) : itr_(itr), ivlIds_(), incremented_(false) {
|
||||
ivlIds_.second = ivlIds;
|
||||
ivlIds_.first = Interval(prevPos, curPos);
|
||||
}
|
||||
inline iterator(const iterator& that) : itr_(), ivlIds_(), incremented_(false) { (*this) = that; }
|
||||
inline iterator& operator=(const iterator& that) {
|
||||
itr_ = that.itr_;
|
||||
ivlIds_.first = that.ivlIds_.first;
|
||||
ivlIds_.second = that.ivlIds_.second;
|
||||
incremented_ = that.incremented_;
|
||||
return *this;
|
||||
};
|
||||
inline bool operator==(const iterator& that) { return itr_ == that.itr_; }
|
||||
inline bool operator!=(const iterator& that) { return itr_ != that.itr_; }
|
||||
inline iterator& operator++() {
|
||||
//std::cout << "increment\n";
|
||||
//std::cout << "state\n";
|
||||
//for(std::set<int>::iterator itr = ivlIds_.second.begin(); itr != ivlIds_.second.end(); ++itr) {
|
||||
// std::cout << (*itr) << " ";
|
||||
//} std::cout << std::endl;
|
||||
//std::cout << "update\n";
|
||||
for(std::set<int>::const_iterator itr = (*itr_).second.begin();
|
||||
itr != (*itr_).second.end(); ++itr) {
|
||||
//std::cout << (*itr) << " ";
|
||||
std::set<int>::iterator lb = ivlIds_.second.find(*itr);
|
||||
if(lb != ivlIds_.second.end()) {
|
||||
ivlIds_.second.erase(lb);
|
||||
} else {
|
||||
ivlIds_.second.insert(*itr);
|
||||
}
|
||||
}
|
||||
//std::cout << std::endl;
|
||||
//std::cout << "new state\n";
|
||||
//for(std::set<int>::iterator itr = ivlIds_.second.begin(); itr != ivlIds_.second.end(); ++itr) {
|
||||
// std::cout << (*itr) << " ";
|
||||
//} std::cout << std::endl;
|
||||
++itr_;
|
||||
//ivlIds_.first = Interval(ivlIds_.first.get(HIGH), itr_->first);
|
||||
incremented_ = true;
|
||||
return *this;
|
||||
}
|
||||
inline const iterator operator++(int){
|
||||
iterator tmpItr(*this);
|
||||
++(*this);
|
||||
return tmpItr;
|
||||
}
|
||||
inline std::pair<Interval, std::set<int> >& operator*() {
|
||||
if(incremented_) ivlIds_.first = Interval(ivlIds_.first.get(HIGH), itr_->first);
|
||||
incremented_ = false;
|
||||
if(ivlIds_.second.empty())(++(*this));
|
||||
if(incremented_) ivlIds_.first = Interval(ivlIds_.first.get(HIGH), itr_->first);
|
||||
incremented_ = false;
|
||||
return ivlIds_; }
|
||||
};
|
||||
|
||||
inline TouchScanEvent() : eventData_() {}
|
||||
template<class iT>
|
||||
inline TouchScanEvent(iT begin, iT end) : eventData_() {
|
||||
for( ; begin != end; ++begin){
|
||||
insert(*begin);
|
||||
}
|
||||
}
|
||||
inline TouchScanEvent(const TouchScanEvent& that) : eventData_(that.eventData_) {}
|
||||
inline TouchScanEvent& operator=(const TouchScanEvent& that){
|
||||
eventData_ = that.eventData_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//Insert an interval polygon id into the EventData
|
||||
inline void insert(const std::pair<Interval, int>& intervalId){
|
||||
insert(intervalId.first.low(), intervalId.second);
|
||||
insert(intervalId.first.high(), intervalId.second);
|
||||
}
|
||||
|
||||
//Insert an position and polygon id into EventData
|
||||
inline void insert(Unit pos, int id) {
|
||||
typename EventData::iterator lb = eventData_.lower_bound(pos);
|
||||
if(lb != eventData_.end() && lb->first == pos) {
|
||||
std::set<int>& mr (lb->second);
|
||||
std::set<int>::iterator mri = mr.find(id);
|
||||
if(mri == mr.end()) {
|
||||
mr.insert(id);
|
||||
} else {
|
||||
mr.erase(id);
|
||||
}
|
||||
} else {
|
||||
lb = eventData_.insert(lb, std::pair<Unit, std::set<int> >(pos, std::set<int>()));
|
||||
(*lb).second.insert(id);
|
||||
}
|
||||
}
|
||||
|
||||
//merge this scan event with that by inserting its data
|
||||
inline void insert(const TouchScanEvent& that){
|
||||
typename EventData::const_iterator itr;
|
||||
for(itr = that.eventData_.begin(); itr != that.eventData_.end(); ++itr) {
|
||||
eventData_[(*itr).first].insert(itr->second.begin(), itr->second.end());
|
||||
}
|
||||
}
|
||||
|
||||
//Get the begin iterator over event data
|
||||
inline iterator begin() const {
|
||||
//std::cout << "begin\n";
|
||||
if(eventData_.empty()) return end();
|
||||
typename EventData::const_iterator itr = eventData_.begin();
|
||||
Unit pos = itr->first;
|
||||
const std::set<int>& idr = itr->second;
|
||||
++itr;
|
||||
return iterator(itr, pos, itr->first, idr);
|
||||
}
|
||||
|
||||
//Get the end iterator over event data
|
||||
inline iterator end() const { return iterator(eventData_.end(), 0, 0, std::set<int>()); }
|
||||
|
||||
inline void clear() { eventData_.clear(); }
|
||||
|
||||
inline Interval extents() const {
|
||||
if(eventData_.empty()) return Interval();
|
||||
return Interval((*(eventData_.begin())).first, (*(eventData_.rbegin())).first);
|
||||
}
|
||||
};
|
||||
|
||||
//declaration of a map of scan events by coordinate value used to store all the
|
||||
//polygon data for a single layer input into the scanline algorithm
|
||||
typedef std::pair<std::map<Unit, TouchScanEvent>, std::map<Unit, TouchScanEvent> > TouchSetData;
|
||||
|
||||
class TouchOp {
|
||||
public:
|
||||
typedef std::map<Unit, std::set<int> > ScanData;
|
||||
typedef std::pair<Unit, std::set<int> > ElementType;
|
||||
protected:
|
||||
ScanData scanData_;
|
||||
typename ScanData::iterator nextItr_;
|
||||
public:
|
||||
inline TouchOp () : scanData_(), nextItr_() { nextItr_ = scanData_.end(); }
|
||||
inline TouchOp (const TouchOp& that) : scanData_(that.scanData_), nextItr_() { nextItr_ = scanData_.begin(); }
|
||||
inline TouchOp& operator=(const TouchOp& that);
|
||||
|
||||
//moves scanline forward
|
||||
inline void advanceScan() { nextItr_ = scanData_.begin(); }
|
||||
|
||||
//proceses the given interval and std::set<int> data
|
||||
//the output data structre is a graph, the indicies in the vector correspond to graph nodes,
|
||||
//the integers in the set are vector indicies and are the nodes with which that node shares an edge
|
||||
template <typename graphT>
|
||||
inline void processInterval(graphT& outputContainer, Interval ivl, const std::set<int>& ids, bool leadingEdge) {
|
||||
//print();
|
||||
typename ScanData::iterator lowItr = lookup_(ivl.low());
|
||||
typename ScanData::iterator highItr = lookup_(ivl.high());
|
||||
//std::cout << "Interval: " << ivl << std::endl;
|
||||
//for(std::set<int>::const_iterator itr = ids.begin(); itr != ids.end(); ++itr)
|
||||
// std::cout << (*itr) << " ";
|
||||
//std::cout << std::endl;
|
||||
//add interval to scan data if it is past the end
|
||||
if(lowItr == scanData_.end()) {
|
||||
//std::cout << "case0" << std::endl;
|
||||
lowItr = insert_(ivl.low(), ids);
|
||||
evaluateBorder_(outputContainer, ids, ids);
|
||||
highItr = insert_(ivl.high(), std::set<int>());
|
||||
return;
|
||||
}
|
||||
//ensure that highItr points to the end of the ivl
|
||||
if(highItr == scanData_.end() || (*highItr).first > ivl.high()) {
|
||||
//std::cout << "case1" << std::endl;
|
||||
//std::cout << highItr->first << std::endl;
|
||||
std::set<int> value = std::set<int>();
|
||||
if(highItr != scanData_.begin()) {
|
||||
--highItr;
|
||||
//std::cout << highItr->first << std::endl;
|
||||
//std::cout << "high set size " << highItr->second.size() << std::endl;
|
||||
value = highItr->second;
|
||||
}
|
||||
nextItr_ = highItr;
|
||||
highItr = insert_(ivl.high(), value);
|
||||
} else {
|
||||
//evaluate border with next higher interval
|
||||
//std::cout << "case1a" << std::endl;
|
||||
if(leadingEdge)evaluateBorder_(outputContainer, highItr->second, ids);
|
||||
}
|
||||
//split the low interval if needed
|
||||
if(lowItr->first > ivl.low()) {
|
||||
//std::cout << "case2" << std::endl;
|
||||
if(lowItr != scanData_.begin()) {
|
||||
//std::cout << "case3" << std::endl;
|
||||
--lowItr;
|
||||
nextItr_ = lowItr;
|
||||
//std::cout << lowItr->first << " " << lowItr->second.size() << std::endl;
|
||||
lowItr = insert_(ivl.low(), lowItr->second);
|
||||
} else {
|
||||
//std::cout << "case4" << std::endl;
|
||||
nextItr_ = lowItr;
|
||||
lowItr = insert_(ivl.low(), std::set<int>());
|
||||
}
|
||||
} else {
|
||||
//evaluate border with next higher interval
|
||||
//std::cout << "case2a" << std::endl;
|
||||
typename ScanData::iterator nextLowerItr = lowItr;
|
||||
if(leadingEdge && nextLowerItr != scanData_.begin()){
|
||||
--nextLowerItr;
|
||||
evaluateBorder_(outputContainer, nextLowerItr->second, ids);
|
||||
}
|
||||
}
|
||||
//std::cout << "low: " << lowItr->first << " high: " << highItr->first << std::endl;
|
||||
//print();
|
||||
//process scan data intersecting interval
|
||||
for(typename ScanData::iterator itr = lowItr; itr != highItr; ){
|
||||
//std::cout << "case5" << std::endl;
|
||||
//std::cout << itr->first << std::endl;
|
||||
std::set<int>& beforeIds = itr->second;
|
||||
++itr;
|
||||
evaluateInterval_(outputContainer, beforeIds, ids, leadingEdge);
|
||||
}
|
||||
//print();
|
||||
//merge the bottom interval with the one below if they have the same count
|
||||
if(lowItr != scanData_.begin()){
|
||||
//std::cout << "case6" << std::endl;
|
||||
typename ScanData::iterator belowLowItr = lowItr;
|
||||
--belowLowItr;
|
||||
if(belowLowItr->second == lowItr->second) {
|
||||
//std::cout << "case7" << std::endl;
|
||||
scanData_.erase(lowItr);
|
||||
}
|
||||
}
|
||||
//merge the top interval with the one above if they have the same count
|
||||
if(highItr != scanData_.begin()) {
|
||||
//std::cout << "case8" << std::endl;
|
||||
typename ScanData::iterator beforeHighItr = highItr;
|
||||
--beforeHighItr;
|
||||
if(beforeHighItr->second == highItr->second) {
|
||||
//std::cout << "case9" << std::endl;
|
||||
scanData_.erase(highItr);
|
||||
highItr = beforeHighItr;
|
||||
++highItr;
|
||||
}
|
||||
}
|
||||
//print();
|
||||
nextItr_ = highItr;
|
||||
}
|
||||
|
||||
// inline void print() const {
|
||||
// for(typename ScanData::const_iterator itr = scanData_.begin(); itr != scanData_.end(); ++itr) {
|
||||
// std::cout << itr->first << ": ";
|
||||
// for(std::set<int>::const_iterator sitr = itr->second.begin();
|
||||
// sitr != itr->second.end(); ++sitr){
|
||||
// std::cout << *sitr << " ";
|
||||
// }
|
||||
// std::cout << std::endl;
|
||||
// }
|
||||
// }
|
||||
|
||||
private:
|
||||
inline typename ScanData::iterator lookup_(Unit pos){
|
||||
if(nextItr_ != scanData_.end() && nextItr_->first >= pos) {
|
||||
return nextItr_;
|
||||
}
|
||||
return nextItr_ = scanData_.lower_bound(pos);
|
||||
}
|
||||
|
||||
inline typename ScanData::iterator insert_(Unit pos, const std::set<int>& ids){
|
||||
//std::cout << "inserting " << ids.size() << " ids at: " << pos << std::endl;
|
||||
return nextItr_ = scanData_.insert(nextItr_, std::pair<Unit, std::set<int> >(pos, ids));
|
||||
}
|
||||
|
||||
template <typename graphT>
|
||||
inline void evaluateInterval_(graphT& outputContainer, std::set<int>& ids,
|
||||
const std::set<int>& changingIds, bool leadingEdge) {
|
||||
for(std::set<int>::const_iterator ciditr = changingIds.begin(); ciditr != changingIds.end(); ++ciditr){
|
||||
//std::cout << "evaluateInterval " << (*ciditr) << std::endl;
|
||||
evaluateId_(outputContainer, ids, *ciditr, leadingEdge);
|
||||
}
|
||||
}
|
||||
template <typename graphT>
|
||||
inline void evaluateBorder_(graphT& outputContainer, const std::set<int>& ids, const std::set<int>& changingIds) {
|
||||
for(std::set<int>::const_iterator ciditr = changingIds.begin(); ciditr != changingIds.end(); ++ciditr){
|
||||
//std::cout << "evaluateBorder " << (*ciditr) << std::endl;
|
||||
evaluateBorderId_(outputContainer, ids, *ciditr);
|
||||
}
|
||||
}
|
||||
template <typename graphT>
|
||||
inline void evaluateBorderId_(graphT& outputContainer, const std::set<int>& ids, int changingId) {
|
||||
for(std::set<int>::const_iterator scanItr = ids.begin(); scanItr != ids.end(); ++scanItr) {
|
||||
//std::cout << "create edge: " << changingId << " " << *scanItr << std::endl;
|
||||
if(changingId != *scanItr){
|
||||
outputContainer[changingId].insert(*scanItr);
|
||||
outputContainer[*scanItr].insert(changingId);
|
||||
}
|
||||
}
|
||||
}
|
||||
template <typename graphT>
|
||||
inline void evaluateId_(graphT& outputContainer, std::set<int>& ids, int changingId, bool leadingEdge) {
|
||||
//std::cout << "changingId: " << changingId << std::endl;
|
||||
//for( std::set<int>::iterator itr = ids.begin(); itr != ids.end(); ++itr){
|
||||
// std::cout << *itr << " ";
|
||||
//}std::cout << std::endl;
|
||||
std::set<int>::iterator lb = ids.lower_bound(changingId);
|
||||
if(lb == ids.end() || (*lb) != changingId) {
|
||||
if(leadingEdge) {
|
||||
//std::cout << "insert\n";
|
||||
//insert and add to output
|
||||
for(std::set<int>::iterator scanItr = ids.begin(); scanItr != ids.end(); ++scanItr) {
|
||||
//std::cout << "create edge: " << changingId << " " << *scanItr << std::endl;
|
||||
if(changingId != *scanItr){
|
||||
outputContainer[changingId].insert(*scanItr);
|
||||
outputContainer[*scanItr].insert(changingId);
|
||||
}
|
||||
}
|
||||
ids.insert(changingId);
|
||||
}
|
||||
} else {
|
||||
if(!leadingEdge){
|
||||
//std::cout << "erase\n";
|
||||
ids.erase(lb);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename graphT>
|
||||
static inline void processEvent(graphT& outputContainer, TouchOp& op, const TouchScanEvent& data, bool leadingEdge) {
|
||||
for(typename TouchScanEvent::iterator itr = data.begin(); itr != data.end(); ++itr) {
|
||||
//std::cout << "processInterval" << std::endl;
|
||||
op.processInterval(outputContainer, (*itr).first, (*itr).second, leadingEdge);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename graphT>
|
||||
static inline void performTouch(graphT& outputContainer, const TouchSetData& data) {
|
||||
typename std::map<Unit, TouchScanEvent>::const_iterator leftItr = data.first.begin();
|
||||
typename std::map<Unit, TouchScanEvent>::const_iterator rightItr = data.second.begin();
|
||||
typename std::map<Unit, TouchScanEvent>::const_iterator leftEnd = data.first.end();
|
||||
typename std::map<Unit, TouchScanEvent>::const_iterator rightEnd = data.second.end();
|
||||
TouchOp op;
|
||||
while(leftItr != leftEnd || rightItr != rightEnd) {
|
||||
//std::cout << "loop" << std::endl;
|
||||
op.advanceScan();
|
||||
//rightItr cannont be at end if leftItr is not at end
|
||||
if(leftItr != leftEnd && rightItr != rightEnd &&
|
||||
leftItr->first <= rightItr->first) {
|
||||
//std::cout << "case1" << std::endl;
|
||||
//std::cout << leftItr ->first << std::endl;
|
||||
processEvent(outputContainer, op, leftItr->second, true);
|
||||
++leftItr;
|
||||
} else {
|
||||
//std::cout << "case2" << std::endl;
|
||||
//std::cout << rightItr ->first << std::endl;
|
||||
processEvent(outputContainer, op, rightItr->second, false);
|
||||
++rightItr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class iT>
|
||||
static inline void populateTouchSetData(TouchSetData& data, iT beginData, iT endData, int id) {
|
||||
Unit prevPos = ((std::numeric_limits<Unit>::max)());
|
||||
Unit prevY = prevPos;
|
||||
int count = 0;
|
||||
for(iT itr = beginData; itr != endData; ++itr) {
|
||||
Unit pos = (*itr).first;
|
||||
if(pos != prevPos) {
|
||||
prevPos = pos;
|
||||
prevY = (*itr).second.first;
|
||||
count = (*itr).second.second;
|
||||
continue;
|
||||
}
|
||||
Unit y = (*itr).second.first;
|
||||
if(count != 0 && y != prevY) {
|
||||
std::pair<Interval, int> element(Interval(prevY, y), id);
|
||||
if(count > 0) {
|
||||
data.first[pos].insert(element);
|
||||
} else {
|
||||
data.second[pos].insert(element);
|
||||
}
|
||||
}
|
||||
prevY = y;
|
||||
count += (*itr).second.second;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void populateTouchSetData(TouchSetData& data, const std::vector<std::pair<Unit, std::pair<Unit, int> > >& inputData, int id) {
|
||||
populateTouchSetData(data, inputData.begin(), inputData.end(), id);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,207 @@
|
|||
/*
|
||||
Copyright 2008 Intel Corporation
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
*/
|
||||
#ifndef BOOST_POLYGON_POLYGON_SET_VIEW_HPP
|
||||
#define BOOST_POLYGON_POLYGON_SET_VIEW_HPP
|
||||
namespace boost { namespace polygon{
|
||||
|
||||
|
||||
template <typename coordinate_type>
|
||||
inline void polygon_set_data<coordinate_type>::clean() const {
|
||||
if(dirty_) {
|
||||
polygon_45_set_data<coordinate_type> tmp;
|
||||
if(downcast(tmp) ) {
|
||||
tmp.clean();
|
||||
data_.clear();
|
||||
is_45_ = true;
|
||||
polygon_set_data<coordinate_type> tmp2;
|
||||
tmp2.insert(tmp);
|
||||
data_.swap(tmp2.data_);
|
||||
dirty_ = false;
|
||||
sort();
|
||||
} else {
|
||||
sort();
|
||||
arbitrary_boolean_op<coordinate_type> abo;
|
||||
polygon_set_data<coordinate_type> tmp2;
|
||||
abo.execute(tmp2, begin(), end(), end(), end(), 0);
|
||||
data_.swap(tmp2.data_);
|
||||
is_45_ = tmp2.is_45_;
|
||||
dirty_ = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void polygon_set_data<double>::clean() const {
|
||||
if(dirty_) {
|
||||
sort();
|
||||
arbitrary_boolean_op<double> abo;
|
||||
polygon_set_data<double> tmp2;
|
||||
abo.execute(tmp2, begin(), end(), end(), end(), 0);
|
||||
data_.swap(tmp2.data_);
|
||||
is_45_ = tmp2.is_45_;
|
||||
dirty_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename value_type, typename arg_type>
|
||||
inline void insert_into_view_arg(value_type& dest, const arg_type& arg);
|
||||
|
||||
template <typename ltype, typename rtype, int op_type>
|
||||
class polygon_set_view;
|
||||
|
||||
template <typename ltype, typename rtype, int op_type>
|
||||
struct polygon_set_traits<polygon_set_view<ltype, rtype, op_type> > {
|
||||
typedef typename polygon_set_view<ltype, rtype, op_type>::coordinate_type coordinate_type;
|
||||
typedef typename polygon_set_view<ltype, rtype, op_type>::iterator_type iterator_type;
|
||||
typedef typename polygon_set_view<ltype, rtype, op_type>::operator_arg_type operator_arg_type;
|
||||
|
||||
static inline iterator_type begin(const polygon_set_view<ltype, rtype, op_type>& polygon_set);
|
||||
static inline iterator_type end(const polygon_set_view<ltype, rtype, op_type>& polygon_set);
|
||||
|
||||
static inline bool clean(const polygon_set_view<ltype, rtype, op_type>& polygon_set);
|
||||
|
||||
static inline bool sort(const polygon_set_view<ltype, rtype, op_type>& polygon_set);
|
||||
};
|
||||
|
||||
//template <typename value_type, typename geometry_type_1, typename geometry_type_2, int op_type>
|
||||
//void execute_boolean_op(value_type& output_, const geometry_type_1& lvalue_, const geometry_type_2& rvalue_,
|
||||
// double coord) {
|
||||
// typedef geometry_type_1 ltype;
|
||||
// typedef geometry_type_2 rtype;
|
||||
// typedef typename polygon_set_traits<ltype>::coordinate_type coordinate_type;
|
||||
// value_type linput_;
|
||||
// value_type rinput_;
|
||||
// insert_into_view_arg(linput_, lvalue_);
|
||||
// insert_into_view_arg(rinput_, rvalue_);
|
||||
// arbitrary_boolean_op<coordinate_type> abo;
|
||||
// abo.execute(output_, linput_.begin(), linput_.end(),
|
||||
// rinput_.begin(), rinput_.end(), op_type);
|
||||
//}
|
||||
|
||||
template <typename value_type, typename geometry_type_1, typename geometry_type_2, int op_type>
|
||||
void execute_boolean_op(value_type& output_, const geometry_type_1& lvalue_, const geometry_type_2& rvalue_) {
|
||||
typedef geometry_type_1 ltype;
|
||||
typedef geometry_type_2 rtype;
|
||||
typedef typename polygon_set_traits<ltype>::coordinate_type coordinate_type;
|
||||
value_type linput_;
|
||||
value_type rinput_;
|
||||
insert_into_view_arg(linput_, lvalue_);
|
||||
insert_into_view_arg(rinput_, rvalue_);
|
||||
polygon_45_set_data<coordinate_type> l45, r45, o45;
|
||||
if(linput_.downcast(l45) && rinput_.downcast(r45)) {
|
||||
//the op codes are screwed up between 45 and arbitrary
|
||||
#ifdef BOOST_POLYGON_MSVC
|
||||
#pragma warning (disable: 4127)
|
||||
#endif
|
||||
if(op_type < 2)
|
||||
l45.template applyAdaptiveBoolean_<op_type>(o45, r45);
|
||||
else if(op_type == 2)
|
||||
l45.template applyAdaptiveBoolean_<3>(o45, r45);
|
||||
else
|
||||
l45.template applyAdaptiveBoolean_<2>(o45, r45);
|
||||
#ifdef BOOST_POLYGON_MSVC
|
||||
#pragma warning (default: 4127)
|
||||
#endif
|
||||
output_.insert(o45);
|
||||
} else {
|
||||
arbitrary_boolean_op<coordinate_type> abo;
|
||||
abo.execute(output_, linput_.begin(), linput_.end(),
|
||||
rinput_.begin(), rinput_.end(), op_type);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename ltype, typename rtype, int op_type>
|
||||
class polygon_set_view {
|
||||
public:
|
||||
typedef typename polygon_set_traits<ltype>::coordinate_type coordinate_type;
|
||||
typedef polygon_set_data<coordinate_type> value_type;
|
||||
typedef typename value_type::iterator_type iterator_type;
|
||||
typedef polygon_set_view operator_arg_type;
|
||||
private:
|
||||
const ltype& lvalue_;
|
||||
const rtype& rvalue_;
|
||||
mutable value_type output_;
|
||||
mutable bool evaluated_;
|
||||
polygon_set_view& operator=(const polygon_set_view&);
|
||||
public:
|
||||
polygon_set_view(const ltype& lvalue,
|
||||
const rtype& rvalue ) :
|
||||
lvalue_(lvalue), rvalue_(rvalue), output_(), evaluated_(false) {}
|
||||
|
||||
// get iterator to begin vertex data
|
||||
public:
|
||||
const value_type& value() const {
|
||||
if(!evaluated_) {
|
||||
evaluated_ = true;
|
||||
execute_boolean_op<value_type, ltype, rtype, op_type>(output_, lvalue_, rvalue_);
|
||||
}
|
||||
return output_;
|
||||
}
|
||||
public:
|
||||
iterator_type begin() const { return value().begin(); }
|
||||
iterator_type end() const { return value().end(); }
|
||||
|
||||
bool dirty() const { return false; } //result of a boolean is clean
|
||||
bool sorted() const { return true; } //result of a boolean is sorted
|
||||
|
||||
void sort() const {} //is always sorted
|
||||
};
|
||||
|
||||
template <typename ltype, typename rtype, int op_type>
|
||||
typename polygon_set_view<ltype, rtype, op_type>::iterator_type
|
||||
polygon_set_traits<polygon_set_view<ltype, rtype, op_type> >::
|
||||
begin(const polygon_set_view<ltype, rtype, op_type>& polygon_set) {
|
||||
return polygon_set.begin();
|
||||
}
|
||||
template <typename ltype, typename rtype, int op_type>
|
||||
typename polygon_set_view<ltype, rtype, op_type>::iterator_type
|
||||
polygon_set_traits<polygon_set_view<ltype, rtype, op_type> >::
|
||||
end(const polygon_set_view<ltype, rtype, op_type>& polygon_set) {
|
||||
return polygon_set.end();
|
||||
}
|
||||
template <typename ltype, typename rtype, int op_type>
|
||||
bool polygon_set_traits<polygon_set_view<ltype, rtype, op_type> >::
|
||||
clean(const polygon_set_view<ltype, rtype, op_type>& ) {
|
||||
return true; }
|
||||
template <typename ltype, typename rtype, int op_type>
|
||||
bool polygon_set_traits<polygon_set_view<ltype, rtype, op_type> >::
|
||||
sort(const polygon_set_view<ltype, rtype, op_type>& ) {
|
||||
return true; }
|
||||
|
||||
template <typename value_type, typename arg_type>
|
||||
inline void insert_into_view_arg(value_type& dest, const arg_type& arg) {
|
||||
typedef typename polygon_set_traits<arg_type>::iterator_type literator;
|
||||
literator itr1, itr2;
|
||||
itr1 = polygon_set_traits<arg_type>::begin(arg);
|
||||
itr2 = polygon_set_traits<arg_type>::end(arg);
|
||||
dest.insert(itr1, itr2);
|
||||
}
|
||||
|
||||
template <typename geometry_type_1, typename geometry_type_2, int op_type>
|
||||
geometry_type_1& self_assignment_boolean_op(geometry_type_1& lvalue_, const geometry_type_2& rvalue_) {
|
||||
typedef geometry_type_1 ltype;
|
||||
typedef typename polygon_set_traits<ltype>::coordinate_type coordinate_type;
|
||||
typedef polygon_set_data<coordinate_type> value_type;
|
||||
value_type output_;
|
||||
execute_boolean_op<value_type, geometry_type_1, geometry_type_2, op_type>(output_, lvalue_, rvalue_);
|
||||
polygon_set_mutable_traits<geometry_type_1>::set(lvalue_, output_.begin(), output_.end());
|
||||
return lvalue_;
|
||||
}
|
||||
|
||||
// copy constructor
|
||||
template <typename coordinate_type>
|
||||
template <typename ltype, typename rtype, int op_type>
|
||||
polygon_set_data<coordinate_type>::polygon_set_data(const polygon_set_view<ltype, rtype, op_type>& that) :
|
||||
data_(that.value().data_), dirty_(that.value().dirty_), unsorted_(that.value().unsorted_), is_45_(that.value().is_45_) {}
|
||||
|
||||
template <typename ltype, typename rtype, int op_type>
|
||||
struct geometry_concept<polygon_set_view<ltype, rtype, op_type> > { typedef polygon_set_concept type; };
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,588 @@
|
|||
/*
|
||||
Copyright 2008 Intel Corporation
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
*/
|
||||
#ifndef BOOST_POLYGON_PROPERTY_MERGE_HPP
|
||||
#define BOOST_POLYGON_PROPERTY_MERGE_HPP
|
||||
namespace boost { namespace polygon{
|
||||
|
||||
template <typename coordinate_type>
|
||||
class property_merge_point {
|
||||
private:
|
||||
coordinate_type x_, y_;
|
||||
public:
|
||||
inline property_merge_point() : x_(), y_() {}
|
||||
inline property_merge_point(coordinate_type x, coordinate_type y) : x_(x), y_(y) {}
|
||||
//use builtin assign and copy
|
||||
inline bool operator==(const property_merge_point& that) const { return x_ == that.x_ && y_ == that.y_; }
|
||||
inline bool operator!=(const property_merge_point& that) const { return !((*this) == that); }
|
||||
inline bool operator<(const property_merge_point& that) const {
|
||||
if(x_ < that.x_) return true;
|
||||
if(x_ > that.x_) return false;
|
||||
return y_ < that.y_;
|
||||
}
|
||||
inline coordinate_type x() const { return x_; }
|
||||
inline coordinate_type y() const { return y_; }
|
||||
inline void x(coordinate_type value) { x_ = value; }
|
||||
inline void y(coordinate_type value) { y_ = value; }
|
||||
};
|
||||
|
||||
template <typename coordinate_type>
|
||||
class property_merge_interval {
|
||||
private:
|
||||
coordinate_type low_, high_;
|
||||
public:
|
||||
inline property_merge_interval() : low_(), high_() {}
|
||||
inline property_merge_interval(coordinate_type low, coordinate_type high) : low_(low), high_(high) {}
|
||||
//use builtin assign and copy
|
||||
inline bool operator==(const property_merge_interval& that) const { return low_ == that.low_ && high_ == that.high_; }
|
||||
inline bool operator!=(const property_merge_interval& that) const { return !((*this) == that); }
|
||||
inline bool operator<(const property_merge_interval& that) const {
|
||||
if(low_ < that.low_) return true;
|
||||
if(low_ > that.low_) return false;
|
||||
return high_ < that.high_;
|
||||
}
|
||||
inline coordinate_type low() const { return low_; }
|
||||
inline coordinate_type high() const { return high_; }
|
||||
inline void low(coordinate_type value) { low_ = value; }
|
||||
inline void high(coordinate_type value) { high_ = value; }
|
||||
};
|
||||
|
||||
template <typename coordinate_type, typename property_type, typename polygon_set_type, typename keytype = std::set<property_type> >
|
||||
class merge_scanline {
|
||||
public:
|
||||
//definitions
|
||||
|
||||
typedef keytype property_set;
|
||||
typedef std::vector<std::pair<property_type, int> > property_map;
|
||||
typedef std::pair<property_merge_point<coordinate_type>, std::pair<property_type, int> > vertex_property;
|
||||
typedef std::pair<property_merge_point<coordinate_type>, property_map> vertex_data;
|
||||
typedef std::vector<vertex_property> property_merge_data;
|
||||
//typedef std::map<property_set, polygon_set_type> Result;
|
||||
typedef std::map<coordinate_type, property_map> scanline_type;
|
||||
typedef typename scanline_type::iterator scanline_iterator;
|
||||
typedef std::pair<property_merge_interval<coordinate_type>, std::pair<property_set, property_set> > edge_property;
|
||||
typedef std::vector<edge_property> edge_property_vector;
|
||||
|
||||
//static public member functions
|
||||
|
||||
template <typename iT, typename orientation_2d_type>
|
||||
static inline void
|
||||
populate_property_merge_data(property_merge_data& pmd, iT input_begin, iT input_end,
|
||||
const property_type& property, orientation_2d_type orient) {
|
||||
for( ; input_begin != input_end; ++input_begin) {
|
||||
std::pair<property_merge_point<coordinate_type>, std::pair<property_type, int> > element;
|
||||
if(orient == HORIZONTAL)
|
||||
element.first = property_merge_point<coordinate_type>((*input_begin).second.first, (*input_begin).first);
|
||||
else
|
||||
element.first = property_merge_point<coordinate_type>((*input_begin).first, (*input_begin).second.first);
|
||||
element.second.first = property;
|
||||
element.second.second = (*input_begin).second.second;
|
||||
pmd.push_back(element);
|
||||
}
|
||||
}
|
||||
|
||||
//public member functions
|
||||
|
||||
merge_scanline() : output(), scanline(), currentVertex(), tmpVector(), previousY(), countFromBelow(), scanlinePosition() {}
|
||||
merge_scanline(const merge_scanline& that) :
|
||||
output(that.output),
|
||||
scanline(that.scanline),
|
||||
currentVertex(that.currentVertex),
|
||||
tmpVector(that.tmpVector),
|
||||
previousY(that.previousY),
|
||||
countFromBelow(that.countFromBelow),
|
||||
scanlinePosition(that.scanlinePosition)
|
||||
{}
|
||||
merge_scanline& operator=(const merge_scanline& that) {
|
||||
output = that.output;
|
||||
scanline = that.scanline;
|
||||
currentVertex = that.currentVertex;
|
||||
tmpVector = that.tmpVector;
|
||||
previousY = that.previousY;
|
||||
countFromBelow = that.countFromBelow;
|
||||
scanlinePosition = that.scanlinePosition;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename result_type>
|
||||
inline void perform_merge(result_type& result, property_merge_data& data) {
|
||||
if(data.empty()) return;
|
||||
//sort
|
||||
std::sort(data.begin(), data.end(), less_vertex_data<vertex_property>());
|
||||
//scanline
|
||||
bool firstIteration = true;
|
||||
scanlinePosition = scanline.end();
|
||||
for(std::size_t i = 0; i < data.size(); ++i) {
|
||||
if(firstIteration) {
|
||||
mergeProperty(currentVertex.second, data[i].second);
|
||||
currentVertex.first = data[i].first;
|
||||
firstIteration = false;
|
||||
} else {
|
||||
if(data[i].first != currentVertex.first) {
|
||||
if(data[i].first.x() != currentVertex.first.x()) {
|
||||
processVertex(output);
|
||||
//std::cout << scanline.size() << " ";
|
||||
countFromBelow.clear(); //should already be clear
|
||||
writeOutput(currentVertex.first.x(), result, output);
|
||||
currentVertex.second.clear();
|
||||
mergeProperty(currentVertex.second, data[i].second);
|
||||
currentVertex.first = data[i].first;
|
||||
//std::cout << assertRedundant(scanline) << "/" << scanline.size() << " ";
|
||||
} else {
|
||||
processVertex(output);
|
||||
currentVertex.second.clear();
|
||||
mergeProperty(currentVertex.second, data[i].second);
|
||||
currentVertex.first = data[i].first;
|
||||
}
|
||||
} else {
|
||||
mergeProperty(currentVertex.second, data[i].second);
|
||||
}
|
||||
}
|
||||
}
|
||||
processVertex(output);
|
||||
writeOutput(currentVertex.first.x(), result, output);
|
||||
//std::cout << assertRedundant(scanline) << "/" << scanline.size() << "\n";
|
||||
//std::cout << scanline.size() << "\n";
|
||||
}
|
||||
|
||||
private:
|
||||
//private supporting types
|
||||
|
||||
template <class T>
|
||||
class less_vertex_data {
|
||||
public:
|
||||
less_vertex_data() {}
|
||||
bool operator()(const T& lvalue, const T& rvalue) {
|
||||
if(lvalue.first.x() < rvalue.first.x()) return true;
|
||||
if(lvalue.first.x() > rvalue.first.x()) return false;
|
||||
if(lvalue.first.y() < rvalue.first.y()) return true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct lessPropertyCount {
|
||||
lessPropertyCount() {}
|
||||
bool operator()(const T& a, const T& b) {
|
||||
return a.first < b.first;
|
||||
}
|
||||
};
|
||||
|
||||
//private static member functions
|
||||
|
||||
static inline void mergeProperty(property_map& lvalue, std::pair<property_type, int>& rvalue) {
|
||||
typename property_map::iterator itr = std::lower_bound(lvalue.begin(), lvalue.end(), rvalue,
|
||||
lessPropertyCount<std::pair<property_type, int> >());
|
||||
if(itr == lvalue.end() ||
|
||||
(*itr).first != rvalue.first) {
|
||||
lvalue.insert(itr, rvalue);
|
||||
} else {
|
||||
(*itr).second += rvalue.second;
|
||||
if((*itr).second == 0)
|
||||
lvalue.erase(itr);
|
||||
}
|
||||
// if(assertSorted(lvalue)) {
|
||||
// std::cout << "in mergeProperty\n";
|
||||
// exit(0);
|
||||
// }
|
||||
}
|
||||
|
||||
// static inline bool assertSorted(property_map& pset) {
|
||||
// bool result = false;
|
||||
// for(std::size_t i = 1; i < pset.size(); ++i) {
|
||||
// if(pset[i] < pset[i-1]) {
|
||||
// std::cout << "Out of Order Error ";
|
||||
// result = true;
|
||||
// }
|
||||
// if(pset[i].first == pset[i-1].first) {
|
||||
// std::cout << "Duplicate Property Error ";
|
||||
// result = true;
|
||||
// }
|
||||
// if(pset[0].second == 0 || pset[1].second == 0) {
|
||||
// std::cout << "Empty Property Error ";
|
||||
// result = true;
|
||||
// }
|
||||
// }
|
||||
// return result;
|
||||
// }
|
||||
|
||||
static inline void setProperty(property_set& pset, property_map& pmap) {
|
||||
for(typename property_map::iterator itr = pmap.begin(); itr != pmap.end(); ++itr) {
|
||||
if((*itr).second > 0) {
|
||||
pset.insert(pset.end(), (*itr).first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//private data members
|
||||
|
||||
edge_property_vector output;
|
||||
scanline_type scanline;
|
||||
vertex_data currentVertex;
|
||||
property_map tmpVector;
|
||||
coordinate_type previousY;
|
||||
property_map countFromBelow;
|
||||
scanline_iterator scanlinePosition;
|
||||
|
||||
//private member functions
|
||||
|
||||
inline void mergeCount(property_map& lvalue, property_map& rvalue) {
|
||||
typename property_map::iterator litr = lvalue.begin();
|
||||
typename property_map::iterator ritr = rvalue.begin();
|
||||
tmpVector.clear();
|
||||
while(litr != lvalue.end() && ritr != rvalue.end()) {
|
||||
if((*litr).first <= (*ritr).first) {
|
||||
if(!tmpVector.empty() &&
|
||||
(*litr).first == tmpVector.back().first) {
|
||||
tmpVector.back().second += (*litr).second;
|
||||
} else {
|
||||
tmpVector.push_back(*litr);
|
||||
}
|
||||
++litr;
|
||||
} else if((*ritr).first <= (*litr).first) {
|
||||
if(!tmpVector.empty() &&
|
||||
(*ritr).first == tmpVector.back().first) {
|
||||
tmpVector.back().second += (*ritr).second;
|
||||
} else {
|
||||
tmpVector.push_back(*ritr);
|
||||
}
|
||||
++ritr;
|
||||
}
|
||||
}
|
||||
while(litr != lvalue.end()) {
|
||||
if(!tmpVector.empty() &&
|
||||
(*litr).first == tmpVector.back().first) {
|
||||
tmpVector.back().second += (*litr).second;
|
||||
} else {
|
||||
tmpVector.push_back(*litr);
|
||||
}
|
||||
++litr;
|
||||
}
|
||||
while(ritr != rvalue.end()) {
|
||||
if(!tmpVector.empty() &&
|
||||
(*ritr).first == tmpVector.back().first) {
|
||||
tmpVector.back().second += (*ritr).second;
|
||||
} else {
|
||||
tmpVector.push_back(*ritr);
|
||||
}
|
||||
++ritr;
|
||||
}
|
||||
lvalue.clear();
|
||||
for(std::size_t i = 0; i < tmpVector.size(); ++i) {
|
||||
if(tmpVector[i].second != 0) {
|
||||
lvalue.push_back(tmpVector[i]);
|
||||
}
|
||||
}
|
||||
// if(assertSorted(lvalue)) {
|
||||
// std::cout << "in mergeCount\n";
|
||||
// exit(0);
|
||||
// }
|
||||
}
|
||||
|
||||
inline void processVertex(edge_property_vector& output) {
|
||||
if(!countFromBelow.empty()) {
|
||||
//we are processing an interval of change in scanline state between
|
||||
//previous vertex position and current vertex position where
|
||||
//count from below represents the change on the interval
|
||||
//foreach scanline element from previous to current we
|
||||
//write the interval on the scanline that is changing
|
||||
//the old value and the new value to output
|
||||
property_merge_interval<coordinate_type> currentInterval(previousY, currentVertex.first.y());
|
||||
coordinate_type currentY = currentInterval.low();
|
||||
if(scanlinePosition == scanline.end() ||
|
||||
(*scanlinePosition).first != previousY) {
|
||||
scanlinePosition = scanline.lower_bound(previousY);
|
||||
}
|
||||
scanline_iterator previousScanlinePosition = scanlinePosition;
|
||||
++scanlinePosition;
|
||||
while(scanlinePosition != scanline.end()) {
|
||||
coordinate_type elementY = (*scanlinePosition).first;
|
||||
if(elementY <= currentInterval.high()) {
|
||||
property_map& countOnLeft = (*previousScanlinePosition).second;
|
||||
edge_property element;
|
||||
output.push_back(element);
|
||||
output.back().first = property_merge_interval<coordinate_type>((*previousScanlinePosition).first, elementY);
|
||||
setProperty(output.back().second.first, countOnLeft);
|
||||
mergeCount(countOnLeft, countFromBelow);
|
||||
setProperty(output.back().second.second, countOnLeft);
|
||||
if(output.back().second.first == output.back().second.second) {
|
||||
output.pop_back(); //it was an internal vertical edge, not to be output
|
||||
}
|
||||
else if(output.size() > 1) {
|
||||
edge_property& secondToLast = output[output.size()-2];
|
||||
if(secondToLast.first.high() == output.back().first.low() &&
|
||||
secondToLast.second.first == output.back().second.first &&
|
||||
secondToLast.second.second == output.back().second.second) {
|
||||
//merge output onto previous output because properties are
|
||||
//identical on both sides implying an internal horizontal edge
|
||||
secondToLast.first.high(output.back().first.high());
|
||||
output.pop_back();
|
||||
}
|
||||
}
|
||||
if(previousScanlinePosition == scanline.begin()) {
|
||||
if(countOnLeft.empty()) {
|
||||
scanline.erase(previousScanlinePosition);
|
||||
}
|
||||
} else {
|
||||
scanline_iterator tmpitr = previousScanlinePosition;
|
||||
--tmpitr;
|
||||
if((*tmpitr).second == (*previousScanlinePosition).second)
|
||||
scanline.erase(previousScanlinePosition);
|
||||
}
|
||||
|
||||
} else if(currentY < currentInterval.high()){
|
||||
//elementY > currentInterval.high()
|
||||
//split the interval between previous and current scanline elements
|
||||
std::pair<coordinate_type, property_map> elementScan;
|
||||
elementScan.first = currentInterval.high();
|
||||
elementScan.second = (*previousScanlinePosition).second;
|
||||
scanlinePosition = scanline.insert(scanlinePosition, elementScan);
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
previousScanlinePosition = scanlinePosition;
|
||||
currentY = previousY = elementY;
|
||||
++scanlinePosition;
|
||||
if(scanlinePosition == scanline.end() &&
|
||||
currentY < currentInterval.high()) {
|
||||
//insert a new element for top of range
|
||||
std::pair<coordinate_type, property_map> elementScan;
|
||||
elementScan.first = currentInterval.high();
|
||||
scanlinePosition = scanline.insert(scanline.end(), elementScan);
|
||||
}
|
||||
}
|
||||
if(scanlinePosition == scanline.end() &&
|
||||
currentY < currentInterval.high()) {
|
||||
//handle case where we iterated to end of the scanline
|
||||
//we need to insert an element into the scanline at currentY
|
||||
//with property value coming from below
|
||||
//and another one at currentInterval.high() with empty property value
|
||||
mergeCount(scanline[currentY], countFromBelow);
|
||||
std::pair<coordinate_type, property_map> elementScan;
|
||||
elementScan.first = currentInterval.high();
|
||||
scanline.insert(scanline.end(), elementScan);
|
||||
|
||||
edge_property element;
|
||||
output.push_back(element);
|
||||
output.back().first = property_merge_interval<coordinate_type>(currentY, currentInterval.high());
|
||||
setProperty(output.back().second.second, countFromBelow);
|
||||
mergeCount(countFromBelow, currentVertex.second);
|
||||
} else {
|
||||
mergeCount(countFromBelow, currentVertex.second);
|
||||
if(countFromBelow.empty()) {
|
||||
if(previousScanlinePosition == scanline.begin()) {
|
||||
if((*previousScanlinePosition).second.empty()) {
|
||||
scanline.erase(previousScanlinePosition);
|
||||
//previousScanlinePosition = scanline.end();
|
||||
//std::cout << "ERASE_A ";
|
||||
}
|
||||
} else {
|
||||
scanline_iterator tmpitr = previousScanlinePosition;
|
||||
--tmpitr;
|
||||
if((*tmpitr).second == (*previousScanlinePosition).second) {
|
||||
scanline.erase(previousScanlinePosition);
|
||||
//previousScanlinePosition = scanline.end();
|
||||
//std::cout << "ERASE_B ";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//count from below is empty, we are starting a new interval of change
|
||||
countFromBelow = currentVertex.second;
|
||||
scanlinePosition = scanline.lower_bound(currentVertex.first.y());
|
||||
if(scanlinePosition != scanline.end()) {
|
||||
if((*scanlinePosition).first != currentVertex.first.y()) {
|
||||
if(scanlinePosition != scanline.begin()) {
|
||||
//decrement to get the lower position of the first interval this vertex intersects
|
||||
--scanlinePosition;
|
||||
//insert a new element into the scanline for the incoming vertex
|
||||
property_map& countOnLeft = (*scanlinePosition).second;
|
||||
std::pair<coordinate_type, property_map> element(currentVertex.first.y(), countOnLeft);
|
||||
scanlinePosition = scanline.insert(scanlinePosition, element);
|
||||
} else {
|
||||
property_map countOnLeft;
|
||||
std::pair<coordinate_type, property_map> element(currentVertex.first.y(), countOnLeft);
|
||||
scanlinePosition = scanline.insert(scanlinePosition, element);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
property_map countOnLeft;
|
||||
std::pair<coordinate_type, property_map> element(currentVertex.first.y(), countOnLeft);
|
||||
scanlinePosition = scanline.insert(scanlinePosition, element);
|
||||
}
|
||||
}
|
||||
previousY = currentVertex.first.y();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline int assertRedundant(T& t) {
|
||||
if(t.empty()) return 0;
|
||||
int count = 0;
|
||||
typename T::iterator itr = t.begin();
|
||||
if((*itr).second.empty())
|
||||
++count;
|
||||
typename T::iterator itr2 = itr;
|
||||
++itr2;
|
||||
while(itr2 != t.end()) {
|
||||
if((*itr).second == (*itr2).second)
|
||||
++count;
|
||||
itr = itr2;
|
||||
++itr2;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void performExtract(T& result, property_merge_data& data) {
|
||||
if(data.empty()) return;
|
||||
//sort
|
||||
std::sort(data.begin(), data.end(), less_vertex_data<vertex_property>());
|
||||
|
||||
//scanline
|
||||
bool firstIteration = true;
|
||||
scanlinePosition = scanline.end();
|
||||
for(std::size_t i = 0; i < data.size(); ++i) {
|
||||
if(firstIteration) {
|
||||
mergeProperty(currentVertex.second, data[i].second);
|
||||
currentVertex.first = data[i].first;
|
||||
firstIteration = false;
|
||||
} else {
|
||||
if(data[i].first != currentVertex.first) {
|
||||
if(data[i].first.x() != currentVertex.first.x()) {
|
||||
processVertex(output);
|
||||
//std::cout << scanline.size() << " ";
|
||||
countFromBelow.clear(); //should already be clear
|
||||
writeGraph(currentVertex.first.x(), result, output, scanline);
|
||||
currentVertex.second.clear();
|
||||
mergeProperty(currentVertex.second, data[i].second);
|
||||
currentVertex.first = data[i].first;
|
||||
} else {
|
||||
processVertex(output);
|
||||
currentVertex.second.clear();
|
||||
mergeProperty(currentVertex.second, data[i].second);
|
||||
currentVertex.first = data[i].first;
|
||||
}
|
||||
} else {
|
||||
mergeProperty(currentVertex.second, data[i].second);
|
||||
}
|
||||
}
|
||||
}
|
||||
processVertex(output);
|
||||
writeGraph(currentVertex.first.x(), result, output, scanline);
|
||||
//std::cout << scanline.size() << "\n";
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void insertEdges(T& graph, property_set& p1, property_set& p2) {
|
||||
for(typename property_set::iterator itr = p1.begin(); itr != p1.end(); ++itr) {
|
||||
for(typename property_set::iterator itr2 = p2.begin(); itr2 != p2.end(); ++itr2) {
|
||||
if(*itr != *itr2) {
|
||||
graph[*itr].insert(*itr2);
|
||||
graph[*itr2].insert(*itr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void propertySetAbove(coordinate_type y, property_set& ps, T& scanline) {
|
||||
ps.clear();
|
||||
typename T::iterator itr = scanline.find(y);
|
||||
if(itr != scanline.end())
|
||||
setProperty(ps, (*itr).second);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void propertySetBelow(coordinate_type y, property_set& ps, T& scanline) {
|
||||
ps.clear();
|
||||
typename T::iterator itr = scanline.find(y);
|
||||
if(itr != scanline.begin()) {
|
||||
--itr;
|
||||
setProperty(ps, (*itr).second);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename T2>
|
||||
inline void writeGraph(coordinate_type x, T& graph, edge_property_vector& output, T2& scanline) {
|
||||
if(output.empty()) return;
|
||||
edge_property* previousEdgeP = &(output[0]);
|
||||
bool firstIteration = true;
|
||||
property_set ps;
|
||||
for(std::size_t i = 0; i < output.size(); ++i) {
|
||||
edge_property& previousEdge = *previousEdgeP;
|
||||
edge_property& edge = output[i];
|
||||
if(previousEdge.first.high() == edge.first.low()) {
|
||||
//horizontal edge
|
||||
insertEdges(graph, edge.second.first, previousEdge.second.first);
|
||||
//corner 1
|
||||
insertEdges(graph, edge.second.first, previousEdge.second.second);
|
||||
//other horizontal edge
|
||||
insertEdges(graph, edge.second.second, previousEdge.second.second);
|
||||
//corner 2
|
||||
insertEdges(graph, edge.second.second, previousEdge.second.first);
|
||||
} else {
|
||||
if(!firstIteration){
|
||||
//look up regions above previous edge
|
||||
propertySetAbove(previousEdge.first.high(), ps, scanline);
|
||||
insertEdges(graph, ps, previousEdge.second.first);
|
||||
insertEdges(graph, ps, previousEdge.second.second);
|
||||
}
|
||||
//look up regions below current edge in the scanline
|
||||
propertySetBelow(edge.first.high(), ps, scanline);
|
||||
insertEdges(graph, ps, edge.second.first);
|
||||
insertEdges(graph, ps, edge.second.second);
|
||||
}
|
||||
firstIteration = false;
|
||||
//vertical edge
|
||||
insertEdges(graph, edge.second.second, edge.second.first);
|
||||
//shared region to left
|
||||
insertEdges(graph, edge.second.second, edge.second.second);
|
||||
//shared region to right
|
||||
insertEdges(graph, edge.second.first, edge.second.first);
|
||||
previousEdgeP = &(output[i]);
|
||||
}
|
||||
edge_property& previousEdge = *previousEdgeP;
|
||||
propertySetAbove(previousEdge.first.high(), ps, scanline);
|
||||
insertEdges(graph, ps, previousEdge.second.first);
|
||||
insertEdges(graph, ps, previousEdge.second.second);
|
||||
output.clear();
|
||||
}
|
||||
|
||||
template <typename Result>
|
||||
inline void writeOutput(coordinate_type x, Result& result, edge_property_vector& output) {
|
||||
for(std::size_t i = 0; i < output.size(); ++i) {
|
||||
edge_property& edge = output[i];
|
||||
//edge.second.first is the property set on the left of the edge
|
||||
if(!edge.second.first.empty()) {
|
||||
typename Result::iterator itr = result.find(edge.second.first);
|
||||
if(itr == result.end()) {
|
||||
std::pair<property_set, polygon_set_type> element(edge.second.first, polygon_set_type(VERTICAL));
|
||||
itr = result.insert(result.end(), element);
|
||||
}
|
||||
std::pair<interval_data<coordinate_type>, int> element2(interval_data<coordinate_type>(edge.first.low(), edge.first.high()), -1); //right edge of figure
|
||||
(*itr).second.insert(x, element2);
|
||||
}
|
||||
if(!edge.second.second.empty()) {
|
||||
//edge.second.second is the property set on the right of the edge
|
||||
typename Result::iterator itr = result.find(edge.second.second);
|
||||
if(itr == result.end()) {
|
||||
std::pair<property_set, polygon_set_type> element(edge.second.second, polygon_set_type(VERTICAL));
|
||||
itr = result.insert(result.end(), element);
|
||||
}
|
||||
std::pair<interval_data<coordinate_type>, int> element3(interval_data<coordinate_type>(edge.first.low(), edge.first.high()), 1); //left edge of figure
|
||||
(*itr).second.insert(x, element3);
|
||||
}
|
||||
}
|
||||
output.clear();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,160 @@
|
|||
/*
|
||||
Copyright 2008 Intel Corporation
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
*/
|
||||
#ifndef BOOST_POLYGON_PROPERTY_MERGE_45_HPP
|
||||
#define BOOST_POLYGON_PROPERTY_MERGE_45_HPP
|
||||
namespace boost { namespace polygon{
|
||||
|
||||
template <typename Unit, typename property_type>
|
||||
struct polygon_45_property_merge {
|
||||
|
||||
typedef point_data<Unit> Point;
|
||||
typedef typename coordinate_traits<Unit>::manhattan_area_type LongUnit;
|
||||
|
||||
template <typename property_map>
|
||||
static inline void merge_property_maps(property_map& mp, const property_map& mp2, bool subtract = false) {
|
||||
polygon_45_touch<Unit>::merge_property_maps(mp, mp2, subtract);
|
||||
}
|
||||
|
||||
class CountMerge {
|
||||
public:
|
||||
inline CountMerge() : counts() {}
|
||||
//inline CountMerge(int count) { counts[0] = counts[1] = count; }
|
||||
//inline CountMerge(int count1, int count2) { counts[0] = count1; counts[1] = count2; }
|
||||
inline CountMerge(const CountMerge& count) : counts(count.counts) {}
|
||||
inline bool operator==(const CountMerge& count) const { return counts == count.counts; }
|
||||
inline bool operator!=(const CountMerge& count) const { return !((*this) == count); }
|
||||
//inline CountMerge& operator=(int count) { counts[0] = counts[1] = count; return *this; }
|
||||
inline CountMerge& operator=(const CountMerge& count) { counts = count.counts; return *this; }
|
||||
inline int& operator[](property_type index) {
|
||||
std::vector<std::pair<int, int> >::iterator itr = lower_bound(counts.begin(), counts.end(), std::make_pair(index, int(0)));
|
||||
if(itr != counts.end() && itr->first == index) {
|
||||
return itr->second;
|
||||
}
|
||||
itr = counts.insert(itr, std::make_pair(index, int(0)));
|
||||
return itr->second;
|
||||
}
|
||||
// inline int operator[](int index) const {
|
||||
// std::vector<std::pair<int, int> >::const_iterator itr = counts.begin();
|
||||
// for( ; itr != counts.end() && itr->first <= index; ++itr) {
|
||||
// if(itr->first == index) {
|
||||
// return itr->second;
|
||||
// }
|
||||
// }
|
||||
// return 0;
|
||||
// }
|
||||
inline CountMerge& operator+=(const CountMerge& count){
|
||||
merge_property_maps(counts, count.counts, false);
|
||||
return *this;
|
||||
}
|
||||
inline CountMerge& operator-=(const CountMerge& count){
|
||||
merge_property_maps(counts, count.counts, true);
|
||||
return *this;
|
||||
}
|
||||
inline CountMerge operator+(const CountMerge& count) const {
|
||||
return CountMerge(*this)+=count;
|
||||
}
|
||||
inline CountMerge operator-(const CountMerge& count) const {
|
||||
return CountMerge(*this)-=count;
|
||||
}
|
||||
inline CountMerge invert() const {
|
||||
CountMerge retval;
|
||||
retval -= *this;
|
||||
return retval;
|
||||
}
|
||||
std::vector<std::pair<property_type, int> > counts;
|
||||
};
|
||||
|
||||
//output is a std::map<std::set<property_type>, polygon_45_set_data<Unit> >
|
||||
struct merge_45_output_functor {
|
||||
template <typename cT>
|
||||
void operator()(cT& output, const CountMerge& count1, const CountMerge& count2,
|
||||
const Point& pt, int rise, direction_1d end) {
|
||||
typedef typename cT::key_type keytype;
|
||||
keytype left;
|
||||
keytype right;
|
||||
int edgeType = end == LOW ? -1 : 1;
|
||||
for(typename std::vector<std::pair<property_type, int> >::const_iterator itr = count1.counts.begin();
|
||||
itr != count1.counts.end(); ++itr) {
|
||||
left.insert(left.end(), (*itr).first);
|
||||
}
|
||||
for(typename std::vector<std::pair<property_type, int> >::const_iterator itr = count2.counts.begin();
|
||||
itr != count2.counts.end(); ++itr) {
|
||||
right.insert(right.end(), (*itr).first);
|
||||
}
|
||||
if(left == right) return;
|
||||
if(!left.empty()) {
|
||||
//std::cout << pt.x() << " " << pt.y() << " " << rise << " " << edgeType << std::endl;
|
||||
output[left].insert_clean(typename boolean_op_45<Unit>::Vertex45(pt, rise, -edgeType));
|
||||
}
|
||||
if(!right.empty()) {
|
||||
//std::cout << pt.x() << " " << pt.y() << " " << rise << " " << -edgeType << std::endl;
|
||||
output[right].insert_clean(typename boolean_op_45<Unit>::Vertex45(pt, rise, edgeType));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
typedef typename std::pair<Point,
|
||||
typename boolean_op_45<Unit>::template Scan45CountT<CountMerge> > Vertex45Compact;
|
||||
typedef std::vector<Vertex45Compact> MergeSetData;
|
||||
|
||||
struct lessVertex45Compact {
|
||||
bool operator()(const Vertex45Compact& l, const Vertex45Compact& r) {
|
||||
return l.first < r.first;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename output_type>
|
||||
static void performMerge(output_type& result, MergeSetData& tsd) {
|
||||
|
||||
std::sort(tsd.begin(), tsd.end(), lessVertex45Compact());
|
||||
typedef std::vector<std::pair<Point, typename boolean_op_45<Unit>::template Scan45CountT<CountMerge> > > TSD;
|
||||
TSD tsd_;
|
||||
tsd_.reserve(tsd.size());
|
||||
for(typename MergeSetData::iterator itr = tsd.begin(); itr != tsd.end(); ) {
|
||||
typename MergeSetData::iterator itr2 = itr;
|
||||
++itr2;
|
||||
for(; itr2 != tsd.end() && itr2->first == itr->first; ++itr2) {
|
||||
(itr->second) += (itr2->second); //accumulate
|
||||
}
|
||||
tsd_.push_back(std::make_pair(itr->first, itr->second));
|
||||
itr = itr2;
|
||||
}
|
||||
typename boolean_op_45<Unit>::template Scan45<CountMerge, merge_45_output_functor> scanline;
|
||||
for(typename TSD::iterator itr = tsd_.begin(); itr != tsd_.end(); ) {
|
||||
typename TSD::iterator itr2 = itr;
|
||||
++itr2;
|
||||
while(itr2 != tsd_.end() && itr2->first.x() == itr->first.x()) {
|
||||
++itr2;
|
||||
}
|
||||
scanline.scan(result, itr, itr2);
|
||||
itr = itr2;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename iT>
|
||||
static void populateMergeSetData(MergeSetData& tsd, iT begin, iT end, property_type property) {
|
||||
for( ; begin != end; ++begin) {
|
||||
Vertex45Compact vertex;
|
||||
vertex.first = typename Vertex45Compact::first_type(begin->pt.x() * 2, begin->pt.y() * 2);
|
||||
tsd.push_back(vertex);
|
||||
for(unsigned int i = 0; i < 4; ++i) {
|
||||
if(begin->count[i]) {
|
||||
tsd.back().second[i][property] += begin->count[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,267 @@
|
|||
/*
|
||||
Copyright 2008 Intel Corporation
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
*/
|
||||
#ifndef BOOST_POLYGON_RECTANGLE_FORMATION_HPP
|
||||
#define BOOST_POLYGON_RECTANGLE_FORMATION_HPP
|
||||
namespace boost { namespace polygon{
|
||||
|
||||
namespace rectangle_formation {
|
||||
template <class T>
|
||||
class ScanLineToRects {
|
||||
public:
|
||||
typedef T rectangle_type;
|
||||
typedef typename rectangle_traits<T>::coordinate_type coordinate_type;
|
||||
typedef rectangle_data<coordinate_type> scan_rect_type;
|
||||
private:
|
||||
|
||||
typedef std::set<scan_rect_type, less_rectangle_concept<scan_rect_type, scan_rect_type> > ScanData;
|
||||
ScanData scanData_;
|
||||
bool haveCurrentRect_;
|
||||
scan_rect_type currentRect_;
|
||||
orientation_2d orient_;
|
||||
typename rectangle_traits<T>::coordinate_type currentCoordinate_;
|
||||
public:
|
||||
inline ScanLineToRects() : scanData_(), haveCurrentRect_(), currentRect_(), orient_(), currentCoordinate_() {}
|
||||
|
||||
inline ScanLineToRects(orientation_2d orient, rectangle_type model) :
|
||||
scanData_(orientation_2d(orient.to_int() ? VERTICAL : HORIZONTAL)),
|
||||
haveCurrentRect_(false), currentRect_(), orient_(orient), currentCoordinate_() {
|
||||
assign(currentRect_, model);
|
||||
currentCoordinate_ = (std::numeric_limits<coordinate_type>::max)();
|
||||
}
|
||||
|
||||
template <typename CT>
|
||||
inline ScanLineToRects& processEdge(CT& rectangles, const interval_data<coordinate_type>& edge);
|
||||
|
||||
inline ScanLineToRects& nextMajorCoordinate(coordinate_type currentCoordinate) {
|
||||
if(haveCurrentRect_) {
|
||||
scanData_.insert(scanData_.end(), currentRect_);
|
||||
haveCurrentRect_ = false;
|
||||
}
|
||||
currentCoordinate_ = currentCoordinate;
|
||||
return *this;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <class CT, class ST, class rectangle_type, typename interval_type, typename coordinate_type> inline CT&
|
||||
processEdge_(CT& rectangles, ST& scanData, const interval_type& edge,
|
||||
bool& haveCurrentRect, rectangle_type& currentRect, coordinate_type currentCoordinate, orientation_2d orient)
|
||||
{
|
||||
typedef typename CT::value_type result_type;
|
||||
bool edgeProcessed = false;
|
||||
if(!scanData.empty()) {
|
||||
|
||||
//process all rectangles in the scanData that touch the edge
|
||||
typename ST::iterator dataIter = scanData.lower_bound(rectangle_type(edge, edge));
|
||||
//decrement beginIter until its low is less than edge's low
|
||||
while((dataIter == scanData.end() || (*dataIter).get(orient).get(LOW) > edge.get(LOW)) &&
|
||||
dataIter != scanData.begin())
|
||||
{
|
||||
--dataIter;
|
||||
}
|
||||
//process each rectangle until the low end of the rectangle
|
||||
//is greater than the high end of the edge
|
||||
while(dataIter != scanData.end() &&
|
||||
(*dataIter).get(orient).get(LOW) <= edge.get(HIGH))
|
||||
{
|
||||
const rectangle_type& rect = *dataIter;
|
||||
//if the rectangle data intersects the edge at all
|
||||
if(rect.get(orient).get(HIGH) >= edge.get(LOW)) {
|
||||
if(contains(rect.get(orient), edge, true)) {
|
||||
//this is a closing edge
|
||||
//we need to write out the intersecting rectangle and
|
||||
//insert between 0 and 2 rectangles into the scanData
|
||||
//write out rectangle
|
||||
rectangle_type tmpRect = rect;
|
||||
|
||||
if(rect.get(orient.get_perpendicular()).get(LOW) < currentCoordinate) {
|
||||
//set the high coordinate perpedicular to slicing orientation
|
||||
//to the current coordinate of the scan event
|
||||
tmpRect.set(orient.get_perpendicular().get_direction(HIGH),
|
||||
currentCoordinate);
|
||||
result_type result;
|
||||
assign(result, tmpRect);
|
||||
rectangles.insert(rectangles.end(), result);
|
||||
}
|
||||
//erase the rectangle from the scan data
|
||||
typename ST::iterator nextIter = dataIter;
|
||||
++nextIter;
|
||||
scanData.erase(dataIter);
|
||||
if(tmpRect.get(orient).get(LOW) < edge.get(LOW)) {
|
||||
//insert a rectangle for the overhang of the bottom
|
||||
//of the rectangle back into scan data
|
||||
rectangle_type lowRect(tmpRect);
|
||||
lowRect.set(orient.get_perpendicular(), interval_data<coordinate_type>(currentCoordinate,
|
||||
currentCoordinate));
|
||||
lowRect.set(orient.get_direction(HIGH), edge.get(LOW));
|
||||
scanData.insert(nextIter, lowRect);
|
||||
}
|
||||
if(tmpRect.get(orient).get(HIGH) > edge.get(HIGH)) {
|
||||
//insert a rectangle for the overhang of the top
|
||||
//of the rectangle back into scan data
|
||||
rectangle_type highRect(tmpRect);
|
||||
highRect.set(orient.get_perpendicular(), interval_data<coordinate_type>(currentCoordinate,
|
||||
currentCoordinate));
|
||||
highRect.set(orient.get_direction(LOW), edge.get(HIGH));
|
||||
scanData.insert(nextIter, highRect);
|
||||
}
|
||||
//we are done with this edge
|
||||
edgeProcessed = true;
|
||||
break;
|
||||
} else {
|
||||
//it must be an opening edge
|
||||
//assert that rect does not overlap the edge but only touches
|
||||
//write out rectangle
|
||||
rectangle_type tmpRect = rect;
|
||||
//set the high coordinate perpedicular to slicing orientation
|
||||
//to the current coordinate of the scan event
|
||||
if(tmpRect.get(orient.get_perpendicular().get_direction(LOW)) < currentCoordinate) {
|
||||
tmpRect.set(orient.get_perpendicular().get_direction(HIGH),
|
||||
currentCoordinate);
|
||||
result_type result;
|
||||
assign(result, tmpRect);
|
||||
rectangles.insert(rectangles.end(), result);
|
||||
}
|
||||
//erase the rectangle from the scan data
|
||||
typename ST::iterator nextIter = dataIter;
|
||||
++nextIter;
|
||||
scanData.erase(dataIter);
|
||||
dataIter = nextIter;
|
||||
if(haveCurrentRect) {
|
||||
if(currentRect.get(orient).get(HIGH) >= edge.get(LOW)){
|
||||
if(!edgeProcessed && currentRect.get(orient.get_direction(HIGH)) > edge.get(LOW)){
|
||||
rectangle_type tmpRect2(currentRect);
|
||||
tmpRect2.set(orient.get_direction(HIGH), edge.get(LOW));
|
||||
scanData.insert(nextIter, tmpRect2);
|
||||
if(currentRect.get(orient.get_direction(HIGH)) > edge.get(HIGH)) {
|
||||
currentRect.set(orient, interval_data<coordinate_type>(edge.get(HIGH), currentRect.get(orient.get_direction(HIGH))));
|
||||
} else {
|
||||
haveCurrentRect = false;
|
||||
}
|
||||
} else {
|
||||
//extend the top of current rect
|
||||
currentRect.set(orient.get_direction(HIGH),
|
||||
(std::max)(edge.get(HIGH),
|
||||
tmpRect.get(orient.get_direction(HIGH))));
|
||||
}
|
||||
} else {
|
||||
//insert current rect into the scanData
|
||||
scanData.insert(nextIter, currentRect);
|
||||
//create a new current rect
|
||||
currentRect.set(orient.get_perpendicular(), interval_data<coordinate_type>(currentCoordinate,
|
||||
currentCoordinate));
|
||||
currentRect.set(orient, interval_data<coordinate_type>((std::min)(tmpRect.get(orient).get(LOW),
|
||||
edge.get(LOW)),
|
||||
(std::max)(tmpRect.get(orient).get(HIGH),
|
||||
edge.get(HIGH))));
|
||||
}
|
||||
} else {
|
||||
haveCurrentRect = true;
|
||||
currentRect.set(orient.get_perpendicular(), interval_data<coordinate_type>(currentCoordinate,
|
||||
currentCoordinate));
|
||||
currentRect.set(orient, interval_data<coordinate_type>((std::min)(tmpRect.get(orient).get(LOW),
|
||||
edge.get(LOW)),
|
||||
(std::max)(tmpRect.get(orient).get(HIGH),
|
||||
edge.get(HIGH))));
|
||||
}
|
||||
//skip to nextIter position
|
||||
edgeProcessed = true;
|
||||
continue;
|
||||
}
|
||||
//edgeProcessed = true;
|
||||
}
|
||||
++dataIter;
|
||||
} //end while edge intersects rectangle data
|
||||
|
||||
}
|
||||
if(!edgeProcessed) {
|
||||
if(haveCurrentRect) {
|
||||
if(currentRect.get(orient.get_perpendicular().get_direction(HIGH))
|
||||
== currentCoordinate &&
|
||||
currentRect.get(orient.get_direction(HIGH)) >= edge.get(LOW))
|
||||
{
|
||||
if(currentRect.get(orient.get_direction(HIGH)) > edge.get(LOW)){
|
||||
rectangle_type tmpRect(currentRect);
|
||||
tmpRect.set(orient.get_direction(HIGH), edge.get(LOW));
|
||||
scanData.insert(scanData.end(), tmpRect);
|
||||
if(currentRect.get(orient.get_direction(HIGH)) > edge.get(HIGH)) {
|
||||
currentRect.set(orient,
|
||||
interval_data<coordinate_type>(edge.get(HIGH),
|
||||
currentRect.get(orient.get_direction(HIGH))));
|
||||
return rectangles;
|
||||
} else {
|
||||
haveCurrentRect = false;
|
||||
return rectangles;
|
||||
}
|
||||
}
|
||||
//extend current rect
|
||||
currentRect.set(orient.get_direction(HIGH), edge.get(HIGH));
|
||||
return rectangles;
|
||||
}
|
||||
scanData.insert(scanData.end(), currentRect);
|
||||
haveCurrentRect = false;
|
||||
}
|
||||
rectangle_type tmpRect(currentRect);
|
||||
tmpRect.set(orient.get_perpendicular(), interval_data<coordinate_type>(currentCoordinate,
|
||||
currentCoordinate));
|
||||
tmpRect.set(orient, edge);
|
||||
scanData.insert(tmpRect);
|
||||
return rectangles;
|
||||
}
|
||||
return rectangles;
|
||||
|
||||
}
|
||||
|
||||
template <class T>
|
||||
template <class CT>
|
||||
inline
|
||||
ScanLineToRects<T>& ScanLineToRects<T>::processEdge(CT& rectangles, const interval_data<coordinate_type>& edge)
|
||||
{
|
||||
processEdge_(rectangles, scanData_, edge, haveCurrentRect_, currentRect_, currentCoordinate_, orient_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
} //namespace rectangle_formation
|
||||
|
||||
template <typename T, typename T2>
|
||||
struct get_coordinate_type_for_rectangles {
|
||||
typedef typename polygon_traits<T>::coordinate_type type;
|
||||
};
|
||||
template <typename T>
|
||||
struct get_coordinate_type_for_rectangles<T, rectangle_concept> {
|
||||
typedef typename rectangle_traits<T>::coordinate_type type;
|
||||
};
|
||||
|
||||
template <typename output_container, typename iterator_type, typename rectangle_concept>
|
||||
void form_rectangles(output_container& output, iterator_type begin, iterator_type end,
|
||||
orientation_2d orient, rectangle_concept ) {
|
||||
typedef typename output_container::value_type rectangle_type;
|
||||
typedef typename get_coordinate_type_for_rectangles<rectangle_type, typename geometry_concept<rectangle_type>::type>::type Unit;
|
||||
rectangle_data<Unit> model;
|
||||
Unit prevPos = (std::numeric_limits<Unit>::max)();
|
||||
rectangle_formation::ScanLineToRects<rectangle_data<Unit> > scanlineToRects(orient, model);
|
||||
for(iterator_type itr = begin;
|
||||
itr != end; ++ itr) {
|
||||
Unit pos = (*itr).first;
|
||||
if(pos != prevPos) {
|
||||
scanlineToRects.nextMajorCoordinate(pos);
|
||||
prevPos = pos;
|
||||
}
|
||||
Unit lowy = (*itr).second.first;
|
||||
iterator_type tmp_itr = itr;
|
||||
++itr;
|
||||
Unit highy = (*itr).second.first;
|
||||
scanlineToRects.processEdge(output, interval_data<Unit>(lowy, highy));
|
||||
if(abs((*itr).second.second) > 1) itr = tmp_itr; //next edge begins from this vertex
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,553 @@
|
|||
/*
|
||||
Copyright 2008 Intel Corporation
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
*/
|
||||
#ifndef BOOST_POLYGON_TRANSFORM_DETAIL_HPP
|
||||
#define BOOST_POLYGON_TRANSFORM_DETAIL_HPP
|
||||
|
||||
namespace boost { namespace polygon{
|
||||
// inline std::ostream& operator<< (std::ostream& o, const axis_transformation& r) {
|
||||
// o << r.atr_;
|
||||
// return o;
|
||||
// }
|
||||
|
||||
// inline std::istream& operator>> (std::istream& i, axis_transformation& r) {
|
||||
// int tmp;
|
||||
// i >> tmp;
|
||||
// r = axis_transformation((axis_transformation::ATR)tmp);
|
||||
// return i;
|
||||
// }
|
||||
|
||||
// template <typename scale_factor_type>
|
||||
// inline std::ostream& operator<< (std::ostream& o, const anisotropic_scale_factor<scale_factor_type>& sc) {
|
||||
// o << sc.scale_[0] << BOOST_POLYGON_SEP << sc.scale_[1] << GTL_SEP << sc.scale_[2];
|
||||
// return o;
|
||||
// }
|
||||
|
||||
// template <typename scale_factor_type>
|
||||
// inline std::istream& operator>> (std::istream& i, anisotropic_scale_factor<scale_factor_type>& sc) {
|
||||
// i >> sc.scale_[0] >> sc.scale_[1] >> sc.scale_[2];
|
||||
// return i;
|
||||
// }
|
||||
|
||||
// template <typename coordinate_type>
|
||||
// inline std::ostream& operator<< (std::ostream& o, const transformation& tr) {
|
||||
// o << tr.atr_ << BOOST_POLYGON_SEP << tr.p_;
|
||||
// return o;
|
||||
// }
|
||||
|
||||
// template <typename coordinate_type>
|
||||
// inline std::istream& operator>> (std::istream& i, transformation& tr) {
|
||||
// i >> tr.atr_ >> tr.p_;
|
||||
// return i;
|
||||
// }
|
||||
|
||||
|
||||
inline axis_transformation::axis_transformation(const orientation_3d& orient) : atr_(NULL_TRANSFORM) {
|
||||
const ATR tmp[3] = {
|
||||
UP_EAST_NORTH, //sort by x, then z, then y
|
||||
EAST_UP_NORTH, //sort by y, then z, then x
|
||||
EAST_NORTH_UP //sort by z, then y, then x
|
||||
};
|
||||
atr_ = tmp[orient.to_int()];
|
||||
}
|
||||
|
||||
inline axis_transformation::axis_transformation(const orientation_2d& orient) : atr_(NULL_TRANSFORM) {
|
||||
const ATR tmp[3] = {
|
||||
NORTH_EAST_UP, //sort by z, then x, then y
|
||||
EAST_NORTH_UP //sort by z, then y, then x
|
||||
};
|
||||
atr_ = tmp[orient.to_int()];
|
||||
}
|
||||
|
||||
inline axis_transformation::axis_transformation(const direction_3d& dir) : atr_(NULL_TRANSFORM) {
|
||||
const ATR tmp[6] = {
|
||||
DOWN_EAST_NORTH, //sort by -x, then z, then y
|
||||
UP_EAST_NORTH, //sort by x, then z, then y
|
||||
EAST_DOWN_NORTH, //sort by -y, then z, then x
|
||||
EAST_UP_NORTH, //sort by y, then z, then x
|
||||
EAST_NORTH_DOWN, //sort by -z, then y, then x
|
||||
EAST_NORTH_UP //sort by z, then y, then x
|
||||
};
|
||||
atr_ = tmp[dir.to_int()];
|
||||
}
|
||||
|
||||
inline axis_transformation::axis_transformation(const direction_2d& dir) : atr_(NULL_TRANSFORM) {
|
||||
const ATR tmp[4] = {
|
||||
SOUTH_EAST_UP, //sort by z, then x, then y
|
||||
NORTH_EAST_UP, //sort by z, then x, then y
|
||||
EAST_SOUTH_UP, //sort by z, then y, then x
|
||||
EAST_NORTH_UP //sort by z, then y, then x
|
||||
};
|
||||
atr_ = tmp[dir.to_int()];
|
||||
}
|
||||
|
||||
inline axis_transformation& axis_transformation::operator=(const axis_transformation& a) {
|
||||
atr_ = a.atr_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline axis_transformation& axis_transformation::operator=(const ATR& atr) {
|
||||
atr_ = atr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool axis_transformation::operator==(const axis_transformation& a) const {
|
||||
return atr_ == a.atr_;
|
||||
}
|
||||
|
||||
inline bool axis_transformation::operator!=(const axis_transformation& a) const {
|
||||
return !(*this == a);
|
||||
}
|
||||
|
||||
inline bool axis_transformation::operator<(const axis_transformation& a) const {
|
||||
return atr_ < a.atr_;
|
||||
}
|
||||
|
||||
inline axis_transformation& axis_transformation::operator+=(const axis_transformation& a){
|
||||
bool abit5 = (a.atr_ & 32) != 0;
|
||||
bool abit4 = (a.atr_ & 16) != 0;
|
||||
bool abit3 = (a.atr_ & 8) != 0;
|
||||
bool abit2 = (a.atr_ & 4) != 0;
|
||||
bool abit1 = (a.atr_ & 2) != 0;
|
||||
bool abit0 = (a.atr_ & 1) != 0;
|
||||
bool bit5 = (atr_ & 32) != 0;
|
||||
bool bit4 = (atr_ & 16) != 0;
|
||||
bool bit3 = (atr_ & 8) != 0;
|
||||
bool bit2 = (atr_ & 4) != 0;
|
||||
bool bit1 = (atr_ & 2) != 0;
|
||||
bool bit0 = (atr_ & 1) != 0;
|
||||
int indexes[2][3] = {
|
||||
{
|
||||
((int)((bit5 & bit2) | (bit4 & !bit2)) << 1) +
|
||||
(int)(bit2 & !bit5),
|
||||
((int)((bit4 & bit2) | (bit5 & !bit2)) << 1) +
|
||||
(int)(!bit5 & !bit2),
|
||||
((int)(!bit4 & !bit5) << 1) +
|
||||
(int)(bit5)
|
||||
},
|
||||
{
|
||||
((int)((abit5 & abit2) | (abit4 & !abit2)) << 1) +
|
||||
(int)(abit2 & !abit5),
|
||||
((int)((abit4 & abit2) | (abit5 & !abit2)) << 1) +
|
||||
(int)(!abit5 & !abit2),
|
||||
((int)(!abit4 & !abit5) << 1) +
|
||||
(int)(abit5)
|
||||
}
|
||||
};
|
||||
int zero_bits[2][3] = {
|
||||
{bit0, bit1, bit3},
|
||||
{abit0, abit1, abit3}
|
||||
};
|
||||
int nbit3 = zero_bits[0][2] ^ zero_bits[1][indexes[0][2]];
|
||||
int nbit1 = zero_bits[0][1] ^ zero_bits[1][indexes[0][1]];
|
||||
int nbit0 = zero_bits[0][0] ^ zero_bits[1][indexes[0][0]];
|
||||
indexes[0][0] = indexes[1][indexes[0][0]];
|
||||
indexes[0][1] = indexes[1][indexes[0][1]];
|
||||
indexes[0][2] = indexes[1][indexes[0][2]];
|
||||
int nbit5 = (indexes[0][2] == 1);
|
||||
int nbit4 = (indexes[0][2] == 0);
|
||||
int nbit2 = (!(nbit5 | nbit4) & (bool)(indexes[0][0] & 1)) | //swap xy
|
||||
(nbit5 & ((indexes[0][0] & 2) >> 1)) | //z->y x->z
|
||||
(nbit4 & ((indexes[0][1] & 2) >> 1)); //z->x y->z
|
||||
atr_ = (ATR)((nbit5 << 5) +
|
||||
(nbit4 << 4) +
|
||||
(nbit3 << 3) +
|
||||
(nbit2 << 2) +
|
||||
(nbit1 << 1) + nbit0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline axis_transformation axis_transformation::operator+(const axis_transformation& a) const {
|
||||
axis_transformation retval(*this);
|
||||
return retval+=a;
|
||||
}
|
||||
|
||||
// populate_axis_array writes the three INDIVIDUAL_AXIS values that the
|
||||
// ATR enum value of 'this' represent into axis_array
|
||||
inline void axis_transformation::populate_axis_array(INDIVIDUAL_AXIS axis_array[]) const {
|
||||
bool bit5 = (atr_ & 32) != 0;
|
||||
bool bit4 = (atr_ & 16) != 0;
|
||||
bool bit3 = (atr_ & 8) != 0;
|
||||
bool bit2 = (atr_ & 4) != 0;
|
||||
bool bit1 = (atr_ & 2) != 0;
|
||||
bool bit0 = (atr_ & 1) != 0;
|
||||
axis_array[2] =
|
||||
(INDIVIDUAL_AXIS)((((int)(!bit4 & !bit5)) << 2) +
|
||||
((int)(bit5) << 1) +
|
||||
bit3);
|
||||
axis_array[1] =
|
||||
(INDIVIDUAL_AXIS)((((int)((bit4 & bit2) | (bit5 & !bit2))) << 2)+
|
||||
((int)(!bit5 & !bit2) << 1) +
|
||||
bit1);
|
||||
axis_array[0] =
|
||||
(INDIVIDUAL_AXIS)((((int)((bit5 & bit2) | (bit4 & !bit2))) << 2) +
|
||||
((int)(bit2 & !bit5) << 1) +
|
||||
bit0);
|
||||
}
|
||||
|
||||
// combine_axis_arrays concatenates this_array and that_array overwriting
|
||||
// the result into this_array
|
||||
inline void
|
||||
axis_transformation::combine_axis_arrays (INDIVIDUAL_AXIS this_array[],
|
||||
const INDIVIDUAL_AXIS that_array[]){
|
||||
int indexes[3] = {this_array[0] >> 1,
|
||||
this_array[1] >> 1,
|
||||
this_array[2] >> 1};
|
||||
int zero_bits[2][3] = {
|
||||
{this_array[0] & 1, this_array[1] & 1, this_array[2] & 1},
|
||||
{that_array[0] & 1, that_array[1] & 1, that_array[2] & 1}
|
||||
};
|
||||
this_array[0] = that_array[indexes[0]];
|
||||
this_array[0] = (INDIVIDUAL_AXIS)((int)this_array[0] & (int)((int)PZ+(int)PY));
|
||||
this_array[0] = (INDIVIDUAL_AXIS)((int)this_array[0] |
|
||||
((int)zero_bits[0][0] ^
|
||||
(int)zero_bits[1][indexes[0]]));
|
||||
this_array[1] = that_array[indexes[1]];
|
||||
this_array[1] = (INDIVIDUAL_AXIS)((int)this_array[1] & (int)((int)PZ+(int)PY));
|
||||
this_array[1] = (INDIVIDUAL_AXIS)((int)this_array[1] |
|
||||
((int)zero_bits[0][1] ^
|
||||
(int)zero_bits[1][indexes[1]]));
|
||||
this_array[2] = that_array[indexes[2]];
|
||||
this_array[2] = (INDIVIDUAL_AXIS)((int)this_array[2] & (int)((int)PZ+(int)PY));
|
||||
this_array[2] = (INDIVIDUAL_AXIS)((int)this_array[2] |
|
||||
((int)zero_bits[0][2] ^
|
||||
(int)zero_bits[1][indexes[2]]));
|
||||
}
|
||||
|
||||
// write_back_axis_array converts an array of three INDIVIDUAL_AXIS values
|
||||
// to the ATR enum value and sets 'this' to that value
|
||||
inline void axis_transformation::write_back_axis_array(const INDIVIDUAL_AXIS this_array[]) {
|
||||
int bit5 = ((int)this_array[2] & 2) != 0;
|
||||
int bit4 = !((((int)this_array[2] & 4) != 0) | (((int)this_array[2] & 2) != 0));
|
||||
int bit3 = ((int)this_array[2] & 1) != 0;
|
||||
//bit 2 is the tricky bit
|
||||
int bit2 = ((!(bit5 | bit4)) & (((int)this_array[0] & 2) != 0)) | //swap xy
|
||||
(bit5 & (((int)this_array[0] & 4) >> 2)) | //z->y x->z
|
||||
(bit4 & (((int)this_array[1] & 4) >> 2)); //z->x y->z
|
||||
int bit1 = ((int)this_array[1] & 1);
|
||||
int bit0 = ((int)this_array[0] & 1);
|
||||
atr_ = ATR((bit5 << 5) +
|
||||
(bit4 << 4) +
|
||||
(bit3 << 3) +
|
||||
(bit2 << 2) +
|
||||
(bit1 << 1) + bit0);
|
||||
}
|
||||
|
||||
// behavior is deterministic but undefined in the case where illegal
|
||||
// combinations of directions are passed in.
|
||||
inline axis_transformation&
|
||||
axis_transformation::set_directions(const direction_2d& horizontalDir,
|
||||
const direction_2d& verticalDir){
|
||||
int bit2 = (static_cast<orientation_2d>(horizontalDir).to_int()) != 0;
|
||||
int bit1 = !(verticalDir.to_int() & 1);
|
||||
int bit0 = !(horizontalDir.to_int() & 1);
|
||||
atr_ = ATR((bit2 << 2) + (bit1 << 1) + bit0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// behavior is deterministic but undefined in the case where illegal
|
||||
// combinations of directions are passed in.
|
||||
inline axis_transformation& axis_transformation::set_directions(const direction_3d& horizontalDir,
|
||||
const direction_3d& verticalDir,
|
||||
const direction_3d& proximalDir){
|
||||
int this_array[3] = {horizontalDir.to_int(),
|
||||
verticalDir.to_int(),
|
||||
proximalDir.to_int()};
|
||||
int bit5 = (this_array[2] & 2) != 0;
|
||||
int bit4 = !(((this_array[2] & 4) != 0) | ((this_array[2] & 2) != 0));
|
||||
int bit3 = !((this_array[2] & 1) != 0);
|
||||
//bit 2 is the tricky bit
|
||||
int bit2 = (!(bit5 | bit4) & ((this_array[0] & 2) != 0 )) | //swap xy
|
||||
(bit5 & ((this_array[0] & 4) >> 2)) | //z->y x->z
|
||||
(bit4 & ((this_array[1] & 4) >> 2)); //z->x y->z
|
||||
int bit1 = !(this_array[1] & 1);
|
||||
int bit0 = !(this_array[0] & 1);
|
||||
atr_ = ATR((bit5 << 5) +
|
||||
(bit4 << 4) +
|
||||
(bit3 << 3) +
|
||||
(bit2 << 2) +
|
||||
(bit1 << 1) + bit0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename coordinate_type_2>
|
||||
inline void axis_transformation::transform(coordinate_type_2& x, coordinate_type_2& y) const {
|
||||
int bit2 = (atr_ & 4) != 0;
|
||||
int bit1 = (atr_ & 2) != 0;
|
||||
int bit0 = (atr_ & 1) != 0;
|
||||
x *= -((bit0 << 1) - 1);
|
||||
y *= -((bit1 << 1) - 1);
|
||||
predicated_swap(bit2 != 0,x,y);
|
||||
}
|
||||
|
||||
template <typename coordinate_type_2>
|
||||
inline void axis_transformation::transform(coordinate_type_2& x, coordinate_type_2& y, coordinate_type_2& z) const {
|
||||
int bit5 = (atr_ & 32) != 0;
|
||||
int bit4 = (atr_ & 16) != 0;
|
||||
int bit3 = (atr_ & 8) != 0;
|
||||
int bit2 = (atr_ & 4) != 0;
|
||||
int bit1 = (atr_ & 2) != 0;
|
||||
int bit0 = (atr_ & 1) != 0;
|
||||
x *= -((bit0 << 1) - 1);
|
||||
y *= -((bit1 << 1) - 1);
|
||||
z *= -((bit3 << 1) - 1);
|
||||
predicated_swap(bit2 != 0, x, y);
|
||||
predicated_swap(bit5 != 0, y, z);
|
||||
predicated_swap(bit4 != 0, x, z);
|
||||
}
|
||||
|
||||
inline axis_transformation& axis_transformation::invert_2d() {
|
||||
int bit2 = ((atr_ & 4) != 0);
|
||||
int bit1 = ((atr_ & 2) != 0);
|
||||
int bit0 = ((atr_ & 1) != 0);
|
||||
//swap bit 0 and bit 1 if bit2 is 1
|
||||
predicated_swap(bit2 != 0, bit0, bit1);
|
||||
bit1 = bit1 << 1;
|
||||
atr_ = (ATR)(atr_ & (32+16+8+4)); //mask away bit0 and bit1
|
||||
atr_ = (ATR)(atr_ | bit0 | bit1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline axis_transformation axis_transformation::inverse_2d() const {
|
||||
axis_transformation retval(*this);
|
||||
return retval.invert_2d();
|
||||
}
|
||||
|
||||
inline axis_transformation& axis_transformation::invert() {
|
||||
int bit5 = ((atr_ & 32) != 0);
|
||||
int bit4 = ((atr_ & 16) != 0);
|
||||
int bit3 = ((atr_ & 8) != 0);
|
||||
int bit2 = ((atr_ & 4) != 0);
|
||||
int bit1 = ((atr_ & 2) != 0);
|
||||
int bit0 = ((atr_ & 1) != 0);
|
||||
predicated_swap(bit2 != 0, bit4, bit5);
|
||||
predicated_swap(bit4 != 0, bit0, bit3);
|
||||
predicated_swap(bit5 != 0, bit1, bit3);
|
||||
predicated_swap(bit2 != 0, bit0, bit1);
|
||||
atr_ = (ATR)((bit5 << 5) +
|
||||
(bit4 << 4) +
|
||||
(bit3 << 3) +
|
||||
(bit2 << 2) +
|
||||
(bit1 << 1) + bit0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline axis_transformation axis_transformation::inverse() const {
|
||||
axis_transformation retval(*this);
|
||||
return retval.invert();
|
||||
}
|
||||
|
||||
template <typename scale_factor_type>
|
||||
inline scale_factor_type anisotropic_scale_factor<scale_factor_type>::get(orientation_3d orient) const {
|
||||
return scale_[orient.to_int()];
|
||||
}
|
||||
|
||||
template <typename scale_factor_type>
|
||||
inline void anisotropic_scale_factor<scale_factor_type>::set(orientation_3d orient, scale_factor_type value) {
|
||||
scale_[orient.to_int()] = value;
|
||||
}
|
||||
|
||||
template <typename scale_factor_type>
|
||||
inline scale_factor_type anisotropic_scale_factor<scale_factor_type>::x() const { return scale_[HORIZONTAL]; }
|
||||
template <typename scale_factor_type>
|
||||
inline scale_factor_type anisotropic_scale_factor<scale_factor_type>::y() const { return scale_[VERTICAL]; }
|
||||
template <typename scale_factor_type>
|
||||
inline scale_factor_type anisotropic_scale_factor<scale_factor_type>::z() const { return scale_[PROXIMAL]; }
|
||||
template <typename scale_factor_type>
|
||||
inline void anisotropic_scale_factor<scale_factor_type>::x(scale_factor_type value) { scale_[HORIZONTAL] = value; }
|
||||
template <typename scale_factor_type>
|
||||
inline void anisotropic_scale_factor<scale_factor_type>::y(scale_factor_type value) { scale_[VERTICAL] = value; }
|
||||
template <typename scale_factor_type>
|
||||
inline void anisotropic_scale_factor<scale_factor_type>::z(scale_factor_type value) { scale_[PROXIMAL] = value; }
|
||||
|
||||
//concatenation operator (convolve scale factors)
|
||||
template <typename scale_factor_type>
|
||||
inline anisotropic_scale_factor<scale_factor_type> anisotropic_scale_factor<scale_factor_type>::operator+(const anisotropic_scale_factor<scale_factor_type>& s) const {
|
||||
anisotropic_scale_factor<scale_factor_type> retval(*this);
|
||||
return retval+=s;
|
||||
}
|
||||
|
||||
//concatenate this with that
|
||||
template <typename scale_factor_type>
|
||||
inline const anisotropic_scale_factor<scale_factor_type>& anisotropic_scale_factor<scale_factor_type>::operator+=(const anisotropic_scale_factor<scale_factor_type>& s){
|
||||
scale_[0] *= s.scale_[0];
|
||||
scale_[1] *= s.scale_[1];
|
||||
scale_[2] *= s.scale_[2];
|
||||
return *this;
|
||||
}
|
||||
|
||||
//transform
|
||||
template <typename scale_factor_type>
|
||||
inline anisotropic_scale_factor<scale_factor_type>& anisotropic_scale_factor<scale_factor_type>::transform(axis_transformation atr){
|
||||
direction_3d dirs[3];
|
||||
atr.get_directions(dirs[0],dirs[1],dirs[2]);
|
||||
scale_factor_type tmp[3] = {scale_[0], scale_[1], scale_[2]};
|
||||
for(int i = 0; i < 3; ++i){
|
||||
scale_[orientation_3d(dirs[i]).to_int()] = tmp[i];
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename scale_factor_type>
|
||||
template <typename coordinate_type_2>
|
||||
inline void anisotropic_scale_factor<scale_factor_type>::scale(coordinate_type_2& x, coordinate_type_2& y) const {
|
||||
x = scaling_policy<coordinate_type_2>::round((scale_factor_type)x * get(HORIZONTAL));
|
||||
y = scaling_policy<coordinate_type_2>::round((scale_factor_type)y * get(HORIZONTAL));
|
||||
}
|
||||
|
||||
template <typename scale_factor_type>
|
||||
template <typename coordinate_type_2>
|
||||
inline void anisotropic_scale_factor<scale_factor_type>::scale(coordinate_type_2& x, coordinate_type_2& y, coordinate_type_2& z) const {
|
||||
scale(x, y);
|
||||
z = scaling_policy<coordinate_type_2>::round((scale_factor_type)z * get(HORIZONTAL));
|
||||
}
|
||||
|
||||
template <typename scale_factor_type>
|
||||
inline anisotropic_scale_factor<scale_factor_type>& anisotropic_scale_factor<scale_factor_type>::invert() {
|
||||
x(1/x());
|
||||
y(1/y());
|
||||
z(1/z());
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
template <typename coordinate_type>
|
||||
inline transformation<coordinate_type>::transformation() : atr_(), p_(0, 0, 0) {;}
|
||||
|
||||
template <typename coordinate_type>
|
||||
inline transformation<coordinate_type>::transformation(axis_transformation atr) : atr_(atr), p_(0, 0, 0){;}
|
||||
|
||||
template <typename coordinate_type>
|
||||
inline transformation<coordinate_type>::transformation(axis_transformation::ATR atr) : atr_(atr), p_(0, 0, 0){;}
|
||||
|
||||
template <typename coordinate_type>
|
||||
template <typename point_type>
|
||||
inline transformation<coordinate_type>::transformation(const point_type& p) : atr_(), p_(0, 0, 0) {
|
||||
set_translation(p);
|
||||
}
|
||||
|
||||
template <typename coordinate_type>
|
||||
template <typename point_type>
|
||||
inline transformation<coordinate_type>::transformation(axis_transformation atr, const point_type& p) :
|
||||
atr_(atr), p_(0, 0, 0) {
|
||||
set_translation(p);
|
||||
}
|
||||
|
||||
template <typename coordinate_type>
|
||||
template <typename point_type>
|
||||
inline transformation<coordinate_type>::transformation(axis_transformation atr, const point_type& referencePt, const point_type& destinationPt) : atr_(), p_(0, 0, 0) {
|
||||
transformation<coordinate_type> tmp(referencePt);
|
||||
transformation<coordinate_type> rotRef(atr);
|
||||
transformation<coordinate_type> tmpInverse = tmp.inverse();
|
||||
point_type decon(referencePt);
|
||||
deconvolve(decon, destinationPt);
|
||||
transformation<coordinate_type> displacement(decon);
|
||||
tmp += rotRef;
|
||||
tmp += tmpInverse;
|
||||
tmp += displacement;
|
||||
(*this) = tmp;
|
||||
}
|
||||
|
||||
template <typename coordinate_type>
|
||||
inline transformation<coordinate_type>::transformation(const transformation<coordinate_type>& tr) :
|
||||
atr_(tr.atr_), p_(tr.p_) {;}
|
||||
|
||||
template <typename coordinate_type>
|
||||
inline bool transformation<coordinate_type>::operator==(const transformation<coordinate_type>& tr) const {
|
||||
return atr_ == tr.atr_ && p_ == tr.p_;
|
||||
}
|
||||
|
||||
template <typename coordinate_type>
|
||||
inline bool transformation<coordinate_type>::operator!=(const transformation<coordinate_type>& tr) const {
|
||||
return !(*this == tr);
|
||||
}
|
||||
|
||||
template <typename coordinate_type>
|
||||
inline bool transformation<coordinate_type>::operator<(const transformation<coordinate_type>& tr) const {
|
||||
return atr_ < tr.atr_ || atr_ == tr.atr_ && p_ < tr.p_;
|
||||
}
|
||||
|
||||
template <typename coordinate_type>
|
||||
inline transformation<coordinate_type> transformation<coordinate_type>::operator+(const transformation<coordinate_type>& tr) const {
|
||||
transformation<coordinate_type> retval(*this);
|
||||
return retval+=tr;
|
||||
}
|
||||
|
||||
template <typename coordinate_type>
|
||||
inline const transformation<coordinate_type>& transformation<coordinate_type>::operator+=(const transformation<coordinate_type>& tr){
|
||||
//apply the inverse transformation of this to the translation point of that
|
||||
//and convolve it with this translation point
|
||||
coordinate_type x, y, z;
|
||||
transformation<coordinate_type> inv = inverse();
|
||||
inv.transform(x, y, z);
|
||||
p_.set(HORIZONTAL, p_.get(HORIZONTAL) + x);
|
||||
p_.set(VERTICAL, p_.get(VERTICAL) + y);
|
||||
p_.set(PROXIMAL, p_.get(PROXIMAL) + z);
|
||||
//concatenate axis transforms
|
||||
atr_ += tr.atr_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename coordinate_type>
|
||||
inline void transformation<coordinate_type>::set_axis_transformation(const axis_transformation& atr) {
|
||||
atr_ = atr;
|
||||
}
|
||||
|
||||
template <typename coordinate_type>
|
||||
template <typename point_type>
|
||||
inline void transformation<coordinate_type>::get_translation(point_type& p) const {
|
||||
assign(p, p_);
|
||||
}
|
||||
|
||||
template <typename coordinate_type>
|
||||
template <typename point_type>
|
||||
inline void transformation<coordinate_type>::set_translation(const point_type& p) {
|
||||
assign(p_, p);
|
||||
}
|
||||
|
||||
template <typename coordinate_type>
|
||||
inline void transformation<coordinate_type>::transform(coordinate_type& x, coordinate_type& y) const {
|
||||
//subtract each component of new origin point
|
||||
y -= p_.get(VERTICAL);
|
||||
x -= p_.get(HORIZONTAL);
|
||||
atr_.transform(x, y);
|
||||
}
|
||||
|
||||
template <typename coordinate_type>
|
||||
inline void transformation<coordinate_type>::transform(coordinate_type& x, coordinate_type& y, coordinate_type& z) const {
|
||||
//subtract each component of new origin point
|
||||
z -= p_.get(PROXIMAL);
|
||||
y -= p_.get(VERTICAL);
|
||||
x -= p_.get(HORIZONTAL);
|
||||
atr_.transform(x,y,z);
|
||||
}
|
||||
|
||||
// sets the axis_transform portion to its inverse
|
||||
// transforms the tranlastion portion by that inverse axis_transform
|
||||
// multiplies the translation portion by -1 to reverse it
|
||||
template <typename coordinate_type>
|
||||
inline transformation<coordinate_type>& transformation<coordinate_type>::invert() {
|
||||
coordinate_type x = p_.get(HORIZONTAL), y = p_.get(VERTICAL), z = p_.get(PROXIMAL);
|
||||
atr_.transform(x, y, z);
|
||||
x *= -1;
|
||||
y *= -1;
|
||||
z *= -1;
|
||||
p_ = point_3d_data<coordinate_type>(x, y, z);
|
||||
atr_.invert();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename coordinate_type>
|
||||
inline transformation<coordinate_type> transformation<coordinate_type>::inverse() const {
|
||||
transformation<coordinate_type> retval(*this);
|
||||
return retval.invert();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
Copyright 2008 Intel Corporation
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
*/
|
||||
#ifndef BOOST_POLYGON_GMP_OVERRIDE_HPP
|
||||
#define BOOST_POLYGON_GMP_OVERRIDE_HPP
|
||||
#include <gmpxx.h>
|
||||
namespace boost { namespace polygon {
|
||||
|
||||
class gmp_int {
|
||||
private:
|
||||
inline gmp_int(const mpq_class& input) : v_(input) {}
|
||||
public:
|
||||
inline gmp_int() {}
|
||||
explicit inline gmp_int(long input) : v_(input) {}
|
||||
inline gmp_int(const gmp_int& input) : v_(input.v_) {}
|
||||
inline gmp_int& operator=(const gmp_int& that) {
|
||||
v_ = that.v_;
|
||||
return (*this);
|
||||
}
|
||||
inline gmp_int& operator=(long that) {
|
||||
v_ = that;
|
||||
return (*this);
|
||||
}
|
||||
inline operator int() const {
|
||||
std::cout << "cast\n";
|
||||
mpz_class num = v_.get_num();
|
||||
mpz_class den = v_.get_den();
|
||||
num /= den;
|
||||
return num.get_si();
|
||||
}
|
||||
inline double get_d() const {
|
||||
return v_.get_d();
|
||||
}
|
||||
inline int get_num() const {
|
||||
return v_.get_num().get_si();
|
||||
}
|
||||
inline int get_den() const {
|
||||
return v_.get_den().get_si();
|
||||
}
|
||||
inline bool operator==(const gmp_int& that) const {
|
||||
return v_ == that.v_;
|
||||
}
|
||||
inline bool operator!=(const gmp_int& that) const {
|
||||
return v_ != that.v_;
|
||||
}
|
||||
inline bool operator<(const gmp_int& that) const {
|
||||
bool retval = v_ < that.v_;
|
||||
return retval;
|
||||
}
|
||||
inline bool operator<=(const gmp_int& that) const {
|
||||
return v_ <= that.v_;
|
||||
}
|
||||
inline bool operator>(const gmp_int& that) const {
|
||||
return v_ > that.v_;
|
||||
}
|
||||
inline bool operator>=(const gmp_int& that) const {
|
||||
return v_ >= that.v_;
|
||||
}
|
||||
inline gmp_int operator+(const gmp_int& b) {
|
||||
return gmp_int((*this).v_ + b.v_);
|
||||
}
|
||||
inline gmp_int operator-(const gmp_int& b) {
|
||||
return gmp_int((*this).v_ - b.v_);
|
||||
}
|
||||
inline gmp_int operator*(const gmp_int& b) {
|
||||
return gmp_int((*this).v_ * b.v_);
|
||||
}
|
||||
inline gmp_int operator/(const gmp_int& b) {
|
||||
return gmp_int((*this).v_ / b.v_);
|
||||
}
|
||||
inline gmp_int& operator+=(const gmp_int& b) {
|
||||
(*this).v_ += b.v_;
|
||||
return (*this);
|
||||
}
|
||||
inline gmp_int& operator-=(const gmp_int& b) {
|
||||
(*this).v_ -= b.v_;
|
||||
return (*this);
|
||||
}
|
||||
inline gmp_int& operator*=(const gmp_int& b) {
|
||||
(*this).v_ *= b.v_;
|
||||
return (*this);
|
||||
}
|
||||
inline gmp_int& operator/=(const gmp_int& b) {
|
||||
(*this).v_ /= b.v_;
|
||||
return (*this);
|
||||
}
|
||||
inline gmp_int& operator++() {
|
||||
++v_;
|
||||
return (*this);
|
||||
}
|
||||
inline gmp_int& operator--() {
|
||||
--v_;
|
||||
return (*this);
|
||||
}
|
||||
inline gmp_int operator++(int) {
|
||||
gmp_int retval(*this);
|
||||
++(*this);
|
||||
return retval;
|
||||
}
|
||||
inline gmp_int operator--(int) {
|
||||
gmp_int retval(*this);
|
||||
--(*this);
|
||||
return retval;
|
||||
}
|
||||
private:
|
||||
mpq_class v_;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct high_precision_type<int> {
|
||||
typedef mpq_class type;
|
||||
};
|
||||
|
||||
template <>
|
||||
int convert_high_precision_type<int>(const mpq_class& v) {
|
||||
mpz_class num = v.get_num();
|
||||
mpz_class den = v.get_den();
|
||||
num /= den;
|
||||
return num.get_si();
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,592 @@
|
|||
/*
|
||||
Copyright 2008 Intel Corporation
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
*/
|
||||
#ifndef BOOST_POLYGON_INTERVAL_CONCEPT_HPP
|
||||
#define BOOST_POLYGON_INTERVAL_CONCEPT_HPP
|
||||
#include "isotropy.hpp"
|
||||
#include "interval_data.hpp"
|
||||
#include "interval_traits.hpp"
|
||||
|
||||
namespace boost { namespace polygon{
|
||||
struct interval_concept {};
|
||||
|
||||
template <typename T>
|
||||
struct is_interval_concept { typedef gtl_no type; };
|
||||
template <>
|
||||
struct is_interval_concept<interval_concept> { typedef gtl_yes type; };
|
||||
|
||||
template <typename T>
|
||||
struct is_mutable_interval_concept { typedef gtl_no type; };
|
||||
template <>
|
||||
struct is_mutable_interval_concept<interval_concept> { typedef gtl_yes type; };
|
||||
|
||||
template <typename T, typename CT>
|
||||
struct interval_coordinate_type_by_concept { typedef void type; };
|
||||
template <typename T>
|
||||
struct interval_coordinate_type_by_concept<T, gtl_yes> { typedef typename interval_traits<T>::coordinate_type type; };
|
||||
|
||||
template <typename T>
|
||||
struct interval_coordinate_type {
|
||||
typedef typename interval_coordinate_type_by_concept<
|
||||
T, typename is_interval_concept<typename geometry_concept<T>::type>::type>::type type;
|
||||
};
|
||||
|
||||
template <typename T, typename CT>
|
||||
struct interval_difference_type_by_concept { typedef void type; };
|
||||
template <typename T>
|
||||
struct interval_difference_type_by_concept<T, gtl_yes> {
|
||||
typedef typename coordinate_traits<typename interval_traits<T>::coordinate_type>::coordinate_difference type; };
|
||||
|
||||
template <typename T>
|
||||
struct interval_difference_type {
|
||||
typedef typename interval_difference_type_by_concept<
|
||||
T, typename is_interval_concept<typename geometry_concept<T>::type>::type>::type type;
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
typename interval_coordinate_type<T>::type
|
||||
get(const T& interval, direction_1d dir,
|
||||
typename enable_if<typename gtl_if<typename is_interval_concept<typename geometry_concept<T>::type>::type>::type>::type * = 0
|
||||
) {
|
||||
return interval_traits<T>::get(interval, dir);
|
||||
}
|
||||
|
||||
template <typename T, typename coordinate_type>
|
||||
void
|
||||
set(T& interval, direction_1d dir, coordinate_type value,
|
||||
typename enable_if<typename is_mutable_interval_concept<typename geometry_concept<T>::type>::type>::type * = 0
|
||||
) {
|
||||
//this may need to be refined
|
||||
interval_mutable_traits<T>::set(interval, dir, value);
|
||||
if(high(interval) < low(interval))
|
||||
interval_mutable_traits<T>::set(interval, dir.backward(), value);
|
||||
}
|
||||
|
||||
template <typename T, typename T2, typename T3>
|
||||
T
|
||||
construct(T2 low_value, T3 high_value,
|
||||
typename enable_if<typename is_mutable_interval_concept<typename geometry_concept<T>::type>::type>::type * = 0
|
||||
) {
|
||||
if(low_value > high_value) std::swap(low_value, high_value);
|
||||
return interval_mutable_traits<T>::construct(low_value, high_value);
|
||||
}
|
||||
|
||||
template <typename T, typename T2>
|
||||
T
|
||||
copy_construct(const T2& interval,
|
||||
typename enable_if< typename gtl_and<typename is_mutable_interval_concept<typename geometry_concept<T>::type>::type,
|
||||
typename is_interval_concept<typename geometry_concept<T2>::type>::type>::type>::type * = 0
|
||||
) {
|
||||
return construct<T>
|
||||
(get(interval, LOW ),
|
||||
get(interval, HIGH));
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
T1 &
|
||||
assign(T1& lvalue, const T2& rvalue,
|
||||
typename enable_if< typename gtl_and< typename is_mutable_interval_concept<typename geometry_concept<T1>::type>::type,
|
||||
typename is_interval_concept<typename geometry_concept<T2>::type>::type>::type>::type * = 0) {
|
||||
lvalue = copy_construct<T1>(rvalue);
|
||||
return lvalue;
|
||||
}
|
||||
|
||||
template <typename T, typename T2>
|
||||
bool
|
||||
equivalence(const T& interval1, const T2& interval2,
|
||||
typename enable_if< typename gtl_and< typename is_interval_concept<typename geometry_concept<T>::type>::type,
|
||||
typename is_interval_concept<typename geometry_concept<T2>::type>::type>::type>::type * = 0
|
||||
) {
|
||||
return get(interval1, LOW) ==
|
||||
get(interval2, LOW) &&
|
||||
get(interval1, HIGH) ==
|
||||
get(interval2, HIGH);
|
||||
}
|
||||
|
||||
struct y_i_contains : gtl_yes {};
|
||||
|
||||
template <typename interval_type>
|
||||
typename enable_if< typename gtl_and< y_i_contains, typename is_interval_concept<typename geometry_concept<interval_type>::type>::type >::type, bool>::type
|
||||
contains(const interval_type& interval,
|
||||
typename interval_traits<interval_type>::coordinate_type value,
|
||||
bool consider_touch = true ) {
|
||||
if(consider_touch) {
|
||||
return value <= high(interval) && value >= low(interval);
|
||||
} else {
|
||||
return value < high(interval) && value > low(interval);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename interval_type, typename interval_type_2>
|
||||
bool
|
||||
contains(const interval_type& interval,
|
||||
const interval_type_2& value, bool consider_touch = true,
|
||||
typename enable_if< typename gtl_and< typename is_interval_concept<typename geometry_concept<interval_type>::type>::type,
|
||||
typename is_interval_concept<typename geometry_concept<interval_type_2>::type>::type>::type>::type * = 0
|
||||
) {
|
||||
return contains(interval, get(value, LOW), consider_touch) &&
|
||||
contains(interval, get(value, HIGH), consider_touch);
|
||||
}
|
||||
|
||||
// get the low coordinate
|
||||
template <typename interval_type>
|
||||
typename interval_traits<interval_type>::coordinate_type
|
||||
low(const interval_type& interval,
|
||||
typename enable_if< typename is_interval_concept<typename geometry_concept<interval_type>::type>::type>::type * = 0
|
||||
) { return get(interval, LOW); }
|
||||
|
||||
// get the high coordinate
|
||||
template <typename interval_type>
|
||||
typename interval_traits<interval_type>::coordinate_type
|
||||
high(const interval_type& interval,
|
||||
typename enable_if< typename is_interval_concept<typename geometry_concept<interval_type>::type>::type>::type * = 0
|
||||
) { return get(interval, HIGH); }
|
||||
|
||||
// get the center coordinate
|
||||
template <typename interval_type>
|
||||
typename interval_traits<interval_type>::coordinate_type
|
||||
center(const interval_type& interval,
|
||||
typename enable_if< typename is_interval_concept<typename geometry_concept<interval_type>::type>::type>::type * = 0
|
||||
) { return (high(interval) + low(interval))/2; }
|
||||
|
||||
|
||||
struct y_i_low : gtl_yes {};
|
||||
|
||||
// set the low coordinate to v
|
||||
template <typename interval_type>
|
||||
typename enable_if<typename gtl_and<y_i_low, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type, void>::type
|
||||
low(interval_type& interval,
|
||||
typename interval_traits<interval_type>::coordinate_type v) { set(interval, LOW, v); }
|
||||
|
||||
struct y_i_high : gtl_yes {};
|
||||
|
||||
// set the high coordinate to v
|
||||
template <typename interval_type>
|
||||
typename enable_if<typename gtl_and<y_i_high, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type, void>::type
|
||||
high(interval_type& interval,
|
||||
typename interval_traits<interval_type>::coordinate_type v) { set(interval, HIGH, v); }
|
||||
|
||||
// get the magnitude of the interval
|
||||
template <typename interval_type>
|
||||
typename interval_difference_type<interval_type>::type
|
||||
delta(const interval_type& interval,
|
||||
typename enable_if< typename is_interval_concept<typename geometry_concept<interval_type>::type>::type>::type * = 0
|
||||
) {
|
||||
typedef typename coordinate_traits<typename interval_traits<interval_type>::coordinate_type>::coordinate_difference diffT;
|
||||
return (diffT)high(interval) - (diffT)low(interval); }
|
||||
|
||||
struct y_i_flip : gtl_yes {};
|
||||
|
||||
// flip this about coordinate
|
||||
template <typename interval_type>
|
||||
typename enable_if<typename gtl_and<y_i_flip, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type, interval_type>::type &
|
||||
flip(interval_type& interval,
|
||||
typename interval_traits<interval_type>::coordinate_type axis = 0) {
|
||||
typename interval_traits<interval_type>::coordinate_type newLow, newHigh;
|
||||
newLow = 2 * axis - high(interval);
|
||||
newHigh = 2 * axis - low(interval);
|
||||
low(interval, newLow);
|
||||
high(interval, newHigh);
|
||||
return interval;
|
||||
}
|
||||
|
||||
struct y_i_scale_up : gtl_yes {};
|
||||
|
||||
// scale interval by factor
|
||||
template <typename interval_type>
|
||||
typename enable_if<typename gtl_and<y_i_scale_up, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type, interval_type>::type &
|
||||
scale_up(interval_type& interval,
|
||||
typename coordinate_traits<typename interval_traits<interval_type>::coordinate_type>::unsigned_area_type factor) {
|
||||
typedef typename interval_traits<interval_type>::coordinate_type Unit;
|
||||
Unit newHigh = high(interval) * (Unit)factor;
|
||||
low(interval, low(interval) * (Unit)factor);
|
||||
high(interval, (newHigh));
|
||||
return interval;
|
||||
}
|
||||
|
||||
struct y_i_scale_down : gtl_yes {};
|
||||
|
||||
template <typename interval_type>
|
||||
typename enable_if<typename gtl_and<y_i_scale_down, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type, interval_type>::type &
|
||||
scale_down(interval_type& interval,
|
||||
typename coordinate_traits<typename interval_traits<interval_type>::coordinate_type>::unsigned_area_type factor) {
|
||||
typedef typename interval_traits<interval_type>::coordinate_type Unit;
|
||||
typedef typename coordinate_traits<Unit>::coordinate_distance dt;
|
||||
Unit newHigh = scaling_policy<Unit>::round((dt)(high(interval)) / (dt)factor);
|
||||
low(interval, scaling_policy<Unit>::round((dt)(low(interval)) / (dt)factor));
|
||||
high(interval, (newHigh));
|
||||
return interval;
|
||||
}
|
||||
|
||||
struct y_i_scale : gtl_yes {};
|
||||
|
||||
template <typename interval_type>
|
||||
typename enable_if<typename gtl_and<y_i_scale, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type, interval_type>::type &
|
||||
scale(interval_type& interval, double factor) {
|
||||
typedef typename interval_traits<interval_type>::coordinate_type Unit;
|
||||
Unit newHigh = scaling_policy<Unit>::round((double)(high(interval)) * factor);
|
||||
low(interval, scaling_policy<Unit>::round((double)low(interval)* factor));
|
||||
high(interval, (newHigh));
|
||||
return interval;
|
||||
}
|
||||
|
||||
// move interval by delta
|
||||
template <typename interval_type>
|
||||
interval_type&
|
||||
move(interval_type& interval,
|
||||
typename interval_difference_type<interval_type>::type displacement,
|
||||
typename enable_if<typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type * = 0
|
||||
) {
|
||||
typedef typename interval_traits<interval_type>::coordinate_type ctype;
|
||||
typedef typename coordinate_traits<ctype>::coordinate_difference Unit;
|
||||
Unit len = delta(interval);
|
||||
low(interval, static_cast<ctype>(static_cast<Unit>(low(interval)) + displacement));
|
||||
high(interval, static_cast<ctype>(static_cast<Unit>(low(interval)) + len));
|
||||
return interval;
|
||||
}
|
||||
|
||||
struct y_i_convolve : gtl_yes {};
|
||||
|
||||
// convolve this with b
|
||||
template <typename interval_type>
|
||||
typename enable_if<typename gtl_and<y_i_convolve, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type, interval_type>::type &
|
||||
convolve(interval_type& interval,
|
||||
typename interval_traits<interval_type>::coordinate_type b) {
|
||||
typedef typename interval_traits<interval_type>::coordinate_type Unit;
|
||||
Unit newLow = low(interval) + b;
|
||||
Unit newHigh = high(interval) + b;
|
||||
low(interval, newLow);
|
||||
high(interval, newHigh);
|
||||
return interval;
|
||||
}
|
||||
|
||||
struct y_i_deconvolve : gtl_yes {};
|
||||
|
||||
// deconvolve this with b
|
||||
template <typename interval_type>
|
||||
typename enable_if<typename gtl_and<y_i_deconvolve, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type, interval_type>::type &
|
||||
deconvolve(interval_type& interval,
|
||||
typename interval_traits<interval_type>::coordinate_type b) {
|
||||
typedef typename interval_traits<interval_type>::coordinate_type Unit;
|
||||
Unit newLow = low(interval) - b;
|
||||
Unit newHigh = high(interval) - b;
|
||||
low(interval, newLow);
|
||||
high(interval, newHigh);
|
||||
return interval;
|
||||
}
|
||||
|
||||
struct y_i_convolve2 : gtl_yes {};
|
||||
|
||||
// convolve this with b
|
||||
template <typename interval_type, typename interval_type_2>
|
||||
typename enable_if<
|
||||
typename gtl_and_3<y_i_convolve2,
|
||||
typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type,
|
||||
typename is_interval_concept<typename geometry_concept<interval_type_2>::type>::type>::type,
|
||||
interval_type>::type &
|
||||
convolve(interval_type& interval,
|
||||
const interval_type_2& b) {
|
||||
typedef typename interval_traits<interval_type>::coordinate_type Unit;
|
||||
Unit newLow = low(interval) + low(b);
|
||||
Unit newHigh = high(interval) + high(b);
|
||||
low(interval, newLow);
|
||||
high(interval, newHigh);
|
||||
return interval;
|
||||
}
|
||||
|
||||
struct y_i_deconvolve2 : gtl_yes {};
|
||||
|
||||
// deconvolve this with b
|
||||
template <typename interval_type, typename interval_type_2>
|
||||
typename enable_if<
|
||||
typename gtl_and_3< y_i_deconvolve2,
|
||||
typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type,
|
||||
typename is_interval_concept<typename geometry_concept<interval_type_2>::type>::type>::type,
|
||||
interval_type>::type &
|
||||
deconvolve(interval_type& interval,
|
||||
const interval_type_2& b) {
|
||||
typedef typename interval_traits<interval_type>::coordinate_type Unit;
|
||||
Unit newLow = low(interval) - low(b);
|
||||
Unit newHigh = high(interval) - high(b);
|
||||
low(interval, newLow);
|
||||
high(interval, newHigh);
|
||||
return interval;
|
||||
}
|
||||
|
||||
struct y_i_reconvolve : gtl_yes {};
|
||||
|
||||
// reflected convolve this with b
|
||||
template <typename interval_type, typename interval_type_2>
|
||||
typename enable_if<
|
||||
typename gtl_and_3<y_i_reconvolve,
|
||||
typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type,
|
||||
typename is_interval_concept<typename geometry_concept<interval_type_2>::type>::type>::type,
|
||||
interval_type>::type &
|
||||
reflected_convolve(interval_type& interval,
|
||||
const interval_type_2& b) {
|
||||
typedef typename interval_traits<interval_type>::coordinate_type Unit;
|
||||
Unit newLow = low(interval) - high(b);
|
||||
Unit newHigh = high(interval) - low(b);
|
||||
low(interval, newLow);
|
||||
high(interval, newHigh);
|
||||
return interval;
|
||||
}
|
||||
|
||||
struct y_i_redeconvolve : gtl_yes {};
|
||||
|
||||
// reflected deconvolve this with b
|
||||
template <typename interval_type, typename interval_type_2>
|
||||
typename enable_if<
|
||||
typename gtl_and_3< y_i_redeconvolve,
|
||||
typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type,
|
||||
typename is_interval_concept<typename geometry_concept<interval_type_2>::type>::type>::type,
|
||||
interval_type>::type &
|
||||
reflected_deconvolve(interval_type& interval,
|
||||
const interval_type_2& b) {
|
||||
typedef typename interval_traits<interval_type>::coordinate_type Unit;
|
||||
Unit newLow = low(interval) + high(b);
|
||||
Unit newHigh = high(interval) + low(b);
|
||||
low(interval, newLow);
|
||||
high(interval, newHigh);
|
||||
return interval;
|
||||
}
|
||||
|
||||
struct y_i_e_dist1 : gtl_yes {};
|
||||
|
||||
// distance from a coordinate to an interval
|
||||
template <typename interval_type>
|
||||
typename enable_if< typename gtl_and<y_i_e_dist1, typename is_interval_concept<typename geometry_concept<interval_type>::type>::type>::type,
|
||||
typename interval_difference_type<interval_type>::type>::type
|
||||
euclidean_distance(const interval_type& interval,
|
||||
typename interval_traits<interval_type>::coordinate_type position) {
|
||||
typedef typename coordinate_traits<typename interval_traits<interval_type>::coordinate_type>::coordinate_difference Unit;
|
||||
Unit dist[3] = {0, (Unit)low(interval) - (Unit)position, (Unit)position - (Unit)high(interval)};
|
||||
return dist[ (dist[1] > 0) + ((dist[2] > 0) << 1) ];
|
||||
}
|
||||
|
||||
struct y_i_e_dist2 : gtl_yes {};
|
||||
|
||||
// distance between two intervals
|
||||
template <typename interval_type, typename interval_type_2>
|
||||
typename enable_if<
|
||||
typename gtl_and_3<y_i_e_dist2, typename is_interval_concept<typename geometry_concept<interval_type>::type>::type,
|
||||
typename is_interval_concept<typename geometry_concept<interval_type_2>::type>::type>::type,
|
||||
typename interval_difference_type<interval_type>::type>::type
|
||||
euclidean_distance(const interval_type& interval,
|
||||
const interval_type_2& b) {
|
||||
typedef typename coordinate_traits<typename interval_traits<interval_type>::coordinate_type>::coordinate_difference Unit;
|
||||
Unit dist[3] = {0, (Unit)low(interval) - (Unit)high(b), (Unit)low(b) - (Unit)high(interval)};
|
||||
return dist[ (dist[1] > 0) + ((dist[2] > 0) << 1) ];
|
||||
}
|
||||
|
||||
struct y_i_e_intersects : gtl_yes {};
|
||||
|
||||
// check if Interval b intersects `this` Interval
|
||||
template <typename interval_type, typename interval_type_2>
|
||||
typename enable_if<
|
||||
typename gtl_and_3<y_i_e_intersects, typename is_interval_concept<typename geometry_concept<interval_type>::type>::type,
|
||||
typename is_interval_concept<typename geometry_concept<interval_type_2>::type>::type>::type,
|
||||
bool>::type
|
||||
intersects(const interval_type& interval, const interval_type_2& b,
|
||||
bool consider_touch = true) {
|
||||
return consider_touch ?
|
||||
(low(interval) <= high(b)) & (high(interval) >= low(b)) :
|
||||
(low(interval) < high(b)) & (high(interval) > low(b));
|
||||
}
|
||||
|
||||
struct y_i_e_bintersect : gtl_yes {};
|
||||
|
||||
// check if Interval b partially overlaps `this` Interval
|
||||
template <typename interval_type, typename interval_type_2>
|
||||
typename enable_if<
|
||||
typename gtl_and_3<y_i_e_bintersect, typename is_interval_concept<typename geometry_concept<interval_type>::type>::type,
|
||||
typename is_interval_concept<typename geometry_concept<interval_type_2>::type>::type>::type,
|
||||
bool>::type
|
||||
boundaries_intersect(const interval_type& interval, const interval_type_2& b,
|
||||
bool consider_touch = true) {
|
||||
return (contains(interval, low(b), consider_touch) ||
|
||||
contains(interval, high(b), consider_touch)) &&
|
||||
(contains(b, low(interval), consider_touch) ||
|
||||
contains(b, high(interval), consider_touch));
|
||||
}
|
||||
|
||||
struct y_i_abuts1 : gtl_yes {};
|
||||
|
||||
// check if they are end to end
|
||||
template <typename interval_type, typename interval_type_2>
|
||||
typename enable_if< typename gtl_and_3<y_i_abuts1, typename is_interval_concept<typename geometry_concept<interval_type>::type>::type,
|
||||
typename is_interval_concept<typename geometry_concept<interval_type_2>::type>::type>::type,
|
||||
bool>::type
|
||||
abuts(const interval_type& interval, const interval_type_2& b, direction_1d dir) {
|
||||
return dir.to_int() ? low(b) == high(interval) : low(interval) == high(b);
|
||||
}
|
||||
|
||||
struct y_i_abuts2 : gtl_yes {};
|
||||
|
||||
// check if they are end to end
|
||||
template <typename interval_type, typename interval_type_2>
|
||||
typename enable_if<
|
||||
typename gtl_and_3<y_i_abuts2, typename is_interval_concept<typename geometry_concept<interval_type>::type>::type,
|
||||
typename is_interval_concept<typename geometry_concept<interval_type_2>::type>::type>::type,
|
||||
bool>::type
|
||||
abuts(const interval_type& interval, const interval_type_2& b) {
|
||||
return abuts(interval, b, HIGH) || abuts(interval, b, LOW);
|
||||
}
|
||||
|
||||
struct y_i_intersect : gtl_yes {};
|
||||
|
||||
// set 'this' interval to the intersection of 'this' and b
|
||||
template <typename interval_type, typename interval_type_2>
|
||||
typename enable_if< typename gtl_and_3<y_i_intersect, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type,
|
||||
typename is_interval_concept<typename geometry_concept<interval_type_2>::type>::type>::type,
|
||||
bool>::type
|
||||
intersect(interval_type& interval, const interval_type_2& b, bool consider_touch = true) {
|
||||
typedef typename interval_traits<interval_type>::coordinate_type Unit;
|
||||
Unit lowVal = (std::max)(low(interval), low(b));
|
||||
Unit highVal = (std::min)(high(interval), high(b));
|
||||
bool valid = consider_touch ?
|
||||
lowVal <= highVal :
|
||||
lowVal < highVal;
|
||||
if(valid) {
|
||||
low(interval, lowVal);
|
||||
high(interval, highVal);
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
struct y_i_g_intersect : gtl_yes {};
|
||||
|
||||
// set 'this' interval to the generalized intersection of 'this' and b
|
||||
template <typename interval_type, typename interval_type_2>
|
||||
typename enable_if<
|
||||
typename gtl_and_3<y_i_g_intersect, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type,
|
||||
typename is_interval_concept<typename geometry_concept<interval_type_2>::type>::type>::type,
|
||||
interval_type>::type &
|
||||
generalized_intersect(interval_type& interval, const interval_type_2& b) {
|
||||
typedef typename interval_traits<interval_type>::coordinate_type Unit;
|
||||
Unit coords[4] = {low(interval), high(interval), low(b), high(b)};
|
||||
//consider implementing faster sorting of small fixed length range
|
||||
std::sort(coords, coords+4);
|
||||
low(interval, coords[1]);
|
||||
high(interval, coords[2]);
|
||||
return interval;
|
||||
}
|
||||
|
||||
struct y_i_bloat : gtl_yes {};
|
||||
|
||||
// bloat the Interval
|
||||
template <typename interval_type>
|
||||
typename enable_if< typename gtl_and<y_i_bloat, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type,
|
||||
interval_type>::type &
|
||||
bloat(interval_type& interval, typename interval_traits<interval_type>::coordinate_type bloating) {
|
||||
low(interval, low(interval)-bloating);
|
||||
high(interval, high(interval)+bloating);
|
||||
return interval;
|
||||
}
|
||||
|
||||
struct y_i_bloat2 : gtl_yes {};
|
||||
|
||||
// bloat the specified side of `this` Interval
|
||||
template <typename interval_type>
|
||||
typename enable_if< typename gtl_and<y_i_bloat2, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type,
|
||||
interval_type>::type &
|
||||
bloat(interval_type& interval, direction_1d dir, typename interval_traits<interval_type>::coordinate_type bloating) {
|
||||
set(interval, dir, get(interval, dir) + dir.get_sign() * bloating);
|
||||
return interval;
|
||||
}
|
||||
|
||||
struct y_i_shrink : gtl_yes {};
|
||||
|
||||
// shrink the Interval
|
||||
template <typename interval_type>
|
||||
typename enable_if< typename gtl_and<y_i_shrink, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type,
|
||||
interval_type>::type &
|
||||
shrink(interval_type& interval, typename interval_traits<interval_type>::coordinate_type shrinking) {
|
||||
return bloat(interval, -shrinking);
|
||||
}
|
||||
|
||||
struct y_i_shrink2 : gtl_yes {};
|
||||
|
||||
// shrink the specified side of `this` Interval
|
||||
template <typename interval_type>
|
||||
typename enable_if< typename gtl_and<y_i_shrink2, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type,
|
||||
interval_type>::type &
|
||||
shrink(interval_type& interval, direction_1d dir, typename interval_traits<interval_type>::coordinate_type shrinking) {
|
||||
return bloat(interval, dir, -shrinking);
|
||||
}
|
||||
|
||||
// Enlarge `this` Interval to encompass the specified Interval
|
||||
template <typename interval_type, typename interval_type_2>
|
||||
bool
|
||||
encompass(interval_type& interval, const interval_type_2& b,
|
||||
typename enable_if<
|
||||
typename gtl_and< typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type,
|
||||
typename is_interval_concept<typename geometry_concept<interval_type_2>::type>::type>::type>::type * = 0
|
||||
) {
|
||||
bool retval = !contains(interval, b, true);
|
||||
low(interval, (std::min)(low(interval), low(b)));
|
||||
high(interval, (std::max)(high(interval), high(b)));
|
||||
return retval;
|
||||
}
|
||||
|
||||
struct y_i_encompass : gtl_yes {};
|
||||
|
||||
// Enlarge `this` Interval to encompass the specified Interval
|
||||
template <typename interval_type>
|
||||
typename enable_if< typename gtl_and<y_i_encompass, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type,
|
||||
bool>::type
|
||||
encompass(interval_type& interval, typename interval_traits<interval_type>::coordinate_type b) {
|
||||
bool retval = !contains(interval, b, true);
|
||||
low(interval, (std::min)(low(interval), b));
|
||||
high(interval, (std::max)(high(interval), b));
|
||||
return retval;
|
||||
}
|
||||
|
||||
struct y_i_get_half : gtl_yes {};
|
||||
|
||||
// gets the half of the interval as an interval
|
||||
template <typename interval_type>
|
||||
typename enable_if<typename gtl_and<y_i_get_half, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type, interval_type>::type
|
||||
get_half(const interval_type& interval, direction_1d d1d) {
|
||||
typedef typename interval_traits<interval_type>::coordinate_type Unit;
|
||||
Unit c = (get(interval, LOW) + get(interval, HIGH)) / 2;
|
||||
return construct<interval_type>((d1d == LOW) ? get(interval, LOW) : c,
|
||||
(d1d == LOW) ? c : get(interval, HIGH));
|
||||
}
|
||||
|
||||
struct y_i_join_with : gtl_yes {};
|
||||
|
||||
// returns true if the 2 intervals exactly touch at one value, like in l1 <= h1 == l2 <= h2
|
||||
// sets the argument to the joined interval
|
||||
template <typename interval_type, typename interval_type_2>
|
||||
typename enable_if<
|
||||
typename gtl_and_3<y_i_join_with, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type,
|
||||
typename is_interval_concept<typename geometry_concept<interval_type_2>::type>::type>::type,
|
||||
bool>::type
|
||||
join_with(interval_type& interval, const interval_type_2& b) {
|
||||
if(abuts(interval, b)) {
|
||||
encompass(interval, b);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
template <class T2>
|
||||
interval_data<T>& interval_data<T>::operator=(const T2& rvalue) {
|
||||
assign(*this, rvalue);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct geometry_concept<interval_data<T> > {
|
||||
typedef interval_concept type;
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
Copyright 2008 Intel Corporation
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
*/
|
||||
#ifndef BOOST_POLYGON_INTERVAL_DATA_HPP
|
||||
#define BOOST_POLYGON_INTERVAL_DATA_HPP
|
||||
#include "isotropy.hpp"
|
||||
namespace boost { namespace polygon{
|
||||
template <typename T>
|
||||
class interval_data {
|
||||
public:
|
||||
typedef T coordinate_type;
|
||||
inline interval_data()
|
||||
#ifndef BOOST_POLYGON_MSVC
|
||||
:coords_()
|
||||
#endif
|
||||
{}
|
||||
inline interval_data(coordinate_type low, coordinate_type high)
|
||||
#ifndef BOOST_POLYGON_MSVC
|
||||
:coords_()
|
||||
#endif
|
||||
{
|
||||
coords_[LOW] = low; coords_[HIGH] = high;
|
||||
}
|
||||
inline interval_data(const interval_data& that)
|
||||
#ifndef BOOST_POLYGON_MSVC
|
||||
:coords_()
|
||||
#endif
|
||||
{
|
||||
(*this) = that;
|
||||
}
|
||||
inline interval_data& operator=(const interval_data& that) {
|
||||
coords_[0] = that.coords_[0]; coords_[1] = that.coords_[1]; return *this;
|
||||
}
|
||||
template <typename T2>
|
||||
inline interval_data& operator=(const T2& rvalue);
|
||||
inline coordinate_type get(direction_1d dir) const {
|
||||
return coords_[dir.to_int()];
|
||||
}
|
||||
inline coordinate_type low() const { return coords_[0]; }
|
||||
inline coordinate_type high() const { return coords_[1]; }
|
||||
inline bool operator==(const interval_data& that) const {
|
||||
return low() == that.low() && high() == that.high(); }
|
||||
inline bool operator!=(const interval_data& that) const {
|
||||
return low() != that.low() || high() != that.high(); }
|
||||
inline bool operator<(const interval_data& that) const {
|
||||
if(coords_[0] < that.coords_[0]) return true;
|
||||
if(coords_[0] > that.coords_[0]) return false;
|
||||
if(coords_[1] < that.coords_[1]) return true;
|
||||
return false;
|
||||
}
|
||||
inline bool operator<=(const interval_data& that) const { return !(that < *this); }
|
||||
inline bool operator>(const interval_data& that) const { return that < *this; }
|
||||
inline bool operator>=(const interval_data& that) const { return !((*this) < that); }
|
||||
inline void set(direction_1d dir, coordinate_type value) {
|
||||
coords_[dir.to_int()] = value;
|
||||
}
|
||||
private:
|
||||
coordinate_type coords_[2];
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
Copyright 2008 Intel Corporation
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
*/
|
||||
#ifndef BOOST_POLYGON_INTERVAL_TRAITS_HPP
|
||||
#define BOOST_POLYGON_INTERVAL_TRAITS_HPP
|
||||
namespace boost { namespace polygon{
|
||||
template <typename T>
|
||||
struct interval_traits {
|
||||
typedef typename T::coordinate_type coordinate_type;
|
||||
|
||||
static inline coordinate_type get(const T& interval, direction_1d dir) {
|
||||
return interval.get(dir);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct interval_mutable_traits {
|
||||
static inline void set(T& interval, direction_1d dir, typename interval_traits<T>::coordinate_type value) {
|
||||
interval.set(dir, value);
|
||||
}
|
||||
static inline T construct(typename interval_traits<T>::coordinate_type low_value,
|
||||
typename interval_traits<T>::coordinate_type high_value) {
|
||||
return T(low_value, high_value);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,542 @@
|
|||
/*
|
||||
Copyright 2008 Intel Corporation
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
*/
|
||||
|
||||
#ifndef BOOST_POLYGON_ISOTROPY_HPP
|
||||
#define BOOST_POLYGON_ISOTROPY_HPP
|
||||
|
||||
//external
|
||||
#include <cmath>
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <vector>
|
||||
#include <deque>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <list>
|
||||
//#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
|
||||
#ifndef BOOST_POLYGON_NO_DEPS
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#ifdef BOOST_MSVC
|
||||
#define BOOST_POLYGON_MSVC
|
||||
#endif
|
||||
#ifdef BOOST_INTEL
|
||||
#define BOOST_POLYGON_ICC
|
||||
#endif
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
#define BOOST_POLYGON_USE_LONG_LONG
|
||||
typedef boost::long_long_type polygon_long_long_type;
|
||||
typedef boost::ulong_long_type polygon_ulong_long_type;
|
||||
//typedef long long polygon_long_long_type;
|
||||
//typedef unsigned long long polygon_ulong_long_type;
|
||||
#endif
|
||||
#include <boost/mpl/size_t.hpp>
|
||||
#include <boost/mpl/protect.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/mpl/or.hpp>
|
||||
#else
|
||||
|
||||
#ifdef WIN32
|
||||
#define BOOST_POLYGON_MSVC
|
||||
#endif
|
||||
#ifdef __ICC
|
||||
#define BOOST_POLYGON_ICC
|
||||
#endif
|
||||
#define BOOST_POLYGON_USE_LONG_LONG
|
||||
typedef long long polygon_long_long_type;
|
||||
typedef unsigned long long polygon_ulong_long_type;
|
||||
|
||||
namespace boost {
|
||||
template <bool B, class T = void>
|
||||
struct enable_if_c {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct enable_if_c<false, T> {};
|
||||
|
||||
template <class Cond, class T = void>
|
||||
struct enable_if : public enable_if_c<Cond::value, T> {};
|
||||
|
||||
template <bool B, class T>
|
||||
struct lazy_enable_if_c {
|
||||
typedef typename T::type type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct lazy_enable_if_c<false, T> {};
|
||||
|
||||
template <class Cond, class T>
|
||||
struct lazy_enable_if : public lazy_enable_if_c<Cond::value, T> {};
|
||||
|
||||
|
||||
template <bool B, class T = void>
|
||||
struct disable_if_c {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct disable_if_c<true, T> {};
|
||||
|
||||
template <class Cond, class T = void>
|
||||
struct disable_if : public disable_if_c<Cond::value, T> {};
|
||||
|
||||
template <bool B, class T>
|
||||
struct lazy_disable_if_c {
|
||||
typedef typename T::type type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct lazy_disable_if_c<true, T> {};
|
||||
|
||||
template <class Cond, class T>
|
||||
struct lazy_disable_if : public lazy_disable_if_c<Cond::value, T> {};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
namespace boost { namespace polygon{
|
||||
|
||||
enum GEOMETRY_CONCEPT_ID {
|
||||
COORDINATE_CONCEPT,
|
||||
INTERVAL_CONCEPT,
|
||||
POINT_CONCEPT,
|
||||
POINT_3D_CONCEPT,
|
||||
RECTANGLE_CONCEPT,
|
||||
POLYGON_90_CONCEPT,
|
||||
POLYGON_90_WITH_HOLES_CONCEPT,
|
||||
POLYGON_45_CONCEPT,
|
||||
POLYGON_45_WITH_HOLES_CONCEPT,
|
||||
POLYGON_CONCEPT,
|
||||
POLYGON_WITH_HOLES_CONCEPT,
|
||||
POLYGON_90_SET_CONCEPT,
|
||||
POLYGON_45_SET_CONCEPT,
|
||||
POLYGON_SET_CONCEPT
|
||||
};
|
||||
|
||||
struct undefined_concept {};
|
||||
|
||||
template <typename T>
|
||||
struct geometry_concept { typedef undefined_concept type; };
|
||||
|
||||
template <typename GCT, typename T>
|
||||
struct view_of {};
|
||||
|
||||
template <typename T1, typename T2>
|
||||
view_of<T1, T2> view_as(const T2& obj) { return view_of<T1, T2>(obj); }
|
||||
|
||||
template <typename T>
|
||||
struct coordinate_traits {};
|
||||
|
||||
template <typename T>
|
||||
struct high_precision_type {
|
||||
typedef long double type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
T convert_high_precision_type(const typename high_precision_type<T>::type& v) {
|
||||
return T(v);
|
||||
}
|
||||
|
||||
template <>
|
||||
struct coordinate_traits<int> {
|
||||
typedef int coordinate_type;
|
||||
typedef long double area_type;
|
||||
#ifdef BOOST_POLYGON_USE_LONG_LONG
|
||||
typedef polygon_long_long_type manhattan_area_type;
|
||||
typedef polygon_ulong_long_type unsigned_area_type;
|
||||
typedef polygon_long_long_type coordinate_difference;
|
||||
#else
|
||||
typedef long manhattan_area_type;
|
||||
typedef unsigned long unsigned_area_type;
|
||||
typedef long coordinate_difference;
|
||||
#endif
|
||||
typedef long double coordinate_distance;
|
||||
};
|
||||
|
||||
#ifdef BOOST_POLYGON_USE_LONG_LONG
|
||||
template <>
|
||||
struct coordinate_traits<polygon_long_long_type> {
|
||||
typedef polygon_long_long_type coordinate_type;
|
||||
typedef long double area_type;
|
||||
typedef polygon_long_long_type manhattan_area_type;
|
||||
typedef polygon_ulong_long_type unsigned_area_type;
|
||||
typedef polygon_long_long_type coordinate_difference;
|
||||
typedef long double coordinate_distance;
|
||||
};
|
||||
#endif
|
||||
|
||||
template <>
|
||||
struct coordinate_traits<float> {
|
||||
typedef float coordinate_type;
|
||||
typedef float area_type;
|
||||
typedef float manhattan_area_type;
|
||||
typedef float unsigned_area_type;
|
||||
typedef float coordinate_difference;
|
||||
typedef float coordinate_distance;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct coordinate_traits<double> {
|
||||
typedef double coordinate_type;
|
||||
typedef double area_type;
|
||||
typedef double manhattan_area_type;
|
||||
typedef double unsigned_area_type;
|
||||
typedef double coordinate_difference;
|
||||
typedef double coordinate_distance;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct scaling_policy {
|
||||
template <typename T2>
|
||||
static inline T round(T2 t2) {
|
||||
return (T)std::floor(t2+0.5);
|
||||
}
|
||||
|
||||
static inline T round(T t2) {
|
||||
return t2;
|
||||
}
|
||||
};
|
||||
|
||||
struct coordinate_concept {};
|
||||
|
||||
template <>
|
||||
struct geometry_concept<int> { typedef coordinate_concept type; };
|
||||
#ifdef BOOST_POLYGON_USE_LONG_LONG
|
||||
template <>
|
||||
struct geometry_concept<polygon_long_long_type> { typedef coordinate_concept type; };
|
||||
#endif
|
||||
template <>
|
||||
struct geometry_concept<float> { typedef coordinate_concept type; };
|
||||
template <>
|
||||
struct geometry_concept<double> { typedef coordinate_concept type; };
|
||||
|
||||
#ifndef BOOST_POLYGON_NO_DEPS
|
||||
struct gtl_no : mpl::bool_<false> {};
|
||||
struct gtl_yes : mpl::bool_<true> {};
|
||||
template <typename T, typename T2>
|
||||
struct gtl_and : mpl::and_<T, T2> {};
|
||||
template <typename T, typename T2, typename T3>
|
||||
struct gtl_and_3 : mpl::and_<T, T2, T3> {};
|
||||
template <typename T, typename T2, typename T3, typename T4>
|
||||
struct gtl_and_4 : mpl::and_<T, T2, T3, T4> {};
|
||||
// template <typename T, typename T2>
|
||||
// struct gtl_or : mpl::or_<T, T2> {};
|
||||
// template <typename T, typename T2, typename T3>
|
||||
// struct gtl_or_3 : mpl::or_<T, T2, T3> {};
|
||||
// template <typename T, typename T2, typename T3, typename T4>
|
||||
// struct gtl_or_4 : mpl::or_<T, T2, T3, T4> {};
|
||||
#else
|
||||
struct gtl_no { static const bool value = false; };
|
||||
struct gtl_yes { typedef gtl_yes type;
|
||||
static const bool value = true; };
|
||||
|
||||
template <bool T, bool T2>
|
||||
struct gtl_and_c { typedef gtl_no type; };
|
||||
template <>
|
||||
struct gtl_and_c<true, true> { typedef gtl_yes type; };
|
||||
|
||||
template <typename T, typename T2>
|
||||
struct gtl_and : gtl_and_c<T::value, T2::value> {};
|
||||
template <typename T, typename T2, typename T3>
|
||||
struct gtl_and_3 { typedef typename gtl_and<
|
||||
T, typename gtl_and<T2, T3>::type>::type type; };
|
||||
|
||||
template <typename T, typename T2, typename T3, typename T4>
|
||||
struct gtl_and_4 { typedef typename gtl_and_3<
|
||||
T, T2, typename gtl_and<T3, T4>::type>::type type; };
|
||||
#endif
|
||||
template <typename T, typename T2>
|
||||
struct gtl_or { typedef gtl_yes type; };
|
||||
template <typename T>
|
||||
struct gtl_or<T, T> { typedef T type; };
|
||||
|
||||
template <typename T, typename T2, typename T3>
|
||||
struct gtl_or_3 { typedef typename gtl_or<
|
||||
T, typename gtl_or<T2, T3>::type>::type type; };
|
||||
|
||||
template <typename T, typename T2, typename T3, typename T4>
|
||||
struct gtl_or_4 { typedef typename gtl_or<
|
||||
T, typename gtl_or_3<T2, T3, T4>::type>::type type; };
|
||||
|
||||
template <typename T>
|
||||
struct gtl_not { typedef gtl_no type; };
|
||||
template <>
|
||||
struct gtl_not<gtl_no> { typedef gtl_yes type; };
|
||||
|
||||
template <typename T>
|
||||
struct gtl_if {
|
||||
#ifdef WIN32
|
||||
typedef gtl_no type;
|
||||
#endif
|
||||
};
|
||||
template <>
|
||||
struct gtl_if<gtl_yes> { typedef gtl_yes type; };
|
||||
|
||||
template <typename T, typename T2>
|
||||
struct gtl_same_type { typedef gtl_no type; };
|
||||
template <typename T>
|
||||
struct gtl_same_type<T, T> { typedef gtl_yes type; };
|
||||
template <typename T, typename T2>
|
||||
struct gtl_different_type { typedef typename gtl_not<typename gtl_same_type<T, T2>::type>::type type; };
|
||||
|
||||
struct manhattan_domain {};
|
||||
struct forty_five_domain {};
|
||||
struct general_domain {};
|
||||
|
||||
template <typename T>
|
||||
struct geometry_domain { typedef general_domain type; };
|
||||
|
||||
template <typename domain_type, typename coordinate_type>
|
||||
struct area_type_by_domain { typedef typename coordinate_traits<coordinate_type>::area_type type; };
|
||||
template <typename coordinate_type>
|
||||
struct area_type_by_domain<manhattan_domain, coordinate_type> {
|
||||
typedef typename coordinate_traits<coordinate_type>::manhattan_area_type type; };
|
||||
|
||||
struct y_c_edist : gtl_yes {};
|
||||
|
||||
template <typename coordinate_type_1, typename coordinate_type_2>
|
||||
typename enable_if<
|
||||
typename gtl_and_3<y_c_edist, typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type, coordinate_concept>::type,
|
||||
typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type, coordinate_concept>::type>::type,
|
||||
typename coordinate_traits<coordinate_type_1>::coordinate_difference>::type
|
||||
euclidean_distance(const coordinate_type_1& lvalue, const coordinate_type_2& rvalue) {
|
||||
typedef typename coordinate_traits<coordinate_type_1>::coordinate_difference Unit;
|
||||
return (lvalue < rvalue) ? (Unit)rvalue - (Unit)lvalue : (Unit)lvalue - (Unit)rvalue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// predicated_swap swaps a and b if pred is true
|
||||
|
||||
// predicated_swap is guarenteed to behave the same as
|
||||
// if(pred){
|
||||
// T tmp = a;
|
||||
// a = b;
|
||||
// b = tmp;
|
||||
// }
|
||||
// but will not generate a branch instruction.
|
||||
// predicated_swap always creates a temp copy of a, but does not
|
||||
// create more than one temp copy of an input.
|
||||
// predicated_swap can be used to optimize away branch instructions in C++
|
||||
template <class T>
|
||||
inline bool predicated_swap(const bool& pred,
|
||||
T& a,
|
||||
T& b) {
|
||||
const T tmp = a;
|
||||
const T* input[2] = {&b, &tmp};
|
||||
a = *input[!pred];
|
||||
b = *input[pred];
|
||||
return pred;
|
||||
}
|
||||
|
||||
enum direction_1d_enum { LOW = 0, HIGH = 1,
|
||||
LEFT = 0, RIGHT = 1,
|
||||
CLOCKWISE = 0, COUNTERCLOCKWISE = 1,
|
||||
REVERSE = 0, FORWARD = 1,
|
||||
NEGATIVE = 0, POSITIVE = 1 };
|
||||
enum orientation_2d_enum { HORIZONTAL = 0, VERTICAL = 1 };
|
||||
enum direction_2d_enum { WEST = 0, EAST = 1, SOUTH = 2, NORTH = 3 };
|
||||
enum orientation_3d_enum { PROXIMAL = 2 };
|
||||
enum direction_3d_enum { DOWN = 4, UP = 5 };
|
||||
enum winding_direction {
|
||||
clockwise_winding = 0,
|
||||
counterclockwise_winding = 1,
|
||||
unknown_winding = 2
|
||||
};
|
||||
|
||||
class direction_2d;
|
||||
class direction_3d;
|
||||
class orientation_2d;
|
||||
|
||||
class direction_1d {
|
||||
private:
|
||||
unsigned int val_;
|
||||
explicit direction_1d(int d);
|
||||
public:
|
||||
inline direction_1d() : val_(LOW) {}
|
||||
inline direction_1d(const direction_1d& that) : val_(that.val_) {}
|
||||
inline direction_1d(const direction_1d_enum val) : val_(val) {}
|
||||
explicit inline direction_1d(const direction_2d& that);
|
||||
explicit inline direction_1d(const direction_3d& that);
|
||||
inline direction_1d& operator = (const direction_1d& d) {
|
||||
val_ = d.val_; return * this; }
|
||||
inline bool operator==(direction_1d d) const { return (val_ == d.val_); }
|
||||
inline bool operator!=(direction_1d d) const { return !((*this) == d); }
|
||||
inline unsigned int to_int(void) const { return val_; }
|
||||
inline direction_1d& backward() { val_ ^= 1; return *this; }
|
||||
inline int get_sign() const { return val_ * 2 - 1; }
|
||||
};
|
||||
|
||||
class direction_2d;
|
||||
|
||||
class orientation_2d {
|
||||
private:
|
||||
unsigned int val_;
|
||||
explicit inline orientation_2d(int o);
|
||||
public:
|
||||
inline orientation_2d() : val_(HORIZONTAL) {}
|
||||
inline orientation_2d(const orientation_2d& ori) : val_(ori.val_) {}
|
||||
inline orientation_2d(const orientation_2d_enum val) : val_(val) {}
|
||||
explicit inline orientation_2d(const direction_2d& that);
|
||||
inline orientation_2d& operator=(const orientation_2d& ori) {
|
||||
val_ = ori.val_; return * this; }
|
||||
inline bool operator==(orientation_2d that) const { return (val_ == that.val_); }
|
||||
inline bool operator!=(orientation_2d that) const { return (val_ != that.val_); }
|
||||
inline unsigned int to_int() const { return (val_); }
|
||||
inline void turn_90() { val_ = val_^ 1; }
|
||||
inline orientation_2d get_perpendicular() const {
|
||||
orientation_2d retval = *this;
|
||||
retval.turn_90();
|
||||
return retval;
|
||||
}
|
||||
inline direction_2d get_direction(direction_1d dir) const;
|
||||
};
|
||||
|
||||
class direction_2d {
|
||||
private:
|
||||
int val_;
|
||||
|
||||
public:
|
||||
|
||||
inline direction_2d() : val_(WEST) {}
|
||||
|
||||
inline direction_2d(const direction_2d& that) : val_(that.val_) {}
|
||||
|
||||
inline direction_2d(const direction_2d_enum val) : val_(val) {}
|
||||
|
||||
inline direction_2d& operator=(const direction_2d& d) {
|
||||
val_ = d.val_;
|
||||
return * this;
|
||||
}
|
||||
|
||||
inline ~direction_2d() { }
|
||||
|
||||
inline bool operator==(direction_2d d) const { return (val_ == d.val_); }
|
||||
inline bool operator!=(direction_2d d) const { return !((*this) == d); }
|
||||
inline bool operator< (direction_2d d) const { return (val_ < d.val_); }
|
||||
inline bool operator<=(direction_2d d) const { return (val_ <= d.val_); }
|
||||
inline bool operator> (direction_2d d) const { return (val_ > d.val_); }
|
||||
inline bool operator>=(direction_2d d) const { return (val_ >= d.val_); }
|
||||
|
||||
// Casting to int
|
||||
inline unsigned int to_int(void) const { return val_; }
|
||||
|
||||
inline direction_2d backward() const {
|
||||
// flip the LSB, toggles 0 - 1 and 2 - 3
|
||||
return direction_2d(direction_2d_enum(val_ ^ 1));
|
||||
}
|
||||
|
||||
// Returns a direction 90 degree left (LOW) or right(HIGH) to this one
|
||||
inline direction_2d turn(direction_1d t) const {
|
||||
return direction_2d(direction_2d_enum(val_ ^ 3 ^ (val_ >> 1) ^ t.to_int()));
|
||||
}
|
||||
|
||||
// Returns a direction 90 degree left to this one
|
||||
inline direction_2d left() const {return turn(HIGH);}
|
||||
|
||||
// Returns a direction 90 degree right to this one
|
||||
inline direction_2d right() const {return turn(LOW);}
|
||||
|
||||
// N, E are positive, S, W are negative
|
||||
inline bool is_positive() const {return (val_ & 1);}
|
||||
inline bool is_negative() const {return !is_positive();}
|
||||
inline int get_sign() const {return ((is_positive()) << 1) -1;}
|
||||
|
||||
};
|
||||
|
||||
direction_1d::direction_1d(const direction_2d& that) : val_(that.to_int() & 1) {}
|
||||
|
||||
orientation_2d::orientation_2d(const direction_2d& that) : val_(that.to_int() >> 1) {}
|
||||
|
||||
direction_2d orientation_2d::get_direction(direction_1d dir) const {
|
||||
return direction_2d(direction_2d_enum((val_ << 1) + dir.to_int()));
|
||||
}
|
||||
|
||||
class orientation_3d {
|
||||
private:
|
||||
unsigned int val_;
|
||||
explicit inline orientation_3d(int o);
|
||||
public:
|
||||
inline orientation_3d() : val_((int)HORIZONTAL) {}
|
||||
inline orientation_3d(const orientation_3d& ori) : val_(ori.val_) {}
|
||||
inline orientation_3d(orientation_2d ori) : val_(ori.to_int()) {}
|
||||
inline orientation_3d(const orientation_3d_enum val) : val_(val) {}
|
||||
explicit inline orientation_3d(const direction_2d& that);
|
||||
explicit inline orientation_3d(const direction_3d& that);
|
||||
inline ~orientation_3d() { }
|
||||
inline orientation_3d& operator=(const orientation_3d& ori) {
|
||||
val_ = ori.val_; return * this; }
|
||||
inline bool operator==(orientation_3d that) const { return (val_ == that.val_); }
|
||||
inline bool operator!=(orientation_3d that) const { return (val_ != that.val_); }
|
||||
inline unsigned int to_int() const { return (val_); }
|
||||
inline direction_3d get_direction(direction_1d dir) const;
|
||||
};
|
||||
|
||||
class direction_3d {
|
||||
private:
|
||||
int val_;
|
||||
|
||||
public:
|
||||
|
||||
inline direction_3d() : val_(WEST) {}
|
||||
|
||||
inline direction_3d(direction_2d that) : val_(that.to_int()) {}
|
||||
inline direction_3d(const direction_3d& that) : val_(that.val_) {}
|
||||
|
||||
inline direction_3d(const direction_2d_enum val) : val_(val) {}
|
||||
inline direction_3d(const direction_3d_enum val) : val_(val) {}
|
||||
|
||||
inline direction_3d& operator=(direction_3d d) {
|
||||
val_ = d.val_;
|
||||
return * this;
|
||||
}
|
||||
|
||||
inline ~direction_3d() { }
|
||||
|
||||
inline bool operator==(direction_3d d) const { return (val_ == d.val_); }
|
||||
inline bool operator!=(direction_3d d) const { return !((*this) == d); }
|
||||
inline bool operator< (direction_3d d) const { return (val_ < d.val_); }
|
||||
inline bool operator<=(direction_3d d) const { return (val_ <= d.val_); }
|
||||
inline bool operator> (direction_3d d) const { return (val_ > d.val_); }
|
||||
inline bool operator>=(direction_3d d) const { return (val_ >= d.val_); }
|
||||
|
||||
// Casting to int
|
||||
inline unsigned int to_int(void) const { return val_; }
|
||||
|
||||
inline direction_3d backward() const {
|
||||
// flip the LSB, toggles 0 - 1 and 2 - 3 and 4 - 5
|
||||
return direction_2d(direction_2d_enum(val_ ^ 1));
|
||||
}
|
||||
|
||||
// N, E, U are positive, S, W, D are negative
|
||||
inline bool is_positive() const {return (val_ & 1);}
|
||||
inline bool is_negative() const {return !is_positive();}
|
||||
inline int get_sign() const {return ((is_positive()) << 1) -1;}
|
||||
|
||||
};
|
||||
|
||||
direction_1d::direction_1d(const direction_3d& that) : val_(that.to_int() & 1) {}
|
||||
orientation_3d::orientation_3d(const direction_3d& that) : val_(that.to_int() >> 1) {}
|
||||
orientation_3d::orientation_3d(const direction_2d& that) : val_(that.to_int() >> 1) {}
|
||||
|
||||
direction_3d orientation_3d::get_direction(direction_1d dir) const {
|
||||
return direction_3d(direction_3d_enum((val_ << 1) + dir.to_int()));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,270 @@
|
|||
/*
|
||||
Copyright 2008 Intel Corporation
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
*/
|
||||
#ifndef GLT_POINT_3D_CONCEPT_HPP
|
||||
#define GLT_POINT_3D_CONCEPT_HPP
|
||||
#include "point_concept.hpp"
|
||||
#include "point_3d_data.hpp"
|
||||
#include "point_3d_traits.hpp"
|
||||
namespace boost { namespace polygon{
|
||||
struct point_3d_concept {};
|
||||
|
||||
template <typename T>
|
||||
struct is_point_3d_concept { typedef gtl_no type; };
|
||||
template <>
|
||||
struct is_point_3d_concept<point_3d_concept> { typedef gtl_yes type; };
|
||||
//template <>
|
||||
//struct is_point_concept<point_3d_concept> { typedef void type; };
|
||||
|
||||
template <typename T>
|
||||
struct is_mutable_point_3d_concept { typedef gtl_no type; };
|
||||
template <>
|
||||
struct is_mutable_point_3d_concept<point_3d_concept> { typedef gtl_yes type; };
|
||||
|
||||
template <typename T, typename CT>
|
||||
struct point_3d_coordinate_type_by_concept { typedef void type; };
|
||||
template <typename T>
|
||||
struct point_3d_coordinate_type_by_concept<T, gtl_yes> { typedef typename point_3d_traits<T>::coordinate_type type; };
|
||||
|
||||
template <typename T>
|
||||
struct point_3d_coordinate_type {
|
||||
typedef typename point_3d_coordinate_type_by_concept<T, typename is_point_3d_concept<typename geometry_concept<T>::type>::type>::type type;
|
||||
};
|
||||
|
||||
template <typename T, typename CT>
|
||||
struct point_3d_difference_type_by_concept { typedef void type; };
|
||||
template <typename T>
|
||||
struct point_3d_difference_type_by_concept<T, gtl_yes> {
|
||||
typedef typename coordinate_traits<typename point_3d_traits<T>::coordinate_type>::coordinate_difference type; };
|
||||
|
||||
template <typename T>
|
||||
struct point_3d_difference_type {
|
||||
typedef typename point_3d_difference_type_by_concept<
|
||||
T, typename is_point_3d_concept<typename geometry_concept<T>::type>::type>::type type;
|
||||
};
|
||||
|
||||
template <typename T, typename CT>
|
||||
struct point_3d_distance_type_by_concept { typedef void type; };
|
||||
template <typename T>
|
||||
struct point_3d_distance_type_by_concept<T, gtl_yes> {
|
||||
typedef typename coordinate_traits<typename point_3d_traits<T>::coordinate_type>::coordinate_distance type; };
|
||||
|
||||
template <typename T>
|
||||
struct point_3d_distance_type {
|
||||
typedef typename point_3d_distance_type_by_concept<
|
||||
T, typename is_point_3d_concept<typename geometry_concept<T>::type>::type>::type type;
|
||||
};
|
||||
|
||||
struct y_p3d_get : gtl_yes {};
|
||||
|
||||
template <typename T>
|
||||
typename enable_if< typename gtl_and<y_p3d_get, typename gtl_if<typename is_point_3d_concept<typename geometry_concept<T>::type>::type>::type>::type,
|
||||
typename point_3d_coordinate_type<T>::type >::type
|
||||
get(const T& point, orientation_3d orient) { return point_3d_traits<T>::get(point, orient); }
|
||||
|
||||
struct y_p3d_set : gtl_yes {};
|
||||
|
||||
template <typename T, typename coordinate_type>
|
||||
typename enable_if< typename gtl_and<y_p3d_set, typename is_mutable_point_3d_concept<typename geometry_concept<T>::type>::type>::type, void>::type
|
||||
set(T& point, orientation_3d orient, coordinate_type value) { point_3d_mutable_traits<T>::set(point, orient, value); }
|
||||
|
||||
struct y_p3d_set2 : gtl_yes {};
|
||||
|
||||
template <typename T, typename coordinate_type>
|
||||
typename enable_if< typename gtl_and<y_p3d_set2, typename is_mutable_point_3d_concept<typename geometry_concept<T>::type>::type>::type, void>::type
|
||||
set(T& point, orientation_2d orient, coordinate_type value) { point_3d_mutable_traits<T>::set(point, orient, value); }
|
||||
|
||||
struct y_p3d_construct : gtl_yes {};
|
||||
|
||||
template <typename T, typename coordinate_type1, typename coordinate_type2, typename coordinate_type3>
|
||||
typename enable_if< typename gtl_and<y_p3d_construct, typename is_mutable_point_3d_concept<typename geometry_concept<T>::type>::type>::type, T>::type
|
||||
construct(coordinate_type1 x_value, coordinate_type2 y_value, coordinate_type3 z_value) {
|
||||
return point_3d_mutable_traits<T>::construct(x_value, y_value, z_value); }
|
||||
|
||||
struct y_p3d_assign : gtl_yes {};
|
||||
|
||||
template <typename point_3d_type_1, typename point_3d_type_2>
|
||||
typename enable_if<
|
||||
typename gtl_and_3<y_p3d_assign, typename is_mutable_point_3d_concept<typename geometry_concept<point_3d_type_1>::type>::type,
|
||||
typename is_point_3d_concept<typename geometry_concept<point_3d_type_2>::type>::type>::type,
|
||||
point_3d_type_1>::type &
|
||||
assign(point_3d_type_1& lvalue, const point_3d_type_2& rvalue) {
|
||||
set(lvalue, HORIZONTAL, get(rvalue, HORIZONTAL));
|
||||
set(lvalue, VERTICAL, get(rvalue, VERTICAL));
|
||||
set(lvalue, PROXIMAL, get(rvalue, PROXIMAL));
|
||||
return lvalue;
|
||||
}
|
||||
|
||||
struct y_p3d_z : gtl_yes {};
|
||||
|
||||
template <typename point_type>
|
||||
typename enable_if< typename gtl_and<y_p3d_z, typename is_point_3d_concept<typename geometry_concept<point_type>::type>::type>::type,
|
||||
typename point_3d_traits<point_type>::coordinate_type >::type
|
||||
z(const point_type& point) { return get(point, PROXIMAL); }
|
||||
|
||||
struct y_p3d_x : gtl_yes {};
|
||||
|
||||
template <typename point_type, typename coordinate_type>
|
||||
typename enable_if< typename gtl_and<y_p3d_x, typename is_mutable_point_3d_concept<typename geometry_concept<point_type>::type>::type>::type, void>::type
|
||||
x(point_type& point, coordinate_type value) { set(point, HORIZONTAL, value); }
|
||||
|
||||
struct y_p3d_y : gtl_yes {};
|
||||
|
||||
template <typename point_type, typename coordinate_type>
|
||||
typename enable_if< typename gtl_and<y_p3d_y, typename is_mutable_point_3d_concept<typename geometry_concept<point_type>::type>::type>::type, void>::type
|
||||
y(point_type& point, coordinate_type value) { set(point, VERTICAL, value); }
|
||||
|
||||
struct y_p3d_z2 : gtl_yes {};
|
||||
|
||||
template <typename point_type, typename coordinate_type>
|
||||
typename enable_if< typename gtl_and<y_p3d_z2, typename is_mutable_point_3d_concept<typename geometry_concept<point_type>::type>::type>::type, void>::type
|
||||
z(point_type& point, coordinate_type value) { set(point, PROXIMAL, value); }
|
||||
|
||||
struct y_p3d_equiv : gtl_yes {};
|
||||
|
||||
template <typename T, typename T2>
|
||||
typename enable_if<
|
||||
typename gtl_and_3<y_p3d_equiv, typename gtl_same_type<point_3d_concept, typename geometry_concept<T>::type>::type,
|
||||
typename gtl_same_type<point_3d_concept, typename geometry_concept<T2>::type>::type>::type,
|
||||
bool>::type
|
||||
equivalence(const T& point1, const T2& point2) {
|
||||
return x(point1) == x(point2) && y(point1) == y(point2) && z(point1) == z(point2);
|
||||
}
|
||||
|
||||
struct y_p3d_dist : gtl_yes {};
|
||||
|
||||
template <typename point_type_1, typename point_type_2>
|
||||
typename enable_if< typename gtl_and_3<y_p3d_dist, typename is_point_3d_concept<typename geometry_concept<point_type_1>::type>::type,
|
||||
typename is_point_3d_concept<typename geometry_concept<point_type_2>::type>::type>::type,
|
||||
typename point_3d_difference_type<point_type_1>::type>::type
|
||||
euclidean_distance(const point_type_1& point1, const point_type_2& point2, orientation_3d orient) {
|
||||
typedef typename coordinate_traits<typename point_3d_traits<point_type_1>::coordinate_type>::coordinate_difference return_type;
|
||||
return_type return_value =
|
||||
(return_type)get(point1, orient) - (return_type)get(point2, orient);
|
||||
return return_value < 0 ? -return_value : return_value;
|
||||
}
|
||||
|
||||
struct y_p3d_man_dist : gtl_yes {};
|
||||
|
||||
template <typename point_type_1, typename point_type_2>
|
||||
typename enable_if< typename gtl_and_3<y_p3d_man_dist, typename gtl_same_type<point_3d_concept, typename geometry_concept<point_type_1>::type>::type,
|
||||
typename gtl_same_type<point_3d_concept, typename geometry_concept<point_type_2>::type>::type>::type,
|
||||
typename point_3d_difference_type<point_type_1>::type>::type
|
||||
manhattan_distance(const point_type_1& point1, const point_type_2& point2) {
|
||||
return euclidean_distance(point1, point2, HORIZONTAL) + euclidean_distance(point1, point2, VERTICAL)
|
||||
+ euclidean_distance(point1, point2, PROXIMAL);
|
||||
}
|
||||
|
||||
struct y_p3d_dist2 : gtl_yes {};
|
||||
|
||||
template <typename point_type_1, typename point_type_2>
|
||||
typename enable_if< typename gtl_and_3< y_p3d_dist2,
|
||||
typename gtl_same_type<point_3d_concept, typename geometry_concept<point_type_1>::type>::type,
|
||||
typename gtl_same_type<point_3d_concept, typename geometry_concept<point_type_2>::type>::type>::type,
|
||||
typename point_3d_distance_type<point_type_1>::type>::type
|
||||
euclidean_distance(const point_type_1& point1, const point_type_2& point2) {
|
||||
typedef typename coordinate_traits<typename point_3d_traits<point_type_1>::coordinate_type>::coordinate_distance return_value;
|
||||
return_value pdist = (return_value)euclidean_distance(point1, point2, PROXIMAL);
|
||||
pdist *= pdist;
|
||||
return sqrt((double)(distance_squared(point1, point2) + pdist));
|
||||
}
|
||||
|
||||
struct y_p3d_convolve : gtl_yes {};
|
||||
|
||||
template <typename point_type_1, typename point_type_2>
|
||||
typename enable_if< typename gtl_and_3< y_p3d_convolve,
|
||||
typename is_mutable_point_3d_concept<typename geometry_concept<point_type_1>::type>::type,
|
||||
typename gtl_same_type<point_3d_concept, typename geometry_concept<point_type_2>::type>::type>::type,
|
||||
point_type_1>::type &
|
||||
convolve(point_type_1& lvalue, const point_type_2& rvalue) {
|
||||
x(lvalue, x(lvalue) + x(rvalue));
|
||||
y(lvalue, y(lvalue) + y(rvalue));
|
||||
z(lvalue, z(lvalue) + z(rvalue));
|
||||
return lvalue;
|
||||
}
|
||||
|
||||
struct y_p3d_deconvolve : gtl_yes {};
|
||||
|
||||
template <typename point_type_1, typename point_type_2>
|
||||
typename enable_if<
|
||||
typename gtl_and_3<y_p3d_deconvolve, typename is_mutable_point_3d_concept<typename geometry_concept<point_type_1>::type>::type,
|
||||
typename gtl_same_type<point_3d_concept, typename geometry_concept<point_type_2>::type>::type>::type,
|
||||
point_type_1>::type &
|
||||
deconvolve(point_type_1& lvalue, const point_type_2& rvalue) {
|
||||
x(lvalue, x(lvalue) - x(rvalue));
|
||||
y(lvalue, y(lvalue) - y(rvalue));
|
||||
z(lvalue, z(lvalue) - z(rvalue));
|
||||
return lvalue;
|
||||
}
|
||||
|
||||
struct y_p3d_scale_up : gtl_yes {};
|
||||
|
||||
template <typename point_type>
|
||||
typename enable_if< typename gtl_and<y_p3d_scale_up, typename is_mutable_point_3d_concept<typename geometry_concept<point_type>::type>::type>::type,
|
||||
point_type>::type &
|
||||
scale_up(point_type& point,
|
||||
typename coordinate_traits<typename point_3d_traits<point_type>::coordinate_type>::unsigned_area_type factor) {
|
||||
x(point, x(point) * (typename point_3d_traits<point_type>::coordinate_type)factor);
|
||||
y(point, y(point) * (typename point_3d_traits<point_type>::coordinate_type)factor);
|
||||
z(point, z(point) * (typename point_3d_traits<point_type>::coordinate_type)factor);
|
||||
return point;
|
||||
}
|
||||
|
||||
struct y_p3d_scale_down : gtl_yes {};
|
||||
|
||||
template <typename point_type>
|
||||
typename enable_if< typename gtl_and<y_p3d_scale_down, typename is_mutable_point_3d_concept<typename geometry_concept<point_type>::type>::type>::type,
|
||||
point_type>::type &
|
||||
scale_down(point_type& point,
|
||||
typename coordinate_traits<typename point_3d_traits<point_type>::coordinate_type>::unsigned_area_type factor) {
|
||||
typedef typename point_3d_traits<point_type>::coordinate_type Unit;
|
||||
typedef typename coordinate_traits<Unit>::coordinate_distance dt;
|
||||
x(point, scaling_policy<Unit>::round((dt)(x(point)) / (dt)factor));
|
||||
y(point, scaling_policy<Unit>::round((dt)(y(point)) / (dt)factor));
|
||||
z(point, scaling_policy<Unit>::round((dt)(z(point)) / (dt)factor));
|
||||
return point;
|
||||
}
|
||||
|
||||
struct y_p3d_scale : gtl_yes {};
|
||||
|
||||
template <typename point_type, typename scaling_type>
|
||||
typename enable_if< typename gtl_and<y_p3d_scale, typename is_mutable_point_3d_concept<typename geometry_concept<point_type>::type>::type>::type,
|
||||
point_type>::type &
|
||||
scale(point_type& point,
|
||||
const scaling_type& scaling) {
|
||||
typedef typename point_3d_traits<point_type>::coordinate_type Unit;
|
||||
Unit x_(x(point)), y_(y(point)), z_(z(point));
|
||||
scaling.scale(x_, y_, z_);
|
||||
x(point, x_);
|
||||
y(point, y_);
|
||||
z(point, z_);
|
||||
return point;
|
||||
}
|
||||
|
||||
struct y_p3d_transform : gtl_yes {};
|
||||
|
||||
template <typename point_type, typename transformation_type>
|
||||
typename enable_if< typename gtl_and<y_p3d_transform, typename is_mutable_point_3d_concept<typename geometry_concept<point_type>::type>::type>::type,
|
||||
point_type>::type &
|
||||
transform(point_type& point, const transformation_type& transformation) {
|
||||
typedef typename point_3d_traits<point_type>::coordinate_type Unit;
|
||||
Unit x_(x(point)), y_(y(point)), z_(z(point));
|
||||
transformation.transform(x_, y_, z_);
|
||||
x(point, x_);
|
||||
y(point, y_);
|
||||
z(point, z_);
|
||||
return point;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct geometry_concept<point_3d_data<T> > {
|
||||
typedef point_3d_concept type;
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
Copyright 2008 Intel Corporation
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
*/
|
||||
#ifndef BOOST_POLYGON_POINT_3D_DATA_HPP
|
||||
#define BOOST_POLYGON_POINT_3D_DATA_HPP
|
||||
namespace boost { namespace polygon{
|
||||
template <typename T>
|
||||
class point_3d_data {
|
||||
public:
|
||||
typedef T coordinate_type;
|
||||
inline point_3d_data():coords_(){}
|
||||
inline point_3d_data(coordinate_type x, coordinate_type y):coords_() {
|
||||
coords_[HORIZONTAL] = x; coords_[VERTICAL] = y; coords_[PROXIMAL] = 0; }
|
||||
inline point_3d_data(coordinate_type x, coordinate_type y, coordinate_type z)
|
||||
#ifndef BOOST_POLYGON_MSVC
|
||||
:coords_()
|
||||
#endif
|
||||
{
|
||||
coords_[HORIZONTAL] = x; coords_[VERTICAL] = y; coords_[PROXIMAL] = z; }
|
||||
inline point_3d_data(const point_3d_data& that):coords_() { (*this) = that; }
|
||||
inline point_3d_data& operator=(const point_3d_data& that) {
|
||||
coords_[0] = that.coords_[0]; coords_[1] = that.coords_[1];
|
||||
coords_[2] = that.coords_[2]; return *this; }
|
||||
template <typename T2>
|
||||
inline point_3d_data& operator=(const T2& rvalue);
|
||||
inline bool operator==(const point_3d_data& that) const {
|
||||
return coords_[0] == that.coords_[0] && coords_[1] == that.coords_[1] && coords_[2] == that.coords_[2];
|
||||
}
|
||||
inline bool operator!=(const point_3d_data& that) const {
|
||||
return !((*this) == that);
|
||||
}
|
||||
inline coordinate_type get(orientation_2d orient) const {
|
||||
return coords_[orient.to_int()]; }
|
||||
inline coordinate_type get(orientation_3d orient) const {
|
||||
return coords_[orient.to_int()]; }
|
||||
inline void set(orientation_2d orient, coordinate_type value) {
|
||||
coords_[orient.to_int()] = value; }
|
||||
inline void set(orientation_3d orient, coordinate_type value) {
|
||||
coords_[orient.to_int()] = value; }
|
||||
private:
|
||||
coordinate_type coords_[3];
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
Copyright 2008 Intel Corporation
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
*/
|
||||
#ifndef BOOST_POLYGON_POINT_3D_TRAITS_HPP
|
||||
#define BOOST_POLYGON_POINT_3D_TRAITS_HPP
|
||||
|
||||
#include "isotropy.hpp"
|
||||
|
||||
namespace boost { namespace polygon{
|
||||
template <typename T>
|
||||
struct point_3d_traits {
|
||||
typedef typename T::coordinate_type coordinate_type;
|
||||
|
||||
static inline coordinate_type get(const T& point, orientation_3d orient) {
|
||||
return point.get(orient); }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct point_3d_mutable_traits {
|
||||
static inline void set(T& point, orientation_3d orient, typename point_3d_traits<T>::coordinate_type value) {
|
||||
point.set(orient, value); }
|
||||
|
||||
static inline T construct(typename point_3d_traits<T>::coordinate_type x_value,
|
||||
typename point_3d_traits<T>::coordinate_type y_value,
|
||||
typename point_3d_traits<T>::coordinate_type z_value) {
|
||||
return T(x_value, y_value, z_value); }
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,298 @@
|
|||
/*
|
||||
Copyright 2008 Intel Corporation
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
*/
|
||||
#ifndef BOOST_POLYGON_POINT_CONCEPT_HPP
|
||||
#define BOOST_POLYGON_POINT_CONCEPT_HPP
|
||||
#include "isotropy.hpp"
|
||||
#include "point_data.hpp"
|
||||
#include "point_traits.hpp"
|
||||
|
||||
namespace boost { namespace polygon{
|
||||
struct point_concept {};
|
||||
|
||||
template <typename T>
|
||||
struct is_point_concept { typedef gtl_no type; };
|
||||
template <>
|
||||
struct is_point_concept<point_concept> { typedef gtl_yes type; };
|
||||
|
||||
struct point_3d_concept;
|
||||
template <>
|
||||
struct is_point_concept<point_3d_concept> { typedef gtl_yes type; };
|
||||
|
||||
template <typename T>
|
||||
struct is_mutable_point_concept { typedef gtl_no type; };
|
||||
template <>
|
||||
struct is_mutable_point_concept<point_concept> { typedef gtl_yes type; };
|
||||
|
||||
template <typename T, typename CT>
|
||||
struct point_coordinate_type_by_concept { typedef void type; };
|
||||
template <typename T>
|
||||
struct point_coordinate_type_by_concept<T, gtl_yes> { typedef typename point_traits<T>::coordinate_type type; };
|
||||
|
||||
template <typename T>
|
||||
struct point_coordinate_type {
|
||||
typedef typename point_coordinate_type_by_concept<T, typename is_point_concept<typename geometry_concept<T>::type>::type>::type type;
|
||||
};
|
||||
|
||||
template <typename T, typename CT>
|
||||
struct point_difference_type_by_concept { typedef void type; };
|
||||
template <typename T>
|
||||
struct point_difference_type_by_concept<T, gtl_yes> {
|
||||
typedef typename coordinate_traits<typename point_traits<T>::coordinate_type>::coordinate_difference type; };
|
||||
|
||||
template <typename T>
|
||||
struct point_difference_type {
|
||||
typedef typename point_difference_type_by_concept<
|
||||
T, typename is_point_concept<typename geometry_concept<T>::type>::type>::type type;
|
||||
};
|
||||
|
||||
template <typename T, typename CT>
|
||||
struct point_distance_type_by_concept { typedef void type; };
|
||||
template <typename T>
|
||||
struct point_distance_type_by_concept<T, gtl_yes> {
|
||||
typedef typename coordinate_traits<typename point_traits<T>::coordinate_type>::coordinate_distance type; };
|
||||
|
||||
template <typename T>
|
||||
struct point_distance_type {
|
||||
typedef typename point_distance_type_by_concept<
|
||||
T, typename is_point_concept<typename geometry_concept<T>::type>::type>::type type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
typename point_coordinate_type<T>::type
|
||||
get(const T& point, orientation_2d orient,
|
||||
typename enable_if< typename gtl_if<typename is_point_concept<typename geometry_concept<T>::type>::type>::type>::type * = 0
|
||||
) {
|
||||
return point_traits<T>::get(point, orient);
|
||||
}
|
||||
|
||||
template <typename T, typename coordinate_type>
|
||||
void
|
||||
set(T& point, orientation_2d orient, coordinate_type value,
|
||||
typename enable_if<typename is_mutable_point_concept<typename geometry_concept<T>::type>::type>::type * = 0
|
||||
) {
|
||||
point_mutable_traits<T>::set(point, orient, value);
|
||||
}
|
||||
|
||||
template <typename T, typename coordinate_type1, typename coordinate_type2>
|
||||
T
|
||||
construct(coordinate_type1 x_value, coordinate_type2 y_value,
|
||||
typename enable_if<typename is_mutable_point_concept<typename geometry_concept<T>::type>::type>::type * = 0
|
||||
) {
|
||||
return point_mutable_traits<T>::construct(x_value, y_value);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
T1&
|
||||
assign(T1& lvalue, const T2& rvalue,
|
||||
typename enable_if< typename gtl_and< typename is_mutable_point_concept<typename geometry_concept<T1>::type>::type,
|
||||
typename is_point_concept<typename geometry_concept<T2>::type>::type>::type>::type * = 0
|
||||
) {
|
||||
set(lvalue, HORIZONTAL, get(rvalue, HORIZONTAL));
|
||||
set(lvalue, VERTICAL, get(rvalue, VERTICAL));
|
||||
return lvalue;
|
||||
}
|
||||
|
||||
struct y_p_x : gtl_yes {};
|
||||
|
||||
template <typename point_type>
|
||||
typename enable_if< typename gtl_and<y_p_x, typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type,
|
||||
typename point_traits<point_type>::coordinate_type >::type
|
||||
x(const point_type& point) {
|
||||
return get(point, HORIZONTAL);
|
||||
}
|
||||
|
||||
struct y_p_y : gtl_yes {};
|
||||
|
||||
template <typename point_type>
|
||||
typename enable_if< typename gtl_and<y_p_y, typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type,
|
||||
typename point_traits<point_type>::coordinate_type >::type
|
||||
y(const point_type& point) {
|
||||
return get(point, VERTICAL);
|
||||
}
|
||||
|
||||
struct y_p_sx : gtl_yes {};
|
||||
|
||||
template <typename point_type, typename coordinate_type>
|
||||
typename enable_if<typename gtl_and<y_p_sx, typename is_mutable_point_concept<typename geometry_concept<point_type>::type>::type>::type,
|
||||
void>::type
|
||||
x(point_type& point, coordinate_type value) {
|
||||
set(point, HORIZONTAL, value);
|
||||
}
|
||||
|
||||
struct y_p_sy : gtl_yes {};
|
||||
|
||||
template <typename point_type, typename coordinate_type>
|
||||
typename enable_if<typename gtl_and<y_p_sy, typename is_mutable_point_concept<typename geometry_concept<point_type>::type>::type>::type,
|
||||
void>::type
|
||||
y(point_type& point, coordinate_type value) {
|
||||
set(point, VERTICAL, value);
|
||||
}
|
||||
|
||||
template <typename T, typename T2>
|
||||
bool
|
||||
equivalence(const T& point1, const T2& point2,
|
||||
typename enable_if< typename gtl_and<typename gtl_same_type<point_concept, typename geometry_concept<T>::type>::type,
|
||||
typename is_point_concept<typename geometry_concept<T2>::type>::type>::type>::type * = 0
|
||||
) {
|
||||
typename point_traits<T>::coordinate_type x1 = x(point1);
|
||||
typename point_traits<T2>::coordinate_type x2 = get(point2, HORIZONTAL);
|
||||
typename point_traits<T>::coordinate_type y1 = get(point1, VERTICAL);
|
||||
typename point_traits<T2>::coordinate_type y2 = y(point2);
|
||||
return x1 == x2 && y1 == y2;
|
||||
}
|
||||
|
||||
template <typename point_type_1, typename point_type_2>
|
||||
typename point_difference_type<point_type_1>::type
|
||||
manhattan_distance(const point_type_1& point1, const point_type_2& point2,
|
||||
typename enable_if< typename gtl_and<typename gtl_same_type<point_concept, typename geometry_concept<point_type_1>::type>::type,
|
||||
typename is_point_concept<typename geometry_concept<point_type_2>::type>::type>::type>::type * = 0) {
|
||||
return euclidean_distance(point1, point2, HORIZONTAL) + euclidean_distance(point1, point2, VERTICAL);
|
||||
}
|
||||
|
||||
struct y_i_ed1 : gtl_yes {};
|
||||
|
||||
template <typename point_type_1, typename point_type_2>
|
||||
typename enable_if< typename gtl_and_3<y_i_ed1, typename is_point_concept<typename geometry_concept<point_type_1>::type>::type,
|
||||
typename is_point_concept<typename geometry_concept<point_type_2>::type>::type>::type,
|
||||
typename point_difference_type<point_type_1>::type>::type
|
||||
euclidean_distance(const point_type_1& point1, const point_type_2& point2, orientation_2d orient) {
|
||||
typename coordinate_traits<typename point_traits<point_type_1>::coordinate_type>::coordinate_difference return_value =
|
||||
get(point1, orient) - get(point2, orient);
|
||||
return return_value < 0 ? (typename coordinate_traits<typename point_traits<point_type_1>::coordinate_type>::coordinate_difference)-return_value : return_value;
|
||||
}
|
||||
|
||||
struct y_i_ed2 : gtl_yes {};
|
||||
|
||||
template <typename point_type_1, typename point_type_2>
|
||||
typename enable_if< typename gtl_and_3<y_i_ed2, typename gtl_same_type<point_concept, typename geometry_concept<point_type_1>::type>::type,
|
||||
typename gtl_same_type<point_concept, typename geometry_concept<point_type_2>::type>::type>::type,
|
||||
typename point_distance_type<point_type_1>::type>::type
|
||||
euclidean_distance(const point_type_1& point1, const point_type_2& point2) {
|
||||
typedef typename point_traits<point_type_1>::coordinate_type Unit;
|
||||
return sqrt((double)(distance_squared(point1, point2)));
|
||||
}
|
||||
|
||||
template <typename point_type_1, typename point_type_2>
|
||||
typename point_difference_type<point_type_1>::type
|
||||
distance_squared(const point_type_1& point1, const point_type_2& point2,
|
||||
typename enable_if< typename gtl_and<typename is_point_concept<typename geometry_concept<point_type_1>::type>::type,
|
||||
typename is_point_concept<typename geometry_concept<point_type_2>::type>::type>::type>::type * = 0
|
||||
) {
|
||||
typedef typename point_traits<point_type_1>::coordinate_type Unit;
|
||||
typename coordinate_traits<Unit>::coordinate_difference dx = euclidean_distance(point1, point2, HORIZONTAL);
|
||||
typename coordinate_traits<Unit>::coordinate_difference dy = euclidean_distance(point1, point2, VERTICAL);
|
||||
dx *= dx;
|
||||
dy *= dy;
|
||||
return dx + dy;
|
||||
}
|
||||
|
||||
template <typename point_type_1, typename point_type_2>
|
||||
point_type_1 &
|
||||
convolve(point_type_1& lvalue, const point_type_2& rvalue,
|
||||
typename enable_if< typename gtl_and<typename is_mutable_point_concept<typename geometry_concept<point_type_1>::type>::type,
|
||||
typename is_point_concept<typename geometry_concept<point_type_2>::type>::type>::type>::type * = 0
|
||||
) {
|
||||
x(lvalue, x(lvalue) + x(rvalue));
|
||||
y(lvalue, y(lvalue) + y(rvalue));
|
||||
return lvalue;
|
||||
}
|
||||
|
||||
template <typename point_type_1, typename point_type_2>
|
||||
point_type_1 &
|
||||
deconvolve(point_type_1& lvalue, const point_type_2& rvalue,
|
||||
typename enable_if< typename gtl_and<typename is_mutable_point_concept<typename geometry_concept<point_type_1>::type>::type,
|
||||
typename is_point_concept<typename geometry_concept<point_type_2>::type>::type>::type>::type * = 0
|
||||
) {
|
||||
x(lvalue, x(lvalue) - x(rvalue));
|
||||
y(lvalue, y(lvalue) - y(rvalue));
|
||||
return lvalue;
|
||||
}
|
||||
|
||||
template <typename point_type, typename coord_type>
|
||||
point_type &
|
||||
scale_up(point_type& point, coord_type factor,
|
||||
typename enable_if<typename is_mutable_point_concept<typename geometry_concept<point_type>::type>::type>::type * = 0
|
||||
) {
|
||||
typedef typename point_traits<point_type>::coordinate_type Unit;
|
||||
x(point, x(point) * (Unit)factor);
|
||||
y(point, y(point) * (Unit)factor);
|
||||
return point;
|
||||
}
|
||||
|
||||
template <typename point_type, typename coord_type>
|
||||
point_type &
|
||||
scale_down(point_type& point, coord_type factor,
|
||||
typename enable_if<typename is_mutable_point_concept<typename geometry_concept<point_type>::type>::type>::type * = 0
|
||||
) {
|
||||
typedef typename point_traits<point_type>::coordinate_type Unit;
|
||||
typedef typename coordinate_traits<Unit>::coordinate_distance dt;
|
||||
x(point, scaling_policy<Unit>::round((dt)((dt)(x(point)) / (dt)factor)));
|
||||
y(point, scaling_policy<Unit>::round((dt)((dt)(y(point)) / (dt)factor)));
|
||||
return point;
|
||||
}
|
||||
|
||||
template <typename point_type, typename scaling_type>
|
||||
point_type &
|
||||
scale(point_type& point,
|
||||
const scaling_type& scaling,
|
||||
typename enable_if<typename is_mutable_point_concept<typename geometry_concept<point_type>::type>::type>::type * = 0
|
||||
) {
|
||||
typedef typename point_traits<point_type>::coordinate_type Unit;
|
||||
Unit x_(x(point)), y_(y(point));
|
||||
scaling.scale(x_, y_);
|
||||
x(point, x_);
|
||||
y(point, y_);
|
||||
return point;
|
||||
}
|
||||
|
||||
template <typename point_type, typename transformation_type>
|
||||
point_type &
|
||||
transform(point_type& point, const transformation_type& transformation,
|
||||
typename enable_if<typename is_mutable_point_concept<typename geometry_concept<point_type>::type>::type>::type * = 0
|
||||
) {
|
||||
typedef typename point_traits<point_type>::coordinate_type Unit;
|
||||
Unit x_(x(point)), y_(y(point));
|
||||
transformation.transform(x_, y_);
|
||||
x(point, x_);
|
||||
y(point, y_);
|
||||
return point;
|
||||
}
|
||||
|
||||
struct y_pt_move : gtl_yes {};
|
||||
|
||||
template <typename point_type>
|
||||
typename enable_if<
|
||||
typename gtl_and< y_pt_move,
|
||||
typename is_mutable_point_concept<
|
||||
typename geometry_concept<point_type>::type>::type>::type,
|
||||
point_type>::type &
|
||||
move(point_type& point, orientation_2d orient,
|
||||
typename point_traits<point_type>::coordinate_type displacement,
|
||||
typename enable_if<typename is_mutable_point_concept<typename geometry_concept<point_type>::type>::type>::type * = 0
|
||||
) {
|
||||
typedef typename point_traits<point_type>::coordinate_type Unit;
|
||||
Unit v(get(point, orient));
|
||||
set(point, orient, v + displacement);
|
||||
return point;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
template <class T2>
|
||||
point_data<T>& point_data<T>::operator=(const T2& rvalue) {
|
||||
assign(*this, rvalue);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct geometry_concept<point_data<T> > {
|
||||
typedef point_concept type;
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
Copyright 2008 Intel Corporation
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
*/
|
||||
#ifndef GTLPOINT_DATA_HPP
|
||||
#define GTLPOINT_DATA_HPP
|
||||
|
||||
#include "isotropy.hpp"
|
||||
|
||||
namespace boost { namespace polygon{
|
||||
|
||||
template <typename T>
|
||||
class point_data {
|
||||
public:
|
||||
typedef T coordinate_type;
|
||||
inline point_data()
|
||||
#ifndef BOOST_POLYGON_MSVC
|
||||
:coords_()
|
||||
#endif
|
||||
{}
|
||||
inline point_data(coordinate_type x, coordinate_type y)
|
||||
#ifndef BOOST_POLYGON_MSVC
|
||||
:coords_()
|
||||
#endif
|
||||
{
|
||||
coords_[HORIZONTAL] = x; coords_[VERTICAL] = y;
|
||||
}
|
||||
inline point_data(const point_data& that)
|
||||
#ifndef BOOST_POLYGON_MSVC
|
||||
:coords_()
|
||||
#endif
|
||||
{ (*this) = that; }
|
||||
template <typename other>
|
||||
point_data(const other& that) : coords_() { (*this) = that; }
|
||||
inline point_data& operator=(const point_data& that) {
|
||||
coords_[0] = that.coords_[0]; coords_[1] = that.coords_[1]; return *this;
|
||||
}
|
||||
template<typename T1, typename T2>
|
||||
inline point_data(const T1& x, const T2& y):coords_() {
|
||||
coords_[HORIZONTAL] = (coordinate_type)x;
|
||||
coords_[VERTICAL] = (coordinate_type)y;
|
||||
}
|
||||
template <typename T2>
|
||||
inline point_data(const point_data<T2>& rvalue):coords_() {
|
||||
coords_[HORIZONTAL] = (coordinate_type)(rvalue.x());
|
||||
coords_[VERTICAL] = (coordinate_type)(rvalue.y());
|
||||
}
|
||||
template <typename T2>
|
||||
inline point_data& operator=(const T2& rvalue);
|
||||
inline bool operator==(const point_data& that) const {
|
||||
return coords_[0] == that.coords_[0] && coords_[1] == that.coords_[1];
|
||||
}
|
||||
inline bool operator!=(const point_data& that) const {
|
||||
return !((*this) == that);
|
||||
}
|
||||
inline bool operator<(const point_data& that) const {
|
||||
return coords_[0] < that.coords_[0] ||
|
||||
(coords_[0] == that.coords_[0] && coords_[1] < that.coords_[1]);
|
||||
}
|
||||
inline bool operator<=(const point_data& that) const { return !(that < *this); }
|
||||
inline bool operator>(const point_data& that) const { return that < *this; }
|
||||
inline bool operator>=(const point_data& that) const { return !((*this) < that); }
|
||||
inline coordinate_type get(orientation_2d orient) const {
|
||||
return coords_[orient.to_int()];
|
||||
}
|
||||
inline void set(orientation_2d orient, coordinate_type value) {
|
||||
coords_[orient.to_int()] = value;
|
||||
}
|
||||
inline coordinate_type x() const {
|
||||
return coords_[HORIZONTAL];
|
||||
}
|
||||
inline coordinate_type y() const {
|
||||
return coords_[VERTICAL];
|
||||
}
|
||||
inline point_data& x(coordinate_type value) {
|
||||
coords_[HORIZONTAL] = value;
|
||||
return *this;
|
||||
}
|
||||
inline point_data& y(coordinate_type value) {
|
||||
coords_[VERTICAL] = value;
|
||||
return *this;
|
||||
}
|
||||
private:
|
||||
coordinate_type coords_[2];
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
Copyright 2008 Intel Corporation
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
*/
|
||||
#ifndef BOOST_POLYGON_POINT_TRAITS_HPP
|
||||
#define BOOST_POLYGON_POINT_TRAITS_HPP
|
||||
|
||||
#include "isotropy.hpp"
|
||||
|
||||
namespace boost { namespace polygon{
|
||||
template <typename T>
|
||||
struct point_traits {
|
||||
typedef typename T::coordinate_type coordinate_type;
|
||||
|
||||
static inline coordinate_type get(const T& point, orientation_2d orient) {
|
||||
return point.get(orient);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct point_mutable_traits {
|
||||
static inline void set(T& point, orientation_2d orient, typename point_traits<T>::coordinate_type value) {
|
||||
point.set(orient, value);
|
||||
}
|
||||
static inline T construct(typename point_traits<T>::coordinate_type x_value, typename point_traits<T>::coordinate_type y_value) {
|
||||
return T(x_value, y_value);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
Copyright 2008 Intel Corporation
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
*/
|
||||
#ifndef BOOST_POLYGON_POLYGON_HPP
|
||||
#define BOOST_POLYGON_POLYGON_HPP
|
||||
|
||||
#include "isotropy.hpp"
|
||||
|
||||
//point
|
||||
#include "point_data.hpp"
|
||||
#include "point_traits.hpp"
|
||||
#include "point_concept.hpp"
|
||||
|
||||
//point 3d
|
||||
#include "point_3d_data.hpp"
|
||||
#include "point_3d_traits.hpp"
|
||||
#include "point_3d_concept.hpp"
|
||||
|
||||
#include "transform.hpp"
|
||||
#include "detail/transform_detail.hpp"
|
||||
|
||||
//interval
|
||||
#include "interval_data.hpp"
|
||||
#include "interval_traits.hpp"
|
||||
#include "interval_concept.hpp"
|
||||
|
||||
//rectangle
|
||||
#include "rectangle_data.hpp"
|
||||
#include "rectangle_traits.hpp"
|
||||
#include "rectangle_concept.hpp"
|
||||
|
||||
//algorithms needed by polygon types
|
||||
#include "detail/iterator_points_to_compact.hpp"
|
||||
#include "detail/iterator_compact_to_points.hpp"
|
||||
|
||||
//polygons
|
||||
#include "polygon_45_data.hpp"
|
||||
#include "polygon_data.hpp"
|
||||
#include "polygon_90_data.hpp"
|
||||
#include "polygon_90_with_holes_data.hpp"
|
||||
#include "polygon_45_with_holes_data.hpp"
|
||||
#include "polygon_with_holes_data.hpp"
|
||||
#include "polygon_traits.hpp"
|
||||
|
||||
//manhattan boolean algorithms
|
||||
#include "detail/boolean_op.hpp"
|
||||
#include "detail/polygon_formation.hpp"
|
||||
#include "detail/rectangle_formation.hpp"
|
||||
#include "detail/max_cover.hpp"
|
||||
#include "detail/property_merge.hpp"
|
||||
#include "detail/polygon_90_touch.hpp"
|
||||
#include "detail/iterator_geometry_to_set.hpp"
|
||||
|
||||
//45 boolean op algorithms
|
||||
#include "detail/boolean_op_45.hpp"
|
||||
#include "detail/polygon_45_formation.hpp"
|
||||
|
||||
//polygon set data types
|
||||
#include "polygon_90_set_data.hpp"
|
||||
//polygon set trait types
|
||||
#include "polygon_90_set_traits.hpp"
|
||||
//polygon set concepts
|
||||
#include "polygon_90_set_concept.hpp"
|
||||
//boolean operator syntax
|
||||
#include "detail/polygon_90_set_view.hpp"
|
||||
|
||||
//45 boolean op algorithms
|
||||
#include "detail/polygon_45_touch.hpp"
|
||||
#include "detail/property_merge_45.hpp"
|
||||
#include "polygon_45_set_data.hpp"
|
||||
#include "polygon_45_set_traits.hpp"
|
||||
#include "polygon_45_set_concept.hpp"
|
||||
#include "detail/polygon_45_set_view.hpp"
|
||||
|
||||
//arbitrary polygon algorithms
|
||||
#include "detail/polygon_arbitrary_formation.hpp"
|
||||
#include "polygon_set_data.hpp"
|
||||
|
||||
//general scanline
|
||||
#include "detail/scan_arbitrary.hpp"
|
||||
#include "polygon_set_traits.hpp"
|
||||
#include "detail/polygon_set_view.hpp"
|
||||
|
||||
#include "polygon_set_concept.hpp"
|
||||
|
||||
#endif
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
Copyright 2008 Intel Corporation
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
*/
|
||||
#ifndef BOOST_POLYGON_POLYGON_45_DATA_HPP
|
||||
#define BOOST_POLYGON_POLYGON_45_DATA_HPP
|
||||
#include "isotropy.hpp"
|
||||
namespace boost { namespace polygon{
|
||||
struct polygon_45_concept;
|
||||
template <typename T> class polygon_data;
|
||||
template <typename T>
|
||||
class polygon_45_data {
|
||||
public:
|
||||
typedef polygon_45_concept geometry_type;
|
||||
typedef T coordinate_type;
|
||||
typedef typename std::vector<point_data<coordinate_type> >::const_iterator iterator_type;
|
||||
typedef typename coordinate_traits<T>::coordinate_distance area_type;
|
||||
typedef point_data<T> point_type;
|
||||
|
||||
inline polygon_45_data() : coords_() {} //do nothing default constructor
|
||||
|
||||
template<class iT>
|
||||
inline polygon_45_data(iT input_begin, iT input_end) : coords_(input_begin, input_end) {}
|
||||
|
||||
template<class iT>
|
||||
inline polygon_45_data& set(iT input_begin, iT input_end) {
|
||||
coords_.clear(); //just in case there was some old data there
|
||||
coords_.insert(coords_.end(), input_begin, input_end);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// copy constructor (since we have dynamic memory)
|
||||
inline polygon_45_data(const polygon_45_data& that) : coords_(that.coords_) {}
|
||||
|
||||
// assignment operator (since we have dynamic memory do a deep copy)
|
||||
inline polygon_45_data& operator=(const polygon_45_data& that) {
|
||||
coords_ = that.coords_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T2>
|
||||
inline polygon_45_data& operator=(const T2& rvalue);
|
||||
|
||||
inline bool operator==(const polygon_45_data& that) const {
|
||||
if(coords_.size() != that.coords_.size()) return false;
|
||||
for(std::size_t i = 0; i < coords_.size(); ++i) {
|
||||
if(coords_[i] != that.coords_[i]) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool operator!=(const polygon_45_data& that) const { return !((*this) == that); }
|
||||
|
||||
// get begin iterator, returns a pointer to a const Unit
|
||||
inline iterator_type begin() const { return coords_.begin(); }
|
||||
|
||||
// get end iterator, returns a pointer to a const Unit
|
||||
inline iterator_type end() const { return coords_.end(); }
|
||||
|
||||
inline std::size_t size() const { return coords_.size(); }
|
||||
|
||||
private:
|
||||
std::vector<point_data<coordinate_type> > coords_;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,441 @@
|
|||
/*
|
||||
Copyright 2008 Intel Corporation
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
*/
|
||||
#ifndef BOOST_POLYGON_POLYGON_45_SET_CONCEPT_HPP
|
||||
#define BOOST_POLYGON_POLYGON_45_SET_CONCEPT_HPP
|
||||
#include "polygon_45_set_data.hpp"
|
||||
#include "polygon_45_set_traits.hpp"
|
||||
#include "detail/polygon_45_touch.hpp"
|
||||
namespace boost { namespace polygon{
|
||||
|
||||
template <typename T, typename T2>
|
||||
struct is_either_polygon_45_set_type {
|
||||
typedef typename gtl_or<typename is_polygon_45_set_type<T>::type, typename is_polygon_45_set_type<T2>::type >::type type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct is_polygon_45_or_90_set_type {
|
||||
typedef typename gtl_or<typename is_polygon_45_set_type<T>::type, typename is_polygon_90_set_type<T>::type >::type type;
|
||||
};
|
||||
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename gtl_if<typename is_polygon_45_or_90_set_type<polygon_set_type>::type>::type,
|
||||
typename polygon_45_set_traits<polygon_set_type>::iterator_type>::type
|
||||
begin_45_set_data(const polygon_set_type& polygon_set) {
|
||||
return polygon_45_set_traits<polygon_set_type>::begin(polygon_set);
|
||||
}
|
||||
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename gtl_if<typename is_polygon_45_or_90_set_type<polygon_set_type>::type>::type,
|
||||
typename polygon_45_set_traits<polygon_set_type>::iterator_type>::type
|
||||
end_45_set_data(const polygon_set_type& polygon_set) {
|
||||
return polygon_45_set_traits<polygon_set_type>::end(polygon_set);
|
||||
}
|
||||
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename gtl_if<typename is_polygon_45_set_type<polygon_set_type>::type>::type,
|
||||
bool>::type
|
||||
clean(const polygon_set_type& polygon_set) {
|
||||
return polygon_45_set_traits<polygon_set_type>::clean(polygon_set);
|
||||
}
|
||||
|
||||
//assign
|
||||
template <typename polygon_set_type_1, typename polygon_set_type_2>
|
||||
typename enable_if< typename gtl_and< typename gtl_if<typename is_mutable_polygon_45_set_type<polygon_set_type_1>::type>::type,
|
||||
typename gtl_if<typename is_polygon_45_or_90_set_type<polygon_set_type_2>::type>::type>::type,
|
||||
polygon_set_type_1>::type &
|
||||
assign(polygon_set_type_1& lvalue, const polygon_set_type_2& rvalue) {
|
||||
polygon_45_set_mutable_traits<polygon_set_type_1>::set(lvalue, begin_45_set_data(rvalue), end_45_set_data(rvalue));
|
||||
return lvalue;
|
||||
}
|
||||
|
||||
//get trapezoids
|
||||
template <typename output_container_type, typename polygon_set_type>
|
||||
typename enable_if< typename gtl_if<typename is_polygon_45_set_type<polygon_set_type>::type>::type,
|
||||
void>::type
|
||||
get_trapezoids(output_container_type& output, const polygon_set_type& polygon_set) {
|
||||
clean(polygon_set);
|
||||
polygon_45_set_data<typename polygon_45_set_traits<polygon_set_type>::coordinate_type> ps;
|
||||
assign(ps, polygon_set);
|
||||
ps.get_trapezoids(output);
|
||||
}
|
||||
|
||||
//get trapezoids
|
||||
template <typename output_container_type, typename polygon_set_type>
|
||||
typename enable_if< typename gtl_if<typename is_polygon_45_set_type<polygon_set_type>::type>::type,
|
||||
void>::type
|
||||
get_trapezoids(output_container_type& output, const polygon_set_type& polygon_set, orientation_2d slicing_orientation) {
|
||||
clean(polygon_set);
|
||||
polygon_45_set_data<typename polygon_45_set_traits<polygon_set_type>::coordinate_type> ps;
|
||||
assign(ps, polygon_set);
|
||||
ps.get_trapezoids(output, slicing_orientation);
|
||||
}
|
||||
|
||||
//equivalence
|
||||
template <typename polygon_set_type_1, typename polygon_set_type_2>
|
||||
typename enable_if< typename gtl_and_3<typename gtl_if<typename is_polygon_45_or_90_set_type<polygon_set_type_1>::type>::type,
|
||||
typename gtl_if<typename is_polygon_45_or_90_set_type<polygon_set_type_2>::type>::type,
|
||||
typename gtl_if<typename is_either_polygon_45_set_type<polygon_set_type_1,
|
||||
polygon_set_type_2>::type>::type>::type,
|
||||
bool>::type
|
||||
equivalence(const polygon_set_type_1& lvalue,
|
||||
const polygon_set_type_2& rvalue) {
|
||||
polygon_45_set_data<typename polygon_45_set_traits<polygon_set_type_1>::coordinate_type> ps1;
|
||||
assign(ps1, lvalue);
|
||||
polygon_45_set_data<typename polygon_45_set_traits<polygon_set_type_2>::coordinate_type> ps2;
|
||||
assign(ps2, rvalue);
|
||||
return ps1 == ps2;
|
||||
}
|
||||
|
||||
//clear
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename gtl_if<typename is_mutable_polygon_45_set_type<polygon_set_type>::type>::type,
|
||||
void>::type
|
||||
clear(polygon_set_type& polygon_set) {
|
||||
polygon_45_set_data<typename polygon_45_set_traits<polygon_set_type>::coordinate_type> ps;
|
||||
assign(polygon_set, ps);
|
||||
}
|
||||
|
||||
//empty
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename gtl_if<typename is_mutable_polygon_45_set_type<polygon_set_type>::type>::type,
|
||||
bool>::type
|
||||
empty(const polygon_set_type& polygon_set) {
|
||||
if(clean(polygon_set)) return begin_45_set_data(polygon_set) == end_45_set_data(polygon_set);
|
||||
polygon_45_set_data<typename polygon_45_set_traits<polygon_set_type>::coordinate_type> ps;
|
||||
assign(ps, polygon_set);
|
||||
ps.clean();
|
||||
return ps.empty();
|
||||
}
|
||||
|
||||
//extents
|
||||
template <typename polygon_set_type, typename rectangle_type>
|
||||
typename enable_if<
|
||||
typename gtl_and< typename gtl_if<typename is_mutable_polygon_45_set_type<polygon_set_type>::type>::type,
|
||||
typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
|
||||
bool>::type
|
||||
extents(rectangle_type& extents_rectangle,
|
||||
const polygon_set_type& polygon_set) {
|
||||
clean(polygon_set);
|
||||
polygon_45_set_data<typename polygon_45_set_traits<polygon_set_type>::coordinate_type> ps;
|
||||
assign(ps, polygon_set);
|
||||
return ps.extents(extents_rectangle);
|
||||
}
|
||||
|
||||
//area
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type,
|
||||
typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::area_type>::type
|
||||
area(const polygon_set_type& polygon_set) {
|
||||
typedef typename polygon_45_set_traits<polygon_set_type>::coordinate_type Unit;
|
||||
typedef polygon_45_with_holes_data<Unit> p_type;
|
||||
typedef typename coordinate_traits<Unit>::area_type area_type;
|
||||
std::vector<p_type> polys;
|
||||
assign(polys, polygon_set);
|
||||
area_type retval = (area_type)0;
|
||||
for(std::size_t i = 0; i < polys.size(); ++i) {
|
||||
retval += area(polys[i]);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
//interact
|
||||
template <typename polygon_set_type_1, typename polygon_set_type_2>
|
||||
typename enable_if <
|
||||
typename gtl_and< typename gtl_if<typename is_mutable_polygon_45_set_type<polygon_set_type_1>::type>::type,
|
||||
typename gtl_if<typename is_polygon_45_or_90_set_type<polygon_set_type_2>::type>::type >::type,
|
||||
polygon_set_type_1>::type&
|
||||
interact(polygon_set_type_1& polygon_set_1, const polygon_set_type_2& polygon_set_2) {
|
||||
typedef typename polygon_45_set_traits<polygon_set_type_1>::coordinate_type Unit;
|
||||
std::vector<polygon_45_data<Unit> > polys;
|
||||
assign(polys, polygon_set_1);
|
||||
std::vector<std::set<int> > graph(polys.size()+1, std::set<int>());
|
||||
connectivity_extraction_45<Unit> ce;
|
||||
ce.insert(polygon_set_2);
|
||||
for(std::size_t i = 0; i < polys.size(); ++i){
|
||||
ce.insert(polys[i]);
|
||||
}
|
||||
ce.extract(graph);
|
||||
clear(polygon_set_1);
|
||||
polygon_45_set_data<Unit> ps;
|
||||
for(std::set<int>::iterator itr = graph[0].begin(); itr != graph[0].end(); ++itr){
|
||||
ps.insert(polys[(*itr)-1]);
|
||||
}
|
||||
assign(polygon_set_1, ps);
|
||||
return polygon_set_1;
|
||||
}
|
||||
|
||||
// //self_intersect
|
||||
// template <typename polygon_set_type>
|
||||
// typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type>::type,
|
||||
// polygon_set_type>::type &
|
||||
// self_intersect(polygon_set_type& polygon_set) {
|
||||
// typedef typename polygon_45_set_traits<polygon_set_type>::coordinate_type Unit;
|
||||
// //TODO
|
||||
// }
|
||||
|
||||
template <typename polygon_set_type, typename coord_type>
|
||||
typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type,
|
||||
polygon_set_type>::type &
|
||||
resize(polygon_set_type& polygon_set, coord_type resizing,
|
||||
RoundingOption rounding = CLOSEST, CornerOption corner = INTERSECTION) {
|
||||
typedef typename polygon_45_set_traits<polygon_set_type>::coordinate_type Unit;
|
||||
clean(polygon_set);
|
||||
polygon_45_set_data<Unit> ps;
|
||||
assign(ps, polygon_set);
|
||||
ps.resize(resizing, rounding, corner);
|
||||
assign(polygon_set, ps);
|
||||
return polygon_set;
|
||||
}
|
||||
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type,
|
||||
polygon_set_type>::type &
|
||||
bloat(polygon_set_type& polygon_set,
|
||||
typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type bloating) {
|
||||
return resize(polygon_set, static_cast<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>(bloating));
|
||||
}
|
||||
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type,
|
||||
polygon_set_type>::type &
|
||||
shrink(polygon_set_type& polygon_set,
|
||||
typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type shrinking) {
|
||||
return resize(polygon_set, -(typename polygon_45_set_traits<polygon_set_type>::coordinate_type)shrinking);
|
||||
}
|
||||
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type,
|
||||
polygon_set_type>::type &
|
||||
grow_and(polygon_set_type& polygon_set,
|
||||
typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type bloating) {
|
||||
typedef typename polygon_45_set_traits<polygon_set_type>::coordinate_type Unit;
|
||||
std::vector<polygon_45_data<Unit> > polys;
|
||||
assign(polys, polygon_set);
|
||||
clear(polygon_set);
|
||||
polygon_45_set_data<Unit> ps;
|
||||
for(std::size_t i = 0; i < polys.size(); ++i) {
|
||||
polygon_45_set_data<Unit> tmpPs;
|
||||
tmpPs.insert(polys[i]);
|
||||
bloat(tmpPs, bloating);
|
||||
tmpPs.clean(); //apply implicit OR on tmp polygon set
|
||||
ps.insert(tmpPs);
|
||||
}
|
||||
ps.self_intersect();
|
||||
assign(polygon_set, ps);
|
||||
return polygon_set;
|
||||
}
|
||||
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type,
|
||||
polygon_set_type>::type &
|
||||
scale_up(polygon_set_type& polygon_set,
|
||||
typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type factor) {
|
||||
typedef typename polygon_45_set_traits<polygon_set_type>::coordinate_type Unit;
|
||||
clean(polygon_set);
|
||||
polygon_45_set_data<Unit> ps;
|
||||
assign(ps, polygon_set);
|
||||
ps.scale_up(factor);
|
||||
assign(polygon_set, ps);
|
||||
return polygon_set;
|
||||
}
|
||||
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type,
|
||||
polygon_set_type>::type &
|
||||
scale_down(polygon_set_type& polygon_set,
|
||||
typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type factor) {
|
||||
typedef typename polygon_45_set_traits<polygon_set_type>::coordinate_type Unit;
|
||||
clean(polygon_set);
|
||||
polygon_45_set_data<Unit> ps;
|
||||
assign(ps, polygon_set);
|
||||
ps.scale_down(factor);
|
||||
assign(polygon_set, ps);
|
||||
return polygon_set;
|
||||
}
|
||||
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type,
|
||||
polygon_set_type>::type &
|
||||
scale(polygon_set_type& polygon_set, double factor) {
|
||||
typedef typename polygon_45_set_traits<polygon_set_type>::coordinate_type Unit;
|
||||
clean(polygon_set);
|
||||
polygon_45_set_data<Unit> ps;
|
||||
assign(ps, polygon_set);
|
||||
ps.scale(factor);
|
||||
assign(polygon_set, ps);
|
||||
return polygon_set;
|
||||
}
|
||||
|
||||
//self_intersect
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type,
|
||||
polygon_set_type>::type &
|
||||
self_intersect(polygon_set_type& polygon_set) {
|
||||
typedef typename polygon_45_set_traits<polygon_set_type>::coordinate_type Unit;
|
||||
polygon_45_set_data<Unit> ps;
|
||||
assign(ps, polygon_set);
|
||||
ps.self_intersect();
|
||||
assign(polygon_set, ps);
|
||||
return polygon_set;
|
||||
}
|
||||
|
||||
//self_xor
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type,
|
||||
polygon_set_type>::type &
|
||||
self_xor(polygon_set_type& polygon_set) {
|
||||
typedef typename polygon_45_set_traits<polygon_set_type>::coordinate_type Unit;
|
||||
polygon_45_set_data<Unit> ps;
|
||||
assign(ps, polygon_set);
|
||||
ps.self_xor();
|
||||
assign(polygon_set, ps);
|
||||
return polygon_set;
|
||||
}
|
||||
|
||||
//transform
|
||||
template <typename polygon_set_type, typename transformation_type>
|
||||
typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type,
|
||||
polygon_set_type>::type &
|
||||
transform(polygon_set_type& polygon_set,
|
||||
const transformation_type& transformation) {
|
||||
typedef typename polygon_45_set_traits<polygon_set_type>::coordinate_type Unit;
|
||||
clean(polygon_set);
|
||||
polygon_45_set_data<Unit> ps;
|
||||
assign(ps, polygon_set);
|
||||
ps.transform(transformation);
|
||||
assign(polygon_set, ps);
|
||||
return polygon_set;
|
||||
}
|
||||
|
||||
//keep
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type,
|
||||
polygon_set_type>::type &
|
||||
keep(polygon_set_type& polygon_set,
|
||||
typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::area_type min_area,
|
||||
typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::area_type max_area,
|
||||
typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type min_width,
|
||||
typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type max_width,
|
||||
typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type min_height,
|
||||
typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type max_height) {
|
||||
typedef typename polygon_45_set_traits<polygon_set_type>::coordinate_type Unit;
|
||||
typedef typename coordinate_traits<Unit>::unsigned_area_type uat;
|
||||
std::list<polygon_45_data<Unit> > polys;
|
||||
assign(polys, polygon_set);
|
||||
typename std::list<polygon_45_data<Unit> >::iterator itr_nxt;
|
||||
for(typename std::list<polygon_45_data<Unit> >::iterator itr = polys.begin(); itr != polys.end(); itr = itr_nxt){
|
||||
itr_nxt = itr;
|
||||
++itr_nxt;
|
||||
rectangle_data<Unit> bbox;
|
||||
extents(bbox, *itr);
|
||||
uat pwidth = delta(bbox, HORIZONTAL);
|
||||
if(pwidth > min_width && pwidth <= max_width){
|
||||
uat pheight = delta(bbox, VERTICAL);
|
||||
if(pheight > min_height && pheight <= max_height){
|
||||
typename coordinate_traits<Unit>::area_type parea = area(*itr);
|
||||
if(parea <= max_area && parea >= min_area) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
polys.erase(itr);
|
||||
}
|
||||
assign(polygon_set, polys);
|
||||
return polygon_set;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct view_of<polygon_90_set_concept, T> {
|
||||
typedef typename get_coordinate_type<T, typename geometry_concept<T>::type >::type coordinate_type;
|
||||
T* tp;
|
||||
std::vector<polygon_90_with_holes_data<coordinate_type> > polys;
|
||||
view_of(T& obj) : tp(&obj), polys() {
|
||||
std::vector<polygon_with_holes_data<coordinate_type> > gpolys;
|
||||
assign(gpolys, obj);
|
||||
for(typename std::vector<polygon_with_holes_data<coordinate_type> >::iterator itr = gpolys.begin();
|
||||
itr != gpolys.end(); ++itr) {
|
||||
polys.push_back(polygon_90_with_holes_data<coordinate_type>());
|
||||
assign(polys.back(), view_as<polygon_90_with_holes_concept>(*itr));
|
||||
}
|
||||
}
|
||||
view_of(const T& obj) : tp(), polys() {
|
||||
std::vector<polygon_with_holes_data<coordinate_type> > gpolys;
|
||||
assign(gpolys, obj);
|
||||
for(typename std::vector<polygon_with_holes_data<coordinate_type> >::iterator itr = gpolys.begin();
|
||||
itr != gpolys.end(); ++itr) {
|
||||
polys.push_back(polygon_90_with_holes_data<coordinate_type>());
|
||||
assign(polys.back(), view_as<polygon_90_with_holes_concept>(*itr));
|
||||
}
|
||||
}
|
||||
|
||||
typedef typename std::vector<polygon_90_with_holes_data<coordinate_type> >::const_iterator iterator_type;
|
||||
typedef view_of operator_arg_type;
|
||||
|
||||
inline iterator_type begin() const {
|
||||
return polys.begin();
|
||||
}
|
||||
|
||||
inline iterator_type end() const {
|
||||
return polys.end();
|
||||
}
|
||||
|
||||
inline orientation_2d orient() const { return HORIZONTAL; }
|
||||
|
||||
inline bool clean() const { return false; }
|
||||
|
||||
inline bool sorted() const { return false; }
|
||||
|
||||
inline T& get() { return *tp; }
|
||||
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct polygon_90_set_traits<view_of<polygon_90_set_concept, T> > {
|
||||
typedef typename view_of<polygon_90_set_concept, T>::coordinate_type coordinate_type;
|
||||
typedef typename view_of<polygon_90_set_concept, T>::iterator_type iterator_type;
|
||||
typedef view_of<polygon_90_set_concept, T> operator_arg_type;
|
||||
|
||||
static inline iterator_type begin(const view_of<polygon_90_set_concept, T>& polygon_set) {
|
||||
return polygon_set.begin();
|
||||
}
|
||||
|
||||
static inline iterator_type end(const view_of<polygon_90_set_concept, T>& polygon_set) {
|
||||
return polygon_set.end();
|
||||
}
|
||||
|
||||
static inline orientation_2d orient(const view_of<polygon_90_set_concept, T>& polygon_set) {
|
||||
return polygon_set.orient(); }
|
||||
|
||||
static inline bool clean(const view_of<polygon_90_set_concept, T>& polygon_set) {
|
||||
return polygon_set.clean(); }
|
||||
|
||||
static inline bool sorted(const view_of<polygon_90_set_concept, T>& polygon_set) {
|
||||
return polygon_set.sorted(); }
|
||||
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct geometry_concept<view_of<polygon_90_set_concept, T> > {
|
||||
typedef polygon_90_set_concept type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct get_coordinate_type<view_of<polygon_90_set_concept, T>, polygon_90_set_concept> {
|
||||
typedef typename view_of<polygon_90_set_concept, T>::coordinate_type type;
|
||||
};
|
||||
template <typename T>
|
||||
struct get_iterator_type_2<view_of<polygon_90_set_concept, T>, polygon_90_set_concept> {
|
||||
typedef typename view_of<polygon_90_set_concept, T>::iterator_type type;
|
||||
static type begin(const view_of<polygon_90_set_concept, T>& t) { return t.begin(); }
|
||||
static type end(const view_of<polygon_90_set_concept, T>& t) { return t.end(); }
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
#include "detail/polygon_45_set_view.hpp"
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
Copyright 2008 Intel Corporation
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
*/
|
||||
#ifndef BOOST_POLYGON_POLYGON_45_SET_TRAITS_HPP
|
||||
#define BOOST_POLYGON_POLYGON_45_SET_TRAITS_HPP
|
||||
namespace boost { namespace polygon{
|
||||
|
||||
//default definition of polygon 45 set traits works for any model of polygon 45, polygon 45 with holes or any vector or list thereof
|
||||
template <typename T>
|
||||
struct polygon_45_set_traits {
|
||||
typedef typename get_coordinate_type<T, typename geometry_concept<T>::type >::type coordinate_type;
|
||||
typedef typename get_iterator_type<T>::type iterator_type;
|
||||
typedef T operator_arg_type;
|
||||
|
||||
static inline iterator_type begin(const T& polygon_set) {
|
||||
return get_iterator_type<T>::begin(polygon_set);
|
||||
}
|
||||
|
||||
static inline iterator_type end(const T& polygon_set) {
|
||||
return get_iterator_type<T>::end(polygon_set);
|
||||
}
|
||||
|
||||
static inline bool clean(const T& ) { return false; }
|
||||
|
||||
static inline bool sorted(const T& ) { return false; }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct is_45_polygonal_concept { typedef gtl_no type; };
|
||||
template <>
|
||||
struct is_45_polygonal_concept<polygon_45_concept> { typedef gtl_yes type; };
|
||||
template <>
|
||||
struct is_45_polygonal_concept<polygon_45_with_holes_concept> { typedef gtl_yes type; };
|
||||
template <>
|
||||
struct is_45_polygonal_concept<polygon_45_set_concept> { typedef gtl_yes type; };
|
||||
|
||||
template <typename T>
|
||||
struct is_polygon_45_set_type {
|
||||
typedef typename is_45_polygonal_concept<typename geometry_concept<T>::type>::type type;
|
||||
};
|
||||
template <typename T>
|
||||
struct is_polygon_45_set_type<std::list<T> > {
|
||||
typedef typename gtl_or<
|
||||
typename is_45_polygonal_concept<typename geometry_concept<std::list<T> >::type>::type,
|
||||
typename is_45_polygonal_concept<typename geometry_concept<typename std::list<T>::value_type>::type>::type>::type type;
|
||||
};
|
||||
template <typename T>
|
||||
struct is_polygon_45_set_type<std::vector<T> > {
|
||||
typedef typename gtl_or<
|
||||
typename is_45_polygonal_concept<typename geometry_concept<std::vector<T> >::type>::type,
|
||||
typename is_45_polygonal_concept<typename geometry_concept<typename std::vector<T>::value_type>::type>::type>::type type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct is_mutable_polygon_45_set_type {
|
||||
typedef typename gtl_same_type<polygon_45_set_concept, typename geometry_concept<T>::type>::type type;
|
||||
};
|
||||
template <typename T>
|
||||
struct is_mutable_polygon_45_set_type<std::list<T> > {
|
||||
typedef typename gtl_or<
|
||||
typename gtl_same_type<polygon_45_set_concept, typename geometry_concept<std::list<T> >::type>::type,
|
||||
typename is_45_polygonal_concept<typename geometry_concept<typename std::list<T>::value_type>::type>::type>::type type;
|
||||
};
|
||||
template <typename T>
|
||||
struct is_mutable_polygon_45_set_type<std::vector<T> > {
|
||||
typedef typename gtl_or<
|
||||
typename gtl_same_type<polygon_45_set_concept, typename geometry_concept<std::vector<T> >::type>::type,
|
||||
typename is_45_polygonal_concept<typename geometry_concept<typename std::vector<T>::value_type>::type>::type>::type type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
bool fracture_holes_45_by_concept() { return false; }
|
||||
template <>
|
||||
inline bool fracture_holes_45_by_concept<polygon_45_concept>() { return true; }
|
||||
|
||||
template <typename T, typename iT>
|
||||
void get_45_polygons_T(T& t, iT begin, iT end) {
|
||||
typedef typename polygon_45_set_traits<T>::coordinate_type Unit;
|
||||
typedef typename geometry_concept<typename T::value_type>::type CType;
|
||||
typename polygon_45_formation<Unit>::Polygon45Formation pf(fracture_holes_45_by_concept<CType>());
|
||||
//std::cout << "FORMING POLYGONS\n";
|
||||
pf.scan(t, begin, end);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct polygon_45_set_mutable_traits {};
|
||||
template <typename T>
|
||||
struct polygon_45_set_mutable_traits<std::list<T> > {
|
||||
template <typename input_iterator_type>
|
||||
static inline void set(std::list<T>& polygon_set, input_iterator_type input_begin, input_iterator_type input_end) {
|
||||
polygon_set.clear();
|
||||
polygon_45_set_data<typename polygon_45_set_traits<std::list<T> >::coordinate_type> ps;
|
||||
ps.insert(input_begin, input_end);
|
||||
ps.sort();
|
||||
ps.clean();
|
||||
get_45_polygons_T(polygon_set, ps.begin(), ps.end());
|
||||
}
|
||||
};
|
||||
template <typename T>
|
||||
struct polygon_45_set_mutable_traits<std::vector<T> > {
|
||||
template <typename input_iterator_type>
|
||||
static inline void set(std::vector<T>& polygon_set, input_iterator_type input_begin, input_iterator_type input_end) {
|
||||
polygon_set.clear();
|
||||
polygon_45_set_data<typename polygon_45_set_traits<std::list<T> >::coordinate_type> ps;
|
||||
ps.insert(input_begin, input_end);
|
||||
ps.sort();
|
||||
ps.clean();
|
||||
get_45_polygons_T(polygon_set, ps.begin(), ps.end());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct polygon_45_set_mutable_traits<polygon_45_set_data<T> > {
|
||||
template <typename input_iterator_type>
|
||||
static inline void set(polygon_45_set_data<T>& polygon_set,
|
||||
input_iterator_type input_begin, input_iterator_type input_end) {
|
||||
polygon_set.set(input_begin, input_end);
|
||||
}
|
||||
};
|
||||
template <typename T>
|
||||
struct polygon_45_set_traits<polygon_45_set_data<T> > {
|
||||
typedef typename polygon_45_set_data<T>::coordinate_type coordinate_type;
|
||||
typedef typename polygon_45_set_data<T>::iterator_type iterator_type;
|
||||
typedef typename polygon_45_set_data<T>::operator_arg_type operator_arg_type;
|
||||
|
||||
static inline iterator_type begin(const polygon_45_set_data<T>& polygon_set) {
|
||||
return polygon_set.begin();
|
||||
}
|
||||
|
||||
static inline iterator_type end(const polygon_45_set_data<T>& polygon_set) {
|
||||
return polygon_set.end();
|
||||
}
|
||||
|
||||
static inline bool clean(const polygon_45_set_data<T>& polygon_set) { polygon_set.clean(); return true; }
|
||||
|
||||
static inline bool sorted(const polygon_45_set_data<T>& polygon_set) { int untested = 0;polygon_set.sort(); return true; }
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
Copyright 2008 Intel Corporation
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
*/
|
||||
#ifndef BOOST_POLYGON_POLYGON_45_WITH_HOLES_DATA_HPP
|
||||
#define BOOST_POLYGON_POLYGON_45_WITH_HOLES_DATA_HPP
|
||||
#include "isotropy.hpp"
|
||||
#include "polygon_45_data.hpp"
|
||||
namespace boost { namespace polygon{
|
||||
struct polygon_45_with_holes_concept;
|
||||
template <typename T>
|
||||
class polygon_45_with_holes_data {
|
||||
public:
|
||||
typedef polygon_45_with_holes_concept geometry_type;
|
||||
typedef T coordinate_type;
|
||||
typedef typename polygon_45_data<T>::iterator_type iterator_type;
|
||||
typedef typename std::list<polygon_45_data<coordinate_type> >::const_iterator iterator_holes_type;
|
||||
typedef polygon_45_data<coordinate_type> hole_type;
|
||||
typedef typename coordinate_traits<T>::coordinate_distance area_type;
|
||||
typedef point_data<T> point_type;
|
||||
|
||||
// default constructor of point does not initialize x and y
|
||||
inline polygon_45_with_holes_data() : self_(), holes_() {} //do nothing default constructor
|
||||
|
||||
template<class iT>
|
||||
inline polygon_45_with_holes_data(iT input_begin, iT input_end) : self_(), holes_() {
|
||||
set(input_begin, input_end);
|
||||
}
|
||||
|
||||
template<class iT, typename hiT>
|
||||
inline polygon_45_with_holes_data(iT input_begin, iT input_end, hiT holes_begin, hiT holes_end) : self_(), holes_() {
|
||||
set(input_begin, input_end);
|
||||
set_holes(holes_begin, holes_end);
|
||||
}
|
||||
|
||||
template<class iT>
|
||||
inline polygon_45_with_holes_data& set(iT input_begin, iT input_end) {
|
||||
self_.set(input_begin, input_end);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// initialize a polygon from x,y values, it is assumed that the first is an x
|
||||
// and that the input is a well behaved polygon
|
||||
template<class iT>
|
||||
inline polygon_45_with_holes_data& set_holes(iT input_begin, iT input_end) {
|
||||
holes_.clear(); //just in case there was some old data there
|
||||
for( ; input_begin != input_end; ++ input_begin) {
|
||||
holes_.push_back(hole_type());
|
||||
holes_.back().set((*input_begin).begin(), (*input_begin).end());
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// copy constructor (since we have dynamic memory)
|
||||
inline polygon_45_with_holes_data(const polygon_45_with_holes_data& that) : self_(that.self_),
|
||||
holes_(that.holes_) {}
|
||||
|
||||
// assignment operator (since we have dynamic memory do a deep copy)
|
||||
inline polygon_45_with_holes_data& operator=(const polygon_45_with_holes_data& that) {
|
||||
self_ = that.self_;
|
||||
holes_ = that.holes_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T2>
|
||||
inline polygon_45_with_holes_data& operator=(const T2& rvalue);
|
||||
|
||||
// get begin iterator, returns a pointer to a const coordinate_type
|
||||
inline const iterator_type begin() const {
|
||||
return self_.begin();
|
||||
}
|
||||
|
||||
// get end iterator, returns a pointer to a const coordinate_type
|
||||
inline const iterator_type end() const {
|
||||
return self_.end();
|
||||
}
|
||||
|
||||
inline std::size_t size() const {
|
||||
return self_.size();
|
||||
}
|
||||
|
||||
// get begin iterator, returns a pointer to a const polygon
|
||||
inline const iterator_holes_type begin_holes() const {
|
||||
return holes_.begin();
|
||||
}
|
||||
|
||||
// get end iterator, returns a pointer to a const polygon
|
||||
inline const iterator_holes_type end_holes() const {
|
||||
return holes_.end();
|
||||
}
|
||||
|
||||
inline std::size_t size_holes() const {
|
||||
return holes_.size();
|
||||
}
|
||||
|
||||
private:
|
||||
polygon_45_data<coordinate_type> self_;
|
||||
std::list<hole_type> holes_;
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
Copyright 2008 Intel Corporation
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
*/
|
||||
#ifndef BOOST_POLYGON_POLYGON_90_DATA_HPP
|
||||
#define BOOST_POLYGON_POLYGON_90_DATA_HPP
|
||||
namespace boost { namespace polygon{
|
||||
struct polygon_90_concept;
|
||||
template <typename T>
|
||||
class polygon_90_data {
|
||||
public:
|
||||
typedef polygon_90_concept geometry_type;
|
||||
typedef T coordinate_type;
|
||||
typedef typename std::vector<coordinate_type>::const_iterator compact_iterator_type;
|
||||
typedef iterator_compact_to_points<compact_iterator_type, point_data<coordinate_type> > iterator_type;
|
||||
typedef typename coordinate_traits<T>::area_type area_type;
|
||||
|
||||
inline polygon_90_data() : coords_() {} //do nothing default constructor
|
||||
|
||||
// initialize a polygon from x,y values, it is assumed that the first is an x
|
||||
// and that the input is a well behaved polygon
|
||||
template<class iT>
|
||||
inline polygon_90_data& set(iT begin_point, iT end_point) {
|
||||
return set_compact(iterator_points_to_compact<iT, typename std::iterator_traits<iT>::value_type>(begin_point, end_point),
|
||||
iterator_points_to_compact<iT, typename std::iterator_traits<iT>::value_type>(end_point, end_point));
|
||||
}
|
||||
|
||||
template<class iT>
|
||||
inline polygon_90_data& set_compact(iT input_begin, iT input_end) {
|
||||
coords_.clear(); //just in case there was some old data there
|
||||
while(input_begin != input_end) {
|
||||
coords_.insert(coords_.end(), *input_begin);
|
||||
++input_begin;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// copy constructor (since we have dynamic memory)
|
||||
inline polygon_90_data(const polygon_90_data& that) : coords_(that.coords_) {}
|
||||
|
||||
// assignment operator (since we have dynamic memory do a deep copy)
|
||||
inline polygon_90_data& operator=(const polygon_90_data& that) {
|
||||
coords_ = that.coords_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T2>
|
||||
inline polygon_90_data& operator=(const T2& rvalue);
|
||||
|
||||
// assignment operator (since we have dynamic memory do a deep copy)
|
||||
inline bool operator==(const polygon_90_data& that) const {
|
||||
return coords_ == that.coords_;
|
||||
}
|
||||
|
||||
// get begin iterator, returns a pointer to a const Unit
|
||||
inline iterator_type begin() const { return iterator_type(coords_.begin(), coords_.end()); }
|
||||
|
||||
// get end iterator, returns a pointer to a const Unit
|
||||
inline iterator_type end() const { return iterator_type(coords_.end(), coords_.end()); }
|
||||
|
||||
// get begin iterator, returns a pointer to a const Unit
|
||||
inline compact_iterator_type begin_compact() const { return coords_.begin(); }
|
||||
|
||||
// get end iterator, returns a pointer to a const Unit
|
||||
inline compact_iterator_type end_compact() const { return coords_.end(); }
|
||||
|
||||
inline std::size_t size() const { return coords_.size(); }
|
||||
|
||||
private:
|
||||
std::vector<coordinate_type> coords_;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,548 @@
|
|||
/*
|
||||
Copyright 2008 Intel Corporation
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
*/
|
||||
#ifndef BOOST_POLYGON_POLYGON_90_SET_CONCEPT_HPP
|
||||
#define BOOST_POLYGON_POLYGON_90_SET_CONCEPT_HPP
|
||||
#include "polygon_90_set_data.hpp"
|
||||
#include "polygon_90_set_traits.hpp"
|
||||
namespace boost { namespace polygon{
|
||||
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_polygon_90_set_type<polygon_set_type>::type,
|
||||
typename polygon_90_set_traits<polygon_set_type>::iterator_type>::type
|
||||
begin_90_set_data(const polygon_set_type& polygon_set) {
|
||||
return polygon_90_set_traits<polygon_set_type>::begin(polygon_set);
|
||||
}
|
||||
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_polygon_90_set_type<polygon_set_type>::type,
|
||||
typename polygon_90_set_traits<polygon_set_type>::iterator_type>::type
|
||||
end_90_set_data(const polygon_set_type& polygon_set) {
|
||||
return polygon_90_set_traits<polygon_set_type>::end(polygon_set);
|
||||
}
|
||||
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_polygon_90_set_type<polygon_set_type>::type,
|
||||
orientation_2d>::type
|
||||
scanline_orientation(const polygon_set_type& polygon_set) {
|
||||
return polygon_90_set_traits<polygon_set_type>::orient(polygon_set);
|
||||
}
|
||||
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_polygon_90_set_type<polygon_set_type>::type,
|
||||
bool>::type
|
||||
clean(const polygon_set_type& polygon_set) {
|
||||
return polygon_90_set_traits<polygon_set_type>::clean(polygon_set);
|
||||
}
|
||||
|
||||
//assign
|
||||
template <typename polygon_set_type_1, typename polygon_set_type_2>
|
||||
typename enable_if <
|
||||
typename gtl_and<
|
||||
typename is_mutable_polygon_90_set_type<polygon_set_type_1>::type,
|
||||
typename is_polygon_90_set_type<polygon_set_type_2>::type>::type,
|
||||
polygon_set_type_1>::type &
|
||||
assign(polygon_set_type_1& lvalue, const polygon_set_type_2& rvalue) {
|
||||
polygon_90_set_mutable_traits<polygon_set_type_1>::set(lvalue, begin_90_set_data(rvalue), end_90_set_data(rvalue),
|
||||
scanline_orientation(rvalue));
|
||||
return lvalue;
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
struct are_not_both_rectangle_concept { typedef gtl_yes type; };
|
||||
template <>
|
||||
struct are_not_both_rectangle_concept<rectangle_concept, rectangle_concept> { typedef gtl_no type; };
|
||||
|
||||
//equivalence
|
||||
template <typename polygon_set_type_1, typename polygon_set_type_2>
|
||||
typename enable_if< typename gtl_and_3<
|
||||
typename is_polygon_90_set_type<polygon_set_type_1>::type,
|
||||
typename is_polygon_90_set_type<polygon_set_type_2>::type,
|
||||
typename are_not_both_rectangle_concept<typename geometry_concept<polygon_set_type_1>::type,
|
||||
typename geometry_concept<polygon_set_type_2>::type>::type>::type,
|
||||
bool>::type
|
||||
equivalence(const polygon_set_type_1& lvalue,
|
||||
const polygon_set_type_2& rvalue) {
|
||||
polygon_90_set_data<typename polygon_90_set_traits<polygon_set_type_1>::coordinate_type> ps1;
|
||||
assign(ps1, lvalue);
|
||||
polygon_90_set_data<typename polygon_90_set_traits<polygon_set_type_2>::coordinate_type> ps2;
|
||||
assign(ps2, rvalue);
|
||||
return ps1 == ps2;
|
||||
}
|
||||
|
||||
|
||||
//get rectangle tiles (slicing orientation is vertical)
|
||||
template <typename output_container_type, typename polygon_set_type>
|
||||
typename enable_if< typename gtl_if<typename is_polygon_90_set_type<polygon_set_type>::type>::type,
|
||||
void>::type
|
||||
get_rectangles(output_container_type& output, const polygon_set_type& polygon_set) {
|
||||
clean(polygon_set);
|
||||
polygon_90_set_data<typename polygon_90_set_traits<polygon_set_type>::coordinate_type> ps(VERTICAL);
|
||||
assign(ps, polygon_set);
|
||||
ps.get_rectangles(output);
|
||||
}
|
||||
|
||||
//get rectangle tiles
|
||||
template <typename output_container_type, typename polygon_set_type>
|
||||
typename enable_if< typename gtl_if<typename is_polygon_90_set_type<polygon_set_type>::type>::type,
|
||||
void>::type
|
||||
get_rectangles(output_container_type& output, const polygon_set_type& polygon_set, orientation_2d slicing_orientation) {
|
||||
clean(polygon_set);
|
||||
polygon_90_set_data<typename polygon_90_set_traits<polygon_set_type>::coordinate_type> ps;
|
||||
assign(ps, polygon_set);
|
||||
ps.get_rectangles(output, slicing_orientation);
|
||||
}
|
||||
|
||||
//get: min_rectangles max_rectangles
|
||||
template <typename output_container_type, typename polygon_set_type>
|
||||
typename enable_if <typename gtl_and<
|
||||
typename is_polygon_90_set_type<polygon_set_type>::type,
|
||||
typename gtl_same_type<rectangle_concept,
|
||||
typename geometry_concept
|
||||
<typename std::iterator_traits
|
||||
<typename output_container_type::iterator>::value_type>::type>::type>::type,
|
||||
void>::type
|
||||
get_max_rectangles(output_container_type& output, const polygon_set_type& polygon_set) {
|
||||
std::vector<rectangle_data<typename polygon_90_set_traits<polygon_set_type>::coordinate_type> > rects;
|
||||
assign(rects, polygon_set);
|
||||
MaxCover<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::getMaxCover(output, rects, scanline_orientation(polygon_set));
|
||||
}
|
||||
|
||||
//clear
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
|
||||
void>::type
|
||||
clear(polygon_set_type& polygon_set) {
|
||||
polygon_90_set_data<typename polygon_90_set_traits<polygon_set_type>::coordinate_type> ps(scanline_orientation(polygon_set));
|
||||
assign(polygon_set, ps);
|
||||
}
|
||||
|
||||
//empty
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
|
||||
bool>::type
|
||||
empty(const polygon_set_type& polygon_set) {
|
||||
if(clean(polygon_set)) return begin_90_set_data(polygon_set) == end_90_set_data(polygon_set);
|
||||
polygon_90_set_data<typename polygon_90_set_traits<polygon_set_type>::coordinate_type> ps;
|
||||
assign(ps, polygon_set);
|
||||
ps.clean();
|
||||
return ps.empty();
|
||||
}
|
||||
|
||||
//extents
|
||||
template <typename polygon_set_type, typename rectangle_type>
|
||||
typename enable_if <typename gtl_and< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
|
||||
typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
|
||||
bool>::type
|
||||
extents(rectangle_type& extents_rectangle,
|
||||
const polygon_set_type& polygon_set) {
|
||||
typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit;
|
||||
polygon_90_set_data<Unit> ps;
|
||||
assign(ps, polygon_set);
|
||||
return ps.extents(extents_rectangle);
|
||||
}
|
||||
|
||||
//area
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
|
||||
typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::manhattan_area_type>::type
|
||||
area(const polygon_set_type& polygon_set) {
|
||||
typedef rectangle_data<typename polygon_90_set_traits<polygon_set_type>::coordinate_type> rectangle_type;
|
||||
typedef typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::manhattan_area_type area_type;
|
||||
std::vector<rectangle_type> rects;
|
||||
assign(rects, polygon_set);
|
||||
area_type retval = (area_type)0;
|
||||
for(std::size_t i = 0; i < rects.size(); ++i) {
|
||||
retval += (area_type)area(rects[i]);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
//interact
|
||||
template <typename polygon_set_type_1, typename polygon_set_type_2>
|
||||
typename enable_if <typename gtl_and< typename is_mutable_polygon_90_set_type<polygon_set_type_1>::type,
|
||||
typename is_mutable_polygon_90_set_type<polygon_set_type_2>::type>::type,
|
||||
polygon_set_type_1>::type&
|
||||
interact(polygon_set_type_1& polygon_set_1, const polygon_set_type_2& polygon_set_2) {
|
||||
typedef typename polygon_90_set_traits<polygon_set_type_1>::coordinate_type Unit;
|
||||
polygon_90_set_data<Unit> ps(scanline_orientation(polygon_set_2));
|
||||
polygon_90_set_data<Unit> ps2(ps);
|
||||
ps.insert(polygon_set_1);
|
||||
ps2.insert(polygon_set_2);
|
||||
ps.interact(ps2);
|
||||
assign(polygon_set_1, ps);
|
||||
return polygon_set_1;
|
||||
}
|
||||
|
||||
//self_intersect
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
|
||||
polygon_set_type>::type &
|
||||
self_intersect(polygon_set_type& polygon_set) {
|
||||
typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit;
|
||||
polygon_90_set_data<Unit> ps;
|
||||
assign(ps, polygon_set);
|
||||
ps.self_intersect();
|
||||
assign(polygon_set, ps);
|
||||
return polygon_set;
|
||||
}
|
||||
|
||||
//self_xor
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
|
||||
polygon_set_type>::type &
|
||||
self_xor(polygon_set_type& polygon_set) {
|
||||
typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit;
|
||||
polygon_90_set_data<Unit> ps;
|
||||
assign(ps, polygon_set);
|
||||
ps.self_xor();
|
||||
assign(polygon_set, ps);
|
||||
return polygon_set;
|
||||
}
|
||||
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
|
||||
polygon_set_type>::type &
|
||||
bloat(polygon_set_type& polygon_set,
|
||||
typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type bloating) {
|
||||
return bloat(polygon_set, bloating, bloating, bloating, bloating);
|
||||
}
|
||||
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
|
||||
polygon_set_type>::type &
|
||||
bloat(polygon_set_type& polygon_set, orientation_2d orient,
|
||||
typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type bloating) {
|
||||
if(orient == orientation_2d(HORIZONTAL))
|
||||
return bloat(polygon_set, bloating, bloating, 0, 0);
|
||||
return bloat(polygon_set, 0, 0, bloating, bloating);
|
||||
}
|
||||
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
|
||||
polygon_set_type>::type &
|
||||
bloat(polygon_set_type& polygon_set, orientation_2d orient,
|
||||
typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type low_bloating,
|
||||
typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type high_bloating) {
|
||||
if(orient == orientation_2d(HORIZONTAL))
|
||||
return bloat(polygon_set, low_bloating, high_bloating, 0, 0);
|
||||
return bloat(polygon_set, 0, 0, low_bloating, high_bloating);
|
||||
}
|
||||
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
|
||||
polygon_set_type>::type &
|
||||
bloat(polygon_set_type& polygon_set, direction_2d dir,
|
||||
typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type bloating) {
|
||||
if(dir == direction_2d(EAST))
|
||||
return bloat(polygon_set, 0, bloating, 0, 0);
|
||||
if(dir == direction_2d(WEST))
|
||||
return bloat(polygon_set, bloating, 0, 0, 0);
|
||||
if(dir == direction_2d(SOUTH))
|
||||
return bloat(polygon_set, 0, 0, bloating, 0);
|
||||
return bloat(polygon_set, 0, 0, 0, bloating);
|
||||
}
|
||||
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
|
||||
polygon_set_type>::type &
|
||||
bloat(polygon_set_type& polygon_set,
|
||||
typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type west_bloating,
|
||||
typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type east_bloating,
|
||||
typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type south_bloating,
|
||||
typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type north_bloating) {
|
||||
typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit;
|
||||
polygon_90_set_data<Unit> ps;
|
||||
assign(ps, polygon_set);
|
||||
ps.bloat(west_bloating, east_bloating, south_bloating, north_bloating);
|
||||
ps.clean();
|
||||
assign(polygon_set, ps);
|
||||
return polygon_set;
|
||||
}
|
||||
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
|
||||
polygon_set_type>::type &
|
||||
shrink(polygon_set_type& polygon_set,
|
||||
typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type shrinking) {
|
||||
return shrink(polygon_set, shrinking, shrinking, shrinking, shrinking);
|
||||
}
|
||||
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
|
||||
polygon_set_type>::type &
|
||||
shrink(polygon_set_type& polygon_set, orientation_2d orient,
|
||||
typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type shrinking) {
|
||||
if(orient == orientation_2d(HORIZONTAL))
|
||||
return shrink(polygon_set, shrinking, shrinking, 0, 0);
|
||||
return shrink(polygon_set, 0, 0, shrinking, shrinking);
|
||||
}
|
||||
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
|
||||
polygon_set_type>::type &
|
||||
shrink(polygon_set_type& polygon_set, orientation_2d orient,
|
||||
typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type low_shrinking,
|
||||
typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type high_shrinking) {
|
||||
if(orient == orientation_2d(HORIZONTAL))
|
||||
return shrink(polygon_set, low_shrinking, high_shrinking, 0, 0);
|
||||
return shrink(polygon_set, 0, 0, low_shrinking, high_shrinking);
|
||||
}
|
||||
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
|
||||
polygon_set_type>::type &
|
||||
shrink(polygon_set_type& polygon_set, direction_2d dir,
|
||||
typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type shrinking) {
|
||||
if(dir == direction_2d(EAST))
|
||||
return shrink(polygon_set, 0, shrinking, 0, 0);
|
||||
if(dir == direction_2d(WEST))
|
||||
return shrink(polygon_set, shrinking, 0, 0, 0);
|
||||
if(dir == direction_2d(SOUTH))
|
||||
return shrink(polygon_set, 0, 0, shrinking, 0);
|
||||
return shrink(polygon_set, 0, 0, 0, shrinking);
|
||||
}
|
||||
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
|
||||
polygon_set_type>::type &
|
||||
shrink(polygon_set_type& polygon_set,
|
||||
typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type west_shrinking,
|
||||
typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type east_shrinking,
|
||||
typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type south_shrinking,
|
||||
typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type north_shrinking) {
|
||||
typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit;
|
||||
polygon_90_set_data<Unit> ps;
|
||||
assign(ps, polygon_set);
|
||||
ps.shrink(west_shrinking, east_shrinking, south_shrinking, north_shrinking);
|
||||
ps.clean();
|
||||
assign(polygon_set, ps);
|
||||
return polygon_set;
|
||||
}
|
||||
|
||||
template <typename polygon_set_type, typename coord_type>
|
||||
typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
|
||||
polygon_set_type>::type &
|
||||
resize(polygon_set_type& polygon_set, coord_type resizing) {
|
||||
typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit;
|
||||
if(resizing > 0) {
|
||||
return bloat(polygon_set, resizing);
|
||||
}
|
||||
if(resizing < 0) {
|
||||
return shrink(polygon_set, -resizing);
|
||||
}
|
||||
return polygon_set;
|
||||
}
|
||||
|
||||
//positive or negative values allow for any and all directions of sizing
|
||||
template <typename polygon_set_type, typename coord_type>
|
||||
typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
|
||||
polygon_set_type>::type &
|
||||
resize(polygon_set_type& polygon_set, coord_type west, coord_type east, coord_type south, coord_type north) {
|
||||
typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit;
|
||||
polygon_90_set_data<Unit> ps;
|
||||
assign(ps, polygon_set);
|
||||
ps.resize(west, east, south, north);
|
||||
assign(polygon_set, ps);
|
||||
return polygon_set;
|
||||
}
|
||||
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
|
||||
polygon_set_type>::type &
|
||||
grow_and(polygon_set_type& polygon_set,
|
||||
typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type bloating) {
|
||||
return grow_and(polygon_set, bloating, bloating, bloating, bloating);
|
||||
}
|
||||
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
|
||||
polygon_set_type>::type &
|
||||
grow_and(polygon_set_type& polygon_set, orientation_2d orient,
|
||||
typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type bloating) {
|
||||
if(orient == orientation_2d(HORIZONTAL))
|
||||
return grow_and(polygon_set, bloating, bloating, 0, 0);
|
||||
return grow_and(polygon_set, 0, 0, bloating, bloating);
|
||||
}
|
||||
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
|
||||
polygon_set_type>::type &
|
||||
grow_and(polygon_set_type& polygon_set, orientation_2d orient,
|
||||
typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type low_bloating,
|
||||
typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type high_bloating) {
|
||||
if(orient == orientation_2d(HORIZONTAL))
|
||||
return grow_and(polygon_set, low_bloating, high_bloating, 0, 0);
|
||||
return grow_and(polygon_set, 0, 0, low_bloating, high_bloating);
|
||||
}
|
||||
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
|
||||
polygon_set_type>::type &
|
||||
grow_and(polygon_set_type& polygon_set, direction_2d dir,
|
||||
typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type bloating) {
|
||||
if(dir == direction_2d(EAST))
|
||||
return grow_and(polygon_set, 0, bloating, 0, 0);
|
||||
if(dir == direction_2d(WEST))
|
||||
return grow_and(polygon_set, bloating, 0, 0, 0);
|
||||
if(dir == direction_2d(SOUTH))
|
||||
return grow_and(polygon_set, 0, 0, bloating, 0);
|
||||
return grow_and(polygon_set, 0, 0, 0, bloating);
|
||||
}
|
||||
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename gtl_if<typename is_mutable_polygon_90_set_type<polygon_set_type>::type>::type,
|
||||
polygon_set_type>::type &
|
||||
grow_and(polygon_set_type& polygon_set,
|
||||
typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type west_bloating,
|
||||
typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type east_bloating,
|
||||
typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type south_bloating,
|
||||
typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type north_bloating) {
|
||||
typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit;
|
||||
std::vector<polygon_90_data<Unit> > polys;
|
||||
assign(polys, polygon_set);
|
||||
clear(polygon_set);
|
||||
polygon_90_set_data<Unit> ps(scanline_orientation(polygon_set));
|
||||
for(std::size_t i = 0; i < polys.size(); ++i) {
|
||||
polygon_90_set_data<Unit> tmpPs(scanline_orientation(polygon_set));
|
||||
tmpPs.insert(polys[i]);
|
||||
bloat(tmpPs, west_bloating, east_bloating, south_bloating, north_bloating);
|
||||
tmpPs.clean(); //apply implicit OR on tmp polygon set
|
||||
ps.insert(tmpPs);
|
||||
}
|
||||
self_intersect(ps);
|
||||
assign(polygon_set, ps);
|
||||
return polygon_set;
|
||||
}
|
||||
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
|
||||
polygon_set_type>::type &
|
||||
scale_up(polygon_set_type& polygon_set,
|
||||
typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>
|
||||
::unsigned_area_type factor) {
|
||||
typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit;
|
||||
polygon_90_set_data<Unit> ps;
|
||||
assign(ps, polygon_set);
|
||||
ps.scale_up(factor);
|
||||
assign(polygon_set, ps);
|
||||
return polygon_set;
|
||||
}
|
||||
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
|
||||
polygon_set_type>::type &
|
||||
scale_down(polygon_set_type& polygon_set,
|
||||
typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>
|
||||
::unsigned_area_type factor) {
|
||||
typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit;
|
||||
polygon_90_set_data<Unit> ps;
|
||||
assign(ps, polygon_set);
|
||||
ps.scale_down(factor);
|
||||
assign(polygon_set, ps);
|
||||
return polygon_set;
|
||||
}
|
||||
|
||||
template <typename polygon_set_type, typename scaling_type>
|
||||
typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
|
||||
polygon_set_type>::type &
|
||||
scale(polygon_set_type& polygon_set,
|
||||
const scaling_type& scaling) {
|
||||
typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit;
|
||||
polygon_90_set_data<Unit> ps;
|
||||
assign(ps, polygon_set);
|
||||
ps.scale(scaling);
|
||||
assign(polygon_set, ps);
|
||||
return polygon_set;
|
||||
}
|
||||
|
||||
//move
|
||||
template <typename polygon_set_type>
|
||||
polygon_set_type&
|
||||
move(polygon_set_type& polygon_set,
|
||||
orientation_2d orient, typename polygon_90_set_traits<polygon_set_type>::coordinate_type displacement,
|
||||
typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type>::type * = 0) {
|
||||
if(orient == HORIZONTAL)
|
||||
return move(polygon_set, displacement, 0);
|
||||
else
|
||||
return move(polygon_set, 0, displacement);
|
||||
}
|
||||
|
||||
template <typename polygon_set_type>
|
||||
polygon_set_type&
|
||||
move(polygon_set_type& polygon_set, typename polygon_90_set_traits<polygon_set_type>::coordinate_type x_displacement,
|
||||
typename polygon_90_set_traits<polygon_set_type>::coordinate_type y_displacement,
|
||||
typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type>::type * = 0
|
||||
) {
|
||||
typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit;
|
||||
polygon_90_set_data<Unit> ps;
|
||||
assign(ps, polygon_set);
|
||||
ps.move(x_displacement, y_displacement);
|
||||
ps.clean();
|
||||
assign(polygon_set, ps);
|
||||
return polygon_set;
|
||||
}
|
||||
|
||||
//transform
|
||||
template <typename polygon_set_type, typename transformation_type>
|
||||
typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
|
||||
polygon_set_type>::type &
|
||||
transform(polygon_set_type& polygon_set,
|
||||
const transformation_type& transformation) {
|
||||
typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit;
|
||||
polygon_90_set_data<Unit> ps;
|
||||
assign(ps, polygon_set);
|
||||
ps.transform(transformation);
|
||||
ps.clean();
|
||||
assign(polygon_set, ps);
|
||||
return polygon_set;
|
||||
typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit;
|
||||
}
|
||||
|
||||
//keep
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
|
||||
polygon_set_type>::type &
|
||||
keep(polygon_set_type& polygon_set,
|
||||
typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type min_area,
|
||||
typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type max_area,
|
||||
typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type min_width,
|
||||
typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type max_width,
|
||||
typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type min_height,
|
||||
typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type max_height) {
|
||||
typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit;
|
||||
typedef typename coordinate_traits<Unit>::unsigned_area_type uat;
|
||||
std::list<polygon_90_data<Unit> > polys;
|
||||
assign(polys, polygon_set);
|
||||
clear(polygon_set);
|
||||
typename std::list<polygon_90_data<Unit> >::iterator itr_nxt;
|
||||
for(typename std::list<polygon_90_data<Unit> >::iterator itr = polys.begin(); itr != polys.end(); itr = itr_nxt){
|
||||
itr_nxt = itr;
|
||||
++itr_nxt;
|
||||
rectangle_data<Unit> bbox;
|
||||
extents(bbox, *itr);
|
||||
uat pwidth = delta(bbox, HORIZONTAL);
|
||||
if(pwidth > min_width && pwidth <= max_width){
|
||||
uat pheight = delta(bbox, VERTICAL);
|
||||
if(pheight > min_height && pheight <= max_height){
|
||||
uat parea = area(*itr);
|
||||
if(parea <= max_area && parea >= min_area) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
polys.erase(itr);
|
||||
}
|
||||
assign(polygon_set, polys);
|
||||
return polygon_set;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
#include "detail/polygon_90_set_view.hpp"
|
||||
#endif
|
|
@ -0,0 +1,647 @@
|
|||
/*
|
||||
Copyright 2008 Intel Corporation
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
*/
|
||||
#ifndef BOOST_POLYGON_POLYGON_90_SET_DATA_HPP
|
||||
#define BOOST_POLYGON_POLYGON_90_SET_DATA_HPP
|
||||
#include "isotropy.hpp"
|
||||
#include "point_concept.hpp"
|
||||
#include "point_3d_concept.hpp"
|
||||
#include "transform.hpp"
|
||||
#include "interval_concept.hpp"
|
||||
#include "rectangle_concept.hpp"
|
||||
#include "detail/iterator_points_to_compact.hpp"
|
||||
#include "detail/iterator_compact_to_points.hpp"
|
||||
#include "polygon_traits.hpp"
|
||||
|
||||
//manhattan boolean algorithms
|
||||
#include "detail/boolean_op.hpp"
|
||||
#include "detail/polygon_formation.hpp"
|
||||
#include "detail/rectangle_formation.hpp"
|
||||
#include "detail/max_cover.hpp"
|
||||
#include "detail/property_merge.hpp"
|
||||
#include "detail/polygon_90_touch.hpp"
|
||||
#include "detail/iterator_geometry_to_set.hpp"
|
||||
|
||||
namespace boost { namespace polygon{
|
||||
template <typename ltype, typename rtype, typename op_type>
|
||||
class polygon_90_set_view;
|
||||
|
||||
template <typename T>
|
||||
class polygon_90_set_data {
|
||||
public:
|
||||
typedef T coordinate_type;
|
||||
typedef std::vector<std::pair<coordinate_type, std::pair<coordinate_type, int> > > value_type;
|
||||
typedef typename std::vector<std::pair<coordinate_type, std::pair<coordinate_type, int> > >::const_iterator iterator_type;
|
||||
typedef polygon_90_set_data operator_arg_type;
|
||||
|
||||
// default constructor
|
||||
inline polygon_90_set_data() : orient_(HORIZONTAL), data_(), dirty_(false), unsorted_(false) {}
|
||||
|
||||
// constructor
|
||||
inline polygon_90_set_data(orientation_2d orient) : orient_(orient), data_(), dirty_(false), unsorted_(false) {}
|
||||
|
||||
// constructor from an iterator pair over vertex data
|
||||
template <typename iT>
|
||||
inline polygon_90_set_data(orientation_2d orient, iT input_begin, iT input_end) :
|
||||
orient_(HORIZONTAL), data_(), dirty_(false), unsorted_(false) {
|
||||
dirty_ = true;
|
||||
unsorted_ = true;
|
||||
for( ; input_begin != input_end; ++input_begin) { insert(*input_begin); }
|
||||
}
|
||||
|
||||
// copy constructor
|
||||
inline polygon_90_set_data(const polygon_90_set_data& that) :
|
||||
orient_(that.orient_), data_(that.data_), dirty_(that.dirty_), unsorted_(that.unsorted_) {}
|
||||
|
||||
template <typename ltype, typename rtype, typename op_type>
|
||||
inline polygon_90_set_data(const polygon_90_set_view<ltype, rtype, op_type>& that);
|
||||
|
||||
// copy with orientation change constructor
|
||||
inline polygon_90_set_data(orientation_2d orient, const polygon_90_set_data& that) :
|
||||
orient_(orient), data_(), dirty_(false), unsorted_(false) {
|
||||
insert(that, false, that.orient_);
|
||||
}
|
||||
|
||||
// destructor
|
||||
inline ~polygon_90_set_data() {}
|
||||
|
||||
// assignement operator
|
||||
inline polygon_90_set_data& operator=(const polygon_90_set_data& that) {
|
||||
if(this == &that) return *this;
|
||||
orient_ = that.orient_;
|
||||
data_ = that.data_;
|
||||
dirty_ = that.dirty_;
|
||||
unsorted_ = that.unsorted_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename ltype, typename rtype, typename op_type>
|
||||
inline polygon_90_set_data& operator=(const polygon_90_set_view<ltype, rtype, op_type>& that);
|
||||
|
||||
template <typename geometry_object>
|
||||
inline polygon_90_set_data& operator=(const geometry_object& geometry) {
|
||||
data_.clear();
|
||||
insert(geometry);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// insert iterator range
|
||||
inline void insert(iterator_type input_begin, iterator_type input_end, orientation_2d orient = HORIZONTAL) {
|
||||
if(input_begin == input_end || (!data_.empty() && &(*input_begin) == &(*(data_.begin())))) return;
|
||||
dirty_ = true;
|
||||
unsorted_ = true;
|
||||
if(orient == orient_)
|
||||
data_.insert(data_.end(), input_begin, input_end);
|
||||
else {
|
||||
for( ; input_begin != input_end; ++input_begin) {
|
||||
insert(*input_begin, false, orient);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// insert iterator range
|
||||
template <typename iT>
|
||||
inline void insert(iT input_begin, iT input_end, orientation_2d orient = HORIZONTAL) {
|
||||
if(input_begin == input_end) return;
|
||||
dirty_ = true;
|
||||
unsorted_ = true;
|
||||
for( ; input_begin != input_end; ++input_begin) {
|
||||
insert(*input_begin, false, orient);
|
||||
}
|
||||
}
|
||||
|
||||
inline void insert(const polygon_90_set_data& polygon_set) {
|
||||
insert(polygon_set.begin(), polygon_set.end(), polygon_set.orient());
|
||||
}
|
||||
|
||||
inline void insert(const std::pair<std::pair<point_data<coordinate_type>, point_data<coordinate_type> >, int>& edge, bool is_hole = false,
|
||||
orientation_2d orient = HORIZONTAL) {
|
||||
std::pair<coordinate_type, std::pair<coordinate_type, int> > vertex;
|
||||
vertex.first = edge.first.first.x();
|
||||
vertex.second.first = edge.first.first.y();
|
||||
vertex.second.second = edge.second * (is_hole ? -1 : 1);
|
||||
insert(vertex, false, VERTICAL);
|
||||
vertex.first = edge.first.second.x();
|
||||
vertex.second.first = edge.first.second.y();
|
||||
vertex.second.second *= -1;
|
||||
insert(vertex, false, VERTICAL);
|
||||
}
|
||||
|
||||
template <typename geometry_type>
|
||||
inline void insert(const geometry_type& geometry_object, bool is_hole = false, orientation_2d = HORIZONTAL) {
|
||||
iterator_geometry_to_set<typename geometry_concept<geometry_type>::type, geometry_type>
|
||||
begin_input(geometry_object, LOW, orient_, is_hole), end_input(geometry_object, HIGH, orient_, is_hole);
|
||||
insert(begin_input, end_input, orient_);
|
||||
}
|
||||
|
||||
inline void insert(const std::pair<coordinate_type, std::pair<coordinate_type, int> >& vertex, bool is_hole = false,
|
||||
orientation_2d orient = HORIZONTAL) {
|
||||
data_.push_back(vertex);
|
||||
if(orient != orient_) std::swap(data_.back().first, data_.back().second.first);
|
||||
if(is_hole) data_.back().second.second *= -1;
|
||||
dirty_ = true;
|
||||
unsorted_ = true;
|
||||
}
|
||||
|
||||
inline void insert(coordinate_type major_coordinate, const std::pair<interval_data<coordinate_type>, int>& edge) {
|
||||
std::pair<coordinate_type, std::pair<coordinate_type, int> > vertex;
|
||||
vertex.first = major_coordinate;
|
||||
vertex.second.first = edge.first.get(LOW);
|
||||
vertex.second.second = edge.second;
|
||||
insert(vertex, false, orient_);
|
||||
vertex.second.first = edge.first.get(HIGH);
|
||||
vertex.second.second *= -1;
|
||||
insert(vertex, false, orient_);
|
||||
}
|
||||
|
||||
template <typename output_container>
|
||||
inline void get(output_container& output) const {
|
||||
get_dispatch(output, typename geometry_concept<typename output_container::value_type>::type());
|
||||
}
|
||||
|
||||
template <typename output_container>
|
||||
inline void get_polygons(output_container& output) const {
|
||||
get_dispatch(output, polygon_90_concept());
|
||||
}
|
||||
|
||||
template <typename output_container>
|
||||
inline void get_rectangles(output_container& output) const {
|
||||
clean();
|
||||
form_rectangles(output, data_.begin(), data_.end(), orient_, rectangle_concept());
|
||||
}
|
||||
|
||||
template <typename output_container>
|
||||
inline void get_rectangles(output_container& output, orientation_2d slicing_orientation) const {
|
||||
if(slicing_orientation == orient_) {
|
||||
get_rectangles(output);
|
||||
} else {
|
||||
polygon_90_set_data<coordinate_type> ps(*this);
|
||||
ps.transform(axis_transformation(axis_transformation::SWAP_XY));
|
||||
output_container result;
|
||||
ps.get_rectangles(result);
|
||||
for(typename output_container::iterator itr = result.begin(); itr != result.end(); ++itr) {
|
||||
::boost::polygon::transform(*itr, axis_transformation(axis_transformation::SWAP_XY));
|
||||
}
|
||||
output.insert(output.end(), result.begin(), result.end());
|
||||
}
|
||||
}
|
||||
|
||||
// equivalence operator
|
||||
inline bool operator==(const polygon_90_set_data& p) const {
|
||||
if(orient_ == p.orient()) {
|
||||
clean();
|
||||
p.clean();
|
||||
return data_ == p.data_;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// inequivalence operator
|
||||
inline bool operator!=(const polygon_90_set_data& p) const {
|
||||
return !((*this) == p);
|
||||
}
|
||||
|
||||
// get iterator to begin vertex data
|
||||
inline iterator_type begin() const {
|
||||
return data_.begin();
|
||||
}
|
||||
|
||||
// get iterator to end vertex data
|
||||
inline iterator_type end() const {
|
||||
return data_.end();
|
||||
}
|
||||
|
||||
const value_type& value() const {
|
||||
return data_;
|
||||
}
|
||||
|
||||
// clear the contents of the polygon_90_set_data
|
||||
inline void clear() { data_.clear(); dirty_ = unsorted_ = false; }
|
||||
|
||||
// find out if Polygon set is empty
|
||||
inline bool empty() const { clean(); return data_.empty(); }
|
||||
|
||||
// get the Polygon set size in vertices
|
||||
inline std::size_t size() const { clean(); return data_.size(); }
|
||||
|
||||
// get the current Polygon set capacity in vertices
|
||||
inline std::size_t capacity() const { return data_.capacity(); }
|
||||
|
||||
// reserve size of polygon set in vertices
|
||||
inline void reserve(std::size_t size) { return data_.reserve(size); }
|
||||
|
||||
// find out if Polygon set is sorted
|
||||
inline bool sorted() const { return !unsorted_; }
|
||||
|
||||
// find out if Polygon set is clean
|
||||
inline bool dirty() const { return dirty_; }
|
||||
|
||||
// get the scanline orientation of the polygon set
|
||||
inline orientation_2d orient() const { return orient_; }
|
||||
|
||||
void clean() const {
|
||||
sort();
|
||||
if(dirty_) {
|
||||
boolean_op::default_arg_workaround<int>::applyBooleanOr(data_);
|
||||
dirty_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
void sort() const{
|
||||
if(unsorted_) {
|
||||
std::sort(data_.begin(), data_.end());
|
||||
unsorted_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename input_iterator_type>
|
||||
void set(input_iterator_type input_begin, input_iterator_type input_end, orientation_2d orient) {
|
||||
data_.clear();
|
||||
data_.insert(data_.end(), input_begin, input_end);
|
||||
orient_ = orient;
|
||||
dirty_ = true;
|
||||
unsorted_ = true;
|
||||
}
|
||||
|
||||
void set(const value_type& value, orientation_2d orient) {
|
||||
data_ = value;
|
||||
orient_ = orient;
|
||||
dirty_ = true;
|
||||
unsorted_ = true;
|
||||
}
|
||||
|
||||
//extents
|
||||
template <typename rectangle_type>
|
||||
bool
|
||||
extents(rectangle_type& extents_rectangle) const {
|
||||
clean();
|
||||
if(data_.empty()) return false;
|
||||
if(orient_ == HORIZONTAL)
|
||||
set_points(extents_rectangle, point_data<coordinate_type>(data_[0].second.first, data_[0].first),
|
||||
point_data<coordinate_type>(data_[data_.size() - 1].second.first, data_[data_.size() - 1].first));
|
||||
else
|
||||
set_points(extents_rectangle, point_data<coordinate_type>(data_[0].first, data_[0].second.first),
|
||||
point_data<coordinate_type>(data_[data_.size() - 1].first, data_[data_.size() - 1].second.first));
|
||||
for(std::size_t i = 1; i < data_.size() - 1; ++i) {
|
||||
if(orient_ == HORIZONTAL)
|
||||
encompass(extents_rectangle, point_data<coordinate_type>(data_[i].second.first, data_[i].first));
|
||||
else
|
||||
encompass(extents_rectangle, point_data<coordinate_type>(data_[i].first, data_[i].second.first));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
polygon_90_set_data&
|
||||
bloat(typename coordinate_traits<coordinate_type>::unsigned_area_type west_bloating,
|
||||
typename coordinate_traits<coordinate_type>::unsigned_area_type east_bloating,
|
||||
typename coordinate_traits<coordinate_type>::unsigned_area_type south_bloating,
|
||||
typename coordinate_traits<coordinate_type>::unsigned_area_type north_bloating) {
|
||||
std::vector<rectangle_data<coordinate_type> > rects;
|
||||
clean();
|
||||
rects.reserve(data_.size() / 2);
|
||||
get(rects);
|
||||
rectangle_data<coordinate_type> convolutionRectangle(interval_data<coordinate_type>(-((coordinate_type)west_bloating),
|
||||
(coordinate_type)east_bloating),
|
||||
interval_data<coordinate_type>(-((coordinate_type)south_bloating),
|
||||
(coordinate_type)north_bloating));
|
||||
for(typename std::vector<rectangle_data<coordinate_type> >::iterator itr = rects.begin();
|
||||
itr != rects.end(); ++itr) {
|
||||
convolve(*itr, convolutionRectangle);
|
||||
}
|
||||
clear();
|
||||
insert(rects.begin(), rects.end());
|
||||
return *this;
|
||||
}
|
||||
|
||||
polygon_90_set_data&
|
||||
shrink(typename coordinate_traits<coordinate_type>::unsigned_area_type west_shrinking,
|
||||
typename coordinate_traits<coordinate_type>::unsigned_area_type east_shrinking,
|
||||
typename coordinate_traits<coordinate_type>::unsigned_area_type south_shrinking,
|
||||
typename coordinate_traits<coordinate_type>::unsigned_area_type north_shrinking) {
|
||||
rectangle_data<coordinate_type> externalBoundary;
|
||||
if(!extents(externalBoundary)) return *this;
|
||||
::boost::polygon::bloat(externalBoundary, 10); //bloat by diferential ammount
|
||||
//insert a hole that encompasses the data
|
||||
insert(externalBoundary, true); //note that the set is in a dirty state now
|
||||
sort(); //does not apply implicit OR operation
|
||||
std::vector<rectangle_data<coordinate_type> > rects;
|
||||
rects.reserve(data_.size() / 2);
|
||||
//begin does not apply implicit or operation, this is a dirty range
|
||||
form_rectangles(rects, data_.begin(), data_.end(), orient_, rectangle_concept());
|
||||
clear();
|
||||
rectangle_data<coordinate_type> convolutionRectangle(interval_data<coordinate_type>(-((coordinate_type)east_shrinking),
|
||||
(coordinate_type)west_shrinking),
|
||||
interval_data<coordinate_type>(-((coordinate_type)north_shrinking),
|
||||
(coordinate_type)south_shrinking));
|
||||
for(typename std::vector<rectangle_data<coordinate_type> >::iterator itr = rects.begin();
|
||||
itr != rects.end(); ++itr) {
|
||||
rectangle_data<coordinate_type>& rect = *itr;
|
||||
convolve(rect, convolutionRectangle);
|
||||
//insert rectangle as a hole
|
||||
insert(rect, true);
|
||||
}
|
||||
convolve(externalBoundary, convolutionRectangle);
|
||||
//insert duplicate of external boundary as solid to cancel out the external hole boundaries
|
||||
insert(externalBoundary);
|
||||
clean(); //we have negative values in the set, so we need to apply an OR operation to make it valid input to a boolean
|
||||
return *this;
|
||||
}
|
||||
|
||||
polygon_90_set_data&
|
||||
resize(coordinate_type west, coordinate_type east, coordinate_type south, coordinate_type north);
|
||||
|
||||
polygon_90_set_data& move(coordinate_type x_delta, coordinate_type y_delta) {
|
||||
for(typename std::vector<std::pair<coordinate_type, std::pair<coordinate_type, int> > >::iterator
|
||||
itr = data_.begin(); itr != data_.end(); ++itr) {
|
||||
if(orient_ == orientation_2d(VERTICAL)) {
|
||||
(*itr).first += x_delta;
|
||||
(*itr).second.first += y_delta;
|
||||
} else {
|
||||
(*itr).second.first += x_delta;
|
||||
(*itr).first += y_delta;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// transform set
|
||||
template <typename transformation_type>
|
||||
polygon_90_set_data& transform(const transformation_type& transformation) {
|
||||
direction_2d dir1, dir2;
|
||||
transformation.get_directions(dir1, dir2);
|
||||
int sign = dir1.get_sign() * dir2.get_sign();
|
||||
for(typename std::vector<std::pair<coordinate_type, std::pair<coordinate_type, int> > >::iterator
|
||||
itr = data_.begin(); itr != data_.end(); ++itr) {
|
||||
if(orient_ == orientation_2d(VERTICAL)) {
|
||||
transformation.transform((*itr).first, (*itr).second.first);
|
||||
} else {
|
||||
transformation.transform((*itr).second.first, (*itr).first);
|
||||
}
|
||||
(*itr).second.second *= sign;
|
||||
}
|
||||
if(dir1 != EAST || dir2 != NORTH)
|
||||
unsorted_ = true; //some mirroring or rotation must have happened
|
||||
return *this;
|
||||
}
|
||||
|
||||
// scale set
|
||||
polygon_90_set_data& scale_up(typename coordinate_traits<coordinate_type>::unsigned_area_type factor) {
|
||||
for(typename std::vector<std::pair<coordinate_type, std::pair<coordinate_type, int> > >::iterator
|
||||
itr = data_.begin(); itr != data_.end(); ++itr) {
|
||||
(*itr).first *= (coordinate_type)factor;
|
||||
(*itr).second.first *= (coordinate_type)factor;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
polygon_90_set_data& scale_down(typename coordinate_traits<coordinate_type>::unsigned_area_type factor) {
|
||||
typedef typename coordinate_traits<coordinate_type>::coordinate_distance dt;
|
||||
for(typename std::vector<std::pair<coordinate_type, std::pair<coordinate_type, int> > >::iterator
|
||||
itr = data_.begin(); itr != data_.end(); ++itr) {
|
||||
(*itr).first = scaling_policy<coordinate_type>::round((dt)((*itr).first) / (dt)factor);
|
||||
(*itr).second.first = scaling_policy<coordinate_type>::round((dt)((*itr).second.first) / (dt)factor);
|
||||
}
|
||||
unsorted_ = true; //scaling down can make coordinates equal that were not previously equal
|
||||
return *this;
|
||||
}
|
||||
template <typename scaling_type>
|
||||
polygon_90_set_data& scale(const anisotropic_scale_factor<scaling_type>& scaling) {
|
||||
for(typename std::vector<std::pair<coordinate_type, std::pair<coordinate_type, int> > >::iterator
|
||||
itr = data_.begin(); itr != data_.end(); ++itr) {
|
||||
if(orient_ == orientation_2d(VERTICAL)) {
|
||||
scaling.scale((*itr).first, (*itr).second.first);
|
||||
} else {
|
||||
scaling.scale((*itr).second.first, (*itr).first);
|
||||
}
|
||||
}
|
||||
unsorted_ = true;
|
||||
return *this;
|
||||
}
|
||||
template <typename scaling_type>
|
||||
polygon_90_set_data& scale_with(const scaling_type& scaling) {
|
||||
for(typename std::vector<std::pair<coordinate_type, std::pair<coordinate_type, int> > >::iterator
|
||||
itr = data_.begin(); itr != data_.end(); ++itr) {
|
||||
if(orient_ == orientation_2d(VERTICAL)) {
|
||||
scaling.scale((*itr).first, (*itr).second.first);
|
||||
} else {
|
||||
scaling.scale((*itr).second.first, (*itr).first);
|
||||
}
|
||||
}
|
||||
unsorted_ = true;
|
||||
return *this;
|
||||
}
|
||||
polygon_90_set_data& scale(double factor) {
|
||||
typedef typename coordinate_traits<coordinate_type>::coordinate_distance dt;
|
||||
for(typename std::vector<std::pair<coordinate_type, std::pair<coordinate_type, int> > >::iterator
|
||||
itr = data_.begin(); itr != data_.end(); ++itr) {
|
||||
(*itr).first = scaling_policy<coordinate_type>::round((dt)((*itr).first) * (dt)factor);
|
||||
(*itr).second.first = scaling_policy<coordinate_type>::round((dt)((*itr).second.first) * (dt)factor);
|
||||
}
|
||||
unsorted_ = true; //scaling make coordinates equal that were not previously equal
|
||||
return *this;
|
||||
}
|
||||
|
||||
polygon_90_set_data& self_xor() {
|
||||
sort();
|
||||
if(dirty_) { //if it is clean it is a no-op
|
||||
boolean_op::default_arg_workaround<boolean_op::UnaryCount>::applyBooleanOr(data_);
|
||||
dirty_ = false;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
polygon_90_set_data& self_intersect() {
|
||||
sort();
|
||||
if(dirty_) { //if it is clean it is a no-op
|
||||
interval_data<coordinate_type> ivl((std::numeric_limits<coordinate_type>::min)(), (std::numeric_limits<coordinate_type>::max)());
|
||||
rectangle_data<coordinate_type> rect(ivl, ivl);
|
||||
insert(rect, true);
|
||||
clean();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline polygon_90_set_data& interact(const polygon_90_set_data& that) {
|
||||
typedef coordinate_type Unit;
|
||||
if(that.dirty_) that.clean();
|
||||
typename touch_90_operation<Unit>::TouchSetData tsd;
|
||||
touch_90_operation<Unit>::populateTouchSetData(tsd, that.data_, 0);
|
||||
std::vector<polygon_90_data<Unit> > polys;
|
||||
get(polys);
|
||||
std::vector<std::set<int> > graph(polys.size()+1, std::set<int>());
|
||||
for(std::size_t i = 0; i < polys.size(); ++i){
|
||||
polygon_90_set_data<Unit> psTmp(that.orient_);
|
||||
psTmp.insert(polys[i]);
|
||||
psTmp.clean();
|
||||
touch_90_operation<Unit>::populateTouchSetData(tsd, psTmp.data_, i+1);
|
||||
}
|
||||
touch_90_operation<Unit>::performTouch(graph, tsd);
|
||||
clear();
|
||||
for(std::set<int>::iterator itr = graph[0].begin(); itr != graph[0].end(); ++itr){
|
||||
insert(polys[(*itr)-1]);
|
||||
}
|
||||
dirty_ = false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
template <class T2, typename iterator_type_1, typename iterator_type_2>
|
||||
void applyBooleanBinaryOp(iterator_type_1 itr1, iterator_type_1 itr1_end,
|
||||
iterator_type_2 itr2, iterator_type_2 itr2_end,
|
||||
T2 defaultCount) {
|
||||
data_.clear();
|
||||
boolean_op::applyBooleanBinaryOp(data_, itr1, itr1_end, itr2, itr2_end, defaultCount);
|
||||
}
|
||||
|
||||
private:
|
||||
orientation_2d orient_;
|
||||
mutable value_type data_;
|
||||
mutable bool dirty_;
|
||||
mutable bool unsorted_;
|
||||
|
||||
private:
|
||||
//functions
|
||||
template <typename output_container>
|
||||
void get_dispatch(output_container& output, rectangle_concept ) const {
|
||||
clean();
|
||||
form_rectangles(output, data_.begin(), data_.end(), orient_, rectangle_concept());
|
||||
}
|
||||
template <typename output_container>
|
||||
void get_dispatch(output_container& output, polygon_90_concept tag) const {
|
||||
get_fracture(output, true, tag);
|
||||
}
|
||||
template <typename output_container>
|
||||
void get_dispatch(output_container& output, polygon_90_with_holes_concept tag) const {
|
||||
get_fracture(output, false, tag);
|
||||
}
|
||||
template <typename output_container>
|
||||
void get_dispatch(output_container& output, polygon_45_concept tag) const {
|
||||
get_fracture(output, true, tag);
|
||||
}
|
||||
template <typename output_container>
|
||||
void get_dispatch(output_container& output, polygon_45_with_holes_concept tag) const {
|
||||
get_fracture(output, false, tag);
|
||||
}
|
||||
template <typename output_container>
|
||||
void get_dispatch(output_container& output, polygon_concept tag) const {
|
||||
get_fracture(output, true, tag);
|
||||
}
|
||||
template <typename output_container>
|
||||
void get_dispatch(output_container& output, polygon_with_holes_concept tag) const {
|
||||
get_fracture(output, false, tag);
|
||||
}
|
||||
template <typename output_container, typename concept_type>
|
||||
void get_fracture(output_container& container, bool fracture_holes, concept_type tag) const {
|
||||
clean();
|
||||
::boost::polygon::get_polygons(container, data_.begin(), data_.end(), orient_, fracture_holes, tag);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename coordinate_type>
|
||||
polygon_90_set_data<coordinate_type>&
|
||||
polygon_90_set_data<coordinate_type>::resize(coordinate_type west,
|
||||
coordinate_type east,
|
||||
coordinate_type south,
|
||||
coordinate_type north) {
|
||||
move(-west, -south);
|
||||
coordinate_type e_total = west + east;
|
||||
coordinate_type n_total = south + north;
|
||||
if((e_total < 0) ^ (n_total < 0)) {
|
||||
//different signs
|
||||
if(e_total < 0) {
|
||||
shrink(0, -e_total, 0, 0);
|
||||
if(n_total != 0)
|
||||
return bloat(0, 0, 0, n_total);
|
||||
else
|
||||
return (*this);
|
||||
} else {
|
||||
shrink(0, 0, 0, -n_total); //shrink first
|
||||
if(e_total != 0)
|
||||
return bloat(0, e_total, 0, 0);
|
||||
else
|
||||
return (*this);
|
||||
}
|
||||
} else {
|
||||
if(e_total < 0) {
|
||||
return shrink(0, -e_total, 0, -n_total);
|
||||
}
|
||||
return bloat(0, e_total, 0, n_total);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename coordinate_type, typename property_type>
|
||||
class property_merge_90 {
|
||||
private:
|
||||
std::vector<std::pair<property_merge_point<coordinate_type>, std::pair<property_type, int> > > pmd_;
|
||||
public:
|
||||
inline property_merge_90() : pmd_() {}
|
||||
inline property_merge_90(const property_merge_90& that) : pmd_(that.pmd_) {}
|
||||
inline property_merge_90& operator=(const property_merge_90& that) { pmd_ = that.pmd_; return *this; }
|
||||
inline void insert(const polygon_90_set_data<coordinate_type>& ps, const property_type& property) {
|
||||
merge_scanline<coordinate_type, property_type, polygon_90_set_data<coordinate_type> >::
|
||||
populate_property_merge_data(pmd_, ps.begin(), ps.end(), property, ps.orient());
|
||||
}
|
||||
template <class GeoObjT>
|
||||
inline void insert(const GeoObjT& geoObj, const property_type& property) {
|
||||
polygon_90_set_data<coordinate_type> ps;
|
||||
ps.insert(geoObj);
|
||||
insert(ps, property);
|
||||
}
|
||||
//merge properties of input geometries and store the resulting geometries of regions
|
||||
//with unique sets of merged properties to polygons sets in a map keyed by sets of properties
|
||||
// T = std::map<std::set<property_type>, polygon_90_set_data<coordiante_type> > or
|
||||
// T = std::map<std::vector<property_type>, polygon_90_set_data<coordiante_type> >
|
||||
template <typename ResultType>
|
||||
inline void merge(ResultType& result) {
|
||||
merge_scanline<coordinate_type, property_type, polygon_90_set_data<coordinate_type>, typename ResultType::key_type> ms;
|
||||
ms.perform_merge(result, pmd_);
|
||||
}
|
||||
};
|
||||
|
||||
//ConnectivityExtraction computes the graph of connectivity between rectangle, polygon and
|
||||
//polygon set graph nodes where an edge is created whenever the geometry in two nodes overlap
|
||||
template <typename coordinate_type>
|
||||
class connectivity_extraction_90 {
|
||||
private:
|
||||
typedef typename touch_90_operation<coordinate_type>::TouchSetData tsd;
|
||||
tsd tsd_;
|
||||
unsigned int nodeCount_;
|
||||
public:
|
||||
inline connectivity_extraction_90() : tsd_(), nodeCount_(0) {}
|
||||
inline connectivity_extraction_90(const connectivity_extraction_90& that) : tsd_(that.tsd_),
|
||||
nodeCount_(that.nodeCount_) {}
|
||||
inline connectivity_extraction_90& operator=(const connectivity_extraction_90& that) {
|
||||
tsd_ = that.tsd_;
|
||||
nodeCount_ = that.nodeCount_; {}
|
||||
return *this;
|
||||
}
|
||||
|
||||
//insert a polygon set graph node, the value returned is the id of the graph node
|
||||
inline unsigned int insert(const polygon_90_set_data<coordinate_type>& ps) {
|
||||
ps.clean();
|
||||
touch_90_operation<coordinate_type>::populateTouchSetData(tsd_, ps.begin(), ps.end(), nodeCount_);
|
||||
return nodeCount_++;
|
||||
}
|
||||
template <class GeoObjT>
|
||||
inline unsigned int insert(const GeoObjT& geoObj) {
|
||||
polygon_90_set_data<coordinate_type> ps;
|
||||
ps.insert(geoObj);
|
||||
return insert(ps);
|
||||
}
|
||||
|
||||
//extract connectivity and store the edges in the graph
|
||||
//graph must be indexable by graph node id and the indexed value must be a std::set of
|
||||
//graph node id
|
||||
template <class GraphT>
|
||||
inline void extract(GraphT& graph) {
|
||||
touch_90_operation<coordinate_type>::performTouch(graph, tsd_);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,362 @@
|
|||
/*
|
||||
Copyright 2008 Intel Corporation
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
*/
|
||||
#ifndef BOOST_POLYGON_POLYGON_90_SET_TRAITS_HPP
|
||||
#define BOOST_POLYGON_POLYGON_90_SET_TRAITS_HPP
|
||||
namespace boost { namespace polygon{
|
||||
|
||||
struct polygon_90_set_concept {};
|
||||
|
||||
template <typename T, typename T2>
|
||||
struct traits_by_concept {};
|
||||
template <typename T>
|
||||
struct traits_by_concept<T, coordinate_concept> { typedef coordinate_traits<T> type; };
|
||||
template <typename T>
|
||||
struct traits_by_concept<T, interval_concept> { typedef interval_traits<T> type; };
|
||||
template <typename T>
|
||||
struct traits_by_concept<T, point_concept> { typedef point_traits<T> type; };
|
||||
template <typename T>
|
||||
struct traits_by_concept<T, point_3d_concept> { typedef point_3d_traits<T> type; };
|
||||
template <typename T>
|
||||
struct traits_by_concept<T, rectangle_concept> { typedef rectangle_traits<T> type; };
|
||||
template <typename T>
|
||||
struct traits_by_concept<T, polygon_90_concept> { typedef polygon_traits<T> type; };
|
||||
template <typename T>
|
||||
struct traits_by_concept<T, polygon_90_with_holes_concept> { typedef polygon_traits<T> type; };
|
||||
template <typename T>
|
||||
struct traits_by_concept<T, polygon_45_concept> { typedef polygon_traits<T> type; };
|
||||
template <typename T>
|
||||
struct traits_by_concept<T, polygon_45_with_holes_concept> { typedef polygon_traits<T> type; };
|
||||
template <typename T>
|
||||
struct traits_by_concept<T, polygon_concept> { typedef polygon_traits<T> type; };
|
||||
template <typename T>
|
||||
struct traits_by_concept<T, polygon_with_holes_concept> { typedef polygon_traits<T> type; };
|
||||
|
||||
struct polygon_45_set_concept;
|
||||
struct polygon_set_concept;
|
||||
template <typename T>
|
||||
struct polygon_90_set_traits;
|
||||
template <typename T>
|
||||
struct polygon_45_set_traits;
|
||||
template <typename T>
|
||||
struct polygon_set_traits;
|
||||
template <typename T>
|
||||
struct traits_by_concept<T, polygon_90_set_concept> { typedef polygon_90_set_traits<T> type; };
|
||||
template <typename T>
|
||||
struct traits_by_concept<T, polygon_45_set_concept> { typedef polygon_45_set_traits<T> type; };
|
||||
template <typename T>
|
||||
struct traits_by_concept<T, polygon_set_concept> { typedef polygon_set_traits<T> type; };
|
||||
|
||||
template <typename T, typename T2>
|
||||
struct get_coordinate_type {
|
||||
typedef typename traits_by_concept<T, T2>::type traits_type;
|
||||
typedef typename traits_type::coordinate_type type;
|
||||
};
|
||||
//want to prevent recursive template definition syntax errors, so duplicate get_coordinate_type
|
||||
template <typename T, typename T2>
|
||||
struct get_coordinate_type_2 {
|
||||
typedef typename traits_by_concept<T, T2>::type traits_type;
|
||||
typedef typename traits_type::coordinate_type type;
|
||||
};
|
||||
template <typename T>
|
||||
struct get_coordinate_type<T, undefined_concept> {
|
||||
typedef typename get_coordinate_type_2<typename std::iterator_traits
|
||||
<typename T::iterator>::value_type,
|
||||
typename geometry_concept<typename std::iterator_traits
|
||||
<typename T::iterator>::value_type>::type>::type type; };
|
||||
|
||||
template <typename T, typename T2>
|
||||
struct get_iterator_type_2 {
|
||||
typedef const T* type;
|
||||
static type begin(const T& t) { return &t; }
|
||||
static type end(const T& t) { const T* tp = &t; ++tp; return tp; }
|
||||
};
|
||||
template <typename T>
|
||||
struct get_iterator_type {
|
||||
typedef get_iterator_type_2<T, typename geometry_concept<T>::type> indirect_type;
|
||||
typedef typename indirect_type::type type;
|
||||
static type begin(const T& t) { return indirect_type::begin(t); }
|
||||
static type end(const T& t) { return indirect_type::end(t); }
|
||||
};
|
||||
template <typename T>
|
||||
struct get_iterator_type_2<T, undefined_concept> {
|
||||
typedef typename T::const_iterator type;
|
||||
static type begin(const T& t) { return t.begin(); }
|
||||
static type end(const T& t) { return t.end(); }
|
||||
};
|
||||
|
||||
// //helpers for allowing polygon 45 and containers of polygon 45 to behave interchangably in polygon_45_set_traits
|
||||
// template <typename T, typename T2>
|
||||
// struct get_coordinate_type_45 {};
|
||||
// template <typename T, typename T2>
|
||||
// struct get_coordinate_type_2_45 {};
|
||||
// template <typename T>
|
||||
// struct get_coordinate_type_45<T, void> {
|
||||
// typedef typename get_coordinate_type_2_45< typename T::value_type, typename geometry_concept<typename T::value_type>::type >::type type; };
|
||||
// template <typename T>
|
||||
// struct get_coordinate_type_45<T, polygon_45_concept> { typedef typename polygon_traits<T>::coordinate_type type; };
|
||||
// template <typename T>
|
||||
// struct get_coordinate_type_45<T, polygon_45_with_holes_concept> { typedef typename polygon_traits<T>::coordinate_type type; };
|
||||
// template <typename T>
|
||||
// struct get_coordinate_type_2_45<T, polygon_45_concept> { typedef typename polygon_traits<T>::coordinate_type type; };
|
||||
// template <typename T>
|
||||
// struct get_coordinate_type_2_45<T, polygon_45_with_holes_concept> { typedef typename polygon_traits<T>::coordinate_type type; };
|
||||
// template <typename T, typename T2>
|
||||
// struct get_iterator_type_45 {};
|
||||
// template <typename T>
|
||||
// struct get_iterator_type_45<T, void> {
|
||||
// typedef typename T::const_iterator type;
|
||||
// static type begin(const T& t) { return t.begin(); }
|
||||
// static type end(const T& t) { return t.end(); }
|
||||
// };
|
||||
// template <typename T>
|
||||
// struct get_iterator_type_45<T, polygon_45_concept> {
|
||||
// typedef const T* type;
|
||||
// static type begin(const T& t) { return &t; }
|
||||
// static type end(const T& t) { const T* tp = &t; ++tp; return tp; }
|
||||
// };
|
||||
// template <typename T>
|
||||
// struct get_iterator_type_45<T, polygon_45_with_holes_concept> {
|
||||
// typedef const T* type;
|
||||
// static type begin(const T& t) { return &t; }
|
||||
// static type end(const T& t) { const T* tp = &t; ++tp; return tp; }
|
||||
// };
|
||||
// template <typename T>
|
||||
// struct get_iterator_type_45<T, polygon_90_set_concept> {
|
||||
// typedef const T* type;
|
||||
// static type begin(const T& t) { return &t; }
|
||||
// static type end(const T& t) { const T* tp = &t; ++tp; return tp; }
|
||||
// };
|
||||
|
||||
template <typename T>
|
||||
struct polygon_90_set_traits {
|
||||
typedef typename get_coordinate_type<T, typename geometry_concept<T>::type >::type coordinate_type;
|
||||
typedef get_iterator_type<T> indirection_type;
|
||||
typedef typename get_iterator_type<T>::type iterator_type;
|
||||
typedef T operator_arg_type;
|
||||
|
||||
static inline iterator_type begin(const T& polygon_set) {
|
||||
return indirection_type::begin(polygon_set);
|
||||
}
|
||||
|
||||
static inline iterator_type end(const T& polygon_set) {
|
||||
return indirection_type::end(polygon_set);
|
||||
}
|
||||
|
||||
static inline orientation_2d orient(const T&) { return HORIZONTAL; }
|
||||
|
||||
static inline bool clean(const T&) { return false; }
|
||||
|
||||
static inline bool sorted(const T&) { return false; }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct is_manhattan_polygonal_concept { typedef gtl_no type; };
|
||||
template <>
|
||||
struct is_manhattan_polygonal_concept<rectangle_concept> { typedef gtl_yes type; };
|
||||
template <>
|
||||
struct is_manhattan_polygonal_concept<polygon_90_concept> { typedef gtl_yes type; };
|
||||
template <>
|
||||
struct is_manhattan_polygonal_concept<polygon_90_with_holes_concept> { typedef gtl_yes type; };
|
||||
template <>
|
||||
struct is_manhattan_polygonal_concept<polygon_90_set_concept> { typedef gtl_yes type; };
|
||||
|
||||
template <typename T>
|
||||
struct is_polygon_90_set_type {
|
||||
typedef typename is_manhattan_polygonal_concept<typename geometry_concept<T>::type>::type type;
|
||||
};
|
||||
template <typename T>
|
||||
struct is_polygon_90_set_type<std::list<T> > {
|
||||
typedef typename gtl_or<
|
||||
typename is_manhattan_polygonal_concept<typename geometry_concept<std::list<T> >::type>::type,
|
||||
typename is_manhattan_polygonal_concept<typename geometry_concept<typename std::list<T>::value_type>::type>::type>::type type;
|
||||
};
|
||||
template <typename T>
|
||||
struct is_polygon_90_set_type<std::vector<T> > {
|
||||
typedef typename gtl_or<
|
||||
typename is_manhattan_polygonal_concept<typename geometry_concept<std::vector<T> >::type>::type,
|
||||
typename is_manhattan_polygonal_concept<typename geometry_concept<typename std::vector<T>::value_type>::type>::type>::type type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct is_mutable_polygon_90_set_type {
|
||||
typedef typename gtl_same_type<polygon_90_set_concept, typename geometry_concept<T>::type>::type type;
|
||||
};
|
||||
template <typename T>
|
||||
struct is_mutable_polygon_90_set_type<std::list<T> > {
|
||||
typedef typename gtl_or<
|
||||
typename gtl_same_type<polygon_90_set_concept, typename geometry_concept<std::list<T> >::type>::type,
|
||||
typename is_manhattan_polygonal_concept<typename geometry_concept<typename std::list<T>::value_type>::type>::type>::type type;
|
||||
};
|
||||
template <typename T>
|
||||
struct is_mutable_polygon_90_set_type<std::vector<T> > {
|
||||
typedef typename gtl_or<
|
||||
typename gtl_same_type<polygon_90_set_concept, typename geometry_concept<std::vector<T> >::type>::type,
|
||||
typename is_manhattan_polygonal_concept<typename geometry_concept<typename std::vector<T>::value_type>::type>::type>::type type;
|
||||
};
|
||||
|
||||
// //specialization for rectangle, polygon_90 and polygon_90_with_holes types
|
||||
// template <typename T>
|
||||
// struct polygon_90_set_traits
|
||||
// typedef typename geometry_concept<T>::type concept_type;
|
||||
// typedef typename get_coordinate_type<T, concept_type>::type coordinate_type;
|
||||
// typedef iterator_geometry_to_set<concept_type, T> iterator_type;
|
||||
// typedef T operator_arg_type;
|
||||
|
||||
// static inline iterator_type begin(const T& polygon_set) {
|
||||
// return iterator_geometry_to_set<concept_type, T>(polygon_set, LOW, HORIZONTAL);
|
||||
// }
|
||||
|
||||
// static inline iterator_type end(const T& polygon_set) {
|
||||
// return iterator_geometry_to_set<concept_type, T>(polygon_set, HIGH, HORIZONTAL);
|
||||
// }
|
||||
|
||||
// static inline orientation_2d orient(const T& polygon_set) { return HORIZONTAL; }
|
||||
|
||||
// static inline bool clean(const T& polygon_set) { return false; }
|
||||
|
||||
// static inline bool sorted(const T& polygon_set) { return false; }
|
||||
|
||||
// };
|
||||
|
||||
// //specialization for containers of recangle, polygon_90, polygon_90_with_holes
|
||||
// template <typename T>
|
||||
// struct polygon_90_set_traits<T, typename is_manhattan_polygonal_concept<typename std::iterator_traits<typename T::iterator>::value_type>::type> {
|
||||
// typedef typename std::iterator_traits<typename T::iterator>::value_type geometry_type;
|
||||
// typedef typename geometry_concept<geometry_type>::type concept_type;
|
||||
// typedef typename get_coordinate_type<geometry_type, concept_type>::type coordinate_type;
|
||||
// typedef iterator_geometry_range_to_set<concept_type, typename T::const_iterator> iterator_type;
|
||||
// typedef T operator_arg_type;
|
||||
|
||||
// static inline iterator_type begin(const T& polygon_set) {
|
||||
// return iterator_type(polygon_set.begin(), HORIZONTAL);
|
||||
// }
|
||||
|
||||
// static inline iterator_type end(const T& polygon_set) {
|
||||
// return iterator_type(polygon_set.end(), HORIZONTAL);
|
||||
// }
|
||||
|
||||
// static inline orientation_2d orient(const T& polygon_set) { return HORIZONTAL; }
|
||||
|
||||
// static inline bool clean(const T& polygon_set) { return false; }
|
||||
|
||||
// static inline bool sorted(const T& polygon_set) { return false; }
|
||||
|
||||
// };
|
||||
|
||||
//get dispatch functions
|
||||
template <typename output_container_type, typename pst>
|
||||
void get_90_dispatch(output_container_type& output, const pst& ps,
|
||||
orientation_2d orient, rectangle_concept ) {
|
||||
form_rectangles(output, ps.begin(), ps.end(), orient, rectangle_concept());
|
||||
}
|
||||
|
||||
template <typename output_container_type, typename pst>
|
||||
void get_90_dispatch(output_container_type& output, const pst& ps,
|
||||
orientation_2d orient, polygon_90_concept tag) {
|
||||
get_polygons(output, ps.begin(), ps.end(), orient, true, tag);
|
||||
}
|
||||
|
||||
template <typename output_container_type, typename pst>
|
||||
void get_90_dispatch(output_container_type& output, const pst& ps,
|
||||
orientation_2d orient, polygon_90_with_holes_concept tag) {
|
||||
get_polygons(output, ps.begin(), ps.end(), orient, false, tag);
|
||||
}
|
||||
|
||||
//by default works with containers of rectangle, polygon or polygon with holes
|
||||
//must be specialized to work with anything else
|
||||
template <typename T>
|
||||
struct polygon_90_set_mutable_traits {};
|
||||
template <typename T>
|
||||
struct polygon_90_set_mutable_traits<std::list<T> > {
|
||||
typedef typename geometry_concept<T>::type concept_type;
|
||||
template <typename input_iterator_type>
|
||||
static inline void set(std::list<T>& polygon_set, input_iterator_type input_begin, input_iterator_type input_end, orientation_2d orient) {
|
||||
polygon_set.clear();
|
||||
polygon_90_set_data<typename polygon_90_set_traits<std::list<T> >::coordinate_type> ps(orient);
|
||||
ps.insert(input_begin, input_end, orient);
|
||||
ps.clean();
|
||||
get_90_dispatch(polygon_set, ps, orient, concept_type());
|
||||
}
|
||||
};
|
||||
template <typename T>
|
||||
struct polygon_90_set_mutable_traits<std::vector<T> > {
|
||||
typedef typename geometry_concept<T>::type concept_type;
|
||||
template <typename input_iterator_type>
|
||||
static inline void set(std::vector<T>& polygon_set, input_iterator_type input_begin, input_iterator_type input_end, orientation_2d orient) {
|
||||
polygon_set.clear();
|
||||
polygon_90_set_data<typename polygon_90_set_traits<std::list<T> >::coordinate_type> ps(orient);
|
||||
ps.insert(input_begin, input_end, orient);
|
||||
ps.clean();
|
||||
get_90_dispatch(polygon_set, ps, orient, concept_type());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct polygon_90_set_mutable_traits<polygon_90_set_data<T> > {
|
||||
|
||||
template <typename input_iterator_type>
|
||||
static inline void set(polygon_90_set_data<T>& polygon_set,
|
||||
input_iterator_type input_begin, input_iterator_type input_end,
|
||||
orientation_2d orient) {
|
||||
polygon_set.clear();
|
||||
polygon_set.insert(input_begin, input_end, orient);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct polygon_90_set_traits<polygon_90_set_data<T> > {
|
||||
typedef typename polygon_90_set_data<T>::coordinate_type coordinate_type;
|
||||
typedef typename polygon_90_set_data<T>::iterator_type iterator_type;
|
||||
typedef typename polygon_90_set_data<T>::operator_arg_type operator_arg_type;
|
||||
|
||||
static inline iterator_type begin(const polygon_90_set_data<T>& polygon_set) {
|
||||
return polygon_set.begin();
|
||||
}
|
||||
|
||||
static inline iterator_type end(const polygon_90_set_data<T>& polygon_set) {
|
||||
return polygon_set.end();
|
||||
}
|
||||
|
||||
static inline orientation_2d orient(const polygon_90_set_data<T>& polygon_set) { return polygon_set.orient(); }
|
||||
|
||||
static inline bool clean(const polygon_90_set_data<T>& polygon_set) { polygon_set.clean(); return true; }
|
||||
|
||||
static inline bool sorted(const polygon_90_set_data<T>& polygon_set) { polygon_set.sort(); return true; }
|
||||
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct is_polygon_90_set_concept { };
|
||||
template <>
|
||||
struct is_polygon_90_set_concept<polygon_90_set_concept> { typedef gtl_yes type; };
|
||||
template <>
|
||||
struct is_polygon_90_set_concept<rectangle_concept> { typedef gtl_yes type; };
|
||||
template <>
|
||||
struct is_polygon_90_set_concept<polygon_90_concept> { typedef gtl_yes type; };
|
||||
template <>
|
||||
struct is_polygon_90_set_concept<polygon_90_with_holes_concept> { typedef gtl_yes type; };
|
||||
|
||||
template <typename T>
|
||||
struct is_mutable_polygon_90_set_concept { typedef gtl_no type; };
|
||||
template <>
|
||||
struct is_mutable_polygon_90_set_concept<polygon_90_set_concept> { typedef gtl_yes type; };
|
||||
|
||||
template <typename T>
|
||||
struct geometry_concept<polygon_90_set_data<T> > { typedef polygon_90_set_concept type; };
|
||||
|
||||
//template <typename T>
|
||||
//typename enable_if<typename is_polygon_90_set_type<T>::type, void>::type
|
||||
//print_is_polygon_90_set_concept(const T& t) { std::cout << "is polygon 90 set concept\n"; }
|
||||
//template <typename T>
|
||||
//typename enable_if<typename is_mutable_polygon_90_set_type<T>::type, void>::type
|
||||
//print_is_mutable_polygon_90_set_concept(const T& t) { std::cout << "is mutable polygon 90 set concept\n"; }
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
Copyright 2008 Intel Corporation
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
*/
|
||||
#ifndef BOOST_POLYGON_POLYGON_90_WITH_HOLES_DATA_HPP
|
||||
#define BOOST_POLYGON_POLYGON_90_WITH_HOLES_DATA_HPP
|
||||
namespace boost { namespace polygon{
|
||||
#include "isotropy.hpp"
|
||||
#include "polygon_90_data.hpp"
|
||||
struct polygon_90_with_holes_concept;
|
||||
template <typename T>
|
||||
class polygon_90_with_holes_data {
|
||||
public:
|
||||
typedef polygon_90_with_holes_concept geometry_type;
|
||||
typedef T coordinate_type;
|
||||
typedef typename polygon_90_data<T>::iterator_type iterator_type;
|
||||
typedef typename polygon_90_data<T>::compact_iterator_type compact_iterator_type;
|
||||
typedef typename std::list<polygon_90_data<coordinate_type> >::const_iterator iterator_holes_type;
|
||||
typedef polygon_90_data<coordinate_type> hole_type;
|
||||
typedef typename coordinate_traits<T>::area_type area_type;
|
||||
typedef point_data<T> point_type;
|
||||
|
||||
// default constructor of point does not initialize x and y
|
||||
inline polygon_90_with_holes_data() : self_(), holes_() {} //do nothing default constructor
|
||||
|
||||
// initialize a polygon from x,y values, it is assumed that the first is an x
|
||||
// and that the input is a well behaved polygon
|
||||
template<class iT>
|
||||
inline polygon_90_with_holes_data& set(iT input_begin, iT input_end) {
|
||||
self_.set(input_begin, input_end);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// initialize a polygon from x,y values, it is assumed that the first is an x
|
||||
// and that the input is a well behaved polygon
|
||||
template<class iT>
|
||||
inline polygon_90_with_holes_data& set_compact(iT input_begin, iT input_end) {
|
||||
self_.set_compact(input_begin, input_end);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// initialize a polygon from x,y values, it is assumed that the first is an x
|
||||
// and that the input is a well behaved polygon
|
||||
template<class iT>
|
||||
inline polygon_90_with_holes_data& set_holes(iT input_begin, iT input_end) {
|
||||
holes_.clear(); //just in case there was some old data there
|
||||
for( ; input_begin != input_end; ++ input_begin) {
|
||||
holes_.push_back(hole_type());
|
||||
holes_.back().set_compact((*input_begin).begin_compact(), (*input_begin).end_compact());
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// copy constructor (since we have dynamic memory)
|
||||
inline polygon_90_with_holes_data(const polygon_90_with_holes_data& that) : self_(that.self_),
|
||||
holes_(that.holes_) {}
|
||||
|
||||
// assignment operator (since we have dynamic memory do a deep copy)
|
||||
inline polygon_90_with_holes_data& operator=(const polygon_90_with_holes_data& that) {
|
||||
self_ = that.self_;
|
||||
holes_ = that.holes_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T2>
|
||||
inline polygon_90_with_holes_data& operator=(const T2& rvalue);
|
||||
|
||||
// get begin iterator, returns a pointer to a const coordinate_type
|
||||
inline const iterator_type begin() const {
|
||||
return self_.begin();
|
||||
}
|
||||
|
||||
// get end iterator, returns a pointer to a const coordinate_type
|
||||
inline const iterator_type end() const {
|
||||
return self_.end();
|
||||
}
|
||||
|
||||
// get begin iterator, returns a pointer to a const coordinate_type
|
||||
inline const compact_iterator_type begin_compact() const {
|
||||
return self_.begin_compact();
|
||||
}
|
||||
|
||||
// get end iterator, returns a pointer to a const coordinate_type
|
||||
inline const compact_iterator_type end_compact() const {
|
||||
return self_.end_compact();
|
||||
}
|
||||
|
||||
inline std::size_t size() const {
|
||||
return self_.size();
|
||||
}
|
||||
|
||||
// get begin iterator, returns a pointer to a const polygon
|
||||
inline const iterator_holes_type begin_holes() const {
|
||||
return holes_.begin();
|
||||
}
|
||||
|
||||
// get end iterator, returns a pointer to a const polygon
|
||||
inline const iterator_holes_type end_holes() const {
|
||||
return holes_.end();
|
||||
}
|
||||
|
||||
inline std::size_t size_holes() const {
|
||||
return holes_.size();
|
||||
}
|
||||
|
||||
private:
|
||||
polygon_90_data<coordinate_type> self_;
|
||||
std::list<hole_type> holes_;
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
Copyright 2008 Intel Corporation
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
*/
|
||||
#ifndef BOOST_POLYGON_POLYGON_DATA_HPP
|
||||
#define BOOST_POLYGON_POLYGON_DATA_HPP
|
||||
namespace boost { namespace polygon{
|
||||
struct polygon_concept;
|
||||
template <typename T>
|
||||
class polygon_data {
|
||||
public:
|
||||
typedef polygon_concept geometry_type;
|
||||
typedef T coordinate_type;
|
||||
typedef typename std::vector<point_data<coordinate_type> >::const_iterator iterator_type;
|
||||
typedef typename coordinate_traits<T>::coordinate_distance area_type;
|
||||
typedef point_data<T> point_type;
|
||||
|
||||
inline polygon_data() : coords_() {} //do nothing default constructor
|
||||
|
||||
template<class iT>
|
||||
inline polygon_data(iT input_begin, iT input_end) : coords_(input_begin, input_end) {}
|
||||
|
||||
template<class iT>
|
||||
inline polygon_data& set(iT input_begin, iT input_end) {
|
||||
coords_.clear(); //just in case there was some old data there
|
||||
coords_.insert(coords_.end(), input_begin, input_end);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// copy constructor (since we have dynamic memory)
|
||||
inline polygon_data(const polygon_data& that) : coords_(that.coords_) {}
|
||||
|
||||
// assignment operator (since we have dynamic memory do a deep copy)
|
||||
inline polygon_data& operator=(const polygon_data& that) {
|
||||
coords_ = that.coords_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T2>
|
||||
inline polygon_data& operator=(const T2& rvalue);
|
||||
|
||||
inline bool operator==(const polygon_data& that) const {
|
||||
if(coords_.size() != that.coords_.size()) return false;
|
||||
for(std::size_t i = 0; i < coords_.size(); ++i) {
|
||||
if(coords_[i] != that.coords_[i]) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool operator!=(const polygon_data& that) const { return !((*this) == that); }
|
||||
|
||||
// get begin iterator, returns a pointer to a const Unit
|
||||
inline iterator_type begin() const { return coords_.begin(); }
|
||||
|
||||
// get end iterator, returns a pointer to a const Unit
|
||||
inline iterator_type end() const { return coords_.end(); }
|
||||
|
||||
inline std::size_t size() const { return coords_.size(); }
|
||||
|
||||
private:
|
||||
std::vector<point_data<coordinate_type> > coords_;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,557 @@
|
|||
/*
|
||||
Copyright 2008 Intel Corporation
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
*/
|
||||
#ifndef BOOST_POLYGON_POLYGON_SET_CONCEPT_HPP
|
||||
#define BOOST_POLYGON_POLYGON_SET_CONCEPT_HPP
|
||||
#include "polygon_set_data.hpp"
|
||||
namespace boost { namespace polygon{
|
||||
|
||||
template <typename T, typename T2>
|
||||
struct is_either_polygon_set_type {
|
||||
typedef typename gtl_or<typename is_polygon_set_type<T>::type, typename is_polygon_set_type<T2>::type >::type type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct is_any_polygon_set_type {
|
||||
typedef typename gtl_or<typename is_polygon_45_or_90_set_type<T>::type, typename is_polygon_set_type<T>::type >::type type;
|
||||
};
|
||||
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_any_polygon_set_type<polygon_set_type>::type,
|
||||
typename polygon_set_traits<polygon_set_type>::iterator_type>::type
|
||||
begin_polygon_set_data(const polygon_set_type& polygon_set) {
|
||||
return polygon_set_traits<polygon_set_type>::begin(polygon_set);
|
||||
}
|
||||
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_any_polygon_set_type<polygon_set_type>::type,
|
||||
typename polygon_set_traits<polygon_set_type>::iterator_type>::type
|
||||
end_polygon_set_data(const polygon_set_type& polygon_set) {
|
||||
return polygon_set_traits<polygon_set_type>::end(polygon_set);
|
||||
}
|
||||
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_polygon_set_type<polygon_set_type>::type,
|
||||
bool>::type
|
||||
clean(const polygon_set_type& polygon_set) {
|
||||
return polygon_set_traits<polygon_set_type>::clean(polygon_set);
|
||||
}
|
||||
|
||||
//assign
|
||||
template <typename polygon_set_type_1, typename polygon_set_type_2>
|
||||
typename enable_if< typename gtl_and<
|
||||
typename is_mutable_polygon_set_type<polygon_set_type_1>::type,
|
||||
typename is_any_polygon_set_type<polygon_set_type_2>::type>::type,
|
||||
polygon_set_type_1>::type &
|
||||
assign(polygon_set_type_1& lvalue, const polygon_set_type_2& rvalue) {
|
||||
if(clean(rvalue))
|
||||
polygon_set_mutable_traits<polygon_set_type_1>::set(lvalue, begin_polygon_set_data(rvalue), end_polygon_set_data(rvalue));
|
||||
else {
|
||||
polygon_set_data<typename polygon_set_traits<polygon_set_type_2>::coordinate_type> ps;
|
||||
ps.insert(begin_polygon_set_data(rvalue), end_polygon_set_data(rvalue));
|
||||
ps.clean();
|
||||
polygon_set_mutable_traits<polygon_set_type_1>::set(lvalue, ps.begin(), ps.end());
|
||||
}
|
||||
return lvalue;
|
||||
}
|
||||
|
||||
//get trapezoids
|
||||
template <typename output_container_type, typename polygon_set_type>
|
||||
typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type,
|
||||
void>::type
|
||||
get_trapezoids(output_container_type& output, const polygon_set_type& polygon_set) {
|
||||
polygon_set_data<typename polygon_set_traits<polygon_set_type>::coordinate_type> ps;
|
||||
assign(ps, polygon_set);
|
||||
ps.get_trapezoids(output);
|
||||
}
|
||||
|
||||
//get trapezoids
|
||||
template <typename output_container_type, typename polygon_set_type>
|
||||
typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type,
|
||||
void>::type
|
||||
get_trapezoids(output_container_type& output, const polygon_set_type& polygon_set,
|
||||
orientation_2d orient) {
|
||||
polygon_set_data<typename polygon_set_traits<polygon_set_type>::coordinate_type> ps;
|
||||
assign(ps, polygon_set);
|
||||
ps.get_trapezoids(output, orient);
|
||||
}
|
||||
|
||||
//equivalence
|
||||
template <typename polygon_set_type_1, typename polygon_set_type_2>
|
||||
typename enable_if< typename gtl_and_3 <
|
||||
typename is_any_polygon_set_type<polygon_set_type_1>::type,
|
||||
typename is_any_polygon_set_type<polygon_set_type_2>::type,
|
||||
typename is_either_polygon_set_type<polygon_set_type_1, polygon_set_type_2>::type>::type,
|
||||
bool>::type
|
||||
equivalence(const polygon_set_type_1& lvalue,
|
||||
const polygon_set_type_2& rvalue) {
|
||||
polygon_set_data<typename polygon_set_traits<polygon_set_type_1>::coordinate_type> ps1;
|
||||
assign(ps1, lvalue);
|
||||
polygon_set_data<typename polygon_set_traits<polygon_set_type_2>::coordinate_type> ps2;
|
||||
assign(ps2, rvalue);
|
||||
return ps1 == ps2;
|
||||
}
|
||||
|
||||
//clear
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type,
|
||||
void>::type
|
||||
clear(polygon_set_type& polygon_set) {
|
||||
polygon_set_data<typename polygon_set_traits<polygon_set_type>::coordinate_type> ps;
|
||||
assign(polygon_set, ps);
|
||||
}
|
||||
|
||||
//empty
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type,
|
||||
bool>::type
|
||||
empty(const polygon_set_type& polygon_set) {
|
||||
if(clean(polygon_set)) return begin_polygon_set_data(polygon_set) == end_polygon_set_data(polygon_set);
|
||||
polygon_set_data<typename polygon_set_traits<polygon_set_type>::coordinate_type> ps;
|
||||
assign(ps, polygon_set);
|
||||
ps.clean();
|
||||
return ps.empty();
|
||||
}
|
||||
|
||||
//extents
|
||||
template <typename polygon_set_type, typename rectangle_type>
|
||||
typename enable_if< typename gtl_and<
|
||||
typename is_mutable_polygon_set_type<polygon_set_type>::type,
|
||||
typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
|
||||
bool>::type
|
||||
extents(rectangle_type& extents_rectangle,
|
||||
const polygon_set_type& polygon_set) {
|
||||
clean(polygon_set);
|
||||
polygon_set_data<typename polygon_set_traits<polygon_set_type>::coordinate_type> ps;
|
||||
assign(ps, polygon_set);
|
||||
return ps.extents(extents_rectangle);
|
||||
}
|
||||
|
||||
//area
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type,
|
||||
typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::area_type>::type
|
||||
area(const polygon_set_type& polygon_set) {
|
||||
typedef typename polygon_set_traits<polygon_set_type>::coordinate_type Unit;
|
||||
typedef polygon_with_holes_data<Unit> p_type;
|
||||
typedef typename coordinate_traits<Unit>::area_type area_type;
|
||||
std::vector<p_type> polys;
|
||||
assign(polys, polygon_set);
|
||||
area_type retval = (area_type)0;
|
||||
for(std::size_t i = 0; i < polys.size(); ++i) {
|
||||
retval += area(polys[i]);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
// TODO: Dafna add ngon parameter passing
|
||||
template <typename polygon_set_type, typename coord_type>
|
||||
typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type,
|
||||
polygon_set_type>::type &
|
||||
resize(polygon_set_type& polygon_set, coord_type resizing, bool corner_fill_arcs = false, int ngon=0) {
|
||||
typedef typename polygon_set_traits<polygon_set_type>::coordinate_type Unit;
|
||||
clean(polygon_set);
|
||||
polygon_set_data<Unit> ps;
|
||||
assign(ps, polygon_set);
|
||||
ps.resize(resizing, corner_fill_arcs,ngon);
|
||||
assign(polygon_set, ps);
|
||||
return polygon_set;
|
||||
}
|
||||
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type,
|
||||
polygon_set_type>::type &
|
||||
bloat(polygon_set_type& polygon_set,
|
||||
typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type bloating) {
|
||||
return resize(polygon_set, bloating);
|
||||
}
|
||||
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type,
|
||||
polygon_set_type>::type &
|
||||
shrink(polygon_set_type& polygon_set,
|
||||
typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type shrinking) {
|
||||
return resize(polygon_set, -(typename polygon_set_traits<polygon_set_type>::coordinate_type)shrinking);
|
||||
}
|
||||
|
||||
//interact
|
||||
template <typename polygon_set_type_1, typename polygon_set_type_2>
|
||||
typename enable_if< typename gtl_and_3 <
|
||||
typename is_any_polygon_set_type<polygon_set_type_1>::type,
|
||||
typename is_any_polygon_set_type<polygon_set_type_2>::type,
|
||||
typename is_either_polygon_set_type<polygon_set_type_1, polygon_set_type_2>::type>::type,
|
||||
polygon_set_type_1>::type&
|
||||
interact(polygon_set_type_1& polygon_set_1, const polygon_set_type_2& polygon_set_2) {
|
||||
polygon_set_data<typename polygon_set_traits<polygon_set_type_1>::coordinate_type> ps1;
|
||||
assign(ps1, polygon_set_1);
|
||||
polygon_set_data<typename polygon_set_traits<polygon_set_type_2>::coordinate_type> ps2;
|
||||
assign(ps2, polygon_set_2);
|
||||
ps1.interact(ps2);
|
||||
assign(polygon_set_1, ps1);
|
||||
return polygon_set_1;
|
||||
}
|
||||
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type,
|
||||
polygon_set_type>::type &
|
||||
scale_up(polygon_set_type& polygon_set,
|
||||
typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type factor) {
|
||||
typedef typename polygon_set_traits<polygon_set_type>::coordinate_type Unit;
|
||||
clean(polygon_set);
|
||||
polygon_set_data<Unit> ps;
|
||||
assign(ps, polygon_set);
|
||||
ps.scale_up(factor);
|
||||
assign(polygon_set, ps);
|
||||
return polygon_set;
|
||||
}
|
||||
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type,
|
||||
polygon_set_type>::type &
|
||||
scale_down(polygon_set_type& polygon_set,
|
||||
typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type factor) {
|
||||
typedef typename polygon_set_traits<polygon_set_type>::coordinate_type Unit;
|
||||
clean(polygon_set);
|
||||
polygon_set_data<Unit> ps;
|
||||
assign(ps, polygon_set);
|
||||
ps.scale_down(factor);
|
||||
assign(polygon_set, ps);
|
||||
return polygon_set;
|
||||
}
|
||||
|
||||
//transform
|
||||
template <typename polygon_set_type, typename transformation_type>
|
||||
typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type,
|
||||
polygon_set_type>::type &
|
||||
transform(polygon_set_type& polygon_set,
|
||||
const transformation_type& transformation) {
|
||||
typedef typename polygon_set_traits<polygon_set_type>::coordinate_type Unit;
|
||||
clean(polygon_set);
|
||||
polygon_set_data<Unit> ps;
|
||||
assign(ps, polygon_set);
|
||||
ps.transform(transformation);
|
||||
assign(polygon_set, ps);
|
||||
return polygon_set;
|
||||
}
|
||||
|
||||
//keep
|
||||
template <typename polygon_set_type>
|
||||
typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type,
|
||||
polygon_set_type>::type &
|
||||
keep(polygon_set_type& polygon_set,
|
||||
typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::area_type min_area,
|
||||
typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::area_type max_area,
|
||||
typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type min_width,
|
||||
typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type max_width,
|
||||
typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type min_height,
|
||||
typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type max_height) {
|
||||
typedef typename polygon_set_traits<polygon_set_type>::coordinate_type Unit;
|
||||
typedef typename coordinate_traits<Unit>::unsigned_area_type uat;
|
||||
std::list<polygon_with_holes_data<Unit> > polys;
|
||||
assign(polys, polygon_set);
|
||||
typename std::list<polygon_with_holes_data<Unit> >::iterator itr_nxt;
|
||||
for(typename std::list<polygon_with_holes_data<Unit> >::iterator itr = polys.begin(); itr != polys.end(); itr = itr_nxt){
|
||||
itr_nxt = itr;
|
||||
++itr_nxt;
|
||||
rectangle_data<Unit> bbox;
|
||||
extents(bbox, *itr);
|
||||
uat pwidth = delta(bbox, HORIZONTAL);
|
||||
if(pwidth > min_width && pwidth <= max_width){
|
||||
uat pheight = delta(bbox, VERTICAL);
|
||||
if(pheight > min_height && pheight <= max_height){
|
||||
typename coordinate_traits<Unit>::area_type parea = area(*itr);
|
||||
if(parea <= max_area && parea >= min_area) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
polys.erase(itr);
|
||||
}
|
||||
assign(polygon_set, polys);
|
||||
return polygon_set;
|
||||
}
|
||||
|
||||
namespace operators {
|
||||
|
||||
struct yes_ps_ob : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename geometry_type_2>
|
||||
typename enable_if< typename gtl_and_4 < yes_ps_ob, typename is_any_polygon_set_type<geometry_type_1>::type,
|
||||
typename is_any_polygon_set_type<geometry_type_2>::type,
|
||||
typename is_either_polygon_set_type<geometry_type_1, geometry_type_2>::type>::type,
|
||||
polygon_set_view<geometry_type_1, geometry_type_2, 0> >::type
|
||||
operator|(const geometry_type_1& lvalue, const geometry_type_2& rvalue) {
|
||||
return polygon_set_view<geometry_type_1, geometry_type_2, 0>
|
||||
(lvalue, rvalue);
|
||||
}
|
||||
|
||||
struct yes_ps_op : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename geometry_type_2>
|
||||
typename enable_if< typename gtl_and_4 < yes_ps_op,
|
||||
typename gtl_if<typename is_any_polygon_set_type<geometry_type_1>::type>::type,
|
||||
typename gtl_if<typename is_any_polygon_set_type<geometry_type_2>::type>::type,
|
||||
typename gtl_if<typename is_either_polygon_set_type<geometry_type_1, geometry_type_2>::type>::type>
|
||||
::type, polygon_set_view<geometry_type_1, geometry_type_2, 0> >::type
|
||||
operator+(const geometry_type_1& lvalue, const geometry_type_2& rvalue) {
|
||||
return polygon_set_view<geometry_type_1, geometry_type_2, 0>
|
||||
(lvalue, rvalue);
|
||||
}
|
||||
|
||||
struct yes_ps_os : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename geometry_type_2>
|
||||
typename enable_if< typename gtl_and_4 < yes_ps_os,
|
||||
typename is_any_polygon_set_type<geometry_type_1>::type,
|
||||
typename is_any_polygon_set_type<geometry_type_2>::type,
|
||||
typename is_either_polygon_set_type<geometry_type_1, geometry_type_2>::type>::type,
|
||||
polygon_set_view<geometry_type_1, geometry_type_2, 1> >::type
|
||||
operator*(const geometry_type_1& lvalue, const geometry_type_2& rvalue) {
|
||||
return polygon_set_view<geometry_type_1, geometry_type_2, 1>
|
||||
(lvalue, rvalue);
|
||||
}
|
||||
|
||||
struct yes_ps_oa : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename geometry_type_2>
|
||||
typename enable_if< typename gtl_and_4 < yes_ps_oa,
|
||||
typename is_any_polygon_set_type<geometry_type_1>::type,
|
||||
typename is_any_polygon_set_type<geometry_type_2>::type,
|
||||
typename is_either_polygon_set_type<geometry_type_1, geometry_type_2>::type>::type,
|
||||
polygon_set_view<geometry_type_1, geometry_type_2, 1> >::type
|
||||
operator&(const geometry_type_1& lvalue, const geometry_type_2& rvalue) {
|
||||
return polygon_set_view<geometry_type_1, geometry_type_2, 1>
|
||||
(lvalue, rvalue);
|
||||
}
|
||||
|
||||
struct yes_ps_ox : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename geometry_type_2>
|
||||
typename enable_if< typename gtl_and_4 < yes_ps_ox,
|
||||
typename is_any_polygon_set_type<geometry_type_1>::type,
|
||||
typename is_any_polygon_set_type<geometry_type_2>::type,
|
||||
typename is_either_polygon_set_type<geometry_type_1, geometry_type_2>::type>::type,
|
||||
polygon_set_view<geometry_type_1, geometry_type_2, 2> >::type
|
||||
operator^(const geometry_type_1& lvalue, const geometry_type_2& rvalue) {
|
||||
return polygon_set_view<geometry_type_1, geometry_type_2, 2>
|
||||
(lvalue, rvalue);
|
||||
}
|
||||
|
||||
struct yes_ps_om : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename geometry_type_2>
|
||||
typename enable_if< typename gtl_and_4 < yes_ps_om,
|
||||
typename gtl_if<typename is_any_polygon_set_type<geometry_type_1>::type>::type,
|
||||
typename gtl_if<typename is_any_polygon_set_type<geometry_type_2>::type>::type,
|
||||
typename gtl_if<typename is_either_polygon_set_type<geometry_type_1, geometry_type_2>::type>::type>
|
||||
::type, polygon_set_view<geometry_type_1, geometry_type_2, 3> >::type
|
||||
operator-(const geometry_type_1& lvalue, const geometry_type_2& rvalue) {
|
||||
return polygon_set_view<geometry_type_1, geometry_type_2, 3>
|
||||
(lvalue, rvalue);
|
||||
}
|
||||
|
||||
struct yes_ps_ope : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename geometry_type_2>
|
||||
typename enable_if< typename gtl_and_4< yes_ps_ope, gtl_yes, typename is_mutable_polygon_set_type<geometry_type_1>::type,
|
||||
typename is_any_polygon_set_type<geometry_type_2>::type>::type,
|
||||
geometry_type_1>::type &
|
||||
operator+=(geometry_type_1& lvalue, const geometry_type_2& rvalue) {
|
||||
return self_assignment_boolean_op<geometry_type_1, geometry_type_2, 0>(lvalue, rvalue);
|
||||
}
|
||||
|
||||
struct yes_ps_obe : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename geometry_type_2>
|
||||
typename enable_if< typename gtl_and_3< yes_ps_obe, typename is_mutable_polygon_set_type<geometry_type_1>::type,
|
||||
typename is_any_polygon_set_type<geometry_type_2>::type>::type,
|
||||
geometry_type_1>::type &
|
||||
operator|=(geometry_type_1& lvalue, const geometry_type_2& rvalue) {
|
||||
return self_assignment_boolean_op<geometry_type_1, geometry_type_2, 0>(lvalue, rvalue);
|
||||
}
|
||||
|
||||
struct yes_ps_ose : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename geometry_type_2>
|
||||
typename enable_if< typename gtl_and_3< yes_ps_ose, typename is_mutable_polygon_set_type<geometry_type_1>::type,
|
||||
typename is_any_polygon_set_type<geometry_type_2>::type>::type,
|
||||
geometry_type_1>::type &
|
||||
operator*=(geometry_type_1& lvalue, const geometry_type_2& rvalue) {
|
||||
return self_assignment_boolean_op<geometry_type_1, geometry_type_2, 1>(lvalue, rvalue);
|
||||
}
|
||||
|
||||
struct yes_ps_oae : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename geometry_type_2>
|
||||
typename enable_if<
|
||||
typename gtl_and_3< yes_ps_oae, typename is_mutable_polygon_set_type<geometry_type_1>::type,
|
||||
typename is_any_polygon_set_type<geometry_type_2>::type>::type,
|
||||
geometry_type_1>::type &
|
||||
operator&=(geometry_type_1& lvalue, const geometry_type_2& rvalue) {
|
||||
return self_assignment_boolean_op<geometry_type_1, geometry_type_2, 1>(lvalue, rvalue);
|
||||
}
|
||||
|
||||
struct yes_ps_oxe : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename geometry_type_2>
|
||||
typename enable_if< typename gtl_and_3< yes_ps_oxe, typename is_mutable_polygon_set_type<geometry_type_1>::type,
|
||||
typename is_any_polygon_set_type<geometry_type_2>::type>::type,
|
||||
geometry_type_1>::type &
|
||||
operator^=(geometry_type_1& lvalue, const geometry_type_2& rvalue) {
|
||||
return self_assignment_boolean_op<geometry_type_1, geometry_type_2, 2>(lvalue, rvalue);
|
||||
}
|
||||
|
||||
struct yes_ps_ome : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename geometry_type_2>
|
||||
typename enable_if<
|
||||
typename gtl_and_3< yes_ps_ome, typename is_mutable_polygon_set_type<geometry_type_1>::type,
|
||||
typename is_any_polygon_set_type<geometry_type_2>::type>::type,
|
||||
geometry_type_1>::type &
|
||||
operator-=(geometry_type_1& lvalue, const geometry_type_2& rvalue) {
|
||||
return self_assignment_boolean_op<geometry_type_1, geometry_type_2, 3>(lvalue, rvalue);
|
||||
}
|
||||
|
||||
// TODO: Dafna, test these four resizing operators
|
||||
struct y_ps_rpe : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename coordinate_type_1>
|
||||
typename enable_if< typename gtl_and_3< y_ps_rpe, typename is_mutable_polygon_set_type<geometry_type_1>::type,
|
||||
typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type,
|
||||
coordinate_concept>::type>::type,
|
||||
geometry_type_1>::type &
|
||||
operator+=(geometry_type_1& lvalue, coordinate_type_1 rvalue) {
|
||||
return resize(lvalue, rvalue);
|
||||
}
|
||||
|
||||
struct y_ps_rme : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename coordinate_type_1>
|
||||
typename enable_if< typename gtl_and_3<y_ps_rme, typename gtl_if<typename is_mutable_polygon_set_type<geometry_type_1>::type>::type,
|
||||
typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type,
|
||||
coordinate_concept>::type>::type,
|
||||
geometry_type_1>::type &
|
||||
operator-=(geometry_type_1& lvalue, coordinate_type_1 rvalue) {
|
||||
return resize(lvalue, -rvalue);
|
||||
}
|
||||
|
||||
struct y_ps_rp : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename coordinate_type_1>
|
||||
typename enable_if< typename gtl_and_3<y_ps_rp, typename gtl_if<typename is_mutable_polygon_set_type<geometry_type_1>::type>::type,
|
||||
typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type,
|
||||
coordinate_concept>::type>
|
||||
::type, geometry_type_1>::type
|
||||
operator+(const geometry_type_1& lvalue, coordinate_type_1 rvalue) {
|
||||
geometry_type_1 retval(lvalue);
|
||||
retval += rvalue;
|
||||
return retval;
|
||||
}
|
||||
|
||||
struct y_ps_rm : gtl_yes {};
|
||||
|
||||
template <typename geometry_type_1, typename coordinate_type_1>
|
||||
typename enable_if< typename gtl_and_3<y_ps_rm, typename gtl_if<typename is_mutable_polygon_set_type<geometry_type_1>::type>::type,
|
||||
typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type,
|
||||
coordinate_concept>::type>
|
||||
::type, geometry_type_1>::type
|
||||
operator-(const geometry_type_1& lvalue, coordinate_type_1 rvalue) {
|
||||
geometry_type_1 retval(lvalue);
|
||||
retval -= rvalue;
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
} //end operators namespace
|
||||
|
||||
template <typename T>
|
||||
struct view_of<polygon_45_set_concept, T> {
|
||||
typedef typename get_coordinate_type<T, typename geometry_concept<T>::type >::type coordinate_type;
|
||||
T* tp;
|
||||
std::vector<polygon_45_with_holes_data<coordinate_type> > polys;
|
||||
view_of(const T& obj) : tp(), polys() {
|
||||
std::vector<polygon_with_holes_data<coordinate_type> > gpolys;
|
||||
assign(gpolys, obj);
|
||||
for(typename std::vector<polygon_with_holes_data<coordinate_type> >::iterator itr = gpolys.begin();
|
||||
itr != gpolys.end(); ++itr) {
|
||||
polys.push_back(polygon_45_with_holes_data<coordinate_type>());
|
||||
assign(polys.back(), view_as<polygon_45_with_holes_concept>(*itr));
|
||||
}
|
||||
}
|
||||
view_of(T& obj) : tp(&obj), polys() {
|
||||
std::vector<polygon_with_holes_data<coordinate_type> > gpolys;
|
||||
assign(gpolys, obj);
|
||||
for(typename std::vector<polygon_with_holes_data<coordinate_type> >::iterator itr = gpolys.begin();
|
||||
itr != gpolys.end(); ++itr) {
|
||||
polys.push_back(polygon_45_with_holes_data<coordinate_type>());
|
||||
assign(polys.back(), view_as<polygon_45_with_holes_concept>(*itr));
|
||||
}
|
||||
}
|
||||
|
||||
typedef typename std::vector<polygon_45_with_holes_data<coordinate_type> >::const_iterator iterator_type;
|
||||
typedef view_of operator_arg_type;
|
||||
|
||||
inline iterator_type begin() const {
|
||||
return polys.begin();
|
||||
}
|
||||
|
||||
inline iterator_type end() const {
|
||||
return polys.end();
|
||||
}
|
||||
|
||||
inline orientation_2d orient() const { return HORIZONTAL; }
|
||||
|
||||
inline bool clean() const { return false; }
|
||||
|
||||
inline bool sorted() const { return false; }
|
||||
|
||||
inline T& get() { return *tp; }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct polygon_45_set_traits<view_of<polygon_45_set_concept, T> > {
|
||||
typedef typename view_of<polygon_45_set_concept, T>::coordinate_type coordinate_type;
|
||||
typedef typename view_of<polygon_45_set_concept, T>::iterator_type iterator_type;
|
||||
typedef view_of<polygon_45_set_concept, T> operator_arg_type;
|
||||
|
||||
static inline iterator_type begin(const view_of<polygon_45_set_concept, T>& polygon_set) {
|
||||
return polygon_set.begin();
|
||||
}
|
||||
|
||||
static inline iterator_type end(const view_of<polygon_45_set_concept, T>& polygon_set) {
|
||||
return polygon_set.end();
|
||||
}
|
||||
|
||||
static inline orientation_2d orient(const view_of<polygon_45_set_concept, T>& polygon_set) {
|
||||
return polygon_set.orient(); }
|
||||
|
||||
static inline bool clean(const view_of<polygon_45_set_concept, T>& polygon_set) {
|
||||
return polygon_set.clean(); }
|
||||
|
||||
static inline bool sorted(const view_of<polygon_45_set_concept, T>& polygon_set) {
|
||||
return polygon_set.sorted(); }
|
||||
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct geometry_concept<view_of<polygon_45_set_concept, T> > {
|
||||
typedef polygon_45_set_concept type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct get_coordinate_type<view_of<polygon_45_set_concept, T>, polygon_45_set_concept> {
|
||||
typedef typename view_of<polygon_45_set_concept, T>::coordinate_type type;
|
||||
};
|
||||
template <typename T>
|
||||
struct get_iterator_type_2<view_of<polygon_45_set_concept, T>, polygon_45_set_concept> {
|
||||
typedef typename view_of<polygon_45_set_concept, T>::iterator_type type;
|
||||
static type begin(const view_of<polygon_45_set_concept, T>& t) { return t.begin(); }
|
||||
static type end(const view_of<polygon_45_set_concept, T>& t) { return t.end(); }
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,860 @@
|
|||
/*
|
||||
Copyright 2008 Intel Corporation
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
*/
|
||||
#ifndef BOOST_POLYGON_POLYGON_SET_DATA_HPP
|
||||
#define BOOST_POLYGON_POLYGON_SET_DATA_HPP
|
||||
#include "polygon_45_set_data.hpp"
|
||||
#include "polygon_45_set_concept.hpp"
|
||||
#include "polygon_traits.hpp"
|
||||
#include "detail/polygon_arbitrary_formation.hpp"
|
||||
#include <iostream>
|
||||
|
||||
namespace boost { namespace polygon {
|
||||
|
||||
|
||||
// utility function to round coordinate types down
|
||||
// rounds down for both negative and positive numbers
|
||||
// intended really for integer type T (does not make sense for float)
|
||||
template <typename T>
|
||||
static inline T round_down(double val) {
|
||||
T rounded_val = (T)(val);
|
||||
if(val < (double)rounded_val)
|
||||
--rounded_val;
|
||||
return rounded_val;
|
||||
}
|
||||
template <typename T>
|
||||
static inline point_data<T> round_down(point_data<double> v) {
|
||||
return point_data<T>(round_down<T>(v.x()),round_down<T>(v.y()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
//foward declare view
|
||||
template <typename ltype, typename rtype, int op_type> class polygon_set_view;
|
||||
|
||||
template <typename T>
|
||||
class polygon_set_data {
|
||||
public:
|
||||
typedef T coordinate_type;
|
||||
typedef point_data<T> point_type;
|
||||
typedef std::pair<point_type, point_type> edge_type;
|
||||
typedef std::pair<edge_type, int> element_type;
|
||||
typedef std::vector<element_type> value_type;
|
||||
typedef typename value_type::const_iterator iterator_type;
|
||||
typedef polygon_set_data operator_arg_type;
|
||||
|
||||
// default constructor
|
||||
inline polygon_set_data() : data_(), dirty_(false), unsorted_(false), is_45_(true) {}
|
||||
|
||||
// constructor from an iterator pair over edge data
|
||||
template <typename iT>
|
||||
inline polygon_set_data(iT input_begin, iT input_end) : data_(), dirty_(false), unsorted_(false), is_45_(true) {
|
||||
for( ; input_begin != input_end; ++input_begin) { insert(*input_begin); }
|
||||
}
|
||||
|
||||
// copy constructor
|
||||
inline polygon_set_data(const polygon_set_data& that) :
|
||||
data_(that.data_), dirty_(that.dirty_), unsorted_(that.unsorted_), is_45_(that.is_45_) {}
|
||||
|
||||
// copy constructor
|
||||
template <typename ltype, typename rtype, int op_type>
|
||||
inline polygon_set_data(const polygon_set_view<ltype, rtype, op_type>& that);
|
||||
|
||||
// destructor
|
||||
inline ~polygon_set_data() {}
|
||||
|
||||
// assignement operator
|
||||
inline polygon_set_data& operator=(const polygon_set_data& that) {
|
||||
if(this == &that) return *this;
|
||||
data_ = that.data_;
|
||||
dirty_ = that.dirty_;
|
||||
unsorted_ = that.unsorted_;
|
||||
is_45_ = that.is_45_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename ltype, typename rtype, int op_type>
|
||||
inline polygon_set_data& operator=(const polygon_set_view<ltype, rtype, op_type>& geometry) {
|
||||
(*this) = geometry.value();
|
||||
dirty_ = false;
|
||||
unsorted_ = false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename geometry_object>
|
||||
inline polygon_set_data& operator=(const geometry_object& geometry) {
|
||||
data_.clear();
|
||||
insert(geometry);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
// insert iterator range
|
||||
inline void insert(iterator_type input_begin, iterator_type input_end, bool is_hole = false) {
|
||||
if(input_begin == input_end || (!data_.empty() && &(*input_begin) == &(*(data_.begin())))) return;
|
||||
dirty_ = true;
|
||||
unsorted_ = true;
|
||||
while(input_begin != input_end) {
|
||||
insert(*input_begin, is_hole);
|
||||
++input_begin;
|
||||
}
|
||||
}
|
||||
|
||||
// insert iterator range
|
||||
template <typename iT>
|
||||
inline void insert(iT input_begin, iT input_end, bool is_hole = false) {
|
||||
if(input_begin == input_end) return;
|
||||
for(; input_begin != input_end; ++input_begin) {
|
||||
insert(*input_begin, is_hole);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename geometry_type>
|
||||
inline void insert(const geometry_type& geometry_object, bool is_hole = false) {
|
||||
insert(geometry_object, is_hole, typename geometry_concept<geometry_type>::type());
|
||||
}
|
||||
|
||||
template <typename polygon_type>
|
||||
inline void insert(const polygon_type& polygon_object, bool is_hole, polygon_concept ) {
|
||||
bool first_iteration = true;
|
||||
point_type first_point;
|
||||
point_type previous_point;
|
||||
point_type current_point;
|
||||
direction_1d winding_dir = winding(polygon_object);
|
||||
int multiplier = winding_dir == COUNTERCLOCKWISE ? 1 : -1;
|
||||
if(is_hole) multiplier *= -1;
|
||||
for(typename polygon_traits<polygon_type>::iterator_type itr = begin_points(polygon_object);
|
||||
itr != end_points(polygon_object); ++itr) {
|
||||
assign(current_point, *itr);
|
||||
if(first_iteration) {
|
||||
first_iteration = false;
|
||||
first_point = previous_point = current_point;
|
||||
} else {
|
||||
if(previous_point != current_point) {
|
||||
element_type elem(edge_type(previous_point, current_point),
|
||||
( previous_point.get(HORIZONTAL) == current_point.get(HORIZONTAL) ? -1 : 1) * multiplier);
|
||||
insert_clean(elem);
|
||||
}
|
||||
}
|
||||
previous_point = current_point;
|
||||
}
|
||||
current_point = first_point;
|
||||
if(!first_iteration) {
|
||||
if(previous_point != current_point) {
|
||||
element_type elem(edge_type(previous_point, current_point),
|
||||
( previous_point.get(HORIZONTAL) == current_point.get(HORIZONTAL) ? -1 : 1) * multiplier);
|
||||
insert_clean(elem);
|
||||
}
|
||||
dirty_ = true;
|
||||
unsorted_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
inline void insert(const polygon_set_data& ps, bool is_hole = false) {
|
||||
insert(ps.data_.begin(), ps.data_.end(), is_hole);
|
||||
}
|
||||
|
||||
template <typename polygon_45_set_type>
|
||||
inline void insert(const polygon_45_set_type& ps, bool is_hole, polygon_45_set_concept) {
|
||||
std::vector<polygon_45_with_holes_data<typename polygon_45_set_traits<polygon_45_set_type>::coordinate_type> > polys;
|
||||
assign(polys, ps);
|
||||
insert(polys.begin(), polys.end(), is_hole);
|
||||
}
|
||||
|
||||
template <typename polygon_90_set_type>
|
||||
inline void insert(const polygon_90_set_type& ps, bool is_hole, polygon_90_set_concept) {
|
||||
std::vector<polygon_90_with_holes_data<typename polygon_90_set_traits<polygon_90_set_type>::coordinate_type> > polys;
|
||||
assign(polys, ps);
|
||||
insert(polys.begin(), polys.end(), is_hole);
|
||||
}
|
||||
|
||||
template <typename polygon_type>
|
||||
inline void insert(const polygon_type& polygon_object, bool is_hole, polygon_45_concept ) {
|
||||
insert(polygon_object, is_hole, polygon_concept()); }
|
||||
|
||||
template <typename polygon_type>
|
||||
inline void insert(const polygon_type& polygon_object, bool is_hole, polygon_90_concept ) {
|
||||
insert(polygon_object, is_hole, polygon_concept()); }
|
||||
|
||||
template <typename polygon_with_holes_type>
|
||||
inline void insert(const polygon_with_holes_type& polygon_with_holes_object, bool is_hole,
|
||||
polygon_with_holes_concept ) {
|
||||
insert(polygon_with_holes_object, is_hole, polygon_concept());
|
||||
for(typename polygon_with_holes_traits<polygon_with_holes_type>::iterator_holes_type itr =
|
||||
begin_holes(polygon_with_holes_object);
|
||||
itr != end_holes(polygon_with_holes_object); ++itr) {
|
||||
insert(*itr, !is_hole, polygon_concept());
|
||||
}
|
||||
}
|
||||
|
||||
template <typename polygon_with_holes_type>
|
||||
inline void insert(const polygon_with_holes_type& polygon_with_holes_object, bool is_hole,
|
||||
polygon_45_with_holes_concept ) {
|
||||
insert(polygon_with_holes_object, is_hole, polygon_with_holes_concept()); }
|
||||
|
||||
template <typename polygon_with_holes_type>
|
||||
inline void insert(const polygon_with_holes_type& polygon_with_holes_object, bool is_hole,
|
||||
polygon_90_with_holes_concept ) {
|
||||
insert(polygon_with_holes_object, is_hole, polygon_with_holes_concept()); }
|
||||
|
||||
template <typename rectangle_type>
|
||||
inline void insert(const rectangle_type& rectangle_object, bool is_hole, rectangle_concept ) {
|
||||
polygon_90_data<coordinate_type> poly;
|
||||
assign(poly, rectangle_object);
|
||||
insert(poly, is_hole, polygon_concept());
|
||||
}
|
||||
|
||||
inline void insert_clean(const element_type& edge, bool is_hole = false) {
|
||||
if( ! scanline_base<coordinate_type>::is_45_degree(edge.first) &&
|
||||
! scanline_base<coordinate_type>::is_horizontal(edge.first) &&
|
||||
! scanline_base<coordinate_type>::is_vertical(edge.first) ) is_45_ = false;
|
||||
data_.push_back(edge);
|
||||
if(data_.back().first.second < data_.back().first.first) {
|
||||
std::swap(data_.back().first.second, data_.back().first.first);
|
||||
data_.back().second *= -1;
|
||||
}
|
||||
if(is_hole)
|
||||
data_.back().second *= -1;
|
||||
}
|
||||
|
||||
inline void insert(const element_type& edge, bool is_hole = false) {
|
||||
insert_clean(edge, is_hole);
|
||||
dirty_ = true;
|
||||
unsorted_ = true;
|
||||
}
|
||||
|
||||
template <class iT>
|
||||
inline void insert_vertex_sequence(iT begin_vertex, iT end_vertex, direction_1d winding, bool is_hole) {
|
||||
polygon_data<coordinate_type> poly;
|
||||
poly.set(begin_vertex, end_vertex);
|
||||
insert(poly, is_hole);
|
||||
}
|
||||
|
||||
template <typename output_container>
|
||||
inline void get(output_container& output) const {
|
||||
get_dispatch(output, typename geometry_concept<typename output_container::value_type>::type());
|
||||
}
|
||||
|
||||
// append to the container cT with polygons of three or four verticies
|
||||
// slicing orientation is vertical
|
||||
template <class cT>
|
||||
void get_trapezoids(cT& container) const {
|
||||
clean();
|
||||
trapezoid_arbitrary_formation<coordinate_type> pf;
|
||||
typedef typename polygon_arbitrary_formation<coordinate_type>::vertex_half_edge vertex_half_edge;
|
||||
std::vector<vertex_half_edge> data;
|
||||
for(iterator_type itr = data_.begin(); itr != data_.end(); ++itr){
|
||||
data.push_back(vertex_half_edge((*itr).first.first, (*itr).first.second, (*itr).second));
|
||||
data.push_back(vertex_half_edge((*itr).first.second, (*itr).first.first, -1 * (*itr).second));
|
||||
}
|
||||
std::sort(data.begin(), data.end());
|
||||
pf.scan(container, data.begin(), data.end());
|
||||
//std::cout << "DONE FORMING POLYGONS\n";
|
||||
}
|
||||
|
||||
// append to the container cT with polygons of three or four verticies
|
||||
template <class cT>
|
||||
void get_trapezoids(cT& container, orientation_2d slicing_orientation) const {
|
||||
if(slicing_orientation == VERTICAL) {
|
||||
get_trapezoids(container);
|
||||
} else {
|
||||
polygon_set_data<T> ps(*this);
|
||||
ps.transform(axis_transformation(axis_transformation::SWAP_XY));
|
||||
cT result;
|
||||
ps.get_trapezoids(result);
|
||||
for(typename cT::iterator itr = result.begin(); itr != result.end(); ++itr) {
|
||||
::boost::polygon::transform(*itr, axis_transformation(axis_transformation::SWAP_XY));
|
||||
}
|
||||
container.insert(container.end(), result.begin(), result.end());
|
||||
}
|
||||
}
|
||||
|
||||
// equivalence operator
|
||||
inline bool operator==(const polygon_set_data& p) const {
|
||||
clean();
|
||||
p.clean();
|
||||
return data_ == p.data_;
|
||||
}
|
||||
|
||||
// inequivalence operator
|
||||
inline bool operator!=(const polygon_set_data& p) const {
|
||||
return !((*this) == p);
|
||||
}
|
||||
|
||||
// get iterator to begin vertex data
|
||||
inline iterator_type begin() const {
|
||||
return data_.begin();
|
||||
}
|
||||
|
||||
// get iterator to end vertex data
|
||||
inline iterator_type end() const {
|
||||
return data_.end();
|
||||
}
|
||||
|
||||
const value_type& value() const {
|
||||
return data_;
|
||||
}
|
||||
|
||||
// clear the contents of the polygon_set_data
|
||||
inline void clear() { data_.clear(); dirty_ = unsorted_ = false; }
|
||||
|
||||
// find out if Polygon set is empty
|
||||
inline bool empty() const { return data_.empty(); }
|
||||
|
||||
// get the Polygon set size in vertices
|
||||
inline std::size_t size() const { clean(); return data_.size(); }
|
||||
|
||||
// get the current Polygon set capacity in vertices
|
||||
inline std::size_t capacity() const { return data_.capacity(); }
|
||||
|
||||
// reserve size of polygon set in vertices
|
||||
inline void reserve(std::size_t size) { return data_.reserve(size); }
|
||||
|
||||
// find out if Polygon set is sorted
|
||||
inline bool sorted() const { return !unsorted_; }
|
||||
|
||||
// find out if Polygon set is clean
|
||||
inline bool dirty() const { return dirty_; }
|
||||
|
||||
void clean() const;
|
||||
|
||||
void sort() const{
|
||||
if(unsorted_) {
|
||||
std::sort(data_.begin(), data_.end());
|
||||
unsorted_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename input_iterator_type>
|
||||
void set(input_iterator_type input_begin, input_iterator_type input_end) {
|
||||
clear();
|
||||
insert(input_begin, input_end);
|
||||
dirty_ = true;
|
||||
unsorted_ = true;
|
||||
}
|
||||
|
||||
void set(const value_type& value) {
|
||||
data_ = value;
|
||||
dirty_ = true;
|
||||
unsorted_ = true;
|
||||
}
|
||||
|
||||
template <typename rectangle_type>
|
||||
bool extents(rectangle_type& rect) {
|
||||
clean();
|
||||
if(empty()) return false;
|
||||
bool first_iteration = true;
|
||||
for(iterator_type itr = begin();
|
||||
itr != end(); ++itr) {
|
||||
rectangle_type edge_box;
|
||||
set_points(edge_box, (*itr).first.first, (*itr).first.second);
|
||||
if(first_iteration)
|
||||
rect = edge_box;
|
||||
else
|
||||
encompass(rect, edge_box);
|
||||
first_iteration = false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline polygon_set_data&
|
||||
resize(coordinate_type resizing, bool corner_fill_arc = false, unsigned int num_circle_segments=0) {
|
||||
if(resizing == 0) return *this;
|
||||
std::list<polygon_with_holes_data<coordinate_type> > pl;
|
||||
get(pl);
|
||||
clear();
|
||||
for(typename std::list<polygon_with_holes_data<coordinate_type> >::iterator itr = pl.begin(); itr != pl.end(); ++itr) {
|
||||
insert_with_resize(*itr, resizing, corner_fill_arc, num_circle_segments);
|
||||
}
|
||||
clean();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename transform_type>
|
||||
inline polygon_set_data&
|
||||
transform(const transform_type& tr) {
|
||||
std::vector<polygon_with_holes_data<T> > polys;
|
||||
get(polys);
|
||||
clear();
|
||||
for(std::size_t i = 0 ; i < polys.size(); ++i) {
|
||||
::boost::polygon::transform(polys[i], tr);
|
||||
insert(polys[i]);
|
||||
}
|
||||
unsorted_ = true;
|
||||
dirty_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline polygon_set_data&
|
||||
scale_up(typename coordinate_traits<coordinate_type>::unsigned_area_type factor) {
|
||||
for(typename value_type::iterator itr = data_.begin(); itr != data_.end(); ++itr) {
|
||||
::boost::polygon::scale_up((*itr).first.first, factor);
|
||||
::boost::polygon::scale_up((*itr).first.second, factor);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline polygon_set_data&
|
||||
scale_down(typename coordinate_traits<coordinate_type>::unsigned_area_type factor) {
|
||||
for(typename value_type::iterator itr = data_.begin(); itr != data_.end(); ++itr) {
|
||||
::boost::polygon::scale_down((*itr).first.first, factor);
|
||||
::boost::polygon::scale_down((*itr).first.second, factor);
|
||||
}
|
||||
unsorted_ = true;
|
||||
dirty_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename scaling_type>
|
||||
inline polygon_set_data& scale(polygon_set_data& polygon_set,
|
||||
const scaling_type& scaling) {
|
||||
for(typename value_type::iterator itr = begin(); itr != end(); ++itr) {
|
||||
::boost::polygon::scale((*itr).first.first, scaling);
|
||||
::boost::polygon::scale((*itr).first.second, scaling);
|
||||
}
|
||||
unsorted_ = true;
|
||||
dirty_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// TODO:: should be private
|
||||
template <typename geometry_type>
|
||||
inline polygon_set_data&
|
||||
insert_with_resize(const geometry_type& poly, coordinate_type resizing, bool corner_fill_arc=false, unsigned int num_circle_segments=0, bool hole = false) {
|
||||
return insert_with_resize_dispatch(poly, resizing, corner_fill_arc, num_circle_segments, hole, typename geometry_concept<geometry_type>::type());
|
||||
}
|
||||
|
||||
template <typename geometry_type>
|
||||
inline polygon_set_data&
|
||||
insert_with_resize_dispatch(const geometry_type& poly, coordinate_type resizing, bool corner_fill_arc, unsigned int num_circle_segments, bool hole,
|
||||
polygon_with_holes_concept tag) {
|
||||
insert_with_resize_dispatch(poly, resizing, corner_fill_arc, num_circle_segments, hole, polygon_concept());
|
||||
for(typename polygon_with_holes_traits<geometry_type>::iterator_holes_type itr =
|
||||
begin_holes(poly); itr != end_holes(poly);
|
||||
++itr) {
|
||||
insert_with_resize_dispatch(*itr, resizing, corner_fill_arc, num_circle_segments, !hole, polygon_concept());
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename geometry_type>
|
||||
inline polygon_set_data&
|
||||
insert_with_resize_dispatch(const geometry_type& poly, coordinate_type resizing, bool corner_fill_arc, unsigned int num_circle_segments, bool hole,
|
||||
polygon_concept tag) {
|
||||
|
||||
if (resizing==0)
|
||||
return *this;
|
||||
|
||||
|
||||
// one dimensional used to store CCW/CW flag
|
||||
//direction_1d wdir = winding(poly);
|
||||
// LOW==CLOCKWISE just faster to type
|
||||
// so > 0 is CCW
|
||||
//int multiplier = wdir == LOW ? -1 : 1;
|
||||
//std::cout<<" multiplier : "<<multiplier<<std::endl;
|
||||
//if(hole) resizing *= -1;
|
||||
direction_1d resize_wdir = resizing>0?COUNTERCLOCKWISE:CLOCKWISE;
|
||||
|
||||
typedef typename polygon_data<T>::iterator_type piterator;
|
||||
piterator first, second, third, end, real_end;
|
||||
real_end = end_points(poly);
|
||||
third = begin_points(poly);
|
||||
first = third;
|
||||
if(first == real_end) return *this;
|
||||
++third;
|
||||
if(third == real_end) return *this;
|
||||
second = end = third;
|
||||
++third;
|
||||
if(third == real_end) return *this;
|
||||
|
||||
// for 1st corner
|
||||
std::vector<point_data<T> > first_pts;
|
||||
std::vector<point_data<T> > all_pts;
|
||||
direction_1d first_wdir = CLOCKWISE;
|
||||
|
||||
// for all corners
|
||||
polygon_set_data<T> sizingSet;
|
||||
bool sizing_sign = resizing>0;
|
||||
bool prev_concave = true;
|
||||
point_data<T> prev_point;
|
||||
|
||||
|
||||
//insert minkofski shapes on edges and corners
|
||||
do { // REAL WORK IS HERE
|
||||
|
||||
|
||||
//first, second and third point to points in correct CCW order
|
||||
// check if convex or concave case
|
||||
point_data<coordinate_type> normal1( second->y()-first->y(), first->x()-second->x());
|
||||
point_data<coordinate_type> normal2( third->y()-second->y(), second->x()-third->x());
|
||||
double direction = normal1.x()*normal2.y()- normal2.x()*normal1.y();
|
||||
bool convex = direction>0;
|
||||
|
||||
bool treat_as_concave = convex ^ sizing_sign ;
|
||||
point_data<double> v;
|
||||
assign(v, normal1);
|
||||
double s2 = (v.x()*v.x()+v.y()*v.y());
|
||||
double s = sqrt(s2)/resizing;
|
||||
v = point_data<double>(v.x()/s,v.y()/s);
|
||||
point_data<T> curr_prev;
|
||||
if (prev_concave)
|
||||
//TODO missing round_down()
|
||||
curr_prev = point_data<T>(first->x()+v.x(),first->y()+v.y());
|
||||
else
|
||||
curr_prev = prev_point;
|
||||
|
||||
// around concave corners - insert rectangle
|
||||
// if previous corner is concave it's point info may be ignored
|
||||
if ( treat_as_concave) {
|
||||
std::vector<point_data<T> > pts;
|
||||
|
||||
pts.push_back(point_data<T>(second->x()+v.x(),second->y()+v.y()));
|
||||
pts.push_back(*second);
|
||||
pts.push_back(*first);
|
||||
pts.push_back(point_data<T>(curr_prev));
|
||||
if (first_pts.size()){
|
||||
sizingSet.insert_vertex_sequence(pts.begin(),pts.end(), resize_wdir,false);
|
||||
}else {
|
||||
first_pts=pts;
|
||||
first_wdir = resize_wdir;
|
||||
}
|
||||
} else {
|
||||
|
||||
// add either intersection_quad or pie_shape, based on corner_fill_arc option
|
||||
// for convex corner (convexity depends on sign of resizing, whether we shrink or grow)
|
||||
std::vector< std::vector<point_data<T> > > pts;
|
||||
direction_1d winding;
|
||||
winding = convex?COUNTERCLOCKWISE:CLOCKWISE;
|
||||
if (make_resizing_vertex_list(pts, curr_prev, prev_concave, *first, *second, *third, resizing
|
||||
, num_circle_segments, corner_fill_arc))
|
||||
{
|
||||
if (first_pts.size()) {
|
||||
for (unsigned i=0; i<pts.size(); i++) {
|
||||
sizingSet.insert_vertex_sequence(pts[i].begin(),pts[i].end(),winding,false);
|
||||
}
|
||||
|
||||
} else {
|
||||
first_pts = pts[0];
|
||||
first_wdir = resize_wdir;
|
||||
for (unsigned i=1; i<pts.size(); i++) {
|
||||
sizingSet.insert_vertex_sequence(pts[i].begin(),pts[i].end(),winding,false);
|
||||
}
|
||||
}
|
||||
prev_point = curr_prev;
|
||||
|
||||
} else {
|
||||
treat_as_concave = true;
|
||||
}
|
||||
}
|
||||
|
||||
prev_concave = treat_as_concave;
|
||||
first = second;
|
||||
second = third;
|
||||
++third;
|
||||
if(third == real_end) {
|
||||
third = begin_points(poly);
|
||||
if(*second == *third) {
|
||||
++third; //skip first point if it is duplicate of last point
|
||||
}
|
||||
}
|
||||
} while(second != end);
|
||||
|
||||
// handle insertion of first point
|
||||
if (!prev_concave) {
|
||||
first_pts[first_pts.size()-1]=prev_point;
|
||||
}
|
||||
sizingSet.insert_vertex_sequence(first_pts.begin(),first_pts.end(),first_wdir,false);
|
||||
|
||||
polygon_set_data<coordinate_type> tmp;
|
||||
|
||||
//insert original shape
|
||||
tmp.insert(poly, false, polygon_concept());
|
||||
if( ((resizing < 0) ^ hole) ) tmp -= sizingSet;
|
||||
else tmp += sizingSet;
|
||||
//tmp.clean();
|
||||
insert(tmp, hole);
|
||||
return (*this);
|
||||
}
|
||||
|
||||
|
||||
inline polygon_set_data&
|
||||
interact(const polygon_set_data& that);
|
||||
|
||||
inline bool downcast(polygon_45_set_data<coordinate_type>& result) const {
|
||||
if(!is_45_) return false;
|
||||
for(iterator_type itr = begin(); itr != end(); ++itr) {
|
||||
const element_type& elem = *itr;
|
||||
int count = elem.second;
|
||||
int rise = 1; //up sloping 45
|
||||
if(scanline_base<coordinate_type>::is_horizontal(elem.first)) rise = 0;
|
||||
else if(scanline_base<coordinate_type>::is_vertical(elem.first)) rise = 2;
|
||||
else {
|
||||
if(!scanline_base<coordinate_type>::is_45_degree(elem.first)) {
|
||||
is_45_ = false;
|
||||
return false; //consider throwing because is_45_ has be be wrong
|
||||
}
|
||||
if(elem.first.first.y() > elem.first.second.y()) rise = -1; //down sloping 45
|
||||
}
|
||||
typename polygon_45_set_data<coordinate_type>::Vertex45Compact vertex(elem.first.first, rise, count);
|
||||
result.insert(vertex);
|
||||
typename polygon_45_set_data<coordinate_type>::Vertex45Compact vertex2(elem.first.second, rise, -count);
|
||||
result.insert(vertex2);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline GEOMETRY_CONCEPT_ID concept_downcast() const {
|
||||
typedef typename coordinate_traits<coordinate_type>::coordinate_difference delta_type;
|
||||
bool is_45 = false;
|
||||
for(iterator_type itr = begin(); itr != end(); ++itr) {
|
||||
const element_type& elem = *itr;
|
||||
delta_type h_delta = euclidean_distance(elem.first.first, elem.first.second, HORIZONTAL);
|
||||
delta_type v_delta = euclidean_distance(elem.first.first, elem.first.second, VERTICAL);
|
||||
if(h_delta != 0 || v_delta != 0) {
|
||||
//neither delta is zero and the edge is not MANHATTAN
|
||||
if(v_delta != h_delta && v_delta != -h_delta) return POLYGON_SET_CONCEPT;
|
||||
else is_45 = true;
|
||||
}
|
||||
}
|
||||
if(is_45) return POLYGON_45_SET_CONCEPT;
|
||||
return POLYGON_90_SET_CONCEPT;
|
||||
}
|
||||
|
||||
private:
|
||||
mutable value_type data_;
|
||||
mutable bool dirty_;
|
||||
mutable bool unsorted_;
|
||||
mutable bool is_45_;
|
||||
|
||||
private:
|
||||
//functions
|
||||
|
||||
template <typename output_container>
|
||||
void get_dispatch(output_container& output, polygon_concept tag) const {
|
||||
get_fracture(output, true, tag);
|
||||
}
|
||||
template <typename output_container>
|
||||
void get_dispatch(output_container& output, polygon_with_holes_concept tag) const {
|
||||
get_fracture(output, false, tag);
|
||||
}
|
||||
template <typename output_container, typename concept_type>
|
||||
void get_fracture(output_container& container, bool fracture_holes, concept_type ) const {
|
||||
clean();
|
||||
polygon_arbitrary_formation<coordinate_type> pf(fracture_holes);
|
||||
typedef typename polygon_arbitrary_formation<coordinate_type>::vertex_half_edge vertex_half_edge;
|
||||
std::vector<vertex_half_edge> data;
|
||||
for(iterator_type itr = data_.begin(); itr != data_.end(); ++itr){
|
||||
data.push_back(vertex_half_edge((*itr).first.first, (*itr).first.second, (*itr).second));
|
||||
data.push_back(vertex_half_edge((*itr).first.second, (*itr).first.first, -1 * (*itr).second));
|
||||
}
|
||||
std::sort(data.begin(), data.end());
|
||||
pf.scan(container, data.begin(), data.end());
|
||||
}
|
||||
};
|
||||
|
||||
struct polygon_set_concept;
|
||||
template <typename T>
|
||||
struct geometry_concept<polygon_set_data<T> > {
|
||||
typedef polygon_set_concept type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline double compute_area(point_data<T>& a, point_data<T>& b, point_data<T>& c) {
|
||||
|
||||
return (double)(b.x()-a.x())*(double)(c.y()-a.y())- (double)(c.x()-a.x())*(double)(b.y()-a.y());
|
||||
|
||||
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline int make_resizing_vertex_list(std::vector<std::vector<point_data< T> > >& return_points,
|
||||
point_data<T>& curr_prev, bool ignore_prev_point,
|
||||
point_data< T> start, point_data<T> middle, point_data< T> end,
|
||||
double sizing_distance, unsigned int num_circle_segments, bool corner_fill_arc) {
|
||||
|
||||
// handle the case of adding an intersection point
|
||||
point_data<double> dn1( middle.y()-start.y(), start.x()-middle.x());
|
||||
double size = sizing_distance/sqrt( dn1.x()*dn1.x()+dn1.y()*dn1.y());
|
||||
dn1 = point_data<double>( dn1.x()*size, dn1.y()* size);
|
||||
point_data<double> dn2( end.y()-middle.y(), middle.x()-end.x());
|
||||
size = sizing_distance/sqrt( dn2.x()*dn2.x()+dn2.y()*dn2.y());
|
||||
dn2 = point_data<double>( dn2.x()*size, dn2.y()* size);
|
||||
point_data<double> start_offset((start.x()+dn1.x()),(start.y()+dn1.y()));
|
||||
point_data<double> mid1_offset((middle.x()+dn1.x()),(middle.y()+dn1.y()));
|
||||
point_data<double> end_offset((end.x()+dn2.x()),(end.y()+dn2.y()));
|
||||
point_data<double> mid2_offset((middle.x()+dn2.x()),(middle.y()+dn2.y()));
|
||||
if (ignore_prev_point)
|
||||
curr_prev = round_down<T>(start_offset);
|
||||
|
||||
|
||||
if (corner_fill_arc) {
|
||||
std::vector<point_data< T> > return_points1;
|
||||
return_points.push_back(return_points1);
|
||||
std::vector<point_data< T> >& return_points_back = return_points[return_points.size()-1];
|
||||
return_points_back.push_back(round_down<T>(mid1_offset));
|
||||
return_points_back.push_back(middle);
|
||||
return_points_back.push_back(start);
|
||||
return_points_back.push_back(curr_prev);
|
||||
point_data<double> dmid(middle.x(),middle.y());
|
||||
return_points.push_back(return_points1);
|
||||
int num = make_arc(return_points[return_points.size()-1],mid1_offset,mid2_offset,dmid,sizing_distance,num_circle_segments);
|
||||
curr_prev = round_down<T>(mid2_offset);
|
||||
return num;
|
||||
|
||||
}
|
||||
|
||||
std::pair<point_data<double>,point_data<double> > he1(start_offset,mid1_offset);
|
||||
std::pair<point_data<double>,point_data<double> > he2(mid2_offset ,end_offset);
|
||||
typedef typename high_precision_type<double>::type high_precision;
|
||||
|
||||
point_data<T> intersect;
|
||||
typename scanline_base<T>::compute_intersection_pack pack;
|
||||
bool res = pack.compute_intersection(intersect,he1,he2,true);
|
||||
if( res ) {
|
||||
std::vector<point_data< T> > return_points1;
|
||||
return_points.push_back(return_points1);
|
||||
std::vector<point_data< T> >& return_points_back = return_points[return_points.size()-1];
|
||||
return_points_back.push_back(intersect);
|
||||
return_points_back.push_back(middle);
|
||||
return_points_back.push_back(start);
|
||||
return_points_back.push_back(curr_prev);
|
||||
|
||||
/*double d1= */compute_area(intersect,middle,start);
|
||||
/*double d2= */compute_area(start,curr_prev,intersect);
|
||||
|
||||
curr_prev = intersect;
|
||||
|
||||
|
||||
return return_points.size();
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
// this routine should take in start and end point s.t. end point is CCW from start
|
||||
// it sould make a pie slice polygon that is an intersection of that arc
|
||||
// with an ngon segments approximation of the circle centered at center with radius r
|
||||
// point start is gauaranteed to be on the segmentation
|
||||
// returnPoints will start with the first point after start
|
||||
// returnPoints vector may be empty
|
||||
template <typename T>
|
||||
inline int make_arc(std::vector<point_data< T> >& return_points,
|
||||
point_data< double> start, point_data< double> end,
|
||||
point_data< double> center, double r, unsigned int num_circle_segments) {
|
||||
const double our_pi=3.1415926535897932384626433832795028841971;
|
||||
|
||||
// derive start and end angles
|
||||
double ps = atan2(start.y()-center.y(), start.x()-center.x());
|
||||
double pe = atan2(end.y()-center.y(), end.x()-center.x());
|
||||
if (ps < 0.0)
|
||||
ps += 2.0 * our_pi;
|
||||
if (pe <= 0.0)
|
||||
pe += 2.0 * our_pi;
|
||||
if (ps >= 2.0 * M_PI)
|
||||
ps -= 2.0 * our_pi;
|
||||
while (pe <= ps)
|
||||
pe += 2.0 * our_pi;
|
||||
double delta_angle = (2.0 * our_pi) / (double)num_circle_segments;
|
||||
if ( start==end) // full circle?
|
||||
{
|
||||
ps = delta_angle*0.5;
|
||||
pe = ps + our_pi * 2.0;
|
||||
double x,y;
|
||||
x = center.x() + r * cos(ps);
|
||||
y = center.y() + r * sin(ps);
|
||||
start = point_data<double>(x,y);
|
||||
end = start;
|
||||
}
|
||||
return_points.push_back(round_down<T>(center));
|
||||
return_points.push_back(round_down<T>(start));
|
||||
int i=0;
|
||||
double curr_angle = ps+delta_angle;
|
||||
while( curr_angle < pe - 0.01 && i < 2 * (int)num_circle_segments) {
|
||||
i++;
|
||||
double x = center.x() + r * cos( curr_angle);
|
||||
double y = center.y() + r * sin( curr_angle);
|
||||
return_points.push_back( round_down<T>((point_data<double>(x,y))));
|
||||
curr_angle+=delta_angle;
|
||||
}
|
||||
return_points.push_back(round_down<T>(end));
|
||||
return return_points.size();
|
||||
}
|
||||
|
||||
}// close namespace
|
||||
}// close name space
|
||||
|
||||
#include "detail/scan_arbitrary.hpp"
|
||||
|
||||
namespace boost { namespace polygon {
|
||||
//ConnectivityExtraction computes the graph of connectivity between rectangle, polygon and
|
||||
//polygon set graph nodes where an edge is created whenever the geometry in two nodes overlap
|
||||
template <typename coordinate_type>
|
||||
class connectivity_extraction{
|
||||
private:
|
||||
typedef arbitrary_connectivity_extraction<coordinate_type, int> ce;
|
||||
ce ce_;
|
||||
unsigned int nodeCount_;
|
||||
public:
|
||||
inline connectivity_extraction() : ce_(), nodeCount_(0) {}
|
||||
inline connectivity_extraction(const connectivity_extraction& that) : ce_(that.ce_),
|
||||
nodeCount_(that.nodeCount_) {}
|
||||
inline connectivity_extraction& operator=(const connectivity_extraction& that) {
|
||||
ce_ = that.ce_;
|
||||
nodeCount_ = that.nodeCount_; {}
|
||||
return *this;
|
||||
}
|
||||
|
||||
//insert a polygon set graph node, the value returned is the id of the graph node
|
||||
inline unsigned int insert(const polygon_set_data<coordinate_type>& ps) {
|
||||
ps.clean();
|
||||
ce_.populateTouchSetData(ps.begin(), ps.end(), nodeCount_);
|
||||
return nodeCount_++;
|
||||
}
|
||||
template <class GeoObjT>
|
||||
inline unsigned int insert(const GeoObjT& geoObj) {
|
||||
polygon_set_data<coordinate_type> ps;
|
||||
ps.insert(geoObj);
|
||||
return insert(ps);
|
||||
}
|
||||
|
||||
//extract connectivity and store the edges in the graph
|
||||
//graph must be indexable by graph node id and the indexed value must be a std::set of
|
||||
//graph node id
|
||||
template <class GraphT>
|
||||
inline void extract(GraphT& graph) {
|
||||
ce_.execute(graph);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
polygon_set_data<T>&
|
||||
polygon_set_data<T>::interact(const polygon_set_data<T>& that) {
|
||||
connectivity_extraction<coordinate_type> ce;
|
||||
std::vector<polygon_with_holes_data<T> > polys;
|
||||
get(polys);
|
||||
clear();
|
||||
for(std::size_t i = 0; i < polys.size(); ++i) {
|
||||
ce.insert(polys[i]);
|
||||
}
|
||||
int id = ce.insert(that);
|
||||
std::vector<std::set<int> > graph(id+1);
|
||||
ce.extract(graph);
|
||||
for(std::set<int>::iterator itr = graph[id].begin();
|
||||
itr != graph[id].end(); ++itr) {
|
||||
insert(polys[*itr]);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#include "polygon_set_traits.hpp"
|
||||
#include "detail/polygon_set_view.hpp"
|
||||
|
||||
#include "polygon_set_concept.hpp"
|
||||
#endif
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
Copyright 2008 Intel Corporation
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
*/
|
||||
#ifndef BOOST_POLYGON_POLYGON_SET_TRAITS_HPP
|
||||
#define BOOST_POLYGON_POLYGON_SET_TRAITS_HPP
|
||||
namespace boost { namespace polygon{
|
||||
|
||||
struct polygon_set_concept {};
|
||||
|
||||
//default definition of polygon set traits works for any model of polygon , polygon with holes or any vector or list thereof
|
||||
template <typename T>
|
||||
struct polygon_set_traits {
|
||||
typedef typename get_coordinate_type<T, typename geometry_concept<T>::type >::type coordinate_type;
|
||||
typedef typename get_iterator_type<T>::type iterator_type;
|
||||
typedef T operator_arg_type;
|
||||
|
||||
static inline iterator_type begin(const T& polygon_set) {
|
||||
return get_iterator_type<T>::begin(polygon_set);
|
||||
}
|
||||
|
||||
static inline iterator_type end(const T& polygon_set) {
|
||||
return get_iterator_type<T>::end(polygon_set);
|
||||
}
|
||||
|
||||
static inline bool clean(const T& ) { return false; }
|
||||
|
||||
static inline bool sorted(const T& ) { return false; }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct is_polygonal_concept { typedef gtl_no type; };
|
||||
template <>
|
||||
struct is_polygonal_concept<polygon_concept> { typedef gtl_yes type; };
|
||||
template <>
|
||||
struct is_polygonal_concept<polygon_with_holes_concept> { typedef gtl_yes type; };
|
||||
template <>
|
||||
struct is_polygonal_concept<polygon_set_concept> { typedef gtl_yes type; };
|
||||
|
||||
template <typename T>
|
||||
struct is_polygon_set_type {
|
||||
typedef typename is_polygonal_concept<typename geometry_concept<T>::type>::type type;
|
||||
};
|
||||
template <typename T>
|
||||
struct is_polygon_set_type<std::list<T> > {
|
||||
typedef typename gtl_or<
|
||||
typename is_polygonal_concept<typename geometry_concept<std::list<T> >::type>::type,
|
||||
typename is_polygonal_concept<typename geometry_concept<typename std::list<T>::value_type>::type>::type>::type type;
|
||||
};
|
||||
template <typename T>
|
||||
struct is_polygon_set_type<std::vector<T> > {
|
||||
typedef typename gtl_or<
|
||||
typename is_polygonal_concept<typename geometry_concept<std::vector<T> >::type>::type,
|
||||
typename is_polygonal_concept<typename geometry_concept<typename std::vector<T>::value_type>::type>::type>::type type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct is_mutable_polygon_set_type {
|
||||
typedef typename gtl_same_type<polygon_set_concept, typename geometry_concept<T>::type>::type type;
|
||||
};
|
||||
template <typename T>
|
||||
struct is_mutable_polygon_set_type<std::list<T> > {
|
||||
typedef typename gtl_or<
|
||||
typename gtl_same_type<polygon_set_concept, typename geometry_concept<std::list<T> >::type>::type,
|
||||
typename is_polygonal_concept<typename geometry_concept<typename std::list<T>::value_type>::type>::type>::type type;
|
||||
};
|
||||
template <typename T>
|
||||
struct is_mutable_polygon_set_type<std::vector<T> > {
|
||||
typedef typename gtl_or<
|
||||
typename gtl_same_type<polygon_set_concept, typename geometry_concept<std::vector<T> >::type>::type,
|
||||
typename is_polygonal_concept<typename geometry_concept<typename std::vector<T>::value_type>::type>::type>::type type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct polygon_set_mutable_traits {};
|
||||
template <typename T>
|
||||
struct polygon_set_mutable_traits<std::list<T> > {
|
||||
template <typename input_iterator_type>
|
||||
static inline void set(std::list<T>& polygon_set, input_iterator_type input_begin, input_iterator_type input_end) {
|
||||
polygon_set.clear();
|
||||
polygon_set_data<typename polygon_set_traits<std::list<T> >::coordinate_type> ps;
|
||||
ps.insert(input_begin, input_end);
|
||||
ps.get(polygon_set);
|
||||
}
|
||||
};
|
||||
template <typename T>
|
||||
struct polygon_set_mutable_traits<std::vector<T> > {
|
||||
template <typename input_iterator_type>
|
||||
static inline void set(std::vector<T>& polygon_set, input_iterator_type input_begin, input_iterator_type input_end) {
|
||||
polygon_set.clear();
|
||||
polygon_set_data<typename polygon_set_traits<std::list<T> >::coordinate_type> ps;
|
||||
ps.insert(input_begin, input_end);
|
||||
ps.get(polygon_set);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct polygon_set_mutable_traits<polygon_set_data<T> > {
|
||||
template <typename input_iterator_type>
|
||||
static inline void set(polygon_set_data<T>& polygon_set,
|
||||
input_iterator_type input_begin, input_iterator_type input_end) {
|
||||
polygon_set.set(input_begin, input_end);
|
||||
}
|
||||
};
|
||||
template <typename T>
|
||||
struct polygon_set_traits<polygon_set_data<T> > {
|
||||
typedef typename polygon_set_data<T>::coordinate_type coordinate_type;
|
||||
typedef typename polygon_set_data<T>::iterator_type iterator_type;
|
||||
typedef typename polygon_set_data<T>::operator_arg_type operator_arg_type;
|
||||
|
||||
static inline iterator_type begin(const polygon_set_data<T>& polygon_set) {
|
||||
return polygon_set.begin();
|
||||
}
|
||||
|
||||
static inline iterator_type end(const polygon_set_data<T>& polygon_set) {
|
||||
return polygon_set.end();
|
||||
}
|
||||
|
||||
static inline bool clean(const polygon_set_data<T>& polygon_set) { polygon_set.clean(); return true; }
|
||||
|
||||
static inline bool sorted(const polygon_set_data<T>& polygon_set) { int untested = 0;polygon_set.sort(); return true; }
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
Copyright 2008 Intel Corporation
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
*/
|
||||
#ifndef BOOST_POLYGON_POLYGON_WITH_HOLES_DATA_HPP
|
||||
#define BOOST_POLYGON_POLYGON_WITH_HOLES_DATA_HPP
|
||||
#include "isotropy.hpp"
|
||||
#include "polygon_data.hpp"
|
||||
namespace boost { namespace polygon{
|
||||
struct polygon_with_holes_concept;
|
||||
template <typename T>
|
||||
class polygon_with_holes_data {
|
||||
public:
|
||||
typedef polygon_with_holes_concept geometry_type;
|
||||
typedef T coordinate_type;
|
||||
typedef typename polygon_data<T>::iterator_type iterator_type;
|
||||
typedef typename std::list<polygon_data<coordinate_type> >::const_iterator iterator_holes_type;
|
||||
typedef polygon_data<coordinate_type> hole_type;
|
||||
typedef typename coordinate_traits<T>::coordinate_distance area_type;
|
||||
typedef point_data<T> point_type;
|
||||
|
||||
// default constructor of point does not initialize x and y
|
||||
inline polygon_with_holes_data() : self_(), holes_() {} //do nothing default constructor
|
||||
|
||||
template<class iT>
|
||||
inline polygon_with_holes_data(iT input_begin, iT input_end) : self_(), holes_() {
|
||||
set(input_begin, input_end);
|
||||
}
|
||||
|
||||
template<class iT, typename hiT>
|
||||
inline polygon_with_holes_data(iT input_begin, iT input_end, hiT holes_begin, hiT holes_end) : self_(), holes_() {
|
||||
set(input_begin, input_end);
|
||||
set_holes(holes_begin, holes_end);
|
||||
}
|
||||
|
||||
template<class iT>
|
||||
inline polygon_with_holes_data& set(iT input_begin, iT input_end) {
|
||||
self_.set(input_begin, input_end);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// initialize a polygon from x,y values, it is assumed that the first is an x
|
||||
// and that the input is a well behaved polygon
|
||||
template<class iT>
|
||||
inline polygon_with_holes_data& set_holes(iT input_begin, iT input_end) {
|
||||
holes_.clear(); //just in case there was some old data there
|
||||
for( ; input_begin != input_end; ++ input_begin) {
|
||||
holes_.push_back(hole_type());
|
||||
holes_.back().set((*input_begin).begin(), (*input_begin).end());
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// copy constructor (since we have dynamic memory)
|
||||
inline polygon_with_holes_data(const polygon_with_holes_data& that) : self_(that.self_),
|
||||
holes_(that.holes_) {}
|
||||
|
||||
// assignment operator (since we have dynamic memory do a deep copy)
|
||||
inline polygon_with_holes_data& operator=(const polygon_with_holes_data& that) {
|
||||
self_ = that.self_;
|
||||
holes_ = that.holes_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T2>
|
||||
inline polygon_with_holes_data& operator=(const T2& rvalue);
|
||||
|
||||
// get begin iterator, returns a pointer to a const coordinate_type
|
||||
inline const iterator_type begin() const {
|
||||
return self_.begin();
|
||||
}
|
||||
|
||||
// get end iterator, returns a pointer to a const coordinate_type
|
||||
inline const iterator_type end() const {
|
||||
return self_.end();
|
||||
}
|
||||
|
||||
inline std::size_t size() const {
|
||||
return self_.size();
|
||||
}
|
||||
|
||||
// get begin iterator, returns a pointer to a const polygon
|
||||
inline const iterator_holes_type begin_holes() const {
|
||||
return holes_.begin();
|
||||
}
|
||||
|
||||
// get end iterator, returns a pointer to a const polygon
|
||||
inline const iterator_holes_type end_holes() const {
|
||||
return holes_.end();
|
||||
}
|
||||
|
||||
inline std::size_t size_holes() const {
|
||||
return holes_.size();
|
||||
}
|
||||
|
||||
private:
|
||||
polygon_data<coordinate_type> self_;
|
||||
std::list<hole_type> holes_;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
Copyright 2008 Intel Corporation
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
*/
|
||||
#ifndef BOOST_POLYGON_RECTANGLE_DATA_HPP
|
||||
#define BOOST_POLYGON_RECTANGLE_DATA_HPP
|
||||
|
||||
#include "isotropy.hpp"
|
||||
//interval
|
||||
#include "interval_data.hpp"
|
||||
|
||||
namespace boost { namespace polygon{
|
||||
|
||||
template <typename T>
|
||||
class rectangle_data {
|
||||
public:
|
||||
typedef T coordinate_type;
|
||||
typedef interval_data<T> interval_type;
|
||||
inline rectangle_data():ranges_() {}
|
||||
inline rectangle_data(T xl, T yl, T xh, T yh):ranges_() {
|
||||
if(xl > xh) std::swap(xl, xh);
|
||||
if(yl > yh) std::swap(yl, yh);
|
||||
ranges_[HORIZONTAL] = interval_data<T>(xl, xh);
|
||||
ranges_[VERTICAL] = interval_data<T>(yl, yh);
|
||||
}
|
||||
template <typename interval_type_1, typename interval_type_2>
|
||||
inline rectangle_data(const interval_type_1& hrange,
|
||||
const interval_type_2& vrange):ranges_() {
|
||||
set(HORIZONTAL, hrange); set(VERTICAL, vrange); }
|
||||
|
||||
inline rectangle_data(const rectangle_data& that):ranges_() { (*this) = that; }
|
||||
inline rectangle_data& operator=(const rectangle_data& that) {
|
||||
ranges_[0] = that.ranges_[0]; ranges_[1] = that.ranges_[1]; return *this;
|
||||
}
|
||||
template <typename T2>
|
||||
inline rectangle_data& operator=(const T2& rvalue);
|
||||
|
||||
template <typename T2>
|
||||
inline bool operator==(const T2& rvalue) const;
|
||||
template <typename T2>
|
||||
inline bool operator!=(const T2& rvalue) const { return !((*this) == rvalue); }
|
||||
|
||||
inline interval_data<coordinate_type> get(orientation_2d orient) const {
|
||||
return ranges_[orient.to_int()]; }
|
||||
inline coordinate_type get(direction_2d dir) const {
|
||||
return ranges_[orientation_2d(dir).to_int()].get(direction_1d(dir));
|
||||
}
|
||||
inline void set(direction_2d dir, coordinate_type value) {
|
||||
return ranges_[orientation_2d(dir).to_int()].set(direction_1d(dir), value);
|
||||
}
|
||||
template <typename interval_type_1>
|
||||
inline void set(orientation_2d orient, const interval_type_1& interval);
|
||||
private:
|
||||
interval_data<coordinate_type> ranges_[2];
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
Copyright 2008 Intel Corporation
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
*/
|
||||
#ifndef BOOST_POLYGON_RECTANGLE_TRAITS_HPP
|
||||
#define BOOST_POLYGON_RECTANGLE_TRAITS_HPP
|
||||
namespace boost { namespace polygon{
|
||||
|
||||
template <typename T, typename enable = gtl_yes>
|
||||
struct rectangle_traits {};
|
||||
template <typename T>
|
||||
struct rectangle_traits<T, gtl_no> {};
|
||||
|
||||
template <typename T>
|
||||
struct rectangle_traits<T, typename gtl_same_type<typename T::interval_type, typename T::interval_type>::type> {
|
||||
typedef typename T::coordinate_type coordinate_type;
|
||||
typedef typename T::interval_type interval_type;
|
||||
static inline interval_type get(const T& rectangle, orientation_2d orient) {
|
||||
return rectangle.get(orient); }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct rectangle_mutable_traits {
|
||||
template <typename T2>
|
||||
static inline void set(T& rectangle, orientation_2d orient, const T2& interval) {
|
||||
rectangle.set(orient, interval); }
|
||||
template <typename T2, typename T3>
|
||||
static inline T construct(const T2& interval_horizontal,
|
||||
const T3& interval_vertical) {
|
||||
return T(interval_horizontal, interval_vertical); }
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,501 @@
|
|||
/*
|
||||
Copyright 2008 Intel Corporation
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
*/
|
||||
#ifndef BOOST_POLYGON_TRANSFORM_HPP
|
||||
#define BOOST_POLYGON_TRANSFORM_HPP
|
||||
#include "isotropy.hpp"
|
||||
#include "point_3d_concept.hpp"
|
||||
namespace boost { namespace polygon{
|
||||
// Transformation of Coordinate Systems
|
||||
// Enum meaning:
|
||||
// Select which direction_3d to change the positive direction of each
|
||||
// axis in the old coordinate system to map it to the new coordiante system.
|
||||
// The first direction_3d listed for each enum is the direction to map the
|
||||
// positive horizontal direction to.
|
||||
// The second direction_3d listed for each enum is the direction to map the
|
||||
// positive vertical direction to.
|
||||
// The third direction_3d listed for each enum is the direction to map the
|
||||
// positive proximal direction to.
|
||||
// The zero position bit (LSB) indicates whether the horizontal axis flips
|
||||
// when transformed.
|
||||
// The 1st postion bit indicates whether the vertical axis flips when
|
||||
// transformed.
|
||||
// The 2nd position bit indicates whether the horizontal and vertical axis
|
||||
// swap positions when transformed.
|
||||
// Note that the first eight values are the complete set of 2D transforms.
|
||||
// The 3rd position bit indicates whether the proximal axis flips when
|
||||
// transformed.
|
||||
// The 4th position bit indicates whether the proximal and horizontal axis are
|
||||
// swapped when transformed. It changes the meaning of the 2nd position bit
|
||||
// to mean that the horizontal and vertical axis are swapped in their new
|
||||
// positions, naturally.
|
||||
// The 5th position bit (MSB) indicates whether the proximal and vertical axis
|
||||
// are swapped when transformed. It is mutually exclusive with the 4th postion
|
||||
// bit, making the maximum legal value 48 (decimal). It similarly changes the
|
||||
// meaning of the 2nd position bit to mean that the horizontal and vertical are
|
||||
// swapped in their new positions.
|
||||
// Enum Values:
|
||||
// 000000 EAST NORTH UP
|
||||
// 000001 WEST NORTH UP
|
||||
// 000010 EAST SOUTH UP
|
||||
// 000011 WEST SOUTH UP
|
||||
// 000100 NORTH EAST UP
|
||||
// 000101 SOUTH EAST UP
|
||||
// 000110 NORTH WEST UP
|
||||
// 000111 SOUTH WEST UP
|
||||
// 001000 EAST NORTH DOWN
|
||||
// 001001 WEST NORTH DOWN
|
||||
// 001010 EAST SOUTH DOWN
|
||||
// 001011 WEST SOUTH DOWN
|
||||
// 001100 NORTH EAST DOWN
|
||||
// 001101 SOUTH EAST DOWN
|
||||
// 001110 NORTH WEST DOWN
|
||||
// 001111 SOUTH WEST DOWN
|
||||
// 010000 UP NORTH EAST
|
||||
// 010001 DOWN NORTH EAST
|
||||
// 010010 UP SOUTH EAST
|
||||
// 010011 DOWN SOUTH EAST
|
||||
// 010100 NORTH UP EAST
|
||||
// 010101 SOUTH UP EAST
|
||||
// 010110 NORTH DOWN EAST
|
||||
// 010111 SOUTH DOWN EAST
|
||||
// 011000 UP NORTH WEST
|
||||
// 011001 DOWN NORTH WEST
|
||||
// 011010 UP SOUTH WEST
|
||||
// 011011 DOWN SOUTH WEST
|
||||
// 011100 NORTH UP WEST
|
||||
// 011101 SOUTH UP WEST
|
||||
// 011110 NORTH DOWN WEST
|
||||
// 011111 SOUTH DOWN WEST
|
||||
// 100000 EAST UP NORTH
|
||||
// 100001 WEST UP NORTH
|
||||
// 100010 EAST DOWN NORTH
|
||||
// 100011 WEST DOWN NORTH
|
||||
// 100100 UP EAST NORTH
|
||||
// 100101 DOWN EAST NORTH
|
||||
// 100110 UP WEST NORTH
|
||||
// 100111 DOWN WEST NORTH
|
||||
// 101000 EAST UP SOUTH
|
||||
// 101001 WEST UP SOUTH
|
||||
// 101010 EAST DOWN SOUTH
|
||||
// 101011 WEST DOWN SOUTH
|
||||
// 101100 UP EAST SOUTH
|
||||
// 101101 DOWN EAST SOUTH
|
||||
// 101110 UP WEST SOUTH
|
||||
// 101111 DOWN WEST SOUTH
|
||||
class axis_transformation {
|
||||
public:
|
||||
// Enum Names and values
|
||||
// NULL_TRANSFORM = 0, BEGIN_TRANSFORM = 0,
|
||||
// ENU = 0, EAST_NORTH_UP = 0, EN = 0, EAST_NORTH = 0,
|
||||
// WNU = 1, WEST_NORTH_UP = 1, WN = 1, WEST_NORTH = 1, FLIP_X = 1,
|
||||
// ESU = 2, EAST_SOUTH_UP = 2, ES = 2, EAST_SOUTH = 2, FLIP_Y = 2,
|
||||
// WSU = 3, WEST_SOUTH_UP = 3, WS = 3, WEST_SOUTH = 3,
|
||||
// NEU = 4, NORTH_EAST_UP = 4, NE = 4, NORTH_EAST = 4, SWAP_XY = 4,
|
||||
// SEU = 5, SOUTH_EAST_UP = 5, SE = 5, SOUTH_EAST = 5,
|
||||
// NWU = 6, NORTH_WEST_UP = 6, NW = 6, NORTH_WEST = 6,
|
||||
// SWU = 7, SOUTH_WEST_UP = 7, SW = 7, SOUTH_WEST = 7,
|
||||
// END_2D_TRANSFORM = 7,
|
||||
// END = 8, EAST_NORTH_DOWN = 8,
|
||||
// WND = 9, WEST_NORTH_DOWN = 9,
|
||||
// ESD = 10, EAST_SOUTH_DOWN = 10,
|
||||
// WSD = 11, WEST_SOUTH_DOWN = 11,
|
||||
// NED = 12, NORTH_EAST_DOWN = 12,
|
||||
// SED = 13, SOUTH_EAST_DOWN = 13,
|
||||
// NWD = 14, NORTH_WEST_DOWN = 14,
|
||||
// SWD = 15, SOUTH_WEST_DOWN = 15,
|
||||
// UNE = 16, UP_NORTH_EAST = 16,
|
||||
// DNE = 17, DOWN_NORTH_EAST = 17,
|
||||
// USE = 18, UP_SOUTH_EAST = 18,
|
||||
// DSE = 19, DOWN_SOUTH_EAST = 19,
|
||||
// NUE = 20, NORTH_UP_EAST = 20,
|
||||
// SUE = 21, SOUTH_UP_EAST = 21,
|
||||
// NDE = 22, NORTH_DOWN_EAST = 22,
|
||||
// SDE = 23, SOUTH_DOWN_EAST = 23,
|
||||
// UNW = 24, UP_NORTH_WEST = 24,
|
||||
// DNW = 25, DOWN_NORTH_WEST = 25,
|
||||
// USW = 26, UP_SOUTH_WEST = 26,
|
||||
// DSW = 27, DOWN_SOUTH_WEST = 27,
|
||||
// NUW = 28, NORTH_UP_WEST = 28,
|
||||
// SUW = 29, SOUTH_UP_WEST = 29,
|
||||
// NDW = 30, NORTH_DOWN_WEST = 30,
|
||||
// SDW = 31, SOUTH_DOWN_WEST = 31,
|
||||
// EUN = 32, EAST_UP_NORTH = 32,
|
||||
// WUN = 33, WEST_UP_NORTH = 33,
|
||||
// EDN = 34, EAST_DOWN_NORTH = 34,
|
||||
// WDN = 35, WEST_DOWN_NORTH = 35,
|
||||
// UEN = 36, UP_EAST_NORTH = 36,
|
||||
// DEN = 37, DOWN_EAST_NORTH = 37,
|
||||
// UWN = 38, UP_WEST_NORTH = 38,
|
||||
// DWN = 39, DOWN_WEST_NORTH = 39,
|
||||
// EUS = 40, EAST_UP_SOUTH = 40,
|
||||
// WUS = 41, WEST_UP_SOUTH = 41,
|
||||
// EDS = 42, EAST_DOWN_SOUTH = 42,
|
||||
// WDS = 43, WEST_DOWN_SOUTH = 43,
|
||||
// UES = 44, UP_EAST_SOUTH = 44,
|
||||
// DES = 45, DOWN_EAST_SOUTH = 45,
|
||||
// UWS = 46, UP_WEST_SOUTH = 46,
|
||||
// DWS = 47, DOWN_WEST_SOUTH = 47, END_TRANSFORM = 47
|
||||
enum ATR {
|
||||
NULL_TRANSFORM = 0, BEGIN_TRANSFORM = 0,
|
||||
ENU = 0, EAST_NORTH_UP = 0, EN = 0, EAST_NORTH = 0,
|
||||
WNU = 1, WEST_NORTH_UP = 1, WN = 1, WEST_NORTH = 1, FLIP_X = 1,
|
||||
ESU = 2, EAST_SOUTH_UP = 2, ES = 2, EAST_SOUTH = 2, FLIP_Y = 2,
|
||||
WSU = 3, WEST_SOUTH_UP = 3, WS = 3, WEST_SOUTH = 3, FLIP_XY = 3,
|
||||
NEU = 4, NORTH_EAST_UP = 4, NE = 4, NORTH_EAST = 4, SWAP_XY = 4,
|
||||
SEU = 5, SOUTH_EAST_UP = 5, SE = 5, SOUTH_EAST = 5, ROTATE_LEFT = 5,
|
||||
NWU = 6, NORTH_WEST_UP = 6, NW = 6, NORTH_WEST = 6, ROTATE_RIGHT = 6,
|
||||
SWU = 7, SOUTH_WEST_UP = 7, SW = 7, SOUTH_WEST = 7, FLIP_SWAP_XY = 7, END_2D_TRANSFORM = 7,
|
||||
END = 8, EAST_NORTH_DOWN = 8, FLIP_Z = 8,
|
||||
WND = 9, WEST_NORTH_DOWN = 9,
|
||||
ESD = 10, EAST_SOUTH_DOWN = 10,
|
||||
WSD = 11, WEST_SOUTH_DOWN = 11,
|
||||
NED = 12, NORTH_EAST_DOWN = 12,
|
||||
SED = 13, SOUTH_EAST_DOWN = 13,
|
||||
NWD = 14, NORTH_WEST_DOWN = 14,
|
||||
SWD = 15, SOUTH_WEST_DOWN = 15,
|
||||
UNE = 16, UP_NORTH_EAST = 16,
|
||||
DNE = 17, DOWN_NORTH_EAST = 17,
|
||||
USE = 18, UP_SOUTH_EAST = 18,
|
||||
DSE = 19, DOWN_SOUTH_EAST = 19,
|
||||
NUE = 20, NORTH_UP_EAST = 20,
|
||||
SUE = 21, SOUTH_UP_EAST = 21,
|
||||
NDE = 22, NORTH_DOWN_EAST = 22,
|
||||
SDE = 23, SOUTH_DOWN_EAST = 23,
|
||||
UNW = 24, UP_NORTH_WEST = 24,
|
||||
DNW = 25, DOWN_NORTH_WEST = 25,
|
||||
USW = 26, UP_SOUTH_WEST = 26,
|
||||
DSW = 27, DOWN_SOUTH_WEST = 27,
|
||||
NUW = 28, NORTH_UP_WEST = 28,
|
||||
SUW = 29, SOUTH_UP_WEST = 29,
|
||||
NDW = 30, NORTH_DOWN_WEST = 30,
|
||||
SDW = 31, SOUTH_DOWN_WEST = 31,
|
||||
EUN = 32, EAST_UP_NORTH = 32,
|
||||
WUN = 33, WEST_UP_NORTH = 33,
|
||||
EDN = 34, EAST_DOWN_NORTH = 34,
|
||||
WDN = 35, WEST_DOWN_NORTH = 35,
|
||||
UEN = 36, UP_EAST_NORTH = 36,
|
||||
DEN = 37, DOWN_EAST_NORTH = 37,
|
||||
UWN = 38, UP_WEST_NORTH = 38,
|
||||
DWN = 39, DOWN_WEST_NORTH = 39,
|
||||
EUS = 40, EAST_UP_SOUTH = 40,
|
||||
WUS = 41, WEST_UP_SOUTH = 41,
|
||||
EDS = 42, EAST_DOWN_SOUTH = 42,
|
||||
WDS = 43, WEST_DOWN_SOUTH = 43,
|
||||
UES = 44, UP_EAST_SOUTH = 44,
|
||||
DES = 45, DOWN_EAST_SOUTH = 45,
|
||||
UWS = 46, UP_WEST_SOUTH = 46,
|
||||
DWS = 47, DOWN_WEST_SOUTH = 47, END_TRANSFORM = 47
|
||||
};
|
||||
|
||||
// Individual axis enum values indicate which axis an implicit individual
|
||||
// axis will be mapped to.
|
||||
// The value of the enum paired with an axis provides the information
|
||||
// about what the axis will transform to.
|
||||
// Three individual axis values, one for each axis, are equivalent to one
|
||||
// ATR enum value, but easier to work with because they are independent.
|
||||
// Converting to and from the individual axis values from the ATR value
|
||||
// is a convenient way to implement tranformation related functionality.
|
||||
// Enum meanings:
|
||||
// PX: map to positive x axis
|
||||
// NX: map to negative x axis
|
||||
// PY: map to positive y axis
|
||||
// NY: map to negative y axis
|
||||
// PZ: map to positive z axis
|
||||
// NZ: map to negative z axis
|
||||
enum INDIVIDUAL_AXIS {
|
||||
PX = 0,
|
||||
NX = 1,
|
||||
PY = 2,
|
||||
NY = 3,
|
||||
PZ = 4,
|
||||
NZ = 5
|
||||
};
|
||||
|
||||
inline axis_transformation() : atr_(NULL_TRANSFORM) {}
|
||||
inline axis_transformation(ATR atr) : atr_(atr) {}
|
||||
inline axis_transformation(const axis_transformation& atr) : atr_(atr.atr_) {}
|
||||
explicit axis_transformation(const orientation_3d& orient);
|
||||
explicit axis_transformation(const direction_3d& dir);
|
||||
explicit axis_transformation(const orientation_2d& orient);
|
||||
explicit axis_transformation(const direction_2d& dir);
|
||||
|
||||
// assignment operator
|
||||
axis_transformation& operator=(const axis_transformation& a);
|
||||
|
||||
// assignment operator
|
||||
axis_transformation& operator=(const ATR& atr);
|
||||
|
||||
// equivalence operator
|
||||
bool operator==(const axis_transformation& a) const;
|
||||
|
||||
// inequivalence operator
|
||||
bool operator!=(const axis_transformation& a) const;
|
||||
|
||||
// ordering
|
||||
bool operator<(const axis_transformation& a) const;
|
||||
|
||||
// concatenation operator
|
||||
axis_transformation operator+(const axis_transformation& a) const;
|
||||
|
||||
// concatenate this with that
|
||||
axis_transformation& operator+=(const axis_transformation& a);
|
||||
|
||||
// populate_axis_array writes the three INDIVIDUAL_AXIS values that the
|
||||
// ATR enum value of 'this' represent into axis_array
|
||||
void populate_axis_array(INDIVIDUAL_AXIS axis_array[]) const;
|
||||
|
||||
// it is recommended that the directions stored in an array
|
||||
// in the caller code for easier isotropic access by orientation value
|
||||
inline void get_directions(direction_2d& horizontal_dir,
|
||||
direction_2d& vertical_dir) const {
|
||||
bool bit2 = (atr_ & 4) != 0;
|
||||
bool bit1 = (atr_ & 2) != 0;
|
||||
bool bit0 = (atr_ & 1) != 0;
|
||||
vertical_dir = direction_2d((direction_2d_enum)(((int)(!bit2) << 1) + !bit1));
|
||||
horizontal_dir = direction_2d((direction_2d_enum)(((int)(bit2) << 1) + !bit0));
|
||||
}
|
||||
|
||||
// it is recommended that the directions stored in an array
|
||||
// in the caller code for easier isotropic access by orientation value
|
||||
inline void get_directions(direction_3d& horizontal_dir,
|
||||
direction_3d& vertical_dir,
|
||||
direction_3d& proximal_dir) const {
|
||||
bool bit5 = (atr_ & 32) != 0;
|
||||
bool bit4 = (atr_ & 16) != 0;
|
||||
bool bit3 = (atr_ & 8) != 0;
|
||||
bool bit2 = (atr_ & 4) != 0;
|
||||
bool bit1 = (atr_ & 2) != 0;
|
||||
bool bit0 = (atr_ & 1) != 0;
|
||||
proximal_dir = direction_3d((direction_2d_enum)((((int)(!bit4 & !bit5)) << 2) +
|
||||
((int)(bit5) << 1) +
|
||||
!bit3));
|
||||
vertical_dir = direction_3d((direction_2d_enum)((((int)((bit4 & bit2) | (bit5 & !bit2))) << 2)+
|
||||
((int)(!bit5 & !bit2) << 1) +
|
||||
!bit1));
|
||||
horizontal_dir = direction_3d((direction_2d_enum)((((int)((bit5 & bit2) |
|
||||
(bit4 & !bit2))) << 2) +
|
||||
((int)(bit2 & !bit5) << 1) +
|
||||
!bit0));
|
||||
}
|
||||
|
||||
// combine_axis_arrays concatenates this_array and that_array overwriting
|
||||
// the result into this_array
|
||||
static void combine_axis_arrays (INDIVIDUAL_AXIS this_array[],
|
||||
const INDIVIDUAL_AXIS that_array[]);
|
||||
|
||||
// write_back_axis_array converts an array of three INDIVIDUAL_AXIS values
|
||||
// to the ATR enum value and sets 'this' to that value
|
||||
void write_back_axis_array(const INDIVIDUAL_AXIS this_array[]);
|
||||
|
||||
// behavior is deterministic but undefined in the case where illegal
|
||||
// combinations of directions are passed in.
|
||||
axis_transformation& set_directions(const direction_2d& horizontal_dir,
|
||||
const direction_2d& vertical_dir);
|
||||
// behavior is deterministic but undefined in the case where illegal
|
||||
// combinations of directions are passed in.
|
||||
axis_transformation& set_directions(const direction_3d& horizontal_dir,
|
||||
const direction_3d& vertical_dir,
|
||||
const direction_3d& proximal_dir);
|
||||
|
||||
// transform the two coordinates by reference using the 2D portion of this
|
||||
template <typename coordinate_type>
|
||||
void transform(coordinate_type& x, coordinate_type& y) const;
|
||||
|
||||
// transform the three coordinates by reference
|
||||
template <typename coordinate_type>
|
||||
void transform(coordinate_type& x, coordinate_type& y, coordinate_type& z) const;
|
||||
|
||||
// invert the 2D portion of this
|
||||
axis_transformation& invert_2d();
|
||||
|
||||
// get the inverse of the 2D portion of this
|
||||
axis_transformation inverse_2d() const;
|
||||
|
||||
// invert this axis_transformation
|
||||
axis_transformation& invert();
|
||||
|
||||
// get the inverse axis_transformation of this
|
||||
axis_transformation inverse() const;
|
||||
|
||||
//friend std::ostream& operator<< (std::ostream& o, const axis_transformation& r);
|
||||
//friend std::istream& operator>> (std::istream& i, axis_transformation& r);
|
||||
|
||||
private:
|
||||
ATR atr_;
|
||||
};
|
||||
|
||||
|
||||
// Scaling object to be used to store the scale factor for each axis
|
||||
|
||||
// For use by the transformation object, in that context the scale factor
|
||||
// is the amount that each axis scales by when transformed.
|
||||
// If the horizontal value of the Scale is 10 that means the horizontal
|
||||
// axis of the input is multiplied by 10 when the transformation is applied.
|
||||
template <typename scale_factor_type>
|
||||
class anisotropic_scale_factor {
|
||||
public:
|
||||
inline anisotropic_scale_factor()
|
||||
#ifndef BOOST_POLYGON_MSVC
|
||||
: scale_()
|
||||
#endif
|
||||
{
|
||||
scale_[0] = 1;
|
||||
scale_[1] = 1;
|
||||
scale_[2] = 1;
|
||||
}
|
||||
inline anisotropic_scale_factor(scale_factor_type xscale, scale_factor_type yscale)
|
||||
#ifndef BOOST_POLYGON_MSVC
|
||||
: scale_()
|
||||
#endif
|
||||
{
|
||||
scale_[0] = xscale;
|
||||
scale_[1] = yscale;
|
||||
scale_[2] = 1;
|
||||
}
|
||||
inline anisotropic_scale_factor(scale_factor_type xscale, scale_factor_type yscale, scale_factor_type zscale)
|
||||
#ifndef BOOST_POLYGON_MSVC
|
||||
: scale_()
|
||||
#endif
|
||||
{
|
||||
scale_[0] = xscale;
|
||||
scale_[1] = yscale;
|
||||
scale_[2] = zscale;
|
||||
}
|
||||
|
||||
// get a component of the anisotropic_scale_factor by orientation
|
||||
scale_factor_type get(orientation_3d orient) const;
|
||||
scale_factor_type get(orientation_2d orient) const { return get(orientation_3d(orient)); }
|
||||
|
||||
// set a component of the anisotropic_scale_factor by orientation
|
||||
void set(orientation_3d orient, scale_factor_type value);
|
||||
void set(orientation_2d orient, scale_factor_type value) { set(orientation_3d(orient), value); }
|
||||
|
||||
scale_factor_type x() const;
|
||||
scale_factor_type y() const;
|
||||
scale_factor_type z() const;
|
||||
void x(scale_factor_type value);
|
||||
void y(scale_factor_type value);
|
||||
void z(scale_factor_type value);
|
||||
|
||||
// concatination operator (convolve scale factors)
|
||||
anisotropic_scale_factor operator+(const anisotropic_scale_factor& s) const;
|
||||
|
||||
// concatinate this with that
|
||||
const anisotropic_scale_factor& operator+=(const anisotropic_scale_factor& s);
|
||||
|
||||
// transform this scale with an axis_transform
|
||||
anisotropic_scale_factor& transform(axis_transformation atr);
|
||||
|
||||
// scale the two coordinates
|
||||
template <typename coordinate_type>
|
||||
void scale(coordinate_type& x, coordinate_type& y) const;
|
||||
|
||||
// scale the three coordinates
|
||||
template <typename coordinate_type>
|
||||
void scale(coordinate_type& x, coordinate_type& y, coordinate_type& z) const;
|
||||
|
||||
// invert this scale factor to give the reverse scale factor
|
||||
anisotropic_scale_factor& invert();
|
||||
|
||||
private:
|
||||
scale_factor_type scale_[3];
|
||||
|
||||
//friend std::ostream& operator<< (std::ostream& o, const Scale& r);
|
||||
//friend std::istream& operator>> (std::istream& i, Scale& r);
|
||||
};
|
||||
|
||||
// Transformation object, stores and provides services for transformations
|
||||
|
||||
// Transformation object stores an axistransformation, a scale factor and a translation.
|
||||
// The tranlation is the position of the origin of the new system of coordinates in the old system.
|
||||
// The scale scales the coordinates before they are transformed.
|
||||
template <typename coordinate_type>
|
||||
class transformation {
|
||||
public:
|
||||
transformation();
|
||||
transformation(axis_transformation atr);
|
||||
transformation(axis_transformation::ATR atr);
|
||||
template <typename point_type>
|
||||
transformation(const point_type& p);
|
||||
template <typename point_type>
|
||||
transformation(axis_transformation atr, const point_type& p);
|
||||
template <typename point_type>
|
||||
transformation(axis_transformation atr, const point_type& referencePt, const point_type& destinationPt);
|
||||
transformation(const transformation& tr);
|
||||
|
||||
// equivalence operator
|
||||
bool operator==(const transformation& tr) const;
|
||||
|
||||
// inequivalence operator
|
||||
bool operator!=(const transformation& tr) const;
|
||||
|
||||
// ordering
|
||||
bool operator<(const transformation& tr) const;
|
||||
|
||||
// concatenation operator
|
||||
transformation operator+(const transformation& tr) const;
|
||||
|
||||
// concatenate this with that
|
||||
const transformation& operator+=(const transformation& tr);
|
||||
|
||||
// get the axis_transformation portion of this
|
||||
inline axis_transformation get_axis_transformation() const {return atr_;}
|
||||
|
||||
// set the axis_transformation portion of this
|
||||
void set_axis_transformation(const axis_transformation& atr);
|
||||
|
||||
// get the translation portion of this as a point3d
|
||||
template <typename point_type>
|
||||
void get_translation(point_type& translation) const;
|
||||
|
||||
// set the translation portion of this with a point3d
|
||||
template <typename point_type>
|
||||
void set_translation(const point_type& p);
|
||||
|
||||
// apply the 2D portion of this transformation to the two coordinates given
|
||||
void transform(coordinate_type& x, coordinate_type& y) const;
|
||||
|
||||
// apply this transformation to the three coordinates given
|
||||
void transform(coordinate_type& x, coordinate_type& y, coordinate_type& z) const;
|
||||
|
||||
// invert this transformation
|
||||
transformation& invert();
|
||||
|
||||
// get the inverse of this transformation
|
||||
transformation inverse() const;
|
||||
|
||||
inline void get_directions(direction_2d& horizontal_dir,
|
||||
direction_2d& vertical_dir) const {
|
||||
return atr_.get_directions(horizontal_dir, vertical_dir); }
|
||||
|
||||
inline void get_directions(direction_3d& horizontal_dir,
|
||||
direction_3d& vertical_dir,
|
||||
direction_3d& proximal_dir) const {
|
||||
return atr_.get_directions(horizontal_dir, vertical_dir, proximal_dir); }
|
||||
|
||||
private:
|
||||
axis_transformation atr_;
|
||||
point_3d_data<coordinate_type> p_;
|
||||
|
||||
template <typename point_type>
|
||||
void construct_dispatch(axis_transformation atr, point_type p, point_concept tag);
|
||||
template <typename point_type>
|
||||
void construct_dispatch(axis_transformation atr, point_type p, point_3d_concept tag);
|
||||
template <typename point_type>
|
||||
void construct_dispatch(axis_transformation atr, point_type rp, point_type dp, point_concept tag);
|
||||
template <typename point_type>
|
||||
void construct_dispatch(axis_transformation atr, point_type rp, point_type dp, point_3d_concept tag);
|
||||
|
||||
//friend std::ostream& operator<< (std::ostream& o, const transformation& tr);
|
||||
//friend std::istream& operator>> (std::istream& i, transformation& tr);
|
||||
};
|
||||
}
|
||||
}
|
||||
#include "detail/transform_detail.hpp"
|
||||
#endif
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue