Formatting.

This commit is contained in:
Jeff Young 2021-06-03 00:01:36 +01:00
parent de89505f02
commit 976e756b02
2 changed files with 60 additions and 76 deletions

View File

@ -962,13 +962,13 @@ public:
* the outline.
*
* @param aAmount is the number of units to offset edges.
* @param aCircleSegmentsCount is the number of segments per 360 degrees to use in curve approx
* @param aCircleSegCount is the number of segments per 360 degrees to use in curve approx
* @param aCornerStrategy #ALLOW_ACUTE_CORNERS to preserve all angles,
* #CHAMFER_ACUTE_CORNERS to chop angles less than 90°,
* #ROUND_ACUTE_CORNERS to round off angles less than 90°,
* #ROUND_ALL_CORNERS to round regardless of angles
*/
void Inflate( int aAmount, int aCircleSegmentsCount,
void Inflate( int aAmount, int aCircleSegCount,
CORNER_STRATEGY aCornerStrategy = ROUND_ALL_CORNERS );
void Deflate( int aAmount, int aCircleSegmentsCount,

View File

@ -2,6 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2019 CERN
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* @author Alejandro García Montoro <alejandro.garciamontoro@gmail.com>
*
@ -52,8 +53,6 @@
#include <md5_hash.h>
#include <geometry/shape_segment.h>
#include <geometry/shape_circle.h>
#include <geometry/shape_simple.h>
#include <geometry/shape_compound.h>
using namespace ClipperLib;
@ -71,13 +70,16 @@ SHAPE_POLY_SET::SHAPE_POLY_SET( const SHAPE_LINE_CHAIN& aOutline ) :
SHAPE_POLY_SET::SHAPE_POLY_SET( const SHAPE_POLY_SET& aOther ) :
SHAPE( aOther ), m_polys( aOther.m_polys )
SHAPE( aOther ),
m_polys( aOther.m_polys )
{
if( aOther.IsTriangulationUpToDate() )
{
for( unsigned i = 0; i < aOther.TriangulatedPolyCount(); i++ )
m_triangulatedPolys.push_back(
std::make_unique<TRIANGULATED_POLYGON>( *aOther.TriangulatedPolygon( i ) ) );
{
const TRIANGULATED_POLYGON* poly = aOther.TriangulatedPolygon( i );
m_triangulatedPolys.push_back( std::make_unique<TRIANGULATED_POLYGON>( *poly ) );
}
m_hash = aOther.GetHash();
m_triangulationValid = true;
@ -143,11 +145,11 @@ bool SHAPE_POLY_SET::GetRelativeIndices( int aGlobalIdx,
bool SHAPE_POLY_SET::GetGlobalIndex( SHAPE_POLY_SET::VERTEX_INDEX aRelativeIndices,
int& aGlobalIdx ) const
int& aGlobalIdx ) const
{
int selectedVertex = aRelativeIndices.m_vertex;
unsigned int selectedContour = aRelativeIndices.m_contour;
unsigned int selectedPolygon = aRelativeIndices.m_polygon;
int selectedVertex = aRelativeIndices.m_vertex;
unsigned int selectedContour = aRelativeIndices.m_contour;
unsigned int selectedPolygon = aRelativeIndices.m_polygon;
// Check whether the vertex indices make sense in this poly set
if( selectedPolygon < m_polys.size() && selectedContour < m_polys[selectedPolygon].size()
@ -162,17 +164,13 @@ bool SHAPE_POLY_SET::GetGlobalIndex( SHAPE_POLY_SET::VERTEX_INDEX aRelativeIndic
currentPolygon = Polygon( polygonIdx );
for( unsigned int contourIdx = 0; contourIdx < currentPolygon.size(); contourIdx++ )
{
aGlobalIdx += currentPolygon[contourIdx].PointCount();
}
}
currentPolygon = Polygon( selectedPolygon );
for( unsigned int contourIdx = 0; contourIdx < selectedContour; contourIdx++ )
{
aGlobalIdx += currentPolygon[contourIdx].PointCount();
}
aGlobalIdx += selectedVertex;
@ -291,9 +289,7 @@ SHAPE_POLY_SET SHAPE_POLY_SET::Subset( int aFirstPolygon, int aLastPolygon )
SHAPE_POLY_SET newPolySet;
for( int index = aFirstPolygon; index < aLastPolygon; index++ )
{
newPolySet.m_polys.push_back( Polygon( index ) );
}
return newPolySet;
}
@ -472,28 +468,26 @@ double SHAPE_POLY_SET::Area()
void SHAPE_POLY_SET::booleanOp( ClipperLib::ClipType aType, const SHAPE_POLY_SET& aOtherShape,
POLYGON_MODE aFastMode )
POLYGON_MODE aFastMode )
{
booleanOp( aType, *this, aOtherShape, aFastMode );
}
void SHAPE_POLY_SET::booleanOp( ClipperLib::ClipType aType,
const SHAPE_POLY_SET& aShape,
const SHAPE_POLY_SET& aOtherShape,
POLYGON_MODE aFastMode )
void SHAPE_POLY_SET::booleanOp( ClipperLib::ClipType aType, const SHAPE_POLY_SET& aShape,
const SHAPE_POLY_SET& aOtherShape, POLYGON_MODE aFastMode )
{
Clipper c;
c.StrictlySimple( aFastMode == PM_STRICTLY_SIMPLE );
for( auto poly : aShape.m_polys )
for( const POLYGON& poly : aShape.m_polys )
{
for( size_t i = 0 ; i < poly.size(); i++ )
c.AddPath( poly[i].convertToClipper( i == 0 ), ptSubject, true );
}
for( auto poly : aOtherShape.m_polys )
for( const POLYGON& poly : aOtherShape.m_polys )
{
for( size_t i = 0; i < poly.size(); i++ )
c.AddPath( poly[i].convertToClipper( i == 0 ), ptClip, true );
@ -525,25 +519,22 @@ void SHAPE_POLY_SET::BooleanIntersection( const SHAPE_POLY_SET& b, POLYGON_MODE
}
void SHAPE_POLY_SET::BooleanAdd( const SHAPE_POLY_SET& a,
const SHAPE_POLY_SET& b,
POLYGON_MODE aFastMode )
void SHAPE_POLY_SET::BooleanAdd( const SHAPE_POLY_SET& a, const SHAPE_POLY_SET& b,
POLYGON_MODE aFastMode )
{
booleanOp( ctUnion, a, b, aFastMode );
}
void SHAPE_POLY_SET::BooleanSubtract( const SHAPE_POLY_SET& a,
const SHAPE_POLY_SET& b,
POLYGON_MODE aFastMode )
void SHAPE_POLY_SET::BooleanSubtract( const SHAPE_POLY_SET& a, const SHAPE_POLY_SET& b,
POLYGON_MODE aFastMode )
{
booleanOp( ctDifference, a, b, aFastMode );
}
void SHAPE_POLY_SET::BooleanIntersection( const SHAPE_POLY_SET& a,
const SHAPE_POLY_SET& b,
POLYGON_MODE aFastMode )
void SHAPE_POLY_SET::BooleanIntersection( const SHAPE_POLY_SET& a, const SHAPE_POLY_SET& b,
POLYGON_MODE aFastMode )
{
booleanOp( ctIntersection, a, b, aFastMode );
}
@ -558,12 +549,11 @@ void SHAPE_POLY_SET::InflateWithLinkedHoles( int aFactor, int aCircleSegmentsCou
}
void SHAPE_POLY_SET::Inflate( int aAmount, int aCircleSegmentsCount,
CORNER_STRATEGY aCornerStrategy )
void SHAPE_POLY_SET::Inflate( int aAmount, int aCircleSegCount, CORNER_STRATEGY aCornerStrategy )
{
// A static table to avoid repetitive calculations of the coefficient
// 1.0 - cos( M_PI / aCircleSegmentsCount )
// aCircleSegmentsCount is most of time <= 64 and usually 8, 12, 16, 32
// 1.0 - cos( M_PI / aCircleSegCount )
// aCircleSegCount is most of time <= 64 and usually 8, 12, 16, 32
#define SEG_CNT_MAX 64
static double arc_tolerance_factor[SEG_CNT_MAX + 1];
@ -617,20 +607,22 @@ void SHAPE_POLY_SET::Inflate( int aAmount, int aCircleSegmentsCount,
// nn = M_PI / acos(1.0 - c.ArcTolerance / abs(aAmount))
// http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Classes/ClipperOffset/Properties/ArcTolerance.htm
if( aCircleSegmentsCount < 6 ) // avoid incorrect aCircleSegmentsCount values
aCircleSegmentsCount = 6;
if( aCircleSegCount < 6 ) // avoid incorrect aCircleSegCount values
aCircleSegCount = 6;
double coeff;
if( aCircleSegmentsCount > SEG_CNT_MAX || arc_tolerance_factor[aCircleSegmentsCount] == 0 )
if( aCircleSegCount > SEG_CNT_MAX || arc_tolerance_factor[aCircleSegCount] == 0 )
{
coeff = 1.0 - cos( M_PI / aCircleSegmentsCount );
coeff = 1.0 - cos( M_PI / aCircleSegCount );
if( aCircleSegmentsCount <= SEG_CNT_MAX )
arc_tolerance_factor[aCircleSegmentsCount] = coeff;
if( aCircleSegCount <= SEG_CNT_MAX )
arc_tolerance_factor[aCircleSegCount] = coeff;
}
else
coeff = arc_tolerance_factor[aCircleSegmentsCount];
{
coeff = arc_tolerance_factor[aCircleSegCount];
}
c.ArcTolerance = std::abs( aAmount ) * coeff;
c.MiterLimit = miterLimit;
@ -684,8 +676,9 @@ struct FractureEdge
return ( y >= m_p1.y || y >= m_p2.y ) && ( y <= m_p1.y || y <= m_p2.y );
}
bool m_connected;
VECTOR2I m_p1, m_p2;
bool m_connected;
VECTOR2I m_p1;
VECTOR2I m_p2;
FractureEdge* m_next;
};
@ -876,9 +869,7 @@ void SHAPE_POLY_SET::Fracture( POLYGON_MODE aFastMode )
Simplify( aFastMode ); // remove overlapping holes/degeneracy
for( POLYGON& paths : m_polys )
{
fractureSingle( paths );
}
}
@ -905,20 +896,20 @@ void SHAPE_POLY_SET::unfractureSingle( SHAPE_POLY_SET::POLYGON& aPoly )
bool operator==( const EDGE& aOther ) const
{
return compareSegs( m_poly->CSegment( m_index ),
aOther.m_poly->CSegment( aOther.m_index ) );
aOther.m_poly->CSegment( aOther.m_index ) );
}
bool operator!=( const EDGE& aOther ) const
{
return !compareSegs( m_poly->CSegment( m_index ),
aOther.m_poly->CSegment( aOther.m_index ) );
aOther.m_poly->CSegment( aOther.m_index ) );
}
struct HASH
{
std::size_t operator()( const EDGE& aEdge ) const
{
const auto& a = aEdge.m_poly->CSegment( aEdge.m_index );
const SEG& a = aEdge.m_poly->CSegment( aEdge.m_index );
return (std::size_t) ( a.A.x + a.B.x + a.A.y + a.B.y );
}
@ -927,16 +918,16 @@ void SHAPE_POLY_SET::unfractureSingle( SHAPE_POLY_SET::POLYGON& aPoly )
struct EDGE_LIST_ENTRY
{
int index;
int index;
EDGE_LIST_ENTRY* next;
};
std::unordered_set<EDGE, EDGE::HASH> uniqueEdges;
auto lc = aPoly[0];
SHAPE_LINE_CHAIN lc = aPoly[0];
lc.Simplify();
auto edgeList = std::make_unique<EDGE_LIST_ENTRY []>( lc.SegmentCount() );
auto edgeList = std::make_unique<EDGE_LIST_ENTRY[]>( lc.SegmentCount() );
for( int i = 0; i < lc.SegmentCount(); i++ )
{
@ -1007,11 +998,12 @@ void SHAPE_POLY_SET::unfractureSingle( SHAPE_POLY_SET::POLYGON& aPoly )
while( queue.size() )
{
auto e_first = (*queue.begin() );
auto e = e_first;
int cnt = 0;
EDGE_LIST_ENTRY* e_first = *queue.begin();
EDGE_LIST_ENTRY* e = e_first;
int cnt = 0;
do {
do
{
edgeBuf[cnt++] = e;
e = e->next;
} while( e && e != e_first );
@ -1020,7 +1012,7 @@ void SHAPE_POLY_SET::unfractureSingle( SHAPE_POLY_SET::POLYGON& aPoly )
for( int i = 0; i < cnt; i++ )
{
auto p = lc.CPoint( edgeBuf[i]->index );
VECTOR2I p = lc.CPoint( edgeBuf[i]->index );
outl.Append( p );
queue.erase( edgeBuf[i] );
}
@ -1061,9 +1053,7 @@ bool SHAPE_POLY_SET::HasHoles() const
void SHAPE_POLY_SET::Unfracture( POLYGON_MODE aFastMode )
{
for( POLYGON& path : m_polys )
{
unfractureSingle( path );
}
Simplify( aFastMode ); // remove overlapping holes/degeneracy
}
@ -1334,9 +1324,9 @@ bool SHAPE_POLY_SET::Collide( const SHAPE* aShape, int aClearance, int* aActual,
int actual = INT_MAX;
VECTOR2I location;
for( const auto& tpoly : m_triangulatedPolys )
for( const std::unique_ptr<TRIANGULATED_POLYGON>& tpoly : m_triangulatedPolys )
{
for ( const auto& tri : tpoly->Triangles() )
for( const TRIANGULATED_POLYGON::TRI& tri : tpoly->Triangles() )
{
int triActual;
VECTOR2I triLocation;
@ -2190,11 +2180,11 @@ MD5_HASH SHAPE_POLY_SET::checksum() const
hash.Hash( m_polys.size() );
for( const auto& outline : m_polys )
for( const POLYGON& outline : m_polys )
{
hash.Hash( outline.size() );
for( const auto& lc : outline )
for( const SHAPE_LINE_CHAIN& lc : outline )
{
hash.Hash( lc.PointCount() );
@ -2217,9 +2207,7 @@ bool SHAPE_POLY_SET::HasTouchingHoles() const
for( int i = 0; i < OutlineCount(); i++ )
{
if( hasTouchingHoles( CPolygon( i ) ) )
{
return true;
}
}
return false;
@ -2228,18 +2216,16 @@ bool SHAPE_POLY_SET::HasTouchingHoles() const
bool SHAPE_POLY_SET::hasTouchingHoles( const POLYGON& aPoly ) const
{
std::set< long long > ptHashes;
std::set<long long> ptHashes;
for( const auto& lc : aPoly )
for( const SHAPE_LINE_CHAIN& lc : aPoly )
{
for( const VECTOR2I& pt : lc.CPoints() )
{
const long long ptHash = (long long) pt.x << 32 | pt.y;
if( ptHashes.count( ptHash ) > 0 )
{
return true;
}
ptHashes.insert( ptHash );
}
@ -2259,7 +2245,7 @@ size_t SHAPE_POLY_SET::GetIndexableSubshapeCount() const
{
size_t n = 0;
for( auto& t : m_triangulatedPolys )
for( const std::unique_ptr<TRIANGULATED_POLYGON>& t : m_triangulatedPolys )
n += t->GetTriangleCount();
return n;
@ -2270,12 +2256,10 @@ void SHAPE_POLY_SET:: GetIndexableSubshapes( std::vector<SHAPE*>& aSubshapes )
{
aSubshapes.reserve( GetIndexableSubshapeCount() );
for( auto& tpoly : m_triangulatedPolys )
for( const std::unique_ptr<TRIANGULATED_POLYGON>& tpoly : m_triangulatedPolys )
{
for ( auto& tri : tpoly->Triangles() )
{
for( TRIANGULATED_POLYGON::TRI& tri : tpoly->Triangles() )
aSubshapes.push_back( &tri );
}
}
}