KiCad PCB EDA Suite
MODEL_3D Class Reference

#include <3d_model.h>

Classes

struct  MATERIAL
 
struct  VERTEX
 

Public Member Functions

 MODEL_3D (const S3DMODEL &a3DModel, MATERIAL_MODE aMaterialMode)
 Load a 3D model. More...
 
 ~MODEL_3D ()
 
void DrawOpaque (bool aUseSelectedMaterial, SFVEC3F aSelectionColor=SFVEC3F(0.0f)) const
 Render the model into the current context. More...
 
void DrawTransparent (float aOpacity, bool aUseSelectedMaterial, SFVEC3F aSelectionColor=SFVEC3F(0.0f)) const
 Render the model into the current context. More...
 
bool HasOpaqueMeshes () const
 Return true if have opaque meshes to render. More...
 
bool HasTransparentMeshes () const
 Return true if have transparent mesh's to render. More...
 
void DrawBbox () const
 Draw main bounding box of the model. More...
 
void DrawBboxes () const
 Draw individual bounding boxes of each mesh. More...
 
const BBOX_3DGetBBox () const
 Get the main bounding box. More...
 

Static Public Member Functions

static void BeginDrawMulti (bool aUseColorInformation)
 Set some basic render states before drawing multiple models. More...
 
static void EndDrawMulti ()
 Cleanup render states after drawing multiple models. More...
 

Private Member Functions

void Draw (bool aTransparent, float aOpacity, bool aUseSelectedMaterial, SFVEC3F &aSelectionColor) const
 

Static Private Member Functions

static void MakeBbox (const BBOX_3D &aBox, unsigned int aIdxOffset, VERTEX *aVtxOut, GLuint *aIdxOut, const glm::vec4 &aColor)
 

Private Attributes

MATERIAL_MODE m_materialMode
 
BBOX_3D m_model_bbox
 global bounding box for this model More...
 
std::vector< BBOX_3Dm_meshes_bbox
 individual bbox for each mesh More...
 
GLuint m_vertex_buffer = 0
 
GLuint m_index_buffer = 0
 
GLenum m_index_buffer_type = GL_INVALID_ENUM
 
std::vector< MATERIALm_materials
 
bool m_have_opaque_meshes = false
 
bool m_have_transparent_meshes = false
 
GLuint m_bbox_vertex_buffer = 0
 
GLuint m_bbox_index_buffer = 0
 
GLenum m_bbox_index_buffer_type = GL_INVALID_ENUM
 

Static Private Attributes

static const wxChar * m_logTrace = wxT( "KI_TRACE_EDA_OGL_3DMODEL" )
 
static constexpr unsigned int bbox_vtx_count = 8
 
static constexpr unsigned int bbox_idx_count = 24
 

Detailed Description

Definition at line 37 of file 3d_model.h.

Constructor & Destructor Documentation

◆ MODEL_3D()

MODEL_3D::MODEL_3D ( const S3DMODEL a3DModel,
MATERIAL_MODE  aMaterialMode 
)

Load a 3D model.

Note
This must be called inside a gl context.
Parameters
a3DModela 3d model data to load.
aMaterialModea mode to render the materials of the model.

WARNING: Horrible hack here! Somehow, buffer values are being shared between pcbnew and the 3d viewer, which then frees the buffer, resulting in errors in pcbnew. To resolve this temporarily, we generate extra buffers in 3dviewer and use the higher numbers. These are freed on close. todo: Correctly separate the OpenGL contexts to prevent overlapping buffer vals

Definition at line 90 of file 3d_model.cpp.

