Commit b9b8bf2f authored by charras's avatar charras
Browse files

In zones filling better shape around rectangular pads (patch from Vesa Solonen)

parent 3c27f847
Loading
Loading
Loading
Loading
+131 −89
Original line number Original line Diff line number Diff line
@@ -346,27 +346,52 @@ void AddPadWithClearancePolygon( Bool_Engine* aBooleng,
            break;
            break;
        }
        }


    case PAD_RECT:
    case PAD_RECT:					// Easy implementation for rectangular cutouts with rounded corners
		angle = aPad.m_Orient;
		angle = aPad.m_Orient;
        corner_position = wxPoint( -dx, -dy );
		int rounding_radius = (int) (aClearanceValue * s_Correction);			// Corner rounding radius
        RotatePoint( &corner_position, angle );
		int angle_pg;															// Polygon increment angle
        corner_position += PadShapePos;
        aBooleng->AddPoint( corner_position.x, corner_position.y );
 
 
        corner_position = wxPoint( -dx, +dy );
		for( int i = 0; i < s_CircleToSegmentsCount / 4 + 1; i++ )
			{
				corner_position = wxPoint( 0, -rounding_radius );
				angle_pg = i * delta;
				RotatePoint( &corner_position, angle_pg );						// Rounding vector rotation
				corner_position -= aPad.m_Size/2 ;								// Rounding vector + Pad corner offset
				RotatePoint( &corner_position, angle );							// Rotate according to module orientation
				corner_position +=	PadShapePos;								// Shift origin to position
				aBooleng->AddPoint( corner_position.x, corner_position.y );
			}
		for( int i = 0; i < s_CircleToSegmentsCount / 4 + 1; i++ )
			{
				corner_position = wxPoint( -rounding_radius, 0 );
				angle_pg = i * delta;
				RotatePoint( &corner_position, angle_pg );
				corner_position -= wxPoint( aPad.m_Size.x/2, -aPad.m_Size.y/2 );
				RotatePoint( &corner_position, angle );
				RotatePoint( &corner_position, angle );
        corner_position += aPad.ReturnShapePos();
				corner_position +=	PadShapePos;
				aBooleng->AddPoint( corner_position.x, corner_position.y );
				aBooleng->AddPoint( corner_position.x, corner_position.y );

			}
        corner_position = wxPoint( +dx, +dy );
		for( int i = 0; i < s_CircleToSegmentsCount / 4 + 1; i++ )
			{
				corner_position = wxPoint( 0, rounding_radius );
				angle_pg = i * delta;
				RotatePoint( &corner_position, angle_pg );
				corner_position += aPad.m_Size/2 ;
				RotatePoint( &corner_position, angle );
				RotatePoint( &corner_position, angle );
				corner_position +=	PadShapePos;
				corner_position +=	PadShapePos;
				aBooleng->AddPoint( corner_position.x, corner_position.y );
				aBooleng->AddPoint( corner_position.x, corner_position.y );

			}
        corner_position = wxPoint( +dx, -dy );
		for( int i = 0; i < s_CircleToSegmentsCount / 4 + 1; i++ )
			{
				corner_position = wxPoint( rounding_radius, 0 );
				angle_pg = i * delta;
				RotatePoint( &corner_position, angle_pg );
				corner_position -= wxPoint( -aPad.m_Size.x/2, aPad.m_Size.y/2 );
				RotatePoint( &corner_position, angle );
				RotatePoint( &corner_position, angle );
				corner_position +=	PadShapePos;
				corner_position +=	PadShapePos;
				aBooleng->AddPoint( corner_position.x, corner_position.y );
				aBooleng->AddPoint( corner_position.x, corner_position.y );
			}
			
		break;
		break;
	}
	}


