KiCad PCB EDA Suite
FACET Class Reference

#include <wrlfacet.h>

Public Member Functions

 FACET ()
 
void Init ()
 
bool HasMinPoints ()
 
bool HasColors ()
 
void AddVertex (WRLVEC3F &aVertex, int aIndex)
 Add the vertex and its associated index to the internal list of polygon vertices. More...
 
void AddColor (const SGCOLOR &aColor)
 Add the given RGB color to the internal list. More...
 
float CalcFaceNormal ()
 Calculate the normal to the facet assuming a CCW orientation and perform the calculation of the angle weighted vertex normals. More...
 
void Renormalize (float aMaxValue)
 
void CalcVertexNormal (int aIndex, std::list< FACET * > &aFacetList, float aCreaseAngle)
 Calculate the weighted normal for the given vertex. More...
 
bool GetWeightedNormal (int aIndex, WRLVEC3F &aNorm)
 Retrieve the angle weighted normal for the given vertex index. More...
 
bool GetFaceNormal (WRLVEC3F &aNorm)
 Retrieve the normal for this facet. More...
 
bool GetData (std::vector< WRLVEC3F > &aVertexList, std::vector< WRLVEC3F > &aNormalsList, std::vector< SGCOLOR > &aColorsList, WRL1_ORDER aVertexOrder)
 Package the internal data as triangles with corresponding per-vertex normals. More...
 
int GetMaxIndex ()
 
void CollectVertices (std::vector< std::list< FACET * > > &aFacetList)
 Add a pointer to this object at each position within aFacetList referenced by the internal vertex indices. More...
 

Private Attributes

std::vector< WRLVEC3Fvertices
 
std::vector< SGCOLORcolors
 
std::vector< int > indices
 
WRLVEC3F face_normal
 
std::vector< WRLVEC3Fnorms
 
std::vector< WRLVEC3Fvnweight
 
int maxIdx
 

Detailed Description

Definition at line 42 of file wrlfacet.h.

Constructor & Destructor Documentation

◆ FACET()

FACET::FACET ( )

Definition at line 149 of file wrlfacet.cpp.

150{
151 face_normal.x = 0.0;
152 face_normal.y = 0.0;
153 face_normal.z = 0.0;
154 maxIdx = 0;
155}
WRLVEC3F face_normal
Definition: wrlfacet.h:125
int maxIdx
Definition: wrlfacet.h:129

References face_normal, and maxIdx.

Member Function Documentation

◆ AddColor()

void FACET::AddColor ( const SGCOLOR aColor)

Add the given RGB color to the internal list.

For per-face coloring only a single color needs to be specified. For a per-vertex coloring the color must be specified for each vertex.

Definition at line 204 of file wrlfacet.cpp.

205{
206 colors.push_back( aColor );
207
208 return;
209}
std::vector< SGCOLOR > colors
Definition: wrlfacet.h:122

References colors.

Referenced by WRL2FACESET::TranslateToSG(), and WRL1FACESET::TranslateToSG().

◆ AddVertex()

void FACET::AddVertex ( WRLVEC3F aVertex,
int  aIndex 
)

Add the vertex and its associated index to the internal list of polygon vertices.

Definition at line 191 of file wrlfacet.cpp.

192{
193 if( aIndex < 0 )
194 return;
195
196 vertices.push_back( aVertex );
197 indices.push_back( aIndex );
198
199 if( aIndex > maxIdx )
200 maxIdx = aIndex;
201}
std::vector< WRLVEC3F > vertices
Definition: wrlfacet.h:121
std::vector< int > indices
Definition: wrlfacet.h:123

References indices, maxIdx, and vertices.

Referenced by WRL2FACESET::TranslateToSG(), X3DIFACESET::TranslateToSG(), and WRL1FACESET::TranslateToSG().

◆ CalcFaceNormal()

float FACET::CalcFaceNormal ( )

Calculate the normal to the facet assuming a CCW orientation and perform the calculation of the angle weighted vertex normals.