91{
92 wxLogTrace( m_logTrace, wxT( "MODEL_3D::MODEL_3D %u meshes %u materials" ),
93 static_cast<unsigned int>( a3DModel.m_MeshesSize ),
94 static_cast<unsigned int>( a3DModel.m_MaterialsSize ) );
95
96 auto start_time = std::chrono::high_resolution_clock::now();
97 GLuint buffers[8];
98
106 glGenBuffers( 6, buffers );
107 m_bbox_vertex_buffer = buffers[2];
108 m_bbox_index_buffer = buffers[3];
109 m_vertex_buffer = buffers[4];
110 m_index_buffer = buffers[5];
111
112 // Validate a3DModel pointers
113 wxASSERT( a3DModel.m_Materials != nullptr );
114 wxASSERT( a3DModel.m_Meshes != nullptr );
115 wxASSERT( a3DModel.m_MaterialsSize > 0 );
116 wxASSERT( a3DModel.m_MeshesSize > 0 );
117
118 m_materialMode = aMaterialMode;
119
120 if( a3DModel.m_Materials == nullptr || a3DModel.m_Meshes == nullptr
121 || a3DModel.m_MaterialsSize == 0 || a3DModel.m_MeshesSize == 0 )
122 return;
123
124 // create empty bbox for each mesh. it will be updated when the vertices are copied.
125 m_meshes_bbox.resize( a3DModel.m_MeshesSize );
126
127 // copy materials for later use during rendering.
128 m_materials.reserve( a3DModel.m_MaterialsSize );
129
130 for( unsigned int i = 0; i < a3DModel.m_MaterialsSize; ++i )
131 m_materials.emplace_back( a3DModel.m_Materials[i] );
132
133 // build temporary vertex and index buffers for bounding boxes.
134 // the first box is the outer box.
135 std::vector<VERTEX> bbox_tmp_vertices( ( m_meshes_bbox.size() + 1 ) * bbox_vtx_count );
136 std::vector<GLuint> bbox_tmp_indices( ( m_meshes_bbox.size() + 1 ) * bbox_idx_count );
137
138 // group all meshes by material.
139 // for each material create a combined vertex and index buffer.
140 // some models might have many sub-meshes. so iterate over the
141 // input meshes only once.
142 struct MESH_GROUP
143 {
144 std::vector<VERTEX> m_vertices;
145 std::vector<GLuint> m_indices;
146 };
147
148 std::vector<MESH_GROUP> mesh_groups( m_materials.size() );
149
150 for( unsigned int mesh_i = 0; mesh_i < a3DModel.m_MeshesSize; ++mesh_i )
151 {
152 const SMESH& mesh = a3DModel.m_Meshes[mesh_i];
153
154 // silently ignore meshes that have invalid material references or invalid geometry.
155 if( mesh.m_MaterialIdx >= m_materials.size()
156 || mesh.m_Positions == nullptr
157 || mesh.m_FaceIdx == nullptr
158 || mesh.m_Normals == nullptr
159 || mesh.m_FaceIdxSize == 0
160 || mesh.m_VertexSize == 0 )
161 {
162 continue;
163 }
164
165 MESH_GROUP& mesh_group = mesh_groups[mesh.m_MaterialIdx];
166 MATERIAL& material = m_materials[mesh.m_MaterialIdx];
167
168 if( material.IsTransparent() && m_materialMode != MATERIAL_MODE::DIFFUSE_ONLY )
170 else
172
173 const unsigned int vtx_offset = mesh_group.m_vertices.size();
174 mesh_group.m_vertices.resize( mesh_group.m_vertices.size() + mesh.m_VertexSize );
175
176 // copy vertex data and update the bounding box.
177 // use material color for mesh bounding box or some sort of average vertex color.
178 glm::vec3 avg_color = material.m_Diffuse;
179
180 for( unsigned int vtx_i = 0; vtx_i < mesh.m_VertexSize; ++vtx_i )
181 {
182 m_meshes_bbox[mesh_i].Union( mesh.m_Positions[vtx_i] );
183
184 VERTEX& vtx_out = mesh_group.m_vertices[vtx_offset + vtx_i];
185
186 vtx_out.m_pos = mesh.m_Positions[vtx_i];
187 vtx_out.m_nrm = glm::clamp( glm::vec4( mesh.m_Normals[vtx_i], 1.0f ) * 127.0f,
188 -127.0f, 127.0f );
189
190 vtx_out.m_tex_uv = mesh.m_Texcoords != nullptr ? mesh.m_Texcoords[vtx_i]
191 : glm::vec2 (0);
192
193 if( mesh.m_Color != nullptr )
194 {
195 avg_color = ( avg_color + mesh.m_Color[vtx_i] ) * 0.5f;
196
197 vtx_out.m_color =
198 glm::clamp( glm::vec4( mesh.m_Color[vtx_i],
199 1 - material.m_Transparency ) * 255.0f,
200 0.0f, 255.0f );
201
202 vtx_out.m_cad_color =
203 glm::clamp( glm::vec4( MaterialDiffuseToColorCAD( mesh.m_Color[vtx_i] ),
204 1 ) * 255.0f, 0.0f, 255.0f );
205 }
206 else
207 {
208 // the mesh will be rendered with other meshes that might have
209 // vertex colors. thus, we can't enable/disable vertex colors
210 // for individual meshes during rendering.
211
212 // if there are no vertex colors, use material color instead.
213 vtx_out.m_color =
214 glm::clamp( glm::vec4( material.m_Diffuse,
215 1 - material.m_Transparency ) * 255.0f,
216 0.0f, 255.0f );
217
218 vtx_out.m_cad_color =
219 glm::clamp( glm::vec4 ( MaterialDiffuseToColorCAD( material.m_Diffuse ),
220 1 ) * 255.0f,
221 0.0f, 255.0f );
222 }
223 }
224
225 if( m_meshes_bbox[mesh_i].IsInitialized() )
226 {
227 // generate geometry for the bounding box
228 MakeBbox( m_meshes_bbox[mesh_i], ( mesh_i + 1 ) * bbox_vtx_count,
229 &bbox_tmp_vertices[( mesh_i + 1 ) * bbox_vtx_count],
230 &bbox_tmp_indices[( mesh_i + 1 ) * bbox_idx_count],
231 { avg_color, 1.0f } );
232
233 // bump the outer bounding box
235 }
236
237
238 // append indices of this mesh to the mesh group.
239 const unsigned int idx_offset = mesh_group.m_indices.size();
240 unsigned int use_idx_count = mesh.m_FaceIdxSize;
241
242 if( use_idx_count % 3 != 0 )
243 {
244 wxLogTrace( m_logTrace, wxT( " index count %u not multiple of 3, truncating" ),
245 static_cast<unsigned int>( use_idx_count ) );
246 use_idx_count = ( use_idx_count / 3 ) * 3;
247 }
248
249 mesh_group.m_indices.resize( mesh_group.m_indices.size() + use_idx_count );
250
251 for( unsigned int idx_i = 0; idx_i < use_idx_count; ++idx_i )
252 {
253 if( mesh.m_FaceIdx[idx_i] >= mesh.m_VertexSize )
254 {
255 wxLogTrace( m_logTrace, wxT( " index %u out of range (%u)" ),
256 static_cast<unsigned int>( mesh.m_FaceIdx[idx_i] ),
257 static_cast<unsigned int>( mesh.m_VertexSize ) );
258
259 // FIXME: should skip this triangle
260 }
261
262 mesh_group.m_indices[idx_offset + idx_i] = mesh.m_FaceIdx[idx_i] + vtx_offset;
263 }
264 }
265
266 // generate geometry for the outer bounding box
268 MakeBbox( m_model_bbox, 0, &bbox_tmp_vertices[0], &bbox_tmp_indices[0],
269 { 0.0f, 1.0f, 0.0f, 1.0f } );
270
271 // create bounding box buffers
272 glGenBuffers( 1, &m_bbox_vertex_buffer );
273 glBindBuffer( GL_ARRAY_BUFFER, m_bbox_vertex_buffer );
274 glBufferData( GL_ARRAY_BUFFER, sizeof( VERTEX ) * bbox_tmp_vertices.size(),
275 bbox_tmp_vertices.data(), GL_STATIC_DRAW );
276
277 glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_bbox_index_buffer );
278
279 if( bbox_tmp_vertices.size() <= std::numeric_limits<GLushort>::max() )
280 {
281 m_bbox_index_buffer_type = GL_UNSIGNED_SHORT;
282
283 auto u16buf = std::make_unique<GLushort[]>( bbox_tmp_indices.size() );
284
285 for( unsigned int i = 0; i < bbox_tmp_indices.size(); ++i )
286 u16buf[i] = static_cast<GLushort>( bbox_tmp_indices[i] );
287
288 glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof( GLushort ) * bbox_tmp_indices.size(),
289 u16buf.get(), GL_STATIC_DRAW );
290 }
291 else
292 {
293 m_bbox_index_buffer_type = GL_UNSIGNED_INT;
294 glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof( GLuint ) * bbox_tmp_indices.size(),
295 bbox_tmp_indices.data(), GL_STATIC_DRAW );
296 }
297
298 // merge the mesh group geometry data.
299 unsigned int total_vertex_count = 0;
300 unsigned int total_index_count = 0;
301
302 for( const MESH_GROUP& mg : mesh_groups )
303 {
304 total_vertex_count += mg.m_vertices.size();
305 total_index_count += mg.m_indices.size();
306 }
307
308 wxLogTrace( m_logTrace, wxT( " total %u vertices, %u indices" ),
309 total_vertex_count, total_index_count );
310
311 glBindBuffer( GL_ARRAY_BUFFER, m_vertex_buffer );
312 glBufferData( GL_ARRAY_BUFFER, sizeof( VERTEX ) * total_vertex_count,
313 nullptr, GL_STATIC_DRAW );
314
315 unsigned int idx_size = 0;
316
317 if( total_vertex_count <= std::numeric_limits<GLushort>::max() )
318 {
319 m_index_buffer_type = GL_UNSIGNED_SHORT;
320 idx_size = sizeof( GLushort );
321 }
322 else
323 {
324 m_index_buffer_type = GL_UNSIGNED_INT;
325 idx_size = sizeof( GLuint );
326 }
327
328 // temporary index buffer which will contain either GLushort or GLuint
329 // type indices. allocate with a bit of meadow at the end.
330 auto tmp_idx = std::make_unique<GLuint[]>( ( idx_size * total_index_count + 8 ) / sizeof( GLuint ) );
331
332 unsigned int prev_vtx_count = 0;
333 unsigned int idx_offset = 0;
334 unsigned int vtx_offset = 0;
335
336 for( unsigned int mg_i = 0; mg_i < mesh_groups.size (); ++mg_i )
337 {
338 MESH_GROUP& mg = mesh_groups[mg_i];
339 MATERIAL& mat = m_materials[mg_i];
340 uintptr_t tmp_idx_ptr = reinterpret_cast<uintptr_t>( tmp_idx.get() );
341
342 if( m_index_buffer_type == GL_UNSIGNED_SHORT )
343 {
344 GLushort* idx_out = reinterpret_cast<GLushort*>( tmp_idx_ptr + idx_offset );
345
346 for( GLuint idx : mg.m_indices )
347 *idx_out++ = static_cast<GLushort>( idx + prev_vtx_count );
348 }
349 else if( m_index_buffer_type == GL_UNSIGNED_INT )
350 {
351 GLuint* idx_out = reinterpret_cast<GLuint*>( tmp_idx_ptr + idx_offset );
352
353 for( GLuint idx : mg.m_indices )
354 *idx_out++ = static_cast<GLuint>( idx + prev_vtx_count );
355 }
356
357 glBufferSubData( GL_ARRAY_BUFFER, vtx_offset, mg.m_vertices.size() * sizeof( VERTEX ),
358 mg.m_vertices.data() );
359
360 mat.m_render_idx_buffer_offset = idx_offset;
361 mat.m_render_idx_count = mg.m_indices.size();
362
363 prev_vtx_count += mg.m_vertices.size();
364 idx_offset += mg.m_indices.size() * idx_size;
365 vtx_offset += mg.m_vertices.size() * sizeof( VERTEX );
366 }
367
368 glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_index_buffer );
369 glBufferData( GL_ELEMENT_ARRAY_BUFFER, idx_size * total_index_count, tmp_idx.get(),
370 GL_STATIC_DRAW );
371
372 glBindBuffer( GL_ARRAY_BUFFER, 0 );
373 glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );
374
375 auto end_time = std::chrono::high_resolution_clock::now();
376
377 wxLogTrace( m_logTrace, wxT( " loaded in %u ms\n" ),
378 (unsigned int)std::chrono::duration_cast<std::chrono::milliseconds> (
379 end_time - start_time).count() );
380}
@ DIFFUSE_ONLY
Use only diffuse material properties.
SFVEC3F MaterialDiffuseToColorCAD(const SFVEC3F &aDiffuseColor)
Definition: 3d_math.h:147
Base material class that can be used to derive other material implementations.
Definition: material.h:240
GLuint m_vertex_buffer
Definition: 3d_model.h:128
bool m_have_opaque_meshes
Definition: 3d_model.h:148
GLenum m_index_buffer_type
Definition: 3d_model.h:130
std::vector< MATERIAL > m_materials
Definition: 3d_model.h:143
static void MakeBbox(const BBOX_3D &aBox, unsigned int aIdxOffset, VERTEX *aVtxOut, GLuint *aIdxOut, const glm::vec4 &aColor)
Definition: 3d_model.cpp:51
GLuint m_index_buffer
Definition: 3d_model.h:129
GLuint m_bbox_index_buffer
Definition: 3d_model.h:157
static constexpr unsigned int bbox_idx_count
Definition: 3d_model.h:154
MATERIAL_MODE m_materialMode
Definition: 3d_model.h:111
static const wxChar * m_logTrace
Definition: 3d_model.h:106
bool m_have_transparent_meshes
Definition: 3d_model.h:149
std::vector< BBOX_3D > m_meshes_bbox
individual bbox for each mesh
Definition: 3d_model.h:114
GLenum m_bbox_index_buffer_type
Definition: 3d_model.h:158
static constexpr unsigned int bbox_vtx_count
Definition: 3d_model.h:153
BBOX_3D m_model_bbox
global bounding box for this model
Definition: 3d_model.h:113
GLuint m_bbox_vertex_buffer
Definition: 3d_model.h:156
void Union(const SFVEC3F &aPoint)
Recalculate the bounding box adding a point.
Definition: bbox_3d.cpp:102
bool IsInitialized() const
Check if this bounding box is already initialized.
Definition: bbox_3d.cpp:88
SMATERIAL * m_Materials
The materials list of this model.
Definition: c3dmodel.h:96
unsigned int m_MeshesSize
Number of meshes in the array.
Definition: c3dmodel.h:92
SMESH * m_Meshes
The meshes list of this model.
Definition: c3dmodel.h:93
unsigned int m_MaterialsSize
Number of materials in the material array.
Definition: c3dmodel.h:95
Per-vertex normal/color/texcoors structure.
Definition: c3dmodel.h:77
unsigned int * m_FaceIdx
Triangle Face Indexes.
Definition: c3dmodel.h:84
SFVEC3F * m_Normals
Vertex normals array.
Definition: c3dmodel.h:80
unsigned int m_MaterialIdx
Material Index to be used in this mesh (must be < m_MaterialsSize )
Definition: c3dmodel.h:85
unsigned int m_VertexSize
Number of vertex in the arrays.
Definition: c3dmodel.h:78
SFVEC2F * m_Texcoords
Vertex texture coordinates array, can be NULL.
Definition: c3dmodel.h:81
unsigned int m_FaceIdxSize
Number of elements of the m_FaceIdx array.
Definition: c3dmodel.h:83
SFVEC3F * m_Color
Vertex color array, can be NULL.
Definition: c3dmodel.h:82
SFVEC3F * m_Positions
Vertex position array.
Definition: c3dmodel.h:79

