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 auto& 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  continue;
162 
163  auto& mesh_group = mesh_groups[mesh.m_MaterialIdx];
164  auto& material = m_materials[mesh.m_MaterialIdx];
165 
166  if( material.IsTransparent()
169  else
170  m_have_opaque_meshes = true;
171 
172  const unsigned int vtx_offset = mesh_group.m_vertices.size();
173  mesh_group.m_vertices.resize( mesh_group.m_vertices.size() + mesh.m_VertexSize );
174 
175  // copy vertex data and update the bounding box.
176  // use material color for mesh bounding box or some sort of average vertex color.
177  glm::vec3 avg_color = material.m_Diffuse;
178 
179  for( unsigned int vtx_i = 0; vtx_i < mesh.m_VertexSize; ++vtx_i )
180  {
181  m_meshes_bbox[mesh_i].Union( mesh.m_Positions[vtx_i] );
182 
183  auto& vtx_out = mesh_group.m_vertices[vtx_offset + vtx_i];
184 
185  vtx_out.m_pos = mesh.m_Positions[vtx_i];
186  vtx_out.m_nrm = glm::clamp( glm::vec4( mesh.m_Normals[vtx_i], 1.0f ) * 127.0f,
187  -127.0f, 127.0f );
188 
189  vtx_out.m_tex_uv = mesh.m_Texcoords != nullptr
190  ? 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
234  m_model_bbox.Union( m_meshes_bbox[mesh_i] );
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( auto& 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[]>(
331  ( idx_size * total_index_count + 8 ) / sizeof( GLuint ) );
332 
333  unsigned int prev_vtx_count = 0;
334  unsigned int idx_offset = 0;
335  unsigned int vtx_offset = 0;
336 
337  for( unsigned int mg_i = 0; mg_i < mesh_groups.size (); ++mg_i )
338  {
339  auto& mg = mesh_groups[mg_i];
340  auto& mat = m_materials[mg_i];
341 
342  if( m_index_buffer_type == GL_UNSIGNED_SHORT )
343  {
344  auto idx_out = reinterpret_cast<GLushort*>(
345  reinterpret_cast<uintptr_t>( tmp_idx.get() ) + idx_offset );
346 
347  for( auto idx : mg.m_indices )
348  *idx_out++ = static_cast<GLushort>( idx + prev_vtx_count );
349  }
350  else if( m_index_buffer_type == GL_UNSIGNED_INT )
351  {
352  auto idx_out = reinterpret_cast<GLuint*>(
353  reinterpret_cast<uintptr_t>( tmp_idx.get() ) + idx_offset );
354 
355  for( auto idx : mg.m_indices )
356  *idx_out++ = static_cast<GLuint>( idx + prev_vtx_count );
357  }
358 
359  glBufferSubData( GL_ARRAY_BUFFER, vtx_offset, mg.m_vertices.size() * sizeof( VERTEX ),
360  mg.m_vertices.data() );
361 
362  mat.m_render_idx_buffer_offset = idx_offset;
363  mat.m_render_idx_count = mg.m_indices.size();
364 
365  prev_vtx_count += mg.m_vertices.size();
366  idx_offset += mg.m_indices.size() * idx_size;
367  vtx_offset += mg.m_vertices.size() * sizeof( VERTEX );
368  }
369 
370  glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_index_buffer );
371  glBufferData( GL_ELEMENT_ARRAY_BUFFER, idx_size * total_index_count, tmp_idx.get(),
372  GL_STATIC_DRAW );
373 
374  glBindBuffer( GL_ARRAY_BUFFER, 0 );
375  glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );
376 
377  auto end_time = std::chrono::high_resolution_clock::now();
378 
379  wxLogTrace( m_logTrace, wxT( " loaded in %u ms\n" ),
380  (unsigned int)std::chrono::duration_cast<std::chrono::milliseconds> (
381  end_time - start_time).count() );
382 }
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_bbox_index_buffer
Definition: 3d_model.h:157
GLuint m_bbox_vertex_buffer
Definition: 3d_model.h:156
SMESH * m_Meshes
The meshes list of this model.
Definition: c3dmodel.h:93
void Union(const SFVEC3F &aPoint)
Recalculate the bounding box adding a point.
Definition: bbox_3d.cpp:102
Use only diffuse material properties.
static constexpr unsigned int bbox_vtx_count
Definition: 3d_model.h:153
GLuint m_vertex_buffer
Definition: 3d_model.h:128
static constexpr unsigned int bbox_idx_count
Definition: 3d_model.h:154
bool m_have_transparent_meshes
Definition: 3d_model.h:149
GLuint m_index_buffer
Definition: 3d_model.h:129
std::vector< MATERIAL > m_materials
Definition: 3d_model.h:143
static const wxChar * m_logTrace
Definition: 3d_model.h:106
unsigned int m_MaterialsSize
Number of materials in the material array.
Definition: c3dmodel.h:95
bool IsInitialized() const
Check if this bounding box is already initialized.
Definition: bbox_3d.cpp:88
bool m_have_opaque_meshes
Definition: 3d_model.h:148
MATERIAL_MODE m_materialMode
Definition: 3d_model.h:111
GLenum m_index_buffer_type
Definition: 3d_model.h:130
SFVEC3F MaterialDiffuseToColorCAD(const SFVEC3F &aDiffuseColor)
Definition: 3d_math.h:147
std::vector< BBOX_3D > m_meshes_bbox
individual bbox for each mesh
Definition: 3d_model.h:114
SMATERIAL * m_Materials
The materials list of this model.
Definition: c3dmodel.h:96
GLenum m_bbox_index_buffer_type
Definition: 3d_model.h:158
unsigned int m_MeshesSize
Number of meshes in the array.
Definition: c3dmodel.h:92
BBOX_3D m_model_bbox
global bounding box for this model
Definition: 3d_model.h:113