Returns
is the max. magnitude of any component of the normal or zero if there is a fault or the normal has already been calculated.

Definition at line 212 of file wrlfacet.cpp.

213{
214 // note: this calculation assumes that the face is a convex polygon;
215 // concave polygons may be supported in the future via functions which
216 // split the polygon into triangles
217
218 if( vertices.size() < 3 )
219 return 0.0;
220
221 // check if the values were already calculated
222 if( vertices.size() == vnweight.size() )
223 return 0.0;
224
225 WRLVEC3F lCPts[3];
226
227 std::vector< WRLVEC3F >::iterator sV = vertices.begin();
228 std::vector< WRLVEC3F >::iterator eV = vertices.end();
229
230 lCPts[0] = vertices.back();
231 lCPts[1] = *sV;
232 ++sV;
233 lCPts[2] = *sV;
234 ++sV;
235
236 face_normal = VCalcTriNorm( lCPts[1], lCPts[0], lCPts[2] );
237
238 vnweight.clear();
239 WRLVEC3F wnorm = face_normal;
240
241 // calculate area:
242 size_t nv = vertices.size();
243 float a1 = 0.0;
244 glm::vec3 sum( 0.0, 0.0, 0.0 );
245 size_t j = 0;
246
247 for( size_t i = 1; i < nv; ++i, ++j )
248 sum += glm::cross( vertices[j], vertices[i] );
249
250 a1 = fabs( glm::dot( face_normal, sum ) );
251 float a2 = acosf( VCalcCosAngle( lCPts[1], lCPts[0], lCPts[2] ) );
252
253 wnorm.x *= a1 * a2;
254 wnorm.y *= a1 * a2;
255 wnorm.z *= a1 * a2;
256 vnweight.push_back( wnorm );
257
258 float maxV = fabs( wnorm.x );
259 float tV = fabs( wnorm.y );
260
261 if( tV > maxV )
262 maxV = tV;
263
264 tV = fabs( wnorm.z );
265
266 if( tV > maxV )
267 maxV = tV;
268
269 while( sV != eV )
270 {
271 lCPts[0] = lCPts[1];
272 lCPts[1] = lCPts[2];
273 lCPts[2] = *sV;
274 ++sV;
275
276 wnorm = face_normal;
277 a2 = acosf( VCalcCosAngle( lCPts[1], lCPts[0], lCPts[2] ) );
278 wnorm.x *= a1 * a2;
279 wnorm.y *= a1 * a2;
280 wnorm.z *= a1 * a2;
281 vnweight.push_back( wnorm );
282
283 tV = fabs( wnorm.x );
284
285 if( tV > maxV )
286 maxV = tV;
287
288 tV = fabs( wnorm.y );
289
290 if( tV > maxV )
291 maxV = tV;
292
293 tV = fabs( wnorm.z );
294
295 if( tV > maxV )
296 maxV = tV;
297 }
298
299 lCPts[0] = lCPts[1];
300 lCPts[1] = lCPts[2];
301 lCPts[2] = vertices.front();
302
303 wnorm = face_normal;
304 a2 = acosf( VCalcCosAngle( lCPts[1], lCPts[0], lCPts[2] ) );
305 wnorm.x *= a1 * a2;
306 wnorm.y *= a1 * a2;
307 wnorm.z *= a1 * a2;
308 vnweight.push_back( wnorm );
309
310 tV = fabs( wnorm.x );
311
312 if( tV > maxV )
313 maxV = tV;
314
315 tV = fabs( wnorm.y );
316
317 if( tV > maxV )
318 maxV = tV;
319
320 tV = fabs( wnorm.z );
321
322 if( tV > maxV )
323 maxV = tV;
324
325 return maxV;
326}
std::vector< WRLVEC3F > vnweight
Definition: wrlfacet.h:127
static float VCalcCosAngle(const WRLVEC3F &p1, const WRLVEC3F &p2, const WRLVEC3F &p3)
Definition: wrlfacet.cpp:99
static WRLVEC3F VCalcTriNorm(const WRLVEC3F &p1, const WRLVEC3F &p2, const WRLVEC3F &p3)
Definition: wrlfacet.cpp:69
glm::vec3 WRLVEC3F
Definition: wrltypes.h:188

