DRAWSEGMENT, S_POLYGON shape: remove useless copies or conversion to std::vector<wxPoint> of SHPE_POLY_SET polygon shape.
Rename GetPolyPoint() to BuildPolyPointsList(), because GetPolyPoint() looks like an accessor, but it is not an accessor. (Using it as accessor can creates a *very long calculation time* for very basic access to polygon vertices) Fixes: lp:1745050 https://bugs.launchpad.net/kicad/+bug/1745050
This commit is contained in:
parent
c95c77c51a
commit
270a63daac
|
@ -520,7 +520,7 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::OnOKButtonClick( wxCommandEvent& event
|
|||
|
||||
SCH_REFERENCE_LIST components;
|
||||
GetParent()->GetCurrentSheet().GetComponents( components );
|
||||
for( int i = 0; i < components.GetCount(); i++ )
|
||||
for( unsigned i = 0; i < components.GetCount(); i++ )
|
||||
{
|
||||
SCH_REFERENCE component = components[i];
|
||||
if( component.GetLibPart()->GetLibId() == thisLibId
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
|
||||
* Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2018 Jean-Pierre Charras, jp.charras at wandadoo.fr
|
||||
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -331,6 +331,8 @@ public:
|
|||
|
||||
static std::string FormatInternalUnits( const wxPoint& aPoint );
|
||||
|
||||
static std::string FormatInternalUnits( const VECTOR2I& aPoint );
|
||||
|
||||
static std::string FormatInternalUnits( const wxSize& aSize );
|
||||
|
||||
virtual void ViewGetLayers( int aLayers[], int& aCount ) const override;
|
||||
|
|
|
@ -515,55 +515,54 @@ void DRAWSEGMENT::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerB
|
|||
break;
|
||||
|
||||
case S_POLYGON:
|
||||
if ( GetPolyPoints().size() < 2 )
|
||||
break; // Malformed polygon.
|
||||
if( IsPolyShapeValid() )
|
||||
{
|
||||
// The polygon is expected to be a simple polygon
|
||||
// not self intersecting, no hole.
|
||||
MODULE* module = GetParentModule(); // NULL for items not in footprints
|
||||
double orientation = module ? module->GetOrientation() : 0.0;
|
||||
wxPoint offset;
|
||||
// The polygon is expected to be a simple polygon
|
||||
// not self intersecting, no hole.
|
||||
MODULE* module = GetParentModule(); // NULL for items not in footprints
|
||||
double orientation = module ? module->GetOrientation() : 0.0;
|
||||
wxPoint offset;
|
||||
|
||||
if( module )
|
||||
offset = module->GetPosition();
|
||||
if( module )
|
||||
offset = module->GetPosition();
|
||||
|
||||
// Build the polygon with the actual position and orientation:
|
||||
std::vector< wxPoint> poly;
|
||||
poly = GetPolyPoints();
|
||||
|
||||
for( unsigned ii = 0; ii < poly.size(); ii++ )
|
||||
{
|
||||
RotatePoint( &poly[ii], orientation );
|
||||
poly[ii] += offset;
|
||||
}
|
||||
|
||||
// Generate polygons for the outline + clearance
|
||||
// This code is compatible with a polygon with holes linked to external outline
|
||||
// by overlapping segments.
|
||||
|
||||
// Insert the initial polygon:
|
||||
aCornerBuffer.NewOutline();
|
||||
|
||||
for( unsigned ii = 0; ii < poly.size(); ii++ )
|
||||
aCornerBuffer.Append( poly[ii].x, poly[ii].y );
|
||||
|
||||
if( linewidth ) // Add thick outlines
|
||||
{
|
||||
CPolyPt corner1( poly[poly.size()-1] );
|
||||
// Build the polygon with the actual position and orientation:
|
||||
std::vector< wxPoint> poly;
|
||||
poly = BuildPolyPointsList();
|
||||
|
||||
for( unsigned ii = 0; ii < poly.size(); ii++ )
|
||||
{
|
||||
CPolyPt corner2( poly[ii] );
|
||||
|
||||
if( corner2 != corner1 )
|
||||
{
|
||||
TransformRoundedEndsSegmentToPolygon( aCornerBuffer,
|
||||
corner1, corner2, aCircleToSegmentsCount, linewidth );
|
||||
}
|
||||
|
||||
corner1 = corner2;
|
||||
RotatePoint( &poly[ii], orientation );
|
||||
poly[ii] += offset;
|
||||
}
|
||||
|
||||
// Generate polygons for the outline + clearance
|
||||
// This code is compatible with a polygon with holes linked to external outline
|
||||
// by overlapping segments.
|
||||
|
||||
// Insert the initial polygon:
|
||||
aCornerBuffer.NewOutline();
|
||||
|
||||
for( unsigned ii = 0; ii < poly.size(); ii++ )
|
||||
aCornerBuffer.Append( poly[ii].x, poly[ii].y );
|
||||
|
||||
if( linewidth ) // Add thick outlines
|
||||
{
|
||||
wxPoint corner1( poly[poly.size()-1] );
|
||||
|
||||
for( unsigned ii = 0; ii < poly.size(); ii++ )
|
||||
{
|
||||
wxPoint corner2( poly[ii] );
|
||||
|
||||
if( corner2 != corner1 )
|
||||
{
|
||||
TransformRoundedEndsSegmentToPolygon( aCornerBuffer,
|
||||
corner1, corner2, aCircleToSegmentsCount, linewidth );
|
||||
}
|
||||
|
||||
corner1 = corner2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -184,6 +184,12 @@ std::string BOARD_ITEM::FormatInternalUnits( const wxPoint& aPoint )
|
|||
}
|
||||
|
||||
|
||||
std::string BOARD_ITEM::FormatInternalUnits( const VECTOR2I& aPoint )
|
||||
{
|
||||
return FormatInternalUnits( aPoint.x ) + " " + FormatInternalUnits( aPoint.y );
|
||||
}
|
||||
|
||||
|
||||
std::string BOARD_ITEM::FormatInternalUnits( const wxSize& aSize )
|
||||
{
|
||||
return FormatInternalUnits( aSize.GetWidth() ) + " " + FormatInternalUnits( aSize.GetHeight() );
|
||||
|
|
|
@ -806,7 +806,8 @@ void DRAWSEGMENT::SetPolyPoints( const std::vector<wxPoint>& aPoints )
|
|||
}
|
||||
}
|
||||
|
||||
const std::vector<wxPoint> DRAWSEGMENT::GetPolyPoints() const
|
||||
|
||||
const std::vector<wxPoint> DRAWSEGMENT::BuildPolyPointsList() const
|
||||
{
|
||||
std::vector<wxPoint> rv;
|
||||
|
||||
|
@ -824,6 +825,30 @@ const std::vector<wxPoint> DRAWSEGMENT::GetPolyPoints() const
|
|||
return rv;
|
||||
}
|
||||
|
||||
|
||||
bool DRAWSEGMENT::IsPolyShapeValid() const
|
||||
{
|
||||
// return true if the polygonal shape is valid (has more than 2 points)
|
||||
if( GetPolyShape().OutlineCount() == 0 )
|
||||
return false;
|
||||
|
||||
const SHAPE_LINE_CHAIN& outline = ((SHAPE_POLY_SET&)GetPolyShape()).Outline( 0 );
|
||||
|
||||
return outline.PointCount() > 2;
|
||||
}
|
||||
|
||||
|
||||
int DRAWSEGMENT::GetPointCount() const
|
||||
{
|
||||
// return the number of corners of the polygonal shape
|
||||
// this shape is expected to be only one polygon without hole
|
||||
if( GetPolyShape().OutlineCount() )
|
||||
return GetPolyShape().VertexCount( 0 );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void DRAWSEGMENT::SwapData( BOARD_ITEM* aImage )
|
||||
{
|
||||
assert( aImage->Type() == PCB_LINE_T );
|
||||
|
|
|
@ -167,9 +167,26 @@ public:
|
|||
// Accessors:
|
||||
const std::vector<wxPoint>& GetBezierPoints() const { return m_BezierPoints; }
|
||||
|
||||
const std::vector<wxPoint> GetPolyPoints() const;
|
||||
/** Build and return the list of corners in a std::vector<wxPoint>
|
||||
* It must be used only to convert the SHAPE_POLY_SET internal corner buffer
|
||||
* to a list of wxPoints, and nothing else, because it duplicates the buffer,
|
||||
* that is inefficient to know for instance the corner count
|
||||
*/
|
||||
const std::vector<wxPoint> BuildPolyPointsList() const;
|
||||
|
||||
/** @return the number of corners of the polygonal shape
|
||||
*/
|
||||
int GetPointCount() const;
|
||||
|
||||
// Accessors to the polygonal shape
|
||||
SHAPE_POLY_SET& GetPolyShape() { return m_Poly; }
|
||||
const SHAPE_POLY_SET& GetPolyShape() const { return m_Poly; }
|
||||
|
||||
/**
|
||||
* @return true if the polygonal shape is valid (has more than 2 points)
|
||||
*/
|
||||
bool IsPolyShapeValid() const;
|
||||
|
||||
void SetPolyShape( const SHAPE_POLY_SET& aShape ) { m_Poly = aShape; }
|
||||
|
||||
void SetBezierPoints( const std::vector<wxPoint>& aPoints )
|
||||
|
|
|
@ -395,7 +395,7 @@ void DIALOG_PAD_PROPERTIES::OnPaintShowPanel( wxPaintEvent& event )
|
|||
|
||||
case S_POLYGON: // polygon
|
||||
{
|
||||
std::vector<wxPoint> poly = dummySegment.GetPolyPoints();
|
||||
std::vector<wxPoint> poly = dummySegment.BuildPolyPointsList();
|
||||
GRClosedPoly( NULL, &dc, poly.size(), &poly[0],
|
||||
m_drawPadOutlineMode ? false : true,
|
||||
primitive.m_Thickness, m_selectedColor, m_selectedColor );
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
*
|
||||
* Copyright (C) 2009-2013 Lorenzo Mercantonio
|
||||
* Copyright (C) 2014-2017 Cirilo Bernardo
|
||||
* Copyright (C) 2013 Jean-Pierre Charras jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2004-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2018 Jean-Pierre Charras jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2004-2018 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -1031,13 +1031,15 @@ static void export_vrml_edge_module( MODEL_VRML& aModel, EDGE_MODULE* aOutline,
|
|||
break;
|
||||
|
||||
case S_POLYGON:
|
||||
if( aOutline->IsPolyShapeValid() )
|
||||
{
|
||||
VRML_LAYER* vl;
|
||||
|
||||
if( !GetLayer( aModel, layer, &vl ) )
|
||||
break;
|
||||
|
||||
int nvert = aOutline->GetPolyPoints().size() - 1;
|
||||
std::vector<wxPoint> poly = aOutline->BuildPolyPointsList();
|
||||
int nvert = poly.size() - 1;
|
||||
int i = 0;
|
||||
|
||||
if( nvert < 3 ) break;
|
||||
|
@ -1049,7 +1051,7 @@ static void export_vrml_edge_module( MODEL_VRML& aModel, EDGE_MODULE* aOutline,
|
|||
|
||||
while( i < nvert )
|
||||
{
|
||||
CPolyPt corner( aOutline->GetPolyPoints()[i] );
|
||||
CPolyPt corner( poly[i] );
|
||||
RotatePoint( &corner.x, &corner.y, aOrientation );
|
||||
corner.x += aOutline->GetPosition().x;
|
||||
corner.y += aOutline->GetPosition().y;
|
||||
|
|
|
@ -870,8 +870,6 @@ void PCB_IO::format( DIMENSION* aDimension, int aNestLevel ) const
|
|||
|
||||
void PCB_IO::format( DRAWSEGMENT* aSegment, int aNestLevel ) const
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
switch( aSegment->GetShape() )
|
||||
{
|
||||
case S_SEGMENT: // Line
|
||||
|
@ -898,12 +896,21 @@ void PCB_IO::format( DRAWSEGMENT* aSegment, int aNestLevel ) const
|
|||
break;
|
||||
|
||||
case S_POLYGON: // Polygon
|
||||
m_out->Print( aNestLevel, "(gr_poly (pts" );
|
||||
if( aSegment->IsPolyShapeValid() )
|
||||
{
|
||||
SHAPE_POLY_SET& poly = aSegment->GetPolyShape();
|
||||
SHAPE_LINE_CHAIN& outline = poly.Outline( 0 );
|
||||
int pointsCount = outline.PointCount();
|
||||
|
||||
for( i = 0; i < aSegment->GetPolyPoints().size(); ++i )
|
||||
m_out->Print( 0, " (xy %s)", FMT_IU( aSegment->GetPolyPoints()[i] ).c_str() );
|
||||
m_out->Print( aNestLevel, "(gr_poly (pts" );
|
||||
|
||||
m_out->Print( 0, ")" );
|
||||
for( int ii = 0; ii < pointsCount; ++ii )
|
||||
{
|
||||
m_out->Print( 0, " (xy %s)", FMT_IU( outline.CPoint( ii ) ).c_str() );
|
||||
}
|
||||
|
||||
m_out->Print( 0, ")" );
|
||||
}
|
||||
break;
|
||||
|
||||
case S_CURVE: // Bezier curve
|
||||
|
@ -955,24 +962,31 @@ void PCB_IO::format( EDGE_MODULE* aModuleDrawing, int aNestLevel ) const
|
|||
FMT_ANGLE( aModuleDrawing->GetAngle() ).c_str() );
|
||||
break;
|
||||
|
||||
case S_POLYGON: // Polygon
|
||||
m_out->Print( aNestLevel, "(fp_poly (pts" );
|
||||
|
||||
for( unsigned i = 0; i < aModuleDrawing->GetPolyPoints().size(); ++i )
|
||||
case S_POLYGON: // Polygonal segment
|
||||
if( aModuleDrawing->IsPolyShapeValid() )
|
||||
{
|
||||
int nestLevel = 0;
|
||||
SHAPE_POLY_SET& poly = aModuleDrawing->GetPolyShape();
|
||||
SHAPE_LINE_CHAIN& outline = poly.Outline( 0 );
|
||||
int pointsCount = outline.PointCount();
|
||||
|
||||
if( i && !(i%4) ) // newline every 4(pts)
|
||||
m_out->Print( aNestLevel, "(fp_poly (pts" );
|
||||
|
||||
for( int ii = 0; ii < pointsCount; ++ii )
|
||||
{
|
||||
nestLevel = aNestLevel + 1;
|
||||
m_out->Print( 0, "\n" );
|
||||
int nestLevel = 0;
|
||||
|
||||
if( ii && !( ii%4 ) ) // newline every 4 pts
|
||||
{
|
||||
nestLevel = aNestLevel + 1;
|
||||
m_out->Print( 0, "\n" );
|
||||
}
|
||||
|
||||
m_out->Print( nestLevel, "%s(xy %s)",
|
||||
nestLevel ? "" : " ", FMT_IU( outline.CPoint( ii ) ).c_str() );
|
||||
}
|
||||
|
||||
m_out->Print( nestLevel, "%s(xy %s)",
|
||||
nestLevel ? "" : " ",
|
||||
FMT_IU( aModuleDrawing->GetPolyPoints()[i] ).c_str() );
|
||||
m_out->Print( 0, ")" );
|
||||
}
|
||||
m_out->Print( 0, ")" );
|
||||
break;
|
||||
|
||||
case S_CURVE: // Bezier curve
|
||||
|
|
|
@ -931,7 +931,7 @@ void PCB_PAINTER::draw( const DRAWSEGMENT* aSegment, int aLayer )
|
|||
|
||||
case S_POLYGON:
|
||||
{
|
||||
const auto& points = aSegment->GetPolyPoints();
|
||||
const auto& points = aSegment->BuildPolyPointsList();
|
||||
std::deque<VECTOR2D> pointsList;
|
||||
|
||||
if( points.empty() )
|
||||
|
|
|
@ -2571,7 +2571,7 @@ D_PAD* PCB_PARSER::parseD_PAD( MODULE* aParent )
|
|||
|
||||
case T_gr_poly:
|
||||
dummysegm = parseDRAWSEGMENT();
|
||||
pad->AddPrimitive( dummysegm->GetPolyPoints(), dummysegm->GetWidth() );
|
||||
pad->AddPrimitive( dummysegm->BuildPolyPointsList(), dummysegm->GetWidth() );
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -520,35 +520,33 @@ void BRDITEMS_PLOTTER::Plot_1_EdgeModule( EDGE_MODULE* aEdge )
|
|||
break;
|
||||
|
||||
case S_POLYGON:
|
||||
{
|
||||
const std::vector<wxPoint>& polyPoints = aEdge->GetPolyPoints();
|
||||
|
||||
if( polyPoints.size() <= 1 ) // Malformed polygon
|
||||
break;
|
||||
|
||||
// We must compute true coordinates from m_PolyList
|
||||
// which are relative to module position, orientation 0
|
||||
MODULE* module = aEdge->GetParentModule();
|
||||
|
||||
std::vector< wxPoint > cornerList;
|
||||
|
||||
cornerList.reserve( polyPoints.size() );
|
||||
|
||||
for( unsigned ii = 0; ii < polyPoints.size(); ii++ )
|
||||
if( aEdge->IsPolyShapeValid() )
|
||||
{
|
||||
wxPoint corner = polyPoints[ii];
|
||||
const std::vector<wxPoint>& polyPoints = aEdge->BuildPolyPointsList();
|
||||
|
||||
if( module )
|
||||
// We must compute true coordinates from m_PolyList
|
||||
// which are relative to module position, orientation 0
|
||||
MODULE* module = aEdge->GetParentModule();
|
||||
|
||||
std::vector< wxPoint > cornerList;
|
||||
|
||||
cornerList.reserve( polyPoints.size() );
|
||||
|
||||
for( unsigned ii = 0; ii < polyPoints.size(); ii++ )
|
||||
{
|
||||
RotatePoint( &corner, module->GetOrientation() );
|
||||
corner += module->GetPosition();
|
||||
wxPoint corner = polyPoints[ii];
|
||||
|
||||
if( module )
|
||||
{
|
||||
RotatePoint( &corner, module->GetOrientation() );
|
||||
corner += module->GetPosition();
|
||||
}
|
||||
|
||||
cornerList.push_back( corner );
|
||||
}
|
||||
|
||||
cornerList.push_back( corner );
|
||||
m_plotter->PlotPoly( cornerList, FILLED_SHAPE, thickness, &gbr_metadata );
|
||||
}
|
||||
|
||||
m_plotter->PlotPoly( cornerList, FILLED_SHAPE, thickness, &gbr_metadata );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -823,7 +823,7 @@ int DRAWING_TOOL::PlaceDXF( const TOOL_EVENT& aEvent )
|
|||
modSeg->SetBezControl1( seg->GetBezControl1() );
|
||||
modSeg->SetBezControl2( seg->GetBezControl2() );
|
||||
modSeg->SetBezierPoints( seg->GetBezierPoints() );
|
||||
modSeg->SetPolyPoints( seg->GetPolyPoints() );
|
||||
modSeg->SetPolyShape( seg->GetPolyShape() );
|
||||
modSeg->SetLocalCoord();
|
||||
converted = modSeg;
|
||||
break;
|
||||
|
|
|
@ -355,7 +355,7 @@ void GRID_HELPER::computeAnchors( BOARD_ITEM* aItem, const VECTOR2I& aRefPos )
|
|||
|
||||
case S_POLYGON:
|
||||
{
|
||||
for( const auto& p : dseg->GetPolyPoints() )
|
||||
for( const auto& p : dseg->BuildPolyPointsList() )
|
||||
{
|
||||
addAnchor( p, CORNER | SNAPPABLE, dseg );
|
||||
}
|
||||
|
|
|
@ -404,7 +404,7 @@ int MODULE_EDITOR_TOOLS::CreatePadFromShapes( const TOOL_EVENT& aEvent )
|
|||
shape.m_Radius = em->GetRadius();
|
||||
shape.m_Thickness = em->GetWidth();
|
||||
shape.m_ArcAngle = em->GetAngle();
|
||||
shape.m_Poly = em->GetPolyPoints();
|
||||
shape.m_Poly = em->BuildPolyPointsList();
|
||||
|
||||
shapes.push_back(shape);
|
||||
|
||||
|
|
|
@ -617,7 +617,7 @@ void POINT_EDITOR::updatePoints()
|
|||
|
||||
case S_POLYGON:
|
||||
{
|
||||
const auto& points = segment->GetPolyPoints();
|
||||
const auto& points = segment->BuildPolyPointsList();
|
||||
for( unsigned i = 0; i < points.size(); i++ )
|
||||
{
|
||||
m_editPoints->Point( i ).SetPosition( points[i] );
|
||||
|
|
Loading…
Reference in New Issue