From 4d128b819a1e79d538425cc7c22d36050949998f Mon Sep 17 00:00:00 2001 From: Wayne Stambaugh Date: Sun, 13 Dec 2020 18:02:57 -0500 Subject: [PATCH] 3D viewer code cleaning round 3. --- .../c3d_render_createscene_ogl_legacy.cpp | 107 +++--- .../c3d_render_ogl_legacy.cpp | 323 ++++++++---------- .../c3d_render_ogl_legacy.h | 111 +++--- .../3d_render_ogl_legacy/c_ogl_3dmodel.cpp | 56 +-- .../3d_render_ogl_legacy/c_ogl_3dmodel.h | 48 +-- 3d-viewer/3d_rendering/buffers_debug.cpp | 53 ++- 3d-viewer/3d_rendering/buffers_debug.h | 23 +- 3d-viewer/3d_rendering/c3d_render_base.cpp | 5 +- 3d-viewer/3d_rendering/c3d_render_base.h | 51 ++- 3d-viewer/3d_rendering/ccamera.cpp | 58 ++-- 3d-viewer/3d_rendering/ccamera.h | 117 ++++--- 3d-viewer/3d_rendering/ccolorrgb.cpp | 18 +- 3d-viewer/3d_rendering/ccolorrgb.h | 16 +- 3d-viewer/3d_rendering/cimage.cpp | 87 ++--- 3d-viewer/3d_rendering/cimage.h | 131 ++++--- 3d-viewer/3d_rendering/cpostshader.cpp | 30 +- 3d-viewer/3d_rendering/cpostshader.h | 57 ++-- 3d-viewer/3d_rendering/cpostshader_ssao.cpp | 67 ++-- 3d-viewer/3d_rendering/cpostshader_ssao.h | 41 +-- 3d-viewer/3d_rendering/ctrack_ball.cpp | 28 +- 3d-viewer/3d_rendering/ctrack_ball.h | 19 +- 3d-viewer/3d_rendering/test_cases.cpp | 136 ++++---- 22 files changed, 747 insertions(+), 835 deletions(-) diff --git a/3d-viewer/3d_rendering/3d_render_ogl_legacy/c3d_render_createscene_ogl_legacy.cpp b/3d-viewer/3d_rendering/3d_render_ogl_legacy/c3d_render_createscene_ogl_legacy.cpp index 5033bf03ae..7cdf7c719c 100644 --- a/3d-viewer/3d_rendering/3d_render_ogl_legacy/c3d_render_createscene_ogl_legacy.cpp +++ b/3d-viewer/3d_rendering/3d_render_ogl_legacy/c3d_render_createscene_ogl_legacy.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2015-2016 Mario Luzeiro - * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2015-2020 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 @@ -44,8 +44,7 @@ void C3D_RENDER_OGL_LEGACY::add_object_to_triangle_layer( const CFILLEDCIRCLE2D const float texture_factor = (8.0f / (float)SIZE_OF_CIRCLE_TEXTURE) + 1.0f; const float f = (sqrtf(2.0f) / 2.0f) * radius * texture_factor; - // Top and Bot segments ends are just triangle semi-circles, so need to add - // it in duplicated + // Top and Bot segments ends are just triangle semi-circles, so need to add it in duplicated. aDstLayer->m_layer_top_segment_ends->AddTriangle( SFVEC3F( center.x + f, center.y, aZtop ), SFVEC3F( center.x - f, center.y, aZtop ), SFVEC3F( center.x, center.y - f, aZtop ) ); @@ -96,7 +95,7 @@ void C3D_RENDER_OGL_LEGACY::generate_ring_contour( const SFVEC2F &aCenter, for( int ii = 0; ii < 3600; ii += delta ) { float angle = (float)( aInvertOrder ? ( 3600 - ii ) : ii ) - * 2.0f * glm::pi() / 3600.0f; + * 2.0f * glm::pi() / 3600.0f; const SFVEC2F rotatedDir = SFVEC2F( cos( angle ), sin( angle ) ); aInnerContourResult.emplace_back( aCenter.x + rotatedDir.x * aInnerRadius, @@ -133,7 +132,6 @@ void C3D_RENDER_OGL_LEGACY::add_object_to_triangle_layer( const CRING2D * aRing, false ); // This will add the top and bot quads that will form the approximated ring - for( unsigned int i = 0; i < ( innerContour.size() - 1 ); ++i ) { const SFVEC2F &vi0 = innerContour[i + 0]; @@ -182,11 +180,11 @@ void C3D_RENDER_OGL_LEGACY::add_object_to_triangle_layer( const CROUNDSEGMENT2D const SFVEC2F& start = aSeg->GetStart(); const SFVEC2F& end = aSeg->GetEnd(); - const float texture_factor = (12.0f / (float)SIZE_OF_CIRCLE_TEXTURE) + 1.0f; - const float texture_factorF= ( 6.0f / (float)SIZE_OF_CIRCLE_TEXTURE) + 1.0f; + const float texture_factor = ( 12.0f / (float) SIZE_OF_CIRCLE_TEXTURE ) + 1.0f; + const float texture_factorF = ( 6.0f / (float) SIZE_OF_CIRCLE_TEXTURE ) + 1.0f; const float radius_of_the_square = sqrtf( aSeg->GetRadiusSquared() * 2.0f ); - const float radius_triangle_factor = (radius_of_the_square - radius) / radius; + const float radius_triangle_factor = ( radius_of_the_square - radius ) / radius; const SFVEC2F factorS = SFVEC2F( -rightDir.y * radius * radius_triangle_factor, rightDir.x * radius * radius_triangle_factor ); @@ -295,9 +293,7 @@ CLAYERS_OGL_DISP_LISTS *C3D_RENDER_OGL_LEGACY::generate_holes_display_list( } // Note: he can have a aListHolesObject2d whith holes but without countours - // eg: when there are only NPTH on the list and the contours were not - // added - + // eg: when there are only NPTH on the list and the contours were not added if( aPoly.OutlineCount() > 0 ) { layerTriangles->AddToMiddleContourns( aPoly, aZbot, aZtop, @@ -386,8 +382,8 @@ C3D_RENDER_OGL_LEGACY::generateLayerListFromContainer( const CBVHCONTAINER2D *aC layerTriangles->AddToMiddleContourns( *aPolyList, layer_z_bot, layer_z_top, m_boardAdapter.BiuTo3Dunits(), false, aThroughHoles ); } + // Create display list - // ///////////////////////////////////////////////////////////////////// return new CLAYERS_OGL_DISP_LISTS( *layerTriangles, m_ogl_circle_texture, layer_z_bot, layer_z_top ); } @@ -421,7 +417,7 @@ CLAYERS_OGL_DISP_LISTS* C3D_RENDER_OGL_LEGACY::createBoard( const SHAPE_POLY_SET itemOnLayer != listBoardObject2d.end(); ++itemOnLayer ) { - const COBJECT2D *object2d_A = static_cast(*itemOnLayer); + const COBJECT2D* object2d_A = static_cast( *itemOnLayer ); wxASSERT( object2d_A->GetObjectType() == OBJECT2D_TYPE::TRIANGLE ); @@ -470,8 +466,6 @@ void C3D_RENDER_OGL_LEGACY::reload( REPORTER* aStatusReporter, REPORTER* aWarnin aStatusReporter->Report( _( "Load OpenGL: board" ) ); // Create Board - // ///////////////////////////////////////////////////////////////////////// - m_board = createBoard( m_boardAdapter.GetBoardPoly(), &m_boardAdapter.GetThroughHole_Inner() ); if( m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) ) @@ -495,22 +489,20 @@ void C3D_RENDER_OGL_LEGACY::reload( REPORTER* aStatusReporter, REPORTER* aWarnin board_poly_with_holes.BooleanSubtract( m_boardAdapter.GetThroughHole_Outer_poly_NPTH(), SHAPE_POLY_SET::PM_FAST ); - m_board_with_holes = createBoard( board_poly_with_holes ); if( m_anti_board ) m_anti_board->SetItIsTransparent( true ); // Create Through Holes and vias - // ///////////////////////////////////////////////////////////////////////// - if( aStatusReporter ) aStatusReporter->Report( _( "Load OpenGL: holes and vias" ) ); SHAPE_POLY_SET outerPolyTHT = m_boardAdapter.GetThroughHole_Outer_poly(); if( m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) ) - outerPolyTHT.BooleanIntersection( m_boardAdapter.GetBoardPoly(), SHAPE_POLY_SET::PM_STRICTLY_SIMPLE ); + outerPolyTHT.BooleanIntersection( m_boardAdapter.GetBoardPoly(), + SHAPE_POLY_SET::PM_STRICTLY_SIMPLE ); m_through_holes_outer = generate_holes_display_list( m_boardAdapter.GetThroughHole_Outer().GetList(), @@ -538,13 +530,12 @@ void C3D_RENDER_OGL_LEGACY::reload( REPORTER* aStatusReporter, REPORTER* aWarnin false ); } - // Not in use + /// @todo Determine what to do with this commented out code. //m_ogl_disp_list_through_holes_vias_inner = generate_holes_display_list( // m_boardAdapter.GetThroughHole_Vias_Inner().GetList(), // m_boardAdapter.GetThroughHole_Vias_Inner_poly(), // 1.0f, 0.0f, // false ); - const MAP_POLY & innerMapHoles = m_boardAdapter.GetPolyMapHoles_Inner(); const MAP_POLY & outerMapHoles = m_boardAdapter.GetPolyMapHoles_Outer(); @@ -557,13 +548,11 @@ void C3D_RENDER_OGL_LEGACY::reload( REPORTER* aStatusReporter, REPORTER* aWarnin float layer_z_bot = 0.0f; float layer_z_top = 0.0f; - for( MAP_POLY::const_iterator ii = outerMapHoles.begin(); - ii != outerMapHoles.end(); - ++ii ) + for( MAP_POLY::const_iterator ii = outerMapHoles.begin(); ii != outerMapHoles.end(); ++ii ) { PCB_LAYER_ID layer_id = static_cast(ii->first); - const SHAPE_POLY_SET *poly = static_cast(ii->second); - const CBVHCONTAINER2D *container = map_holes.at( layer_id ); + const SHAPE_POLY_SET* poly = static_cast( ii->second ); + const CBVHCONTAINER2D* container = map_holes.at( layer_id ); get_layer_z_pos( layer_id, layer_z_top, layer_z_bot ); @@ -572,13 +561,11 @@ void C3D_RENDER_OGL_LEGACY::reload( REPORTER* aStatusReporter, REPORTER* aWarnin layer_z_bot, false ); } - for( MAP_POLY::const_iterator ii = innerMapHoles.begin(); - ii != innerMapHoles.end(); - ++ii ) + for( MAP_POLY::const_iterator ii = innerMapHoles.begin(); ii != innerMapHoles.end(); ++ii ) { - PCB_LAYER_ID layer_id = static_cast(ii->first); - const SHAPE_POLY_SET *poly = static_cast(ii->second); - const CBVHCONTAINER2D *container = map_holes.at( layer_id ); + PCB_LAYER_ID layer_id = static_cast( ii->first ); + const SHAPE_POLY_SET* poly = static_cast( ii->second ); + const CBVHCONTAINER2D* container = map_holes.at( layer_id ); get_layer_z_pos( layer_id, layer_z_top, layer_z_bot ); @@ -592,7 +579,6 @@ void C3D_RENDER_OGL_LEGACY::reload( REPORTER* aStatusReporter, REPORTER* aWarnin generate_3D_Vias_and_Pads(); // Add layers maps - if( aStatusReporter ) aStatusReporter->Report( _( "Load OpenGL: layers" ) ); @@ -602,12 +588,12 @@ void C3D_RENDER_OGL_LEGACY::reload( REPORTER* aStatusReporter, REPORTER* aWarnin ii != m_boardAdapter.GetMapLayers().end(); ++ii ) { - PCB_LAYER_ID layer_id = static_cast(ii->first); + PCB_LAYER_ID layer_id = static_cast( ii->first ); if( !m_boardAdapter.Is3DLayerEnabled( layer_id ) ) continue; - const CBVHCONTAINER2D *container2d = static_cast(ii->second); + const CBVHCONTAINER2D* container2d = static_cast( ii->second ); SHAPE_POLY_SET polyListSubtracted; SHAPE_POLY_SET *aPolyList = nullptr; @@ -621,14 +607,16 @@ void C3D_RENDER_OGL_LEGACY::reload( REPORTER* aStatusReporter, REPORTER* aWarnin if( ( layer_id != B_Paste ) && ( layer_id != F_Paste ) && m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) ) { - polyListSubtracted.BooleanIntersection( m_boardAdapter.GetBoardPoly(), SHAPE_POLY_SET::PM_FAST ); + polyListSubtracted.BooleanIntersection( m_boardAdapter.GetBoardPoly(), + SHAPE_POLY_SET::PM_FAST ); if( ( layer_id != B_Mask ) && ( layer_id != F_Mask ) ) { polyListSubtracted.BooleanSubtract( m_boardAdapter.GetThroughHole_Outer_poly(), SHAPE_POLY_SET::PM_FAST ); - polyListSubtracted.BooleanSubtract( m_boardAdapter.GetThroughHole_Outer_poly_NPTH(), - SHAPE_POLY_SET::PM_FAST ); + polyListSubtracted.BooleanSubtract( + m_boardAdapter.GetThroughHole_Outer_poly_NPTH(), + SHAPE_POLY_SET::PM_FAST ); } if( m_boardAdapter.GetFlag( FL_SUBTRACT_MASK_FROM_SILK ) ) @@ -650,14 +638,15 @@ void C3D_RENDER_OGL_LEGACY::reload( REPORTER* aStatusReporter, REPORTER* aWarnin aPolyList = &polyListSubtracted; } - CLAYERS_OGL_DISP_LISTS* oglList = generateLayerListFromContainer( container2d, aPolyList, - layer_id, - &m_boardAdapter.GetThroughHole_Inner() ); + CLAYERS_OGL_DISP_LISTS* oglList = generateLayerListFromContainer( + container2d, aPolyList, + layer_id, + &m_boardAdapter.GetThroughHole_Inner() ); if( oglList != nullptr ) m_layers[layer_id] = oglList; - }// for each layer on + } if( m_boardAdapter.GetFlag( FL_RENDER_PLATED_PADS_AS_PLATED ) && m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) ) @@ -672,8 +661,9 @@ void C3D_RENDER_OGL_LEGACY::reload( REPORTER* aStatusReporter, REPORTER* aWarnin polySubtracted.BooleanSubtract( m_boardAdapter.GetThroughHole_Outer_poly_NPTH(), SHAPE_POLY_SET::PM_FAST ); - m_platedPads_F_Cu = generateLayerListFromContainer( m_boardAdapter.GetPlatedPads_Front(), - &polySubtracted, F_Cu ); + m_platedPads_F_Cu = generateLayerListFromContainer( + m_boardAdapter.GetPlatedPads_Front(), + &polySubtracted, F_Cu ); } if( m_boardAdapter.GetPolyPlatedPads_Back() ) @@ -692,7 +682,6 @@ void C3D_RENDER_OGL_LEGACY::reload( REPORTER* aStatusReporter, REPORTER* aWarnin } // Load 3D models - // ///////////////////////////////////////////////////////////////////////// if( aStatusReporter ) aStatusReporter->Report( _( "Loading 3D models" ) ); @@ -784,14 +773,14 @@ void C3D_RENDER_OGL_LEGACY::generate_3D_Vias_and_Pads() if( m_boardAdapter.GetStats_Nr_Vias() ) { const unsigned int reserve_nr_triangles_estimation = - m_boardAdapter.GetNrSegmentsCircle( m_boardAdapter.GetStats_Med_Via_Hole_Diameter3DU() ) * - 8 * - m_boardAdapter.GetStats_Nr_Vias(); + m_boardAdapter.GetNrSegmentsCircle( + m_boardAdapter.GetStats_Med_Via_Hole_Diameter3DU() ) * 8 * + m_boardAdapter.GetStats_Nr_Vias(); - CLAYER_TRIANGLES *layerTriangleVIA = new CLAYER_TRIANGLES( reserve_nr_triangles_estimation ); + CLAYER_TRIANGLES *layerTriangleVIA = + new CLAYER_TRIANGLES( reserve_nr_triangles_estimation ); // Insert plated vertical holes inside the board - // ///////////////////////////////////////////////////////////////////////// // Insert vias holes (vertical cylinders) for( auto track : m_boardAdapter.GetBoard()->Tracks() ) @@ -800,10 +789,10 @@ void C3D_RENDER_OGL_LEGACY::generate_3D_Vias_and_Pads() { const VIA *via = static_cast(track); - const float holediameter = via->GetDrillValue() * m_boardAdapter.BiuTo3Dunits(); - const float thickness = m_boardAdapter.GetCopperThickness3DU(); - const int nrSegments = m_boardAdapter.GetNrSegmentsCircle( via->GetDrillValue() ); - const float hole_inner_radius = holediameter / 2.0f; + const float holediameter = via->GetDrillValue() * m_boardAdapter.BiuTo3Dunits(); + const float thickness = m_boardAdapter.GetCopperThickness3DU(); + const int nrSegments = m_boardAdapter.GetNrSegmentsCircle( via->GetDrillValue() ); + const float hole_inner_radius = holediameter / 2.0f; const SFVEC2F via_center( via->GetStart().x * m_boardAdapter.BiuTo3Dunits(), -via->GetStart().y * m_boardAdapter.BiuTo3Dunits() ); @@ -921,17 +910,11 @@ void C3D_RENDER_OGL_LEGACY::generate_3D_Vias_and_Pads() } -/* - * This function will get models from the cache and load it to openGL lists - * in the form of C_OGL_3DMODEL. So this map of models will work as a local - * cache for this render. (cache based on C_OGL_3DMODEL with associated - * openGL lists in GPU memory) - */ void C3D_RENDER_OGL_LEGACY::load_3D_models( REPORTER* aStatusReporter ) { if( !m_boardAdapter.GetFlag( FL_FP_ATTRIBUTES_NORMAL ) - && !m_boardAdapter.GetFlag( FL_FP_ATTRIBUTES_NORMAL_INSERT ) - && !m_boardAdapter.GetFlag( FL_FP_ATTRIBUTES_VIRTUAL ) ) + && !m_boardAdapter.GetFlag( FL_FP_ATTRIBUTES_NORMAL_INSERT ) + && !m_boardAdapter.GetFlag( FL_FP_ATTRIBUTES_VIRTUAL ) ) { return; } diff --git a/3d-viewer/3d_rendering/3d_render_ogl_legacy/c3d_render_ogl_legacy.cpp b/3d-viewer/3d_rendering/3d_render_ogl_legacy/c3d_render_ogl_legacy.cpp index a1e5ae2af4..5e02e0a8f3 100644 --- a/3d-viewer/3d_rendering/3d_render_ogl_legacy/c3d_render_ogl_legacy.cpp +++ b/3d-viewer/3d_rendering/3d_render_ogl_legacy/c3d_render_ogl_legacy.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2015-2020 Mario Luzeiro - * Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2015-2020 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 @@ -34,8 +34,8 @@ #include /** - * Scale conversion from 3d model units to pcb units - */ + * Scale conversion from 3d model units to pcb units + */ #define UNITS3D_TO_UNITSPCB (IU_PER_MM) C3D_RENDER_OGL_LEGACY::C3D_RENDER_OGL_LEGACY( BOARD_ADAPTER& aAdapter, CCAMERA& aCamera ) : @@ -144,7 +144,8 @@ void C3D_RENDER_OGL_LEGACY::render_3D_arrows() glLoadIdentity(); const glm::mat4 TranslationMatrix = glm::translate( glm::mat4(1.0f), - SFVEC3F( 0.0f, 0.0f, -(arrow_size * 2.75f) ) ); + SFVEC3F( 0.0f, 0.0f, + -(arrow_size * 2.75f) ) ); const glm::mat4 ViewMatrix = TranslationMatrix * m_camera.GetRotationMatrix(); @@ -202,7 +203,8 @@ void C3D_RENDER_OGL_LEGACY::setupMaterials() // Non plated copper (raw copper) m_materials.m_NonPlatedCopper.m_Ambient = SFVEC3F( 0.191f, 0.073f, 0.022f ); - m_materials.m_NonPlatedCopper.m_Diffuse = SFVEC3F( 184.0f / 255.0f, 115.0f / 255.0f, 50.0f / 255.0f ); + m_materials.m_NonPlatedCopper.m_Diffuse = SFVEC3F( 184.0f / 255.0f, 115.0f / 255.0f, + 50.0f / 255.0f ); m_materials.m_NonPlatedCopper.m_Specular = SFVEC3F( 0.256f, 0.137f, 0.086f ); m_materials.m_NonPlatedCopper.m_Shininess = 0.1f * 128.0f; m_materials.m_NonPlatedCopper.m_Emissive = SFVEC3F( 0.0f, 0.0f, 0.0f ); @@ -222,7 +224,6 @@ void C3D_RENDER_OGL_LEGACY::setupMaterials() m_materials.m_Paste.m_Shininess = 0.1f * 128.0f; m_materials.m_Paste.m_Emissive = SFVEC3F( 0.0f, 0.0f, 0.0f ); - // Silk screen material mixed with silk screen color m_materials.m_SilkSTop.m_Ambient = SFVEC3F( m_boardAdapter.m_SilkScreenColorTop.r, m_boardAdapter.m_SilkScreenColorTop.g, @@ -320,73 +321,74 @@ void C3D_RENDER_OGL_LEGACY::set_layer_material( PCB_LAYER_ID aLayerID ) { switch( aLayerID ) { - case F_Mask: - case B_Mask: + case F_Mask: + case B_Mask: + { + const SFVEC4F layerColor = get_layer_color( aLayerID ); + + m_materials.m_SolderMask.m_Diffuse = layerColor; + + // Convert Opacity to Transparency + m_materials.m_SolderMask.m_Transparency = 1.0f - layerColor.a; + + if( m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) ) { - const SFVEC4F layerColor = get_layer_color( aLayerID ); + m_materials.m_SolderMask.m_Ambient = m_materials.m_SolderMask.m_Diffuse * 0.3f; - m_materials.m_SolderMask.m_Diffuse = layerColor; - m_materials.m_SolderMask.m_Transparency = 1.0f - layerColor.a; // Convert Opacity to Transparency - - if( m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) ) - { - m_materials.m_SolderMask.m_Ambient = m_materials.m_SolderMask.m_Diffuse * 0.3f; - - m_materials.m_SolderMask.m_Specular = m_materials.m_SolderMask.m_Diffuse * - m_materials.m_SolderMask.m_Diffuse; - } - - OGL_SetMaterial( m_materials.m_SolderMask, 1.0f ); - break; + m_materials.m_SolderMask.m_Specular = + m_materials.m_SolderMask.m_Diffuse * m_materials.m_SolderMask.m_Diffuse; } - case B_Paste: - case F_Paste: - m_materials.m_Paste.m_Diffuse = get_layer_color( aLayerID ); - OGL_SetMaterial( m_materials.m_Paste, 1.0f ); - break; + OGL_SetMaterial( m_materials.m_SolderMask, 1.0f ); + break; + } - case B_SilkS: - m_materials.m_SilkSBot.m_Diffuse = get_layer_color( aLayerID ); - OGL_SetMaterial( m_materials.m_SilkSBot, 1.0f ); - break; - - case F_SilkS: - m_materials.m_SilkSTop.m_Diffuse = get_layer_color( aLayerID ); - OGL_SetMaterial( m_materials.m_SilkSTop, 1.0f ); - break; - - case B_Adhes: - case F_Adhes: - case Dwgs_User: - case Cmts_User: - case Eco1_User: - case Eco2_User: - case Edge_Cuts: - case Margin: - case B_CrtYd: - case F_CrtYd: - case B_Fab: - case F_Fab: - m_materials.m_Plastic.m_Diffuse = get_layer_color( aLayerID ); - - m_materials.m_Plastic.m_Ambient = SFVEC3F( m_materials.m_Plastic.m_Diffuse.r * 0.05f, - m_materials.m_Plastic.m_Diffuse.g * 0.05f, - m_materials.m_Plastic.m_Diffuse.b * 0.05f ); - - m_materials.m_Plastic.m_Specular = SFVEC3F( m_materials.m_Plastic.m_Diffuse.r * 0.7f, - m_materials.m_Plastic.m_Diffuse.g * 0.7f, - m_materials.m_Plastic.m_Diffuse.b * 0.7f ); - - m_materials.m_Plastic.m_Shininess = 0.078125f * 128.0f; - m_materials.m_Plastic.m_Emissive = SFVEC3F( 0.0f, 0.0f, 0.0f ); - OGL_SetMaterial( m_materials.m_Plastic, 1.0f ); + case B_Paste: + case F_Paste: + m_materials.m_Paste.m_Diffuse = get_layer_color( aLayerID ); + OGL_SetMaterial( m_materials.m_Paste, 1.0f ); break; - default: - m_materials.m_Copper.m_Diffuse = get_layer_color( aLayerID ); - OGL_SetMaterial( m_materials.m_Copper, 1.0f ); + case B_SilkS: + m_materials.m_SilkSBot.m_Diffuse = get_layer_color( aLayerID ); + OGL_SetMaterial( m_materials.m_SilkSBot, 1.0f ); + break; + case F_SilkS: + m_materials.m_SilkSTop.m_Diffuse = get_layer_color( aLayerID ); + OGL_SetMaterial( m_materials.m_SilkSTop, 1.0f ); + break; + + case B_Adhes: + case F_Adhes: + case Dwgs_User: + case Cmts_User: + case Eco1_User: + case Eco2_User: + case Edge_Cuts: + case Margin: + case B_CrtYd: + case F_CrtYd: + case B_Fab: + case F_Fab: + m_materials.m_Plastic.m_Diffuse = get_layer_color( aLayerID ); + + m_materials.m_Plastic.m_Ambient = SFVEC3F( m_materials.m_Plastic.m_Diffuse.r * 0.05f, + m_materials.m_Plastic.m_Diffuse.g * 0.05f, + m_materials.m_Plastic.m_Diffuse.b * 0.05f ); + + m_materials.m_Plastic.m_Specular = SFVEC3F( m_materials.m_Plastic.m_Diffuse.r * 0.7f, + m_materials.m_Plastic.m_Diffuse.g * 0.7f, + m_materials.m_Plastic.m_Diffuse.b * 0.7f ); + + m_materials.m_Plastic.m_Shininess = 0.078125f * 128.0f; + m_materials.m_Plastic.m_Emissive = SFVEC3F( 0.0f, 0.0f, 0.0f ); + OGL_SetMaterial( m_materials.m_Plastic, 1.0f ); + break; + + default: + m_materials.m_Copper.m_Diffuse = get_layer_color( aLayerID ); + OGL_SetMaterial( m_materials.m_Copper, 1.0f ); break; } } @@ -400,48 +402,48 @@ SFVEC4F C3D_RENDER_OGL_LEGACY::get_layer_color( PCB_LAYER_ID aLayerID ) { switch( aLayerID ) { - case B_Adhes: - case F_Adhes: - break; + case B_Adhes: + case F_Adhes: + break; - case B_Mask: - layerColor = m_boardAdapter.m_SolderMaskColorBot; - break; - case F_Mask: - layerColor = m_boardAdapter.m_SolderMaskColorTop; - break; + case B_Mask: + layerColor = m_boardAdapter.m_SolderMaskColorBot; + break; + case F_Mask: + layerColor = m_boardAdapter.m_SolderMaskColorTop; + break; - case B_Paste: - case F_Paste: - layerColor = m_boardAdapter.m_SolderPasteColor; - break; + case B_Paste: + case F_Paste: + layerColor = m_boardAdapter.m_SolderPasteColor; + break; - case B_SilkS: - layerColor = m_boardAdapter.m_SilkScreenColorBot; - break; - case F_SilkS: - layerColor = m_boardAdapter.m_SilkScreenColorTop; - break; + case B_SilkS: + layerColor = m_boardAdapter.m_SilkScreenColorBot; + break; + case F_SilkS: + layerColor = m_boardAdapter.m_SilkScreenColorTop; + break; - case Dwgs_User: - case Cmts_User: - case Eco1_User: - case Eco2_User: - case Edge_Cuts: - case Margin: - break; + case Dwgs_User: + case Cmts_User: + case Eco1_User: + case Eco2_User: + case Edge_Cuts: + case Margin: + break; - case B_CrtYd: - case F_CrtYd: - break; + case B_CrtYd: + case F_CrtYd: + break; - case B_Fab: - case F_Fab: - break; + case B_Fab: + case F_Fab: + break; - default: - layerColor = m_boardAdapter.m_CopperColor; - break; + default: + layerColor = m_boardAdapter.m_CopperColor; + break; } } @@ -453,7 +455,6 @@ void init_lights(void) { // Setup light // https://www.opengl.org/sdk/docs/man2/xhtml/glLight.xml - // ///////////////////////////////////////////////////////////////////////// const GLfloat ambient[] = { 0.084f, 0.084f, 0.084f, 1.0f }; const GLfloat diffuse0[] = { 0.3f, 0.3f, 0.3f, 1.0f }; const GLfloat specular0[] = { 0.5f, 0.5f, 0.5f, 1.0f }; @@ -481,7 +482,6 @@ void init_lights(void) glLightfv( GL_LIGHT1, GL_SPECULAR, specular12 ); glLightfv( GL_LIGHT1, GL_POSITION, position ); - // defines a directional light that points along the positive z-axis position[2] = -position[2]; @@ -521,7 +521,9 @@ void C3D_RENDER_OGL_LEGACY::unsetDepthOffset() void C3D_RENDER_OGL_LEGACY::render_board_body( bool aSkipRenderHoles ) { m_materials.m_EpoxyBoard.m_Diffuse = m_boardAdapter.m_BoardBodyColor; - m_materials.m_EpoxyBoard.m_Transparency = 1.0f - m_boardAdapter.m_BoardBodyColor.a; // opacity to transparency + + // opacity to transparency + m_materials.m_EpoxyBoard.m_Transparency = 1.0f - m_boardAdapter.m_BoardBodyColor.a; OGL_SetMaterial( m_materials.m_EpoxyBoard, 1.0f ); @@ -581,12 +583,10 @@ bool C3D_RENDER_OGL_LEGACY::Redraw( bool aIsMoving, REPORTER* aStatusReporter, setupMaterials(); // Initial setup - // ///////////////////////////////////////////////////////////////////////// glDepthFunc( GL_LESS ); glEnable( GL_CULL_FACE ); glFrontFace( GL_CCW ); // This is the OpenGL default glEnable( GL_NORMALIZE ); // This allow OpenGL to normalize the normals after transformations - glViewport( 0, 0, m_windowSize.x, m_windowSize.y ); if( m_boardAdapter.GetFlag( FL_RENDER_OPENGL_AA_DISABLE_ON_MOVE ) && aIsMoving ) @@ -595,7 +595,6 @@ bool C3D_RENDER_OGL_LEGACY::Redraw( bool aIsMoving, REPORTER* aStatusReporter, glEnable( GL_MULTISAMPLE ); // clear color and depth buffers - // ///////////////////////////////////////////////////////////////////////// glClearColor( 0.0f, 0.0f, 0.0f, 1.0f ); glClearDepth( 1.0f ); glClearStencil( 0x00 ); @@ -604,26 +603,19 @@ bool C3D_RENDER_OGL_LEGACY::Redraw( bool aIsMoving, REPORTER* aStatusReporter, OGL_ResetTextureStateDefaults(); // Draw the background ( rectangle with color gradient) - // ///////////////////////////////////////////////////////////////////////// OGL_DrawBackground( SFVEC3F( m_boardAdapter.m_BgColorTop ), SFVEC3F( m_boardAdapter.m_BgColorBot ) ); glEnable( GL_DEPTH_TEST ); - // Set projection and modelview matrixes - // ///////////////////////////////////////////////////////////////////////// glMatrixMode( GL_PROJECTION ); glLoadMatrixf( glm::value_ptr( m_camera.GetProjectionMatrix() ) ); - glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); glLoadMatrixf( glm::value_ptr( m_camera.GetViewMatrix() ) ); - // Position the headlight - // ///////////////////////////////////////////////////////////////////////// - setLight_Front( true ); setLight_Top( true ); setLight_Bottom( true ); @@ -680,30 +672,26 @@ bool C3D_RENDER_OGL_LEGACY::Redraw( bool aIsMoving, REPORTER* aStatusReporter, m_pad_holes->DrawAll(); // Display copper and tech layers - // ///////////////////////////////////////////////////////////////////////// for( MAP_OGL_DISP_LISTS::const_iterator ii = m_layers.begin(); ii != m_layers.end(); ++ii ) { - const PCB_LAYER_ID layer_id = (PCB_LAYER_ID)(ii->first); + const PCB_LAYER_ID layer_id = ( PCB_LAYER_ID )( ii->first ); // Mask layers are not processed here because they are a special case if( (layer_id == B_Mask) || (layer_id == F_Mask) ) continue; - // Do not show inner layers when it is displaying the board - // and board body is full opaque + // Do not show inner layers when it is displaying the board and board body is full opaque if( m_boardAdapter.GetFlag( FL_SHOW_BOARD_BODY ) && ( m_boardAdapter.m_BoardBodyColor.a > 0.99f ) ) { - if( (layer_id > F_Cu) && (layer_id < B_Cu) ) + if( ( layer_id > F_Cu ) && ( layer_id < B_Cu ) ) continue; } glPushMatrix(); - // !TODO: if we want to increase the separation between layers + /// @todo Determine what to do with this commented out code. //glScalef( 1.0f, 1.0f, 3.0f ); - - CLAYERS_OGL_DISP_LISTS *pLayerDispList = static_cast(ii->second); if( (layer_id >= F_Cu) && (layer_id <= B_Cu) ) @@ -720,7 +708,6 @@ bool C3D_RENDER_OGL_LEGACY::Redraw( bool aIsMoving, REPORTER* aStatusReporter, pLayerDispList->DrawAllCameraCulled( m_camera.GetPos().z, drawMiddleSegments ); // Draw copper plated pads - if( ( ( layer_id == F_Cu ) || ( layer_id == B_Cu ) ) && ( m_platedPads_F_Cu || m_platedPads_B_Cu ) ) setPlatedCopperAndDepthOffset( layer_id ); @@ -756,7 +743,8 @@ bool C3D_RENDER_OGL_LEGACY::Redraw( bool aIsMoving, REPORTER* aStatusReporter, if( m_layers_holes_outer.find( layer_id ) != m_layers_holes_outer.end() ) { - const CLAYERS_OGL_DISP_LISTS* viasHolesLayer = m_layers_holes_outer.at( layer_id ); + const CLAYERS_OGL_DISP_LISTS* viasHolesLayer = + m_layers_holes_outer.at( layer_id ); wxASSERT( viasHolesLayer != NULL ); @@ -777,17 +765,19 @@ bool C3D_RENDER_OGL_LEGACY::Redraw( bool aIsMoving, REPORTER* aStatusReporter, if( layer_id == F_Cu && m_platedPads_F_Cu ) { - m_platedPads_F_Cu->DrawAllCameraCulledSubtractLayer( drawMiddleSegments, - m_through_holes_outer, - viasHolesLayer, - m_anti_board ); + m_platedPads_F_Cu->DrawAllCameraCulledSubtractLayer( + drawMiddleSegments, + m_through_holes_outer, + viasHolesLayer, + m_anti_board ); } else if( layer_id == B_Cu && m_platedPads_B_Cu ) { - m_platedPads_B_Cu->DrawAllCameraCulledSubtractLayer( drawMiddleSegments, - m_through_holes_outer, - viasHolesLayer, - m_anti_board ); + m_platedPads_B_Cu->DrawAllCameraCulledSubtractLayer( + drawMiddleSegments, + m_through_holes_outer, + viasHolesLayer, + m_anti_board ); } unsetDepthOffset(); @@ -800,7 +790,6 @@ bool C3D_RENDER_OGL_LEGACY::Redraw( bool aIsMoving, REPORTER* aStatusReporter, m_anti_board ); // Draw copper plated pads - if( ( ( layer_id == F_Cu ) || ( layer_id == B_Cu ) ) && ( m_platedPads_F_Cu || m_platedPads_B_Cu ) ) { @@ -810,8 +799,8 @@ bool C3D_RENDER_OGL_LEGACY::Redraw( bool aIsMoving, REPORTER* aStatusReporter, if( layer_id == F_Cu && m_platedPads_F_Cu ) { m_platedPads_F_Cu->DrawAllCameraCulledSubtractLayer( drawMiddleSegments, - m_through_holes_outer, - m_anti_board ); + m_through_holes_outer, + m_anti_board ); } else if( layer_id == B_Cu && m_platedPads_B_Cu ) { @@ -837,7 +826,8 @@ bool C3D_RENDER_OGL_LEGACY::Redraw( bool aIsMoving, REPORTER* aStatusReporter, if( throughHolesOuter ) { - throughHolesOuter->ApplyScalePosition( pLayerDispList->GetZBot(), + throughHolesOuter->ApplyScalePosition( + pLayerDispList->GetZBot(), pLayerDispList->GetZTop() - pLayerDispList->GetZBot() ); } @@ -848,15 +838,16 @@ bool C3D_RENDER_OGL_LEGACY::Redraw( bool aIsMoving, REPORTER* aStatusReporter, if( anti_board ) { - anti_board->ApplyScalePosition( pLayerDispList->GetZBot(), + anti_board->ApplyScalePosition( + pLayerDispList->GetZBot(), pLayerDispList->GetZTop() - pLayerDispList->GetZBot() ); } if( !skipRenderHoles - && m_boardAdapter.GetFlag( FL_SUBTRACT_MASK_FROM_SILK ) - && m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) - && ( ( layer_id == B_SilkS && m_layers.find( B_Mask ) != m_layers.end() ) - || ( layer_id == F_SilkS && m_layers.find( F_Mask ) != m_layers.end() ) ) ) + && m_boardAdapter.GetFlag( FL_SUBTRACT_MASK_FROM_SILK ) + && m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) + && ( ( layer_id == B_SilkS && m_layers.find( B_Mask ) != m_layers.end() ) + || ( layer_id == F_SilkS && m_layers.find( F_Mask ) != m_layers.end() ) ) ) { const PCB_LAYER_ID layerMask_id = (layer_id == B_SilkS) ? B_Mask : F_Mask; @@ -873,7 +864,8 @@ bool C3D_RENDER_OGL_LEGACY::Redraw( bool aIsMoving, REPORTER* aStatusReporter, && ( layer_id == B_SilkS || layer_id == F_SilkS ) ) { pLayerDispList->DrawAllCameraCulledSubtractLayer( drawMiddleSegments, nullptr, - throughHolesOuter, anti_board ); + throughHolesOuter, + anti_board ); } else { @@ -892,19 +884,16 @@ bool C3D_RENDER_OGL_LEGACY::Redraw( bool aIsMoving, REPORTER* aStatusReporter, } // Render 3D Models (Non-transparent) - // ///////////////////////////////////////////////////////////////////////// render_3D_models( false, false ); render_3D_models( true, false ); // Display board body - // ///////////////////////////////////////////////////////////////////////// if( m_boardAdapter.GetFlag( FL_SHOW_BOARD_BODY ) ) { render_board_body( skipRenderHoles ); } // Display transparent mask layers - // ///////////////////////////////////////////////////////////////////////// if( m_boardAdapter.GetFlag( FL_SOLDERMASK ) ) { //setLight_Top( true ); @@ -938,12 +927,9 @@ bool C3D_RENDER_OGL_LEGACY::Redraw( bool aIsMoving, REPORTER* aStatusReporter, // Render 3D Models (Transparent) - // ///////////////////////////////////////////////////////////////////////// // !TODO: this can be optimized. If there are no transparent models (or no opacity), // then there is no need to make this function call. - glDepthMask( GL_FALSE ); - glEnable( GL_BLEND ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); @@ -975,8 +961,6 @@ bool C3D_RENDER_OGL_LEGACY::Redraw( bool aIsMoving, REPORTER* aStatusReporter, glDepthMask( GL_TRUE ); // Render Grid - // ///////////////////////////////////////////////////////////////////////// - if( m_boardAdapter.GridGet() != GRID3D_TYPE::NONE ) { glDisable( GL_LIGHTING ); @@ -987,15 +971,12 @@ bool C3D_RENDER_OGL_LEGACY::Redraw( bool aIsMoving, REPORTER* aStatusReporter, glEnable( GL_LIGHTING ); } - // Render 3D arrows - // ///////////////////////////////////////////////////////////////////////// if( m_boardAdapter.GetFlag( FL_AXIS ) ) render_3D_arrows(); // Return back to the original viewport (this is important if we want // to take a screenshot after the render) - // ///////////////////////////////////////////////////////////////////////// glViewport( 0, 0, m_windowSize.x, m_windowSize.y ); return false; @@ -1016,11 +997,12 @@ bool C3D_RENDER_OGL_LEGACY::initializeOpenGL() if( !circleImage ) return false; - circleImage->CircleFilled( (SIZE_OF_CIRCLE_TEXTURE / 2) - 0, - (SIZE_OF_CIRCLE_TEXTURE / 2) - 0, - (SIZE_OF_CIRCLE_TEXTURE / 2) - 4, + circleImage->CircleFilled( ( SIZE_OF_CIRCLE_TEXTURE / 2 ) - 0, + ( SIZE_OF_CIRCLE_TEXTURE / 2 ) - 0, + ( SIZE_OF_CIRCLE_TEXTURE / 2 ) - 4, 0xFF ); + /// @todo Determine what to do with this commented out code. //circleImage->CircleFilled( (SIZE_OF_CIRCLE_TEXTURE / 4)*1.5f - 1, // (SIZE_OF_CIRCLE_TEXTURE / 4)*1.5f - 1, // (SIZE_OF_CIRCLE_TEXTURE / 4)*1.5f - 2, 0xFF ); @@ -1043,7 +1025,6 @@ bool C3D_RENDER_OGL_LEGACY::initializeOpenGL() // Use this mode if you want see the triangle lines (debug proposes) //glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); - m_is_opengl_initialized = true; return true; @@ -1078,7 +1059,7 @@ void C3D_RENDER_OGL_LEGACY::ogl_free_all_display_lists() for( MAP_OGL_DISP_LISTS::const_iterator ii = m_layers.begin(); ii != m_layers.end(); ++ii ) { - CLAYERS_OGL_DISP_LISTS *pLayerDispList = static_cast(ii->second); + CLAYERS_OGL_DISP_LISTS *pLayerDispList = static_cast( ii->second ); delete pLayerDispList; } @@ -1090,23 +1071,21 @@ void C3D_RENDER_OGL_LEGACY::ogl_free_all_display_lists() delete m_platedPads_B_Cu; m_platedPads_B_Cu = nullptr; - for( MAP_OGL_DISP_LISTS::const_iterator ii = m_layers_holes_outer.begin(); ii != m_layers_holes_outer.end(); ++ii ) { - CLAYERS_OGL_DISP_LISTS *pLayerDispList = static_cast(ii->second); + CLAYERS_OGL_DISP_LISTS* pLayerDispList = static_cast( ii->second ); delete pLayerDispList; } m_layers_holes_outer.clear(); - for( MAP_OGL_DISP_LISTS::const_iterator ii = m_layers_holes_inner.begin(); ii != m_layers_holes_inner.end(); ++ii ) { - CLAYERS_OGL_DISP_LISTS *pLayerDispList = static_cast(ii->second); + CLAYERS_OGL_DISP_LISTS* pLayerDispList = static_cast( ii->second ); delete pLayerDispList; } @@ -1119,7 +1098,6 @@ void C3D_RENDER_OGL_LEGACY::ogl_free_all_display_lists() m_triangles.clear(); - for( MAP_3DMODEL::const_iterator ii = m_3dmodel_map.begin(); ii != m_3dmodel_map.end(); ++ii ) { C_OGL_3DMODEL *pointer = static_cast(ii->second); @@ -1128,7 +1106,6 @@ void C3D_RENDER_OGL_LEGACY::ogl_free_all_display_lists() m_3dmodel_map.clear(); - delete m_board; m_board = nullptr; @@ -1155,9 +1132,9 @@ void C3D_RENDER_OGL_LEGACY::ogl_free_all_display_lists() } -void C3D_RENDER_OGL_LEGACY::render_solder_mask_layer(PCB_LAYER_ID aLayerID, float aZPosition, - bool aDrawMiddleSegments, - bool aSkipRenderHoles ) +void C3D_RENDER_OGL_LEGACY::render_solder_mask_layer( PCB_LAYER_ID aLayerID, float aZPosition, + bool aDrawMiddleSegments, + bool aSkipRenderHoles ) { wxASSERT( (aLayerID == B_Mask) || (aLayerID == F_Mask) ); @@ -1228,8 +1205,8 @@ void C3D_RENDER_OGL_LEGACY::render_3D_models_selected( bool aRenderTopOrBot, const bool isIntersected = ( fp == m_currentIntersectedBoardItem ); if( m_boardAdapter.GetFlag( FL_USE_SELECTION ) && !isIntersected - && ( ( aRenderSelectedOnly && !fp->IsSelected() ) - || ( !aRenderSelectedOnly && fp->IsSelected() ) ) ) + && ( ( aRenderSelectedOnly && !fp->IsSelected() ) + || ( !aRenderSelectedOnly && fp->IsSelected() ) ) ) { continue; } @@ -1238,7 +1215,6 @@ void C3D_RENDER_OGL_LEGACY::render_3D_models_selected( bool aRenderTopOrBot, { glEnable( GL_POLYGON_OFFSET_LINE ); glPolygonOffset( 8.0, 1.0 ); - glPolygonMode( GL_FRONT, GL_LINE ); glLineWidth( 6 ); } @@ -1267,8 +1243,7 @@ void C3D_RENDER_OGL_LEGACY::render_3D_models_selected( bool aRenderTopOrBot, } -void C3D_RENDER_OGL_LEGACY::render_3D_models( bool aRenderTopOrBot, - bool aRenderTransparentOnly ) +void C3D_RENDER_OGL_LEGACY::render_3D_models( bool aRenderTopOrBot, bool aRenderTransparentOnly ) { if( m_boardAdapter.GetFlag( FL_USE_SELECTION ) ) render_3D_models_selected( aRenderTopOrBot, aRenderTransparentOnly, true ); @@ -1291,10 +1266,10 @@ void C3D_RENDER_OGL_LEGACY::render_3D_footprint( const FOOTPRINT* aFootprint, glTranslatef( pos.x * m_boardAdapter.BiuTo3Dunits(), -pos.y * m_boardAdapter.BiuTo3Dunits(), - zpos ); + zpos ); if( aFootprint->GetOrientation() ) - glRotated((double) aFootprint->GetOrientation() / 10.0, 0.0, 0.0, 1.0 ); + glRotated( (double) aFootprint->GetOrientation() / 10.0, 0.0, 0.0, 1.0 ); if( aFootprint->IsFlipped() ) { @@ -1381,8 +1356,6 @@ void C3D_RENDER_OGL_LEGACY::render_3D_footprint( const FOOTPRINT* aFootprint, } -// create a 3D grid to an OpenGL display list: an horizontal grid (XY plane and Z = 0, -// and a vertical grid (XZ plane and Y = 0) void C3D_RENDER_OGL_LEGACY::generate_new_3DGrid( GRID3D_TYPE aGridType ) { if( glIsList( m_grid ) ) diff --git a/3d-viewer/3d_rendering/3d_render_ogl_legacy/c3d_render_ogl_legacy.h b/3d-viewer/3d_rendering/3d_render_ogl_legacy/c3d_render_ogl_legacy.h index d63b475074..0ee120ae1f 100644 --- a/3d-viewer/3d_rendering/3d_render_ogl_legacy/c3d_render_ogl_legacy.h +++ b/3d-viewer/3d_rendering/3d_render_ogl_legacy/c3d_render_ogl_legacy.h @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2015-2016 Mario Luzeiro - * Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2015-2020 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 @@ -54,7 +54,7 @@ typedef std::map< wxString, C_OGL_3DMODEL * > MAP_3DMODEL; #define SIZE_OF_CIRCLE_TEXTURE 1024 /** - * @brief The C3D_RENDER_OGL_LEGACY class render the board using openGL legacy mode + * Object to render the board using openGL legacy mode. */ class C3D_RENDER_OGL_LEGACY : public C3D_RENDER_BASE { @@ -63,7 +63,6 @@ public: ~C3D_RENDER_OGL_LEGACY(); - // Imported from C3D_RENDER_BASE void SetCurWindowSize( const wxSize &aSize ) override; bool Redraw( bool aIsMoving, REPORTER* aStatusReporter, REPORTER* aWarningReporter ) override; @@ -74,43 +73,6 @@ public: m_currentIntersectedBoardItem = aCurrentIntersectedBoardItem; } -private: - bool initializeOpenGL(); - CLAYERS_OGL_DISP_LISTS* createBoard( const SHAPE_POLY_SET& aBoardPoly, - const CBVHCONTAINER2D *aThroughHoles = nullptr ); - void reload( REPORTER* aStatusReporter, REPORTER* aWarningReporter ); - - void ogl_set_arrow_material(); - - void ogl_free_all_display_lists(); - MAP_OGL_DISP_LISTS m_layers; - CLAYERS_OGL_DISP_LISTS* m_platedPads_F_Cu; - CLAYERS_OGL_DISP_LISTS* m_platedPads_B_Cu; - MAP_OGL_DISP_LISTS m_layers_holes_outer; - MAP_OGL_DISP_LISTS m_layers_holes_inner; - CLAYERS_OGL_DISP_LISTS* m_board; - CLAYERS_OGL_DISP_LISTS* m_board_with_holes; - CLAYERS_OGL_DISP_LISTS* m_anti_board; - CLAYERS_OGL_DISP_LISTS* m_through_holes_outer; - CLAYERS_OGL_DISP_LISTS* m_through_holes_vias_outer; - CLAYERS_OGL_DISP_LISTS* m_through_holes_outer_ring; - CLAYERS_OGL_DISP_LISTS* m_vias_and_pad_holes_outer_contourn_and_caps; - - LIST_TRIANGLES m_triangles; ///< store pointers so can be deleted latter - GLuint m_ogl_circle_texture; - - GLuint m_grid; ///< oGL list that stores current grid - GRID3D_TYPE m_last_grid_type; ///< Stores the last grid computed - - CLAYERS_OGL_DISP_LISTS* m_vias; - CLAYERS_OGL_DISP_LISTS* m_pad_holes; - - MAP_3DMODEL m_3dmodel_map; - - BOARD_ITEM* m_currentIntersectedBoardItem; - - SHAPE_POLY_SET m_anti_board_poly; ///< negative polygon representation of the board outline - private: CLAYERS_OGL_DISP_LISTS *generate_holes_display_list( const LIST_OBJECT2D &aListHolesObject2d, const SHAPE_POLY_SET &aPoly, @@ -120,9 +82,9 @@ private: const CBVHCONTAINER2D *aThroughHoles = nullptr ); CLAYERS_OGL_DISP_LISTS* generateLayerListFromContainer( const CBVHCONTAINER2D *aContainer, - const SHAPE_POLY_SET *aPolyList, - PCB_LAYER_ID aLayerId, - const CBVHCONTAINER2D *aThroughHoles = nullptr ); + const SHAPE_POLY_SET *aPolyList, + PCB_LAYER_ID aLayerId, + const CBVHCONTAINER2D *aThroughHoles = nullptr ); void add_triangle_top_bot( CLAYER_TRIANGLES *aDst, const SFVEC2F &v0, @@ -185,13 +147,19 @@ private: void generate_3D_Vias_and_Pads(); + /** + * Load footprint models from the cache and load it to openGL lists in the form of + * #C_OGL_3DMODEL objects. + * + * This map of models will work as a local cache for this render. (cache based on + * C_OGL_3DMODEL with associated openGL lists in GPU memory) + */ void load_3D_models( REPORTER* aStatusReporter ); /** - * @brief render_3D_models - * @param aRenderTopOrBot - true will render Top, false will render bottom - * @param aRenderTransparentOnly - true will render only the transparent - * objects, false will render opaque + * @param aRenderTopOrBot true will render Top, false will render bottom + * @param aRenderTransparentOnly true will render only the transparent objects, false will + * render opaque */ void render_3D_models( bool aRenderTopOrBot, bool aRenderTransparentOnly ); @@ -207,6 +175,11 @@ private: void render_3D_arrows(); + /** + * 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 generate_new_3DGrid( GRID3D_TYPE aGridType ); // Materials @@ -216,6 +189,18 @@ private: void setPlatedCopperAndDepthOffset( PCB_LAYER_ID aLayer_id ); void unsetDepthOffset(); + void set_layer_material( PCB_LAYER_ID aLayerID ); + SFVEC4F get_layer_color( PCB_LAYER_ID aLayerID ); + + bool initializeOpenGL(); + CLAYERS_OGL_DISP_LISTS* createBoard( const SHAPE_POLY_SET& aBoardPoly, + const CBVHCONTAINER2D *aThroughHoles = nullptr ); + void reload( REPORTER* aStatusReporter, REPORTER* aWarningReporter ); + + void ogl_set_arrow_material(); + + void ogl_free_all_display_lists(); + struct { SMATERIAL m_Paste; @@ -227,11 +212,35 @@ private: SMATERIAL m_Copper; SMATERIAL m_Plastic; SMATERIAL m_GrayMaterial; - }m_materials; + } m_materials; - void set_layer_material( PCB_LAYER_ID aLayerID ); - SFVEC4F get_layer_color( PCB_LAYER_ID aLayerID ); + MAP_OGL_DISP_LISTS m_layers; + CLAYERS_OGL_DISP_LISTS* m_platedPads_F_Cu; + CLAYERS_OGL_DISP_LISTS* m_platedPads_B_Cu; + MAP_OGL_DISP_LISTS m_layers_holes_outer; + MAP_OGL_DISP_LISTS m_layers_holes_inner; + CLAYERS_OGL_DISP_LISTS* m_board; + CLAYERS_OGL_DISP_LISTS* m_board_with_holes; + CLAYERS_OGL_DISP_LISTS* m_anti_board; + CLAYERS_OGL_DISP_LISTS* m_through_holes_outer; + CLAYERS_OGL_DISP_LISTS* m_through_holes_vias_outer; + CLAYERS_OGL_DISP_LISTS* m_through_holes_outer_ring; + CLAYERS_OGL_DISP_LISTS* m_vias_and_pad_holes_outer_contourn_and_caps; + + LIST_TRIANGLES m_triangles; ///< store pointers so can be deleted latter + GLuint m_ogl_circle_texture; + + GLuint m_grid; ///< oGL list that stores current grid + GRID3D_TYPE m_last_grid_type; ///< Stores the last grid computed + + CLAYERS_OGL_DISP_LISTS* m_vias; + CLAYERS_OGL_DISP_LISTS* m_pad_holes; + + MAP_3DMODEL m_3dmodel_map; + + BOARD_ITEM* m_currentIntersectedBoardItem; + + SHAPE_POLY_SET m_anti_board_poly; ///< negative polygon representation of the board outline }; #endif // C3D_RENDER_OGL_LEGACY_H_ - diff --git a/3d-viewer/3d_rendering/3d_render_ogl_legacy/c_ogl_3dmodel.cpp b/3d-viewer/3d_rendering/3d_render_ogl_legacy/c_ogl_3dmodel.cpp index 639d0e9783..c1c451bd3f 100644 --- a/3d-viewer/3d_rendering/3d_render_ogl_legacy/c_ogl_3dmodel.cpp +++ b/3d-viewer/3d_rendering/3d_render_ogl_legacy/c_ogl_3dmodel.cpp @@ -3,7 +3,7 @@ * * Copyright (C) 2020 Oleg Endo * Copyright (C) 2015-2020 Mario Luzeiro - * Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2015-2020 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 @@ -37,11 +37,16 @@ #include #include + +/* + * Flag to enable connectivity profiling + * @ingroup trace_env_vars + */ const wxChar * C_OGL_3DMODEL::m_logTrace = wxT( "KI_TRACE_EDA_OGL_3DMODEL" ); -void C_OGL_3DMODEL::MakeBbox( const CBBOX &aBox, unsigned int aIdxOffset, - VERTEX *aVtxOut, GLuint *aIdxOut, - const glm::vec4 &aColor ) + +void C_OGL_3DMODEL::MakeBbox( const CBBOX &aBox, unsigned int aIdxOffset, VERTEX *aVtxOut, + GLuint *aIdxOut, const glm::vec4 &aColor ) { aVtxOut[0].m_pos = { aBox.Min().x, aBox.Min().y, aBox.Min().z }; aVtxOut[1].m_pos = { aBox.Max().x, aBox.Min().y, aBox.Min().z }; @@ -78,8 +83,8 @@ void C_OGL_3DMODEL::MakeBbox( const CBBOX &aBox, unsigned int aIdxOffset, #undef bbox_line } -C_OGL_3DMODEL::C_OGL_3DMODEL( const S3DMODEL &a3DModel, - MATERIAL_MODE aMaterialMode ) + +C_OGL_3DMODEL::C_OGL_3DMODEL( const S3DMODEL &a3DModel, MATERIAL_MODE aMaterialMode ) { wxLogTrace( m_logTrace, wxT( "C_OGL_3DMODEL::C_OGL_3DMODEL %u meshes %u materials" ), static_cast( a3DModel.m_MeshesSize ), @@ -152,8 +157,7 @@ C_OGL_3DMODEL::C_OGL_3DMODEL( const S3DMODEL &a3DModel, mesh_group.m_vertices.resize( mesh_group.m_vertices.size() + mesh.m_VertexSize ); // copy vertex data and update the bounding box. - // use material color for mesh bounding box or some sort of average - // vertex color. + // use material color for mesh bounding box or some sort of average vertex color. glm::vec3 avg_color = material.m_Diffuse; for( unsigned int vtx_i = 0; vtx_i < mesh.m_VertexSize; ++vtx_i ) @@ -233,11 +237,11 @@ C_OGL_3DMODEL::C_OGL_3DMODEL( const S3DMODEL &a3DModel, { if( mesh.m_FaceIdx[idx_i] >= mesh.m_VertexSize ) { - wxLogTrace( m_logTrace, wxT( " index %u out of range (%u)" ), - static_cast( mesh.m_FaceIdx[idx_i] ), - static_cast( mesh.m_VertexSize ) ); + wxLogTrace( m_logTrace, wxT( " index %u out of range (%u)" ), + static_cast( mesh.m_FaceIdx[idx_i] ), + static_cast( mesh.m_VertexSize ) ); - // FIXME: should skip this triangle + // FIXME: should skip this triangle } mesh_group.m_indices[idx_offset + idx_i] = mesh.m_FaceIdx[idx_i] + vtx_offset; @@ -277,7 +281,6 @@ C_OGL_3DMODEL::C_OGL_3DMODEL( const S3DMODEL &a3DModel, bbox_tmp_indices.data(), GL_STATIC_DRAW ); } - // merge the mesh group geometry data. unsigned int total_vertex_count = 0; unsigned int total_index_count = 0; @@ -368,6 +371,7 @@ C_OGL_3DMODEL::C_OGL_3DMODEL( const S3DMODEL &a3DModel, end_time - start_time).count() ); } + void C_OGL_3DMODEL::BeginDrawMulti( bool aUseColorInformation ) { glEnableClientState( GL_VERTEX_ARRAY ); @@ -383,6 +387,7 @@ void C_OGL_3DMODEL::BeginDrawMulti( bool aUseColorInformation ) glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE ); } + void C_OGL_3DMODEL::EndDrawMulti() { glDisable( GL_COLOR_MATERIAL ); @@ -396,12 +401,12 @@ void C_OGL_3DMODEL::EndDrawMulti() } -void C_OGL_3DMODEL::Draw(bool aTransparent, float aOpacity, bool aUseSelectedMaterial , SFVEC3F aSelectionColor ) const +void C_OGL_3DMODEL::Draw( bool aTransparent, float aOpacity, bool aUseSelectedMaterial, + SFVEC3F aSelectionColor ) const { if( aOpacity <= FLT_EPSILON ) return; - if( !glBindBuffer ) throw std::runtime_error( "The OpenGL context no longer exists: unable to draw" ); @@ -428,38 +433,35 @@ void C_OGL_3DMODEL::Draw(bool aTransparent, float aOpacity, bool aUseSelectedMat glTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, (const float*)¶m.x ); // BeginDrawMulti(); - for( auto& mat : m_materials ) { - if( ( mat.IsTransparent() != aTransparent ) && - ( aOpacity >= 1.0f ) ) + if( ( mat.IsTransparent() != aTransparent ) && ( aOpacity >= 1.0f ) ) continue; switch( m_material_mode ) { - case MATERIAL_MODE::NORMAL: - OGL_SetMaterial( mat, aOpacity, aUseSelectedMaterial, aSelectionColor ); + case MATERIAL_MODE::NORMAL: + OGL_SetMaterial( mat, aOpacity, aUseSelectedMaterial, aSelectionColor ); break; - case MATERIAL_MODE::DIFFUSE_ONLY: - OGL_SetDiffuseOnlyMaterial( mat.m_Diffuse, aOpacity ); + case MATERIAL_MODE::DIFFUSE_ONLY: + OGL_SetDiffuseOnlyMaterial( mat.m_Diffuse, aOpacity ); break; - case MATERIAL_MODE::CAD_MODE: - OGL_SetDiffuseOnlyMaterial( MaterialDiffuseToColorCAD( mat.m_Diffuse ), aOpacity ); + case MATERIAL_MODE::CAD_MODE: + OGL_SetDiffuseOnlyMaterial( MaterialDiffuseToColorCAD( mat.m_Diffuse ), aOpacity ); break; - default: + default: break; } glDrawElements( GL_TRIANGLES, mat.m_render_idx_count, m_index_buffer_type, reinterpret_cast( mat.m_render_idx_buffer_offset ) ); } - - // EndDrawMulti(); } + C_OGL_3DMODEL::~C_OGL_3DMODEL() { if( glDeleteBuffers ) diff --git a/3d-viewer/3d_rendering/3d_render_ogl_legacy/c_ogl_3dmodel.h b/3d-viewer/3d_rendering/3d_render_ogl_legacy/c_ogl_3dmodel.h index 0987844cb2..562d43b756 100644 --- a/3d-viewer/3d_rendering/3d_render_ogl_legacy/c_ogl_3dmodel.h +++ b/3d-viewer/3d_rendering/3d_render_ogl_legacy/c_ogl_3dmodel.h @@ -3,7 +3,7 @@ * * Copyright (C) 2020 Oleg Endo * Copyright (C) 2015-2016 Mario Luzeiro - * Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2015-2020 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 @@ -37,62 +37,71 @@ #include "../3d_render_raytracing/shapes3D/cbbox.h" #include "../../3d_enums.h" -/// -class C_OGL_3DMODEL +class C_OGL_3DMODEL { public: /** - * @brief C_OGL_3DMODEL - Load a 3d model. This must be called inside a gl context - * @param a3DModel: a 3d model data to load. - * @param aMaterialMode: a mode to render the materials of the model + * Load a 3d model. + * + * @note This must be called inside a gl context. + * @param a3DModel a 3d model data to load. + * @param aMaterialMode a mode to render the materials of the model. */ C_OGL_3DMODEL( const S3DMODEL &a3DModel, MATERIAL_MODE aMaterialMode ); ~C_OGL_3DMODEL(); /** - * @brief Draw_opaque - render the model into the current context + * Render the model into the current context. */ - void Draw_opaque( bool aUseSelectedMaterial, SFVEC3F aSelectionColor = SFVEC3F( 0.0f ) ) const { Draw( false, 1.0f, aUseSelectedMaterial, aSelectionColor ); } + void Draw_opaque( bool aUseSelectedMaterial, + SFVEC3F aSelectionColor = SFVEC3F( 0.0f ) ) const + { + Draw( false, 1.0f, aUseSelectedMaterial, aSelectionColor ); + } /** - * @brief Draw_transparent - render the model into the current context + * Render the model into the current context. */ - void Draw_transparent( float aOpacity, bool aUseSelectedMaterial, SFVEC3F aSelectionColor = SFVEC3F( 0.0f ) ) const { Draw( true, aOpacity, aUseSelectedMaterial, aSelectionColor ); } + void Draw_transparent( float aOpacity, bool aUseSelectedMaterial, + SFVEC3F aSelectionColor = SFVEC3F( 0.0f ) ) const + { + Draw( true, aOpacity, aUseSelectedMaterial, aSelectionColor ); + } /** - * @brief Have_opaque - return true if have opaque meshs to render + * Return true if have opaque meshes to render. */ bool Have_opaque() const { return m_have_opaque_meshes; } /** - * @brief Have_transparent - return true if have transparent meshs to render + * Return true if have transparent mesh's to render. */ bool Have_transparent() const { return m_have_transparent_meshes; } /** - * @brief Draw_bbox - draw main bounding box of the model + * Draw main bounding box of the model. */ void Draw_bbox() const; /** - * @brief Draw_bboxes - draw individual bounding boxes of each mesh + * Draw individual bounding boxes of each mesh. */ void Draw_bboxes() const; /** - * @brief GetBBox - Get main bbox - * @return the main model bbox + * Get the main bounding box. + * @return the main model bounding box. */ const CBBOX &GetBBox() const { return m_model_bbox; } /** - * @brief BeginDrawMulti - set some basic render states before drawing multiple models + * Set some basic render states before drawing multiple models. */ static void BeginDrawMulti( bool aUseColorInformation ); /** - * @brief EndDrawMulti - cleanup render states after drawing multiple models + * Cleanup render states after drawing multiple models. */ static void EndDrawMulti(); @@ -155,7 +164,8 @@ private: VERTEX *aVtxOut, GLuint *aIdxOut, const glm::vec4 &aColor ); - void Draw( bool aTransparent, float aOpacity, bool aUseSelectedMaterial, SFVEC3F aSelectionColor ) const; + void Draw( bool aTransparent, float aOpacity, bool aUseSelectedMaterial, + SFVEC3F aSelectionColor ) const; }; #endif // _C_OGL_3DMODEL_H_ diff --git a/3d-viewer/3d_rendering/buffers_debug.cpp b/3d-viewer/3d_rendering/buffers_debug.cpp index 3318900a15..f4fd89520a 100644 --- a/3d-viewer/3d_rendering/buffers_debug.cpp +++ b/3d-viewer/3d_rendering/buffers_debug.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2016 Mario Luzeiro - * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2016-2020 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 @@ -31,18 +31,12 @@ #include // Used for save an image to disk /** - * @brief dbg_save_rgb_buffer - * @param aFileName - * @param aRGBpixelBuffer: from wxWidget documentation + * @param aRGBpixelBuffer from the wxWidgets documentation * "The data given must have the size (width*height*3). * The data must have been allocated with malloc(), NOT with operator new." - * @param aXSize - * @param aYSize */ -static void dbg_save_rgb_buffer( const wxString& aFileName, - unsigned char *aRGBpixelBuffer, - unsigned int aXSize, - unsigned int aYSize ) +static void dbg_save_rgb_buffer( const wxString& aFileName, unsigned char *aRGBpixelBuffer, + unsigned int aXSize, unsigned int aYSize ) { wxImage image( aXSize, aYSize ); image.SetData( aRGBpixelBuffer ); @@ -52,10 +46,8 @@ static void dbg_save_rgb_buffer( const wxString& aFileName, } -void DBG_SaveBuffer( const wxString& aFileName, - const unsigned char *aInBuffer, - unsigned int aXSize, - unsigned int aYSize ) +void DBG_SaveBuffer( const wxString& aFileName, const unsigned char *aInBuffer, + unsigned int aXSize, unsigned int aYSize ) { const unsigned int wxh = aXSize * aYSize; @@ -75,10 +67,8 @@ void DBG_SaveBuffer( const wxString& aFileName, } -void DBG_SaveBuffer( const wxString& aFileName, - const float *aInBuffer, - unsigned int aXSize, - unsigned int aYSize ) +void DBG_SaveBuffer( const wxString& aFileName, const float *aInBuffer, + unsigned int aXSize, unsigned int aYSize ) { const unsigned int wxh = aXSize * aYSize; @@ -86,8 +76,7 @@ void DBG_SaveBuffer( const wxString& aFileName, for( unsigned int i = 0; i < wxh; ++i ) { - const unsigned char v = (unsigned char)glm::min( (int)(aInBuffer[i] * 255.0f), - 255 ); + const unsigned char v = (unsigned char)glm::min( (int)(aInBuffer[i] * 255.0f), 255 ); // Set RGB value with all same values intensities pixelbuffer[i * 3 + 0] = v; @@ -99,10 +88,8 @@ void DBG_SaveBuffer( const wxString& aFileName, } -void DBG_SaveBuffer( const wxString& aFileName, - const SFVEC3F *aInBuffer, - unsigned int aXSize, - unsigned int aYSize ) +void DBG_SaveBuffer( const wxString& aFileName, const SFVEC3F *aInBuffer, + unsigned int aXSize, unsigned int aYSize ) { const unsigned int wxh = aXSize * aYSize; @@ -114,19 +101,17 @@ void DBG_SaveBuffer( const wxString& aFileName, const unsigned int ix3 = i * 3; // Set RGB value with all same values intensities - pixelbuffer[ix3 + 0] = (unsigned char)glm::min( (int)(v.r * 255.0f), 255 ); - pixelbuffer[ix3 + 1] = (unsigned char)glm::min( (int)(v.g * 255.0f), 255 ); - pixelbuffer[ix3 + 2] = (unsigned char)glm::min( (int)(v.b * 255.0f), 255 ); + pixelbuffer[ix3 + 0] = (unsigned char) glm::min( (int) ( v.r * 255.0f ), 255 ); + pixelbuffer[ix3 + 1] = (unsigned char) glm::min( (int) ( v.g * 255.0f ), 255 ); + pixelbuffer[ix3 + 2] = (unsigned char) glm::min( (int) ( v.b * 255.0f ), 255 ); } dbg_save_rgb_buffer( aFileName, pixelbuffer, aXSize, aYSize ); } -void DBG_SaveNormalsBuffer( const wxString& aFileName, - const SFVEC3F *aInNormalsBuffer, - unsigned int aXSize, - unsigned int aYSize ) +void DBG_SaveNormalsBuffer( const wxString& aFileName, const SFVEC3F *aInNormalsBuffer, + unsigned int aXSize, unsigned int aYSize ) { const unsigned int wxh = aXSize * aYSize; @@ -138,9 +123,9 @@ void DBG_SaveNormalsBuffer( const wxString& aFileName, const unsigned int ix3 = i * 3; // Set RGB value with all same values intensities - pixelbuffer[ix3 + 0] = (unsigned char)glm::min( (int)((v.r + 1.0f) * 127.0f), 255 ); - pixelbuffer[ix3 + 1] = (unsigned char)glm::min( (int)((v.g + 1.0f) * 127.0f), 255 ); - pixelbuffer[ix3 + 2] = (unsigned char)glm::min( (int)((v.b + 1.0f) * 127.0f), 255 ); + pixelbuffer[ix3 + 0] = (unsigned char) glm::min( (int) ( ( v.r + 1.0f ) * 127.0f ), 255 ); + pixelbuffer[ix3 + 1] = (unsigned char) glm::min( (int) ( ( v.g + 1.0f ) * 127.0f ), 255 ); + pixelbuffer[ix3 + 2] = (unsigned char) glm::min( (int) ( ( v.b + 1.0f ) * 127.0f ), 255 ); } dbg_save_rgb_buffer( aFileName, pixelbuffer, aXSize, aYSize ); diff --git a/3d-viewer/3d_rendering/buffers_debug.h b/3d-viewer/3d_rendering/buffers_debug.h index c64975d7af..9e5fd9700a 100644 --- a/3d-viewer/3d_rendering/buffers_debug.h +++ b/3d-viewer/3d_rendering/buffers_debug.h @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2016 Mario Luzeiro - * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2016-2020 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 @@ -33,23 +33,16 @@ #include #include -void DBG_SaveBuffer( const wxString& aFileName, - const unsigned char *aInBuffer, +void DBG_SaveBuffer( const wxString& aFileName, const unsigned char *aInBuffer, unsigned int aXSize, unsigned int aYSize ); -void DBG_SaveBuffer( const wxString& aFileName, - const float *aInBuffer, - unsigned int aXSize, - unsigned int aYSize ); +void DBG_SaveBuffer( const wxString& aFileName, const float *aInBuffer, + unsigned int aXSize, unsigned int aYSize ); -void DBG_SaveBuffer( const wxString& aFileName, - const SFVEC3F *aInBuffer, - unsigned int aXSize, - unsigned int aYSize ); +void DBG_SaveBuffer( const wxString& aFileName, const SFVEC3F *aInBuffer, + unsigned int aXSize, unsigned int aYSize ); -void DBG_SaveNormalsBuffer( const wxString& aFileName, - const SFVEC3F *aInNormalsBuffer, - unsigned int aXSize, - unsigned int aYSize ); +void DBG_SaveNormalsBuffer( const wxString& aFileName, const SFVEC3F *aInNormalsBuffer, + unsigned int aXSize, unsigned int aYSize ); #endif // BUFFER_DEBUG_H diff --git a/3d-viewer/3d_rendering/c3d_render_base.cpp b/3d-viewer/3d_rendering/c3d_render_base.cpp index b1cac973dd..d45e410561 100644 --- a/3d-viewer/3d_rendering/c3d_render_base.cpp +++ b/3d-viewer/3d_rendering/c3d_render_base.cpp @@ -33,11 +33,14 @@ /** * Trace mask used to enable or disable the trace output of this class. + * * The debug output can be turned on by setting the WXTRACE environment variable to * "KI_TRACE_3D_RENDER". See the wxWidgets documentation on wxLogTrace for * more information. + * + * @ingroup trace_env_vars */ -const wxChar * C3D_RENDER_BASE::m_logTrace = wxT( "KI_TRACE_3D_RENDER" ); +const wxChar* C3D_RENDER_BASE::m_logTrace = wxT( "KI_TRACE_3D_RENDER" ); C3D_RENDER_BASE::C3D_RENDER_BASE( BOARD_ADAPTER& aBoardAdapter, CCAMERA& aCamera ) : diff --git a/3d-viewer/3d_rendering/c3d_render_base.h b/3d-viewer/3d_rendering/c3d_render_base.h index 475dda52e5..305a40710b 100644 --- a/3d-viewer/3d_rendering/c3d_render_base.h +++ b/3d-viewer/3d_rendering/c3d_render_base.h @@ -42,50 +42,46 @@ */ class C3D_RENDER_BASE { - - - // Operations public: - explicit C3D_RENDER_BASE( BOARD_ADAPTER& aBoardAdapter, CCAMERA& aCamera ); virtual ~C3D_RENDER_BASE() = 0; /** - * @brief SetCurWindowSize - Before each render, the canvas will tell the - * render what is the size of its windows, so render can take actions if it - * changed. - * @param aSize: the current size of the render window + * Before each render, the canvas will tell the render what is the size of its windows, + * so render can take actions if it changed. + * + * @param aSize the current size of the render window */ virtual void SetCurWindowSize( const wxSize &aSize ) = 0; /** - * @brief Redraw - Ask to redraw the view - * @param aIsMoving: if the user is moving the scene, it should be render in - * preview mode - * @param aStatusReporter: a pointer to the status progress reporter - * @return it will return true if the render would like to redraw again + * Redraw the view. + * + * @param aIsMoving if the user is moving the scene, it should be render in preview mode. + * @param aStatusReporter a pointer to the status progress reporter. + * @return true if the render would like to redraw again. */ virtual bool Redraw( bool aIsMoving, REPORTER* aStatusReporter = NULL, REPORTER* aWarningReporter = NULL ) = 0; /** - * @brief ReloadRequest - !TODO: this must be reviewed to add flags to - * improve specific render + * @todo This must be reviewed to add flags to improve specific render. */ void ReloadRequest() { m_reloadRequested = true; } /** - * @brief IsReloadRequestPending - Query if there is a pending reload request + * Query if there is a pending reload request. + * * @return true if it wants to reload, false if there is no reload pending */ bool IsReloadRequestPending() const { return m_reloadRequested; } /** - * @brief GetWaitForEditingTimeOut - Give the interface the time (in ms) - * that it should wait for editing or movements before - * (this works for display preview mode) - * @return a value in miliseconds + * Give the interface the time (in ms) that it should wait for editing or movements before + * (this works for display preview mode). + * + * @return a value in milliseconds */ virtual int GetWaitForEditingTimeOut() = 0; @@ -97,27 +93,24 @@ public: */ void SetBusyIndicatorFactory( BUSY_INDICATOR::FACTORY aNewFactory ); - // Attributes - protected: /** - * Return a created busy indicator, if a factory has been set, else - * a null pointer. + * Return a created busy indicator, if a factory has been set, else a null pointer. */ std::unique_ptr CreateBusyIndicator() const; - /// settings refrence in use for this render + ///< Settings reference in use for this render. BOARD_ADAPTER& m_boardAdapter; CCAMERA& m_camera; - /// flag if the opengl specific for this render was already initialized + ///< Flag if the opengl specific for this render was already initialized. bool m_is_opengl_initialized; - /// !TODO: this must be reviewed in order to flag change types + ///< @todo This must be reviewed in order to flag change types. bool m_reloadRequested; - /// The window size that this camera is working. + ///< The window size that this camera is working. wxSize m_windowSize; /** @@ -129,7 +122,7 @@ protected: static const wxChar *m_logTrace; private: - /// Factory that returns a suitable busy indicator for the context. + ///< Factory that returns a suitable busy indicator for the context. BUSY_INDICATOR::FACTORY m_busyIndicatorFactory; }; diff --git a/3d-viewer/3d_rendering/ccamera.cpp b/3d-viewer/3d_rendering/ccamera.cpp index c0d437e757..b0ea14db55 100644 --- a/3d-viewer/3d_rendering/ccamera.cpp +++ b/3d-viewer/3d_rendering/ccamera.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2015-2016 Mario Luzeiro - * Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2015-2020 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 @@ -43,16 +43,15 @@ inline void normalise2PI( float& aAngle ) /** - * Trace mask used to enable or disable the trace output of this class. - * The debug output can be turned on by setting the WXTRACE environment variable to - * "KI_TRACE_CCAMERA". See the wxWidgets documentation on wxLogTrace for - * more information. + * @ingroup trace_env_vars */ const wxChar *CCAMERA::m_logTrace = wxT( "KI_TRACE_CCAMERA" ); + #define MIN_ZOOM 0.10f #define MAX_ZOOM 1.25f + CCAMERA::CCAMERA( float aRangeScale ) { wxLogTrace( m_logTrace, wxT( "CCAMERA::CCAMERA" ) ); @@ -107,7 +106,6 @@ void CCAMERA::Reset_T1() m_rotate_aux_t1 = SFVEC3F( 0.0f ); m_lookat_pos_t1 = m_board_lookat_pos_init; - // Since 0 = 2pi, we want to reset the angle to be the closest // one to where we currently are. That ensures that we rotate // the board around the smallest distance getting there. @@ -162,14 +160,12 @@ const glm::mat4 CCAMERA::GetRotationMatrix() const void CCAMERA::rebuildProjection() { - if( (m_windowSize.x == 0) || - (m_windowSize.y == 0) ) + if( ( m_windowSize.x == 0 ) || ( m_windowSize.y == 0 ) ) return; m_frustum.ratio = (float) m_windowSize.x / (float)m_windowSize.y; // Consider that we can render double the length multiplied by the 2/sqrt(2) - // m_frustum.farD = glm::length( m_camera_pos_init ) * 2.0f * ( 2.0f * sqrtf( 2.0f ) ); switch( m_projectionType ) @@ -182,7 +178,6 @@ void CCAMERA::rebuildProjection() // Ratio width / height of the window display m_frustum.angle = 45.0f * m_zoom; - m_projectionMatrix = glm::perspective( glm::radians( m_frustum.angle ), m_frustum.ratio, m_frustum.nearD, @@ -209,7 +204,7 @@ void CCAMERA::rebuildProjection() const float orthoReductionFactor = glm::length( m_camera_pos_init ) * m_zoom * m_zoom * 0.5f; - // Initialize Projection Matrix for Ortographic View + // Initialize Projection Matrix for Orthographic View m_projectionMatrix = glm::ortho( -m_frustum.ratio * orthoReductionFactor, m_frustum.ratio * orthoReductionFactor, -orthoReductionFactor, @@ -226,8 +221,7 @@ void CCAMERA::rebuildProjection() break; } - if ( (m_windowSize.x > 0) && - (m_windowSize.y > 0) ) + if( ( m_windowSize.x > 0 ) && ( m_windowSize.y > 0 ) ) { m_scr_nX.resize( m_windowSize.x + 1 ); m_scr_nY.resize( m_windowSize.y + 1 ); @@ -275,7 +269,6 @@ void CCAMERA::updateFrustum() m_pos = SFVEC3F( m_viewMatrixInverse * glm::vec4( SFVEC3F( 0.0, 0.0, 0.0 ), 1.0 ) ); - /* * Frustum is a implementation based on a tutorial by * http://www.lighthouse3d.com/tutorials/view-frustum-culling/ @@ -297,8 +290,7 @@ void CCAMERA::updateFrustum() m_frustum.fbl = m_frustum.fc - m_up * m_frustum.fh - m_right * m_frustum.fw; m_frustum.fbr = m_frustum.fc - m_up * m_frustum.fh + m_right * m_frustum.fw; - if ( (m_windowSize.x > 0) && - (m_windowSize.y > 0) ) + if( ( m_windowSize.x > 0 ) && ( m_windowSize.y > 0 ) ) { // Reserve size for precalc values m_right_nX.resize( m_windowSize.x + 1 ); @@ -307,27 +299,25 @@ void CCAMERA::updateFrustum() // Precalc X values for camera -> ray generation const SFVEC3F right_nw = m_right * m_frustum.nw; - for( unsigned int x = 0; x < ((unsigned int)m_windowSize.x + 1); ++x ) + for( unsigned int x = 0; x < ( (unsigned int) m_windowSize.x + 1 ); ++x ) m_right_nX[x] = right_nw * m_scr_nX[x]; // Precalc Y values for camera -> ray generation const SFVEC3F up_nh = m_up * m_frustum.nh; - for( unsigned int y = 0; y < ((unsigned int)m_windowSize.y + 1); ++y ) + for( unsigned int y = 0; y < ( (unsigned int) m_windowSize.y + 1 ); ++y ) m_up_nY[y] = up_nh * m_scr_nY[y]; } } -void CCAMERA::MakeRay( const SFVEC2I &aWindowPos, - SFVEC3F &aOutOrigin, +void CCAMERA::MakeRay( const SFVEC2I &aWindowPos, SFVEC3F &aOutOrigin, SFVEC3F &aOutDirection ) const { wxASSERT( aWindowPos.x < m_windowSize.x ); wxASSERT( aWindowPos.y < m_windowSize.y ); - const SFVEC3F up_plus_right = m_up_nY[aWindowPos.y] + - m_right_nX[aWindowPos.x]; + const SFVEC3F up_plus_right = m_up_nY[aWindowPos.y] + m_right_nX[aWindowPos.x]; switch( m_projectionType ) { @@ -345,7 +335,8 @@ void CCAMERA::MakeRay( const SFVEC2I &aWindowPos, } -void CCAMERA::MakeRay( const SFVEC2F &aWindowPos, SFVEC3F &aOutOrigin, SFVEC3F &aOutDirection ) const +void CCAMERA::MakeRay( const SFVEC2F &aWindowPos, SFVEC3F &aOutOrigin, + SFVEC3F &aOutDirection ) const { wxASSERT( aWindowPos.x < (float)m_windowSize.x ); wxASSERT( aWindowPos.y < (float)m_windowSize.y ); @@ -376,11 +367,9 @@ void CCAMERA::MakeRay( const SFVEC2F &aWindowPos, SFVEC3F &aOutOrigin, SFVEC3F & } -void CCAMERA::MakeRayAtCurrrentMousePosition( SFVEC3F &aOutOrigin, - SFVEC3F &aOutDirection ) const +void CCAMERA::MakeRayAtCurrrentMousePosition( SFVEC3F &aOutOrigin, SFVEC3F &aOutDirection ) const { - const SFVEC2I windowPos = SFVEC2I( m_lastPosition.x, - m_windowSize.y - m_lastPosition.y ); + const SFVEC2I windowPos = SFVEC2I( m_lastPosition.x, m_windowSize.y - m_lastPosition.y ); if( ( 0 < windowPos.x ) && ( windowPos.x < m_windowSize.x ) && ( 0 < windowPos.y ) && ( windowPos.y < m_windowSize.y ) ) @@ -477,12 +466,15 @@ void CCAMERA::ZoomReset() bool CCAMERA::Zoom( float aFactor ) { - if ( ( m_zoom == MIN_ZOOM && aFactor > 1 ) || ( m_zoom == MAX_ZOOM && aFactor < 1 ) || aFactor == 1 ) + if( ( m_zoom == MIN_ZOOM && aFactor > 1 ) || ( m_zoom == MAX_ZOOM && aFactor < 1 ) + || aFactor == 1 ) return false; m_zoom /= aFactor; + if( m_zoom <= MIN_ZOOM ) m_zoom = MIN_ZOOM; + if( m_zoom >= MAX_ZOOM ) m_zoom = MAX_ZOOM; @@ -494,15 +486,19 @@ bool CCAMERA::Zoom( float aFactor ) return true; } + bool CCAMERA::Zoom_T1( float aFactor ) { - if( ( m_zoom == MIN_ZOOM && aFactor > 1 ) || ( m_zoom == MAX_ZOOM && aFactor < 1 ) || aFactor == 1 ) + if( ( m_zoom == MIN_ZOOM && aFactor > 1 ) || ( m_zoom == MAX_ZOOM && aFactor < 1 ) + || aFactor == 1 ) return false; m_zoom_t1 = m_zoom / aFactor; - if (m_zoom_t1 < MIN_ZOOM ) + + if( m_zoom_t1 < MIN_ZOOM ) m_zoom_t1 = MIN_ZOOM; - if (m_zoom_t1 > MAX_ZOOM ) + + if( m_zoom_t1 > MAX_ZOOM ) m_zoom_t1 = MAX_ZOOM; m_camera_pos_t1.z = m_camera_pos_init.z * m_zoom_t1; diff --git a/3d-viewer/3d_rendering/ccamera.h b/3d-viewer/3d_rendering/ccamera.h index 11210a002b..ce21fe98c9 100644 --- a/3d-viewer/3d_rendering/ccamera.h +++ b/3d-viewer/3d_rendering/ccamera.h @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2015-2016 Mario Luzeiro - * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2015-2020 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 @@ -41,7 +41,6 @@ enum class PROJECTION_TYPE }; /** - * Frustum structure * Frustum is a implementation based on a tutorial by * http://www.lighthouse3d.com/tutorials/view-frustum-culling/ */ @@ -71,21 +70,19 @@ enum class CAMERA_INTERPOLATION /** - * Class CCAMERA - * is a virtual class used to derive CCAMERA objects from. + * A class used to derive camera objects from. * - * It must be derived to other classes to implement a real camera object. + * It must be derived by other classes to implement a real camera object. */ class CCAMERA { - - public: - +public: /** - * @brief CCAMERA initialize a camera - * @param aRangeScale: it will be expected that the board will have a - * -aRangeScale/2 to +aRangeScale/2 - * it will initialize the initial Z position with aRangeScale + * Initialize a camera. + * + * @param aRangeScale it will be expected that the board will have a + * -aRangeScale/2 to +aRangeScale/2. It will initialize the + * Z position with aRangeScale. */ explicit CCAMERA( float aRangeScale ); @@ -95,8 +92,8 @@ class CCAMERA /** - * Function GetRotationMatrix - * Get the rotation matrix to be applied in a transformation camera + * Get the rotation matrix to be applied in a transformation camera. + * * @return the rotation matrix of the camera */ const glm::mat4 GetRotationMatrix() const; @@ -115,7 +112,8 @@ class CCAMERA float GetNear() const { return m_frustum.nearD; } float GetFar() const { return m_frustum.farD; } - void SetBoardLookAtPos( const SFVEC3F &aBoardPos ) { + void SetBoardLookAtPos( const SFVEC3F &aBoardPos ) + { if( m_board_lookat_pos_init != aBoardPos ) { m_board_lookat_pos_init = aBoardPos; @@ -125,7 +123,8 @@ class CCAMERA virtual void SetLookAtPos( const SFVEC3F &aLookAtPos ) = 0; - void SetLookAtPos_T1( const SFVEC3F &aLookAtPos ) { + void SetLookAtPos_T1( const SFVEC3F &aLookAtPos ) + { m_lookat_pos_t1 = aLookAtPos; } @@ -144,7 +143,6 @@ class CCAMERA virtual void Pan_T1( const SFVEC3F &aDeltaOffsetInc ) = 0; - /** * Reset the camera to initial state */ @@ -155,8 +153,7 @@ class CCAMERA void ResetXYpos_T1(); /** - * It updates the current mouse position without make any new recalculations - * on camera. + * Update the current mouse position without make any new calculations on camera. */ void SetCurMousePosition( const wxPoint &aPosition ); @@ -164,9 +161,9 @@ class CCAMERA PROJECTION_TYPE GetProjection() { return m_projectionType; } /** - * @brief SetCurWindowSize - update the windows size of the camera - * @param aSize - * @return true if the windows size changed since last time + * Update the windows size of the camera. + * + * @return true if the windows size changed since last time. */ bool SetCurWindowSize( const wxSize &aSize ); @@ -187,13 +184,14 @@ class CCAMERA void RotateZ_T1( float aAngleInRadians ); /** - * @brief SetT0_and_T1_current_T - This will set T0 and T1 with the current values + * This will set T0 and T1 with the current values. */ virtual void SetT0_and_T1_current_T(); /** - * @brief Interpolate - It will update the matrix to interpolate between T0 and T1 values - * @param t the interpolation time, between 0.0f and 1.0f (it will clamp if >1) + * It will update the matrix to interpolate between T0 and T1 values. + * + * @param t the interpolation time, between 0.0f and 1.0f (it will clamp if >1). */ virtual void Interpolate( float t ); @@ -203,44 +201,43 @@ class CCAMERA } /** - * Function ParametersChanged - * @return true if some of the parameters in camera was changed, - * it will reset the flag + * @return true if some of the parameters in camera was changed, it will reset the flag. */ bool ParametersChanged(); /** - * Function ParametersChangedQuery - * @return true if some of the parameters in camera was changed, - * it will NOT reset the flag + * @return true if some of the parameters in camera was changed, it will NOT reset the flag. */ bool ParametersChangedQuery() const { return m_parametersChanged; } /** - * @brief MakeRay - Make a ray based on a windows screen position - * @param aWindowPos: the windows buffer position - * @param aOutOrigin: out origin position of the ray - * @param aOutDirection: out direction + * Make a ray based on a windows screen position. + * + * @param aWindowPos the windows buffer position. + * @param aOutOrigin out origin position of the ray. + * @param aOutDirection out direction */ void MakeRay( const SFVEC2I &aWindowPos, SFVEC3F &aOutOrigin, SFVEC3F &aOutDirection ) const; /** - * @brief MakeRay - Make a ray based on a windows screen position, it will interpolate based on the float aWindowPos - * @param aWindowPos: the windows buffer position (float value) - * @param aOutOrigin: out origin position of the ray - * @param aOutDirection: out direction + * Make a ray based on a windows screen position, it will interpolate based on the + * \a aWindowPos. + * + * @param aWindowPos the windows buffer position (float value). + * @param aOutOrigin out origin position of the ray. + * @param aOutDirection out direction. */ void MakeRay( const SFVEC2F &aWindowPos, SFVEC3F &aOutOrigin, SFVEC3F &aOutDirection ) const; /** - * @brief MakeRayAtCurrrentMousePosition - Make a ray based on the latest mouse position - * @param aOutOrigin: out origin position of the ray - * @param aOutDirection: out direction + * Make a ray based on the latest mouse position. + * + * @param aOutOrigin out origin position of the ray. + * @param aOutDirection out direction. */ void MakeRayAtCurrrentMousePosition( SFVEC3F &aOutOrigin, SFVEC3F &aOutDirection ) const; - protected: - +protected: void rebuildProjection(); void updateFrustum(); void updateViewMatrix(); @@ -248,25 +245,26 @@ class CCAMERA void updateRotationMatrix(); /** - * @brief m_range_scale - the nominal range expected to be used in the camera. + * The nominal range expected to be used in the camera. + * * It will be used to initialize the Z position */ float m_range_scale; /** - * 3D zoom value (Min 0.0 ... Max 1.0) + * 3D zoom value (Min 0.0 ... Max 1.0) */ float m_zoom; float m_zoom_t0; float m_zoom_t1; /** - * The window size that this camera is working. + * The window size that this camera is working. */ SFVEC2I m_windowSize; /** - * The last mouse position in the screen + * The last mouse position in the screen */ wxPoint m_lastPosition; @@ -295,39 +293,38 @@ class CCAMERA SFVEC3F m_lookat_pos; SFVEC3F m_lookat_pos_t0; SFVEC3F m_lookat_pos_t1; - SFVEC3F m_board_lookat_pos_init; ///< Default boardlookat position (the board center) + SFVEC3F m_board_lookat_pos_init; ///< Default boardlookat position (the board center). - SFVEC3F m_rotate_aux; ///< Stores the rotation angle auxiliar + SFVEC3F m_rotate_aux; ///< Stores the rotation angle auxiliary. SFVEC3F m_rotate_aux_t0; SFVEC3F m_rotate_aux_t1; CAMERA_INTERPOLATION m_interpolation_mode; /** - * Precalc values array used to calc ray for each pixel - * (constant for the same window size) + * Precalc values array used to calc ray for each pixel (constant for the same window size). */ std::vector< float > m_scr_nX; std::vector< float > m_scr_nY; /** - * Precalc values array used to calc ray for each pixel, - * for X and Y axis of each new camera position + * Precalc values array used to calc ray for each pixel, for X and Y axis of each new + * camera position. */ std::vector< SFVEC3F > m_right_nX; std::vector< SFVEC3F > m_up_nY; - /** - * Set to true if any of the parameters in the camera was changed + * Set to true if any of the parameters in the camera was changed */ bool m_parametersChanged; /** - * Trace mask used to enable or disable the trace output of this class. - * The debug output can be turned on by setting the WXTRACE environment variable to - * "KI_TRACE_CCAMERA". See the wxWidgets documentation on wxLogTrace for - * more information. + * Trace mask used to enable or disable the trace output of this class. + * + * The debug output can be turned on by setting the WXTRACE environment variable to + * "KI_TRACE_CCAMERA". See the wxWidgets documentation on wxLogTrace for + * more information. */ static const wxChar *m_logTrace; }; diff --git a/3d-viewer/3d_rendering/ccolorrgb.cpp b/3d-viewer/3d_rendering/ccolorrgb.cpp index 4fc2ad4d80..8a0694dbd0 100644 --- a/3d-viewer/3d_rendering/ccolorrgb.cpp +++ b/3d-viewer/3d_rendering/ccolorrgb.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2015-2016 Mario Luzeiro - * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2015-2020 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 @@ -33,9 +33,9 @@ CCOLORRGB::CCOLORRGB( const SFVEC3F &aColor ) { - r = (unsigned int)glm::clamp( (int)(aColor.r * 255), 0, 255 ); - g = (unsigned int)glm::clamp( (int)(aColor.g * 255), 0, 255 ); - b = (unsigned int)glm::clamp( (int)(aColor.b * 255), 0, 255 ); + r = (unsigned int) glm::clamp( (int) ( aColor.r * 255 ), 0, 255 ); + g = (unsigned int) glm::clamp( (int) ( aColor.g * 255 ), 0, 255 ); + b = (unsigned int) glm::clamp( (int) ( aColor.b * 255 ), 0, 255 ); } @@ -45,7 +45,7 @@ CCOLORRGB BlendColor( const CCOLORRGB &aC1, const CCOLORRGB &aC2 ) const unsigned int g = aC1.g + aC2.g; const unsigned int b = aC1.b + aC2.b; - return CCOLORRGB( (r >> 1), (g >> 1), (b >> 1) ); + return CCOLORRGB( ( r >> 1 ), ( g >> 1 ), ( b >> 1 ) ); } @@ -55,18 +55,16 @@ CCOLORRGB BlendColor( const CCOLORRGB &aC1, const CCOLORRGB &aC2, const CCOLORRG const unsigned int g = aC1.g + aC2.g + aC3.g; const unsigned int b = aC1.b + aC2.b + aC3.b; - return CCOLORRGB( (r / 3), (g / 3), (b / 3) ); + return CCOLORRGB( ( r / 3 ), ( g / 3 ), ( b / 3 ) ); } -CCOLORRGB BlendColor( const CCOLORRGB &aC1, - const CCOLORRGB &aC2, - const CCOLORRGB &aC3, +CCOLORRGB BlendColor( const CCOLORRGB &aC1, const CCOLORRGB &aC2, const CCOLORRGB &aC3, const CCOLORRGB &aC4 ) { const unsigned int r = aC1.r + aC2.r + aC3.r + aC4.r; const unsigned int g = aC1.g + aC2.g + aC3.g + aC4.g; const unsigned int b = aC1.b + aC2.b + aC3.b + aC4.b; - return CCOLORRGB( (r >> 2), (g >> 2), (b >> 2) ); + return CCOLORRGB( ( r >> 2 ), ( g >> 2 ), ( b >> 2 ) ); } diff --git a/3d-viewer/3d_rendering/ccolorrgb.h b/3d-viewer/3d_rendering/ccolorrgb.h index a413b2d96f..05c3cf4c58 100644 --- a/3d-viewer/3d_rendering/ccolorrgb.h +++ b/3d-viewer/3d_rendering/ccolorrgb.h @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2015-2016 Mario Luzeiro - * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2015-2020 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 @@ -45,16 +45,18 @@ union CCOLORRGB CCOLORRGB( const SFVEC3F &aColor ); CCOLORRGB() { r = 0; g = 0; b = 0; } - CCOLORRGB( unsigned char aR, unsigned char aG, unsigned char aB ) { r = aR; - g = aG; - b = aB; } + CCOLORRGB( unsigned char aR, unsigned char aG, unsigned char aB ) + { + r = aR; + g = aG; + b = aB; + } }; + CCOLORRGB BlendColor( const CCOLORRGB &aC1, const CCOLORRGB &aC2 ); CCOLORRGB BlendColor( const CCOLORRGB &aC1, const CCOLORRGB &aC2, const CCOLORRGB &aC3 ); -CCOLORRGB BlendColor( const CCOLORRGB &aC1, - const CCOLORRGB &aC2, - const CCOLORRGB &aC3, +CCOLORRGB BlendColor( const CCOLORRGB &aC1, const CCOLORRGB &aC2, const CCOLORRGB &aC3, const CCOLORRGB &aC4 ); #endif // CCOLORRGB_H diff --git a/3d-viewer/3d_rendering/cimage.cpp b/3d-viewer/3d_rendering/cimage.cpp index 8af41fe550..9ed801a72d 100644 --- a/3d-viewer/3d_rendering/cimage.cpp +++ b/3d-viewer/3d_rendering/cimage.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2015-2016 Mario Luzeiro - * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2015-2020 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 @@ -36,8 +36,9 @@ #include #include + #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 @@ -80,28 +81,27 @@ bool CIMAGE::wrapCoords( int *aXo, int *aYo ) const int x = *aXo; int y = *aYo; - switch(m_wraping) + switch( m_wraping ) { case IMAGE_WRAP::CLAMP: - x = (x < 0 )?0:x; - x = (x >= (int)(m_width - 1))?(m_width - 1):x; - y = (y < 0)?0:y; - y = (y >= (int)(m_height - 1))?(m_height - 1):y; + x = ( x < 0 ) ? 0 : x; + x = ( x >= (int) ( m_width - 1 ) ) ? ( m_width - 1 ) : x; + y = ( y < 0 ) ? 0 : y; + y = ( y >= (int) ( m_height - 1 ) ) ? ( m_height - 1 ) : y; break; case IMAGE_WRAP::WRAP: - x = (x < 0)?((m_width - 1)+x):x; - x = (x >= (int)(m_width - 1))?(x - m_width):x; - y = (y < 0)?((m_height - 1)+y):y; - y = (y >= (int)(m_height - 1))?(y - m_height):y; + x = ( x < 0 ) ? ( ( m_width - 1 ) + x ) : x; + x = ( x >= (int) ( m_width - 1 ) ) ? ( x - m_width ) : x; + y = ( y < 0 ) ? ( ( m_height - 1 ) + y ) : y; + y = ( y >= (int) ( m_height - 1 ) ) ? ( y - m_height ) : y; break; default: 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; *aXo = x; @@ -110,6 +110,7 @@ bool CIMAGE::wrapCoords( int *aXo, int *aYo ) const return true; } + void CIMAGE::plot8CircleLines( int aCx, int aCy, int aX, int aY, unsigned char aValue ) { Hline( aCx - aX, aCx + aX, aCy + aY, aValue ); @@ -137,10 +138,8 @@ unsigned char CIMAGE::Getpixel( int aX, int aY ) const void CIMAGE::Hline( int aXStart, int aXEnd, int aY, unsigned char aValue ) { - if( ( aY < 0 ) || - ( aY >= (int)m_height ) || - ( ( aXStart < 0 ) && ( aXEnd < 0) ) || - ( ( aXStart >= (int)m_width ) && ( aXEnd >= (int)m_width) ) ) + if( ( aY < 0 ) || ( aY >= (int) m_height ) || ( ( aXStart < 0 ) && ( aXEnd < 0 ) ) + || ( ( aXStart >= (int) m_width ) && ( aXEnd >= (int) m_width ) ) ) return; if( aXStart > aXEnd ) @@ -159,7 +158,7 @@ void CIMAGE::Hline( int aXStart, int aXEnd, int aY, unsigned char aValue ) aXEnd = m_width - 1; unsigned char* pixelPtr = &m_pixels[aXStart + aY * m_width]; - unsigned char* pixelPtrEnd = pixelPtr + (unsigned int)((aXEnd - aXStart) + 1); + unsigned char* pixelPtrEnd = pixelPtr + (unsigned int) ( ( aXEnd - aXStart ) + 1 ); while( pixelPtr < pixelPtrEnd ) { @@ -168,9 +167,10 @@ void CIMAGE::Hline( int aXStart, int aXEnd, int aY, unsigned char aValue ) } } + // Based on paper // http://web.engr.oregonstate.edu/~sllu/bcircle.pdf -void CIMAGE::CircleFilled(int aCx, int aCy, int aRadius, unsigned char aValue) +void CIMAGE::CircleFilled( int aCx, int aCy, int aRadius, unsigned char aValue ) { int x = aRadius; int y = 0; @@ -185,7 +185,7 @@ void CIMAGE::CircleFilled(int aCx, int aCy, int aRadius, unsigned char aValue) radiusError += yChange; yChange += 2; - if( (2 * radiusError + xChange) > 0 ) + if( ( 2 * radiusError + xChange ) > 0 ) { x--; radiusError += xChange; @@ -213,15 +213,15 @@ void CIMAGE::CopyFull( const CIMAGE* aImgA, const CIMAGE* aImgB, IMAGE_OP aOpera } else { - if( (aImgA == NULL) || (aImgB == NULL) ) + if( ( aImgA == NULL ) || ( aImgB == NULL ) ) return; } - switch(aOperation) + switch( aOperation ) { case IMAGE_OP::RAW: memcpy( m_pixels, aImgA->m_pixels, m_wxh ); - break; + break; case IMAGE_OP::ADD: for( unsigned int it = 0;it < m_wxh; it++ ) @@ -234,7 +234,7 @@ void CIMAGE::CopyFull( const CIMAGE* aImgA, const CIMAGE* aImgB, IMAGE_OP aOpera m_pixels[it] = aV; } - break; + break; case IMAGE_OP::SUB: for( unsigned int it = 0;it < m_wxh; it++ ) @@ -247,7 +247,7 @@ void CIMAGE::CopyFull( const CIMAGE* aImgA, const CIMAGE* aImgB, IMAGE_OP aOpera m_pixels[it] = aV; } - break; + break; case IMAGE_OP::DIF: for( unsigned int it = 0;it < m_wxh; it++ ) @@ -257,7 +257,7 @@ void CIMAGE::CopyFull( const CIMAGE* aImgA, const CIMAGE* aImgB, IMAGE_OP aOpera m_pixels[it] = abs( aV - bV ); } - break; + break; case IMAGE_OP::MUL: for( unsigned int it = 0;it < m_wxh; it++ ) @@ -265,30 +265,31 @@ void CIMAGE::CopyFull( const CIMAGE* aImgA, const CIMAGE* aImgB, IMAGE_OP aOpera aV = aImgA->m_pixels[it]; bV = aImgB->m_pixels[it]; - m_pixels[it] = (unsigned char)((((float)aV / 255.0f) * ((float)bV / 255.0f)) * 255); + m_pixels[it] = + (unsigned char) ( ( ( (float) aV / 255.0f ) * ( (float) bV / 255.0f ) ) * 255 ); } - break; + break; case IMAGE_OP::AND: for( unsigned int it = 0;it < m_wxh; it++ ) { m_pixels[it] = aImgA->m_pixels[it] & aImgB->m_pixels[it]; } - break; + break; case IMAGE_OP::OR: for( unsigned int it = 0;it < m_wxh; it++ ) { m_pixels[it] = aImgA->m_pixels[it] | aImgB->m_pixels[it]; } - break; + break; case IMAGE_OP::XOR: for( unsigned int it = 0;it < m_wxh; it++ ) { m_pixels[it] = aImgA->m_pixels[it] ^ aImgB->m_pixels[it]; } - break; + break; case IMAGE_OP::BLEND50: for( unsigned int it = 0;it < m_wxh; it++ ) @@ -298,7 +299,7 @@ void CIMAGE::CopyFull( const CIMAGE* aImgA, const CIMAGE* aImgB, IMAGE_OP aOpera m_pixels[it] = (aV + bV) / 2; } - break; + break; case IMAGE_OP::MIN: for( unsigned int it = 0;it < m_wxh; it++ ) @@ -308,7 +309,7 @@ void CIMAGE::CopyFull( const CIMAGE* aImgA, const CIMAGE* aImgB, IMAGE_OP aOpera m_pixels[it] = (aV < bV)?aV:bV; } - break; + break; case IMAGE_OP::MAX: for( unsigned int it = 0;it < m_wxh; it++ ) @@ -318,13 +319,14 @@ void CIMAGE::CopyFull( const CIMAGE* aImgA, const CIMAGE* aImgB, IMAGE_OP aOpera m_pixels[it] = (aV > bV)?aV:bV; } - break; + break; default: - break; + break; } } + // TIP: If you want create or test filters you can use GIMP // with a generic convolution matrix and get the values from there. // http://docs.gimp.org/nl/plug-in-convmatrix.html @@ -465,10 +467,10 @@ static const S_FILTER FILTERS[] = { // clang-format on -// !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 +/// @todo: This function can be optimized slipping 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, IMAGE_FILTER aFilterType ) { S_FILTER filter = FILTERS[static_cast( aFilterType )]; @@ -486,8 +488,8 @@ void CIMAGE::EfxFilter( CIMAGE* aInImg, IMAGE_FILTER aFilterType ) std::thread t = std::thread( [&]() { for( size_t iy = nextRow.fetch_add( 1 ); - iy < m_height; - iy = nextRow.fetch_add( 1 ) ) + iy < m_height; + iy = nextRow.fetch_add( 1 ) ) { for( size_t ix = 0; ix < m_width; ix++ ) { @@ -508,7 +510,8 @@ void CIMAGE::EfxFilter( CIMAGE* aInImg, IMAGE_FILTER aFilterType ) v /= filter.div; v += filter.offset; CLAMP(v, 0, 255); - //TODO: This needs to write to a separate buffer + + /// @todo This needs to write to a separate buffer. m_pixels[ix + iy * m_width] = v; } } diff --git a/3d-viewer/3d_rendering/cimage.h b/3d-viewer/3d_rendering/cimage.h index 211fe7888c..046f8a0172 100644 --- a/3d-viewer/3d_rendering/cimage.h +++ b/3d-viewer/3d_rendering/cimage.h @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2015-2016 Mario Luzeiro - * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2015-2020 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 @@ -54,7 +54,7 @@ enum class IMAGE_WRAP { ZERO, ///< Coords that wraps are not evaluated CLAMP, ///< Coords are clamped to image size - WRAP ///< Coords are wrapped arround + WRAP ///< Coords are wrapped around }; @@ -75,34 +75,33 @@ enum class IMAGE_FILTER }; /// 5x5 Filter struct parameters -typedef struct { +typedef struct +{ signed char kernel[5][5]; unsigned int div; unsigned char offset; -}S_FILTER; +} S_FILTER; /** - * CIMAGE - * manages a 8-bit channel image + * Manage an 8-bit channel image. */ class CIMAGE { - public: - /** - * Constructor CIMAGE - * constructs a CIMAGE based on image size + * Construct a CIMAGE based on image size. + * * @param aXsize x size * @param aYsize y size */ CIMAGE( unsigned int aXsize, unsigned int aYsize ); /** - * @brief CIMAGE - * constructs a CIMAGE based on an existent image. It will copy the image to - * the new + * Construct a CIMAGE based from an existing image. + * + * It will make a copy the \a aSrcImage. + * * @param aSrcImage */ CIMAGE( const CIMAGE &aSrcImage ); @@ -110,9 +109,9 @@ public: ~CIMAGE(); /** - * Function Setpixel - * set a value in a pixel position, position is clamped in accord with the - * current clamp settings + * Set a value in a pixel position, position is clamped in accordance with the + * current clamp settings. + * * @param aX x position * @param aY y position * @param aValue value to set the pixel @@ -120,9 +119,9 @@ public: 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 + * 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 @@ -130,98 +129,92 @@ public: unsigned char Getpixel( int aX, int aY ) const; /** - * @brief hline - Draws an horizontal line - * @param aXStart - x start position - * @param aXEnd - x end position - * @param aY - y positoin - * @param aValue - value to add + * Draw a horizontal line. + * + * @param aXStart x start position + * @param aXEnd x end position + * @param aY y position + * @param aValue value to add */ void Hline( int aXStart, int aXEnd, int aY, unsigned char aValue ); - /** - * @brief CircleFilled - * @param aCx - * @param aCy - * @param aRadius - * @param aValue - */ void CircleFilled( int aCx, int aCy, int aRadius, unsigned char aValue ); /** - * 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 + * Perform a copy operation based on \a aOperation type. + * + * The available image operations. + * - IMAGE_OP::RAW this <- aImgA + * - IMAGE_OP::ADD this <- CLAMP(aImgA + aImgB) + * - IMAGE_OP::SUB this <- CLAMP(aImgA - aImgB) + * - IMAGE_OP::DIF this <- abs(aImgA - aImgB) + * - IMAGE_OP::MUL this <- aImgA * aImgB + * - IMAGE_OP::AND this <- aImgA & aImgB + * - IMAGE_OP::OR this <- aImgA | aImgB + * - IMAGE_OP::XOR this <- aImgA ^ aImgB + * - IMAGE_OP::BLEND50 this <- (aImgA + aImgB) / 2 + * - IMAGE_OP::MIN this <- (aImgA < aImgB) ? aImgA : aImgB + * - IMAGE_OP::MAX this <- (aImgA > aImgB) ? aImgA : aImgB + * + * @param aImgA an image input. + * @param aImgB an image input. * @param aOperation operation to perform - * IMAGE_OP::RAW this <- aImgA - * IMAGE_OP::ADD this <- CLAMP(aImgA + aImgB) - * IMAGE_OP::SUB this <- CLAMP(aImgA - aImgB) - * IMAGE_OP::DIF this <- abs(aImgA - aImgB) - * IMAGE_OP::MUL this <- aImgA * aImgB - * IMAGE_OP::AND this <- aImgA & aImgB - * IMAGE_OP::OR this <- aImgA | aImgB - * IMAGE_OP::XOR this <- aImgA ^ aImgB - * IMAGE_OP::BLEND50 this <- (aImgA + aImgB) / 2 - * IMAGE_OP::MIN this <- (aImgA < aImgB)?aImgA:aImgB - * IMAGE_OP::MAX this <- (aImgA > aImgB)?aImgA:aImgB */ void CopyFull( const CIMAGE* aImgA, const CIMAGE* aImgB, IMAGE_OP aOperation ); /** - * Function Invert - * invert the values of image this <- (255 - this) + * Invert the values of this image <- (255 - this) */ void Invert(); /** - * Function EfxFilter - * apply a filter to the input image and stores it in the image class - * this <- FilterType(aInImg) + * Apply a filter to the input image and store it in the image class. + * * @param aInImg input image * @param aFilterType filter type to apply */ void EfxFilter( CIMAGE* aInImg, IMAGE_FILTER aFilterType ); /** - * 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) + * Save image buffer to a PNG file into the working folder. + * + * Each RGB channel will have the 8bit-channel from the image. + * + * @param aFileName file name (without extension) */ void SaveAsPNG( const wxString& aFileName ) const; /** - * Function SetPixelsFromNormalizedFloat - * set the current channel from a float normalized (0.0 - 1.0) buffer + * 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 SetPixelsFromNormalizedFloat( const float* aNormalizedFloatArray ); /** - * Function GetBuffer - * get the image buffer pointer - * @return unsigned char * - the pointer of the buffer 8bit channel + * Get the image buffer pointer. + * + * @return unsigned char* the pointer of the buffer 8bit channel. */ unsigned char* GetBuffer() const; unsigned int GetWidth() const { return m_width; } unsigned int GetHeight() const { return m_height; } -private: +private: /** - * Function wrapCoords - * calculate the coordinates points in accord with the current clamping settings - * @param aXo X coordinate to be converted (output) - * @param aXo Y coordinate to be converted (output) - * @return bool - true if the coordinates are inside the image, false otherwise + * Calculate the coordinates points in accord with the current clamping settings. + * + * @param aXo X coordinate to be converted (output). + * @param aXo Y coordinate to be converted (output). + * @return bool - true if the coordinates are inside the image, false otherwise. */ bool wrapCoords( int *aXo, int *aYo ) const; void plot8CircleLines( int aCx, int aCy, int aX, int aY, unsigned char aValue ); -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 diff --git a/3d-viewer/3d_rendering/cpostshader.cpp b/3d-viewer/3d_rendering/cpostshader.cpp index 927047a7f9..12c5dedb2f 100644 --- a/3d-viewer/3d_rendering/cpostshader.cpp +++ b/3d-viewer/3d_rendering/cpostshader.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2015-2016 Mario Luzeiro - * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2015-2020 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 @@ -75,17 +75,13 @@ void CPOSTSHADER::UpdateSize( const SFVEC2UI &aSize ) } -void CPOSTSHADER::SetPixelData( unsigned int x, - unsigned int y, - const SFVEC3F &aNormal, - const SFVEC3F &aColor, - const SFVEC3F &aHitPosition, - float aDepth, - float aShadowAttFactor ) +void CPOSTSHADER::SetPixelData( unsigned int x, unsigned int y, const SFVEC3F &aNormal, + const SFVEC3F &aColor, const SFVEC3F &aHitPosition, + float aDepth, float aShadowAttFactor ) { wxASSERT( x < m_size.x ); wxASSERT( y < m_size.y ); - wxASSERT( (aShadowAttFactor >= 0.0f) && (aShadowAttFactor <= 1.0f) ); + wxASSERT( ( aShadowAttFactor >= 0.0f ) && ( aShadowAttFactor <= 1.0f ) ); const unsigned int idx = x + y * m_size.x; @@ -109,11 +105,16 @@ void CPOSTSHADER::SetPixelData( unsigned int x, void CPOSTSHADER::destroy_buffers() { - delete[] m_normals; m_normals = nullptr; - delete[] m_color; m_color = nullptr; - delete[] m_depth; m_depth = nullptr; - delete[] m_shadow_att_factor; m_shadow_att_factor = nullptr; - delete[] m_wc_hitposition; m_wc_hitposition = nullptr; + delete[] m_normals; + m_normals = nullptr; + delete[] m_color; + m_color = nullptr; + delete[] m_depth; + m_depth = nullptr; + delete[] m_shadow_att_factor; + m_shadow_att_factor = nullptr; + delete[] m_wc_hitposition; + m_wc_hitposition = nullptr; } @@ -195,7 +196,6 @@ void CPOSTSHADER::DebugBuffersOutputAsImages() const DBG_SaveNormalsBuffer( "m_normals", m_normals, m_size.x, m_size.y ); // Normalize depth - // ///////////////////////////////////////////////////////////////////////// float *normalizedDepth = (float*) malloc( m_size.x * m_size.y * sizeof( float ) ); float *normalizedDepthPTr = normalizedDepth; diff --git a/3d-viewer/3d_rendering/cpostshader.h b/3d-viewer/3d_rendering/cpostshader.h index abeeee2b9f..e0ac819fe6 100644 --- a/3d-viewer/3d_rendering/cpostshader.h +++ b/3d-viewer/3d_rendering/cpostshader.h @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2015-2016 Mario Luzeiro - * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2015-2020 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 @@ -41,11 +41,13 @@ public: virtual SFVEC3F Shade( const SFVEC2I &aShaderPos ) const = 0; /** - * @brief ApplyShadeColor - apply the final color process using a previous stage color - * @param aShadeColor - The result of the shader + * Apply the final color process using a previous stage color. + * + * @param aShadeColor The result of the shader. * @return the result of the shade process */ - virtual SFVEC3F ApplyShadeColor( const SFVEC2I &aShaderPos, const SFVEC3F &aInputColor, const SFVEC3F &aShadeColor ) const = 0; + virtual SFVEC3F ApplyShadeColor( const SFVEC2I &aShaderPos, const SFVEC3F &aInputColor, + const SFVEC3F &aShadeColor ) const = 0; void UpdateSize( const SFVEC2UI &aSize ); @@ -53,37 +55,14 @@ public: void InitFrame() { m_tmin = FLT_MAX; m_tmax = 0.0f; } - void SetPixelData( unsigned int x, - unsigned int y, - const SFVEC3F &aNormal, - const SFVEC3F &aColor, - const SFVEC3F &aHitPosition, - float aDepth, - float aShadowAttFactor ); + void SetPixelData( unsigned int x, unsigned int y, const SFVEC3F &aNormal, + const SFVEC3F &aColor, const SFVEC3F &aHitPosition, + float aDepth, float aShadowAttFactor ); const SFVEC3F &GetColorAtNotProtected( const SFVEC2I &aPos ) const; void DebugBuffersOutputAsImages() const; -protected: - const SFVEC3F &GetNormalAt( const SFVEC2F &aPos ) const; - const SFVEC3F &GetColorAt( const SFVEC2F &aPos ) const; - const SFVEC3F &GetPositionAt( const SFVEC2F &aPos ) const; - float GetDepthAt( const SFVEC2F &aPos ) const; - - const SFVEC3F &GetNormalAt( const SFVEC2I &aPos ) const; - const SFVEC3F &GetColorAt( const SFVEC2I &aPos ) const; - const SFVEC3F &GetPositionAt( const SFVEC2I &aPos ) const; - const float &GetShadowFactorAt( const SFVEC2I &aPos ) const; - - float GetDepthAt( const SFVEC2I &aPos ) const; - float GetDepthNormalizedAt( const SFVEC2I &aPos ) const; - float GetMaxDepth() const { return m_tmax; } - -private: - void destroy_buffers(); - -public: inline unsigned int GetIndex( const SFVEC2F& aPos ) const { SFVEC2F clampPos; @@ -107,6 +86,24 @@ public: return (unsigned int)( clampPos.x + m_size.x * clampPos.y ); } +protected: + const SFVEC3F &GetNormalAt( const SFVEC2F &aPos ) const; + const SFVEC3F &GetColorAt( const SFVEC2F &aPos ) const; + const SFVEC3F &GetPositionAt( const SFVEC2F &aPos ) const; + float GetDepthAt( const SFVEC2F &aPos ) const; + + const SFVEC3F &GetNormalAt( const SFVEC2I &aPos ) const; + const SFVEC3F &GetColorAt( const SFVEC2I &aPos ) const; + const SFVEC3F &GetPositionAt( const SFVEC2I &aPos ) const; + const float &GetShadowFactorAt( const SFVEC2I &aPos ) const; + + float GetDepthAt( const SFVEC2I &aPos ) const; + float GetDepthNormalizedAt( const SFVEC2I &aPos ) const; + float GetMaxDepth() const { return m_tmax; } + +private: + void destroy_buffers(); + protected: const CCAMERA &m_camera; diff --git a/3d-viewer/3d_rendering/cpostshader_ssao.cpp b/3d-viewer/3d_rendering/cpostshader_ssao.cpp index c0cea6cf6c..d5f5149f2e 100644 --- a/3d-viewer/3d_rendering/cpostshader_ssao.cpp +++ b/3d-viewer/3d_rendering/cpostshader_ssao.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2015-2016 Mario Luzeiro - * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2015-2020 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 @@ -38,19 +38,15 @@ CPOSTSHADER_SSAO::CPOSTSHADER_SSAO( const CCAMERA &aCamera ) : { } -// There are differente sources for this shader on the web +// There are different sources for this shader on the web //https://github.com/scanberg/hbao/blob/master/resources/shaders/ssao_frag.glsl //http://www.gamedev.net/topic/556187-the-best-ssao-ive-seen/ //http://www.gamedev.net/topic/556187-the-best-ssao-ive-seen/?view=findpost&p=4632208 -float CPOSTSHADER_SSAO::aoFF( const SFVEC2I &aShaderPos, - const SFVEC3F &ddiff, - const SFVEC3F &cnorm, - const float aShadowAtSamplePos, - const float aShadowAtCenterPos, - int c1, - int c2 ) const +float CPOSTSHADER_SSAO::aoFF( const SFVEC2I &aShaderPos, const SFVEC3F &ddiff, + const SFVEC3F &cnorm, const float aShadowAtSamplePos, + const float aShadowAtCenterPos, int c1, int c2 ) const { const float shadowGain = 0.60f; const float aoGain = 1.0f; @@ -81,27 +77,28 @@ float CPOSTSHADER_SSAO::aoFF( const SFVEC2I &aShaderPos, float sampledNormalFactor = glm::max( glm::dot( GetNormalAt( vr ), cnorm ), 0.0f ); - sampledNormalFactor = glm::max( 1.0f - sampledNormalFactor * sampledNormalFactor, 0.0f ); + sampledNormalFactor = glm::max( 1.0f - sampledNormalFactor * + sampledNormalFactor, 0.0f ); const float shadowAttDistFactor = glm::max( glm::min( rd * 5.0f - 0.25f, 1.0f ), 0.0f ); float shadowAttFactor = glm::min( sampledNormalFactor + shadowAttDistFactor, 1.0f ); - const float shadowFactor = glm::mix( shadow_factor_at_sample, - shadow_factor_at_center, + const float shadowFactor = glm::mix( shadow_factor_at_sample, shadow_factor_at_center, shadowAttFactor ); // This is a dot product threshold factor. - // it defines after wich angle we consider that the point starts to occlude. + // it defines after which angle we consider that the point starts to occlude. // if the value is high, it will discard low angles point const float aDotThreshold = 0.15f; - // This is the dot product between the center pixel normal (the one that is being shaded) - // and the vector from the center to the sampled point + // This is the dot product between the center pixel normal (the one that is being + // shaded) and the vector from the center to the sampled point const float localNormalFactor = glm::dot( cnorm, vv ); - const float localNormalFactorWithThreshold = (glm::max( localNormalFactor, aDotThreshold ) - aDotThreshold) / - (1.0f - aDotThreshold); + const float localNormalFactorWithThreshold = + ( glm::max( localNormalFactor, aDotThreshold ) - aDotThreshold) / + ( 1.0f - aDotThreshold ); const float aoFactor = localNormalFactorWithThreshold * aoGain * attDistFactor; @@ -113,16 +110,10 @@ float CPOSTSHADER_SSAO::aoFF( const SFVEC2I &aShaderPos, } -float CPOSTSHADER_SSAO::giFF( const SFVEC2I &aShaderPos, - const SFVEC3F &ddiff, - const SFVEC3F &cnorm, - const float aShadow, - int c1, - int c2 ) const +float CPOSTSHADER_SSAO::giFF( const SFVEC2I &aShaderPos, const SFVEC3F &ddiff, + const SFVEC3F &cnorm, const float aShadow, int c1, int c2 ) const { - if( (ddiff.x > FLT_EPSILON) || - (ddiff.y > FLT_EPSILON) || - (ddiff.z > FLT_EPSILON) ) + if( ( ddiff.x > FLT_EPSILON ) || ( ddiff.y > FLT_EPSILON ) || ( ddiff.z > FLT_EPSILON ) ) { const SFVEC3F vv = glm::normalize( ddiff ); const float rd = glm::length( ddiff ); @@ -131,7 +122,8 @@ float CPOSTSHADER_SSAO::giFF( const SFVEC2I &aShaderPos, const float attDistFactor = 1.0f / ( rd * rd + 1.0f ); return ( glm::clamp( glm::dot( GetNormalAt( vr ), -vv), 0.0f, 1.0f ) * - glm::clamp( glm::dot( cnorm, vv ), 0.0f, 1.0f ) * attDistFactor ) * ( 0.03f + aShadow ) * 3.0f; + glm::clamp( glm::dot( cnorm, vv ), 0.0f, 1.0f ) * attDistFactor ) * + ( 0.03f + aShadow ) * 3.0f; } return 0.0f; @@ -146,7 +138,7 @@ SFVEC3F CPOSTSHADER_SSAO::Shade( const SFVEC2I &aShaderPos ) const { cdepth = ( 30.0f / ( cdepth * 2.0f + 1.0f ) ); - // read current normal,position and color. + // read current normal, position and color. const SFVEC3F n = GetNormalAt( aShaderPos ); const SFVEC3F p = GetPositionAt( aShaderPos ); @@ -229,17 +221,19 @@ SFVEC3F CPOSTSHADER_SSAO::Shade( const SFVEC2I &aShaderPos ) const return glm::mix( SFVEC3F( ao ), -gi, giL ); } else - return SFVEC3F(0.0f); + { + return SFVEC3F( 0.0f ); + } } -SFVEC3F CPOSTSHADER_SSAO::ApplyShadeColor( const SFVEC2I &aShaderPos, const SFVEC3F &aInputColor, const SFVEC3F &aShadeColor ) const +SFVEC3F CPOSTSHADER_SSAO::ApplyShadeColor( const SFVEC2I &aShaderPos, const SFVEC3F &aInputColor, + const SFVEC3F &aShadeColor ) const { SFVEC3F outColor; const SFVEC3F subtracted = aInputColor - aShadeColor; - const SFVEC3F mixed = glm::mix( aInputColor, - aInputColor * 0.50f - aShadeColor * 0.05f, + const SFVEC3F mixed = glm::mix( aInputColor, aInputColor * 0.50f - aShadeColor * 0.05f, glm::min( aShadeColor, 1.0f ) ); outColor.r = ( aShadeColor.r < 0.0f ) ? subtracted.r : mixed.r; @@ -252,15 +246,16 @@ SFVEC3F CPOSTSHADER_SSAO::ApplyShadeColor( const SFVEC2I &aShaderPos, const SFVE SFVEC3F CPOSTSHADER_SSAO::giColorCurve( const SFVEC3F &aColor ) const { - const SFVEC3F vec1 = SFVEC3F(1.0f); + const SFVEC3F vec1 = SFVEC3F( 1.0f ); - // This option actually apply a gama since we are using linear color space + // This option actually apply a gamma since we are using linear color space // and the result shader will be applied after convert back to sRGB // http://fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIxLjAtKDEuMC8oeCo5LjArMS4wKSkreCowLjEiLCJjb2xvciI6IiMwMDAwMDAifSx7InR5cGUiOjEwMDAsIndpbmRvdyI6WyItMC4wNjIxODQ2MTUzODQ2MTU1MDUiLCIxLjE0Mjk4NDYxNTM4NDYxNDYiLCItMC4xMjcwOTk5OTk5OTk5OTk3NyIsIjEuMTMyNiJdfV0- return vec1 - ( vec1 / (aColor * SFVEC3F(9.0f) + vec1) ) + aColor * SFVEC3F(0.10f); } + SFVEC3F CPOSTSHADER_SSAO::Blur( const SFVEC2I& aShaderPos ) const { const float dCenter = GetDepthAt( aShaderPos ); @@ -283,8 +278,8 @@ SFVEC3F CPOSTSHADER_SSAO::Blur( const SFVEC2I& aShaderPos ) const const float d = GetDepthAt( SFVEC2I( aShaderPos.x + x, aShaderPos.y + y ) ); - const float depthAtt = ( dCenter - d ) * dCenter - * 25.0f; // increse the value will get more sharpness effect + // Increasing the value will get more sharpness effect. + const float depthAtt = ( dCenter - d ) * dCenter * 25.0f; const float depthAttSqr = depthAtt * depthAtt; diff --git a/3d-viewer/3d_rendering/cpostshader_ssao.h b/3d-viewer/3d_rendering/cpostshader_ssao.h index 4f03dc573e..010a96d52f 100644 --- a/3d-viewer/3d_rendering/cpostshader_ssao.h +++ b/3d-viewer/3d_rendering/cpostshader_ssao.h @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2015-2016 Mario Luzeiro - * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2015-2020 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 @@ -34,15 +34,14 @@ #include "cpostshader.h" -class CPOSTSHADER_SSAO : public CPOSTSHADER +class CPOSTSHADER_SSAO : public CPOSTSHADER { public: explicit CPOSTSHADER_SSAO( const CCAMERA &aCamera ); - //~CPOSTSHADER_SSAO(); - // Imported from CPOSTSHADER SFVEC3F Shade(const SFVEC2I &aShaderPos ) const override; - SFVEC3F ApplyShadeColor( const SFVEC2I &aShaderPos, const SFVEC3F &aInputColor, const SFVEC3F &aShadeColor ) const override; + SFVEC3F ApplyShadeColor( const SFVEC2I &aShaderPos, const SFVEC3F &aInputColor, + const SFVEC3F &aShadeColor ) const override; SFVEC3F Blur( const SFVEC2I& aShaderPos ) const; @@ -57,31 +56,25 @@ public: } private: - SFVEC3F posFromDepth( const SFVEC2F &coord ) const; + SFVEC3F posFromDepth( const SFVEC2F& coord ) const; - float ec_depth( const SFVEC2F &tc ) const; + float ec_depth( const SFVEC2F& tc ) const; - float aoFF( const SFVEC2I &aShaderPos, - const SFVEC3F &ddiff, - const SFVEC3F &cnorm, - const float aShadowAtSamplePos, - const float aShadowAtCenterPos, - int c1, - int c2 ) const; + float aoFF( const SFVEC2I& aShaderPos, const SFVEC3F& ddiff, const SFVEC3F& cnorm, + const float aShadowAtSamplePos, const float aShadowAtCenterPos, + int c1, int c2 ) const; - float giFF( const SFVEC2I &aShaderPos, - const SFVEC3F &ddiff, - const SFVEC3F &cnorm, - const float aShadow, - int c1, - int c2 ) const; + float giFF( const SFVEC2I& aShaderPos, const SFVEC3F& ddiff, const SFVEC3F& cnorm, + const float aShadow, int c1, int c2 ) const; /** - * @brief giColorCurve - Apply a curve transformation to the original color - * it will atenuate the bright colors (works as a gamma function): + * Apply a curve transformation to the original color. + * + * It will attenuate the bright colors (works as a gamma function): * http://fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIxLjAtKDEvKHgqMS4wKzEuMCkpK3gqMC4zMCIsImNvbG9yIjoiIzAwMDAwMCJ9LHsidHlwZSI6MTAwMCwid2luZG93IjpbIi0wLjA2MjE4NDYxNTM4NDYxNTUwNSIsIjEuMTQyOTg0NjE1Mzg0NjE0NiIsIi0wLjEyNzA5OTk5OTk5OTk5OTc3IiwiMS4xMzI2Il19XQ-- - * @param aColor input color - * @return transformated color + * + * @param aColor input color. + * @return transformed color. */ SFVEC3F giColorCurve( const SFVEC3F &aColor ) const; diff --git a/3d-viewer/3d_rendering/ctrack_ball.cpp b/3d-viewer/3d_rendering/ctrack_ball.cpp index ebc39d8984..0ae7710d0e 100644 --- a/3d-viewer/3d_rendering/ctrack_ball.cpp +++ b/3d-viewer/3d_rendering/ctrack_ball.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2015-2016 Mario Luzeiro - * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2015-2020 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 @@ -48,7 +48,7 @@ CTRACK_BALL::CTRACK_BALL( float aRangeScale ) : CCAMERA( aRangeScale ) } -void CTRACK_BALL::Drag( const wxPoint &aNewMousePosition ) +void CTRACK_BALL::Drag( const wxPoint& aNewMousePosition ) { m_parametersChanged = true; @@ -58,11 +58,10 @@ void CTRACK_BALL::Drag( const wxPoint &aNewMousePosition ) // the mouse, scaled so they are from (-1.0 ... 1.0)." const float zoom = 1.0f; - trackball( spin_quat, - zoom * (2.0 * m_lastPosition.x - m_windowSize.x) / m_windowSize.x, - zoom * (m_windowSize.y - 2.0 * m_lastPosition.y) / m_windowSize.y, - zoom * (2.0 * aNewMousePosition.x - m_windowSize.x) / m_windowSize.x, - zoom * ( m_windowSize.y - 2.0 * aNewMousePosition.y ) / m_windowSize.y); + trackball( spin_quat, zoom * ( 2.0 * m_lastPosition.x - m_windowSize.x ) / m_windowSize.x, + zoom * ( m_windowSize.y - 2.0 * m_lastPosition.y ) / m_windowSize.y, + zoom * ( 2.0 * aNewMousePosition.x - m_windowSize.x ) / m_windowSize.x, + zoom * ( m_windowSize.y - 2.0 * aNewMousePosition.y ) / m_windowSize.y ); add_quats( spin_quat, m_quat, m_quat ); @@ -78,7 +77,7 @@ void CTRACK_BALL::Drag( const wxPoint &aNewMousePosition ) } -void CTRACK_BALL::SetLookAtPos( const SFVEC3F &aLookAtPos ) +void CTRACK_BALL::SetLookAtPos( const SFVEC3F& aLookAtPos ) { if( m_lookat_pos != aLookAtPos ) { @@ -92,13 +91,13 @@ void CTRACK_BALL::SetLookAtPos( const SFVEC3F &aLookAtPos ) } -void CTRACK_BALL::Pan( const wxPoint &aNewMousePosition ) +void CTRACK_BALL::Pan( const wxPoint& aNewMousePosition ) { m_parametersChanged = true; if( m_projectionType == PROJECTION_TYPE::ORTHO ) { - // With the ortographic projection, there is just a zoom factor + // With the orthographic projection, there is just a zoom factor const float panFactor = m_zoom / 37.5f; // Magic number from CCAMERA::rebuildProjection m_camera_pos.x -= panFactor * ( m_lastPosition.x - aNewMousePosition.x ); m_camera_pos.y -= panFactor * ( aNewMousePosition.y - m_lastPosition.y ); @@ -107,7 +106,8 @@ void CTRACK_BALL::Pan( const wxPoint &aNewMousePosition ) { // Unproject the coordinates using the precomputed frustum tangent (zoom level dependent) const float panFactor = -m_camera_pos.z * m_frustum.tang * 2; - m_camera_pos.x -= panFactor * m_frustum.ratio * ( m_lastPosition.x - aNewMousePosition.x ) / m_windowSize.x; + m_camera_pos.x -= panFactor * m_frustum.ratio * + ( m_lastPosition.x - aNewMousePosition.x ) / m_windowSize.x; m_camera_pos.y -= panFactor * ( aNewMousePosition.y - m_lastPosition.y ) / m_windowSize.y; } @@ -116,7 +116,7 @@ void CTRACK_BALL::Pan( const wxPoint &aNewMousePosition ) } -void CTRACK_BALL::Pan( const SFVEC3F &aDeltaOffsetInc ) +void CTRACK_BALL::Pan( const SFVEC3F& aDeltaOffsetInc ) { m_parametersChanged = true; @@ -127,7 +127,7 @@ void CTRACK_BALL::Pan( const SFVEC3F &aDeltaOffsetInc ) } -void CTRACK_BALL::Pan_T1( const SFVEC3F &aDeltaOffsetInc ) +void CTRACK_BALL::Pan_T1( const SFVEC3F& aDeltaOffsetInc ) { m_camera_pos_t1 = m_camera_pos + aDeltaOffsetInc; } @@ -165,7 +165,7 @@ void CTRACK_BALL::Interpolate( float t ) wxASSERT( t >= 0.0f ); // Limit t o 1.0 - t = (t > 1.0f)?1.0f:t; + t = ( t > 1.0f ) ? 1.0f : t; switch( m_interpolation_mode ) { diff --git a/3d-viewer/3d_rendering/ctrack_ball.h b/3d-viewer/3d_rendering/ctrack_ball.h index 059b7d08aa..b0baff2375 100644 --- a/3d-viewer/3d_rendering/ctrack_ball.h +++ b/3d-viewer/3d_rendering/ctrack_ball.h @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2015-2016 Mario Luzeiro - * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2015-2020 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 @@ -35,24 +35,22 @@ class CTRACK_BALL : public CCAMERA { - - public: - +public: explicit CTRACK_BALL( float aRangeScale ); virtual ~CTRACK_BALL() { } - void Drag( const wxPoint &aNewMousePosition ) override; + void Drag( const wxPoint& aNewMousePosition ) override; - void Pan( const wxPoint &aNewMousePosition ) override; + void Pan( const wxPoint& aNewMousePosition ) override; - void Pan( const SFVEC3F &aDeltaOffsetInc ) override; + void Pan( const SFVEC3F& aDeltaOffsetInc ) override; - void Pan_T1( const SFVEC3F &aDeltaOffsetInc ) override; + void Pan_T1( const SFVEC3F& aDeltaOffsetInc ) override; - void SetLookAtPos( const SFVEC3F &aLookAtPos ) override; + void SetLookAtPos( const SFVEC3F& aLookAtPos ) override; void Reset() override; @@ -62,8 +60,7 @@ class CTRACK_BALL : public CCAMERA void Interpolate( float t ) override; - private: - +private: /** * quarternion of the trackball */ diff --git a/3d-viewer/3d_rendering/test_cases.cpp b/3d-viewer/3d_rendering/test_cases.cpp index f545ba13b8..b3d56aa8df 100644 --- a/3d-viewer/3d_rendering/test_cases.cpp +++ b/3d-viewer/3d_rendering/test_cases.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2015-2016 Mario Luzeiro - * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2015-2020 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 @@ -28,13 +28,13 @@ * @brief it run only once and only in debug build */ -#include -#include "3d_render_raytracing/shapes3D/cbbox.h" +#include "3d_render_raytracing/cfrustum.h" #include "3d_render_raytracing/shapes2D/cbbox2d.h" #include "3d_render_raytracing/shapes2D/cfilledcircle2d.h" -#include "3d_render_raytracing/shapes2D/croundsegment2d.h" #include "3d_render_raytracing/shapes2D/cpolygon2d.h" -#include "3d_render_raytracing/cfrustum.h" +#include "3d_render_raytracing/shapes2D/croundsegment2d.h" +#include "3d_render_raytracing/shapes3D/cbbox.h" +#include //#ifdef DEBUG #if 0 @@ -42,13 +42,12 @@ static bool s_Run_Test_Cases = true; void Run_3d_viewer_test_cases() { - if( s_Run_Test_Cases == false) + if( s_Run_Test_Cases == false ) return; s_Run_Test_Cases = true; // Test CBBOX2D - // ///////////////////////////////////////////////////////////////////////// CBBOX2D bbox2d_A; CBBOX2D bbox2d_B; @@ -66,7 +65,7 @@ void Run_3d_viewer_test_cases() wxASSERT( bbox2d_A.MaxDimension() == 0 ); wxASSERT( bbox2d_A.Perimeter() == 0.0f ); */ - bbox2d_A.Set( SFVEC2F(1.0f, -1.0f), SFVEC2F(-1.0f, 1.0f) ); + bbox2d_A.Set( SFVEC2F( 1.0f, -1.0f ), SFVEC2F( -1.0f, 1.0f ) ); wxASSERT( bbox2d_A.IsInitialized() == true ); wxASSERT( bbox2d_A.Area() == 4.0f ); @@ -120,24 +119,21 @@ void Run_3d_viewer_test_cases() wxASSERT( bbox2d_A.MaxDimension() == 0 ); wxASSERT( bbox2d_A.Perimeter() == 20.0f ); - bbox2d_A.Set( SFVEC2F(-1.0f, -1.0f), SFVEC2F(1.0f, 1.0f) ); - bbox2d_B.Set( SFVEC2F(-2.0f, -2.0f), SFVEC2F(2.0f, 2.0f) ); - wxASSERT( bbox2d_A.Intersects( bbox2d_B ) == true ); - wxASSERT( bbox2d_B.Intersects( bbox2d_A ) == true ); + bbox2d_A.Set( SFVEC2F( -1.0f, -1.0f ), SFVEC2F( 1.0f, 1.0f ) ); + bbox2d_B.Set( SFVEC2F( -2.0f, -2.0f ), SFVEC2F( 2.0f, 2.0f ) ); + wxASSERT( bbox2d_A.Intersects( bbox2d_B ) == true ); + wxASSERT( bbox2d_B.Intersects( bbox2d_A ) == true ); - bbox2d_B.Set( SFVEC2F( 1.0f, 1.0f), SFVEC2F(1.0f, 1.0f) ); - wxASSERT( bbox2d_A.Intersects( bbox2d_B ) == true ); + bbox2d_B.Set( SFVEC2F( 1.0f, 1.0f ), SFVEC2F( 1.0f, 1.0f ) ); + wxASSERT( bbox2d_A.Intersects( bbox2d_B ) == true ); - bbox2d_B.Set( SFVEC2F( 1.1f, 1.1f), SFVEC2F(2.0f, 2.0f) ); + bbox2d_B.Set( SFVEC2F( 1.1f, 1.1f ), SFVEC2F( 2.0f, 2.0f ) ); wxASSERT( bbox2d_A.Intersects( bbox2d_B ) == false ); - bbox2d_B.Set( SFVEC2F(-0.5f, -0.5f), SFVEC2F(0.5f, 0.5f) ); - wxASSERT( bbox2d_A.Intersects( bbox2d_B ) == true ); - + bbox2d_B.Set( SFVEC2F(-0.5f, -0.5f ), SFVEC2F( 0.5f, 0.5f ) ); + wxASSERT( bbox2d_A.Intersects( bbox2d_B ) == true ); // Test CFILLEDCIRCLE2D - // ///////////////////////////////////////////////////////////////////////// - CFILLEDCIRCLE2D filledCircle2d( SFVEC2F( 2.0f, 2.0f ), 1.0f ); wxASSERT( filledCircle2d.IsPointInside( SFVEC2F( 2.0f, 2.0f ) ) == true ); @@ -151,39 +147,37 @@ void Run_3d_viewer_test_cases() wxASSERT( filledCircle2d.IsPointInside( SFVEC2F( 2.6f, 2.6f ) ) == true ); wxASSERT( filledCircle2d.IsPointInside( SFVEC2F( 1.2f, 1.2f ) ) == false ); - bbox2d_B.Set( SFVEC2F( 0.0f, 0.0f), SFVEC2F( 4.0f, 4.0f) ); + bbox2d_B.Set( SFVEC2F( 0.0f, 0.0f ), SFVEC2F( 4.0f, 4.0f ) ); wxASSERT( filledCircle2d.Intersects( bbox2d_B ) == true ); - bbox2d_B.Set( SFVEC2F( 1.5f, 1.5f), SFVEC2F( 2.5f, 2.5f) ); + bbox2d_B.Set( SFVEC2F( 1.5f, 1.5f ), SFVEC2F( 2.5f, 2.5f ) ); wxASSERT( filledCircle2d.Intersects( bbox2d_B ) == true ); // A box that does not intersect the sphere but still intersect the bbox of the sphere - bbox2d_B.Set( SFVEC2F( 0.0f, 0.0f), SFVEC2F( 1.2f, 1.2f) ); + bbox2d_B.Set( SFVEC2F( 0.0f, 0.0f ), SFVEC2F( 1.2f, 1.2f ) ); wxASSERT( filledCircle2d.Intersects( bbox2d_B ) == false ); - bbox2d_B.Set( SFVEC2F(-1.0f, -1.0f), SFVEC2F( 0.5f, 0.5f) ); + bbox2d_B.Set( SFVEC2F(-1.0f, -1.0f ), SFVEC2F( 0.5f, 0.5f ) ); wxASSERT( filledCircle2d.Intersects( bbox2d_B ) == false ); - bbox2d_B.Set( SFVEC2F( 0.0f, 0.0f), SFVEC2F( 2.0f, 2.0f) ); + bbox2d_B.Set( SFVEC2F( 0.0f, 0.0f ), SFVEC2F( 2.0f, 2.0f ) ); wxASSERT( filledCircle2d.Intersects( bbox2d_B ) == true ); - bbox2d_B.Set( SFVEC2F( 0.0f, 0.0f), SFVEC2F( 2.0f, 4.0f) ); + bbox2d_B.Set( SFVEC2F( 0.0f, 0.0f ), SFVEC2F( 2.0f, 4.0f ) ); wxASSERT( filledCircle2d.Intersects( bbox2d_B ) == true ); - bbox2d_B.Set( SFVEC2F( 2.0f, 0.0f), SFVEC2F( 4.0f, 4.0f) ); + bbox2d_B.Set( SFVEC2F( 2.0f, 0.0f ), SFVEC2F( 4.0f, 4.0f ) ); wxASSERT( filledCircle2d.Intersects( bbox2d_B ) == true ); - bbox2d_B.Set( SFVEC2F( 0.0f, 2.0f), SFVEC2F( 4.0f, 4.0f) ); + bbox2d_B.Set( SFVEC2F( 0.0f, 2.0f ), SFVEC2F( 4.0f, 4.0f ) ); wxASSERT( filledCircle2d.Intersects( bbox2d_B ) == true ); - bbox2d_B.Set( SFVEC2F( 0.0f, 0.0f), SFVEC2F( 4.0f, 2.0f) ); + bbox2d_B.Set( SFVEC2F( 0.0f, 0.0f ), SFVEC2F( 4.0f, 2.0f ) ); wxASSERT( filledCircle2d.Intersects( bbox2d_B ) == true ); // Test CROUNDSEGMENT2D - // ///////////////////////////////////////////////////////////////////////// - - CROUNDSEGMENT2D roundSegment2d( SFVEC2F(-1.0f, 0.0f), SFVEC2F( 1.0f, 0.0f), 2.0f); + CROUNDSEGMENT2D roundSegment2d( SFVEC2F( -1.0f, 0.0f ), SFVEC2F( 1.0f, 0.0f ), 2.0f ); wxASSERT( roundSegment2d.IsPointInside( SFVEC2F( 0.0f, 0.0f ) ) == true ); wxASSERT( roundSegment2d.IsPointInside( SFVEC2F( 1.0f, 0.0f ) ) == true ); @@ -200,52 +194,50 @@ void Run_3d_viewer_test_cases() wxASSERT( roundSegment2d.IsPointInside( SFVEC2F( 1.8f, 0.8f ) ) == false ); wxASSERT( roundSegment2d.IsPointInside( SFVEC2F( 1.8f,-0.8f ) ) == false ); - wxASSERT( roundSegment2d.IsPointInside( SFVEC2F(-1.8f, 0.8f ) ) == false ); - wxASSERT( roundSegment2d.IsPointInside( SFVEC2F(-1.8f,-0.8f ) ) == false ); + wxASSERT( roundSegment2d.IsPointInside( SFVEC2F( -1.8f, 0.8f ) ) == false ); + wxASSERT( roundSegment2d.IsPointInside( SFVEC2F( -1.8f,-0.8f ) ) == false ); wxASSERT( roundSegment2d.IsPointInside( SFVEC2F( 1.6f, 0.6f ) ) == true ); wxASSERT( roundSegment2d.IsPointInside( SFVEC2F( 1.6f,-0.6f ) ) == true ); - wxASSERT( roundSegment2d.IsPointInside( SFVEC2F(-1.6f, 0.6f ) ) == true ); - wxASSERT( roundSegment2d.IsPointInside( SFVEC2F(-1.6f,-0.6f ) ) == true ); + wxASSERT( roundSegment2d.IsPointInside( SFVEC2F( -1.6f, 0.6f ) ) == true ); + wxASSERT( roundSegment2d.IsPointInside( SFVEC2F( -1.6f,-0.6f ) ) == true ); bbox2d_A.Set( SFVEC2F(-2.0f,-1.0f), SFVEC2F( 2.0f, 1.0f) ); wxASSERT( roundSegment2d.Intersects( bbox2d_A ) == true ); - bbox2d_A.Set( SFVEC2F(-2.1f,-1.1f), SFVEC2F( 2.1f, 1.1f) ); + bbox2d_A.Set( SFVEC2F(-2.1f,-1.1f ), SFVEC2F( 2.1f, 1.1f ) ); wxASSERT( roundSegment2d.Intersects( bbox2d_A ) == true ); - bbox2d_A.Set( SFVEC2F(-1.9f,-0.9f), SFVEC2F( 1.9f, 0.9f) ); + bbox2d_A.Set( SFVEC2F( -1.9f,-0.9f ), SFVEC2F( 1.9f, 0.9f ) ); wxASSERT( roundSegment2d.Intersects( bbox2d_A ) == true ); - bbox2d_A.Set( SFVEC2F(-1.0f,-1.0f), SFVEC2F( 1.0f, 1.0f) ); + bbox2d_A.Set( SFVEC2F( -1.0f,-1.0f ), SFVEC2F( 1.0f, 1.0f ) ); wxASSERT( roundSegment2d.Intersects( bbox2d_A ) == true ); - bbox2d_A.Set( SFVEC2F(-1.0f,-0.5f), SFVEC2F( 1.0f, 0.5f) ); + bbox2d_A.Set( SFVEC2F( -1.0f,-0.5f ), SFVEC2F( 1.0f, 0.5f ) ); wxASSERT( roundSegment2d.Intersects( bbox2d_A ) == true ); - bbox2d_A.Set( SFVEC2F(-4.0f,-0.5f), SFVEC2F(-3.0f, 0.5f) ); + bbox2d_A.Set( SFVEC2F( -4.0f,-0.5f ), SFVEC2F( -3.0f, 0.5f ) ); wxASSERT( roundSegment2d.Intersects( bbox2d_A ) == false ); - bbox2d_A.Set( SFVEC2F( 1.8f, 0.8f), SFVEC2F( 2.0f, 1.0f) ); + bbox2d_A.Set( SFVEC2F( 1.8f, 0.8f ), SFVEC2F( 2.0f, 1.0f ) ); wxASSERT( roundSegment2d.Intersects( bbox2d_A ) == false ); - bbox2d_A.Set( SFVEC2F(-2.0f, 0.8f), SFVEC2F(-1.8f, 1.0f) ); + bbox2d_A.Set( SFVEC2F( -2.0f, 0.8f ), SFVEC2F( -1.8f, 1.0f ) ); wxASSERT( roundSegment2d.Intersects( bbox2d_A ) == false ); - bbox2d_A.Set( SFVEC2F(-2.0f,-1.0f), SFVEC2F(-1.8f,-0.8f) ); + bbox2d_A.Set( SFVEC2F( -2.0f, -1.0f ), SFVEC2F( -1.8f, -0.8f ) ); wxASSERT( roundSegment2d.Intersects( bbox2d_A ) == false ); // Test CPOLYGON2D - // ///////////////////////////////////////////////////////////////////////// Polygon2d_TestModule(); #if 0 // Test Frustum - // ///////////////////////////////////////////////////////////////////////// { CFRUSTUM frustum; - SFVEC3F ori = SFVEC3F(0.0, 0.0, 0.0); + SFVEC3F ori = SFVEC3F( 0.0, 0.0, 0.0 ); float z = 10.0; /* @@ -296,40 +288,38 @@ void Run_3d_viewer_test_cases() const RAY bottomLeft( ori, glm::normalize( ori - SFVEC3F(+1.0,-1.0, z) ) ); const RAY bottomRight( ori, glm::normalize( ori - SFVEC3F(-1.0,-1.0, z) ) ); - - frustum.GenerateFrustum( topLeft, topRight, bottomLeft, bottomRight ); CBBOX bbox3d; - bbox3d.Set( SFVEC3F(-1.0f, -1.0f, z), SFVEC3F(+1.0f,+1.0f, z + 1.0f) ); + bbox3d.Set( SFVEC3F( -1.0f, -1.0f, z ), SFVEC3F( +1.0f, +1.0f, z + 1.0f ) ); wxASSERT( frustum.Intersect( bbox3d ) == true ); - bbox3d.Set( SFVEC3F(-1.0f, -1.0f, z+z), SFVEC3F(+1.0f,+1.0f, z+z + 1.0f) ); + bbox3d.Set( SFVEC3F( -1.0f, -1.0f, z + z ), SFVEC3F( +1.0f, +1.0f, z + z + 1.0f ) ); wxASSERT( frustum.Intersect( bbox3d ) == true ); - bbox3d.Set( SFVEC3F(-1.0f, -1.0f, 1.0f), SFVEC3F(0.0f,0.0f, 2.0f) ); + bbox3d.Set( SFVEC3F( -1.0f, -1.0f, 1.0f ), SFVEC3F( 0.0f, 0.0f, 2.0f ) ); wxASSERT( frustum.Intersect( bbox3d ) == true ); - bbox3d.Set( SFVEC3F(-1.0f, -1.0f, -z-1.0f), SFVEC3F(+1.0f,+1.0f, -z) ); + bbox3d.Set( SFVEC3F( -1.0f, -1.0f, -z - 1.0f ), SFVEC3F( +1.0f, +1.0f, -z ) ); wxASSERT( frustum.Intersect( bbox3d ) == false ); - bbox3d.Set( SFVEC3F(z-1.0f, z-1.0f, 0.0), SFVEC3F(z+1.0f,z+1.0f, 1.0) ); + bbox3d.Set( SFVEC3F( z - 1.0f, z - 1.0f, 0.0 ), SFVEC3F( z + 1.0f, z + 1.0f, 1.0 ) ); wxASSERT( frustum.Intersect( bbox3d ) == false ); - bbox3d.Set( SFVEC3F(-z, -z, 0.0), SFVEC3F( -1.0f,-1.0f, 1.0f) ); + bbox3d.Set( SFVEC3F( -z, -z, 0.0), SFVEC3F( -1.0f, -1.0f, 1.0f ) ); wxASSERT( frustum.Intersect( bbox3d ) == false ); - bbox3d.Set( SFVEC3F(-z, -z, -1.0f), SFVEC3F(+z,+z, 1.0f) ); + bbox3d.Set( SFVEC3F( -z, -z, -1.0f ), SFVEC3F( +z, +z, 1.0f ) ); wxASSERT( frustum.Intersect( bbox3d ) == true ); - bbox3d.Set( SFVEC3F(-z, -z, z-1), SFVEC3F(+z,+z, z+1.0f) ); + bbox3d.Set( SFVEC3F( -z, -z, z-1 ), SFVEC3F( +z, +z, z + 1.0f ) ); wxASSERT( frustum.Intersect( bbox3d ) == true ); - bbox3d.Set( SFVEC3F( 0.5, 0.5, 0.0), SFVEC3F( 2.0, 2.0, z) ); + bbox3d.Set( SFVEC3F( 0.5, 0.5, 0.0 ), SFVEC3F( 2.0, 2.0, z ) ); wxASSERT( frustum.Intersect( bbox3d ) == true ); - bbox3d.Set( SFVEC3F( 1.1, 1.0, 0.0), SFVEC3F( 2.0, 2.0, z) ); + bbox3d.Set( SFVEC3F( 1.1, 1.0, 0.0 ), SFVEC3F( 2.0, 2.0, z ) ); wxASSERT( frustum.Intersect( bbox3d ) == false ); } { @@ -337,46 +327,46 @@ void Run_3d_viewer_test_cases() float z = 10.0; - SFVEC3F ori = SFVEC3F(0.0, 0.0, z); + SFVEC3F ori = SFVEC3F( 0.0, 0.0, z ); - const RAY topLeft( ori, glm::normalize( SFVEC3F(-1.0, 1.0, 0.0) - ori ) ); - const RAY topRight( ori, glm::normalize( SFVEC3F(+1.0, 1.0, 0.0) - ori ) ); - const RAY bottomLeft( ori, glm::normalize( SFVEC3F(-1.0,-1.0, 0.0) - ori ) ); - const RAY bottomRight( ori, glm::normalize( SFVEC3F(+1.0,-1.0, 0.0) - ori ) ); + const RAY topLeft( ori, glm::normalize( SFVEC3F( -1.0, 1.0, 0.0 ) - ori ) ); + const RAY topRight( ori, glm::normalize( SFVEC3F( +1.0, 1.0, 0.0 ) - ori ) ); + const RAY bottomLeft( ori, glm::normalize( SFVEC3F( -1.0, -1.0, 0.0 ) - ori ) ); + const RAY bottomRight( ori, glm::normalize( SFVEC3F( +1.0, -1.0, 0.0 ) - ori ) ); frustum.GenerateFrustum( topLeft, topRight, bottomLeft, bottomRight ); CBBOX bbox3d; - bbox3d.Set( SFVEC3F(-1.0f, -1.0f, -z), SFVEC3F(+1.0f,+1.0f, -z + 1.0f) ); + bbox3d.Set( SFVEC3F( -1.0f, -1.0f, -z), SFVEC3F( +1.0f, +1.0f, -z + 1.0f ) ); wxASSERT( frustum.Intersect( bbox3d ) == true ); - bbox3d.Set( SFVEC3F(-1.0f, -1.0f, -(z+z)), SFVEC3F(+1.0f,+1.0f, -(z+z + 1.0f)) ); + bbox3d.Set( SFVEC3F( -1.0f, -1.0f, -( z + z ) ), SFVEC3F( +1.0f, +1.0f, -( z + z + 1.0f ) ) ); wxASSERT( frustum.Intersect( bbox3d ) == true ); - bbox3d.Set( SFVEC3F(-1.0f, -1.0f, 1.0f), SFVEC3F(0.0f,0.0f, 2.0f) ); + bbox3d.Set( SFVEC3F(- 1.0f, -1.0f, 1.0f ), SFVEC3F( 0.0f, 0.0f, 2.0f ) ); wxASSERT( frustum.Intersect( bbox3d ) == true ); // !TODO: The frustum alg is not excluse all the the situations //bbox3d.Set( SFVEC3F(-1.0f, -1.0f, z+1.0f), SFVEC3F(+1.0f,+1.0f, +z+2.0f) ); //wxASSERT( frustum.Intersect( bbox3d ) == false ); - bbox3d.Set( SFVEC3F(z-1.0f, z-1.0f, 0.0), SFVEC3F(z+1.0f,z+1.0f, 1.0) ); + bbox3d.Set( SFVEC3F( z - 1.0f, z - 1.0f, 0.0), SFVEC3F( z + 1.0f, z + 1.0f, 1.0 ) ); wxASSERT( frustum.Intersect( bbox3d ) == false ); - bbox3d.Set( SFVEC3F(-z, -z, 0.0), SFVEC3F( -1.0f,-1.0f, 1.0f) ); + bbox3d.Set( SFVEC3F( -z, -z, 0.0 ), SFVEC3F( -1.0f,-1.0f, 1.0f ) ); wxASSERT( frustum.Intersect( bbox3d ) == false ); - bbox3d.Set( SFVEC3F(-z, -z, -1.0f), SFVEC3F(+z,+z, 1.0f) ); + bbox3d.Set( SFVEC3F( -z, -z, -1.0f ), SFVEC3F( +z, +z, 1.0f ) ); wxASSERT( frustum.Intersect( bbox3d ) == true ); - bbox3d.Set( SFVEC3F(-z, -z, -(z-1)), SFVEC3F(+z,+z, -(z+1.0f)) ); + bbox3d.Set( SFVEC3F( -z, -z, -( z - 1 ) ), SFVEC3F( +z, +z, -( z + 1.0f ) ) ); wxASSERT( frustum.Intersect( bbox3d ) == true ); - bbox3d.Set( SFVEC3F( 0.5, 0.5, 0.0), SFVEC3F( 2.0, 2.0, z) ); + bbox3d.Set( SFVEC3F( 0.5, 0.5, 0.0 ), SFVEC3F( 2.0, 2.0, z ) ); wxASSERT( frustum.Intersect( bbox3d ) == true ); - bbox3d.Set( SFVEC3F( 1.1, 1.0, 0.0), SFVEC3F( 2.0, 2.0, z) ); + bbox3d.Set( SFVEC3F( 1.1, 1.0, 0.0 ), SFVEC3F( 2.0, 2.0, z ) ); wxASSERT( frustum.Intersect( bbox3d ) == false ); } #endif