References face_normal, VCalcCosAngle(), VCalcTriNorm(), vertices, and vnweight.

◆ CalcVertexNormal()

void FACET::CalcVertexNormal ( int  aIndex,
std::list< FACET * > &  aFacetList,
float  aCreaseAngle 
)

Calculate the weighted normal for the given vertex.

Parameters
aIndexis the VRML file's Vertex Index for the vertex to be processed.
aFacetListis the list of all faces which share this vertex.

Definition at line 329 of file wrlfacet.cpp.

330{
331 if( vertices.size() < 3 )
332 return;
333
334 if( vnweight.size() != vertices.size() )
335 return;
336
337 if( norms.size() != vertices.size() )
338 norms.resize( vertices.size() );
339
340 std::vector< int >::iterator sI = indices.begin();
341 std::vector< int >::iterator eI = indices.end();
342 int idx = 0;
343
344 WRLVEC3F fp[2]; // vectors to calculate facet angle
345 fp[0].x = 0.0;
346 fp[0].y = 0.0;
347 fp[0].z = 0.0;
348
349 while( sI != eI )
350 {
351 if( *sI == aIndex )
352 {
353 // first set the default (weighted) normal value
354 norms[idx] = vnweight[idx];
355
356 // iterate over adjacent facets
357 std::list< FACET* >::iterator sF = aFacetList.begin();
358 std::list< FACET* >::iterator eF = aFacetList.end();
359
360 while( sF != eF )
361 {
362 if( this == *sF )
363 {
364 ++sF;
365 continue;
366 }
367
368 // check the crease angle limit
369 (*sF)->GetFaceNormal( fp[1] );
370
371 float thrs = VCalcCosAngle( fp[0], face_normal, fp[1] );
372
373 if( aCreaseLimit <= thrs && (*sF)->GetWeightedNormal( aIndex, fp[1] ) )
374 {
375 norms[idx].x += fp[1].x;
376 norms[idx].y += fp[1].y;
377 norms[idx].z += fp[1].z;
378 }
379
380 ++sF;
381 }
382
383 // normalize the vector
384 float dn = sqrtf( norms[idx].x * norms[idx].x
385 + norms[idx].y * norms[idx].y
386 + norms[idx].z * norms[idx].z );
387
388 if( dn > LOWER_LIMIT )
389 {
390 norms[idx].x /= dn;
391 norms[idx].y /= dn;
392 norms[idx].z /= dn;
393 }
394
395 // if the normals is an invalid normal this test will pass
396 if( fabs( norms[idx].x ) < 0.5
397 && fabs( norms[idx].y ) < 0.5
398 && fabs( norms[idx].z ) < 0.5 )
399 {
400 norms[idx] = face_normal;
401 }
402
403 return;
404 }
405
406 ++idx;
407 ++sI;
408 }
409}
std::vector< WRLVEC3F > norms
Definition: wrlfacet.h:126
#define LOWER_LIMIT
Definition: wrlfacet.cpp:34

References face_normal, indices, LOWER_LIMIT, norms, VCalcCosAngle(), vertices, and vnweight.

◆ CollectVertices()

void FACET::CollectVertices ( std::vector< std::list< FACET * > > &  aFacetList)

Add a pointer to this object at each position within aFacetList referenced by the internal vertex indices.

Definition at line 642 of file wrlfacet.cpp.

643{
644 // check if this facet may contribute anything at all
645 if( vertices.size() < 3 )
646 return;
647
648 // note: in principle this should never be invoked
649 if( (maxIdx + 1) >= (int)aFacetList.size() )
650 aFacetList.resize( static_cast<std::size_t>( maxIdx ) + 1 );
651
652 std::vector< int >::iterator sI = indices.begin();
653 std::vector< int >::iterator eI = indices.end();
654
655 while( sI != eI )
656 {
657 aFacetList[*sI].push_back( this );
658 ++sI;
659 }
660}

