summaryrefslogtreecommitdiff
path: root/pcbnew/zones_convert_to_polygons_aux_functions.cpp
diff options
context:
space:
mode:
authorsaurabhb172020-02-26 15:57:49 +0530
committersaurabhb172020-02-26 15:57:49 +0530
commitaa35045840b78d3f48212db45da59a2e5c69b223 (patch)
tree6acee185a4dc19113fcbf0f9a3d6941085dedaf7 /pcbnew/zones_convert_to_polygons_aux_functions.cpp
parent0db48f6533517ecebfd9f0693f89deca28408b76 (diff)
downloadKiCad-eSim-aa35045840b78d3f48212db45da59a2e5c69b223.tar.gz
KiCad-eSim-aa35045840b78d3f48212db45da59a2e5c69b223.tar.bz2
KiCad-eSim-aa35045840b78d3f48212db45da59a2e5c69b223.zip
Added main execs
Diffstat (limited to 'pcbnew/zones_convert_to_polygons_aux_functions.cpp')
-rw-r--r--pcbnew/zones_convert_to_polygons_aux_functions.cpp251
1 files changed, 251 insertions, 0 deletions
diff --git a/pcbnew/zones_convert_to_polygons_aux_functions.cpp b/pcbnew/zones_convert_to_polygons_aux_functions.cpp
new file mode 100644
index 0000000..1671936
--- /dev/null
+++ b/pcbnew/zones_convert_to_polygons_aux_functions.cpp
@@ -0,0 +1,251 @@
+/**
+ * @file zones_convert_to_polygons_aux_functions.cpp
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 1992-2013 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <PolyLine.h>
+#include <wxPcbStruct.h>
+#include <trigo.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_zone.h>
+
+#include <pcbnew.h>
+#include <zones.h>
+
+ /* Function TransformOutlinesShapeWithClearanceToPolygon
+ * Convert the zone filled areas polygons to polygons
+ * inflated (optional) by max( aClearanceValue, the zone clearance)
+ * and copy them in aCornerBuffer
+ * param aClearanceValue = the clearance around polygons
+ * param aAddClearance = true to add a clearance area to the polygon
+ * false to create the outline polygon.
+ */
+void ZONE_CONTAINER::TransformOutlinesShapeWithClearanceToPolygon(
+ SHAPE_POLY_SET& aCornerBuffer, int aMinClearanceValue, bool aUseNetClearance )
+{
+ // Creates the zone outline polygon (with holes if any)
+ SHAPE_POLY_SET polybuffer;
+ BuildFilledSolidAreasPolygons( NULL, &polybuffer );
+
+ // add clearance to outline
+ int clearance = aMinClearanceValue;
+
+ if( aUseNetClearance && IsOnCopperLayer() )
+ {
+ clearance = GetClearance();
+ if( aMinClearanceValue > clearance )
+ clearance = aMinClearanceValue;
+ }
+
+ // Calculate the polygon with clearance
+ // holes are linked to the main outline, so only one polygon is created.
+ if( clearance )
+ polybuffer.Inflate( clearance, 16 );
+
+ polybuffer.Fracture();
+ aCornerBuffer.Append( polybuffer );
+}
+
+
+
+/**
+ * Function BuildUnconnectedThermalStubsPolygonList
+ * Creates a set of polygons corresponding to stubs created by thermal shapes on pads
+ * which are not connected to a zone (dangling bridges)
+ * @param aCornerBuffer = a SHAPE_POLY_SET where to store polygons
+ * @param aPcb = the board.
+ * @param aZone = a pointer to the ZONE_CONTAINER to examine.
+ * @param aArcCorrection = a pointer to the ZONE_CONTAINER to examine.
+ * @param aRoundPadThermalRotation = the rotation in 1.0 degree for thermal stubs in round pads
+ */
+
+void BuildUnconnectedThermalStubsPolygonList( SHAPE_POLY_SET& aCornerBuffer,
+ BOARD* aPcb,
+ ZONE_CONTAINER* aZone,
+ double aArcCorrection,
+ double aRoundPadThermalRotation )
+{
+ std::vector<wxPoint> corners_buffer; // a local polygon buffer to store one stub
+ corners_buffer.reserve( 4 );
+ wxPoint ptTest[4];
+
+ int zone_clearance = aZone->GetZoneClearance();
+
+ EDA_RECT item_boundingbox;
+ EDA_RECT zone_boundingbox = aZone->GetBoundingBox();
+ int biggest_clearance = aPcb->GetDesignSettings().GetBiggestClearanceValue();
+ biggest_clearance = std::max( biggest_clearance, zone_clearance );
+ zone_boundingbox.Inflate( biggest_clearance );
+
+ // half size of the pen used to draw/plot zones outlines
+ int pen_radius = aZone->GetMinThickness() / 2;
+
+ for( MODULE* module = aPcb->m_Modules; module; module = module->Next() )
+ {
+ for( D_PAD* pad = module->Pads(); pad != NULL; pad = pad->Next() )
+ {
+ // Rejects non-standard pads with tht-only thermal reliefs
+ if( aZone->GetPadConnection( pad ) == PAD_ZONE_CONN_THT_THERMAL
+ && pad->GetAttribute() != PAD_ATTRIB_STANDARD )
+ continue;
+
+ if( aZone->GetPadConnection( pad ) != PAD_ZONE_CONN_THERMAL
+ && aZone->GetPadConnection( pad ) != PAD_ZONE_CONN_THT_THERMAL )
+ continue;
+
+ // check
+ if( !pad->IsOnLayer( aZone->GetLayer() ) )
+ continue;
+
+ if( pad->GetNetCode() != aZone->GetNetCode() )
+ continue;
+
+ // Calculate thermal bridge half width
+ int thermalBridgeWidth = aZone->GetThermalReliefCopperBridge( pad )
+ - aZone->GetMinThickness();
+ if( thermalBridgeWidth <= 0 )
+ continue;
+
+ // we need the thermal bridge half width
+ // with a small extra size to be sure we create a stub
+ // slightly larger than the actual stub
+ thermalBridgeWidth = ( thermalBridgeWidth + 4 ) / 2;
+
+ int thermalReliefGap = aZone->GetThermalReliefGap( pad );
+
+ item_boundingbox = pad->GetBoundingBox();
+ item_boundingbox.Inflate( thermalReliefGap );
+ if( !( item_boundingbox.Intersects( zone_boundingbox ) ) )
+ continue;
+
+ // Thermal bridges are like a segment from a starting point inside the pad
+ // to an ending point outside the pad
+
+ // calculate the ending point of the thermal pad, outside the pad
+ wxPoint endpoint;
+ endpoint.x = ( pad->GetSize().x / 2 ) + thermalReliefGap;
+ endpoint.y = ( pad->GetSize().y / 2 ) + thermalReliefGap;
+
+ // Calculate the starting point of the thermal stub
+ // inside the pad
+ wxPoint startpoint;
+ int copperThickness = aZone->GetThermalReliefCopperBridge( pad )
+ - aZone->GetMinThickness();
+
+ if( copperThickness < 0 )
+ copperThickness = 0;
+
+ // Leave a small extra size to the copper area inside to pad
+ copperThickness += KiROUND( IU_PER_MM * 0.04 );
+
+ startpoint.x = std::min( pad->GetSize().x, copperThickness );
+ startpoint.y = std::min( pad->GetSize().y, copperThickness );
+
+ startpoint.x /= 2;
+ startpoint.y /= 2;
+
+ // This is a CIRCLE pad tweak
+ // for circle pads, the thermal stubs orientation is 45 deg
+ double fAngle = pad->GetOrientation();
+ if( pad->GetShape() == PAD_SHAPE_CIRCLE )
+ {
+ endpoint.x = KiROUND( endpoint.x * aArcCorrection );
+ endpoint.y = endpoint.x;
+ fAngle = aRoundPadThermalRotation;
+ }
+
+ // contour line width has to be taken into calculation to avoid "thermal stub bleed"
+ endpoint.x += pen_radius;
+ endpoint.y += pen_radius;
+ // compute north, south, west and east points for zone connection.
+ ptTest[0] = wxPoint( 0, endpoint.y ); // lower point
+ ptTest[1] = wxPoint( 0, -endpoint.y ); // upper point
+ ptTest[2] = wxPoint( endpoint.x, 0 ); // right point
+ ptTest[3] = wxPoint( -endpoint.x, 0 ); // left point
+
+ // Test all sides
+ for( int i = 0; i < 4; i++ )
+ {
+ // rotate point
+ RotatePoint( &ptTest[i], fAngle );
+
+ // translate point
+ ptTest[i] += pad->ShapePos();
+
+ if( aZone->HitTestFilledArea( ptTest[i] ) )
+ continue;
+
+ corners_buffer.clear();
+
+ // polygons are rectangles with width of copper bridge value
+ switch( i )
+ {
+ case 0: // lower stub
+ corners_buffer.push_back( wxPoint( -thermalBridgeWidth, endpoint.y ) );
+ corners_buffer.push_back( wxPoint( +thermalBridgeWidth, endpoint.y ) );
+ corners_buffer.push_back( wxPoint( +thermalBridgeWidth, startpoint.y ) );
+ corners_buffer.push_back( wxPoint( -thermalBridgeWidth, startpoint.y ) );
+ break;
+
+ case 1: // upper stub
+ corners_buffer.push_back( wxPoint( -thermalBridgeWidth, -endpoint.y ) );
+ corners_buffer.push_back( wxPoint( +thermalBridgeWidth, -endpoint.y ) );
+ corners_buffer.push_back( wxPoint( +thermalBridgeWidth, -startpoint.y ) );
+ corners_buffer.push_back( wxPoint( -thermalBridgeWidth, -startpoint.y ) );
+ break;
+
+ case 2: // right stub
+ corners_buffer.push_back( wxPoint( endpoint.x, -thermalBridgeWidth ) );
+ corners_buffer.push_back( wxPoint( endpoint.x, thermalBridgeWidth ) );
+ corners_buffer.push_back( wxPoint( +startpoint.x, thermalBridgeWidth ) );
+ corners_buffer.push_back( wxPoint( +startpoint.x, -thermalBridgeWidth ) );
+ break;
+
+ case 3: // left stub
+ corners_buffer.push_back( wxPoint( -endpoint.x, -thermalBridgeWidth ) );
+ corners_buffer.push_back( wxPoint( -endpoint.x, thermalBridgeWidth ) );
+ corners_buffer.push_back( wxPoint( -startpoint.x, thermalBridgeWidth ) );
+ corners_buffer.push_back( wxPoint( -startpoint.x, -thermalBridgeWidth ) );
+ break;
+ }
+
+ aCornerBuffer.NewOutline();
+
+ // add computed polygon to list
+ for( unsigned ic = 0; ic < corners_buffer.size(); ic++ )
+ {
+ wxPoint cpos = corners_buffer[ic];
+ RotatePoint( &cpos, fAngle ); // Rotate according to module orientation
+ cpos += pad->ShapePos(); // Shift origin to position
+ aCornerBuffer.Append( cpos.x, cpos.y );
+ }
+ }
+ }
+ }
+}