Exemplo n.º 1
0
bool D_PAD::HitTest( const wxPoint& aPosition )
{
    int     dx, dy;
    double  dist;

    wxPoint shape_pos = ReturnShapePos();

    wxPoint delta = aPosition - shape_pos;

    // first test: a test point must be inside a minimum sized bounding circle.
    int radius = GetBoundingRadius();

    if( ( abs( delta.x ) > radius ) || ( abs( delta.y ) > radius ) )
        return false;

    dx = m_Size.x >> 1; // dx also is the radius for rounded pads
    dy = m_Size.y >> 1;

    switch( m_PadShape & 0x7F )
    {
    case PAD_CIRCLE:
        dist = hypot( delta.x, delta.y );

        if( KiROUND( dist ) <= dx )
            return true;

        break;

    case PAD_TRAPEZOID:
    {
        wxPoint poly[4];
        BuildPadPolygon( poly, wxSize(0,0), 0 );
        RotatePoint( &delta, -m_Orient );
        return TestPointInsidePolygon( poly, 4, delta );
    }

    default:
        RotatePoint( &delta, -m_Orient );

        if( (abs( delta.x ) <= dx ) && (abs( delta.y ) <= dy) )
            return true;

        break;
    }

    return false;
}
Exemplo n.º 2
0
void D_PAD::DrawShape( EDA_RECT* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo )
{
    wxPoint coord[4];
    int     delta_cx, delta_cy;
    int     angle = m_Orient;
    int     seg_width;

    GRSetDrawMode( aDC, aDrawInfo.m_DrawMode );

    // calculate pad shape position :
    wxPoint shape_pos = ReturnShapePos() - aDrawInfo.m_Offset;

    wxSize  halfsize = m_Size;
    halfsize.x >>= 1;
    halfsize.y >>= 1;

    switch( GetShape() )
    {
    case PAD_CIRCLE:
        if( aDrawInfo.m_ShowPadFilled )
            GRFilledCircle( aClipBox, aDC, shape_pos.x, shape_pos.y,
                            halfsize.x + aDrawInfo.m_Mask_margin.x, 0,
                            aDrawInfo.m_Color, aDrawInfo.m_Color );
        else
            GRCircle( aClipBox, aDC, shape_pos.x, shape_pos.y,
                      halfsize.x + aDrawInfo.m_Mask_margin.x,
                      m_PadSketchModePenSize, aDrawInfo.m_Color );

        if( aDrawInfo.m_PadClearance )
        {
            GRCircle( aClipBox,
                      aDC, shape_pos.x, shape_pos.y,
                      halfsize.x + aDrawInfo.m_PadClearance,
                      0,
                      aDrawInfo.m_Color );
        }

        break;

    case PAD_OVAL:
    {
        wxPoint segStart, segEnd;
        seg_width = BuildSegmentFromOvalShape(segStart, segEnd, angle);
        segStart += shape_pos;
        segEnd += shape_pos;

        if( aDrawInfo.m_ShowPadFilled )
        {
            GRFillCSegm( aClipBox, aDC, segStart.x, segStart.y, segEnd.x, segEnd.y,
                         seg_width, aDrawInfo.m_Color );
        }
        else
        {
            GRCSegm( aClipBox, aDC, segStart.x, segStart.y, segEnd.x, segEnd.y,
                     seg_width, m_PadSketchModePenSize, aDrawInfo.m_Color );
        }

        /* Draw the isolation line. */
        if( aDrawInfo.m_PadClearance )
        {
            seg_width += 2 * aDrawInfo.m_PadClearance;
            GRCSegm( aClipBox, aDC, segStart.x, segStart.y, segEnd.x, segEnd.y,
                     seg_width, aDrawInfo.m_Color );
        }
    }
        break;

    case PAD_RECT:
    case PAD_TRAPEZOID:
        BuildPadPolygon( coord, aDrawInfo.m_Mask_margin, angle );

        for( int ii = 0; ii < 4; ii++ )
            coord[ii] += shape_pos;

        GRClosedPoly( aClipBox, aDC, 4, coord, aDrawInfo.m_ShowPadFilled,
                      aDrawInfo.m_ShowPadFilled ? 0 : m_PadSketchModePenSize,
                      aDrawInfo.m_Color, aDrawInfo.m_Color );

        if( aDrawInfo.m_PadClearance )
        {
            BuildPadPolygon( coord, wxSize( aDrawInfo.m_PadClearance,
                                            aDrawInfo.m_PadClearance ), angle );
            for( int ii = 0; ii < 4; ii++ )
                coord[ii] += shape_pos;

            GRClosedPoly( aClipBox, aDC, 4, coord, 0, aDrawInfo.m_Color, aDrawInfo.m_Color );
        }
        break;


    default:
        break;
    }

    /* Draw the pad hole */
    wxPoint holepos = m_Pos - aDrawInfo.m_Offset;
    int     hole    = m_Drill.x >> 1;

    bool drawhole = hole > 0;

    if( !aDrawInfo.m_ShowPadFilled && !aDrawInfo. m_ShowNotPlatedHole )
        drawhole = false;

    if( drawhole )
    {
        bool blackpenstate = false;

        if( aDrawInfo.m_IsPrinting )
        {
            blackpenstate = GetGRForceBlackPenState();
            GRForceBlackPen( false );
            aDrawInfo.m_HoleColor = g_DrawBgColor;
        }

        if( aDrawInfo.m_DrawMode != GR_XOR )
            GRSetDrawMode( aDC, GR_COPY );
        else
            GRSetDrawMode( aDC, GR_XOR );

        int hole_color = aDrawInfo.m_HoleColor;

        if( aDrawInfo. m_ShowNotPlatedHole )    // Draw a specific hole color
            hole_color = aDrawInfo.m_NPHoleColor;

        switch( m_DrillShape )
        {
        case PAD_CIRCLE:
            if( aDC->LogicalToDeviceXRel( hole ) > 1 )
                GRFilledCircle( aClipBox, aDC, holepos.x, holepos.y, hole, 0,
                                aDrawInfo.m_Color, hole_color );
            break;

        case PAD_OVAL:
            halfsize.x = m_Drill.x >> 1;
            halfsize.y = m_Drill.y >> 1;

            if( m_Drill.x > m_Drill.y )  /* horizontal */
            {
                delta_cx = halfsize.x - halfsize.y;
                delta_cy = 0;
                seg_width    = m_Drill.y;
            }
            else                         /* vertical */
            {
                delta_cx = 0;
                delta_cy = halfsize.y - halfsize.x;
                seg_width    = m_Drill.x;
            }

            RotatePoint( &delta_cx, &delta_cy, angle );

            GRFillCSegm( aClipBox, aDC, holepos.x + delta_cx, holepos.y + delta_cy,
                         holepos.x - delta_cx, holepos.y - delta_cy, seg_width,
                         hole_color );
            break;

        default:
            break;
        }

        if( aDrawInfo.m_IsPrinting )
            GRForceBlackPen( blackpenstate );
    }

    GRSetDrawMode( aDC, aDrawInfo.m_DrawMode );

    /* Draw "No connect" ( / or \ or cross X ) if necessary. : */
    if( m_Netname.IsEmpty() && aDrawInfo.m_ShowNCMark )
    {
        int dx0 = MIN( halfsize.x, halfsize.y );
        int nc_color = BLUE;

        if( m_layerMask & LAYER_FRONT )    /* Draw \ */
            GRLine( aClipBox, aDC, holepos.x - dx0, holepos.y - dx0,
                    holepos.x + dx0, holepos.y + dx0, 0, nc_color );

        if( m_layerMask & LAYER_BACK ) /* Draw / */
            GRLine( aClipBox, aDC, holepos.x + dx0, holepos.y - dx0,
                    holepos.x - dx0, holepos.y + dx0, 0, nc_color );
    }

    /* Draw the pad number */
    if( !aDrawInfo.m_Display_padnum && !aDrawInfo.m_Display_netname )
        return;

    wxPoint tpos0 = shape_pos;     // Position of the centre of text
    wxPoint tpos  = tpos0;
    wxSize  AreaSize;              // size of text area, normalized to AreaSize.y < AreaSize.x
    int     shortname_len = m_ShortNetname.Len();

    if( !aDrawInfo.m_Display_netname )
        shortname_len = 0;

    if( GetShape() == PAD_CIRCLE )
        angle = 0;

    AreaSize = m_Size;

    if( m_Size.y > m_Size.x )
    {
        angle += 900;
        AreaSize.x = m_Size.y;
        AreaSize.y = m_Size.x;
    }

    if( shortname_len > 0 )       // if there is a netname, provides room to display this netname
    {
        AreaSize.y /= 2;          // Text used only the upper area of the
                                  // pad. The lower area displays the net name
        tpos.y -= AreaSize.y / 2;
    }

    // Calculate the position of text, that is the middle point of the upper
    // area of the pad
    RotatePoint( &tpos, shape_pos, angle );

    /* Draw text with an angle between -90 deg and + 90 deg */
    int t_angle = angle;
    NORMALIZE_ANGLE_90( t_angle );

    /* Note: in next calculations, texte size is calculated for 3 or more
     * chars.  Of course, pads numbers and nets names can have less than 3
     * chars. but after some tries, i found this is gives the best look
     */
    #define MIN_CHAR_COUNT 3
    wxString buffer;

    int      tsize;

    if( aDrawInfo.m_Display_padnum )
    {
        ReturnStringPadName( buffer );
        int numpad_len = buffer.Len();
        numpad_len = MAX( numpad_len, MIN_CHAR_COUNT );

        tsize = min( AreaSize.y, AreaSize.x / numpad_len );
        #define CHAR_SIZE_MIN 5

        if( aDC->LogicalToDeviceXRel( tsize ) >= CHAR_SIZE_MIN ) // Not drawable when size too small.
        {
            // tsize reserve room for marges and segments thickness
            tsize = (int) ( tsize * 0.8 );
            DrawGraphicText( aDrawInfo.m_DrawPanel, aDC, tpos, WHITE, buffer, t_angle,
                             wxSize( tsize, tsize ), GR_TEXT_HJUSTIFY_CENTER,
                             GR_TEXT_VJUSTIFY_CENTER, tsize / 7, false, false );
        }
    }

    // display the short netname, if exists
    if( shortname_len == 0 )
        return;

    shortname_len = MAX( shortname_len, MIN_CHAR_COUNT );
    tsize = min( AreaSize.y, AreaSize.x / shortname_len );

    if( aDC->LogicalToDeviceXRel( tsize ) >= CHAR_SIZE_MIN )  // Not drawable in size too small.
    {
        tpos = tpos0;

        if( aDrawInfo.m_Display_padnum )
            tpos.y += AreaSize.y / 2;

        RotatePoint( &tpos, shape_pos, angle );

        // tsize reserve room for marges and segments thickness
        tsize = (int) ( tsize * 0.8 );
        DrawGraphicText( aDrawInfo.m_DrawPanel, aDC, tpos, WHITE, m_ShortNetname, t_angle,
                         wxSize( tsize, tsize ), GR_TEXT_HJUSTIFY_CENTER,
                         GR_TEXT_VJUSTIFY_CENTER, tsize / 7, false, false );
    }
}
Exemplo n.º 3
0
void D_PAD::Draw3D(Pcb3D_GLCanvas * glcanvas)
/***********************************************/
/* Dessin 3D des pads avec leur trou de percage
*/
{
int ii, ll, layer, nlmax;
int	ux0,uy0,
	dx,dx0,dy,dy0,
	delta_cx, delta_cy,
	xc, yc;
int angle, delta_angle;
int coord[4][2];
double fcoord[8][2], f_hole_coord[8][2];
float scale;
double zpos;
wxPoint shape_pos;
double x, y, r, w, hole;
double drillx, drilly;
bool Oncu, Oncmp, Both;
int color;

	scale = g_Parm_3D_Visu.m_BoardScale;
	hole = (double)m_Drill * scale / 2;

	/* calcul du centre des formes des pads : */
    shape_pos = ReturnShapePos();
	ux0 = shape_pos.x;
	uy0 = shape_pos.y;
	xc = ux0;
	yc = uy0;

	/* le trace depend de la rotation de l'empreinte */
	dx = dx0 = m_Size.x >> 1 ;
	dy = dy0 = m_Size.y >> 1 ; /* demi dim  dx et dy */

	angle = m_Orient;
	drillx = m_Pos.x  * scale;
	drilly = m_Pos.y * scale;
	/* trace du trou de percage */
	if ( m_Drill )
	{
		SetGLColor(DARKGRAY);
		Draw3D_FilledCylinder(drillx, -drilly, hole, g_Parm_3D_Visu.m_LayerZcoord[CMP_N], 0.0);
	}

 	glNormal3f( 0.0, 0.0, 1.0);	// Normal is Z axis
	nlmax = g_Parm_3D_Visu.m_Layers-1;
	Oncu = (m_Masque_Layer & CUIVRE_LAYER) ? TRUE : FALSE;
	Oncmp = (m_Masque_Layer & CMP_LAYER) ? TRUE : FALSE;
	Both = Oncu && Oncmp;
	switch (m_PadShape & 0x7F)
		{
		case CIRCLE :
			x = xc * scale;
			y = yc * scale;
			r = (double)dx * scale;
			for ( layer = CUIVRE_N; layer <= CMP_N; layer ++)
			{
				if (layer && (layer == nlmax) ) layer = CMP_N;
				if ( (layer == CMP_N) && ! Oncmp ) continue;
				if ( (layer == CUIVRE_N) && ! Oncu ) continue;
				if ( (layer > CUIVRE_N) && (layer < CMP_N) && !Both) continue;
				color = g_Parm_3D_Visu.m_BoardSettings->m_LayerColor[layer];
				if ( color & ITEM_NOT_SHOW ) continue;
				SetGLColor(color);
				glNormal3f( 0.0, 0.0, (layer == CUIVRE_N) ? -1.0 : 1.0);
				zpos = g_Parm_3D_Visu.m_LayerZcoord[layer];
				Draw3D_FilledCircle(x, -y, r, hole, zpos);
			}
			break;

		case OVALE :
			/* calcul de l'entraxe de l'ellipse */
			if( dx > dy )	/* ellipse horizontale */
				{
				delta_cx = dx - dy; delta_cy = 0;
				w = m_Size.y * scale;
				delta_angle = angle+900;
				}
			else			/* ellipse verticale */
				{
				delta_cx = 0; delta_cy = dy - dx;
				w = m_Size.x * scale;
				delta_angle = angle;
				}
			RotatePoint(&delta_cx, &delta_cy, angle);
			{
			double ox, oy, fx, fy;
			ox = (double)(ux0 + delta_cx) * scale;
			oy = (double)(uy0 + delta_cy) * scale;
			fx = (double)(ux0 - delta_cx) * scale;
			fy = (double)(uy0 - delta_cy) * scale;
			for ( layer = CUIVRE_N; layer <= CMP_N; layer ++)
			{
				if (layer && (layer == nlmax) ) layer = CMP_N;
				if ( (layer == CMP_N) && ! Oncmp ) continue;
				if ( (layer == CUIVRE_N) && ! Oncu ) continue;
				if ( (layer > CUIVRE_N) && (layer < CMP_N) && !Both) continue;
				color = g_Parm_3D_Visu.m_BoardSettings->m_LayerColor[layer];
				glNormal3f( 0.0, 0.0, (layer == CUIVRE_N) ? -1.0 : 1.0);
				if ( color & ITEM_NOT_SHOW ) continue;
				SetGLColor(color);
				zpos = g_Parm_3D_Visu.m_LayerZcoord[layer];
				Draw3D_FilledSegmentWithHole(ox, -oy, fx, -fy, w, drillx, -drilly, hole, zpos);
			}
			}
			break;

		case RECT :
		case SPECIAL_PAD:
		case TRAPEZE:
			{
			int ddx, ddy ;
			ddx = m_DeltaSize.x >> 1 ;
			ddy = m_DeltaSize.y >> 1 ; /* demi dim  dx et dy */

			 coord[0][0] = - dx - ddy;
			 coord[0][1] = + dy + ddx;

			 coord[1][0] = - dx + ddy;
			 coord[1][1] = - dy - ddx;

			 coord[2][0] = + dx - ddy;
			 coord[2][1] = - dy + ddx;

			 coord[3][0] = + dx + ddy;
			 coord[3][1] = + dy - ddx;

			for (ii = 0; ii < 4; ii++)
				{
				RotatePoint(&coord[ii][0],&coord[ii][1], angle);
				coord[ii][0] += ux0;
				coord[ii][1] += uy0;
				ll = ii*2;
				fcoord[ll][0] = coord[ii][0] * scale;
				fcoord[ll][1] = coord[ii][1] * scale;
				}
			for (ii = 0; ii < 7; ii+=2)
				{
				ll = ii+2; if (ll > 7) ll -= 8;
				fcoord[ii+1][0] = (fcoord[ii][0] + fcoord[ll][0])/2;
				fcoord[ii+1][1] = (fcoord[ii][1] + fcoord[ll][1])/2;
				}
			for (ii = 0; ii < 8; ii++)
				{
				f_hole_coord[ii][0] = -hole*0.707;
				f_hole_coord[ii][1] = hole*0.707;
				RotatePoint(&f_hole_coord[ii][0], &f_hole_coord[ii][1],
					angle -(ii * 450) );
				f_hole_coord[ii][0] += drillx;
				f_hole_coord[ii][1] += drilly;
				}

			for ( layer = CUIVRE_N; layer <= CMP_N; layer ++)
			{
				if (layer && (layer == nlmax) ) layer = CMP_N;
				if ( (layer == CMP_N) && ! Oncmp ) continue;
				if ( (layer == CUIVRE_N) && ! Oncu ) continue;
				if ( (layer > CUIVRE_N) && (layer < CMP_N) && !Both) continue;
				color = g_Parm_3D_Visu.m_BoardSettings->m_LayerColor[layer];
				glNormal3f( 0.0, 0.0, (layer == CUIVRE_N) ? -1.0 : 1.0);
				if ( color & ITEM_NOT_SHOW ) continue;
				SetGLColor(color);
				zpos = g_Parm_3D_Visu.m_LayerZcoord[layer];
				glBegin(GL_QUAD_STRIP);
				for ( ii = 0; ii < 8; ii++ )
				{
					glVertex3f( f_hole_coord[ii][0], -f_hole_coord[ii][1] , zpos);
					glVertex3f( fcoord[ii][0], -fcoord[ii][1] , zpos);
				}
				glVertex3f( f_hole_coord[0][0], -f_hole_coord[0][1] , zpos);
				glVertex3f( fcoord[0][0], -fcoord[0][1] , zpos);
				glEnd();
			}
			break;

			default:
				break;
			}
		}

}