References indices, maxIdx, and vertices.

◆ GetData()

bool FACET::GetData ( std::vector< WRLVEC3F > &  aVertexList,
std::vector< WRLVEC3F > &  aNormalsList,
std::vector< SGCOLOR > &  aColorsList,
WRL1_ORDER  aVertexOrder 
)

Package the internal data as triangles with corresponding per-vertex normals.

Parameters
aVertexListis the list of vertices to add to.
aNormalsListis the list of per-vertex normals to add to.
aColorsListis the list of per-vertex colors (if any) to add to.
aVertexOrderinforms the function of the vertex winding order.

Definition at line 462 of file wrlfacet.cpp.

464{
465 // if no normals are calculated we simply return
466 if( norms.empty() )
467 return false;
468
469 // the output must always be triangle sets in order to conform to the
470 // requirements of the SG* classes
471 int idx[3];
472
473 idx[0] = 0;
474 idx[1] = 1;
475 idx[2] = 2;
476 WRLVEC3F tnorm;
477
478 if( aVertexOrder != WRL1_ORDER::ORD_CLOCKWISE )
479 {
480 aVertexList.push_back( vertices[idx[0]] );
481 aVertexList.push_back( vertices[idx[1]] );
482 aVertexList.push_back( vertices[idx[2]] );
483
484 aNormalsList.push_back( norms[idx[0]] );
485 aNormalsList.push_back( norms[idx[1]] );
486 aNormalsList.push_back( norms[idx[2]] );
487 }
488
489 if( aVertexOrder != WRL1_ORDER::ORD_CCW )
490 {
491 aVertexList.push_back( vertices[idx[0]] );
492 aVertexList.push_back( vertices[idx[2]] );
493 aVertexList.push_back( vertices[idx[1]] );
494
495 tnorm = norms[idx[0]];
496 tnorm.x = -tnorm.x;
497 tnorm.y = -tnorm.y;
498 tnorm.z = -tnorm.z;
499 aNormalsList.push_back( tnorm );
500
501 tnorm = norms[idx[2]];
502 tnorm.x = -tnorm.x;
503 tnorm.y = -tnorm.y;
504 tnorm.z = -tnorm.z;
505 aNormalsList.push_back( tnorm );
506
507 tnorm = norms[idx[1]];
508 tnorm.x = -tnorm.x;
509 tnorm.y = -tnorm.y;
510 tnorm.z = -tnorm.z;
511 aNormalsList.push_back( tnorm );
512 }
513
514 bool hasColor = false;
515 bool perVC = false; // per-vertex colors?
516
517 if( !colors.empty() )
518 {
519 hasColor = true;
520
521 if( colors.size() >= vertices.size() )
522 perVC = true;
523
524 if( perVC )
525 {
526 if( aVertexOrder != WRL1_ORDER::ORD_CLOCKWISE )
527 {
528 aColorsList.push_back( colors[idx[0]] );
529 aColorsList.push_back( colors[idx[1]] );
530 aColorsList.push_back( colors[idx[2]] );
531 }
532
533 if( aVertexOrder != WRL1_ORDER::ORD_CCW )
534 {
535 aColorsList.push_back( colors[idx[0]] );
536 aColorsList.push_back( colors[idx[2]] );
537 aColorsList.push_back( colors[idx[1]] );
538 }
539 }
540 else
541 {
542 if( aVertexOrder != WRL1_ORDER::ORD_CLOCKWISE )
543 {
544 aColorsList.push_back( colors[0] );
545 aColorsList.push_back( colors[0] );
546 aColorsList.push_back( colors[0] );
547 }
548
549 if( aVertexOrder != WRL1_ORDER::ORD_CCW )
550 {
551 aColorsList.push_back( colors[0] );
552 aColorsList.push_back( colors[0] );
553 aColorsList.push_back( colors[0] );
554 }
555 }
556 }
557
558 int lim = (int) vertices.size() - 1;
559
560 while( idx[2] < lim )
561 {
562 idx[1] = idx[2];
563 ++idx[2];
564
565 if( aVertexOrder != WRL1_ORDER::ORD_CLOCKWISE )
566 {
567 aVertexList.push_back( vertices[idx[0]] );
568 aVertexList.push_back( vertices[idx[1]] );
569 aVertexList.push_back( vertices[idx[2]] );
570
571 aNormalsList.push_back( norms[idx[0]] );
572 aNormalsList.push_back( norms[idx[1]] );
573 aNormalsList.push_back( norms[idx[2]] );
574 }
575
576 if( aVertexOrder != WRL1_ORDER::ORD_CCW )
577 {
578 aVertexList.push_back( vertices[idx[0]] );
579 aVertexList.push_back( vertices[idx[2]] );
580 aVertexList.push_back( vertices[idx[1]] );
581
582 tnorm = norms[idx[0]];
583 tnorm.x = -tnorm.x;
584 tnorm.y = -tnorm.y;
585 tnorm.z = -tnorm.z;
586 aNormalsList.push_back( tnorm );
587
588 tnorm = norms[idx[2]];
589 tnorm.x = -tnorm.x;
590 tnorm.y = -tnorm.y;
591 tnorm.z = -tnorm.z;
592 aNormalsList.push_back( tnorm );
593
594 tnorm = norms[idx[1]];
595 tnorm.x = -tnorm.x;
596 tnorm.y = -tnorm.y;
597 tnorm.z = -tnorm.z;
598 aNormalsList.push_back( tnorm );
599 }
600
601 if( hasColor )
602 {
603 if( perVC )
604 {
605 if( aVertexOrder != WRL1_ORDER::ORD_CLOCKWISE )
606 {
607 aColorsList.push_back( colors[idx[0]] );
608 aColorsList.push_back( colors[idx[1]] );
609 aColorsList.push_back( colors[idx[2]] );
610 }
611
612 if( aVertexOrder != WRL1_ORDER::ORD_CCW )
613 {
614 aColorsList.push_back( colors[idx[0]] );
615 aColorsList.push_back( colors[idx[2]] );
616 aColorsList.push_back( colors[idx[1]] );
617 }
618 }
619 else
620 {
621 if( aVertexOrder != WRL1_ORDER::ORD_CLOCKWISE )
622 {
623 aColorsList.push_back( colors[0] );
624 aColorsList.push_back( colors[0] );
625 aColorsList.push_back( colors[0] );
626 }
627
628 if( aVertexOrder != WRL1_ORDER::ORD_CCW )
629 {
630 aColorsList.push_back( colors[0] );
631 aColorsList.push_back( colors[0] );
632 aColorsList.push_back( colors[0] );
633 }
634 }
635 }
636 }
637
638 return true;
639}