References bbox_idx_count, bbox_vtx_count, DIFFUSE_ONLY, BBOX_3D::IsInitialized(), MODEL_3D::MATERIAL::IsTransparent(), m_bbox_index_buffer, m_bbox_index_buffer_type, m_bbox_vertex_buffer, MODEL_3D::VERTEX::m_cad_color, MODEL_3D::VERTEX::m_color, SMESH::m_Color, SMATERIAL::m_Diffuse, SMESH::m_FaceIdx, SMESH::m_FaceIdxSize, m_have_opaque_meshes, m_have_transparent_meshes, m_index_buffer, m_index_buffer_type, m_logTrace, SMESH::m_MaterialIdx, m_materialMode, m_materials, S3DMODEL::m_Materials, S3DMODEL::m_MaterialsSize, S3DMODEL::m_Meshes, m_meshes_bbox, S3DMODEL::m_MeshesSize, m_model_bbox, SMESH::m_Normals, MODEL_3D::VERTEX::m_nrm, MODEL_3D::VERTEX::m_pos, SMESH::m_Positions, MODEL_3D::MATERIAL::m_render_idx_buffer_offset, MODEL_3D::MATERIAL::m_render_idx_count, MODEL_3D::VERTEX::m_tex_uv, SMESH::m_Texcoords, SMATERIAL::m_Transparency, m_vertex_buffer, SMESH::m_VertexSize, MakeBbox(), MaterialDiffuseToColorCAD(), and BBOX_3D::Union().

