Eeschem: fix bug when moving fields in schematic: incorrect field move for rotated+mirrored components
(added InverseTransform( ) in TRANSFORM class)
This commit is contained in:
parent
f43f7af5fe
commit
42b9e0e676
|
@ -653,7 +653,7 @@ void MODULE::Draw3D( Pcb3D_GLCanvas* glcanvas )
|
||||||
pad->Draw3D( glcanvas );
|
pad->Draw3D( glcanvas );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draw module shape: 3D shape if exists (or module edge if not exists) */
|
/* Draw module shape: 3D shape if exists (or module outlines if not exists) */
|
||||||
S3D_MASTER* Struct3D = m_3D_Drawings;
|
S3D_MASTER* Struct3D = m_3D_Drawings;
|
||||||
bool As3dShape = FALSE;
|
bool As3dShape = FALSE;
|
||||||
if( g_Parm_3D_Visu.m_Draw3DModule )
|
if( g_Parm_3D_Visu.m_Draw3DModule )
|
||||||
|
|
|
@ -46,16 +46,9 @@ void SCH_EDIT_FRAME::StartMoveCmpField( SCH_FIELD* aField, wxDC* DC )
|
||||||
|
|
||||||
pos = comp->m_Pos;
|
pos = comp->m_Pos;
|
||||||
|
|
||||||
/* Positions are computed by the transpose matrix. Rotating mirror. */
|
/* Positions are computed by the rotation/mirror transform. */
|
||||||
newpos = aField->m_Pos - pos;
|
newpos = aField->m_Pos - pos;
|
||||||
|
|
||||||
// Empirically this is necessary. The Y coordinate appears to be inverted
|
|
||||||
// under some circumstances, but that inversion is not preserved by all
|
|
||||||
// combinations of mirroring and rotation. The following clause is true
|
|
||||||
// when the number of rotations and the number of mirrorings are both odd.
|
|
||||||
if( comp->GetTransform().x2 * comp->GetTransform().y1 < 0 )
|
|
||||||
NEGATE( newpos.y );
|
|
||||||
|
|
||||||
newpos = comp->GetTransform().TransformCoordinate( newpos ) + pos;
|
newpos = comp->GetTransform().TransformCoordinate( newpos ) + pos;
|
||||||
|
|
||||||
DrawPanel->CursorOff( DC );
|
DrawPanel->CursorOff( DC );
|
||||||
|
@ -206,10 +199,14 @@ static void MoveCmpField( WinEDA_DrawPanel* panel, wxDC* DC, bool erase )
|
||||||
|
|
||||||
pos = ( (SCH_COMPONENT*) currentField->GetParent() )->m_Pos;
|
pos = ( (SCH_COMPONENT*) currentField->GetParent() )->m_Pos;
|
||||||
|
|
||||||
/* Positions are calculated by the transpose matrix, Rotating mirror. */
|
// Actual positions are calculated by the rotation/mirror transform
|
||||||
|
// But here we want the relative position of the moved field
|
||||||
|
// and we know the actual position.
|
||||||
|
// So we are using the inverse rotation/mirror transform.
|
||||||
wxPoint pt( panel->GetScreen()->m_Curseur - pos );
|
wxPoint pt( panel->GetScreen()->m_Curseur - pos );
|
||||||
|
|
||||||
currentField->m_Pos = pos + component->GetTransform().TransformCoordinate( pt );
|
TRANSFORM itrsfm = component->GetTransform().InverseTransform();
|
||||||
|
currentField->m_Pos = pos + itrsfm.TransformCoordinate( pt );
|
||||||
|
|
||||||
currentField->Draw( panel, DC, wxPoint( 0, 0 ), g_XorMode );
|
currentField->Draw( panel, DC, wxPoint( 0, 0 ), g_XorMode );
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,30 @@ wxPoint TRANSFORM::TransformCoordinate( const wxPoint& aPoint ) const
|
||||||
( x2 * aPoint.x ) + ( y2 * aPoint.y ) );
|
( x2 * aPoint.x ) + ( y2 * aPoint.y ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Calculate the Inverse mirror/rotation transform.
|
||||||
|
*/
|
||||||
|
TRANSFORM TRANSFORM::InverseTransform( ) const
|
||||||
|
{
|
||||||
|
int invx1;
|
||||||
|
int invx2;
|
||||||
|
int invy1;
|
||||||
|
int invy2;
|
||||||
|
|
||||||
|
/* Calculates the inverse matrix coeffs:
|
||||||
|
* for a matrix m{x1, x2, y1, y2}
|
||||||
|
* the inverse matrix is 1/(x1*y2 -x2*y1) m{y2,-x2,-y1,x1)
|
||||||
|
*/
|
||||||
|
int det = x1*y2 -x2*y1; // Is never null, because the inverse matrix exists
|
||||||
|
invx1 = y2/det;
|
||||||
|
invx2 = -x2/det;
|
||||||
|
invy1 = -y1/det;
|
||||||
|
invy2 = x1/det;
|
||||||
|
|
||||||
|
TRANSFORM invtransform( invx1, invy1, invx2, invy2 );
|
||||||
|
return invtransform;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool TRANSFORM::MapAngles( int* aAngle1, int* aAngle2 ) const
|
bool TRANSFORM::MapAngles( int* aAngle1, int* aAngle2 ) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -59,13 +59,24 @@ public:
|
||||||
bool operator!=( const TRANSFORM& aTransform ) const { return !( *this == aTransform ); }
|
bool operator!=( const TRANSFORM& aTransform ) const { return !( *this == aTransform ); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate new coordinate according to the transform.
|
* Calculate new coordinate according to the mirror/rotation transform.
|
||||||
*
|
* Useful to calculate actual coordinates of a point
|
||||||
|
* from coordinates relative to a component
|
||||||
|
* which are given for a non rotated, non mirrored item
|
||||||
* @param aPoint = The position to transform
|
* @param aPoint = The position to transform
|
||||||
* @return The transformed coordinate.
|
* @return The transformed coordinate.
|
||||||
*/
|
*/
|
||||||
wxPoint TransformCoordinate( const wxPoint& aPoint ) const;
|
wxPoint TransformCoordinate( const wxPoint& aPoint ) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the Inverse mirror/rotation transform.
|
||||||
|
* Useful to calculate coordinates relative to a component
|
||||||
|
* which must be for a non rotated, non mirrored item
|
||||||
|
* from the actual coordinate.
|
||||||
|
* @return The inverse transform.
|
||||||
|
*/
|
||||||
|
TRANSFORM InverseTransform( ) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate new angles according to the transform.
|
* Calculate new angles according to the transform.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1091,9 +1091,12 @@ static void export_vrml_module( BOARD* aPcb, MODULE* aModule,
|
||||||
int offsety = wxRound( vrmlm->m_MatPosition.y * UNITS_3D_TO_PCB_UNITS );
|
int offsety = wxRound( vrmlm->m_MatPosition.y * UNITS_3D_TO_PCB_UNITS );
|
||||||
double offsetz = vrmlm->m_MatPosition.z * UNITS_3D_TO_PCB_UNITS;
|
double offsetz = vrmlm->m_MatPosition.z * UNITS_3D_TO_PCB_UNITS;
|
||||||
|
|
||||||
RotatePoint(&offsetx, &offsety, aModule->m_Orient);
|
|
||||||
if ( isFlipped )
|
if ( isFlipped )
|
||||||
NEGATE(offsetz);
|
NEGATE(offsetz);
|
||||||
|
else // In normal mode, Y axis is reversed in Pcbnew.
|
||||||
|
NEGATE(offsety);
|
||||||
|
|
||||||
|
RotatePoint(&offsetx, &offsety, aModule->m_Orient);
|
||||||
|
|
||||||
fprintf( aOutputFile, " translation %g %g %g\n",
|
fprintf( aOutputFile, " translation %g %g %g\n",
|
||||||
(double) (offsetx + aModule->m_Pos.x),
|
(double) (offsetx + aModule->m_Pos.x),
|
||||||
|
|
|
@ -143,13 +143,24 @@ void BOARD_PRINTOUT_CONTROLER::DrawPage()
|
||||||
|
|
||||||
WinEDA_BasePcbFrame* pcbframe = (WinEDA_BasePcbFrame*) m_Parent;
|
WinEDA_BasePcbFrame* pcbframe = (WinEDA_BasePcbFrame*) m_Parent;
|
||||||
pcbframe->GetBoard()->ComputeBoundaryBox();
|
pcbframe->GetBoard()->ComputeBoundaryBox();
|
||||||
|
EDA_Rect brd_BBox = pcbframe->GetBoard()->m_BoundaryBox;
|
||||||
|
// In module editor, the module is located at 0,0 but for printing
|
||||||
|
// it is moved to SheetSize.x/2, SheetSize.y/2.
|
||||||
|
// So the equivalent board must be moved:
|
||||||
|
if( m_Parent->m_Ident == MODULE_EDITOR_FRAME )
|
||||||
|
{
|
||||||
|
wxPoint mv_offset;
|
||||||
|
mv_offset.x = SheetSize.x / 2;
|
||||||
|
mv_offset.y = SheetSize.y / 2;
|
||||||
|
brd_BBox.Move( mv_offset );
|
||||||
|
}
|
||||||
/* Compute the PCB size in internal units*/
|
/* Compute the PCB size in internal units*/
|
||||||
userscale = m_PrintParams.m_PrintScale;
|
userscale = m_PrintParams.m_PrintScale;
|
||||||
if( userscale == 0 ) // fit in page
|
if( userscale == 0 ) // fit in page
|
||||||
{
|
{
|
||||||
int extra_margin = 4000*2; // Margin = 4000 units pcb = 0.4 inch
|
int extra_margin = 4000*2; // Margin = 4000 units pcb = 0.4 inch
|
||||||
SheetSize.x = pcbframe->GetBoard()->m_BoundaryBox.GetWidth() + extra_margin;
|
SheetSize.x = brd_BBox.GetWidth() + extra_margin;
|
||||||
SheetSize.y = pcbframe->GetBoard()->m_BoundaryBox.GetHeight() + extra_margin;
|
SheetSize.y = brd_BBox.GetHeight() + extra_margin;
|
||||||
userscale = 0.99;
|
userscale = 0.99;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,7 +168,7 @@ void BOARD_PRINTOUT_CONTROLER::DrawPage()
|
||||||
if( (m_PrintParams.m_PrintScale > 1.0) // scale > 1 -> Recadrage
|
if( (m_PrintParams.m_PrintScale > 1.0) // scale > 1 -> Recadrage
|
||||||
|| (m_PrintParams.m_PrintScale == 0) ) // fit in page
|
|| (m_PrintParams.m_PrintScale == 0) ) // fit in page
|
||||||
{
|
{
|
||||||
DrawOffset += pcbframe->GetBoard()->m_BoundaryBox.Centre();
|
DrawOffset += brd_BBox.Centre();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( m_PrintParams.m_PageSetupData )
|
if( m_PrintParams.m_PageSetupData )
|
||||||
|
@ -266,7 +277,7 @@ void BOARD_PRINTOUT_CONTROLER::DrawPage()
|
||||||
* for scales > 1, the DrawOffset was already computed to have the board centre
|
* for scales > 1, the DrawOffset was already computed to have the board centre
|
||||||
* to the middle of the page.
|
* to the middle of the page.
|
||||||
*/
|
*/
|
||||||
wxPoint pcb_centre = pcbframe->GetBoard()->m_BoundaryBox.Centre();
|
wxPoint pcb_centre = brd_BBox.Centre();
|
||||||
if( userscale <= 1.0 )
|
if( userscale <= 1.0 )
|
||||||
DrawOffset.y += pcb_centre.y - (ysize / 2);
|
DrawOffset.y += pcb_centre.y - (ysize / 2);
|
||||||
#ifdef USE_WX_ZOOM
|
#ifdef USE_WX_ZOOM
|
||||||
|
|
Loading…
Reference in New Issue