Refactor PCBNew lock point and sorted pad list functions into board object.
This commit is contained in:
parent
1c4d925d1f
commit
5427a68a7b
|
@ -19,6 +19,19 @@ wxPoint BOARD_ITEM::ZeroOffset( 0, 0 );
|
||||||
BOARD_DESIGN_SETTINGS boardDesignSettings;
|
BOARD_DESIGN_SETTINGS boardDesignSettings;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function SortPadsByXCoord
|
||||||
|
* is used to Sort a pad list by x coordinate value.
|
||||||
|
*/
|
||||||
|
static int sortPadsByXCoord( const void* pt_ref, const void* pt_comp )
|
||||||
|
{
|
||||||
|
D_PAD* ref = *(LISTE_PAD*) pt_ref;
|
||||||
|
D_PAD* comp = *(LISTE_PAD*) pt_comp;
|
||||||
|
|
||||||
|
return ref->m_Pos.x - comp->m_Pos.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
BOARD::BOARD( EDA_ITEM* parent, PCB_BASE_FRAME* frame ) :
|
BOARD::BOARD( EDA_ITEM* parent, PCB_BASE_FRAME* frame ) :
|
||||||
BOARD_ITEM( (BOARD_ITEM*)parent, TYPE_PCB ),
|
BOARD_ITEM( (BOARD_ITEM*)parent, TYPE_PCB ),
|
||||||
m_NetClasses( this )
|
m_NetClasses( this )
|
||||||
|
@ -1744,6 +1757,15 @@ D_PAD* BOARD::GetPad( LISTE_PAD* aPad, const wxPoint& aPosition, int aLayerMask
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void BOARD::GetSortedPadListByXCoord( std::vector<D_PAD*>& aVector )
|
||||||
|
{
|
||||||
|
aVector.insert( aVector.end(), m_NetInfo->m_PadsFullList.begin(),
|
||||||
|
m_NetInfo->m_PadsFullList.end() );
|
||||||
|
|
||||||
|
qsort( &aVector[0], GetPadsCount(), sizeof( D_PAD*), sortPadsByXCoord );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
TRACK* BOARD::GetTrace( TRACK* aTrace, const wxPoint& aPosition, int aLayerMask )
|
TRACK* BOARD::GetTrace( TRACK* aTrace, const wxPoint& aPosition, int aLayerMask )
|
||||||
{
|
{
|
||||||
for( TRACK* track = aTrace; track; track = track->Next() )
|
for( TRACK* track = aTrace; track; track = track->Next() )
|
||||||
|
@ -2095,6 +2117,122 @@ MODULE* BOARD::GetFootprint( const wxPoint& aPosition, int aActiveLayer,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BOARD_ITEM* BOARD::GetLockPoint( const wxPoint& aPosition, int aLayerMask )
|
||||||
|
{
|
||||||
|
for( MODULE* module = m_Modules; module; module = module->Next() )
|
||||||
|
{
|
||||||
|
D_PAD* pad = module->GetPad( aPosition, aLayerMask );
|
||||||
|
|
||||||
|
if( pad )
|
||||||
|
return pad;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No pad has been located so check for a segment of the trace. */
|
||||||
|
TRACK* segment = ::GetTrace( m_Track, NULL, aPosition, aLayerMask );
|
||||||
|
|
||||||
|
if( segment == NULL )
|
||||||
|
segment = GetTrace( m_Track, aPosition, aLayerMask );
|
||||||
|
|
||||||
|
return segment;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TRACK* BOARD::CreateLockPoint( wxPoint& aPosition, TRACK* aSegment, PICKED_ITEMS_LIST* aList )
|
||||||
|
{
|
||||||
|
if( aSegment->m_Start == aPosition || aSegment->m_End == aPosition )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* A via is a good lock point */
|
||||||
|
if( aSegment->Type() == TYPE_VIA )
|
||||||
|
{
|
||||||
|
aPosition = aSegment->m_Start;
|
||||||
|
return aSegment;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculation coordinate of intermediate point relative to the start point of aSegment
|
||||||
|
wxPoint delta = aSegment->m_End - aSegment->m_Start;
|
||||||
|
|
||||||
|
// Not yet in use:
|
||||||
|
#if 0
|
||||||
|
int ox, oy, fx, fy;
|
||||||
|
|
||||||
|
if( aRefSegm )
|
||||||
|
{
|
||||||
|
ox = aRefSegm->m_Start.x - aSegment->m_Start.x;
|
||||||
|
oy = aRefSegm->m_Start.y - aSegment->m_Start.y;
|
||||||
|
fx = aRefSegm->m_End.x - aSegment->m_Start.x;
|
||||||
|
fy = aRefSegm->m_End.y - aSegment->m_Start.y;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// calculate coordinates of aPosition relative to aSegment->m_Start
|
||||||
|
wxPoint newPoint = aPosition - aSegment->m_Start;
|
||||||
|
|
||||||
|
// newPoint must be on aSegment:
|
||||||
|
// Ensure newPoint.y/newPoint.y = delta.y/delta.x
|
||||||
|
if( delta.x == 0 )
|
||||||
|
newPoint.x = 0; /* horizontal segment*/
|
||||||
|
else
|
||||||
|
newPoint.y = wxRound( ( (double)newPoint.x * delta.y ) / delta.x );
|
||||||
|
|
||||||
|
/* Create the intermediate point (that is to say creation of a new
|
||||||
|
* segment, beginning at the intermediate point.
|
||||||
|
*/
|
||||||
|
newPoint.x += aSegment->m_Start.x;
|
||||||
|
newPoint.y += aSegment->m_Start.y;
|
||||||
|
|
||||||
|
TRACK* newTrack = aSegment->Copy();
|
||||||
|
|
||||||
|
if( aList )
|
||||||
|
{
|
||||||
|
ITEM_PICKER picker( newTrack, UR_NEW );
|
||||||
|
aList->PushItem( picker );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DLIST<TRACK>* list = (DLIST<TRACK>*)aSegment->GetList();
|
||||||
|
wxASSERT( list );
|
||||||
|
list->Insert( newTrack, aSegment->Next() );
|
||||||
|
|
||||||
|
if( aList )
|
||||||
|
{
|
||||||
|
ITEM_PICKER picker( aSegment, UR_CHANGED );
|
||||||
|
picker.m_Link = aSegment->Copy();
|
||||||
|
aList->PushItem( picker );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Correct pointer at the end of the new segment. */
|
||||||
|
newTrack->end = aSegment->end;
|
||||||
|
newTrack->SetState( END_ONPAD, aSegment->GetState( END_ONPAD ) );
|
||||||
|
|
||||||
|
/* Set connections info relative to the new point
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Old segment now ends at new point. */
|
||||||
|
aSegment->m_End = newPoint;
|
||||||
|
aSegment->end = newTrack;
|
||||||
|
aSegment->SetState( END_ONPAD, OFF );
|
||||||
|
|
||||||
|
/* The new segment begins at the new point. */
|
||||||
|
newTrack->m_Start = newPoint;
|
||||||
|
newTrack->start = aSegment;
|
||||||
|
newTrack->SetState( BEGIN_ONPAD, OFF );
|
||||||
|
|
||||||
|
D_PAD * pad = GetPad( newTrack, START );
|
||||||
|
|
||||||
|
if ( pad )
|
||||||
|
{
|
||||||
|
newTrack->start = pad;
|
||||||
|
newTrack->SetState( BEGIN_ONPAD, ON );
|
||||||
|
aSegment->end = pad;
|
||||||
|
aSegment->SetState( END_ONPAD, ON );
|
||||||
|
}
|
||||||
|
|
||||||
|
aPosition = newPoint;
|
||||||
|
return newTrack;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#if defined(DEBUG)
|
#if defined(DEBUG)
|
||||||
|
|
||||||
void BOARD::Show( int nestLevel, std::ostream& os )
|
void BOARD::Show( int nestLevel, std::ostream& os )
|
||||||
|
|
|
@ -1157,6 +1157,17 @@ public:
|
||||||
*/
|
*/
|
||||||
D_PAD* GetPad( LISTE_PAD* aPad, const wxPoint& aPosition, int aLayerMask );
|
D_PAD* GetPad( LISTE_PAD* aPad, const wxPoint& aPosition, int aLayerMask );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function GetSortedPadListByXCoord
|
||||||
|
* first empties then fills the vector with all pads and sorts them by
|
||||||
|
* increasing x coordinate. The vector only holds pointers to the pads and
|
||||||
|
* those pointers are only references to pads which are owned by the BOARD
|
||||||
|
* through other links.
|
||||||
|
* @param aVector Where to put the pad pointers.
|
||||||
|
*/
|
||||||
|
void GetSortedPadListByXCoord( std::vector<D_PAD*>& aVector );
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function GetTrace
|
* Function GetTrace
|
||||||
* find the segment of \a aTrace at \a aPosition on \a aLayer if \a Layer is visible.
|
* find the segment of \a aTrace at \a aPosition on \a aLayer if \a Layer is visible.
|
||||||
|
@ -1205,7 +1216,7 @@ public:
|
||||||
* active layer is returned. The distance is calculated via manhattan distance from
|
* active layer is returned. The distance is calculated via manhattan distance from
|
||||||
* the center of the bounding rectangle to \a aPosition.
|
* the center of the bounding rectangle to \a aPosition.
|
||||||
*
|
*
|
||||||
* @param aPosition Flag bits, tuning the search, see pcbnew.h
|
* @param aPosition A wxPoint object containing the position to test.
|
||||||
* @param aActiveLayer Layer to test.
|
* @param aActiveLayer Layer to test.
|
||||||
* @param aVisibleOnly Search only the visible layers if true.
|
* @param aVisibleOnly Search only the visible layers if true.
|
||||||
* @param aIgnoreLocked Ignore locked modules when true.
|
* @param aIgnoreLocked Ignore locked modules when true.
|
||||||
|
@ -1213,6 +1224,40 @@ public:
|
||||||
*/
|
*/
|
||||||
MODULE* GetFootprint( const wxPoint& aPosition, int aActiveLayer,
|
MODULE* GetFootprint( const wxPoint& aPosition, int aActiveLayer,
|
||||||
bool aVisibleOnly, bool aIgnoreLocked = false );
|
bool aVisibleOnly, bool aIgnoreLocked = false );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function GetLockPoint
|
||||||
|
* returns the item at the "attachment" point at the end of a trace at \a aPosition
|
||||||
|
* on \a aLayerMask.
|
||||||
|
* <p>
|
||||||
|
* This may be a PAD or another trace segment.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param aPosition A wxPoint object containing the position to test.
|
||||||
|
* @param aLayerMask A layer or layers to mask the hit test. Use -1 to ignore
|
||||||
|
* layer mask.
|
||||||
|
* @return A pointer to a BOARD_ITEM object if found otherwise NULL.
|
||||||
|
*/
|
||||||
|
BOARD_ITEM* GetLockPoint( const wxPoint& aPosition, int aLayerMask );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function CreateLockPoint
|
||||||
|
* creates an intermediate point on \a aSegment and break it into two segments
|
||||||
|
* at \a aPoition.
|
||||||
|
* <p>
|
||||||
|
* The new segment starts from \a aPosition and ends at the end point of \a
|
||||||
|
* aSegement. The original segment now ends at \a aPosition.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param aPosition A wxPoint object containing the position to test and the new
|
||||||
|
* segment start position if the return value is not NULL.
|
||||||
|
* @param aSegment The trace segment to create the lock point on.
|
||||||
|
* @param aList The pick list to add the created items to.
|
||||||
|
* @return NULL if no new point was created or a pointer to a TRACK ojbect of the
|
||||||
|
* created segment. If \a aSegment points to a via the exact value of \a
|
||||||
|
* aPosition and a pointer to the via are returned.
|
||||||
|
*/
|
||||||
|
TRACK* CreateLockPoint( wxPoint& aPosition, TRACK* aSegment, PICKED_ITEMS_LIST* aList );
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // #ifndef CLASS_BOARD_H
|
#endif // #ifndef CLASS_BOARD_H
|
||||||
|
|
|
@ -469,27 +469,6 @@ static void Build_Pads_Info_Connections_By_Tracks( TRACK* pt_start_conn, TRACK*
|
||||||
|
|
||||||
#define POS_AFF_CHREF 62
|
#define POS_AFF_CHREF 62
|
||||||
|
|
||||||
/**
|
|
||||||
* Function SortPadsByXCoord
|
|
||||||
* is used to Sort a pad list by x coordinate value.
|
|
||||||
*/
|
|
||||||
static int SortPadsByXCoord( const void* pt_ref, const void* pt_comp )
|
|
||||||
{
|
|
||||||
D_PAD* ref = *(LISTE_PAD*) pt_ref;
|
|
||||||
D_PAD* comp = *(LISTE_PAD*) pt_comp;
|
|
||||||
|
|
||||||
return ref->m_Pos.x - comp->m_Pos.x;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void CreateSortedPadListByXCoord( BOARD* aBoard, std::vector<D_PAD*>* aVector )
|
|
||||||
{
|
|
||||||
aVector->insert( aVector->end(), aBoard->m_NetInfo->m_PadsFullList.begin(),
|
|
||||||
aBoard->m_NetInfo->m_PadsFullList.end() );
|
|
||||||
|
|
||||||
qsort( &(*aVector)[0], aBoard->GetPadsCount(), sizeof( D_PAD*), SortPadsByXCoord );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void PCB_BASE_FRAME::RecalculateAllTracksNetcode()
|
void PCB_BASE_FRAME::RecalculateAllTracksNetcode()
|
||||||
{
|
{
|
||||||
|
@ -523,7 +502,7 @@ void PCB_BASE_FRAME::RecalculateAllTracksNetcode()
|
||||||
/**************************************************************/
|
/**************************************************************/
|
||||||
/* Pass 1: search the connections between track ends and pads */
|
/* Pass 1: search the connections between track ends and pads */
|
||||||
/**************************************************************/
|
/**************************************************************/
|
||||||
CreateSortedPadListByXCoord( m_Pcb, &sortedPads );
|
m_Pcb->GetSortedPadListByXCoord( sortedPads );
|
||||||
|
|
||||||
/* Reset variables and flags used in computation */
|
/* Reset variables and flags used in computation */
|
||||||
pt_trace = m_Pcb->m_Track;
|
pt_trace = m_Pcb->m_Track;
|
||||||
|
|
|
@ -121,9 +121,7 @@ DRC::~DRC()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*********************************************/
|
|
||||||
int DRC::Drc( TRACK* aRefSegm, TRACK* aList )
|
int DRC::Drc( TRACK* aRefSegm, TRACK* aList )
|
||||||
/*********************************************/
|
|
||||||
{
|
{
|
||||||
updatePointers();
|
updatePointers();
|
||||||
|
|
||||||
|
@ -411,7 +409,7 @@ void DRC::testPad2Pad()
|
||||||
{
|
{
|
||||||
std::vector<D_PAD*> sortedPads;
|
std::vector<D_PAD*> sortedPads;
|
||||||
|
|
||||||
CreateSortedPadListByXCoord( m_pcb, &sortedPads );
|
m_pcb->GetSortedPadListByXCoord( sortedPads );
|
||||||
|
|
||||||
// find the max size of the pads (used to stop the test)
|
// find the max size of the pads (used to stop the test)
|
||||||
int max_size = 0;
|
int max_size = 0;
|
||||||
|
@ -420,7 +418,8 @@ void DRC::testPad2Pad()
|
||||||
{
|
{
|
||||||
D_PAD* pad = sortedPads[i];
|
D_PAD* pad = sortedPads[i];
|
||||||
|
|
||||||
if( pad->m_ShapeMaxRadius > max_size ) // m_ShapeMaxRadius is the radius value of the circle containing the pad
|
// m_ShapeMaxRadius is the radius value of the circle containing the pad
|
||||||
|
if( pad->m_ShapeMaxRadius > max_size )
|
||||||
max_size = pad->m_ShapeMaxRadius;
|
max_size = pad->m_ShapeMaxRadius;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -491,7 +490,7 @@ void DRC::testUnconnected()
|
||||||
|
|
||||||
void DRC::testZones( bool adoTestFillSegments )
|
void DRC::testZones( bool adoTestFillSegments )
|
||||||
{
|
{
|
||||||
// Test copper areas for valide netcodes
|
// Test copper areas for valid netcodes
|
||||||
// if a netcode is < 0 the netname was not found when reading a netlist
|
// if a netcode is < 0 the netname was not found when reading a netlist
|
||||||
// if a netcode is == 0 the netname is void, and the zone is not connected.
|
// if a netcode is == 0 the netname is void, and the zone is not connected.
|
||||||
// This is allowed, but i am not sure this is a good idea
|
// This is allowed, but i am not sure this is a good idea
|
||||||
|
@ -558,7 +557,7 @@ bool DRC::doPadToPadsDrc( D_PAD* aRefPad, LISTE_PAD* aStart, LISTE_PAD* aEnd, in
|
||||||
MODULE dummymodule( m_pcb ); // Creates a dummy parent
|
MODULE dummymodule( m_pcb ); // Creates a dummy parent
|
||||||
D_PAD dummypad( &dummymodule );
|
D_PAD dummypad( &dummymodule );
|
||||||
dummypad.m_layerMask |= ALL_CU_LAYERS; // Ensure the hole is on all copper layers
|
dummypad.m_layerMask |= ALL_CU_LAYERS; // Ensure the hole is on all copper layers
|
||||||
dummypad.m_LocalClearance = 1; /* Use the minimal local clerance value for the dummy pad
|
dummypad.m_LocalClearance = 1; /* Use the minimal local clearance value for the dummy pad
|
||||||
* the clearance of the active pad will be used
|
* the clearance of the active pad will be used
|
||||||
* as minimum distance to a hole
|
* as minimum distance to a hole
|
||||||
* (a value = 0 means use netclass value)
|
* (a value = 0 means use netclass value)
|
||||||
|
@ -577,7 +576,7 @@ bool DRC::doPadToPadsDrc( D_PAD* aRefPad, LISTE_PAD* aStart, LISTE_PAD* aEnd, in
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// No problem if pads are on different copper layers,
|
// No problem if pads are on different copper layers,
|
||||||
// but their hole (if any ) can create RDC error because they are on all
|
// but their hole (if any ) can create DRC error because they are on all
|
||||||
// copper layers, so we test them
|
// copper layers, so we test them
|
||||||
if( (pad->m_layerMask & layerMask ) == 0 )
|
if( (pad->m_layerMask & layerMask ) == 0 )
|
||||||
{
|
{
|
||||||
|
@ -590,20 +589,24 @@ bool DRC::doPadToPadsDrc( D_PAD* aRefPad, LISTE_PAD* aStart, LISTE_PAD* aEnd, in
|
||||||
if( aRefPad->m_DrillShape == PAD_CIRCLE )
|
if( aRefPad->m_DrillShape == PAD_CIRCLE )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if( pad->m_Orient == aRefPad->m_Orient ) // for oval holes: must also have the same orientation
|
// for oval holes: must also have the same orientation
|
||||||
|
if( pad->m_Orient == aRefPad->m_Orient )
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Here, we must test clearance between holes and pads
|
/* Here, we must test clearance between holes and pads
|
||||||
* dummy pad size and shape is adjusted to pad drill size and shape
|
* dummy pad size and shape is adjusted to pad drill size and shape
|
||||||
*/
|
*/
|
||||||
if( pad->m_Drill.x ) // pad under testing has a hole, test this hole against pad reference
|
if( pad->m_Drill.x )
|
||||||
{
|
{
|
||||||
|
// pad under testing has a hole, test this hole against pad reference
|
||||||
dummypad.SetPosition( pad->GetPosition() );
|
dummypad.SetPosition( pad->GetPosition() );
|
||||||
dummypad.m_Size = pad->m_Drill;
|
dummypad.m_Size = pad->m_Drill;
|
||||||
dummypad.m_PadShape = (pad->m_DrillShape == PAD_OVAL) ? PAD_OVAL : PAD_CIRCLE;
|
dummypad.m_PadShape = (pad->m_DrillShape == PAD_OVAL) ? PAD_OVAL : PAD_CIRCLE;
|
||||||
dummypad.m_Orient = pad->m_Orient;
|
dummypad.m_Orient = pad->m_Orient;
|
||||||
dummypad.ComputeShapeMaxRadius(); // compute the radius of the circle containing this pad
|
|
||||||
|
// compute the radius of the circle containing this pad
|
||||||
|
dummypad.ComputeShapeMaxRadius();
|
||||||
|
|
||||||
if( !checkClearancePadToPad( aRefPad, &dummypad ) )
|
if( !checkClearancePadToPad( aRefPad, &dummypad ) )
|
||||||
{
|
{
|
||||||
|
@ -620,7 +623,10 @@ bool DRC::doPadToPadsDrc( D_PAD* aRefPad, LISTE_PAD* aStart, LISTE_PAD* aEnd, in
|
||||||
dummypad.m_Size = aRefPad->m_Drill;
|
dummypad.m_Size = aRefPad->m_Drill;
|
||||||
dummypad.m_PadShape = (aRefPad->m_DrillShape == PAD_OVAL) ? PAD_OVAL : PAD_CIRCLE;
|
dummypad.m_PadShape = (aRefPad->m_DrillShape == PAD_OVAL) ? PAD_OVAL : PAD_CIRCLE;
|
||||||
dummypad.m_Orient = aRefPad->m_Orient;
|
dummypad.m_Orient = aRefPad->m_Orient;
|
||||||
dummypad.ComputeShapeMaxRadius(); // compute the radius of the circle containing this pad
|
|
||||||
|
// compute the radius of the circle containing this pad
|
||||||
|
dummypad.ComputeShapeMaxRadius();
|
||||||
|
|
||||||
if( !checkClearancePadToPad( pad, &dummypad ) )
|
if( !checkClearancePadToPad( pad, &dummypad ) )
|
||||||
{
|
{
|
||||||
// here we have a drc error on aRefPad!
|
// here we have a drc error on aRefPad!
|
||||||
|
|
|
@ -1001,7 +1001,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
|
||||||
wxPoint pos = GetScreen()->GetCrossHairPosition();
|
wxPoint pos = GetScreen()->GetCrossHairPosition();
|
||||||
track->Draw( DrawPanel, &dc, GR_XOR );
|
track->Draw( DrawPanel, &dc, GR_XOR );
|
||||||
PICKED_ITEMS_LIST itemsListPicker;
|
PICKED_ITEMS_LIST itemsListPicker;
|
||||||
TRACK* newtrack = CreateLockPoint( GetBoard(), pos, track, &itemsListPicker );
|
TRACK* newtrack = GetBoard()->CreateLockPoint( pos, track, &itemsListPicker );
|
||||||
SaveCopyInUndoList( itemsListPicker, UR_UNSPECIFIED );
|
SaveCopyInUndoList( itemsListPicker, UR_UNSPECIFIED );
|
||||||
track->Draw( DrawPanel, &dc, GR_XOR );
|
track->Draw( DrawPanel, &dc, GR_XOR );
|
||||||
newtrack->Draw( DrawPanel, &dc, GR_XOR );
|
newtrack->Draw( DrawPanel, &dc, GR_XOR );
|
||||||
|
|
|
@ -89,7 +89,7 @@ TRACK* PCB_EDIT_FRAME::Begin_Route( TRACK* aTrack, wxDC* aDC )
|
||||||
GetBoard()->SetHighLightNet( 0 );
|
GetBoard()->SetHighLightNet( 0 );
|
||||||
|
|
||||||
// Search for a starting point of the new track, a track or pad
|
// Search for a starting point of the new track, a track or pad
|
||||||
LockPoint = LocateLockPoint( GetBoard(), pos, layerMask );
|
LockPoint = GetBoard()->GetLockPoint( pos, layerMask );
|
||||||
|
|
||||||
if( LockPoint ) // An item (pad or track) is found
|
if( LockPoint ) // An item (pad or track) is found
|
||||||
{
|
{
|
||||||
|
@ -105,7 +105,7 @@ TRACK* PCB_EDIT_FRAME::Begin_Route( TRACK* aTrack, wxDC* aDC )
|
||||||
{
|
{
|
||||||
TrackOnStartPoint = (TRACK*) LockPoint;
|
TrackOnStartPoint = (TRACK*) LockPoint;
|
||||||
GetBoard()->SetHighLightNet( TrackOnStartPoint->GetNet() );
|
GetBoard()->SetHighLightNet( TrackOnStartPoint->GetNet() );
|
||||||
CreateLockPoint( GetBoard(), pos, TrackOnStartPoint, &s_ItemsListPicker );
|
GetBoard()->CreateLockPoint( pos, TrackOnStartPoint, &s_ItemsListPicker );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -420,7 +420,7 @@ bool PCB_EDIT_FRAME::End_Route( TRACK* aTrack, wxDC* aDC )
|
||||||
* This helps to reduce the computing time */
|
* This helps to reduce the computing time */
|
||||||
|
|
||||||
/* Attaching the end of the track. */
|
/* Attaching the end of the track. */
|
||||||
BOARD_ITEM* LockPoint = LocateLockPoint( GetBoard(), pos, layerMask );
|
BOARD_ITEM* LockPoint = GetBoard()->GetLockPoint( pos, layerMask );
|
||||||
|
|
||||||
if( LockPoint ) /* End of trace is on a pad. */
|
if( LockPoint ) /* End of trace is on a pad. */
|
||||||
{
|
{
|
||||||
|
@ -434,8 +434,7 @@ bool PCB_EDIT_FRAME::End_Route( TRACK* aTrack, wxDC* aDC )
|
||||||
GetBoard()->SetHighLightNet( adr_buf->GetNet() );
|
GetBoard()->SetHighLightNet( adr_buf->GetNet() );
|
||||||
|
|
||||||
/* Possible establishment of a hanging point. */
|
/* Possible establishment of a hanging point. */
|
||||||
LockPoint = CreateLockPoint( GetBoard(),
|
LockPoint = GetBoard()->CreateLockPoint( g_CurrentTrackSegment->m_End,
|
||||||
g_CurrentTrackSegment->m_End,
|
|
||||||
adr_buf,
|
adr_buf,
|
||||||
&s_ItemsListPicker );
|
&s_ItemsListPicker );
|
||||||
}
|
}
|
||||||
|
|
|
@ -1038,148 +1038,3 @@ bool PCB_EDIT_FRAME::PlaceDraggedOrMovedTrackSegment( TRACK* Track, wxDC* DC )
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Find the point "attachment" of the end of a trace.
|
|
||||||
* This may be a TBP or another segment of the trace
|
|
||||||
* Returns:
|
|
||||||
* - Pointer to the PAD or:
|
|
||||||
* - Pointer to the segment or:
|
|
||||||
* - NULL
|
|
||||||
* Parameters:
|
|
||||||
* - position to test
|
|
||||||
* - mask layers to be tested
|
|
||||||
*/
|
|
||||||
BOARD_ITEM* LocateLockPoint( BOARD* Pcb, wxPoint pos, int LayerMask )
|
|
||||||
{
|
|
||||||
for( MODULE* module = Pcb->m_Modules; module; module = module->Next() )
|
|
||||||
{
|
|
||||||
D_PAD* pad = module->GetPad( pos, LayerMask );
|
|
||||||
|
|
||||||
if( pad )
|
|
||||||
return pad;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* No pad has been located so check for a segment of the trace. */
|
|
||||||
TRACK* ptsegm = GetTrace( Pcb->m_Track, NULL, pos, LayerMask );
|
|
||||||
|
|
||||||
if( ptsegm == NULL )
|
|
||||||
ptsegm = Pcb->GetTrace( Pcb->m_Track, pos, LayerMask );
|
|
||||||
|
|
||||||
return ptsegm;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Create an intermediate point on a segment
|
|
||||||
* aSegm segment is broken into 2 segments connecting point pX, pY
|
|
||||||
* After insertion:
|
|
||||||
* The new segment starts from to new point, and ends to initial aSegm ending point
|
|
||||||
* the old segment aSegm ends to new point
|
|
||||||
* Returns:
|
|
||||||
* NULL if no new point (ie if aRefPoint already corresponded at one end of aSegm
|
|
||||||
* or
|
|
||||||
* Pointer to the segment created
|
|
||||||
* Returns the exact value of aRefPoint
|
|
||||||
* If aSegm points to a via:
|
|
||||||
* Returns the exact value of aRefPoint and a pointer to the via,
|
|
||||||
* But does not create extra point
|
|
||||||
*/
|
|
||||||
TRACK* CreateLockPoint( BOARD* aPcb,
|
|
||||||
wxPoint& aRefPoint,
|
|
||||||
TRACK* aSegm,
|
|
||||||
PICKED_ITEMS_LIST* aItemsListPicker )
|
|
||||||
{
|
|
||||||
if( aSegm->m_Start == aRefPoint || aSegm->m_End == aRefPoint )
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* A via is a good lock point */
|
|
||||||
if( aSegm->Type() == TYPE_VIA )
|
|
||||||
{
|
|
||||||
aRefPoint = aSegm->m_Start;
|
|
||||||
return aSegm;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Calculation coordinate of intermediate point relative to
|
|
||||||
* the start point of aSegm
|
|
||||||
*/
|
|
||||||
wxPoint delta = aSegm->m_End - aSegm->m_Start;
|
|
||||||
|
|
||||||
// Not yet in use:
|
|
||||||
#if 0
|
|
||||||
int ox, oy, fx, fy;
|
|
||||||
|
|
||||||
if( aRefSegm )
|
|
||||||
{
|
|
||||||
ox = aRefSegm->m_Start.x - aSegm->m_Start.x;
|
|
||||||
oy = aRefSegm->m_Start.y - aSegm->m_Start.y;
|
|
||||||
fx = aRefSegm->m_End.x - aSegm->m_Start.x;
|
|
||||||
fy = aRefSegm->m_End.y - aSegm->m_Start.y;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// calculate coordinates of aRefPoint relative to aSegm->m_Start
|
|
||||||
wxPoint newPoint = aRefPoint - aSegm->m_Start;
|
|
||||||
|
|
||||||
// newPoint must be on aSegm:
|
|
||||||
// Ensure newPoint.y/newPoint.y = delta.y/delta.x
|
|
||||||
if( delta.x == 0 )
|
|
||||||
newPoint.x = 0; /* horizontal segment*/
|
|
||||||
else
|
|
||||||
newPoint.y = wxRound(( (double)newPoint.x * delta.y ) / delta.x);
|
|
||||||
|
|
||||||
/* Create the intermediate point (that is to say creation of a new
|
|
||||||
* segment, beginning at the intermediate point.
|
|
||||||
*/
|
|
||||||
newPoint.x += aSegm->m_Start.x;
|
|
||||||
newPoint.y += aSegm->m_Start.y;
|
|
||||||
|
|
||||||
TRACK* newTrack = aSegm->Copy();
|
|
||||||
|
|
||||||
if( aItemsListPicker )
|
|
||||||
{
|
|
||||||
ITEM_PICKER picker( newTrack, UR_NEW );
|
|
||||||
aItemsListPicker->PushItem( picker );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DLIST<TRACK>* list = (DLIST<TRACK>*)aSegm->GetList();
|
|
||||||
wxASSERT( list );
|
|
||||||
list->Insert( newTrack, aSegm->Next() );
|
|
||||||
|
|
||||||
if( aItemsListPicker )
|
|
||||||
{
|
|
||||||
ITEM_PICKER picker( aSegm, UR_CHANGED );
|
|
||||||
picker.m_Link = aSegm->Copy();
|
|
||||||
aItemsListPicker->PushItem( picker );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Correct pointer at the end of the new segment. */
|
|
||||||
newTrack->end = aSegm->end;
|
|
||||||
newTrack->SetState( END_ONPAD, aSegm->GetState( END_ONPAD ) );
|
|
||||||
|
|
||||||
/* Set connections info relative to the new point
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Old segment now ends at new point. */
|
|
||||||
aSegm->m_End = newPoint;
|
|
||||||
aSegm->end = newTrack;
|
|
||||||
aSegm->SetState( END_ONPAD, OFF );
|
|
||||||
|
|
||||||
/* The new segment begins at the new point. */
|
|
||||||
newTrack->m_Start = newPoint;
|
|
||||||
newTrack->start = aSegm;
|
|
||||||
newTrack->SetState( BEGIN_ONPAD, OFF );
|
|
||||||
|
|
||||||
D_PAD * pad = aPcb->GetPad( newTrack, START );
|
|
||||||
|
|
||||||
if ( pad )
|
|
||||||
{
|
|
||||||
newTrack->start = pad;
|
|
||||||
newTrack->SetState( BEGIN_ONPAD, ON );
|
|
||||||
aSegm->end = pad;
|
|
||||||
aSegm->SetState( END_ONPAD, ON );
|
|
||||||
}
|
|
||||||
|
|
||||||
aRefPoint = newPoint;
|
|
||||||
return newTrack;
|
|
||||||
}
|
|
||||||
|
|
|
@ -28,17 +28,6 @@ void SwapData( BOARD_ITEM* aItem, BOARD_ITEM* aImage );
|
||||||
|
|
||||||
class D_PAD;
|
class D_PAD;
|
||||||
|
|
||||||
/**
|
|
||||||
* Function CreateSortedPadListByXCoord
|
|
||||||
* first empties then fills the vector with all pads and sorts them by
|
|
||||||
* increasing x coordinate. The vector only holds pointers to the pads and
|
|
||||||
* those pointers are only references to pads which are owned by the BOARD
|
|
||||||
* through other links.
|
|
||||||
* @param aBoard Which board to gather pads from.
|
|
||||||
* @param aVector Where to put the pad pointers.
|
|
||||||
*/
|
|
||||||
void CreateSortedPadListByXCoord( BOARD* aBoard, std::vector<D_PAD*>* aVector );
|
|
||||||
|
|
||||||
|
|
||||||
/***************/
|
/***************/
|
||||||
/* TRPISTE.CPP */
|
/* TRPISTE.CPP */
|
||||||
|
@ -84,38 +73,6 @@ void ShowNewTrackWhenMovingCursor( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPo
|
||||||
void CalculateSegmentEndPoint( const wxPoint& aPosition, int ox, int oy, int* fx, int* fy );
|
void CalculateSegmentEndPoint( const wxPoint& aPosition, int ox, int oy, int* fx, int* fy );
|
||||||
|
|
||||||
|
|
||||||
/* Routine to find the point "attachment" at the end of a trace.
|
|
||||||
* This may be a PAD or another trace segment.
|
|
||||||
* Returns:
|
|
||||||
* - Pointer to the PAD or:
|
|
||||||
* - Pointer to the segment or:
|
|
||||||
* - NULL
|
|
||||||
* Parameters:
|
|
||||||
* - aPos - coordinate point test
|
|
||||||
* ALayerMask of mask layers to be tested
|
|
||||||
*/
|
|
||||||
BOARD_ITEM* LocateLockPoint( BOARD* aPcb, wxPoint aPos, int aLayerMask );
|
|
||||||
|
|
||||||
/* Create an intermediate point on a segment
|
|
||||||
* aSegm segment is broken into 2 segments connecting point pX, pY
|
|
||||||
* After insertion:
|
|
||||||
* The new segment starts from to new point, and ends to initial aSegm ending point
|
|
||||||
* the old segment aSegm ends to new point
|
|
||||||
* Returns:
|
|
||||||
* NULL if no new point (ie if aRefPoint already corresponded at one end of aSegm
|
|
||||||
* or
|
|
||||||
* Pointer to the segment created
|
|
||||||
* Returns the exact value of aRefPoint
|
|
||||||
* If aSegm points to a via:
|
|
||||||
* Returns the exact value of aRefPoint and a pointer to the via,
|
|
||||||
* But does not create extra point
|
|
||||||
*/
|
|
||||||
TRACK* CreateLockPoint( BOARD* aPcb,
|
|
||||||
wxPoint& aRefPoint,
|
|
||||||
TRACK* aSegm,
|
|
||||||
PICKED_ITEMS_LIST* aItemsListPicker );
|
|
||||||
|
|
||||||
|
|
||||||
/****************/
|
/****************/
|
||||||
/* CONTROLE.CPP */
|
/* CONTROLE.CPP */
|
||||||
/****************/
|
/****************/
|
||||||
|
|
Loading…
Reference in New Issue