2007-06-05 12:10:51 +00:00
|
|
|
/******************************************************/
|
|
|
|
/* Routines de localisation d'un element d'un schema. */
|
|
|
|
/******************************************************/
|
|
|
|
|
|
|
|
#include "fctsys.h"
|
|
|
|
#include "gr_basic.h"
|
|
|
|
|
|
|
|
#include "common.h"
|
|
|
|
#include "program.h"
|
|
|
|
#include "libcmp.h"
|
|
|
|
#include "general.h"
|
|
|
|
#include "trigo.h"
|
|
|
|
#include "macros.h"
|
|
|
|
|
|
|
|
#include "protos.h"
|
|
|
|
|
|
|
|
/* Routines exportees */
|
|
|
|
int distance(int dx, int dy, int spot_cX, int spot_cY, int seuil);
|
|
|
|
|
|
|
|
/* Routines Locales */
|
|
|
|
static EDA_BaseStruct *LastSnappedStruct = NULL;
|
|
|
|
static int PickedBoxMinX, PickedBoxMinY, PickedBoxMaxX, PickedBoxMaxY ;
|
|
|
|
static bool IsBox1InBox2( int StartX1, int StartY1, int EndX1, int EndY1,
|
|
|
|
int StartX2, int StartY2, int EndX2, int EndY2 );
|
|
|
|
static bool IsPointInBox( int pX, int pY,
|
|
|
|
int BoxX1, int BoxY1, int BoxX2, int BoxY2 );
|
|
|
|
static bool IsPointOnSegment( int pX, int pY,
|
|
|
|
int SegmX1, int SegmY1, int SegmX2, int SegmY2, int seuil = 0);
|
|
|
|
static bool SnapPoint2(const wxPoint & PosRef, int SearchMask,
|
|
|
|
EDA_BaseStruct *DrawList, DrawPickedStruct *DontSnapList, int zoom_value);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*********************************************************************/
|
|
|
|
EDA_SchComponentStruct * LocateSmallestComponent( SCH_SCREEN * Screen )
|
|
|
|
/*********************************************************************/
|
|
|
|
/* Search the smaller (considering its area) component under the mouse cursor or the pcb cursor
|
|
|
|
If more than 1 component is found, a pointer to the smaller component is returned
|
|
|
|
*/
|
|
|
|
{
|
|
|
|
EDA_SchComponentStruct * DrawLibItem = NULL, * LastDrawLibItem = NULL;
|
|
|
|
EDA_BaseStruct *DrawList;
|
|
|
|
EDA_Rect BoundaryBox;
|
|
|
|
float sizeref = 0, sizecurr;
|
|
|
|
|
|
|
|
DrawList = Screen->EEDrawList;
|
|
|
|
|
|
|
|
while ( DrawList )
|
|
|
|
{
|
|
|
|
if( ( SnapPoint2(Screen->m_MousePosition, LIBITEM,
|
|
|
|
DrawList,NULL, Screen->GetZoom())) == FALSE )
|
|
|
|
{
|
|
|
|
if( ( SnapPoint2(Screen->m_Curseur, LIBITEM,
|
|
|
|
DrawList,NULL, Screen->GetZoom())) == FALSE ) break;
|
|
|
|
}
|
|
|
|
DrawLibItem = (EDA_SchComponentStruct *) LastSnappedStruct;
|
|
|
|
DrawList = DrawLibItem->Pnext;
|
|
|
|
if ( LastDrawLibItem == NULL ) // First time a component is located
|
|
|
|
{
|
|
|
|
LastDrawLibItem = DrawLibItem;
|
|
|
|
BoundaryBox = LastDrawLibItem->GetBoundaryBox();
|
|
|
|
sizeref = ABS((float)BoundaryBox.GetWidth() * BoundaryBox.GetHeight());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
BoundaryBox = DrawLibItem->GetBoundaryBox();
|
|
|
|
sizecurr = ABS((float)BoundaryBox.GetWidth() * BoundaryBox.GetHeight());
|
|
|
|
if ( sizeref > sizecurr ) // a smallest component is found
|
|
|
|
{
|
|
|
|
sizeref = sizecurr;
|
|
|
|
LastDrawLibItem = DrawLibItem;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return LastDrawLibItem;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* SearchMask = (bitwise OR):
|
|
|
|
LIBITEM
|
|
|
|
WIREITEM
|
|
|
|
BUSITEM
|
|
|
|
RACCORDITEM
|
|
|
|
JUNCTIONITEM
|
|
|
|
DRAWITEM
|
|
|
|
TEXTITEM
|
|
|
|
LABELITEM
|
|
|
|
SHEETITEM
|
|
|
|
MARKERITEM
|
|
|
|
NOCONNECTITEM
|
|
|
|
SEARCH_PINITEM
|
|
|
|
SHEETLABELITEM
|
|
|
|
FIELDCMPITEM
|
|
|
|
|
|
|
|
if EXCLUDE_WIRE_BUS_ENDPOINTS is set, in wire ou bus search and locate,
|
|
|
|
start and end points are not included in search
|
|
|
|
if WIRE_BUS_ENDPOINTS_ONLY is set, in wire ou bus search and locate,
|
|
|
|
only start and end points are included in search
|
|
|
|
|
|
|
|
|
|
|
|
Return:
|
|
|
|
-Bloc search:
|
|
|
|
pointeur sur liste de pointeurs de structures si Plusieurs
|
|
|
|
structures selectionnees.
|
|
|
|
pointeur sur la structure si 1 seule
|
|
|
|
|
|
|
|
Positon serach:
|
|
|
|
pointeur sur la structure.
|
|
|
|
Si pas de structures selectionnees: retourne NULL
|
|
|
|
|
|
|
|
*/
|
|
|
|
/***********************************************************************/
|
|
|
|
EDA_BaseStruct * PickStruct(const wxPoint & refpos,
|
|
|
|
EDA_BaseStruct *DrawList, int SearchMask )
|
|
|
|
/************************************************************************/
|
|
|
|
/* Search an item at pos pos
|
|
|
|
*/
|
|
|
|
{
|
|
|
|
bool Snapped;
|
|
|
|
int zoom = ActiveScreen->GetZoom();
|
|
|
|
if ( DrawList == NULL ) return NULL;
|
|
|
|
|
|
|
|
if( (Snapped = SnapPoint2(refpos, SearchMask,
|
|
|
|
DrawList,NULL, zoom)) != FALSE)
|
|
|
|
{
|
|
|
|
return( LastSnappedStruct);
|
|
|
|
}
|
|
|
|
return( NULL );
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************/
|
|
|
|
EDA_BaseStruct * PickStruct( EDA_Rect & block,
|
|
|
|
EDA_BaseStruct *DrawList, int SearchMask )
|
|
|
|
/************************************************************************/
|
|
|
|
/* Search items in block
|
|
|
|
*/
|
|
|
|
{
|
|
|
|
int x, y, OrigX, OrigY;
|
|
|
|
DrawPickedStruct *PickedList = NULL, *PickedItem;
|
|
|
|
EDA_BaseStruct *DrawStruct;
|
|
|
|
|
|
|
|
OrigX = block.GetX();
|
|
|
|
OrigY = block.GetY();
|
|
|
|
x = block.GetRight();
|
|
|
|
y = block.GetBottom();
|
|
|
|
|
|
|
|
if (x < OrigX) EXCHG(x, OrigX);
|
|
|
|
if (y < OrigY) EXCHG(y, OrigY);
|
|
|
|
|
|
|
|
for (DrawStruct = DrawList; DrawStruct != NULL; DrawStruct = DrawStruct->Pnext)
|
|
|
|
{
|
|
|
|
if( DrawStructInBox(OrigX, OrigY, x, y, DrawStruct) )
|
|
|
|
{
|
|
|
|
/* Put this structure in the picked list: */
|
|
|
|
PickedItem = new DrawPickedStruct(DrawStruct);
|
|
|
|
PickedItem->Pnext = PickedList;
|
|
|
|
PickedList = PickedItem;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (PickedList && PickedList->Pnext == NULL)
|
|
|
|
{
|
|
|
|
/* Only one item was picked - convert to scalar form (no list): */
|
|
|
|
PickedItem = PickedList;
|
|
|
|
PickedList = (DrawPickedStruct *) PickedList->m_PickedStruct;
|
|
|
|
delete PickedItem;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (PickedList != NULL)
|
|
|
|
{
|
|
|
|
PickedBoxMinX = OrigX; PickedBoxMinY = OrigY;
|
|
|
|
PickedBoxMaxX = x; PickedBoxMaxY = y;
|
|
|
|
}
|
|
|
|
|
|
|
|
return PickedList;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
* Routine to search all objects for the closest point to a given point, in *
|
|
|
|
* drawing space, and snap it to that points if closer than SnapDistance. *
|
|
|
|
* Note we use L1 norm as distance measure, as it is the fastest. *
|
|
|
|
* This routine updates LastSnappedStruct to the last object used in to snap *
|
|
|
|
* a point. This variable is global to this module only (see above). *
|
|
|
|
* If DontSnapList is not NULL, structes in this list are skipped. *
|
|
|
|
* The routine returns TRUE if point was snapped. *
|
|
|
|
*****************************************************************************/
|
|
|
|
bool SnapPoint2(const wxPoint & PosRef, int SearchMask,
|
|
|
|
EDA_BaseStruct *DrawList, DrawPickedStruct *DontSnapList, int zoom_value)
|
|
|
|
{
|
|
|
|
int i, *Points, x = PosRef.x, y = PosRef.y;
|
|
|
|
int x1, y1, x2, y2, NumOfPoints2;
|
|
|
|
DrawPickedStruct *DontSnap;
|
|
|
|
int dx, dy;
|
|
|
|
|
|
|
|
for (; DrawList != NULL; DrawList = DrawList->Pnext)
|
|
|
|
{
|
|
|
|
/* Make sure this structure is NOT in the dont snap list: */
|
|
|
|
DontSnap = DontSnapList;
|
|
|
|
for( ; DontSnap != NULL; DontSnap = (DrawPickedStruct *)DontSnap->Pnext)
|
|
|
|
if (DontSnap->m_PickedStruct == DrawList) break;
|
|
|
|
|
|
|
|
if(DontSnap) if (DontSnap->m_PickedStruct == DrawList) continue;
|
|
|
|
|
|
|
|
switch (DrawList->m_StructType)
|
|
|
|
{
|
|
|
|
case DRAW_POLYLINE_STRUCT_TYPE:
|
|
|
|
#undef STRUCT
|
|
|
|
#define STRUCT ((DrawPolylineStruct *) DrawList)
|
|
|
|
if( !(SearchMask & (DRAWITEM|WIREITEM|BUSITEM)) ) break;
|
|
|
|
Points = STRUCT->m_Points;
|
|
|
|
NumOfPoints2 = STRUCT->m_NumOfPoints * 2;
|
|
|
|
for (i = 0; i < NumOfPoints2 - 2; i += 2)
|
|
|
|
{
|
|
|
|
x1 = Points[i]; y1 = Points[i+1];
|
|
|
|
x2 = Points[i+2]; y2 = Points[i+3];
|
|
|
|
if (IsPointOnSegment(x,y, x1, y1, x2, y2) )
|
|
|
|
{
|
|
|
|
LastSnappedStruct = DrawList;
|
|
|
|
return(TRUE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DRAW_SEGMENT_STRUCT_TYPE:
|
|
|
|
#undef STRUCT
|
|
|
|
#define STRUCT ((EDA_DrawLineStruct *) DrawList)
|
|
|
|
if( !(SearchMask & (DRAWITEM|WIREITEM|BUSITEM)) ) break;
|
|
|
|
|
|
|
|
if (IsPointOnSegment(x,y, STRUCT->m_Start.x,STRUCT->m_Start.y ,
|
|
|
|
STRUCT->m_End.x, STRUCT->m_End.y) )
|
|
|
|
{
|
|
|
|
if( ((SearchMask & DRAWITEM) && (STRUCT->m_Layer == LAYER_NOTES)) ||
|
|
|
|
((SearchMask & WIREITEM) && (STRUCT->m_Layer == LAYER_WIRE)) ||
|
|
|
|
((SearchMask & BUSITEM) && (STRUCT->m_Layer == LAYER_BUS))
|
|
|
|
)
|
|
|
|
{
|
|
|
|
if (SearchMask & EXCLUDE_WIRE_BUS_ENDPOINTS)
|
|
|
|
{
|
|
|
|
if ( x == STRUCT->m_Start.x && y == STRUCT->m_Start.y )
|
|
|
|
break;
|
|
|
|
if ( x == STRUCT->m_End.x && y == STRUCT->m_End.y )
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (SearchMask & WIRE_BUS_ENDPOINTS_ONLY)
|
|
|
|
{
|
|
|
|
if ( ! STRUCT->IsOneEndPointAt(wxPoint(x, y)) ) break;
|
|
|
|
}
|
|
|
|
|
|
|
|
LastSnappedStruct = DrawList;
|
|
|
|
return(TRUE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case DRAW_BUSENTRY_STRUCT_TYPE:
|
|
|
|
#undef STRUCT
|
|
|
|
#define STRUCT ((DrawBusEntryStruct *) DrawList)
|
|
|
|
if( !(SearchMask & (RACCORDITEM)) ) break;
|
|
|
|
|
|
|
|
if (IsPointOnSegment(x,y, STRUCT->m_Pos.x,STRUCT->m_Pos.y,
|
|
|
|
STRUCT->m_End().x, STRUCT->m_End().y) )
|
|
|
|
{
|
|
|
|
LastSnappedStruct = DrawList;
|
|
|
|
return(TRUE);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DRAW_JUNCTION_STRUCT_TYPE:
|
|
|
|
#undef STRUCT
|
|
|
|
#define STRUCT ((DrawJunctionStruct *) DrawList)
|
|
|
|
if( !(SearchMask & JUNCTIONITEM) )break;
|
|
|
|
dx = DRAWJUNCTION_SIZE / 2;
|
|
|
|
x1 = STRUCT->m_Pos.x - dx;
|
|
|
|
y1 = STRUCT->m_Pos.y - dx;
|
|
|
|
x2 = STRUCT->m_Pos.x + dx;
|
|
|
|
y2 = STRUCT->m_Pos.y + dx;
|
|
|
|
if(IsPointInBox(x, y, x1,y1, x2,y2) )
|
|
|
|
{
|
|
|
|
LastSnappedStruct = DrawList;
|
|
|
|
return(TRUE);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case DRAW_NOCONNECT_STRUCT_TYPE:
|
|
|
|
#undef STRUCT
|
|
|
|
#define STRUCT ((DrawNoConnectStruct *) DrawList)
|
|
|
|
if( !(SearchMask & NOCONNECTITEM) )break;
|
|
|
|
dx = (DRAWNOCONNECT_SIZE*zoom_value) / 2;
|
|
|
|
x1 = STRUCT->m_Pos.x - dx;
|
|
|
|
y1 = STRUCT->m_Pos.y - dx;
|
|
|
|
x2 = STRUCT->m_Pos.x + dx;
|
|
|
|
y2 = STRUCT->m_Pos.y + dx;
|
|
|
|
if(IsPointInBox(x, y, x1,y1, x2,y2) )
|
|
|
|
{
|
|
|
|
LastSnappedStruct = DrawList;
|
|
|
|
return(TRUE);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DRAW_MARKER_STRUCT_TYPE:
|
|
|
|
#undef STRUCT
|
|
|
|
#define STRUCT ((DrawMarkerStruct *) DrawList)
|
|
|
|
if( !(SearchMask & MARKERITEM) )break;
|
|
|
|
dx = (DRAWMARKER_SIZE*zoom_value) / 2;
|
|
|
|
x1 = STRUCT->m_Pos.x - dx;
|
|
|
|
y1 = STRUCT->m_Pos.y - dx;
|
|
|
|
x2 = STRUCT->m_Pos.x + dx;
|
|
|
|
y2 = STRUCT->m_Pos.y + dx;
|
|
|
|
if(IsPointInBox(x, y, x1,y1, x2,y2) )
|
|
|
|
{
|
|
|
|
LastSnappedStruct = DrawList;
|
|
|
|
return(TRUE);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DRAW_LABEL_STRUCT_TYPE:
|
|
|
|
case DRAW_TEXT_STRUCT_TYPE:
|
|
|
|
#undef STRUCT
|
|
|
|
#define STRUCT ((DrawTextStruct *) DrawList)
|
|
|
|
if( !(SearchMask & (TEXTITEM|LABELITEM)) ) break;
|
|
|
|
dx = STRUCT->m_Size.x * STRUCT->GetLength();
|
|
|
|
dy = STRUCT->m_Size.y;
|
|
|
|
x1 = x2 = STRUCT->m_Pos.x;
|
|
|
|
y1 = y2 = STRUCT->m_Pos.y;
|
|
|
|
switch( STRUCT->m_Orient)
|
|
|
|
{
|
|
|
|
case 0 : /* HORIZONTAL */
|
|
|
|
x2 += dx; y2 -= dy;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 1 : /* VERTICAL UP */
|
|
|
|
x2 -= dy; y2 -= dx;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2 : /* horizontal inverse */
|
|
|
|
x2 -= dx; y2 += dy;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 3 : /* vertical DOWN */
|
|
|
|
x2 += dy; y2 += dx;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if(IsPointInBox(x, y, x1,y1, x2,y2) )
|
|
|
|
{
|
|
|
|
LastSnappedStruct = DrawList;
|
|
|
|
return(TRUE);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case DRAW_GLOBAL_LABEL_STRUCT_TYPE:
|
|
|
|
#undef STRUCT
|
|
|
|
#define STRUCT ((DrawGlobalLabelStruct *) DrawList)
|
|
|
|
if( !(SearchMask & LABELITEM) ) break;
|
|
|
|
dx = STRUCT->m_Size.x * ( STRUCT->GetLength() + 1 ); /* longueur */
|
|
|
|
dy = STRUCT->m_Size.y / 2; /* Demi hauteur */
|
|
|
|
x1 = x2 = STRUCT->m_Pos.x;
|
|
|
|
y1 = y2 = STRUCT->m_Pos.y;
|
|
|
|
switch( STRUCT->m_Orient)
|
|
|
|
{
|
|
|
|
case 0 : /* HORIZONTAL */
|
|
|
|
x2 -= dx; y2 += dy; y1 -= dy;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 1 : /* VERTICAL UP */
|
|
|
|
x1 -= dy; x2 += dy; y2 += dx;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2 : /* horizontal inverse */
|
|
|
|
x2 += dx; y2 += dy; y1 -= dy;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 3 : /* vertical DOWN */
|
|
|
|
x1 -= dy; x2 += dy; y2 -= dx;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if(IsPointInBox(x, y, x1,y1, x2,y2) )
|
|
|
|
{
|
|
|
|
LastSnappedStruct = DrawList;
|
|
|
|
return(TRUE);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DRAW_LIB_ITEM_STRUCT_TYPE:
|
|
|
|
if( !(SearchMask & (LIBITEM|FIELDCMPITEM) ) ) break;
|
|
|
|
|
|
|
|
if ( SearchMask & FIELDCMPITEM )
|
|
|
|
{
|
|
|
|
PartTextStruct * Field;
|
|
|
|
EDA_SchComponentStruct * DrawLibItem = (EDA_SchComponentStruct *) DrawList;
|
|
|
|
for ( i = REFERENCE; i < NUMBER_OF_FIELDS; i++ )
|
|
|
|
{
|
|
|
|
Field = &DrawLibItem->m_Field[i];
|
|
|
|
if ( (Field->m_Attributs & TEXT_NO_VISIBLE) ) continue;
|
|
|
|
if ( Field->IsVoid() ) continue;
|
|
|
|
EDA_Rect BoundaryBox = Field->GetBoundaryBox();
|
|
|
|
if(BoundaryBox.Inside(x, y) )
|
|
|
|
{
|
|
|
|
LastSnappedStruct = Field;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
#undef STRUCT
|
|
|
|
#define STRUCT ((EDA_SchComponentStruct *) DrawList)
|
|
|
|
EDA_Rect BoundaryBox = STRUCT->GetBoundaryBox();
|
|
|
|
if ( BoundaryBox.Inside(x, y) )
|
|
|
|
{
|
|
|
|
LastSnappedStruct = DrawList;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DRAW_SHEET_STRUCT_TYPE:
|
|
|
|
#undef STRUCT
|
|
|
|
#define STRUCT ((DrawSheetStruct *) DrawList)
|
|
|
|
if( !(SearchMask & SHEETITEM) ) break;
|
|
|
|
/* Recalcul des coordonnees de l'encadrement du composant */
|
|
|
|
x1 = STRUCT->m_Pos.x;
|
|
|
|
y1 = STRUCT->m_Pos.y;
|
|
|
|
x2 = STRUCT->m_Pos.x + STRUCT->m_Size.x;
|
|
|
|
y2 = STRUCT->m_Pos.y + STRUCT->m_Size.y;
|
|
|
|
|
|
|
|
if(IsPointInBox(x, y, x1, y1, x2, y2) )
|
|
|
|
{
|
|
|
|
LastSnappedStruct = DrawList;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DRAW_PICK_ITEM_STRUCT_TYPE : break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
wxString msg;
|
|
|
|
msg.Printf(wxT("SnapPoint2() error: unexpected strct type %d ("), DrawList->m_StructType);
|
|
|
|
msg << DrawList->ReturnClassName() << wxT(")");
|
|
|
|
DisplayError(NULL, msg);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
* Routine to test if an object has non empty intersection with the box *
|
|
|
|
* defined by x1/y1 and x2/y2 (x1 < x2, y1 < y2), and return TRUE if so. This *
|
|
|
|
* routine is used to pick all points in a given box. *
|
|
|
|
*****************************************************************************/
|
|
|
|
bool DrawStructInBox(int x1, int y1, int x2, int y2,
|
|
|
|
EDA_BaseStruct *DrawStruct)
|
|
|
|
{
|
|
|
|
int i, *Points, xt1, yt1, xt2, yt2, NumOfPoints2;
|
|
|
|
int dx, dy;
|
|
|
|
wxString msg;
|
|
|
|
|
|
|
|
switch (DrawStruct->m_StructType)
|
|
|
|
{
|
|
|
|
case DRAW_POLYLINE_STRUCT_TYPE:
|
|
|
|
#undef STRUCT
|
|
|
|
#define STRUCT ((DrawPolylineStruct *) DrawStruct)
|
|
|
|
Points = STRUCT->m_Points;
|
|
|
|
NumOfPoints2 = STRUCT->m_NumOfPoints * 2;
|
|
|
|
for (i = 0; i < NumOfPoints2; i += 2)
|
|
|
|
{
|
|
|
|
if (Points[i] >= x1 && Points[i] <= x2 &&
|
|
|
|
Points[i+1] >= y1 && Points[i+1] <=y2) return TRUE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DRAW_SEGMENT_STRUCT_TYPE:
|
|
|
|
#undef STRUCT
|
|
|
|
#define STRUCT ((EDA_DrawLineStruct *) DrawStruct)
|
|
|
|
if( STRUCT->m_Start.x >= x1 && STRUCT->m_Start.x <= x2 &&
|
|
|
|
STRUCT->m_Start.y >= y1 && STRUCT->m_Start.y <=y2) return TRUE;
|
|
|
|
if( (STRUCT->m_End.x >= x1) && (STRUCT->m_End.x <= x2) &&
|
|
|
|
(STRUCT->m_End.y >= y1) && (STRUCT->m_End.y <=y2) ) return TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DRAW_BUSENTRY_STRUCT_TYPE:
|
|
|
|
#undef STRUCT
|
|
|
|
#define STRUCT ((DrawBusEntryStruct *) DrawStruct)
|
|
|
|
if( STRUCT->m_Pos.x >= x1 && STRUCT->m_Pos.x <= x2 &&
|
|
|
|
STRUCT->m_Pos.y >= y1 && STRUCT->m_Pos.y <=y2)
|
|
|
|
return TRUE;
|
|
|
|
if( (STRUCT->m_End().x >= x1) && ( STRUCT->m_End().x <= x2) &&
|
|
|
|
( STRUCT->m_End().y >= y1) && ( STRUCT->m_End().y <=y2) )
|
|
|
|
return TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DRAW_JUNCTION_STRUCT_TYPE:
|
|
|
|
#undef STRUCT
|
|
|
|
#define STRUCT ((DrawJunctionStruct *) DrawStruct)
|
|
|
|
if( (STRUCT->m_Pos.x >= x1) && (STRUCT->m_Pos.x <= x2) &&
|
|
|
|
(STRUCT->m_Pos.y >= y1) && (STRUCT->m_Pos.y <= y2) )
|
|
|
|
return TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case DRAW_NOCONNECT_STRUCT_TYPE:
|
|
|
|
#undef STRUCT
|
|
|
|
#define STRUCT ((DrawNoConnectStruct *) DrawStruct)
|
|
|
|
if( (STRUCT->m_Pos.x >= x1) && (STRUCT->m_Pos.x <= x2) &&
|
|
|
|
(STRUCT->m_Pos.y >= y1) && (STRUCT->m_Pos.y <= y2) )
|
|
|
|
return TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case DRAW_MARKER_STRUCT_TYPE:
|
|
|
|
#undef STRUCT
|
|
|
|
#define STRUCT ((DrawMarkerStruct *) DrawStruct)
|
|
|
|
if( (STRUCT->m_Pos.x >= x1) && (STRUCT->m_Pos.x <= x2) &&
|
|
|
|
(STRUCT->m_Pos.y >= y1) && (STRUCT->m_Pos.y <= y2) )
|
|
|
|
return TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DRAW_LABEL_STRUCT_TYPE:
|
|
|
|
case DRAW_TEXT_STRUCT_TYPE:
|
|
|
|
#undef STRUCT
|
|
|
|
#define STRUCT ((DrawTextStruct *) DrawStruct)
|
|
|
|
dx = STRUCT->m_Size.x * STRUCT->GetLength();
|
|
|
|
dy = STRUCT->m_Size.y;
|
|
|
|
xt1 = xt2 = STRUCT->m_Pos.x;
|
|
|
|
yt1 = yt2 = STRUCT->m_Pos.y;
|
|
|
|
switch( STRUCT->m_Orient)
|
|
|
|
{
|
|
|
|
case 0 : /* HORIZONTAL */
|
|
|
|
xt2 += dx; yt2 -= dy;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 1 : /* VERTICAL UP */
|
|
|
|
xt2 -= dy; yt2 -= dx;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2 : /* horizontal inverse */
|
|
|
|
xt2 -= dx; yt2 += dy;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 3 : /* vertical DOWN */
|
|
|
|
xt2 += dy; yt2 += dx;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if( IsBox1InBox2(xt1,yt1, xt2, yt2, x1, y1, x2, y2) ) return TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DRAW_GLOBAL_LABEL_STRUCT_TYPE:
|
|
|
|
#undef STRUCT
|
|
|
|
#define STRUCT ((DrawGlobalLabelStruct *) DrawStruct)
|
|
|
|
dx = STRUCT->m_Size.x * ( STRUCT->GetLength() + 1); /* longueur totale */
|
|
|
|
dy = STRUCT->m_Size.y / 2; /* Demi hauteur */
|
|
|
|
xt1 = xt2 = STRUCT->m_Pos.x;
|
|
|
|
yt1 = yt2 = STRUCT->m_Pos.y;
|
|
|
|
switch( STRUCT->m_Orient)
|
|
|
|
{
|
|
|
|
case 0 : /* HORIZONTAL */
|
|
|
|
xt2 -= dx; yt2 += dy; yt1 -= dy;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 1 : /* VERTICAL UP */
|
|
|
|
xt1 -= dy; xt2 += dy; yt2 += dx;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2 : /* horizontal inverse */
|
|
|
|
xt2 += dx; yt2 += dy; yt1 -= dy;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 3 : /* vertical DOWN */
|
|
|
|
xt1 -= dy; xt2 += dy; yt2 -= dx;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if( IsBox1InBox2(xt1,yt1, xt2, yt2, x1, y1, x2, y2) ) return TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DRAW_LIB_ITEM_STRUCT_TYPE:
|
|
|
|
{
|
|
|
|
#undef STRUCT
|
|
|
|
#define STRUCT ((EDA_SchComponentStruct *) DrawStruct)
|
|
|
|
EDA_Rect BoundaryBox = STRUCT->GetBoundaryBox();
|
|
|
|
xt1 = BoundaryBox.GetX();
|
|
|
|
yt1 = BoundaryBox.GetY();
|
|
|
|
xt2 = BoundaryBox.GetRight();
|
|
|
|
yt2 = BoundaryBox.GetBottom();
|
|
|
|
if( IsBox1InBox2(xt1,yt1, xt2, yt2, x1, y1, x2, y2) ) return TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case DRAW_SHEET_STRUCT_TYPE :
|
|
|
|
#undef STRUCT
|
|
|
|
#define STRUCT ((DrawSheetStruct *) DrawStruct)
|
|
|
|
/* Recalcul des coordonnees de l'encadrement du composant */
|
|
|
|
xt1 = STRUCT->m_Pos.x;
|
|
|
|
yt1 = STRUCT->m_Pos.y;
|
|
|
|
xt2 = STRUCT->m_Pos.x + STRUCT->m_Size.x;
|
|
|
|
yt2 = STRUCT->m_Pos.y + STRUCT->m_Size.y;
|
|
|
|
|
|
|
|
if( IsBox1InBox2(xt1,yt1, xt2, yt2, x1, y1, x2, y2) )
|
|
|
|
return TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DRAW_SHEETLABEL_STRUCT_TYPE : break;
|
|
|
|
case DRAW_PICK_ITEM_STRUCT_TYPE : break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
msg.Printf(
|
|
|
|
wxT("DrawStructInBox() Err: unexpected StructType %d ("),
|
|
|
|
DrawStruct->m_StructType );
|
|
|
|
msg << DrawStruct->ReturnClassName() << wxT(")");
|
|
|
|
DisplayError(NULL, msg );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************/
|
|
|
|
static bool IsBox1InBox2( int StartX1, int StartY1, int EndX1, int EndY1,
|
|
|
|
int StartX2, int StartY2, int EndX2, int EndY2 )
|
|
|
|
/****************************************************************************/
|
|
|
|
/* Routine detectant que le rectangle 1 (Box1) et le rectangle 2 (Box2) se
|
|
|
|
recouvrent.
|
|
|
|
Retourne TRUE ou FALSE.
|
|
|
|
|
|
|
|
On Considere ici qu'il y a recouvrement si l'un au moins des coins
|
|
|
|
d'un 'Box' est compris dans l'autre
|
|
|
|
*/
|
|
|
|
{
|
|
|
|
int cX, cY;
|
|
|
|
|
|
|
|
if(StartX1 > EndX1) EXCHG(StartX1, EndX1);
|
|
|
|
if(StartX2 > EndX2) EXCHG(StartX2, EndX2);
|
|
|
|
if(StartY1 > EndY1) EXCHG(StartY1, EndY1);
|
|
|
|
if(StartY2 > EndY2) EXCHG(StartY2, EndY2);
|
|
|
|
|
|
|
|
/* Tst des 4 coins du rectangle 1 */
|
|
|
|
cX = StartX1; cY = StartY1; /* 1er coin */
|
|
|
|
if( (cX >= StartX2) && (cX <= EndX2) && (cY >= StartY2) && (cY <= EndY2) )
|
|
|
|
return(TRUE);
|
|
|
|
|
|
|
|
cX = EndX1; cY = StartY1; /* 2er coin */
|
|
|
|
if( (cX >= StartX2) && (cX <= EndX2) && (cY >= StartY2) && (cY <= EndY2) )
|
|
|
|
return(TRUE);
|
|
|
|
|
|
|
|
cX = EndX1; cY = EndY1; /* 3eme coin */
|
|
|
|
if( (cX >= StartX2) && (cX <= EndX2) && (cY >= StartY2) && (cY <= EndY2) )
|
|
|
|
return(TRUE);
|
|
|
|
|
|
|
|
cX = StartX1; cY = EndY1; /* 4eme coin */
|
|
|
|
if( (cX >= StartX2) && (cX <= EndX2) && (cY >= StartY2) && (cY <= EndY2) )
|
|
|
|
return(TRUE);
|
|
|
|
|
|
|
|
/* Tst des 4 coins du rectangle 2 */
|
|
|
|
cX = StartX2; cY = StartY2; /* 1er coin */
|
|
|
|
if( (cX >= StartX1) && (cX <= EndX1) && (cY >= StartY1) && (cY <= EndY1) )
|
|
|
|
return(TRUE);
|
|
|
|
|
|
|
|
cX = EndX2; cY = StartY2; /* 2er coin */
|
|
|
|
if( (cX >= StartX1) && (cX <= EndX1) && (cY >= StartY1) && (cY <= EndY1) )
|
|
|
|
return(TRUE);
|
|
|
|
|
|
|
|
cX = EndX2; cY = EndY2; /* 3er coin */
|
|
|
|
if( (cX >= StartX1) && (cX <= EndX1) && (cY >= StartY1) && (cY <= EndY1) )
|
|
|
|
return(TRUE);
|
|
|
|
|
|
|
|
cX = StartX2; cY = EndY2; /* 4er coin */
|
|
|
|
if( (cX >= StartX1) && (cX <= EndX1) && (cY >= StartY1) && (cY <= EndY1) )
|
|
|
|
return(TRUE);
|
|
|
|
|
|
|
|
|
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**********************************************************************/
|
|
|
|
static bool IsPointInBox( int pX, int pY,
|
|
|
|
int BoxX1, int BoxY1, int BoxX2, int BoxY2 )
|
|
|
|
/**********************************************************************/
|
|
|
|
/* Routine detectant que le point pX,pY est dans le rectangle (Box)
|
|
|
|
Retourne TRUE ou FALSE.
|
|
|
|
|
|
|
|
*/
|
|
|
|
{
|
|
|
|
if(BoxX1 > BoxX2) EXCHG(BoxX1, BoxX2);
|
|
|
|
if(BoxY1 > BoxY2) EXCHG(BoxY1, BoxY2);
|
|
|
|
|
|
|
|
if( (pX >= BoxX1) && (pX <= BoxX2) && (pY >= BoxY1) && (pY <= BoxY2) )
|
|
|
|
return(TRUE);
|
|
|
|
|
|
|
|
else return(FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/********************************************************************************/
|
|
|
|
static bool IsPointOnSegment( int pX, int pY,
|
|
|
|
int SegmX1, int SegmY1, int SegmX2, int SegmY2, int seuil )
|
|
|
|
/********************************************************************************/
|
|
|
|
/* Routine detectant que le point pX,pY est sur le Segment X1,Y1 a X2,Y2
|
|
|
|
Retourne TRUE ou FALSE.
|
|
|
|
*/
|
|
|
|
{
|
|
|
|
/* Recalcul des coord avec SegmX1, SegmX2 comme origine */
|
|
|
|
pX -= SegmX1; pY -= SegmY1;
|
|
|
|
SegmX2 -= SegmX1; SegmY2 -= SegmY1;
|
|
|
|
|
|
|
|
if( distance( SegmX2, SegmY2, pX, pY, seuil ) ) return(TRUE);
|
|
|
|
|
|
|
|
else return(FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*********************************************************************************/
|
|
|
|
LibEDA_BaseStruct * LocateDrawItem(SCH_SCREEN * Screen, const wxPoint & refpoint,
|
|
|
|
EDA_LibComponentStruct * LibEntry, int Unit, int Convert, int masque)
|
|
|
|
/*********************************************************************************/
|
|
|
|
/* Routine de localisation d'un element de dessin de symbole( sauf pins )
|
|
|
|
Unit = Unite d'appartenance (si Unit = 0, recherche sur toutes unites)
|
|
|
|
Convert = Conversion d'appartenance (si Convert = 0, recherche sur
|
|
|
|
toutes variantes)
|
|
|
|
*/
|
|
|
|
{
|
|
|
|
int x, y, dx, dy, ii, *ptpoly;
|
|
|
|
int px, py;
|
|
|
|
LibEDA_BaseStruct * DrawItem;
|
|
|
|
int seuil;
|
|
|
|
|
|
|
|
if( LibEntry == NULL ) return(NULL);
|
|
|
|
|
|
|
|
if ( LibEntry->Type != ROOT )
|
|
|
|
{
|
|
|
|
DisplayError(NULL, wxT("Error in LocateDrawItem: Entry is ALIAS"));
|
|
|
|
return(NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
DrawItem = LibEntry->m_Drawings;
|
|
|
|
|
|
|
|
seuil = 3; /* Tolerance: 1/2 pas de petite grille */
|
|
|
|
px = refpoint.x;
|
|
|
|
py = refpoint.y;
|
|
|
|
|
|
|
|
for( ; DrawItem != NULL ; DrawItem = DrawItem->Next() )
|
|
|
|
{
|
|
|
|
if(Unit && DrawItem->m_Unit && (Unit != DrawItem->m_Unit) ) continue;
|
|
|
|
if(Convert && DrawItem->m_Convert && (Convert != DrawItem->m_Convert) )
|
|
|
|
continue;
|
|
|
|
|
|
|
|
switch ( DrawItem->m_StructType )
|
|
|
|
{
|
|
|
|
case COMPONENT_ARC_DRAW_TYPE:
|
|
|
|
{
|
|
|
|
LibDrawArc * Arc = (LibDrawArc *) DrawItem;
|
|
|
|
if( (masque & LOCATE_COMPONENT_ARC_DRAW_TYPE) == 0) break;
|
|
|
|
dx = px - Arc->m_Pos.x;
|
|
|
|
dy = py + Arc->m_Pos.y;
|
|
|
|
ii = (int)sqrt( dx*dx + dy*dy);
|
|
|
|
if ( abs(ii - Arc->m_Rayon) <= seuil) return( DrawItem);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case COMPONENT_CIRCLE_DRAW_TYPE:
|
|
|
|
{
|
|
|
|
LibDrawCircle * Circle = (LibDrawCircle *) DrawItem;
|
|
|
|
if( (masque & LOCATE_COMPONENT_CIRCLE_DRAW_TYPE) == 0) break;
|
|
|
|
dx = px - Circle->m_Pos.x;
|
|
|
|
dy = py + Circle->m_Pos.y;
|
|
|
|
ii = (int)sqrt( dx*dx + dy*dy);
|
|
|
|
if ( abs(ii - Circle->m_Rayon) <= seuil) return( DrawItem);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case COMPONENT_RECT_DRAW_TYPE:
|
|
|
|
{ // Locate a rect if the mouse cursor is on a segment
|
|
|
|
LibDrawSquare * Square = (LibDrawSquare *) DrawItem;
|
|
|
|
if( (masque & LOCATE_COMPONENT_RECT_DRAW_TYPE) == 0) break;
|
|
|
|
if(IsPointOnSegment(px,py, // locate lower segment
|
|
|
|
Square->m_Pos.x, - Square->m_Pos.y,
|
|
|
|
Square->m_End.x, - Square->m_Pos.y, seuil) )
|
|
|
|
return(DrawItem);
|
|
|
|
if(IsPointOnSegment(px, py, // locate right segment
|
|
|
|
Square->m_End.x, - Square->m_Pos.y,
|
|
|
|
Square->m_End.x, - Square->m_End.y, seuil) )
|
|
|
|
return(DrawItem);
|
|
|
|
if(IsPointOnSegment(px, py, // locate upper segment
|
|
|
|
Square->m_End.x, - Square->m_End.y,
|
|
|
|
Square->m_Pos.x, - Square->m_End.y, seuil) )
|
|
|
|
return(DrawItem);
|
|
|
|
if(IsPointOnSegment(px, py, // locate left segment
|
|
|
|
Square->m_Pos.x, - Square->m_End.y,
|
|
|
|
Square->m_Pos.x, - Square->m_Pos.y, seuil) )
|
|
|
|
return(DrawItem);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case COMPONENT_POLYLINE_DRAW_TYPE:
|
|
|
|
{
|
|
|
|
LibDrawPolyline * polyline = (LibDrawPolyline *) DrawItem;
|
|
|
|
if( (masque & LOCATE_COMPONENT_POLYLINE_DRAW_TYPE) == 0) break;
|
|
|
|
ptpoly = polyline->PolyList;
|
|
|
|
for( ii = polyline->n-1; ii > 0; ii--, ptpoly += 2)
|
|
|
|
{
|
|
|
|
if(IsPointOnSegment(px, py,
|
|
|
|
ptpoly[0], - ptpoly[1], ptpoly[2], - ptpoly[3], seuil) )
|
|
|
|
return(DrawItem);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case COMPONENT_LINE_DRAW_TYPE:
|
|
|
|
{
|
|
|
|
LibDrawSegment * Segment = (LibDrawSegment *) DrawItem;
|
|
|
|
if( (masque & LOCATE_COMPONENT_LINE_DRAW_TYPE) == 0) break;
|
|
|
|
if(IsPointOnSegment(px, py,
|
|
|
|
Segment->m_Pos.x, - Segment->m_Pos.y,
|
|
|
|
Segment->m_End.x, - Segment->m_End.y, seuil) )
|
|
|
|
return(DrawItem);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case COMPONENT_GRAPHIC_TEXT_DRAW_TYPE:
|
|
|
|
{
|
|
|
|
LibDrawText * Text = (LibDrawText *) DrawItem;
|
|
|
|
if( (masque & LOCATE_COMPONENT_GRAPHIC_TEXT_DRAW_TYPE) == 0) break;
|
|
|
|
ii = Text->m_Text.Len(); if ( ii < 2 ) ii = 2;
|
|
|
|
dx = (Text->m_Size.x * ii) / 2;
|
|
|
|
dy = Text->m_Size.y / 2;
|
|
|
|
if(Text->m_Horiz == TEXT_ORIENT_VERT)
|
|
|
|
{
|
|
|
|
EXCHG(dx,dy);
|
|
|
|
}
|
|
|
|
x = px - Text->m_Pos.x;
|
|
|
|
y = py + Text->m_Pos.y;
|
|
|
|
if( (abs(x) <= dx) && (abs(y) <= dy) )
|
|
|
|
return(DrawItem); /* Texte trouve */
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return(NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/****************************************************************/
|
|
|
|
int distance(int dx, int dy, int spot_cX, int spot_cY, int seuil)
|
|
|
|
/****************************************************************/
|
|
|
|
/*
|
|
|
|
Calcul de la distance du point spot_cx,spot_cy a un segment de droite,
|
|
|
|
d'origine 0,0 et d'extremite dx, dy;
|
|
|
|
retourne:
|
|
|
|
0 si distance > seuil
|
|
|
|
1 si distance <= seuil
|
|
|
|
Variables utilisees ( sont ramenees au repere centre sur l'origine du segment)
|
|
|
|
dx, dy = coord de l'extremite segment.
|
|
|
|
spot_cX,spot_cY = coord du curseur souris
|
|
|
|
la recherche se fait selon 4 cas:
|
|
|
|
segment horizontal
|
|
|
|
segment vertical
|
|
|
|
segment quelconque
|
|
|
|
*/
|
|
|
|
{
|
|
|
|
int cXrot, cYrot , /* coord du point (souris) dans le repere tourne */
|
|
|
|
segX, segY; /* coord extremite segment tj >= 0 */
|
|
|
|
int pointX, pointY; /* coord point a tester dans repere modifie dans lequel
|
|
|
|
segX et segY sont >=0 */
|
|
|
|
|
|
|
|
segX = dx ; segY = dy; pointX = spot_cX ; pointY = spot_cY ;
|
|
|
|
|
|
|
|
/*Recalcul coord pour que le segment soit dans 1er quadrant (coord >= 0)*/
|
|
|
|
if (segX < 0) /* mise en0 par symetrie par rapport a l'axe Y */
|
|
|
|
{
|
|
|
|
segX = -segX ; pointX = - pointX ;
|
|
|
|
}
|
|
|
|
if (segY < 0) /* mise en > 0 par symymetrie par rapport a l'axe X */
|
|
|
|
{
|
|
|
|
segY = -segY ; pointY = -pointY ;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if ( segY == 0 ) /* piste Horizontale */
|
|
|
|
{
|
|
|
|
if(abs(pointY) <= seuil )
|
|
|
|
{
|
|
|
|
if((pointX >= 0) && (pointX <= segX) ) return(1);
|
|
|
|
/* Etude des extremites : cercle de rayon seuil */
|
|
|
|
if( (pointX < 0) && (pointX >= -seuil) )
|
|
|
|
{
|
|
|
|
if( ((pointX * pointX) + (pointY*pointY)) <= (seuil*seuil) )
|
|
|
|
return(1);
|
|
|
|
}
|
|
|
|
if( (pointX > segX) && (pointX <= (segX+seuil)) )
|
|
|
|
{
|
|
|
|
if( (((pointX-segX) * (pointX-segX)) + (pointY*pointY)) <= (seuil*seuil) )
|
|
|
|
return(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
else if ( segX == 0 ) /* piste verticale */
|
|
|
|
{
|
|
|
|
if( abs(pointX) <= seuil)
|
|
|
|
{
|
|
|
|
if((pointY >= 0 ) && (pointY <= segY) ) return(1);
|
|
|
|
if( (pointY < 0) && (pointY >= -seuil) )
|
|
|
|
{
|
|
|
|
if( ((pointY * pointY) + (pointX*pointX)) <= (seuil*seuil) )
|
|
|
|
return(1);
|
|
|
|
}
|
|
|
|
if( (pointY > segY) && (pointY <= (segY+seuil)) )
|
|
|
|
{
|
|
|
|
if( ( ((pointY-segY) * (pointY-segY)) + (pointX*pointX)) <= (seuil*seuil) )
|
|
|
|
return(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
else /* orientation quelconque */
|
|
|
|
{
|
|
|
|
/* On fait un changement d'axe (rotation) de facon a ce que le segment
|
|
|
|
de piste soit horizontal dans le nouveau repere */
|
|
|
|
int angle;
|
|
|
|
|
|
|
|
angle = (int)( atan2((float)segY, (float)segX) * 1800 / M_PI) ;
|
|
|
|
cXrot = pointX; cYrot = pointY;
|
|
|
|
RotatePoint(&cXrot, &cYrot, angle); /* Rotation du point a tester */
|
|
|
|
RotatePoint(&segX, &segY, angle) ; /* Rotation du segment */
|
|
|
|
|
|
|
|
/*la piste est Horizontale , par suite des modifs de coordonnes
|
|
|
|
et d'axe, donc segX = longueur du segment */
|
|
|
|
|
|
|
|
if ( abs(cYrot) <= seuil ) /* ok sur axe vertical) */
|
|
|
|
{
|
|
|
|
if ((cXrot >= 0) && (cXrot <= segX) ) return(1) ;
|
|
|
|
/* Etude des extremites : cercle de rayon seuil */
|
|
|
|
if( (cXrot < 0) && (cXrot >= -seuil) )
|
|
|
|
{
|
|
|
|
if( ((cXrot * cXrot) + (cYrot*cYrot)) <= (seuil*seuil) )
|
|
|
|
return(1);
|
|
|
|
}
|
|
|
|
if( (cXrot > segX) && (cXrot <= (segX+seuil)) )
|
|
|
|
{
|
|
|
|
if( (((cXrot-segX) * (cXrot-segX)) + (cYrot*cYrot)) <= (seuil*seuil) )
|
|
|
|
return(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return(0) ;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*******************************************************************/
|
|
|
|
LibEDA_BaseStruct * LocatePin( const wxPoint & RefPos,
|
|
|
|
EDA_LibComponentStruct * Entry,
|
|
|
|
int Unit, int convert, EDA_SchComponentStruct * DrawLibItem)
|
|
|
|
/*******************************************************************/
|
|
|
|
/* Routine de localisation d'une PIN de la PartLib pointee par Entry
|
|
|
|
retourne un pointeur sur la pin, ou NULL si pas trouve
|
|
|
|
Si Unit = 0, le numero d'unite n'est pas teste
|
|
|
|
Si convert = 0, le numero convert n'est pas teste
|
|
|
|
|
|
|
|
m_Transform = matrice de transformation.
|
|
|
|
Si NULL: matrice de transformation " normale" [1 , 0 , 0 , -1]
|
|
|
|
(la matrice de transformation " normale" etant [1 , 0 , 0 , -1]
|
|
|
|
la coord dy doit etre inversee).
|
|
|
|
PartX, PartY: coordonnees de positionnement du composant
|
|
|
|
*/
|
|
|
|
{
|
|
|
|
LibEDA_BaseStruct * DrawItem;
|
|
|
|
LibDrawPin * Pin;
|
|
|
|
int x1, y1, x2, y2;
|
|
|
|
|
|
|
|
if ( Entry == NULL ) return(NULL);
|
|
|
|
|
|
|
|
if ( Entry->Type != ROOT )
|
|
|
|
{
|
|
|
|
DisplayError(NULL, wxT("LocatePin() error: Entry is ALIAS"));
|
|
|
|
return(NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
DrawItem = Entry->m_Drawings;
|
|
|
|
for ( ; DrawItem != NULL; DrawItem = DrawItem->Next())
|
|
|
|
{
|
|
|
|
if(DrawItem->m_StructType == COMPONENT_PIN_DRAW_TYPE) /* Pin Trouvee */
|
|
|
|
{
|
|
|
|
Pin = (LibDrawPin *) DrawItem;
|
|
|
|
|
|
|
|
if( Unit && DrawItem->m_Unit && (DrawItem->m_Unit != Unit) )
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if( convert && DrawItem->m_Convert && (DrawItem->m_Convert != convert) )
|
|
|
|
continue;
|
|
|
|
|
|
|
|
x2 = Pin->m_Pos.x;
|
|
|
|
y2 = Pin->m_Pos.y;
|
|
|
|
x1 = Pin->ReturnPinEndPoint().x;
|
|
|
|
y1 = Pin->ReturnPinEndPoint().y;
|
|
|
|
|
|
|
|
if(DrawLibItem == NULL )
|
|
|
|
{
|
|
|
|
y1 = -y1; y2 = -y2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int x = x1, y = y1;
|
|
|
|
x1 = DrawLibItem->m_Pos.x + DrawLibItem->m_Transform[0][0] * x
|
|
|
|
+ DrawLibItem->m_Transform[0][1] * y;
|
|
|
|
y1 = DrawLibItem->m_Pos.y + DrawLibItem->m_Transform[1][0] * x
|
|
|
|
+ DrawLibItem->m_Transform[1][1] * y;
|
|
|
|
x = x2; y = y2;
|
|
|
|
x2 = DrawLibItem->m_Pos.x + DrawLibItem->m_Transform[0][0] * x
|
|
|
|
+ DrawLibItem->m_Transform[0][1] * y;
|
|
|
|
y2 = DrawLibItem->m_Pos.y + DrawLibItem->m_Transform[1][0] * x
|
|
|
|
+ DrawLibItem->m_Transform[1][1] * y;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (x1 > x2 ) EXCHG(x1,x2); if (y1 > y2 ) EXCHG(y1,y2);
|
|
|
|
|
|
|
|
if( (RefPos.x >= x1) && (RefPos.x <= x2) &&
|
|
|
|
(RefPos.y >= y1) && (RefPos.y <= y2) )
|
|
|
|
return(DrawItem);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return(NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************************/
|
|
|
|
DrawSheetLabelStruct * LocateSheetLabel(DrawSheetStruct *Sheet, const wxPoint & pos)
|
|
|
|
/***********************************************************************************/
|
|
|
|
{
|
|
|
|
int size , dy, minx, maxx;
|
|
|
|
DrawSheetLabelStruct * SheetLabel;
|
|
|
|
|
|
|
|
SheetLabel = Sheet->m_Label;
|
|
|
|
while((SheetLabel) && (SheetLabel->m_StructType==DRAW_SHEETLABEL_STRUCT_TYPE))
|
|
|
|
{
|
|
|
|
size = ( SheetLabel->GetLength()+1 ) * SheetLabel->m_Size.x;
|
|
|
|
if (SheetLabel->m_Edge) size = -size ;
|
|
|
|
minx = SheetLabel->m_Pos.x; maxx = SheetLabel->m_Pos.x + size;
|
|
|
|
if( maxx < minx ) EXCHG(maxx,minx);
|
|
|
|
dy = SheetLabel->m_Size.x / 2;
|
|
|
|
if( (ABS(pos.y - SheetLabel->m_Pos.y) <= dy ) &&
|
|
|
|
(pos.x <= maxx) &&
|
|
|
|
(pos.x >= minx) )
|
|
|
|
return(SheetLabel);
|
|
|
|
SheetLabel = (DrawSheetLabelStruct *) SheetLabel->Pnext;
|
|
|
|
}
|
|
|
|
return(NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**************************************************************************/
|
|
|
|
LibDrawPin * LocateAnyPin(EDA_BaseStruct *DrawList, const wxPoint & RefPos,
|
|
|
|
EDA_SchComponentStruct ** libpart)
|
|
|
|
/**************************************************************************/
|
|
|
|
{
|
|
|
|
EDA_BaseStruct *DrawStruct;
|
|
|
|
EDA_LibComponentStruct * Entry;
|
|
|
|
EDA_SchComponentStruct * LibItem = NULL;
|
|
|
|
LibDrawPin * Pin = NULL;
|
|
|
|
|
|
|
|
for(DrawStruct = DrawList; DrawStruct != NULL; DrawStruct = DrawStruct->Pnext )
|
|
|
|
{
|
|
|
|
if( DrawStruct->m_StructType != DRAW_LIB_ITEM_STRUCT_TYPE )
|
|
|
|
continue;
|
|
|
|
LibItem = (EDA_SchComponentStruct *) DrawStruct;
|
|
|
|
Entry = FindLibPart( LibItem->m_ChipName.GetData(), wxEmptyString, FIND_ROOT);
|
|
|
|
if( Entry == NULL ) continue;
|
|
|
|
Pin = (LibDrawPin *) LocatePin(RefPos, Entry, LibItem->m_Multi,
|
|
|
|
LibItem->m_Convert, LibItem);
|
|
|
|
if( Pin ) break;
|
|
|
|
}
|
|
|
|
if ( libpart ) *libpart = LibItem;
|
|
|
|
return Pin;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***************************************************************/
|
|
|
|
DrawSheetLabelStruct * LocateAnyPinSheet(const wxPoint & RefPos,
|
|
|
|
EDA_BaseStruct *DrawList)
|
|
|
|
/***************************************************************/
|
|
|
|
{
|
|
|
|
EDA_BaseStruct *DrawStruct;
|
|
|
|
DrawSheetLabelStruct * PinSheet = NULL;
|
|
|
|
|
|
|
|
for( DrawStruct = DrawList; DrawStruct != NULL; DrawStruct = DrawStruct->Pnext )
|
|
|
|
{
|
|
|
|
if( DrawStruct->m_StructType != DRAW_SHEET_STRUCT_TYPE )
|
|
|
|
continue;
|
|
|
|
PinSheet = LocateSheetLabel( (DrawSheetStruct *) DrawStruct,
|
|
|
|
RefPos);
|
|
|
|
if( PinSheet ) break;
|
|
|
|
}
|
|
|
|
return PinSheet;
|
|
|
|
}
|
|
|
|
|