Commit e730219b authored by Dick Hollenbeck's avatar Dick Hollenbeck
Browse files

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

parent 66528456
Loading
Loading
Loading
Loading
+56 −15
Original line number Original line Diff line number Diff line
@@ -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
+30 −0
Original line number Original line Diff line number Diff line
@@ -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;
}
}


+13 −4
Original line number Original line Diff line number Diff line
@@ -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);
}
}