add PCNBEW nanometer support to specctra round-tripper, use micro-meters to do it.
This commit is contained in:
parent
6652845683
commit
e730219b31
|
@ -157,17 +157,42 @@ namespace DSN {
|
||||||
|
|
||||||
const KICAD_T SPECCTRA_DB::scanPADs[] = { PCB_PAD_T, EOT };
|
const KICAD_T SPECCTRA_DB::scanPADs[] = { PCB_PAD_T, EOT };
|
||||||
|
|
||||||
|
// "specctra reported units" are what we tell the external router that our
|
||||||
|
// exported lengths are in.
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function scale
|
* Function scale
|
||||||
* converts a distance from KiCad units to our reported specctra dsn units:
|
* converts a distance from PCBNEW internal units to the reported specctra dsn units
|
||||||
* 1/10000 inches (deci-mils) to mils. So the factor of 10 comes in.
|
* in floating point format.
|
||||||
*/
|
*/
|
||||||
static inline double scale( int kicadDist )
|
static inline double scale( int kicadDist )
|
||||||
{
|
{
|
||||||
|
#if defined(USE_PCBNEW_NANOMETRES)
|
||||||
|
|
||||||
|
// nanometers to um
|
||||||
|
return kicadDist / 1000.0;
|
||||||
|
|
||||||
|
// nanometers to mils
|
||||||
|
// return kicadDist/25400.0;
|
||||||
|
|
||||||
|
#else
|
||||||
|
// deci-mils to mils.
|
||||||
return kicadDist/10.0;
|
return kicadDist/10.0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Convert integer internal units to float um
|
||||||
|
static inline double IU2um( int kicadDist )
|
||||||
|
{
|
||||||
|
#if defined(USE_PCBNEW_NANOMETRES)
|
||||||
|
return kicadDist / 1000.0;
|
||||||
|
#else
|
||||||
|
return kicadDist * 25.4e-1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline double mapX( int x )
|
static inline double mapX( int x )
|
||||||
{
|
{
|
||||||
return scale(x);
|
return scale(x);
|
||||||
|
@ -367,8 +392,9 @@ PADSTACK* SPECCTRA_DB::makePADSTACK( BOARD* aBoard, D_PAD* aPad )
|
||||||
circle->SetVertex( dsnOffset );
|
circle->SetVertex( dsnOffset );
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf( name, sizeof(name), "Round%sPad_%.6g_mil",
|
snprintf( name, sizeof(name), "Round%sPad_%.6g_um",
|
||||||
uniqifier.c_str(), scale(aPad->GetSize().x) );
|
uniqifier.c_str(), IU2um( aPad->GetSize().x ) );
|
||||||
|
|
||||||
name[ sizeof(name)-1 ] = 0;
|
name[ sizeof(name)-1 ] = 0;
|
||||||
|
|
||||||
padstack->SetPadstackId( name );
|
padstack->SetPadstackId( name );
|
||||||
|
@ -398,8 +424,11 @@ PADSTACK* SPECCTRA_DB::makePADSTACK( BOARD* aBoard, D_PAD* aPad )
|
||||||
rect->SetCorners( lowerLeft, upperRight );
|
rect->SetCorners( lowerLeft, upperRight );
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf( name, sizeof(name), "Rect%sPad_%.6gx%.6g_mil",
|
snprintf( name, sizeof(name), "Rect%sPad_%.6gx%.6g_um",
|
||||||
uniqifier.c_str(), scale(aPad->GetSize().x), scale(aPad->GetSize().y) );
|
uniqifier.c_str(),
|
||||||
|
IU2um( aPad->GetSize().x ),
|
||||||
|
IU2um( aPad->GetSize().y ) );
|
||||||
|
|
||||||
name[ sizeof(name)-1 ] = 0;
|
name[ sizeof(name)-1 ] = 0;
|
||||||
|
|
||||||
padstack->SetPadstackId( name );
|
padstack->SetPadstackId( name );
|
||||||
|
@ -446,8 +475,10 @@ PADSTACK* SPECCTRA_DB::makePADSTACK( BOARD* aBoard, D_PAD* aPad )
|
||||||
path->aperture_width = 2.0 * radius;
|
path->aperture_width = 2.0 * radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf( name, sizeof(name), "Oval%sPad_%.6gx%.6g_mil",
|
snprintf( name, sizeof(name), "Oval%sPad_%.6gx%.6g_um",
|
||||||
uniqifier.c_str(), scale(aPad->GetSize().x), scale(aPad->GetSize().y) );
|
uniqifier.c_str(),
|
||||||
|
IU2um( aPad->GetSize().x ),
|
||||||
|
IU2um( aPad->GetSize().y ) );
|
||||||
name[ sizeof(name)-1 ] = 0;
|
name[ sizeof(name)-1 ] = 0;
|
||||||
|
|
||||||
padstack->SetPadstackId( name );
|
padstack->SetPadstackId( name );
|
||||||
|
@ -493,12 +524,12 @@ PADSTACK* SPECCTRA_DB::makePADSTACK( BOARD* aBoard, D_PAD* aPad )
|
||||||
D(printf( "m_DeltaSize: %d,%d\n", aPad->GetDelta().x, aPad->GetDelta().y );)
|
D(printf( "m_DeltaSize: %d,%d\n", aPad->GetDelta().x, aPad->GetDelta().y );)
|
||||||
|
|
||||||
// this string _must_ be unique for a given physical shape
|
// this string _must_ be unique for a given physical shape
|
||||||
snprintf( name, sizeof(name), "Trapz%sPad_%.6gx%.6g_%c%.6gx%c%.6g_mil",
|
snprintf( name, sizeof(name), "Trapz%sPad_%.6gx%.6g_%c%.6gx%c%.6g_um",
|
||||||
uniqifier.c_str(), scale(aPad->GetSize().x), scale(aPad->GetSize().y),
|
uniqifier.c_str(), IU2um( aPad->GetSize().x ), IU2um( aPad->GetSize().y ),
|
||||||
aPad->GetDelta().x < 0 ? 'n' : 'p',
|
aPad->GetDelta().x < 0 ? 'n' : 'p',
|
||||||
abs( scale( aPad->GetDelta().x )),
|
abs( IU2um( aPad->GetDelta().x )),
|
||||||
aPad->GetDelta().y < 0 ? 'n' : 'p',
|
aPad->GetDelta().y < 0 ? 'n' : 'p',
|
||||||
abs( scale( aPad->GetDelta().y ))
|
abs( IU2um( aPad->GetDelta().y ) )
|
||||||
);
|
);
|
||||||
name[ sizeof(name)-1 ] = 0;
|
name[ sizeof(name)-1 ] = 0;
|
||||||
|
|
||||||
|
@ -708,10 +739,10 @@ PADSTACK* SPECCTRA_DB::makeVia( int aCopperDiameter, int aDrillDiameter,
|
||||||
circle->SetLayerId( layerIds[layer].c_str() );
|
circle->SetLayerId( layerIds[layer].c_str() );
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf( name, sizeof(name), "Via[%d-%d]_%.6g:%.6g_mil",
|
snprintf( name, sizeof(name), "Via[%d-%d]_%.6g:%.6g_um",
|
||||||
aTopLayer, aBotLayer, dsnDiameter,
|
aTopLayer, aBotLayer, dsnDiameter,
|
||||||
// encode the drill value into the name for later import
|
// encode the drill value into the name for later import
|
||||||
scale( aDrillDiameter )
|
IU2um( aDrillDiameter )
|
||||||
);
|
);
|
||||||
|
|
||||||
name[ sizeof(name)-1 ] = 0;
|
name[ sizeof(name)-1 ] = 0;
|
||||||
|
@ -1004,6 +1035,16 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR )
|
||||||
|
|
||||||
//-----<unit_descriptor> & <resolution_descriptor>--------------------
|
//-----<unit_descriptor> & <resolution_descriptor>--------------------
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#if defined(USE_PCBNEW_NANOMETRES)
|
||||||
|
// tell freerouter about centi-mil
|
||||||
|
|
||||||
|
pcb->unit->units = T_um;
|
||||||
|
pcb->resolution->units = T_um;
|
||||||
|
|
||||||
|
pcb->resolution->value = 10;
|
||||||
|
|
||||||
|
#else
|
||||||
pcb->unit->units = T_mil;
|
pcb->unit->units = T_mil;
|
||||||
pcb->resolution->units = T_mil;
|
pcb->resolution->units = T_mil;
|
||||||
|
|
||||||
|
@ -1013,9 +1054,9 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR )
|
||||||
// resolution precisely at 1/10th for now. For more on this, see:
|
// resolution precisely at 1/10th for now. For more on this, see:
|
||||||
// http://www.freerouting.net/usren/viewtopic.php?f=3&t=354
|
// http://www.freerouting.net/usren/viewtopic.php?f=3&t=354
|
||||||
pcb->resolution->value = 10;
|
pcb->resolution->value = 10;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//-----<boundary_descriptor>------------------------------------------
|
//-----<boundary_descriptor>------------------------------------------
|
||||||
{
|
{
|
||||||
// Because fillBOUNDARY() can throw an exception, we link in an
|
// Because fillBOUNDARY() can throw an exception, we link in an
|
||||||
|
|
|
@ -146,6 +146,33 @@ static int scale( double distance, UNIT_RES* aResolution )
|
||||||
{
|
{
|
||||||
double resValue = aResolution->GetValue();
|
double resValue = aResolution->GetValue();
|
||||||
|
|
||||||
|
#if defined(USE_PCBNEW_NANOMETRES)
|
||||||
|
|
||||||
|
double factor;
|
||||||
|
|
||||||
|
switch( aResolution->GetEngUnits() )
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case T_inch:
|
||||||
|
factor = 25.4e6; // nanometers per inch
|
||||||
|
break;
|
||||||
|
case T_mil:
|
||||||
|
factor = 25.4e3; // nanometers per mil
|
||||||
|
break;
|
||||||
|
case T_cm:
|
||||||
|
factor = 1e7; // nanometers per cm
|
||||||
|
break;
|
||||||
|
case T_mm:
|
||||||
|
factor = 1e6; // nanometers per mm
|
||||||
|
break;
|
||||||
|
case T_um:
|
||||||
|
factor = 1e3; // nanometers per um
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret = wxRound( factor * distance / resValue );
|
||||||
|
|
||||||
|
#else
|
||||||
double factor; // multiply this times session value to get mils for KiCad.
|
double factor; // multiply this times session value to get mils for KiCad.
|
||||||
|
|
||||||
switch( aResolution->GetEngUnits() )
|
switch( aResolution->GetEngUnits() )
|
||||||
|
@ -173,6 +200,9 @@ static int scale( double distance, UNIT_RES* aResolution )
|
||||||
factor *= 10.0;
|
factor *= 10.0;
|
||||||
|
|
||||||
int ret = wxRound( factor * distance / resValue );
|
int ret = wxRound( factor * distance / resValue );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#define PCBU_PER_MIL 10
|
#define PCBU_PER_MIL 10
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define to_int( x ) wxRound( (x) )
|
#define to_int( x ) wxRound( (x) )
|
||||||
|
|
||||||
#ifndef MIN
|
#ifndef MIN
|
||||||
|
@ -115,7 +116,8 @@ int CPolyLine::NormalizeWithKbool( std::vector<CPolyLine*> * aExtraPolyList, boo
|
||||||
side_style.clear();
|
side_style.clear();
|
||||||
bool first = true;
|
bool first = true;
|
||||||
while( m_Kbool_Poly_Engine->PolygonHasMorePoints() )
|
while( m_Kbool_Poly_Engine->PolygonHasMorePoints() )
|
||||||
{ // foreach point in the polygon
|
{
|
||||||
|
// foreach point in the polygon
|
||||||
int x = (int) m_Kbool_Poly_Engine->GetPolygonXPoint();
|
int x = (int) m_Kbool_Poly_Engine->GetPolygonXPoint();
|
||||||
int y = (int) m_Kbool_Poly_Engine->GetPolygonYPoint();
|
int y = (int) m_Kbool_Poly_Engine->GetPolygonYPoint();
|
||||||
if( first )
|
if( first )
|
||||||
|
@ -1406,6 +1408,7 @@ void CPolyLine::Hatch()
|
||||||
spacing = 20 * PCBU_PER_MIL;
|
spacing = 20 * PCBU_PER_MIL;
|
||||||
else
|
else
|
||||||
spacing = 50 * PCBU_PER_MIL;
|
spacing = 50 * PCBU_PER_MIL;
|
||||||
|
|
||||||
// set the "lenght" of hatch lines (the lenght on horizontal axis)
|
// set the "lenght" of hatch lines (the lenght on horizontal axis)
|
||||||
double hatch_line_len = 20 * PCBU_PER_MIL;
|
double hatch_line_len = 20 * PCBU_PER_MIL;
|
||||||
|
|
||||||
|
@ -1437,9 +1440,11 @@ void CPolyLine::Hatch()
|
||||||
// loop through hatch lines
|
// loop through hatch lines
|
||||||
#define MAXPTS 200 // Usually we store only few values
|
#define MAXPTS 200 // Usually we store only few values
|
||||||
// depending on the compexity of the zone outline
|
// depending on the compexity of the zone outline
|
||||||
|
|
||||||
static std::vector <CPoint> pointbuffer;
|
static std::vector <CPoint> pointbuffer;
|
||||||
pointbuffer.clear();
|
pointbuffer.clear();
|
||||||
pointbuffer.reserve(MAXPTS+2);
|
pointbuffer.reserve(MAXPTS+2);
|
||||||
|
|
||||||
for( int a = min_a; a < max_a; a += spacing )
|
for( int a = min_a; a < max_a; a += spacing )
|
||||||
{
|
{
|
||||||
// get intersection points for this hatch line
|
// get intersection points for this hatch line
|
||||||
|
@ -1520,17 +1525,21 @@ void CPolyLine::Hatch()
|
||||||
{
|
{
|
||||||
double dy = pointbuffer[ip + 1].y - pointbuffer[ip].y;
|
double dy = pointbuffer[ip + 1].y - pointbuffer[ip].y;
|
||||||
double slope = dy / dx;
|
double slope = dy / dx;
|
||||||
|
|
||||||
if( dx > 0 )
|
if( dx > 0 )
|
||||||
dx = hatch_line_len;
|
dx = hatch_line_len;
|
||||||
else
|
else
|
||||||
dx = -hatch_line_len;
|
dx = -hatch_line_len;
|
||||||
|
|
||||||
double x1 = pointbuffer[ip].x + dx;
|
double x1 = pointbuffer[ip].x + dx;
|
||||||
double x2 = pointbuffer[ip + 1].x - dx;
|
double x2 = pointbuffer[ip + 1].x - dx;
|
||||||
double y1 = pointbuffer[ip].y + dx * slope;
|
double y1 = pointbuffer[ip].y + dx * slope;
|
||||||
double y2 = pointbuffer[ip + 1].y - dx * slope;
|
double y2 = pointbuffer[ip + 1].y - dx * slope;
|
||||||
|
|
||||||
m_HatchLines.push_back( CSegment( pointbuffer[ip].x,
|
m_HatchLines.push_back( CSegment( pointbuffer[ip].x,
|
||||||
pointbuffer[ip].y,
|
pointbuffer[ip].y,
|
||||||
to_int( x1 ), to_int( y1 ) ) );
|
to_int( x1 ), to_int( y1 ) ) );
|
||||||
|
|
||||||
m_HatchLines.push_back( CSegment( pointbuffer[ip + 1].x,
|
m_HatchLines.push_back( CSegment( pointbuffer[ip + 1].x,
|
||||||
pointbuffer[ip + 1].y,
|
pointbuffer[ip + 1].y,
|
||||||
to_int( x2 ), to_int( y2 ) ) );
|
to_int( x2 ), to_int( y2 ) ) );
|
||||||
|
@ -1560,6 +1569,7 @@ bool CPolyLine::TestPointInside( int px, int py )
|
||||||
{
|
{
|
||||||
int istart = GetContourStart( icont );
|
int istart = GetContourStart( icont );
|
||||||
int iend = GetContourEnd( icont );
|
int iend = GetContourEnd( icont );
|
||||||
|
|
||||||
// Test this polygon:
|
// Test this polygon:
|
||||||
if( TestPointInsidePolygon( corner, istart, iend, px, py) ) // test point inside the current polygon
|
if( TestPointInsidePolygon( corner, istart, iend, px, py) ) // test point inside the current polygon
|
||||||
inside = not inside;
|
inside = not inside;
|
||||||
|
@ -1671,4 +1681,3 @@ void CPolyLine::AppendBezier(int x1, int y1, int x2, int y2, int x3, int y3, int
|
||||||
for( unsigned int i = 0; i < bezier_points.size() ; i++)
|
for( unsigned int i = 0; i < bezier_points.size() ; i++)
|
||||||
AppendCorner( bezier_points[i].x, bezier_points[i].y);
|
AppendCorner( bezier_points[i].x, bezier_points[i].y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue