Commit 97003fef authored by Marco Mattila's avatar Marco Mattila

Change board bounding box calculation to include all board items by default in...

Change board bounding box calculation to include all board items by default in pcbnew. Add a parameter to look for board edges only.
parent e07643f0
......@@ -121,7 +121,7 @@ GLuint Pcb3D_GLCanvas::CreateDrawGL_List()
m_gllist = glGenLists( 1 );
pcb->ComputeBoundaryBox();
pcb->ComputeBoundingBox();
g_Parm_3D_Visu.m_BoardSettings = pcb->GetBoardDesignSettings();
g_Parm_3D_Visu.m_BoardSize = pcb->m_BoundaryBox.GetSize();
g_Parm_3D_Visu.m_BoardPos = pcb->m_BoundaryBox.Centre();
......
......@@ -107,7 +107,7 @@ static bool WriteGeneralDescrPcb( BOARD* Pcb, FILE* File )
fprintf( File, "LayerCount %d\n", NbLayers );
/* Compute and print the board bounding box */
Pcb->ComputeBoundaryBox();
Pcb->ComputeBoundingBox();
fprintf( File, "Di %d %d %d %d\n",
Pcb->m_BoundaryBox.GetX(), Pcb->m_BoundaryBox.GetY(),
Pcb->m_BoundaryBox.GetRight(),
......
......@@ -1108,7 +1108,6 @@ public:
bool include_fixe );
void FixeModule( MODULE* Module, bool Fixe );
void AutoMoveModulesOnPcb( bool PlaceModulesHorsPcb );
bool SetBoardBoundaryBoxFromEdgesOnly();
void AutoPlaceModule( MODULE* Module, int place_mode, wxDC* DC );
int RecherchePlacementModule( MODULE* Module, wxDC* DC );
void GenModuleOnBoard( MODULE* Module );
......
......@@ -186,7 +186,7 @@ void WinEDA_PcbFrame::AutoMoveModulesOnPcb( bool PlaceModulesHorsPcb )
if( !IsOK( this, _( "Move modules?" ) ) )
return;
edgesExists = SetBoardBoundaryBoxFromEdgesOnly();
edgesExists = GetBoard()->ComputeBoundingBox( true );
if( PlaceModulesHorsPcb && !edgesExists )
{
......
......@@ -382,7 +382,7 @@ int WinEDA_PcbFrame::GenPlaceBoard()
Board.UnInitBoard();
if( !SetBoardBoundaryBoxFromEdgesOnly() )
if( !GetBoard()->ComputeBoundingBox( true ) )
{
DisplayError( this, _( "No PCB edge found, unknown board size!" ) );
return 0;
......@@ -1086,73 +1086,6 @@ static MODULE* PickModule( WinEDA_PcbFrame* pcbframe, wxDC* DC )
}
/*
* Determine the rectangle of the pcb, according to the contours
* layer (EDGE) only
* Output:
* GetBoard()->m_BoundaryBox updated
* Returns FALSE if no contour
*/
bool WinEDA_PcbFrame::SetBoardBoundaryBoxFromEdgesOnly()
{
int rayon, cx, cy, d;
int xmax, ymax;
BOARD_ITEM* PtStruct;
DRAWSEGMENT* ptr;
bool succes = FALSE;
if( GetBoard() == NULL )
return FALSE;
GetBoard()->m_BoundaryBox.m_Pos.x = GetBoard()->m_BoundaryBox.m_Pos.y =
0x7FFFFFFFl;
xmax = ymax = -0x7FFFFFFFl;
PtStruct = GetBoard()->m_Drawings;
for( ; PtStruct != NULL; PtStruct = PtStruct->Next() )
{
if( PtStruct->Type() != TYPE_DRAWSEGMENT )
continue;
succes = TRUE;
ptr = (DRAWSEGMENT*) PtStruct;
d = (ptr->m_Width / 2) + 1;
if( ptr->m_Shape == S_CIRCLE )
{
cx = ptr->m_Start.x; cy = ptr->m_Start.y;
rayon =
(int) hypot( (double) ( ptr->m_End.x - cx ),
(double) ( ptr->m_End.y - cy ) );
rayon += d;
GetBoard()->m_BoundaryBox.m_Pos.x = MIN(
GetBoard()->m_BoundaryBox.m_Pos.x, cx - rayon );
GetBoard()->m_BoundaryBox.m_Pos.y = MIN(
GetBoard()->m_BoundaryBox.m_Pos.y, cy - rayon );
xmax = MAX( xmax, cx + rayon );
ymax = MAX( ymax, cy + rayon );
}
else
{
cx = MIN( ptr->m_Start.x, ptr->m_End.x );
cy = MIN( ptr->m_Start.y, ptr->m_End.y );
GetBoard()->m_BoundaryBox.m_Pos.x = MIN(
GetBoard()->m_BoundaryBox.m_Pos.x, cx - d );
GetBoard()->m_BoundaryBox.m_Pos.y = MIN(
GetBoard()->m_BoundaryBox.m_Pos.y, cy - d );
cx = MAX( ptr->m_Start.x, ptr->m_End.x );
cy = MAX( ptr->m_Start.y, ptr->m_End.y );
xmax = MAX( xmax, cx + d );
ymax = MAX( ymax, cy + d );
}
}
GetBoard()->m_BoundaryBox.SetWidth(
xmax - GetBoard()->m_BoundaryBox.m_Pos.x );
GetBoard()->m_BoundaryBox.SetHeight(
ymax - GetBoard()->m_BoundaryBox.m_Pos.y );
return succes;
}
/********************************************/
int Propagation( WinEDA_PcbFrame* frame )
/********************************************/
......
......@@ -110,7 +110,7 @@ int WinEDA_BasePcbFrame::BestZoom( void )
if( m_Pcb == NULL )
return 32 * GetScreen()->m_ZoomScalar;
m_Pcb->ComputeBoundaryBox();
m_Pcb->ComputeBoundingBox();
dx = m_Pcb->m_BoundaryBox.GetWidth();
dy = m_Pcb->m_BoundaryBox.GetHeight();
......
......@@ -36,7 +36,7 @@ bool ComputeMatriceSize( WinEDA_BasePcbFrame* frame, int g_GridRoutingSize )
{
BOARD* pcb = frame->GetBoard();
pcb->ComputeBoundaryBox();
pcb->ComputeBoundingBox();
/* The boundary box must have its start point on routing grid: */
pcb->m_BoundaryBox.m_Pos.x -= pcb->m_BoundaryBox.m_Pos.x % g_GridRoutingSize;
......
/*******************************************/
/* class_board.cpp - BOARD class functions */
/*******************************************/
#include <limits.h>
#include "fctsys.h"
#include "common.h"
......@@ -741,99 +742,152 @@ unsigned BOARD::GetNodesCount()
}
/**
* Function ComputeBoundaryBox
* Calculate the bounding box of the board
* This box contains pcb edges, pads , vias and tracks
* Update m_PcbBox member
*
* @return 0 for an empty board (no items), else 1
*/
bool BOARD::ComputeBoundaryBox()
bool BOARD::ComputeBoundingBox( bool aBoardEdgesOnly )
{
int rayon, cx, cy, d, xmin, ymin, xmax, ymax;
bool hasItems = FALSE;
EDA_ITEM* PtStruct;
DRAWSEGMENT* ptr;
int rayon, cx, cy, d, xmin, ymin, xmax, ymax;
bool hasItems = false;
xmin = ymin = 0x7FFFFFFFl;
xmax = ymax = -0x7FFFFFFFl;
xmin = ymin = INT_MAX;
xmax = ymax = INT_MIN;
/* Analyze PCB edges*/
PtStruct = m_Drawings;
for( ; PtStruct != NULL; PtStruct = PtStruct->Next() )
// Check segments, dimensions, texts, and fiducials
for( EDA_ITEM* PtStruct = m_Drawings; PtStruct != NULL; PtStruct = PtStruct->Next() )
{
if( PtStruct->Type() != TYPE_DRAWSEGMENT )
continue;
switch( PtStruct->Type() )
{
case TYPE_DRAWSEGMENT:
{
DRAWSEGMENT* ptr;
ptr = (DRAWSEGMENT*) PtStruct;
d = (ptr->m_Width / 2) + 1;
ptr = (DRAWSEGMENT*) PtStruct;
d = (ptr->m_Width / 2) + 1;
if( aBoardEdgesOnly && ptr->GetLayer() != EDGE_N )
break;
if( ptr->m_Shape == S_CIRCLE )
if( ptr->m_Shape == S_CIRCLE )
{
cx = ptr->m_Start.x; cy = ptr->m_Start.y;
rayon = (int) hypot( (double) ( ptr->m_End.x - cx ),
(double) ( ptr->m_End.y - cy ) );
rayon += d;
xmin = MIN( xmin, cx - rayon );
ymin = MIN( ymin, cy - rayon );
xmax = MAX( xmax, cx + rayon );
ymax = MAX( ymax, cy + rayon );
hasItems = true;
}
else
{
cx = MIN( ptr->m_Start.x, ptr->m_End.x );
cy = MIN( ptr->m_Start.y, ptr->m_End.y );
xmin = MIN( xmin, cx - d );
ymin = MIN( ymin, cy - d );
cx = MAX( ptr->m_Start.x, ptr->m_End.x );
cy = MAX( ptr->m_Start.y, ptr->m_End.y );
xmax = MAX( xmax, cx + d );
ymax = MAX( ymax, cy + d );
hasItems = true;
}
break;
}
case TYPE_DIMENSION:
{
cx = ptr->m_Start.x; cy = ptr->m_Start.y;
rayon = (int) hypot( (double) ( ptr->m_End.x - cx ),
(double) ( ptr->m_End.y - cy ) );
rayon += d;
xmin = MIN( xmin, cx - rayon );
ymin = MIN( ymin, cy - rayon );
xmax = MAX( xmax, cx + rayon );
ymax = MAX( ymax, cy + rayon );
hasItems = TRUE;
if( aBoardEdgesOnly )
break;
EDA_Rect rect = ((DIMENSION*) PtStruct)->GetBoundingBox();
xmin = MIN( xmin, rect.GetX() );
ymin = MIN( ymin, rect.GetY() );
xmax = MAX( xmax, rect.GetRight() );
ymax = MAX( ymax, rect.GetBottom() );
hasItems = true;
break;
}
else
case TYPE_TEXTE:
{
if( aBoardEdgesOnly )
break;
EDA_Rect rect = ((TEXTE_PCB*) PtStruct)->GetTextBox( -1 );
xmin = MIN( xmin, rect.GetX() );
ymin = MIN( ymin, rect.GetY() );
xmax = MAX( xmax, rect.GetRight() );
ymax = MAX( ymax, rect.GetBottom() );
hasItems = true;
break;
}
case TYPE_MIRE:
{
cx = MIN( ptr->m_Start.x, ptr->m_End.x );
cy = MIN( ptr->m_Start.y, ptr->m_End.y );
if( aBoardEdgesOnly )
break;
EDA_Rect rect = ((DIMENSION*) PtStruct)->GetBoundingBox();
xmin = MIN( xmin, rect.GetX() );
ymin = MIN( ymin, rect.GetY() );
xmax = MAX( xmax, rect.GetRight() );
ymax = MAX( ymax, rect.GetBottom() );
hasItems = true;
break;
}
default:
break;
}
}
if( !aBoardEdgesOnly )
{
// Check modules
for( MODULE* module = m_Modules; module; module = module->Next() )
{
EDA_Rect bBox = module->GetBoundingBox();
xmin = MIN( xmin, bBox.GetX() );
ymin = MIN( ymin, bBox.GetY() );
xmax = MAX( xmax, bBox.GetRight() );
ymax = MAX( ymax, bBox.GetBottom() );
hasItems = true;
}
// Check tracks
for( TRACK* track = m_Track; track; track = track->Next() )
{
d = ( track->m_Width / 2 ) + 1;
cx = MIN( track->m_Start.x, track->m_End.x );
cy = MIN( track->m_Start.y, track->m_End.y );
xmin = MIN( xmin, cx - d );
ymin = MIN( ymin, cy - d );
cx = MAX( ptr->m_Start.x, ptr->m_End.x );
cy = MAX( ptr->m_Start.y, ptr->m_End.y );
cx = MAX( track->m_Start.x, track->m_End.x );
cy = MAX( track->m_Start.y, track->m_End.y );
xmax = MAX( xmax, cx + d );
ymax = MAX( ymax, cy + d );
hasItems = TRUE;
hasItems = true;
}
}
/* Analyze footprints */
for( MODULE* module = m_Modules; module; module = module->Next() )
{
hasItems = TRUE;
EDA_Rect box = module->GetBoundingBox();
xmin = MIN( xmin, box.GetX() );
ymin = MIN( ymin, box.GetY() );
xmax = MAX( xmax, box.GetRight() );
ymax = MAX( ymax, box.GetBottom() );
}
/* Analize track and zones */
for( TRACK* track = m_Track; track; track = track->Next() )
{
d = ( track->m_Width / 2 ) + 1;
cx = MIN( track->m_Start.x, track->m_End.x );
cy = MIN( track->m_Start.y, track->m_End.y );
xmin = MIN( xmin, cx - d );
ymin = MIN( ymin, cy - d );
cx = MAX( track->m_Start.x, track->m_End.x );
cy = MAX( track->m_Start.y, track->m_End.y );
xmax = MAX( xmax, cx + d );
ymax = MAX( ymax, cy + d );
hasItems = TRUE;
}
// Check segment zones
for( TRACK* track = m_Zone; track; track = track->Next() )
{
d = ( track->m_Width / 2 ) + 1;
cx = MIN( track->m_Start.x, track->m_End.x );
cy = MIN( track->m_Start.y, track->m_End.y );
xmin = MIN( xmin, cx - d );
ymin = MIN( ymin, cy - d );
cx = MAX( track->m_Start.x, track->m_End.x );
cy = MAX( track->m_Start.y, track->m_End.y );
xmax = MAX( xmax, cx + d );
ymax = MAX( ymax, cy + d );
hasItems = true;
}
for( TRACK* track = m_Zone; track; track = track->Next() )
{
d = ( track->m_Width / 2 ) + 1;
cx = MIN( track->m_Start.x, track->m_End.x );
cy = MIN( track->m_Start.y, track->m_End.y );
xmin = MIN( xmin, cx - d );
ymin = MIN( ymin, cy - d );
cx = MAX( track->m_Start.x, track->m_End.x );
cy = MAX( track->m_Start.y, track->m_End.y );
xmax = MAX( xmax, cx + d );
ymax = MAX( ymax, cy + d );
hasItems = TRUE;
// Check polygonal zones
for( unsigned int i = 0; i < m_ZoneDescriptorList.size(); i++ )
{
ZONE_CONTAINER* aZone = m_ZoneDescriptorList[i];
EDA_Rect bBox = aZone->GetBoundingBox();
xmin = MIN( xmin, bBox.GetX() );
ymin = MIN( ymin, bBox.GetY() );
xmax = MAX( xmax, bBox.GetRight() );
ymax = MAX( ymax, bBox.GetBottom() );
hasItems = true;
}
}
if( !hasItems && m_PcbFrame )
......
......@@ -499,9 +499,13 @@ public:
return m_NetInfo->GetPadsCount();
}
bool ComputeBoundaryBox();
/**
* Function ComputeBoundingBox
* calculates the bounding box containing all board items (or board edge segments).
* @param aBoardEdgesOnly is true if we are interested in board edge segments only.
* @return bool - True if items (or board edge segments) were found.
*/
bool ComputeBoundingBox( bool aBoardEdgesOnly = false );
/**
* Function DisplayInfo
......
......@@ -737,3 +737,43 @@ bool DIMENSION::HitTest( EDA_Rect& refArea )
return true;
return false;
}
EDA_Rect DIMENSION::GetBoundingBox() const
{
EDA_Rect bBox;
int xmin, xmax, ymin, ymax;
bBox = m_Text->GetTextBox( -1 );
xmin = bBox.GetX();
xmax = bBox.GetRight();
ymin = bBox.GetY();
ymax = bBox.GetBottom();
xmin = MIN( xmin, Barre_ox );
xmin = MIN( xmin, Barre_fx );
ymin = MIN( ymin, Barre_oy );
ymin = MIN( ymin, Barre_fy );
xmax = MAX( xmax, Barre_ox );
xmax = MAX( xmax, Barre_fx );
ymax = MAX( ymax, Barre_oy );
ymax = MAX( ymax, Barre_fy );
xmin = MIN( xmin, TraitG_ox );
xmin = MIN( xmin, TraitG_fx );
ymin = MIN( ymin, TraitG_oy );
ymin = MIN( ymin, TraitG_fy );
xmax = MAX( xmax, TraitG_ox );
xmax = MAX( xmax, TraitG_fx );
ymax = MAX( ymax, TraitG_oy );
ymax = MAX( ymax, TraitG_fy );
bBox.SetX( xmin );
bBox.SetY( ymin );
bBox.SetWidth( xmax - xmin + 1 );
bBox.SetHeight( ymax - ymin + 1 );
bBox.Normalize();
return bBox;
}
......@@ -132,6 +132,8 @@ public:
{
return wxT( "DIMENSION" );
}
EDA_Rect GetBoundingBox() const;
};
#endif // #define DIMENSION_H
......@@ -222,3 +222,15 @@ void MIREPCB::Flip(const wxPoint& aCentre )
m_Pos.y = aCentre.y - ( m_Pos.y - aCentre.y );
SetLayer( ChangeSideNumLayer( GetLayer() ) );
}
EDA_Rect MIREPCB::GetBoundingBox() const
{
EDA_Rect bBox;
bBox.SetX( m_Pos.x - m_Size/2 );
bBox.SetY( m_Pos.y - m_Size/2 );
bBox.SetWidth( m_Size );
bBox.SetHeight( m_Size );
return bBox;
}
......@@ -87,6 +87,7 @@ public:
*/
bool HitTest( EDA_Rect& refArea );
EDA_Rect GetBoundingBox() const;
};
......
......@@ -89,7 +89,7 @@ void WinEDA_PcbFrame::ExportToGenCAD( wxCommandEvent& event )
}
/* Update some board data, to ensure a reliable gencad export: */
GetBoard()->ComputeBoundaryBox();
GetBoard()->ComputeBoundingBox();
offsetX = m_Auxiliary_Axis_Position.x;
offsetY = m_Auxiliary_Axis_Position.y;
......
......@@ -1214,7 +1214,7 @@ bool WinEDA_PcbFrame::ExportVRML_File( const wxString & aFullFileName,
/* Define the translation to have the board centre to the 2D axis origin
* more easy for rotations...
*/
pcb->ComputeBoundaryBox();
pcb->ComputeBoundingBox();
double dx = board_scaling_factor * pcb->m_BoundaryBox.Centre().x * aScale;
double dy = board_scaling_factor * pcb->m_BoundaryBox.Centre().y * aScale;
fprintf(output_file, " translation %g %g 0.0\n", -dx, dy );
......
......@@ -40,8 +40,9 @@ void GenDrillMapFile( BOARD* aPcb, FILE* aFile, const wxString& aFullFileName,
PLOTTER* plotter = NULL;
SetLocaleTo_C_standard(); // Use the standard notation for float numbers
/* Calculate dimensions and center of PCB */
aPcb->ComputeBoundaryBox();
// Calculate dimensions and center of PCB
aPcb->ComputeBoundingBox();
dX = aPcb->m_BoundaryBox.GetWidth();
dY = aPcb->m_BoundaryBox.GetHeight();
......
......@@ -347,7 +347,7 @@ void WinEDA_PcbFrame::GenModuleReport( wxCommandEvent& event )
fputs( "##\n", rptfile );
fputs( "\n$BeginDESCRIPTION\n", rptfile );
GetBoard()->ComputeBoundaryBox();
GetBoard()->ComputeBoundingBox();
fputs( "\n$BOARD\n", rptfile );
fputs( "unit INCH\n", rptfile );
sprintf( line, "upper_left_corner %9.6f %9.6f\n",
......
......@@ -789,7 +789,7 @@ bool WinEDA_PcbFrame::WriteGeneralDescrPcb( FILE* File )
fprintf( File, "NoConn %d\n", GetBoard()->m_NbNoconnect );
/* Write Bounding box info */
GetBoard()->ComputeBoundaryBox();
GetBoard()->ComputeBoundingBox();
fprintf( File, "Di %d %d %d %d\n",
GetBoard()->m_BoundaryBox.GetX(),
GetBoard()->m_BoundaryBox.GetY(),
......
......@@ -1002,7 +1002,7 @@ void LoadListeModules( WinEDA_PcbFrame* aPcbFrame )
ref = cmp = s_ModuleToLoad_List;
// Calculate the footprint "best" position:
if( aPcbFrame->SetBoardBoundaryBoxFromEdgesOnly() )
if( aPcbFrame->GetBoard()->ComputeBoundingBox( true ) )
{
ModuleBestPosition.x =
aPcbFrame->GetBoard()->m_BoundaryBox.GetRight() + 5000;
......
......@@ -55,7 +55,7 @@ bool WinEDA_BasePcbFrame::Genere_HPGL( const wxString& FullFileName, int Layer,
SheetSize.y = currentsheet->m_Size.y * U_PCB;
/* Calculate the center of the PCB. */
m_Pcb->ComputeBoundaryBox();
m_Pcb->ComputeBoundingBox();
BoardSize = m_Pcb->m_BoundaryBox.GetSize();
BoardCenter = m_Pcb->m_BoundaryBox.Centre();
......
......@@ -62,7 +62,7 @@ bool WinEDA_BasePcbFrame::Genere_PS( const wxString& FullFileName, int Layer,
paperscale = 1;
}
m_Pcb->ComputeBoundaryBox();
m_Pcb->ComputeBoundingBox();
BoardSize = m_Pcb->m_BoundaryBox.GetSize();
BoardCenter = m_Pcb->m_BoundaryBox.Centre();
......
......@@ -138,8 +138,9 @@ void BOARD_PRINTOUT_CONTROLER::DrawPage()
SheetSize.y *= m_Parent->m_InternalUnits / 1000; // size in internal units
WinEDA_BasePcbFrame* pcbframe = (WinEDA_BasePcbFrame*) m_Parent;
pcbframe->GetBoard()->ComputeBoundaryBox();
pcbframe->GetBoard()->ComputeBoundingBox();
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:
......
......@@ -882,7 +882,7 @@ void SPECCTRA_DB::fillBOUNDARY( BOARD* aBoard, BOUNDARY* boundary ) throw( IO_ER
}
else
{
aBoard->ComputeBoundaryBox();
aBoard->ComputeBoundingBox();
RECTANGLE* rect = new RECTANGLE( boundary );
boundary->rectangle = rect;
......
......@@ -102,7 +102,8 @@ int WinEDA_PcbFrame::Fill_Zone( ZONE_CONTAINER* zone_container, bool verbose )
wxString msg;
MsgPanel->EraseMsgBox();
if( GetBoard()->ComputeBoundaryBox() == false )
if( GetBoard()->ComputeBoundingBox() == false )
{
if( verbose )
wxMessageBox( wxT( "Board is empty!" ) );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment