| 749 | } |
| 750 | |
| 751 | Vector3f findCenterFromFaces( const MeshTopology & topology, const VertCoords & points ) |
| 752 | { |
| 753 | MR_TIMER; |
| 754 | struct Acc |
| 755 | { |
| 756 | Vector3d areaPos; |
| 757 | double area = 0; |
| 758 | Acc operator +( const Acc & b ) |
| 759 | { |
| 760 | return { |
| 761 | .areaPos = areaPos + b.areaPos, |
| 762 | .area = area + b.area |
| 763 | }; |
| 764 | } |
| 765 | }; |
| 766 | auto acc = parallel_deterministic_reduce( tbb::blocked_range( 0_f, FaceId{ topology.faceSize() }, 1024 ), Acc{}, |
| 767 | [&] ( const auto & range, Acc curr ) |
| 768 | { |
| 769 | for ( FaceId f = range.begin(); f < range.end(); ++f ) |
| 770 | if ( topology.hasFace( f ) ) |
| 771 | { |
| 772 | double triArea = area( topology, points, f ); |
| 773 | Vector3d center( triCenter( topology, points, f ) ); |
| 774 | curr.area += triArea; |
| 775 | curr.areaPos += center * triArea; |
| 776 | } |
| 777 | return curr; |
| 778 | }, |
| 779 | [] ( auto a, auto b ) { return a + b; } ); |
| 780 | if ( acc.area <= 0 ) |
| 781 | { |
| 782 | assert( false ); |
| 783 | return {}; |
| 784 | } |
| 785 | return Vector3f{ acc.areaPos / acc.area }; |
| 786 | } |
| 787 | |
| 788 | Vector3f findCenterFromBBox( const MeshTopology & topology, const VertCoords & points ) |
| 789 | { |