From 75d02086ad6362cecfc790c06fd1986e28fdf888 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Fri, 31 Jul 2015 21:04:30 +0200 Subject: [PATCH] Modedit: fix a minor bug in footprint transform (polygons not mirrored or rotated in global footprint transform). Code cleaning: in class EDGE_MODULE and TEXTE_MODULE, remove duplicate methods for fp edition (about rotation, mirroring and move) and add comments. --- pcbnew/block_module_editor.cpp | 62 +++++++---------------- pcbnew/class_edge_mod.cpp | 91 ++++++++++++++++++++++++++++------ pcbnew/class_edge_mod.h | 56 ++++++++++++++++----- pcbnew/class_module.cpp | 14 ++---- pcbnew/class_text_mod.cpp | 66 ++++++++---------------- pcbnew/class_text_mod.h | 29 ++++------- 6 files changed, 174 insertions(+), 144 deletions(-) diff --git a/pcbnew/block_module_editor.cpp b/pcbnew/block_module_editor.cpp index 972de852b3..1ec2447fde 100644 --- a/pcbnew/block_module_editor.cpp +++ b/pcbnew/block_module_editor.cpp @@ -485,10 +485,10 @@ void MoveMarkedItems( MODULE* module, wxPoint offset ) return; if( module->Reference().IsSelected() ) - module->Reference().MoveTransformWithModule( offset ); + module->Reference().Move( offset ); if( module->Value().IsSelected() ) - module->Value().MoveTransformWithModule( offset ); + module->Value().Move( offset ); D_PAD* pad = module->Pads(); @@ -511,7 +511,7 @@ void MoveMarkedItems( MODULE* module, wxPoint offset ) switch( item->Type() ) { case PCB_MODULE_TEXT_T: - static_cast( item )->MoveTransformWithModule( offset ); + static_cast( item )->Move( offset ); break; case PCB_MODULE_EDGE_T: @@ -588,10 +588,10 @@ void MirrorMarkedItems( MODULE* module, wxPoint offset, bool force_all ) return; if( module->Reference().IsSelected() || force_all ) - module->Reference().MirrorTransformWithModule( offset.x ); + module->Reference().Mirror( offset, false ); if( module->Value().IsSelected() || force_all ) - module->Value().MirrorTransformWithModule( offset.x ); + module->Value().Mirror( offset, false ); for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() ) { @@ -625,25 +625,11 @@ void MirrorMarkedItems( MODULE* module, wxPoint offset, bool force_all ) switch( item->Type() ) { case PCB_MODULE_EDGE_T: - { - EDGE_MODULE* em = (EDGE_MODULE*) item; - - tmp = em->GetStart0(); - SETMIRROR( tmp.x ); - em->SetStart0( tmp ); - em->SetStartX( tmp.x ); - - tmp = em->GetEnd0(); - SETMIRROR( tmp.x ); - em->SetEnd0( tmp ); - em->SetEndX( tmp.x ); - - em->SetAngle( -em->GetAngle() ); - } + ((EDGE_MODULE*) item)->Mirror( offset, false ); break; case PCB_MODULE_TEXT_T: - static_cast( item )->MirrorTransformWithModule( offset.x ); + static_cast( item )->Mirror( offset, false ); break; default: @@ -667,10 +653,10 @@ void RotateMarkedItems( MODULE* module, wxPoint offset, bool force_all ) return; if( module->Reference().IsSelected() || force_all ) - module->Reference().RotateTransformWithModule( offset, 900 ); + module->Reference().Rotate( offset, 900 ); if( module->Value().IsSelected() || force_all ) - module->Value().RotateTransformWithModule( offset, 900 ); + module->Value().Rotate( offset, 900 ); for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() ) { @@ -693,23 +679,11 @@ void RotateMarkedItems( MODULE* module, wxPoint offset, bool force_all ) switch( item->Type() ) { case PCB_MODULE_EDGE_T: - { - EDGE_MODULE* em = (EDGE_MODULE*) item; - - wxPoint tmp = em->GetStart0(); - ROTATE( tmp ); - em->SetStart0( tmp ); - - tmp = em->GetEnd0(); - ROTATE( tmp ); - em->SetEnd0( tmp ); - - em->SetDrawCoord(); - } - break; + ((EDGE_MODULE*) item)->Rotate( offset, 900 ); + break; case PCB_MODULE_TEXT_T: - static_cast( item )->RotateTransformWithModule( offset, 900 ); + static_cast( item )->Rotate( offset, 900 ); break; default: @@ -754,14 +728,14 @@ void MoveMarkedItemsExactly( MODULE* module, const wxPoint& centre, if( module->Reference().IsSelected() || force_all ) { - module->Reference().RotateTransformWithModule( centre, rotation ); - module->Reference().MoveTransformWithModule( translation ); + module->Reference().Rotate( centre, rotation ); + module->Reference().Move( translation ); } if( module->Value().IsSelected() || force_all ) { - module->Value().RotateTransformWithModule( centre, rotation ); - module->Value().MoveTransformWithModule( translation ); + module->Value().Rotate( centre, rotation ); + module->Value().Move( translation ); } D_PAD* pad = module->Pads(); @@ -797,8 +771,8 @@ void MoveMarkedItemsExactly( MODULE* module, const wxPoint& centre, { TEXTE_MODULE* text = static_cast( item ); - text->RotateTransformWithModule( centre, rotation ); - text->MoveTransformWithModule( translation ); + text->Rotate( centre, rotation ); + text->Move( translation ); break; } case PCB_MODULE_EDGE_T: diff --git a/pcbnew/class_edge_mod.cpp b/pcbnew/class_edge_mod.cpp index c79daa27c1..9d9abd1006 100644 --- a/pcbnew/class_edge_mod.cpp +++ b/pcbnew/class_edge_mod.cpp @@ -1,10 +1,10 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr + * Copyright (C) 2015 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck * Copyright (C) 2012 Wayne Stambaugh - * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -220,7 +220,7 @@ void EDGE_MODULE::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE draw_mode, case S_POLYGON: { - // We must compute true coordinates from m_PolyPoints + // We must compute absolute coordinates from m_PolyPoints // which are relative to module position, orientation 0 std::vector points = m_PolyPoints; @@ -300,36 +300,99 @@ void EDGE_MODULE::Flip( const wxPoint& aCentre ) default: case S_SEGMENT: pt = GetStart(); - pt.y -= aCentre.y; - pt.y = -pt.y; - pt.y += aCentre.y; + MIRROR( pt.y, aCentre.y ); SetStart( pt ); pt = GetEnd(); - pt.y -= aCentre.y; - pt.y = -pt.y; - pt.y += aCentre.y; + MIRROR( pt.y, aCentre.y ); SetEnd( pt ); - m_Start0.y = -m_Start0.y; - m_End0.y = -m_End0.y; + MIRROR( m_Start0.y, 0 ); + MIRROR( m_End0.y, 0 ); break; case S_POLYGON: // polygon corners coordinates are always relative to the // footprint position, orientation 0 for( unsigned ii = 0; ii < m_PolyPoints.size(); ii++ ) - m_PolyPoints[ii].y = -m_PolyPoints[ii].y; + MIRROR( m_PolyPoints[ii].y, 0 ); } SetLayer( FlipLayer( GetLayer() ) ); } + +void EDGE_MODULE::Mirror( wxPoint aCentre, bool aMirrorAroundXAxis ) +{ + // Mirror an edge of the footprint. the layer is not modified + // This is a footprint shape modification. + wxPoint pt; + + switch( GetShape() ) + { + case S_ARC: + SetAngle( -GetAngle() ); + //Fall through + default: + case S_SEGMENT: + if( aMirrorAroundXAxis ) + { + MIRROR( m_Start0.y, aCentre.y ); + MIRROR( m_End0.y, aCentre.y ); + } + else + { + MIRROR( m_Start0.x, aCentre.x ); + MIRROR( m_End0.x, aCentre.x ); + } + break; + + case S_POLYGON: + // polygon corners coordinates are always relative to the + // footprint position, orientation 0 + for( unsigned ii = 0; ii < m_PolyPoints.size(); ii++ ) + { + if( aMirrorAroundXAxis ) + MIRROR( m_PolyPoints[ii].y, aCentre.y ); + else + MIRROR( m_PolyPoints[ii].x, aCentre.x ); + } + } + + SetDrawCoord(); +} + void EDGE_MODULE::Rotate( const wxPoint& aRotCentre, double aAngle ) { - // do the base class rotation + // We should rotate the relative coordinates, but to avoid duplicate code, + // do the base class rotation of draw coordinates, which is acceptable + // because in module editor, m_Pos0 = m_Pos DRAWSEGMENT::Rotate( aRotCentre, aAngle ); - // and now work out the new offset + // and now update the relative coordinates, which are + // the reference in most transforms. SetLocalCoord(); } + + +void EDGE_MODULE::Move( const wxPoint& aMoveVector ) +{ + // Move an edge of the footprint. + // This is a footprint shape modification. + m_Start0 += aMoveVector; + m_End0 += aMoveVector; + + switch( GetShape() ) + { + default: + break; + + case S_POLYGON: + // polygon corners coordinates are always relative to the + // footprint position, orientation 0 + for( unsigned ii = 0; ii < m_PolyPoints.size(); ii++ ) + m_PolyPoints[ii] += aMoveVector; + } + + SetDrawCoord(); +} diff --git a/pcbnew/class_edge_mod.h b/pcbnew/class_edge_mod.h index 1230ee87c8..b2eebc58b7 100644 --- a/pcbnew/class_edge_mod.h +++ b/pcbnew/class_edge_mod.h @@ -1,9 +1,9 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr + * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2013 Wayne Stambaugh - * Copyright (C) 1992-2013 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -61,14 +61,36 @@ public: void Copy( EDGE_MODULE* source ); // copy structure - void Move( const wxPoint& aMoveVector ) - { - m_Start += aMoveVector; - m_End += aMoveVector; - SetLocalCoord(); - } - - /// Flip entity relative to aCentre + /** + * Move an edge of the footprint. + * This is a footprint shape modification. + * (should be only called by a footprint editing function) + */ + void Move( const wxPoint& aMoveVector ); + + /** + * Mirror an edge of the footprint. + * Do not change the layer + * This is a footprint shape modification. + * (should be only called by a footprint editing function) + */ + void Mirror( const wxPoint aCentre, bool aMirrorAroundXAxis ); + + /** + * Rotate an edge of the footprint. + * This is a footprint shape modification. + * (should be only called by a footprint editing function ) + */ + void Rotate( const wxPoint& aRotCentre, double aAngle ); + + /** + * Flip entity relative to aCentre. + * The item is mirrored, and layer changed to the paired corresponding layer + * if it is on a paired layer + * This function should be called only from MODULE::Flip because there is + * not usual to flip an item alone, without flipping the parent footprint. + * (consider Mirror for a mirror transform). + */ void Flip( const wxPoint& aCentre ); void SetStart0( const wxPoint& aPoint ) { m_Start0 = aPoint; } @@ -77,10 +99,19 @@ public: void SetEnd0( const wxPoint& aPoint ) { m_End0 = aPoint; } const wxPoint& GetEnd0() const { return m_End0; } - ///> Set relative coordinates. + /** + * Set relative coordinates from draw coordinates. + * Call in only when the geometry ov the footprint is modified + * and therefore the relative coordinates have to be updated from + * the draw coordinates + */ void SetLocalCoord(); - ///> Set absolute coordinates. + /** + * Set draw coordinates (absolute values ) from relative coordinates. + * Must be called when a relative coordinate has changed, in order + * to see the changes on screen + */ void SetDrawCoord(); /* drawing functions */ @@ -100,7 +131,6 @@ public: EDA_ITEM* Clone() const; - void Rotate( const wxPoint& aRotCentre, double aAngle ); // override #if defined(DEBUG) void Show( int nestLevel, std::ostream& os ) const { ShowDummy( os ); } // override diff --git a/pcbnew/class_module.cpp b/pcbnew/class_module.cpp index 093df74201..562489af4d 100644 --- a/pcbnew/class_module.cpp +++ b/pcbnew/class_module.cpp @@ -945,9 +945,7 @@ void MODULE::Flip( const wxPoint& aCentre ) { // Move module to its final position: wxPoint finalPos = m_Pos; - - finalPos.y = aCentre.y - ( finalPos.y - aCentre.y ); /// Mirror the Y position - + MIRROR( finalPos.y, aCentre.y ); /// Mirror the Y position SetPosition( finalPos ); // Flip layer @@ -961,11 +959,9 @@ void MODULE::Flip( const wxPoint& aCentre ) for( D_PAD* pad = m_Pads; pad; pad = pad->Next() ) pad->Flip( m_Pos ); - // Mirror reference. - m_Reference->FlipWithModule( m_Pos.y ); - - // Mirror value. - m_Value->FlipWithModule( m_Pos.y ); + // Mirror reference and value. + m_Reference->Flip( m_Pos ); + m_Value->Flip( m_Pos ); // Reverse mirror module graphics and texts. for( EDA_ITEM* item = m_Drawings; item; item = item->Next() ) @@ -977,7 +973,7 @@ void MODULE::Flip( const wxPoint& aCentre ) break; case PCB_MODULE_TEXT_T: - static_cast( item )->FlipWithModule( m_Pos.y ); + static_cast( item )->Flip( m_Pos ); break; default: diff --git a/pcbnew/class_text_mod.cpp b/pcbnew/class_text_mod.cpp index ef83ccdee1..0cc8389100 100644 --- a/pcbnew/class_text_mod.cpp +++ b/pcbnew/class_text_mod.cpp @@ -55,15 +55,12 @@ TEXTE_MODULE::TEXTE_MODULE( MODULE* parent, TEXT_TYPE text_type ) : MODULE* module = static_cast( m_Parent ); m_Type = text_type; - m_NoShow = false; - // Set text tickness to a default value m_Thickness = Millimeter2iu( 0.15 ); - SetLayer( F_SilkS ); - // Set position and layer if there is already a parent module + // Set position and give a default layer if a valid parent footprint exists if( module && ( module->Type() == PCB_MODULE_T ) ) { m_Pos = module->GetPosition(); @@ -73,12 +70,9 @@ TEXTE_MODULE::TEXTE_MODULE( MODULE* parent, TEXT_TYPE text_type ) : SetLayer( B_SilkS ); m_Mirror = true; } - else - { - SetLayer( F_SilkS ); - m_Mirror = false; - } } + + SetDrawCoord(); } @@ -89,63 +83,44 @@ TEXTE_MODULE::~TEXTE_MODULE() void TEXTE_MODULE::Rotate( const wxPoint& aRotCentre, double aAngle ) { + // Used in footprint edition + // Note also in module editor, m_Pos0 = m_Pos RotatePoint( &m_Pos, aRotCentre, aAngle ); - - m_Orient += aAngle; - NORMALIZE_ANGLE_360( m_Orient ); - + SetOrientation( GetOrientation() + aAngle ); SetLocalCoord(); } -void TEXTE_MODULE::Flip(const wxPoint& aCentre ) -{ - m_Pos.y = aCentre.y - ( m_Pos.y - aCentre.y ); - SetLayer( FlipLayer( GetLayer() ) ); - m_Mirror = !m_Mirror; -} - - -void TEXTE_MODULE::FlipWithModule( int aOffset ) +void TEXTE_MODULE::Flip( const wxPoint& aCentre ) { // flipping the footprint is relative to the X axis - m_Pos.y = aOffset - (m_Pos.y - aOffset); + MIRROR( m_Pos.y, aCentre.y ); NEGATE_AND_NORMALIZE_ANGLE_POS( m_Orient ); - wxPoint tmp = GetPos0(); - tmp.y = -tmp.y; - SetPos0( tmp ); SetLayer( FlipLayer( GetLayer() ) ); m_Mirror = IsBackLayer( GetLayer() ); + SetLocalCoord(); } -void TEXTE_MODULE::MirrorTransformWithModule( int aOffset ) +void TEXTE_MODULE::Mirror( const wxPoint& aCentre, bool aMirrorAroundXAxis ) { // Used in modedit, to transform the footprint - // the mirror is relative to the Y axis + // the mirror is around the Y axis or X axis if aMirrorAroundXAxis = true // the position is mirrored, but the text itself is not mirrored - // Note also in module editor, m_Pos0 = m_Pos - m_Pos.x = aOffset - (m_Pos.x - aOffset); - m_Pos0 = m_Pos; + if( aMirrorAroundXAxis ) + MIRROR( m_Pos.x, aCentre.x ); + else + MIRROR( m_Pos.x, aCentre.x ); NEGATE_AND_NORMALIZE_ANGLE_POS( m_Orient ); + SetLocalCoord(); } -void TEXTE_MODULE::RotateTransformWithModule( const wxPoint& aOffset, double aAngle ) +void TEXTE_MODULE::Move( const wxPoint& aMoveVector ) { // Used in modedit, to transform the footprint - // Note also in module editor, m_Pos0 = m_Pos - RotatePoint( &m_Pos, aOffset, aAngle ); - m_Pos0 = m_Pos; - SetOrientation( GetOrientation() + aAngle ); -} - -void TEXTE_MODULE::MoveTransformWithModule( const wxPoint& aMoveVector ) -{ - // Used in modedit, to transform the footprint - // Note also in module editor, m_Pos0 = m_Pos m_Pos0 += aMoveVector; - m_Pos = m_Pos0; + SetDrawCoord();; } void TEXTE_MODULE::Copy( TEXTE_MODULE* source ) @@ -329,7 +304,7 @@ void TEXTE_MODULE::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE draw_mode, DrawGraphicText( panel->GetClipBox(), DC, pos, color, GetShownText(), orient, size, m_HJustify, m_VJustify, width, m_Italic, m_Bold ); - // Enable these line to draw the bounding box (debug tests purposes only) + // Enable these line to draw the bounding box (debug test purpose only) #if 0 { EDA_RECT BoundaryBox = GetBoundingBox(); @@ -528,9 +503,8 @@ wxString TEXTE_MODULE::GetShownText() const if( (m_Type != TEXT_is_DIVERS) || (wxString::npos == m_Text.find('%')) ) return m_Text; - wxString newbuf; - + wxString newbuf; const MODULE *module = static_cast( GetParent() ); for( wxString::const_iterator it = m_Text.begin(); diff --git a/pcbnew/class_text_mod.h b/pcbnew/class_text_mod.h index 16f263b7b4..e4e3bcabde 100644 --- a/pcbnew/class_text_mod.h +++ b/pcbnew/class_text_mod.h @@ -84,28 +84,21 @@ public: SetLocalCoord(); } - void Move( const wxPoint& aMoveVector ) - { - m_Pos += aMoveVector; - SetLocalCoord(); - } - - void Rotate( const wxPoint& aRotCentre, double aAngle ); - - void Flip( const wxPoint& aCentre ); - - /// Rotate text during module rotation transform, in footprint editor - void RotateTransformWithModule( const wxPoint& aOffset, double aAngle ); + /// Rotate text, in footprint editor + /// (for instance in footprint rotation transform) + void Rotate( const wxPoint& aOffset, double aAngle ); /// Flip entity during module flip - void FlipWithModule( int aOffset ); + void Flip( const wxPoint& aCentre ); - /// Mirror text during module mirroring transform, in footprint editor - /// the text itself is not mirrored, only position. - void MirrorTransformWithModule( int aOffset ); + /// Mirror text position in footprint edition + /// the text itself is not mirrored, and the layer not modified, + /// only position is mirrored. + /// (use Flip to change layer to its paired and mirror the text in fp editor). + void Mirror( const wxPoint& aCentre, bool aMirrorAroundXAxis ); - /// move text during module mirroring transform, in footprint editor - void MoveTransformWithModule( const wxPoint& aMoveVector ); + /// move text in move transform, in footprint editor + void Move( const wxPoint& aMoveVector ); /// @deprecated it seems (but the type is used to 'protect' // reference and value from deletion, and for identification)