Commit 8db15e72 authored by unknown's avatar unknown Committed by jean-pierre charras

3D-viewer: Fixes and enhancements (add 3D bounding box for components). Add...

3D-viewer: Fixes and enhancements (add 3D bounding box for components). Add comments in header files. Fix some coding style issues.
parents 33acfae7 eee901ff
...@@ -105,9 +105,9 @@ void TransfertToGLlist( std::vector< S3D_VERTEX >& aVertices, double aBiuTo3DUni ...@@ -105,9 +105,9 @@ void TransfertToGLlist( std::vector< S3D_VERTEX >& aVertices, double aBiuTo3DUni
ay = aVertices[1].y - aVertices[0].y; ay = aVertices[1].y - aVertices[0].y;
az = aVertices[1].z - aVertices[0].z; az = aVertices[1].z - aVertices[0].z;
bx = aVertices[aVertices.size() - 1].x - aVertices[0].x; bx = aVertices[2].x - aVertices[0].x;
by = aVertices[aVertices.size() - 1].y - aVertices[0].y; by = aVertices[2].y - aVertices[0].y;
bz = aVertices[aVertices.size() - 1].z - aVertices[0].z; bz = aVertices[2].z - aVertices[0].z;
nx = ay * bz - az * by; nx = ay * bz - az * by;
ny = az * bx - ax * bz; ny = az * bx - ax * bz;
......
...@@ -94,6 +94,8 @@ EDA_3D_CANVAS::EDA_3D_CANVAS( EDA_3D_FRAME* parent, int* attribList ) : ...@@ -94,6 +94,8 @@ EDA_3D_CANVAS::EDA_3D_CANVAS( EDA_3D_FRAME* parent, int* attribList ) :
m_ZBottom = 0.0; m_ZBottom = 0.0;
m_ZTop = 0.0; m_ZTop = 0.0;
m_lightPos = S3D_VERTEX(0.0f, 0.0f, 50.0f);
// Clear all gl list identifiers: // Clear all gl list identifiers:
for( int ii = GL_ID_BEGIN; ii < GL_ID_END; ii++ ) for( int ii = GL_ID_BEGIN; ii < GL_ID_END; ii++ )
m_glLists[ii] = 0; m_glLists[ii] = 0;
...@@ -110,6 +112,12 @@ EDA_3D_CANVAS::~EDA_3D_CANVAS() ...@@ -110,6 +112,12 @@ EDA_3D_CANVAS::~EDA_3D_CANVAS()
ClearLists(); ClearLists();
m_init = false; m_init = false;
delete m_glRC; 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 ) ...@@ -132,6 +140,17 @@ void EDA_3D_CANVAS::ClearLists( int aGlList )
m_glLists[ii] = 0; 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() ...@@ -564,12 +583,12 @@ void EDA_3D_CANVAS::InitGL()
void EDA_3D_CANVAS::SetLights() void EDA_3D_CANVAS::SetLights()
{ {
// activate light. the source is above the xy plane, at source_pos // 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) GLfloat light_color[4]; // color of lights (RGBA values)
light_color[3] = 1.0; light_color[3] = 1.0;
// Light above the xy plane // 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 ); glLightfv( GL_LIGHT0, GL_AMBIENT, light_color );
light_color[0] = light_color[1] = light_color[2] = 1.0; light_color[0] = light_color[1] = light_color[2] = 1.0;
...@@ -580,7 +599,7 @@ void EDA_3D_CANVAS::SetLights() ...@@ -580,7 +599,7 @@ void EDA_3D_CANVAS::SetLights()
glLightfv( GL_LIGHT0, GL_POSITION, source_pos ); 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 ); glLightModelfv( GL_LIGHT_MODEL_AMBIENT, light_color );
glEnable( GL_LIGHT0 ); // White spot on Z axis ( top ) glEnable( GL_LIGHT0 ); // White spot on Z axis ( top )
......
...@@ -43,7 +43,9 @@ ...@@ -43,7 +43,9 @@
#endif #endif
#include <3d_struct.h> #include <3d_struct.h>
#include <modelparsers.h>
#include <class_module.h> #include <class_module.h>
#include <CBBox.h>
class BOARD_DESIGN_SETTINGS; class BOARD_DESIGN_SETTINGS;
class EDA_3D_FRAME; class EDA_3D_FRAME;
...@@ -78,16 +80,15 @@ class EDA_3D_CANVAS : public wxGLCanvas ...@@ -78,16 +80,15 @@ class EDA_3D_CANVAS : public wxGLCanvas
{ {
private: private:
bool m_init; bool m_init;
bool m_reportWarnings; // true to report all wranings when build the 3D scene bool m_reportWarnings; ///< true to report all wranings when build the 3D scene false to report errors only
// false to report errors only GLuint m_glLists[GL_ID_END]; ///< GL lists
GLuint m_glLists[GL_ID_END]; // GL lists
wxGLContext* m_glRC; wxGLContext* m_glRC;
wxRealPoint m_draw3dOffset; // offset to draw the 3D mesh. wxRealPoint m_draw3dOffset; ///< offset to draw the 3D mesh.
double m_ZBottom; // position of the back layer double m_ZBottom; ///< position of the back layer
double m_ZTop; // position of the front 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_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_silk; ///< an index to the texture generated for silk layers
// Index to the textures generated for shadows // Index to the textures generated for shadows
bool m_shadow_init; bool m_shadow_init;
...@@ -95,9 +96,21 @@ private: ...@@ -95,9 +96,21 @@ private:
GLuint m_text_fake_shadow_back; GLuint m_text_fake_shadow_back;
GLuint m_text_fake_shadow_board; 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 ); GLuint aTexture_size, bool aDraw_body, int aBlurPasses );
void calcBBox();
public: public:
EDA_3D_CANVAS( EDA_3D_FRAME* parent, int* attribList = 0 ); EDA_3D_CANVAS( EDA_3D_FRAME* parent, int* attribList = 0 );
~EDA_3D_CANVAS(); ~EDA_3D_CANVAS();
...@@ -187,33 +200,33 @@ private: ...@@ -187,33 +200,33 @@ private:
wxPoint getBoardCenter() const; wxPoint getBoardCenter() const;
/** /**
* Helper function SetGLTechLayersColor * Helper function setGLTechLayersColor
* Initialize the color to draw the non copper layers * Initialize the color to draw the non copper layers
* in realistic mode and normal mode. * in realistic mode and normal mode.
*/ */
void setGLTechLayersColor( LAYER_NUM aLayer ); void setGLTechLayersColor( LAYER_NUM aLayer );
/** /**
* Helper function SetGLCopperColor * Helper function setGLCopperColor
* Initialize the copper color to draw the board * Initialize the copper color to draw the board
* in realistic mode (a golden yellow color ) * in realistic mode (a golden yellow color )
*/ */
void setGLCopperColor(); void setGLCopperColor();
/** /**
* Helper function SetGLEpoxyColor * Helper function setGLEpoxyColor
* Initialize the color to draw the epoxy body board in realistic mode. * Initialize the color to draw the epoxy body board in realistic mode.
*/ */
void setGLEpoxyColor( float aTransparency = 1.0 ); void setGLEpoxyColor( float aTransparency = 1.0 );
/** /**
* Helper function SetGLSolderMaskColor * Helper function setGLSolderMaskColor
* Initialize the color to draw the solder mask layers in realistic mode. * Initialize the color to draw the solder mask layers in realistic mode.
*/ */
void setGLSolderMaskColor( float aTransparency = 1.0 ); void setGLSolderMaskColor( float aTransparency = 1.0 );
/** /**
* Function BuildBoard3DView * Function buildBoard3DView
* Called by CreateDrawGL_List() * Called by CreateDrawGL_List()
* Populates the OpenGL GL_ID_BOARD draw list with board items only on copper layers. * 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 * 3D footprint shapes, tech layers and aux layers are not on this list
...@@ -224,27 +237,27 @@ private: ...@@ -224,27 +237,27 @@ private:
* created by the build process (can be NULL) * created by the build process (can be NULL)
* @param aShowWarnings = true to show all messages, false to show errors only * @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 ); wxString* aErrorMessages, bool aShowWarnings );
/** /**
* Function BuildTechLayers3DView * Function buildTechLayers3DView
* Called by CreateDrawGL_List() * Called by CreateDrawGL_List()
* Populates the OpenGL GL_ID_TECH_LAYERS draw list with items on tech layers * Populates the OpenGL GL_ID_TECH_LAYERS draw list with items on tech layers
* @param aErrorMessages = a wxString to add error and warning messages * @param aErrorMessages = a wxString to add error and warning messages
* created by the build process (can be NULL) * created by the build process (can be NULL)
* @param aShowWarnings = true to show all messages, false to show errors only * @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() * 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() * Called by CreateDrawGL_List()
* Fills the OpenGL GL_ID_3DSHAPES_SOLID and GL_ID_3DSHAPES_TRANSP * Fills the OpenGL GL_ID_3DSHAPES_SOLID and GL_ID_3DSHAPES_TRANSP
* draw lists with 3D footprint shapes * draw lists with 3D footprint shapes
...@@ -252,19 +265,18 @@ private: ...@@ -252,19 +265,18 @@ private:
* @param aTransparentList is the gl list for non transparent items, * @param aTransparentList is the gl list for non transparent items,
* which need to be drawn after all other items * which need to be drawn after all other items
*/ */
void BuildFootprintShape3DList( GLuint aOpaqueList, void buildFootprintShape3DList( GLuint aOpaqueList,
GLuint aTransparentList, GLuint aTransparentList );
bool aSideToLoad );
/** /**
* Function BuildBoard3DAuxLayers * Function buildBoard3DAuxLayers
* Called by CreateDrawGL_List() * Called by CreateDrawGL_List()
* Fills the OpenGL GL_ID_AUX_LAYERS draw list * Fills the OpenGL GL_ID_AUX_LAYERS draw list
* with items on aux layers only * with items on aux layers only
*/ */
void BuildBoard3DAuxLayers(); void buildBoard3DAuxLayers();
void Draw3DGrid( double aGriSizeMM ); void draw3DGrid( double aGriSizeMM );
void Draw3DAxis(); void draw3DAxis();
/** /**
* Helper function BuildPadShapeThickOutlineAsPolygon: * Helper function BuildPadShapeThickOutlineAsPolygon:
...@@ -272,7 +284,7 @@ private: ...@@ -272,7 +284,7 @@ private:
* with a line thickness = aWidth * with a line thickness = aWidth
* Used only to draw pads outlines on silkscreen layers. * Used only to draw pads outlines on silkscreen layers.
*/ */
void BuildPadShapeThickOutlineAsPolygon( const D_PAD* aPad, void buildPadShapeThickOutlineAsPolygon( const D_PAD* aPad,
CPOLYGONS_LIST& aCornerBuffer, CPOLYGONS_LIST& aCornerBuffer,
int aWidth, int aWidth,
int aCircleToSegmentsCount, int aCircleToSegmentsCount,
...@@ -280,54 +292,48 @@ private: ...@@ -280,54 +292,48 @@ private:
/** /**
* Helper function Draw3DViaHole: * Helper function draw3DViaHole:
* Draw the via hole: * Draw the via hole:
* Build a vertical hole (a cylinder) between the first and the last via layers * 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: * Draw the pad hole:
* Build a vertical hole (round or oblong) between the front and back layers * 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 * insert mesh in gl list
* @param module * @param module
* @param aIsRenderingJustNonTransparentObjects = true to load non transparent objects * @param aIsRenderingJustNonTransparentObjects = true to load non transparent objects
* @param aIsRenderingJustTransparentObjects = 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 * in openGL, transparent objects should be drawn *after* non transparent objects
*/ */
void Render3DComponentShape( MODULE* module, void render3DComponentShape( MODULE* module,
bool aIsRenderingJustNonTransparentObjects, bool aIsRenderingJustNonTransparentObjects,
bool aIsRenderingJustTransparentObjects, bool aIsRenderingJustTransparentObjects );
bool aSideToLoad );
/** /**
* function Read3DComponentShape * function read3DComponentShape
* read the 3D component shape(s) of the footprint (physical shape). * read the 3D component shape(s) of the footprint (physical shape).
* @param module * @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 * @return true if load was succeeded, false otherwise
*/ */
bool Read3DComponentShape( MODULE* module, bool read3DComponentShape( MODULE* module );
std::vector<S3D_MODEL_PARSER *>& model_parsers_list,
std::vector<wxString>& model_filename_list );
/** /**
* function GenerateFakeShadowsTextures * function generateFakeShadowsTextures
* creates shadows of the board an footprints * creates shadows of the board an footprints
* for aesthetical purpose * for aesthetical purpose
* @param aErrorMessages = a wxString to add error and warning messages * @param aErrorMessages = a wxString to add error and warning messages
* created by the build process (can be NULL) * created by the build process (can be NULL)
* @param aShowWarnings = true to show all messages, false to show errors only * @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() DECLARE_EVENT_TABLE()
}; };
......
/**
* @file 3d_class.cpp
*/
/* /*
* 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.
* *
...@@ -25,6 +21,9 @@ ...@@ -25,6 +21,9 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
/**
* @file 3d_class.cpp
*/
#include <fctsys.h> #include <fctsys.h>
...@@ -79,12 +78,14 @@ S3D_MASTER:: ~S3D_MASTER() ...@@ -79,12 +78,14 @@ S3D_MASTER:: ~S3D_MASTER()
{ {
next = m_3D_Drawings->Next(); next = m_3D_Drawings->Next();
delete m_3D_Drawings; delete m_3D_Drawings;
m_3D_Drawings = 0;
} }
for( ; m_Materials != NULL; m_Materials = nextmat ) for( ; m_Materials != NULL; m_Materials = nextmat )
{ {
nextmat = m_Materials->Next(); nextmat = m_Materials->Next();
delete m_Materials; delete m_Materials;
m_Materials = 0;
} }
} }
...@@ -115,19 +116,59 @@ void S3D_MASTER::SetShape3DName( const wxString& aShapeName ) ...@@ -115,19 +116,59 @@ void S3D_MASTER::SetShape3DName( const wxString& aShapeName )
return; return;
wxFileName fn = m_Shape3DName; 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; m_ShapeType = FILE3D_VRML;
else if( ext == wxT( "idf" ) ) else if( m_Shape3DNameExtension == wxT( "idf" ) )
m_ShapeType = FILE3D_IDF; m_ShapeType = FILE3D_IDF;
else else
m_ShapeType = FILE3D_UNKNOWN; 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; 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 ) : STRUCT_3D_SHAPE::STRUCT_3D_SHAPE( EDA_ITEM* aParent ) :
EDA_ITEM( aParent, NOT_USED ) EDA_ITEM( aParent, NOT_USED )
{ {
......
This diff is collapsed.
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
#include <modelparsers.h> #include <modelparsers.h>
// Number of segments to approximate a circle by segments // Number of segments to approximate a circle by segments
#define SEGM_PER_CIRCLE 16 #define SEGM_PER_CIRCLE 24
#ifndef CALLBACK #ifndef CALLBACK
#define CALLBACK #define CALLBACK
...@@ -57,12 +57,12 @@ static void CALLBACK tessCPolyPt2Vertex( const GLvoid* data ); ...@@ -57,12 +57,12 @@ static void CALLBACK tessCPolyPt2Vertex( const GLvoid* data );
// 2 helper functions to set the current normal vector for gle items // 2 helper functions to set the current normal vector for gle items
static inline void SetNormalZpos() static inline void SetNormalZpos()
{ {
//glNormal3f( 0.0, 0.0, 1.0 ); glNormal3f( 0.0, 0.0, 1.0 );
} }
static inline void SetNormalZneg() 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 ); void TransfertToGLlist( std::vector< S3D_VERTEX >& aVertices, double aBiuTo3DUnits );
...@@ -203,6 +203,7 @@ void Draw3D_SolidHorizontalPolyPolygons( const CPOLYGONS_LIST& aPolysList, ...@@ -203,6 +203,7 @@ void Draw3D_SolidHorizontalPolyPolygons( const CPOLYGONS_LIST& aPolysList,
} }
// https://www.opengl.org/sdk/docs/man2/xhtml/gluTessNormal.xml // https://www.opengl.org/sdk/docs/man2/xhtml/gluTessNormal.xml
if( !aThickness )
gluTessNormal( tess, 0.0, 0.0, 0.0 ); gluTessNormal( tess, 0.0, 0.0, 0.0 );
...@@ -231,6 +232,7 @@ void Draw3D_SolidHorizontalPolyPolygons( const CPOLYGONS_LIST& aPolysList, ...@@ -231,6 +232,7 @@ void Draw3D_SolidHorizontalPolyPolygons( const CPOLYGONS_LIST& aPolysList,
s_currentZpos = zpos; // for Tess callback functions s_currentZpos = zpos; // for Tess callback functions
v_data[2] = zpos; v_data[2] = zpos;
// Set normal toward negative Z axis, for a solid object on bottom side // Set normal toward negative Z axis, for a solid object on bottom side
if( aThickness )
SetNormalZneg(); SetNormalZneg();
} }
...@@ -248,7 +250,7 @@ void Draw3D_SolidHorizontalPolyPolygons( const CPOLYGONS_LIST& aPolysList, ...@@ -248,7 +250,7 @@ void Draw3D_SolidHorizontalPolyPolygons( const CPOLYGONS_LIST& aPolysList,
} }
// Build the 3D data : vertical side // 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, ...@@ -292,9 +294,11 @@ void Draw3D_ZaxisCylinder( wxPoint aCenterPos, int aRadius,
if( aHeight ) if( aHeight )
{ {
// Draw the vertical outer side // Draw the vertical outer side
Draw3D_VerticalPolygonalCylinder( outer_cornerBuffer, Draw3D_VerticalPolygonalCylinder( outer_cornerBuffer,
aHeight, aZpos, false, aBiuTo3DUnits ); aHeight, aZpos, false, aBiuTo3DUnits );
if( aThickness ) if( aThickness )
// Draws the vertical inner side (hole) // Draws the vertical inner side (hole)
Draw3D_VerticalPolygonalCylinder( inner_cornerBuffer, Draw3D_VerticalPolygonalCylinder( inner_cornerBuffer,
......
...@@ -181,7 +181,7 @@ void EDA_3D_CANVAS::setGLTechLayersColor( LAYER_NUM aLayer ) ...@@ -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] ) if( ! m_glLists[GL_ID_AXIS] )
{ {
...@@ -207,7 +207,7 @@ void EDA_3D_CANVAS::Draw3DAxis() ...@@ -207,7 +207,7 @@ void EDA_3D_CANVAS::Draw3DAxis()
// draw a 3D grid: an horizontal grid (XY plane and Z = 0, // draw a 3D grid: an horizontal grid (XY plane and Z = 0,
// and a vertical grid (XZ plane and Y = 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; double zpos = 0.0;
EDA_COLOR_T gridcolor = DARKGRAY; // Color of grid lines EDA_COLOR_T gridcolor = DARKGRAY; // Color of grid lines
...@@ -343,7 +343,7 @@ void EDA_3D_CANVAS::Draw3DGrid( double aGriSizeMM ) ...@@ -343,7 +343,7 @@ void EDA_3D_CANVAS::Draw3DGrid( double aGriSizeMM )
// Draw 3D pads. // 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 // Draw the pad hole
wxSize drillsize = aPad->GetDrillSize(); wxSize drillsize = aPad->GetDrillSize();
...@@ -363,13 +363,13 @@ void EDA_3D_CANVAS::Draw3DPadHole( const D_PAD* aPad ) ...@@ -363,13 +363,13 @@ void EDA_3D_CANVAS::Draw3DPadHole( const D_PAD* aPad )
else else
SetGLColor( DARKGRAY ); SetGLColor( DARKGRAY );
int holeZpoz = GetPrm3DVisu().GetLayerZcoordBIU( B_Cu ) + thickness / 2; int holeZpoz = GetPrm3DVisu().GetLayerZcoordBIU( B_Cu ) - thickness / 2;
int holeHeight = height - thickness; int holeHeight = height + thickness;
if( drillsize.x == drillsize.y ) // usual round hole if( drillsize.x == drillsize.y ) // usual round hole
{ {
Draw3D_ZaxisCylinder( aPad->GetPosition(), Draw3D_ZaxisCylinder( aPad->GetPosition(),
(drillsize.x + thickness) / 2, holeHeight, (drillsize.x + thickness / 2) / 2, holeHeight,
thickness, holeZpoz, GetPrm3DVisu().m_BiuTo3Dunits ); thickness, holeZpoz, GetPrm3DVisu().m_BiuTo3Dunits );
} }
else // Oblong hole else // Oblong hole
...@@ -401,11 +401,11 @@ void EDA_3D_CANVAS::Draw3DPadHole( const D_PAD* aPad ) ...@@ -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; LAYER_ID top_layer, bottom_layer;
int inner_radius = aVia->GetDrillValue() / 2;
int thickness = GetPrm3DVisu().GetCopperThicknessBIU(); 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 ); aVia->LayerPair( &top_layer, &bottom_layer );
...@@ -419,17 +419,17 @@ void EDA_3D_CANVAS::Draw3DViaHole( const VIA* aVia ) ...@@ -419,17 +419,17 @@ void EDA_3D_CANVAS::Draw3DViaHole( const VIA* aVia )
} }
int height = GetPrm3DVisu().GetLayerZcoordBIU( top_layer ) - int height = GetPrm3DVisu().GetLayerZcoordBIU( top_layer ) -
GetPrm3DVisu().GetLayerZcoordBIU( bottom_layer ) - thickness; GetPrm3DVisu().GetLayerZcoordBIU( bottom_layer ) + thickness;
int zpos = GetPrm3DVisu().GetLayerZcoordBIU( bottom_layer ) + thickness / 2; 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 ); thickness, zpos, GetPrm3DVisu().m_BiuTo3Dunits );
} }
/* Build a pad outline as non filled polygon, to draw pads on silkscreen layer /* Build a pad outline as non filled polygon, to draw pads on silkscreen layer
* Used only to draw pads outlines on silkscreen layers. * 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, CPOLYGONS_LIST& aCornerBuffer,
int aWidth, int aWidth,
int aCircleToSegmentsCount, int aCircleToSegmentsCount,
......
...@@ -57,6 +57,7 @@ static const wxChar keyRenderTextures[] = wxT( "Render_Textures" ); ...@@ -57,6 +57,7 @@ static const wxChar keyRenderTextures[] = wxT( "Render_Textures" );
static const wxChar keyRenderSmoothNormals[] = wxT( "Render_Smooth_Normals" ); static const wxChar keyRenderSmoothNormals[] = wxT( "Render_Smooth_Normals" );
static const wxChar keyRenderUseModelNormals[] =wxT( "Render_Use_Model_Normals" ); static const wxChar keyRenderUseModelNormals[] =wxT( "Render_Use_Model_Normals" );
static const wxChar keyRenderMaterial[] = wxT( "Render_Material" ); static const wxChar keyRenderMaterial[] = wxT( "Render_Material" );
static const wxChar keyRenderShowModelBBox[] = wxT( "Render_ShowModelBoudingBoxes" );
static const wxChar keyShowAxis[] = wxT( "ShowAxis" ); static const wxChar keyShowAxis[] = wxT( "ShowAxis" );
static const wxChar keyShowGrid[] = wxT( "ShowGrid3D" ); static const wxChar keyShowGrid[] = wxT( "ShowGrid3D" );
...@@ -257,6 +258,9 @@ void EDA_3D_FRAME::LoadSettings( wxConfigBase* aCfg ) ...@@ -257,6 +258,9 @@ void EDA_3D_FRAME::LoadSettings( wxConfigBase* aCfg )
aCfg->Read( keyRenderMaterial, &tmp, false ); aCfg->Read( keyRenderMaterial, &tmp, false );
prms.SetFlag( FL_RENDER_MATERIAL, tmp ); prms.SetFlag( FL_RENDER_MATERIAL, tmp );
aCfg->Read( keyRenderShowModelBBox, &tmp, false );
prms.SetFlag( FL_RENDER_SHOW_MODEL_BBOX, tmp );
aCfg->Read( keyShowAxis, &tmp, true ); aCfg->Read( keyShowAxis, &tmp, true );
prms.SetFlag( FL_AXIS, tmp ); prms.SetFlag( FL_AXIS, tmp );
...@@ -319,6 +323,7 @@ void EDA_3D_FRAME::SaveSettings( wxConfigBase* aCfg ) ...@@ -319,6 +323,7 @@ void EDA_3D_FRAME::SaveSettings( wxConfigBase* aCfg )
aCfg->Write( keyRenderSmoothNormals, prms.GetFlag( FL_RENDER_SMOOTH_NORMALS ) ); aCfg->Write( keyRenderSmoothNormals, prms.GetFlag( FL_RENDER_SMOOTH_NORMALS ) );
aCfg->Write( keyRenderUseModelNormals, prms.GetFlag( FL_RENDER_USE_MODEL_NORMALS ) ); aCfg->Write( keyRenderUseModelNormals, prms.GetFlag( FL_RENDER_USE_MODEL_NORMALS ) );
aCfg->Write( keyRenderMaterial, prms.GetFlag( FL_RENDER_MATERIAL ) ); 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( keyShowAxis, prms.GetFlag( FL_AXIS ) );
aCfg->Write( keyShowGrid, prms.GetFlag( FL_GRID ) ); aCfg->Write( keyShowGrid, prms.GetFlag( FL_GRID ) );
...@@ -509,6 +514,11 @@ void EDA_3D_FRAME::Process_Special_Functions( wxCommandEvent& event ) ...@@ -509,6 +514,11 @@ void EDA_3D_FRAME::Process_Special_Functions( wxCommandEvent& event )
NewDisplay(); NewDisplay();
return; 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: case ID_MENU3D_SHOW_BOARD_BODY:
GetPrm3DVisu().SetFlag( FL_SHOW_BOARD_BODY, isChecked ); GetPrm3DVisu().SetFlag( FL_SHOW_BOARD_BODY, isChecked );
NewDisplay(); NewDisplay();
...@@ -526,43 +536,43 @@ void EDA_3D_FRAME::Process_Special_Functions( wxCommandEvent& event ) ...@@ -526,43 +536,43 @@ void EDA_3D_FRAME::Process_Special_Functions( wxCommandEvent& event )
case ID_MENU3D_USE_COPPER_THICKNESS: case ID_MENU3D_USE_COPPER_THICKNESS:
GetPrm3DVisu().SetFlag( FL_USE_COPPER_THICKNESS, isChecked ); GetPrm3DVisu().SetFlag( FL_USE_COPPER_THICKNESS, isChecked );
NewDisplay(GL_ID_BOARD); NewDisplay( GL_ID_BOARD );
NewDisplay(GL_ID_TECH_LAYERS); NewDisplay( GL_ID_TECH_LAYERS );
return; return;
case ID_MENU3D_ZONE_ONOFF: case ID_MENU3D_ZONE_ONOFF:
GetPrm3DVisu().SetFlag( FL_ZONE, isChecked ); GetPrm3DVisu().SetFlag( FL_ZONE, isChecked );
NewDisplay(GL_ID_BOARD); NewDisplay( GL_ID_BOARD );
return; return;
case ID_MENU3D_ADHESIVE_ONOFF: case ID_MENU3D_ADHESIVE_ONOFF:
GetPrm3DVisu().SetFlag( FL_ADHESIVE, isChecked ); GetPrm3DVisu().SetFlag( FL_ADHESIVE, isChecked );
NewDisplay(GL_ID_TECH_LAYERS); NewDisplay( GL_ID_TECH_LAYERS );
return; return;
case ID_MENU3D_SILKSCREEN_ONOFF: case ID_MENU3D_SILKSCREEN_ONOFF:
GetPrm3DVisu().SetFlag( FL_SILKSCREEN, isChecked ); GetPrm3DVisu().SetFlag( FL_SILKSCREEN, isChecked );
NewDisplay(GL_ID_TECH_LAYERS); NewDisplay( GL_ID_TECH_LAYERS );
return; return;
case ID_MENU3D_SOLDER_MASK_ONOFF: case ID_MENU3D_SOLDER_MASK_ONOFF:
GetPrm3DVisu().SetFlag( FL_SOLDERMASK, isChecked ); GetPrm3DVisu().SetFlag( FL_SOLDERMASK, isChecked );
NewDisplay(GL_ID_TECH_LAYERS); NewDisplay( GL_ID_TECH_LAYERS );
return; return;
case ID_MENU3D_SOLDER_PASTE_ONOFF: case ID_MENU3D_SOLDER_PASTE_ONOFF:
GetPrm3DVisu().SetFlag( FL_SOLDERPASTE, isChecked ); GetPrm3DVisu().SetFlag( FL_SOLDERPASTE, isChecked );
NewDisplay(GL_ID_TECH_LAYERS); NewDisplay();
return; return;
case ID_MENU3D_COMMENTS_ONOFF: case ID_MENU3D_COMMENTS_ONOFF:
GetPrm3DVisu().SetFlag( FL_COMMENTS, isChecked ); GetPrm3DVisu().SetFlag( FL_COMMENTS, isChecked );
NewDisplay(GL_ID_AUX_LAYERS); NewDisplay( GL_ID_AUX_LAYERS );
return; return;
case ID_MENU3D_ECO_ONOFF: case ID_MENU3D_ECO_ONOFF:
GetPrm3DVisu().SetFlag( FL_ECO, isChecked ); GetPrm3DVisu().SetFlag( FL_ECO, isChecked );
NewDisplay(GL_ID_AUX_LAYERS); NewDisplay( GL_ID_AUX_LAYERS );
return; return;
default: default:
......
/* /*
* 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) 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. * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.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
...@@ -55,10 +55,10 @@ S3D_MATERIAL::S3D_MATERIAL( S3D_MASTER* father, const wxString& name ) : ...@@ -55,10 +55,10 @@ S3D_MATERIAL::S3D_MATERIAL( S3D_MASTER* father, const wxString& name ) :
void SetOpenGlDefaultMaterial() void SetOpenGlDefaultMaterial()
{ {
glm::vec4 ambient( 0.2, 0.2, 0.2, 1.0 ); glm::vec4 ambient( 0.2f, 0.2f, 0.2f, 1.0f );
glm::vec4 specular( 0.0, 0.0, 0.0, 1.0 ); glm::vec4 specular( 0.0f, 0.0f, 0.0f, 1.0f );
glm::vec4 emissive( 0.0, 0.0, 0.0, 1.0 ); glm::vec4 emissive( 0.0f, 0.0f, 0.0f, 1.0f );
glm::vec4 diffuse( 0.0, 0.0, 0.0, 1.0 ); glm::vec4 diffuse( 0.0f, 0.0f, 0.0f, 1.0f );
GLint shininess_value = 0; GLint shininess_value = 0;
glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE ); glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE );
......
/* /*
* 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) 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. * Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.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
......
This diff is collapsed.
/* /*
* 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) 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. * Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.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
...@@ -30,24 +30,12 @@ ...@@ -30,24 +30,12 @@
#ifndef __3D_MESH_MODEL_H__ #ifndef __3D_MESH_MODEL_H__
#define __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 <vector>
#include <kicad_string.h> #include <gal/opengl/glm/glm.hpp>
#include <info3d_visu.h> #include "3d_struct.h"
#ifdef __WXMAC__ #include "3d_material.h"
# ifdef __DARWIN__ #include "CBBox.h"
# include <OpenGL/glu.h>
# else
# include <glu.h>
# endif
#else
# include <GL/glu.h>
#endif
#include <wx/glcanvas.h>
class S3D_MESH; class S3D_MESH;
...@@ -64,26 +52,24 @@ public: ...@@ -64,26 +52,24 @@ public:
S3D_MATERIAL *m_Materials; S3D_MATERIAL *m_Materials;
// Point and index list // 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_CoordIndex;
std::vector< std::vector<int> > m_NormalIndex; std::vector< std::vector<int> > m_NormalIndex;
std::vector< glm::vec3 > m_PerFaceNormalsNormalized; std::vector< S3D_VERTEX > m_PerFaceNormalsNormalized;
std::vector< glm::vec3 > m_PerVertexNormalsNormalized; std::vector< S3D_VERTEX > m_PerVertexNormalsNormalized;
std::vector< int > m_MaterialIndex; std::vector< int > m_MaterialIndex;
std::vector< S3D_MESH * > childs;
glm::vec3 m_translation; S3D_VERTEX m_translation;
glm::vec4 m_rotation; glm::vec4 m_rotation;
glm::vec3 m_scale; S3D_VERTEX m_scale;
glm::vec4 m_scaleOrientation; // not used
glm::vec3 m_center; // not used
std::vector<S3D_MESH *> childs; CBBOX &getBBox();
private: private:
std::vector< glm::vec3 > m_PerFaceNormalsRaw_X_PerFaceSquaredArea; std::vector< S3D_VERTEX > m_PerFaceNormalsRaw_X_PerFaceSquaredArea;
std::vector< std::vector< glm::vec3 > > m_PerFaceVertexNormals; std::vector< std::vector< S3D_VERTEX > > m_PerFaceVertexNormals;
std::vector< glm::vec3 > m_PointNormalized; 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
...@@ -99,6 +85,11 @@ private: ...@@ -99,6 +85,11 @@ private:
bool isPerVertexNormalsVerified; bool isPerVertexNormalsVerified;
void perVertexNormalsVerify_and_Repair(); void perVertexNormalsVerify_and_Repair();
void calcBBox();
void calcBBoxAllChilds();
CBBOX m_BBox;
void openGL_Render( bool aIsRenderingJustNonTransparentObjects, void openGL_Render( bool aIsRenderingJustNonTransparentObjects,
bool aIsRenderingJustTransparentObjects ); bool aIsRenderingJustTransparentObjects );
}; };
......
/* /*
* 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) 2015 Mario Luzeiro <mrluzeiro@gmail.com>
* Copyright (C) 2015 Jean-Pierre Charras, jp.charras@wanadoo.fr * Copyright (C) 2015 Jean-Pierre Charras, jp.charras@wanadoo.fr
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net> * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
...@@ -32,14 +33,14 @@ ...@@ -32,14 +33,14 @@
#include <macros.h> #include <macros.h>
#include <kicad_string.h> #include <kicad_string.h>
#include <pgm_base.h> #include <pgm_base.h>
#include <gal/opengl/glm/gtc/matrix_transform.hpp>
#include <3d_viewer.h> #include <3d_viewer.h>
#include <info3d_visu.h> #include <info3d_visu.h>
#include "3d_struct.h" #include "3d_struct.h"
#include "modelparsers.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 ) const wxString aExtension )
{ {
if ( aExtension == wxT( "x3d" ) ) if ( aExtension == wxT( "x3d" ) )
...@@ -50,46 +51,25 @@ S3D_MODEL_PARSER* S3D_MODEL_PARSER::Create( S3D_MASTER* aMaster, ...@@ -50,46 +51,25 @@ S3D_MODEL_PARSER* S3D_MODEL_PARSER::Create( S3D_MASTER* aMaster,
return NULL; 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() ) int S3D_MASTER::ReadData( S3D_MODEL_PARSER* aParser )
return shapeName;
if( !default_path.EndsWith( wxT("/") ) && !default_path.EndsWith( wxT("\\") ) )
default_path += wxT("/");
default_path += shapeName;
return default_path;
}
int S3D_MASTER::ReadData()
{ {
if( m_Shape3DName.IsEmpty() ) 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__ #ifdef __WINDOWS__
filename.Replace( wxT( "/" ), wxT( "\\" ) ); filename.Replace( wxT( "/" ), wxT( "\\" ) );
...@@ -97,35 +77,30 @@ int S3D_MASTER::ReadData() ...@@ -97,35 +77,30 @@ int S3D_MASTER::ReadData()
filename.Replace( wxT( "\\" ), wxT( "/" ) ); filename.Replace( wxT( "\\" ), wxT( "/" ) );
#endif #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 ); wxFileName fn( filename );
wxString extension = fn.GetExt(); if( aParser->Load( filename ) )
m_parser = S3D_MODEL_PARSER::Create( this, extension );
if( m_parser )
{ {
m_parser->Load( filename ); // Invalidate bounding boxes
m_fastAABBox.Reset();
m_BBox.Reset();
m_parser = aParser;
return 0; 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; return -1;
} }
void S3D_MASTER::Render( bool aIsRenderingJustNonTransparentObjects, void S3D_MASTER::Render( bool aIsRenderingJustNonTransparentObjects,
bool aIsRenderingJustTransparentObjects ) bool aIsRenderingJustTransparentObjects )
{ {
...@@ -136,31 +111,80 @@ void S3D_MASTER::Render( bool aIsRenderingJustNonTransparentObjects, ...@@ -136,31 +111,80 @@ void S3D_MASTER::Render( bool aIsRenderingJustNonTransparentObjects,
glScalef( aVrmlunits_to_3Dunits, aVrmlunits_to_3Dunits, aVrmlunits_to_3Dunits ); glScalef( aVrmlunits_to_3Dunits, aVrmlunits_to_3Dunits, aVrmlunits_to_3Dunits );
glm::vec3 matScale( m_MatScale.x, glTranslatef( m_MatPosition.x * SCALE_3D_CONV,
m_MatScale.y, m_MatPosition.y * SCALE_3D_CONV,
m_MatScale.z ); m_MatPosition.z * SCALE_3D_CONV );
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 matRot( m_MatRotation.x, glScalef( m_MatScale.x, m_MatScale.y, m_MatScale.z );
m_MatRotation.y,
m_MatRotation.z );
glm::vec3 matPos( m_MatPosition.x, for( unsigned int idx = 0; idx < m_parser->childs.size(); idx++ )
m_MatPosition.y, m_parser->childs[idx]->openGL_RenderAllChilds( aIsRenderingJustNonTransparentObjects,
m_MatPosition.z ); aIsRenderingJustTransparentObjects );
}
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 ); CBBOX &S3D_MASTER::getBBox( )
glRotatef( -matRot.y, 0.0f, 1.0f, 0.0f ); {
glRotatef( -matRot.x, 1.0f, 0.0f, 0.0f ); if( !m_BBox.IsInitialized() )
calcBBox();
return m_BBox;
}
CBBOX &S3D_MASTER::getFastAABBox( )
{
if( !m_fastAABBox.IsInitialized() )
calcBBox();
return m_fastAABBox;
}
glScalef( matScale.x, matScale.y, matScale.z );
void S3D_MASTER::calcBBox()
{
if( m_parser == NULL )
return;
bool firstBBox = true;
for( unsigned int idx = 0; idx < m_parser->childs.size(); idx++ ) for( unsigned int idx = 0; idx < m_parser->childs.size(); idx++ )
if( firstBBox )
{ {
m_parser->childs[idx]->openGL_RenderAllChilds( aIsRenderingJustNonTransparentObjects, firstBBox = false;
aIsRenderingJustTransparentObjects ); 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 );
} }
/* /*
* 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) 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) 2004 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net> * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
...@@ -34,54 +34,12 @@ ...@@ -34,54 +34,12 @@
#include <common.h> #include <common.h>
#include <base_struct.h> #include <base_struct.h>
#include <3d_material.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 S3D_MASTER;
class STRUCT_3D_SHAPE; 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; class S3D_MODEL_PARSER;
// Master structure for a 3D footprint shape description // Master structure for a 3D footprint shape description
...@@ -112,8 +70,10 @@ public: ...@@ -112,8 +70,10 @@ public:
bool m_use_modelfile_shininess; bool m_use_modelfile_shininess;
private: private:
wxString m_Shape3DName; // the 3D shape filename in 3D library wxString m_Shape3DName; ///< The 3D shape filename in 3D library
FILE3D_TYPE m_ShapeType; 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: public:
S3D_MASTER( EDA_ITEM* aParent ); S3D_MASTER( EDA_ITEM* aParent );
...@@ -131,8 +91,9 @@ public: ...@@ -131,8 +91,9 @@ public:
* Function ReadData * Function ReadData
* Select the parser to read the 3D data file (vrml, x3d ...) * Select the parser to read the 3D data file (vrml, x3d ...)
* and build the description objects list * 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, void Render( bool aIsRenderingJustNonTransparentObjects,
bool aIsRenderingJustTransparentObjects ); bool aIsRenderingJustTransparentObjects );
...@@ -177,6 +138,12 @@ public: ...@@ -177,6 +138,12 @@ public:
*/ */
const wxString GetShape3DFullFilename(); const wxString GetShape3DFullFilename();
/**
* Function GetShape3DExtension
* @return the extension of the filename of the 3D shape,
*/
const wxString GetShape3DExtension();
/** /**
* Function SetShape3DName * Function SetShape3DName
* @param aShapeName = file name of the data file relative to the 3D shape * @param aShapeName = file name of the data file relative to the 3D shape
...@@ -185,6 +152,23 @@ public: ...@@ -185,6 +152,23 @@ public:
* (vrl, x3d, idf ) the type of file. * (vrl, x3d, idf ) the type of file.
*/ */
void SetShape3DName( const wxString& aShapeName ); 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: ...@@ -208,30 +192,4 @@ public:
#endif #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 #endif // STRUCT_3D_H
...@@ -187,6 +187,10 @@ void EDA_3D_FRAME::CreateMenuBar() ...@@ -187,6 +187,10 @@ void EDA_3D_FRAME::CreateMenuBar()
_( "Render Material Properties" ), _( "Render Material Properties" ),
KiBitmap( green_xpm ), wxITEM_CHECK ); 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(); prefsMenu->AppendSeparator();
wxMenu * backgrounColorMenu = new wxMenu; wxMenu * backgrounColorMenu = new wxMenu;
...@@ -300,6 +304,9 @@ void EDA_3D_FRAME::SetMenuBarOptionsState() ...@@ -300,6 +304,9 @@ void EDA_3D_FRAME::SetMenuBarOptionsState()
item = menuBar->FindItem( ID_MENU3D_FL_RENDER_MATERIAL ); item = menuBar->FindItem( ID_MENU3D_FL_RENDER_MATERIAL );
item->Check( GetPrm3DVisu().GetFlag( 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 = menuBar->FindItem( ID_MENU3D_SHOW_BOARD_BODY );
item->Check( GetPrm3DVisu().GetFlag( FL_SHOW_BOARD_BODY ) ); item->Check( GetPrm3DVisu().GetFlag( FL_SHOW_BOARD_BODY ) );
......
/*
* 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
...@@ -52,6 +52,7 @@ enum id_3dview_frm ...@@ -52,6 +52,7 @@ enum id_3dview_frm
ID_MENU3D_FL_RENDER_SMOOTH_NORMALS, ID_MENU3D_FL_RENDER_SMOOTH_NORMALS,
ID_MENU3D_FL_RENDER_USE_MODEL_NORMALS, ID_MENU3D_FL_RENDER_USE_MODEL_NORMALS,
ID_MENU3D_FL_RENDER_MATERIAL, ID_MENU3D_FL_RENDER_MATERIAL,
ID_MENU3D_FL_RENDER_SHOW_MODEL_BBOX,
ID_END_COMMAND_3D, ID_END_COMMAND_3D,
ID_TOOL_SET_VISIBLE_ITEMS, ID_TOOL_SET_VISIBLE_ITEMS,
......
/*
* 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();
}
/*
* 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
...@@ -22,17 +22,26 @@ ...@@ -22,17 +22,26 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
/**
* @file CImage.cpp
* @brief one 8bit-channel image implementation
*/
#include "CImage.h" #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;} #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_wxh = aXsize * aYsize;
m_width = xsize; m_pixels = (unsigned char*)malloc( m_wxh );
m_height = ysize; m_width = aXsize;
m_wxh = xsize * ysize; m_height = aYsize;
m_wraping = (E_WRAP)WRAP_CLAMP; m_wraping = (E_WRAP)WRAP_CLAMP;
} }
...@@ -43,10 +52,16 @@ CIMAGE::~CIMAGE() ...@@ -43,10 +52,16 @@ CIMAGE::~CIMAGE()
} }
bool CIMAGE::wrapCoords( int *xo, int *yo ) unsigned char* CIMAGE::GetBuffer() const
{ {
int x = *xo; return m_pixels;
int y = *yo; }
bool CIMAGE::wrapCoords( int *aXo, int *aYo ) const
{
int x = *aXo;
int y = *aYo;
switch(m_wraping) switch(m_wraping)
{ {
...@@ -66,40 +81,41 @@ bool CIMAGE::wrapCoords( int *xo, int *yo ) ...@@ -66,40 +81,41 @@ bool CIMAGE::wrapCoords( int *xo, int *yo )
break; 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; return false;
*xo = x; *aXo = x;
*yo = y; *aYo = y;
return true; 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 ) ) if( wrapCoords( &aX, &aY ) )
m_pixels[x + y * m_width] = value; 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 ) ) if( wrapCoords( &aX, &aY ) )
return m_pixels[x + y * m_width]; return m_pixels[aX + aY * m_width];
else else
return 0; 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]; 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; int aV, bV;
...@@ -117,8 +133,7 @@ void CIMAGE::copyFull( const CIMAGE *aImgA, const CIMAGE *aImgB, E_IMAGE_OP aOpe ...@@ -117,8 +133,7 @@ void CIMAGE::copyFull( const CIMAGE *aImgA, const CIMAGE *aImgB, E_IMAGE_OP aOpe
switch(aOperation) switch(aOperation)
{ {
case COPY_RAW: case COPY_RAW:
for( unsigned int it = 0;it < m_wxh; it++ ) memcpy( m_pixels, aImgA->m_pixels, m_wxh );
m_pixels[it] = aImgA->m_pixels[it];
break; break;
case COPY_ADD: case COPY_ADD:
...@@ -189,6 +204,13 @@ void CIMAGE::copyFull( const CIMAGE *aImgA, const CIMAGE *aImgB, E_IMAGE_OP aOpe ...@@ -189,6 +204,13 @@ void CIMAGE::copyFull( const CIMAGE *aImgA, const CIMAGE *aImgB, E_IMAGE_OP aOpe
break; break;
case COPY_BLEND50: case COPY_BLEND50:
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; break;
case COPY_MIN: case COPY_MIN:
...@@ -210,11 +232,16 @@ void CIMAGE::copyFull( const CIMAGE *aImgA, const CIMAGE *aImgB, E_IMAGE_OP aOpe ...@@ -210,11 +232,16 @@ void CIMAGE::copyFull( const CIMAGE *aImgA, const CIMAGE *aImgB, E_IMAGE_OP aOpe
m_pixels[it] = (aV > bV)?aV:bV; m_pixels[it] = (aV > bV)?aV:bV;
} }
break; break;
default:
break;
} }
} }
// TIP: If you want create or test filters you can use GIMP
S_FILTER FILTERS[9] = { // 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 // Hi Pass
{ {
{ { 0, -1, -1, -1, 0}, { { 0, -1, -1, -1, 0},
...@@ -230,17 +257,28 @@ S_FILTER FILTERS[9] = { ...@@ -230,17 +257,28 @@ S_FILTER FILTERS[9] = {
// Blur // Blur
{ {
{ { 3, 5, 7, 5, 3}, { { 3, 5, 7, 5, 3},
{ 4, 9, 12, 9, 5}, { 5, 9, 12, 9, 5},
{ 7, 12, 20, 12, 7}, { 7, 12, 20, 12, 7},
{ 4, 9, 12, 9, 5}, { 5, 9, 12, 9, 5},
{ 3, 5, 7, 5, 3} { 3, 5, 7, 5, 3}
}, },
180, 182,
0 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}, { { 0, 2, 4, 2, 0},
{ 2, -2, 1, -2, 2}, { 2, -2, 1, -2, 2},
...@@ -326,31 +364,41 @@ S_FILTER FILTERS[9] = { ...@@ -326,31 +364,41 @@ S_FILTER FILTERS[9] = {
};// Filters };// 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]; S_FILTER filter = FILTERS[aFilterType];
aInImg->m_wraping = WRAP_CLAMP; aInImg->m_wraping = WRAP_CLAMP;
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 iy = 0; iy < (int)m_height; iy++)
{ {
for( int ix = 0; ix < (int)m_width; ix++ ) 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 sy = 0; sy < 5; sy++ )
{ {
for( int sx = 0; sx < 5; sx++ ) for( int sx = 0; sx < 5; sx++ )
{ {
int factor = filter.kernel[sx][sy]; 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 += pixelv * factor;
} }
} }
v /= filter.div; v /= filter.div;
v += filter.offset;
CLAMP(v, 0, 255); CLAMP(v, 0, 255);
m_pixels[ix + iy * m_width] = v; m_pixels[ix + iy * m_width] = v;
...@@ -359,7 +407,7 @@ void CIMAGE::efxFilter( CIMAGE *aInImg, float aGain, E_FILTER aFilterType ) ...@@ -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++ ) for( unsigned int i = 0; i < m_wxh; i++ )
{ {
...@@ -370,26 +418,23 @@ void CIMAGE::setPixelsFromNormalizedFloat( const float * aNormalizedFloatArray ) ...@@ -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* pixelbuffer = (unsigned char*) malloc( m_wxh * 3 );
//unsigned char* alphabuffer = (unsigned char*) malloc( m_width * aHeight );
wxImage image( m_width, m_height ); wxImage image( m_width, m_height );
for( unsigned int i = 0; i < m_wxh; i++) for( unsigned int i = 0; i < m_wxh; i++)
{ {
unsigned char v = m_pixels[i]; unsigned char v = m_pixels[i];
// Set RGB value with all same values intensities
pixelbuffer[i * 3 + 0] = v; pixelbuffer[i * 3 + 0] = v;
pixelbuffer[i * 3 + 1] = v; pixelbuffer[i * 3 + 1] = v;
pixelbuffer[i * 3 + 2] = v; pixelbuffer[i * 3 + 2] = v;
//alphabuffer[i * 1 + 0] = aRGBABufferImage[i * 4 + 3];
} }
image.SetData( pixelbuffer ); image.SetData( pixelbuffer );
//image.SetAlpha( alphabuffer );
image = image.Mirror( false ); image = image.Mirror( false );
image.SaveFile( aFileName + ".png", wxBITMAP_TYPE_PNG ); image.SaveFile( aFileName + ".png", wxBITMAP_TYPE_PNG );
image.Destroy(); image.Destroy();
} }
...@@ -22,11 +22,17 @@ ...@@ -22,11 +22,17 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
/**
* @file CImage.h
* @brief one 8bit-channel image definition
*/
#ifndef CImage_h #ifndef CImage_h
#define CImage_h #define CImage_h
#include <wx/image.h> #include <wx/string.h>
/// Image operation type
enum E_IMAGE_OP { enum E_IMAGE_OP {
COPY_RAW, COPY_RAW,
COPY_ADD, COPY_ADD,
...@@ -41,17 +47,23 @@ enum E_IMAGE_OP { ...@@ -41,17 +47,23 @@ enum E_IMAGE_OP {
COPY_MAX COPY_MAX
}; };
/// Image wrap type enumeration
enum E_WRAP { enum E_WRAP {
WRAP_ZERO, ///< Coords that wraps are not evaluated WRAP_ZERO, ///< Coords that wraps are not evaluated
WRAP_CLAMP, WRAP_CLAMP, ///< Coords are clamped to image size
WRAP_WRAP ///< Coords are wrapped arround WRAP_WRAP ///< Coords are wrapped arround
}; };
/// Filter type enumeration
enum E_FILTER { enum E_FILTER {
FILTER_HIPASS, FILTER_HIPASS,
FILTER_BLUR FILTER_GAUSSIAN_BLUR,
FILTER_INVERT_BLUR,
}; };
/// 5x5 Filter struct parameters
typedef struct { typedef struct {
signed char kernel[5][5]; signed char kernel[5][5];
unsigned char div; unsigned char div;
...@@ -59,36 +71,120 @@ typedef struct { ...@@ -59,36 +71,120 @@ typedef struct {
}S_FILTER; }S_FILTER;
/**
* Class CIMAGE
* manages a 8-bit channel image
*/
class CIMAGE class CIMAGE
{ {
public: 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(); ~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;
/**
* 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 copyFull( const CIMAGE *aImgA, const CIMAGE *aImgB, E_IMAGE_OP aOperation ); /**
* Function Invert
* invert the values of image this <- (255 - this)
*/
void Invert();
/**
* 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 invert(); /**
* 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;
void efxFilter( CIMAGE *aInImg, float aGain, E_FILTER aFilterType ); /**
* 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 );
void saveAsPNG( wxString aFileName ); /**
* 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: private:
bool wrapCoords( int *xo, int *yo );
public: /**
unsigned char* m_pixels; * Function wrapCoords
unsigned int m_width; * calculate the coordinates points in accord with the current clamping settings
unsigned int m_height; * @param aXo X coordinate to be converted (output)
unsigned int m_wxh; * @param aXo Y coordinate to be converted (output)
E_WRAP m_wraping; * @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
...@@ -31,6 +31,7 @@ set(3D-VIEWER_SRCS ...@@ -31,6 +31,7 @@ set(3D-VIEWER_SRCS
vrml_v2_modelparser.cpp vrml_v2_modelparser.cpp
x3dmodelparser.cpp x3dmodelparser.cpp
CImage.cpp CImage.cpp
CBBox.cpp
) )
add_library(3d-viewer STATIC ${3D-VIEWER_SRCS}) add_library(3d-viewer STATIC ${3D-VIEWER_SRCS})
......
...@@ -231,10 +231,19 @@ void INFO3D_VISU::InitSettings( BOARD* aBoard ) ...@@ -231,10 +231,19 @@ void INFO3D_VISU::InitSettings( BOARD* aBoard )
*/ */
double INFO3D_VISU::GetModulesZcoord3DIU( bool aIsFlipped ) double INFO3D_VISU::GetModulesZcoord3DIU( bool aIsFlipped )
{ {
// NOTE: Z position to display modules in top of Paste and near the shadow
if( aIsFlipped ) if( aIsFlipped )
return m_layerZcoord[B_Paste] - ( m_copperThickness / 2 ); {
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 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 );
}
} }
...@@ -78,6 +78,7 @@ enum DISPLAY3D_FLG { ...@@ -78,6 +78,7 @@ enum DISPLAY3D_FLG {
FL_RENDER_SMOOTH_NORMALS, FL_RENDER_SMOOTH_NORMALS,
FL_RENDER_USE_MODEL_NORMALS, FL_RENDER_USE_MODEL_NORMALS,
FL_RENDER_MATERIAL, FL_RENDER_MATERIAL,
FL_RENDER_SHOW_MODEL_BBOX,
FL_LAST FL_LAST
}; };
......
...@@ -35,7 +35,6 @@ ...@@ -35,7 +35,6 @@
#include <3d_mesh_model.h> #include <3d_mesh_model.h>
class S3D_MASTER; class S3D_MASTER;
class S3D_MODEL_PARSER;
class X3D_MODEL_PARSER; class X3D_MODEL_PARSER;
/** /**
...@@ -49,13 +48,7 @@ public: ...@@ -49,13 +48,7 @@ public:
master( aMaster ) master( aMaster )
{} {}
~S3D_MODEL_PARSER() virtual ~S3D_MODEL_PARSER(){}
{
for( unsigned int idx = 0; idx < childs.size(); idx++ )
{
delete childs[idx];
}
}
S3D_MASTER* GetMaster() S3D_MASTER* GetMaster()
{ {
...@@ -73,22 +66,14 @@ public: ...@@ -73,22 +66,14 @@ public:
static S3D_MODEL_PARSER* Create( S3D_MASTER* aMaster, const wxString aExtension ); static S3D_MODEL_PARSER* Create( S3D_MASTER* aMaster, const wxString aExtension );
/** /**
* pure virtual Function * virtual Function
* Concrete parsers should implement this function * Concrete parsers should implement this function
* @param aFilename = the full file name of the file to load * @param aFilename = the full file name of the file to load
* @return true if as succeeded * @return true if as succeeded
*/ */
virtual bool Load( const wxString& aFilename ) = 0; virtual bool Load( const wxString& aFilename ) {
return false;
/** };
* 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 );
std::vector< S3D_MESH* > childs; std::vector< S3D_MESH* > childs;
...@@ -158,6 +143,7 @@ private: ...@@ -158,6 +143,7 @@ private:
typedef std::map< std::string, std::vector< glm::vec3 > > VRML2_COORDINATE_MAP; 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 * class VRML2_MODEL_PARSER
...@@ -171,6 +157,15 @@ public: ...@@ -171,6 +157,15 @@ public:
bool Load( const wxString& aFilename ); 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 * Return string representing VRML2 file in vrml2 format
* Function Load must be called before this function, otherwise empty * Function Load must be called before this function, otherwise empty
...@@ -179,6 +174,7 @@ public: ...@@ -179,6 +174,7 @@ public:
wxString VRML2_representation(); wxString VRML2_representation();
private: private:
int loadFileModel( S3D_MESH *transformationModel );
int read_Transform(); int read_Transform();
int read_DEF(); int read_DEF();
int read_DEF_Coordinate(); int read_DEF_Coordinate();
...@@ -195,16 +191,33 @@ private: ...@@ -195,16 +191,33 @@ private:
int read_Color(); int read_Color();
int read_coordIndex(); int read_coordIndex();
int read_colorIndex(); 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 m_normalPerVertex;
bool colorPerVertex; bool colorPerVertex;
S3D_MESH* m_model; S3D_MESH* m_model; ///< It stores the current model that the parsing is adding data
FILE* m_file; FILE* m_file;
wxString m_Filename; wxFileName m_Filename;
VRML2_COORDINATE_MAP m_defCoordinateMap; 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_MODEL_PARSER* m_ModelParser;
S3D_MASTER* m_Master; S3D_MASTER* m_Master;
wxString m_debugSpacer; ///< Used to give identation space
}; };
...@@ -267,7 +280,6 @@ public: ...@@ -267,7 +280,6 @@ public:
* by the vrml file data * by the vrml file data
*/ */
VRML_MODEL_PARSER( S3D_MASTER* aMaster ); VRML_MODEL_PARSER( S3D_MASTER* aMaster );
~VRML_MODEL_PARSER(); ~VRML_MODEL_PARSER();
/** /**
...@@ -279,11 +291,6 @@ public: ...@@ -279,11 +291,6 @@ public:
* to our internal units. * to our internal units.
*/ */
bool Load( const wxString& aFilename ); 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;
}; };
......
/* /*
* 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) 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. * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.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
...@@ -24,11 +24,58 @@ ...@@ -24,11 +24,58 @@
/** /**
* @file vrml_aux.cpp * @file vrml_aux.cpp
* @brief implements auxiliar functions to parse VRML files
*/ */
#include "vrml_aux.h" #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 ); static int SkipGetChar ( FILE* File );
...@@ -140,7 +187,7 @@ bool GetNextTag( FILE* File, char* tag, size_t len ) ...@@ -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; int c;
...@@ -150,12 +197,12 @@ int read_NotImplemented( FILE* File, char closeChar ) ...@@ -150,12 +197,12 @@ int read_NotImplemented( FILE* File, char closeChar )
if( c == '{' ) if( c == '{' )
{ {
// DBG( printf( "{\n") ); // DBG( printf( "{\n") );
read_NotImplemented( File, '}' ); Read_NotImplemented( File, '}' );
} }
else if( c == '[' ) else if( c == '[' )
{ {
// DBG( printf( "[\n") ); // DBG( printf( "[\n") );
read_NotImplemented( File, ']' ); Read_NotImplemented( File, ']' );
} }
else if( c == closeChar ) else if( c == closeChar )
{ {
...@@ -169,15 +216,15 @@ int read_NotImplemented( FILE* File, char 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(); dst_vector.clear();
glm::vec3 vertex; glm::vec3 vertex;
while( parseVertex( File, vertex ) == 3 ) while( ParseVertex( File, vertex ) == 3 )
{ {
dst_vector.push_back( vertex ); dst_vector.push_back( vertex );
} }
...@@ -186,7 +233,7 @@ int parseVertexList( FILE* File, std::vector<glm::vec3>& dst_vector ) ...@@ -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; float a, b, c;
int ret = fscanf( File, "%e %e %e", &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 ) ...@@ -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; float value;
int ret = fscanf( File, "%e", &value ); int ret = fscanf( File, "%e", &value );
......
/* /*
* 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) 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. * Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.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
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
/** /**
* @file vrml_aux.h * @file vrml_aux.h
* @brief auxiliar functions to parse VRML files
*/ */
#ifndef _VRML_AUX_H #ifndef _VRML_AUX_H
...@@ -48,10 +49,63 @@ ...@@ -48,10 +49,63 @@
#endif #endif
#include <wx/glcanvas.h> #include <wx/glcanvas.h>
int read_NotImplemented( FILE* File, char closeChar); /**
int parseVertexList( FILE* File, std::vector< glm::vec3 > &dst_vector); * Function GetEpoxyThicknessBIU
int parseVertex( FILE* File, glm::vec3 &dst_vertex ); * skip a VRML block and eventualy internal blocks until it find the close char
int parseFloat( FILE* File, float *dst_float ); * @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 ); 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 #endif
...@@ -138,7 +138,7 @@ int VRML1_MODEL_PARSER::read_separator() ...@@ -138,7 +138,7 @@ int VRML1_MODEL_PARSER::read_separator()
else if( ( *text != '}' ) ) else if( ( *text != '}' ) )
{ {
// DBG( printf( "read_NotImplemented %s\n", text ) ); // DBG( printf( "read_NotImplemented %s\n", text ) );
read_NotImplemented( m_file, '}' ); Read_NotImplemented( m_file, '}' );
} }
else else
break; break;
...@@ -272,7 +272,7 @@ int VRML1_MODEL_PARSER::readMaterial_ambientColor() ...@@ -272,7 +272,7 @@ int VRML1_MODEL_PARSER::readMaterial_ambientColor()
{ {
// DBG( printf( " readMaterial_ambientColor\n" ) ); // 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() ...@@ -280,7 +280,7 @@ int VRML1_MODEL_PARSER::readMaterial_diffuseColor()
{ {
// DBG( printf( " readMaterial_diffuseColor\n" ) ); // 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() ...@@ -288,7 +288,7 @@ int VRML1_MODEL_PARSER::readMaterial_emissiveColor()
{ {
// DBG( printf( " readMaterial_emissiveColor\n" ) ); // 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 ) if( m_Master->m_use_modelfile_emissiveColor == false )
{ {
...@@ -303,7 +303,7 @@ int VRML1_MODEL_PARSER::readMaterial_specularColor() ...@@ -303,7 +303,7 @@ int VRML1_MODEL_PARSER::readMaterial_specularColor()
{ {
// DBG( printf( " readMaterial_specularColor\n" ) ); // 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 ) if( m_Master->m_use_modelfile_specularColor == false )
{ {
...@@ -368,7 +368,7 @@ int VRML1_MODEL_PARSER::readCoordinate3_point() ...@@ -368,7 +368,7 @@ int VRML1_MODEL_PARSER::readCoordinate3_point()
{ {
// DBG( printf( " readCoordinate3_point\n" ) ); // 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; return 0;
} }
......
This diff is collapsed.
...@@ -41,17 +41,20 @@ ...@@ -41,17 +41,20 @@
VRML_MODEL_PARSER::VRML_MODEL_PARSER( S3D_MASTER* aMaster ) : VRML_MODEL_PARSER::VRML_MODEL_PARSER( S3D_MASTER* aMaster ) :
S3D_MODEL_PARSER( aMaster ) S3D_MODEL_PARSER( aMaster )
{ {
vrml1_parser = NULL;
vrml2_parser = NULL;
m_curr3DShape = NULL;
} }
VRML_MODEL_PARSER::~VRML_MODEL_PARSER() 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 ) bool VRML_MODEL_PARSER::Load( const wxString& aFilename )
{ {
char line[11 + 1]; char line[11 + 1];
...@@ -72,20 +75,20 @@ bool VRML_MODEL_PARSER::Load( const wxString& aFilename ) ...@@ -72,20 +75,20 @@ bool VRML_MODEL_PARSER::Load( const wxString& aFilename )
fclose( file ); fclose( file );
childs.clear();
if( stricmp( line, "#VRML V2.0" ) == 0 ) 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 ); vrml2_parser->Load( aFilename );
delete vrml2_parser; delete vrml2_parser;
vrml2_parser = NULL;
return true; return true;
} }
else if( stricmp( line, "#VRML V1.0" ) == 0 ) 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 ); vrml1_parser->Load( aFilename );
delete vrml1_parser; delete vrml1_parser;
vrml1_parser = NULL;
return true; return true;
} }
......
...@@ -58,6 +58,14 @@ X3D_MODEL_PARSER::X3D_MODEL_PARSER( S3D_MASTER* aMaster ) : ...@@ -58,6 +58,14 @@ X3D_MODEL_PARSER::X3D_MODEL_PARSER( S3D_MASTER* aMaster ) :
X3D_MODEL_PARSER::~X3D_MODEL_PARSER() X3D_MODEL_PARSER::~X3D_MODEL_PARSER()
{ {
for( unsigned int idx = 0; idx < childs.size(); idx++ )
{
if( childs[idx] )
{
delete childs[idx];
childs[idx] = 0;
}
}
} }
......
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