400 lines
11 KiB
C++
400 lines
11 KiB
C++
/****************************************************
|
|
* class_module_transform_functions.cpp :
|
|
* functions of class MODULE to handle some geometric changes:
|
|
* move, rot ...
|
|
****************************************************/
|
|
|
|
#include "fctsys.h"
|
|
#include "wxstruct.h"
|
|
#include "common.h"
|
|
#include "trigo.h"
|
|
#include "pcbcommon.h"
|
|
|
|
#include "pcbnew.h"
|
|
#include "protos.h"
|
|
|
|
/*************************************/
|
|
int ChangeSideNumLayer( int oldlayer )
|
|
/*************************************/
|
|
|
|
/* Routine de recalcul du numero de couche lors des
|
|
* echanges cote cu/cmp pour les couches CU/CMP specialisees
|
|
* (cuivre, serigr., pate , soudure)
|
|
*/
|
|
{
|
|
int newlayer;
|
|
|
|
switch( oldlayer )
|
|
{
|
|
case COPPER_LAYER_N:
|
|
newlayer = CMP_N; break;
|
|
|
|
case CMP_N:
|
|
newlayer = COPPER_LAYER_N; break;
|
|
|
|
case SILKSCREEN_N_CU:
|
|
newlayer = SILKSCREEN_N_CMP; break;
|
|
|
|
case SILKSCREEN_N_CMP:
|
|
newlayer = SILKSCREEN_N_CU; break;
|
|
|
|
case ADHESIVE_N_CU:
|
|
newlayer = ADHESIVE_N_CMP; break;
|
|
|
|
case ADHESIVE_N_CMP:
|
|
newlayer = ADHESIVE_N_CU; break;
|
|
|
|
case SOLDERMASK_N_CU:
|
|
newlayer = SOLDERMASK_N_CMP; break;
|
|
|
|
case SOLDERMASK_N_CMP:
|
|
newlayer = SOLDERMASK_N_CU; break;
|
|
|
|
case SOLDERPASTE_N_CU:
|
|
newlayer = SOLDERPASTE_N_CMP; break;
|
|
|
|
case SOLDERPASTE_N_CMP:
|
|
newlayer = SOLDERPASTE_N_CU; break;
|
|
|
|
default:
|
|
newlayer = oldlayer;
|
|
}
|
|
|
|
return newlayer;
|
|
}
|
|
|
|
/*********************************************/
|
|
static int ChangeSideMaskLayer( int masque )
|
|
/*********************************************/
|
|
|
|
/* Routine de recalcul du masque-layer lors des
|
|
* echanges cote cu/cmp pour les couches CU/CMP specialisees
|
|
* (cuivre, serigr., pate , soudure)
|
|
*/
|
|
{
|
|
int newmasque;
|
|
|
|
newmasque = masque & ~(CUIVRE_LAYER | CMP_LAYER |
|
|
SILKSCREEN_LAYER_CU | SILKSCREEN_LAYER_CMP |
|
|
ADHESIVE_LAYER_CU | ADHESIVE_LAYER_CMP |
|
|
SOLDERMASK_LAYER_CU | SOLDERMASK_LAYER_CMP |
|
|
SOLDERPASTE_LAYER_CU | SOLDERPASTE_LAYER_CMP |
|
|
ADHESIVE_LAYER_CU | ADHESIVE_LAYER_CMP);
|
|
|
|
if( masque & CUIVRE_LAYER )
|
|
newmasque |= CMP_LAYER;
|
|
if( masque & CMP_LAYER )
|
|
newmasque |= CUIVRE_LAYER;
|
|
|
|
if( masque & SILKSCREEN_LAYER_CU )
|
|
newmasque |= SILKSCREEN_LAYER_CMP;
|
|
if( masque & SILKSCREEN_LAYER_CMP )
|
|
newmasque |= SILKSCREEN_LAYER_CU;
|
|
|
|
if( masque & ADHESIVE_LAYER_CU )
|
|
newmasque |= ADHESIVE_LAYER_CMP;
|
|
if( masque & ADHESIVE_LAYER_CMP )
|
|
newmasque |= ADHESIVE_LAYER_CU;
|
|
|
|
if( masque & SOLDERMASK_LAYER_CU )
|
|
newmasque |= SOLDERMASK_LAYER_CMP;
|
|
if( masque & SOLDERMASK_LAYER_CMP )
|
|
newmasque |= SOLDERMASK_LAYER_CU;
|
|
|
|
if( masque & SOLDERPASTE_LAYER_CU )
|
|
newmasque |= SOLDERPASTE_LAYER_CMP;
|
|
if( masque & SOLDERPASTE_LAYER_CMP )
|
|
newmasque |= SOLDERPASTE_LAYER_CU;
|
|
|
|
if( masque & ADHESIVE_LAYER_CU )
|
|
newmasque |= ADHESIVE_LAYER_CMP;
|
|
if( masque & ADHESIVE_LAYER_CMP )
|
|
newmasque |= ADHESIVE_LAYER_CU;
|
|
|
|
return newmasque;
|
|
}
|
|
|
|
|
|
/**
|
|
* Function Move (virtual)
|
|
* move this object.
|
|
* @param const wxPoint& aMoveVector - the move vector for this object.
|
|
*/
|
|
void MODULE::Move(const wxPoint& aMoveVector)
|
|
{
|
|
wxPoint newpos = m_Pos + aMoveVector;
|
|
SetPosition( newpos );
|
|
}
|
|
|
|
/**
|
|
* Function Rotate
|
|
* Rotate this object.
|
|
* @param const wxPoint& aRotCentre - the rotation point.
|
|
* @param aAngle - the rotation angle in 0.1 degree.
|
|
*/
|
|
void MODULE::Rotate(const wxPoint& aRotCentre, int aAngle)
|
|
{
|
|
wxPoint newpos = m_Pos;
|
|
RotatePoint( &newpos, aRotCentre, aAngle );
|
|
SetPosition( newpos );
|
|
SetOrientation( m_Orient + aAngle );
|
|
}
|
|
|
|
/**
|
|
* Function Flip
|
|
* Flip this object, i.e. change the board side for this object
|
|
* @param const wxPoint& aCentre - the rotation point.
|
|
*/
|
|
void MODULE::Flip(const wxPoint& aCentre )
|
|
{
|
|
D_PAD* pt_pad;
|
|
TEXTE_MODULE* pt_texte;
|
|
EDGE_MODULE* pt_edgmod;
|
|
EDA_BaseStruct* PtStruct;
|
|
|
|
// Move module to its final position:
|
|
wxPoint finalPos = m_Pos;
|
|
finalPos.y = aCentre.y - (finalPos.y - aCentre.y); /// Mirror the Y position
|
|
SetPosition(finalPos);
|
|
|
|
/* Flip layer */
|
|
SetLayer( ChangeSideNumLayer( GetLayer() ) );
|
|
|
|
/* Inversion miroir de l'orientation */
|
|
NEGATE( m_Orient );
|
|
NORMALIZE_ANGLE_POS( m_Orient );
|
|
|
|
/* Inversion miroir + layers des pastilles */
|
|
pt_pad = m_Pads;
|
|
for( ; pt_pad != NULL; pt_pad = pt_pad->Next() )
|
|
{
|
|
pt_pad->m_Pos.y -= m_Pos.y;
|
|
pt_pad->m_Pos.y = -pt_pad->m_Pos.y;
|
|
pt_pad->m_Pos.y += m_Pos.y;
|
|
NEGATE(pt_pad->m_Pos0.y);
|
|
NEGATE(pt_pad->m_Offset.y);
|
|
NEGATE(pt_pad->m_DeltaSize.y);
|
|
NEGATE_AND_NORMALIZE_ANGLE_POS( pt_pad->m_Orient );
|
|
|
|
/* flip pads layers*/
|
|
pt_pad->m_Masque_Layer = ChangeSideMaskLayer( pt_pad->m_Masque_Layer );
|
|
}
|
|
|
|
/* Inversion miroir de la Reference et mise en miroir : */
|
|
pt_texte = m_Reference;
|
|
pt_texte->m_Pos.y -= m_Pos.y;
|
|
pt_texte->m_Pos.y = -pt_texte->m_Pos.y;
|
|
pt_texte->m_Pos.y += m_Pos.y;
|
|
NEGATE(pt_texte->m_Pos0.y);
|
|
pt_texte->m_Mirror = false;
|
|
NEGATE_AND_NORMALIZE_ANGLE_POS( pt_texte->m_Orient );
|
|
pt_texte->SetLayer( GetLayer() );
|
|
pt_texte->SetLayer( ChangeSideNumLayer( pt_texte->GetLayer() ) );
|
|
|
|
if( GetLayer() == COPPER_LAYER_N )
|
|
pt_texte->SetLayer( SILKSCREEN_N_CU );
|
|
|
|
if( GetLayer() == CMP_N )
|
|
pt_texte->SetLayer( SILKSCREEN_N_CMP );
|
|
|
|
if( (GetLayer() == SILKSCREEN_N_CU)
|
|
|| (GetLayer() == ADHESIVE_N_CU) || (GetLayer() == COPPER_LAYER_N) )
|
|
pt_texte->m_Mirror = true;
|
|
|
|
/* Inversion miroir de la Valeur et mise en miroir : */
|
|
pt_texte = m_Value;
|
|
pt_texte->m_Pos.y -= m_Pos.y;
|
|
NEGATE(pt_texte->m_Pos.y);
|
|
pt_texte->m_Pos.y += m_Pos.y;
|
|
NEGATE(pt_texte->m_Pos0.y);
|
|
pt_texte->m_Mirror = false;
|
|
NEGATE_AND_NORMALIZE_ANGLE_POS( pt_texte->m_Orient );
|
|
pt_texte->SetLayer( GetLayer() );
|
|
pt_texte->SetLayer( ChangeSideNumLayer( pt_texte->GetLayer() ) );
|
|
|
|
if( GetLayer() == COPPER_LAYER_N )
|
|
pt_texte->SetLayer( SILKSCREEN_N_CU );
|
|
|
|
if( GetLayer() == CMP_N )
|
|
pt_texte->SetLayer( SILKSCREEN_N_CMP );
|
|
|
|
if( (GetLayer() == SILKSCREEN_N_CU)
|
|
|| (GetLayer() == ADHESIVE_N_CU) || (GetLayer() == COPPER_LAYER_N) )
|
|
pt_texte->m_Mirror = true;
|
|
|
|
/* Inversion miroir des dessins de l'empreinte : */
|
|
PtStruct = m_Drawings;
|
|
for( ; PtStruct != NULL; PtStruct = PtStruct->Next() )
|
|
{
|
|
switch( PtStruct->Type() )
|
|
{
|
|
case TYPE_EDGE_MODULE:
|
|
pt_edgmod = (EDGE_MODULE*) PtStruct;
|
|
pt_edgmod->m_Start.y -= m_Pos.y;
|
|
pt_edgmod->m_Start.y = -pt_edgmod->m_Start.y;
|
|
pt_edgmod->m_Start.y += m_Pos.y;
|
|
pt_edgmod->m_End.y -= m_Pos.y;
|
|
pt_edgmod->m_End.y = -pt_edgmod->m_End.y;
|
|
pt_edgmod->m_End.y += m_Pos.y;
|
|
/* inversion des coords locales */
|
|
NEGATE(pt_edgmod->m_Start0.y);
|
|
NEGATE(pt_edgmod->m_End0.y);
|
|
if( pt_edgmod->m_Shape == S_ARC )
|
|
{
|
|
NEGATE(pt_edgmod->m_Angle);
|
|
}
|
|
|
|
pt_edgmod->SetLayer( ChangeSideNumLayer( pt_edgmod->GetLayer() ) );
|
|
break;
|
|
|
|
case TYPE_TEXTE_MODULE:
|
|
/* Inversion miroir de la position et mise en miroir : */
|
|
pt_texte = (TEXTE_MODULE*) PtStruct;
|
|
pt_texte->m_Pos.y -= m_Pos.y;
|
|
pt_texte->m_Pos.y = -pt_texte->m_Pos.y;
|
|
pt_texte->m_Pos.y += m_Pos.y;
|
|
NEGATE(pt_texte->m_Pos0.y);
|
|
pt_texte->m_Mirror = false;
|
|
NEGATE_AND_NORMALIZE_ANGLE_POS( pt_texte->m_Orient );
|
|
|
|
pt_texte->SetLayer( GetLayer() );
|
|
pt_texte->SetLayer( ChangeSideNumLayer( pt_texte->GetLayer() ) );
|
|
|
|
if( GetLayer() == COPPER_LAYER_N )
|
|
pt_texte->SetLayer( SILKSCREEN_N_CU );
|
|
|
|
if( GetLayer() == CMP_N )
|
|
pt_texte->SetLayer( SILKSCREEN_N_CMP );
|
|
|
|
if( GetLayer() == SILKSCREEN_N_CU
|
|
|| GetLayer() == ADHESIVE_N_CU
|
|
|| GetLayer() == COPPER_LAYER_N )
|
|
{
|
|
pt_texte->m_Mirror = true;
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
wxMessageBox( wxT( "MODULE::Flip() error: Unknown Draw Type" ) );
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* calcul du rectangle d'encadrement */
|
|
Set_Rectangle_Encadrement();
|
|
}
|
|
|
|
|
|
/*************************************************/
|
|
void MODULE::SetPosition( const wxPoint& newpos )
|
|
/*************************************************/
|
|
|
|
// replace le module en position newpos
|
|
{
|
|
int deltaX = newpos.x - m_Pos.x;
|
|
int deltaY = newpos.y - m_Pos.y;
|
|
|
|
/* deplacement de l'ancre */
|
|
m_Pos.x += deltaX;
|
|
m_Pos.y += deltaY;
|
|
|
|
/* deplacement de la reference */
|
|
m_Reference->m_Pos.x += deltaX;
|
|
m_Reference->m_Pos.y += deltaY;
|
|
|
|
/* deplacement de la Valeur */
|
|
m_Value->m_Pos.x += deltaX;
|
|
m_Value->m_Pos.y += deltaY;
|
|
|
|
/* deplacement des pastilles */
|
|
for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
|
|
{
|
|
pad->m_Pos.x += deltaX;
|
|
pad->m_Pos.y += deltaY;
|
|
}
|
|
|
|
/* deplacement des dessins de l'empreinte : */
|
|
EDA_BaseStruct* PtStruct = m_Drawings;
|
|
for( ; PtStruct != NULL; PtStruct = PtStruct->Next() )
|
|
{
|
|
switch( PtStruct->Type() )
|
|
{
|
|
case TYPE_EDGE_MODULE:
|
|
{
|
|
EDGE_MODULE* pt_edgmod = (EDGE_MODULE*) PtStruct;
|
|
pt_edgmod->SetDrawCoord();
|
|
break;
|
|
}
|
|
|
|
case TYPE_TEXTE_MODULE:
|
|
{
|
|
TEXTE_MODULE* pt_texte = (TEXTE_MODULE*) PtStruct;
|
|
pt_texte->m_Pos.x += deltaX;
|
|
pt_texte->m_Pos.y += deltaY;
|
|
break;
|
|
}
|
|
|
|
default:
|
|
wxMessageBox( wxT( "Type Draw Indefini" ) ); break;
|
|
}
|
|
}
|
|
|
|
Set_Rectangle_Encadrement();
|
|
}
|
|
|
|
|
|
/*********************************************/
|
|
void MODULE::SetOrientation( int newangle )
|
|
/*********************************************/
|
|
|
|
/* Tourne de newangle (en 0.1 degres) le module
|
|
*/
|
|
{
|
|
int px, py;
|
|
|
|
newangle -= m_Orient; // = delta de rotation
|
|
|
|
m_Orient += newangle;
|
|
NORMALIZE_ANGLE_POS( m_Orient );
|
|
|
|
/* deplacement et rotation des pastilles */
|
|
for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
|
|
{
|
|
px = pad->m_Pos0.x;
|
|
py = pad->m_Pos0.y;
|
|
|
|
pad->m_Orient += newangle; /* change m_Orientation */
|
|
NORMALIZE_ANGLE_POS( pad->m_Orient );
|
|
|
|
RotatePoint( &px, &py, (int) m_Orient );
|
|
pad->m_Pos.x = m_Pos.x + px;
|
|
pad->m_Pos.y = m_Pos.y + py;
|
|
}
|
|
|
|
/* mise a jour de la reference et de la valeur*/
|
|
m_Reference->SetDrawCoord();
|
|
m_Value->SetDrawCoord();
|
|
|
|
/* deplacement des contours et textes de l'empreinte : */
|
|
for( BOARD_ITEM* item = m_Drawings; item; item = item->Next() )
|
|
{
|
|
if( item->Type() == TYPE_EDGE_MODULE )
|
|
{
|
|
EDGE_MODULE* pt_edgmod = (EDGE_MODULE*) item;
|
|
pt_edgmod->SetDrawCoord();
|
|
}
|
|
|
|
if( item->Type() == TYPE_TEXTE_MODULE )
|
|
{
|
|
/* deplacement des inscriptions : */
|
|
TEXTE_MODULE* pt_texte = (TEXTE_MODULE*) item;
|
|
pt_texte->SetDrawCoord();
|
|
}
|
|
}
|
|
|
|
/* Recalcul du rectangle d'encadrement */
|
|
Set_Rectangle_Encadrement();
|
|
}
|
|
|