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 Diff line number Diff line
@@ -157,17 +157,42 @@ namespace DSN {

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
 * converts a distance from KiCad units to our reported specctra dsn units:
 * 1/10000 inches (deci-mils) to mils.  So the factor of 10 comes in.
 * converts a distance from PCBNEW internal units to the reported specctra dsn units
 * in floating point format.
 */
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;
#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 )
{
    return scale(x);
@@ -367,8 +392,9 @@ PADSTACK* SPECCTRA_DB::makePADSTACK( BOARD* aBoard, D_PAD* aPad )
                circle->SetVertex( dsnOffset );
            }

            snprintf( name, sizeof(name), "Round%sPad_%.6g_mil",
                     uniqifier.c_str(), scale(aPad->GetSize().x) );
            snprintf( name, sizeof(name), "Round%sPad_%.6g_um",
                     uniqifier.c_str(), IU2um( aPad->GetSize().x ) );

            name[ sizeof(name)-1 ] = 0;

            padstack->SetPadstackId( name );
@@ -398,8 +424,11 @@ PADSTACK* SPECCTRA_DB::makePADSTACK( BOARD* aBoard, D_PAD* aPad )
                rect->SetCorners( lowerLeft, upperRight );
            }

            snprintf( name, sizeof(name),  "Rect%sPad_%.6gx%.6g_mil",
                     uniqifier.c_str(), scale(aPad->GetSize().x), scale(aPad->GetSize().y)  );
            snprintf( name, sizeof(name),  "Rect%sPad_%.6gx%.6g_um",
                     uniqifier.c_str(),
                     IU2um( aPad->GetSize().x ),
                     IU2um( aPad->GetSize().y ) );

            name[ sizeof(name)-1 ] = 0;

            padstack->SetPadstackId( name );
@@ -446,8 +475,10 @@ PADSTACK* SPECCTRA_DB::makePADSTACK( BOARD* aBoard, D_PAD* aPad )
                path->aperture_width = 2.0 * radius;
            }

            snprintf( name, sizeof(name),  "Oval%sPad_%.6gx%.6g_mil",
                     uniqifier.c_str(), scale(aPad->GetSize().x), scale(aPad->GetSize().y)  );
            snprintf( name, sizeof(name),  "Oval%sPad_%.6gx%.6g_um",
                     uniqifier.c_str(),
                     IU2um( aPad->GetSize().x ),
                     IU2um( aPad->GetSize().y ) );
            name[ sizeof(name)-1 ] = 0;

            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 );)

            // this string _must_ be unique for a given physical shape
            snprintf( name, sizeof(name), "Trapz%sPad_%.6gx%.6g_%c%.6gx%c%.6g_mil",
                     uniqifier.c_str(), scale(aPad->GetSize().x), scale(aPad->GetSize().y),
            snprintf( name, sizeof(name), "Trapz%sPad_%.6gx%.6g_%c%.6gx%c%.6g_um",
                     uniqifier.c_str(), IU2um( aPad->GetSize().x ), IU2um( aPad->GetSize().y ),
                     aPad->GetDelta().x < 0 ? 'n' : 'p',
                     abs( scale( aPad->GetDelta().x )),
                     abs( IU2um( aPad->GetDelta().x )),
                     aPad->GetDelta().y < 0 ? 'n' : 'p',
                     abs( scale( aPad->GetDelta().y ))
                     abs( IU2um( aPad->GetDelta().y ) )
                     );
            name[ sizeof(name)-1 ] = 0;

@@ -708,10 +739,10 @@ PADSTACK* SPECCTRA_DB::makeVia( int aCopperDiameter, int aDrillDiameter,
        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,
             // encode the drill value into the name for later import
             scale( aDrillDiameter )
             IU2um( aDrillDiameter )
             );

    name[ sizeof(name)-1 ] = 0;
@@ -1004,6 +1035,16 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR )

    //-----<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->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:
        // http://www.freerouting.net/usren/viewtopic.php?f=3&t=354
        pcb->resolution->value = 10;
#endif
    }


    //-----<boundary_descriptor>------------------------------------------
    {
        // Because fillBOUNDARY() can throw an exception, we link in an
+30 −0
Original line number Diff line number Diff line
@@ -146,6 +146,33 @@ static int scale( double distance, UNIT_RES* aResolution )
{
    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.

    switch( aResolution->GetEngUnits() )
@@ -173,6 +200,9 @@ static int scale( double distance, UNIT_RES* aResolution )
    factor *= 10.0;

    int ret = wxRound( factor * distance / resValue );

#endif

    return ret;
}

+13 −4
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#define PCBU_PER_MIL    10
#endif


#define to_int( x ) wxRound( (x) )

#ifndef MIN
@@ -115,7 +116,8 @@ int CPolyLine::NormalizeWithKbool( std::vector<CPolyLine*> * aExtraPolyList, boo
            side_style.clear();
            bool first = true;
            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 y = (int) m_Kbool_Poly_Engine->GetPolygonYPoint();
                if( first )
@@ -1406,6 +1408,7 @@ void CPolyLine::Hatch()
        spacing = 20 * PCBU_PER_MIL;
    else
        spacing = 50 * PCBU_PER_MIL;

    // set the "lenght" of hatch lines (the lenght on horizontal axis)
    double hatch_line_len = 20 * PCBU_PER_MIL;

@@ -1437,9 +1440,11 @@ void CPolyLine::Hatch()
    // loop through hatch lines
    #define MAXPTS 200      // Usually we store only few values
                            // depending on the compexity of the zone outline

    static std::vector <CPoint> pointbuffer;
    pointbuffer.clear();
    pointbuffer.reserve(MAXPTS+2);

    for( int a = min_a; a < max_a; a += spacing )
    {
        // get intersection points for this hatch line
@@ -1520,17 +1525,21 @@ void CPolyLine::Hatch()
            {
                double dy    = pointbuffer[ip + 1].y - pointbuffer[ip].y;
                double slope = dy / dx;

                if( dx > 0 )
                    dx = hatch_line_len;
                else
                    dx = -hatch_line_len;

                double x1 = pointbuffer[ip].x + dx;
                double x2 = pointbuffer[ip + 1].x - dx;
                double y1 = pointbuffer[ip].y + dx * slope;
                double y2 = pointbuffer[ip + 1].y - dx * slope;

                m_HatchLines.push_back( CSegment( pointbuffer[ip].x,
                                                  pointbuffer[ip].y,
                                                  to_int( x1 ), to_int( y1 ) ) );

                m_HatchLines.push_back( CSegment( pointbuffer[ip + 1].x,
                                                  pointbuffer[ip + 1].y,
                                                  to_int( x2 ), to_int( y2 ) ) );
@@ -1560,6 +1569,7 @@ bool CPolyLine::TestPointInside( int px, int py )
    {
        int istart = GetContourStart( icont );
        int iend   = GetContourEnd( icont );

        // Test this polygon:
        if( TestPointInsidePolygon( corner, istart, iend, px, py) )   // test point inside the current polygon
            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++)
        AppendCorner( bezier_points[i].x, bezier_points[i].y);
}