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
30932a46
Commit
30932a46
authored
Feb 26, 2008
by
dickelbeck
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Werner Almesberger's patches
parent
5977accf
Changes
5
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
639 additions
and
314 deletions
+639
-314
class_track.cpp
pcbnew/class_track.cpp
+2
-4
controle.cpp
pcbnew/controle.cpp
+167
-29
editrack.cpp
pcbnew/editrack.cpp
+135
-16
locate.cpp
pcbnew/locate.cpp
+28
-0
protos.h
pcbnew/protos.h
+307
-265
No files found.
pcbnew/class_track.cpp
View file @
30932a46
...
...
@@ -890,10 +890,8 @@ bool TRACK::HitTest( const wxPoint& ref_pos )
if
(
Type
()
==
TYPEVIA
)
/* VIA rencontree */
{
if
(
(
abs
(
spot_cX
)
<=
l_piste
)
&&
(
abs
(
spot_cY
)
<=
l_piste
)
)
return
true
;
else
return
false
;
return
(
int64_t
)
spot_cX
*
spot_cX
+
(
int64_t
)
spot_cY
*
spot_cY
<=
(
int64_t
)
l_piste
*
l_piste
;
}
else
{
...
...
pcbnew/controle.cpp
View file @
30932a46
...
...
@@ -219,6 +219,152 @@ BOARD_ITEM* WinEDA_BasePcbFrame::PcbGeneralLocateAndDisplay( int aHotKeyCode )
}
/*
* "Join" finds the point where b0+x*(b1-b0) intersects with a0+y*(a1-a0).
* 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,
* "false" if both lines are parallel.
*/
static
bool
Join
(
wxPoint
&
res
,
wxPoint
a0
,
wxPoint
a1
,
wxPoint
b0
,
wxPoint
b1
)
{
int64_t
denom
;
double
t
;
a1
-=
a0
;
b1
-=
b0
;
b0
-=
a0
;
denom
=
(
int64_t
)
b1
.
y
*
a1
.
x
-
(
int64_t
)
b1
.
x
*
a1
.
y
;
if
(
!
denom
)
return
false
;
// parallel
t
=
((
int64_t
)
b1
.
y
*
b0
.
x
-
(
int64_t
)
b1
.
x
*
b0
.
y
)
/
(
double
)
denom
;
t
=
min
(
max
(
t
,
0.0
),
1.0
);
res
.
x
=
(
int
)
round
(
a0
.
x
+
t
*
a1
.
x
);
res
.
y
=
(
int
)
round
(
a0
.
y
+
t
*
a1
.
y
);
return
true
;
}
/*
* "Project" finds the projection of a grid point on a track. This is the point
* from where we want to draw new orthogonal tracks when starting on a track.
*/
bool
Project
(
wxPoint
&
res
,
wxPoint
on_grid
,
const
TRACK
*
track
)
{
wxPoint
vec
;
double
t
;
if
(
track
->
m_Start
==
track
->
m_End
)
return
false
;
vec
=
track
->
m_End
-
track
->
m_Start
;
t
=
(
int64_t
)
(
on_grid
.
x
-
track
->
m_Start
.
x
)
*
vec
.
x
+
(
int64_t
)
(
on_grid
.
y
-
track
->
m_Start
.
y
)
*
vec
.
y
;
t
/=
(
int64_t
)
vec
.
x
*
vec
.
x
+
(
int64_t
)
vec
.
y
*
vec
.
y
;
t
=
min
(
max
(
t
,
0.0
),
1.0
);
res
.
x
=
(
int
)
round
(
track
->
m_Start
.
x
+
t
*
vec
.
x
);
res
.
y
=
(
int
)
round
(
track
->
m_Start
.
y
+
t
*
vec
.
y
);
return
true
;
}
static
bool
Magnetize
(
BOARD
*
m_Pcb
,
WinEDA_PcbFrame
*
frame
,
int
m_ID_current_state
,
wxSize
grid
,
wxPoint
on_grid
,
wxPoint
&
curpos
)
{
const
D_PAD
*
pad
;
const
TRACK
*
curr
=
NULL
;
const
TRACK
*
via
,
*
track
;
int
layer
,
layer_mask
;
bool
sometimes
=
g_MagneticPadOption
!=
capture_always
&&
Drc_On
;
curr
=
g_CurrentTrackSegment
;
if
(
frame
->
GetCurItem
()
!=
curr
)
curr
=
NULL
;
switch
(
g_MagneticPadOption
)
{
case
capture_cursor_in_track_tool
:
if
(
m_ID_current_state
!=
ID_TRACK_BUTT
)
return
false
;
break
;
case
capture_always
:
break
;
case
no_effect
:
default
:
return
false
;
}
pad
=
Locate_Any_Pad
(
m_Pcb
,
CURSEUR_OFF_GRILLE
,
TRUE
);
if
(
pad
)
{
if
(
curr
&&
curr
->
GetNet
()
!=
pad
->
GetNet
()
&&
sometimes
)
return
false
;
curpos
=
pad
->
m_Pos
;
return
true
;
}
layer
=
(
(
PCB_SCREEN
*
)
ActiveScreen
)
->
m_Active_Layer
;
via
=
Locate_Via_Area
(
m_Pcb
,
curpos
,
layer
);
if
(
via
)
{
if
(
curr
&&
curr
->
GetNet
()
!=
via
->
GetNet
()
&&
sometimes
)
return
false
;
curpos
=
via
->
m_Start
;
return
true
;
}
layer_mask
=
g_TabOneLayerMask
[
layer
];
if
(
!
curr
)
{
track
=
Locate_Pistes
(
m_Pcb
->
m_Track
,
layer_mask
,
CURSEUR_OFF_GRILLE
);
if
(
!
track
||
track
->
Type
()
!=
TYPETRACK
)
return
false
;
return
Project
(
curpos
,
on_grid
,
track
);
}
/*
* In two segment mode, ignore the final segment if it's inside a grid
* square.
*/
if
(
g_TwoSegmentTrackBuild
&&
curr
->
Pback
&&
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
();
track
=
Locate_Pistes
(
m_Pcb
->
m_Track
,
layer_mask
,
CURSEUR_OFF_GRILLE
);
for
(
;
track
;
track
=
track
->
Next
()
)
{
if
(
track
->
Type
()
!=
TYPETRACK
)
continue
;
if
(
curr
->
GetNet
()
!=
track
->
GetNet
()
&&
sometimes
)
continue
;
if
(
Join
(
curpos
,
track
->
m_Start
,
track
->
m_End
,
curr
->
m_Start
,
curr
->
m_End
)
)
return
true
;
}
return
false
;
}
/****************************************************************/
void
WinEDA_BasePcbFrame
::
GeneralControle
(
wxDC
*
DC
,
wxPoint
Mouse
)
/*****************************************************************/
...
...
@@ -341,7 +487,6 @@ void WinEDA_BasePcbFrame::GeneralControle( wxDC* DC, wxPoint Mouse )
* But if the tool DELETE is active the cursor is left off grid
* this is better to reach items to delete off grid
*/
D_PAD
*
pad
;
bool
keep_on_grid
=
TRUE
;
if
(
m_ID_current_state
==
ID_PCB_DELETE_ITEM_BUTT
)
keep_on_grid
=
FALSE
;
...
...
@@ -354,34 +499,27 @@ void WinEDA_BasePcbFrame::GeneralControle( wxDC* DC, wxPoint Mouse )
if
(
DrawStruct
&&
DrawStruct
->
m_Flags
)
keep_on_grid
=
TRUE
;
switch
(
g_MagneticPadOption
)
{
case
capture_cursor_in_track_tool
:
case
capture_always
:
pad
=
Locate_Any_Pad
(
m_Pcb
,
CURSEUR_OFF_GRILLE
,
TRUE
);
if
(
(
m_ID_current_state
!=
ID_TRACK_BUTT
)
&&
(
g_MagneticPadOption
==
capture_cursor_in_track_tool
)
)
pad
=
NULL
;
if
(
keep_on_grid
)
{
wxPoint
on_grid
=
curpos
;
if
(
keep_on_grid
)
{
if
(
pad
)
// Put cursor on the pad
GetScreen
()
->
m_Curseur
=
curpos
=
pad
->
m_Pos
;
else
// Put cursor on grid
PutOnGrid
(
&
GetScreen
()
->
m_Curseur
);
}
break
;
case
no_effect
:
default
:
PutOnGrid
(
&
on_grid
);
if
(
Magnetize
(
m_Pcb
,
(
WinEDA_PcbFrame
*
)
this
,
m_ID_current_state
,
GetScreen
()
->
GetGrid
(),
on_grid
,
curpos
))
GetScreen
()
->
m_Curseur
=
curpos
;
else
{
extern
TRACK
*
LocateIntrusion
(
TRACK
*
start
,
int
net
,
int
width
);
// If we are not in delete function, put cursor on grid
if
(
keep_on_grid
)
{
PutOnGrid
(
&
GetScreen
()
->
m_Curseur
);
/*
* If there's an intrusion and DRC is active, we pass the cursor
* "as is", and let ShowNewTrackWhenMovingCursor figure our what to
* do.
*/
if
(
!
Drc_On
||
!
g_CurrentTrackSegment
||
g_CurrentTrackSegment
!=
this
->
GetCurItem
()
||
!
LocateIntrusion
(
m_Pcb
->
m_Track
,
g_CurrentTrackSegment
->
GetNet
(),
g_CurrentTrackSegment
->
m_Width
))
GetScreen
()
->
m_Curseur
=
on_grid
;
}
break
;
}
if
(
oldpos
!=
GetScreen
()
->
m_Curseur
)
...
...
pcbnew/editrack.cpp
View file @
30932a46
...
...
@@ -18,7 +18,7 @@
static
void
Exit_Editrack
(
WinEDA_DrawPanel
*
panel
,
wxDC
*
DC
);
void
ShowNewTrackWhenMovingCursor
(
WinEDA_DrawPanel
*
panel
,
wxDC
*
DC
,
bool
erase
);
static
void
ComputeBreakPoint
(
TRACK
*
track
,
int
n
);
static
void
ComputeBreakPoint
(
TRACK
*
track
,
int
n
,
wxPoint
end
);
static
TRACK
*
DeleteNullTrackSegments
(
BOARD
*
pcb
,
TRACK
*
track
,
int
*
segmcount
);
static
void
EnsureEndTrackOnPad
(
D_PAD
*
Pad
);
...
...
@@ -493,6 +493,120 @@ void WinEDA_PcbFrame::End_Route( TRACK* track, wxDC* DC )
SetCurItem
(
NULL
);
}
/*
* PushTrack detecs if the mouse is pointing into a conflicting track.
* In this case, it tries to push the new track out of the conflicting track's
* clearance zone. This gives us a cheap mechanism for drawing tracks that
* tightly follow others, independent of grid settings.
*
* KNOWN BUGS:
* - we do the same sort of search and calculation up to three times:
* 1) we search for magnetic hits (in controle.cpp)
* 2) we check if there's a DRC violation in the making (also controle.cpp)
* 3) we try to fix the DRC violation (here)
* - if we have a magnetic hit and a DRC violation at the same time, we choose
* the magnetic hit instead of solving the violation
* - should locate conflicting tracks also when we're crossing over them
* - we obviously shouldn't access functions through "extern" or have #includes
* in the middle of the file
*/
#include "trigo.h"
extern
bool
Project
(
wxPoint
&
res
,
wxPoint
on_grid
,
const
TRACK
*
track
);
TRACK
*
LocateIntrusion
(
TRACK
*
start
,
int
net
,
int
width
)
{
int
layer
=
((
PCB_SCREEN
*
)
ActiveScreen
)
->
m_Active_Layer
;
int
layer_mask
=
g_TabOneLayerMask
[
layer
];
wxPoint
ref
=
ActiveScreen
->
RefPos
(
1
);
TRACK
*
track
,
*
found
=
NULL
;
for
(
track
=
start
;
track
;
track
=
track
->
Next
())
{
int
dist
;
wxPoint
pos
,
vec
;
int64_t
tmp
;
/* Locate_Pistes */
if
(
track
->
GetState
(
BUSY
|
DELETED
))
continue
;
if
(
!
(
g_TabOneLayerMask
[
track
->
GetLayer
()]
&
layer_mask
))
continue
;
if
(
track
->
GetNet
()
==
net
)
continue
;
if
(
track
->
Type
()
==
TYPEVIA
)
continue
;
/* TRACK::HitTest */
dist
=
width
/
2
+
track
->
m_Width
/
2
+
g_DesignSettings
.
m_TrackClearence
;
pos
=
ref
-
track
->
m_Start
;
vec
=
track
->
m_End
-
track
->
m_Start
;
if
(
!
DistanceTest
(
dist
,
vec
.
x
,
vec
.
y
,
pos
.
x
,
pos
.
y
))
continue
;
found
=
track
;
/* prefer intrusions from the side, not the end */
tmp
=
(
int64_t
)
pos
.
x
*
vec
.
x
+
(
int64_t
)
pos
.
y
*
vec
.
y
;
if
(
tmp
>=
0
&&
tmp
<=
(
int64_t
)
vec
.
x
*
vec
.
x
+
(
int64_t
)
vec
.
y
*
vec
.
y
)
break
;
}
return
found
;
}
static
void
PushTrack
(
WinEDA_DrawPanel
*
panel
)
{
BOARD
*
pcb
=
((
WinEDA_BasePcbFrame
*
)
(
panel
->
m_Parent
))
->
m_Pcb
;
wxPoint
cursor
=
ActiveScreen
->
m_Curseur
;
wxPoint
cv
,
vec
,
n
;
TRACK
*
track
=
g_CurrentTrackSegment
;
TRACK
*
other
;
int64_t
det
;
int
dist
;
double
f
;
other
=
LocateIntrusion
(
pcb
->
m_Track
,
track
->
GetNet
(),
track
->
m_Width
);
/* are we currently pointing into a conflicting trace ? */
if
(
!
other
)
return
;
if
(
other
->
GetNet
()
==
track
->
GetNet
())
return
;
cv
=
cursor
-
other
->
m_Start
;
vec
=
other
->
m_End
-
other
->
m_Start
;
det
=
(
int64_t
)
cv
.
x
*
vec
.
y
-
(
int64_t
)
cv
.
y
*
vec
.
x
;
/* cursor is right at the center of the old track */
if
(
!
det
)
return
;
dist
=
(
track
->
m_Width
+
1
)
/
2
+
(
other
->
m_Width
+
1
)
/
2
+
g_DesignSettings
.
m_TrackClearence
+
2
;
/*
* DRC wants >, so +1.
* We may have a quantization error of 1/sqrt(2), so +1 again.
*/
/* Vector "n" is perpendicular to "other", pointing towards the cursor. */
if
(
det
>
0
)
{
n
.
x
=
vec
.
y
;
n
.
y
=
-
vec
.
x
;
}
else
{
n
.
x
=
-
vec
.
y
;
n
.
y
=
vec
.
x
;
}
f
=
dist
/
hypot
(
n
.
x
,
n
.
y
);
n
.
x
=
(
int
)
round
(
f
*
n
.
x
);
n
.
y
=
(
int
)
round
(
f
*
n
.
y
);
Project
(
track
->
m_End
,
cursor
,
other
);
track
->
m_End
+=
n
;
}
/****************************************************************************/
void
ShowNewTrackWhenMovingCursor
(
WinEDA_DrawPanel
*
panel
,
wxDC
*
DC
,
bool
erase
)
...
...
@@ -538,8 +652,13 @@ void ShowNewTrackWhenMovingCursor( WinEDA_DrawPanel* panel, wxDC* DC, bool erase
if
(
Track_45_Only
)
{
if
(
g_TwoSegmentTrackBuild
)
ComputeBreakPoint
(
g_CurrentTrackSegment
,
g_TrackSegmentCount
);
if
(
g_TwoSegmentTrackBuild
)
{
g_CurrentTrackSegment
->
m_End
=
ActiveScreen
->
m_Curseur
;
if
(
Drc_On
)
PushTrack
(
panel
);
ComputeBreakPoint
(
g_CurrentTrackSegment
,
g_TrackSegmentCount
,
g_CurrentTrackSegment
->
m_End
);
}
else
{
/* Calcul de l'extremite de la piste pour orientations permises:
...
...
@@ -625,7 +744,7 @@ void Calcule_Coord_Extremite_45( int ox, int oy, int* fx, int* fy )
/********************************************************/
void
ComputeBreakPoint
(
TRACK
*
track
,
int
SegmentCount
)
void
ComputeBreakPoint
(
TRACK
*
track
,
int
SegmentCount
,
wxPoint
end
)
/********************************************************/
/**
...
...
@@ -646,8 +765,8 @@ void ComputeBreakPoint( TRACK* track, int SegmentCount )
SegmentCount
--
;
if
(
track
)
{
iDx
=
ActiveScreen
->
m_Curseur
.
x
-
track
->
m_Start
.
x
;
iDy
=
ActiveScreen
->
m_Curseur
.
y
-
track
->
m_Start
.
y
;
iDx
=
end
.
x
-
track
->
m_Start
.
x
;
iDy
=
end
.
y
-
track
->
m_Start
.
y
;
iDx
=
abs
(
iDx
);
iDy
=
abs
(
iDy
);
...
...
@@ -680,10 +799,10 @@ void ComputeBreakPoint( TRACK* track, int SegmentCount )
break
;
case
0
:
if
(
(
ActiveScreen
->
m_Curseur
.
x
-
track
->
m_Start
.
x
)
<
0
)
track
->
m_End
.
x
=
ActiveScreen
->
m_Curseur
.
x
+
iDy
;
if
(
(
end
.
x
-
track
->
m_Start
.
x
)
<
0
)
track
->
m_End
.
x
=
end
.
x
+
iDy
;
else
track
->
m_End
.
x
=
ActiveScreen
->
m_Curseur
.
x
-
iDy
;
track
->
m_End
.
x
=
end
.
x
-
iDy
;
track
->
m_End
.
y
=
track
->
m_Start
.
y
;
break
;
...
...
@@ -691,19 +810,19 @@ void ComputeBreakPoint( TRACK* track, int SegmentCount )
iDx
=
MIN
(
iDx
,
iDy
);
iDy
=
iDx
;
/* recalcul des signes de deltax et deltay */
if
(
(
ActiveScreen
->
m_Curseur
.
x
-
track
->
m_Start
.
x
)
<
0
)
if
(
(
end
.
x
-
track
->
m_Start
.
x
)
<
0
)
iDx
=
-
iDx
;
if
(
(
ActiveScreen
->
m_Curseur
.
y
-
track
->
m_Start
.
y
)
<
0
)
if
(
(
end
.
y
-
track
->
m_Start
.
y
)
<
0
)
iDy
=
-
iDy
;
track
->
m_End
.
x
=
track
->
m_Start
.
x
+
iDx
;
track
->
m_End
.
y
=
track
->
m_Start
.
y
+
iDy
;
break
;
case
90
:
if
(
(
ActiveScreen
->
m_Curseur
.
y
-
track
->
m_Start
.
y
)
<
0
)
track
->
m_End
.
y
=
ActiveScreen
->
m_Curseur
.
y
+
iDx
;
if
(
(
end
.
y
-
track
->
m_Start
.
y
)
<
0
)
track
->
m_End
.
y
=
end
.
y
+
iDx
;
else
track
->
m_End
.
y
=
ActiveScreen
->
m_Curseur
.
y
-
iDx
;
track
->
m_End
.
y
=
end
.
y
-
iDx
;
track
->
m_End
.
x
=
track
->
m_Start
.
x
;
break
;
}
...
...
@@ -711,10 +830,10 @@ void ComputeBreakPoint( TRACK* track, int SegmentCount )
if
(
track
)
{
if
(
track
->
IsNull
()
)
track
->
m_End
=
ActiveScreen
->
m_Curseur
;
track
->
m_End
=
end
;
NewTrack
->
m_Start
=
track
->
m_End
;
}
NewTrack
->
m_End
=
ActiveScreen
->
m_Curseur
;
NewTrack
->
m_End
=
end
;
}
...
...
pcbnew/locate.cpp
View file @
30932a46
...
...
@@ -111,6 +111,34 @@ TRACK* Locate_Via( BOARD* Pcb, const wxPoint& pos, int layer )
}
/*******************************************************************/
TRACK
*
Locate_Via_Area
(
BOARD
*
Pcb
,
const
wxPoint
&
pos
,
int
layer
)
/*******************************************************************/
/*
* Like Locate_Via, but finds any via covering the cursor position
*/
{
TRACK
*
Track
;
for
(
Track
=
Pcb
->
m_Track
;
Track
!=
NULL
;
Track
=
Track
->
Next
()
)
{
if
(
Track
->
Type
()
!=
TYPEVIA
)
continue
;
if
(
!
Track
->
HitTest
(
pos
))
continue
;
if
(
Track
->
GetState
(
BUSY
|
DELETED
)
)
continue
;
if
(
layer
<
0
)
return
Track
;
if
(
Track
->
IsOnLayer
(
layer
)
)
return
Track
;
}
return
NULL
;
}
/********************************************************************/
D_PAD
*
Locate_Pad_Connecte
(
BOARD
*
Pcb
,
TRACK
*
ptr_piste
,
int
extr
)
/********************************************************************/
...
...
pcbnew/protos.h
View file @
30932a46
This diff is collapsed.
Click to expand it.
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