D_PAD::D_PAD( MODULE* parent ) :
    BOARD_CONNECTED_ITEM( parent, PCB_PAD_T )
{
    m_NumPadName          = 0;
    m_Size.x = m_Size.y   = Mils2iu( 60 );  // Default pad size 60 mils.
    m_Drill.x = m_Drill.y = Mils2iu( 30 );  // Default drill size 30 mils.
    m_Orient              = 0;              // Pad rotation in 1/10 degrees.
    m_LengthPadToDie      = 0;

    if( m_Parent  &&  m_Parent->Type() == PCB_MODULE_T )
    {
        m_Pos = GetParent()->GetPosition();
    }

    SetShape( PAD_SHAPE_CIRCLE );                   // Default pad shape is PAD_CIRCLE.
    SetDrillShape( PAD_DRILL_SHAPE_CIRCLE );        // Default pad drill shape is a circle.
    m_Attribute           = PAD_ATTRIB_STANDARD;    // Default pad type is NORMAL (thru hole)
    m_LocalClearance      = 0;
    m_LocalSolderMaskMargin  = 0;
    m_LocalSolderPasteMargin = 0;
    m_LocalSolderPasteMarginRatio = 0.0;
    // Parameters for round rect only:
    m_padRoundRectRadiusScale = 0.25;                   // from  IPC-7351C standard

    m_ZoneConnection      = PAD_ZONE_CONN_INHERITED; // Use parent setting by default
    m_ThermalWidth        = 0;                  // Use parent setting by default
    m_ThermalGap          = 0;                  // Use parent setting by default

    // Set layers mask to default for a standard thru hole pad.
    m_layerMask           = StandardMask();

    SetSubRatsnest( 0 );                       // used in ratsnest calculations

    m_boundingRadius      = -1;
}
Beispiel #2
0
ZONE_SETTINGS::ZONE_SETTINGS()
{
    m_ZonePriority = 0;
    m_FillMode = 0;                                            // Mode for filling zone : 1 use segments, 0 use polygons
    // Clearance value
    m_ZoneClearance      = Mils2iu( ZONE_CLEARANCE_MIL );
    // Min thickness value in filled areas (this is the minimum width of copper to fill solid areas) :
    m_ZoneMinThickness   = Mils2iu( ZONE_THICKNESS_MIL );
    m_NetcodeSelection   = 0;                                  // Net code selection for the current zone
    m_CurrentZone_Layer  = FIRST_LAYER;                        // Layer used to create the current zone
    m_Zone_HatchingStyle = CPolyLine::DIAGONAL_EDGE;           // Option to show the zone area (outlines only, short hatches or full hatches

    m_ArcToSegmentsCount = ARC_APPROX_SEGMENTS_COUNT_LOW_DEF;  // Option to select number of segments to approximate a circle
                                                               // ARC_APPROX_SEGMENTS_COUNT_LOW_DEF
                                                               // or ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF segments

    // thickness of the gap in thermal reliefs:
    m_ThermalReliefGap = Mils2iu( ZONE_THERMAL_RELIEF_GAP_MIL );
    // thickness of the copper bridge in thermal reliefs:
    m_ThermalReliefCopperBridge = Mils2iu( ZONE_THERMAL_RELIEF_COPPER_WIDTH_MIL );

    m_PadConnection = THERMAL_PAD;                             // How pads are covered by copper in zone

    m_Zone_45_Only = false;

    m_cornerSmoothingType = SMOOTHING_NONE;
    m_cornerRadius = 0;

    SetIsKeepout( false );
    SetDoNotAllowCopperPour( false );
    SetDoNotAllowVias( true );
    SetDoNotAllowTracks( true );
}
void EDA_TEXT::Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControlBits ) const
    throw( IO_ERROR )
{
#ifndef GERBVIEW        // Gerbview does not use EDA_TEXT::Format
                        // and does not define FMT_IU, used here
                        // however this function should exist
    if( !IsDefaultFormatting() )
    {
        aFormatter->Print( aNestLevel+1, "(effects" );

        if( ( m_Size.x != Mils2iu( DEFAULT_SIZE_TEXT ) )
          || ( m_Size.y != Mils2iu( DEFAULT_SIZE_TEXT ) )
          || ( m_Thickness != 0 ) || m_Bold || m_Italic )
        {
            aFormatter->Print( 0, " (font" );

            // Add font support here at some point in the future.

            if( ( m_Size.x != Mils2iu( DEFAULT_SIZE_TEXT ) )
              || ( m_Size.y != Mils2iu( DEFAULT_SIZE_TEXT ) ) )
                aFormatter->Print( 0, " (size %s %s)", FMT_IU( m_Size.GetHeight() ).c_str(),
                                   FMT_IU( m_Size.GetWidth() ).c_str() );

            if( m_Thickness != 0 )
                aFormatter->Print( 0, " (thickness %s)", FMT_IU( GetThickness() ).c_str() );

            if( m_Bold )
                aFormatter->Print( 0, " bold" );

            if( IsItalic() )
                aFormatter->Print( 0, " italic" );

            aFormatter->Print( 0, ")");
        }

        if( m_Mirror || ( m_HJustify != GR_TEXT_HJUSTIFY_CENTER )
          || ( m_VJustify != GR_TEXT_VJUSTIFY_CENTER ) )
        {
            aFormatter->Print( 0, " (justify");

            if( m_HJustify != GR_TEXT_HJUSTIFY_CENTER )
                aFormatter->Print( 0, (m_HJustify == GR_TEXT_HJUSTIFY_LEFT) ? " left" : " right" );

            if( m_VJustify != GR_TEXT_VJUSTIFY_CENTER )
                aFormatter->Print( 0, (m_VJustify == GR_TEXT_VJUSTIFY_TOP) ? " top" : " bottom" );

            if( m_Mirror )
                aFormatter->Print( 0, " mirror" );

            aFormatter->Print( 0, ")" );
        }

        // As of now the only place this is used is in Eeschema to hide or show the text.
        if( m_Attributs )
            aFormatter->Print( 0, " hide" );

        aFormatter->Print( 0, ")\n" );
    }
#endif
}
bool EDA_TEXT::IsDefaultFormatting() const
{
    return (  ( m_Size.x == Mils2iu( DEFAULT_SIZE_TEXT ) )
           && ( m_Size.y == Mils2iu( DEFAULT_SIZE_TEXT ) )
           && ( m_Attributs == 0 )
           && ( m_Mirror == false )
           && ( m_HJustify == GR_TEXT_HJUSTIFY_CENTER )
           && ( m_VJustify == GR_TEXT_VJUSTIFY_CENTER )
           && ( m_Thickness == 0 )
           && ( m_Italic == false )
           && ( m_Bold == false )
           && ( m_MultilineAllowed == false ) );
}
Beispiel #5
0
void ZONE_SETTINGS::ExportSetting( ZONE_CONTAINER& aTarget, bool aFullExport ) const
{
    aTarget.SetFillMode( m_FillMode );
    aTarget.SetZoneClearance( m_ZoneClearance );
    aTarget.SetMinThickness( m_ZoneMinThickness );
    aTarget.SetArcSegmentCount( m_ArcToSegmentsCount );
    aTarget.SetThermalReliefGap( m_ThermalReliefGap );
    aTarget.SetThermalReliefCopperBridge( m_ThermalReliefCopperBridge );
    aTarget.SetPadConnection( m_PadConnection );
    aTarget.SetCornerSmoothingType( m_cornerSmoothingType );
    aTarget.SetCornerRadius( m_cornerRadius );
    aTarget.SetIsKeepout( GetIsKeepout() );
    aTarget.SetDoNotAllowCopperPour( GetDoNotAllowCopperPour() );
    aTarget.SetDoNotAllowVias( GetDoNotAllowVias() );
    aTarget.SetDoNotAllowTracks( GetDoNotAllowTracks() );

    if( aFullExport )
    {
        aTarget.SetPriority( m_ZonePriority );
        aTarget.SetNet( m_NetcodeSelection );
        aTarget.SetLayer( m_CurrentZone_Layer );
        aTarget.Outline()->SetLayer( m_CurrentZone_Layer );
    }

    // call SetHatch last, because hatch lines will be rebuilt,
    // using new parameters values
    aTarget.Outline()->SetHatch( m_Zone_HatchingStyle, Mils2iu( 20 ), true );
}
Beispiel #6
0
bool DIALOG_TARGET_PROPERTIES::TransferDataFromWindow()
{
    // Zero-size targets are hard to see/select.
    if( !m_Size.Validate( Mils2iu( 1 ), INT_MAX ) )
        return false;

    BOARD_COMMIT commit( m_Parent );
    commit.Modify( m_Target );

    if( m_DC )
        m_Target->Draw( m_Parent->GetCanvas(), m_DC, GR_XOR );

    // Save old item in undo list, if is is not currently edited (will be later if so)
    bool pushCommit = ( m_Target->GetFlags() == 0 );

    if( m_Target->GetFlags() != 0 )         // other edit in progress (MOVE, NEW ..)
        m_Target->SetFlags( IN_EDIT );      // set flag in edit to force
    // undo/redo/abort proper operation

    m_Target->SetWidth( m_Thickness.GetValue() );
    m_Target->SetSize( m_Size.GetValue() );
    m_Target->SetShape( m_TargetShape->GetSelection() ? 1 : 0 );

    if( m_DC )
        m_Target->Draw( m_Parent->GetCanvas(), m_DC, ( m_Target->IsMoving() ) ? GR_XOR : GR_OR );

    if( pushCommit )
        commit.Push( _( "Modified alignment target" ) );

    return true;
}
double StrToDoublePrecisionUnits( wxString aStr, char aAxe, wxString aActualConversion )
{
    wxString    ls;
    double      i;
    char        u;

    ls = aStr;
    ls.Trim( true );
    ls.Trim( false );

    if( ls.Len() > 0 )
    {
        u = ls[ls.Len() - 1];

        while( ls.Len() > 0
               && !( ls[ls.Len() - 1] == wxT( '.' )
                     || ls[ls.Len() - 1] == wxT( ',' )
                     || (ls[ls.Len() - 1] >= wxT( '0' ) && ls[ls.Len() - 1] <= wxT( '9' ) ) ) )
        {
            ls = ls.Left( ls.Len() - 1 );
        }

        while( ls.Len() > 0
               && !( ls[0] == wxT( '-' )
                     || ls[0] == wxT( '+' )
                     || ls[0] == wxT( '.' )
                     || ls[0] == wxT( ',' )
                     || (ls[0] >= wxT( '0' ) && ls[0] <= wxT( '9' ) ) ) )
        {
            ls = ls.Mid( 1 );
        }

        if( u == wxT( 'm' ) )
        {
            ls.ToDouble( &i );
#ifdef PCAD2KICAD_SCALE_SCH_TO_INCH_GRID
            if( aActualConversion == wxT( "SCH" )
                || aActualConversion == wxT( "SCHLIB" ) )
                i = i * (0.0254 / 0.025);
#endif
            i = Millimeter2iu( i );
        }
        else
        {
            ls.ToDouble( &i );
            i = Mils2iu( i );
        }
    }
    else
        i = 0.0;

    if( ( aActualConversion == wxT( "PCB" ) || aActualConversion == wxT( "SCH" ) )
        && aAxe == wxT( 'Y' ) )
        return -i;
    else
        return i; // Y axe is mirrored compared to P-Cad
}
void DIALOG_PAGES_SETTINGS::OnOkClick( wxCommandEvent& event )
{
    if( !m_customSizeX.Validate( Mils2iu( MIN_PAGE_SIZE ), Mils2iu( m_maxPageSizeMils.x ) ) )
        return;

    if( !m_customSizeY.Validate( Mils2iu( MIN_PAGE_SIZE ), Mils2iu( m_maxPageSizeMils.y ) ) )
        return;

    if( SavePageSettings() )
    {
        m_screen->SetModify();

        if( LocalPrjConfigChanged() )
            m_parent->SaveProjectSettings( false );

        // Call the post processing (if any) after changes
        m_parent->OnPageSettingsChange();
    }

    event.Skip();
}
double GERBVIEW_FRAME::BestZoom()
{
    EDA_RECT bbox = GetGerberLayout()->ComputeBoundingBox();

    // gives a size to bbox (current page size), if no item in list
    if( bbox.GetWidth() == 0 || bbox.GetHeight() == 0 )
    {
        wxSize pagesize = GetPageSettings().GetSizeMils();
        bbox.SetSize( wxSize( Mils2iu( pagesize.x ), Mils2iu( pagesize.y ) ) );
    }

    // Compute best zoom:
    wxSize  size = m_canvas->GetClientSize();
    double  x   = (double) bbox.GetWidth() / (double) size.x;
    double  y   = (double) bbox.GetHeight() / (double) size.y;
    double  best_zoom = std::max( x, y ) * 1.1;

    SetScrollCenterPosition( bbox.Centre() );

    return best_zoom;
}
Beispiel #10
0
EDA_TEXT::EDA_TEXT( const wxString& text )
{
    m_Size.x    = m_Size.y = Mils2iu( DEFAULT_SIZE_TEXT );  // Width and height of font.
    m_Orient    = 0;                             // Rotation angle in 0.1 degrees.
    m_Attributs = 0;
    m_Mirror    = false;                         // display mirror if true
    m_HJustify  = GR_TEXT_HJUSTIFY_CENTER;       // Default horizontal justification is centered.
    m_VJustify  = GR_TEXT_VJUSTIFY_CENTER;       // Default vertical justification is centered.
    m_Thickness = 0;                             // thickness
    m_Italic    = false;                         // true = italic shape.
    m_Bold      = false;
    m_MultilineAllowed = false;                  // Set to true for multiline text.
    m_Text = text;
}
void DIMENSION::AdjustDimensionDetails( bool aDoNotChangeText )
{
    const int   arrowz = Mils2iu( 50 );             // size of arrows
    int         ii;
    int         measure, deltax, deltay;            // value of the measure on X and Y axes
    int         arrow_up_X  = 0, arrow_up_Y = 0;    // coordinates of arrow line /
    int         arrow_dw_X  = 0, arrow_dw_Y = 0;    // coordinates of arrow line '\'
    int         hx, hy;                             // dimension line interval
    double      angle, angle_f;
    wxString    msg;

    // Init layer :
    m_Text.SetLayer( GetLayer() );

    // calculate the size of the dimension (text + line above the text)
    ii = m_Text.GetSize().y + m_Text.GetThickness() + (m_Width * 3);

    deltax  = m_featureLineDO.x - m_featureLineGO.x;
    deltay  = m_featureLineDO.y - m_featureLineGO.y;

    // Calculate dimension value
    measure = KiROUND( hypot( deltax, deltay ) );

    angle = atan2( (double)deltay, (double)deltax );

    // Calculation of parameters X and Y dimensions of the arrows and lines.
    hx = hy = ii;

    // Taking into account the slope of the side lines.
    if( measure )
    {
        hx  = abs( KiROUND( ( (double) deltay * hx ) / measure ) );
        hy  = abs( KiROUND( ( (double) deltax * hy ) / measure ) );

        if( m_featureLineGO.x > m_crossBarO.x )
            hx = -hx;

        if( m_featureLineGO.x == m_crossBarO.x )
            hx = 0;

        if( m_featureLineGO.y > m_crossBarO.y )
            hy = -hy;

        if( m_featureLineGO.y == m_crossBarO.y )
            hy = 0;

        angle_f     = angle + DEG2RAD( 27.5 );
        arrow_up_X  = wxRound( arrowz * cos( angle_f ) );
        arrow_up_Y  = wxRound( arrowz * sin( angle_f ) );
        angle_f     = angle - DEG2RAD( 27.5 );
        arrow_dw_X  = wxRound( arrowz * cos( angle_f ) );
        arrow_dw_Y  = wxRound( arrowz * sin( angle_f ) );
    }

    int dx = KiROUND( m_Height * cos( angle + M_PI / 2 ) );
    int dy = KiROUND( m_Height * sin( angle + M_PI / 2 ) );
    m_crossBarO.x   = m_featureLineGO.x + dx;
    m_crossBarO.y   = m_featureLineGO.y + dy;
    m_crossBarF.x   = m_featureLineDO.x + dx;
    m_crossBarF.y   = m_featureLineDO.y + dy;

    m_arrowG1F.x    = m_crossBarO.x + arrow_up_X;
    m_arrowG1F.y    = m_crossBarO.y + arrow_up_Y;

    m_arrowG2F.x    = m_crossBarO.x + arrow_dw_X;
    m_arrowG2F.y    = m_crossBarO.y + arrow_dw_Y;

    /* The right arrow is symmetrical to the left.
     *  / = -\  and  \ = -/
     */
    m_arrowD1F.x    = m_crossBarF.x - arrow_dw_X;
    m_arrowD1F.y    = m_crossBarF.y - arrow_dw_Y;

    m_arrowD2F.x    = m_crossBarF.x - arrow_up_X;
    m_arrowD2F.y    = m_crossBarF.y - arrow_up_Y;

    m_featureLineGF.x   = m_crossBarO.x + hx;
    m_featureLineGF.y   = m_crossBarO.y + hy;

    m_featureLineDF.x   = m_crossBarF.x + hx;
    m_featureLineDF.y   = m_crossBarF.y + hy;

    // Calculate the better text position and orientation:
    wxPoint textPos;
    textPos.x  = (m_crossBarF.x + m_featureLineGF.x) / 2;
    textPos.y  = (m_crossBarF.y + m_featureLineGF.y) / 2;
    m_Text.SetTextPosition( textPos );

    double newAngle = -RAD2DECIDEG( angle );

    NORMALIZE_ANGLE_POS( newAngle );

    if( newAngle > 900  &&  newAngle < 2700 )
        newAngle -= 1800;

    m_Text.SetOrientation( newAngle );

    if( !aDoNotChangeText )
    {
        m_Value = measure;
        msg     = ::CoordinateToString( m_Value );
        SetText( msg );
    }
}
void ZONE_CONTAINER::SetCornerRadius( unsigned int aRadius )
{
    m_cornerRadius = aRadius;
    if( m_cornerRadius > (unsigned int) Mils2iu( MAX_ZONE_CORNER_RADIUS_MILS ) )
        m_cornerRadius = Mils2iu( MAX_ZONE_CORNER_RADIUS_MILS );
};
int ZONE_CONTAINER::FillZoneAreasWithSegments()
{
    int      ics, ice;
    int count = 0;
    std::vector <int> x_coordinates;
    bool error = false;

    int      istart, iend;      // index of the starting and the endif corner of one filled area in m_FilledPolysList

    int margin = m_ZoneMinThickness * 2 / 10;
    int minwidth = Mils2iu( 2 );
    margin = std::max ( minwidth, margin );
    int step = m_ZoneMinThickness - margin;
    step = std::max( step, minwidth );

    // Read all filled areas in m_FilledPolysList
    m_FillSegmList.clear();
    istart = 0;
    int end_list =  m_FilledPolysList.GetCornersCount()-1;

    for( int ic = 0; ic <= end_list; ic++ )
    {
        CPolyPt* corner = &m_FilledPolysList[ic];
        if ( corner->end_contour || (ic == end_list) )
        {
            iend = ic;
            EDA_RECT rect = CalculateSubAreaBoundaryBox( istart, iend );

            // Calculate the y limits of the zone
            int refy = rect.GetY();
            int endy = rect.GetBottom();

            for( ; refy < endy; refy += step )
            {
                // find all intersection points of an infinite line with polyline sides
                x_coordinates.clear();

                for( ics = istart, ice = iend; ics <= iend; ice = ics, ics++ )
                {
                    if ( m_FilledPolysList[ice].m_utility )
                        continue;

                    int seg_startX = m_FilledPolysList[ics].x;
                    int seg_startY = m_FilledPolysList[ics].y;
                    int seg_endX   = m_FilledPolysList[ice].x;
                    int seg_endY   = m_FilledPolysList[ice].y;


                    /* Trivial cases: skip if ref above or below the segment to test */
                    if( ( seg_startY > refy ) && (seg_endY > refy ) )
                        continue;

                    // segment below ref point, or its Y end pos on Y coordinate ref point: skip
                    if( ( seg_startY <= refy ) && (seg_endY <= refy ) )
                        continue;

                    /* at this point refy is between seg_startY and seg_endY
                     * see if an horizontal line at Y = refy is intersecting this segment
                    */
                    // calculate the x position of the intersection of this segment and the
                    // infinite line this is more easier if we move the X,Y axis origin to
                    // the segment start point:
                    seg_endX -= seg_startX;
                    seg_endY -= seg_startY;
                    double newrefy = (double) (refy - seg_startY);
                    double intersec_x;

                    if ( seg_endY == 0 )    // horizontal segment on the same line: skip
                        continue;

                    // Now calculate the x intersection coordinate of the horizontal line at
                    // y = newrefy and the segment from (0,0) to (seg_endX,seg_endY) with the
                    // horizontal line at the new refy position the line slope is:
                    // slope = seg_endY/seg_endX; and inv_slope = seg_endX/seg_endY
                    // and the x pos relative to the new origin is:
                    // intersec_x = refy/slope = refy * inv_slope
                    // Note: because horizontal segments are already tested and skipped, slope
                    // exists (seg_end_y not O)
                    double inv_slope      = (double)seg_endX / seg_endY;
                    intersec_x = newrefy * inv_slope;
                    x_coordinates.push_back((int) intersec_x + seg_startX);
                }

                // A line scan is finished: build list of segments

                // Sort intersection points by increasing x value:
                // So 2 consecutive points are the ends of a segment
                sort( x_coordinates.begin(), x_coordinates.end(), SortByXValues );

                // Create segments

                if ( !error && ( x_coordinates.size() & 1 ) != 0 )
                {   // An even number of coordinates is expected, because a segment has 2 ends.
                    // An if this algorithm always works, it must always find an even count.
                    wxString msg = wxT("Fill Zone: odd number of points at y = ");
                    msg << refy;
                    wxMessageBox(msg );
                    error = true;
                }

                if ( error )
                    break;

                int iimax = x_coordinates.size()-1;

                for (int ii = 0; ii < iimax; ii +=2 )
                {
                    wxPoint  seg_start, seg_end;
                    count++;
                    seg_start.x = x_coordinates[ii];
                    seg_start.y = refy;
                    seg_end.x = x_coordinates[ii+1];
                    seg_end.y = refy;
                    SEGMENT segment( seg_start, seg_end );
                    m_FillSegmList.push_back( segment );
                }
            }   //End examine segments in one area

            if ( error )
                break;

            istart = iend + 1;  // istart points the first corner of the next area
        }   // End find one end of outline

        if ( error )
            break;
    }   // End examine all areas

    return count;
}