Bonsoir,
Je suis en train de rechercher une méthode efficace de compression de maillages triangulaires/quadrilataires
L'algorithme utilisé consiste à compter pour chaque sommet le nombre de faces encore non trouvées qui y sont attachées et le degrée de chacune d'elles, les faces et les sommets étant pré-ordonnés par l'ordre horaire de leur énumération selon le sens anti-horaire
(on pourrait tout aussi parfaitement utiliser le sens horaire qu'anti-horaire, le seul truc étant de toujours utiliser la même convention de sens)
Par exemple, pour un maillage de 2x2 carrés (9 sommets) , en préssortant les sommets et les faces dans un ordre spilaré, cela peut se résumer à ceci pour la partie connectivité (topologique) du maillage
4 4 4 4 4
Soit 4 faces (le premier 4) , suivi des 4 degrées des 4 faces séquentiellement énumérées (les 4x 4 suivants)
Ces 5 entiers peuvent même être compactés de la sorte **EN UN SEUL OCTET** en utilisant ce compactage en mode binaire
* degree = 7 : 1 suivi de 7 bits indiquant si les 7 faces énumérées sont triangulaires (bit à 0) ou des quadrilatères ( bit à 1)
* degree = 6 !: 01 suivi de 6 bits indiquant si les 6 faces énumérées sont triangulaires (bit à 0) ou des quadrilatères ( bit à 1)
* degree = 5 : 001 suivi de 5 bits indiquant si les 5 faces énumérées sont triangulaires (bit à 0) ou des quadrilatères ( bit à 1)
* degree = 4 : 0001 suivi de 4 bits indiquant si les 4 faces énumérées sont triangulaires (bit à 0) ou des quadrilatères ( bit à 1)
* degree = 3 : 00001 suivi de 3 bits indiquant si les 3 faces énumérées sont triangulaires (bit à 0) ou des quadrilatères ( bit à 1)
* degree = 2 : 000001 suivi de 2 bits indiquant si les 2 faces énumérées sont triangulaires (bit à 0) ou des quadrilatères ( bit à 1)
* degree = 1 : 0000001 suivi de 1 bit indiquant si la face énumérée est triangulaires (bit à 0) ou un quadrilatère ( bit à 1)
* degree = 0 : 00000000 iindiquant que ce sommet ne contient aucune information sur la connectivité
Dans l'exemple basique du maillage de 2x2 carrés, ceci ne génère donc qu'une simple valeur binaire 0001(4 faces énumérées) 1111(chacune des 4 faces est un quadrilatère), **SOIT UN SEUL OCTET** pour coder la connectivité d'un maillage de 2x2 quadrilatères = 9 sommets !!!!!
(pour l'instant, cela nécessite 8 octets de plus = 0 à la suite pour coder la connectivité/degrées des 8 derniers sommets suivants mais ils pourraient très bien être automatiquement générés, donc non sauvegardés, lorsque l'on rencontre le signal EOF indiquant que l'on arrive en fin de fichier par exemple)
Je viens de commencer un embryon de programme permettant de décoder ce style d'énumérations en une suite ordonnée de triangles utilisant une suite ordonnée des sommets selon un ordre en spirale, et pense ensuite passer à la partie encodage par la suite, une fois la partie décodage sera totalement terminée
Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109 #include <stdio.h> #include <stdlib.h> int v0 = 0; int nV = 0; void PrintTriangle( int v0, int v1, int v2 ) { printf("\tTriangle(v%d, v%d, v%d) \n", v0, v1, v2); } void PrintByte( unsigned char byte ) { for( int i = 0 ; i < 8 ; i++ ) { if ( byte & (0x80 >> i) ) { printf("1"); } else { printf("0"); } } } int AnalyseLine( char *line ) { int degrees, degree; unsigned char flag, flag1; printf("%s",line); if( line[0] != '#' ) { degrees = line[0] - '0'; flag = (degrees ? 0x80 >> (7-degrees) : 0 ); flag1 = flag >> 1; for ( int i = 1 ; i <= degrees ; i++, flag1 >>= 1 ) { degree = line[i] - '0'; if ( degree == 4 ) { flag |= flag1; } degree -= 2; for ( int j = 1 ; j <= degree ; j++) { if ( (i != degrees) || (j != degree) ) { PrintTriangle( v0, nV+1, nV+2) ; nV++; } else { PrintTriangle( v0, nV+1, v0+1); } } // printf("\n"); } printf("\n\tDegrees[v%d] = 0b", v0); PrintByte(flag); printf("\n"); v0++; } } int main( int argc, char **argv) { char line[1024]; FILE *fp; if ( (fp = fopen( argv[1] ,"r")) == NULL ) { // Cannot open the file :( return 1; } while ( !feof( fp ) ) { if( fgets(line,1024,fp) ) { AnalyseLine(line); } } for ( int v = v0 + 1 ; v <= nV + 1 ; v++ ) { printf("\tDegrees[v%d] = 0b", v); PrintByte(0); printf("\n"); } return 0; }
Et qui me génère ça :
Mais qui peut générer ceci pour une énumération un peu plus longue d'un maillage de 3x3 quads (16 sommets)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 yannoo@cyclone ~/Dev/Facets $ ./degrees 4quads.deg #*this is a window of 4 quads 44444 Triangle(v0, v1, v2) Triangle(v0, v2, v3) Triangle(v0, v3, v4) Triangle(v0, v4, v5) Triangle(v0, v5, v6) Triangle(v0, v6, v7) Triangle(v0, v7, v8) Triangle(v0, v8, v1) Degrees[v0] = 0b00011111 #*end Degrees[v2] = 0b00000000 Degrees[v3] = 0b00000000 Degrees[v4] = 0b00000000 Degrees[v5] = 0b00000000 Degrees[v6] = 0b00000000 Degrees[v7] = 0b00000000 Degrees[v8] = 0b00000000
Et on peut bien sûr y mélanger des triangles et des quadrilatères, un quandrillataire n'étant après tout que 2 triangles ayant leur hypothénuse commune
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
44
45 yannoo@cyclone ~/Dev/Facets $ ./degrees 9quads.deg # an array 3x3 quads 44444 Triangle(v0, v1, v2) Triangle(v0, v2, v3) Triangle(v0, v3, v4) Triangle(v0, v4, v5) Triangle(v0, v5, v6) Triangle(v0, v6, v7) Triangle(v0, v7, v8) Triangle(v0, v8, v1) Degrees[v0] = 0b00011111 244 Triangle(v1, v8, v9) Triangle(v1, v9, v10) Triangle(v1, v10, v11) Triangle(v1, v11, v2) Degrees[v1] = 0b00000111 244 Triangle(v2, v11, v12) Triangle(v2, v12, v13) Triangle(v2, v13, v14) Triangle(v2, v14, v3) Degrees[v2] = 0b00000111 14 Triangle(v3, v14, v15) Triangle(v3, v15, v4) Degrees[v3] = 0b00000011 # end Degrees[v5] = 0b00000000 Degrees[v6] = 0b00000000 Degrees[v7] = 0b00000000 Degrees[v8] = 0b00000000 Degrees[v9] = 0b00000000 Degrees[v10] = 0b00000000 Degrees[v11] = 0b00000000 Degrees[v12] = 0b00000000 Degrees[v13] = 0b00000000 Degrees[v14] = 0b00000000 Degrees[v15] = 0b00000000
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67 yannoo@cyclone ~/Dev/Facets $ ./degrees TriQuads.deg 43434 Triangle(v0, v1, v2) Triangle(v0, v2, v3) Triangle(v0, v3, v4) Triangle(v0, v4, v5) Triangle(v0, v5, v6) Triangle(v0, v6, v1) Degrees[v0] = 0b00010101 43343 Triangle(v1, v6, v7) Triangle(v1, v7, v8) Triangle(v1, v8, v9) Triangle(v1, v9, v10) Triangle(v1, v10, v2) Degrees[v1] = 0b00010010 3433 Triangle(v2, v10, v11) Triangle(v2, v11, v12) Triangle(v2, v12, v13) Triangle(v2, v13, v3) Degrees[v2] = 0b00001100 0 Degrees[v3] = 0b00000000 13 Triangle(v4, v13, v5) Degrees[v4] = 0b00000010 0 Degrees[v5] = 0b00000000 0 Degrees[v6] = 0b00000000 0 Degrees[v7] = 0b00000000 0 Degrees[v8] = 0b00000000 13 Triangle(v9, v13, v10) Degrees[v9] = 0b00000010 0 Degrees[v10] = 0b00000000 0 Degrees[v11] = 0b00000000 0 Degrees[v12] = 0b00000000 0 Degrees[v13] = 0b00000000 0 Degrees[v14] = 0b00000000 0 Degrees[v15] = 0b00000000
Partager