◆ ~MODEL_3D()

MODEL_3D::~MODEL_3D ( )

Definition at line 478 of file 3d_model.cpp.

479{
480 if( glDeleteBuffers )
481 {
482 glDeleteBuffers( 1, &m_vertex_buffer );
483 glDeleteBuffers( 1, &m_index_buffer );
484 glDeleteBuffers( 1, &m_bbox_vertex_buffer );
485 glDeleteBuffers( 1, &m_bbox_index_buffer );
486 }
487}

References m_bbox_index_buffer, m_bbox_vertex_buffer, m_index_buffer, and m_vertex_buffer.

Member Function Documentation

◆ BeginDrawMulti()

void MODEL_3D::BeginDrawMulti ( bool  aUseColorInformation)
static

Set some basic render states before drawing multiple models.

Definition at line 383 of file 3d_model.cpp.

384{
385 glEnableClientState( GL_VERTEX_ARRAY );
386 glEnableClientState( GL_NORMAL_ARRAY );
387
388 if( aUseColorInformation )
389 {
390 glEnableClientState( GL_COLOR_ARRAY );
391 glEnableClientState( GL_TEXTURE_COORD_ARRAY );
392 glEnable( GL_COLOR_MATERIAL );
393 }
394
395 glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE );
396}

Referenced by EDA_3D_MODEL_VIEWER::OnPaint(), and RENDER_3D_OPENGL::render3dModelsSelected().

