Commit dd64b2f2 authored by jean-pierre charras's avatar jean-pierre charras

3D board display: better rendering of the board: the board polygon outlines...

3D board display: better rendering of the board: the board polygon outlines (generated by the specctra function) is now used to create the 3D body of the board.
parent 964933db
...@@ -49,7 +49,6 @@ ...@@ -49,7 +49,6 @@
#include <3d_draw_basic_functions.h> #include <3d_draw_basic_functions.h>
// Imported function: // Imported function:
extern void SetGLColor( EDA_COLOR_T color );
extern void Set_Object_Data( std::vector<S3D_VERTEX>& aVertices, double aBiuTo3DUnits ); extern void Set_Object_Data( std::vector<S3D_VERTEX>& aVertices, double aBiuTo3DUnits );
extern void CheckGLError(); extern void CheckGLError();
...@@ -161,14 +160,28 @@ void EDA_3D_CANVAS::BuildBoard3DView() ...@@ -161,14 +160,28 @@ void EDA_3D_CANVAS::BuildBoard3DView()
// for holes and items which do not need // for holes and items which do not need
// a fine representation // a fine representation
double correctionFactorLQ = 1.0 / cos( M_PI / (segcountLowQuality * 2) ); double correctionFactorLQ = 1.0 / cos( M_PI / (segcountLowQuality * 2) );
CPOLYGONS_LIST bufferPolys; CPOLYGONS_LIST bufferPolys;
bufferPolys.reserve( 200000 ); // Reserve for large board (tracks mainly)
CPOLYGONS_LIST bufferPcbOutlines; // stores the board main outlines
CPOLYGONS_LIST allLayerHoles; // Contains through holes, calculated only once
allLayerHoles.reserve( 20000 );
// Build a polygon from edge cut items
wxString msg;
if( ! pcb->GetBoardPolygonOutlines( bufferPcbOutlines,
allLayerHoles, &msg ) )
{
msg << wxT("\n\n") <<
_("Unable to calculate the board outlines, will use the outlines boundary box");
wxMessageBox( msg );
}
bufferPolys.reserve( 200000 ); // Reserve for large board (tracks mainly)
CPOLYGONS_LIST bufferZonesPolys; CPOLYGONS_LIST bufferZonesPolys;
bufferPolys.reserve( 500000 ); // Reserve for large board ( copper zones mainly ) bufferZonesPolys.reserve( 500000 ); // Reserve for large board ( copper zones mainly )
CPOLYGONS_LIST currLayerHoles; // Contains holes for the current layer CPOLYGONS_LIST currLayerHoles; // Contains holes for the current layer
CPOLYGONS_LIST allLayerHoles; // Contains through holes, calculated only once
allLayerHoles.reserve( 20000 );
bool throughHolesListBuilt = false; // flag to build the through hole polygon list only once bool throughHolesListBuilt = false; // flag to build the through hole polygon list only once
bool hightQualityMode = false; bool hightQualityMode = false;
...@@ -282,7 +295,8 @@ void EDA_3D_CANVAS::BuildBoard3DView() ...@@ -282,7 +295,8 @@ void EDA_3D_CANVAS::BuildBoard3DView()
} }
} }
// bufferPolys contains polygons to merge. Many overlaps . Calculate merged polygons // bufferPolys contains polygons to merge. Many overlaps .
// Calculate merged polygons
if( bufferPolys.GetCornersCount() == 0 ) if( bufferPolys.GetCornersCount() == 0 )
continue; continue;
...@@ -346,6 +360,9 @@ void EDA_3D_CANVAS::BuildBoard3DView() ...@@ -346,6 +360,9 @@ void EDA_3D_CANVAS::BuildBoard3DView()
if( !g_Parm_3D_Visu.m_BoardSettings->IsLayerVisible( layer ) ) if( !g_Parm_3D_Visu.m_BoardSettings->IsLayerVisible( layer ) )
continue; continue;
if( layer == EDGE_N )
continue;
bufferPolys.RemoveAllContours(); bufferPolys.RemoveAllContours();
for( BOARD_ITEM* item = pcb->m_Drawings; item; item = item->Next() ) for( BOARD_ITEM* item = pcb->m_Drawings; item; item = item->Next() )
...@@ -407,26 +424,29 @@ void EDA_3D_CANVAS::BuildBoard3DView() ...@@ -407,26 +424,29 @@ void EDA_3D_CANVAS::BuildBoard3DView()
// Calculate merged polygons and remove pads and vias holes // Calculate merged polygons and remove pads and vias holes
if( bufferPolys.GetCornersCount() == 0 ) if( bufferPolys.GetCornersCount() == 0 )
continue; continue;
KI_POLYGON_SET currLayerPolyset; KI_POLYGON_SET currLayerPolyset;
KI_POLYGON_SET polyset; KI_POLYGON_SET polyset;
bufferPolys.ExportTo( polyset );
// merge polys: // Solder mask layers are "negative" layers.
currLayerPolyset += polyset; // Shapes should be removed from the full board area.
if( layer == SOLDERMASK_N_BACK || layer == SOLDERMASK_N_FRONT )
{
bufferPcbOutlines.ExportTo( currLayerPolyset );
bufferPolys.Append( allLayerHoles );
bufferPolys.ExportTo( polyset );
currLayerPolyset -= polyset;
}
else // usuall layers, merge polys built from each item shape:
{
bufferPolys.ExportTo( polyset );
currLayerPolyset += polyset;
}
EDA_COLOR_T color = g_ColorsSettings.GetLayerColor( layer ); EDA_COLOR_T color = g_ColorsSettings.GetLayerColor( layer );
int thickness = g_Parm_3D_Visu.GetLayerObjectThicknessBIU( layer ); int thickness = g_Parm_3D_Visu.GetLayerObjectThicknessBIU( layer );
int zpos = g_Parm_3D_Visu.GetLayerZcoordBIU( layer ); int zpos = g_Parm_3D_Visu.GetLayerZcoordBIU( layer );
if( layer == EDGE_N ) SetGLColor( color, 0.7 );
{
thickness = g_Parm_3D_Visu.GetLayerZcoordBIU( LAYER_N_FRONT )
- g_Parm_3D_Visu.GetLayerZcoordBIU( LAYER_N_BACK );
zpos = g_Parm_3D_Visu.GetLayerZcoordBIU( LAYER_N_BACK )
+ (thickness / 2);
}
SetGLColor( color );
glNormal3f( 0.0, 0.0, Get3DLayer_Z_Orientation( layer ) ); glNormal3f( 0.0, 0.0, Get3DLayer_Z_Orientation( layer ) );
bufferPolys.RemoveAllContours(); bufferPolys.RemoveAllContours();
...@@ -435,6 +455,37 @@ void EDA_3D_CANVAS::BuildBoard3DView() ...@@ -435,6 +455,37 @@ void EDA_3D_CANVAS::BuildBoard3DView()
thickness, g_Parm_3D_Visu.m_BiuTo3Dunits ); thickness, g_Parm_3D_Visu.m_BiuTo3Dunits );
} }
// Draw board substrate:
if( bufferPcbOutlines.GetCornersCount() )
{
int copper_thickness = g_Parm_3D_Visu.GetLayerObjectThicknessBIU( LAYER_N_BACK );
int zpos = g_Parm_3D_Visu.GetLayerZcoordBIU( LAYER_N_BACK );
int thickness = g_Parm_3D_Visu.GetLayerZcoordBIU( LAYER_N_FRONT )
- g_Parm_3D_Visu.GetLayerZcoordBIU( LAYER_N_BACK );
zpos += (thickness/2) + (copper_thickness/2);
thickness -= copper_thickness;
EDA_COLOR_T color = g_ColorsSettings.GetLayerColor( EDGE_N );
SetGLColor( color, 0.8 );
glNormal3f( 0.0, 0.0, Get3DLayer_Z_Orientation( LAYER_N_FRONT ) );
KI_POLYGON_SET currLayerPolyset;
KI_POLYGON_SET polysetHoles;
// Add polygons, without holes
bufferPcbOutlines.ExportTo( currLayerPolyset );
// Build holes list
allLayerHoles.ExportTo( polysetHoles );
// remove holes
currLayerPolyset -= polysetHoles;
bufferPcbOutlines.RemoveAllContours();
bufferPcbOutlines.ImportFrom( currLayerPolyset );
Draw3D_SolidHorizontalPolyPolygons( bufferPcbOutlines, zpos,
thickness, g_Parm_3D_Visu.m_BiuTo3Dunits );
}
// draw modules 3D shapes // draw modules 3D shapes
for( MODULE* module = pcb->m_Modules; module != NULL; module = module->Next() ) for( MODULE* module = pcb->m_Modules; module != NULL; module = module->Next() )
module->ReadAndInsert3DComponentShape( this ); module->ReadAndInsert3DComponentShape( this );
...@@ -517,6 +568,7 @@ void EDA_3D_CANVAS::DrawGrid( double aGriSizeMM ) ...@@ -517,6 +568,7 @@ void EDA_3D_CANVAS::DrawGrid( double aGriSizeMM )
EDA_COLOR_T gridcolor = DARKGRAY; // Color of grid lines EDA_COLOR_T gridcolor = DARKGRAY; // Color of grid lines
EDA_COLOR_T gridcolor_marker = LIGHTGRAY; // Color of grid lines every 5 lines EDA_COLOR_T gridcolor_marker = LIGHTGRAY; // Color of grid lines every 5 lines
double scale = g_Parm_3D_Visu.m_BiuTo3Dunits; double scale = g_Parm_3D_Visu.m_BiuTo3Dunits;
double transparency = 0.4;
glNormal3f( 0.0, 0.0, 1.0 ); glNormal3f( 0.0, 0.0, 1.0 );
...@@ -539,9 +591,9 @@ void EDA_3D_CANVAS::DrawGrid( double aGriSizeMM ) ...@@ -539,9 +591,9 @@ void EDA_3D_CANVAS::DrawGrid( double aGriSizeMM )
for( int ii = 0; ; ii++ ) for( int ii = 0; ; ii++ )
{ {
if( (ii % 5) ) if( (ii % 5) )
SetGLColor( gridcolor ); SetGLColor( gridcolor, transparency );
else else
SetGLColor( gridcolor_marker ); SetGLColor( gridcolor_marker, transparency );
int delta = KiROUND( ii * aGriSizeMM * IU_PER_MM ); int delta = KiROUND( ii * aGriSizeMM * IU_PER_MM );
...@@ -588,9 +640,9 @@ void EDA_3D_CANVAS::DrawGrid( double aGriSizeMM ) ...@@ -588,9 +640,9 @@ void EDA_3D_CANVAS::DrawGrid( double aGriSizeMM )
for( int ii = 0; ; ii++ ) for( int ii = 0; ; ii++ )
{ {
if( (ii % 5) ) if( (ii % 5) )
SetGLColor( gridcolor ); SetGLColor( gridcolor, transparency );
else else
SetGLColor( gridcolor_marker ); SetGLColor( gridcolor_marker, transparency );
double delta = ii * aGriSizeMM * IU_PER_MM; double delta = ii * aGriSizeMM * IU_PER_MM;
...@@ -615,9 +667,9 @@ void EDA_3D_CANVAS::DrawGrid( double aGriSizeMM ) ...@@ -615,9 +667,9 @@ void EDA_3D_CANVAS::DrawGrid( double aGriSizeMM )
for( int ii = 0; ; ii++ ) for( int ii = 0; ; ii++ )
{ {
if( (ii % 5) ) if( (ii % 5) )
SetGLColor( gridcolor ); SetGLColor( gridcolor, transparency);
else else
SetGLColor( gridcolor_marker ); SetGLColor( gridcolor_marker, transparency );
double delta = ii * aGriSizeMM * IU_PER_MM * scale; double delta = ii * aGriSizeMM * IU_PER_MM * scale;
......
...@@ -34,7 +34,6 @@ ...@@ -34,7 +34,6 @@
#include <info3d_visu.h> #include <info3d_visu.h>
#include <3d_draw_basic_functions.h> #include <3d_draw_basic_functions.h>
// Imported function: // Imported function:
extern void Set_Object_Data( std::vector<S3D_VERTEX>& aVertices, double aBiuTo3DUnits ); extern void Set_Object_Data( std::vector<S3D_VERTEX>& aVertices, double aBiuTo3DUnits );
extern void CheckGLError(); extern void CheckGLError();
...@@ -122,7 +121,7 @@ static void Draw3D_VerticalPolygonalCylinder( const CPOLYGONS_LIST& aPolysList, ...@@ -122,7 +121,7 @@ static void Draw3D_VerticalPolygonalCylinder( const CPOLYGONS_LIST& aPolysList,
} }
void SetGLColor( EDA_COLOR_T color ) void SetGLColor( EDA_COLOR_T color, double alpha )
{ {
double red, green, blue; double red, green, blue;
const StructColors &colordata = g_ColorRefs[ColorGetBase( color )]; const StructColors &colordata = g_ColorRefs[ColorGetBase( color )];
...@@ -130,7 +129,7 @@ void SetGLColor( EDA_COLOR_T color ) ...@@ -130,7 +129,7 @@ void SetGLColor( EDA_COLOR_T color )
red = colordata.m_Red / 255.0; red = colordata.m_Red / 255.0;
blue = colordata.m_Blue / 255.0; blue = colordata.m_Blue / 255.0;
green = colordata.m_Green / 255.0; green = colordata.m_Green / 255.0;
glColor3f( red, green, blue ); glColor4f( red, green, blue, alpha );
} }
......
...@@ -118,5 +118,12 @@ void Draw3D_ZaxisCylinder( wxPoint aCenterPos, int aRadius, ...@@ -118,5 +118,12 @@ void Draw3D_ZaxisCylinder( wxPoint aCenterPos, int aRadius,
void Draw3D_ZaxisOblongCylinder( wxPoint aAxis1Pos, wxPoint aAxis2Pos, void Draw3D_ZaxisOblongCylinder( wxPoint aAxis1Pos, wxPoint aAxis2Pos,
int aRadius, int aHeight, int aThickness, int aRadius, int aHeight, int aThickness,
int aZpos, double aBiuTo3DUnits ); int aZpos, double aBiuTo3DUnits );
/**
* Set the current 3D color from a Kicad color, with optional transparency
* @param aColor = a EDA_COLOR_T kicad color index
* @param aTransparency = the color transparency (default = 1.0 = no transparency)
*/
void SetGLColor( EDA_COLOR_T aColor, double aTransparency = 1.0 );
#endif // _3D_DRAW_BASIC_FUNCTIONS_H_ #endif // _3D_DRAW_BASIC_FUNCTIONS_H_
...@@ -67,6 +67,10 @@ bool GERBER_PLOTTER::StartPlot() ...@@ -67,6 +67,10 @@ bool GERBER_PLOTTER::StartPlot()
if( outputFile == NULL ) if( outputFile == NULL )
return false; return false;
/* Set coordinate format to 3.4 absolute, leading zero omitted */
fputs( "%FSLAX34Y34*%\n", outputFile );
fputs( "G04 Gerber Fmt 3.4, Leading zero omitted, Abs format*\n", outputFile );
wxString Title = creator + wxT( " " ) + GetBuildVersion(); wxString Title = creator + wxT( " " ) + GetBuildVersion();
fprintf( outputFile, "G04 (created by %s) date %s*\n", fprintf( outputFile, "G04 (created by %s) date %s*\n",
TO_UTF8( Title ), TO_UTF8( DateAndTime() ) ); TO_UTF8( Title ), TO_UTF8( DateAndTime() ) );
...@@ -74,10 +78,6 @@ bool GERBER_PLOTTER::StartPlot() ...@@ -74,10 +78,6 @@ bool GERBER_PLOTTER::StartPlot()
/* Mass parameter: unit = INCHES */ /* Mass parameter: unit = INCHES */
fputs( "%MOIN*%\n", outputFile ); fputs( "%MOIN*%\n", outputFile );
/* Set coordinate format to 3.4 absolute, leading zero omitted */
fputs( "G04 Gerber Fmt 3.4, Leading zero omitted, Abs format*\n%FSLAX34Y34*%\n",
outputFile );
/* Specify linear interpol (G01), unit = INCH (G70), abs format (G90) */ /* Specify linear interpol (G01), unit = INCH (G70), abs format (G90) */
fputs( "G01*\nG70*\nG90*\n", outputFile ); fputs( "G01*\nG70*\nG90*\n", outputFile );
fputs( "G04 APERTURE LIST*\n", outputFile ); fputs( "G04 APERTURE LIST*\n", outputFile );
......
...@@ -31,6 +31,9 @@ set( CVPCB_SRCS ...@@ -31,6 +31,9 @@ set( CVPCB_SRCS
../common/base_units.cpp ../common/base_units.cpp
../pcbnew/board_items_to_polygon_shape_transform.cpp ../pcbnew/board_items_to_polygon_shape_transform.cpp
../pcbnew/class_drc_item.cpp ../pcbnew/class_drc_item.cpp
../pcbnew/specctra.cpp
../pcbnew/specctra_export.cpp
../pcbnew/specctra_keywords.cpp
autosel.cpp autosel.cpp
cfg.cpp cfg.cpp
class_components_listbox.cpp class_components_listbox.cpp
......
...@@ -58,8 +58,8 @@ ...@@ -58,8 +58,8 @@
*/ */
/* /*
* Note there are some variant of tool definition: * Note there are some variant of tool definition:
* T1F00S00C... Feed Rate and Spindle Speed of Tool 1 * T1F00S00C0.2 or T1C0.02F00S00 ... Feed Rate and Spindle Speed of Tool 1
* Feed Rate and Spindle Speed are just skipped because they are not used in a viwer * Feed Rate and Spindle Speed are just skipped because they are not used in a viewer
*/ */
#include <fctsys.h> #include <fctsys.h>
...@@ -348,7 +348,7 @@ bool EXCELLON_IMAGE::Execute_HEADER_Command( char*& text ) ...@@ -348,7 +348,7 @@ bool EXCELLON_IMAGE::Execute_HEADER_Command( char*& text )
m_State = READ_PROGRAM_STATE; m_State = READ_PROGRAM_STATE;
break; break;
case DRILL_REWIND_STOP: // TODO: what this command really is ? case DRILL_REWIND_STOP: // End of header. No action in a viewer
m_State = READ_PROGRAM_STATE; m_State = READ_PROGRAM_STATE;
break; break;
...@@ -440,11 +440,11 @@ bool EXCELLON_IMAGE::Execute_HEADER_Command( char*& text ) ...@@ -440,11 +440,11 @@ bool EXCELLON_IMAGE::Execute_HEADER_Command( char*& text )
case DRILL_TOOL_INFORMATION: case DRILL_TOOL_INFORMATION:
// Read a tool definition like T1C0.02: // Read a tool definition like T1C0.02:
// or T1F00S00C0.02000 // or T1F00S00C0.02 or T1C0.02F00S00
// Read tool number: // Read tool number:
iprm = ReadInt( text, false ); iprm = ReadInt( text, false );
// Skip Feed rate and Spindle speed // Skip Feed rate and Spindle speed, if any here
while( *text && ( *text == 'F' || *text == 'S' ) ) while( *text && ( *text == 'F' || *text == 'S' ) )
{ {
text++; text++;
......
...@@ -141,7 +141,7 @@ void GERBVIEW_FRAME::ExportDataInPcbnewFormat( wxCommandEvent& event ) ...@@ -141,7 +141,7 @@ void GERBVIEW_FRAME::ExportDataInPcbnewFormat( wxCommandEvent& event )
wxFileDialog filedlg( this, _( "Board file name:" ), wxFileDialog filedlg( this, _( "Board file name:" ),
path, fileName, LegacyPcbFileWildcard, path, fileName, LegacyPcbFileWildcard,
wxFD_OPEN ); wxFD_SAVE );
if( filedlg.ShowModal() == wxID_CANCEL ) if( filedlg.ShowModal() == wxID_CANCEL )
return; return;
...@@ -233,7 +233,7 @@ void GBR_TO_PCB_EXPORTER::export_non_copper_item( GERBER_DRAW_ITEM* aGbrItem, LA ...@@ -233,7 +233,7 @@ void GBR_TO_PCB_EXPORTER::export_non_copper_item( GERBER_DRAW_ITEM* aGbrItem, LA
#define SEG_SHAPE 0 #define SEG_SHAPE 0
#define ARC_SHAPE 2 #define ARC_SHAPE 2
int shape = SEG_SHAPE; int shape = SEG_SHAPE;
// please note: the old PCB format only has integer support for angles // please note: the old PCB format only has integer support for angles
int angle = 0; int angle = 0;
wxPoint seg_start, seg_end; wxPoint seg_start, seg_end;
......
...@@ -6,8 +6,8 @@ ...@@ -6,8 +6,8 @@
/* /*
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2011 jean-pierre.charras * Copyright (C) 2013 jean-pierre.charras jp.charras at wanadoo.fr
* Copyright (C) 2011 KiCad Developers, see change_log.txt for contributors. * Copyright (C) 2013 KiCad Developers, see change_log.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
...@@ -31,13 +31,13 @@ ...@@ -31,13 +31,13 @@
#define _BITMAP_BASE_H_ #define _BITMAP_BASE_H_
#include <plot_common.h> class PLOTTER;
/** /**
* This class handle bitmap images in KiCad. * This class handle bitmap images in KiCad.
* It is not intended to be used alone, but inside an other class, * It is not intended to be used alone, but inside an other class,
* so all methods are protected ( or private ) * so all methods are protected ( or private )
* It is used in SCH_BITMAP class (and other in futute) * It is used in SCH_BITMAP class and WS_DRAW_ITEM_BITMAP (and other in future)
* *
* Remember not all plotters are able to plot a bitmap * Remember not all plotters are able to plot a bitmap
* Mainly GERBER plotters cannot. * Mainly GERBER plotters cannot.
...@@ -106,13 +106,13 @@ public: BITMAP_BASE( const wxPoint& pos = wxPoint( 0, 0 ) ); ...@@ -106,13 +106,13 @@ public: BITMAP_BASE( const wxPoint& pos = wxPoint( 0, 0 ) );
/** /**
* Function GetSize * Function GetSize
* @returns the actual size (in user units, not in pixels) of the image * @return the actual size (in user units, not in pixels) of the image
*/ */
wxSize GetSize() const; wxSize GetSize() const;
/** /**
* Function GetSizePixels * Function GetSizePixels
* @returns the size in pixels of the image * @return the size in pixels of the image
*/ */
wxSize GetSizePixels() const wxSize GetSizePixels() const
{ {
...@@ -136,8 +136,8 @@ public: BITMAP_BASE( const wxPoint& pos = wxPoint( 0, 0 ) ); ...@@ -136,8 +136,8 @@ public: BITMAP_BASE( const wxPoint& pos = wxPoint( 0, 0 ) );
/** /**
* Function ReadImageFile * Function ReadImageFile
* Reads and stores an image file. Init the bitmap used to draw this item * Reads and stores in memory an image file.
* format. * Init the bitmap format used to draw this item.
* supported images formats are format supported by wxImage * supported images formats are format supported by wxImage
* if all handlers are loaded * if all handlers are loaded
* by default, .png, .jpeg are alway loaded * by default, .png, .jpeg are alway loaded
...@@ -191,7 +191,7 @@ public: BITMAP_BASE( const wxPoint& pos = wxPoint( 0, 0 ) ); ...@@ -191,7 +191,7 @@ public: BITMAP_BASE( const wxPoint& pos = wxPoint( 0, 0 ) );
* @param aDefaultColor = the color used to plot the rectangle when bitmap is not supported * @param aDefaultColor = the color used to plot the rectangle when bitmap is not supported
* @param aDefaultPensize = the pen size used to plot the rectangle when bitmap is not supported * @param aDefaultPensize = the pen size used to plot the rectangle when bitmap is not supported
*/ */
void PlotImage( PLOTTER* aPlotter, const wxPoint& aPos, void PlotImage( PLOTTER* aPlotter, const wxPoint& aPos,
EDA_COLOR_T aDefaultColor, int aDefaultPensize ); EDA_COLOR_T aDefaultColor, int aDefaultPensize );
}; };
......
...@@ -2715,3 +2715,19 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets, ...@@ -2715,3 +2715,19 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
} }
} }
/* Extracts the board outlines and build a closed polygon
* from lines, arcs and circle items on edge cut layer
* Any closed outline inside the main outline is a hole
* All contours should be closed, i.e. are valid vertices for a closed polygon
* return true if success, false if a contour is not valid
*/
#include <specctra.h>
bool BOARD::GetBoardPolygonOutlines( CPOLYGONS_LIST& aOutlines,
CPOLYGONS_LIST& aHoles,
wxString* aErrorText )
{
// the SPECCTRA_DB function to extract board outlines:
SPECCTRA_DB dummy;
return dummy.GetBoardPolygonOutlines( this, aOutlines,
aHoles, aErrorText );
}
...@@ -628,6 +628,23 @@ public: ...@@ -628,6 +628,23 @@ public:
m_colorsSettings = aColorsSettings; m_colorsSettings = aColorsSettings;
} }
/**
* Function GetBoardPolygonOutlines
* Extracts the board outlines and build a closed polygon
* from lines, arcs and circle items on edge cut layer
* Any closed outline inside the main outline is a hole
* All contours should be closed, i.e. have valid vertices to build a closed polygon
* @param aOutlines The CPOLYGONS_LIST to fill in with main outlines.
* @param aHoles The empty CPOLYGONS_LIST to fill in with holes, if any.
* @param aErrorText = a wxString reference to display an error message
* with the coordinate of the point which creates the error
* (default = NULL , no message returned on error)
* @return true if success, false if a contour is not valid
*/
bool GetBoardPolygonOutlines( CPOLYGONS_LIST& aOutlines,
CPOLYGONS_LIST& aHoles,
wxString* aErrorText = NULL );
/** /**
* Function GetLayerName * Function GetLayerName
* returns the name of a layer given by aLayer. Copper layers may * returns the name of a layer given by aLayer. Copper layers may
......
...@@ -465,6 +465,9 @@ public: ...@@ -465,6 +465,9 @@ public:
point1.FixNegativeZero(); point1.FixNegativeZero();
} }
POINT GetOrigin() { return point0; }
POINT GetEnd() { return point1; }
void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR ) void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
{ {
const char* newline = nestLevel ? "\n" : ""; const char* newline = nestLevel ? "\n" : "";
...@@ -593,6 +596,8 @@ public: ...@@ -593,6 +596,8 @@ public:
points.push_back( aPoint ); points.push_back( aPoint );
} }
POINTS& GetPoints() {return points; }
void SetLayerId( const char* aLayerId ) void SetLayerId( const char* aLayerId )
{ {
layer_id = aLayerId; layer_id = aLayerId;
...@@ -662,6 +667,40 @@ public: ...@@ -662,6 +667,40 @@ public:
delete rectangle; delete rectangle;
} }
/**
* GetCorners fills aBuffer with a list of coordinates (x,y) of corners
*/
void GetCorners( std::vector<double>& aBuffer )
{
if( rectangle )
{
aBuffer.push_back( rectangle->GetOrigin().x );
aBuffer.push_back( rectangle->GetOrigin().y );
aBuffer.push_back( rectangle->GetOrigin().x );
aBuffer.push_back( rectangle->GetEnd().y );
aBuffer.push_back( rectangle->GetEnd().x );
aBuffer.push_back( rectangle->GetEnd().y );
aBuffer.push_back( rectangle->GetEnd().x );
aBuffer.push_back( rectangle->GetOrigin().y );
}
else
{
for( PATHS::iterator i=paths.begin(); i!=paths.end(); ++i )
{
POINTS& plist = i->GetPoints();
for( unsigned jj = 0; jj < plist.size(); jj++ )
{
aBuffer.push_back( plist[jj].x );
aBuffer.push_back( plist[jj].y );
}
}
}
}
void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR ) void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
{ {
out->Print( nestLevel, "(%s\n", Name() ); out->Print( nestLevel, "(%s\n", Name() );
...@@ -3926,6 +3965,26 @@ public: ...@@ -3926,6 +3965,26 @@ public:
* flips the modules which were on the back side of the board back to the back. * flips the modules which were on the back side of the board back to the back.
*/ */
void RevertMODULEs( BOARD* aBoard ); void RevertMODULEs( BOARD* aBoard );
/**
* Function GetBoardPolygonOutlines
* Is not used in SPECCTRA export, but uses a lot of functions from it
* and is used to extract a board outlines (3D view, automatic zones build ...)
* makes the board perimeter by filling the BOUNDARY element
* any closed outline inside the main outline is a hole
* All contours should be closed, i.e. have valid vertices to build a closed polygon
* @param aBoard The BOARD to get information from in order to make the outlines.
* @param aOutlines The CPOLYGONS_LIST to fill in with main outlines.
* @param aHoles The empty CPOLYGONS_LIST to fill in with holes, if any.
* @param aErrorText = a wxString reference to display an error message
* with the coordinate of the point which creates the error
* (default = NULL , no message returned on error)
* @return true if success, false if a contour is not valid
*/
bool GetBoardPolygonOutlines( BOARD* aBoard,
CPOLYGONS_LIST& aOutlines,
CPOLYGONS_LIST& aHoles,
wxString* aErrorText = NULL );
}; };
......
...@@ -1251,6 +1251,98 @@ void SPECCTRA_DB::fillBOUNDARY( BOARD* aBoard, BOUNDARY* boundary ) throw( IO_ER ...@@ -1251,6 +1251,98 @@ void SPECCTRA_DB::fillBOUNDARY( BOARD* aBoard, BOUNDARY* boundary ) throw( IO_ER
} }
} }
/* This function is not used in SPECCTRA export,
* but uses a lot of functions from it
* and is used to extract a board outlines (3D view, automatic zones build ...)
* makes the board perimeter for the DSN file by filling the BOUNDARY element.
* Any closed outline inside the main outline is a hole
* All contours should be closed, i.e. valid closed polygon vertices
*/
bool SPECCTRA_DB::GetBoardPolygonOutlines( BOARD* aBoard,
CPOLYGONS_LIST& aOutlines,
CPOLYGONS_LIST& aHoles,
wxString* aErrorText )
{
bool success = true;
double specctra2UIfactor = IU_PER_MM / 1000.0; // Specctra unite = micron
if( ! pcb )
{
pcb = new PCB();
pcb->structure = new STRUCTURE( pcb );
}
CPolyPt corner;
BOUNDARY* boundary = new BOUNDARY( 0 );
pcb->structure->SetBOUNDARY( boundary );
try
{
fillBOUNDARY( aBoard, boundary );
std::vector<double> buffer;
boundary->GetCorners( buffer );
for( unsigned ii = 0; ii < buffer.size(); ii+=2 )
{
corner.x = buffer[ii] * specctra2UIfactor;
corner.y = - buffer[ii+1] * specctra2UIfactor;
aOutlines.Append( corner );
}
aOutlines.CloseLastContour();
// Export holes, stored as keepouts polygonal shapes.
// by fillBOUNDARY()
KEEPOUTS& holes = pcb->structure->keepouts;
for( KEEPOUTS::iterator i=holes.begin(); i!=holes.end(); ++i )
{
KEEPOUT& keepout = *i;
PATH* poly_hole = (PATH*)keepout.shape;
POINTS& plist = poly_hole->GetPoints();
for( unsigned ii = 0; ii < plist.size(); ii+=2 )
{
corner.x = plist[ii].x * specctra2UIfactor;
corner.y = - plist[ii].y * specctra2UIfactor;
aHoles.Append( corner );
}
aHoles.CloseLastContour();
}
}
catch( IO_ERROR ioe )
{
// Creates a valid polygon outline is not possible.
// So uses the board edge cuts bounding box to create a
// rectangular outline
// (when no edge cuts items, fillBOUNDARY biuld n outline
// from global bounding box
success = false;
if( aErrorText )
*aErrorText = ioe.errorText;
EDA_RECT bbbox = aBoard->ComputeBoundingBox( true );
corner.x = bbbox.GetOrigin().x;
corner.y = bbbox.GetOrigin().y;
aOutlines.Append( corner );
corner.x = bbbox.GetOrigin().x;
corner.y = bbbox.GetEnd().y;
aOutlines.Append( corner );
corner.x = bbbox.GetEnd().x;
corner.y = bbbox.GetEnd().y;
aOutlines.Append( corner );
corner.x = bbbox.GetEnd().x;
corner.y = bbbox.GetOrigin().y;
aOutlines.Append( corner );
aOutlines.CloseLastContour();
}
return success;
}
typedef std::set<std::string> STRINGSET; typedef std::set<std::string> STRINGSET;
typedef std::pair<STRINGSET::iterator, bool> STRINGSET_PAIR; typedef std::pair<STRINGSET::iterator, bool> STRINGSET_PAIR;
......
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