@@ -376,7 +401,7 @@ void AddPadWithClearancePolygon( Bool_Engine* aBooleng,


/** function AddThermalReliefPadPolygon
/** function AddThermalReliefPadPolygon
 * Add holes around a pad to create a thermal relief
 * Add holes around a pad to create a thermal relief
 * copper tickness is min (dx/2, aCopperWitdh) or min (dy/2, aCopperWitdh)
 * copper thickness is min (dx/2, aCopperWitdh) or min (dy/2, aCopperWitdh)
 * @param aBooleng = current Bool_Engine
 * @param aBooleng = current Bool_Engine
 * @param aPad     = the current pad used to create the thermal shape
 * @param aPad     = the current pad used to create the thermal shape
 * @param aThermalGap = gap in thermal shape
 * @param aThermalGap = gap in thermal shape
@@ -417,7 +442,7 @@ void AddThermalReliefPadPolygon( Bool_Engine* aBooleng,
    wxPoint PadShapePos = aPad.ReturnShapePos();    /* Note: for pad having a shape offset,
    wxPoint PadShapePos = aPad.ReturnShapePos();    /* Note: for pad having a shape offset,
                                                     * the pad position is NOT the shape position */
                                                     * the pad position is NOT the shape position */
    int     angle = 0;
    int     angle = 0;
    wxSize  copper_tickness;
    wxSize  copper_thickness;
    int     dx = aPad.m_Size.x / 2;
    int     dx = aPad.m_Size.x / 2;
    int     dy = aPad.m_Size.y / 2;
    int     dy = aPad.m_Size.y / 2;


@@ -430,15 +455,15 @@ void AddThermalReliefPadPolygon( Bool_Engine* aBooleng,
    aThermalGap += aMinThicknessValue / 2;
    aThermalGap += aMinThicknessValue / 2;


    /* Keep in account the polygon outline thickness
    /* Keep in account the polygon outline thickness
     * copper_tickness must be decreased by aMinThicknessValue because drawing outlines
     * copper_thickness must be decreased by aMinThicknessValue because drawing outlines
     * with a thickness of aMinThicknessValue will increase real thickness by aMinThicknessValue
     * with a thickness of aMinThicknessValue will increase real thickness by aMinThicknessValue
     */
     */
    aCopperThickness -= aMinThicknessValue;
    aCopperThickness -= aMinThicknessValue;
    if( aCopperThickness < 0 )
    if( aCopperThickness < 0 )
        aCopperThickness = 0;
        aCopperThickness = 0;


    copper_tickness.x = min( dx, aCopperThickness );
    copper_thickness.x = min( dx, aCopperThickness );
    copper_tickness.y = min( dy, aCopperThickness );
    copper_thickness.y = min( dy, aCopperThickness );


    switch( aPad.m_PadShape )
    switch( aPad.m_PadShape )
    {
    {
@@ -464,16 +489,16 @@ void AddThermalReliefPadPolygon( Bool_Engine* aBooleng,
        int outer_radius = dx + aThermalGap;     // The radius of the outer arc is pad radius + aThermalGap
        int outer_radius = dx + aThermalGap;     // The radius of the outer arc is pad radius + aThermalGap


        // Crosspoint of thermal spoke sides, the first point of polygon buffer
        // Crosspoint of thermal spoke sides, the first point of polygon buffer
        corners_buffer.push_back( wxPoint( copper_tickness.x / 2, copper_tickness.y / 2 ) );
        corners_buffer.push_back( wxPoint( copper_thickness.x / 2, copper_thickness.y / 2 ) );


        // Add an intermediate point on spoke sides, to allow a > 90 deg angle between side and first seg of arc approx
        // Add an intermediate point on spoke sides, to allow a > 90 deg angle between side and first seg of arc approx
        corner.x = copper_tickness.x / 2;
        corner.x = copper_thickness.x / 2;
        int y = outer_radius - (aThermalGap / 4);
        int y = outer_radius - (aThermalGap / 4);
        corner.y = (int) sqrt( ( ( (double) y * y ) - (double) corner.x * corner.x ) );
        corner.y = (int) sqrt( ( ( (double) y * y ) - (double) corner.x * corner.x ) );
        corners_buffer.push_back( corner );
        corners_buffer.push_back( corner );


        // calculate the starting point of the outter arc
        // calculate the starting point of the outter arc
        corner.x = copper_tickness.x / 2;
        corner.x = copper_thickness.x / 2;
        double dtmp =
        double dtmp =
            sqrt( ( (double) outer_radius * outer_radius ) - ( (double) corner.x * corner.x ) );
            sqrt( ( (double) outer_radius * outer_radius ) - ( (double) corner.x * corner.x ) );
        corner.y = (int) dtmp;
        corner.y = (int) dtmp;
@@ -543,7 +568,7 @@ void AddThermalReliefPadPolygon( Bool_Engine* aBooleng,
        {
        {
            EXCHG( dx, dy );
            EXCHG( dx, dy );
            supp_angle = 900;
            supp_angle = 900;
            EXCHG( copper_tickness.x, copper_tickness.y );
            EXCHG( copper_thickness.x, copper_thickness.y );
        }
        }
        int deltasize = dx - dy;        // = distance between shape position and the 2 demi-circle ends centre
        int deltasize = dx - dy;        // = distance between shape position and the 2 demi-circle ends centre
        // here we have dx > dy
        // here we have dx > dy
@@ -554,12 +579,12 @@ void AddThermalReliefPadPolygon( Bool_Engine* aBooleng,
        shape_offset = wxPoint( deltasize, 0 );
        shape_offset = wxPoint( deltasize, 0 );


        // Crosspoint of thermal spoke sides, the first point of polygon buffer
        // Crosspoint of thermal spoke sides, the first point of polygon buffer
        corners_buffer.push_back( wxPoint( copper_tickness.x / 2, copper_tickness.y / 2 ) );
        corners_buffer.push_back( wxPoint( copper_thickness.x / 2, copper_thickness.y / 2 ) );


        // Arc start point calculation, the intersecting point of cutout arc and thermal spoke edge
        // Arc start point calculation, the intersecting point of cutout arc and thermal spoke edge
        if( copper_tickness.x > deltasize )          // If copper thickness is more than shape offset, we need to calculate arc intercept point.
        if( copper_thickness.x > deltasize )          // If copper thickness is more than shape offset, we need to calculate arc intercept point.
        {
        {
            corner.x = copper_tickness.x / 2;
            corner.x = copper_thickness.x / 2;
            corner.y =
            corner.y =
                (int) sqrt( ( (double) outer_radius * outer_radius ) -
                (int) sqrt( ( (double) outer_radius * outer_radius ) -
                    ( (double) ( corner.x - delta ) * ( corner.x - deltasize ) ) );
                    ( (double) ( corner.x - delta ) * ( corner.x - deltasize ) ) );
@@ -575,21 +600,21 @@ void AddThermalReliefPadPolygon( Bool_Engine* aBooleng,
        }
        }
        else
        else
        {
        {
            corner.x = copper_tickness.x / 2;
            corner.x = copper_thickness.x / 2;
            corner.y = outer_radius;
            corner.y = outer_radius;
            corners_buffer.push_back( corner );
            corners_buffer.push_back( corner );
            corner.x = ( deltasize - copper_tickness.x ) / 2;
            corner.x = ( deltasize - copper_thickness.x ) / 2;
        }
        }


        // Add an intermediate point on spoke sides, to allow a > 90 deg angle between side and first seg of arc approx
        // Add an intermediate point on spoke sides, to allow a > 90 deg angle between side and first seg of arc approx
        wxPoint last_corner;
        wxPoint last_corner;
        last_corner.y = copper_tickness.y / 2;
        last_corner.y = copper_thickness.y / 2;
        int     px = outer_radius - (aThermalGap / 4);
        int     px = outer_radius - (aThermalGap / 4);
        last_corner.x =
        last_corner.x =
            (int) sqrt( ( ( (double) px * px ) - (double) last_corner.y * last_corner.y ) );
            (int) sqrt( ( ( (double) px * px ) - (double) last_corner.y * last_corner.y ) );


        // Arc stop point calculation, the intersecting point of cutout arc and thermal spoke edge
        // Arc stop point calculation, the intersecting point of cutout arc and thermal spoke edge
        corner_end.y = copper_tickness.y / 2;
        corner_end.y = copper_thickness.y / 2;
        corner_end.x =
        corner_end.x =
            (int) sqrt( ( (double) outer_radius *
            (int) sqrt( ( (double) outer_radius *
                         outer_radius ) - ( (double) corner_end.y * corner_end.y ) );
                         outer_radius ) - ( (double) corner_end.y * corner_end.y ) );
@@ -680,26 +705,42 @@ void AddThermalReliefPadPolygon( Bool_Engine* aBooleng,
        //  |        |
        //  |        |
        //  |        |
        //  |        |
        // 1  -------4
        // 1  -------4
        wxPoint corners_hole[4];            // buffer for 4 corners
        // Create 1 hole, for a pad centered at 0,0, orient 0
        // Calculate coordinates for corner 1 to corner 4:
        corners_hole[0] = wxPoint( copper_tickness.x / 2, -copper_tickness.y / 2 );
        corners_hole[1] = wxPoint( (copper_tickness.x / 2), -dy - aThermalGap );
        corners_hole[2] = wxPoint(   dx + aThermalGap, -dy - aThermalGap );
        corners_hole[3] = wxPoint( dx + aThermalGap, -(copper_tickness.y / 2) );
        
        
        /* Create 2 holes, rotated by pad rotation.
        // Modified rectangles with one corner rounded. TODO: merging with oval thermals and possibly round too.
         */
        
        std::vector <wxPoint> corners_buffer;               // Polygon buffer as vector

        int     dx = (aPad.m_Size.x / 2) + aThermalGap;     // Cutout radius x
        int     dy = (aPad.m_Size.y / 2) + aThermalGap;     // Cutout radius y
        
		// The first point of polygon buffer is left lower corner, second the crosspoint of thermal spoke sides,
		// the third is upper right corner and the rest are rounding vertices going anticlockwise. Note the inveted Y-axis in CG.
		corners_buffer.push_back( wxPoint( -dx, -copper_thickness.y / 2 ) );
		corners_buffer.push_back( wxPoint( -copper_thickness.x / 2, -copper_thickness.y / 2 ) );
		corners_buffer.push_back( wxPoint( -copper_thickness.x / 2, -dy ) );
		
		angle = aPad.m_Orient;
		angle = aPad.m_Orient;
		int rounding_radius = (int) (aThermalGap * s_Correction);				// Corner rounding radius
		int angle_pg;															// Polygon increment angle

		for( int i = 0; i < s_CircleToSegmentsCount / 4 + 1; i++ )
			{
				wxPoint corner_position = wxPoint( 0, -rounding_radius );
				angle_pg = i * delta;
				RotatePoint( &corner_position, angle_pg );						// Rounding vector rotation
				corner_position -= aPad.m_Size/2 ;								// Rounding vector + Pad corner offset
				corners_buffer.push_back( wxPoint( corner_position.x, corner_position.y ) );
			}

		for( int irect = 0; irect < 2; irect++ )
		for( int irect = 0; irect < 2; irect++ )
		{
		{
			if( aBooleng->StartPolygonAdd( GROUP_B ) )
			if( aBooleng->StartPolygonAdd( GROUP_B ) )
			{
			{
                for( int ic = 0; ic < 4; ic++ )
				for( unsigned ic = 0; ic < corners_buffer.size(); ic++ )
				{
				{
                    wxPoint cpos = corners_hole[ic];
					wxPoint cpos = corners_buffer[ic];
                    RotatePoint( &cpos, angle );
					RotatePoint( &cpos, angle );								// Rotate according to module orientation
                    cpos += PadShapePos;
					cpos += PadShapePos;										// Shift origin to position
					aBooleng->AddPoint( cpos.x, cpos.y );
					aBooleng->AddPoint( cpos.x, cpos.y );
				}
				}


@@ -710,21 +751,22 @@ void AddThermalReliefPadPolygon( Bool_Engine* aBooleng,
			}
			}
		}
		}


        // Create a holes, that is the mirrored of the previous hole
		// Create holes, that are the mirrored from the previous holes
        corners_hole[0].x = -corners_hole[0].x;
        for( unsigned ic = 0; ic < corners_buffer.size(); ic++ )
        corners_hole[1].x = -corners_hole[1].x;
        {
        corners_hole[2].x = -corners_hole[2].x;
            wxPoint swap = corners_buffer[ic];
        corners_hole[3].x = -corners_hole[3].x;
            swap.x = -swap.x;
            corners_buffer[ic] = swap;
        }


        // Now add corner 4 and 2 (2 is the corner 4 rotated by 180 deg
        // Now add corner 4 and 2 (2 is the corner 4 rotated by 180 deg
        angle = aPad.m_Orient;
        for( int irect = 0; irect < 2; irect++ )
        for( int irect = 0; irect < 2; irect++ )
        {
        {
            if( aBooleng->StartPolygonAdd( GROUP_B ) )
            if( aBooleng->StartPolygonAdd( GROUP_B ) )
            {
            {
                for( int ic = 0; ic < 4; ic++ )
                for( unsigned ic = 0; ic < corners_buffer.size(); ic++ )
                {
                {
                    wxPoint cpos = corners_hole[ic];
					wxPoint cpos = corners_buffer[ic];
					RotatePoint( &cpos, angle );
					RotatePoint( &cpos, angle );
					cpos += PadShapePos;
					cpos += PadShapePos;
					aBooleng->AddPoint( cpos.x, cpos.y );
					aBooleng->AddPoint( cpos.x, cpos.y );
@@ -736,10 +778,10 @@ void AddThermalReliefPadPolygon( Bool_Engine* aBooleng,
					angle -= 3600;
					angle -= 3600;
			}
			}
		}
		}
    }
		break;
		break;
		}
		}
	}
	}
}
	
	


/** Function AddTrackWithClearancePolygon
/** Function AddTrackWithClearancePolygon