◆ Draw()

void MODEL_3D::Draw ( bool  aTransparent,
float  aOpacity,
bool  aUseSelectedMaterial,
SFVEC3F aSelectionColor 
) const
private

Definition at line 412 of file 3d_model.cpp.

414{
415 if( aOpacity <= FLT_EPSILON )
416 return;
417
418 if( !glBindBuffer )
419 throw std::runtime_error( "The OpenGL context no longer exists: unable to draw" );
420
421 glBindBuffer( GL_ARRAY_BUFFER, m_vertex_buffer );
422 glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_index_buffer );
423
424 glVertexPointer( 3, GL_FLOAT, sizeof( VERTEX ),
425 reinterpret_cast<const void*>( offsetof( VERTEX, m_pos ) ) );
426
427 glNormalPointer( GL_BYTE, sizeof( VERTEX ),
428 reinterpret_cast<const void*>( offsetof( VERTEX, m_nrm ) ) );
429
430 glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( VERTEX ),
431 reinterpret_cast<const void*>( m_materialMode == MATERIAL_MODE::CAD_MODE
432 ? offsetof( VERTEX, m_cad_color )
433 : offsetof( VERTEX, m_color ) ) );
434
435 glTexCoordPointer( 2, GL_FLOAT, sizeof( VERTEX ),
436 reinterpret_cast<const void*>( offsetof( VERTEX, m_tex_uv ) ) );
437
438 const SFVEC4F param = SFVEC4F( 1.0f, 1.0f, 1.0f, aOpacity );
439
440 glTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, (const float*)&param.x );
441
442 // BeginDrawMulti();
443 for( const MODEL_3D::MATERIAL& mat : m_materials )
444 {
445 if( ( mat.IsTransparent() != aTransparent )
446 && ( aOpacity >= 1.0f )
448 {
449 continue;
450 }
451
452 switch( m_materialMode )
453 {
455 OglSetMaterial( mat, aOpacity, aUseSelectedMaterial, aSelectionColor );
456 break;
457
459 OglSetDiffuseMaterial( mat.m_Diffuse, aOpacity, aUseSelectedMaterial, aSelectionColor );
460 break;
461
463 OglSetDiffuseMaterial( MaterialDiffuseToColorCAD( mat.m_Diffuse ), aOpacity,
464 aUseSelectedMaterial, aSelectionColor );
465 break;
466
467 default:
468 break;
469 }
470
471 glDrawElements( GL_TRIANGLES, mat.m_render_idx_count, m_index_buffer_type,
472 reinterpret_cast<const void*>(
473 static_cast<uintptr_t>( mat.m_render_idx_buffer_offset ) ) );
474 }
475}
@ NORMAL
Use all material properties from model file.
@ CAD_MODE
Use a gray shading based on diffuse material.
void OglSetDiffuseMaterial(const SFVEC3F &aMaterialDiffuse, float aOpacity, bool aUseSelectedMaterial, SFVEC3F aSelectionColor)
Sets only the diffuse color and keep other parameters with default values.
Definition: ogl_utils.cpp:143
void OglSetMaterial(const SMATERIAL &aMaterial, float aOpacity, bool aUseSelectedMaterial, SFVEC3F aSelectionColor)
Set OpenGL materials.
Definition: ogl_utils.cpp:119
glm::vec4 SFVEC4F
Definition: xv3d_types.h:46

References CAD_MODE, DIFFUSE_ONLY, m_index_buffer, m_index_buffer_type, m_materialMode, m_materials, m_vertex_buffer, MaterialDiffuseToColorCAD(), NORMAL, OglSetDiffuseMaterial(), and OglSetMaterial().

Referenced by DrawOpaque(), and DrawTransparent().

◆ DrawBbox()

void MODEL_3D::DrawBbox ( ) const

Draw main bounding box of the model.

Definition at line 490 of file 3d_model.cpp.

491{
492 if( !glBindBuffer )
493 throw std::runtime_error( "The OpenGL context no longer exists: unable to draw bbox" );
494
495 glBindBuffer( GL_ARRAY_BUFFER, m_bbox_vertex_buffer );
496 glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_bbox_index_buffer );
497
498 glVertexPointer( 3, GL_FLOAT, sizeof( VERTEX ),
499 reinterpret_cast<const void*>( offsetof( VERTEX, m_pos ) ) );
500
501 glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( VERTEX ),
502 reinterpret_cast<const void*>( offsetof( VERTEX, m_color ) ) );
503
504 glDrawElements( GL_LINES, bbox_idx_count, m_bbox_index_buffer_type,
505 reinterpret_cast<const void*>( 0 ) );
506}

References bbox_idx_count, m_bbox_index_buffer, m_bbox_index_buffer_type, and m_bbox_vertex_buffer.

◆ DrawBboxes()

void MODEL_3D::DrawBboxes ( ) const

Draw individual bounding boxes of each mesh.

Definition at line 509 of file 3d_model.cpp.

510{
511 if( !glBindBuffer )
512 throw std::runtime_error( "The OpenGL context no longer exists: unable to draw bboxes" );
513
514 glBindBuffer( GL_ARRAY_BUFFER, m_bbox_vertex_buffer );
515 glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_bbox_index_buffer );
516
517 glVertexPointer( 3, GL_FLOAT, sizeof( VERTEX ),
518 reinterpret_cast<const void*>( offsetof( VERTEX, m_pos ) ) );
519
520 glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( VERTEX ),
521 reinterpret_cast<const void*>( offsetof( VERTEX, m_color ) ) );
522
523 unsigned int idx_size = m_bbox_index_buffer_type == GL_UNSIGNED_SHORT ? sizeof( GLushort )
524 : sizeof( GLuint );
525
526 glDrawElements( GL_LINES, bbox_idx_count * m_meshes_bbox.size(), m_bbox_index_buffer_type,
527 reinterpret_cast<const void*>(
528 static_cast<uintptr_t>( bbox_idx_count * idx_size ) ) );
529}