References bbox_idx_count, bbox_vtx_count, DIFFUSE_ONLY, BBOX_3D::IsInitialized(), m_bbox_index_buffer, m_bbox_index_buffer_type, m_bbox_vertex_buffer, m_have_opaque_meshes, m_have_transparent_meshes, m_index_buffer, m_index_buffer_type, m_logTrace, m_materialMode, S3DMODEL::m_Materials, m_materials, S3DMODEL::m_MaterialsSize, S3DMODEL::m_Meshes, m_meshes_bbox, S3DMODEL::m_MeshesSize, m_model_bbox, m_vertex_buffer, MakeBbox(), MaterialDiffuseToColorCAD(), and BBOX_3D::Union().

◆ ~MODEL_3D()

MODEL_3D::~MODEL_3D ( )

Definition at line 480 of file 3d_model.cpp.

481 {
482  if( glDeleteBuffers )
483  {
484  glDeleteBuffers( 1, &m_vertex_buffer );
485  glDeleteBuffers( 1, &m_index_buffer );
486  glDeleteBuffers( 1, &m_bbox_vertex_buffer );
487  glDeleteBuffers( 1, &m_bbox_index_buffer );
488  }
489 }
GLuint m_bbox_index_buffer
Definition: 3d_model.h:157
GLuint m_bbox_vertex_buffer
Definition: 3d_model.h:156
GLuint m_vertex_buffer
Definition: 3d_model.h:128
GLuint m_index_buffer
Definition: 3d_model.h:129

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 385 of file 3d_model.cpp.

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

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 414 of file 3d_model.cpp.

416 {
417  if( aOpacity <= FLT_EPSILON )
418  return;
419 
420  if( !glBindBuffer )
421  throw std::runtime_error( "The OpenGL context no longer exists: unable to draw" );
422 
423  glBindBuffer( GL_ARRAY_BUFFER, m_vertex_buffer );
424  glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_index_buffer );
425 
426  glVertexPointer( 3, GL_FLOAT, sizeof( VERTEX ),
427  reinterpret_cast<const void*>( offsetof( VERTEX, m_pos ) ) );
428 
429  glNormalPointer( GL_BYTE, sizeof( VERTEX ),
430  reinterpret_cast<const void*>( offsetof( VERTEX, m_nrm ) ) );
431 
432  glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( VERTEX ),
433  reinterpret_cast<const void*>( m_materialMode == MATERIAL_MODE::CAD_MODE
434  ? offsetof( VERTEX, m_cad_color )
435  : offsetof( VERTEX, m_color ) ) );
436 
437  glTexCoordPointer( 2, GL_FLOAT, sizeof( VERTEX ),
438  reinterpret_cast<const void*>( offsetof( VERTEX, m_tex_uv ) ) );
439 
440  const SFVEC4F param = SFVEC4F( 1.0f, 1.0f, 1.0f, aOpacity );
441 
442  glTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, (const float*)&param.x );
443 
444  // BeginDrawMulti();
445  for( const MODEL_3D::MATERIAL& mat : m_materials )
446  {
447  if( ( mat.IsTransparent() != aTransparent )
448  && ( aOpacity >= 1.0f )
450  {
451  continue;
452  }
453 
454  switch( m_materialMode )
455  {
457  OglSetMaterial( mat, aOpacity, aUseSelectedMaterial, aSelectionColor );
458  break;
459 
461  OglSetDiffuseMaterial( mat.m_Diffuse, aOpacity, aUseSelectedMaterial, aSelectionColor );
462  break;
463 
465  OglSetDiffuseMaterial( MaterialDiffuseToColorCAD( mat.m_Diffuse ), aOpacity,
466  aUseSelectedMaterial, aSelectionColor );
467  break;
468 
469  default:
470  break;
471  }
472 
473  glDrawElements( GL_TRIANGLES, mat.m_render_idx_count, m_index_buffer_type,
474  reinterpret_cast<const void*>(
475  static_cast<uintptr_t>( mat.m_render_idx_buffer_offset ) ) );
476  }
477 }
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
Use only diffuse material properties.
GLuint m_vertex_buffer
Definition: 3d_model.h:128
GLuint m_index_buffer
Definition: 3d_model.h:129
Use all material properties from model file.
std::vector< MATERIAL > m_materials
Definition: 3d_model.h:143
MATERIAL_MODE m_materialMode
Definition: 3d_model.h:111
GLenum m_index_buffer_type
Definition: 3d_model.h:130
SFVEC3F MaterialDiffuseToColorCAD(const SFVEC3F &aDiffuseColor)
Definition: 3d_math.h:147

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 492 of file 3d_model.cpp.

493 {
494  if( !glBindBuffer )
495  throw std::runtime_error( "The OpenGL context no longer exists: unable to draw bbox" );
496 
497  glBindBuffer( GL_ARRAY_BUFFER, m_bbox_vertex_buffer );
498  glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_bbox_index_buffer );
499 
500  glVertexPointer( 3, GL_FLOAT, sizeof( VERTEX ),
501  reinterpret_cast<const void*>( offsetof( VERTEX, m_pos ) ) );
502 
503  glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( VERTEX ),
504  reinterpret_cast<const void*>( offsetof( VERTEX, m_color ) ) );
505 
506  glDrawElements( GL_LINES, bbox_idx_count, m_bbox_index_buffer_type,
507  reinterpret_cast<const void*>( 0 ) );
508 }
GLuint m_bbox_index_buffer
Definition: 3d_model.h:157
GLuint m_bbox_vertex_buffer
Definition: 3d_model.h:156
static constexpr unsigned int bbox_idx_count
Definition: 3d_model.h:154
GLenum m_bbox_index_buffer_type
Definition: 3d_model.h:158

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 511 of file 3d_model.cpp.

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

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:414

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  }
void Draw(bool aTransparent, float aOpacity, bool aUseSelectedMaterial, SFVEC3F &aSelectionColor) const
Definition: 3d_model.cpp:414

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 401 of file 3d_model.cpp.

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

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; }
BBOX_3D m_model_bbox
global bounding box for this model
Definition: 3d_model.h:113

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; }
bool m_have_opaque_meshes
Definition: 3d_model.h:148

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.

77 { return m_have_transparent_meshes; }
bool m_have_transparent_meshes
Definition: 3d_model.h:149

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 }
const SFVEC3F & Max() const
Return the maximum vertex pointer.
Definition: bbox_3d.h:198
const SFVEC3F & Min() const
Return the minimum vertex pointer.
Definition: bbox_3d.h:191
#define bbox_line(vtx_a, vtx_b)

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
staticprivate

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
staticprivate

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: