TRACK * CreateLockPoint(int *pX, int *pY, TRACK * ptsegm, TRACK * refsegm)
/******************************************************************************/
/* Routine de creation d'un point intermediaire sur un segment
	le segment ptsegm est casse en 2 segments se raccordant au point pX, pY
	retourne:
		NULL si pas de nouveau point ( c.a.d si pX, pY correspondait deja
		a une extremite ou:
		pointeur sur le segment cree
	si refsegm != NULL refsegm est pointeur sur le segment incident,
	et le point cree est l'intersection des 2 axes des segments ptsegm et
	refsegm
	retourne la valeur exacte de pX et pY
	Si ptsegm pointe sur une via:
		retourne la valeur exacte de pX et pY et ptsegm,
		mais ne cree pas de point supplementaire

*/
{
int cX, cY;
int dx, dy;			/* Coord de l'extremite du segm ptsegm / origine */
int ox, oy, fx , fy;	/* coord de refsegm / origine de prsegm */
TRACK * NewTrack;

	if( (ptsegm->m_Start.x == *pX) && (ptsegm->m_Start.y == *pY) ) return(NULL);
	if( (ptsegm->m_End.x == *pX) && (ptsegm->m_End.y == *pY) ) return(NULL);

	/* le point n'est pas sur une extremite de piste */
	if(ptsegm->m_StructType == TYPEVIA )
		{
		*pX = ptsegm->m_Start.x; *pY = ptsegm->m_Start.y;
		return(ptsegm);
		}
	/* calcul des coord vraies du point intermediaire dans le repere d'origine
	= origine de ptsegm */
	cX = *pX - ptsegm->m_Start.x;
    cY = *pY - ptsegm->m_Start.y;
	dx = ptsegm->m_End.x - ptsegm->m_Start.x;
    dy = ptsegm->m_End.y - ptsegm->m_Start.y;

// ***** A COMPLETER : non utilise
    if ( refsegm )
        {
    	ox = refsegm->m_Start.x - ptsegm->m_Start.x;
        oy = refsegm->m_Start.y - ptsegm->m_Start.y;
    	fx = refsegm->m_End.x - ptsegm->m_Start.x;
        fy = refsegm->m_End.y - ptsegm->m_Start.y;
        }

	/* pour que le point soit sur le segment ptsegm: cY/cX = dy/dx */
	if ( dx == 0 )	cX = 0; /* segm horizontal */
	else cY = (cX * dy) / dx;

	/* creation du point intermediaire ( c'est a dire creation d'un nouveau
	segment, debutant au point intermediaire */

	cX += ptsegm->m_Start.x; cY += ptsegm->m_Start.y;
	NewTrack = ptsegm->Copy();

	NewTrack->Insert(NULL, ptsegm);
	/* correction du pointeur de fin du nouveau segment */
	NewTrack->end = ptsegm->end;

	/* le segment primitif finit au nouveau point : */
	ptsegm->m_End.x = cX; ptsegm->m_End.y = cY;
	ptsegm->SetState(END_ONPAD, OFF);

	/* le nouveau segment debute au nouveau point : */
	ptsegm = NewTrack;;
	ptsegm->m_Start.x = cX; ptsegm->m_Start.y = cY;
	ptsegm->SetState(BEGIN_ONPAD, OFF);
	*pX = cX; *pY = cY;

	return(ptsegm);

}
Exemple #2
0
/* Insere la nouvelle piste creee dans la liste standard des pistes.
	Modifie les points de debut et fin de piste pour qu'ils soient relies
	au centre des pads corresponadants, meme hors grille
*/
static void Place_Piste_en_Buffer(WinEDA_PcbFrame * pcbframe, wxDC * DC)
{
TRACK* pt_track;
int dx0, dy0, dx1,dy1;
int marge, via_marge;
WinEDA_DrawPanel * panel = pcbframe->DrawPanel;

	marge = g_DesignSettings.m_TrackClearence + (g_DesignSettings.m_CurrentTrackWidth /2);
	via_marge = g_DesignSettings.m_TrackClearence + (g_DesignSettings.m_CurrentViaSize /2);

	/* tst point d'arrivee : doit etre sur pad start */

	dx1 = g_CurrentTrackSegment->m_End.x - g_CurrentTrackSegment->m_Start.x;
	dy1 = g_CurrentTrackSegment->m_End.y - g_CurrentTrackSegment->m_Start.y;
	/* Replacement sur le centre du pad si hors grille */

	dx0 = pt_cur_ch->pad_start->m_Pos.x - g_CurrentTrackSegment->m_Start.x;
	dy0 = pt_cur_ch->pad_start->m_Pos.y - g_CurrentTrackSegment->m_Start.y;

	/* si aligne: modif du point origine */
	if(abs(dx0*dy1) == abs(dx1*dy0) ) /* Alignes ! */
		{
		g_CurrentTrackSegment->m_End.x = pt_cur_ch->pad_start->m_Pos.x;
		g_CurrentTrackSegment->m_End.y = pt_cur_ch->pad_start->m_Pos.y;
		}
	else /* Creation d'un segment suppl raccord */
		{
		TRACK * NewTrack = g_CurrentTrackSegment->Copy();
		NewTrack->Insert(pcbframe->m_Pcb, g_CurrentTrackSegment);

		NewTrack->m_End.x = pt_cur_ch->pad_start->m_Pos.x;
		NewTrack->m_End.y = pt_cur_ch->pad_start->m_Pos.y;
		NewTrack->m_Start.x = g_CurrentTrackSegment->m_End.x;
		NewTrack->m_Start.y = g_CurrentTrackSegment->m_End.y;

		g_CurrentTrackSegment = NewTrack; g_TrackSegmentCount++;
		}


	g_FirstTrackSegment->start = Locate_Pad_Connecte(pcbframe->m_Pcb, g_FirstTrackSegment,START);
	if(g_FirstTrackSegment->start) g_FirstTrackSegment->SetState(BEGIN_ONPAD,ON);

	g_CurrentTrackSegment->end = Locate_Pad_Connecte(pcbframe->m_Pcb, g_CurrentTrackSegment,END);
	if(g_CurrentTrackSegment->end) g_CurrentTrackSegment->SetState(END_ONPAD,ON);

	/* recherche de la zone de rangement et insertion de la nouvelle piste */
	pt_track = g_FirstTrackSegment->GetBestInsertPoint(pcbframe->m_Pcb);
	g_FirstTrackSegment->Insert(pcbframe->m_Pcb, pt_track);

	Trace_Une_Piste(panel, DC, g_FirstTrackSegment,g_TrackSegmentCount,GR_OR) ;

	pcbframe->test_1_net_connexion(DC, g_FirstTrackSegment->m_NetCode );

	/* Trace de la forme exacte de la piste en BOARD */
	for ( pt_track = g_FirstTrackSegment; ; pt_track = (TRACK*)pt_track->Pnext)
		{
		TraceSegmentPcb(pcbframe->m_Pcb,pt_track,HOLE,marge,WRITE_CELL);
		TraceSegmentPcb(pcbframe->m_Pcb,pt_track,VIA_IMPOSSIBLE,via_marge,WRITE_OR_CELL);
		if(pt_track == g_CurrentTrackSegment ) break;
		}

	ActiveScreen->SetModify();
}
int WinEDA_BasePcbFrame::ReadListeSegmentDescr(wxDC * DC, FILE * File,
									TRACK * PtSegm,int StructType,
									int * LineNum, int NumSegm)