References bbox_idx_count, m_bbox_index_buffer, m_bbox_index_buffer_type, m_bbox_vertex_buffer, and m_meshes_bbox.

◆ DrawOpaque()

void MODEL_3D::DrawOpaque ( bool  aUseSelectedMaterial,
SFVEC3F  aSelectionColor = SFVEC3F( 0.0f ) 
) const
inline

Render the model into the current context.

Definition at line 55 of file 3d_model.h.

56 {
57 Draw( false, 1.0f, aUseSelectedMaterial, aSelectionColor );
58 }
void Draw(bool aTransparent, float aOpacity, bool aUseSelectedMaterial, SFVEC3F &aSelectionColor) const
Definition: 3d_model.cpp:412

References Draw().

Referenced by EDA_3D_MODEL_VIEWER::OnPaint().

◆ DrawTransparent()

void MODEL_3D::DrawTransparent ( float  aOpacity,
bool  aUseSelectedMaterial,
SFVEC3F  aSelectionColor = SFVEC3F( 0.0f ) 
) const
inline

Render the model into the current context.

Definition at line 63 of file 3d_model.h.

65 {
66 Draw( true, aOpacity, aUseSelectedMaterial, aSelectionColor );
67 }

References Draw().

Referenced by EDA_3D_MODEL_VIEWER::OnPaint().

◆ EndDrawMulti()

void MODEL_3D::EndDrawMulti ( )
static

Cleanup render states after drawing multiple models.

Definition at line 399 of file 3d_model.cpp.

400{
401 glDisable( GL_COLOR_MATERIAL );
402 glDisableClientState( GL_VERTEX_ARRAY );
403 glDisableClientState( GL_NORMAL_ARRAY );
404 glDisableClientState( GL_COLOR_ARRAY );
405 glDisableClientState( GL_TEXTURE_COORD_ARRAY );
406
407 glBindBuffer( GL_ARRAY_BUFFER, 0 );
408 glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );
409}

Referenced by EDA_3D_MODEL_VIEWER::OnPaint(), and RENDER_3D_OPENGL::render3dModelsSelected().

◆ GetBBox()

const BBOX_3D & MODEL_3D::GetBBox ( ) const
inline

Get the main bounding box.

Returns
the main model bounding box.

Definition at line 93 of file 3d_model.h.

93{ return m_model_bbox; }

References m_model_bbox.

Referenced by EDA_3D_MODEL_VIEWER::OnPaint().

◆ HasOpaqueMeshes()

bool MODEL_3D::HasOpaqueMeshes ( ) const
inline

Return true if have opaque meshes to render.

Definition at line 72 of file 3d_model.h.

72{ return m_have_opaque_meshes; }

References m_have_opaque_meshes.

◆ HasTransparentMeshes()

bool MODEL_3D::HasTransparentMeshes ( ) const
inline

Return true if have transparent mesh's to render.

Definition at line 77 of file 3d_model.h.

References m_have_transparent_meshes.

◆ MakeBbox()

void MODEL_3D::MakeBbox ( const BBOX_3D aBox,
unsigned int  aIdxOffset,
VERTEX aVtxOut,
GLuint *  aIdxOut,
const glm::vec4 &  aColor 
)
staticprivate

Definition at line 51 of file 3d_model.cpp.

53{
54 aVtxOut[0].m_pos = { aBox.Min().x, aBox.Min().y, aBox.Min().z };
55 aVtxOut[1].m_pos = { aBox.Max().x, aBox.Min().y, aBox.Min().z };
56 aVtxOut[2].m_pos = { aBox.Max().x, aBox.Max().y, aBox.Min().z };
57 aVtxOut[3].m_pos = { aBox.Min().x, aBox.Max().y, aBox.Min().z };
58
59 aVtxOut[4].m_pos = { aBox.Min().x, aBox.Min().y, aBox.Max().z };
60 aVtxOut[5].m_pos = { aBox.Max().x, aBox.Min().y, aBox.Max().z };
61 aVtxOut[6].m_pos = { aBox.Max().x, aBox.Max().y, aBox.Max().z };
62 aVtxOut[7].m_pos = { aBox.Min().x, aBox.Max().y, aBox.Max().z };
63
64 for( unsigned int i = 0; i < 8; ++i )
65 aVtxOut[i].m_color = aVtxOut[i].m_cad_color = glm::clamp( aColor * 255.0f, 0.0f, 255.0f );
66
67 #define bbox_line( vtx_a, vtx_b )\
68 do { *aIdxOut++ = vtx_a + aIdxOffset; \
69 *aIdxOut++ = vtx_b + aIdxOffset; } while( 0 )
70
71 bbox_line( 0, 1 );
72 bbox_line( 1, 2 );
73 bbox_line( 2, 3 );
74 bbox_line( 3, 0 );
75
76 bbox_line( 4, 5 );
77 bbox_line( 5, 6 );
78 bbox_line( 6, 7 );
79 bbox_line( 7, 4 );
80
81 bbox_line( 0, 4 );
82 bbox_line( 1, 5 );
83 bbox_line( 2, 6 );
84 bbox_line( 3, 7 );
85
86 #undef bbox_line
87}
#define bbox_line(vtx_a, vtx_b)
const SFVEC3F & Min() const
Return the minimum vertex pointer.
Definition: bbox_3d.h:183
const SFVEC3F & Max() const
Return the maximum vertex pointer.
Definition: bbox_3d.h:190

