Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
K
kicad-source-mirror
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
Elphel
kicad-source-mirror
Commits
0d4b71ef
Commit
0d4b71ef
authored
Sep 18, 2013
by
tomasz.wlostowski@cern.ch
Browse files
Options
Browse Files
Download
Plain Diff
Merged Orson's latest changes.
parents
87dccc9f
9ec4520c
Changes
34
Hide whitespace changes
Inline
Side-by-side
Showing
34 changed files
with
1808 additions
and
1532 deletions
+1808
-1532
opengl_gal.cpp
common/gal/opengl/opengl_gal.cpp
+2
-4
painter.cpp
common/painter.cpp
+0
-22
jump_x86_64_sysv_elf_gas.S
common/system/jump_x86_64_sysv_elf_gas.S
+1
-1
make_x86_64_sysv_elf_gas.S
common/system/make_x86_64_sysv_elf_gas.S
+8
-1
tool_dispatcher.cpp
common/tool/tool_dispatcher.cpp
+3
-11
view.cpp
common/view/view.cpp
+23
-7
wx_view_controls.cpp
common/view/wx_view_controls.cpp
+41
-18
worksheet_item.cpp
common/worksheet_item.cpp
+3
-4
base_struct.h
include/base_struct.h
+3
-106
painter.h
include/painter.h
+30
-7
tool_dispatcher.h
include/tool/tool_dispatcher.h
+0
-2
view.h
include/view/view.h
+29
-0
view_controls.h
include/view/view_controls.h
+9
-14
view_group.h
include/view/view_group.h
+1
-1
view_item.h
include/view/view_item.h
+109
-0
wx_view_controls.h
include/view/wx_view_controls.h
+6
-0
CMakeLists.txt
pcbnew/CMakeLists.txt
+1
-0
basepcbframe.cpp
pcbnew/basepcbframe.cpp
+10
-0
class_dimension.cpp
pcbnew/class_dimension.cpp
+19
-0
class_dimension.h
pcbnew/class_dimension.h
+3
-0
class_module.cpp
pcbnew/class_module.cpp
+2
-1
pcb_painter.cpp
pcbnew/pcb_painter.cpp
+27
-21
pcb_painter.h
pcbnew/pcb_painter.h
+1
-1
pcbframe.cpp
pcbnew/pcbframe.cpp
+1
-2
bright_box.cpp
pcbnew/tools/bright_box.cpp
+72
-0
bright_box.h
pcbnew/tools/bright_box.h
+62
-0
selection_area.cpp
pcbnew/tools/selection_area.cpp
+3
-5
selection_area.h
pcbnew/tools/selection_area.h
+6
-7
selection_tool.cpp
pcbnew/tools/selection_tool.cpp
+48
-12
utils.h
polygon/poly2tri/common/utils.h
+123
-123
cdt.cc
polygon/poly2tri/sweep/cdt.cc
+72
-72
cdt.h
polygon/poly2tri/sweep/cdt.h
+105
-105
sweep.cc
polygon/poly2tri/sweep/sweep.cc
+800
-800
sweep_context.h
polygon/poly2tri/sweep/sweep_context.h
+185
-185
No files found.
common/gal/opengl/opengl_gal.cpp
View file @
0d4b71ef
...
@@ -278,10 +278,8 @@ void OPENGL_GAL::DrawSegment( const VECTOR2D& aStartPoint, const VECTOR2D& aEndP
...
@@ -278,10 +278,8 @@ void OPENGL_GAL::DrawSegment( const VECTOR2D& aStartPoint, const VECTOR2D& aEndP
VECTOR2D
(
lineLength
,
-
aWidth
/
2.0
)
);
VECTOR2D
(
lineLength
,
-
aWidth
/
2.0
)
);
// Draw line caps
// Draw line caps
drawStrokedSemiCircle
(
VECTOR2D
(
0.0
,
0.0
),
drawStrokedSemiCircle
(
VECTOR2D
(
0.0
,
0.0
),
aWidth
/
2
,
M_PI
/
2
);
(
aWidth
+
lineWidth
)
/
2
,
M_PI
/
2
);
drawStrokedSemiCircle
(
VECTOR2D
(
lineLength
,
0.0
),
aWidth
/
2
,
-
M_PI
/
2
);
drawStrokedSemiCircle
(
VECTOR2D
(
lineLength
,
0.0
),
(
aWidth
+
lineWidth
)
/
2
,
-
M_PI
/
2
);
Restore
();
Restore
();
}
}
...
...
common/painter.cpp
View file @
0d4b71ef
...
@@ -79,25 +79,3 @@ void PAINTER::SetGAL( GAL* aGal )
...
@@ -79,25 +79,3 @@ void PAINTER::SetGAL( GAL* aGal )
{
{
m_gal
=
aGal
;
m_gal
=
aGal
;
}
}
void
PAINTER
::
DrawBrightened
(
const
VIEW_ITEM
*
aItem
)
{
BOX2I
box
=
aItem
->
ViewBBox
();
RenderTarget
oldTarget
=
m_gal
->
GetTarget
();
m_gal
->
SetTarget
(
TARGET_OVERLAY
);
m_gal
->
PushDepth
();
m_gal
->
SetLayerDepth
(
-
1.0
);
// Draw an outline that marks items as brightened
m_gal
->
SetIsStroke
(
true
);
m_gal
->
SetLineWidth
(
100000.0
);
m_gal
->
SetStrokeColor
(
m_brightenedColor
);
m_gal
->
DrawRectangle
(
box
.
GetOrigin
(),
box
.
GetOrigin
()
+
box
.
GetSize
()
);
m_gal
->
PopDepth
();
m_gal
->
SetTarget
(
oldTarget
);
}
common/system/jump_x86_64_sysv_elf_gas.S
View file @
0d4b71ef
...
@@ -41,7 +41,7 @@
...
@@ -41,7 +41,7 @@
.text
.text
.globl jump_fcontext
.globl jump_fcontext
.type jump_fcontext,@function
.type jump_fcontext,@function
.align
16
.align
8
jump_fcontext:
jump_fcontext:
movq %rbx, (%rdi) /* save RBX */
movq %rbx, (%rdi) /* save RBX */
movq %r12, 0x8(%rdi) /* save R12 */
movq %r12, 0x8(%rdi) /* save R12 */
...
...
common/system/make_x86_64_sysv_elf_gas.S
View file @
0d4b71ef
...
@@ -40,8 +40,12 @@
...
@@ -40,8 +40,12 @@
.text
.text
.globl make_fcontext
.globl make_fcontext
#ifndef __APPLE__
.type make_fcontext,@function
.type make_fcontext,@function
.align 16
#endif
.align 8
make_fcontext:
make_fcontext:
leaq -0x58(%rdi), %rax /* reserve space for fcontext_t at top of context stack */
leaq -0x58(%rdi), %rax /* reserve space for fcontext_t at top of context stack */
...
@@ -70,5 +74,8 @@ finish:
...
@@ -70,5 +74,8 @@ finish:
xorq %rdi, %rdi /* exit code is zero */
xorq %rdi, %rdi /* exit code is zero */
call _exit@PLT /* exit application */
call _exit@PLT /* exit application */
hlt
hlt
#ifndef __APPLE__
.size make_fcontext,.-make_fcontext
.size make_fcontext,.-make_fcontext
#endif
common/tool/tool_dispatcher.cpp
View file @
0d4b71ef
...
@@ -31,6 +31,7 @@
...
@@ -31,6 +31,7 @@
#include <tool/tool_manager.h>
#include <tool/tool_manager.h>
#include <tool/tool_dispatcher.h>
#include <tool/tool_dispatcher.h>
#include <view/view.h>
#include <view/view.h>
#include <view/view_controls.h>
#include <class_drawpanel_gal.h>
#include <class_drawpanel_gal.h>
...
@@ -122,15 +123,6 @@ int TOOL_DISPATCHER::decodeModifiers( const wxKeyboardState* aState ) const
...
@@ -122,15 +123,6 @@ int TOOL_DISPATCHER::decodeModifiers( const wxKeyboardState* aState ) const
}
}
wxPoint
TOOL_DISPATCHER
::
getCurrentMousePos
()
const
{
wxPoint
msp
=
wxGetMousePosition
();
wxPoint
winp
=
m_editFrame
->
GetGalCanvas
()
->
GetScreenPosition
();
return
wxPoint
(
msp
.
x
-
winp
.
x
,
msp
.
y
-
winp
.
y
);
}
bool
TOOL_DISPATCHER
::
handleMouseButton
(
wxEvent
&
aEvent
,
int
aIndex
,
bool
aMotion
)
bool
TOOL_DISPATCHER
::
handleMouseButton
(
wxEvent
&
aEvent
,
int
aIndex
,
bool
aMotion
)
{
{
ButtonState
*
st
=
m_buttons
[
aIndex
];
ButtonState
*
st
=
m_buttons
[
aIndex
];
...
@@ -208,7 +200,6 @@ bool TOOL_DISPATCHER::handleMouseButton( wxEvent& aEvent, int aIndex, bool aMoti
...
@@ -208,7 +200,6 @@ bool TOOL_DISPATCHER::handleMouseButton( wxEvent& aEvent, int aIndex, bool aMoti
void
TOOL_DISPATCHER
::
DispatchWxEvent
(
wxEvent
&
aEvent
)
void
TOOL_DISPATCHER
::
DispatchWxEvent
(
wxEvent
&
aEvent
)
{
{
bool
motion
=
false
,
buttonEvents
=
false
;
bool
motion
=
false
,
buttonEvents
=
false
;
VECTOR2D
pos
;
optional
<
TOOL_EVENT
>
evt
;
optional
<
TOOL_EVENT
>
evt
;
int
type
=
aEvent
.
GetEventType
();
int
type
=
aEvent
.
GetEventType
();
...
@@ -220,7 +211,8 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent )
...
@@ -220,7 +211,8 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent )
type
==
wxEVT_RIGHT_DOWN
||
type
==
wxEVT_RIGHT_UP
||
type
==
wxEVT_RIGHT_DOWN
||
type
==
wxEVT_RIGHT_UP
||
type
==
EVT_REFRESH_MOUSE
)
type
==
EVT_REFRESH_MOUSE
)
{
{
pos
=
getView
()
->
ToWorld
(
getCurrentMousePos
()
);
VECTOR2D
screenPos
=
m_toolMgr
->
GetViewControls
()
->
GetCursorPosition
();
VECTOR2D
pos
=
getView
()
->
ToWorld
(
screenPos
);
if
(
pos
!=
m_lastMousePos
||
type
==
EVT_REFRESH_MOUSE
)
if
(
pos
!=
m_lastMousePos
||
type
==
EVT_REFRESH_MOUSE
)
{
{
motion
=
true
;
motion
=
true
;
...
...
common/view/view.cpp
View file @
0d4b71ef
...
@@ -45,8 +45,11 @@ VIEW::VIEW( bool aIsDynamic ) :
...
@@ -45,8 +45,11 @@ VIEW::VIEW( bool aIsDynamic ) :
m_scale
(
1.0
),
m_scale
(
1.0
),
m_painter
(
NULL
),
m_painter
(
NULL
),
m_gal
(
NULL
),
m_gal
(
NULL
),
m_dynamic
(
aIsDynamic
)
m_dynamic
(
aIsDynamic
),
m_scaleLimits
(
15000.0
,
1.0
)
{
{
m_panBoundary
.
SetMaximum
();
// Redraw everything at the beginning
// Redraw everything at the beginning
for
(
int
i
=
0
;
i
<
TARGETS_NUMBER
;
++
i
)
for
(
int
i
=
0
;
i
<
TARGETS_NUMBER
;
++
i
)
MarkTargetDirty
(
i
);
MarkTargetDirty
(
i
);
...
@@ -290,6 +293,11 @@ void VIEW::SetScale( double aScale )
...
@@ -290,6 +293,11 @@ void VIEW::SetScale( double aScale )
void
VIEW
::
SetScale
(
double
aScale
,
const
VECTOR2D
&
aAnchor
)
void
VIEW
::
SetScale
(
double
aScale
,
const
VECTOR2D
&
aAnchor
)
{
{
if
(
aScale
>
m_scaleLimits
.
x
)
aScale
=
m_scaleLimits
.
x
;
else
if
(
aScale
<
m_scaleLimits
.
y
)
aScale
=
m_scaleLimits
.
y
;
VECTOR2D
a
=
ToScreen
(
aAnchor
);
VECTOR2D
a
=
ToScreen
(
aAnchor
);
m_gal
->
SetZoomFactor
(
aScale
);
m_gal
->
SetZoomFactor
(
aScale
);
...
@@ -308,6 +316,20 @@ void VIEW::SetScale( double aScale, const VECTOR2D& aAnchor )
...
@@ -308,6 +316,20 @@ void VIEW::SetScale( double aScale, const VECTOR2D& aAnchor )
void
VIEW
::
SetCenter
(
const
VECTOR2D
&
aCenter
)
void
VIEW
::
SetCenter
(
const
VECTOR2D
&
aCenter
)
{
{
m_center
=
aCenter
;
m_center
=
aCenter
;
if
(
!
m_panBoundary
.
Contains
(
aCenter
)
)
{
if
(
aCenter
.
x
<
m_panBoundary
.
GetLeft
()
)
m_center
.
x
=
m_panBoundary
.
GetLeft
();
else
if
(
aCenter
.
x
>
m_panBoundary
.
GetRight
()
)
m_center
.
x
=
m_panBoundary
.
GetRight
();
if
(
aCenter
.
y
<
m_panBoundary
.
GetTop
()
)
m_center
.
y
=
m_panBoundary
.
GetTop
();
else
if
(
aCenter
.
y
>
m_panBoundary
.
GetBottom
()
)
m_center
.
y
=
m_panBoundary
.
GetBottom
();
}
m_gal
->
SetLookAtPoint
(
m_center
);
m_gal
->
SetLookAtPoint
(
m_center
);
m_gal
->
ComputeWorldScreenMatrix
();
m_gal
->
ComputeWorldScreenMatrix
();
...
@@ -604,12 +626,6 @@ void VIEW::draw( VIEW_ITEM* aItem, int aLayer, bool aImmediate ) const
...
@@ -604,12 +626,6 @@ void VIEW::draw( VIEW_ITEM* aItem, int aLayer, bool aImmediate ) const
if
(
!
m_painter
->
Draw
(
aItem
,
aLayer
)
)
if
(
!
m_painter
->
Draw
(
aItem
,
aLayer
)
)
aItem
->
ViewDraw
(
aLayer
,
m_gal
);
// Alternative drawing method
aItem
->
ViewDraw
(
aLayer
,
m_gal
);
// Alternative drawing method
}
}
// Draws a bright contour around the item
if
(
static_cast
<
const
EDA_ITEM
*>
(
aItem
)
->
IsBrightened
()
)
{
m_painter
->
DrawBrightened
(
aItem
);
}
}
}
...
...
common/view/wx_view_controls.cpp
View file @
0d4b71ef
...
@@ -28,6 +28,7 @@
...
@@ -28,6 +28,7 @@
#include <view/view.h>
#include <view/view.h>
#include <view/wx_view_controls.h>
#include <view/wx_view_controls.h>
#include <gal/graphics_abstraction_layer.h>
#include <gal/graphics_abstraction_layer.h>
#include <tool/tool_dispatcher.h>
using
namespace
KiGfx
;
using
namespace
KiGfx
;
...
@@ -58,18 +59,20 @@ WX_VIEW_CONTROLS::WX_VIEW_CONTROLS( VIEW* aView, wxWindow* aParentPanel ) :
...
@@ -58,18 +59,20 @@ WX_VIEW_CONTROLS::WX_VIEW_CONTROLS( VIEW* aView, wxWindow* aParentPanel ) :
WX_VIEW_CONTROLS
::
onTimer
),
NULL
,
this
);
WX_VIEW_CONTROLS
::
onTimer
),
NULL
,
this
);
}
}
void
VIEW_CONTROLS
::
ShowCursor
(
bool
aEnabled
)
void
VIEW_CONTROLS
::
ShowCursor
(
bool
aEnabled
)
{
{
m_view
->
GetGAL
()
->
SetCursorEnabled
(
aEnabled
);
m_view
->
GetGAL
()
->
SetCursorEnabled
(
aEnabled
);
}
}
void
WX_VIEW_CONTROLS
::
onMotion
(
wxMouseEvent
&
aEvent
)
void
WX_VIEW_CONTROLS
::
onMotion
(
wxMouseEvent
&
aEvent
)
{
{
m_mousePosition
.
x
=
aEvent
.
GetX
();
m_mousePosition
.
x
=
aEvent
.
GetX
();
m_mousePosition
.
y
=
aEvent
.
GetY
();
m_mousePosition
.
y
=
aEvent
.
GetY
();
if
(
m_forceCursorPosition
)
if
(
m_forceCursorPosition
)
m_cursorPosition
=
m_view
->
ToScreen
(
m_forcedPosition
);
m_cursorPosition
=
m_view
->
ToScreen
(
m_forcedPosition
);
else
if
(
m_snappingEnabled
)
else
if
(
m_snappingEnabled
)
m_cursorPosition
=
m_view
->
GetGAL
()
->
GetGridPoint
(
m_mousePosition
);
m_cursorPosition
=
m_view
->
GetGAL
()
->
GetGridPoint
(
m_mousePosition
);
else
else
...
@@ -190,26 +193,28 @@ void WX_VIEW_CONTROLS::onTimer( wxTimerEvent& aEvent )
...
@@ -190,26 +193,28 @@ void WX_VIEW_CONTROLS::onTimer( wxTimerEvent& aEvent )
{
{
switch
(
m_state
)
switch
(
m_state
)
{
{
case
AUTO_PANNING
:
case
AUTO_PANNING
:
{
{
double
borderSize
=
std
::
min
(
m_autoPanMargin
*
m_view
->
GetScreenPixelSize
().
x
,
double
borderSize
=
std
::
min
(
m_autoPanMargin
*
m_view
->
GetScreenPixelSize
().
x
,
m_autoPanMargin
*
m_view
->
GetScreenPixelSize
().
y
);
m_autoPanMargin
*
m_view
->
GetScreenPixelSize
().
y
);
VECTOR2D
dir
(
m_panDirection
);
VECTOR2D
dir
(
m_panDirection
);
if
(
dir
.
EuclideanNorm
()
>
borderSize
)
if
(
dir
.
EuclideanNorm
()
>
borderSize
)
dir
=
dir
.
Resize
(
borderSize
);
dir
=
dir
.
Resize
(
borderSize
);
dir
=
m_view
->
ToWorld
(
dir
,
false
);
dir
=
m_view
->
ToWorld
(
dir
,
false
);
m_view
->
SetCenter
(
m_view
->
GetCenter
()
+
dir
*
m_autoPanSpeed
);
m_view
->
SetCenter
(
m_view
->
GetCenter
()
+
dir
*
m_autoPanSpeed
);
m_parentPanel
->
Refresh
();
// Notify tools that the cursor position has changed in the world coordinates
}
wxCommandEvent
moveEvent
(
TOOL_DISPATCHER
::
EVT_REFRESH_MOUSE
);
break
;
wxPostEvent
(
m_parentPanel
,
moveEvent
);
}
break
;
case
IDLE
:
// Just remove unnecessary warnings
case
IDLE
:
// Just remove unnecessary warnings
case
DRAG_PANNING
:
case
DRAG_PANNING
:
break
;
break
;
}
}
}
}
...
@@ -225,6 +230,24 @@ void WX_VIEW_CONTROLS::SetGrabMouse( bool aEnabled )
...
@@ -225,6 +230,24 @@ void WX_VIEW_CONTROLS::SetGrabMouse( bool aEnabled )
}
}
const
VECTOR2D
WX_VIEW_CONTROLS
::
GetMousePosition
()
const
{
wxPoint
msp
=
wxGetMousePosition
();
wxPoint
winp
=
m_parentPanel
->
GetScreenPosition
();
return
VECTOR2D
(
msp
.
x
-
winp
.
x
,
msp
.
y
-
winp
.
y
);
}
const
VECTOR2D
WX_VIEW_CONTROLS
::
GetCursorPosition
()
const
{
if
(
m_snappingEnabled
)
return
m_view
->
GetGAL
()
->
GetGridPoint
(
GetMousePosition
()
);
else
return
GetMousePosition
();
}
bool
WX_VIEW_CONTROLS
::
handleAutoPanning
(
const
wxMouseEvent
&
aEvent
)
bool
WX_VIEW_CONTROLS
::
handleAutoPanning
(
const
wxMouseEvent
&
aEvent
)
{
{
VECTOR2D
p
(
aEvent
.
GetX
(),
aEvent
.
GetY
()
);
VECTOR2D
p
(
aEvent
.
GetX
(),
aEvent
.
GetY
()
);
...
...
common/worksheet_item.cpp
View file @
0d4b71ef
...
@@ -97,9 +97,6 @@ void WORKSHEET_ITEM::ViewDraw( int aLayer, GAL* aGal ) const
...
@@ -97,9 +97,6 @@ void WORKSHEET_ITEM::ViewDraw( int aLayer, GAL* aGal ) const
EDA_COLOR_T
edaColor
=
ColorFindNearest
(
color
.
r
*
255
,
color
.
g
*
255
,
color
.
b
*
255
);
EDA_COLOR_T
edaColor
=
ColorFindNearest
(
color
.
r
*
255
,
color
.
g
*
255
,
color
.
b
*
255
);
drawList
.
BuildWorkSheetGraphicList
(
*
m_pageInfo
,
*
m_titleBlock
,
edaColor
,
edaColor
);
drawList
.
BuildWorkSheetGraphicList
(
*
m_pageInfo
,
*
m_titleBlock
,
edaColor
,
edaColor
);
// Draw gray line that outlines the sheet size
drawBorder
(
aGal
);
// Draw all the components that make the page layout
// Draw all the components that make the page layout
WS_DRAW_ITEM_BASE
*
item
=
drawList
.
GetFirst
();
WS_DRAW_ITEM_BASE
*
item
=
drawList
.
GetFirst
();
while
(
item
)
while
(
item
)
...
@@ -125,6 +122,9 @@ void WORKSHEET_ITEM::ViewDraw( int aLayer, GAL* aGal ) const
...
@@ -125,6 +122,9 @@ void WORKSHEET_ITEM::ViewDraw( int aLayer, GAL* aGal ) const
item
=
drawList
.
GetNext
();
item
=
drawList
.
GetNext
();
}
}
// Draw gray line that outlines the sheet size
drawBorder
(
aGal
);
}
}
...
@@ -200,6 +200,5 @@ void WORKSHEET_ITEM::drawBorder( GAL* aGal ) const
...
@@ -200,6 +200,5 @@ void WORKSHEET_ITEM::drawBorder( GAL* aGal ) const
aGal
->
SetIsStroke
(
true
);
aGal
->
SetIsStroke
(
true
);
aGal
->
SetIsFill
(
false
);
aGal
->
SetIsFill
(
false
);
aGal
->
SetStrokeColor
(
COLOR4D
(
0.5
,
0.5
,
0.5
,
1.0
)
);
aGal
->
DrawRectangle
(
origin
,
end
);
aGal
->
DrawRectangle
(
origin
,
end
);
}
}
include/base_struct.h
View file @
0d4b71ef
...
@@ -47,104 +47,6 @@ extern std::ostream& operator <<( std::ostream& out, const wxPoint& pt );
...
@@ -47,104 +47,6 @@ extern std::ostream& operator <<( std::ostream& out, const wxPoint& pt );
#endif
#endif
/**
* Enum KICAD_T
* is the set of class identification values, stored in EDA_ITEM::m_StructType
*/
enum
KICAD_T
{
NOT_USED
=
-
1
,
///< the 3d code uses this value
EOT
=
0
,
///< search types array terminator (End Of Types)
TYPE_NOT_INIT
=
0
,
PCB_T
,
SCREEN_T
,
///< not really an item, used to identify a screen
// Items in pcb
PCB_MODULE_T
,
///< class MODULE, a footprint
PCB_PAD_T
,
///< class D_PAD, a pad in a footprint
PCB_LINE_T
,
///< class DRAWSEGMENT, a segment not on copper layers
PCB_TEXT_T
,
///< class TEXTE_PCB, text on a layer
PCB_MODULE_TEXT_T
,
///< class TEXTE_MODULE, text in a footprint
PCB_MODULE_EDGE_T
,
///< class EDGE_MODULE, a footprint edge
PCB_TRACE_T
,
///< class TRACKE, a track segment (segment on a copper layer)
PCB_VIA_T
,
///< class SEGVIA, a via (like a track segment on a copper layer)
PCB_ZONE_T
,
///< class SEGZONE, a segment used to fill a zone area (segment on a
///< copper layer)
PCB_MARKER_T
,
///< class MARKER_PCB, a marker used to show something
PCB_DIMENSION_T
,
///< class DIMENSION, a dimension (graphic item)
PCB_TARGET_T
,
///< class PCB_TARGET, a target (graphic item)
PCB_ZONE_AREA_T
,
///< class ZONE_CONTAINER, a zone area
PCB_ITEM_LIST_T
,
///< class BOARD_ITEM_LIST, a list of board items
// Schematic draw Items. The order of these items effects the sort order.
// It is currently ordered to mimic the old Eeschema locate behavior where
// the smallest item is the selected item.
SCH_MARKER_T
,
SCH_JUNCTION_T
,
SCH_NO_CONNECT_T
,
SCH_BUS_WIRE_ENTRY_T
,
SCH_BUS_BUS_ENTRY_T
,
SCH_LINE_T
,
SCH_BITMAP_T
,
SCH_TEXT_T
,
SCH_LABEL_T
,
SCH_GLOBAL_LABEL_T
,
SCH_HIERARCHICAL_LABEL_T
,
SCH_FIELD_T
,
SCH_COMPONENT_T
,
SCH_SHEET_PIN_T
,
SCH_SHEET_T
,
// Be prudent with these 3 types:
// they should be used only to locate a specific field type
// among SCH_FIELD_T items types
SCH_FIELD_LOCATE_REFERENCE_T
,
SCH_FIELD_LOCATE_VALUE_T
,
SCH_FIELD_LOCATE_FOOTPRINT_T
,
// General
SCH_SCREEN_T
,
/*
* Draw items in library component.
*
* The order of these items effects the sort order for items inside the
* "DRAW/ENDDRAW" section of the component definition in a library file.
* If you add a new draw item, type, please make sure you add it so the
* sort order is logical.
*/
LIB_COMPONENT_T
,
LIB_ALIAS_T
,
LIB_ARC_T
,
LIB_CIRCLE_T
,
LIB_TEXT_T
,
LIB_RECTANGLE_T
,
LIB_POLYLINE_T
,
LIB_BEZIER_T
,
LIB_PIN_T
,
/*
* Fields are not saved inside the "DRAW/ENDDRAW". Add new draw item
* types before this line.
*/
LIB_FIELD_T
,
/*
* For GerbView: items type:
*/
TYPE_GERBER_DRAW_ITEM
,
/*
* for Pl_Editor, in undo/redo commands
*/
TYPE_PL_EDITOR_LAYOUT
,
// End value
MAX_STRUCT_TYPE_ID
};
/**
/**
* Enum FILL_T
* Enum FILL_T
* is the set of fill types used in plotting or drawing enclosed areas.
* is the set of fill types used in plotting or drawing enclosed areas.
...
@@ -440,12 +342,7 @@ public:
...
@@ -440,12 +342,7 @@ public:
EDA_ITEM
(
const
EDA_ITEM
&
base
);
EDA_ITEM
(
const
EDA_ITEM
&
base
);
virtual
~
EDA_ITEM
()
{
};
virtual
~
EDA_ITEM
()
{
};
/**
/// @copydoc VIEW_ITEM::Type()
* Function Type
* returns the type of object. This attribute should never be changed
* after a constructor sets it, so there is no public "setter" method.
* @return KICAD_T - the type of object.
*/
KICAD_T
Type
()
const
{
return
m_StructType
;
}
KICAD_T
Type
()
const
{
return
m_StructType
;
}
void
SetTimeStamp
(
time_t
aNewTimeStamp
)
{
m_TimeStamp
=
aNewTimeStamp
;
}
void
SetTimeStamp
(
time_t
aNewTimeStamp
)
{
m_TimeStamp
=
aNewTimeStamp
;
}
...
@@ -474,11 +371,11 @@ public:
...
@@ -474,11 +371,11 @@ public:
inline
void
SetSelected
()
{
SetFlags
(
SELECTED
);
ViewUpdate
(
COLOR
);
}
inline
void
SetSelected
()
{
SetFlags
(
SELECTED
);
ViewUpdate
(
COLOR
);
}
inline
void
SetHighlighted
()
{
SetFlags
(
HIGHLIGHTED
);
ViewUpdate
(
COLOR
);
}
inline
void
SetHighlighted
()
{
SetFlags
(
HIGHLIGHTED
);
ViewUpdate
(
COLOR
);
}
inline
void
SetBrightened
()
{
SetFlags
(
BRIGHTENED
);
ViewUpdate
(
COLOR
);
}
inline
void
SetBrightened
()
{
SetFlags
(
BRIGHTENED
);
}
inline
void
ClearSelected
()
{
ClearFlags
(
SELECTED
);
ViewUpdate
(
COLOR
);
}
inline
void
ClearSelected
()
{
ClearFlags
(
SELECTED
);
ViewUpdate
(
COLOR
);
}
inline
void
ClearHighlighted
()
{
ClearFlags
(
HIGHLIGHTED
);
ViewUpdate
(
COLOR
);
}
inline
void
ClearHighlighted
()
{
ClearFlags
(
HIGHLIGHTED
);
ViewUpdate
(
COLOR
);
}
inline
void
ClearBrightened
()
{
ClearFlags
(
BRIGHTENED
);
ViewUpdate
(
COLOR
);
}
inline
void
ClearBrightened
()
{
ClearFlags
(
BRIGHTENED
);
}
void
SetModified
();
void
SetModified
();
...
...
include/painter.h
View file @
0d4b71ef
...
@@ -80,6 +80,16 @@ public:
...
@@ -80,6 +80,16 @@ public:
m_activeLayers
.
erase
(
aLayerId
);
m_activeLayers
.
erase
(
aLayerId
);
}
}
/**
* Function GetActiveLayers()
* Returns the set of currently active layers.
* @return The set of currently active layers.
*/
const
std
::
set
<
unsigned
int
>
GetActiveLayers
()
{
return
m_activeLayers
;
}
/**
/**
* Function ClearActiveLayers
* Function ClearActiveLayers
* Clears the list of active layers.
* Clears the list of active layers.
...
@@ -89,6 +99,16 @@ public:
...
@@ -89,6 +99,16 @@ public:
m_activeLayers
.
clear
();
m_activeLayers
.
clear
();
}
}
/**
* Function IsActiveLayer
* Returns information whether the queried layer is marked as active.
* @return True if the queried layer is marked as active.
*/
inline
bool
IsActiveLayer
(
int
aLayerId
)
const
{
return
(
m_activeLayers
.
count
(
aLayerId
)
>
0
);
}
/**
/**
* Function SetHighlight
* Function SetHighlight
* Turns on/off highlighting - it may be done for the active layer or the specified net.
* Turns on/off highlighting - it may be done for the active layer or the specified net.
...
@@ -114,6 +134,16 @@ public:
...
@@ -114,6 +134,16 @@ public:
m_hiContrastEnabled
=
aEnabled
;
m_hiContrastEnabled
=
aEnabled
;
}
}
/**
* Function GetHighContrast
* Returns information about high contrast display mode.
* @return True if the high contrast mode is on, false otherwise.
*/
inline
bool
GetHighContrast
()
const
{
return
m_hiContrastEnabled
;
}
/**
/**
* Function GetColor
* Function GetColor
* Returns the color that should be used to draw the specific VIEW_ITEM on the specific layer
* Returns the color that should be used to draw the specific VIEW_ITEM on the specific layer
...
@@ -224,13 +254,6 @@ public:
...
@@ -224,13 +254,6 @@ public:
*/
*/
virtual
bool
Draw
(
const
VIEW_ITEM
*
aItem
,
int
aLayer
)
=
0
;
virtual
bool
Draw
(
const
VIEW_ITEM
*
aItem
,
int
aLayer
)
=
0
;
/**
* Function DrawBrightened
* Draws a special marking for the item.
* @param aItem is the item that is going to be marked.
*/
virtual
void
DrawBrightened
(
const
VIEW_ITEM
*
aItem
);
protected
:
protected
:
/// Instance of graphic abstraction layer that gives an interface to call
/// Instance of graphic abstraction layer that gives an interface to call
/// commands used to draw (eg. DrawLine, DrawCircle, etc.)
/// commands used to draw (eg. DrawLine, DrawCircle, etc.)
...
...
include/tool/tool_dispatcher.h
View file @
0d4b71ef
...
@@ -76,8 +76,6 @@ private:
...
@@ -76,8 +76,6 @@ private:
bool
handleMouseButton
(
wxEvent
&
aEvent
,
int
aIndex
,
bool
aMotion
);
bool
handleMouseButton
(
wxEvent
&
aEvent
,
int
aIndex
,
bool
aMotion
);
bool
handlePopupMenu
(
wxEvent
&
aEvent
);
bool
handlePopupMenu
(
wxEvent
&
aEvent
);
wxPoint
getCurrentMousePos
()
const
;
int
decodeModifiers
(
const
wxKeyboardState
*
aState
)
const
;
int
decodeModifiers
(
const
wxKeyboardState
*
aState
)
const
;
struct
ButtonState
;
struct
ButtonState
;
...
...
include/view/view.h
View file @
0d4b71ef
...
@@ -455,6 +455,29 @@ public:
...
@@ -455,6 +455,29 @@ public:
m_dirtyTargets
[
i
]
=
true
;
m_dirtyTargets
[
i
]
=
true
;
}
}
/**
* Function SetPanBoundary()
* Sets limits for panning area.
* @param aBoundary is the box that limits panning area.
*/
void
SetPanBoundary
(
const
BOX2I
&
aBoundary
)
{
m_panBoundary
=
aBoundary
;
}
/**
* Function SetScaleLimits()
* Sets minimum and maximum values for scale.
* @param aMaximum is the maximum value for scale..
* @param aMinimum is the minimum value for scale.
*/
void
SetScaleLimits
(
double
aMaximum
,
double
aMinimum
)
{
wxASSERT_MSG
(
aMaximum
>
aMinimum
,
wxT
(
"I guess you passed parameters in wrong order"
)
);
m_scaleLimits
=
VECTOR2D
(
aMaximum
,
aMinimum
);
}
static
const
int
VIEW_MAX_LAYERS
=
128
;
///* maximum number of layers that may be shown
static
const
int
VIEW_MAX_LAYERS
=
128
;
///* maximum number of layers that may be shown
private
:
private
:
...
@@ -588,6 +611,12 @@ private:
...
@@ -588,6 +611,12 @@ private:
/// Rendering order modifier for layers that are marked as top layers
/// Rendering order modifier for layers that are marked as top layers
static
const
int
TOP_LAYER_MODIFIER
=
-
VIEW_MAX_LAYERS
;
static
const
int
TOP_LAYER_MODIFIER
=
-
VIEW_MAX_LAYERS
;
/// Panning boundaries
BOX2I
m_panBoundary
;
/// Zoom limits
VECTOR2D
m_scaleLimits
;
};
};
}
// namespace KiGfx
}
// namespace KiGfx
...
...
include/view/view_controls.h
View file @
0d4b71ef
...
@@ -46,9 +46,9 @@ class VIEW;
...
@@ -46,9 +46,9 @@ class VIEW;
class
VIEW_CONTROLS
class
VIEW_CONTROLS
{
{
public
:
public
:
VIEW_CONTROLS
(
VIEW
*
aView
)
:
m_view
(
aView
),
m_
snappingEnabled
(
false
),
VIEW_CONTROLS
(
VIEW
*
aView
)
:
m_view
(
aView
),
m_
forceCursorPosition
(
false
),
m_
grabMouse
(
false
),
m_autoPanEnabled
(
false
),
m_autoPanMargin
(
0
.
1
),
m_
snappingEnabled
(
false
),
m_grabMouse
(
false
),
m_autoPanEnabled
(
false
),
m_autoPanSpeed
(
0
.
15
)
{};
m_autoPan
Margin
(
0
.
1
),
m_autoPan
Speed
(
0
.
15
)
{};
virtual
~
VIEW_CONTROLS
()
{};
virtual
~
VIEW_CONTROLS
()
{};
/**
/**
...
@@ -110,10 +110,7 @@ public:
...
@@ -110,10 +110,7 @@ public:
*
*
* @return The current mouse pointer position.
* @return The current mouse pointer position.
*/
*/
virtual
const
VECTOR2D
&
GetMousePosition
()
const
virtual
const
VECTOR2D
GetMousePosition
()
const
=
0
;
{
return
m_mousePosition
;
}
/**
/**
* Function GetCursorPosition()
* Function GetCursorPosition()
...
@@ -122,10 +119,7 @@ public:
...
@@ -122,10 +119,7 @@ public:
*
*
* @return The current cursor position in screen coordinates.
* @return The current cursor position in screen coordinates.
*/
*/
virtual
const
VECTOR2D
&
GetCursorPosition
()
const
virtual
const
VECTOR2D
GetCursorPosition
()
const
=
0
;
{
return
m_cursorPosition
;
}
/**
/**
...
@@ -140,7 +134,7 @@ public:
...
@@ -140,7 +134,7 @@ public:
m_forceCursorPosition
=
aEnabled
;
m_forceCursorPosition
=
aEnabled
;
}
}
virtual
void
ShowCursor
(
bool
aEnabled
);
virtual
void
ShowCursor
(
bool
aEnabled
);
protected
:
protected
:
/// Pointer to controlled VIEW.
/// Pointer to controlled VIEW.
...
@@ -155,6 +149,9 @@ protected:
...
@@ -155,6 +149,9 @@ protected:
/// Forced cursor position
/// Forced cursor position
VECTOR2D
m_forcedPosition
;
VECTOR2D
m_forcedPosition
;
/// Is the forced cursor position enabled
bool
m_forceCursorPosition
;
/// Should the cursor snap to grid or move freely
/// Should the cursor snap to grid or move freely
bool
m_snappingEnabled
;
bool
m_snappingEnabled
;
...
@@ -164,8 +161,6 @@ protected:
...
@@ -164,8 +161,6 @@ protected:
/// Flag for turning on autopanning
/// Flag for turning on autopanning
bool
m_autoPanEnabled
;
bool
m_autoPanEnabled
;
bool
m_forceCursorPosition
;
/// Distance from cursor to VIEW edge when panning is active
/// Distance from cursor to VIEW edge when panning is active
float
m_autoPanMargin
;
float
m_autoPanMargin
;
...
...
include/view/view_group.h
View file @
0d4b71ef
...
@@ -142,7 +142,7 @@ public:
...
@@ -142,7 +142,7 @@ public:
*
*
* @return Pointer to the VIEW instance.
* @return Pointer to the VIEW instance.
*/
*/
KiGfx
::
VIEW
*
GetView
()
const
KiGfx
::
VIEW
*
GetView
()
const
{
{
return
m_view
;
return
m_view
;
}
}
...
...
include/view/view_item.h
View file @
0d4b71ef
...
@@ -36,6 +36,104 @@
...
@@ -36,6 +36,104 @@
#include <view/view.h>
#include <view/view.h>
#include <gal/definitions.h>
#include <gal/definitions.h>
/**
* Enum KICAD_T
* is the set of class identification values, stored in EDA_ITEM::m_StructType
*/
enum
KICAD_T
{
NOT_USED
=
-
1
,
///< the 3d code uses this value
EOT
=
0
,
///< search types array terminator (End Of Types)
TYPE_NOT_INIT
=
0
,
PCB_T
,
SCREEN_T
,
///< not really an item, used to identify a screen
// Items in pcb
PCB_MODULE_T
,
///< class MODULE, a footprint
PCB_PAD_T
,
///< class D_PAD, a pad in a footprint
PCB_LINE_T
,
///< class DRAWSEGMENT, a segment not on copper layers
PCB_TEXT_T
,
///< class TEXTE_PCB, text on a layer
PCB_MODULE_TEXT_T
,
///< class TEXTE_MODULE, text in a footprint
PCB_MODULE_EDGE_T
,
///< class EDGE_MODULE, a footprint edge
PCB_TRACE_T
,
///< class TRACKE, a track segment (segment on a copper layer)
PCB_VIA_T
,
///< class SEGVIA, a via (like a track segment on a copper layer)
PCB_ZONE_T
,
///< class SEGZONE, a segment used to fill a zone area (segment on a
///< copper layer)
PCB_MARKER_T
,
///< class MARKER_PCB, a marker used to show something
PCB_DIMENSION_T
,
///< class DIMENSION, a dimension (graphic item)
PCB_TARGET_T
,
///< class PCB_TARGET, a target (graphic item)
PCB_ZONE_AREA_T
,
///< class ZONE_CONTAINER, a zone area
PCB_ITEM_LIST_T
,
///< class BOARD_ITEM_LIST, a list of board items
// Schematic draw Items. The order of these items effects the sort order.
// It is currently ordered to mimic the old Eeschema locate behavior where
// the smallest item is the selected item.
SCH_MARKER_T
,
SCH_JUNCTION_T
,
SCH_NO_CONNECT_T
,
SCH_BUS_WIRE_ENTRY_T
,
SCH_BUS_BUS_ENTRY_T
,
SCH_LINE_T
,
SCH_BITMAP_T
,
SCH_TEXT_T
,
SCH_LABEL_T
,
SCH_GLOBAL_LABEL_T
,
SCH_HIERARCHICAL_LABEL_T
,
SCH_FIELD_T
,
SCH_COMPONENT_T
,
SCH_SHEET_PIN_T
,
SCH_SHEET_T
,
// Be prudent with these 3 types:
// they should be used only to locate a specific field type
// among SCH_FIELD_T items types
SCH_FIELD_LOCATE_REFERENCE_T
,
SCH_FIELD_LOCATE_VALUE_T
,
SCH_FIELD_LOCATE_FOOTPRINT_T
,
// General
SCH_SCREEN_T
,
/*
* Draw items in library component.
*
* The order of these items effects the sort order for items inside the
* "DRAW/ENDDRAW" section of the component definition in a library file.
* If you add a new draw item, type, please make sure you add it so the
* sort order is logical.
*/
LIB_COMPONENT_T
,
LIB_ALIAS_T
,
LIB_ARC_T
,
LIB_CIRCLE_T
,
LIB_TEXT_T
,
LIB_RECTANGLE_T
,
LIB_POLYLINE_T
,
LIB_BEZIER_T
,
LIB_PIN_T
,
/*
* Fields are not saved inside the "DRAW/ENDDRAW". Add new draw item
* types before this line.
*/
LIB_FIELD_T
,
/*
* For GerbView: items type:
*/
TYPE_GERBER_DRAW_ITEM
,
/*
* for Pl_Editor, in undo/redo commands
*/
TYPE_PL_EDITOR_LAYOUT
,
// End value
MAX_STRUCT_TYPE_ID
};
namespace
KiGfx
namespace
KiGfx
{
{
// Forward declarations
// Forward declarations
...
@@ -81,6 +179,17 @@ public:
...
@@ -81,6 +179,17 @@ public:
delete
[]
m_groups
;
delete
[]
m_groups
;
};
};
/**
* Function Type
* returns the type of object. This attribute should never be changed
* after a constructor sets it, so there is no public "setter" method.
* @return KICAD_T - the type of object.
*/
virtual
KICAD_T
Type
()
const
{
return
NOT_USED
;
}
/**
/**
* Function ViewBBox()
* Function ViewBBox()
* returns the bounding box of the item covering all its layers.
* returns the bounding box of the item covering all its layers.
...
...
include/view/wx_view_controls.h
View file @
0d4b71ef
...
@@ -78,6 +78,12 @@ public:
...
@@ -78,6 +78,12 @@ public:
m_state
=
IDLE
;
m_state
=
IDLE
;
}
}
/// @copydoc VIEW_CONTROLS::GetMousePosition()
virtual
const
VECTOR2D
GetMousePosition
()
const
;
/// @copydoc VIEW_CONTROLS::GetCursorPosition()
virtual
const
VECTOR2D
GetCursorPosition
()
const
;
private
:
private
:
/// Possible states for WX_VIEW_CONTROLS
/// Possible states for WX_VIEW_CONTROLS
enum
State
{
enum
State
{
...
...
pcbnew/CMakeLists.txt
View file @
0d4b71ef
...
@@ -221,6 +221,7 @@ set(PCBNEW_CLASS_SRCS
...
@@ -221,6 +221,7 @@ set(PCBNEW_CLASS_SRCS
tools/selection_tool.cpp
tools/selection_tool.cpp
tools/selection_area.cpp
tools/selection_area.cpp
tools/bright_box.cpp
tools/move_tool.cpp
tools/move_tool.cpp
tools/pcb_tools.cpp
tools/pcb_tools.cpp
)
)
...
...
pcbnew/basepcbframe.cpp
View file @
0d4b71ef
...
@@ -217,6 +217,7 @@ void PCB_BASE_FRAME::ViewReloadBoard( const BOARD* aBoard ) const
...
@@ -217,6 +217,7 @@ void PCB_BASE_FRAME::ViewReloadBoard( const BOARD* aBoard ) const
view
->
Add
(
worksheet
);
view
->
Add
(
worksheet
);
view
->
SetPanBoundary
(
worksheet
->
ViewBBox
()
);
view
->
RecacheAllItems
(
true
);
view
->
RecacheAllItems
(
true
);
if
(
m_galCanvasActive
)
if
(
m_galCanvasActive
)
...
@@ -857,8 +858,17 @@ void PCB_BASE_FRAME::LoadSettings()
...
@@ -857,8 +858,17 @@ void PCB_BASE_FRAME::LoadSettings()
view
->
SetRequired
(
ITEM_GAL_LAYER
(
VIAS_HOLES_VISIBLE
),
ITEM_GAL_LAYER
(
VIAS_VISIBLE
)
);
view
->
SetRequired
(
ITEM_GAL_LAYER
(
VIAS_HOLES_VISIBLE
),
ITEM_GAL_LAYER
(
VIAS_VISIBLE
)
);
view
->
SetRequired
(
ITEM_GAL_LAYER
(
PADS_HOLES_VISIBLE
),
ITEM_GAL_LAYER
(
PADS_VISIBLE
)
);
view
->
SetRequired
(
ITEM_GAL_LAYER
(
PADS_HOLES_VISIBLE
),
ITEM_GAL_LAYER
(
PADS_VISIBLE
)
);
view
->
SetRequired
(
ITEM_GAL_LAYER
(
PADS_NETNAMES_VISIBLE
),
ITEM_GAL_LAYER
(
PADS_VISIBLE
)
);
view
->
SetRequired
(
ITEM_GAL_LAYER
(
PADS_NETNAMES_VISIBLE
),
ITEM_GAL_LAYER
(
PADS_VISIBLE
)
);
view
->
SetRequired
(
ITEM_GAL_LAYER
(
PAD_FR_NETNAMES_VISIBLE
),
ITEM_GAL_LAYER
(
PAD_FR_VISIBLE
)
);
view
->
SetRequired
(
ITEM_GAL_LAYER
(
PAD_FR_NETNAMES_VISIBLE
),
ITEM_GAL_LAYER
(
PAD_FR_VISIBLE
)
);
view
->
SetRequired
(
ADHESIVE_N_FRONT
,
ITEM_GAL_LAYER
(
PAD_FR_VISIBLE
)
);
view
->
SetRequired
(
SOLDERPASTE_N_FRONT
,
ITEM_GAL_LAYER
(
PAD_FR_VISIBLE
)
);
view
->
SetRequired
(
SOLDERMASK_N_FRONT
,
ITEM_GAL_LAYER
(
PAD_FR_VISIBLE
)
);
view
->
SetRequired
(
ITEM_GAL_LAYER
(
PAD_BK_NETNAMES_VISIBLE
),
ITEM_GAL_LAYER
(
PAD_BK_VISIBLE
)
);
view
->
SetRequired
(
ITEM_GAL_LAYER
(
PAD_BK_NETNAMES_VISIBLE
),
ITEM_GAL_LAYER
(
PAD_BK_VISIBLE
)
);
view
->
SetRequired
(
ADHESIVE_N_BACK
,
ITEM_GAL_LAYER
(
PAD_BK_VISIBLE
)
);
view
->
SetRequired
(
SOLDERPASTE_N_BACK
,
ITEM_GAL_LAYER
(
PAD_BK_VISIBLE
)
);
view
->
SetRequired
(
SOLDERMASK_N_BACK
,
ITEM_GAL_LAYER
(
PAD_BK_VISIBLE
)
);
view
->
SetLayerTarget
(
ITEM_GAL_LAYER
(
SELECTION
),
KiGfx
::
TARGET_OVERLAY
);
view
->
SetLayerTarget
(
ITEM_GAL_LAYER
(
SELECTION
),
KiGfx
::
TARGET_OVERLAY
);
view
->
SetLayerTarget
(
ITEM_GAL_LAYER
(
GP_OVERLAY
),
KiGfx
::
TARGET_OVERLAY
);
view
->
SetLayerTarget
(
ITEM_GAL_LAYER
(
GP_OVERLAY
),
KiGfx
::
TARGET_OVERLAY
);
...
...
pcbnew/class_dimension.cpp
View file @
0d4b71ef
...
@@ -468,6 +468,15 @@ EDA_RECT DIMENSION::GetBoundingBox() const
...
@@ -468,6 +468,15 @@ EDA_RECT DIMENSION::GetBoundingBox() const
ymax
=
std
::
max
(
ymax
,
m_featureLineGO
.
y
);
ymax
=
std
::
max
(
ymax
,
m_featureLineGO
.
y
);
ymax
=
std
::
max
(
ymax
,
m_featureLineGF
.
y
);
ymax
=
std
::
max
(
ymax
,
m_featureLineGF
.
y
);
xmin
=
std
::
min
(
xmin
,
m_featureLineDO
.
x
);
xmin
=
std
::
min
(
xmin
,
m_featureLineDF
.
x
);
ymin
=
std
::
min
(
ymin
,
m_featureLineDO
.
y
);
ymin
=
std
::
min
(
ymin
,
m_featureLineDF
.
y
);
xmax
=
std
::
max
(
xmax
,
m_featureLineDO
.
x
);
xmax
=
std
::
max
(
xmax
,
m_featureLineDF
.
x
);
ymax
=
std
::
max
(
ymax
,
m_featureLineDO
.
y
);
ymax
=
std
::
max
(
ymax
,
m_featureLineDF
.
y
);
bBox
.
SetX
(
xmin
);
bBox
.
SetX
(
xmin
);
bBox
.
SetY
(
ymin
);
bBox
.
SetY
(
ymin
);
bBox
.
SetWidth
(
xmax
-
xmin
+
1
);
bBox
.
SetWidth
(
xmax
-
xmin
+
1
);
...
@@ -489,6 +498,16 @@ wxString DIMENSION::GetSelectMenuText() const
...
@@ -489,6 +498,16 @@ wxString DIMENSION::GetSelectMenuText() const
}
}
const
BOX2I
DIMENSION
::
ViewBBox
()
const
{
BOX2I
dimBBox
=
BOX2I
(
VECTOR2I
(
GetBoundingBox
().
GetPosition
()
),
VECTOR2I
(
GetBoundingBox
().
GetSize
()
)
);
dimBBox
.
Merge
(
m_Text
.
ViewBBox
()
);
return
dimBBox
;
}
void
DIMENSION
::
ViewGetLayers
(
int
aLayers
[],
int
&
aCount
)
const
void
DIMENSION
::
ViewGetLayers
(
int
aLayers
[],
int
&
aCount
)
const
{
{
// Layer that simply displays the text
// Layer that simply displays the text
...
...
pcbnew/class_dimension.h
View file @
0d4b71ef
...
@@ -144,6 +144,9 @@ public:
...
@@ -144,6 +144,9 @@ public:
EDA_ITEM
*
Clone
()
const
;
EDA_ITEM
*
Clone
()
const
;
/// @copydoc VIEW_ITEM::ViewBBox()
virtual
const
BOX2I
ViewBBox
()
const
;
/// @copydoc VIEW_ITEM::ViewGetLayers()
/// @copydoc VIEW_ITEM::ViewGetLayers()
virtual
void
ViewGetLayers
(
int
aLayers
[],
int
&
aCount
)
const
;
virtual
void
ViewGetLayers
(
int
aLayers
[],
int
&
aCount
)
const
;
...
...
pcbnew/class_module.cpp
View file @
0d4b71ef
...
@@ -1027,6 +1027,7 @@ void MODULE::SetOrientation( double newangle )
...
@@ -1027,6 +1027,7 @@ void MODULE::SetOrientation( double newangle )
void
MODULE
::
ViewGetLayers
(
int
aLayers
[],
int
&
aCount
)
const
void
MODULE
::
ViewGetLayers
(
int
aLayers
[],
int
&
aCount
)
const
{
{
aCount
=
1
;
aCount
=
2
;
aLayers
[
0
]
=
ITEM_GAL_LAYER
(
SELECTION
);
// Selection box
aLayers
[
0
]
=
ITEM_GAL_LAYER
(
SELECTION
);
// Selection box
aLayers
[
1
]
=
m_Layer
;
}
}
pcbnew/pcb_painter.cpp
View file @
0d4b71ef
...
@@ -76,6 +76,7 @@ void PCB_RENDER_SETTINGS::ImportLegacyColors( COLORS_DESIGN_SETTINGS* aSettings
...
@@ -76,6 +76,7 @@ void PCB_RENDER_SETTINGS::ImportLegacyColors( COLORS_DESIGN_SETTINGS* aSettings
m_layerColors
[
ITEM_GAL_LAYER
(
PAD_FR_NETNAMES_VISIBLE
)]
=
COLOR4D
(
0.8
,
0.8
,
0.8
,
0.7
);
m_layerColors
[
ITEM_GAL_LAYER
(
PAD_FR_NETNAMES_VISIBLE
)]
=
COLOR4D
(
0.8
,
0.8
,
0.8
,
0.7
);
m_layerColors
[
ITEM_GAL_LAYER
(
PAD_BK_NETNAMES_VISIBLE
)]
=
COLOR4D
(
0.8
,
0.8
,
0.8
,
0.7
);
m_layerColors
[
ITEM_GAL_LAYER
(
PAD_BK_NETNAMES_VISIBLE
)]
=
COLOR4D
(
0.8
,
0.8
,
0.8
,
0.7
);
m_layerColors
[
ITEM_GAL_LAYER
(
WORKSHEET
)]
=
COLOR4D
(
0.5
,
0.0
,
0.0
,
1.0
);
m_layerColors
[
ITEM_GAL_LAYER
(
WORKSHEET
)]
=
COLOR4D
(
0.5
,
0.0
,
0.0
,
1.0
);
m_layerColors
[
ITEM_GAL_LAYER
(
SELECTION
)]
=
COLOR4D
(
1.0
,
1.0
,
1.0
,
0.5
);
// Netnames for copper layers
// Netnames for copper layers
for
(
LAYER_NUM
layer
=
FIRST_COPPER_LAYER
;
layer
<=
LAST_COPPER_LAYER
;
++
layer
)
for
(
LAYER_NUM
layer
=
FIRST_COPPER_LAYER
;
layer
<=
LAST_COPPER_LAYER
;
++
layer
)
...
@@ -205,10 +206,8 @@ PCB_PAINTER::PCB_PAINTER( GAL* aGal ) :
...
@@ -205,10 +206,8 @@ PCB_PAINTER::PCB_PAINTER( GAL* aGal ) :
bool
PCB_PAINTER
::
Draw
(
const
VIEW_ITEM
*
aItem
,
int
aLayer
)
bool
PCB_PAINTER
::
Draw
(
const
VIEW_ITEM
*
aItem
,
int
aLayer
)
{
{
const
BOARD_ITEM
*
item
=
static_cast
<
const
BOARD_ITEM
*>
(
aItem
);
// the "cast" applied in here clarifies which overloaded draw() is called
// the "cast" applied in here clarifies which overloaded draw() is called
switch
(
i
tem
->
Type
()
)
switch
(
aI
tem
->
Type
()
)
{
{
case
PCB_ZONE_T
:
case
PCB_ZONE_T
:
case
PCB_TRACE_T
:
case
PCB_TRACE_T
:
...
@@ -229,7 +228,7 @@ bool PCB_PAINTER::Draw( const VIEW_ITEM* aItem, int aLayer )
...
@@ -229,7 +228,7 @@ bool PCB_PAINTER::Draw( const VIEW_ITEM* aItem, int aLayer )
break
;
break
;
case
PCB_MODULE_T
:
case
PCB_MODULE_T
:
draw
(
(
MODULE
*
)
aItem
);
draw
(
(
MODULE
*
)
aItem
,
aLayer
);
break
;
break
;
case
PCB_TEXT_T
:
case
PCB_TEXT_T
:
...
@@ -273,7 +272,7 @@ void PCB_PAINTER::draw( const TRACK* aTrack, int aLayer )
...
@@ -273,7 +272,7 @@ void PCB_PAINTER::draw( const TRACK* aTrack, int aLayer )
if
(
m_pcbSettings
->
m_netNamesOnTracks
&&
IsNetnameLayer
(
aLayer
)
)
if
(
m_pcbSettings
->
m_netNamesOnTracks
&&
IsNetnameLayer
(
aLayer
)
)
{
{
// If there is a net name - display it on the track
// If there is a net name - display it on the track
if
(
netNumber
!=
0
)
if
(
netNumber
>
0
)
{
{
VECTOR2D
line
=
(
end
-
start
);
VECTOR2D
line
=
(
end
-
start
);
double
length
=
line
.
EuclideanNorm
();
double
length
=
line
.
EuclideanNorm
();
...
@@ -283,7 +282,7 @@ void PCB_PAINTER::draw( const TRACK* aTrack, int aLayer )
...
@@ -283,7 +282,7 @@ void PCB_PAINTER::draw( const TRACK* aTrack, int aLayer )
return
;
return
;
NETINFO_ITEM
*
net
=
(
(
BOARD
*
)
aTrack
->
GetParent
()
)
->
FindNet
(
netNumber
);
NETINFO_ITEM
*
net
=
(
(
BOARD
*
)
aTrack
->
GetParent
()
)
->
FindNet
(
netNumber
);
if
(
!
net
)
if
(
!
net
)
return
;
return
;
std
::
string
netName
=
std
::
string
(
net
->
GetShortNetname
().
mb_str
()
);
std
::
string
netName
=
std
::
string
(
net
->
GetShortNetname
().
mb_str
()
);
...
@@ -631,7 +630,7 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer )
...
@@ -631,7 +630,7 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer )
void
PCB_PAINTER
::
draw
(
const
DRAWSEGMENT
*
aSegment
)
void
PCB_PAINTER
::
draw
(
const
DRAWSEGMENT
*
aSegment
)
{
{
COLOR4D
color
=
m_pcbSettings
->
GetColor
(
NULL
,
aSegment
->
GetLayer
()
);
COLOR4D
color
=
m_pcbSettings
->
GetColor
(
aSegment
,
aSegment
->
GetLayer
()
);
m_gal
->
SetIsFill
(
false
);
m_gal
->
SetIsFill
(
false
);
m_gal
->
SetIsStroke
(
true
);
m_gal
->
SetIsStroke
(
true
);
...
@@ -700,11 +699,14 @@ void PCB_PAINTER::draw( const DRAWSEGMENT* aSegment )
...
@@ -700,11 +699,14 @@ void PCB_PAINTER::draw( const DRAWSEGMENT* aSegment )
}
}
void
PCB_PAINTER
::
draw
(
const
MODULE
*
aModule
)
void
PCB_PAINTER
::
draw
(
const
MODULE
*
aModule
,
int
aLayer
)
{
{
// For modules we have to draw a selection box if needed
// For modules we have to draw a selection box if needed
if
(
aModule
->
IsSelected
()
)
if
(
aLayer
==
ITEM_GAL_LAYER
(
SELECTION
)
)
drawSelectionBox
(
aModule
);
{
if
(
aModule
->
IsSelected
()
)
drawSelectionBox
(
aModule
);
}
}
}
...
@@ -720,7 +722,7 @@ void PCB_PAINTER::draw( const TEXTE_PCB* aText, int aLayer )
...
@@ -720,7 +722,7 @@ void PCB_PAINTER::draw( const TEXTE_PCB* aText, int aLayer )
if
(
aText
->
GetText
().
Length
()
==
0
)
if
(
aText
->
GetText
().
Length
()
==
0
)
return
;
return
;
COLOR4D
strokeColor
=
m_pcbSettings
->
GetColor
(
NULL
,
aText
->
GetLayer
()
);
COLOR4D
strokeColor
=
m_pcbSettings
->
GetColor
(
aText
,
aText
->
GetLayer
()
);
VECTOR2D
position
(
aText
->
GetTextPosition
().
x
,
aText
->
GetTextPosition
().
y
);
VECTOR2D
position
(
aText
->
GetTextPosition
().
x
,
aText
->
GetTextPosition
().
y
);
double
orientation
=
aText
->
GetOrientation
()
*
M_PI
/
1800.0
;
double
orientation
=
aText
->
GetOrientation
()
*
M_PI
/
1800.0
;
...
@@ -744,7 +746,7 @@ void PCB_PAINTER::draw( const TEXTE_MODULE* aText, int aLayer )
...
@@ -744,7 +746,7 @@ void PCB_PAINTER::draw( const TEXTE_MODULE* aText, int aLayer )
if
(
aText
->
GetLength
()
==
0
)
if
(
aText
->
GetLength
()
==
0
)
return
;
return
;
COLOR4D
strokeColor
=
m_pcbSettings
->
GetColor
(
NULL
,
aLayer
);
COLOR4D
strokeColor
=
m_pcbSettings
->
GetColor
(
aText
,
aLayer
);
VECTOR2D
position
(
aText
->
GetTextPosition
().
x
,
aText
->
GetTextPosition
().
y
);
VECTOR2D
position
(
aText
->
GetTextPosition
().
x
,
aText
->
GetTextPosition
().
y
);
double
orientation
=
aText
->
GetDrawRotation
()
*
M_PI
/
1800.0
;
double
orientation
=
aText
->
GetDrawRotation
()
*
M_PI
/
1800.0
;
...
@@ -759,7 +761,7 @@ void PCB_PAINTER::draw( const TEXTE_MODULE* aText, int aLayer )
...
@@ -759,7 +761,7 @@ void PCB_PAINTER::draw( const TEXTE_MODULE* aText, int aLayer )
void
PCB_PAINTER
::
draw
(
const
ZONE_CONTAINER
*
aZone
)
void
PCB_PAINTER
::
draw
(
const
ZONE_CONTAINER
*
aZone
)
{
{
COLOR4D
color
=
m_pcbSettings
->
GetColor
(
NULL
,
aZone
->
GetLayer
()
);
COLOR4D
color
=
m_pcbSettings
->
GetColor
(
aZone
,
aZone
->
GetLayer
()
);
std
::
deque
<
VECTOR2D
>
corners
;
std
::
deque
<
VECTOR2D
>
corners
;
PCB_RENDER_SETTINGS
::
DisplayZonesMode
displayMode
=
m_pcbSettings
->
m_displayZoneMode
;
PCB_RENDER_SETTINGS
::
DisplayZonesMode
displayMode
=
m_pcbSettings
->
m_displayZoneMode
;
...
@@ -836,7 +838,7 @@ void PCB_PAINTER::draw( const DIMENSION* aDimension, int aLayer )
...
@@ -836,7 +838,7 @@ void PCB_PAINTER::draw( const DIMENSION* aDimension, int aLayer )
else
else
{
{
int
layer
=
aDimension
->
GetLayer
();
int
layer
=
aDimension
->
GetLayer
();
COLOR4D
strokeColor
=
m_pcbSettings
->
GetColor
(
NULL
,
layer
);
COLOR4D
strokeColor
=
m_pcbSettings
->
GetColor
(
aDimension
,
layer
);
m_gal
->
SetStrokeColor
(
strokeColor
);
m_gal
->
SetStrokeColor
(
strokeColor
);
m_gal
->
SetIsFill
(
false
);
m_gal
->
SetIsFill
(
false
);
...
@@ -855,14 +857,20 @@ void PCB_PAINTER::draw( const DIMENSION* aDimension, int aLayer )
...
@@ -855,14 +857,20 @@ void PCB_PAINTER::draw( const DIMENSION* aDimension, int aLayer )
m_gal
->
DrawLine
(
VECTOR2D
(
aDimension
->
m_arrowG2O
),
VECTOR2D
(
aDimension
->
m_arrowG2F
)
);
m_gal
->
DrawLine
(
VECTOR2D
(
aDimension
->
m_arrowG2O
),
VECTOR2D
(
aDimension
->
m_arrowG2F
)
);
// Draw text
// Draw text
draw
(
&
aDimension
->
Text
(),
layer
);
TEXTE_PCB
&
text
=
aDimension
->
Text
();
VECTOR2D
position
(
text
.
GetTextPosition
().
x
,
text
.
GetTextPosition
().
y
);
double
orientation
=
text
.
GetOrientation
()
*
M_PI
/
1800.0
;
m_gal
->
SetLineWidth
(
text
.
GetThickness
()
);
m_gal
->
SetTextAttributes
(
&
text
);
m_gal
->
StrokeText
(
std
::
string
(
text
.
GetText
().
mb_str
()
),
position
,
orientation
);
}
}
}
}
void
PCB_PAINTER
::
draw
(
const
PCB_TARGET
*
aTarget
)
void
PCB_PAINTER
::
draw
(
const
PCB_TARGET
*
aTarget
)
{
{
COLOR4D
strokeColor
=
m_pcbSettings
->
GetColor
(
NULL
,
aTarget
->
GetLayer
()
);
COLOR4D
strokeColor
=
m_pcbSettings
->
GetColor
(
aTarget
,
aTarget
->
GetLayer
()
);
VECTOR2D
position
(
aTarget
->
GetPosition
()
);
VECTOR2D
position
(
aTarget
->
GetPosition
()
);
double
size
,
radius
;
double
size
,
radius
;
...
@@ -888,10 +896,8 @@ void PCB_PAINTER::draw( const PCB_TARGET* aTarget )
...
@@ -888,10 +896,8 @@ void PCB_PAINTER::draw( const PCB_TARGET* aTarget )
radius
=
aTarget
->
GetSize
()
/
3.0
;
radius
=
aTarget
->
GetSize
()
/
3.0
;
}
}
m_gal
->
DrawLine
(
VECTOR2D
(
-
size
,
0.0
),
m_gal
->
DrawLine
(
VECTOR2D
(
-
size
,
0.0
),
VECTOR2D
(
size
,
0.0
)
);
VECTOR2D
(
size
,
0.0
)
);
m_gal
->
DrawLine
(
VECTOR2D
(
0.0
,
-
size
),
VECTOR2D
(
0.0
,
size
)
);
m_gal
->
DrawLine
(
VECTOR2D
(
0.0
,
-
size
),
VECTOR2D
(
0.0
,
size
)
);
m_gal
->
DrawCircle
(
VECTOR2D
(
0.0
,
0.0
),
radius
);
m_gal
->
DrawCircle
(
VECTOR2D
(
0.0
,
0.0
),
radius
);
m_gal
->
Restore
();
m_gal
->
Restore
();
...
@@ -904,6 +910,6 @@ void PCB_PAINTER::drawSelectionBox( const VIEW_ITEM* aItem ) const
...
@@ -904,6 +910,6 @@ void PCB_PAINTER::drawSelectionBox( const VIEW_ITEM* aItem ) const
m_gal
->
SetIsStroke
(
false
);
m_gal
->
SetIsStroke
(
false
);
m_gal
->
SetIsFill
(
true
);
m_gal
->
SetIsFill
(
true
);
m_gal
->
SetFillColor
(
COLOR4D
(
1.0
,
1.0
,
1.0
,
0.5
)
);
m_gal
->
SetFillColor
(
m_pcbSettings
->
GetLayerColor
(
ITEM_GAL_LAYER
(
SELECTION
)
)
);
m_gal
->
DrawRectangle
(
boundingBox
.
GetOrigin
(),
boundingBox
.
GetEnd
()
);
m_gal
->
DrawRectangle
(
boundingBox
.
GetOrigin
(),
boundingBox
.
GetEnd
()
);
}
}
pcbnew/pcb_painter.h
View file @
0d4b71ef
...
@@ -145,7 +145,7 @@ protected:
...
@@ -145,7 +145,7 @@ protected:
void
draw
(
const
SEGVIA
*
,
int
);
void
draw
(
const
SEGVIA
*
,
int
);
void
draw
(
const
D_PAD
*
,
int
);
void
draw
(
const
D_PAD
*
,
int
);
void
draw
(
const
DRAWSEGMENT
*
);
void
draw
(
const
DRAWSEGMENT
*
);
void
draw
(
const
MODULE
*
);
void
draw
(
const
MODULE
*
,
int
);
void
draw
(
const
TEXTE_PCB
*
,
int
);
void
draw
(
const
TEXTE_PCB
*
,
int
);
void
draw
(
const
TEXTE_MODULE
*
,
int
);
void
draw
(
const
TEXTE_MODULE
*
,
int
);
void
draw
(
const
ZONE_CONTAINER
*
);
void
draw
(
const
ZONE_CONTAINER
*
);
...
...
pcbnew/pcbframe.cpp
View file @
0d4b71ef
...
@@ -767,8 +767,7 @@ void PCB_EDIT_FRAME::setHighContrastLayer( LAYER_NUM aLayer )
...
@@ -767,8 +767,7 @@ void PCB_EDIT_FRAME::setHighContrastLayer( LAYER_NUM aLayer )
LAYER_NUM
layers
[]
=
{
LAYER_NUM
layers
[]
=
{
GetNetnameLayer
(
aLayer
),
ITEM_GAL_LAYER
(
VIAS_VISIBLE
),
GetNetnameLayer
(
aLayer
),
ITEM_GAL_LAYER
(
VIAS_VISIBLE
),
ITEM_GAL_LAYER
(
VIAS_HOLES_VISIBLE
),
ITEM_GAL_LAYER
(
PADS_VISIBLE
),
ITEM_GAL_LAYER
(
VIAS_HOLES_VISIBLE
),
ITEM_GAL_LAYER
(
PADS_VISIBLE
),
ITEM_GAL_LAYER
(
PADS_HOLES_VISIBLE
),
ITEM_GAL_LAYER
(
PADS_NETNAMES_VISIBLE
),
ITEM_GAL_LAYER
(
PADS_HOLES_VISIBLE
),
ITEM_GAL_LAYER
(
PADS_NETNAMES_VISIBLE
)
ITEM_GAL_LAYER
(
SELECTION
)
};
};
for
(
unsigned
int
i
=
0
;
i
<
sizeof
(
layers
)
/
sizeof
(
LAYER_NUM
);
++
i
)
for
(
unsigned
int
i
=
0
;
i
<
sizeof
(
layers
)
/
sizeof
(
LAYER_NUM
);
++
i
)
...
...
pcbnew/tools/bright_box.cpp
0 → 100644
View file @
0d4b71ef
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2013 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "bright_box.h"
#include <gal/graphics_abstraction_layer.h>
#include <class_track.h>
using
namespace
KiGfx
;
BRIGHT_BOX
::
BRIGHT_BOX
(
BOARD_ITEM
*
aItem
)
:
EDA_ITEM
(
NOT_USED
),
// this item is never added to a BOARD so it needs no type
item
(
aItem
)
{
}
const
BOX2I
BRIGHT_BOX
::
ViewBBox
()
const
{
return
item
->
ViewBBox
();
}
void
BRIGHT_BOX
::
ViewGetLayers
(
int
aLayers
[],
int
&
aCount
)
const
{
aLayers
[
0
]
=
BrightBoxLayer
;
aCount
=
1
;
}
void
BRIGHT_BOX
::
ViewDraw
(
int
aLayer
,
GAL
*
aGal
)
const
{
aGal
->
SetIsStroke
(
true
);
aGal
->
SetIsFill
(
false
);
aGal
->
SetLineWidth
(
LineWidth
);
aGal
->
SetStrokeColor
(
BrightColor
);
if
(
item
->
Type
()
==
PCB_TRACE_T
)
{
const
TRACK
*
track
=
static_cast
<
const
TRACK
*>
(
item
);
aGal
->
DrawSegment
(
track
->
GetStart
(),
track
->
GetEnd
(),
track
->
GetWidth
()
);
}
else
{
BOX2I
box
=
item
->
ViewBBox
();
aGal
->
DrawRectangle
(
box
.
GetOrigin
(),
box
.
GetOrigin
()
+
box
.
GetSize
()
);
}
}
const
COLOR4D
BRIGHT_BOX
::
BrightColor
=
KiGfx
::
COLOR4D
(
0.0
,
1.0
,
0.0
,
1.0
);
pcbnew/tools/bright_box.h
0 → 100644
View file @
0d4b71ef
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2013 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __BRIGHT_BOX_H
#define __BRIGHT_BOX_H
#include <math/box2.h>
#include <view/view.h>
#include <class_board_item.h>
#include <layers_id_colors_and_visibility.h>
#include <gal/color4d.h>
/**
* Class BRIGHT_BOX
*
* Draws a decoration to indicate a brightened item.
*/
class
BRIGHT_BOX
:
public
EDA_ITEM
{
public
:
BRIGHT_BOX
(
BOARD_ITEM
*
aItem
);
~
BRIGHT_BOX
()
{};
virtual
const
BOX2I
ViewBBox
()
const
;
void
ViewDraw
(
int
aLayer
,
KiGfx
::
GAL
*
aGal
)
const
;
void
ViewGetLayers
(
int
aLayers
[],
int
&
aCount
)
const
;
void
Show
(
int
x
,
std
::
ostream
&
st
)
const
{
}
private
:
static
const
int
BrightBoxLayer
=
ITEM_GAL_LAYER
(
SELECTION
);
static
const
KiGfx
::
COLOR4D
BrightColor
;
static
const
double
LineWidth
=
100000
.
0
;
BOARD_ITEM
*
item
;
};
#endif
pcbnew/tools/selection_area.cpp
View file @
0d4b71ef
...
@@ -22,11 +22,9 @@
...
@@ -22,11 +22,9 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
*/
#include <wx/wx.h>
#include <layers_id_colors_and_visibility.h>
#include "selection_area.h"
#include "selection_area.h"
#include <gal/graphics_abstraction_layer.h>
#include <gal/color4d.h>
using
namespace
KiGfx
;
using
namespace
KiGfx
;
...
@@ -47,7 +45,7 @@ void SELECTION_AREA::ViewGetLayers( int aLayers[], int& aCount ) const
...
@@ -47,7 +45,7 @@ void SELECTION_AREA::ViewGetLayers( int aLayers[], int& aCount ) const
}
}
void
SELECTION_AREA
::
ViewDraw
(
int
aLayer
,
GAL
*
aGal
)
const
void
SELECTION_AREA
::
ViewDraw
(
int
aLayer
,
KiGfx
::
GAL
*
aGal
)
const
{
{
aGal
->
SetLineWidth
(
1.0
);
aGal
->
SetLineWidth
(
1.0
);
aGal
->
SetStrokeColor
(
COLOR4D
(
1.0
,
1.0
,
0.4
,
1.0
)
);
aGal
->
SetStrokeColor
(
COLOR4D
(
1.0
,
1.0
,
0.4
,
1.0
)
);
...
...
pcbnew/tools/selection_area.h
View file @
0d4b71ef
...
@@ -25,15 +25,14 @@
...
@@ -25,15 +25,14 @@
#ifndef __SELECTION_AREA_H
#ifndef __SELECTION_AREA_H
#define __SELECTION_AREA_H
#define __SELECTION_AREA_H
#include <tool/tool_event.h>
#include <tool/tool_manager.h>
#include <math/box2.h>
#include <view/view.h>
#include <gal/graphics_abstraction_layer.h>
#include <base_struct.h>
#include <base_struct.h>
#include <layers_id_colors_and_visibility.h>
#include <layers_id_colors_and_visibility.h>
#include <math/box2.h>
namespace
KiGfx
{
class
GAL
;
}
/**
/**
* Class SELECTION_AREA
* Class SELECTION_AREA
...
...
pcbnew/tools/selection_tool.cpp
View file @
0d4b71ef
...
@@ -34,11 +34,15 @@
...
@@ -34,11 +34,15 @@
#include <wxPcbStruct.h>
#include <wxPcbStruct.h>
#include <collectors.h>
#include <collectors.h>
#include <view/view_controls.h>
#include <view/view_controls.h>
#include <painter.h>
#include <tool/context_menu.h>
#include <tool/context_menu.h>
#include <tool/tool_event.h>
#include <tool/tool_manager.h>
#include "selection_tool.h"
#include "selection_tool.h"
#include "selection_area.h"
#include "selection_area.h"
#include "bright_box.h"
using
namespace
KiGfx
;
using
namespace
KiGfx
;
using
boost
::
optional
;
using
boost
::
optional
;
...
@@ -115,7 +119,8 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent )
...
@@ -115,7 +119,8 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent )
// Check if dragging event started within the currently selected items bounding box
// Check if dragging event started within the currently selected items bounding box
std
::
set
<
BOARD_ITEM
*>::
iterator
it
,
it_end
;
std
::
set
<
BOARD_ITEM
*>::
iterator
it
,
it_end
;
for
(
it
=
m_selectedItems
.
begin
(),
it_end
=
m_selectedItems
.
end
();
it
!=
it_end
;
++
it
)
for
(
it
=
m_selectedItems
.
begin
(),
it_end
=
m_selectedItems
.
end
();
it
!=
it_end
;
++
it
)
{
{
BOX2I
itemBox
=
(
*
it
)
->
ViewBBox
();
BOX2I
itemBox
=
(
*
it
)
->
ViewBBox
();
itemBox
.
Inflate
(
500000
);
// Give some margin for gripping an item
itemBox
.
Inflate
(
500000
);
// Give some margin for gripping an item
...
@@ -204,12 +209,12 @@ void SELECTION_TOOL::selectSingle( const VECTOR2I& aWhere )
...
@@ -204,12 +209,12 @@ void SELECTION_TOOL::selectSingle( const VECTOR2I& aWhere )
break
;
break
;
default
:
default
:
// Remove
footprint
s, they have to be selected by clicking on area that does not
// Remove
module
s, they have to be selected by clicking on area that does not
// contain anything but
footprint
// contain anything but
module footprint and not selectable items
for
(
int
i
=
0
;
i
<
collector
.
GetCount
();
++
i
)
for
(
int
i
=
collector
.
GetCount
()
-
1
;
i
>=
0
;
--
i
)
{
{
BOARD_ITEM
*
boardItem
=
(
collector
)[
i
];
BOARD_ITEM
*
boardItem
=
(
collector
)[
i
];
if
(
boardItem
->
Type
()
==
PCB_MODULE_T
)
if
(
boardItem
->
Type
()
==
PCB_MODULE_T
||
!
selectable
(
boardItem
)
)
collector
.
Remove
(
i
);
collector
.
Remove
(
i
);
}
}
...
@@ -218,7 +223,7 @@ void SELECTION_TOOL::selectSingle( const VECTOR2I& aWhere )
...
@@ -218,7 +223,7 @@ void SELECTION_TOOL::selectSingle( const VECTOR2I& aWhere )
{
{
toggleSelection
(
collector
[
0
]
);
toggleSelection
(
collector
[
0
]
);
}
}
else
else
if
(
collector
.
GetCount
()
>
1
)
{
{
item
=
disambiguationMenu
(
&
collector
);
item
=
disambiguationMenu
(
&
collector
);
if
(
item
)
if
(
item
)
...
@@ -332,8 +337,8 @@ bool SELECTION_TOOL::selectMultiple()
...
@@ -332,8 +337,8 @@ bool SELECTION_TOOL::selectMultiple()
BOARD_ITEM
*
SELECTION_TOOL
::
disambiguationMenu
(
GENERAL_COLLECTOR
*
aCollector
)
BOARD_ITEM
*
SELECTION_TOOL
::
disambiguationMenu
(
GENERAL_COLLECTOR
*
aCollector
)
{
{
OPT_TOOL_EVENT
evt
;
BOARD_ITEM
*
current
=
NULL
;
BOARD_ITEM
*
current
=
NULL
;
boost
::
shared_ptr
<
BRIGHT_BOX
>
brightBox
;
m_menu
.
reset
(
new
CONTEXT_MENU
()
);
m_menu
.
reset
(
new
CONTEXT_MENU
()
);
m_menu
->
SetTitle
(
_
(
"Clarify selection"
)
);
m_menu
->
SetTitle
(
_
(
"Clarify selection"
)
);
...
@@ -350,10 +355,11 @@ BOARD_ITEM* SELECTION_TOOL::disambiguationMenu( GENERAL_COLLECTOR* aCollector )
...
@@ -350,10 +355,11 @@ BOARD_ITEM* SELECTION_TOOL::disambiguationMenu( GENERAL_COLLECTOR* aCollector )
SetContextMenu
(
m_menu
.
get
(),
CMENU_NOW
);
SetContextMenu
(
m_menu
.
get
(),
CMENU_NOW
);
while
(
evt
=
Wait
()
)
while
(
OPT_TOOL_EVENT
evt
=
Wait
()
)
{
{
if
(
evt
->
Action
()
==
TA_ContextMenuUpdate
)
if
(
evt
->
Action
()
==
TA_ContextMenuUpdate
)
{
{
// User has pointed an item, so show it in a different way
if
(
current
)
if
(
current
)
current
->
ClearBrightened
();
current
->
ClearBrightened
();
...
@@ -378,21 +384,51 @@ BOARD_ITEM* SELECTION_TOOL::disambiguationMenu( GENERAL_COLLECTOR* aCollector )
...
@@ -378,21 +384,51 @@ BOARD_ITEM* SELECTION_TOOL::disambiguationMenu( GENERAL_COLLECTOR* aCollector )
{
{
current
=
(
*
aCollector
)[
*
id
];
current
=
(
*
aCollector
)[
*
id
];
current
->
SetSelected
();
current
->
SetSelected
();
return
current
;
}
}
return
NULL
;
break
;
}
if
(
current
&&
current
->
IsBrightened
()
)
{
brightBox
.
reset
(
new
BRIGHT_BOX
(
current
)
);
getView
()
->
Add
(
brightBox
.
get
()
);
}
}
}
}
return
NULL
;
getView
()
->
MarkTargetDirty
(
TARGET_OVERLAY
);
return
current
;
}
}
bool
SELECTION_TOOL
::
selectable
(
const
BOARD_ITEM
*
aItem
)
bool
SELECTION_TOOL
::
selectable
(
const
BOARD_ITEM
*
aItem
)
{
{
BOARD
*
board
=
getModel
<
BOARD
>
(
PCB_T
);
bool
highContrast
=
getView
()
->
GetPainter
()
->
GetSettings
()
->
GetHighContrast
();
if
(
highContrast
)
{
bool
onActive
=
false
;
int
layers
[
KiGfx
::
VIEW
::
VIEW_MAX_LAYERS
],
layers_count
;
// Filter out items that do not belong to active layers
std
::
set
<
unsigned
int
>
activeLayers
=
getView
()
->
GetPainter
()
->
GetSettings
()
->
GetActiveLayers
();
aItem
->
ViewGetLayers
(
layers
,
layers_count
);
for
(
int
i
=
0
;
i
<
layers_count
;
++
i
)
{
if
(
activeLayers
.
count
(
layers
[
i
]
)
>
0
)
// Item is on at least one active layer
{
onActive
=
true
;
break
;
}
}
if
(
!
onActive
)
return
false
;
}
BOARD
*
board
=
getModel
<
BOARD
>
(
PCB_T
);
switch
(
aItem
->
Type
()
)
switch
(
aItem
->
Type
()
)
{
{
case
PCB_VIA_T
:
case
PCB_VIA_T
:
...
...
polygon/poly2tri/common/utils.h
View file @
0d4b71ef
/*
/*
* Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
* Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
* http://code.google.com/p/poly2tri/
* http://code.google.com/p/poly2tri/
*
*
* All rights reserved.
* All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without modification,
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* are permitted provided that the following conditions are met:
*
*
* * Redistributions of source code must retain the above copyright notice,
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* and/or other materials provided with the distribution.
* * Neither the name of Poly2Tri nor the names of its contributors may be
* * Neither the name of Poly2Tri nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific
* used to endorse or promote products derived from this software without specific
* prior written permission.
* prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
*/
#ifndef UTILS_H
#ifndef UTILS_H
#define UTILS_H
#define UTILS_H
// Otherwise #defines like M_PI are undeclared under Visual Studio
// Otherwise #defines like M_PI are undeclared under Visual Studio
#define _USE_MATH_DEFINES
#define _USE_MATH_DEFINES
#include <exception>
#include <exception>
#include <math.h>
#include <math.h>
namespace
p2t
{
namespace
p2t
{
const
double
PI_3div4
=
3
*
M_PI
/
4
;
const
double
PI_3div4
=
3
*
M_PI
/
4
;
const
double
PI_div2
=
1
.
57079632679489661923
;
const
double
PI_div2
=
1
.
57079632679489661923
;
const
double
EPSILON
=
1e-12
;
const
double
EPSILON
=
1e-12
;
enum
Orientation
{
CW
,
CCW
,
COLLINEAR
};
enum
Orientation
{
CW
,
CCW
,
COLLINEAR
};
/**
/**
* Forumla to calculate signed area<br>
* Forumla to calculate signed area<br>
* Positive if CCW<br>
* Positive if CCW<br>
* Negative if CW<br>
* Negative if CW<br>
* 0 if collinear<br>
* 0 if collinear<br>
* <pre>
* <pre>
* A[P1,P2,P3] = (x1*y2 - y1*x2) + (x2*y3 - y2*x3) + (x3*y1 - y3*x1)
* A[P1,P2,P3] = (x1*y2 - y1*x2) + (x2*y3 - y2*x3) + (x3*y1 - y3*x1)
* = (x1-x3)*(y2-y3) - (y1-y3)*(x2-x3)
* = (x1-x3)*(y2-y3) - (y1-y3)*(x2-x3)
* </pre>
* </pre>
*/
*/
Orientation
Orient2d
(
Point
&
pa
,
Point
&
pb
,
Point
&
pc
)
Orientation
Orient2d
(
Point
&
pa
,
Point
&
pb
,
Point
&
pc
)
{
{
double
detleft
=
(
pa
.
x
-
pc
.
x
)
*
(
pb
.
y
-
pc
.
y
);
double
detleft
=
(
pa
.
x
-
pc
.
x
)
*
(
pb
.
y
-
pc
.
y
);
double
detright
=
(
pa
.
y
-
pc
.
y
)
*
(
pb
.
x
-
pc
.
x
);
double
detright
=
(
pa
.
y
-
pc
.
y
)
*
(
pb
.
x
-
pc
.
x
);
double
val
=
detleft
-
detright
;
double
val
=
detleft
-
detright
;
if
(
val
>
-
EPSILON
&&
val
<
EPSILON
)
{
if
(
val
>
-
EPSILON
&&
val
<
EPSILON
)
{
return
COLLINEAR
;
return
COLLINEAR
;
}
else
if
(
val
>
0
)
{
}
else
if
(
val
>
0
)
{
return
CCW
;
return
CCW
;
}
}
return
CW
;
return
CW
;
}
}
/*
/*
bool InScanArea(Point& pa, Point& pb, Point& pc, Point& pd)
bool InScanArea(Point& pa, Point& pb, Point& pc, Point& pd)
{
{
double pdx = pd.x;
double pdx = pd.x;
double pdy = pd.y;
double pdy = pd.y;
double adx = pa.x - pdx;
double adx = pa.x - pdx;
double ady = pa.y - pdy;
double ady = pa.y - pdy;
double bdx = pb.x - pdx;
double bdx = pb.x - pdx;
double bdy = pb.y - pdy;
double bdy = pb.y - pdy;
double adxbdy = adx * bdy;
double adxbdy = adx * bdy;
double bdxady = bdx * ady;
double bdxady = bdx * ady;
double oabd = adxbdy - bdxady;
double oabd = adxbdy - bdxady;
if (oabd <= EPSILON) {
if (oabd <= EPSILON) {
return false;
return false;
}
}
double cdx = pc.x - pdx;
double cdx = pc.x - pdx;
double cdy = pc.y - pdy;
double cdy = pc.y - pdy;
double cdxady = cdx * ady;
double cdxady = cdx * ady;
double adxcdy = adx * cdy;
double adxcdy = adx * cdy;
double ocad = cdxady - adxcdy;
double ocad = cdxady - adxcdy;
if (ocad <= EPSILON) {
if (ocad <= EPSILON) {
return false;
return false;
}
}
return true;
return true;
}
}
*/
*/
bool
InScanArea
(
Point
&
pa
,
Point
&
pb
,
Point
&
pc
,
Point
&
pd
)
bool
InScanArea
(
Point
&
pa
,
Point
&
pb
,
Point
&
pc
,
Point
&
pd
)
{
{
double
oadb
=
(
pa
.
x
-
pb
.
x
)
*
(
pd
.
y
-
pb
.
y
)
-
(
pd
.
x
-
pb
.
x
)
*
(
pa
.
y
-
pb
.
y
);
double
oadb
=
(
pa
.
x
-
pb
.
x
)
*
(
pd
.
y
-
pb
.
y
)
-
(
pd
.
x
-
pb
.
x
)
*
(
pa
.
y
-
pb
.
y
);
if
(
oadb
>=
-
EPSILON
)
{
if
(
oadb
>=
-
EPSILON
)
{
return
false
;
return
false
;
}
}
double
oadc
=
(
pa
.
x
-
pc
.
x
)
*
(
pd
.
y
-
pc
.
y
)
-
(
pd
.
x
-
pc
.
x
)
*
(
pa
.
y
-
pc
.
y
);
double
oadc
=
(
pa
.
x
-
pc
.
x
)
*
(
pd
.
y
-
pc
.
y
)
-
(
pd
.
x
-
pc
.
x
)
*
(
pa
.
y
-
pc
.
y
);
if
(
oadc
<=
EPSILON
)
{
if
(
oadc
<=
EPSILON
)
{
return
false
;
return
false
;
}
}
return
true
;
return
true
;
}
}
}
}
#endif
#endif
polygon/poly2tri/sweep/cdt.cc
View file @
0d4b71ef
/*
/*
* Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
* Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
* http://code.google.com/p/poly2tri/
* http://code.google.com/p/poly2tri/
*
*
* All rights reserved.
* All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without modification,
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* are permitted provided that the following conditions are met:
*
*
* * Redistributions of source code must retain the above copyright notice,
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* and/or other materials provided with the distribution.
* * Neither the name of Poly2Tri nor the names of its contributors may be
* * Neither the name of Poly2Tri nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific
* used to endorse or promote products derived from this software without specific
* prior written permission.
* prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
*/
#include "cdt.h"
#include "cdt.h"
namespace
p2t
{
namespace
p2t
{
CDT
::
CDT
(
std
::
vector
<
Point
*>
polyline
)
CDT
::
CDT
(
std
::
vector
<
Point
*>
polyline
)
{
{
sweep_context_
=
new
SweepContext
(
polyline
);
sweep_context_
=
new
SweepContext
(
polyline
);
sweep_
=
new
Sweep
;
sweep_
=
new
Sweep
;
}
}
void
CDT
::
AddHole
(
std
::
vector
<
Point
*>
polyline
)
void
CDT
::
AddHole
(
std
::
vector
<
Point
*>
polyline
)
{
{
sweep_context_
->
AddHole
(
polyline
);
sweep_context_
->
AddHole
(
polyline
);
}
}
void
CDT
::
AddPoint
(
Point
*
point
)
{
void
CDT
::
AddPoint
(
Point
*
point
)
{
sweep_context_
->
AddPoint
(
point
);
sweep_context_
->
AddPoint
(
point
);
}
}
void
CDT
::
Triangulate
()
void
CDT
::
Triangulate
()
{
{
sweep_
->
Triangulate
(
*
sweep_context_
);
sweep_
->
Triangulate
(
*
sweep_context_
);
}
}
std
::
vector
<
p2t
::
Triangle
*>
CDT
::
GetTriangles
()
std
::
vector
<
p2t
::
Triangle
*>
CDT
::
GetTriangles
()
{
{
return
sweep_context_
->
GetTriangles
();
return
sweep_context_
->
GetTriangles
();
}
}
std
::
list
<
p2t
::
Triangle
*>
CDT
::
GetMap
()
std
::
list
<
p2t
::
Triangle
*>
CDT
::
GetMap
()
{
{
return
sweep_context_
->
GetMap
();
return
sweep_context_
->
GetMap
();
}
}
CDT
::~
CDT
()
CDT
::~
CDT
()
{
{
delete
sweep_context_
;
delete
sweep_context_
;
delete
sweep_
;
delete
sweep_
;
}
}
}
}
polygon/poly2tri/sweep/cdt.h
View file @
0d4b71ef
/*
/*
* Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
* Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
* http://code.google.com/p/poly2tri/
* http://code.google.com/p/poly2tri/
*
*
* All rights reserved.
* All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without modification,
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* are permitted provided that the following conditions are met:
*
*
* * Redistributions of source code must retain the above copyright notice,
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* and/or other materials provided with the distribution.
* * Neither the name of Poly2Tri nor the names of its contributors may be
* * Neither the name of Poly2Tri nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific
* used to endorse or promote products derived from this software without specific
* prior written permission.
* prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
*/
#ifndef CDT_H
#ifndef CDT_H
#define CDT_H
#define CDT_H
#include "advancing_front.h"
#include "advancing_front.h"
#include "sweep_context.h"
#include "sweep_context.h"
#include "sweep.h"
#include "sweep.h"
/**
/**
*
*
* @author Mason Green <mason.green@gmail.com>
* @author Mason Green <mason.green@gmail.com>
*
*
*/
*/
namespace
p2t
{
namespace
p2t
{
class
CDT
class
CDT
{
{
public
:
public
:
/**
/**
* Constructor - add polyline with non repeating points
* Constructor - add polyline with non repeating points
*
*
* @param polyline
* @param polyline
*/
*/
CDT
(
std
::
vector
<
Point
*>
polyline
);
CDT
(
std
::
vector
<
Point
*>
polyline
);
/**
/**
* Destructor - clean up memory
* Destructor - clean up memory
*/
*/
~
CDT
();
~
CDT
();
/**
/**
* Add a hole
* Add a hole
*
*
* @param polyline
* @param polyline
*/
*/
void
AddHole
(
std
::
vector
<
Point
*>
polyline
);
void
AddHole
(
std
::
vector
<
Point
*>
polyline
);
/**
/**
* Add a steiner point
* Add a steiner point
*
*
* @param point
* @param point
*/
*/
void
AddPoint
(
Point
*
point
);
void
AddPoint
(
Point
*
point
);
/**
/**
* Triangulate - do this AFTER you've added the polyline, holes, and Steiner points
* Triangulate - do this AFTER you've added the polyline, holes, and Steiner points
*/
*/
void
Triangulate
();
void
Triangulate
();
/**
/**
* Get CDT triangles
* Get CDT triangles
*/
*/
std
::
vector
<
Triangle
*>
GetTriangles
();
std
::
vector
<
Triangle
*>
GetTriangles
();
/**
/**
* Get triangle map
* Get triangle map
*/
*/
std
::
list
<
Triangle
*>
GetMap
();
std
::
list
<
Triangle
*>
GetMap
();
private
:
private
:
/**
/**
* Internals
* Internals
*/
*/
SweepContext
*
sweep_context_
;
SweepContext
*
sweep_context_
;
Sweep
*
sweep_
;
Sweep
*
sweep_
;
};
};
}
}
#endif
#endif
polygon/poly2tri/sweep/sweep.cc
View file @
0d4b71ef
/*
/*
* Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
* Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
* http://code.google.com/p/poly2tri/
* http://code.google.com/p/poly2tri/
*
*
* All rights reserved.
* All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without modification,
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* are permitted provided that the following conditions are met:
*
*
* * Redistributions of source code must retain the above copyright notice,
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* and/or other materials provided with the distribution.
* * Neither the name of Poly2Tri nor the names of its contributors may be
* * Neither the name of Poly2Tri nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific
* used to endorse or promote products derived from this software without specific
* prior written permission.
* prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
*/
#include <stdexcept>
#include <stdexcept>
#include "sweep.h"
#include "sweep.h"
#include "sweep_context.h"
#include "sweep_context.h"
#include "advancing_front.h"
#include "advancing_front.h"
#include "../common/utils.h"
#include "../common/utils.h"
namespace
p2t
{
namespace
p2t
{
// Triangulate simple polygon with holes
// Triangulate simple polygon with holes
void
Sweep
::
Triangulate
(
SweepContext
&
tcx
)
void
Sweep
::
Triangulate
(
SweepContext
&
tcx
)
{
{
tcx
.
InitTriangulation
();
tcx
.
InitTriangulation
();
tcx
.
CreateAdvancingFront
(
nodes_
);
tcx
.
CreateAdvancingFront
(
nodes_
);
// Sweep points; build mesh
// Sweep points; build mesh
SweepPoints
(
tcx
);
SweepPoints
(
tcx
);
// Clean up
// Clean up
FinalizationPolygon
(
tcx
);
FinalizationPolygon
(
tcx
);
}
}
void
Sweep
::
SweepPoints
(
SweepContext
&
tcx
)
void
Sweep
::
SweepPoints
(
SweepContext
&
tcx
)
{
{
for
(
int
i
=
1
;
i
<
tcx
.
point_count
();
i
++
)
{
for
(
int
i
=
1
;
i
<
tcx
.
point_count
();
i
++
)
{
Point
&
point
=
*
tcx
.
GetPoint
(
i
);
Point
&
point
=
*
tcx
.
GetPoint
(
i
);
Node
*
node
=
&
PointEvent
(
tcx
,
point
);
Node
*
node
=
&
PointEvent
(
tcx
,
point
);
for
(
unsigned
int
i
=
0
;
i
<
point
.
edge_list
.
size
();
i
++
)
{
for
(
unsigned
int
i
=
0
;
i
<
point
.
edge_list
.
size
();
i
++
)
{
EdgeEvent
(
tcx
,
point
.
edge_list
[
i
],
node
);
EdgeEvent
(
tcx
,
point
.
edge_list
[
i
],
node
);
}
}
}
}
}
}
void
Sweep
::
FinalizationPolygon
(
SweepContext
&
tcx
)
void
Sweep
::
FinalizationPolygon
(
SweepContext
&
tcx
)
{
{
// Get an Internal triangle to start with
// Get an Internal triangle to start with
Triangle
*
t
=
tcx
.
front
()
->
head
()
->
next
->
triangle
;
Triangle
*
t
=
tcx
.
front
()
->
head
()
->
next
->
triangle
;
Point
*
p
=
tcx
.
front
()
->
head
()
->
next
->
point
;
Point
*
p
=
tcx
.
front
()
->
head
()
->
next
->
point
;
while
(
!
t
->
GetConstrainedEdgeCW
(
*
p
))
{
while
(
!
t
->
GetConstrainedEdgeCW
(
*
p
))
{
t
=
t
->
NeighborCCW
(
*
p
);
t
=
t
->
NeighborCCW
(
*
p
);
}
}
// Collect interior triangles constrained by edges
// Collect interior triangles constrained by edges
tcx
.
MeshClean
(
*
t
);
tcx
.
MeshClean
(
*
t
);
}
}
Node
&
Sweep
::
PointEvent
(
SweepContext
&
tcx
,
Point
&
point
)
Node
&
Sweep
::
PointEvent
(
SweepContext
&
tcx
,
Point
&
point
)
{
{
Node
&
node
=
tcx
.
LocateNode
(
point
);
Node
&
node
=
tcx
.
LocateNode
(
point
);
Node
&
new_node
=
NewFrontTriangle
(
tcx
,
point
,
node
);
Node
&
new_node
=
NewFrontTriangle
(
tcx
,
point
,
node
);
// Only need to check +epsilon since point never have smaller
// Only need to check +epsilon since point never have smaller
// x value than node due to how we fetch nodes from the front
// x value than node due to how we fetch nodes from the front
if
(
point
.
x
<=
node
.
point
->
x
+
EPSILON
)
{
if
(
point
.
x
<=
node
.
point
->
x
+
EPSILON
)
{
Fill
(
tcx
,
node
);
Fill
(
tcx
,
node
);
}
}
//tcx.AddNode(new_node);
//tcx.AddNode(new_node);
FillAdvancingFront
(
tcx
,
new_node
);
FillAdvancingFront
(
tcx
,
new_node
);
return
new_node
;
return
new_node
;
}
}
void
Sweep
::
EdgeEvent
(
SweepContext
&
tcx
,
Edge
*
edge
,
Node
*
node
)
void
Sweep
::
EdgeEvent
(
SweepContext
&
tcx
,
Edge
*
edge
,
Node
*
node
)
{
{
tcx
.
edge_event
.
constrained_edge
=
edge
;
tcx
.
edge_event
.
constrained_edge
=
edge
;
tcx
.
edge_event
.
right
=
(
edge
->
p
->
x
>
edge
->
q
->
x
);
tcx
.
edge_event
.
right
=
(
edge
->
p
->
x
>
edge
->
q
->
x
);
if
(
IsEdgeSideOfTriangle
(
*
node
->
triangle
,
*
edge
->
p
,
*
edge
->
q
))
{
if
(
IsEdgeSideOfTriangle
(
*
node
->
triangle
,
*
edge
->
p
,
*
edge
->
q
))
{
return
;
return
;
}
}
// For now we will do all needed filling
// For now we will do all needed filling
// TODO: integrate with flip process might give some better performance
// TODO: integrate with flip process might give some better performance
// but for now this avoid the issue with cases that needs both flips and fills
// but for now this avoid the issue with cases that needs both flips and fills
FillEdgeEvent
(
tcx
,
edge
,
node
);
FillEdgeEvent
(
tcx
,
edge
,
node
);
EdgeEvent
(
tcx
,
*
edge
->
p
,
*
edge
->
q
,
node
->
triangle
,
*
edge
->
q
);
EdgeEvent
(
tcx
,
*
edge
->
p
,
*
edge
->
q
,
node
->
triangle
,
*
edge
->
q
);
}
}
void
Sweep
::
EdgeEvent
(
SweepContext
&
tcx
,
Point
&
ep
,
Point
&
eq
,
Triangle
*
triangle
,
Point
&
point
)
void
Sweep
::
EdgeEvent
(
SweepContext
&
tcx
,
Point
&
ep
,
Point
&
eq
,
Triangle
*
triangle
,
Point
&
point
)
{
{
if
(
IsEdgeSideOfTriangle
(
*
triangle
,
ep
,
eq
))
{
if
(
IsEdgeSideOfTriangle
(
*
triangle
,
ep
,
eq
))
{
return
;
return
;
}
}
Point
*
p1
=
triangle
->
PointCCW
(
point
);
Point
*
p1
=
triangle
->
PointCCW
(
point
);
Orientation
o1
=
Orient2d
(
eq
,
*
p1
,
ep
);
Orientation
o1
=
Orient2d
(
eq
,
*
p1
,
ep
);
if
(
o1
==
COLLINEAR
)
{
if
(
o1
==
COLLINEAR
)
{
if
(
triangle
->
Contains
(
&
eq
,
p1
))
{
if
(
triangle
->
Contains
(
&
eq
,
p1
))
{
triangle
->
MarkConstrainedEdge
(
&
eq
,
p1
);
triangle
->
MarkConstrainedEdge
(
&
eq
,
p1
);
// We are modifying the constraint maybe it would be better to
// We are modifying the constraint maybe it would be better to
// not change the given constraint and just keep a variable for the new constraint
// not change the given constraint and just keep a variable for the new constraint
tcx
.
edge_event
.
constrained_edge
->
q
=
p1
;
tcx
.
edge_event
.
constrained_edge
->
q
=
p1
;
triangle
=
&
triangle
->
NeighborAcross
(
point
);
triangle
=
&
triangle
->
NeighborAcross
(
point
);
EdgeEvent
(
tcx
,
ep
,
*
p1
,
triangle
,
*
p1
);
EdgeEvent
(
tcx
,
ep
,
*
p1
,
triangle
,
*
p1
);
}
else
{
}
else
{
std
::
runtime_error
(
"EdgeEvent - collinear points not supported"
);
std
::
runtime_error
(
"EdgeEvent - collinear points not supported"
);
assert
(
0
);
assert
(
0
);
}
}
return
;
return
;
}
}
Point
*
p2
=
triangle
->
PointCW
(
point
);
Point
*
p2
=
triangle
->
PointCW
(
point
);
Orientation
o2
=
Orient2d
(
eq
,
*
p2
,
ep
);
Orientation
o2
=
Orient2d
(
eq
,
*
p2
,
ep
);
if
(
o2
==
COLLINEAR
)
{
if
(
o2
==
COLLINEAR
)
{
if
(
triangle
->
Contains
(
&
eq
,
p2
))
{
if
(
triangle
->
Contains
(
&
eq
,
p2
))
{
triangle
->
MarkConstrainedEdge
(
&
eq
,
p2
);
triangle
->
MarkConstrainedEdge
(
&
eq
,
p2
);
// We are modifying the constraint maybe it would be better to
// We are modifying the constraint maybe it would be better to
// not change the given constraint and just keep a variable for the new constraint
// not change the given constraint and just keep a variable for the new constraint
tcx
.
edge_event
.
constrained_edge
->
q
=
p2
;
tcx
.
edge_event
.
constrained_edge
->
q
=
p2
;
triangle
=
&
triangle
->
NeighborAcross
(
point
);
triangle
=
&
triangle
->
NeighborAcross
(
point
);
EdgeEvent
(
tcx
,
ep
,
*
p2
,
triangle
,
*
p2
);
EdgeEvent
(
tcx
,
ep
,
*
p2
,
triangle
,
*
p2
);
}
else
{
}
else
{
std
::
runtime_error
(
"EdgeEvent - collinear points not supported"
);
std
::
runtime_error
(
"EdgeEvent - collinear points not supported"
);
assert
(
0
);
assert
(
0
);
}
}
return
;
return
;
}
}
if
(
o1
==
o2
)
{
if
(
o1
==
o2
)
{
// Need to decide if we are rotating CW or CCW to get to a triangle
// Need to decide if we are rotating CW or CCW to get to a triangle
// that will cross edge
// that will cross edge
if
(
o1
==
CW
)
{
if
(
o1
==
CW
)
{
triangle
=
triangle
->
NeighborCCW
(
point
);
triangle
=
triangle
->
NeighborCCW
(
point
);
}
else
{
}
else
{
triangle
=
triangle
->
NeighborCW
(
point
);
triangle
=
triangle
->
NeighborCW
(
point
);
}
}
EdgeEvent
(
tcx
,
ep
,
eq
,
triangle
,
point
);
EdgeEvent
(
tcx
,
ep
,
eq
,
triangle
,
point
);
}
else
{
}
else
{
// This triangle crosses constraint so lets flippin start!
// This triangle crosses constraint so lets flippin start!
FlipEdgeEvent
(
tcx
,
ep
,
eq
,
triangle
,
point
);
FlipEdgeEvent
(
tcx
,
ep
,
eq
,
triangle
,
point
);
}
}
}
}
bool
Sweep
::
IsEdgeSideOfTriangle
(
Triangle
&
triangle
,
Point
&
ep
,
Point
&
eq
)
bool
Sweep
::
IsEdgeSideOfTriangle
(
Triangle
&
triangle
,
Point
&
ep
,
Point
&
eq
)
{
{
int
index
=
triangle
.
EdgeIndex
(
&
ep
,
&
eq
);
int
index
=
triangle
.
EdgeIndex
(
&
ep
,
&
eq
);
if
(
index
!=
-
1
)
{
if
(
index
!=
-
1
)
{
triangle
.
MarkConstrainedEdge
(
index
);
triangle
.
MarkConstrainedEdge
(
index
);
Triangle
*
t
=
triangle
.
GetNeighbor
(
index
);
Triangle
*
t
=
triangle
.
GetNeighbor
(
index
);
if
(
t
)
{
if
(
t
)
{
t
->
MarkConstrainedEdge
(
&
ep
,
&
eq
);
t
->
MarkConstrainedEdge
(
&
ep
,
&
eq
);
}
}
return
true
;
return
true
;
}
}
return
false
;
return
false
;
}
}
Node
&
Sweep
::
NewFrontTriangle
(
SweepContext
&
tcx
,
Point
&
point
,
Node
&
node
)
Node
&
Sweep
::
NewFrontTriangle
(
SweepContext
&
tcx
,
Point
&
point
,
Node
&
node
)
{
{
Triangle
*
triangle
=
new
Triangle
(
point
,
*
node
.
point
,
*
node
.
next
->
point
);
Triangle
*
triangle
=
new
Triangle
(
point
,
*
node
.
point
,
*
node
.
next
->
point
);
triangle
->
MarkNeighbor
(
*
node
.
triangle
);
triangle
->
MarkNeighbor
(
*
node
.
triangle
);
tcx
.
AddToMap
(
triangle
);
tcx
.
AddToMap
(
triangle
);
Node
*
new_node
=
new
Node
(
point
);
Node
*
new_node
=
new
Node
(
point
);
nodes_
.
push_back
(
new_node
);
nodes_
.
push_back
(
new_node
);
new_node
->
next
=
node
.
next
;
new_node
->
next
=
node
.
next
;
new_node
->
prev
=
&
node
;
new_node
->
prev
=
&
node
;
node
.
next
->
prev
=
new_node
;
node
.
next
->
prev
=
new_node
;
node
.
next
=
new_node
;
node
.
next
=
new_node
;
if
(
!
Legalize
(
tcx
,
*
triangle
))
{
if
(
!
Legalize
(
tcx
,
*
triangle
))
{
tcx
.
MapTriangleToNodes
(
*
triangle
);
tcx
.
MapTriangleToNodes
(
*
triangle
);
}
}
return
*
new_node
;
return
*
new_node
;
}
}
void
Sweep
::
Fill
(
SweepContext
&
tcx
,
Node
&
node
)
void
Sweep
::
Fill
(
SweepContext
&
tcx
,
Node
&
node
)
{
{
Triangle
*
triangle
=
new
Triangle
(
*
node
.
prev
->
point
,
*
node
.
point
,
*
node
.
next
->
point
);
Triangle
*
triangle
=
new
Triangle
(
*
node
.
prev
->
point
,
*
node
.
point
,
*
node
.
next
->
point
);
// TODO: should copy the constrained_edge value from neighbor triangles
// TODO: should copy the constrained_edge value from neighbor triangles
// for now constrained_edge values are copied during the legalize
// for now constrained_edge values are copied during the legalize
triangle
->
MarkNeighbor
(
*
node
.
prev
->
triangle
);
triangle
->
MarkNeighbor
(
*
node
.
prev
->
triangle
);
triangle
->
MarkNeighbor
(
*
node
.
triangle
);
triangle
->
MarkNeighbor
(
*
node
.
triangle
);
tcx
.
AddToMap
(
triangle
);
tcx
.
AddToMap
(
triangle
);
// Update the advancing front
// Update the advancing front
node
.
prev
->
next
=
node
.
next
;
node
.
prev
->
next
=
node
.
next
;
node
.
next
->
prev
=
node
.
prev
;
node
.
next
->
prev
=
node
.
prev
;
// If it was legalized the triangle has already been mapped
// If it was legalized the triangle has already been mapped
if
(
!
Legalize
(
tcx
,
*
triangle
))
{
if
(
!
Legalize
(
tcx
,
*
triangle
))
{
tcx
.
MapTriangleToNodes
(
*
triangle
);
tcx
.
MapTriangleToNodes
(
*
triangle
);
}
}
}
}
void
Sweep
::
FillAdvancingFront
(
SweepContext
&
tcx
,
Node
&
n
)
void
Sweep
::
FillAdvancingFront
(
SweepContext
&
tcx
,
Node
&
n
)
{
// Fill right holes
Node
*
node
=
n
.
next
;
while
(
node
->
next
)
{
// if HoleAngle exceeds 90 degrees then break.
if
(
LargeHole_DontFill
(
node
))
break
;
Fill
(
tcx
,
*
node
);
node
=
node
->
next
;
}
// Fill left holes
node
=
n
.
prev
;
while
(
node
->
prev
)
{
// if HoleAngle exceeds 90 degrees then break.
if
(
LargeHole_DontFill
(
node
))
break
;
Fill
(
tcx
,
*
node
);
node
=
node
->
prev
;
}
// Fill right basins
if
(
n
.
next
&&
n
.
next
->
next
)
{
double
angle
=
BasinAngle
(
n
);
if
(
angle
<
PI_3div4
)
{
FillBasin
(
tcx
,
n
);
}
}
}
// True if HoleAngle exceeds 90 degrees.
bool
Sweep
::
LargeHole_DontFill
(
Node
*
node
)
{
Node
*
nextNode
=
node
->
next
;
Node
*
prevNode
=
node
->
prev
;
if
(
!
AngleExceeds90Degrees
(
node
->
point
,
nextNode
->
point
,
prevNode
->
point
))
return
false
;
// Check additional points on front.
Node
*
next2Node
=
nextNode
->
next
;
// "..Plus.." because only want angles on same side as point being added.
if
((
next2Node
!=
NULL
)
&&
!
AngleExceedsPlus90DegreesOrIsNegative
(
node
->
point
,
next2Node
->
point
,
prevNode
->
point
))
return
false
;
Node
*
prev2Node
=
prevNode
->
prev
;
// "..Plus.." because only want angles on same side as point being added.
if
((
prev2Node
!=
NULL
)
&&
!
AngleExceedsPlus90DegreesOrIsNegative
(
node
->
point
,
nextNode
->
point
,
prev2Node
->
point
))
return
false
;
return
true
;
}
bool
Sweep
::
AngleExceeds90Degrees
(
Point
*
origin
,
Point
*
pa
,
Point
*
pb
)
{
double
angle
=
Angle
(
*
origin
,
*
pa
,
*
pb
);
bool
exceeds90Degrees
=
((
angle
>
PI_div2
)
||
(
angle
<
-
PI_div2
));
return
exceeds90Degrees
;
}
bool
Sweep
::
AngleExceedsPlus90DegreesOrIsNegative
(
Point
*
origin
,
Point
*
pa
,
Point
*
pb
)
{
double
angle
=
Angle
(
*
origin
,
*
pa
,
*
pb
);
bool
exceedsPlus90DegreesOrIsNegative
=
(
angle
>
PI_div2
)
||
(
angle
<
0
);
return
exceedsPlus90DegreesOrIsNegative
;
}
double
Sweep
::
Angle
(
Point
&
origin
,
Point
&
pa
,
Point
&
pb
)
{
/* Complex plane
* ab = cosA +i*sinA
* ab = (ax + ay*i)(bx + by*i) = (ax*bx + ay*by) + i(ax*by-ay*bx)
* atan2(y,x) computes the principal value of the argument function
* applied to the complex number x+iy
* Where x = ax*bx + ay*by
* y = ax*by - ay*bx
*/
double
px
=
origin
.
x
;
double
py
=
origin
.
y
;
double
ax
=
pa
.
x
-
px
;
double
ay
=
pa
.
y
-
py
;
double
bx
=
pb
.
x
-
px
;
double
by
=
pb
.
y
-
py
;
double
x
=
ax
*
by
-
ay
*
bx
;
double
y
=
ax
*
bx
+
ay
*
by
;
double
angle
=
atan2
(
x
,
y
);
return
angle
;
}
double
Sweep
::
BasinAngle
(
Node
&
node
)
{
double
ax
=
node
.
point
->
x
-
node
.
next
->
next
->
point
->
x
;
double
ay
=
node
.
point
->
y
-
node
.
next
->
next
->
point
->
y
;
return
atan2
(
ay
,
ax
);
}
double
Sweep
::
HoleAngle
(
Node
&
node
)
{
/* Complex plane
* ab = cosA +i*sinA
* ab = (ax + ay*i)(bx + by*i) = (ax*bx + ay*by) + i(ax*by-ay*bx)
* atan2(y,x) computes the principal value of the argument function
* applied to the complex number x+iy
* Where x = ax*bx + ay*by
* y = ax*by - ay*bx
*/
double
ax
=
node
.
next
->
point
->
x
-
node
.
point
->
x
;
double
ay
=
node
.
next
->
point
->
y
-
node
.
point
->
y
;
double
bx
=
node
.
prev
->
point
->
x
-
node
.
point
->
x
;
double
by
=
node
.
prev
->
point
->
y
-
node
.
point
->
y
;
return
atan2
(
ax
*
by
-
ay
*
bx
,
ax
*
bx
+
ay
*
by
);
}
bool
Sweep
::
Legalize
(
SweepContext
&
tcx
,
Triangle
&
t
)
{
// To legalize a triangle we start by finding if any of the three edges
// violate the Delaunay condition
for
(
int
i
=
0
;
i
<
3
;
i
++
)
{
if
(
t
.
delaunay_edge
[
i
])
continue
;
Triangle
*
ot
=
t
.
GetNeighbor
(
i
);
if
(
ot
)
{
Point
*
p
=
t
.
GetPoint
(
i
);
Point
*
op
=
ot
->
OppositePoint
(
t
,
*
p
);
int
oi
=
ot
->
Index
(
op
);
// If this is a Constrained Edge or a Delaunay Edge(only during recursive legalization)
// then we should not try to legalize
if
(
ot
->
constrained_edge
[
oi
]
||
ot
->
delaunay_edge
[
oi
])
{
t
.
constrained_edge
[
i
]
=
ot
->
constrained_edge
[
oi
];
continue
;
}
bool
inside
=
Incircle
(
*
p
,
*
t
.
PointCCW
(
*
p
),
*
t
.
PointCW
(
*
p
),
*
op
);
if
(
inside
)
{
// Lets mark this shared edge as Delaunay
t
.
delaunay_edge
[
i
]
=
true
;
ot
->
delaunay_edge
[
oi
]
=
true
;
// Lets rotate shared edge one vertex CW to legalize it
RotateTrianglePair
(
t
,
*
p
,
*
ot
,
*
op
);
// We now got one valid Delaunay Edge shared by two triangles
// This gives us 4 new edges to check for Delaunay
// Make sure that triangle to node mapping is done only one time for a specific triangle
bool
not_legalized
=
!
Legalize
(
tcx
,
t
);
if
(
not_legalized
)
{
tcx
.
MapTriangleToNodes
(
t
);
}
not_legalized
=
!
Legalize
(
tcx
,
*
ot
);
if
(
not_legalized
)
tcx
.
MapTriangleToNodes
(
*
ot
);
// Reset the Delaunay edges, since they only are valid Delaunay edges
// until we add a new triangle or point.
// XXX: need to think about this. Can these edges be tried after we
// return to previous recursive level?
t
.
delaunay_edge
[
i
]
=
false
;
ot
->
delaunay_edge
[
oi
]
=
false
;
// If triangle have been legalized no need to check the other edges since
// the recursive legalization will handles those so we can end here.
return
true
;
}
}
}
return
false
;
}
bool
Sweep
::
Incircle
(
Point
&
pa
,
Point
&
pb
,
Point
&
pc
,
Point
&
pd
)
{
double
adx
=
pa
.
x
-
pd
.
x
;
double
ady
=
pa
.
y
-
pd
.
y
;
double
bdx
=
pb
.
x
-
pd
.
x
;
double
bdy
=
pb
.
y
-
pd
.
y
;
double
adxbdy
=
adx
*
bdy
;
double
bdxady
=
bdx
*
ady
;
double
oabd
=
adxbdy
-
bdxady
;
if
(
oabd
<=
0
)
return
false
;
double
cdx
=
pc
.
x
-
pd
.
x
;
double
cdy
=
pc
.
y
-
pd
.
y
;
double
cdxady
=
cdx
*
ady
;
double
adxcdy
=
adx
*
cdy
;
double
ocad
=
cdxady
-
adxcdy
;
if
(
ocad
<=
0
)
return
false
;
double
bdxcdy
=
bdx
*
cdy
;
double
cdxbdy
=
cdx
*
bdy
;
double
alift
=
adx
*
adx
+
ady
*
ady
;
double
blift
=
bdx
*
bdx
+
bdy
*
bdy
;
double
clift
=
cdx
*
cdx
+
cdy
*
cdy
;
double
det
=
alift
*
(
bdxcdy
-
cdxbdy
)
+
blift
*
ocad
+
clift
*
oabd
;
return
det
>
0
;
}
void
Sweep
::
RotateTrianglePair
(
Triangle
&
t
,
Point
&
p
,
Triangle
&
ot
,
Point
&
op
)
{
Triangle
*
n1
,
*
n2
,
*
n3
,
*
n4
;
n1
=
t
.
NeighborCCW
(
p
);
n2
=
t
.
NeighborCW
(
p
);
n3
=
ot
.
NeighborCCW
(
op
);
n4
=
ot
.
NeighborCW
(
op
);
bool
ce1
,
ce2
,
ce3
,
ce4
;
ce1
=
t
.
GetConstrainedEdgeCCW
(
p
);
ce2
=
t
.
GetConstrainedEdgeCW
(
p
);
ce3
=
ot
.
GetConstrainedEdgeCCW
(
op
);
ce4
=
ot
.
GetConstrainedEdgeCW
(
op
);
bool
de1
,
de2
,
de3
,
de4
;
de1
=
t
.
GetDelunayEdgeCCW
(
p
);
de2
=
t
.
GetDelunayEdgeCW
(
p
);
de3
=
ot
.
GetDelunayEdgeCCW
(
op
);
de4
=
ot
.
GetDelunayEdgeCW
(
op
);
t
.
Legalize
(
p
,
op
);
ot
.
Legalize
(
op
,
p
);
// Remap delaunay_edge
ot
.
SetDelunayEdgeCCW
(
p
,
de1
);
t
.
SetDelunayEdgeCW
(
p
,
de2
);
t
.
SetDelunayEdgeCCW
(
op
,
de3
);
ot
.
SetDelunayEdgeCW
(
op
,
de4
);
// Remap constrained_edge
ot
.
SetConstrainedEdgeCCW
(
p
,
ce1
);
t
.
SetConstrainedEdgeCW
(
p
,
ce2
);
t
.
SetConstrainedEdgeCCW
(
op
,
ce3
);
ot
.
SetConstrainedEdgeCW
(
op
,
ce4
);
// Remap neighbors
// XXX: might optimize the markNeighbor by keeping track of
// what side should be assigned to what neighbor after the
// rotation. Now mark neighbor does lots of testing to find
// the right side.
t
.
ClearNeighbors
();
ot
.
ClearNeighbors
();
if
(
n1
)
ot
.
MarkNeighbor
(
*
n1
);
if
(
n2
)
t
.
MarkNeighbor
(
*
n2
);
if
(
n3
)
t
.
MarkNeighbor
(
*
n3
);
if
(
n4
)
ot
.
MarkNeighbor
(
*
n4
);
t
.
MarkNeighbor
(
ot
);
}
void
Sweep
::
FillBasin
(
SweepContext
&
tcx
,
Node
&
node
)
{
if
(
Orient2d
(
*
node
.
point
,
*
node
.
next
->
point
,
*
node
.
next
->
next
->
point
)
==
CCW
)
{
tcx
.
basin
.
left_node
=
node
.
next
->
next
;
}
else
{
tcx
.
basin
.
left_node
=
node
.
next
;
}
// Find the bottom and right node
tcx
.
basin
.
bottom_node
=
tcx
.
basin
.
left_node
;
while
(
tcx
.
basin
.
bottom_node
->
next
&&
tcx
.
basin
.
bottom_node
->
point
->
y
>=
tcx
.
basin
.
bottom_node
->
next
->
point
->
y
)
{
tcx
.
basin
.
bottom_node
=
tcx
.
basin
.
bottom_node
->
next
;
}
if
(
tcx
.
basin
.
bottom_node
==
tcx
.
basin
.
left_node
)
{
// No valid basin
return
;
}
tcx
.
basin
.
right_node
=
tcx
.
basin
.
bottom_node
;
while
(
tcx
.
basin
.
right_node
->
next
&&
tcx
.
basin
.
right_node
->
point
->
y
<
tcx
.
basin
.
right_node
->
next
->
point
->
y
)
{
tcx
.
basin
.
right_node
=
tcx
.
basin
.
right_node
->
next
;
}
if
(
tcx
.
basin
.
right_node
==
tcx
.
basin
.
bottom_node
)
{
// No valid basins
return
;
}
tcx
.
basin
.
width
=
tcx
.
basin
.
right_node
->
point
->
x
-
tcx
.
basin
.
left_node
->
point
->
x
;
tcx
.
basin
.
left_highest
=
tcx
.
basin
.
left_node
->
point
->
y
>
tcx
.
basin
.
right_node
->
point
->
y
;
FillBasinReq
(
tcx
,
tcx
.
basin
.
bottom_node
);
}
void
Sweep
::
FillBasinReq
(
SweepContext
&
tcx
,
Node
*
node
)
{
{
// if shallow stop filling
// Fill right holes
if
(
IsShallow
(
tcx
,
*
node
))
{
Node
*
node
=
n
.
next
;
return
;
}
while
(
node
->
next
)
{
// if HoleAngle exceeds 90 degrees then break.
if
(
LargeHole_DontFill
(
node
))
break
;
Fill
(
tcx
,
*
node
);
node
=
node
->
next
;
}
// Fill left holes
node
=
n
.
prev
;
while
(
node
->
prev
)
{
// if HoleAngle exceeds 90 degrees then break.
if
(
LargeHole_DontFill
(
node
))
break
;
Fill
(
tcx
,
*
node
);
node
=
node
->
prev
;
}
// Fill right basins
if
(
n
.
next
&&
n
.
next
->
next
)
{
double
angle
=
BasinAngle
(
n
);
if
(
angle
<
PI_3div4
)
{
FillBasin
(
tcx
,
n
);
}
}
}
// True if HoleAngle exceeds 90 degrees.
bool
Sweep
::
LargeHole_DontFill
(
Node
*
node
)
{
Node
*
nextNode
=
node
->
next
;
Node
*
prevNode
=
node
->
prev
;
if
(
!
AngleExceeds90Degrees
(
node
->
point
,
nextNode
->
point
,
prevNode
->
point
))
return
false
;
// Check additional points on front.
Node
*
next2Node
=
nextNode
->
next
;
// "..Plus.." because only want angles on same side as point being added.
if
((
next2Node
!=
NULL
)
&&
!
AngleExceedsPlus90DegreesOrIsNegative
(
node
->
point
,
next2Node
->
point
,
prevNode
->
point
))
return
false
;
Node
*
prev2Node
=
prevNode
->
prev
;
// "..Plus.." because only want angles on same side as point being added.
if
((
prev2Node
!=
NULL
)
&&
!
AngleExceedsPlus90DegreesOrIsNegative
(
node
->
point
,
nextNode
->
point
,
prev2Node
->
point
))
return
false
;
return
true
;
}
bool
Sweep
::
AngleExceeds90Degrees
(
Point
*
origin
,
Point
*
pa
,
Point
*
pb
)
{
double
angle
=
Angle
(
*
origin
,
*
pa
,
*
pb
);
bool
exceeds90Degrees
=
((
angle
>
PI_div2
)
||
(
angle
<
-
PI_div2
));
return
exceeds90Degrees
;
}
bool
Sweep
::
AngleExceedsPlus90DegreesOrIsNegative
(
Point
*
origin
,
Point
*
pa
,
Point
*
pb
)
{
double
angle
=
Angle
(
*
origin
,
*
pa
,
*
pb
);
bool
exceedsPlus90DegreesOrIsNegative
=
(
angle
>
PI_div2
)
||
(
angle
<
0
);
return
exceedsPlus90DegreesOrIsNegative
;
}
double
Sweep
::
Angle
(
Point
&
origin
,
Point
&
pa
,
Point
&
pb
)
{
/* Complex plane
* ab = cosA +i*sinA
* ab = (ax + ay*i)(bx + by*i) = (ax*bx + ay*by) + i(ax*by-ay*bx)
* atan2(y,x) computes the principal value of the argument function
* applied to the complex number x+iy
* Where x = ax*bx + ay*by
* y = ax*by - ay*bx
*/
double
px
=
origin
.
x
;
double
py
=
origin
.
y
;
double
ax
=
pa
.
x
-
px
;
double
ay
=
pa
.
y
-
py
;
double
bx
=
pb
.
x
-
px
;
double
by
=
pb
.
y
-
py
;
double
x
=
ax
*
by
-
ay
*
bx
;
double
y
=
ax
*
bx
+
ay
*
by
;
double
angle
=
atan2
(
x
,
y
);
return
angle
;
}
double
Sweep
::
BasinAngle
(
Node
&
node
)
{
double
ax
=
node
.
point
->
x
-
node
.
next
->
next
->
point
->
x
;
double
ay
=
node
.
point
->
y
-
node
.
next
->
next
->
point
->
y
;
return
atan2
(
ay
,
ax
);
}
double
Sweep
::
HoleAngle
(
Node
&
node
)
{
/* Complex plane
* ab = cosA +i*sinA
* ab = (ax + ay*i)(bx + by*i) = (ax*bx + ay*by) + i(ax*by-ay*bx)
* atan2(y,x) computes the principal value of the argument function
* applied to the complex number x+iy
* Where x = ax*bx + ay*by
* y = ax*by - ay*bx
*/
double
ax
=
node
.
next
->
point
->
x
-
node
.
point
->
x
;
double
ay
=
node
.
next
->
point
->
y
-
node
.
point
->
y
;
double
bx
=
node
.
prev
->
point
->
x
-
node
.
point
->
x
;
double
by
=
node
.
prev
->
point
->
y
-
node
.
point
->
y
;
return
atan2
(
ax
*
by
-
ay
*
bx
,
ax
*
bx
+
ay
*
by
);
}
bool
Sweep
::
Legalize
(
SweepContext
&
tcx
,
Triangle
&
t
)
{
// To legalize a triangle we start by finding if any of the three edges
// violate the Delaunay condition
for
(
int
i
=
0
;
i
<
3
;
i
++
)
{
if
(
t
.
delaunay_edge
[
i
])
continue
;
Triangle
*
ot
=
t
.
GetNeighbor
(
i
);
if
(
ot
)
{
Point
*
p
=
t
.
GetPoint
(
i
);
Point
*
op
=
ot
->
OppositePoint
(
t
,
*
p
);
int
oi
=
ot
->
Index
(
op
);
// If this is a Constrained Edge or a Delaunay Edge(only during recursive legalization)
// then we should not try to legalize
if
(
ot
->
constrained_edge
[
oi
]
||
ot
->
delaunay_edge
[
oi
])
{
t
.
constrained_edge
[
i
]
=
ot
->
constrained_edge
[
oi
];
continue
;
}
bool
inside
=
Incircle
(
*
p
,
*
t
.
PointCCW
(
*
p
),
*
t
.
PointCW
(
*
p
),
*
op
);
if
(
inside
)
{
// Lets mark this shared edge as Delaunay
t
.
delaunay_edge
[
i
]
=
true
;
ot
->
delaunay_edge
[
oi
]
=
true
;
// Lets rotate shared edge one vertex CW to legalize it
RotateTrianglePair
(
t
,
*
p
,
*
ot
,
*
op
);
// We now got one valid Delaunay Edge shared by two triangles
// This gives us 4 new edges to check for Delaunay
// Make sure that triangle to node mapping is done only one time for a specific triangle
bool
not_legalized
=
!
Legalize
(
tcx
,
t
);
if
(
not_legalized
)
{
tcx
.
MapTriangleToNodes
(
t
);
}
not_legalized
=
!
Legalize
(
tcx
,
*
ot
);
if
(
not_legalized
)
tcx
.
MapTriangleToNodes
(
*
ot
);
// Reset the Delaunay edges, since they only are valid Delaunay edges
// until we add a new triangle or point.
// XXX: need to think about this. Can these edges be tried after we
// return to previous recursive level?
t
.
delaunay_edge
[
i
]
=
false
;
ot
->
delaunay_edge
[
oi
]
=
false
;
// If triangle have been legalized no need to check the other edges since
// the recursive legalization will handles those so we can end here.
return
true
;
}
}
}
return
false
;
}
bool
Sweep
::
Incircle
(
Point
&
pa
,
Point
&
pb
,
Point
&
pc
,
Point
&
pd
)
{
double
adx
=
pa
.
x
-
pd
.
x
;
double
ady
=
pa
.
y
-
pd
.
y
;
double
bdx
=
pb
.
x
-
pd
.
x
;
double
bdy
=
pb
.
y
-
pd
.
y
;
double
adxbdy
=
adx
*
bdy
;
double
bdxady
=
bdx
*
ady
;
double
oabd
=
adxbdy
-
bdxady
;
if
(
oabd
<=
0
)
return
false
;
double
cdx
=
pc
.
x
-
pd
.
x
;
double
cdy
=
pc
.
y
-
pd
.
y
;
double
cdxady
=
cdx
*
ady
;
double
adxcdy
=
adx
*
cdy
;
double
ocad
=
cdxady
-
adxcdy
;
if
(
ocad
<=
0
)
return
false
;
double
bdxcdy
=
bdx
*
cdy
;
double
cdxbdy
=
cdx
*
bdy
;
double
alift
=
adx
*
adx
+
ady
*
ady
;
double
blift
=
bdx
*
bdx
+
bdy
*
bdy
;
double
clift
=
cdx
*
cdx
+
cdy
*
cdy
;
double
det
=
alift
*
(
bdxcdy
-
cdxbdy
)
+
blift
*
ocad
+
clift
*
oabd
;
return
det
>
0
;
}
void
Sweep
::
RotateTrianglePair
(
Triangle
&
t
,
Point
&
p
,
Triangle
&
ot
,
Point
&
op
)
{
Triangle
*
n1
,
*
n2
,
*
n3
,
*
n4
;
n1
=
t
.
NeighborCCW
(
p
);
n2
=
t
.
NeighborCW
(
p
);
n3
=
ot
.
NeighborCCW
(
op
);
n4
=
ot
.
NeighborCW
(
op
);
bool
ce1
,
ce2
,
ce3
,
ce4
;
ce1
=
t
.
GetConstrainedEdgeCCW
(
p
);
ce2
=
t
.
GetConstrainedEdgeCW
(
p
);
ce3
=
ot
.
GetConstrainedEdgeCCW
(
op
);
ce4
=
ot
.
GetConstrainedEdgeCW
(
op
);
bool
de1
,
de2
,
de3
,
de4
;
de1
=
t
.
GetDelunayEdgeCCW
(
p
);
de2
=
t
.
GetDelunayEdgeCW
(
p
);
de3
=
ot
.
GetDelunayEdgeCCW
(
op
);
de4
=
ot
.
GetDelunayEdgeCW
(
op
);
t
.
Legalize
(
p
,
op
);
ot
.
Legalize
(
op
,
p
);
// Remap delaunay_edge
ot
.
SetDelunayEdgeCCW
(
p
,
de1
);
t
.
SetDelunayEdgeCW
(
p
,
de2
);
t
.
SetDelunayEdgeCCW
(
op
,
de3
);
ot
.
SetDelunayEdgeCW
(
op
,
de4
);
// Remap constrained_edge
ot
.
SetConstrainedEdgeCCW
(
p
,
ce1
);
t
.
SetConstrainedEdgeCW
(
p
,
ce2
);
t
.
SetConstrainedEdgeCCW
(
op
,
ce3
);
ot
.
SetConstrainedEdgeCW
(
op
,
ce4
);
// Remap neighbors
// XXX: might optimize the markNeighbor by keeping track of
// what side should be assigned to what neighbor after the
// rotation. Now mark neighbor does lots of testing to find
// the right side.
t
.
ClearNeighbors
();
ot
.
ClearNeighbors
();
if
(
n1
)
ot
.
MarkNeighbor
(
*
n1
);
if
(
n2
)
t
.
MarkNeighbor
(
*
n2
);
if
(
n3
)
t
.
MarkNeighbor
(
*
n3
);
if
(
n4
)
ot
.
MarkNeighbor
(
*
n4
);
t
.
MarkNeighbor
(
ot
);
}
void
Sweep
::
FillBasin
(
SweepContext
&
tcx
,
Node
&
node
)
{
if
(
Orient2d
(
*
node
.
point
,
*
node
.
next
->
point
,
*
node
.
next
->
next
->
point
)
==
CCW
)
{
tcx
.
basin
.
left_node
=
node
.
next
->
next
;
}
else
{
tcx
.
basin
.
left_node
=
node
.
next
;
}
// Find the bottom and right node
tcx
.
basin
.
bottom_node
=
tcx
.
basin
.
left_node
;
while
(
tcx
.
basin
.
bottom_node
->
next
&&
tcx
.
basin
.
bottom_node
->
point
->
y
>=
tcx
.
basin
.
bottom_node
->
next
->
point
->
y
)
{
tcx
.
basin
.
bottom_node
=
tcx
.
basin
.
bottom_node
->
next
;
}
if
(
tcx
.
basin
.
bottom_node
==
tcx
.
basin
.
left_node
)
{
// No valid basin
return
;
}
tcx
.
basin
.
right_node
=
tcx
.
basin
.
bottom_node
;
while
(
tcx
.
basin
.
right_node
->
next
&&
tcx
.
basin
.
right_node
->
point
->
y
<
tcx
.
basin
.
right_node
->
next
->
point
->
y
)
{
tcx
.
basin
.
right_node
=
tcx
.
basin
.
right_node
->
next
;
}
if
(
tcx
.
basin
.
right_node
==
tcx
.
basin
.
bottom_node
)
{
// No valid basins
return
;
}
tcx
.
basin
.
width
=
tcx
.
basin
.
right_node
->
point
->
x
-
tcx
.
basin
.
left_node
->
point
->
x
;
tcx
.
basin
.
left_highest
=
tcx
.
basin
.
left_node
->
point
->
y
>
tcx
.
basin
.
right_node
->
point
->
y
;
FillBasinReq
(
tcx
,
tcx
.
basin
.
bottom_node
);
}
void
Sweep
::
FillBasinReq
(
SweepContext
&
tcx
,
Node
*
node
)
{
// if shallow stop filling
if
(
IsShallow
(
tcx
,
*
node
))
{
return
;
}
Fill
(
tcx
,
*
node
);
Fill
(
tcx
,
*
node
);
if
(
node
->
prev
==
tcx
.
basin
.
left_node
&&
node
->
next
==
tcx
.
basin
.
right_node
)
{
if
(
node
->
prev
==
tcx
.
basin
.
left_node
&&
node
->
next
==
tcx
.
basin
.
right_node
)
{
return
;
return
;
}
else
if
(
node
->
prev
==
tcx
.
basin
.
left_node
)
{
}
else
if
(
node
->
prev
==
tcx
.
basin
.
left_node
)
{
Orientation
o
=
Orient2d
(
*
node
->
point
,
*
node
->
next
->
point
,
*
node
->
next
->
next
->
point
);
Orientation
o
=
Orient2d
(
*
node
->
point
,
*
node
->
next
->
point
,
*
node
->
next
->
next
->
point
);
if
(
o
==
CW
)
{
if
(
o
==
CW
)
{
return
;
return
;
}
}
node
=
node
->
next
;
node
=
node
->
next
;
}
else
if
(
node
->
next
==
tcx
.
basin
.
right_node
)
{
}
else
if
(
node
->
next
==
tcx
.
basin
.
right_node
)
{
Orientation
o
=
Orient2d
(
*
node
->
point
,
*
node
->
prev
->
point
,
*
node
->
prev
->
prev
->
point
);
Orientation
o
=
Orient2d
(
*
node
->
point
,
*
node
->
prev
->
point
,
*
node
->
prev
->
prev
->
point
);
if
(
o
==
CCW
)
{
if
(
o
==
CCW
)
{
return
;
return
;
}
}
node
=
node
->
prev
;
node
=
node
->
prev
;
}
else
{
}
else
{
// Continue with the neighbor node with lowest Y value
// Continue with the neighbor node with lowest Y value
if
(
node
->
prev
->
point
->
y
<
node
->
next
->
point
->
y
)
{
if
(
node
->
prev
->
point
->
y
<
node
->
next
->
point
->
y
)
{
node
=
node
->
prev
;
node
=
node
->
prev
;
}
else
{
}
else
{
node
=
node
->
next
;
node
=
node
->
next
;
}
}
}
}
FillBasinReq
(
tcx
,
node
);
FillBasinReq
(
tcx
,
node
);
}
}
bool
Sweep
::
IsShallow
(
SweepContext
&
tcx
,
Node
&
node
)
bool
Sweep
::
IsShallow
(
SweepContext
&
tcx
,
Node
&
node
)
{
{
double
height
;
double
height
;
if
(
tcx
.
basin
.
left_highest
)
{
if
(
tcx
.
basin
.
left_highest
)
{
height
=
tcx
.
basin
.
left_node
->
point
->
y
-
node
.
point
->
y
;
height
=
tcx
.
basin
.
left_node
->
point
->
y
-
node
.
point
->
y
;
}
else
{
}
else
{
height
=
tcx
.
basin
.
right_node
->
point
->
y
-
node
.
point
->
y
;
height
=
tcx
.
basin
.
right_node
->
point
->
y
-
node
.
point
->
y
;
}
}
// if shallow stop filling
// if shallow stop filling
if
(
tcx
.
basin
.
width
>
height
)
{
if
(
tcx
.
basin
.
width
>
height
)
{
return
true
;
return
true
;
}
}
return
false
;
return
false
;
}
}
void
Sweep
::
FillEdgeEvent
(
SweepContext
&
tcx
,
Edge
*
edge
,
Node
*
node
)
void
Sweep
::
FillEdgeEvent
(
SweepContext
&
tcx
,
Edge
*
edge
,
Node
*
node
)
{
{
if
(
tcx
.
edge_event
.
right
)
{
if
(
tcx
.
edge_event
.
right
)
{
FillRightAboveEdgeEvent
(
tcx
,
edge
,
node
);
FillRightAboveEdgeEvent
(
tcx
,
edge
,
node
);
}
else
{
}
else
{
FillLeftAboveEdgeEvent
(
tcx
,
edge
,
node
);
FillLeftAboveEdgeEvent
(
tcx
,
edge
,
node
);
}
}
}
}
void
Sweep
::
FillRightAboveEdgeEvent
(
SweepContext
&
tcx
,
Edge
*
edge
,
Node
*
node
)
void
Sweep
::
FillRightAboveEdgeEvent
(
SweepContext
&
tcx
,
Edge
*
edge
,
Node
*
node
)
{
{
while
(
node
->
next
->
point
->
x
<
edge
->
p
->
x
)
{
while
(
node
->
next
->
point
->
x
<
edge
->
p
->
x
)
{
// Check if next node is below the edge
// Check if next node is below the edge
if
(
Orient2d
(
*
edge
->
q
,
*
node
->
next
->
point
,
*
edge
->
p
)
==
CCW
)
{
if
(
Orient2d
(
*
edge
->
q
,
*
node
->
next
->
point
,
*
edge
->
p
)
==
CCW
)
{
FillRightBelowEdgeEvent
(
tcx
,
edge
,
*
node
);
FillRightBelowEdgeEvent
(
tcx
,
edge
,
*
node
);
}
else
{
}
else
{
node
=
node
->
next
;
node
=
node
->
next
;
}
}
}
}
}
}
void
Sweep
::
FillRightBelowEdgeEvent
(
SweepContext
&
tcx
,
Edge
*
edge
,
Node
&
node
)
void
Sweep
::
FillRightBelowEdgeEvent
(
SweepContext
&
tcx
,
Edge
*
edge
,
Node
&
node
)
{
{
if
(
node
.
point
->
x
<
edge
->
p
->
x
)
{
if
(
node
.
point
->
x
<
edge
->
p
->
x
)
{
if
(
Orient2d
(
*
node
.
point
,
*
node
.
next
->
point
,
*
node
.
next
->
next
->
point
)
==
CCW
)
{
if
(
Orient2d
(
*
node
.
point
,
*
node
.
next
->
point
,
*
node
.
next
->
next
->
point
)
==
CCW
)
{
// Concave
// Concave
FillRightConcaveEdgeEvent
(
tcx
,
edge
,
node
);
FillRightConcaveEdgeEvent
(
tcx
,
edge
,
node
);
}
else
{
}
else
{
// Convex
// Convex
FillRightConvexEdgeEvent
(
tcx
,
edge
,
node
);
FillRightConvexEdgeEvent
(
tcx
,
edge
,
node
);
// Retry this one
// Retry this one
FillRightBelowEdgeEvent
(
tcx
,
edge
,
node
);
FillRightBelowEdgeEvent
(
tcx
,
edge
,
node
);
}
}
}
}
}
}
void
Sweep
::
FillRightConcaveEdgeEvent
(
SweepContext
&
tcx
,
Edge
*
edge
,
Node
&
node
)
void
Sweep
::
FillRightConcaveEdgeEvent
(
SweepContext
&
tcx
,
Edge
*
edge
,
Node
&
node
)
{
{
Fill
(
tcx
,
*
node
.
next
);
Fill
(
tcx
,
*
node
.
next
);
if
(
node
.
next
->
point
!=
edge
->
p
)
{
if
(
node
.
next
->
point
!=
edge
->
p
)
{
// Next above or below edge?
// Next above or below edge?
if
(
Orient2d
(
*
edge
->
q
,
*
node
.
next
->
point
,
*
edge
->
p
)
==
CCW
)
{
if
(
Orient2d
(
*
edge
->
q
,
*
node
.
next
->
point
,
*
edge
->
p
)
==
CCW
)
{
// Below
// Below
if
(
Orient2d
(
*
node
.
point
,
*
node
.
next
->
point
,
*
node
.
next
->
next
->
point
)
==
CCW
)
{
if
(
Orient2d
(
*
node
.
point
,
*
node
.
next
->
point
,
*
node
.
next
->
next
->
point
)
==
CCW
)
{
// Next is concave
// Next is concave
FillRightConcaveEdgeEvent
(
tcx
,
edge
,
node
);
FillRightConcaveEdgeEvent
(
tcx
,
edge
,
node
);
}
else
{
}
else
{
// Next is convex
// Next is convex
}
}
}
}
}
}
}
}
void
Sweep
::
FillRightConvexEdgeEvent
(
SweepContext
&
tcx
,
Edge
*
edge
,
Node
&
node
)
void
Sweep
::
FillRightConvexEdgeEvent
(
SweepContext
&
tcx
,
Edge
*
edge
,
Node
&
node
)
{
{
// Next concave or convex?
// Next concave or convex?
if
(
Orient2d
(
*
node
.
next
->
point
,
*
node
.
next
->
next
->
point
,
*
node
.
next
->
next
->
next
->
point
)
==
CCW
)
{
if
(
Orient2d
(
*
node
.
next
->
point
,
*
node
.
next
->
next
->
point
,
*
node
.
next
->
next
->
next
->
point
)
==
CCW
)
{
// Concave
// Concave
FillRightConcaveEdgeEvent
(
tcx
,
edge
,
*
node
.
next
);
FillRightConcaveEdgeEvent
(
tcx
,
edge
,
*
node
.
next
);
}
else
{
}
else
{
// Convex
// Convex
// Next above or below edge?
// Next above or below edge?
if
(
Orient2d
(
*
edge
->
q
,
*
node
.
next
->
next
->
point
,
*
edge
->
p
)
==
CCW
)
{
if
(
Orient2d
(
*
edge
->
q
,
*
node
.
next
->
next
->
point
,
*
edge
->
p
)
==
CCW
)
{
// Below
// Below
FillRightConvexEdgeEvent
(
tcx
,
edge
,
*
node
.
next
);
FillRightConvexEdgeEvent
(
tcx
,
edge
,
*
node
.
next
);
}
else
{
}
else
{
// Above
// Above
}
}
}
}
}
}
void
Sweep
::
FillLeftAboveEdgeEvent
(
SweepContext
&
tcx
,
Edge
*
edge
,
Node
*
node
)
void
Sweep
::
FillLeftAboveEdgeEvent
(
SweepContext
&
tcx
,
Edge
*
edge
,
Node
*
node
)
{
{
while
(
node
->
prev
->
point
->
x
>
edge
->
p
->
x
)
{
while
(
node
->
prev
->
point
->
x
>
edge
->
p
->
x
)
{
// Check if next node is below the edge
// Check if next node is below the edge
if
(
Orient2d
(
*
edge
->
q
,
*
node
->
prev
->
point
,
*
edge
->
p
)
==
CW
)
{
if
(
Orient2d
(
*
edge
->
q
,
*
node
->
prev
->
point
,
*
edge
->
p
)
==
CW
)
{
FillLeftBelowEdgeEvent
(
tcx
,
edge
,
*
node
);
FillLeftBelowEdgeEvent
(
tcx
,
edge
,
*
node
);
}
else
{
}
else
{
node
=
node
->
prev
;
node
=
node
->
prev
;
}
}
}
}
}
}
void
Sweep
::
FillLeftBelowEdgeEvent
(
SweepContext
&
tcx
,
Edge
*
edge
,
Node
&
node
)
void
Sweep
::
FillLeftBelowEdgeEvent
(
SweepContext
&
tcx
,
Edge
*
edge
,
Node
&
node
)
{
{
if
(
node
.
point
->
x
>
edge
->
p
->
x
)
{
if
(
node
.
point
->
x
>
edge
->
p
->
x
)
{
if
(
Orient2d
(
*
node
.
point
,
*
node
.
prev
->
point
,
*
node
.
prev
->
prev
->
point
)
==
CW
)
{
if
(
Orient2d
(
*
node
.
point
,
*
node
.
prev
->
point
,
*
node
.
prev
->
prev
->
point
)
==
CW
)
{
// Concave
// Concave
FillLeftConcaveEdgeEvent
(
tcx
,
edge
,
node
);
FillLeftConcaveEdgeEvent
(
tcx
,
edge
,
node
);
}
else
{
}
else
{
// Convex
// Convex
FillLeftConvexEdgeEvent
(
tcx
,
edge
,
node
);
FillLeftConvexEdgeEvent
(
tcx
,
edge
,
node
);
// Retry this one
// Retry this one
FillLeftBelowEdgeEvent
(
tcx
,
edge
,
node
);
FillLeftBelowEdgeEvent
(
tcx
,
edge
,
node
);
}
}
}
}
}
}
void
Sweep
::
FillLeftConvexEdgeEvent
(
SweepContext
&
tcx
,
Edge
*
edge
,
Node
&
node
)
void
Sweep
::
FillLeftConvexEdgeEvent
(
SweepContext
&
tcx
,
Edge
*
edge
,
Node
&
node
)
{
{
// Next concave or convex?
// Next concave or convex?
if
(
Orient2d
(
*
node
.
prev
->
point
,
*
node
.
prev
->
prev
->
point
,
*
node
.
prev
->
prev
->
prev
->
point
)
==
CW
)
{
if
(
Orient2d
(
*
node
.
prev
->
point
,
*
node
.
prev
->
prev
->
point
,
*
node
.
prev
->
prev
->
prev
->
point
)
==
CW
)
{
// Concave
// Concave
FillLeftConcaveEdgeEvent
(
tcx
,
edge
,
*
node
.
prev
);
FillLeftConcaveEdgeEvent
(
tcx
,
edge
,
*
node
.
prev
);
}
else
{
}
else
{
// Convex
// Convex
// Next above or below edge?
// Next above or below edge?
if
(
Orient2d
(
*
edge
->
q
,
*
node
.
prev
->
prev
->
point
,
*
edge
->
p
)
==
CW
)
{
if
(
Orient2d
(
*
edge
->
q
,
*
node
.
prev
->
prev
->
point
,
*
edge
->
p
)
==
CW
)
{
// Below
// Below
FillLeftConvexEdgeEvent
(
tcx
,
edge
,
*
node
.
prev
);
FillLeftConvexEdgeEvent
(
tcx
,
edge
,
*
node
.
prev
);
}
else
{
}
else
{
// Above
// Above
}
}
}
}
}
}
void
Sweep
::
FillLeftConcaveEdgeEvent
(
SweepContext
&
tcx
,
Edge
*
edge
,
Node
&
node
)
void
Sweep
::
FillLeftConcaveEdgeEvent
(
SweepContext
&
tcx
,
Edge
*
edge
,
Node
&
node
)
{
{
Fill
(
tcx
,
*
node
.
prev
);
Fill
(
tcx
,
*
node
.
prev
);
if
(
node
.
prev
->
point
!=
edge
->
p
)
{
if
(
node
.
prev
->
point
!=
edge
->
p
)
{
// Next above or below edge?
// Next above or below edge?
if
(
Orient2d
(
*
edge
->
q
,
*
node
.
prev
->
point
,
*
edge
->
p
)
==
CW
)
{
if
(
Orient2d
(
*
edge
->
q
,
*
node
.
prev
->
point
,
*
edge
->
p
)
==
CW
)
{
// Below
// Below
if
(
Orient2d
(
*
node
.
point
,
*
node
.
prev
->
point
,
*
node
.
prev
->
prev
->
point
)
==
CW
)
{
if
(
Orient2d
(
*
node
.
point
,
*
node
.
prev
->
point
,
*
node
.
prev
->
prev
->
point
)
==
CW
)
{
// Next is concave
// Next is concave
FillLeftConcaveEdgeEvent
(
tcx
,
edge
,
node
);
FillLeftConcaveEdgeEvent
(
tcx
,
edge
,
node
);
}
else
{
}
else
{
// Next is convex
// Next is convex
}
}
}
}
}
}
}
}
void
Sweep
::
FlipEdgeEvent
(
SweepContext
&
tcx
,
Point
&
ep
,
Point
&
eq
,
Triangle
*
t
,
Point
&
p
)
void
Sweep
::
FlipEdgeEvent
(
SweepContext
&
tcx
,
Point
&
ep
,
Point
&
eq
,
Triangle
*
t
,
Point
&
p
)
{
{
Triangle
&
ot
=
t
->
NeighborAcross
(
p
);
Triangle
&
ot
=
t
->
NeighborAcross
(
p
);
Point
&
op
=
*
ot
.
OppositePoint
(
*
t
,
p
);
Point
&
op
=
*
ot
.
OppositePoint
(
*
t
,
p
);
if
(
&
ot
==
NULL
)
{
if
(
&
ot
==
NULL
)
{
// If we want to integrate the fillEdgeEvent do it here
// If we want to integrate the fillEdgeEvent do it here
// With current implementation we should never get here
// With current implementation we should never get here
//throw new RuntimeException( "[BUG:FIXME] FLIP failed due to missing triangle");
//throw new RuntimeException( "[BUG:FIXME] FLIP failed due to missing triangle");
assert
(
0
);
assert
(
0
);
}
}
if
(
InScanArea
(
p
,
*
t
->
PointCCW
(
p
),
*
t
->
PointCW
(
p
),
op
))
{
if
(
InScanArea
(
p
,
*
t
->
PointCCW
(
p
),
*
t
->
PointCW
(
p
),
op
))
{
// Lets rotate shared edge one vertex CW
// Lets rotate shared edge one vertex CW
RotateTrianglePair
(
*
t
,
p
,
ot
,
op
);
RotateTrianglePair
(
*
t
,
p
,
ot
,
op
);
tcx
.
MapTriangleToNodes
(
*
t
);
tcx
.
MapTriangleToNodes
(
*
t
);
tcx
.
MapTriangleToNodes
(
ot
);
tcx
.
MapTriangleToNodes
(
ot
);
if
(
p
==
eq
&&
op
==
ep
)
{
if
(
p
==
eq
&&
op
==
ep
)
{
if
(
eq
==
*
tcx
.
edge_event
.
constrained_edge
->
q
&&
ep
==
*
tcx
.
edge_event
.
constrained_edge
->
p
)
{
if
(
eq
==
*
tcx
.
edge_event
.
constrained_edge
->
q
&&
ep
==
*
tcx
.
edge_event
.
constrained_edge
->
p
)
{
t
->
MarkConstrainedEdge
(
&
ep
,
&
eq
);
t
->
MarkConstrainedEdge
(
&
ep
,
&
eq
);
ot
.
MarkConstrainedEdge
(
&
ep
,
&
eq
);
ot
.
MarkConstrainedEdge
(
&
ep
,
&
eq
);
Legalize
(
tcx
,
*
t
);
Legalize
(
tcx
,
*
t
);
Legalize
(
tcx
,
ot
);
Legalize
(
tcx
,
ot
);
}
else
{
}
else
{
// XXX: I think one of the triangles should be legalized here?
// XXX: I think one of the triangles should be legalized here?
}
}
}
else
{
}
else
{
Orientation
o
=
Orient2d
(
eq
,
op
,
ep
);
Orientation
o
=
Orient2d
(
eq
,
op
,
ep
);
t
=
&
NextFlipTriangle
(
tcx
,
(
int
)
o
,
*
t
,
ot
,
p
,
op
);
t
=
&
NextFlipTriangle
(
tcx
,
(
int
)
o
,
*
t
,
ot
,
p
,
op
);
FlipEdgeEvent
(
tcx
,
ep
,
eq
,
t
,
p
);
FlipEdgeEvent
(
tcx
,
ep
,
eq
,
t
,
p
);
}
}
}
else
{
}
else
{
Point
&
newP
=
NextFlipPoint
(
ep
,
eq
,
ot
,
op
);
Point
&
newP
=
NextFlipPoint
(
ep
,
eq
,
ot
,
op
);
FlipScanEdgeEvent
(
tcx
,
ep
,
eq
,
*
t
,
ot
,
newP
);
FlipScanEdgeEvent
(
tcx
,
ep
,
eq
,
*
t
,
ot
,
newP
);
EdgeEvent
(
tcx
,
ep
,
eq
,
t
,
p
);
EdgeEvent
(
tcx
,
ep
,
eq
,
t
,
p
);
}
}
}
}
Triangle
&
Sweep
::
NextFlipTriangle
(
SweepContext
&
tcx
,
int
o
,
Triangle
&
t
,
Triangle
&
ot
,
Point
&
p
,
Point
&
op
)
Triangle
&
Sweep
::
NextFlipTriangle
(
SweepContext
&
tcx
,
int
o
,
Triangle
&
t
,
Triangle
&
ot
,
Point
&
p
,
Point
&
op
)
{
{
if
(
o
==
CCW
)
{
if
(
o
==
CCW
)
{
// ot is not crossing edge after flip
// ot is not crossing edge after flip
int
edge_index
=
ot
.
EdgeIndex
(
&
p
,
&
op
);
int
edge_index
=
ot
.
EdgeIndex
(
&
p
,
&
op
);
ot
.
delaunay_edge
[
edge_index
]
=
true
;
ot
.
delaunay_edge
[
edge_index
]
=
true
;
Legalize
(
tcx
,
ot
);
Legalize
(
tcx
,
ot
);
ot
.
ClearDelunayEdges
();
ot
.
ClearDelunayEdges
();
return
t
;
return
t
;
}
}
// t is not crossing edge after flip
// t is not crossing edge after flip
int
edge_index
=
t
.
EdgeIndex
(
&
p
,
&
op
);
int
edge_index
=
t
.
EdgeIndex
(
&
p
,
&
op
);
t
.
delaunay_edge
[
edge_index
]
=
true
;
t
.
delaunay_edge
[
edge_index
]
=
true
;
Legalize
(
tcx
,
t
);
Legalize
(
tcx
,
t
);
t
.
ClearDelunayEdges
();
t
.
ClearDelunayEdges
();
return
ot
;
return
ot
;
}
}
Point
&
Sweep
::
NextFlipPoint
(
Point
&
ep
,
Point
&
eq
,
Triangle
&
ot
,
Point
&
op
)
Point
&
Sweep
::
NextFlipPoint
(
Point
&
ep
,
Point
&
eq
,
Triangle
&
ot
,
Point
&
op
)
{
{
Orientation
o2d
=
Orient2d
(
eq
,
op
,
ep
);
Orientation
o2d
=
Orient2d
(
eq
,
op
,
ep
);
if
(
o2d
==
CW
)
{
if
(
o2d
==
CW
)
{
// Right
// Right
return
*
ot
.
PointCCW
(
op
);
return
*
ot
.
PointCCW
(
op
);
}
else
if
(
o2d
==
CCW
)
{
}
else
if
(
o2d
==
CCW
)
{
// Left
// Left
return
*
ot
.
PointCW
(
op
);
return
*
ot
.
PointCW
(
op
);
}
else
{
}
else
{
//throw new RuntimeException("[Unsupported] Opposing point on constrained edge");
//throw new RuntimeException("[Unsupported] Opposing point on constrained edge");
assert
(
0
);
assert
(
0
);
}
}
}
}
void
Sweep
::
FlipScanEdgeEvent
(
SweepContext
&
tcx
,
Point
&
ep
,
Point
&
eq
,
Triangle
&
flip_triangle
,
void
Sweep
::
FlipScanEdgeEvent
(
SweepContext
&
tcx
,
Point
&
ep
,
Point
&
eq
,
Triangle
&
flip_triangle
,
Triangle
&
t
,
Point
&
p
)
Triangle
&
t
,
Point
&
p
)
{
{
Triangle
&
ot
=
t
.
NeighborAcross
(
p
);
Triangle
&
ot
=
t
.
NeighborAcross
(
p
);
Point
&
op
=
*
ot
.
OppositePoint
(
t
,
p
);
Point
&
op
=
*
ot
.
OppositePoint
(
t
,
p
);
if
(
&
t
.
NeighborAcross
(
p
)
==
NULL
)
{
if
(
&
t
.
NeighborAcross
(
p
)
==
NULL
)
{
// If we want to integrate the fillEdgeEvent do it here
// If we want to integrate the fillEdgeEvent do it here
// With current implementation we should never get here
// With current implementation we should never get here
//throw new RuntimeException( "[BUG:FIXME] FLIP failed due to missing triangle");
//throw new RuntimeException( "[BUG:FIXME] FLIP failed due to missing triangle");
assert
(
0
);
assert
(
0
);
}
}
if
(
InScanArea
(
eq
,
*
flip_triangle
.
PointCCW
(
eq
),
*
flip_triangle
.
PointCW
(
eq
),
op
))
{
if
(
InScanArea
(
eq
,
*
flip_triangle
.
PointCCW
(
eq
),
*
flip_triangle
.
PointCW
(
eq
),
op
))
{
// flip with new edge op->eq
// flip with new edge op->eq
FlipEdgeEvent
(
tcx
,
eq
,
op
,
&
ot
,
op
);
FlipEdgeEvent
(
tcx
,
eq
,
op
,
&
ot
,
op
);
// TODO: Actually I just figured out that it should be possible to
// TODO: Actually I just figured out that it should be possible to
// improve this by getting the next ot and op before the the above
// improve this by getting the next ot and op before the the above
// flip and continue the flipScanEdgeEvent here
// flip and continue the flipScanEdgeEvent here
// set new ot and op here and loop back to inScanArea test
// set new ot and op here and loop back to inScanArea test
// also need to set a new flip_triangle first
// also need to set a new flip_triangle first
// Turns out at first glance that this is somewhat complicated
// Turns out at first glance that this is somewhat complicated
// so it will have to wait.
// so it will have to wait.
}
else
{
}
else
{
Point
&
newP
=
NextFlipPoint
(
ep
,
eq
,
ot
,
op
);
Point
&
newP
=
NextFlipPoint
(
ep
,
eq
,
ot
,
op
);
FlipScanEdgeEvent
(
tcx
,
ep
,
eq
,
flip_triangle
,
ot
,
newP
);
FlipScanEdgeEvent
(
tcx
,
ep
,
eq
,
flip_triangle
,
ot
,
newP
);
}
}
}
}
Sweep
::~
Sweep
()
{
Sweep
::~
Sweep
()
{
...
@@ -807,7 +807,7 @@ Sweep::~Sweep() {
...
@@ -807,7 +807,7 @@ Sweep::~Sweep() {
delete
nodes_
[
i
];
delete
nodes_
[
i
];
}
}
}
}
}
}
polygon/poly2tri/sweep/sweep_context.h
View file @
0d4b71ef
/*
/*
* Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
* Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
* http://code.google.com/p/poly2tri/
* http://code.google.com/p/poly2tri/
*
*
* All rights reserved.
* All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without modification,
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* are permitted provided that the following conditions are met:
*
*
* * Redistributions of source code must retain the above copyright notice,
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* and/or other materials provided with the distribution.
* * Neither the name of Poly2Tri nor the names of its contributors may be
* * Neither the name of Poly2Tri nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific
* used to endorse or promote products derived from this software without specific
* prior written permission.
* prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
*/
#ifndef SWEEP_CONTEXT_H
#ifndef SWEEP_CONTEXT_H
#define SWEEP_CONTEXT_H
#define SWEEP_CONTEXT_H
#include <list>
#include <list>
#include <vector>
#include <vector>
#include <cstddef>
#include <cstddef>
namespace
p2t
{
namespace
p2t
{
// Inital triangle factor, seed triangle will extend 30% of
// Inital triangle factor, seed triangle will extend 30% of
// PointSet width to both left and right.
// PointSet width to both left and right.
const
double
kAlpha
=
0
.
3
;
const
double
kAlpha
=
0
.
3
;
struct
Point
;
struct
Point
;
class
Triangle
;
class
Triangle
;
struct
Node
;
struct
Node
;
struct
Edge
;
struct
Edge
;
class
AdvancingFront
;
class
AdvancingFront
;
class
SweepContext
{
class
SweepContext
{
public
:
public
:
/// Constructor
/// Constructor
SweepContext
(
std
::
vector
<
Point
*>
polyline
);
SweepContext
(
std
::
vector
<
Point
*>
polyline
);
/// Destructor
/// Destructor
~
SweepContext
();
~
SweepContext
();
void
set_head
(
Point
*
p1
);
void
set_head
(
Point
*
p1
);
Point
*
head
();
Point
*
head
();
void
set_tail
(
Point
*
p1
);
void
set_tail
(
Point
*
p1
);
Point
*
tail
();
Point
*
tail
();
int
point_count
();
int
point_count
();
Node
&
LocateNode
(
Point
&
point
);
Node
&
LocateNode
(
Point
&
point
);
void
RemoveNode
(
Node
*
node
);
void
RemoveNode
(
Node
*
node
);
void
CreateAdvancingFront
(
std
::
vector
<
Node
*>
nodes
);
void
CreateAdvancingFront
(
std
::
vector
<
Node
*>
nodes
);
/// Try to map a node to all sides of this triangle that don't have a neighbor
/// Try to map a node to all sides of this triangle that don't have a neighbor
void
MapTriangleToNodes
(
Triangle
&
t
);
void
MapTriangleToNodes
(
Triangle
&
t
);
void
AddToMap
(
Triangle
*
triangle
);
void
AddToMap
(
Triangle
*
triangle
);
Point
*
GetPoint
(
const
int
&
index
);
Point
*
GetPoint
(
const
int
&
index
);
Point
*
GetPoints
();
Point
*
GetPoints
();
void
RemoveFromMap
(
Triangle
*
triangle
);
void
RemoveFromMap
(
Triangle
*
triangle
);
void
AddHole
(
std
::
vector
<
Point
*>
polyline
);
void
AddHole
(
std
::
vector
<
Point
*>
polyline
);
void
AddPoint
(
Point
*
point
);
void
AddPoint
(
Point
*
point
);
AdvancingFront
*
front
();
AdvancingFront
*
front
();
void
MeshClean
(
Triangle
&
triangle
);
void
MeshClean
(
Triangle
&
triangle
);
std
::
vector
<
Triangle
*>
GetTriangles
();
std
::
vector
<
Triangle
*>
GetTriangles
();
std
::
list
<
Triangle
*>
GetMap
();
std
::
list
<
Triangle
*>
GetMap
();
std
::
vector
<
Edge
*>
edge_list
;
std
::
vector
<
Edge
*>
edge_list
;
struct
Basin
{
struct
Basin
{
Node
*
left_node
;
Node
*
left_node
;
Node
*
bottom_node
;
Node
*
bottom_node
;
Node
*
right_node
;
Node
*
right_node
;
double
width
;
double
width
;
bool
left_highest
;
bool
left_highest
;
Basin
()
:
left_node
(
NULL
),
bottom_node
(
NULL
),
right_node
(
NULL
),
width
(
0
.
0
),
left_highest
(
false
)
Basin
()
:
left_node
(
NULL
),
bottom_node
(
NULL
),
right_node
(
NULL
),
width
(
0
.
0
),
left_highest
(
false
)
{
{
}
}
void
Clear
()
void
Clear
()
{
{
left_node
=
NULL
;
left_node
=
NULL
;
bottom_node
=
NULL
;
bottom_node
=
NULL
;
right_node
=
NULL
;
right_node
=
NULL
;
width
=
0
.
0
;
width
=
0
.
0
;
left_highest
=
false
;
left_highest
=
false
;
}
}
};
};
struct
EdgeEvent
{
struct
EdgeEvent
{
Edge
*
constrained_edge
;
Edge
*
constrained_edge
;
bool
right
;
bool
right
;
EdgeEvent
()
:
constrained_edge
(
NULL
),
right
(
false
)
EdgeEvent
()
:
constrained_edge
(
NULL
),
right
(
false
)
{
{
}
}
};
};
Basin
basin
;
Basin
basin
;
EdgeEvent
edge_event
;
EdgeEvent
edge_event
;
private
:
private
:
friend
class
Sweep
;
friend
class
Sweep
;
std
::
vector
<
Triangle
*>
triangles_
;
std
::
vector
<
Triangle
*>
triangles_
;
std
::
list
<
Triangle
*>
map_
;
std
::
list
<
Triangle
*>
map_
;
std
::
vector
<
Point
*>
points_
;
std
::
vector
<
Point
*>
points_
;
// Advancing front
// Advancing front
AdvancingFront
*
front_
;
AdvancingFront
*
front_
;
// head point used with advancing front
// head point used with advancing front
Point
*
head_
;
Point
*
head_
;
// tail point used with advancing front
// tail point used with advancing front
Point
*
tail_
;
Point
*
tail_
;
Node
*
af_head_
,
*
af_middle_
,
*
af_tail_
;
Node
*
af_head_
,
*
af_middle_
,
*
af_tail_
;
void
InitTriangulation
();
void
InitTriangulation
();
void
InitEdges
(
std
::
vector
<
Point
*>
polyline
);
void
InitEdges
(
std
::
vector
<
Point
*>
polyline
);
};
};
inline
AdvancingFront
*
SweepContext
::
front
()
inline
AdvancingFront
*
SweepContext
::
front
()
{
{
return
front_
;
return
front_
;
}
}
inline
int
SweepContext
::
point_count
()
inline
int
SweepContext
::
point_count
()
{
{
return
points_
.
size
();
return
points_
.
size
();
}
}
inline
void
SweepContext
::
set_head
(
Point
*
p1
)
inline
void
SweepContext
::
set_head
(
Point
*
p1
)
{
{
head_
=
p1
;
head_
=
p1
;
}
}
inline
Point
*
SweepContext
::
head
()
inline
Point
*
SweepContext
::
head
()
{
{
return
head_
;
return
head_
;
}
}
inline
void
SweepContext
::
set_tail
(
Point
*
p1
)
inline
void
SweepContext
::
set_tail
(
Point
*
p1
)
{
{
tail_
=
p1
;
tail_
=
p1
;
}
}
inline
Point
*
SweepContext
::
tail
()
inline
Point
*
SweepContext
::
tail
()
{
{
return
tail_
;
return
tail_
;
}
}
}
}
#endif
#endif
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment