KiCad PCB EDA Suite
clayer_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 <mrluzeiro@ua.pt>
5  * Copyright (C) 1992-2016 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 
31 #include "clayer_triangles.h"
32 #include <wx/debug.h> // For the wxASSERT
33 #include <mutex>
34 #include <thread>
35 #include <atomic>
36 
37 
38 CLAYER_TRIANGLE_CONTAINER::CLAYER_TRIANGLE_CONTAINER( unsigned int aNrReservedTriangles,
39  bool aReserveNormals )
40 {
41  wxASSERT( aNrReservedTriangles > 0 );
42 
43  m_vertexs.clear();
44  m_normals.clear();
45 
46  m_vertexs.reserve( aNrReservedTriangles * 3 );
47 
48  if( aReserveNormals )
49  m_normals.reserve( aNrReservedTriangles * 3 );
50 }
51 
52 
53 void CLAYER_TRIANGLE_CONTAINER::Reserve_More( unsigned int aNrReservedTriangles,
54  bool aReserveNormals )
55 {
56  m_vertexs.reserve( m_vertexs.size() + aNrReservedTriangles * 3 );
57 
58  if( aReserveNormals )
59  m_normals.reserve( m_normals.size() + aNrReservedTriangles * 3 );
60 }
61 
62 
64  const SFVEC3F &aV2,
65  const SFVEC3F &aV3,
66  const SFVEC3F &aV4 )
67 {
68  m_vertexs.push_back( aV1 );
69  m_vertexs.push_back( aV2 );
70  m_vertexs.push_back( aV3 );
71 
72  m_vertexs.push_back( aV3 );
73  m_vertexs.push_back( aV4 );
74  m_vertexs.push_back( aV1 );
75 }
76 
77 
79  const SFVEC3F &aV2,
80  const SFVEC3F &aV3 )
81 {
82  m_vertexs.push_back( aV1 );
83  m_vertexs.push_back( aV2 );
84  m_vertexs.push_back( aV3 );
85 }
86 
87 
89  const SFVEC3F &aN2,
90  const SFVEC3F &aN3 )
91 {
92  m_normals.push_back( aN1 );
93  m_normals.push_back( aN2 );
94  m_normals.push_back( aN3 );
95 }
96 
98  const SFVEC3F &aN2,
99  const SFVEC3F &aN3,
100  const SFVEC3F &aN4 )
101 {
102  m_normals.push_back( aN1 );
103  m_normals.push_back( aN2 );
104  m_normals.push_back( aN3 );
105 
106  m_normals.push_back( aN3 );
107  m_normals.push_back( aN4 );
108  m_normals.push_back( aN1 );
109 }
110 
111 
112 CLAYER_TRIANGLES::CLAYER_TRIANGLES( unsigned int aNrReservedTriangles )
113 {
114  wxASSERT( aNrReservedTriangles > 0 );
115 
116  m_layer_top_segment_ends = new CLAYER_TRIANGLE_CONTAINER( aNrReservedTriangles,
117  false );
118  m_layer_top_triangles = new CLAYER_TRIANGLE_CONTAINER( aNrReservedTriangles,
119  false );
120  m_layer_middle_contourns_quads = new CLAYER_TRIANGLE_CONTAINER( aNrReservedTriangles,
121  true );
122  m_layer_bot_triangles = new CLAYER_TRIANGLE_CONTAINER( aNrReservedTriangles,
123  false );
124  m_layer_bot_segment_ends = new CLAYER_TRIANGLE_CONTAINER( aNrReservedTriangles,
125  false );
126 }
127 
128 
130 {
133 
134  delete m_layer_top_triangles;
136 
139 
140  delete m_layer_bot_triangles;
142 
145 }
146 
147 
148 void CLAYER_TRIANGLES::AddToMiddleContourns( const std::vector< SFVEC2F > &aContournPoints,
149  float zBot,
150  float zTop,
151  bool aInvertFaceDirection,
152  const CBVHCONTAINER2D *aThroughHoles )
153 {
154  if( aContournPoints.size() >= 4 )
155  {
156  // Calculate normals of each segment of the contourn
157  std::vector< SFVEC2F > contournNormals;
158 
159  contournNormals.clear();
160  contournNormals.resize( aContournPoints.size() - 1 );
161 
162  if( aInvertFaceDirection )
163  {
164  for( unsigned int i = 0; i < ( aContournPoints.size() - 1 ); ++i )
165  {
166  const SFVEC2F &v0 = aContournPoints[i + 0];
167  const SFVEC2F &v1 = aContournPoints[i + 1];
168  const SFVEC2F n = glm::normalize( v1 - v0 );
169 
170  contournNormals[i] = SFVEC2F( n.y,-n.x );
171  }
172  }
173  else
174  {
175  for( unsigned int i = 0; i < ( aContournPoints.size() - 1 ); ++i )
176  {
177  const SFVEC2F &v0 = aContournPoints[i + 0];
178  const SFVEC2F &v1 = aContournPoints[i + 1];
179  const SFVEC2F n = glm::normalize( v1 - v0 );
180 
181  contournNormals[i] = SFVEC2F( -n.y, n.x );
182  }
183  }
184 
185 
186  if( aInvertFaceDirection )
187  std::swap( zBot, zTop );
188 
189  const unsigned int nContournsToProcess = ( aContournPoints.size() - 1 );
190 
191  for( unsigned int i = 0; i < nContournsToProcess; ++i )
192  {
193  SFVEC2F lastNormal;
194 
195  if( i > 0 )
196  lastNormal = contournNormals[i - 1];
197  else
198  lastNormal = contournNormals[nContournsToProcess - 1];
199 
200  SFVEC2F n0 = contournNormals[i];
201 
202  // Only interpolate the normal if the angle is closer
203  if( glm::dot( n0, lastNormal ) > 0.5f )
204  n0 = glm::normalize( n0 + lastNormal );
205 
206  SFVEC2F nextNormal;
207 
208  if( i < (nContournsToProcess - 1) )
209  nextNormal = contournNormals[i + 1];
210  else
211  nextNormal = contournNormals[0];
212 
213  SFVEC2F n1 = contournNormals[i];
214 
215  if( glm::dot( n1, nextNormal ) > 0.5f )
216  n1 = glm::normalize( n1 + nextNormal );
217 
218  const SFVEC3F n3d0 = SFVEC3F( n0.x, n0.y, 0.0f );
219  const SFVEC3F n3d1 = SFVEC3F( n1.x, n1.y, 0.0f );
220 
221  const SFVEC2F &v0 = aContournPoints[i + 0];
222  const SFVEC2F &v1 = aContournPoints[i + 1];
223 
224  if( aThroughHoles && aThroughHoles->IntersectAny( RAYSEG2D( v0, v1 ) ) )
225  continue;
226  else
227  {
228  std::lock_guard<std::mutex> lock( m_middle_layer_lock );
229  m_layer_middle_contourns_quads->AddQuad( SFVEC3F( v0.x, v0.y, zTop ),
230  SFVEC3F( v1.x, v1.y, zTop ),
231  SFVEC3F( v1.x, v1.y, zBot ),
232  SFVEC3F( v0.x, v0.y, zBot ) );
233 
234  m_layer_middle_contourns_quads->AddNormal( n3d0, n3d1, n3d1, n3d0 );
235  }
236  }
237  }
238 }
239 
240 
242  float zBot,
243  float zTop,
244  double aBiuTo3Du,
245  bool aInvertFaceDirection,
246  const CBVHCONTAINER2D *aThroughHoles )
247 {
248  std::vector< SFVEC2F >contournPoints;
249 
250  contournPoints.clear();
251  contournPoints.reserve( outlinePath.PointCount() + 2 );
252 
253  const VECTOR2I &firstV = outlinePath.CPoint( 0 );
254 
255  SFVEC2F lastV = SFVEC2F( firstV.x * aBiuTo3Du,
256  -firstV.y * aBiuTo3Du );
257 
258  contournPoints.push_back( lastV );
259 
260  for( unsigned int i = 1; i < (unsigned int)outlinePath.PointCount(); ++i )
261  {
262  const VECTOR2I & v = outlinePath.CPoint( i );
263 
264  const SFVEC2F vf = SFVEC2F( v.x * aBiuTo3Du,
265  -v.y * aBiuTo3Du );
266 
267  if( vf != lastV ) // Do not add repeated points
268  {
269  lastV = vf;
270  contournPoints.push_back( vf );
271  }
272  }
273 
274  // Add first position fo the list to close the path
275  if( lastV != contournPoints[0] )
276  contournPoints.push_back( contournPoints[0] );
277 
278  AddToMiddleContourns( contournPoints, zBot, zTop, aInvertFaceDirection, aThroughHoles );
279 }
280 
281 
283  float zBot,
284  float zTop,
285  double aBiuTo3Du,
286  bool aInvertFaceDirection,
287  const CBVHCONTAINER2D *aThroughHoles )
288 {
289  if( aPolySet.OutlineCount() == 0 )
290  return;
291 
292  // Calculate an estimation of points to reserve
293  unsigned int nrContournPointsToReserve = 0;
294 
295  for( int i = 0; i < aPolySet.OutlineCount(); ++i )
296  {
297  const SHAPE_LINE_CHAIN& pathOutline = aPolySet.COutline( i );
298 
299  nrContournPointsToReserve += pathOutline.PointCount();
300 
301  for( int h = 0; h < aPolySet.HoleCount( i ); ++h )
302  {
303  const SHAPE_LINE_CHAIN &hole = aPolySet.CHole( i, h );
304 
305  nrContournPointsToReserve += hole.PointCount();
306  }
307  }
308 
309  // Request to reserve more space
310  m_layer_middle_contourns_quads->Reserve_More( nrContournPointsToReserve * 2,
311  true );
312 
313  for( int i = 0; i < aPolySet.OutlineCount(); i++ )
314  {
315  // Add outline
316  const SHAPE_LINE_CHAIN& pathOutline = aPolySet.COutline( i );
317 
318  AddToMiddleContourns( pathOutline, zBot, zTop, aBiuTo3Du, aInvertFaceDirection, aThroughHoles );
319 
320  // Add holes for this outline
321  for( int h = 0; h < aPolySet.HoleCount( i ); ++h )
322  {
323  const SHAPE_LINE_CHAIN &hole = aPolySet.CHole( i, h );
324  AddToMiddleContourns( hole, zBot, zTop, aBiuTo3Du, aInvertFaceDirection, aThroughHoles );
325  }
326  }
327 }
328 
329 
331  GLuint aTextureIndexForSegEnds,
332  float aZBot,
333  float aZTop )
334 {
335  m_zBot = aZBot;
336  m_zTop = aZTop;
337 
343 
344  if( aTextureIndexForSegEnds )
345  {
346  wxASSERT( glIsTexture( aTextureIndexForSegEnds ) );
347 
348  if( glIsTexture( aTextureIndexForSegEnds ) )
349  {
352  true,
353  aTextureIndexForSegEnds );
354 
357  false,
358  aTextureIndexForSegEnds );
359  }
360  }
361 
363  true );
364 
366  false );
367 
368 
369  if( aLayerTriangles.m_layer_middle_contourns_quads->GetVertexSize() > 0 )
370  {
373  }
374 
375  m_draw_it_transparent = false;
376  m_haveTransformation = false;
378  m_zScaleTransformation = 0.0f;
379 }
380 
381 
383 {
384  if( glIsList( m_layer_top_segment_ends ) )
385  glDeleteLists( m_layer_top_segment_ends, 1 );
386 
387  if( glIsList( m_layer_top_triangles ) )
388  glDeleteLists( m_layer_top_triangles, 1 );
389 
390  if( glIsList( m_layer_middle_contourns_quads ) )
391  glDeleteLists( m_layer_middle_contourns_quads, 1 );
392 
393  if( glIsList( m_layer_bot_triangles ) )
394  glDeleteLists( m_layer_bot_triangles, 1 );
395 
396  if( glIsList( m_layer_bot_segment_ends ) )
397  glDeleteLists( m_layer_bot_segment_ends, 1 );
398 
404 }
405 
406 
408 {
410 
411  if( glIsList( m_layer_middle_contourns_quads ) )
412  glCallList( m_layer_middle_contourns_quads );
413 
414  if( glIsList( m_layer_top_triangles ) )
415  glCallList( m_layer_top_triangles );
416 
417  if( glIsList( m_layer_top_segment_ends ) )
418  glCallList( m_layer_top_segment_ends );
419 
421 }
422 
423 
425 {
427 
428  if( glIsList( m_layer_middle_contourns_quads ) )
429  glCallList( m_layer_middle_contourns_quads );
430 
431  if( glIsList( m_layer_bot_triangles ) )
432  glCallList( m_layer_bot_triangles );
433 
434  if( glIsList( m_layer_bot_segment_ends ) )
435  glCallList( m_layer_bot_segment_ends );
436 
438 }
439 
440 
442 {
444 
445  if( glIsList( m_layer_top_triangles ) )
446  glCallList( m_layer_top_triangles );
447 
448  if( glIsList( m_layer_top_segment_ends ) )
449  glCallList( m_layer_top_segment_ends );
450 
452 }
453 
454 
456 {
458 
459  if( glIsList( m_layer_bot_triangles ) )
460  glCallList( m_layer_bot_triangles );
461 
462  if( glIsList( m_layer_bot_segment_ends ) )
463  glCallList( m_layer_bot_segment_ends );
464 
466 }
467 
468 
470 {
472 
473  if( glIsList( m_layer_middle_contourns_quads ) )
474  glCallList( m_layer_middle_contourns_quads );
475 
477 }
478 
479 
480 void CLAYERS_OGL_DISP_LISTS::DrawAll( bool aDrawMiddle ) const
481 {
483 
484  if( aDrawMiddle )
485  if( glIsList( m_layer_middle_contourns_quads ) )
486  glCallList( m_layer_middle_contourns_quads );
487 
488  if( glIsList( m_layer_top_triangles ) )
489  glCallList( m_layer_top_triangles );
490 
491  if( glIsList( m_layer_bot_triangles ) )
492  glCallList( m_layer_bot_triangles );
493 
494  if( glIsList( m_layer_top_segment_ends ) )
495  glCallList( m_layer_top_segment_ends );
496 
497  if( glIsList( m_layer_bot_segment_ends ) )
498  glCallList( m_layer_bot_segment_ends );
499 
501 }
502 
503 
504 void CLAYERS_OGL_DISP_LISTS::DrawAllCameraCulled(float zCameraPos, bool aDrawMiddle ) const
505 {
506  zCameraPos = m_haveTransformation?( (zCameraPos - m_zPositionTransformation ) /
507  m_zScaleTransformation ):zCameraPos;
508 
509  if( aDrawMiddle )
510  DrawMiddle();
511 
512  if( zCameraPos > m_zTop )
513  {
514  DrawTop();
515  }
516  else
517  {
518  if( zCameraPos < m_zBot )
519  {
520  DrawBot();
521  }
522  else
523  {
524  // If camera is in the middle dont draw it
525  }
526  }
527 }
528 
529 
531  const CLAYERS_OGL_DISP_LISTS *aLayerToSubtractA,
532  const CLAYERS_OGL_DISP_LISTS *aLayerToSubtractB,
533  const CLAYERS_OGL_DISP_LISTS *aLayerToSubtractC,
534  const CLAYERS_OGL_DISP_LISTS *aLayerToSubtractD ) const
535 {
536  glClearStencil( 0x00 );
537  glClear( GL_STENCIL_BUFFER_BIT );
538 
539  glEnable( GL_CULL_FACE );
540  glCullFace( GL_BACK );
541 
542  glDisable( GL_DEPTH_TEST );
543  glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
544  glDepthMask( GL_FALSE );
545  glEnable( GL_STENCIL_TEST );
546  glStencilFunc( GL_ALWAYS, 1, 0 );
547  glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );
548 
549  if( aLayerToSubtractA )
550  aLayerToSubtractA->DrawBot();
551 
552  if( aLayerToSubtractB )
553  aLayerToSubtractB->DrawBot();
554 
555  if( aLayerToSubtractC )
556  aLayerToSubtractC->DrawBot();
557 
558  if( aLayerToSubtractD )
559  aLayerToSubtractD->DrawBot();
560 
561  //if( !m_draw_it_transparent )
562  {
563  glEnable(GL_DEPTH_TEST);
564  glDepthMask(GL_TRUE);
565  }
566 
567  glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
568  glStencilFunc( GL_EQUAL, 0, 1 );
569  glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
570  DrawBot();
571 
572  glDisable( GL_DEPTH_TEST );
573  glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
574  glDepthMask( GL_FALSE );
575  glEnable( GL_STENCIL_TEST );
576  glStencilFunc( GL_ALWAYS, 2, 0 );
577  glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );
578 
579  if( aLayerToSubtractA )
580  aLayerToSubtractA->DrawTop();
581 
582  if( aLayerToSubtractB )
583  aLayerToSubtractB->DrawTop();
584 
585  if( aLayerToSubtractC )
586  aLayerToSubtractC->DrawTop();
587 
588  if( aLayerToSubtractD )
589  aLayerToSubtractD->DrawTop();
590 
591  //if( !m_draw_it_transparent )
592  {
593  glEnable(GL_DEPTH_TEST);
594  glDepthMask(GL_TRUE);
595  }
596 
597  glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
598  glStencilFunc( GL_NOTEQUAL, 2, 0x03 );
599  glStencilOp( GL_KEEP, GL_KEEP, GL_INCR );
600  DrawTop();
601 
602  if( aDrawMiddle )
603  DrawMiddle();
604 
605  glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE );
606 
607  glCullFace( GL_FRONT );
608  glStencilFunc( GL_GEQUAL, 3, 0x03 );
609  glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
610  glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
611 
612  if( aDrawMiddle )
613  {
614  if( aLayerToSubtractA )
615  aLayerToSubtractA->DrawMiddle();
616 
617  // It will not render the middle contours of the layer.
618  // It is used with vias and holes (copper vias and to subtract solder
619  // mask holes). But since in the vias, it will draw a cylinder
620  // and in soldermask it doesn't need to draw the contour.
621  // so it is not used the middle part of B
622 // if( aLayerToSubtractB )
623 // aLayerToSubtractB->DrawMiddle();
624  }
625 
626  glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE );
627 
628  glCullFace( GL_BACK );
629  glDisable( GL_STENCIL_TEST );
630 
631 /*
632  if( m_draw_it_transparent )
633  {
634  glEnable(GL_DEPTH_TEST);
635  glDepthMask(GL_TRUE);
636  }*/
637 }
638 
639 
641  float aZscale )
642 {
643  wxASSERT( aZscale > FLT_EPSILON );
644 
645  m_zPositionTransformation = aZposition;
646  m_zScaleTransformation = aZscale;
647  m_haveTransformation = true;
648 }
649 
650 
651 void CLAYERS_OGL_DISP_LISTS::SetItIsTransparent( bool aSetTransparent )
652 {
653  m_draw_it_transparent = aSetTransparent;
654 }
655 
656 
658  const CLAYER_TRIANGLE_CONTAINER *aTriangleContainer,
659  bool aIsNormalUp,
660  GLuint aTextureId ) const
661 {
662  wxASSERT( aTriangleContainer != NULL );
663 
664  wxASSERT( (aTriangleContainer->GetVertexSize() % 3) == 0 );
665 
666  // Top and Bot dont have normals array stored in container
667  wxASSERT( aTriangleContainer->GetNormalsSize() == 0 );
668 
669  if( (aTriangleContainer->GetVertexSize() > 0) &&
670  ((aTriangleContainer->GetVertexSize() % 3) == 0) )
671  {
672  GLuint listIdx = glGenLists( 1 );
673 
674  if( glIsList( listIdx ) )
675  {
676  // Prepare an array of UV text coordinates
677  SFVEC2F *uvArray = new SFVEC2F[aTriangleContainer->GetVertexSize()];
678 
679  for( unsigned int i = 0;
680  i < aTriangleContainer->GetVertexSize();
681  i += 3 )
682  {
683  uvArray[i + 0] = SFVEC2F( 1.0f, 0.0f );
684  uvArray[i + 1] = SFVEC2F( 0.0f, 1.0f );
685  uvArray[i + 2] = SFVEC2F( 0.0f, 0.0f );
686  }
687 
688  glEnableClientState( GL_TEXTURE_COORD_ARRAY );
689  glDisableClientState( GL_COLOR_ARRAY );
690  glDisableClientState( GL_NORMAL_ARRAY );
691  glEnableClientState( GL_VERTEX_ARRAY );
692  glVertexPointer( 3, GL_FLOAT, 0, aTriangleContainer->GetVertexPointer() );
693  glTexCoordPointer( 2, GL_FLOAT, 0, uvArray );
694 
695  glNewList( listIdx, GL_COMPILE );
696 
697  glDisable( GL_COLOR_MATERIAL );
698 
699  glEnable( GL_TEXTURE_2D );
700  glBindTexture( GL_TEXTURE_2D, aTextureId );
701 
703 
704  glAlphaFunc( GL_GREATER, 0.2f );
705  glEnable( GL_ALPHA_TEST );
706 
707  glNormal3f( 0.0f, 0.0f, aIsNormalUp?1.0f:-1.0f );
708 
709  glDrawArrays( GL_TRIANGLES, 0, aTriangleContainer->GetVertexSize() );
710 
711  glDisable( GL_TEXTURE_2D );
712  glDisable( GL_ALPHA_TEST );
713  glDisable( GL_BLEND );
714 
715  glEndList();
716 
717  glDisableClientState( GL_VERTEX_ARRAY );
718  glDisableClientState( GL_TEXTURE_COORD_ARRAY );
719 
720  delete [] uvArray;
721  return listIdx;
722  }
723  }
724 
725  return 0;
726 }
727 
728 
730  const CLAYER_TRIANGLE_CONTAINER *aTriangleContainer,
731  bool aIsNormalUp ) const
732 {
733  wxASSERT( aTriangleContainer != NULL );
734 
735  wxASSERT( (aTriangleContainer->GetVertexSize() % 3) == 0 );
736 
737  // Top and Bot dont have normals array stored in container
738  wxASSERT( aTriangleContainer->GetNormalsSize() == 0 );
739 
740  if( (aTriangleContainer->GetVertexSize() > 0) &&
741  ( (aTriangleContainer->GetVertexSize() % 3) == 0) )
742  {
743  const GLuint listIdx = glGenLists( 1 );
744 
745  if( glIsList( listIdx ) )
746  {
747  glDisableClientState( GL_TEXTURE_COORD_ARRAY );
748  glDisableClientState( GL_COLOR_ARRAY );
749  glDisableClientState( GL_NORMAL_ARRAY );
750  glEnableClientState( GL_VERTEX_ARRAY );
751  glVertexPointer( 3, GL_FLOAT, 0, aTriangleContainer->GetVertexPointer() );
752 
753  glNewList( listIdx, GL_COMPILE );
754 
756 
757  glNormal3f( 0.0f, 0.0f, aIsNormalUp?1.0f:-1.0f );
758 
759  glDrawArrays( GL_TRIANGLES, 0, aTriangleContainer->GetVertexSize() );
760 
761  glDisable( GL_BLEND );
762  glEndList();
763 
764  glDisableClientState( GL_VERTEX_ARRAY );
765 
766  return listIdx;
767  }
768  }
769 
770  return 0;
771 }
772 
773 
775  const CLAYER_TRIANGLE_CONTAINER *aTriangleContainer ) const
776 {
777  wxASSERT( aTriangleContainer != NULL );
778 
779  // We expect that it is a multiple of 3 vertex
780  wxASSERT( (aTriangleContainer->GetVertexSize() % 3) == 0 );
781 
782  // We expect that it is a multiple of 6 vertex (because we expect to add quads)
783  wxASSERT( (aTriangleContainer->GetVertexSize() % 6) == 0 );
784 
785  // We expect that there are normals with same size as vertex
786  wxASSERT( aTriangleContainer->GetNormalsSize() == aTriangleContainer->GetVertexSize() );
787 
788 
789  if( ( aTriangleContainer->GetVertexSize() > 0 ) &&
790  ( (aTriangleContainer->GetVertexSize() % 3) == 0 ) &&
791  ( (aTriangleContainer->GetVertexSize() % 6) == 0 ) &&
792  ( aTriangleContainer->GetNormalsSize() == aTriangleContainer->GetVertexSize() ) )
793  {
794  const GLuint listIdx = glGenLists( 1 );
795 
796  if( glIsList( listIdx ) )
797  {
798  glDisableClientState( GL_TEXTURE_COORD_ARRAY );
799  glDisableClientState( GL_COLOR_ARRAY );
800  glEnableClientState( GL_NORMAL_ARRAY );
801  glEnableClientState( GL_VERTEX_ARRAY );
802  glVertexPointer( 3, GL_FLOAT, 0, aTriangleContainer->GetVertexPointer() );
803  glNormalPointer( GL_FLOAT, 0, aTriangleContainer->GetNormalsPointer() );
804 
805  glNewList( listIdx, GL_COMPILE );
806 
808 
809  glDrawArrays( GL_TRIANGLES, 0, aTriangleContainer->GetVertexSize() );
810 
811  glDisable( GL_BLEND );
812  glEndList();
813 
814  glDisableClientState( GL_VERTEX_ARRAY );
815  glDisableClientState( GL_NORMAL_ARRAY );
816 
817  return listIdx;
818  }
819  }
820 
821  return 0;
822 }
823 
824 
826 {
828  {
829  glPopMatrix();
830  }
831 }
832 
833 
835 {
836  glEnable( GL_BLEND );
837  glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
838 }
839 
840 
842 {
844  {
845  glPushMatrix();
846  glTranslatef( 0.0f, 0.0f, m_zPositionTransformation );
847  glScalef( 1.0f, 1.0f, m_zScaleTransformation );
848  }
849 }
void DrawBotAndMiddle() const
DrawBotAndMiddle - This function calls the display lists for the botton elements and middle contourns...
int OutlineCount() const
Returns the number of outlines in the set
const float * GetNormalsPointer() const
GetNormalsPointer - Get the array of normals.
The CLAYER_TRIANGLES class stores arrays of triangles to be used to create display lists.
bool IntersectAny(const RAYSEG2D &aSegRay) const override
IntersectAny - Intersect and check if a segment ray hits a object or is inside it.
GLuint generate_middle_triangles(const CLAYER_TRIANGLE_CONTAINER *aTriangleContainer) const
unsigned int GetNormalsSize() const
GetNormalsSize.
const float * GetVertexPointer() const
GetVertexPointer - Get the array of vertexes.
const SHAPE_LINE_CHAIN & CHole(int aOutline, int aHole) const
void AddToMiddleContourns(const SHAPE_LINE_CHAIN &outlinePath, float zBot, float zTop, double aBiuTo3Du, bool aInvertFaceDirection, const CBVHCONTAINER2D *aThroughHoles=nullptr)
void DrawBot() const
DrawBot - This function calls the display lists for the botton elements.
int PointCount() const
Function PointCount()
CLAYER_TRIANGLE_CONTAINER(unsigned int aNrReservedTriangles, bool aReserveNormals)
CLAYER_TRIANGLE_CONTAINER.
void ApplyScalePosition(float aZposition, float aZscale)
std::mutex m_middle_layer_lock
~CLAYER_TRIANGLES()
~CLAYER_TRIANGLES - Free containers
CLAYER_TRIANGLES(unsigned int aNrReservedTriangles)
CLAYER_TRIANGLES - initialize arrays with reserved triangles.
void DrawTop() const
DrawTop - This function calls the display lists for the top elements.
const VECTOR2I & CPoint(int aIndex) const
Function Point()
The CLAYER_TRIANGLE_CONTAINER class stores an manage vector of triangles.
glm::vec2 SFVEC2F
Definition: xv3d_types.h:45
#define NULL
void DrawAllCameraCulledSubtractLayer(bool aDrawMiddle, const CLAYERS_OGL_DISP_LISTS *aLayerToSubtractA=nullptr, const CLAYERS_OGL_DISP_LISTS *aLayerToSubtractB=nullptr, const CLAYERS_OGL_DISP_LISTS *aLayerToSubtractC=nullptr, const CLAYERS_OGL_DISP_LISTS *aLayerToSubtractD=nullptr) const
SHAPE_POLY_SET.
CLAYERS_OGL_DISP_LISTS(const CLAYER_TRIANGLES &aLayerTriangles, GLuint aTextureIndexForSegEnds, float aZBot, float aZTop)
CLAYERS_OGL_DISP_LISTS - Creates the display lists for a layer.
CLAYER_TRIANGLE_CONTAINER * m_layer_top_triangles
~CLAYERS_OGL_DISP_LISTS()
~CLAYERS_OGL_DISP_LISTS - Destroy this class while free the display lists from GPU mem
CLAYER_TRIANGLE_CONTAINER * m_layer_middle_contourns_quads
SFVEC3F_VECTOR m_vertexs
vertex array
void AddNormal(const SFVEC3F &aN1, const SFVEC3F &aN2, const SFVEC3F &aN3)
AddNormal.
void AddTriangle(const SFVEC3F &aV1, const SFVEC3F &aV2, const SFVEC3F &aV3)
AddTriangle.
void DrawAllCameraCulled(float zCameraPos, bool aDrawMiddle=true) const
DrawAllCameraCulled - Draw all layers if they are visible by the camera.
void DrawTopAndMiddle() const
DrawTopAndMiddle - This function calls the display lists for the top elements and middle contourns.
GLuint generate_top_or_bot_triangles(const CLAYER_TRIANGLE_CONTAINER *aTriangleContainer, bool aIsNormalUp) const
int HoleCount(int aOutline) const
Returns the number of holes in a given outline
void DrawAll(bool aDrawMiddle=true) const
DrawAll - This function calls all the display lists.
The CLAYERS_OGL_DISP_LISTS class stores the openGL display lists to related with a layer.
void Reserve_More(unsigned int aNrReservedTriangles, bool aReserveNormals)
Reserve_More - reserve more triangles.
CLAYER_TRIANGLE_CONTAINER * m_layer_bot_segment_ends
CLAYER_TRIANGLE_CONTAINER * m_layer_bot_triangles
SHAPE_LINE_CHAIN.
glm::vec3 SFVEC3F
Definition: xv3d_types.h:47
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
void SetItIsTransparent(bool aSetTransparent)
GLuint generate_top_or_bot_seg_ends(const CLAYER_TRIANGLE_CONTAINER *aTriangleContainer, bool aIsNormalUp, GLuint aTextureId) const
void DrawMiddle() const
DrawMiddle - This function calls the display lists for the middle elements.
CLAYER_TRIANGLE_CONTAINER * m_layer_top_segment_ends
unsigned int GetVertexSize() const
GetVertexSize.
SFVEC3F_VECTOR m_normals
normals array
Definition: ray.h:110
void AddQuad(const SFVEC3F &aV1, const SFVEC3F &aV2, const SFVEC3F &aV3, const SFVEC3F &aV4)
AddQuad.