Add logging and area check to tesselation
Logging is useful when we find an area that cannot be triangulated.
This will be used to generated test cases.
Skipping minor untesselated areas means that the polygon will still be
considered fully tesselated (and not sent back again and again) even if
the tesselation misses an area less than the configured limit.
Currently, this is 31^2nm.
(cherry picked from commit 7e7fec69f6
)
This commit is contained in:
parent
3d4a7c7c3f
commit
d2db96886d
|
@ -107,6 +107,7 @@ static const wxChar MinimumSegmentLength[] = wxT( "MinimumSegmentLength" );
|
|||
static const wxChar OcePluginLinearDeflection[] = wxT( "OcePluginLinearDeflection" );
|
||||
static const wxChar OcePluginAngularDeflection[] = wxT( "OcePluginAngularDeflection" );
|
||||
static const wxChar TriangulateSimplificationLevel[] = wxT( "TriangulateSimplificationLevel" );
|
||||
static const wxChar TriangulateMinimumArea[] = wxT( "TriangulateMinimumArea" );
|
||||
} // namespace KEYS
|
||||
|
||||
|
||||
|
@ -255,6 +256,7 @@ ADVANCED_CFG::ADVANCED_CFG()
|
|||
m_OcePluginAngularDeflection = 30;
|
||||
|
||||
m_TriangulateSimplificationLevel = 50;
|
||||
m_TriangulateMinimumArea = 1000;
|
||||
|
||||
loadFromConfigFile();
|
||||
}
|
||||
|
@ -464,6 +466,10 @@ void ADVANCED_CFG::loadSettings( wxConfigBase& aCfg )
|
|||
&m_TriangulateSimplificationLevel,
|
||||
m_TriangulateSimplificationLevel, 0, 1000 ) );
|
||||
|
||||
configParams.push_back( new PARAM_CFG_INT( true, AC_KEYS::TriangulateMinimumArea,
|
||||
&m_TriangulateMinimumArea,
|
||||
m_TriangulateMinimumArea, 0, 100000 ) );
|
||||
|
||||
// Special case for trace mask setting...we just grab them and set them immediately
|
||||
// Because we even use wxLogTrace inside of advanced config
|
||||
wxString traceMasks;
|
||||
|
|
|
@ -546,6 +546,17 @@ public:
|
|||
*/
|
||||
int m_TriangulateSimplificationLevel;
|
||||
|
||||
/**
|
||||
* The minimum area of a polygon that can be left over after triangulation and
|
||||
* still consider the triangulation successful. This is internal units, so
|
||||
* it is square nm in pcbnew.
|
||||
*
|
||||
* Setting name: "TriangulateMinimumArea"
|
||||
* Valid values: 0 to 100000
|
||||
* Default value: 1000
|
||||
*/
|
||||
int m_TriangulateMinimumArea;
|
||||
|
||||
///@}
|
||||
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#include <deque>
|
||||
#include <cmath>
|
||||
|
||||
#include <advanced_config.h>
|
||||
#include <clipper.hpp>
|
||||
#include <geometry/shape_line_chain.h>
|
||||
#include <geometry/shape_poly_set.h>
|
||||
|
@ -93,6 +94,10 @@ public:
|
|||
else
|
||||
{
|
||||
auto retval = earcutList( firstVertex );
|
||||
|
||||
if( !retval )
|
||||
logRemaining();
|
||||
|
||||
m_vertices.clear();
|
||||
return retval;
|
||||
}
|
||||
|
@ -324,7 +329,7 @@ private:
|
|||
void logRemaining()
|
||||
{
|
||||
std::set<VERTEX*> seen;
|
||||
|
||||
wxLog::EnableLogging();
|
||||
for( VERTEX& p : m_vertices )
|
||||
{
|
||||
if( !p.next || p.next == &p || seen.find( &p ) != seen.end() )
|
||||
|
@ -332,15 +337,27 @@ private:
|
|||
|
||||
seen.insert( &p );
|
||||
|
||||
wxString msg = wxString::Format( "Remaining: %d,%d,", p.x, p.y );
|
||||
// Don't both logging tiny areas
|
||||
if( std::abs( p.area() ) < 10 )
|
||||
continue;
|
||||
|
||||
int count = 1;
|
||||
wxString msg = wxString::Format( "Remaining: %d,%d,", static_cast<int>( p.x ),
|
||||
static_cast<int>( p.y ) );
|
||||
VERTEX* q = p.next;
|
||||
|
||||
do
|
||||
{
|
||||
msg += wxString::Format( "%d,%d,", q->x, q->y );
|
||||
msg += wxString::Format( "%d,%d,", static_cast<int>( q->x ),
|
||||
static_cast<int>( q->y ) );
|
||||
seen.insert( q );
|
||||
q = q->next;
|
||||
} while ( q != &p );
|
||||
count++;
|
||||
} while( q != &p );
|
||||
|
||||
// Don't log anything that only has 2 or fewer points
|
||||
if( count < 3 )
|
||||
continue;
|
||||
|
||||
msg.RemoveLast();
|
||||
wxLogTrace( TRIANGULATE_TRACE, msg );
|
||||
|
@ -362,12 +379,18 @@ private:
|
|||
{
|
||||
if( *p == *( p->next ) || area( p->prev, p, p->next ) == 0.0 )
|
||||
{
|
||||
// This is a spike, remove it, leaving only one point
|
||||
if( *( p->next ) == *( p->prev ) )
|
||||
p->next->remove();
|
||||
|
||||
p = p->prev;
|
||||
p->next->remove();
|
||||
retval = aStart;
|
||||
|
||||
if( p == p->next )
|
||||
break;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
p = p->next;
|
||||
|
@ -551,7 +574,10 @@ private:
|
|||
/*
|
||||
* At this point, our polygon should be fully tessellated.
|
||||
*/
|
||||
return( aPoint->prev == aPoint->next );
|
||||
if( aPoint->prev != aPoint->next )
|
||||
return std::abs( aPoint->area() > ADVANCED_CFG::GetCfg().m_TriangulateMinimumArea );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue