KiCad PCB EDA Suite
layer_triangles.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2015-2016 Mario Luzeiro <[email protected]>
5  * Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
25 #include "layer_triangles.h"
26 #include "../raytracing/ray.h"
27 #include <wx/debug.h> // For the wxASSERT
28 #include <mutex>
29 
30 
31 TRIANGLE_LIST::TRIANGLE_LIST( unsigned int aNrReservedTriangles, bool aReserveNormals )
32 {
33  wxASSERT( aNrReservedTriangles > 0 );
34 
35  m_vertexs.clear();
36  m_normals.clear();
37 
38  m_vertexs.reserve( aNrReservedTriangles * 3 );
39 
40  if( aReserveNormals )
41  m_normals.reserve( aNrReservedTriangles * 3 );
42 }
43 
44 
45 void TRIANGLE_LIST::Reserve_More( unsigned int aNrReservedTriangles, bool aReserveNormals )
46 {
47  m_vertexs.reserve( m_vertexs.size() + aNrReservedTriangles * 3 );
48 
49  if( aReserveNormals )
50  m_normals.reserve( m_normals.size() + aNrReservedTriangles * 3 );
51 }
52 
53 
54 void TRIANGLE_LIST::AddQuad( const SFVEC3F& aV1, const SFVEC3F& aV2, const SFVEC3F& aV3,
55  const SFVEC3F& aV4 )
56 {
57  m_vertexs.push_back( aV1 );
58  m_vertexs.push_back( aV2 );
59  m_vertexs.push_back( aV3 );
60 
61  m_vertexs.push_back( aV3 );
62  m_vertexs.push_back( aV4 );
63  m_vertexs.push_back( aV1 );
64 }
65 
66 
67 void TRIANGLE_LIST::AddTriangle( const SFVEC3F& aV1, const SFVEC3F& aV2, const SFVEC3F& aV3 )
68 {
69  m_vertexs.push_back( aV1 );
70  m_vertexs.push_back( aV2 );
71  m_vertexs.push_back( aV3 );
72 }
73 
74 
75 void TRIANGLE_LIST::AddNormal( const SFVEC3F& aN1, const SFVEC3F& aN2, const SFVEC3F& aN3 )
76 {
77  m_normals.push_back( aN1 );
78  m_normals.push_back( aN2 );
79  m_normals.push_back( aN3 );
80 }
81 
82 void TRIANGLE_LIST::AddNormal( const SFVEC3F& aN1, const SFVEC3F& aN2, const SFVEC3F& aN3,
83  const SFVEC3F& aN4 )
84 {
85  m_normals.push_back( aN1 );
86  m_normals.push_back( aN2 );
87  m_normals.push_back( aN3 );
88 
89  m_normals.push_back( aN3 );
90  m_normals.push_back( aN4 );
91  m_normals.push_back( aN1 );
92 }
93 
94 
95 TRIANGLE_DISPLAY_LIST::TRIANGLE_DISPLAY_LIST( unsigned int aNrReservedTriangles )
96 {
97  wxASSERT( aNrReservedTriangles > 0 );
98 
99  m_layer_top_segment_ends = new TRIANGLE_LIST( aNrReservedTriangles, false );
100  m_layer_top_triangles = new TRIANGLE_LIST( aNrReservedTriangles, false );
101  m_layer_middle_contourns_quads = new TRIANGLE_LIST( aNrReservedTriangles, true );
102  m_layer_bot_triangles = new TRIANGLE_LIST( aNrReservedTriangles, false );
103  m_layer_bot_segment_ends = new TRIANGLE_LIST( aNrReservedTriangles, false );
104 }
105 
106 
108 {
110  m_layer_top_segment_ends = nullptr;
111 
112  delete m_layer_top_triangles;
113  m_layer_top_triangles = nullptr;
114 
117 
118  delete m_layer_bot_triangles;
119  m_layer_bot_triangles = nullptr;
120 
122  m_layer_bot_segment_ends = nullptr;
123 }
124 
125 
126 void TRIANGLE_DISPLAY_LIST::AddToMiddleContourns( const std::vector< SFVEC2F >& aContournPoints,
127  float zBot, float zTop, bool aInvertFaceDirection,
128  const BVH_CONTAINER_2D* aThroughHoles )
129 {
130  if( aContournPoints.size() >= 4 )
131  {
132  // Calculate normals of each segment of the contourn
133  std::vector< SFVEC2F > contournNormals;
134 
135  contournNormals.clear();
136  contournNormals.resize( aContournPoints.size() - 1 );
137 
138  if( aInvertFaceDirection )
139  {
140  for( unsigned int i = 0; i < ( aContournPoints.size() - 1 ); ++i )
141  {
142  const SFVEC2F& v0 = aContournPoints[i + 0];
143  const SFVEC2F& v1 = aContournPoints[i + 1];
144  const SFVEC2F n = glm::normalize( v1 - v0 );
145 
146  contournNormals[i] = SFVEC2F( n.y,-n.x );
147  }
148  }
149  else
150  {
151  for( unsigned int i = 0; i < ( aContournPoints.size() - 1 ); ++i )
152  {
153  const SFVEC2F& v0 = aContournPoints[i + 0];
154  const SFVEC2F& v1 = aContournPoints[i + 1];
155  const SFVEC2F n = glm::normalize( v1 - v0 );
156 
157  contournNormals[i] = SFVEC2F( -n.y, n.x );
158  }
159  }
160 
161 
162  if( aInvertFaceDirection )
163  std::swap( zBot, zTop );
164 
165  const unsigned int nContournsToProcess = ( aContournPoints.size() - 1 );
166 
167  for( unsigned int i = 0; i < nContournsToProcess; ++i )
168  {
169  SFVEC2F lastNormal;
170 
171  if( i > 0 )
172  lastNormal = contournNormals[i - 1];
173  else
174  lastNormal = contournNormals[nContournsToProcess - 1];
175 
176  SFVEC2F n0 = contournNormals[i];
177 
178  // Only interpolate the normal if the angle is closer
179  if( glm::dot( n0, lastNormal ) > 0.5f )
180  n0 = glm::normalize( n0 + lastNormal );
181 
182  SFVEC2F nextNormal;
183 
184  if( i < (nContournsToProcess - 1) )
185  nextNormal = contournNormals[i + 1];
186  else
187  nextNormal = contournNormals[0];
188 
189  SFVEC2F n1 = contournNormals[i];
190 
191  if( glm::dot( n1, nextNormal ) > 0.5f )
192  n1 = glm::normalize( n1 + nextNormal );
193 
194  const SFVEC3F n3d0 = SFVEC3F( n0.x, n0.y, 0.0f );
195  const SFVEC3F n3d1 = SFVEC3F( n1.x, n1.y, 0.0f );
196 
197  const SFVEC2F& v0 = aContournPoints[i + 0];
198  const SFVEC2F& v1 = aContournPoints[i + 1];
199 
200  if( aThroughHoles && aThroughHoles->IntersectAny( RAYSEG2D( v0, v1 ) ) )
201  {
202  continue;
203  }
204  else
205  {
206  std::lock_guard<std::mutex> lock( m_middle_layer_lock );
207  m_layer_middle_contourns_quads->AddQuad( SFVEC3F( v0.x, v0.y, zTop ),
208  SFVEC3F( v1.x, v1.y, zTop ),
209  SFVEC3F( v1.x, v1.y, zBot ),
210  SFVEC3F( v0.x, v0.y, zBot ) );
211 
212  m_layer_middle_contourns_quads->AddNormal( n3d0, n3d1, n3d1, n3d0 );
213  }
214  }
215  }
216 }
217 
218 
220  float zTop, double aBiuTo3Du,
221  bool aInvertFaceDirection,
222  const BVH_CONTAINER_2D* aThroughHoles )
223 {
224  std::vector< SFVEC2F >contournPoints;
225 
226  contournPoints.clear();
227  contournPoints.reserve( outlinePath.PointCount() + 2 );
228 
229  const VECTOR2I& firstV = outlinePath.CPoint( 0 );
230 
231  SFVEC2F lastV = SFVEC2F( firstV.x * aBiuTo3Du, -firstV.y * aBiuTo3Du );
232 
233  contournPoints.push_back( lastV );
234 
235  for( unsigned int i = 1; i < (unsigned int)outlinePath.PointCount(); ++i )
236  {
237  const VECTOR2I& v = outlinePath.CPoint( i );
238 
239  const SFVEC2F vf = SFVEC2F( v.x * aBiuTo3Du, -v.y * aBiuTo3Du );
240 
241  if( vf != lastV ) // Do not add repeated points
242  {
243  lastV = vf;
244  contournPoints.push_back( vf );
245  }
246  }
247 
248  // Add first position fo the list to close the path
249  if( lastV != contournPoints[0] )
250  contournPoints.push_back( contournPoints[0] );
251 
252  AddToMiddleContourns( contournPoints, zBot, zTop, aInvertFaceDirection, aThroughHoles );
253 }
254 
255 
257  float zTop, double aBiuTo3Du,
258  bool aInvertFaceDirection,
259  const BVH_CONTAINER_2D* aThroughHoles )
260 {
261  if( aPolySet.OutlineCount() == 0 )
262  return;
263 
264  // Calculate an estimation of points to reserve
265  unsigned int nrContournPointsToReserve = 0;
266 
267  for( int i = 0; i < aPolySet.OutlineCount(); ++i )
268  {
269  const SHAPE_LINE_CHAIN& pathOutline = aPolySet.COutline( i );
270 
271  nrContournPointsToReserve += pathOutline.PointCount();
272 
273  for( int h = 0; h < aPolySet.HoleCount( i ); ++h )
274  {
275  const SHAPE_LINE_CHAIN& hole = aPolySet.CHole( i, h );
276 
277  nrContournPointsToReserve += hole.PointCount();
278  }
279  }
280 
281  // Request to reserve more space
282  m_layer_middle_contourns_quads->Reserve_More( nrContournPointsToReserve * 2, true );
283 
284  for( int i = 0; i < aPolySet.OutlineCount(); i++ )
285  {
286  // Add outline
287  const SHAPE_LINE_CHAIN& pathOutline = aPolySet.COutline( i );
288 
289  AddToMiddleContourns( pathOutline, zBot, zTop, aBiuTo3Du, aInvertFaceDirection,
290  aThroughHoles );
291 
292  // Add holes for this outline
293  for( int h = 0; h < aPolySet.HoleCount( i ); ++h )
294  {
295  const SHAPE_LINE_CHAIN& hole = aPolySet.CHole( i, h );
296  AddToMiddleContourns( hole, zBot, zTop, aBiuTo3Du, aInvertFaceDirection,
297  aThroughHoles );
298  }
299  }
300 }
301 
302 
304  GLuint aTextureIndexForSegEnds,
305  float aZBot, float aZTop )
306 {
307  m_zBot = aZBot;
308  m_zTop = aZTop;
309 
315 
316  if( aTextureIndexForSegEnds )
317  {
318  wxASSERT( glIsTexture( aTextureIndexForSegEnds ) );
319 
320  if( glIsTexture( aTextureIndexForSegEnds ) )
321  {
324  true, aTextureIndexForSegEnds );
325 
328  false, aTextureIndexForSegEnds );
329  }
330  }
331 
333  true );
334 
336  false );
337 
338 
339  if( aLayerTriangles.m_layer_middle_contourns_quads->GetVertexSize() > 0 )
340  {
343  }
344 
345  m_draw_it_transparent = false;
346  m_haveTransformation = false;
348  m_zScaleTransformation = 0.0f;
349 }
350 
351 
353 {
354  if( glIsList( m_layer_top_segment_ends ) )
355  glDeleteLists( m_layer_top_segment_ends, 1 );
356 
357  if( glIsList( m_layer_top_triangles ) )
358  glDeleteLists( m_layer_top_triangles, 1 );
359 
360  if( glIsList( m_layer_middle_contourns_quads ) )
361  glDeleteLists( m_layer_middle_contourns_quads, 1 );
362 
363  if( glIsList( m_layer_bot_triangles ) )
364  glDeleteLists( m_layer_bot_triangles, 1 );
365 
366  if( glIsList( m_layer_bot_segment_ends ) )
367  glDeleteLists( m_layer_bot_segment_ends, 1 );
368 
374 }
375 
376 
378 {
380 
381  if( glIsList( m_layer_middle_contourns_quads ) )
382  glCallList( m_layer_middle_contourns_quads );
383 
384  if( glIsList( m_layer_top_triangles ) )
385  glCallList( m_layer_top_triangles );
386 
387  if( glIsList( m_layer_top_segment_ends ) )
388  glCallList( m_layer_top_segment_ends );
389 
391 }
392 
393 
395 {
397 
398  if( glIsList( m_layer_middle_contourns_quads ) )
399  glCallList( m_layer_middle_contourns_quads );
400 
401  if( glIsList( m_layer_bot_triangles ) )
402  glCallList( m_layer_bot_triangles );
403 
404  if( glIsList( m_layer_bot_segment_ends ) )
405  glCallList( m_layer_bot_segment_ends );
406 
408 }
409 
410 
412 {
414 
415  if( glIsList( m_layer_top_triangles ) )
416  glCallList( m_layer_top_triangles );
417 
418  if( glIsList( m_layer_top_segment_ends ) )
419  glCallList( m_layer_top_segment_ends );
420 
422 }
423 
424 
426 {
428 
429  if( glIsList( m_layer_bot_triangles ) )
430  glCallList( m_layer_bot_triangles );
431 
432  if( glIsList( m_layer_bot_segment_ends ) )
433  glCallList( m_layer_bot_segment_ends );
434 
436 }
437 
438 
440 {
442 
443  if( glIsList( m_layer_middle_contourns_quads ) )
444  glCallList( m_layer_middle_contourns_quads );
445 
447 }
448 
449 
450 void OPENGL_RENDER_LIST::DrawAll( bool aDrawMiddle ) const
451 {
453 
454  if( aDrawMiddle )
455  if( glIsList( m_layer_middle_contourns_quads ) )
456  glCallList( m_layer_middle_contourns_quads );
457 
458  if( glIsList( m_layer_top_triangles ) )
459  glCallList( m_layer_top_triangles );
460 
461  if( glIsList( m_layer_bot_triangles ) )
462  glCallList( m_layer_bot_triangles );
463 
464  if( glIsList( m_layer_top_segment_ends ) )
465  glCallList( m_layer_top_segment_ends );
466 
467  if( glIsList( m_layer_bot_segment_ends ) )
468  glCallList( m_layer_bot_segment_ends );
469 
471 }
472 
473 
474 void OPENGL_RENDER_LIST::DrawAllCameraCulled( float zCameraPos, bool aDrawMiddle ) const
475 {
476  zCameraPos = m_haveTransformation
477  ? ( ( zCameraPos - m_zPositionTransformation ) / m_zScaleTransformation )
478  : zCameraPos;
479 
480  if( aDrawMiddle )
481  DrawMiddle();
482 
483  if( zCameraPos > m_zTop )
484  {
485  DrawTop();
486  }
487  else
488  {
489  if( zCameraPos < m_zBot )
490  {
491  DrawBot();
492  }
493  else
494  {
495  // If camera is in the middle dont draw it.
496  }
497  }
498 }
499 
500 
502  const OPENGL_RENDER_LIST* aLayerToSubtractA,
503  const OPENGL_RENDER_LIST* aLayerToSubtractB,
504  const OPENGL_RENDER_LIST* aLayerToSubtractC,
505  const OPENGL_RENDER_LIST* aLayerToSubtractD ) const
506 {
507  glClearStencil( 0x00 );
508  glClear( GL_STENCIL_BUFFER_BIT );
509 
510  glEnable( GL_CULL_FACE );
511  glCullFace( GL_BACK );
512 
513  glDisable( GL_DEPTH_TEST );
514  glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
515  glDepthMask( GL_FALSE );
516  glEnable( GL_STENCIL_TEST );
517  glStencilFunc( GL_ALWAYS, 1, 0 );
518  glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );
519 
520  if( aLayerToSubtractA )
521  aLayerToSubtractA->DrawBot();
522 
523  if( aLayerToSubtractB )
524  aLayerToSubtractB->DrawBot();
525 
526  if( aLayerToSubtractC )
527  aLayerToSubtractC->DrawBot();
528 
529  if( aLayerToSubtractD )
530  aLayerToSubtractD->DrawBot();
531 
532  glEnable(GL_DEPTH_TEST);
533  glDepthMask(GL_TRUE);
534 
535  glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
536  glStencilFunc( GL_EQUAL, 0, 1 );
537  glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
538  DrawBot();
539 
540  glDisable( GL_DEPTH_TEST );
541  glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
542  glDepthMask( GL_FALSE );
543  glEnable( GL_STENCIL_TEST );
544  glStencilFunc( GL_ALWAYS, 2, 0 );
545  glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );
546 
547  if( aLayerToSubtractA )
548  aLayerToSubtractA->DrawTop();
549 
550  if( aLayerToSubtractB )
551  aLayerToSubtractB->DrawTop();
552 
553  if( aLayerToSubtractC )
554  aLayerToSubtractC->DrawTop();
555 
556  if( aLayerToSubtractD )
557  aLayerToSubtractD->DrawTop();
558 
559  glEnable(GL_DEPTH_TEST);
560  glDepthMask(GL_TRUE);
561  glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
562  glStencilFunc( GL_NOTEQUAL, 2, 0x03 );
563  glStencilOp( GL_KEEP, GL_KEEP, GL_INCR );
564  DrawTop();
565 
566  if( aDrawMiddle )
567  DrawMiddle();
568 
569  glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE );
570 
571  glCullFace( GL_FRONT );
572  glStencilFunc( GL_GEQUAL, 3, 0x03 );
573  glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
574  glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
575 
576  if( aDrawMiddle )
577  {
578  if( aLayerToSubtractA )
579  aLayerToSubtractA->DrawMiddle();
580  }
581 
582  glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE );
583 
584  glCullFace( GL_BACK );
585  glDisable( GL_STENCIL_TEST );
586 }
587 
588 
589 void OPENGL_RENDER_LIST::ApplyScalePosition( float aZposition, float aZscale )
590 {
591  wxASSERT( aZscale > FLT_EPSILON );
592 
593  m_zPositionTransformation = aZposition;
594  m_zScaleTransformation = aZscale;
595  m_haveTransformation = true;
596 }
597 
598 
599 void OPENGL_RENDER_LIST::SetItIsTransparent( bool aSetTransparent )
600 {
601  m_draw_it_transparent = aSetTransparent;
602 }
603 
604 
606  const TRIANGLE_LIST* aTriangleContainer, bool aIsNormalUp, GLuint aTextureId ) const
607 {
608  wxASSERT( aTriangleContainer != nullptr );
609 
610  wxASSERT( ( aTriangleContainer->GetVertexSize() % 3 ) == 0 );
611 
612  // Top and Bot dont have normals array stored in container
613  wxASSERT( aTriangleContainer->GetNormalsSize() == 0 );
614 
615  if( ( aTriangleContainer->GetVertexSize() > 0 )
616  && ( ( aTriangleContainer->GetVertexSize() % 3 ) == 0 ) )
617  {
618  GLuint listIdx = glGenLists( 1 );
619 
620  if( glIsList( listIdx ) )
621  {
622  // Prepare an array of UV text coordinates
623  SFVEC2F* uvArray = new SFVEC2F[aTriangleContainer->GetVertexSize()];
624 
625  for( unsigned int i = 0; i < aTriangleContainer->GetVertexSize(); i += 3 )
626  {
627  uvArray[i + 0] = SFVEC2F( 1.0f, 0.0f );
628  uvArray[i + 1] = SFVEC2F( 0.0f, 1.0f );
629  uvArray[i + 2] = SFVEC2F( 0.0f, 0.0f );
630  }
631 
632  glEnableClientState( GL_TEXTURE_COORD_ARRAY );
633  glDisableClientState( GL_COLOR_ARRAY );
634  glDisableClientState( GL_NORMAL_ARRAY );
635  glEnableClientState( GL_VERTEX_ARRAY );
636  glVertexPointer( 3, GL_FLOAT, 0, aTriangleContainer->GetVertexPointer() );
637  glTexCoordPointer( 2, GL_FLOAT, 0, uvArray );
638 
639  glNewList( listIdx, GL_COMPILE );
640 
641  glDisable( GL_COLOR_MATERIAL );
642 
643  glEnable( GL_TEXTURE_2D );
644  glBindTexture( GL_TEXTURE_2D, aTextureId );
645 
646  glAlphaFunc( GL_GREATER, 0.2f );
647  glEnable( GL_ALPHA_TEST );
648 
649  glNormal3f( 0.0f, 0.0f, aIsNormalUp?1.0f:-1.0f );
650 
651  glDrawArrays( GL_TRIANGLES, 0, aTriangleContainer->GetVertexSize() );
652 
653  glBindTexture( GL_TEXTURE_2D, 0 );
654  glDisable( GL_TEXTURE_2D );
655  glDisable( GL_ALPHA_TEST );
656  glDisable( GL_BLEND );
657 
658  glEndList();
659 
660  glDisableClientState( GL_VERTEX_ARRAY );
661  glDisableClientState( GL_TEXTURE_COORD_ARRAY );
662 
663  delete [] uvArray;
664  return listIdx;
665  }
666  }
667 
668  return 0;
669 }
670 
671 
673  bool aIsNormalUp ) const
674 {
675  wxASSERT( aTriangleContainer != nullptr );
676 
677  wxASSERT( ( aTriangleContainer->GetVertexSize() % 3 ) == 0 );
678 
679  // Top and Bot dont have normals array stored in container
680  wxASSERT( aTriangleContainer->GetNormalsSize() == 0 );
681 
682  if( ( aTriangleContainer->GetVertexSize() > 0 )
683  && ( ( aTriangleContainer->GetVertexSize() % 3 ) == 0 ) )
684  {
685  const GLuint listIdx = glGenLists( 1 );
686 
687  if( glIsList( listIdx ) )
688  {
689  glDisableClientState( GL_TEXTURE_COORD_ARRAY );
690  glDisableClientState( GL_COLOR_ARRAY );
691  glDisableClientState( GL_NORMAL_ARRAY );
692  glEnableClientState( GL_VERTEX_ARRAY );
693  glVertexPointer( 3, GL_FLOAT, 0, aTriangleContainer->GetVertexPointer() );
694 
695  glNewList( listIdx, GL_COMPILE );
696 
698 
699  glNormal3f( 0.0f, 0.0f, aIsNormalUp?1.0f:-1.0f );
700 
701  glDrawArrays( GL_TRIANGLES, 0, aTriangleContainer->GetVertexSize() );
702 
703  glDisable( GL_BLEND );
704  glEndList();
705 
706  glDisableClientState( GL_VERTEX_ARRAY );
707 
708  return listIdx;
709  }
710  }
711 
712  return 0;
713 }
714 
715 
717  const TRIANGLE_LIST* aTriangleContainer ) const
718 {
719  wxASSERT( aTriangleContainer != nullptr );
720 
721  // We expect that it is a multiple of 3 vertex
722  wxASSERT( ( aTriangleContainer->GetVertexSize() % 3 ) == 0 );
723 
724  // We expect that it is a multiple of 6 vertex (because we expect to add quads)
725  wxASSERT( (aTriangleContainer->GetVertexSize() % 6 ) == 0 );
726 
727  // We expect that there are normals with same size as vertex
728  wxASSERT( aTriangleContainer->GetNormalsSize() == aTriangleContainer->GetVertexSize() );
729 
730  if( ( aTriangleContainer->GetVertexSize() > 0 )
731  && ( ( aTriangleContainer->GetVertexSize() % 3 ) == 0 )
732  && ( ( aTriangleContainer->GetVertexSize() % 6 ) == 0 )
733  && ( aTriangleContainer->GetNormalsSize() == aTriangleContainer->GetVertexSize() ) )
734  {
735  const GLuint listIdx = glGenLists( 1 );
736 
737  if( glIsList( listIdx ) )
738  {
739  glDisableClientState( GL_TEXTURE_COORD_ARRAY );
740  glDisableClientState( GL_COLOR_ARRAY );
741  glEnableClientState( GL_NORMAL_ARRAY );
742  glEnableClientState( GL_VERTEX_ARRAY );
743  glVertexPointer( 3, GL_FLOAT, 0, aTriangleContainer->GetVertexPointer() );
744  glNormalPointer( GL_FLOAT, 0, aTriangleContainer->GetNormalsPointer() );
745 
746  glNewList( listIdx, GL_COMPILE );
747 
749 
750  glDrawArrays( GL_TRIANGLES, 0, aTriangleContainer->GetVertexSize() );
751 
752  glDisable( GL_BLEND );
753  glEndList();
754 
755  glDisableClientState( GL_VERTEX_ARRAY );
756  glDisableClientState( GL_NORMAL_ARRAY );
757 
758  return listIdx;
759  }
760  }
761 
762  return 0;
763 }
764 
765 
767 {
769  {
770  glPopMatrix();
771  }
772 }
773 
774 
776 {
777  glEnable( GL_BLEND );
778  glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
779 }
780 
781 
783 {
785  {
786  glPushMatrix();
787  glTranslatef( 0.0f, 0.0f, m_zPositionTransformation );
788  glScalef( 1.0f, 1.0f, m_zScaleTransformation );
789  }
790 }
Container to manage a vector of triangles.
TRIANGLE_LIST(unsigned int aNrReservedTriangles, bool aReserveNormals)
int OutlineCount() const
Return the number of vertices in a given outline/hole.
bool IntersectAny(const RAYSEG2D &aSegRay) const override
Intersect and check if a segment ray hits a object or is inside it.
unsigned int GetVertexSize() const
Store arrays of triangles to be used to create display lists.
void DrawBotAndMiddle() const
Call the display lists for the bottom elements and middle contours.
void DrawTop() const
Call the display lists for the top elements.
void DrawAllCameraCulledSubtractLayer(bool aDrawMiddle, const OPENGL_RENDER_LIST *aLayerToSubtractA=nullptr, const OPENGL_RENDER_LIST *aLayerToSubtractB=nullptr, const OPENGL_RENDER_LIST *aLayerToSubtractC=nullptr, const OPENGL_RENDER_LIST *aLayerToSubtractD=nullptr) const
void DrawAllCameraCulled(float zCameraPos, bool aDrawMiddle=true) const
Draw all layers if they are visible by the camera if camera position is above the layer.
std::mutex m_middle_layer_lock
void beginTransformation() const
TRIANGLE_LIST * m_layer_middle_contourns_quads
void DrawTopAndMiddle() const
Call the display lists for the top elements and middle contours.
void Reserve_More(unsigned int aNrReservedTriangles, bool aReserveNormals)
Reserve more triangles.
TRIANGLE_LIST * m_layer_top_triangles
TRIANGLE_DISPLAY_LIST(unsigned int aNrReservedTriangles)
Initialize arrays with reserved triangles.
void DrawMiddle() const
Call the display lists for the middle elements.
const SHAPE_LINE_CHAIN & CHole(int aOutline, int aHole) const
int PointCount() const
Return the number of points (vertices) in this line chain.
void setBlendfunction() const
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
OPENGL_RENDER_LIST(const TRIANGLE_DISPLAY_LIST &aLayerTriangles, GLuint aTextureIndexForSegEnds, float aZBot, float aZTop)
Create the display lists for a layer.
const float * GetNormalsPointer() const
Get the array of normals.
glm::vec2 SFVEC2F
Definition: xv3d_types.h:42
unsigned int GetNormalsSize() const
Represent a set of closed polygons.
void AddQuad(const SFVEC3F &aV1, const SFVEC3F &aV2, const SFVEC3F &aV3, const SFVEC3F &aV4)
void AddTriangle(const SFVEC3F &aV1, const SFVEC3F &aV2, const SFVEC3F &aV3)
void ApplyScalePosition(float aZposition, float aZscale)
void AddToMiddleContourns(const SHAPE_LINE_CHAIN &outlinePath, float zBot, float zTop, double aBiuTo3Du, bool aInvertFaceDirection, const BVH_CONTAINER_2D *aThroughHoles=nullptr)
TRIANGLE_LIST * m_layer_bot_triangles
int HoleCount(int aOutline) const
Return the reference to aIndex-th outline in the set.
void DrawAll(bool aDrawMiddle=true) const
Call to draw all the display lists.
SFVEC3F_VECTOR m_normals
normals array
Store the OpenGL display lists to related with a layer.
const float * GetVertexPointer() const
Get the array of vertices.
GLuint generate_top_or_bot_seg_ends(const TRIANGLE_LIST *aTriangleContainer, bool aIsNormalUp, GLuint aTextureId) const
void DrawBot() const
Call the display lists for the bottom elements.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
glm::vec3 SFVEC3F
Definition: xv3d_types.h:44
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
GLuint generate_middle_triangles(const TRIANGLE_LIST *aTriangleContainer) const
void SetItIsTransparent(bool aSetTransparent)
GLuint generate_top_or_bot_triangles(const TRIANGLE_LIST *aTriangleContainer, bool aIsNormalUp) const
TRIANGLE_LIST * m_layer_bot_segment_ends
GLuint m_layer_middle_contourns_quads
void endTransformation() const
~OPENGL_RENDER_LIST()
Destroy this class while free the display lists from GPU memory.
void AddNormal(const SFVEC3F &aN1, const SFVEC3F &aN2, const SFVEC3F &aN3)
TRIANGLE_LIST * m_layer_top_segment_ends
SFVEC3F_VECTOR m_vertexs
vertex array
Definition: ray.h:105