Rotate fp zones before comparing with library versions.
Also includes some performance fixes to not copy around triangulation data when it's not needed. Fixes https://gitlab.com/kicad/code/kicad/issues/10143
This commit is contained in:
parent
2cb719f0cf
commit
65185f53a1
|
@ -722,11 +722,9 @@ void BOARD_ADAPTER::addShape( const PCB_SHAPE* aShape, CONTAINER_2D_BASE* aConta
|
||||||
void BOARD_ADAPTER::addSolidAreasShapes( const ZONE* aZone, CONTAINER_2D_BASE* aContainer,
|
void BOARD_ADAPTER::addSolidAreasShapes( const ZONE* aZone, CONTAINER_2D_BASE* aContainer,
|
||||||
PCB_LAYER_ID aLayerId )
|
PCB_LAYER_ID aLayerId )
|
||||||
{
|
{
|
||||||
// Copy the polys list because we have to simplify it
|
|
||||||
SHAPE_POLY_SET polyList = SHAPE_POLY_SET( *aZone->GetFilledPolysList( aLayerId ) );
|
|
||||||
|
|
||||||
// This convert the poly in outline and holes
|
// This convert the poly in outline and holes
|
||||||
ConvertPolygonToTriangles( polyList, *aContainer, m_biuTo3Dunits, *aZone );
|
ConvertPolygonToTriangles( *aZone->GetFilledPolysList( aLayerId ), *aContainer,
|
||||||
|
m_biuTo3Dunits, *aZone );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -395,9 +395,8 @@ OPENGL_RENDER_LIST* RENDER_3D_OPENGL::createBoard( const SHAPE_POLY_SET& aBoardP
|
||||||
{
|
{
|
||||||
OPENGL_RENDER_LIST* dispLists = nullptr;
|
OPENGL_RENDER_LIST* dispLists = nullptr;
|
||||||
CONTAINER_2D boardContainer;
|
CONTAINER_2D boardContainer;
|
||||||
SHAPE_POLY_SET brd_outlines = aBoardPoly;
|
|
||||||
|
|
||||||
ConvertPolygonToTriangles( brd_outlines, boardContainer, m_boardAdapter.BiuTo3dUnits(),
|
ConvertPolygonToTriangles( aBoardPoly, boardContainer, m_boardAdapter.BiuTo3dUnits(),
|
||||||
(const BOARD_ITEM &)*m_boardAdapter.GetBoard() );
|
(const BOARD_ITEM &)*m_boardAdapter.GetBoard() );
|
||||||
|
|
||||||
const LIST_OBJECT2D& listBoardObject2d = boardContainer.GetList();
|
const LIST_OBJECT2D& listBoardObject2d = boardContainer.GetList();
|
||||||
|
@ -481,7 +480,7 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
|
||||||
m_antiBoard = createBoard( m_antiBoardPolys );
|
m_antiBoard = createBoard( m_antiBoardPolys );
|
||||||
}
|
}
|
||||||
|
|
||||||
SHAPE_POLY_SET board_poly_with_holes = m_boardAdapter.GetBoardPoly();
|
SHAPE_POLY_SET board_poly_with_holes = m_boardAdapter.GetBoardPoly().CloneDropTriangulation();
|
||||||
board_poly_with_holes.BooleanSubtract( m_boardAdapter.GetThroughHoleOdPolys(),
|
board_poly_with_holes.BooleanSubtract( m_boardAdapter.GetThroughHoleOdPolys(),
|
||||||
SHAPE_POLY_SET::PM_FAST );
|
SHAPE_POLY_SET::PM_FAST );
|
||||||
board_poly_with_holes.BooleanSubtract( m_boardAdapter.GetOuterNonPlatedThroughHolePoly(),
|
board_poly_with_holes.BooleanSubtract( m_boardAdapter.GetOuterNonPlatedThroughHolePoly(),
|
||||||
|
@ -496,11 +495,13 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
|
||||||
if( aStatusReporter )
|
if( aStatusReporter )
|
||||||
aStatusReporter->Report( _( "Load OpenGL: holes and vias" ) );
|
aStatusReporter->Report( _( "Load OpenGL: holes and vias" ) );
|
||||||
|
|
||||||
SHAPE_POLY_SET outerPolyTHT = m_boardAdapter.GetThroughHoleOdPolys();
|
SHAPE_POLY_SET outerPolyTHT = m_boardAdapter.GetThroughHoleOdPolys().CloneDropTriangulation();
|
||||||
|
|
||||||
if( m_boardAdapter.m_Cfg->m_Render.realistic )
|
if( m_boardAdapter.m_Cfg->m_Render.realistic )
|
||||||
|
{
|
||||||
outerPolyTHT.BooleanIntersection( m_boardAdapter.GetBoardPoly(),
|
outerPolyTHT.BooleanIntersection( m_boardAdapter.GetBoardPoly(),
|
||||||
SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||||
|
}
|
||||||
|
|
||||||
m_outerThroughHoles = generateHoles( m_boardAdapter.GetThroughHoleOds().GetList(),
|
m_outerThroughHoles = generateHoles( m_boardAdapter.GetThroughHoleOds().GetList(),
|
||||||
outerPolyTHT, 1.0f, 0.0f, false,
|
outerPolyTHT, 1.0f, 0.0f, false,
|
||||||
|
@ -630,9 +631,12 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
|
||||||
if( m_boardAdapter.m_Cfg->m_Render.renderPlatedPadsAsPlated
|
if( m_boardAdapter.m_Cfg->m_Render.renderPlatedPadsAsPlated
|
||||||
&& m_boardAdapter.m_Cfg->m_Render.realistic )
|
&& m_boardAdapter.m_Cfg->m_Render.realistic )
|
||||||
{
|
{
|
||||||
if( m_boardAdapter.GetFrontPlatedPadPolys() )
|
const SHAPE_POLY_SET* frontPlatedPadPolys = m_boardAdapter.GetFrontPlatedPadPolys();
|
||||||
|
const SHAPE_POLY_SET* backPlatedPadPolys = m_boardAdapter.GetBackPlatedPadPolys();
|
||||||
|
|
||||||
|
if( frontPlatedPadPolys )
|
||||||
{
|
{
|
||||||
SHAPE_POLY_SET polySubtracted = *m_boardAdapter.GetFrontPlatedPadPolys();
|
SHAPE_POLY_SET polySubtracted = frontPlatedPadPolys->CloneDropTriangulation();
|
||||||
polySubtracted.BooleanIntersection( m_boardAdapter.GetBoardPoly(),
|
polySubtracted.BooleanIntersection( m_boardAdapter.GetBoardPoly(),
|
||||||
SHAPE_POLY_SET::PM_FAST );
|
SHAPE_POLY_SET::PM_FAST );
|
||||||
polySubtracted.BooleanSubtract( m_boardAdapter.GetThroughHoleOdPolys(),
|
polySubtracted.BooleanSubtract( m_boardAdapter.GetThroughHoleOdPolys(),
|
||||||
|
@ -648,9 +652,9 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
|
||||||
m_layers[F_Cu] = generateEmptyLayerList( F_Cu );
|
m_layers[F_Cu] = generateEmptyLayerList( F_Cu );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( m_boardAdapter.GetBackPlatedPadPolys() )
|
if( backPlatedPadPolys )
|
||||||
{
|
{
|
||||||
SHAPE_POLY_SET polySubtracted = *m_boardAdapter.GetBackPlatedPadPolys();
|
SHAPE_POLY_SET polySubtracted = backPlatedPadPolys->CloneDropTriangulation();
|
||||||
polySubtracted.BooleanIntersection( m_boardAdapter.GetBoardPoly(),
|
polySubtracted.BooleanIntersection( m_boardAdapter.GetBoardPoly(),
|
||||||
SHAPE_POLY_SET::PM_FAST );
|
SHAPE_POLY_SET::PM_FAST );
|
||||||
polySubtracted.BooleanSubtract( m_boardAdapter.GetThroughHoleOdPolys(),
|
polySubtracted.BooleanSubtract( m_boardAdapter.GetThroughHoleOdPolys(),
|
||||||
|
|
|
@ -118,14 +118,14 @@ bool TRIANGLE_2D::IsPointInside( const SFVEC2F& aPoint ) const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ConvertPolygonToTriangles( SHAPE_POLY_SET& aPolyList, CONTAINER_2D_BASE& aDstContainer,
|
void ConvertPolygonToTriangles( const SHAPE_POLY_SET& aPolyList, CONTAINER_2D_BASE& aDstContainer,
|
||||||
float aBiuTo3dUnitsScale, const BOARD_ITEM& aBoardItem )
|
float aBiuTo3dUnitsScale, const BOARD_ITEM& aBoardItem )
|
||||||
{
|
{
|
||||||
VECTOR2I a;
|
VECTOR2I a;
|
||||||
VECTOR2I b;
|
VECTOR2I b;
|
||||||
VECTOR2I c;
|
VECTOR2I c;
|
||||||
|
|
||||||
aPolyList.CacheTriangulation( false );
|
const_cast<SHAPE_POLY_SET&>( aPolyList ).CacheTriangulation( false );
|
||||||
const double conver_d = (double)aBiuTo3dUnitsScale;
|
const double conver_d = (double)aBiuTo3dUnitsScale;
|
||||||
|
|
||||||
for( unsigned int j = 0; j < aPolyList.TriangulatedPolyCount(); j++ )
|
for( unsigned int j = 0; j < aPolyList.TriangulatedPolyCount(); j++ )
|
||||||
|
|
|
@ -64,6 +64,6 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void ConvertPolygonToTriangles( SHAPE_POLY_SET& aPolyList, CONTAINER_2D_BASE& aDstContainer,
|
void ConvertPolygonToTriangles( const SHAPE_POLY_SET& aPolyList, CONTAINER_2D_BASE& aDstContainer,
|
||||||
float aBiuTo3dUnitsScale, const BOARD_ITEM& aBoardItem );
|
float aBiuTo3dUnitsScale, const BOARD_ITEM& aBoardItem );
|
||||||
#endif // _TRIANGLE_2D_H_
|
#endif // _TRIANGLE_2D_H_
|
||||||
|
|
|
@ -417,6 +417,7 @@ void DS_DATA_ITEM_POLYGONS::SyncDrawItems( DS_DRAW_ITEM_LIST* aCollector, KIGFX:
|
||||||
|
|
||||||
// Transfer all outlines (basic polygons)
|
// Transfer all outlines (basic polygons)
|
||||||
SHAPE_POLY_SET& polygons = poly_shape->GetPolygons();
|
SHAPE_POLY_SET& polygons = poly_shape->GetPolygons();
|
||||||
|
|
||||||
for( int kk = 0; kk < GetPolyCount(); kk++ )
|
for( int kk = 0; kk < GetPolyCount(); kk++ )
|
||||||
{
|
{
|
||||||
// Create new outline
|
// Create new outline
|
||||||
|
|
|
@ -1696,7 +1696,7 @@ void GERBER_PLOTTER::FlashPadCustom( const VECTOR2I& aPadPos, const VECTOR2I& aS
|
||||||
if( aData )
|
if( aData )
|
||||||
gbr_metadata = *static_cast<GBR_METADATA*>( aData );
|
gbr_metadata = *static_cast<GBR_METADATA*>( aData );
|
||||||
|
|
||||||
SHAPE_POLY_SET polyshape = *aPolygons;
|
SHAPE_POLY_SET polyshape = aPolygons->CloneDropTriangulation();
|
||||||
|
|
||||||
if( aTraceMode != FILLED )
|
if( aTraceMode != FILLED )
|
||||||
{
|
{
|
||||||
|
|
|
@ -476,7 +476,7 @@ void GBR_TO_PCB_EXPORTER::writePcbHeader( const int* aLayerLookUpTable )
|
||||||
void GBR_TO_PCB_EXPORTER::writePcbPolygon( const SHAPE_POLY_SET& aPolys, int aLayer,
|
void GBR_TO_PCB_EXPORTER::writePcbPolygon( const SHAPE_POLY_SET& aPolys, int aLayer,
|
||||||
const VECTOR2I& aOffset )
|
const VECTOR2I& aOffset )
|
||||||
{
|
{
|
||||||
SHAPE_POLY_SET polys = aPolys;
|
SHAPE_POLY_SET polys = aPolys.CloneDropTriangulation();
|
||||||
|
|
||||||
// Cleanup the polygon
|
// Cleanup the polygon
|
||||||
polys.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
polys.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||||
|
@ -523,7 +523,7 @@ void GBR_TO_PCB_EXPORTER::writePcbPolygon( const SHAPE_POLY_SET& aPolys, int aLa
|
||||||
|
|
||||||
void GBR_TO_PCB_EXPORTER::writePcbZoneItem( const GERBER_DRAW_ITEM* aGbrItem, int aLayer )
|
void GBR_TO_PCB_EXPORTER::writePcbZoneItem( const GERBER_DRAW_ITEM* aGbrItem, int aLayer )
|
||||||
{
|
{
|
||||||
SHAPE_POLY_SET polys = aGbrItem->m_Polygon;
|
SHAPE_POLY_SET polys = aGbrItem->m_Polygon.CloneDropTriangulation();
|
||||||
polys.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
polys.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||||
|
|
||||||
if( polys.OutlineCount() == 0 )
|
if( polys.OutlineCount() == 0 )
|
||||||
|
|
|
@ -536,6 +536,8 @@ public:
|
||||||
/// @copydoc SHAPE::Clone()
|
/// @copydoc SHAPE::Clone()
|
||||||
SHAPE* Clone() const override;
|
SHAPE* Clone() const override;
|
||||||
|
|
||||||
|
SHAPE_POLY_SET CloneDropTriangulation() const;
|
||||||
|
|
||||||
///< Creates a new empty polygon in the set and returns its index
|
///< Creates a new empty polygon in the set and returns its index
|
||||||
int NewOutline();
|
int NewOutline();
|
||||||
|
|
||||||
|
@ -1366,6 +1368,10 @@ public:
|
||||||
static const SHAPE_POLY_SET BuildPolysetFromOrientedPaths( const std::vector<SHAPE_LINE_CHAIN>& aPaths, bool aReverseOrientation = false, bool aEvenOdd = false );
|
static const SHAPE_POLY_SET BuildPolysetFromOrientedPaths( const std::vector<SHAPE_LINE_CHAIN>& aPaths, bool aReverseOrientation = false, bool aEvenOdd = false );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
enum DROP_TRIANGULATION_FLAG { SINGLETON };
|
||||||
|
|
||||||
|
SHAPE_POLY_SET( const SHAPE_POLY_SET& aOther, DROP_TRIANGULATION_FLAG );
|
||||||
|
|
||||||
void fractureSingle( POLYGON& paths );
|
void fractureSingle( POLYGON& paths );
|
||||||
void unfractureSingle ( POLYGON& path );
|
void unfractureSingle ( POLYGON& path );
|
||||||
void importTree( ClipperLib::PolyTree* tree,
|
void importTree( ClipperLib::PolyTree* tree,
|
||||||
|
|
|
@ -108,6 +108,16 @@ SHAPE_POLY_SET::SHAPE_POLY_SET( const SHAPE_POLY_SET& aOther ) :
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SHAPE_POLY_SET::SHAPE_POLY_SET( const SHAPE_POLY_SET& aOther, DROP_TRIANGULATION_FLAG ) :
|
||||||
|
SHAPE( aOther ),
|
||||||
|
m_polys( aOther.m_polys )
|
||||||
|
{
|
||||||
|
m_triangulationValid = false;
|
||||||
|
m_hash = MD5_HASH();
|
||||||
|
m_triangulatedPolys.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SHAPE_POLY_SET::~SHAPE_POLY_SET()
|
SHAPE_POLY_SET::~SHAPE_POLY_SET()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -119,6 +129,12 @@ SHAPE* SHAPE_POLY_SET::Clone() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SHAPE_POLY_SET SHAPE_POLY_SET::CloneDropTriangulation() const
|
||||||
|
{
|
||||||
|
return SHAPE_POLY_SET( *this, DROP_TRIANGULATION_FLAG::SINGLETON );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SHAPE_POLY_SET::GetRelativeIndices( int aGlobalIdx,
|
bool SHAPE_POLY_SET::GetRelativeIndices( int aGlobalIdx,
|
||||||
SHAPE_POLY_SET::VERTEX_INDEX* aRelativeIndices ) const
|
SHAPE_POLY_SET::VERTEX_INDEX* aRelativeIndices ) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -145,7 +145,7 @@ bool AR_AUTOPLACER::fillMatrix()
|
||||||
VECTOR2I coord_orgin = m_matrix.GetBrdCoordOrigin(); // Board coordinate of matruix cell (0,0)
|
VECTOR2I coord_orgin = m_matrix.GetBrdCoordOrigin(); // Board coordinate of matruix cell (0,0)
|
||||||
|
|
||||||
// Create a single board outline:
|
// Create a single board outline:
|
||||||
SHAPE_POLY_SET brd_shape = m_boardShape;
|
SHAPE_POLY_SET brd_shape = m_boardShape.CloneDropTriangulation();
|
||||||
brd_shape.Fracture( SHAPE_POLY_SET::PM_FAST );
|
brd_shape.Fracture( SHAPE_POLY_SET::PM_FAST );
|
||||||
const SHAPE_LINE_CHAIN& outline = brd_shape.Outline(0);
|
const SHAPE_LINE_CHAIN& outline = brd_shape.Outline(0);
|
||||||
const BOX2I& rect = outline.BBox();
|
const BOX2I& rect = outline.BBox();
|
||||||
|
@ -800,7 +800,7 @@ void AR_AUTOPLACER::drawPlacementRoutingMatrix( )
|
||||||
m_overlay->SetIsFill( true );
|
m_overlay->SetIsFill( true );
|
||||||
m_overlay->SetIsStroke( false );
|
m_overlay->SetIsStroke( false );
|
||||||
|
|
||||||
SHAPE_POLY_SET freeArea = m_topFreeArea;
|
SHAPE_POLY_SET freeArea = m_topFreeArea.CloneDropTriangulation();
|
||||||
freeArea.Fracture( SHAPE_POLY_SET::PM_FAST );
|
freeArea.Fracture( SHAPE_POLY_SET::PM_FAST );
|
||||||
|
|
||||||
// Draw the free polygon areas, top side:
|
// Draw the free polygon areas, top side:
|
||||||
|
|
|
@ -244,9 +244,9 @@ bool ConvertOutlineToPolygon( std::vector<PCB_SHAPE*>& aSegList, SHAPE_POLY_SET&
|
||||||
|
|
||||||
case SHAPE_T::POLY:
|
case SHAPE_T::POLY:
|
||||||
{
|
{
|
||||||
const SHAPE_POLY_SET poly = graphic->GetPolyShape();
|
const SHAPE_POLY_SET& poly = graphic->GetPolyShape();
|
||||||
EDA_ANGLE orientation = ANGLE_0;
|
EDA_ANGLE orientation = ANGLE_0;
|
||||||
VECTOR2I offset = VECTOR2I( 0, 0 );
|
VECTOR2I offset = VECTOR2I( 0, 0 );
|
||||||
|
|
||||||
if( graphic->GetParentFootprint() )
|
if( graphic->GetParentFootprint() )
|
||||||
{
|
{
|
||||||
|
@ -946,7 +946,7 @@ bool isCopperOutside( const FOOTPRINT* aMod, SHAPE_POLY_SET& aShape )
|
||||||
|
|
||||||
for( PAD* pad : aMod->Pads() )
|
for( PAD* pad : aMod->Pads() )
|
||||||
{
|
{
|
||||||
SHAPE_POLY_SET poly = aShape;
|
SHAPE_POLY_SET poly = aShape.CloneDropTriangulation();
|
||||||
|
|
||||||
poly.BooleanIntersection( *pad->GetEffectivePolygon(), SHAPE_POLY_SET::PM_FAST );
|
poly.BooleanIntersection( *pad->GetEffectivePolygon(), SHAPE_POLY_SET::PM_FAST );
|
||||||
|
|
||||||
|
|
|
@ -130,7 +130,7 @@ bool DRC_TEST_PROVIDER_DISALLOW::Run()
|
||||||
// enough to exclude it. This is particularly important for detecting
|
// enough to exclude it. This is particularly important for detecting
|
||||||
// copper fills as they will be exactly touching along the entire
|
// copper fills as they will be exactly touching along the entire
|
||||||
// exclusion border.
|
// exclusion border.
|
||||||
SHAPE_POLY_SET areaPoly = *ruleArea->Outline();
|
SHAPE_POLY_SET areaPoly = ruleArea->Outline()->CloneDropTriangulation();
|
||||||
areaPoly.Deflate( epsilon, 0, SHAPE_POLY_SET::ALLOW_ACUTE_CORNERS );
|
areaPoly.Deflate( epsilon, 0, SHAPE_POLY_SET::ALLOW_ACUTE_CORNERS );
|
||||||
|
|
||||||
DRC_RTREE* zoneRTree = board->m_CopperZoneRTrees[ copperZone ].get();
|
DRC_RTREE* zoneRTree = board->m_CopperZoneRTrees[ copperZone ].get();
|
||||||
|
|
|
@ -294,11 +294,17 @@ bool zonesNeedUpdate( const FP_ZONE* a, const FP_ZONE* b )
|
||||||
|
|
||||||
TEST( a->Outline()->TotalVertices(), b->Outline()->TotalVertices() );
|
TEST( a->Outline()->TotalVertices(), b->Outline()->TotalVertices() );
|
||||||
|
|
||||||
|
// The footprint's zone will be in board position, so we must translate & rotate the library
|
||||||
|
// footprint's zone to match.
|
||||||
|
FOOTPRINT* parentFootprint = static_cast<FOOTPRINT*>( a->GetParentFootprint() );
|
||||||
|
const SHAPE_POLY_SET& aPoly = *a->Outline();
|
||||||
|
SHAPE_POLY_SET bPoly = b->Outline()->CloneDropTriangulation();
|
||||||
|
|
||||||
|
bPoly.Rotate( parentFootprint->GetOrientation() );
|
||||||
|
bPoly.Move( parentFootprint->GetPosition() );
|
||||||
|
|
||||||
for( int ii = 0; ii < a->Outline()->TotalVertices(); ++ii )
|
for( int ii = 0; ii < a->Outline()->TotalVertices(); ++ii )
|
||||||
{
|
TEST( aPoly.CVertex( ii ), bPoly.CVertex( ii ) );
|
||||||
TEST( a->Outline()->CVertex( ii ) - a->GetParent()->GetPosition(),
|
|
||||||
b->Outline()->CVertex( ii ) - b->GetParent()->GetPosition() );
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -516,7 +516,7 @@ void DRC_TEST_PROVIDER_MECHANICAL_CLEARANCE::testZoneLayer( ZONE* aZone, PCB_LAY
|
||||||
{
|
{
|
||||||
int epsilon = m_board->GetDesignSettings().GetDRCEpsilon();
|
int epsilon = m_board->GetDesignSettings().GetDRCEpsilon();
|
||||||
int clearance = aConstraint.GetValue().Min();
|
int clearance = aConstraint.GetValue().Min();
|
||||||
SHAPE_POLY_SET fill = *aZone->GetFilledPolysList( aLayer );
|
SHAPE_POLY_SET fill = aZone->GetFilledPolysList( aLayer )->CloneDropTriangulation();
|
||||||
|
|
||||||
if( aConstraint.GetSeverity() == RPT_SEVERITY_IGNORE || clearance - epsilon <= 0 )
|
if( aConstraint.GetSeverity() == RPT_SEVERITY_IGNORE || clearance - epsilon <= 0 )
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -125,6 +125,7 @@ bool DRC_TEST_PROVIDER_SLIVER_CHECKER::Run()
|
||||||
{
|
{
|
||||||
PCB_LAYER_ID layer = copperLayers[i];
|
PCB_LAYER_ID layer = copperLayers[i];
|
||||||
SHAPE_POLY_SET& poly = layerPolys[i];
|
SHAPE_POLY_SET& poly = layerPolys[i];
|
||||||
|
SHAPE_POLY_SET fill;
|
||||||
|
|
||||||
forEachGeometryItem( s_allBasicItems, LSET().set( layer ),
|
forEachGeometryItem( s_allBasicItems, LSET().set( layer ),
|
||||||
[&]( BOARD_ITEM* item ) -> bool
|
[&]( BOARD_ITEM* item ) -> bool
|
||||||
|
@ -135,11 +136,11 @@ bool DRC_TEST_PROVIDER_SLIVER_CHECKER::Run()
|
||||||
|
|
||||||
if( !zone->GetIsRuleArea() )
|
if( !zone->GetIsRuleArea() )
|
||||||
{
|
{
|
||||||
SHAPE_POLY_SET layerPoly = *zone->GetFill( layer );
|
fill = zone->GetFill( layer )->CloneDropTriangulation();
|
||||||
layerPoly.Unfracture( SHAPE_POLY_SET::PM_FAST );
|
fill.Unfracture( SHAPE_POLY_SET::PM_FAST );
|
||||||
|
|
||||||
for( int jj = 0; jj < layerPoly.OutlineCount(); ++jj )
|
for( int jj = 0; jj < fill.OutlineCount(); ++jj )
|
||||||
poly.AddOutline( layerPoly.Outline( jj ) );
|
poly.AddOutline( fill.Outline( jj ) );
|
||||||
|
|
||||||
// Report progress on board zones only. Everything
|
// Report progress on board zones only. Everything
|
||||||
// else is in the noise.
|
// else is in the noise.
|
||||||
|
|
|
@ -169,7 +169,7 @@ bool DRC_TEST_PROVIDER_TEXT_DIMS::Run()
|
||||||
for( ii = 0; ii < outlineCount; ++ii )
|
for( ii = 0; ii < outlineCount; ++ii )
|
||||||
holeCount += outlineGlyph->HoleCount( ii );
|
holeCount += outlineGlyph->HoleCount( ii );
|
||||||
|
|
||||||
SHAPE_POLY_SET poly = *outlineGlyph;
|
SHAPE_POLY_SET poly = outlineGlyph->CloneDropTriangulation();
|
||||||
poly.Deflate( constraint.Value().Min() / 2, 16 );
|
poly.Deflate( constraint.Value().Min() / 2, 16 );
|
||||||
poly.Simplify( SHAPE_POLY_SET::PM_FAST );
|
poly.Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||||
|
|
||||||
|
|
|
@ -485,45 +485,51 @@ bool HYPERLYNX_EXPORTER::writeNetObjects( const std::vector<BOARD_ITEM*>& aObjec
|
||||||
for( PCB_LAYER_ID layer : zone->GetLayerSet().Seq() )
|
for( PCB_LAYER_ID layer : zone->GetLayerSet().Seq() )
|
||||||
{
|
{
|
||||||
const wxString layerName = m_board->GetLayerName( layer );
|
const wxString layerName = m_board->GetLayerName( layer );
|
||||||
SHAPE_POLY_SET filledShape = *zone->GetFilledPolysList( layer );
|
SHAPE_POLY_SET fill = zone->GetFilledPolysList( layer )->CloneDropTriangulation();
|
||||||
|
|
||||||
filledShape.Simplify( SHAPE_POLY_SET::PM_FAST );
|
fill.Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||||
|
|
||||||
for( int i = 0; i < filledShape.OutlineCount(); i++ )
|
for( int i = 0; i < fill.OutlineCount(); i++ )
|
||||||
{
|
{
|
||||||
const SHAPE_LINE_CHAIN& outl = filledShape.COutline( i );
|
const SHAPE_LINE_CHAIN& outl = fill.COutline( i );
|
||||||
|
|
||||||
auto p0 = outl.CPoint( 0 );
|
auto p0 = outl.CPoint( 0 );
|
||||||
m_out->Print( 1, "{POLYGON T=POUR L=\"%s\" ID=%d X=%.10f Y=%.10f\n",
|
m_out->Print( 1, "{POLYGON T=POUR L=\"%s\" ID=%d X=%.10f Y=%.10f\n",
|
||||||
(const char*) layerName.c_str(), m_polyId, iu2hyp( p0.x ),
|
(const char*) layerName.c_str(),
|
||||||
iu2hyp( p0.y ) );
|
m_polyId,
|
||||||
|
iu2hyp( p0.x ),
|
||||||
|
iu2hyp( p0.y ) );
|
||||||
|
|
||||||
for( int v = 0; v < outl.PointCount(); v++ )
|
for( int v = 0; v < outl.PointCount(); v++ )
|
||||||
{
|
{
|
||||||
m_out->Print( 2, "(LINE X=%.10f Y=%.10f)\n", iu2hyp( outl.CPoint( v ).x ),
|
m_out->Print( 2, "(LINE X=%.10f Y=%.10f)\n",
|
||||||
iu2hyp( outl.CPoint( v ).y ) );
|
iu2hyp( outl.CPoint( v ).x ),
|
||||||
|
iu2hyp( outl.CPoint( v ).y ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
m_out->Print( 2, "(LINE X=%.10f Y=%.10f)\n", iu2hyp( p0.x ), iu2hyp( p0.y ) );
|
m_out->Print( 2, "(LINE X=%.10f Y=%.10f)\n", iu2hyp( p0.x ), iu2hyp( p0.y ) );
|
||||||
m_out->Print( 1, "}\n" );
|
m_out->Print( 1, "}\n" );
|
||||||
|
|
||||||
for( int h = 0; h < filledShape.HoleCount( i ); h++ )
|
for( int h = 0; h < fill.HoleCount( i ); h++ )
|
||||||
{
|
{
|
||||||
const SHAPE_LINE_CHAIN& holeShape = filledShape.CHole( i, h );
|
const SHAPE_LINE_CHAIN& holeShape = fill.CHole( i, h );
|
||||||
VECTOR2I ph0 = holeShape.CPoint( 0 );
|
VECTOR2I ph0 = holeShape.CPoint( 0 );
|
||||||
|
|
||||||
m_out->Print( 1, "{POLYVOID ID=%d X=%.10f Y=%.10f\n", m_polyId,
|
m_out->Print( 1, "{POLYVOID ID=%d X=%.10f Y=%.10f\n",
|
||||||
iu2hyp( ph0.x ), iu2hyp( ph0.y ) );
|
m_polyId,
|
||||||
|
iu2hyp( ph0.x ),
|
||||||
|
iu2hyp( ph0.y ) );
|
||||||
|
|
||||||
for( int v = 0; v < holeShape.PointCount(); v++ )
|
for( int v = 0; v < holeShape.PointCount(); v++ )
|
||||||
{
|
{
|
||||||
m_out->Print( 2, "(LINE X=%.10f Y=%.10f)\n",
|
m_out->Print( 2, "(LINE X=%.10f Y=%.10f)\n",
|
||||||
iu2hyp( holeShape.CPoint( v ).x ),
|
iu2hyp( holeShape.CPoint( v ).x ),
|
||||||
iu2hyp( holeShape.CPoint( v ).y ) );
|
iu2hyp( holeShape.CPoint( v ).y ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
m_out->Print( 2, "(LINE X=%.10f Y=%.10f)\n",
|
m_out->Print( 2, "(LINE X=%.10f Y=%.10f)\n",
|
||||||
iu2hyp( ph0.x ), iu2hyp( ph0.y ) );
|
iu2hyp( ph0.x ),
|
||||||
|
iu2hyp( ph0.y ) );
|
||||||
m_out->Print( 1, "}\n" );
|
m_out->Print( 1, "}\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -894,7 +894,7 @@ SHAPE_POLY_SET FOOTPRINT::GetBoundingHull() const
|
||||||
{
|
{
|
||||||
for( PCB_LAYER_ID layer : zone->GetLayerSet().Seq() )
|
for( PCB_LAYER_ID layer : zone->GetLayerSet().Seq() )
|
||||||
{
|
{
|
||||||
SHAPE_POLY_SET layerPoly = *zone->GetFilledPolysList( layer );
|
const SHAPE_POLY_SET& layerPoly = *zone->GetFilledPolysList( layer );
|
||||||
|
|
||||||
for( int ii = 0; ii < layerPoly.OutlineCount(); ii++ )
|
for( int ii = 0; ii < layerPoly.OutlineCount(); ii++ )
|
||||||
{
|
{
|
||||||
|
|
|
@ -452,7 +452,7 @@ bool calcIsInsideArea( BOARD_ITEM* aItem, const EDA_RECT& aItemBBox, PCB_EXPR_CO
|
||||||
// Collisions include touching, so we need to deflate outline by enough to exclude it.
|
// Collisions include touching, so we need to deflate outline by enough to exclude it.
|
||||||
// This is particularly important for detecting copper fills as they will be exactly
|
// This is particularly important for detecting copper fills as they will be exactly
|
||||||
// touching along the entire exclusion border.
|
// touching along the entire exclusion border.
|
||||||
SHAPE_POLY_SET areaOutline = *aArea->Outline();
|
SHAPE_POLY_SET areaOutline = aArea->Outline()->CloneDropTriangulation();
|
||||||
areaOutline.Deflate( board->GetDesignSettings().GetDRCEpsilon(), 0,
|
areaOutline.Deflate( board->GetDesignSettings().GetDRCEpsilon(), 0,
|
||||||
SHAPE_POLY_SET::ALLOW_ACUTE_CORNERS );
|
SHAPE_POLY_SET::ALLOW_ACUTE_CORNERS );
|
||||||
|
|
||||||
|
@ -498,7 +498,7 @@ bool calcIsInsideArea( BOARD_ITEM* aItem, const EDA_RECT& aItemBBox, PCB_EXPR_CO
|
||||||
|
|
||||||
if( ( aArea->GetLayerSet() & LSET::FrontMask() ).any() )
|
if( ( aArea->GetLayerSet() & LSET::FrontMask() ).any() )
|
||||||
{
|
{
|
||||||
SHAPE_POLY_SET courtyard = footprint->GetPolyCourtyard( F_CrtYd );
|
const SHAPE_POLY_SET& courtyard = footprint->GetPolyCourtyard( F_CrtYd );
|
||||||
|
|
||||||
if( courtyard.OutlineCount() == 0 )
|
if( courtyard.OutlineCount() == 0 )
|
||||||
{
|
{
|
||||||
|
@ -515,7 +515,7 @@ bool calcIsInsideArea( BOARD_ITEM* aItem, const EDA_RECT& aItemBBox, PCB_EXPR_CO
|
||||||
|
|
||||||
if( ( aArea->GetLayerSet() & LSET::BackMask() ).any() )
|
if( ( aArea->GetLayerSet() & LSET::BackMask() ).any() )
|
||||||
{
|
{
|
||||||
SHAPE_POLY_SET courtyard = footprint->GetPolyCourtyard( B_CrtYd );
|
const SHAPE_POLY_SET& courtyard = footprint->GetPolyCourtyard( B_CrtYd );
|
||||||
|
|
||||||
if( courtyard.OutlineCount() == 0 )
|
if( courtyard.OutlineCount() == 0 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -546,7 +546,7 @@ bool PCB_PAINTER::Draw( const VIEW_ITEM* aItem, int aLayer )
|
||||||
|
|
||||||
if( fp )
|
if( fp )
|
||||||
{
|
{
|
||||||
SHAPE_POLY_SET convex = fp->GetBoundingHull();
|
const SHAPE_POLY_SET& convex = fp->GetBoundingHull();
|
||||||
|
|
||||||
m_gal->DrawPolyline( convex.COutline( 0 ) );
|
m_gal->DrawPolyline( convex.COutline( 0 ) );
|
||||||
}
|
}
|
||||||
|
@ -1953,7 +1953,7 @@ void PCB_PAINTER::draw( const FOOTPRINT* aFootprint, int aLayer )
|
||||||
m_gal->SetIsStroke( false );
|
m_gal->SetIsStroke( false );
|
||||||
m_gal->SetFillColor( color );
|
m_gal->SetFillColor( color );
|
||||||
|
|
||||||
SHAPE_POLY_SET poly = aFootprint->GetBoundingHull();
|
const SHAPE_POLY_SET& poly = aFootprint->GetBoundingHull();
|
||||||
m_gal->DrawPolygon( poly );
|
m_gal->DrawPolygon( poly );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -614,7 +614,7 @@ void PlotStandardLayer( BOARD* aBoard, PLOTTER* aPlotter, LSET aLayerMask,
|
||||||
if( !aLayerMask[layer] )
|
if( !aLayerMask[layer] )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
SHAPE_POLY_SET mainArea = *zone->GetFilledPolysList( layer );
|
SHAPE_POLY_SET mainArea = zone->GetFilledPolysList( layer )->CloneDropTriangulation();
|
||||||
SHAPE_POLY_SET islands;
|
SHAPE_POLY_SET islands;
|
||||||
|
|
||||||
for( int i = mainArea.OutlineCount() - 1; i >= 0; i-- )
|
for( int i = mainArea.OutlineCount() - 1; i >= 0; i-- )
|
||||||
|
|
|
@ -1013,7 +1013,7 @@ void BRDITEMS_PLOTTER::PlotPcbShape( const PCB_SHAPE* aShape )
|
||||||
// ( for the future or to show a non expected shape )
|
// ( for the future or to show a non expected shape )
|
||||||
// This must be simplified and fractured to prevent overlapping polygons
|
// This must be simplified and fractured to prevent overlapping polygons
|
||||||
// from generating invalid Gerber files
|
// from generating invalid Gerber files
|
||||||
SHAPE_POLY_SET tmpPoly = SHAPE_POLY_SET( aShape->GetPolyShape() );
|
SHAPE_POLY_SET tmpPoly = aShape->GetPolyShape().CloneDropTriangulation();
|
||||||
tmpPoly.Fracture( SHAPE_POLY_SET::PM_FAST );
|
tmpPoly.Fracture( SHAPE_POLY_SET::PM_FAST );
|
||||||
FILL_T fill = aShape->IsFilled() ? FILL_T::FILLED_SHAPE : FILL_T::NO_FILL;
|
FILL_T fill = aShape->IsFilled() ? FILL_T::FILLED_SHAPE : FILL_T::NO_FILL;
|
||||||
|
|
||||||
|
|
|
@ -1060,7 +1060,7 @@ bool ZONE::BuildSmoothedPoly( SHAPE_POLY_SET& aSmoothedPoly, PCB_LAYER_ID aLayer
|
||||||
|
|
||||||
// Processing of arc shapes in zones is not yet supported because Clipper can't do boolean
|
// Processing of arc shapes in zones is not yet supported because Clipper can't do boolean
|
||||||
// operations on them. The poly outline must be converted to segments first.
|
// operations on them. The poly outline must be converted to segments first.
|
||||||
SHAPE_POLY_SET flattened = *m_Poly;
|
SHAPE_POLY_SET flattened = m_Poly->CloneDropTriangulation();
|
||||||
flattened.ClearArcs();
|
flattened.ClearArcs();
|
||||||
|
|
||||||
if( GetIsRuleArea() )
|
if( GetIsRuleArea() )
|
||||||
|
@ -1132,22 +1132,19 @@ bool ZONE::BuildSmoothedPoly( SHAPE_POLY_SET& aSmoothedPoly, PCB_LAYER_ID aLayer
|
||||||
|
|
||||||
for( ZONE* zone : interactingZones )
|
for( ZONE* zone : interactingZones )
|
||||||
{
|
{
|
||||||
SHAPE_POLY_SET flattened_outline = *zone->Outline();
|
SHAPE_POLY_SET flattened_outline = zone->Outline()->CloneDropTriangulation();
|
||||||
flattened_outline.ClearArcs();
|
flattened_outline.ClearArcs();
|
||||||
aSmoothedPoly.BooleanAdd( flattened_outline, SHAPE_POLY_SET::PM_FAST );
|
aSmoothedPoly.BooleanAdd( flattened_outline, SHAPE_POLY_SET::PM_FAST );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( aBoardOutline )
|
if( aBoardOutline )
|
||||||
{
|
aSmoothedPoly.BooleanIntersection( *aBoardOutline, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||||
SHAPE_POLY_SET poly = *aBoardOutline;
|
|
||||||
aSmoothedPoly.BooleanIntersection( poly, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
|
||||||
}
|
|
||||||
|
|
||||||
smooth( aSmoothedPoly );
|
smooth( aSmoothedPoly );
|
||||||
|
|
||||||
if( aSmoothedPolyWithApron )
|
if( aSmoothedPolyWithApron )
|
||||||
{
|
{
|
||||||
SHAPE_POLY_SET poly = *maxExtents;
|
SHAPE_POLY_SET poly = maxExtents->CloneDropTriangulation();
|
||||||
poly.Inflate( m_ZoneMinThickness, 64 );
|
poly.Inflate( m_ZoneMinThickness, 64 );
|
||||||
*aSmoothedPolyWithApron = aSmoothedPoly;
|
*aSmoothedPolyWithApron = aSmoothedPoly;
|
||||||
aSmoothedPolyWithApron->BooleanIntersection( poly, SHAPE_POLY_SET::PM_FAST );
|
aSmoothedPolyWithApron->BooleanIntersection( poly, SHAPE_POLY_SET::PM_FAST );
|
||||||
|
|
|
@ -921,7 +921,7 @@ void ZONE_FILLER::subtractHigherPriorityZones( const ZONE* aZone, PCB_LAYER_ID a
|
||||||
// Processing of arc shapes in zones is not yet supported because Clipper
|
// Processing of arc shapes in zones is not yet supported because Clipper
|
||||||
// can't do boolean operations on them. The poly outline must be converted to
|
// can't do boolean operations on them. The poly outline must be converted to
|
||||||
// segments first.
|
// segments first.
|
||||||
SHAPE_POLY_SET outline = *aKnockout->Outline();
|
SHAPE_POLY_SET outline = aKnockout->Outline()->CloneDropTriangulation();
|
||||||
outline.ClearArcs();
|
outline.ClearArcs();
|
||||||
|
|
||||||
aRawFill.BooleanSubtract( outline, SHAPE_POLY_SET::PM_FAST );
|
aRawFill.BooleanSubtract( outline, SHAPE_POLY_SET::PM_FAST );
|
||||||
|
@ -1034,7 +1034,7 @@ bool ZONE_FILLER::fillCopperZone( const ZONE* aZone, PCB_LAYER_ID aLayer, PCB_LA
|
||||||
// Create a temporary zone that we can hit-test spoke-ends against. It's only temporary
|
// Create a temporary zone that we can hit-test spoke-ends against. It's only temporary
|
||||||
// because the "real" subtract-clearance-holes has to be done after the spokes are added.
|
// because the "real" subtract-clearance-holes has to be done after the spokes are added.
|
||||||
static const bool USE_BBOX_CACHES = true;
|
static const bool USE_BBOX_CACHES = true;
|
||||||
SHAPE_POLY_SET testAreas = aFillPolys;
|
SHAPE_POLY_SET testAreas = aFillPolys.CloneDropTriangulation();
|
||||||
testAreas.BooleanSubtract( clearanceHoles, SHAPE_POLY_SET::PM_FAST );
|
testAreas.BooleanSubtract( clearanceHoles, SHAPE_POLY_SET::PM_FAST );
|
||||||
DUMP_POLYS_TO_COPPER_LAYER( testAreas, In4_Cu, wxT( "minus-clearance-holes" ) );
|
DUMP_POLYS_TO_COPPER_LAYER( testAreas, In4_Cu, wxT( "minus-clearance-holes" ) );
|
||||||
|
|
||||||
|
@ -1395,7 +1395,7 @@ bool ZONE_FILLER::addHatchFillTypeOnZone( const ZONE* aZone, PCB_LAYER_ID aLayer
|
||||||
int linethickness = thickness - aZone->GetMinThickness();
|
int linethickness = thickness - aZone->GetMinThickness();
|
||||||
int gridsize = thickness + aZone->GetHatchGap();
|
int gridsize = thickness + aZone->GetHatchGap();
|
||||||
|
|
||||||
SHAPE_POLY_SET filledPolys = aFillPolys;
|
SHAPE_POLY_SET filledPolys = aFillPolys.CloneDropTriangulation();
|
||||||
// Use a area that contains the rotated bbox by orientation, and after rotate the result
|
// Use a area that contains the rotated bbox by orientation, and after rotate the result
|
||||||
// by -orientation.
|
// by -orientation.
|
||||||
if( !aZone->GetHatchOrientation().IsZero() )
|
if( !aZone->GetHatchOrientation().IsZero() )
|
||||||
|
@ -1517,12 +1517,12 @@ bool ZONE_FILLER::addHatchFillTypeOnZone( const ZONE* aZone, PCB_LAYER_ID aLayer
|
||||||
|
|
||||||
// The fill has already been deflated to ensure GetMinThickness() so we just have to
|
// The fill has already been deflated to ensure GetMinThickness() so we just have to
|
||||||
// account for anything beyond that.
|
// account for anything beyond that.
|
||||||
SHAPE_POLY_SET deflatedFilledPolys = aFillPolys;
|
SHAPE_POLY_SET deflatedFilledPolys = aFillPolys.CloneDropTriangulation();
|
||||||
deflatedFilledPolys.Deflate( outline_margin - aZone->GetMinThickness(), 16 );
|
deflatedFilledPolys.Deflate( outline_margin - aZone->GetMinThickness(), 16 );
|
||||||
holes.BooleanIntersection( deflatedFilledPolys, SHAPE_POLY_SET::PM_FAST );
|
holes.BooleanIntersection( deflatedFilledPolys, SHAPE_POLY_SET::PM_FAST );
|
||||||
DUMP_POLYS_TO_COPPER_LAYER( holes, In11_Cu, wxT( "fill-clipped-hatch-holes" ) );
|
DUMP_POLYS_TO_COPPER_LAYER( holes, In11_Cu, wxT( "fill-clipped-hatch-holes" ) );
|
||||||
|
|
||||||
SHAPE_POLY_SET deflatedOutline = *aZone->Outline();
|
SHAPE_POLY_SET deflatedOutline = aZone->Outline()->CloneDropTriangulation();
|
||||||
deflatedOutline.Deflate( outline_margin, 16 );
|
deflatedOutline.Deflate( outline_margin, 16 );
|
||||||
holes.BooleanIntersection( deflatedOutline, SHAPE_POLY_SET::PM_FAST );
|
holes.BooleanIntersection( deflatedOutline, SHAPE_POLY_SET::PM_FAST );
|
||||||
DUMP_POLYS_TO_COPPER_LAYER( holes, In12_Cu, wxT( "outline-clipped-hatch-holes" ) );
|
DUMP_POLYS_TO_COPPER_LAYER( holes, In12_Cu, wxT( "outline-clipped-hatch-holes" ) );
|
||||||
|
|
Loading…
Reference in New Issue