Commit 22987934 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 which calclaltes outlines) is now used to create the 3D body of the board,
in pcbnew and cvpcb.
parents 964933db 7a259383
...@@ -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) bufferPolys.reserve( 200000 ); // Reserve for large board (tracks mainly)
CPOLYGONS_LIST bufferZonesPolys;
bufferPolys.reserve( 500000 ); // Reserve for large board ( copper zones mainly ) CPOLYGONS_LIST bufferPcbOutlines; // stores the board main outlines
CPOLYGONS_LIST currLayerHoles; // Contains holes for the current layer
CPOLYGONS_LIST allLayerHoles; // Contains through holes, calculated only once CPOLYGONS_LIST allLayerHoles; // Contains through holes, calculated only once
allLayerHoles.reserve( 20000 ); 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 );
}
CPOLYGONS_LIST bufferZonesPolys;
bufferZonesPolys.reserve( 500000 ); // Reserve for large board ( copper zones mainly )
CPOLYGONS_LIST currLayerHoles; // Contains holes for the current layer
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;
// Solder mask layers are "negative" layers.
// 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 ); bufferPolys.ExportTo( polyset );
// merge polys:
currLayerPolyset += 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_
...@@ -139,6 +139,9 @@ set(PCB_COMMON_SRCS ...@@ -139,6 +139,9 @@ set(PCB_COMMON_SRCS
../pcbnew/kicad_plugin.cpp ../pcbnew/kicad_plugin.cpp
../pcbnew/gpcb_plugin.cpp ../pcbnew/gpcb_plugin.cpp
../pcbnew/pcb_netlist.cpp ../pcbnew/pcb_netlist.cpp
../pcbnew/specctra.cpp
../pcbnew/specctra_export.cpp
../pcbnew/specctra_keywords.cpp
pcb_plot_params_keywords.cpp pcb_plot_params_keywords.cpp
pcb_keywords.cpp pcb_keywords.cpp
../pcbnew/pcb_parser.cpp ../pcbnew/pcb_parser.cpp
...@@ -155,6 +158,17 @@ set_source_files_properties( ${PCB_COMMON_SRCS} PROPERTIES ...@@ -155,6 +158,17 @@ set_source_files_properties( ${PCB_COMMON_SRCS} PROPERTIES
add_library(pcbcommon STATIC ${PCB_COMMON_SRCS}) add_library(pcbcommon STATIC ${PCB_COMMON_SRCS})
# auto-generate specctra_lexer.h and specctra_keywords.cpp
make_lexer(
${PROJECT_SOURCE_DIR}/pcbnew/specctra.keywords
${PROJECT_SOURCE_DIR}/pcbnew/specctra_lexer.h
${PROJECT_SOURCE_DIR}/pcbnew/specctra_keywords.cpp
DSN
# Pass header file with dependency on *_lexer.h as extra_arg
specctra.h
)
# auto-generate netlist_lexer.h and netlist_keywords.cpp # auto-generate netlist_lexer.h and netlist_keywords.cpp
make_lexer( make_lexer(
${CMAKE_CURRENT_SOURCE_DIR}/netlist.keywords ${CMAKE_CURRENT_SOURCE_DIR}/netlist.keywords
......
...@@ -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 );
......
...@@ -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;
......
...@@ -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
......
...@@ -199,10 +199,10 @@ set( PCBNEW_CLASS_SRCS ...@@ -199,10 +199,10 @@ set( PCBNEW_CLASS_SRCS
print_board_functions.cpp print_board_functions.cpp
printout_controler.cpp printout_controler.cpp
ratsnest.cpp ratsnest.cpp
specctra.cpp # specctra.cpp #moved in pcbcommon lib
specctra_export.cpp # specctra_export.cpp
# specctra_keywords.cpp
specctra_import.cpp specctra_import.cpp
specctra_keywords.cpp
swap_layers.cpp swap_layers.cpp
target_edit.cpp target_edit.cpp
tool_modedit.cpp tool_modedit.cpp
......
...@@ -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