3D-viewer: Fixes and enhancements (add 3D bounding box for components). Add comments in header files. Fix some coding style issues.

This commit is contained in:
unknown 2015-03-28 12:36:19 +01:00 committed by jean-pierre charras
commit 8db15e7299
31 changed files with 2599 additions and 914 deletions

View File

@ -105,9 +105,9 @@ void TransfertToGLlist( std::vector< S3D_VERTEX >& aVertices, double aBiuTo3DUni
ay = aVertices[1].y - aVertices[0].y;
az = aVertices[1].z - aVertices[0].z;
bx = aVertices[aVertices.size() - 1].x - aVertices[0].x;
by = aVertices[aVertices.size() - 1].y - aVertices[0].y;
bz = aVertices[aVertices.size() - 1].z - aVertices[0].z;
bx = aVertices[2].x - aVertices[0].x;
by = aVertices[2].y - aVertices[0].y;
bz = aVertices[2].z - aVertices[0].z;
nx = ay * bz - az * by;
ny = az * bx - ax * bz;

View File

@ -94,6 +94,8 @@ EDA_3D_CANVAS::EDA_3D_CANVAS( EDA_3D_FRAME* parent, int* attribList ) :
m_ZBottom = 0.0;
m_ZTop = 0.0;
m_lightPos = S3D_VERTEX(0.0f, 0.0f, 50.0f);
// Clear all gl list identifiers:
for( int ii = GL_ID_BEGIN; ii < GL_ID_END; ii++ )
m_glLists[ii] = 0;
@ -110,6 +112,12 @@ EDA_3D_CANVAS::~EDA_3D_CANVAS()
ClearLists();
m_init = false;
delete m_glRC;
// Free the list of parsers list
for( unsigned int i = 0; i < m_model_parsers_list.size(); i++ )
if( m_model_parsers_list[i] )
delete m_model_parsers_list[i];
}
@ -132,6 +140,17 @@ void EDA_3D_CANVAS::ClearLists( int aGlList )
m_glLists[ii] = 0;
}
if( m_text_fake_shadow_front >= 0 )
glDeleteTextures( 1, &m_text_fake_shadow_front );
if( m_text_fake_shadow_back >= 0 )
glDeleteTextures( 1, &m_text_fake_shadow_back );
if( m_text_fake_shadow_board >= 0 )
glDeleteTextures( 1, &m_text_fake_shadow_board );
m_shadow_init = false;
}
@ -564,12 +583,12 @@ void EDA_3D_CANVAS::InitGL()
void EDA_3D_CANVAS::SetLights()
{
// activate light. the source is above the xy plane, at source_pos
GLfloat source_pos[4] = { 0.0, 0.0, 1000.0, 0.0 };
GLfloat source_pos[4] = { m_lightPos.x, m_lightPos.y, m_lightPos.z, 0.0f };
GLfloat light_color[4]; // color of lights (RGBA values)
light_color[3] = 1.0;
// Light above the xy plane
light_color[0] = light_color[1] = light_color[2] = 0.1;
light_color[0] = light_color[1] = light_color[2] = 0.2;
glLightfv( GL_LIGHT0, GL_AMBIENT, light_color );
light_color[0] = light_color[1] = light_color[2] = 1.0;
@ -580,7 +599,7 @@ void EDA_3D_CANVAS::SetLights()
glLightfv( GL_LIGHT0, GL_POSITION, source_pos );
light_color[0] = light_color[1] = light_color[2] = 0.1;
light_color[0] = light_color[1] = light_color[2] = 0.2;
glLightModelfv( GL_LIGHT_MODEL_AMBIENT, light_color );
glEnable( GL_LIGHT0 ); // White spot on Z axis ( top )

View File

@ -43,7 +43,9 @@
#endif
#include <3d_struct.h>
#include <modelparsers.h>
#include <class_module.h>
#include <CBBox.h>
class BOARD_DESIGN_SETTINGS;
class EDA_3D_FRAME;
@ -78,16 +80,15 @@ class EDA_3D_CANVAS : public wxGLCanvas
{
private:
bool m_init;
bool m_reportWarnings; // true to report all wranings when build the 3D scene
// false to report errors only
GLuint m_glLists[GL_ID_END]; // GL lists
bool m_reportWarnings; ///< true to report all wranings when build the 3D scene false to report errors only
GLuint m_glLists[GL_ID_END]; ///< GL lists
wxGLContext* m_glRC;
wxRealPoint m_draw3dOffset; // offset to draw the 3D mesh.
double m_ZBottom; // position of the back layer
double m_ZTop; // position of the front layer
wxRealPoint m_draw3dOffset; ///< offset to draw the 3D mesh.
double m_ZBottom; ///< position of the back layer
double m_ZTop; ///< position of the front layer
GLuint m_text_pcb; // an index to the texture generated for pcb texts
GLuint m_text_silk; // an index to the texture generated for silk layers
GLuint m_text_pcb; ///< an index to the texture generated for pcb texts
GLuint m_text_silk; ///< an index to the texture generated for silk layers
// Index to the textures generated for shadows
bool m_shadow_init;
@ -95,9 +96,21 @@ private:
GLuint m_text_fake_shadow_back;
GLuint m_text_fake_shadow_board;
void Create_and_Render_Shadow_Buffer( GLuint *aDst_gl_texture,
CBBOX m_boardAABBox; ///< Axis Align Bounding Box of the board
CBBOX m_fastAABBox; ///< Axis Align Bounding Box that contain the other bounding boxes
CBBOX m_fastAABBox_Shadow; ///< A bit scalled version of the m_fastAABBox
S3D_VERTEX m_lightPos;
/// Stores the list of parsers for each new file name (dont repeat files already loaded)
std::vector<S3D_MODEL_PARSER *> m_model_parsers_list;
std::vector<wxString> m_model_filename_list;
void create_and_render_shadow_buffer( GLuint *aDst_gl_texture,
GLuint aTexture_size, bool aDraw_body, int aBlurPasses );
void calcBBox();
public:
EDA_3D_CANVAS( EDA_3D_FRAME* parent, int* attribList = 0 );
~EDA_3D_CANVAS();
@ -187,33 +200,33 @@ private:
wxPoint getBoardCenter() const;
/**
* Helper function SetGLTechLayersColor
* Helper function setGLTechLayersColor
* Initialize the color to draw the non copper layers
* in realistic mode and normal mode.
*/
void setGLTechLayersColor( LAYER_NUM aLayer );
/**
* Helper function SetGLCopperColor
* Helper function setGLCopperColor
* Initialize the copper color to draw the board
* in realistic mode (a golden yellow color )
*/
void setGLCopperColor();
/**
* Helper function SetGLEpoxyColor
* Helper function setGLEpoxyColor
* Initialize the color to draw the epoxy body board in realistic mode.
*/
void setGLEpoxyColor( float aTransparency = 1.0 );
/**
* Helper function SetGLSolderMaskColor
* Helper function setGLSolderMaskColor
* Initialize the color to draw the solder mask layers in realistic mode.
*/
void setGLSolderMaskColor( float aTransparency = 1.0 );
/**
* Function BuildBoard3DView
* Function buildBoard3DView
* Called by CreateDrawGL_List()
* Populates the OpenGL GL_ID_BOARD draw list with board items only on copper layers.
* 3D footprint shapes, tech layers and aux layers are not on this list
@ -224,27 +237,27 @@ private:
* created by the build process (can be NULL)
* @param aShowWarnings = true to show all messages, false to show errors only
*/
void BuildBoard3DView( GLuint aBoardList, GLuint aBodyOnlyList,
void buildBoard3DView( GLuint aBoardList, GLuint aBodyOnlyList,
wxString* aErrorMessages, bool aShowWarnings );
/**
* Function BuildTechLayers3DView
* Function buildTechLayers3DView
* Called by CreateDrawGL_List()
* Populates the OpenGL GL_ID_TECH_LAYERS draw list with items on tech layers
* @param aErrorMessages = a wxString to add error and warning messages
* created by the build process (can be NULL)
* @param aShowWarnings = true to show all messages, false to show errors only
*/
void BuildTechLayers3DView( wxString* aErrorMessages, bool aShowWarnings );
void buildTechLayers3DView( wxString* aErrorMessages, bool aShowWarnings );
/**
* Function BuildShadowList
* Function buildShadowList
* Called by CreateDrawGL_List()
*/
void BuildShadowList( GLuint aFrontList, GLuint aBacklist, GLuint aBoardList );
void buildShadowList( GLuint aFrontList, GLuint aBacklist, GLuint aBoardList );
/**
* Function BuildFootprintShape3DList
* Function buildFootprintShape3DList
* Called by CreateDrawGL_List()
* Fills the OpenGL GL_ID_3DSHAPES_SOLID and GL_ID_3DSHAPES_TRANSP
* draw lists with 3D footprint shapes
@ -252,19 +265,18 @@ private:
* @param aTransparentList is the gl list for non transparent items,
* which need to be drawn after all other items
*/
void BuildFootprintShape3DList( GLuint aOpaqueList,
GLuint aTransparentList,
bool aSideToLoad );
void buildFootprintShape3DList( GLuint aOpaqueList,
GLuint aTransparentList );
/**
* Function BuildBoard3DAuxLayers
* Function buildBoard3DAuxLayers
* Called by CreateDrawGL_List()
* Fills the OpenGL GL_ID_AUX_LAYERS draw list
* with items on aux layers only
*/
void BuildBoard3DAuxLayers();
void buildBoard3DAuxLayers();
void Draw3DGrid( double aGriSizeMM );
void Draw3DAxis();
void draw3DGrid( double aGriSizeMM );
void draw3DAxis();
/**
* Helper function BuildPadShapeThickOutlineAsPolygon:
@ -272,7 +284,7 @@ private:
* with a line thickness = aWidth
* Used only to draw pads outlines on silkscreen layers.
*/
void BuildPadShapeThickOutlineAsPolygon( const D_PAD* aPad,
void buildPadShapeThickOutlineAsPolygon( const D_PAD* aPad,
CPOLYGONS_LIST& aCornerBuffer,
int aWidth,
int aCircleToSegmentsCount,
@ -280,54 +292,48 @@ private:
/**
* Helper function Draw3DViaHole:
* Helper function draw3DViaHole:
* Draw the via hole:
* Build a vertical hole (a cylinder) between the first and the last via layers
*/
void Draw3DViaHole( const VIA * aVia );
void draw3DViaHole( const VIA * aVia );
/**
* Helper function Draw3DPadHole:
* Helper function draw3DPadHole:
* Draw the pad hole:
* Build a vertical hole (round or oblong) between the front and back layers
*/
void Draw3DPadHole( const D_PAD * aPad );
void draw3DPadHole( const D_PAD * aPad );
/**
* function Render3DComponentShape
* function render3DComponentShape
* insert mesh in gl list
* @param module
* @param aIsRenderingJustNonTransparentObjects = true to load non transparent objects
* @param aIsRenderingJustTransparentObjects = true to load non transparent objects
* @param aSideToLoad = false will load not fliped, true will load fliped objects
* in openGL, transparent objects should be drawn *after* non transparent objects
*/
void Render3DComponentShape( MODULE* module,
void render3DComponentShape( MODULE* module,
bool aIsRenderingJustNonTransparentObjects,
bool aIsRenderingJustTransparentObjects,
bool aSideToLoad );
bool aIsRenderingJustTransparentObjects );
/**
* function Read3DComponentShape
* function read3DComponentShape
* read the 3D component shape(s) of the footprint (physical shape).
* @param module
* @param model_parsers_list = list of each new model loaded
* @param model_filename_list = list of each new filename model loaded
* @return true if load was succeeded, false otherwise
*/
bool Read3DComponentShape( MODULE* module,
std::vector<S3D_MODEL_PARSER *>& model_parsers_list,
std::vector<wxString>& model_filename_list );
bool read3DComponentShape( MODULE* module );
/**
* function GenerateFakeShadowsTextures
* function generateFakeShadowsTextures
* creates shadows of the board an footprints
* for aesthetical purpose
* @param aErrorMessages = a wxString to add error and warning messages
* created by the build process (can be NULL)
* @param aShowWarnings = true to show all messages, false to show errors only
*/
void GenerateFakeShadowsTextures( wxString* aErrorMessages, bool aShowWarnings );
void generateFakeShadowsTextures( wxString* aErrorMessages, bool aShowWarnings );
DECLARE_EVENT_TABLE()
};

View File

@ -1,7 +1,3 @@
/**
* @file 3d_class.cpp
*/
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
@ -25,7 +21,10 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file 3d_class.cpp
*/
#include <fctsys.h>
#include "3d_viewer.h"
@ -79,12 +78,14 @@ S3D_MASTER:: ~S3D_MASTER()
{
next = m_3D_Drawings->Next();
delete m_3D_Drawings;
m_3D_Drawings = 0;
}
for( ; m_Materials != NULL; m_Materials = nextmat )
{
nextmat = m_Materials->Next();
delete m_Materials;
m_Materials = 0;
}
}
@ -115,19 +116,59 @@ void S3D_MASTER::SetShape3DName( const wxString& aShapeName )
return;
wxFileName fn = m_Shape3DName;
wxString ext = fn.GetExt();
m_Shape3DNameExtension = fn.GetExt();
if( ext == wxT( "wrl" ) || ext == wxT( "x3d" ) )
if( m_Shape3DNameExtension == wxT( "wrl" ) ||
m_Shape3DNameExtension == wxT( "x3d" ) )
m_ShapeType = FILE3D_VRML;
else if( ext == wxT( "idf" ) )
else if( m_Shape3DNameExtension == wxT( "idf" ) )
m_ShapeType = FILE3D_IDF;
else
m_ShapeType = FILE3D_UNKNOWN;
// Expand any environment variables embedded in footprint's m_Shape3DName field.
// To ensure compatibility with most of footprint's m_Shape3DName field,
// if the m_Shape3DName is not an absolute path the default path
// given by the environment variable KISYS3DMOD will be used
if( m_Shape3DName.StartsWith( wxT("${") ) )
m_Shape3DFullFilename = wxExpandEnvVars( m_Shape3DName );
else
m_Shape3DFullFilename = m_Shape3DName;
wxFileName fnFull( m_Shape3DFullFilename );
if( !( fnFull.IsAbsolute() || m_Shape3DFullFilename.StartsWith( wxT(".") ) ) )
{
wxString default_path;
wxGetEnv( KISYS3DMOD, &default_path );
if( !( default_path.IsEmpty() ) )
{
if( !default_path.EndsWith( wxT("/") ) && !default_path.EndsWith( wxT("\\") ) )
default_path += wxT("/");
m_Shape3DFullFilename = default_path + m_Shape3DFullFilename;
}
}
return;
}
const wxString S3D_MASTER::GetShape3DFullFilename()
{
return m_Shape3DFullFilename;
}
const wxString S3D_MASTER::GetShape3DExtension()
{
return m_Shape3DNameExtension;
}
STRUCT_3D_SHAPE::STRUCT_3D_SHAPE( EDA_ITEM* aParent ) :
EDA_ITEM( aParent, NOT_USED )
{

File diff suppressed because it is too large Load Diff

View File

@ -36,7 +36,7 @@
#include <modelparsers.h>
// Number of segments to approximate a circle by segments
#define SEGM_PER_CIRCLE 16
#define SEGM_PER_CIRCLE 24
#ifndef CALLBACK
#define CALLBACK
@ -57,12 +57,12 @@ static void CALLBACK tessCPolyPt2Vertex( const GLvoid* data );
// 2 helper functions to set the current normal vector for gle items
static inline void SetNormalZpos()
{
//glNormal3f( 0.0, 0.0, 1.0 );
glNormal3f( 0.0, 0.0, 1.0 );
}
static inline void SetNormalZneg()
{
//glNormal3f( 0.0, 0.0, -1.0 );
glNormal3f( 0.0, 0.0, -1.0 );
}
void TransfertToGLlist( std::vector< S3D_VERTEX >& aVertices, double aBiuTo3DUnits );
@ -203,7 +203,8 @@ void Draw3D_SolidHorizontalPolyPolygons( const CPOLYGONS_LIST& aPolysList,
}
// https://www.opengl.org/sdk/docs/man2/xhtml/gluTessNormal.xml
gluTessNormal( tess, 0.0, 0.0, 0.0 );
if( !aThickness )
gluTessNormal( tess, 0.0, 0.0, 0.0 );
v_data[0] = polylist.GetX( ii ) * aBiuTo3DUnits;
@ -231,7 +232,8 @@ void Draw3D_SolidHorizontalPolyPolygons( const CPOLYGONS_LIST& aPolysList,
s_currentZpos = zpos; // for Tess callback functions
v_data[2] = zpos;
// Set normal toward negative Z axis, for a solid object on bottom side
SetNormalZneg();
if( aThickness )
SetNormalZneg();
}
if( startContour == 0 )
@ -248,7 +250,7 @@ void Draw3D_SolidHorizontalPolyPolygons( const CPOLYGONS_LIST& aPolysList,
}
// Build the 3D data : vertical side
Draw3D_VerticalPolygonalCylinder( polylist, aThickness, aZpos - (aThickness / 2.0), false, aBiuTo3DUnits );
Draw3D_VerticalPolygonalCylinder( polylist, aThickness, aZpos - (aThickness / 2.0), true, aBiuTo3DUnits );
}
@ -292,9 +294,11 @@ void Draw3D_ZaxisCylinder( wxPoint aCenterPos, int aRadius,
if( aHeight )
{
// Draw the vertical outer side
Draw3D_VerticalPolygonalCylinder( outer_cornerBuffer,
aHeight, aZpos, false, aBiuTo3DUnits );
if( aThickness )
// Draws the vertical inner side (hole)
Draw3D_VerticalPolygonalCylinder( inner_cornerBuffer,

View File

@ -181,7 +181,7 @@ void EDA_3D_CANVAS::setGLTechLayersColor( LAYER_NUM aLayer )
}
}
void EDA_3D_CANVAS::Draw3DAxis()
void EDA_3D_CANVAS::draw3DAxis()
{
if( ! m_glLists[GL_ID_AXIS] )
{
@ -207,7 +207,7 @@ void EDA_3D_CANVAS::Draw3DAxis()
// draw a 3D grid: an horizontal grid (XY plane and Z = 0,
// and a vertical grid (XZ plane and Y = 0)
void EDA_3D_CANVAS::Draw3DGrid( double aGriSizeMM )
void EDA_3D_CANVAS::draw3DGrid( double aGriSizeMM )
{
double zpos = 0.0;
EDA_COLOR_T gridcolor = DARKGRAY; // Color of grid lines
@ -343,7 +343,7 @@ void EDA_3D_CANVAS::Draw3DGrid( double aGriSizeMM )
// Draw 3D pads.
void EDA_3D_CANVAS::Draw3DPadHole( const D_PAD* aPad )
void EDA_3D_CANVAS::draw3DPadHole( const D_PAD* aPad )
{
// Draw the pad hole
wxSize drillsize = aPad->GetDrillSize();
@ -363,13 +363,13 @@ void EDA_3D_CANVAS::Draw3DPadHole( const D_PAD* aPad )
else
SetGLColor( DARKGRAY );
int holeZpoz = GetPrm3DVisu().GetLayerZcoordBIU( B_Cu ) + thickness / 2;
int holeHeight = height - thickness;
int holeZpoz = GetPrm3DVisu().GetLayerZcoordBIU( B_Cu ) - thickness / 2;
int holeHeight = height + thickness;
if( drillsize.x == drillsize.y ) // usual round hole
{
Draw3D_ZaxisCylinder( aPad->GetPosition(),
(drillsize.x + thickness) / 2, holeHeight,
(drillsize.x + thickness / 2) / 2, holeHeight,
thickness, holeZpoz, GetPrm3DVisu().m_BiuTo3Dunits );
}
else // Oblong hole
@ -401,11 +401,11 @@ void EDA_3D_CANVAS::Draw3DPadHole( const D_PAD* aPad )
}
void EDA_3D_CANVAS::Draw3DViaHole( const VIA* aVia )
void EDA_3D_CANVAS::draw3DViaHole( const VIA* aVia )
{
LAYER_ID top_layer, bottom_layer;
int inner_radius = aVia->GetDrillValue() / 2;
int thickness = GetPrm3DVisu().GetCopperThicknessBIU();
int inner_radius = (int)((float)aVia->GetDrillValue() * 1.01f) / 2.0f; // This add a bit more in order to correct a draw artifact while using tickness
aVia->LayerPair( &top_layer, &bottom_layer );
@ -419,17 +419,17 @@ void EDA_3D_CANVAS::Draw3DViaHole( const VIA* aVia )
}
int height = GetPrm3DVisu().GetLayerZcoordBIU( top_layer ) -
GetPrm3DVisu().GetLayerZcoordBIU( bottom_layer ) - thickness;
int zpos = GetPrm3DVisu().GetLayerZcoordBIU( bottom_layer ) + thickness / 2;
GetPrm3DVisu().GetLayerZcoordBIU( bottom_layer ) + thickness;
int zpos = GetPrm3DVisu().GetLayerZcoordBIU( bottom_layer ) - thickness / 2;
Draw3D_ZaxisCylinder( aVia->GetStart(), inner_radius + thickness / 2, height,
Draw3D_ZaxisCylinder( aVia->GetStart(), inner_radius, height,
thickness, zpos, GetPrm3DVisu().m_BiuTo3Dunits );
}
/* Build a pad outline as non filled polygon, to draw pads on silkscreen layer
* Used only to draw pads outlines on silkscreen layers.
*/
void EDA_3D_CANVAS::BuildPadShapeThickOutlineAsPolygon( const D_PAD* aPad,
void EDA_3D_CANVAS::buildPadShapeThickOutlineAsPolygon( const D_PAD* aPad,
CPOLYGONS_LIST& aCornerBuffer,
int aWidth,
int aCircleToSegmentsCount,

View File

@ -57,6 +57,7 @@ static const wxChar keyRenderTextures[] = wxT( "Render_Textures" );
static const wxChar keyRenderSmoothNormals[] = wxT( "Render_Smooth_Normals" );
static const wxChar keyRenderUseModelNormals[] =wxT( "Render_Use_Model_Normals" );
static const wxChar keyRenderMaterial[] = wxT( "Render_Material" );
static const wxChar keyRenderShowModelBBox[] = wxT( "Render_ShowModelBoudingBoxes" );
static const wxChar keyShowAxis[] = wxT( "ShowAxis" );
static const wxChar keyShowGrid[] = wxT( "ShowGrid3D" );
@ -257,6 +258,9 @@ void EDA_3D_FRAME::LoadSettings( wxConfigBase* aCfg )
aCfg->Read( keyRenderMaterial, &tmp, false );
prms.SetFlag( FL_RENDER_MATERIAL, tmp );
aCfg->Read( keyRenderShowModelBBox, &tmp, false );
prms.SetFlag( FL_RENDER_SHOW_MODEL_BBOX, tmp );
aCfg->Read( keyShowAxis, &tmp, true );
prms.SetFlag( FL_AXIS, tmp );
@ -319,7 +323,8 @@ void EDA_3D_FRAME::SaveSettings( wxConfigBase* aCfg )
aCfg->Write( keyRenderSmoothNormals, prms.GetFlag( FL_RENDER_SMOOTH_NORMALS ) );
aCfg->Write( keyRenderUseModelNormals, prms.GetFlag( FL_RENDER_USE_MODEL_NORMALS ) );
aCfg->Write( keyRenderMaterial, prms.GetFlag( FL_RENDER_MATERIAL ) );
aCfg->Write( keyRenderShowModelBBox, prms.GetFlag( FL_RENDER_SHOW_MODEL_BBOX ) );
aCfg->Write( keyShowAxis, prms.GetFlag( FL_AXIS ) );
aCfg->Write( keyShowGrid, prms.GetFlag( FL_GRID ) );
aCfg->Write( keyShowGridSize, prms.m_3D_Grid );
@ -509,6 +514,11 @@ void EDA_3D_FRAME::Process_Special_Functions( wxCommandEvent& event )
NewDisplay();
return;
case ID_MENU3D_FL_RENDER_SHOW_MODEL_BBOX:
GetPrm3DVisu().SetFlag( FL_RENDER_SHOW_MODEL_BBOX, isChecked );
NewDisplay();
return;
case ID_MENU3D_SHOW_BOARD_BODY:
GetPrm3DVisu().SetFlag( FL_SHOW_BOARD_BODY, isChecked );
NewDisplay();
@ -526,43 +536,43 @@ void EDA_3D_FRAME::Process_Special_Functions( wxCommandEvent& event )
case ID_MENU3D_USE_COPPER_THICKNESS:
GetPrm3DVisu().SetFlag( FL_USE_COPPER_THICKNESS, isChecked );
NewDisplay(GL_ID_BOARD);
NewDisplay(GL_ID_TECH_LAYERS);
NewDisplay( GL_ID_BOARD );
NewDisplay( GL_ID_TECH_LAYERS );
return;
case ID_MENU3D_ZONE_ONOFF:
GetPrm3DVisu().SetFlag( FL_ZONE, isChecked );
NewDisplay(GL_ID_BOARD);
NewDisplay( GL_ID_BOARD );
return;
case ID_MENU3D_ADHESIVE_ONOFF:
GetPrm3DVisu().SetFlag( FL_ADHESIVE, isChecked );
NewDisplay(GL_ID_TECH_LAYERS);
NewDisplay( GL_ID_TECH_LAYERS );
return;
case ID_MENU3D_SILKSCREEN_ONOFF:
GetPrm3DVisu().SetFlag( FL_SILKSCREEN, isChecked );
NewDisplay(GL_ID_TECH_LAYERS);
NewDisplay( GL_ID_TECH_LAYERS );
return;
case ID_MENU3D_SOLDER_MASK_ONOFF:
GetPrm3DVisu().SetFlag( FL_SOLDERMASK, isChecked );
NewDisplay(GL_ID_TECH_LAYERS);
NewDisplay( GL_ID_TECH_LAYERS );
return;
case ID_MENU3D_SOLDER_PASTE_ONOFF:
GetPrm3DVisu().SetFlag( FL_SOLDERPASTE, isChecked );
NewDisplay(GL_ID_TECH_LAYERS);
NewDisplay();
return;
case ID_MENU3D_COMMENTS_ONOFF:
GetPrm3DVisu().SetFlag( FL_COMMENTS, isChecked );
NewDisplay(GL_ID_AUX_LAYERS);
NewDisplay( GL_ID_AUX_LAYERS );
return;
case ID_MENU3D_ECO_ONOFF:
GetPrm3DVisu().SetFlag( FL_ECO, isChecked );
NewDisplay(GL_ID_AUX_LAYERS);
NewDisplay( GL_ID_AUX_LAYERS );
return;
default:

View File

@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014 Mario Luzeiro <mrluzeiro@gmail.com>
* Copyright (C) 2014-2015 Mario Luzeiro <mrluzeiro@gmail.com>
* Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
@ -55,10 +55,10 @@ S3D_MATERIAL::S3D_MATERIAL( S3D_MASTER* father, const wxString& name ) :
void SetOpenGlDefaultMaterial()
{
glm::vec4 ambient( 0.2, 0.2, 0.2, 1.0 );
glm::vec4 specular( 0.0, 0.0, 0.0, 1.0 );
glm::vec4 emissive( 0.0, 0.0, 0.0, 1.0 );
glm::vec4 diffuse( 0.0, 0.0, 0.0, 1.0 );
glm::vec4 ambient( 0.2f, 0.2f, 0.2f, 1.0f );
glm::vec4 specular( 0.0f, 0.0f, 0.0f, 1.0f );
glm::vec4 emissive( 0.0f, 0.0f, 0.0f, 1.0f );
glm::vec4 diffuse( 0.0f, 0.0f, 0.0f, 1.0f );
GLint shininess_value = 0;
glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE );

View File

@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014 Mario Luzeiro <mrluzeiro@gmail.com>
* Copyright (C) 2014-2015 Mario Luzeiro <mrluzeiro@gmail.com>
* Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
@ -45,8 +45,8 @@ public:
std::vector< glm::vec3 > m_DiffuseColor;
std::vector< glm::vec3 > m_EmissiveColor;
std::vector< glm::vec3 > m_SpecularColor;
std::vector< float > m_Shininess;
std::vector< float > m_Transparency;
std::vector< float > m_Shininess;
std::vector< float > m_Transparency;
public:
S3D_MATERIAL( S3D_MASTER* father, const wxString& name );

View File

@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014 Mario Luzeiro <mrluzeiro@gmail.com>
* Copyright (C) 2014-2015 Mario Luzeiro <mrluzeiro@gmail.com>
* Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
@ -27,33 +27,130 @@
* @brief
*/
#include <fctsys.h>
#include <3d_mesh_model.h>
#include <boost/geometry/algorithms/area.hpp>
#include <gal/opengl/glm/gtc/matrix_transform.hpp>
#include <gal/opengl/glm/glm.hpp>
#ifdef __WXMAC__
# ifdef __DARWIN__
# include <OpenGL/glu.h>
# else
# include <glu.h>
# endif
#else
# include <GL/glu.h>
#endif
#ifdef USE_OPENMP
#include <omp.h>
#endif // USE_OPENMP
#include "info3d_visu.h"
S3D_MESH::S3D_MESH()
{
isPerFaceNormalsComputed = false;
isPointNormalizedComputed = false;
isPerPointNormalsComputed = false;
isPerVertexNormalsVerified = false;
isPerFaceNormalsComputed = false;
isPointNormalizedComputed = false;
isPerPointNormalsComputed = false;
isPerVertexNormalsVerified = false;
m_Materials = NULL;
childs.clear();
m_translation = glm::vec3( 0.0f, 0.0f, 0.0f );
m_rotation = glm::vec4( 0.0f, 0.0f, 0.0f, 0.0f );
m_scale = glm::vec3( 1.0f, 1.0f, 1.0f );
m_scaleOrientation = glm::vec4( 0.0f, 0.0f, 1.0f, 0.0f ); // not used
m_center = glm::vec3( 0.0f, 0.0f, 0.0f ); // not used
m_translation = glm::vec3( 0.0f, 0.0f, 0.0f );
m_rotation = glm::vec4( 0.0f, 0.0f, 0.0f, 0.0f );
m_scale = glm::vec3( 1.0f, 1.0f, 1.0f );
}
S3D_MESH::~S3D_MESH()
{
for( unsigned int idx = 0; idx < childs.size(); idx++ )
{
if( childs[idx] )
{
delete childs[idx];
}
}
}
CBBOX &S3D_MESH::getBBox( )
{
if( !m_BBox.IsInitialized() )
calcBBoxAllChilds();
return m_BBox;
}
void S3D_MESH::calcBBoxAllChilds( )
{
// Calc your own boudingbox
calcBBox();
for( unsigned int idx = 0; idx < childs.size(); idx++ )
m_BBox.Union( childs[idx]->getBBox() );
CBBOX tmpBBox = m_BBox;
// Calc transformation matrix
glm::mat4 fullTransformMatrix;
glm::mat4 translationMatrix = glm::translate( glm::mat4(), m_translation );
if( m_rotation[3] != 0.0f )
{
glm::mat4 rotationMatrix = glm::rotate( translationMatrix, m_rotation[3],
S3D_VERTEX( m_rotation[0], m_rotation[1], m_rotation[2] ) );
fullTransformMatrix = glm::scale( rotationMatrix, m_scale );
}
else
fullTransformMatrix = glm::scale( translationMatrix, m_scale );
// Apply transformation
m_BBox.Set( S3D_VERTEX( fullTransformMatrix * glm::vec4( tmpBBox.Min(), 1.0f ) ),
S3D_VERTEX( fullTransformMatrix * glm::vec4( tmpBBox.Max(), 1.0f ) ) );
}
void S3D_MESH::calcBBox( )
{
CBBOX tmpBBox;
bool firstBBox = true;
bool useMaterial = g_Parm_3D_Visu.GetFlag( FL_RENDER_MATERIAL );
// Do not add complete transparent materials
if( useMaterial && (m_Materials != 0) && ( m_MaterialIndex.size() == 0 ) )
if( m_Materials->m_Transparency.size() > 0 )
if( m_Materials->m_Transparency[0] >= 1.0f )
return;
// Calc boudingbox for all coords
for( unsigned int idx = 0; idx < m_CoordIndex.size(); idx++ )
{
// Do not add complete transparent materials
if( useMaterial && (m_Materials != 0) && ( m_MaterialIndex.size() > idx ) )
if( (int)m_Materials->m_Transparency.size() > m_MaterialIndex[idx] )
if( m_Materials->m_Transparency[m_MaterialIndex[idx]] >= 1.0f )
continue;
for( unsigned int ii = 0; ii < m_CoordIndex[idx].size(); ii++ )
if( firstBBox )
{
firstBBox = false;
tmpBBox = CBBOX( m_Point[m_CoordIndex[idx][ii]] ); // Initialize with the first vertex found
}
else
tmpBBox.Union( m_Point[m_CoordIndex[idx][ii]] );
}
m_BBox = tmpBBox;
}
@ -72,11 +169,11 @@ void S3D_MESH::openGL_RenderAllChilds( bool aIsRenderingJustNonTransparentObjec
openGL_Render( aIsRenderingJustNonTransparentObjects,
aIsRenderingJustTransparentObjects );
// Render childs
// Render childs recursively
for( unsigned int idx = 0; idx < childs.size(); idx++ )
{
childs[idx]->openGL_Render( aIsRenderingJustNonTransparentObjects,
aIsRenderingJustTransparentObjects );
childs[idx]->openGL_RenderAllChilds( aIsRenderingJustNonTransparentObjects,
aIsRenderingJustTransparentObjects );
}
SetOpenGlDefaultMaterial();
@ -142,7 +239,7 @@ void S3D_MESH::openGL_Render( bool aIsRenderingJustNonTransparentObjects,
{
if( m_Materials )
{
if ( m_MaterialIndex.size() > 0 )
if ( m_MaterialIndex.size() > idx )
{
bool isTransparent = m_Materials->SetOpenGLMaterial( m_MaterialIndex[idx], useMaterial );
@ -153,9 +250,9 @@ void S3D_MESH::openGL_Render( bool aIsRenderingJustNonTransparentObjects,
continue;
if( useMaterial )
if( m_Materials->m_Transparency.size() > idx )
if( m_Materials->m_Transparency[idx] >= 1.0f )
return;
if( (int)m_Materials->m_Transparency.size() > m_MaterialIndex[idx] )
if( m_Materials->m_Transparency[m_MaterialIndex[idx]] >= 1.0f )
continue;
}
else
{
@ -270,37 +367,37 @@ void S3D_MESH::perVertexNormalsVerify_and_Repair()
{
glm::vec3 normal = m_PerVertexNormalsNormalized[idx];
if( (normal.x == 1.0) && ((normal.y != 0.0) || (normal.z != 0.0)) )
if( (normal.x == 1.0f) && ((normal.y != 0.0f) || (normal.z != 0.0f)) )
{
normal.y = 0.0;
normal.z = 0.0;
normal.y = 0.0f;
normal.z = 0.0f;
}
else
if( (normal.y == 1.0) && ((normal.x != 0.0) || (normal.z != 0.0)) )
if( (normal.y == 1.0f) && ((normal.x != 0.0f) || (normal.z != 0.0f)) )
{
normal.x = 0.0;
normal.z = 0.0;
normal.x = 0.0f;
normal.z = 0.0f;
}
else
if( (normal.z == 1.0) && ((normal.x != 0.0) || (normal.y != 0.0)) )
if( (normal.z == 1.0f) && ((normal.x != 0.0f) || (normal.y != 0.0f)) )
{
normal.x = 0.0;
normal.y = 0.0;
normal.x = 0.0f;
normal.y = 0.0f;
}
else
if( (normal.x < FLT_EPSILON) && (normal.x > -FLT_EPSILON) )
{
normal.x = 0.0;
normal.x = 0.0f;
}
else
if( (normal.y < FLT_EPSILON) && (normal.y > -FLT_EPSILON) )
{
normal.y = 0.0;
normal.y = 0.0f;
}
else
if( (normal.z < FLT_EPSILON) && (normal.z > -FLT_EPSILON) )
{
normal.z = 0.0;
normal.z = 0.0f;
}
float l = glm::length( normal );
@ -328,10 +425,6 @@ void S3D_MESH::calcPointNormalized()
isPointNormalizedComputed = true;
/*
m_PointNormalized = m_Point;
*/
m_PointNormalized.clear();
m_PointNormalized.resize( m_Point.size() );
@ -406,9 +499,9 @@ void S3D_MESH::calcPerFaceNormals()
{
glm::vec3 cross_prod;
cross_prod.x = 0.0;
cross_prod.y = 0.0;
cross_prod.z = 0.0;
cross_prod.x = 0.0f;
cross_prod.y = 0.0f;
cross_prod.z = 0.0f;
// Newell's Method
// http://www.opengl.org/wiki/Calculating_a_Surface_Normal
@ -434,15 +527,6 @@ void S3D_MESH::calcPerFaceNormals()
float area = glm::dot( cross_prod, cross_prod );
area = fabs( area );
// Dont remmember why this code was used for..
/*
if( cross_prod[2] < 0.0 )
area = -area;
if( area < FLT_EPSILON )
area = FLT_EPSILON * 2.0f;
*/
m_PerFaceNormalsRaw_X_PerFaceSquaredArea[idx] = cross_prod * area;
if( haveAlreadyNormals_from_model_file == false )
@ -456,35 +540,35 @@ void S3D_MESH::calcPerFaceNormals()
}
else
{
DBG( printf( "Cannot calc normal idx: %u cross(%f, %f, %f) l:%f m_CoordIndex[idx].size: %u\n",
/* DBG( printf( "Cannot calc normal idx: %u cross(%f, %f, %f) l:%f m_CoordIndex[idx].size: %u\n",
idx,
cross_prod.x, cross_prod.y, cross_prod.z,
l,
(unsigned int)m_CoordIndex[idx].size()) );
*/
if( ( cross_prod.x > cross_prod.y ) && ( cross_prod.x > cross_prod.z ) )
{
cross_prod.x = 0.0;
cross_prod.y = 1.0;
cross_prod.z = 0.0;
cross_prod.x = 0.0f;
cross_prod.y = 1.0f;
cross_prod.z = 0.0f;
}
else if( ( cross_prod.y > cross_prod.x ) && ( cross_prod.y > cross_prod.z ) )
{
cross_prod.x = 0.0;
cross_prod.y = 1.0;
cross_prod.z = 0.0;
cross_prod.x = 0.0f;
cross_prod.y = 1.0f;
cross_prod.z = 0.0f;
}
else if( ( cross_prod.z > cross_prod.x ) && ( cross_prod.z > cross_prod.y ) )
{
cross_prod.x = 0.0;
cross_prod.y = 0.0;
cross_prod.z = 1.0;
cross_prod.x = 0.0f;
cross_prod.y = 0.0f;
cross_prod.z = 1.0f;
}
else
{
cross_prod.x = 0.0;
cross_prod.y = 0.0;
cross_prod.z = 0.0;
cross_prod.x = 0.0f;
cross_prod.y = 0.0f;
cross_prod.z = 0.0f;
}
}
@ -494,6 +578,7 @@ void S3D_MESH::calcPerFaceNormals()
}
// Documentation literature
// http://www.bytehazard.com/code/vertnorm.html
// http://www.emeyex.com/site/tuts/VertexNormals.pdf
void S3D_MESH::calcPerPointNormals()

View File

@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014 Mario Luzeiro <mrluzeiro@gmail.com>
* Copyright (C) 2014-2015 Mario Luzeiro <mrluzeiro@gmail.com>
* Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
@ -30,24 +30,12 @@
#ifndef __3D_MESH_MODEL_H__
#define __3D_MESH_MODEL_H__
#include <fctsys.h>
#include <common.h>
#include <macros.h>
#include <base_struct.h>
#include <gal/opengl/glm/glm.hpp>
#include <vector>
#include <kicad_string.h>
#include <info3d_visu.h>
#ifdef __WXMAC__
# ifdef __DARWIN__
# include <OpenGL/glu.h>
# else
# include <glu.h>
# endif
#else
# include <GL/glu.h>
#endif
#include <wx/glcanvas.h>
#include <gal/opengl/glm/glm.hpp>
#include "3d_struct.h"
#include "3d_material.h"
#include "CBBox.h"
class S3D_MESH;
@ -59,33 +47,31 @@ public:
~S3D_MESH();
void openGL_RenderAllChilds( bool aIsRenderingJustNonTransparentObjects,
bool aIsRenderingJustTransparentObjects );
bool aIsRenderingJustTransparentObjects );
S3D_MATERIAL *m_Materials;
S3D_MATERIAL *m_Materials;
// Point and index list
std::vector< glm::vec3 > m_Point;
std::vector< S3D_VERTEX > m_Point;
std::vector< std::vector<int> > m_CoordIndex;
std::vector< std::vector<int> > m_NormalIndex;
std::vector< glm::vec3 > m_PerFaceNormalsNormalized;
std::vector< glm::vec3 > m_PerVertexNormalsNormalized;
std::vector< S3D_VERTEX > m_PerFaceNormalsNormalized;
std::vector< S3D_VERTEX > m_PerVertexNormalsNormalized;
std::vector< int > m_MaterialIndex;
std::vector< S3D_MESH * > childs;
std::vector< int > m_MaterialIndex;
S3D_VERTEX m_translation;
glm::vec4 m_rotation;
S3D_VERTEX m_scale;
glm::vec3 m_translation;
glm::vec4 m_rotation;
glm::vec3 m_scale;
glm::vec4 m_scaleOrientation; // not used
glm::vec3 m_center; // not used
std::vector<S3D_MESH *> childs;
CBBOX &getBBox();
private:
std::vector< glm::vec3 > m_PerFaceNormalsRaw_X_PerFaceSquaredArea;
std::vector< std::vector< glm::vec3 > > m_PerFaceVertexNormals;
std::vector< glm::vec3 > m_PointNormalized;
std::vector< S3D_VERTEX > m_PerFaceNormalsRaw_X_PerFaceSquaredArea;
std::vector< std::vector< S3D_VERTEX > > m_PerFaceVertexNormals;
std::vector< S3D_VERTEX > m_PointNormalized;
std::vector< std::vector<int> > m_InvalidCoordIndexes; //!TODO: check for invalid CoordIndex in file and remove the index and the same material index
std::vector< std::vector<int> > m_InvalidCoordIndexes; //!TODO: check for invalid CoordIndex in file and remove the index and the same material index
bool isPerFaceNormalsComputed;
void calcPerFaceNormals ();
@ -99,6 +85,11 @@ private:
bool isPerVertexNormalsVerified;
void perVertexNormalsVerify_and_Repair();
void calcBBox();
void calcBBoxAllChilds();
CBBOX m_BBox;
void openGL_Render( bool aIsRenderingJustNonTransparentObjects,
bool aIsRenderingJustTransparentObjects );
};

View File

@ -1,6 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015 Mario Luzeiro <mrluzeiro@gmail.com>
* Copyright (C) 2015 Jean-Pierre Charras, jp.charras@wanadoo.fr
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
@ -32,14 +33,14 @@
#include <macros.h>
#include <kicad_string.h>
#include <pgm_base.h>
#include <gal/opengl/glm/gtc/matrix_transform.hpp>
#include <3d_viewer.h>
#include <info3d_visu.h>
#include "3d_struct.h"
#include "modelparsers.h"
S3D_MODEL_PARSER* S3D_MODEL_PARSER::Create( S3D_MASTER* aMaster,
S3D_MODEL_PARSER *S3D_MODEL_PARSER::Create( S3D_MASTER* aMaster,
const wxString aExtension )
{
if ( aExtension == wxT( "x3d" ) )
@ -50,46 +51,25 @@ S3D_MODEL_PARSER* S3D_MODEL_PARSER::Create( S3D_MASTER* aMaster,
return NULL;
}
const wxString S3D_MASTER::GetShape3DFullFilename()
{
wxString shapeName;
// Expand any environment variables embedded in footprint's m_Shape3DName field.
// To ensure compatibility with most of footprint's m_Shape3DName field,
// if the m_Shape3DName is not an absolute path the default path
// given by the environment variable KISYS3DMOD will be used
if( m_Shape3DName.StartsWith( wxT("${") ) )
shapeName = wxExpandEnvVars( m_Shape3DName );
else
shapeName = m_Shape3DName;
wxFileName fn( shapeName );
if( fn.IsAbsolute() || shapeName.StartsWith( wxT(".") ) )
return shapeName;
wxString default_path;
wxGetEnv( KISYS3DMOD, &default_path );
if( default_path.IsEmpty() )
return shapeName;
if( !default_path.EndsWith( wxT("/") ) && !default_path.EndsWith( wxT("\\") ) )
default_path += wxT("/");
default_path += shapeName;
return default_path;
}
int S3D_MASTER::ReadData()
int S3D_MASTER::ReadData( S3D_MODEL_PARSER* aParser )
{
if( m_Shape3DName.IsEmpty() )
return 1;
{
//DBG( printf("m_Shape3DName.IsEmpty") );
return -1;
}
wxString filename = GetShape3DFullFilename();
if( m_Shape3DFullFilename.IsEmpty() )
{
//DBG( printf("m_Shape3DFullFilename.IsEmpty") );
return -1;
}
if( aParser == NULL )
return -1;
wxString filename = m_Shape3DFullFilename;
#ifdef __WINDOWS__
filename.Replace( wxT( "/" ), wxT( "\\" ) );
@ -97,35 +77,30 @@ int S3D_MASTER::ReadData()
filename.Replace( wxT( "\\" ), wxT( "/" ) );
#endif
if( !wxFileName::FileExists( filename ) )
if( wxFileName::FileExists( filename ) )
{
wxLogDebug( wxT( "3D shape '%s' not found, even tried '%s' after env var substitution." ),
GetChars( m_Shape3DName ),
GetChars( filename )
);
return -1;
wxFileName fn( filename );
if( aParser->Load( filename ) )
{
// Invalidate bounding boxes
m_fastAABBox.Reset();
m_BBox.Reset();
m_parser = aParser;
return 0;
}
}
wxFileName fn( filename );
wxString extension = fn.GetExt();
m_parser = S3D_MODEL_PARSER::Create( this, extension );
if( m_parser )
{
m_parser->Load( filename );
return 0;
}
else
{
wxLogDebug( wxT( "Unknown file type '%s'" ), GetChars( extension ) );
}
wxLogDebug( wxT( "3D shape '%s' not found, even tried '%s' after env var substitution." ),
GetChars( m_Shape3DName ),
GetChars( filename ) );
return -1;
}
void S3D_MASTER::Render( bool aIsRenderingJustNonTransparentObjects,
bool aIsRenderingJustTransparentObjects )
{
@ -136,31 +111,80 @@ void S3D_MASTER::Render( bool aIsRenderingJustNonTransparentObjects,
glScalef( aVrmlunits_to_3Dunits, aVrmlunits_to_3Dunits, aVrmlunits_to_3Dunits );
glm::vec3 matScale( m_MatScale.x,
m_MatScale.y,
m_MatScale.z );
glTranslatef( m_MatPosition.x * SCALE_3D_CONV,
m_MatPosition.y * SCALE_3D_CONV,
m_MatPosition.z * SCALE_3D_CONV );
glm::vec3 matRot( m_MatRotation.x,
m_MatRotation.y,
m_MatRotation.z );
glRotatef( -m_MatRotation.z, 0.0f, 0.0f, 1.0f );
glRotatef( -m_MatRotation.y, 0.0f, 1.0f, 0.0f );
glRotatef( -m_MatRotation.x, 1.0f, 0.0f, 0.0f );
glm::vec3 matPos( m_MatPosition.x,
m_MatPosition.y,
m_MatPosition.z );
glTranslatef( matPos.x * SCALE_3D_CONV,
matPos.y * SCALE_3D_CONV,
matPos.z * SCALE_3D_CONV );
glRotatef( -matRot.z, 0.0f, 0.0f, 1.0f );
glRotatef( -matRot.y, 0.0f, 1.0f, 0.0f );
glRotatef( -matRot.x, 1.0f, 0.0f, 0.0f );
glScalef( matScale.x, matScale.y, matScale.z );
glScalef( m_MatScale.x, m_MatScale.y, m_MatScale.z );
for( unsigned int idx = 0; idx < m_parser->childs.size(); idx++ )
{
m_parser->childs[idx]->openGL_RenderAllChilds( aIsRenderingJustNonTransparentObjects,
aIsRenderingJustTransparentObjects );
}
}
}
CBBOX &S3D_MASTER::getBBox( )
{
if( !m_BBox.IsInitialized() )
calcBBox();
return m_BBox;
}
CBBOX &S3D_MASTER::getFastAABBox( )
{
if( !m_fastAABBox.IsInitialized() )
calcBBox();
return m_fastAABBox;
}
void S3D_MASTER::calcBBox()
{
if( m_parser == NULL )
return;
bool firstBBox = true;
for( unsigned int idx = 0; idx < m_parser->childs.size(); idx++ )
if( firstBBox )
{
firstBBox = false;
m_BBox = m_parser->childs[idx]->getBBox();
}
else
m_BBox.Union( m_parser->childs[idx]->getBBox() );
// Calc transformation matrix to apply in AABBox
float aVrmlunits_to_3Dunits = g_Parm_3D_Visu.m_BiuTo3Dunits * UNITS3D_TO_UNITSPCB;
glm::mat4 fullTransformMatrix;
fullTransformMatrix = glm::scale( glm::mat4(), S3D_VERTEX( aVrmlunits_to_3Dunits,
aVrmlunits_to_3Dunits,
aVrmlunits_to_3Dunits ) );
fullTransformMatrix = glm::translate( fullTransformMatrix, S3D_VERTEX( m_MatPosition.x * SCALE_3D_CONV,
m_MatPosition.y * SCALE_3D_CONV,
m_MatPosition.z * SCALE_3D_CONV) );
if( m_MatRotation.z != 0.0 )
fullTransformMatrix = glm::rotate( fullTransformMatrix, -(float)m_MatRotation.z, S3D_VERTEX( 0.0f, 0.0f, 1.0f ) );
if( m_MatRotation.y != 0.0 )
fullTransformMatrix = glm::rotate( fullTransformMatrix, -(float)m_MatRotation.y, S3D_VERTEX( 0.0f, 1.0f, 0.0f ) );
if( m_MatRotation.x != 0.0 )
fullTransformMatrix = glm::rotate( fullTransformMatrix, -(float)m_MatRotation.x, S3D_VERTEX( 1.0f, 0.0f, 0.0f ) );
fullTransformMatrix = glm::scale( fullTransformMatrix, S3D_VERTEX( m_MatScale.x, m_MatScale.y, m_MatScale.z ) );
// Apply transformation
m_fastAABBox = m_BBox;
m_fastAABBox.ApplyTransformationAA( fullTransformMatrix );
}

View File

@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014 Mario Luzeiro <mrluzeiro@gmail.com>
* Copyright (C) 2014-2015 Mario Luzeiro <mrluzeiro@gmail.com>
* Copyright (C) 2004 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
@ -34,54 +34,12 @@
#include <common.h>
#include <base_struct.h>
#include <3d_material.h>
#include <gal/opengl/glm/glm.hpp>
#include <3d_types.h>
#include <CBBox.h>
/**
* @note For historical reasons the 3D modeling unit is 0.1 inch
* 1 3Dunit = 2.54 mm = 0.1 inch = 100 mils
*/
#define UNITS3D_TO_UNITSPCB (IU_PER_MILS * 100)
/**
* scaling factor for 3D shape offset ( S3D_MASTER::m_MatPosition member )
* Was in inches in legacy version, and, due to a mistake, still in inches
* in .kicad_pcb files (which are using mm)
* so this scaling convert file units (inch) to 3D units (0.1 inch), only
* for S3D_MASTER::m_MatPosition parameter
*/
#define SCALE_3D_CONV 10
class S3D_MASTER;
class STRUCT_3D_SHAPE;
// S3D_VERTEX manages a opengl 3D coordinate (3 float numbers: x,y,z coordinates)
// float are widely used in opengl functions.
// they are used here in coordinates which are also used in opengl functions.
#define S3D_VERTEX glm::vec3
// S3DPOINT manages a set of 3 double values (x,y,z )
// It is used for values which are not directly used in opengl functions.
// It is used in dialogs, or when reading/writing files for instance
class S3DPOINT
{
public:
double x, y, z;
public:
S3DPOINT()
{
x = y = z = 0.0;
}
S3DPOINT( double px, double py, double pz)
{
x = px;
y = py;
z = pz;
}
};
class S3D_MODEL_PARSER;
// Master structure for a 3D footprint shape description
@ -112,8 +70,10 @@ public:
bool m_use_modelfile_shininess;
private:
wxString m_Shape3DName; // the 3D shape filename in 3D library
FILE3D_TYPE m_ShapeType;
wxString m_Shape3DName; ///< The 3D shape filename in 3D library
FILE3D_TYPE m_ShapeType; ///< Shape type based on filename extension
wxString m_Shape3DFullFilename; ///< Full file path name
wxString m_Shape3DNameExtension; ///< Extension of the shape file name
public:
S3D_MASTER( EDA_ITEM* aParent );
@ -131,8 +91,9 @@ public:
* Function ReadData
* Select the parser to read the 3D data file (vrml, x3d ...)
* and build the description objects list
* @param aParser the parser that should be used to read model data and stored in
*/
int ReadData();
int ReadData( S3D_MODEL_PARSER* aParser );
void Render( bool aIsRenderingJustNonTransparentObjects,
bool aIsRenderingJustTransparentObjects );
@ -177,6 +138,12 @@ public:
*/
const wxString GetShape3DFullFilename();
/**
* Function GetShape3DExtension
* @return the extension of the filename of the 3D shape,
*/
const wxString GetShape3DExtension();
/**
* Function SetShape3DName
* @param aShapeName = file name of the data file relative to the 3D shape
@ -185,6 +152,23 @@ public:
* (vrl, x3d, idf ) the type of file.
*/
void SetShape3DName( const wxString& aShapeName );
/**
* Function getBBox Model Space Bouding Box
* @return return the model space bouding box
*/
CBBOX &getBBox();
/**
* Function getFastAABBox
* @return return the Axis Align Bounding Box of the other bouding boxes
*/
CBBOX &getFastAABBox();
private:
void calcBBox();
CBBOX m_BBox; ///< Model oriented Bouding Box
CBBOX m_fastAABBox; ///< Axis Align Bounding Box that contain the other bounding boxes
};
@ -208,30 +192,4 @@ public:
#endif
};
/**
* Class S3DPOINT_VALUE_CTRL
* displays a S3DPOINT for editing (in dialogs). A S3DPOINT is a triplet of values
* Values can be scale, rotation, offset...
*/
class S3DPOINT_VALUE_CTRL
{
private:
wxTextCtrl* m_XValueCtrl, * m_YValueCtrl, * m_ZValueCtrl;
public:
S3DPOINT_VALUE_CTRL( wxWindow* parent, wxBoxSizer* BoxSizer );
~S3DPOINT_VALUE_CTRL();
/**
* Function GetValue
* @return the 3D point in internal units.
*/
S3DPOINT GetValue();
void SetValue( S3DPOINT a3Dpoint );
void Enable( bool enbl );
void SetToolTip( const wxString& text );
};
#endif // STRUCT_3D_H

View File

@ -187,6 +187,10 @@ void EDA_3D_FRAME::CreateMenuBar()
_( "Render Material Properties" ),
KiBitmap( green_xpm ), wxITEM_CHECK );
AddMenuItem( renderOptionsMenu, ID_MENU3D_FL_RENDER_SHOW_MODEL_BBOX,
_( "Show Model Bouding Boxes" ),
KiBitmap( green_xpm ), wxITEM_CHECK );
prefsMenu->AppendSeparator();
wxMenu * backgrounColorMenu = new wxMenu;
@ -300,6 +304,9 @@ void EDA_3D_FRAME::SetMenuBarOptionsState()
item = menuBar->FindItem( ID_MENU3D_FL_RENDER_MATERIAL );
item->Check( GetPrm3DVisu().GetFlag( FL_RENDER_MATERIAL ) );
item = menuBar->FindItem( ID_MENU3D_FL_RENDER_SHOW_MODEL_BBOX );
item->Check( GetPrm3DVisu().GetFlag( FL_RENDER_SHOW_MODEL_BBOX ) );
item = menuBar->FindItem( ID_MENU3D_SHOW_BOARD_BODY );
item->Check( GetPrm3DVisu().GetFlag( FL_SHOW_BOARD_BODY ) );

107
3d-viewer/3d_types.h Normal file
View File

@ -0,0 +1,107 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015 Mario Luzeiro <mrluzeiro@gmail.com>
* Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file 3d_types.h
*/
#ifndef _3D_TYPES_H_
#define _3D_TYPES_H_
#include <gal/opengl/glm/glm.hpp>
#include <base_units.h> // for IU_PER_MILS
/**
* @note For historical reasons the 3D modeling unit is 0.1 inch
* 1 3Dunit = 2.54 mm = 0.1 inch = 100 mils
*/
#define UNITS3D_TO_UNITSPCB (IU_PER_MILS * 100)
/**
* scaling factor for 3D shape offset ( S3D_MASTER::m_MatPosition member )
* Was in inches in legacy version, and, due to a mistake, still in inches
* in .kicad_pcb files (which are using mm)
* so this scaling convert file units (inch) to 3D units (0.1 inch), only
* for S3D_MASTER::m_MatPosition parameter
*/
#define SCALE_3D_CONV 10
// S3D_VERTEX manages a opengl 3D coordinate (3 float numbers: x,y,z coordinates)
// float are widely used in opengl functions.
// they are used here in coordinates which are also used in opengl functions.
#define S3D_VERTEX glm::vec3
// S3DPOINT manages a set of 3 double values (x,y,z )
// It is used for values which are not directly used in opengl functions.
// It is used in dialogs, or when reading/writing files for instance
class S3DPOINT
{
public:
double x, y, z;
public:
S3DPOINT()
{
x = y = z = 0.0;
}
S3DPOINT( double px, double py, double pz)
{
x = px;
y = py;
z = pz;
}
};
/**
* Class S3DPOINT_VALUE_CTRL
* displays a S3DPOINT for editing (in dialogs). A S3DPOINT is a triplet of values
* Values can be scale, rotation, offset...
*/
class S3DPOINT_VALUE_CTRL
{
private:
wxTextCtrl* m_XValueCtrl, * m_YValueCtrl, * m_ZValueCtrl;
public:
S3DPOINT_VALUE_CTRL( wxWindow* parent, wxBoxSizer* BoxSizer );
~S3DPOINT_VALUE_CTRL();
/**
* Function GetValue
* @return the 3D point in internal units.
*/
S3DPOINT GetValue();
void SetValue( S3DPOINT a3Dpoint );
void Enable( bool enbl );
void SetToolTip( const wxString& text );
};
#endif // 3D_TYPES_H

View File

@ -52,6 +52,7 @@ enum id_3dview_frm
ID_MENU3D_FL_RENDER_SMOOTH_NORMALS,
ID_MENU3D_FL_RENDER_USE_MODEL_NORMALS,
ID_MENU3D_FL_RENDER_MATERIAL,
ID_MENU3D_FL_RENDER_SHOW_MODEL_BBOX,
ID_END_COMMAND_3D,
ID_TOOL_SET_VISIBLE_ITEMS,

278
3d-viewer/CBBox.cpp Normal file
View File

@ -0,0 +1,278 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015 Mario Luzeiro <mrluzeiro@gmail.com>
* Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file CBBox.cpp
* @brief Bounding Box class implementation
*/
#include "CBBox.h"
// openGL includes used for debug the bounding box
#ifdef __WXMAC__
# ifdef __DARWIN__
# include <OpenGL/glu.h>
# else
# include <glu.h>
# endif
#else
# include <GL/glu.h>
#endif
CBBOX::CBBOX()
{
Reset();
}
CBBOX::CBBOX( const S3D_VERTEX &aPbInit )
{
m_min = aPbInit;
m_max = aPbInit;
m_initialized = true;
}
CBBOX::CBBOX( const S3D_VERTEX &aPbMin, const S3D_VERTEX &aPbMax )
{
Set( aPbMin, aPbMax );
}
CBBOX::~CBBOX()
{
}
void CBBOX::Set( const S3D_VERTEX &aPbMin, const S3D_VERTEX &aPbMax )
{
m_min.x = glm::min( aPbMin.x, aPbMax.x );
m_min.y = glm::min( aPbMin.y, aPbMax.y );
m_min.z = glm::min( aPbMin.z, aPbMax.z );
m_max.x = glm::max( aPbMin.x, aPbMax.x );
m_max.y = glm::max( aPbMin.y, aPbMax.y );
m_max.z = glm::max( aPbMin.z, aPbMax.z );
m_initialized = true;
}
bool CBBOX::IsInitialized() const
{
return m_initialized;
}
void CBBOX::Reset()
{
m_min = S3D_VERTEX( 0.0f, 0.0f, 0.0f );
m_max = S3D_VERTEX( 0.0f, 0.0f, 0.0f );
m_initialized = false;
}
void CBBOX::Union( const S3D_VERTEX &aPoint )
{
if( !m_initialized )
{
m_initialized = true;
// Initialize the bounding box with the given point
m_min = aPoint;
m_max = aPoint;
}
else
{
// get the minimun value between the added point and the existent bounding box
m_min.x = glm::min( m_min.x, aPoint.x );
m_min.y = glm::min( m_min.y, aPoint.y );
m_min.z = glm::min( m_min.z, aPoint.z );
// get the maximun value between the added point and the existent bounding box
m_max.x = glm::max( m_max.x, aPoint.x );
m_max.y = glm::max( m_max.y, aPoint.y );
m_max.z = glm::max( m_max.z, aPoint.z );
}
}
void CBBOX::Union( const CBBOX &aBBox )
{
if( aBBox.m_initialized == false )
return;
if( !m_initialized )
{
// Initialize the bounding box with the given bounding box
m_initialized = true;
m_min = aBBox.m_min;
m_max = aBBox.m_max;
}
else
{
// get the minimun value between the added bounding box and the existent bounding box
m_min.x = glm::min( m_min.x, aBBox.m_min.x );
m_min.y = glm::min( m_min.y, aBBox.m_min.y );
m_min.z = glm::min( m_min.z, aBBox.m_min.z );
// get the maximun value between the added bounding box and the existent bounding box
m_max.x = glm::max( m_max.x, aBBox.m_max.x );
m_max.y = glm::max( m_max.y, aBBox.m_max.y );
m_max.z = glm::max( m_max.z, aBBox.m_max.z );
}
}
S3D_VERTEX CBBOX::GetCenter() const
{
return (m_max + m_min) * 0.5f;
}
S3D_VERTEX CBBOX::Min() const
{
return m_min;
}
S3D_VERTEX CBBOX::Max() const
{
return m_max;
}
void CBBOX::Scale( float aScale )
{
if( m_initialized == false )
return;
S3D_VERTEX scaleV = S3D_VERTEX( aScale, aScale, aScale );
S3D_VERTEX centerV = GetCenter();
m_min = (m_min - centerV) * scaleV + centerV;
m_max = (m_max - centerV) * scaleV + centerV;
}
bool CBBOX::OverlapsBox( const CBBOX &aBBox ) const
{
if( aBBox.m_initialized == false )
return false;
bool x = ( m_max.x >= aBBox.m_min.x ) && ( m_min.x <= aBBox.m_max.x );
bool y = ( m_max.y >= aBBox.m_min.y ) && ( m_min.y <= aBBox.m_max.y );
bool z = ( m_max.z >= aBBox.m_min.z ) && ( m_min.z <= aBBox.m_max.z );
return ( x && y && z );
}
bool CBBOX::Inside( const S3D_VERTEX &aPoint ) const
{
if( m_initialized == false )
return false;
return (( aPoint.x >= m_min.x ) && ( aPoint.x <= m_max.x ) &&
( aPoint.y >= m_min.y ) && ( aPoint.y <= m_max.y ) &&
( aPoint.z >= m_min.z ) && ( aPoint.z <= m_max.z ));
}
float CBBOX::Volume() const
{
if( m_initialized == false )
return 0.0f;
S3D_VERTEX d = m_max - m_min;
return d.x * d.y * d.z;
}
void CBBOX::ApplyTransformation( glm::mat4 aTransformMatrix )
{
if( m_initialized == false )
return;
S3D_VERTEX v1 = S3D_VERTEX( aTransformMatrix * glm::vec4( m_min.x, m_min.y, m_min.z, 1.0f ) );
S3D_VERTEX v2 = S3D_VERTEX( aTransformMatrix * glm::vec4( m_max.x, m_max.y, m_max.z, 1.0f ) );
Reset();
Union( v1 );
Union( v2 );
}
void CBBOX::ApplyTransformationAA( glm::mat4 aTransformMatrix )
{
if( m_initialized == false )
return;
// apply the transformation matrix for each of vertices of the bounding box
// and make a union with all vertices
CBBOX tmpBBox = CBBOX( S3D_VERTEX( aTransformMatrix * glm::vec4( m_min.x, m_min.y, m_min.z, 1.0f ) ) );
tmpBBox.Union( S3D_VERTEX( aTransformMatrix * glm::vec4( m_max.x, m_min.y, m_min.z, 1.0f ) ) );
tmpBBox.Union( S3D_VERTEX( aTransformMatrix * glm::vec4( m_min.x, m_max.y, m_min.z, 1.0f ) ) );
tmpBBox.Union( S3D_VERTEX( aTransformMatrix * glm::vec4( m_min.x, m_min.y, m_max.z, 1.0f ) ) );
tmpBBox.Union( S3D_VERTEX( aTransformMatrix * glm::vec4( m_min.x, m_max.y, m_max.z, 1.0f ) ) );
tmpBBox.Union( S3D_VERTEX( aTransformMatrix * glm::vec4( m_max.x, m_max.y, m_min.z, 1.0f ) ) );
tmpBBox.Union( S3D_VERTEX( aTransformMatrix * glm::vec4( m_max.x, m_min.y, m_max.z, 1.0f ) ) );
tmpBBox.Union( S3D_VERTEX( aTransformMatrix * glm::vec4( m_max.x, m_max.y, m_max.z, 1.0f ) ) );
m_min = tmpBBox.m_min;
m_max = tmpBBox.m_max;
}
void CBBOX::GLdebug() const
{
if( m_initialized == false )
return;
glBegin( GL_LINE_LOOP );
glVertex3f( m_min.x, m_min.y, m_min.z );
glVertex3f( m_max.x, m_min.y, m_min.z );
glVertex3f( m_max.x, m_max.y, m_min.z );
glVertex3f( m_min.x, m_max.y, m_min.z );
glEnd();
glBegin( GL_LINE_LOOP );
glVertex3f( m_min.x, m_min.y, m_max.z );
glVertex3f( m_max.x, m_min.y, m_max.z );
glVertex3f( m_max.x, m_max.y, m_max.z );
glVertex3f( m_min.x, m_max.y, m_max.z );
glEnd();
glBegin( GL_LINE_STRIP );
glVertex3f( m_min.x, m_min.y, m_min.z );
glVertex3f( m_min.x, m_min.y, m_max.z );
glEnd();
glBegin( GL_LINE_STRIP );
glVertex3f( m_max.x, m_min.y, m_min.z );
glVertex3f( m_max.x, m_min.y, m_max.z );
glEnd();
glBegin( GL_LINE_STRIP );
glVertex3f( m_max.x, m_max.y, m_min.z );
glVertex3f( m_max.x, m_max.y, m_max.z );
glEnd();
glBegin( GL_LINE_STRIP );
glVertex3f( m_min.x, m_max.y, m_min.z );
glVertex3f( m_min.x, m_max.y, m_max.z );
glEnd();
}

182
3d-viewer/CBBox.h Normal file
View File

@ -0,0 +1,182 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015 Mario Luzeiro <mrluzeiro@gmail.com>
* Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file CBBox.h
* @brief Bounding Box class definition
*/
#ifndef CBBox_h
#define CBBox_h
#include <gal/opengl/glm/glm.hpp>
#include <3d_types.h>
/**
* Class CBBOX
* manages a bounding box defined by two S3D_VERTEX points.
*/
class CBBOX
{
public:
/**
* Constructor CBBOX
* Create with default values a bounding box (not inizialized)
*/
CBBOX();
/**
* Constructor CBBOX
* Initialize a bounding box with a given point
* @param aPbInit a point for the bounding box initialization
*/
CBBOX( const S3D_VERTEX &aPbInit );
/**
* Constructor CBBOX
* Initialize a bounding box with a minimon and a maximun point
* @param aPbMin the minimun point to initialize the bounding box
* @param aPbMax the maximun point to initialize the bounding box
*/
CBBOX( const S3D_VERTEX &aPbMin, const S3D_VERTEX &aPbMax );
~CBBOX();
/**
* Function Set
* Set bounding box with new parameters
* @param aPbMin the minimun point to initialize the bounding box
* @param aPbMax the maximun point to initialize the bounding box
*/
void Set( const S3D_VERTEX &aPbMin, const S3D_VERTEX &aPbMax );
/**
* Function Union
* recalculate the bounding box adding a point
* @param aPoint the point to be bounded
*/
void Union( const S3D_VERTEX &aPoint );
/**
* Function Union
* recalculate the bounding box adding other bounding box
* @param aBBox the bounding box to be bounded
*/
void Union( const CBBOX &aBBox );
/**
* Function Scale
* scales a bounding box by its center
* @param aScale scale factor to apply
*/
void Scale( float aScale );
/**
* Function OverlapsBox
* test if a bounding box overlaps this box
* @param aBBox the bounding box to check if it overlaps
*/
bool OverlapsBox( const CBBOX &aBBox ) const;
/**
* Function Inside
* check is a point is inside this bounding box
* @param aPoint point to test
*/
bool Inside( const S3D_VERTEX &aPoint ) const;
/**
* Function ApplyTransformation
* apply a transformation matrix to the box points
* @param aTransformMatrix matrix to apply to the points of the bounding box
*/
void ApplyTransformation( glm::mat4 aTransformMatrix );
/**
* Function ApplyTransformationAA
* apply a transformation matrix to the box points and recalculate it
* to fit an axis aligned bounding box
* @param aTransformMatrix matrix to apply to the points of the bounding box
*/
void ApplyTransformationAA( glm::mat4 aTransformMatrix );
/**
* Function Volume
* calculate the volume of a bounding box
* @return float - volume of this bounding box
*/
float Volume() const;
/**
* Function GLdebug
* render a wired bounding box using openGL
*/
void GLdebug() const;
/**
* Function IsInitialized
* check if this bounding box is already initialized
* @return bool - return true if it was initialized, false if otherwise
*/
bool IsInitialized() const;
/**
* Function Reset
* reset the bounding box to zero and de-initialized it
*/
void Reset();
/**
* Function GetCenter
* return the center point of the bounding box
* @return S3D_VERTEX - the position of the center of this bounding box
*/
S3D_VERTEX GetCenter() const;
/**
* Function Min
* return the minimun vertex pointer
* @return S3D_VERTEX - the minimun vertice position
*/
S3D_VERTEX Min() const;
/**
* Function Max
* return the maximum vertex pointer
* @return S3D_VERTEX - the maximun vertice position
*/
S3D_VERTEX Max() const;
private:
S3D_VERTEX m_min; ///< point of the lower position of the bounding box
S3D_VERTEX m_max; ///< point of the higher position of the bounding box
bool m_initialized; ///< initialization status of the bounding box. true - if initialized, false otherwise
};
#endif // CBBox_h

View File

@ -22,17 +22,26 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file CImage.cpp
* @brief one 8bit-channel image implementation
*/
#include "CImage.h"
#include <wx/image.h> // Used for save an image to disk
#include <string.h> // For memcpy
#ifndef CLAMP
#define CLAMP(n, min, max) {if (n < min) n=min; else if (n > max) n = max;}
#endif
CIMAGE::CIMAGE( unsigned int xsize, unsigned int ysize )
CIMAGE::CIMAGE( unsigned int aXsize, unsigned int aYsize )
{
m_pixels = (unsigned char*)malloc( xsize * ysize );
m_width = xsize;
m_height = ysize;
m_wxh = xsize * ysize;
m_wxh = aXsize * aYsize;
m_pixels = (unsigned char*)malloc( m_wxh );
m_width = aXsize;
m_height = aYsize;
m_wraping = (E_WRAP)WRAP_CLAMP;
}
@ -43,10 +52,16 @@ CIMAGE::~CIMAGE()
}
bool CIMAGE::wrapCoords( int *xo, int *yo )
unsigned char* CIMAGE::GetBuffer() const
{
int x = *xo;
int y = *yo;
return m_pixels;
}
bool CIMAGE::wrapCoords( int *aXo, int *aYo ) const
{
int x = *aXo;
int y = *aYo;
switch(m_wraping)
{
@ -66,40 +81,41 @@ bool CIMAGE::wrapCoords( int *xo, int *yo )
break;
}
if( (x < 0) || (x >= (int)m_width) || (y < 0) || (y >= (int)m_height))
if( (x < 0) || (x >= (int)m_width) ||
(y < 0) || (y >= (int)m_height) )
return false;
*xo = x;
*yo = y;
*aXo = x;
*aYo = y;
return true;
}
void CIMAGE::setpixel( int x, int y, unsigned char value )
void CIMAGE::Setpixel( int aX, int aY, unsigned char aValue )
{
if( wrapCoords( &x, &y ) )
m_pixels[x + y * m_width] = value;
if( wrapCoords( &aX, &aY ) )
m_pixels[aX + aY * m_width] = aValue;
}
unsigned char CIMAGE::getpixel(int x, int y)
unsigned char CIMAGE::Getpixel( int aX, int aY ) const
{
if( wrapCoords( &x, &y ) )
return m_pixels[x + y * m_width];
if( wrapCoords( &aX, &aY ) )
return m_pixels[aX + aY * m_width];
else
return 0;
}
void CIMAGE::invert()
void CIMAGE::Invert()
{
for( unsigned int it = 0;it < m_wxh; it++ )
for( unsigned int it = 0; it < m_wxh; it++ )
m_pixels[it] = 255 - m_pixels[it];
}
void CIMAGE::copyFull( const CIMAGE *aImgA, const CIMAGE *aImgB, E_IMAGE_OP aOperation )
void CIMAGE::CopyFull( const CIMAGE *aImgA, const CIMAGE *aImgB, E_IMAGE_OP aOperation )
{
int aV, bV;
@ -116,105 +132,116 @@ void CIMAGE::copyFull( const CIMAGE *aImgA, const CIMAGE *aImgB, E_IMAGE_OP aOpe
switch(aOperation)
{
case COPY_RAW:
for( unsigned int it = 0;it < m_wxh; it++ )
m_pixels[it] = aImgA->m_pixels[it];
break;
case COPY_RAW:
memcpy( m_pixels, aImgA->m_pixels, m_wxh );
break;
case COPY_ADD:
for( unsigned int it = 0;it < m_wxh; it++ )
{
aV = aImgA->m_pixels[it];
bV = aImgB->m_pixels[it];
case COPY_ADD:
for( unsigned int it = 0;it < m_wxh; it++ )
{
aV = aImgA->m_pixels[it];
bV = aImgB->m_pixels[it];
aV = (aV + bV);
aV = (aV > 255)?255:aV;
aV = (aV + bV);
aV = (aV > 255)?255:aV;
m_pixels[it] = aV;
}
break;
m_pixels[it] = aV;
}
break;
case COPY_SUB:
for( unsigned int it = 0;it < m_wxh; it++ )
{
aV = aImgA->m_pixels[it];
bV = aImgB->m_pixels[it];
case COPY_SUB:
for( unsigned int it = 0;it < m_wxh; it++ )
{
aV = aImgA->m_pixels[it];
bV = aImgB->m_pixels[it];
aV = (aV - bV);
aV = (aV < 0)?0:aV;
aV = (aV - bV);
aV = (aV < 0)?0:aV;
m_pixels[it] = aV;
}
break;
m_pixels[it] = aV;
}
break;
case COPY_DIF:
for( unsigned int it = 0;it < m_wxh; it++ )
{
aV = aImgA->m_pixels[it];
bV = aImgB->m_pixels[it];
case COPY_DIF:
for( unsigned int it = 0;it < m_wxh; it++ )
{
aV = aImgA->m_pixels[it];
bV = aImgB->m_pixels[it];
m_pixels[it] = abs(aV - bV);
}
break;
m_pixels[it] = abs(aV - bV);
}
break;
case COPY_MUL:
for( unsigned int it = 0;it < m_wxh; it++ )
{
aV = aImgA->m_pixels[it];
bV = aImgB->m_pixels[it];
case COPY_MUL:
for( unsigned int it = 0;it < m_wxh; it++ )
{
aV = aImgA->m_pixels[it];
bV = aImgB->m_pixels[it];
m_pixels[it] = (unsigned char)((((float)aV / 255.0f) * ((float)bV / 255.0f)) * 255);
}
break;
m_pixels[it] = (unsigned char)((((float)aV / 255.0f) * ((float)bV / 255.0f)) * 255);
}
break;
case COPY_AND:
for( unsigned int it = 0;it < m_wxh; it++ )
{
m_pixels[it] = aImgA->m_pixels[it] & aImgB->m_pixels[it];
}
break;
case COPY_AND:
for( unsigned int it = 0;it < m_wxh; it++ )
{
m_pixels[it] = aImgA->m_pixels[it] & aImgB->m_pixels[it];
}
break;
case COPY_OR:
for( unsigned int it = 0;it < m_wxh; it++ )
{
m_pixels[it] = aImgA->m_pixels[it] | aImgB->m_pixels[it];
}
break;
case COPY_OR:
for( unsigned int it = 0;it < m_wxh; it++ )
{
m_pixels[it] = aImgA->m_pixels[it] | aImgB->m_pixels[it];
}
break;
case COPY_XOR:
for( unsigned int it = 0;it < m_wxh; it++ )
{
m_pixels[it] = aImgA->m_pixels[it] ^ aImgB->m_pixels[it];
}
break;
case COPY_BLEND50:
break;
case COPY_XOR:
for( unsigned int it = 0;it < m_wxh; it++ )
{
m_pixels[it] = aImgA->m_pixels[it] ^ aImgB->m_pixels[it];
}
break;
case COPY_BLEND50:
for( unsigned int it = 0;it < m_wxh; it++ )
{
aV = aImgA->m_pixels[it];
bV = aImgB->m_pixels[it];
case COPY_MIN:
for( unsigned int it = 0;it < m_wxh; it++ )
{
aV = aImgA->m_pixels[it];
bV = aImgB->m_pixels[it];
m_pixels[it] = (aV + bV) / 2;
}
break;
m_pixels[it] = (aV < bV)?aV:bV;
}
break;
case COPY_MIN:
for( unsigned int it = 0;it < m_wxh; it++ )
{
aV = aImgA->m_pixels[it];
bV = aImgB->m_pixels[it];
case COPY_MAX:
for( unsigned int it = 0;it < m_wxh; it++ )
{
aV = aImgA->m_pixels[it];
bV = aImgB->m_pixels[it];
m_pixels[it] = (aV < bV)?aV:bV;
}
break;
m_pixels[it] = (aV > bV)?aV:bV;
}
break;
case COPY_MAX:
for( unsigned int it = 0;it < m_wxh; it++ )
{
aV = aImgA->m_pixels[it];
bV = aImgB->m_pixels[it];
m_pixels[it] = (aV > bV)?aV:bV;
}
break;
default:
break;
}
}
S_FILTER FILTERS[9] = {
// TIP: If you want create or test filters you can use GIMP
// with a generic convolution matrix and get the values from there.
// http://docs.gimp.org/nl/plug-in-convmatrix.html
static const S_FILTER FILTERS[] = {
// Hi Pass
{
{ { 0, -1, -1, -1, 0},
@ -230,17 +257,28 @@ S_FILTER FILTERS[9] = {
// Blur
{
{ { 3, 5, 7, 5, 3},
{ 4, 9, 12, 9, 5},
{ 5, 9, 12, 9, 5},
{ 7, 12, 20, 12, 7},
{ 4, 9, 12, 9, 5},
{ 5, 9, 12, 9, 5},
{ 3, 5, 7, 5, 3}
},
180,
182,
0
},
// Blur Invert
{
{ { 0, 0, 0, 0, 0},
{ 0, 0, -1, 0, 0},
{ 0, -1, 0, -1, 0},
{ 0, 0, -1, 0, 0},
{ 0, 0, 0, 0, 0}
},
4,
255
},
// KS 01
//
{
{ { 0, 2, 4, 2, 0},
{ 2, -2, 1, -2, 2},
@ -326,31 +364,41 @@ S_FILTER FILTERS[9] = {
};// Filters
void CIMAGE::efxFilter( CIMAGE *aInImg, float aGain, E_FILTER aFilterType )
//!TODO: This functions can be optimized slipting it between the edges and
// do it without use the getpixel function.
// Optimization can be done to m_pixels[ix + iy * m_width]
// but keep in mind the parallel process of the algorithm
void CIMAGE::EfxFilter( CIMAGE *aInImg, E_FILTER aFilterType )
{
S_FILTER filter = FILTERS[aFilterType];
aInImg->m_wraping = WRAP_CLAMP;
m_wraping = WRAP_CLAMP;
#ifdef USE_OPENMP
#pragma omp parallel for
#endif /* USE_OPENMP */
for( int iy = 0; iy < (int)m_height; iy++)
{
for( int ix = 0; ix < (int)m_width; ix++ )
{
int v = filter.offset;
int v = 0;
for( int sy = 0; sy < 5; sy++ )
{
for( int sx = 0; sx < 5; sx++ )
{
int factor = filter.kernel[sx][sy];
unsigned char pixelv = aInImg->getpixel( ix + sx - 2, iy + sy - 2 );
unsigned char pixelv = aInImg->Getpixel( ix + sx - 2, iy + sy - 2 );
v += pixelv * factor;
}
}
v /= filter.div;
v += filter.offset;
CLAMP(v, 0, 255);
m_pixels[ix + iy * m_width] = v;
@ -359,7 +407,7 @@ void CIMAGE::efxFilter( CIMAGE *aInImg, float aGain, E_FILTER aFilterType )
}
void CIMAGE::setPixelsFromNormalizedFloat( const float * aNormalizedFloatArray )
void CIMAGE::SetPixelsFromNormalizedFloat( const float * aNormalizedFloatArray )
{
for( unsigned int i = 0; i < m_wxh; i++ )
{
@ -370,26 +418,23 @@ void CIMAGE::setPixelsFromNormalizedFloat( const float * aNormalizedFloatArray )
}
void CIMAGE::saveAsPNG( wxString aFileName )
void CIMAGE::SaveAsPNG( wxString aFileName ) const
{
unsigned char* pixelbuffer = (unsigned char*) malloc( m_wxh * 3 );
//unsigned char* alphabuffer = (unsigned char*) malloc( m_width * aHeight );
unsigned char* pixelbuffer = (unsigned char*) malloc( m_wxh * 3 );
wxImage image( m_width, m_height );
for( unsigned int i = 0; i < m_wxh; i++)
{
unsigned char v = m_pixels[i];
// Set RGB value with all same values intensities
pixelbuffer[i * 3 + 0] = v;
pixelbuffer[i * 3 + 1] = v;
pixelbuffer[i * 3 + 2] = v;
//alphabuffer[i * 1 + 0] = aRGBABufferImage[i * 4 + 3];
}
image.SetData( pixelbuffer );
//image.SetAlpha( alphabuffer );
image = image.Mirror( false );
image.SaveFile( aFileName + ".png", wxBITMAP_TYPE_PNG );
image.Destroy();
}

View File

@ -22,11 +22,17 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file CImage.h
* @brief one 8bit-channel image definition
*/
#ifndef CImage_h
#define CImage_h
#include <wx/image.h>
#include <wx/string.h>
/// Image operation type
enum E_IMAGE_OP {
COPY_RAW,
COPY_ADD,
@ -41,17 +47,23 @@ enum E_IMAGE_OP {
COPY_MAX
};
/// Image wrap type enumeration
enum E_WRAP {
WRAP_ZERO, ///< Coords that wraps are not evaluated
WRAP_CLAMP,
WRAP_WRAP ///< Coords are wrapped arround
WRAP_ZERO, ///< Coords that wraps are not evaluated
WRAP_CLAMP, ///< Coords are clamped to image size
WRAP_WRAP ///< Coords are wrapped arround
};
/// Filter type enumeration
enum E_FILTER {
FILTER_HIPASS,
FILTER_BLUR
FILTER_GAUSSIAN_BLUR,
FILTER_INVERT_BLUR,
};
/// 5x5 Filter struct parameters
typedef struct {
signed char kernel[5][5];
unsigned char div;
@ -59,36 +71,120 @@ typedef struct {
}S_FILTER;
/**
* Class CIMAGE
* manages a 8-bit channel image
*/
class CIMAGE
{
public:
CIMAGE( unsigned int xsize, unsigned int ysize );
/**
* Constructor CIMAGE
* constructs a CIMAGE based on image size
* @param aXsize x size
* @param aYsize y size
*/
CIMAGE( unsigned int aXsize, unsigned int aYsize );
~CIMAGE();
void setpixel( int x, int y, unsigned char value );
unsigned char getpixel( int x, int y );
/**
* Function Setpixel
* set a value in a pixel position, position is clamped in accord with the
* current clamp settings
* @param aX x position
* @param aY y position
* @param aValue value to set the pixel
*/
void Setpixel( int aX, int aY, unsigned char aValue );
/**
* Function Getpixel
* get the pixel value from pixel position, position is clamped in accord with the
* current clamp settings
* @param aX x position
* @param aY y position
* @return unsigned char - pixel value
*/
unsigned char Getpixel( int aX, int aY ) const;
void copyFull( const CIMAGE *aImgA, const CIMAGE *aImgB, E_IMAGE_OP aOperation );
/**
* Function CopyFull
* perform a copy operation, based on operation type. The result destination is the self image class
* @param aImgA an image input
* @param aImgB an image input
* @param aOperation operation to perform
* COPY_RAW this <- aImgA
* COPY_ADD this <- CLAMP(aImgA + aImgB)
* COPY_SUB this <- CLAMP(aImgA - aImgB)
* COPY_DIF this <- abs(aImgA - aImgB)
* COPY_MUL this <- aImgA * aImgB
* COPY_AND this <- aImgA & aImgB
* COPY_OR this <- aImgA | aImgB
* COPY_XOR this <- aImgA ^ aImgB
* COPY_BLEND50 this <- (aImgA + aImgB) / 2
* COPY_MIN this <- (aImgA < aImgB)?aImgA:aImgB
* COPY_MAX this <- (aImgA > aImgB)?aImgA:aImgB
*/
void CopyFull( const CIMAGE *aImgA, const CIMAGE *aImgB, E_IMAGE_OP aOperation );
void invert();
/**
* Function Invert
* invert the values of image this <- (255 - this)
*/
void Invert();
void efxFilter( CIMAGE *aInImg, float aGain, E_FILTER aFilterType );
/**
* Function EfxFilter
* apply a filter to the input image and stores it in the image class
* this <- FilterType(aInImg)
* @param aInImg input image
* @param aFilterType filter type to apply
*/
void EfxFilter( CIMAGE *aInImg, E_FILTER aFilterType );
void saveAsPNG( wxString aFileName );
/**
* Function SaveAsPNG
* save image buffer to a PNG file into the working folder.
* each of RGB channel will have the 8bit-channel from the image.
* @param aFileName fime name (without extension)
*/
void SaveAsPNG( wxString aFileName ) const;
/**
* Function SetPixelsFromNormalizedFloat
* set the current channel from a float normalized (0.0 - 1.0) buffer
* this <- CLAMP(NormalizedFloat * 255)
* @param aNormalizedFloatArray a float array with the same size of the image
*/
void SetPixelsFromNormalizedFloat( const float * aNormalizedFloatArray );
/**
* Function GetBuffer
* get the image buffer pointer
* @return unsigned char * - the pointer of the buffer 8bit channel
*/
unsigned char* GetBuffer() const;
void setPixelsFromNormalizedFloat( const float * aNormalizedFloatArray );
private:
bool wrapCoords( int *xo, int *yo );
public:
unsigned char* m_pixels;
unsigned int m_width;
unsigned int m_height;
unsigned int m_wxh;
E_WRAP m_wraping;
/**
* Function wrapCoords
* calculate the coordinates points in accord with the current clamping settings
* @param aXo X coordinate to be converted (output)
* @param aXo Y coordinate to be converted (output)
* @return bool - true if the coordinates are inside the image, false otherwise
*/
bool wrapCoords( int *aXo, int *aYo ) const;
private:
unsigned char* m_pixels; ///< buffer to store the image 8bit-channel
unsigned int m_width; ///< width of the image
unsigned int m_height; ///< height of the image
unsigned int m_wxh; ///< width * height precalc value
E_WRAP m_wraping; ///< current wrapping type
};
#endif
#endif // CImage_h

View File

@ -31,6 +31,7 @@ set(3D-VIEWER_SRCS
vrml_v2_modelparser.cpp
x3dmodelparser.cpp
CImage.cpp
CBBox.cpp
)
add_library(3d-viewer STATIC ${3D-VIEWER_SRCS})

View File

@ -231,10 +231,19 @@ void INFO3D_VISU::InitSettings( BOARD* aBoard )
*/
double INFO3D_VISU::GetModulesZcoord3DIU( bool aIsFlipped )
{
// NOTE: Z position to display modules in top of Paste and near the shadow
if( aIsFlipped )
return m_layerZcoord[B_Paste] - ( m_copperThickness / 2 );
if( aIsFlipped )
{
if( g_Parm_3D_Visu.GetFlag( FL_SOLDERPASTE ) )
return m_layerZcoord[B_SilkS] - ( m_copperThickness / 2.0 );
else
return m_layerZcoord[B_Paste] - ( m_copperThickness / 2.0 );
}
else
return m_layerZcoord[F_Paste] + ( m_copperThickness / 2 );
{
if( g_Parm_3D_Visu.GetFlag( FL_SOLDERPASTE ) )
return m_layerZcoord[F_SilkS] + ( m_copperThickness / 2.0 );
else
return m_layerZcoord[F_Paste] + ( m_copperThickness / 2.0 );
}
}

View File

@ -78,6 +78,7 @@ enum DISPLAY3D_FLG {
FL_RENDER_SMOOTH_NORMALS,
FL_RENDER_USE_MODEL_NORMALS,
FL_RENDER_MATERIAL,
FL_RENDER_SHOW_MODEL_BBOX,
FL_LAST
};

View File

@ -35,7 +35,6 @@
#include <3d_mesh_model.h>
class S3D_MASTER;
class S3D_MODEL_PARSER;
class X3D_MODEL_PARSER;
/**
@ -49,13 +48,7 @@ public:
master( aMaster )
{}
~S3D_MODEL_PARSER()
{
for( unsigned int idx = 0; idx < childs.size(); idx++ )
{
delete childs[idx];
}
}
virtual ~S3D_MODEL_PARSER(){}
S3D_MASTER* GetMaster()
{
@ -73,22 +66,14 @@ public:
static S3D_MODEL_PARSER* Create( S3D_MASTER* aMaster, const wxString aExtension );
/**
* pure virtual Function
* virtual Function
* Concrete parsers should implement this function
* @param aFilename = the full file name of the file to load
* @return true if as succeeded
*/
virtual bool Load( const wxString& aFilename ) = 0;
/**
* Function Render
* Render the model to openGL. The arguments can be both false but just only one
* can be true.
* @param aIsRenderingJustNonTransparentObjects
* @param aIsRenderingJustTransparentObjects
*/
void Render( bool aIsRenderingJustNonTransparentObjects,
bool aIsRenderingJustTransparentObjects );
virtual bool Load( const wxString& aFilename ) {
return false;
};
std::vector< S3D_MESH* > childs;
@ -158,6 +143,7 @@ private:
typedef std::map< std::string, std::vector< glm::vec3 > > VRML2_COORDINATE_MAP;
typedef std::map< std::string, S3D_MESH* > VRML2_DEF_GROUP_MAP;
/**
* class VRML2_MODEL_PARSER
@ -171,6 +157,15 @@ public:
bool Load( const wxString& aFilename );
/**
* Function Load
* Load a VRML2 filename and apply a transformation to the root
* @param aFilename file name with path
* @param aTransformationModel a model with translation, rotation and scale to apply to default root
* @return bool - true if finnished with success
*/
bool Load( const wxString& aFilename, S3D_MESH *aTransformationModel );
/**
* Return string representing VRML2 file in vrml2 format
* Function Load must be called before this function, otherwise empty
@ -179,6 +174,7 @@ public:
wxString VRML2_representation();
private:
int loadFileModel( S3D_MESH *transformationModel );
int read_Transform();
int read_DEF();
int read_DEF_Coordinate();
@ -195,16 +191,33 @@ private:
int read_Color();
int read_coordIndex();
int read_colorIndex();
int read_USE();
int read_geometry();
int read_IndexedFaceSet_USE();
int read_Transform_USE();
int read_Inline();
/** Function debug_enter
* Used in debug to increase a ' ' in the m_debugSpacer,
* should be called after the first debug comment in a function
*/
void debug_enter();
/** Function debug_exit
* Used in debug to decrease a ' ' in the m_debugSpacer,
* should be called before the last debug comment in a funtion before exit
*/
void debug_exit();
bool m_normalPerVertex;
bool colorPerVertex;
S3D_MESH* m_model;
S3D_MESH* m_model; ///< It stores the current model that the parsing is adding data
FILE* m_file;
wxString m_Filename;
wxFileName m_Filename;
VRML2_COORDINATE_MAP m_defCoordinateMap;
VRML2_DEF_GROUP_MAP m_defGroupMap; ///< Stores a list of labels for groups and meshs that will be used later by the USE keyword
S3D_MODEL_PARSER* m_ModelParser;
S3D_MASTER* m_Master;
wxString m_debugSpacer; ///< Used to give identation space
};
@ -267,7 +280,6 @@ public:
* by the vrml file data
*/
VRML_MODEL_PARSER( S3D_MASTER* aMaster );
~VRML_MODEL_PARSER();
/**
@ -279,11 +291,6 @@ public:
* to our internal units.
*/
bool Load( const wxString& aFilename );
private:
S3D_MASTER* m_curr3DShape; ///< the current 3D shape to build from the file
VRML1_MODEL_PARSER* vrml1_parser;
VRML2_MODEL_PARSER* vrml2_parser;
};

View File

@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014 Mario Luzeiro <mrluzeiro@gmail.com>
* Copyright (C) 2014-2015 Mario Luzeiro <mrluzeiro@gmail.com>
* Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
@ -24,11 +24,58 @@
/**
* @file vrml_aux.cpp
* @brief implements auxiliar functions to parse VRML files
*/
#include "vrml_aux.h"
bool GetString( FILE* File, char* aDstString, size_t maxDstLen )
{
if( (!aDstString) || (maxDstLen == 0) )
return false;
int c;
while( ( c = fgetc( File ) ) != EOF )
{
if( c == '\"' )
{
break;
}
}
if( c != '\"' )
{
return false;
}
while( (( c = fgetc( File ) ) != EOF) && (maxDstLen > 0) )
{
if( c == '\"' )
{
break;
}
maxDstLen--;
*aDstString = c;
aDstString++;
}
*aDstString = 0;
if( c == '\"' )
{
return true;
}
return false;
}
static int SkipGetChar ( FILE* File );
@ -140,7 +187,7 @@ bool GetNextTag( FILE* File, char* tag, size_t len )
}
int read_NotImplemented( FILE* File, char closeChar )
int Read_NotImplemented( FILE* File, char closeChar )
{
int c;
@ -150,12 +197,12 @@ int read_NotImplemented( FILE* File, char closeChar )
if( c == '{' )
{
// DBG( printf( "{\n") );
read_NotImplemented( File, '}' );
Read_NotImplemented( File, '}' );
}
else if( c == '[' )
{
// DBG( printf( "[\n") );
read_NotImplemented( File, ']' );
Read_NotImplemented( File, ']' );
}
else if( c == closeChar )
{
@ -169,15 +216,15 @@ int read_NotImplemented( FILE* File, char closeChar )
}
int parseVertexList( FILE* File, std::vector<glm::vec3>& dst_vector )
int ParseVertexList( FILE* File, std::vector<glm::vec3>& dst_vector )
{
// DBG( printf( " parseVertexList\n" ) );
// DBG( printf( " ParseVertexList\n" ) );
dst_vector.clear();
glm::vec3 vertex;
while( parseVertex( File, vertex ) == 3 )
while( ParseVertex( File, vertex ) == 3 )
{
dst_vector.push_back( vertex );
}
@ -186,7 +233,7 @@ int parseVertexList( FILE* File, std::vector<glm::vec3>& dst_vector )
}
int parseVertex( FILE* File, glm::vec3& dst_vertex )
int ParseVertex( FILE* File, glm::vec3& dst_vertex )
{
float a, b, c;
int ret = fscanf( File, "%e %e %e", &a, &b, &c );
@ -209,7 +256,7 @@ int parseVertex( FILE* File, glm::vec3& dst_vertex )
}
int parseFloat( FILE* File, float* dst_float )
int ParseFloat( FILE* File, float* dst_float )
{
float value;
int ret = fscanf( File, "%e", &value );

View File

@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014 Mario Luzeiro <mrluzeiro@gmail.com>
* Copyright (C) 2014-2015 Mario Luzeiro <mrluzeiro@gmail.com>
* Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
@ -24,6 +24,7 @@
/**
* @file vrml_aux.h
* @brief auxiliar functions to parse VRML files
*/
#ifndef _VRML_AUX_H
@ -48,10 +49,63 @@
#endif
#include <wx/glcanvas.h>
int read_NotImplemented( FILE* File, char closeChar);
int parseVertexList( FILE* File, std::vector< glm::vec3 > &dst_vector);
int parseVertex( FILE* File, glm::vec3 &dst_vertex );
int parseFloat( FILE* File, float *dst_float );
/**
* Function GetEpoxyThicknessBIU
* skip a VRML block and eventualy internal blocks until it find the close char
* @param File file to read from
* @param closeChar the expected close char of the block
* @return int - -1 if failed, 0 if OK
*/
int Read_NotImplemented( FILE* File, char closeChar);
/**
* Function ParseVertexList
* parse a vertex list
* @param File file to read from
* @param dst_vector destination vector list
* @return int - -1 if failed, 0 if OK
*/
int ParseVertexList( FILE* File, std::vector< glm::vec3 > &dst_vector);
/**
* Function ParseVertex
* parse a vertex
* @param File file to read from
* @param dst_vertex destination vector
* @return int - return the number of elements readed
*/
int ParseVertex( FILE* File, glm::vec3 &dst_vertex );
/**
* Function ParseFloat
* parse a float value
* @param File file to read from
* @param dst_float destination float
* @return int - Return the number of floats readed
*/
int ParseFloat( FILE* File, float *dst_float );
/**
* Function GetNextTag
* parse the next tag
* @param File file to read from
* @param tag destination pointer
* @param len max length of storage
* @return bool - true if succeeded, false if EOF
*/
bool GetNextTag( FILE* File, char* tag, size_t len );
/**
* Function GetString
* parse a string, it expects starting by " and end with "
* @param File file to read from
* @param aDstString destination pointer
* @param maxDstLen max length of storage
* @return bool - true if successful read the string, false if failed to get a string
*/
bool GetString( FILE* File, char* aDstString, size_t maxDstLen );
#endif

View File

@ -138,7 +138,7 @@ int VRML1_MODEL_PARSER::read_separator()
else if( ( *text != '}' ) )
{
// DBG( printf( "read_NotImplemented %s\n", text ) );
read_NotImplemented( m_file, '}' );
Read_NotImplemented( m_file, '}' );
}
else
break;
@ -272,7 +272,7 @@ int VRML1_MODEL_PARSER::readMaterial_ambientColor()
{
// DBG( printf( " readMaterial_ambientColor\n" ) );
return parseVertexList( m_file, m_model->m_Materials->m_AmbientColor );
return ParseVertexList( m_file, m_model->m_Materials->m_AmbientColor );
}
@ -280,7 +280,7 @@ int VRML1_MODEL_PARSER::readMaterial_diffuseColor()
{
// DBG( printf( " readMaterial_diffuseColor\n" ) );
return parseVertexList( m_file, m_model->m_Materials->m_DiffuseColor );
return ParseVertexList( m_file, m_model->m_Materials->m_DiffuseColor );
}
@ -288,7 +288,7 @@ int VRML1_MODEL_PARSER::readMaterial_emissiveColor()
{
// DBG( printf( " readMaterial_emissiveColor\n" ) );
int ret = parseVertexList( m_file, m_model->m_Materials->m_EmissiveColor );
int ret = ParseVertexList( m_file, m_model->m_Materials->m_EmissiveColor );
if( m_Master->m_use_modelfile_emissiveColor == false )
{
@ -303,7 +303,7 @@ int VRML1_MODEL_PARSER::readMaterial_specularColor()
{
// DBG( printf( " readMaterial_specularColor\n" ) );
int ret = parseVertexList( m_file, m_model->m_Materials->m_SpecularColor );
int ret = ParseVertexList( m_file, m_model->m_Materials->m_SpecularColor );
if( m_Master->m_use_modelfile_specularColor == false )
{
@ -368,7 +368,7 @@ int VRML1_MODEL_PARSER::readCoordinate3_point()
{
// DBG( printf( " readCoordinate3_point\n" ) );
if( parseVertexList( m_file, m_model->m_Point ) == 0 )
if( ParseVertexList( m_file, m_model->m_Point ) == 0 )
{
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -41,17 +41,20 @@
VRML_MODEL_PARSER::VRML_MODEL_PARSER( S3D_MASTER* aMaster ) :
S3D_MODEL_PARSER( aMaster )
{
vrml1_parser = NULL;
vrml2_parser = NULL;
m_curr3DShape = NULL;
}
VRML_MODEL_PARSER::~VRML_MODEL_PARSER()
{
for( unsigned int idx = 0; idx < childs.size(); idx++ )
{
if( childs[idx] )
{
delete childs[idx];
childs[idx] = 0;
}
}
}
bool VRML_MODEL_PARSER::Load( const wxString& aFilename )
{
char line[11 + 1];
@ -72,20 +75,20 @@ bool VRML_MODEL_PARSER::Load( const wxString& aFilename )
fclose( file );
childs.clear();
if( stricmp( line, "#VRML V2.0" ) == 0 )
{
vrml2_parser = new VRML2_MODEL_PARSER( this );
VRML2_MODEL_PARSER *vrml2_parser = new VRML2_MODEL_PARSER( this );
vrml2_parser->Load( aFilename );
delete vrml2_parser;
vrml2_parser = NULL;
return true;
}
else if( stricmp( line, "#VRML V1.0" ) == 0 )
{
vrml1_parser = new VRML1_MODEL_PARSER( this );
VRML1_MODEL_PARSER *vrml1_parser = new VRML1_MODEL_PARSER( this );
vrml1_parser->Load( aFilename );
delete vrml1_parser;
vrml1_parser = NULL;
return true;
}

View File

@ -58,6 +58,14 @@ X3D_MODEL_PARSER::X3D_MODEL_PARSER( S3D_MASTER* aMaster ) :
X3D_MODEL_PARSER::~X3D_MODEL_PARSER()
{
for( unsigned int idx = 0; idx < childs.size(); idx++ )
{
if( childs[idx] )
{
delete childs[idx];
childs[idx] = 0;
}
}
}