References bbox_line, MODEL_3D::VERTEX::m_pos, BBOX_3D::Max(), and BBOX_3D::Min().

Referenced by MODEL_3D().

Member Data Documentation

◆ bbox_idx_count

constexpr unsigned int MODEL_3D::bbox_idx_count = 24
staticconstexprprivate

Definition at line 154 of file 3d_model.h.

Referenced by DrawBbox(), DrawBboxes(), and MODEL_3D().

◆ bbox_vtx_count

constexpr unsigned int MODEL_3D::bbox_vtx_count = 8
staticconstexprprivate

Definition at line 153 of file 3d_model.h.

Referenced by MODEL_3D().

◆ m_bbox_index_buffer

GLuint MODEL_3D::m_bbox_index_buffer = 0
private

Definition at line 157 of file 3d_model.h.

Referenced by DrawBbox(), DrawBboxes(), MODEL_3D(), and ~MODEL_3D().

◆ m_bbox_index_buffer_type

GLenum MODEL_3D::m_bbox_index_buffer_type = GL_INVALID_ENUM
private

Definition at line 158 of file 3d_model.h.

Referenced by DrawBbox(), DrawBboxes(), and MODEL_3D().

◆ m_bbox_vertex_buffer

GLuint MODEL_3D::m_bbox_vertex_buffer = 0
private

Definition at line 156 of file 3d_model.h.

Referenced by DrawBbox(), DrawBboxes(), MODEL_3D(), and ~MODEL_3D().

◆ m_have_opaque_meshes

bool MODEL_3D::m_have_opaque_meshes = false
private

Definition at line 148 of file 3d_model.h.

Referenced by HasOpaqueMeshes(), and MODEL_3D().

◆ m_have_transparent_meshes

bool MODEL_3D::m_have_transparent_meshes = false
private

Definition at line 149 of file 3d_model.h.

Referenced by HasTransparentMeshes(), and MODEL_3D().

◆ m_index_buffer

GLuint MODEL_3D::m_index_buffer = 0
private

Definition at line 129 of file 3d_model.h.

Referenced by Draw(), MODEL_3D(), and ~MODEL_3D().

◆ m_index_buffer_type

GLenum MODEL_3D::m_index_buffer_type = GL_INVALID_ENUM
private

Definition at line 130 of file 3d_model.h.

Referenced by Draw(), and MODEL_3D().

◆ m_logTrace

const wxChar * MODEL_3D::m_logTrace = wxT( "KI_TRACE_EDA_OGL_3DMODEL" )
staticprivate

Definition at line 106 of file 3d_model.h.

Referenced by MODEL_3D().

◆ m_materialMode

MATERIAL_MODE MODEL_3D::m_materialMode
private

Definition at line 111 of file 3d_model.h.

Referenced by Draw(), and MODEL_3D().

◆ m_materials

std::vector<MATERIAL> MODEL_3D::m_materials
private

Definition at line 143 of file 3d_model.h.

Referenced by Draw(), and MODEL_3D().

◆ m_meshes_bbox

std::vector<BBOX_3D> MODEL_3D::m_meshes_bbox
private

individual bbox for each mesh

Definition at line 114 of file 3d_model.h.

Referenced by DrawBboxes(), and MODEL_3D().

◆ m_model_bbox

BBOX_3D MODEL_3D::m_model_bbox
private

global bounding box for this model

Definition at line 113 of file 3d_model.h.

Referenced by GetBBox(), and MODEL_3D().

◆ m_vertex_buffer

GLuint MODEL_3D::m_vertex_buffer = 0
private

Definition at line 128 of file 3d_model.h.

Referenced by Draw(), MODEL_3D(), and ~MODEL_3D().


The documentation for this class was generated from the following files: