Comments.

This commit is contained in:
Jeff Young 2020-07-03 16:12:28 +01:00
parent 40d8cb1a19
commit 5bc6389477
12 changed files with 225 additions and 190 deletions

View File

@ -15,6 +15,7 @@ set( KIMATH_SRCS
src/geometry/shape_file_io.cpp
src/geometry/shape_line_chain.cpp
src/geometry/shape_poly_set.cpp
src/geometry/shape_rect.cpp
src/math/util.cpp
)

View File

@ -195,7 +195,5 @@ protected:
SHAPE_TYPE m_type;
};
bool CollideShapes( const SHAPE* aA, const SHAPE* aB, int aClearance, int* aActual,
VECTOR2I* aMTV );
#endif // __SHAPE_H

View File

@ -26,11 +26,8 @@
#ifndef __SHAPE_ARC_H
#define __SHAPE_ARC_H
#include <geometry/seg.h>
#include <geometry/shape.h>
#include <math/box2.h> // for BOX2I
#include <math/vector2d.h> // for VECTOR2I
#include <trigo.h>
class SHAPE_LINE_CHAIN;

View File

@ -27,18 +27,10 @@
#define __SHAPE_LINE_CHAIN
#include <algorithm> // for max
#include <sstream>
#include <vector>
#include <wx/gdicmn.h> // for wxPoint
#include <core/optional.h>
#include <clipper.hpp>
#include <geometry/seg.h>
#include <geometry/shape.h>
#include <geometry/shape_arc.h>
#include <math/box2.h> // for BOX2I
#include <math/vector2d.h>
@ -485,8 +477,7 @@ public:
/**
* Function Replace()
*
* Replaces points with indices in range [start_index, end_index] with a single
* point aP.
* Replaces points with indices in range [start_index, end_index] with a single point aP.
* @param aStartIndex start of the point range to be replaced (inclusive)
* @param aEndIndex end of the point range to be replaced (inclusive)
* @param aP replacement point
@ -496,8 +487,8 @@ public:
/**
* Function Replace()
*
* Replaces points with indices in range [start_index, end_index] with the points from
* line chain aLine.
* Replaces points with indices in range [start_index, end_index] with the points from line
* chain aLine.
* @param aStartIndex start of the point range to be replaced (inclusive)
* @param aEndIndex end of the point range to be replaced (inclusive)
* @param aLine replacement line chain.
@ -526,8 +517,8 @@ public:
/**
* Function Split()
*
* Inserts the point aP belonging to one of the our segments, splitting the adjacent
* segment in two.
* Inserts the point aP belonging to one of the our segments, splitting the adjacent segment
* in two.
* @param aP the point to be inserted
* @return index of the newly inserted point (or a negative value if aP does not lie on
* our line)
@ -583,8 +574,8 @@ public:
*
* Finds all intersection points between our line chain and the segment aSeg.
* @param aSeg the segment chain to find intersections with
* @param aIp reference to a vector to store found intersections. Intersection points
* are sorted with increasing distances from point aSeg.a.
* @param aIp reference to a vector to store found intersections. Intersection points are
* sorted with increasing distances from point aSeg.a.
* @return number of intersections found
*/
int Intersect( const SEG& aSeg, INTERSECTIONS& aIp ) const;
@ -594,8 +585,8 @@ public:
*
* Finds all intersection points between our line chain and the line chain aChain.
* @param aChain the line chain to find intersections with
* @param aIp reference to a vector to store found intersections. Intersection points
* are sorted with increasing path lengths from the starting point of aChain.
* @param aIp reference to a vector to store found intersections. Intersection points are
* sorted with increasing path lengths from the starting point of aChain.
* @return number of intersections found
*/
int Intersect( const SHAPE_LINE_CHAIN& aChain, INTERSECTIONS& aIp ) const;
@ -603,10 +594,9 @@ public:
/**
* Function PathLength()
*
* Computes the walk path length from the beginning of the line chain and
* the point aP belonging to our line.
* @return: path length in Euclidean metric or negative if aP does not belong to
* the line chain.
* Computes the walk path length from the beginning of the line chain and the point aP
* belonging to our line.
* @return: path length in Euclidean metric or -1 if aP does not belong to the line chain.
*/
int PathLength( const VECTOR2I& aP ) const;
@ -616,7 +606,7 @@ public:
* Checks if point aP lies inside a polygon (any type) defined by the line chain.
* For closed shapes only.
* @param aPt point to check
* @param aUseBBoxCache gives better peformance if the bounding boxe caches have been
* @param aUseBBoxCache gives better peformance if the bounding box caches have been
* generated.
* @return true if the point is inside the shape (edge is not treated as being inside).
*/
@ -676,7 +666,6 @@ public:
/**
* Creates a new Clipper path from the SHAPE_LINE_CHAIN in a given orientation
*
*/
ClipperLib::Path convertToClipper( bool aRequiredOrientation ) const;
@ -699,8 +688,8 @@ public:
/**
* Function NearestPoint()
*
* Finds a point on the line chain that is closest to the line defined
* by the points of segment aSeg, also returns the distance.
* Finds a point on the line chain that is closest to the line defined by the points of
* segment aSeg, also returns the distance.
* @param aSeg Segment defining the line.
* @param dist reference receiving the distance to the nearest point.
* @return the nearest point.
@ -794,9 +783,9 @@ private:
std::vector<VECTOR2I> m_points;
/**
* Array of indices that refer to the index of the shape if the point
* is part of a larger shape, e.g. arc or spline.
* If the value is -1, the point is just a point
* Array of indices that refer to the index of the shape if the point is part of a larger
* shape, e.g. arc or spline.
* If the value is -1, the point is just a point.
*/
std::vector<ssize_t> m_shapes;
@ -807,8 +796,9 @@ private:
/// Width of the segments (for BBox calculations in RTree)
/// TODO Adjust usage of SHAPE_LINE_CHAIN to account for where we need a width and where not
/// Alternatively, we could split the class into a LINE_CHAIN (no width) and SHAPE_LINE_CHAIN that derives from
/// SHAPE as well that does have a width. Not sure yet on the correct path.
/// Alternatively, we could split the class into a LINE_CHAIN (no width) and SHAPE_LINE_CHAIN
/// that derives from SHAPE as well that does have a width. Not sure yet on the correct path.
/// TODO Note that we also have SHAPE_SIMPLE which is a closed, filled SHAPE_LINE_CHAIN.
int m_width;
/// cached bounding box

