File size: 1,484 Bytes
346b70f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import numpy as np

LARGE_MESH_THRESHOLD = 1000
MINIMUM_SAMPLE_COUNT = 100
MIN_AREA_WEIGHT = 1
MAX_AREA_WEIGHT = 10


def sample_colors(face_colors, sampling_ratio=0.1, face_areas=None):
    total_faces = len(face_colors)

    if total_faces > LARGE_MESH_THRESHOLD:
        number_to_sample = max(int(total_faces * sampling_ratio), MINIMUM_SAMPLE_COUNT)
        randomly_selected_indices = np.random.choice(
            total_faces, size=number_to_sample, replace=False
        )
        selected_face_colors = face_colors[randomly_selected_indices]
        print(
            f"Sampled {number_to_sample} of {total_faces} faces ({sampling_ratio*100:.1f}%)"
        )

        if face_areas is not None:
            selected_areas = face_areas[randomly_selected_indices]
            area_based_repetitions = compute_area_weights(selected_areas)
            return np.repeat(selected_face_colors, area_based_repetitions, axis=0)

        return selected_face_colors
    else:
        print(f"Using all {total_faces} faces (below sampling threshold)")

        if face_areas is not None:
            area_based_repetitions = compute_area_weights(face_areas)
            return np.repeat(face_colors, area_based_repetitions, axis=0)

        return face_colors


def compute_area_weights(areas):
    mean_area = areas.mean()
    normalized_weights = areas / mean_area
    integer_weights = normalized_weights.astype(int)
    return integer_weights.clip(MIN_AREA_WEIGHT, MAX_AREA_WEIGHT)