References colors, norms, ORD_CCW, ORD_CLOCKWISE, and vertices.

◆ GetFaceNormal()

bool FACET::GetFaceNormal ( WRLVEC3F aNorm)

Retrieve the normal for this facet.

Parameters
aNormwill hold the result.

Definition at line 445 of file wrlfacet.cpp.

446{
447 aNorm.x = 0.0;
448 aNorm.y = 0.0;
449 aNorm.z = 0.0;
450
451 if( vertices.size() < 3 )
452 return false;
453
454 if( vnweight.size() != vertices.size() )
455 return false;
456
457 aNorm = face_normal;
458 return true;
459}

References face_normal, vertices, and vnweight.

◆ GetMaxIndex()

int FACET::GetMaxIndex ( )
inline

Definition at line 109 of file wrlfacet.h.

110 {
111 return maxIdx;
112 }

References maxIdx.

◆ GetWeightedNormal()

bool FACET::GetWeightedNormal ( int  aIndex,
WRLVEC3F aNorm 
)

Retrieve the angle weighted normal for the given vertex index.

Parameters
aIndexis the VRML file's Vertex Index for the vertex to be processed.
aNormwill hold the result.

Definition at line 412 of file wrlfacet.cpp.

413{
414 // the default weighted normal shall have no effect even if accidentally included
415 aNorm.x = 0.0;
416 aNorm.y = 0.0;
417 aNorm.z = 0.0;
418
419 if( vertices.size() < 3 )
420 return false;
421
422 if( vnweight.size() != vertices.size() )
423 return false;
424
425 std::vector< int >::iterator sI = indices.begin();
426 std::vector< int >::iterator eI = indices.end();
427 int idx = 0;
428
429 while( sI != eI )
430 {
431 if( *sI == aIndex )
432 {
433 aNorm = vnweight[idx];
434 return true;
435 }
436
437 ++idx;
438 ++sI;
439 }
440
441 return false;
442}