View File

@ -138,6 +138,14 @@ public:
m_p0 += aVector;
}
/**
* Function Rotate()
* This function has limited utility for SHAPE_RECT as non-cartesian rotations will distort
* the rectangle. If you might need to handle non-90º rotations then the SHAPE_RECT should
* first be converted to a SHAPE_SIMPLE which can then be free-rotated.
* @param aAngle
* @param aCenter
*/
void Rotate( double aAngle, const VECTOR2I& aCenter = { 0, 0 } ) override
{
m_p0 -= aCenter;

View File

@ -366,6 +366,7 @@ void TransformSegmentToPolygon( SHAPE_POLY_SET& aCornerBuffer, wxPoint aStart, w
int seg_len = KiROUND( EuclideanNorm( endp ) );
// Compute the outlines of the segment, and creates a polygon
// add right rounded end:
for( int ii = 0; ii < 1800; ii += delta )
{
@ -448,7 +449,6 @@ void TransformArcToPolygon( SHAPE_POLY_SET& aCornerBuffer, wxPoint aCentre, wxPo
void TransformRingToPolygon( SHAPE_POLY_SET& aCornerBuffer, wxPoint aCentre, int aRadius,
int aError, int aWidth )
{
// Compute the corners positions and creates the poly
int inner_radius = aRadius - ( aWidth / 2 );
int outer_radius = inner_radius + aWidth;

View File

@ -23,22 +23,15 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <algorithm>
#include <math.h>
#include <vector>
#include <geometry/geometry_utils.h>
#include <geometry/seg.h> // for SEG
#include <geometry/shape_arc.h>
#include <geometry/shape_line_chain.h>
#include <math.h> // for cos, sin, M_PI, atan2, ceil
#include <math/box2.h> // for BOX2I
#include <math/vector2d.h> // for VECTOR2I, VECTOR2D, VECTOR2
#include <type_traits> // for swap
#include <trigo.h>
SHAPE_ARC::SHAPE_ARC( const VECTOR2I& aArcCenter, const VECTOR2I& aArcStartPoint,
double aCenterAngle, int aWidth ) :
double aCenterAngle, int aWidth ) :
SHAPE( SH_ARC ), m_width( aWidth )
{
m_start = aArcStartPoint;
@ -53,7 +46,7 @@ SHAPE_ARC::SHAPE_ARC( const VECTOR2I& aArcCenter, const VECTOR2I& aArcStartPoint
SHAPE_ARC::SHAPE_ARC( const VECTOR2I& aArcStart, const VECTOR2I& aArcMid,
const VECTOR2I& aArcEnd, int aWidth ) :
const VECTOR2I& aArcEnd, int aWidth ) :
SHAPE( SH_ARC ), m_start( aArcStart ), m_mid( aArcMid ), m_end( aArcEnd ),
m_width( aWidth )
{

View File

@ -87,7 +87,8 @@ static inline bool Collide( const SHAPE_RECT& aA, const SHAPE_CIRCLE& aB, int aC
bool inside = c.x >= p0.x && c.x <= ( p0.x + size.x )
&& c.y >= p0.y && c.y <= ( p0.y + size.y );
if( inside && !aMTV )
// If we're not looking for MTV, short-circuit once we find a hard collision
if( !aMTV && inside )
{
if( aActual )
*aActual = 0;
@ -102,7 +103,8 @@ static inline bool Collide( const SHAPE_RECT& aA, const SHAPE_CIRCLE& aB, int aC
VECTOR2I pn = side.NearestPoint( c );
ecoord side_dist_sq = ( pn - c ).SquaredEuclideanNorm();
if( ( side_dist_sq == 0 || side_dist_sq < min_dist_sq ) && !aMTV && !aActual )
// If we're not looking for MTV or actual, short-circuit once we find any collision
if( !aMTV && !aActual && ( side_dist_sq == 0 || side_dist_sq < min_dist_sq ) )
return true;
if( side_dist_sq < nearest_side_dist_sq )
@ -163,18 +165,18 @@ static VECTOR2I pushoutForce( const SHAPE_CIRCLE& aA, const SEG& aB, int aCleara
static inline bool Collide( const SHAPE_CIRCLE& aA, const SHAPE_LINE_CHAIN& aB, int aClearance,
int* aActual, VECTOR2I* aMTV )
{
bool found = false;
bool collided = false;
for( int s = 0; s < aB.SegmentCount(); s++ )
{
if( aA.Collide( aB.CSegment( s ), aClearance, aActual ) )
{
found = true;
collided = true;
break;
}
}
if( !found )
if( !collided )
return false;
if( aMTV )
@ -229,18 +231,21 @@ static inline bool Collide( const SHAPE_CIRCLE& aA, const SHAPE_SIMPLE& aB, int
static inline bool Collide( const SHAPE_CIRCLE& aA, const SHAPE_SEGMENT& aSeg, int aClearance,
int* aActual, VECTOR2I* aMTV )
{
bool col = aA.Collide( aSeg.GetSeg(), aClearance + aSeg.GetWidth() / 2, aActual );
if( !aA.Collide( aSeg.GetSeg(), aClearance + aSeg.GetWidth() / 2, aActual ) )
return false;
if( col && aMTV )
if( aMTV )
*aMTV = -pushoutForce( aA, aSeg.GetSeg(), aClearance + aSeg.GetWidth() / 2);
return col;
return true;
}
static inline bool Collide( const SHAPE_LINE_CHAIN& aA, const SHAPE_LINE_CHAIN& aB, int aClearance,
int* aActual, VECTOR2I* aMTV )
{
// TODO: why doesn't this handle MTV?
for( int i = 0; i < aB.SegmentCount(); i++ )
{
if( aA.Collide( aB.CSegment( i ), aClearance, aActual ) )
@ -277,7 +282,8 @@ static inline bool Collide( const SHAPE_RECT& aA, const SHAPE_LINE_CHAIN& aB, in
{
minActual = std::min( minActual, actual );
if( !aActual )
// If we're not looking for MTV or Actual, short-circuit after any collision
if( !aActual && !aMTV )
return true;
}
}
@ -285,6 +291,8 @@ static inline bool Collide( const SHAPE_RECT& aA, const SHAPE_LINE_CHAIN& aB, in
if( aActual )
*aActual = std::max( 0, minActual );
// TODO: why doesn't this handle MTV?
return minActual < INT_MAX;
}
@ -306,6 +314,8 @@ static inline bool Collide( const SHAPE_RECT& aA, const SHAPE_SEGMENT& aSeg, int
if( aActual )
*aActual = std::max( 0, actual - aSeg.GetWidth() / 2 );
// TODO: why doesn't this handle MTV?
return true;
}
@ -323,6 +333,8 @@ static inline bool Collide( const SHAPE_SEGMENT& aA, const SHAPE_SEGMENT& aB, in
if( aActual )
*aActual = std::max( 0, actual - aB.GetWidth() / 2 );
// TODO: why doesn't this handle MTV?
return true;
}
@ -340,6 +352,8 @@ static inline bool Collide( const SHAPE_LINE_CHAIN& aA, const SHAPE_SEGMENT& aB,
if( aActual )
*aActual = std::max( 0, actual - aB.GetWidth() / 2 );
// TODO: why doesn't this handle MTV?
return true;
}
@ -431,7 +445,7 @@ inline bool CollCaseReversed ( const SHAPE* aA, const SHAPE* aB, int aClearance,
}
bool CollideShapes( const SHAPE* aA, const SHAPE* aB, int aClearance, int* aActual, VECTOR2I* aMTV )
bool collideShapes( const SHAPE* aA, const SHAPE* aB, int aClearance, int* aActual, VECTOR2I* aMTV )
{
switch( aA->Type() )
{
@ -606,48 +620,13 @@ bool CollideShapes( const SHAPE* aA, const SHAPE* aB, int aClearance, int* aActu
bool SHAPE::Collide( const SHAPE* aShape, int aClearance, VECTOR2I* aMTV ) const
{
return CollideShapes( this, aShape, aClearance, nullptr, aMTV );
return collideShapes( this, aShape, aClearance, nullptr, aMTV );
}
bool SHAPE::Collide( const SHAPE* aShape, int aClearance, int* aActual ) const
{
return CollideShapes( this, aShape, aClearance, aActual, nullptr );
return collideShapes( this, aShape, aClearance, aActual, nullptr );
}
bool SHAPE_RECT::Collide( const SEG& aSeg, int aClearance, int* aActual ) const
{
if( BBox( 0 ).Contains( aSeg.A ) || BBox( 0 ).Contains( aSeg.B ) )
{
if( aActual )
*aActual = 0;
return true;
}
VECTOR2I corners[] = { VECTOR2I( m_p0.x, m_p0.y ),
VECTOR2I( m_p0.x, m_p0.y + m_h ),
VECTOR2I( m_p0.x + m_w, m_p0.y + m_h ),
VECTOR2I( m_p0.x + m_w, m_p0.y ),
VECTOR2I( m_p0.x, m_p0.y ) };
SEG s( corners[0], corners[1] );
SEG::ecoord dist_squared = s.SquaredDistance( aSeg );
for( int i = 1; i < 4; i++ )
{
s = SEG( corners[i], corners[ i + 1] );
dist_squared = std::min( dist_squared, s.SquaredDistance( aSeg ) );
}
if( dist_squared < (ecoord) aClearance * aClearance )
{
if( aActual )
*aActual = sqrt( dist_squared );
return true;
}
return false;
}

View File

@ -0,0 +1,63 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015 CERN
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
*
* 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 <geometry/shape_rect.h>
bool SHAPE_RECT::Collide( const SEG& aSeg, int aClearance, int* aActual ) const
{
if( BBox( 0 ).Contains( aSeg.A ) || BBox( 0 ).Contains( aSeg.B ) )
{
if( aActual )
*aActual = 0;
return true;
}
VECTOR2I corners[] = { VECTOR2I( m_p0.x, m_p0.y ),
VECTOR2I( m_p0.x, m_p0.y + m_h ),
VECTOR2I( m_p0.x + m_w, m_p0.y + m_h ),
VECTOR2I( m_p0.x + m_w, m_p0.y ),
VECTOR2I( m_p0.x, m_p0.y ) };
SEG s( corners[0], corners[1] );
SEG::ecoord dist_squared = s.SquaredDistance( aSeg );
for( int i = 1; i < 4; i++ )
{
s = SEG( corners[i], corners[ i + 1] );
dist_squared = std::min( dist_squared, s.SquaredDistance( aSeg ) );
}
if( dist_squared < (ecoord) aClearance * aClearance )
{
if( aActual )
*aActual = sqrt( dist_squared );
return true;
}
return false;
}

View File

@ -75,9 +75,9 @@ D_PAD::D_PAD( MODULE* parent ) :
m_LocalSolderPasteMargin = 0;
m_LocalSolderPasteMarginRatio = 0.0;
// Parameters for round rect only:
m_padRoundRectRadiusScale = 0.25; // from IPC-7351C standard
m_roundedCornerScale = 0.25; // from IPC-7351C standard
// Parameters for chamfered rect only:
m_padChamferRectScale = 0.2; // Size of chamfer: ratio of smallest of X,Y size
m_chamferScale = 0.2; // Size of chamfer: ratio of smallest of X,Y size
m_chamferPositions = RECT_NO_CHAMFER; // No chamfered corner
m_ZoneConnection = ZONE_CONNECTION::INHERITED; // Use parent setting by default
@ -162,7 +162,7 @@ int D_PAD::calcBoundingRadius() const
int D_PAD::GetRoundRectCornerRadius() const
{
return KiROUND( std::min( m_Size.x, m_Size.y ) * m_padRoundRectRadiusScale );
return KiROUND( std::min( m_Size.x, m_Size.y ) * m_roundedCornerScale );
}
@ -177,7 +177,7 @@ void D_PAD::SetRoundRectCornerRadius( double aRadius )
void D_PAD::SetRoundRectRadiusRatio( double aRadiusScale )
{
m_padRoundRectRadiusScale = std::max( 0.0, std::min( aRadiusScale, 0.5 ) );
m_roundedCornerScale = std::max( 0.0, std::min( aRadiusScale, 0.5 ) );
m_shapesDirty = true;
}
@ -185,7 +185,7 @@ void D_PAD::SetRoundRectRadiusRatio( double aRadiusScale )
void D_PAD::SetChamferRectRatio( double aChamferScale )
{
m_padChamferRectScale = std::max( 0.0, std::min( aChamferScale, 0.5 ) );
m_chamferScale = std::max( 0.0, std::min( aChamferScale, 0.5 ) );
m_shapesDirty = true;
}

View File

@ -68,7 +68,8 @@ public:
// Do not create a copy constructor & operator=.
// The ones generated by the compiler are adequate.
/* Default layers used for pads, according to the pad type.
/*
* Default layers used for pads, according to the pad type.
* this is default values only, they can be changed for a given pad
*/
static LSET StandardMask(); ///< layer set for a through hole pad
@ -229,14 +230,15 @@ public:
const wxPoint& GetOffset() const { return m_Offset; }
/**
* Has meaning only for free shape pads.
* Has meaning only for custom shape pads.
* add a free shape to the shape list.
* the shape can be
* a polygon (outline can have a thickness)
* a thick segment
* a filled circle or ring ( if thickness == 0, this is a filled circle, else a ring)
* a filled circle (thickness == 0) or ring
* a filled rect (thickness == 0) or rectangular outline
* a arc
* a curve
* a bezier curve
*/
void AddPrimitivePoly( const SHAPE_POLY_SET& aPoly, int aThickness );
void AddPrimitivePoly( const std::vector<wxPoint>& aPoly, int aThickness );
@ -378,7 +380,13 @@ public:
/**
* Function GetEffectiveShapes
* Returns a list of SHAPE objects representing the pad's copper.
* Some pad shapes can be complex (rounded/chamfered rectangle), even without considering
* custom shapes. This routine returns a list of simple shapes which make up the pad for
* use with routing, collision determiniation, etc.
*
* Note that this list can contain a SHAPE_SIMPLE (a simple single-outline non-intersecting
* polygon), but should never contain a SHAPE_POLY_LIST (a complex polygon consisting of
* multiple outlines and/or holes).
*/
const std::vector<std::shared_ptr<SHAPE>>& GetEffectiveShapes() const;
@ -408,13 +416,13 @@ public:
/**
* Function GetSolderMaskMargin
* @return the margin for the solder mask layer
* usually > 0 (mask shape bigger than pad
* usually > 0 (mask shape bigger than pad)
* For pads also on copper layers, the value (used to build a default shape) is
* 1 - the local value
* 2 - if 0, the parent footprint value
* 3 - if 0, the global value
* For pads NOT on copper layers, the value is the local value because there is
* not default shape to build
* For pads NOT on copper layers, the value is the local value because there is no default
* shape to build
*/
int GetSolderMaskMargin() const;
@ -430,7 +438,7 @@ public:
* 3 - if 0, the global value
*
* For pads NOT on copper layers, the value is the local value because there is
* not default shape to build
* no default shape to build
*/
wxSize GetSolderPasteMargin() const;
@ -443,6 +451,11 @@ public:
*/
ZONE_CONNECTION GetEffectiveZoneConnection() const;
/**
* Set the width of the thermal spokes connecting the pad to a zone. If != 0 this will
* override similar settings in the parent footprint and zone.
* @param aWidth
*/
void SetThermalWidth( int aWidth ) { m_ThermalWidth = aWidth; }
int GetThermalWidth() const;
@ -451,7 +464,7 @@ public:
/**
* Function SetRoundRectCornerRadius
* Has meaning only for rounded rect pads
* has meaning only for rounded rect pads
* @return The radius of the rounded corners for this pad.
*/
void SetRoundRectCornerRadius( double aRadius );
@ -461,28 +474,24 @@ public:
/**
* has meaning only for rounded rect pads
* @return the scaling factor between the smaller Y or Y size and the radius
* of the rounded corners.
* Cannot be > 0.5
* the normalized IPC-7351C value is 0.25
* Set the ratio between the smaller X or Y size and the rounded corner radius.
* Cannot be > 0.5; the normalized IPC-7351C value is 0.25
*/
void SetRoundRectRadiusRatio( double aRadiusScale );
double GetRoundRectRadiusRatio() const { return m_padRoundRectRadiusScale; }
double GetRoundRectRadiusRatio() const { return m_roundedCornerScale; }
/**
* has meaning only for chamfered rect pads
* Set the ratio between the smaller Y or Y size and the radius
* of the rounded corners.
* Cannot be < 0.5 and obviously must be > 0
* Set the ratio between the smaller X or Y size and chamfered corner size.
* Cannot be < 0.5.
*/
void SetChamferRectRatio( double aChamferScale );
double GetChamferRectRatio() const { return m_padChamferRectScale; }
double GetChamferRectRatio() const { return m_chamferScale; }
/**
* has meaning only for chamfered rect pads
* set the position of the chamfer for a 0 orientation, one of
* RECT_CHAMFER_TOP_LEFT, RECT_CHAMFER_TOP_RIGHT,
* RECT_CHAMFER_BOTTOM_LEFT, RECT_CHAMFER_BOTTOM_RIGHT
* set the position of the chamfers for orientation 0.
* @param aPositions a bit-set of RECT_CHAMFER_POSITIONS
*/
void SetChamferPositions( int aPositions ) { m_chamferPositions = aPositions; }
int GetChamferPositions() const { return m_chamferPositions; }
@ -509,7 +518,10 @@ public:
return wxT( "PAD" );
}
// Virtual function:
/**
* Function GetBoundingBox
* The bounding box is cached, so this will be efficient most of the time.
*/
const EDA_RECT GetBoundingBox() const override;
///> Set absolute coordinates.
@ -541,13 +553,13 @@ public:
/**
* Function ShowPadShape
* @return the name of the shape
* @return the GUI-appropriate name of the shape
*/
wxString ShowPadShape() const;
/**
* Function ShowPadAttr
* @return the name of the pad type (attribute) : STD, SMD ...
* @return the GUI-appropriate description of the pad type (attribute) : Std, SMD ...
*/
wxString ShowPadAttr() const;
@ -570,7 +582,8 @@ public:
bool PadShouldBeNPTH() const;
/**
* Rebuilds the shape cache for the pad and clears the dirty bit
* Rebuilds the effective shape cache (and bounding box and radius) for the pad and clears
* the dirty bit.
*/
void BuildEffectiveShapes() const;
@ -597,17 +610,18 @@ private:
void addPadPrimitivesToPolygon( SHAPE_POLY_SET* aMergedPolygon, int aError ) const;
private:
wxString m_name; ///< pad name (pin number in schematic)
wxString m_pinFunction; ///< pin function in schematic
wxString m_name; // Pad name (pin number in schematic)
wxString m_pinFunction; // Pin function in schematic
wxPoint m_Pos; ///< pad Position on board
wxPoint m_Pos; // Pad Position on board
PAD_SHAPE_T m_padShape; ///< Shape: PAD_SHAPE_CIRCLE, PAD_SHAPE_RECT,
///< PAD_SHAPE_OVAL, PAD_SHAPE_TRAPEZOID,
///< PAD_SHAPE_ROUNDRECT, PAD_SHAPE_POLYGON
// Edit definitions of primitives for custom pad shapes. In local coordinates relative
// to m_Pos (NOT shapePos) at orient 0.
PAD_SHAPE_T m_padShape; // Shape: PAD_SHAPE_CIRCLE, PAD_SHAPE_RECT,
// PAD_SHAPE_OVAL, PAD_SHAPE_TRAPEZOID,
// PAD_SHAPE_ROUNDRECT, PAD_SHAPE_POLYGON
/*
* Editing definitions of primitives for custom pad shapes. In local coordinates relative
* to m_Pos (NOT shapePos) at orient 0.
*/
std::vector<std::shared_ptr<DRAWSEGMENT>> m_editPrimitives;
mutable bool m_shapesDirty;
@ -616,83 +630,75 @@ private:
mutable std::vector<std::shared_ptr<SHAPE>> m_effectiveShapes;
mutable std::shared_ptr<SHAPE_SEGMENT> m_effectiveHoleShape;
/**
/*
* How to build the custom shape in zone, to create the clearance area:
* CUST_PAD_SHAPE_IN_ZONE_OUTLINE = use pad shape
* CUST_PAD_SHAPE_IN_ZONE_CONVEXHULL = use the convex hull of the pad shape
* other values are currently reserved
*/
CUST_PAD_SHAPE_IN_ZONE m_customShapeClearanceArea;
int m_SubRatsnest; ///< variable used in rats nest computations
///< handle subnet (block) number in ratsnest connection
int m_SubRatsnest; // Variable used to handle subnet (block) number in
// ratsnest computations
wxSize m_Drill; ///< Drill diam (drill shape = PAD_CIRCLE) or drill size
///< (shape = OVAL) for drill shape = PAD_CIRCLE, drill
///< diam = m_Drill.x
wxSize m_Drill; // Drill diameter (x == y) or slot dimensions (x != y)
wxSize m_Size; // X and Y size (relative to orient 0)
wxSize m_Size; ///< X and Y size ( relative to orient 0)
PAD_DRILL_SHAPE_T m_drillShape; // PAD_DRILL_SHAPE_CIRCLE, PAD_DRILL_SHAPE_OBLONG
PAD_DRILL_SHAPE_T m_drillShape; ///< PAD_DRILL_SHAPE_CIRCLE, PAD_DRILL_SHAPE_OBLONG
double m_roundedCornerScale; // Scaling factor of min(width, hieght) to corner
// radius, default 0.25
double m_chamferScale; // Scaling factor of min(width, height) to chamfer
// size, default 0.25
int m_chamferPositions; // The positions of the chamfers (at orient 0)
double m_padRoundRectRadiusScale; ///< scaling factor from smallest m_Size coord
///< to corner radius, default 0.25
double m_padChamferRectScale; ///< scaling factor from smallest m_Size coord
///< to chamfer value, default 0.25
int m_chamferPositions; ///< the positions of the chamfers for a 0 orientation
PAD_SHAPE_T m_anchorPadShape; // For custom shaped pads: shape of pad anchor,
// PAD_SHAPE_RECT, PAD_SHAPE_CIRCLE
PAD_SHAPE_T m_anchorPadShape; ///< for custom shaped pads: shape of pad anchor,
///< PAD_SHAPE_RECT, PAD_SHAPE_CIRCLE
/**
* m_Offset is useful only for oblong and rect pads (it can be used for other
* shapes, but without any interest).
* This is the offset between the pad hole and the pad shape (you must
* understand here pad shape = copper area around the hole)
* Most of cases, the hole is the center of the shape (m_Offset = 0).
* But some board designers use oblong/rect pads with a hole moved to one of the
* oblong/rect pad shape ends.
* In all cases the pad position is the pad hole.
* The physical shape position (used to draw it for instance) is pad
* position (m_Pos) + m_Offset.
* D_PAD::ShapePos() returns the physical shape position according to
* the offset and the pad rotation.
/*
* Most of the time the hole is the center of the shape (m_Offset = 0). But some designers
* use oblong/rect pads with a hole moved to one of the oblong/rect pad shape ends.
* In all cases the hole is at the pad position. This offset is from the hole to the center
* of the pad shape (ie: the copper area around the hole).
* ShapePos() returns the board shape position according to the offset and the pad rotation.
*/
wxPoint m_Offset;
LSET m_layerMask; ///< Bitwise layer :1= copper layer, 15= cmp,
///< 2..14 = internal layers
///< 16 .. 31 = technical layers
LSET m_layerMask; // Bitwise layer: 1 = copper layer, 15 = cmp,
// 2..14 = internal layers, 16..31 = technical layers
wxSize m_DeltaSize; ///< delta on rectangular shapes
wxSize m_DeltaSize; // Delta for PAD_SHAPE_TRAPEZOID; half the delta squeezes
// one end and half expands the other. It is only valid
// to have a single axis be non-0.
wxPoint m_Pos0; ///< Initial Pad position (i.e. pad position relative to the
///< module anchor, orientation 0)
wxPoint m_Pos0; // Initial Pad position (i.e. pad position relative to the
// module anchor, orientation 0)
PAD_ATTR_T m_Attribute; ///< PAD_ATTRIB_NORMAL, PAD_ATTRIB_SMD,
///< PAD_ATTRIB_CONN, PAD_ATTRIB_HOLE_NOT_PLATED
PAD_PROP_T m_Property; ///< property in fab files (BGA, FIDUCIAL, TEST POINT, CASTELLATED)
PAD_ATTR_T m_Attribute; // PAD_ATTRIB_NORMAL, PAD_ATTRIB_SMD, PAD_ATTRIB_CONN,
// PAD_ATTRIB_HOLE_NOT_PLATED
PAD_PROP_T m_Property; // Property in fab files (BGA, FIDUCIAL, TESTPOINT, etc.)
double m_Orient; ///< in 1/10 degrees
double m_Orient; // in 1/10 degrees
int m_LengthPadToDie; ///< Length net from pad to die, inside the package
int m_LengthPadToDie; // Length net from pad to die, inside the package
/// Local clearance. When null, the module default value is used.
/// when the module default value is null, the netclass value is used
/// Usually the local clearance is null
/*
* Pad clearances, margins, etc. exist in a hiearchy. If a given level is specified then
* the remaining levels are NOT consulted.
*
* LEVEL 1: (highest priority) local overrides (pad, footprint, etc.)
* LEVEL 2: Rules
* LEVEL 3: Accumulated local settings, netclass settings, & board design settings
*
* These are the LEVEL 1 settings for a pad.
*/
int m_LocalClearance;
int m_LocalSolderMaskMargin; // Local solder mask margin
int m_LocalSolderPasteMargin; // Local solder paste margin absolute value
double m_LocalSolderPasteMarginRatio; // Local solder mask margin ratio of pad size
// The final margin is the sum of these 2 values
/// Local mask margins: when 0, the parent footprint design values are used
int m_LocalSolderMaskMargin; ///< Local solder mask margin
int m_LocalSolderPasteMargin; ///< Local solder paste margin absolute value
double m_LocalSolderPasteMarginRatio; ///< Local solder mask margin ratio value of pad size
///< The final margin is the sum of these 2 values
/// how the connection to zone is made: no connection, thermal relief ...
ZONE_CONNECTION m_ZoneConnection;
int m_ThermalWidth;
ZONE_CONNECTION m_ZoneConnection; // No connection, thermal relief, etc.
int m_ThermalWidth; // Thermal spoke width.
int m_ThermalGap;
};

View File

@ -815,7 +815,7 @@ void DIALOG_PAD_PROPERTIES::OnPadShapeSelection( wxCommandEvent& event )
case CHOICE_SHAPE_CHAMFERED_RECT:
m_shapePropsBook->SetSelection( 3 );
// A reasonable default is all corners chamferred.
// A reasonable default is all corners chamfered.
if( !m_cbTopLeft->GetValue() && !m_cbTopRight->GetValue()
&& !m_cbBottomLeft->GetValue() && !m_cbBottomRight->GetValue() )
{