Commit e730219b authored by Dick Hollenbeck's avatar Dick Hollenbeck

add PCNBEW nanometer support to specctra round-tripper, use micro-meters to do it.

parent 66528456
...@@ -157,17 +157,42 @@ namespace DSN { ...@@ -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 ) ...@@ -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 ) ...@@ -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 ) ...@@ -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 ) ...@@ -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, ...@@ -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 ) ...@@ -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 ) ...@@ -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 ) ...@@ -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 ) ...@@ -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 @@ ...@@ -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 ...@@ -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() ...@@ -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() ...@@ -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() ...@@ -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 ) ...@@ -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 ...@@ -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);
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment