Comments.
This commit is contained in:
parent
40d8cb1a19
commit
5bc6389477
|
@ -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
|
||||
)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -23,18 +23,11 @@
|
|||
* 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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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() )
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue