BOARD_ITEM* MODULE::DuplicateAndAddItem( const BOARD_ITEM* aItem, bool aIncrementPadNumbers ) { BOARD_ITEM* new_item = NULL; switch( aItem->Type() ) { case PCB_PAD_T: { D_PAD* new_pad = new D_PAD( *static_cast<const D_PAD*>( aItem ) ); Pads().PushBack( new_pad ); new_item = new_pad; break; } case PCB_MODULE_TEXT_T: { const TEXTE_MODULE* old_text = static_cast<const TEXTE_MODULE*>( aItem ); // do not duplicate value or reference fields // (there can only be one of each) if( old_text->GetType() == TEXTE_MODULE::TEXT_is_DIVERS ) { TEXTE_MODULE* new_text = new TEXTE_MODULE( *old_text ); GraphicalItems().PushBack( new_text ); new_item = new_text; } break; } case PCB_MODULE_EDGE_T: { EDGE_MODULE* new_edge = new EDGE_MODULE( *static_cast<const EDGE_MODULE*>(aItem) ); GraphicalItems().PushBack( new_edge ); new_item = new_edge; break; } case PCB_MODULE_T: // Ignore the module itself break; default: // Un-handled item for duplication wxASSERT_MSG( false, "Duplication not supported for items of class " + aItem->GetClass() ); break; } if( aIncrementPadNumbers && new_item ) { new_item->IncrementItemReference(); } return new_item; }
void MODULE::MoveAnchorPosition( const wxPoint& aMoveVector ) { /* Move the reference point of the footprint * the footprints elements (pads, outlines, edges .. ) are moved * but: * - the footprint position is not modified. * - the relative (local) coordinates of these items are modified */ wxPoint footprintPos = GetPosition(); /* Update the relative coordinates: * The coordinates are relative to the anchor point. * Calculate deltaX and deltaY from the anchor. */ wxPoint moveVector = aMoveVector; RotatePoint( &moveVector, -GetOrientation() ); // Update of the reference and value. m_Reference->SetPos0( m_Reference->GetPos0() + moveVector ); m_Reference->SetDrawCoord(); m_Value->SetPos0( m_Value->GetPos0() + moveVector ); m_Value->SetDrawCoord(); // Update the pad local coordinates. for( D_PAD* pad = Pads(); pad; pad = pad->Next() ) { pad->SetPos0( pad->GetPos0() + moveVector ); pad->SetPosition( pad->GetPos0() + footprintPos ); } // Update the draw element coordinates. for( EDA_ITEM* item = GraphicalItems(); item; item = item->Next() ) { switch( item->Type() ) { case PCB_MODULE_EDGE_T: { EDGE_MODULE* edge = static_cast<EDGE_MODULE*>( item ); edge->m_Start0 += moveVector; edge->m_End0 += moveVector; edge->SetDrawCoord(); break; } case PCB_MODULE_TEXT_T: { TEXTE_MODULE* text = static_cast<TEXTE_MODULE*>( item ); text->SetPos0( text->GetPos0() + moveVector ); text->SetDrawCoord(); break; } default: break; } } CalculateBoundingBox(); }
/* generate shapes of graphic items (outlines) on layer aLayer as polygons, * and adds these polygons to aCornerBuffer * aCornerBuffer = the buffer to store polygons * aInflateValue = a value to inflate shapes * aCircleToSegmentsCount = number of segments to approximate a circle * aCorrectionFactor = the correction to apply to the circle radius * to generate the polygon. * if aCorrectionFactor = 1.0, the polygon is inside the circle * the radius of circle approximated by segments is * initial radius * aCorrectionFactor */ void MODULE::TransformGraphicShapesWithClearanceToPolygonSet( LAYER_NUM aLayer, CPOLYGONS_LIST& aCornerBuffer, int aInflateValue, int aCircleToSegmentsCount, double aCorrectionFactor ) { std::vector<TEXTE_MODULE *> texts; // List of TEXTE_MODULE to convert EDGE_MODULE* outline; for( EDA_ITEM* item = GraphicalItems(); item != NULL; item = item->Next() ) { switch( item->Type() ) { case PCB_MODULE_TEXT_T: if( ((TEXTE_MODULE*)item)->GetLayer() == aLayer ) texts.push_back( (TEXTE_MODULE *) item ); break; case PCB_MODULE_EDGE_T: outline = (EDGE_MODULE*) item; if( outline->GetLayer() != aLayer ) break; switch( outline->GetShape() ) { case S_SEGMENT: TransformRoundedEndsSegmentToPolygon( aCornerBuffer, outline->GetStart(), outline->GetEnd(), aCircleToSegmentsCount, outline->GetWidth() ); break; case S_CIRCLE: TransformRingToPolygon( aCornerBuffer, outline->GetCenter(), outline->GetRadius(), aCircleToSegmentsCount, outline->GetWidth() ); break; case S_ARC: TransformArcToPolygon( aCornerBuffer, outline->GetCenter(), outline->GetArcStart(), outline->GetAngle(), aCircleToSegmentsCount, outline->GetWidth() ); break; case S_POLYGON: // for outline shape = S_POLYGON: // We must compute true coordinates from m_PolyPoints // which are relative to module position and module orientation = 0 for( unsigned ii = 0; ii < outline->GetPolyPoints().size(); ii++ ) { CPolyPt corner( outline->GetPolyPoints()[ii] ); RotatePoint( &corner.x, &corner.y, GetOrientation() ); corner.x += GetPosition().x; corner.y += GetPosition().y; aCornerBuffer.Append( corner ); } aCornerBuffer.CloseLastContour(); break; default: DBG( printf( "Error: Shape %d not implemented!\n", outline->GetShape() ); ) break; } break; default: break; } }
/* generate shapes of graphic items (outlines) on layer aLayer as polygons, * and adds these polygons to aCornerBuffer * aCornerBuffer = the buffer to store polygons * aInflateValue = a value to inflate shapes * aCircleToSegmentsCount = number of segments to approximate a circle * aCorrectionFactor = the correction to apply to the circle radius * to generate the polygon. * if aCorrectionFactor = 1.0, the polygon is inside the circle * the radius of circle approximated by segments is * initial radius * aCorrectionFactor */ void MODULE::TransformGraphicShapesWithClearanceToPolygonSet( LAYER_ID aLayer, SHAPE_POLY_SET& aCornerBuffer, int aInflateValue, int aCircleToSegmentsCount, double aCorrectionFactor, int aCircleToSegmentsCountForTexts ) { std::vector<TEXTE_MODULE *> texts; // List of TEXTE_MODULE to convert EDGE_MODULE* outline; for( EDA_ITEM* item = GraphicalItems(); item != NULL; item = item->Next() ) { switch( item->Type() ) { case PCB_MODULE_TEXT_T: { TEXTE_MODULE* text = static_cast<TEXTE_MODULE*>( item ); if( text->GetLayer() == aLayer && text->IsVisible() ) texts.push_back( text ); break; } case PCB_MODULE_EDGE_T: outline = (EDGE_MODULE*) item; if( outline->GetLayer() != aLayer ) break; outline->TransformShapeWithClearanceToPolygon( aCornerBuffer, 0, aCircleToSegmentsCount, aCorrectionFactor ); break; default: break; } } // Convert texts sur modules if( Reference().GetLayer() == aLayer && Reference().IsVisible() ) texts.push_back( &Reference() ); if( Value().GetLayer() == aLayer && Value().IsVisible() ) texts.push_back( &Value() ); s_cornerBuffer = &aCornerBuffer; // To allow optimization of circles approximated by segments, // aCircleToSegmentsCountForTexts, when not 0, is used. // if 0 (default value) the aCircleToSegmentsCount is used s_textCircle2SegmentCount = aCircleToSegmentsCountForTexts ? aCircleToSegmentsCountForTexts : aCircleToSegmentsCount; for( unsigned ii = 0; ii < texts.size(); ii++ ) { TEXTE_MODULE *textmod = texts[ii]; s_textWidth = textmod->GetThickness() + ( 2 * aInflateValue ); wxSize size = textmod->GetSize(); if( textmod->IsMirrored() ) size.x = -size.x; DrawGraphicText( NULL, NULL, textmod->GetTextPosition(), BLACK, textmod->GetShownText(), textmod->GetDrawRotation(), size, textmod->GetHorizJustify(), textmod->GetVertJustify(), textmod->GetThickness(), textmod->IsItalic(), true, addTextSegmToPoly ); } }