/**********************************************************************/
/* Lecture de la description d'une liste de segments (Tracks, zones)
	Retourne:
		si ok nombre d'items lus.
		si pas de fin de block ($..) - nombre.
*/
{
int shape, width, layer, type, flags, net_code;
int ii = 0, PerCent, Pas;
char Line[256];
TRACK * NewTrack;

	PerCent = 0; Pas = NumSegm / 99;
#ifdef PCBNEW
	switch ( StructType )
		{
		case TYPETRACK:
		case TYPEVIA:
			DisplayActivity(PerCent, wxT("Tracks:") );
			break;

		case TYPEZONE:
			DisplayActivity(PerCent, wxT("Zones:") );
			break;
		}
#endif
	while( GetLine(File, Line, LineNum ) )
		{
		if(Line[0] == '$')
			{
			return(ii);		/* fin de liste OK */
			}

		 switch ( StructType )
			 {
			 default:
			 case TYPETRACK: NewTrack = new TRACK( m_Pcb );
				 break;
			 case TYPEVIA: NewTrack = new SEGVIA( m_Pcb );
				 break;
			 case TYPEZONE: NewTrack = new SEGZONE( m_Pcb );
				 break;
			 }
		NewTrack->Insert(m_Pcb, PtSegm); PtSegm = NewTrack;

		int arg_count = sscanf( Line+2," %d %d %d %d %d %d %d",&shape,
				&PtSegm->m_Start.x, &PtSegm->m_Start.y,
				&PtSegm->m_End.x, &PtSegm->m_End.y, &width,
				& PtSegm->m_Drill);

		PtSegm->m_Width = width; PtSegm->m_Shape = shape;
		if ( arg_count < 7 ) PtSegm->m_Drill = -1;

		if( GetLine(File, Line, LineNum ) == NULL ) break;
		if(Line[0] == '$') break;

		sscanf( Line+2," %d %d %d %lX %X", &layer, &type,&net_code,
									&PtSegm->m_TimeStamp, &flags);
		if ( type == 1 ) PtSegm->m_StructType = TYPEVIA;
		PtSegm->m_Layer = layer;
		PtSegm->m_NetCode = net_code; PtSegm->SetState(flags, ON);
#ifdef PCBNEW
		PtSegm->Draw(DrawPanel, DC, GR_OR);
#endif
		ii++;
		if( ( Pas && (ii % Pas ) == 0) )
			{
			PerCent ++;
#ifdef PCBNEW
			switch ( StructType )
				{
				case TYPETRACK:
				case TYPEVIA:
					DisplayActivity(PerCent, wxT("Tracks:") );
					break;

				case TYPEZONE:
					DisplayActivity(PerCent, wxT("Zones:") );
					break;
				}
#endif
			}
		}
	DisplayError(this, _("Error: Unexpected end of file !") );
	return(-ii);
}