247 lines
9.1 KiB
C++
247 lines
9.1 KiB
C++
/*
|
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
|
*
|
|
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
|
* Copyright (C) 2015-2021 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
|
|
*/
|
|
|
|
#ifndef RENDER_3D_OPENGL_H
|
|
#define RENDER_3D_OPENGL_H
|
|
|
|
#include "../render_3d_base.h"
|
|
#include "layer_triangles.h"
|
|
|
|
#include "../raytracing/shapes2D/polygon_2d.h"
|
|
#include "../raytracing/shapes2D/triangle_2d.h"
|
|
#include "../raytracing/shapes2D/4pt_polygon_2d.h"
|
|
#include "../raytracing/shapes2D/filled_circle_2d.h"
|
|
#include "../raytracing/shapes2D/ring_2d.h"
|
|
#include "../raytracing/shapes2D/round_segment_2d.h"
|
|
|
|
#include "3d_model.h"
|
|
|
|
#include "3d_cache/3d_info.h"
|
|
|
|
#include <map>
|
|
|
|
typedef std::map< PCB_LAYER_ID, OPENGL_RENDER_LIST* > MAP_OGL_DISP_LISTS;
|
|
typedef std::list<TRIANGLE_DISPLAY_LIST* > LIST_TRIANGLES;
|
|
|
|
#define SIZE_OF_CIRCLE_TEXTURE 1024
|
|
|
|
/**
|
|
* Object to render the board using openGL.
|
|
*/
|
|
class RENDER_3D_OPENGL : public RENDER_3D_BASE
|
|
{
|
|
public:
|
|
explicit RENDER_3D_OPENGL( EDA_3D_CANVAS* aCanvas, BOARD_ADAPTER& aAdapter, CAMERA& aCamera );
|
|
|
|
~RENDER_3D_OPENGL();
|
|
|
|
void SetCurWindowSize( const wxSize& aSize ) override;
|
|
bool Redraw( bool aIsMoving, REPORTER* aStatusReporter, REPORTER* aWarningReporter ) override;
|
|
|
|
int GetWaitForEditingTimeOut() override;
|
|
|
|
void SetCurrentRollOverItem( BOARD_ITEM* aRollOverItem )
|
|
{
|
|
m_currentRollOverItem = aRollOverItem;
|
|
}
|
|
|
|
/**
|
|
* Load footprint models if they are not already loaded, i.e. if m_3dModelMap is empty
|
|
*/
|
|
void Load3dModelsIfNeeded();
|
|
|
|
private:
|
|
OPENGL_RENDER_LIST* generateHoles( const LIST_OBJECT2D& aListHolesObject2d,
|
|
const SHAPE_POLY_SET& aPoly, float aZtop,
|
|
float aZbot, bool aInvertFaces,
|
|
const BVH_CONTAINER_2D* aThroughHoles = nullptr );
|
|
|
|
OPENGL_RENDER_LIST* generateLayerList( const BVH_CONTAINER_2D* aContainer,
|
|
const SHAPE_POLY_SET* aPolyList,
|
|
PCB_LAYER_ID aLayerId,
|
|
const BVH_CONTAINER_2D* aThroughHoles = nullptr );
|
|
|
|
OPENGL_RENDER_LIST* generateEmptyLayerList( PCB_LAYER_ID aLayerId );
|
|
|
|
void addTopAndBottomTriangles( TRIANGLE_DISPLAY_LIST* aDst, const SFVEC2F& v0,
|
|
const SFVEC2F& v1, const SFVEC2F& v2, float top, float bot );
|
|
|
|
void addObjectTriangles( const RING_2D* aRing, TRIANGLE_DISPLAY_LIST* aDstLayer,
|
|
float aZtop, float aZbot );
|
|
|
|
void addObjectTriangles( const POLYGON_4PT_2D* aPoly, TRIANGLE_DISPLAY_LIST* aDstLayer,
|
|
float aZtop, float aZbot );
|
|
|
|
void addObjectTriangles( const FILLED_CIRCLE_2D* aFilledCircle,
|
|
TRIANGLE_DISPLAY_LIST* aDstLayer, float aZtop, float aZbot );
|
|
|
|
void addObjectTriangles( const TRIANGLE_2D* aTri, TRIANGLE_DISPLAY_LIST* aDstLayer,
|
|
float aZtop, float aZbot );
|
|
|
|
void addObjectTriangles( const ROUND_SEGMENT_2D* aSeg,
|
|
TRIANGLE_DISPLAY_LIST* aDstLayer, float aZtop, float aZbot );
|
|
|
|
void renderSolderMaskLayer( PCB_LAYER_ID aLayerID, float aZPosition,
|
|
bool aDrawMiddleSegments, bool aSkipRenderHoles );
|
|
|
|
void renderBoardBody( bool aSkipRenderHoles );
|
|
|
|
void getLayerZPos( PCB_LAYER_ID aLayerID, float& aOutZtop, float& aOutZbot ) const;
|
|
|
|
void generateRing( const SFVEC2F& aCenter, float aInnerRadius, float aOuterRadius,
|
|
unsigned int aNr_sides_per_circle,
|
|
std::vector< SFVEC2F >& aInnerContourResult,
|
|
std::vector< SFVEC2F >& aOuterContourResult, bool aInvertOrder );
|
|
|
|
void generateCylinder( const SFVEC2F& aCenter, float aInnerRadius, float aOuterRadius,
|
|
float aZtop, float aZbot, unsigned int aNr_sides_per_circle,
|
|
TRIANGLE_DISPLAY_LIST* aDstLayer );
|
|
|
|
void generateViasAndPads();
|
|
|
|
/**
|
|
* Load footprint models from the cache and load it to openGL lists in the form of
|
|
* #MODEL_3D objects.
|
|
*
|
|
* This map of models will work as a local cache for this render. (cache based on
|
|
* MODEL_3D with associated openGL lists in GPU memory)
|
|
*/
|
|
void load3dModels( REPORTER* aStatusReporter );
|
|
|
|
struct MODELTORENDER
|
|
{
|
|
glm::mat4 m_modelWorldMat;
|
|
const MODEL_3D* m_model;
|
|
float m_opacity;
|
|
bool m_isTransparent;
|
|
bool m_isSelected;
|
|
|
|
MODELTORENDER( glm::mat4 aModelWorldMat,
|
|
const MODEL_3D* aNodel,
|
|
float aOpacity,
|
|
bool aIsTransparent,
|
|
bool aIsSelected ) :
|
|
m_modelWorldMat( std::move( aModelWorldMat ) ),
|
|
m_model( aNodel ),
|
|
m_opacity( aOpacity ),
|
|
m_isTransparent( aIsTransparent ),
|
|
m_isSelected( aIsSelected )
|
|
{
|
|
}
|
|
};
|
|
|
|
void renderOpaqueModels( const glm::mat4 &aCameraViewMatrix );
|
|
void renderTransparentModels( const glm::mat4 &aCameraViewMatrix );
|
|
|
|
void renderModel( const glm::mat4 &aCameraViewMatrix,
|
|
const MODELTORENDER &aModelToRender,
|
|
const SFVEC3F &aSelColor,
|
|
const SFVEC3F *aCameraWorldPos );
|
|
|
|
|
|
void get3dModelsSelected( std::list<MODELTORENDER> &aDstRenderList,
|
|
bool aGetTop, bool aGetBot, bool aRenderTransparentOnly,
|
|
bool aRenderSelectedOnly );
|
|
|
|
void get3dModelsFromFootprint( std::list<MODELTORENDER> &aDstRenderList,
|
|
const FOOTPRINT* aFootprint, bool aRenderTransparentOnly,
|
|
bool aIsSelected );
|
|
|
|
void setLightFront( bool enabled );
|
|
void setLightTop( bool enabled );
|
|
void setLightBottom( bool enabled );
|
|
|
|
void render3dArrows();
|
|
|
|
/**
|
|
* Create a 3D grid to an OpenGL display list.
|
|
*
|
|
* A horizontal grid (XY plane and Z = 0, and a vertical grid (XZ plane and Y = 0).
|
|
*/
|
|
void generate3dGrid( GRID3D_TYPE aGridType );
|
|
|
|
// Materials
|
|
void setupMaterials();
|
|
|
|
void setCopperMaterial();
|
|
void setPlatedCopperAndDepthOffset( PCB_LAYER_ID aLayer_id );
|
|
void unsetDepthOffset();
|
|
|
|
void setLayerMaterial( PCB_LAYER_ID aLayerID );
|
|
|
|
bool initializeOpenGL();
|
|
OPENGL_RENDER_LIST* createBoard( const SHAPE_POLY_SET& aBoardPoly,
|
|
const BVH_CONTAINER_2D* aThroughHoles = nullptr );
|
|
void reload( REPORTER* aStatusReporter, REPORTER* aWarningReporter );
|
|
|
|
void setArrowMaterial();
|
|
|
|
void freeAllLists();
|
|
|
|
struct
|
|
{
|
|
SMATERIAL m_Paste;
|
|
SMATERIAL m_SilkSBot;
|
|
SMATERIAL m_SilkSTop;
|
|
SMATERIAL m_SolderMask;
|
|
SMATERIAL m_EpoxyBoard;
|
|
SMATERIAL m_NonPlatedCopper; // raw copper
|
|
SMATERIAL m_Copper;
|
|
SMATERIAL m_Plastic;
|
|
SMATERIAL m_GrayMaterial;
|
|
} m_materials;
|
|
|
|
MAP_OGL_DISP_LISTS m_layers;
|
|
OPENGL_RENDER_LIST* m_platedPadsFront;
|
|
OPENGL_RENDER_LIST* m_platedPadsBack;
|
|
MAP_OGL_DISP_LISTS m_outerLayerHoles;
|
|
MAP_OGL_DISP_LISTS m_innerLayerHoles;
|
|
OPENGL_RENDER_LIST* m_board;
|
|
OPENGL_RENDER_LIST* m_boardWithHoles;
|
|
OPENGL_RENDER_LIST* m_antiBoard;
|
|
OPENGL_RENDER_LIST* m_outerThroughHoles;
|
|
OPENGL_RENDER_LIST* m_outerViaThroughHoles;
|
|
OPENGL_RENDER_LIST* m_outerThroughHoleRings;
|
|
|
|
LIST_TRIANGLES m_triangles; ///< store pointers so can be deleted latter
|
|
GLuint m_circleTexture;
|
|
|
|
GLuint m_grid; ///< oGL list that stores current grid
|
|
GRID3D_TYPE m_lastGridType; ///< Stores the last grid type.
|
|
|
|
OPENGL_RENDER_LIST* m_vias;
|
|
OPENGL_RENDER_LIST* m_padHoles;
|
|
|
|
// Caches
|
|
std::map< wxString, MODEL_3D* > m_3dModelMap;
|
|
std::map< std::vector<float>, glm::mat4 > m_3dModelMatrixMap;
|
|
|
|
BOARD_ITEM* m_currentRollOverItem;
|
|
|
|
SHAPE_POLY_SET m_antiBoardPolys; ///< The negative polygon representation of the board
|
|
///< outline.
|
|
};
|
|
|
|
#endif // RENDER_3D_OPENGL_H
|