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
79eca85b
Commit
79eca85b
authored
Mar 04, 2008
by
dickelbeck
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Magnetism
parent
c254c13e
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
178 additions
and
120 deletions
+178
-120
controle.cpp
pcbnew/controle.cpp
+150
-96
locate.cpp
pcbnew/locate.cpp
+19
-23
protos.h
pcbnew/protos.h
+9
-1
No files found.
pcbnew/controle.cpp
View file @
79eca85b
...
@@ -221,10 +221,10 @@ BOARD_ITEM* WinEDA_BasePcbFrame::PcbGeneralLocateAndDisplay( int aHotKeyCode )
...
@@ -221,10 +221,10 @@ BOARD_ITEM* WinEDA_BasePcbFrame::PcbGeneralLocateAndDisplay( int aHotKeyCode )
/**
/**
* Function Join
* Function Join
* finds the point where
b0+x*(b1-b0) intersects with a0+y*(a1-
a0).
* finds the point where
line segment (b1,b0) intersects with segment (a1,
a0).
* If that point would be outside of
a0-a1
, the respective endpoint is used.
* If that point would be outside of
(a0,a1)
, the respective endpoint is used.
* Join returns the point in "res" and "true" if a suitable point was found,
* Join returns the point in "res" and "true" if a suitable point was found,
* "false" if both lines are parallel.
* "false" if both lines are parallel
or if the length of either segment is zero
.
*/
*/
static
bool
Join
(
wxPoint
*
res
,
wxPoint
a0
,
wxPoint
a1
,
wxPoint
b0
,
wxPoint
b1
)
static
bool
Join
(
wxPoint
*
res
,
wxPoint
a0
,
wxPoint
a1
,
wxPoint
b0
,
wxPoint
b1
)
{
{
...
@@ -236,8 +236,16 @@ static bool Join( wxPoint* res, wxPoint a0, wxPoint a1, wxPoint b0, wxPoint b1 )
...
@@ -236,8 +236,16 @@ static bool Join( wxPoint* res, wxPoint a0, wxPoint a1, wxPoint b0, wxPoint b1 )
double
denom
;
double
denom
;
double
t
;
double
t
;
// if either segment is zero length
if
(
a1
.
x
==
a0
.
x
&&
a1
.
y
==
a0
.
y
)
return
false
;
if
(
b1
.
x
==
b0
.
x
&&
b1
.
y
==
b0
.
y
)
return
false
;
a1
-=
a0
;
a1
-=
a0
;
b1
-=
b0
;
b1
-=
b0
;
b0
-=
a0
;
b0
-=
a0
;
denom
=
(
double
)
b1
.
y
*
a1
.
x
-
(
double
)
b1
.
x
*
a1
.
y
;
denom
=
(
double
)
b1
.
y
*
a1
.
x
-
(
double
)
b1
.
x
*
a1
.
y
;
...
@@ -290,131 +298,177 @@ bool Project( wxPoint* res, wxPoint on_grid, const TRACK* track )
...
@@ -290,131 +298,177 @@ bool Project( wxPoint* res, wxPoint on_grid, const TRACK* track )
* "curpos". If yes, then curpos is adjusted appropriately according to that
* "curpos". If yes, then curpos is adjusted appropriately according to that
* near magnetic item and true is returned.
* near magnetic item and true is returned.
* @param curpos The initial position, and what to adjust if a change is needed.
* @param curpos The initial position, and what to adjust if a change is needed.
* @return bool - true if the position was adjusted magnetically, else false.
*/
*/
static
bool
Magnetize
(
BOARD
*
m_Pcb
,
WinEDA_PcbFrame
*
frame
,
static
bool
Magnetize
(
BOARD
*
m_Pcb
,
WinEDA_PcbFrame
*
frame
,
int
aCurrentTool
,
wxSize
grid
,
wxPoint
on_grid
,
wxPoint
*
curpos
)
int
aCurrentTool
,
wxSize
grid
,
wxPoint
on_grid
,
wxPoint
*
curpos
)
{
{
D_PAD
*
pad
;
TRACK
*
curr
=
g_CurrentTrackSegment
;
TRACK
*
via
;
TRACK
*
track
;
int
layer
,
layer_mask
;
bool
doCheckNet
=
g_MagneticPadOption
!=
capture_always
&&
Drc_On
;
bool
doCheckNet
=
g_MagneticPadOption
!=
capture_always
&&
Drc_On
;
bool
doTrack
=
false
;
bool
doPad
=
false
;
bool
amMovingVia
=
false
;
if
(
frame
->
GetCurItem
()
!=
curr
)
TRACK
*
currTrack
=
g_CurrentTrackSegment
;
{
BOARD_ITEM
*
currItem
=
frame
->
GetCurItem
();
curr
=
NULL
;
}
// D( printf( "currTrack=%p currItem=%p currTrack->Type()=%d currItem->Type()=%d\n", currTrack, currItem, currTrack ? currTrack->Type() : 0, currItem ? currItem->Type() : 0 ); )
bool
pad_ok
=
false
;
if
(
!
currTrack
&&
currItem
&&
currItem
->
Type
()
==
TYPEVIA
&&
currItem
->
m_Flags
)
if
(
g_MagneticPadOption
==
capture_always
)
pad_ok
=
true
;
bool
track_ok
=
false
;
if
(
g_MagneticTrackOption
==
capture_always
)
track_ok
=
true
;
if
(
aCurrentTool
==
ID_TRACK_BUTT
)
{
int
q
=
capture_cursor_in_track_tool
;
if
(
g_MagneticPadOption
==
q
)
pad_ok
=
true
;
if
(
g_MagneticTrackOption
==
q
)
track_ok
=
true
;
}
if
(
!
pad_ok
&&
!
track_ok
)
//then nothing magnetic to do
return
false
;
pad
=
Locate_Any_Pad
(
m_Pcb
,
CURSEUR_OFF_GRILLE
,
TRUE
);
if
(
pad
&&
pad_ok
)
{
{
if
(
doCheckNet
&&
curr
&&
curr
->
GetNet
()
!=
pad
->
GetNet
()
)
// moving a VIA
return
false
;
currTrack
=
(
TRACK
*
)
currItem
;
amMovingVia
=
true
;
*
curpos
=
pad
->
m_Pos
;
return
false
;
// comment this return out and play with it.
return
true
;
}
else
if
(
currItem
!=
currTrack
)
{
currTrack
=
NULL
;
}
}
layer
=
(
(
PCB_SCREEN
*
)
ActiveScreen
)
->
m_Active_Layer
;
via
=
Locate_Via_Area
(
m_Pcb
,
*
curpos
,
layer
);
if
(
g_MagneticPadOption
==
capture_always
)
if
(
via
&&
track_ok
)
//vias are part of tracks...?
doPad
=
true
;
if
(
g_MagneticTrackOption
==
capture_always
)
doTrack
=
true
;
if
(
aCurrentTool
==
ID_TRACK_BUTT
||
amMovingVia
)
{
{
if
(
doCheckNet
&&
curr
&&
curr
->
GetNet
()
!=
via
->
GetNet
()
)
int
q
=
capture_cursor_in_track_tool
;
return
false
;
*
curpos
=
via
->
m_Start
;
if
(
g_MagneticPadOption
==
q
)
return
true
;
doPad
=
true
;
if
(
g_MagneticTrackOption
==
q
)
doTrack
=
true
;
}
}
layer_mask
=
g_TabOneLayerMask
[
layer
];
D
(
printf
(
"doPad=%d doTrack=%d aCurrentTool=%d amMovingVia=%d
\n
"
,
doPad
,
doTrack
,
aCurrentTool
,
amMovingVia
);)
// The search precedence order is pads, then tracks/vias
if
(
!
curr
&&
track_ok
)
if
(
doPad
)
{
{
track
=
Locate_Pistes
(
m_Pcb
->
m_Track
,
layer_mask
,
CURSEUR_OFF_GRILLE
);
D_PAD
*
pad
=
Locate_Any_Pad
(
m_Pcb
,
CURSEUR_OFF_GRILLE
,
TRUE
);
if
(
!
track
||
track
->
Type
()
!=
TYPETRACK
)
if
(
pad
)
return
false
;
{
if
(
doCheckNet
&&
currTrack
&&
currTrack
->
GetNet
()
!=
pad
->
GetNet
()
)
return
false
;
return
Project
(
curpos
,
on_grid
,
track
);
*
curpos
=
pad
->
m_Pos
;
return
true
;
}
}
}
/*
// after pads, only track & via tests remain, skip them if not desired
* In two segment mode, ignore the final segment if it's inside a grid
if
(
doTrack
)
* square.
*/
if
(
curr
&&
g_TwoSegmentTrackBuild
&&
curr
->
Back
()
&&
curr
->
m_Start
.
x
-
grid
.
x
<
curr
->
m_End
.
x
&&
curr
->
m_Start
.
x
+
grid
.
x
>
curr
->
m_End
.
x
&&
curr
->
m_Start
.
y
-
grid
.
y
<
curr
->
m_End
.
y
&&
curr
->
m_Start
.
y
+
grid
.
y
>
curr
->
m_End
.
y
)
{
{
curr
=
curr
->
Back
();
int
layer
=
(
(
PCB_SCREEN
*
)
ActiveScreen
)
->
m_Active_Layer
;
}
for
(
track
=
m_Pcb
->
m_Track
;
track
&&
track_ok
;
track
=
track
->
Next
()
)
for
(
TRACK
*
via
=
m_Pcb
->
m_Track
;
{
via
&&
(
via
=
Locate_Via_Area
(
via
,
*
curpos
,
layer
))
!=
NULL
;
if
(
track
->
Type
()
!=
TYPETRACK
)
via
=
via
->
Next
()
)
continue
;
{
if
(
via
!=
currTrack
)
// a via cannot influence itself
{
if
(
doCheckNet
&&
currTrack
&&
currTrack
->
GetNet
()
!=
via
->
GetNet
()
)
return
false
;
if
(
doCheckNet
&&
curr
->
GetNet
()
!=
track
->
GetNet
()
)
*
curpos
=
via
->
m_Start
;
continue
;
D
(
printf
(
"via hit
\n
"
);)
return
true
;
}
else
{
D
(
printf
(
"skipping self
\n
"
);
)
}
}
if
(
(
g_DesignSettings
.
m_LayerColor
[
track
->
GetLayer
()]
&
ITEM_NOT_SHOW
)
)
if
(
!
currTrack
)
continue
;
{
int
layer_mask
=
g_TabOneLayerMask
[
layer
];
if
(
!
track
->
IsOnLayer
(
layer
)
)
TRACK
*
track
=
Locate_Pistes
(
m_Pcb
->
m_Track
,
layer_mask
,
CURSEUR_OFF_GRILLE
);
continue
;
if
(
!
track
||
track
->
Type
()
!=
TYPETRACK
)
return
false
;
// @todo, this should be a track overlap test, not a mouse on track test.
D
(
printf
(
"Project
\n
"
);
)
// The former would consider the new track's width.
return
Project
(
curpos
,
on_grid
,
track
);
if
(
!
track
->
HitTest
(
*
curpos
)
)
}
continue
;
if
(
Join
(
curpos
,
track
->
m_Start
,
track
->
m_End
,
curr
->
m_Start
,
curr
->
m_End
)
)
/*
* In two segment mode, ignore the final segment if it's inside a grid
* square.
*/
if
(
!
amMovingVia
&&
currTrack
&&
g_TwoSegmentTrackBuild
&&
currTrack
->
Back
()
&&
currTrack
->
m_Start
.
x
-
grid
.
x
<
currTrack
->
m_End
.
x
&&
currTrack
->
m_Start
.
x
+
grid
.
x
>
currTrack
->
m_End
.
x
&&
currTrack
->
m_Start
.
y
-
grid
.
y
<
currTrack
->
m_End
.
y
&&
currTrack
->
m_Start
.
y
+
grid
.
y
>
currTrack
->
m_End
.
y
)
{
{
return
true
;
currTrack
=
currTrack
->
Back
()
;
}
}
if
(
aCurrentTool
==
ID_TRACK_BUTT
)
for
(
TRACK
*
track
=
m_Pcb
->
m_Track
;
track
;
track
=
track
->
Next
()
)
{
{
// At this point we have a drawing mouse on a track, we are drawing
if
(
track
->
Type
()
!=
TYPETRACK
)
// a new track and that new track is parallel to the track the
continue
;
// mouse is on. Find the nearest end point of the track under mouse
// to the mouse and return that.
if
(
doCheckNet
&&
currTrack
&&
currTrack
->
GetNet
()
!=
track
->
GetNet
()
)
double
distStart
=
hypot
(
double
(
curpos
->
x
-
track
->
m_Start
.
x
),
continue
;
double
(
curpos
->
y
-
track
->
m_Start
.
y
));
if
(
(
g_DesignSettings
.
m_LayerColor
[
track
->
GetLayer
()]
&
ITEM_NOT_SHOW
)
)
double
distEnd
=
hypot
(
double
(
curpos
->
x
-
track
->
m_End
.
x
),
continue
;
double
(
curpos
->
y
-
track
->
m_End
.
y
));
// omit the layer check if moving a via
if
(
distStart
<
distEnd
)
if
(
!
amMovingVia
&&
!
track
->
IsOnLayer
(
layer
)
)
*
curpos
=
track
->
m_Start
;
continue
;
else
*
curpos
=
track
->
m_End
;
if
(
!
track
->
HitTest
(
*
curpos
)
)
return
true
;
continue
;
if
(
Join
(
curpos
,
track
->
m_Start
,
track
->
m_End
,
currTrack
->
m_Start
,
currTrack
->
m_End
)
)
{
D
(
printf
(
"join currTrack->Type()=%d
\n
"
,
currTrack
->
Type
()
);)
return
true
;
}
if
(
aCurrentTool
==
ID_TRACK_BUTT
||
amMovingVia
)
{
// At this point we have a drawing mouse on a track, we are drawing
// a new track and that new track is parallel to the track the
// mouse is on. Find the nearest end point of the track under mouse
// to the mouse and return that.
double
distStart
=
hypot
(
double
(
curpos
->
x
-
track
->
m_Start
.
x
),
double
(
curpos
->
y
-
track
->
m_Start
.
y
));
double
distEnd
=
hypot
(
double
(
curpos
->
x
-
track
->
m_End
.
x
),
double
(
curpos
->
y
-
track
->
m_End
.
y
));
// if track not via, or if its a via dragging but not with its adjacent track
if
(
currTrack
->
Type
()
!=
TYPEVIA
||
(
currTrack
->
m_Start
!=
track
->
m_Start
&&
currTrack
->
m_Start
!=
track
->
m_End
))
{
if
(
distStart
<=
currTrack
->
m_Width
/
2
)
{
D
(
printf
(
"nearest end is start
\n
"
);)
*
curpos
=
track
->
m_Start
;
return
true
;
}
if
(
distEnd
<=
currTrack
->
m_Width
/
2
)
{
D
(
printf
(
"nearest end is end
\n
"
);)
*
curpos
=
track
->
m_End
;
return
true
;
}
// @todo otherwise confine curpos such that it stays centered
// within "track"
}
}
}
}
}
}
...
...
pcbnew/locate.cpp
View file @
79eca85b
...
@@ -42,51 +42,47 @@ TRACK* Locate_Via( BOARD* Pcb, const wxPoint& pos, int layer )
...
@@ -42,51 +42,47 @@ TRACK* Locate_Via( BOARD* Pcb, const wxPoint& pos, int layer )
* (TRACK*) adresse de la via
* (TRACK*) adresse de la via
*/
*/
{
{
TRACK
*
T
rack
;
TRACK
*
t
rack
;
for
(
Track
=
Pcb
->
m_Track
;
Track
!=
NULL
;
Track
=
T
rack
->
Next
()
)
for
(
track
=
Pcb
->
m_Track
;
track
;
track
=
t
rack
->
Next
()
)
{
{
if
(
T
rack
->
Type
()
!=
TYPEVIA
)
if
(
t
rack
->
Type
()
!=
TYPEVIA
)
continue
;
continue
;
if
(
T
rack
->
m_Start
!=
pos
)
if
(
t
rack
->
m_Start
!=
pos
)
continue
;
continue
;
if
(
T
rack
->
GetState
(
BUSY
|
DELETED
)
)
if
(
t
rack
->
GetState
(
BUSY
|
DELETED
)
)
continue
;
continue
;
if
(
layer
<
0
)
if
(
layer
<
0
)
return
Trac
k
;
brea
k
;
if
(
T
rack
->
IsOnLayer
(
layer
)
)
if
(
t
rack
->
IsOnLayer
(
layer
)
)
return
Trac
k
;
brea
k
;
}
}
return
NULL
;
return
track
;
}
}
/*******************************************************************/
/*******************************************************************/
TRACK
*
Locate_Via_Area
(
BOARD
*
Pcb
,
const
wxPoint
&
pos
,
int
layer
)
TRACK
*
Locate_Via_Area
(
TRACK
*
aStart
,
const
wxPoint
&
pos
,
int
layer
)
/*******************************************************************/
/*******************************************************************/
/*
* Like Locate_Via, but finds any via covering the cursor position
*/
{
{
TRACK
*
T
rack
;
TRACK
*
t
rack
;
for
(
Track
=
Pcb
->
m_Track
;
Track
!=
NULL
;
Track
=
T
rack
->
Next
()
)
for
(
track
=
aStart
;
track
;
track
=
t
rack
->
Next
()
)
{
{
if
(
T
rack
->
Type
()
!=
TYPEVIA
)
if
(
t
rack
->
Type
()
!=
TYPEVIA
)
continue
;
continue
;
if
(
!
Track
->
HitTest
(
pos
)
)
if
(
!
track
->
HitTest
(
pos
)
)
continue
;
continue
;
if
(
T
rack
->
GetState
(
BUSY
|
DELETED
)
)
if
(
t
rack
->
GetState
(
BUSY
|
DELETED
)
)
continue
;
continue
;
if
(
layer
<
0
)
if
(
layer
<
0
)
return
Trac
k
;
brea
k
;
if
(
T
rack
->
IsOnLayer
(
layer
)
)
if
(
t
rack
->
IsOnLayer
(
layer
)
)
return
Trac
k
;
brea
k
;
}
}
return
NULL
;
return
track
;
}
}
...
...
pcbnew/protos.h
View file @
79eca85b
...
@@ -77,7 +77,15 @@ void Trace_Pads_Only( WinEDA_DrawPanel* panel, wxDC* DC, MODULE* Module, int ox,
...
@@ -77,7 +77,15 @@ void Trace_Pads_Only( WinEDA_DrawPanel* panel, wxDC* DC, MODULE* Module, int ox,
TRACK
*
Locate_Via
(
BOARD
*
Pcb
,
const
wxPoint
&
pos
,
int
layer
=
-
1
);
TRACK
*
Locate_Via
(
BOARD
*
Pcb
,
const
wxPoint
&
pos
,
int
layer
=
-
1
);
TRACK
*
Locate_Via_Area
(
BOARD
*
Pcb
,
const
wxPoint
&
pos
,
int
layer
=
-
1
);
/**
* Function Locate_Via_Area
* finds the first SEGVIA which covers the given aPos with a matching layer.
* @param aStart The starting TRACK or SEGVIA in the BOARD's list.
* @param aPos The wxPoint to HitTest() against.
* @param aLayer The layer to match, pass -1 for a don't care.
* @return TRACK* - actually a SEGVIA* if found, else NULL.
*/
TRACK
*
Locate_Via_Area
(
TRACK
*
aStart
,
const
wxPoint
&
aPos
,
int
aLayer
=
-
1
);
TRACK
*
Fast_Locate_Via
(
TRACK
*
start_adr
,
TRACK
*
end_adr
,
TRACK
*
Fast_Locate_Via
(
TRACK
*
start_adr
,
TRACK
*
end_adr
,
const
wxPoint
&
pos
,
int
masquelayer
);
const
wxPoint
&
pos
,
int
masquelayer
);
...
...
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