References indices, vertices, and vnweight.

◆ HasColors()

bool FACET::HasColors ( void  )

Definition at line 182 of file wrlfacet.cpp.

183{
184 if( colors.empty() )
185 return false;
186
187 return true;
188}

References colors.

Referenced by WRL1FACESET::TranslateToSG().

◆ HasMinPoints()

bool FACET::HasMinPoints ( )

Definition at line 173 of file wrlfacet.cpp.

174{
175 if( vertices.size() < 3 )
176 return false;
177
178 return true;
179}

References vertices.

Referenced by WRL2FACESET::TranslateToSG(), X3DIFACESET::TranslateToSG(), and WRL1FACESET::TranslateToSG().

◆ Init()

void FACET::Init ( )

Definition at line 158 of file wrlfacet.cpp.

159{
160 vertices.clear();
161 colors.clear();
162 indices.clear();
163 norms.clear();
164 vnweight.clear();
165
166 face_normal.x = 0.0;
167 face_normal.y = 0.0;
168 face_normal.z = 0.0;
169 maxIdx = 0;
170}

References colors, face_normal, indices, maxIdx, norms, vertices, and vnweight.

Referenced by WRL2FACESET::TranslateToSG(), X3DIFACESET::TranslateToSG(), and WRL1FACESET::TranslateToSG().

◆ Renormalize()

void FACET::Renormalize ( float  aMaxValue)

Definition at line 663 of file wrlfacet.cpp.

664{
665 if( vnweight.empty() || aMaxValue < LOWER_LIMIT )
666 return;
667
668 size_t vs = vnweight.size();
669
670 for( size_t i = 0; i < vs; ++i )
671 {
672 vnweight[i].x /= aMaxValue;
673 vnweight[i].y /= aMaxValue;
674 vnweight[i].z /= aMaxValue;
675 }
676}

References LOWER_LIMIT, and vnweight.

Member Data Documentation

◆ colors

std::vector< SGCOLOR > FACET::colors
private

Definition at line 122 of file wrlfacet.h.

Referenced by AddColor(), GetData(), HasColors(), and Init().

◆ face_normal

WRLVEC3F FACET::face_normal
private

Definition at line 125 of file wrlfacet.h.

Referenced by CalcFaceNormal(), CalcVertexNormal(), FACET(), GetFaceNormal(), and Init().

◆ indices

std::vector< int > FACET::indices
private

Definition at line 123 of file wrlfacet.h.

Referenced by AddVertex(), CalcVertexNormal(), CollectVertices(), GetWeightedNormal(), and Init().

◆ maxIdx

int FACET::maxIdx
private

Definition at line 129 of file wrlfacet.h.

Referenced by AddVertex(), CollectVertices(), FACET(), GetMaxIndex(), and Init().

◆ norms

std::vector< WRLVEC3F > FACET::norms
private

Definition at line 126 of file wrlfacet.h.

Referenced by CalcVertexNormal(), GetData(), and Init().

◆ vertices

std::vector< WRLVEC3F > FACET::vertices
private

◆ vnweight

std::vector< WRLVEC3F > FACET::vnweight
private

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