Salome HOME
Copyright update 2020
[modules/hexablock.git] / internal_doc / index.html
1 <!DOCTYPE html PUBLIC "-//w3c//dtd html 4.0 transitional//en">
2 <html><head>
3 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
4 <meta name="Generator" content="Microsoft Word 97">
5 <meta name="GENERATOR" content="Mozilla/4.7 [fr] (WinNT; I) [Netscape]">
6 <meta name="Author" content="Alain Buhsing">
7 <meta name="Classification" content="Logiciel scientifique.">
8 <meta name="Description" content="Description du logiciel Moïra">
9 <meta name="KeyWords" content="Environnement de développement, Logiciel scientifique"><title>Projet HEXABLOCK</title></head>
10 <body>
11 &nbsp;
12 <table cols="2" width="100%">
13 <tbody>
14 <tr>
15 <td><img src="logo-cs.gif" alt="Simply Moira" style="width: 145px; height: 84px;"></td>
16 <td>&nbsp;</td>
17 </tr>
18 </tbody>
19 </table>
20 <center><a name="DebutPage"></a>
21 <br>
22 <big><big><b><font size="+3"><big><big>HexaBlock</big></big></font></b></big></big><b><font size="+3"><br>
23 <br>
24 <small>Bibliothèque de formes</small><br><small><small><br>Documentation interne du moteur</small></small><br>
25 </font></b></center>
26 <blockquote><i><span style="font-weight: bold;"></span><br>
27 Ce document constitue la documentation interne du composant HEXABLOCK.<br>Ce
28 document fait partie des sources du projet et&nbsp;est géré en
29 configuration Pour le mettre à jour, utiliser kompozer, disponible sur
30 Linux<br>
31 <br>
32 </i></blockquote>
33 <hr width="100%">
34 <p><img src="blue-ball.gif" alt="o" height="12" width="12"><b> Table of contents :</b>
35 <br>
36 &nbsp;
37 </p>
38 <center>
39 <table style="width: 677px; height: 108px;">
40 <tbody>
41 <tr>
42 <td>
43 <dt><img src="green-ball.gif" alt="o" height="12" width="12"> &nbsp; <a href="#Partie_1">Partie&nbsp;1 : Prévisualisation des éléments créés</a></dt>
44 </td>
45 </tr>
46 <tr>
47 <td>
48 <dt><img src="green-ball.gif" alt="o" height="12" width="12"> &nbsp;&nbsp;<a href="#Partie_2">Partie 2 : Nouvelles fonctions de construction</a></dt><ul><li><a href="#Partie_2">Création d'hexaèdres</a></li><li><a href="#Partie_2.2">Génération d'hexaèdres par révolution</a></li><li><a href="#Partie_2.3">Substitution d'hexaèdres</a></li></ul>
49 </td>
50 </tr>
51 <tr>
52 <td><img src="green-ball.gif" alt="o" height="12" width="12"> &nbsp; <a href="#Partie_3">Partie 3 : Bibliothèques de formes</a></td>
53 </tr>
54
55
56 <tr><td><img src="green-ball.gif" alt="o" height="12" width="12"> &nbsp; <a href="#Partie_4">Partie 4 : Evolution des associations</a></td></tr></tbody>
57 </table>
58 </center>
59 <p><img src="blue-ball.gif" alt="o" height="12" width="12"><b> See also :</b></p><center>
60 <table style="width: 677px; height: 60px;">
61 <tbody>
62 <tr>
63 <td>
64 <dt><img src="green-ball.gif" alt="o" height="12" width="12"> &nbsp;&nbsp;<a href="LastNews.html"><span style="text-decoration: underline;">Last news</span></a></dt>
65 </td>
66 </tr>
67 <tr><td><img src="green-ball.gif" alt="o" height="12" width="12"> &nbsp; Last last News : Voir les <a href="#Partie_3">nouvelles formes </a><br> </td></tr><tr><td><img src="green-ball.gif" alt="o" height="12" width="12"> &nbsp; Précisions sur las <a href="AssoLines.html">associations par lignes</a></td></tr><tr>
68 <td>
69 <dt><img src="green-ball.gif" alt="o" height="12" width="12"> &nbsp;&nbsp;<a href="Questions.html"><span style="text-decoration: underline;">Frequently asked questions</span></a></dt>
70 </td>
71 </tr><tr><td><img src="green-ball.gif" alt="o" height="12" width="12"> &nbsp;&nbsp;<a href="Bugs.html">Maintenance</a></td></tr>
72
73
74
75 </tbody>
76 </table>
77 </center>
78 <p></p>
79 <hr width="100%">
80 <p><a name="Partie_1"></a></p>
81 <p><big><img src="blue-ball.gif" alt="o" height="12" width="12"><b><font size="+1"><big> Partie 1 : prévisualisation des éléments créés</big></font></b></big></p>Pour
82 que SALOME puisse prévisualiser le "document" en cours de modivication,
83 il est nécessaire&nbsp;de créer une copie de l'original. L'évolution
84 majeure du moteur &nbsp;consiste à implémenter une fonction de
85 copie.&nbsp; <br><br>Ce qui revient à ajouter dans la classe Document la méthode suivante :<br><br>
86 <table style="width: 80%; text-align: left; margin-left: auto; margin-right: auto; font-family: monospace;" border="1" cellpadding="2" cellspacing="2">
87 <tbody>
88 <tr>
89 <td>Document* copyDocument ();
90 </td>
91 </tr>
92 </tbody>
93 </table>
94 <br>La valeur rendue est le document copié.<br>Les éléments copiés sont les éléments
95 intrinsèques du document : vertices, edges, quadrangles, hexaèdres,
96 lois. Qui sont aussi ceux sauvegardés dans un texte XML. On ne stocke
97 pas les éléments intermédiaires de construction (grilles, vecteurs,
98 etc...).<br><br>Cette rège pourra être remise en cause si l'application interactive a besoin d'autres informations.<br><br>La copie se déroule ainsi :<br><ul><li>Chaque élément dispose d'un champ (nommé <span style="font-weight: bold;">clone</span>) qui permet de mémoriser l'adresse du dernier élément copié à partir de cet élément dans le cadre de la copie de document.</li><li>Copier&nbsp;les
99 éléments de bas niveau (les vertices) : méthode&nbsp;<span style="font-weight: bold;">Vertex::duplicate(Document* cible)</span>. Cette méthode ne rend pas de pointeur ; elle crée un clone du sommet courant et le mémorise sur le champ <span style="font-weight: bold;">clone</span> de la classe <span style="font-weight: bold;">Vertex</span>.</li><li>Copier&nbsp; les éléments présents de plus haut niveau dans l'ordre (edges, quads, hexas) : méthode virtuelle <span style="font-weight: bold;">EltBase::duplicate ()</span></li><ul><li>Si
100 un élément utilise n éléments de plus bas niveau, sa copie utilise les
101 copies des éléments utilisés. Il est aisé de retrouver la copie car on
102 en a stocké l'adresse.</li><li>Détail
103 : la méthode duplicate n'a pas besoin d'argument de type Document* elle
104 reprend le document cible des éléments de plus bas niveau..</li></ul><li>Copier les lois</li></ul>Les associations sont copiées lors de la copie de chaque élément.<br><br><br>
105 <a href="#DebutPage">Retour au début</a>
106 <hr width="100%">
107 <p><a name="Partie_2"></a></p>
108 <p><big><img src="blue-ball.gif" alt="o" height="12" width="12"></big><b><font size="+1"><big>
109 &nbsp;Partie 2 : Nouvelles fonctions de construction</big></font></b></p><p><big><img src="green-ball.gif" style="width: 12px; height: 12px;" alt="o"></big><b><font size="+1"><big> 2.1 Création d'Hexaèdres</big></font></b></p>
110 <p class="MsoNormal" style="text-align: left;" align="left">Il s'agit de construire un hexaèdre à partir de quadrangles déjà créés dans le
111 modèle de blocs. Cet hexaèdre est produit à partir des 4 cas suivants :</p>
112
113 <ul style="margin-top: 0cm;" type="disc"><li class="MsoNormal" style="text-align: left;">à partir de 2 quadrangles reliés ou pas,</li><li class="MsoNormal" style="text-align: left;">à partir de 3 quadrangles tous reliés,</li><li class="MsoNormal" style="text-align: left;">à partir de 4 quadrangles tous reliés,</li><li class="MsoNormal" style="text-align: left;">à partir de 5 quadrangles tous reliés.</li></ul>Les points d'entrée sont naturellement :<br><br>
114
115 <span style="font-size: 11pt; font-family: Garamond;"></span>
116 <table style="width: 80%; text-align: left; margin-left: auto; margin-right: auto; font-family: monospace;" border="1" cellpadding="2" cellspacing="2">
117 <tbody>
118 <tr>
119 <td>Hexa* <a href="#addHexa2Quads">addHexa2Quads</a> (Quad* q1,&nbsp;Quad* q2);<br>Hexa* <a href="#addHexa3Quads">addHexa3Quads</a> (Quad* q1,&nbsp;Quad* q2, Quad* q3);<br>Hexa* <a href="#addHexa4Quads">addHexa4Quads</a> (Quad* q1,&nbsp;Quad* q2, Quad* q3,&nbsp;Quad* q4);<br>Hexa* <a href="#addHexa5Quads">addHexa5Quads</a> (Quad* q1,&nbsp;Quad* q2, Quad* q3,&nbsp;Quad* q4,&nbsp;Quad* q5);</td>
120 </tr>
121 </tbody>
122 </table><p>Chacun des cas amène une discussion. La démarche est la suivante :&nbsp;</p><ul><li>Les quadrangles passés en argument dans un ordre quelconque.</li><li>Un
123 analyseur d'intersections (classe&nbsp;<span style="font-weight: bold;">AnaQuads</span>,
124 définie dans
125 HexAnaQuads.hxx) détermine les arêtes communes aux n quadrangles passés
126 en argument. et mémorise ces informations qui seront transmises aux
127 fonctions internes, afin de ne pas répêter ces calculs d'intersection.</li><li>En fonction du nombre d'arêtes communes à chaque quadrangle, on se ramène à 7 cas.&nbsp;</li><li>Si le nombre d'arêtes communes est insuffisant, le cas est rejeté.</li><li>On nomme ces cas en se servant de la nomenclature des faces dans le projet : (A, B, C, D, E,F)</li></ul>Remarques :<br><ul><li>Les quadrangles passés en arguments sont considérés comme planaires, il n'y a pas de contrôle d'arguments en entrée à ce niveau</li><li>Ils
128 sont sensés générer des quadrangles planaires et non croisés. Par
129 exemple pour addHexaQuadsACD() : il n'y a pas de contrôle de planéité
130 de la face B.&nbsp;</li></ul><img src="red-ball.gif" style="width: 12px; height: 12px;" alt="o">&nbsp;&nbsp;&nbsp; <span style="font-weight: bold;">Rappel&nbsp; :&nbsp; formalisation des Hexaèdres/Quadrangles/Vertex</span><br><br><a name="RappelNotations"></a><br>Pour rappel :<br><table style="width: 80%; text-align: left; margin-left: auto; margin-right: auto; font-family: monospace;" border="1" cellpadding="2" cellspacing="2">
131 <tbody>
132 <tr>
133 <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
134 //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; z=0&nbsp;&nbsp; z=1&nbsp;&nbsp;
135 y=0&nbsp;&nbsp; y=1&nbsp;&nbsp; x=0&nbsp; x=1<br>enum EnumHQuad&nbsp;&nbsp; {Q_A,&nbsp; Q_B,&nbsp; Q_C,&nbsp; Q_D,&nbsp; Q_E, Q_F,&nbsp; HQ_MAXI};<br></td>
136 </tr>
137 </tbody>
138 </table><br>La face A est opposée à B, C est opposée à D, E à F. La
139 position des faces&nbsp; A, C, E normales à Oz, Oy, Ox est purement
140 théorique. Elle améliore la visualisation. Les orientations sont en
141 fait&nbsp; interchangeables. On peut intervertir les couples (C,D) et
142 (E,F), on peut intervertir A et B, C et D, E et F, l'essentiel est
143 d'avoir une cohérence&nbsp; avec les autres dénominations d'edges (ac,
144 af, ad ...) ou de&nbsp;sommets (ace, acf, adf ...) &nbsp;et les
145 conventions de départ.<br><br>L'arête située la face X et la face Y est notée xy. Un sommet situé entre les 3 faces X, Y Z est noté xyz :<br><br><table style="font-family: monospace; width: 500px; text-align: left; margin-left: auto; margin-right: auto;" border="1" cellpadding="2" cellspacing="2"><tbody><tr><td style="width: 50%;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6=bde&nbsp; +----bd-----+ bdf=7<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
146 /|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /|<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; be |&nbsp;&nbsp; <span style="font-weight: bold;">B</span>&nbsp;&nbsp;&nbsp; bf |<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /&nbsp; |<br>&nbsp;&nbsp;&nbsp; 4=bce +----bc-----+...|...bcf=5<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp; de&nbsp;&nbsp;&nbsp;&nbsp; <big style="font-weight: bold;">D</big> |&nbsp;&nbsp; df<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
147 | <span style="font-weight: bold;">E</span> |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | F
148 |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
149 z<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ce&nbsp;&nbsp; |
150 <span style="font-weight: bold;">C&nbsp;</span>&nbsp;&nbsp;&nbsp; cf&nbsp;
151 |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
152 ^<br>&nbsp; 2=ade...|...+----ad-|---+ adf=3&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp; y<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
153 |&nbsp; /&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;
154 /&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
155 |&nbsp; /<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |
156 ae&nbsp;&nbsp;&nbsp; <span style="font-weight: bold;">A</span>&nbsp;&nbsp; |
157 af&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
158 | /<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
159 |/&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
160 |/&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
161 |/<br>&nbsp;&nbsp;&nbsp; 0=ace +----ac-----+ acf=1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +-----&gt;&nbsp;x<br>&nbsp;&nbsp; <br><br></td>
162 </tr>
163 </tbody>
164 </table><br><img src="red-ball.gif" style="width: 12px; height: 12px;" alt="o">&nbsp;&nbsp;&nbsp; <span style="font-weight: bold;">La classe AnaQuads</span><br><br>Cette
165 classe analyse les relations topologiques existant entre plusieurs
166 quandrangles. Un objet de ce type est créé au début de chaque fonction
167 addHexaXQuads.<br><br>Le constructeur est :<br><br>
168
169 <span style="font-size: 11pt; font-family: Garamond;"></span>
170 <table style="width: 80%; text-align: left; margin-left: auto; margin-right: auto; font-family: monospace;" border="1" cellpadding="2" cellspacing="2">
171 <tbody>
172 <tr>
173 <td>AnaQuads (Quad* q1, Quad* q2, Quad* q3=NULL, Quad* q4=NULL, Quad* q5=NULL);<br></td>
174 </tr>
175 </tbody>
176 </table><br>Les champs affectés lors de la construction de l'objet :<br><br><table style="width: 80%; text-align: left; margin-left: auto; margin-right: auto;" border="1" cellpadding="2" cellspacing="2"><tbody><tr><td>MawQuads </td><td>Constante égale à 5 5</td></tr><tr><td>int&nbsp;&nbsp;&nbsp; nbr_quads;</td><td>Nombre de quadrangles</td></tr><tr><td>int&nbsp;&nbsp;&nbsp; nbr_aretes;</td><td>Nombre total d'arêtes</td></tr><tr><td>Quad*&nbsp; tab_quads&nbsp; [i];</td><td>Le ième quadrangle passé en argument </td></tr><tr><td>int&nbsp;&nbsp;&nbsp; inter_nbre [i];</td><td>Nombre d'intersections du ième quadrangle</td></tr><tr><td>int&nbsp;&nbsp;&nbsp; inter_edge [i][j];</td><td>Nro d'arête de i intersectant le jème quadrangle</td></tr><tr><td>int&nbsp;&nbsp;&nbsp; inter_quad [i][j];</td><td>Nro de quadrangle présent sur la jème arete du iéme quad</td></tr></tbody></table><br><img src="red-ball.gif" style="width: 12px; height: 12px;" alt="o">&nbsp;&nbsp;&nbsp; <span style="font-weight: bold;">La classe Cramer</span><br><br>Cette
177 classe résout un système linéaire de n équations &nbsp;à n inconnues.
178 Quand n est "petit", n&lt;10. Peut être réutilisée sur un autre projet.
179 <br>Implémentation : HexCramer.hxx.<br>Test unitaire : test_cramer dans test_hexa1.cxx<br><br><br>
180
181 <span style="font-size: 11pt; font-family: Garamond;"></span>
182 <table style="width: 80%; text-align: left; margin-left: auto; margin-right: auto; font-family: monospace;" border="1" cellpadding="2" cellspacing="2">
183 <tbody>
184 <tr>
185 <td>int test_cramer (int nbargs, cpchar tabargs[])<br>{<br>&nbsp;&nbsp; double matrice [] = { 2, 7, 1,&nbsp; &nbsp; 0, 3, 0,&nbsp; &nbsp; 1, 9, 5 };<br>&nbsp;&nbsp; double second_membre&nbsp; [] = { 1, 1, 1 };<br>&nbsp;&nbsp; Hex::Real3&nbsp; solution;<br>&nbsp;&nbsp; <span style="font-weight: bold;">Hex::Cramer system(3)</span>; &nbsp; // On dimensionne le système de Cramer à la construction<br><br>&nbsp;&nbsp; int ier = <span style="font-weight: bold;">system.resoudre</span> (matrice, second_membre, solution);<br><br>&nbsp;&nbsp;
186 cout &lt;&lt; " Solution&nbsp; = (" &lt;&lt; solution[0] &lt;&lt; ", "
187 &lt;&lt; solution[1] &lt;&lt; ", " &lt;&lt; solution[2] <br>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&lt;&lt; "), ier = " &lt;&lt; ier &lt;&lt; endl;<br>&nbsp;
188 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
189 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Pour vérifier : <br>&nbsp;&nbsp; Hex::Real3 produit;<br>&nbsp;&nbsp; <span style="font-weight: bold;">system.multiply</span> (solution, produit);<br>&nbsp;&nbsp;
190 cout &lt;&lt; " Produit&nbsp;= (" &lt;&lt; produit[0] &lt;&lt; ", "
191 &lt;&lt; produit[1] &lt;&lt; ", " &lt;&lt; produit[2] <br>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&lt;&lt; ")" &nbsp;&lt;&lt; endl;<br>&nbsp;&nbsp; return HOK;<br>}<br></td>
192 </tr>
193 </tbody>
194 </table><br><br><br><a name="addHexa2Quads"></a><br><img src="red-ball.gif" style="width: 12px; height: 12px;" alt="o">&nbsp;&nbsp;&nbsp; <span style="font-weight: bold;">Création d'un hexaèdre avec deux quadrangles :&nbsp;</span>&nbsp;<ul><li>La classe AnaQuads ne détecte aucune arête commune : appel à addHexaQuadsAB</li><li>La classe AnaQuads&nbsp; détecte&nbsp;une arête commune : appel à addHexaQuadsAC</li></ul><table style="text-align: left; width: 90%;" border="1" cellpadding="2" cellspacing="2"><tbody><tr><td style="vertical-align: middle; text-align: center;"><p><img src="Quads_AB.png" style="width: 282px; height: 226px;" alt="En diedre"></p></td><td style="vertical-align: middle; text-align: center;"><img src="Quads_AC.png" style="width: 278px; height: 223px;" alt="Vis a vis"></td></tr><tr><td style="vertical-align: middle;">addHexa2Quads avec 2 quadrangles&nbsp; non reliés. <br>Fonction : addHexaQuadsAB</td><td style="vertical-align: middle;">addHexa2Quads avec 2 quadrangles&nbsp;&nbsp; reliés. <br>Fonction : addHexaQuadsAC</td></tr></tbody></table><p><span style="font-weight: bold;"></span></p><p><span style="font-weight: bold;">addHexaQuadAB</span> :</p>Les huits sommets sont présents, il manque quatre arêtes verticales ce, cf, df, de.<br>La
195 difficuté consiste à faire correspondre deux à deux les quatre sommets
196 de chaque quadrangle sans que les arêtes ne se croisent. La situation
197 est analogue à <span style="font-weight: bold;">mergeQuads</span> ou <span style="font-weight: bold;">joinQuads</span>, sauf que dans ces cas, on passe
198 en argument quatre vertex pour déterminer dans ambiguité les sommets
199 correspondants deux à deux. On a choisi ici
200 d'automatiser l'association :<br><ul><li>il
201 existe huit combinaisons permettant d'associer deux à deux les 4
202 sommets de 2 quadrangles : décalage de 0 à 3 dans un sens puis dans
203 l'autre. </li><li>Pour chaque combinaison, on calcule la longueur totale des 4 arêtes créées.</li><li>On retient la combinaison qui mène à une longueur minimale.</li></ul>Une fois la combinaison optimale établie :<br><ul><li>Création
204 des 4 arêtes verticales en fonction des combinaisons, stockées dans tu
205 tableau tedge[4]. Le premier vertex fourni est celui de la face A. </li><li>Création des 4 quadrangles verticaux.</li><li>Création de l'hexaèdre.</li></ul>Pour créer le&nbsp;i-ème quadrangle vertical : <br><ul><li>l'arête verticale de gauche e_left = tedge[i]</li><li>l'arête verticale de droite e_left = tedge[(i+1) modulo 4]</li><li>l'arête
206 horizontale basse s'obtient grâce à la fonction Quad::findEdge (v1,
207 v2). On recherche dans le quadrangle A l'arête dont les 2 sommets sont
208 les extrémités amont des arêtes e_left et e_right, qui par construction
209 appartiennent au quadrangle A.</li><li>idem pour&nbsp; l'arête haute ; sauf que ce sont les extrémités aval.</li></ul> <p><span style="font-weight: bold;">addHexaQuadAC</span> :</p><p>Deux
210 faces présentes A et C, une arête commune ac. Il manque deux sommets
211 bde et bdf à partir des quels on construit les arêtes manquantes bd,
212 be, de, bf, df.&nbsp;<br>On doit s'assurer de ma planéité des quadrangles créés. </p><p>La
213 solution n'est pas unique. Il existe une infinité de sommets pouvant
214 définir un hexaèdre &nbsp;conforme. On se contente ici d'en choisir une
215 et de démontrer que l'objet créé est conforme.&nbsp;</p><p>Le point bde (resp bdf) est construit en
216 sommant les vecteurs ac et ce (resp&nbsp;af et cf), ce qui revient à
217 définir un parallélogramme. On assure ainsi sa présence dans le plan E
218 (resp. F). Les faces créées E et F sont donc planaires.</p><p>Pour démontrer la planéité de la face B :<br></p><table style="width: 80%; text-align: left; margin-left: auto; margin-right: auto; font-family: monospace;" border="1" cellpadding="2" cellspacing="2">
219 <tbody>
220 <tr>
221 <td><ol><li>(ae , af)&nbsp; coplanaires (donnée)</li><li>be = ae (construction d'un parallèlogramme)</li><li>df = af &nbsp;(idem)</li><li>(1), (2), (3) =&gt; (be, bf) coplanaires </li></ol></td>
222 </tr>
223 </tbody>
224 </table><br>On procéderait de la même manière pour établir que la face D est plane.<br><br>La fonction s'écrit ainsi :<br><ul><li>q_a est le premier quadrangle fourni, q_c le second</li><li>L'edge e_ac est défini qrâce à la strucrure AnaQuads</li><li>On effectue un calcul analogue aux deux extrémités s (amont et aval) de e_ac :</li><ul><li>vx1 = extrémité étudiée de e_ac, vx2 l'autre</li><li>vxa
225 = sommet adjacent de vx1 sur&nbsp; la face A, différent de vx2. Il est
226 obtenu en prenant le sommet opposé à vx2 sur la face A. L'indice de vxa
227 dans qa vaut vx2+2 modulo 4.</li><li>de même, vxc = sommet adjacent de vx1 sur la face&nbsp; C.</li><li>Calcul des coordonnées&nbsp;et&nbsp; création du vertex tv_bdx[s] (x représente la choix entre e et f).</li><li>Création des deux arêtes manquantes&nbsp;te_bx[s] et te_dx[s]</li><li>Création des du quadrangle latéral tq_ef [s]</li></ul><li>Création de l'arête e_bd à partir dses deux vertices de&nbsp; tv_bdx</li><li>Création
228 du quadrangle D à partir de te_dx[], e_ef, te_dx[1] et de l'arête
229 opposée à e_ac dans A (fonction Quad::getOpposedEdge(e,n)</li><li>Création du quadrangle B à partir de te_bx[], e_ef, te_bx[1] et de
230 l'arête opposée à e_ac dans C (fonction Quad::getOpposedEdge(e,n)</li><li>Création de l'hexaèdre</li></ul><p><a name="addHexa3Quads"></a></p><p><img src="red-ball.gif" style="width: 12px; height: 12px;" alt="o">&nbsp;&nbsp;&nbsp; <span style="font-weight: bold;">Création d'un hexaèdre avec trois quadrangles :&nbsp;</span>&nbsp;</p><ul><li>La
231 classe AnaQuads&nbsp; détecte deux arêtes communes : appel à
232 addHexaQuadsACD. La face A sera celle qui possède deux arêtes communes,
233 la face C la suivante, D la derniére.</li><li>La classe AnaQuads&nbsp;
234 détecte trois arêtes communes : appel à addHexaQuadsACE. Ce cas est
235 symétrique, la face A sera la première de la liste, C la seconde.</li></ul><p></p><br><table style="text-align: left; width: 90%;" border="1" cellpadding="2" cellspacing="2"><tbody><tr><td style="vertical-align: middle; text-align: center;"><p><img src="Quads_ACD.png" style="width: 282px; height: 226px;" alt="En diedre"></p></td><td style="vertical-align: middle; text-align: center;"><img src="Quads_ACE.png" style="width: 278px; height: 223px;" alt="Trièdre"></td></tr><tr><td style="vertical-align: middle;">addHexa2Quads avec 3 quadrangles&nbsp;disposés en U. <br>Fonction : addHexaQuadsACD</td><td style="vertical-align: middle;">addHexa2Quads avec&nbsp; quadrangles disposés&nbsp; en trièdre<br>Fonction : addHexaQuadsACE</td></tr></tbody></table><p><br></p><p><span style="font-weight: bold;">addHexaQuadACD</span> :</p><p>Tous les sommets sont présents. Il reste à créer :</p><ul><li>Les arêtes be et bf&nbsp;</li><li>Les quadrangles E, B, F en déterminant les arêtes qui les constituent. </li></ul><p>La difficulté est d'identifier clairement les arêtes et les sommets à partir des quadrangles existant :&nbsp;</p><ul><li>q_a est le quadrangle qui possède deux arêtes communes, q_b et q_c les suivants.</li><li>On exploite les indices d'edges communs fournis par <span style="font-weight: bold;">AnaQuads</span>. Rappelons que dans un quadrangle le ième edge est adjacent aux edges i-1 et i+1 et opposé à l'edge i+2.</li><li>e_ac et e_ad sont les intersections de q_a avec q_c et q_d. (nommés ici mais non utilisés dans le programme)</li><li>e_bc est l'arête opposée à e_ac dans q_c,&nbsp;&nbsp;e_bd est l'arête opposée à e_ad dans q_d.</li><li>e_ae
236 est l'arête suivante de e_ac dans q_a, e_af &nbsp;l'arête précédente.
237 Ce choix arbitraire&nbsp; détermine les autres dénominations.</li><li>e_ce est l'arête adjacente de e_ac dans q_c qui a un sommet commun (v_ace) avec e_ae.</li><li>e_de est l'arête adjacente de e_ac dans q_d qui a un sommet commun (v_ade) avec e_ae.</li><li>v_acf est le sommet commun à e_af et e_cf</li><li>v_adf est le sommet commun à e_af et e_df</li><li>Création de l'arete e_be &nbsp;à paertir de e_bce et v_bde, puis de l'arête e_bf,</li><li>Créations des quadrangles q_b, q_e, q_f</li><li>Création de l'hexaèdre.</li></ul><p></p><p><span style="font-weight: bold;">addHexaQuadACE</span> :</p><p>Il
238 est nécessaire de créer le sommet v_bdf. Il est l'intersection des
239 plans (B, D, F). Chaque plan est défini par trois points présents sur
240 les autres quadrangles :</p><ul><li>Le plan B est défini par les sommets bcd, bce, bcf . Son vecteur normal norm_b est le produit vectoriel&nbsp;de bc par be.</li><li>Le plan D est défini par les sommets adf, ade, adb. Son vecteur normal norm_d&nbsp; est le produit vectoriel&nbsp;de ac par ae.</li><li>Le
241 plan F est défini par les sommets adf, acf, bcf.&nbsp; Son vecteur
242 normal norm_f&nbsp; est le produit vectoriel&nbsp;de ae par ec.</li></ul><p>Soit un plan P défini par un point A et un vecteur normal N. Un point M appartient à P si le produit scalaire N.AM est nul</p><p>On obtient le système d'équations <br></p><table style="width: 80%; text-align: left; margin-left: auto; margin-right: auto; font-family: monospace;" border="1" cellpadding="2" cellspacing="2">
243 <tbody>
244 <tr>
245 <td><ol><li>(bdf,bce) . norm_b = 0</li><li>(bdf,ade) . norm_d = 0</li><li>(bdf,acf) . norm_f = 0</li></ol></td>
246 </tr>
247 </tbody>
248 </table>Equivalent à :&nbsp;<br><table style="width: 80%; text-align: left; margin-left: auto; margin-right: auto; font-family: monospace;" border="1" cellpadding="2" cellspacing="2">
249 <tbody>
250 <tr>
251 <td><ol><li>&nbsp; &nbsp;norme_b[0]*X + norme_b[1]*Y + norme_b[2]*Z = prod_scalaire (v_bce, norm_b)</li><li>&nbsp;&nbsp; norme_d[0]*X + norme_d[1]*Y + norme_d[2]*Z =&nbsp;prod_scalaire (v_ade, norm_d)</li><li>&nbsp;&nbsp; norme_f[0]*X + norme_f[1]*Y + norme_f[2]*Z =&nbsp;prod_scalaire (v_acf, norm_f)</li></ol></td>
252 </tr>
253 </tbody>
254 </table><br>Ce système de 3 équations à trois inconnues est résolu par la méthode de <span style="font-weight: bold;">Cramer</span> au moyen d'une classe du même nom défini dans le nouveau fichier <span style="font-weight: bold;">HexCramer.hxx.</span> Notons qu'un test unitaire de la classe Cramer existe dans le fichier test_quads.cxx<br style="font-weight: bold;"><p>Une fois le système résolu ; s'il n'est pas régulier on retourne un vecteur nul, la suite est aisée :</p><ul><li>Création du vertex s_bdf à partir des coordonnées calculées</li><li>Détermination
255 des sommets opposés s_be, s_bcf, s_adf en utilisant la méthode
256 Edge::commonVertex (edge) sur les arêtes dèja déterminées.</li><li>Création des 3 arêtes manquantes e_bd, e_bf, e_df</li><li>Création des quadrangles manquants q_b, q_d, q_f.</li><li>Création de l'hexaèdre.</li></ul><p><a name="addHexa4Quads"></a></p><p><img src="red-ball.gif" style="width: 12px; height: 12px;" alt="o">&nbsp;&nbsp;&nbsp; <span style="font-weight: bold;">Création d'un hexaèdre avec quatre quadrangles :&nbsp;</span>&nbsp;</p><ul><li>La classe AnaQuads&nbsp;
257 détecte trois arêtes communes : appel à addHexaQuadsACDE.&nbsp;La face A sera la première trouvée qui en possède trois,
258 la face E la suivante à trois arêtes,C et D lles deux autres faces à deux arêtes communes.</li><li>La classe AnaQuads&nbsp; détecte quatre arêtes communes : appel à
259 addHexaQuadsABCD.&nbsp;Ce
260 cas est
261 symétrique chaque face possède deux arêtes. La face A sera la première
262 de la liste, C et D&nbsp;les deux faces sécantes à A, B la dernière.</li></ul><table style="text-align: left; width: 90%;" border="1" cellpadding="2" cellspacing="2"><tbody><tr><td style="vertical-align: middle; text-align: center;"><p><img src="Quads_ABCD.png" style="width: 282px; height: 226px;" alt="En tunnel"></p></td><td style="vertical-align: middle; text-align: center;"><img src="Quads_ACDE.png" style="width: 278px; height: 223px;" alt="En but"></td></tr><tr><td style="vertical-align: middle;">addHexa2Quads avec 4 quadrangles&nbsp; disposés en tunnel. <br>Fonction : addHexaQuadsABCD</td><td style="vertical-align: middle;">addHexa2Quads avec 4 quadrangles&nbsp;disposés en fauteuil. <br>Fonction : addHexaQuadsACDE</td></tr></tbody></table><p><span style="font-weight: bold;">addHexaQuadABCD</span> :</p><p>Le
263 rôle des quadrangles passés en&nbsp;arguments est symétrique On nommera q_a
264 le premier trouvé, q_c le premier qui intersecte q_a, q_c le second et
265 q_d celui qui n'intersecte pas q_a.</p><p>Tous les sommets et arêtes sont présents. Il suffit de créer les deux quadrangles E et F:</p><p>Les problèmes de détermination des variables se traiotent comme dans <span style="font-weight: bold;">addHexaQuadABC</span></p><p><span style="font-weight: bold;">addHexaQuadACDE</span> :</p><p>Le rôle de q_a et qc est symétrique. Ils ont chacun trois arêtes communes avec les autres. q_e et q_f n'en ont que 2.</p><p>Tous les sommets sont présents. Il suffit de créer l'arête e_bf et les deux quasrangles B et F:</p><p>Les edges se déterminent aisément grâce aux indices d'interection fournis par <span style="font-weight: bold;">AnaQuads</span>. Il suffiit de prendre l'opposé :<span style="font-family: monospace;">et à la propriété de la classe Quad : l'indice d'une arête opposée à l'arête i vaut i+2.</span></p><table style="width: 80%; text-align: left; margin-left: auto; margin-right: auto; font-family: monospace;" border="1" cellpadding="2" cellspacing="2"><tbody><tr><td>&nbsp;&nbsp; int&nbsp;&nbsp; nc_ac = strquads.inter_edge[pos_c][pos_a]; // Nro dans&nbsp; q_c de e_ac<br>&nbsp;&nbsp; int&nbsp;&nbsp; nc_ce = strquads.inter_edge[pos_c][pos_e]; // Nro dans&nbsp; q_c de e_ce<br>&nbsp;&nbsp; int&nbsp;&nbsp; nd_ad = strquads.inter_edge[pos_d][pos_a]; // Nro dans&nbsp; q_d de e_ad<br>&nbsp;&nbsp; int&nbsp;&nbsp; nd_de = strquads.inter_edge[pos_d][pos_e]; // Nro dans&nbsp; q_d de e_de<br>&nbsp;&nbsp; int&nbsp;&nbsp; ne_ae = strquads.inter_edge[pos_e][pos_a]; // Nro dans&nbsp; q_e de e_ae<br><br>&nbsp;&nbsp; Edge* e_af&nbsp; = q_a-&gt;getEdge ((na_ac + 3) MODULO QUAD4);<br>&nbsp;&nbsp; Edge* e_bc&nbsp; = q_c-&gt;getEdge ((nc_ac + 2) MODULO QUAD4);<br>&nbsp;&nbsp; Edge* e_cf&nbsp; = q_c-&gt;getEdge ((nc_ce + 2) MODULO QUAD4);<br>&nbsp;&nbsp; Edge* e_bd&nbsp; = q_d-&gt;getEdge ((nd_ad + 2) MODULO QUAD4);<br>&nbsp;&nbsp; Edge* e_df&nbsp; = q_d-&gt;getEdge ((nd_de + 2) MODULO QUAD4);<br>&nbsp;&nbsp; Edge* e_be&nbsp; = q_e-&gt;getEdge ((ne_ae + 2) MODULO QUAD4);<br><br>&nbsp;&nbsp; Vertex* v_bcf = e_cf-&gt;opposedVertex (e_cf-&gt;commonVertex (e_af));<br>&nbsp;&nbsp; Vertex* v_bdf = e_df-&gt;opposedVertex (e_df-&gt;commonVertex (e_af));</td>
266 </tr>
267 </tbody>
268 </table><p><a name="addHexa5Quads"></a></p><img src="red-ball.gif" style="width: 12px; height: 12px;" alt="o">&nbsp;&nbsp;&nbsp; <span style="font-weight: bold;">Création d'un hexaèdre avec cinq quadrangles :&nbsp;</span> <br><br>Il n'y a pas besoin de dissocier plusieurs cas, le travail est réalisé directement dans la méthode <span style="font-weight: bold;">addHexa5Quads</span>().<br><p style="text-align: center;"><img src="Quads_5.png" style="width: 278px; height: 223px;" alt="En but"></p>Ce cas est assez simple : c'est un hexaèdre auquel il manque la face que l'on convient de nommer B.<br><ul><li>La face q_a est celle qui possède 4 intersections.</li><li>Une
269 fois son indice qbase déterminé dans AnaQuads, on boucle sur les 4
270 quadrangles sécants à q_a et on obtient l'arête opposée t_edge[i] et le
271 quadrangle associé tquad[i]. Les quadrangles q_c, g_d, q_e, q_f se
272 retrouvent dans le tableau tquad dans un ordre exploitable, le problème
273 étant symétrique.</li><li>On construit qb à partir des t_edge[i] donnés dans
274 cet odre :&nbsp; q_b&nbsp; = new Quad (tedge[0], tedge[1], tedge[2],
275 tedge[3]);</li><li>Enfin l'hexaèdre : hexa = new Hexa (q_a, q_b, tquad[0], tquad[2], tquad[1], tquad[3])</li></ul><p><a href="index.html#DebutPage">Retour au début</a></p><a name="Partie_2.2"></a><p><big><img src="green-ball.gif" style="width: 12px; height: 12px;" alt="o"></big><b><font size="+1"><big> 2.2 Génération d'Hexaèdres par révolution</big></font></b></p><p>Le pont d'entrée dans la classe Document est :<br>
276
277 <span style="font-size: 11pt; font-family: Garamond;"></span>
278 </p><table style="width: 80%; text-align: left; margin-left: auto; margin-right: auto; font-family: monospace;" border="1" cellpadding="2" cellspacing="2">
279 <tbody>
280 <tr>
281 <td>Elements* revolutionQuads (Quads&amp; start, Vertex* center, Vector* axis, vector&lt;double&gt;&amp; angles);<br></td>
282 </tr>
283 </tbody>
284 </table><br>Avec :<br><ul><li><span style="font-weight: bold;">start</span> est la liste des quadrangles de départ. Ils doivent costituer une surface libre.Rappelons que le type <span style="font-weight: bold;">Quads</span> est équivalent à <span style="font-weight: bold;">vector&lt;Quad*&gt;</span></li><li><span style="font-weight: bold;">center</span> et <span style="font-weight: bold;">axis</span> sont respecttivement le centre et l'axe de la rotation</li><li>le vecteur <span style="font-weight: bold;">angles</span> définit pour chaque incrément l'angle de la rotation.</li></ul><br><br><br><table style="text-align: left; width: 90%;" border="1" cellpadding="2" cellspacing="2"><tbody><tr><td style="vertical-align: middle; text-align: center;"><p><img src="QuadRevolution1.png" style="width: 282px; height: 226px;" alt="En diedre"></p></td><td style="vertical-align: middle; text-align: center;"><img src="QuadRevolution2.png" style="width: 278px; height: 223px;" alt="Trièdre"></td></tr><tr><td style="vertical-align: middle;">Avant la revolution : on a coloré les quadrangles à déplacer, ainsi que l'axe de rotation.</td><td style="vertical-align: middle;">Résultat de&nbsp; la revolution.</td><td style="vertical-align: middle;"></td></tr></tbody></table><br><p><a href="index.html#DebutPage">Retour au début</a></p><a name="Partie_2.3"></a><p><big><img src="green-ball.gif" style="width: 12px; height: 12px;" alt="o"></big><b><font size="+1"><big> 2.3 Substitution d'Hexaèdres</big></font></b></p><p>Il
285 s'agit de remplacer un hexaèdre ou des hexaèdres par une autre série
286 d'hexaaaèdres. Pour pouvoir effectuer ce remplacement, cette autre
287 série d'hexaèdres doit vérifier des conditions de collage de faces.<br>
288
289 <span style="font-size: 11pt; font-family: Garamond;"></span>
290 </p><br><br><table style="text-align: left; width: 90%;" border="1" cellpadding="2" cellspacing="2"><tbody><tr><td style="vertical-align: middle; text-align: center;"><p><img src="ReplaceBefore.gif" style="width: 282px; height: 226px;" alt="En diedre"></p></td><td style="vertical-align: middle; text-align: center;"><img src="ReplaceResult.gif" style="width: 278px; height: 223px;" alt="Trièdre"></td></tr><tr><td style="vertical-align: middle; text-align: center;">Exemple
291 : remplacement des 3 hexaèdres jaunes centraux par 3 fois 5 nouveaux
292 hexaèdres qui sont construits par extrusion des 5 quadrangles marrons
293 (le motif).</td><td style="vertical-align: middle; text-align: center;">Résultat du remplacement.&nbsp;</td></tr></tbody></table><br><br>La signature de la fonction est la suivante :<br><table style="width: 80%; text-align: left; margin-left: auto; margin-right: auto; font-family: monospace;" border="1" cellpadding="2" cellspacing="2">
294 <tbody>
295 <tr>
296 <td>Elements* Document::revolutionQuads (Hexas&amp; pattern, Vertex* p1,&nbsp;Vertex* c1, <br>&nbsp;
297 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
298 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Vertex*
299 p2,&nbsp;Vertex* c2,&nbsp;Vertex* p3,&nbsp;Vertex* c3);<br></td>
300 </tr>
301 </tbody>
302 </table><br>Avec :<br><ul><li><span style="font-weight: bold;">pattern </span>est la liste des hexaèdres&nbsp; à extruder.<span style="font-weight: bold;"></span></li><li><span style="font-weight: bold;">c1, c2 </span>et&nbsp;<span style="font-weight: bold;">c3</span>
303 définissent le quadrangle "cible" QB. Soit QA la face opposée à QB. A
304 partir de cette face, on définit l'ensemble des n hexaèdres liés par
305 les faces "opposées" &nbsp;(QAi, QBi).&nbsp;</li><li><span style="font-weight: bold;">p1, p2 </span>et <span style="font-weight: bold;">p3</span> sont les vertices du pattern qui seront associés resperctivement à c1, c2 et c3.&nbsp;&nbsp;</li></ul><p></p><p style="font-weight: bold;"><big>Conditions :&nbsp;</big></p><ul><li>Le pattern doit avoir exactement&nbsp;4 faces latérales externes, que l'on appellera pqc, pqd, pqe, pqf. </li><li>Les
306 faces"transversales" inférieure et supérieure et doivent être
307 superposables : le motif des quadrangles qui constituent ces faces doit
308 être identique.</li><li>c1,c2 et c3 sont sur une face externe</li></ul><p></p><p>Pour désigner les faces d'un hexaèdres, on utilise les&nbsp; <a href="#RappelNotations">notations habituelles</a> définies plus haut.</p><p><big><span style="font-weight: bold;">Conventions et orientations</span></big> : </p><ul><li>Les
309 3 vertices de départ du pattern définissent deux edges : pe_ac (sens
310 Ox) et pe_ae (sens oy) et 3 vertices pv_aed, pv_ace, pv_acf.&nbsp;
311 pv_ace est celui des 3 vertices qui est commun aux deux edges, pv_ade
312 la première des extrémités. </li><li>Les&nbsp;4 faces latérales externes du pattern sont notées pq_c, pq_d, pq_e, pq_f.</li><li>Les
313 3 vertices cibles définissent un quadrangle cq_b , deux edges&nbsp;
314 &nbsp;ce_bc (Ox) et ce_be (Oy) et 3 vertices cv_bed, cv_bce et cv_bcf.
315 définis comme pout le pattern.</li></ul><br>&nbsp; (A suivre ...)<p></p><p></p><p><br> </p><p><a href="index.html#DebutPage">Retour au début</a>
316 </p><hr width="100%">
317 <p><a name="Partie_3"></a></p>
318 <p><img src="blue-ball.gif" alt="o" height="12" width="12"><b><font size="+1">
319 &nbsp;<big>Partie 3 : Bibliothèque de formes</big></font></b></p><p>Cette biblothèque est constituée de quatre nouvelles formes :<br></p><ul><li>La demi-sphère trouée&nbsp;</li><li>Le huitième de sphère trouée</li><li>La demi-écorce trouée</li><li>Le huitième d'écorce trouée&nbsp;</li></ul><p>Ces formes sont implémentées (et traduites ....) de la façon suivante :</p><table style="width: 80%; text-align: left; margin-left: auto; margin-right: auto; font-family: monospace;" border="1" cellpadding="2" cellspacing="2">
320 <tbody>
321 <tr>
322 <td><span style="font-family: monospace;">Elements* makeSphere (Vertex* center, </span><span style="font-family: monospace;">Vector* vx, Vector* vz,</span><span style="font-family: monospace;"> <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; double radius,&nbsp;</span><span style="font-family: monospace;">double radhole, </span><span style="font-family: monospace;"><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Vertex*
323 plorig,&nbsp;</span><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int
324 nrad, int nang, int nhaut);</span><span style="font-family: monospace;"></span><span style="font-family: monospace;"></span><br></td>
325 </tr>
326 <tr><td><span style="font-family: monospace;">Elements* makePartSphere (Vertex* center, </span><span style="font-family: monospace;"></span><span style="font-family: monospace;">Vector* vx, Vector* vz,</span><span style="font-family: monospace;"> </span><span style="font-family: monospace;"><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;double&nbsp; radius, </span><span style="font-family: monospace;"></span><span style="font-family: monospace;">double radhole</span><span style="font-family: monospace;">,</span><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Vertex*
327 plorig,&nbsp;</span><span style="font-family: monospace;">double angle,</span><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int
328 nrad, int nang, int nhaut);</span></td></tr><tr><td><span style="font-family: monospace;">Elements* makeRind (Vertex* center, </span><span style="font-family: monospace;"></span><span style="font-family: monospace;">Vector* vx, Vector* vz,</span><span style="font-family: monospace;"> </span><span style="font-family: monospace;"><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;double&nbsp; radius, double radint, </span><span style="font-family: monospace;"></span><span style="font-family: monospace;">double radhole</span><span style="font-family: monospace;">,</span><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Vertex*
329 plorig,&nbsp;</span><span style="font-family: monospace;"></span><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int
330 nrad, int nang, int nhaut);</span></td></tr><tr><td><span style="font-family: monospace;">Elements* makePartRind (Vertex* center, </span><span style="font-family: monospace;"></span><span style="font-family: monospace;">Vector* vx, Vector* vz,</span><span style="font-family: monospace;"> <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="font-family: monospace;">double&nbsp; radius, double radint, </span><span style="font-family: monospace;"></span><span style="font-family: monospace;">double radhole</span><span style="font-family: monospace;">,</span><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Vertex*
331 plorig, </span><span style="font-family: monospace;">double angle,</span><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int
332 nrad, int nang, int nhaut);</span></td></tr></tbody>
333 </table><br>Remarques :<br><ul><li>Le plan sécant ne passe pas
334 forcément par le centre de la sphère. Il définit le demi-espace dans
335 lequel se situe l'objet à dessiner.Il peut même être disjoint de la
336 sphère. S'il est "en dessous", la sphère est entièrement dessinée, s'il
337 est "au dessus", l'objet sera vide.&nbsp;&nbsp;</li></ul><br><p><big><img src="green-ball.gif" style="width: 12px; height: 12px;" alt="o"></big><b><font size="+1"><big>&nbsp;3.1&nbsp; <span style="font-family: Terminal;"></span> Aspect visuel (exemples)</big></font></b></p><br>Conditions<br><table style="text-align: left; width: 90%;" border="1" cellpadding="2" cellspacing="2"><tbody><tr><td style="vertical-align: middle; text-align: center;"><p><img src="HemiSphere.png" style="width: 282px; height: 226px;" alt="Demi Sphere trouee"></p></td><td style="vertical-align: middle; text-align: center;"><img src="PartSphere.png" style="width: 278px; height: 223px;" alt="Huitième de sphère"></td></tr><tr><td style="vertical-align: middle; text-align: center;">Demi-Sphère trouée (makeSphere ())</td><td style="vertical-align: middle; text-align: center;">Huitième de sphère trouée (makePartSphere ())</td></tr><tr><td style="vertical-align: middle; text-align: center;"><p><img src="Rind.png" style="width: 282px; height: 226px;" alt="Ecorce trouée">&nbsp;&nbsp; &nbsp;</p></td><td style="vertical-align: middle; text-align: center;"><p><img src="PartRind.png" style="width: 282px; height: 226px;" alt="Huitième d'ecorce"> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;</p></td></tr><tr><td style="text-align: center;" valign="middle">Demi écorce trouée (makeRind ())</td><td style="text-align: center;" valign="middle">Huitième d'écorce trouée (makePartRind ())</td></tr></tbody></table><p><big><img src="green-ball.gif" style="width: 12px; height: 12px;" alt="o"></big><b><font size="+1"><big>&nbsp;3.1&nbsp; <span style="font-family: Terminal;"></span> Im</big></font></b><b><font size="+1"><big>plémentation</big></font></b></p><p>Toutes ces fonctions publiques appellent une seule fonction&nbsp; de la classe <span style="font-weight: bold;">Elements :</span></p><table style="width: 80%; text-align: left; margin-left: auto; margin-right: auto; font-family: monospace;" border="1" cellpadding="2" cellspacing="2">
338 <tbody>
339
340 <tr><td><span style="font-family: monospace;">int makeRind (EnumGrid type, Vertex* center, </span><span style="font-family: monospace;"></span><span style="font-family: monospace;">Vector* vx, Vector* vz,</span><span style="font-family: monospace;"> <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="font-family: monospace;">double&nbsp; radius, double radint, </span><span style="font-family: monospace;"></span><span style="font-family: monospace;">double radhole</span><span style="font-family: monospace;">,</span><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Vertex*
341 plorig, </span><span style="font-family: monospace;">double angle,</span><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int
342 nrad, int nang, int nhaut);</span></td></tr></tbody>
343 </table><br>Une fonction <span style="font-weight: bold;">controlRind() </span>vérifie
344 la cohérence des arguments passés en entrée et calcule les deux extrema
345 de l'angle d'élévation phi (voir chapitre suivant).<br>Une boucle à triple indice sur (nrad, nang, nhaut) calculme les coordonnées des sommets par appel de la fonction <span style="font-weight: bold;">getCylPoint (nx,ny,nz, px,py,pz)</span>.<br>Ce
346 calcul se fait sur une sphère de centre O et d'axe Oz, dont les
347 hexaedres sont comptés à partir de l'axe Ox de façon à remplir le
348 secteur angulaire theta.. Les coordonnées sont ensuite replacées dans
349 les coordonnes utilisateur grâce à la fonction <span style="font-weight: bold;">transfoVertices</span>(). Edges, quadrangles et hexaèdres sont ensuites assemblés grâce à &nbsp;la fonction <span style="font-weight: bold;">fillGrid</span>().<br><br><p><big><img src="green-ball.gif" style="width: 12px; height: 12px;" alt="o"></big><b><font size="+1"><big>&nbsp;3.2 Détermination de l'angle d'élévation (phi) <span style="font-family: Terminal;"></span>&nbsp;</big></font></b></p>L'angle
350 d'azimuth theta (longitude) est défini explicitement par l'utilisateur.
351 L'angle d'élévation phi est délimité par la position du&nbsp; plan
352 horizontal et par le diamètre du trou. &nbsp;Soit :<br><ul><li>Une sphère de centre O et de rayon R.</li><li>La phère est traversée par un trou cylindrique de rayon r.</li><li>Un plan défini par son vecteur normal n (vertical sur la figure qui suit) et un point A</li></ul><p style="text-align: center;"><img src="Sphere.gif" style="width: 373px; height: 311px;" alt="Sphere"></p>A partir de ces éléments de base, on&nbsp; définit<small><small><small><small><small><small> </small></small></small></small></small></small>:<br><ul><li>Le point H, projection orhogonale du centre O de la sphere sur le plan (A,n)</li><li>L'angle alpha défini par le centre O et le cylindre : sin (alpha) = &nbsp;r/R</li><li>L'angle beta délimité&nbsp; par l'horizontale et l'intersection du plan (A,n) et de la sphère.&nbsp;</li><ul><li>sin (beta) = OH/R</li><li>et OH = OA.n/|n| &nbsp;(produit scalaire de OA par le vecteur unitaire associé à n).</li></ul></ul>L'angle d'élévation&nbsp; phi &nbsp;est encadré par les valeurs suivantes : <ul><li>max (alpha-pi/2, beta) &lt;= phi &lt;= pi/2 - alpha</li></ul><br><p><a href="index.html#DebutPage">Retour au début</a>
353 </p><hr width="100%">
354 <p><a name="Partie_4"></a></p>
355 <p><img src="blue-ball.gif" alt="o" height="12" width="12"><b><font size="+1">
356 &nbsp;<big>Partie 4 : Evolution des associations</big></font></b></p><p class="MsoNormal">Cette tâche est composée de 3 évolutions, au sujet de
357 l'association, qui sont décrites ci-après.</p><p><big><img src="green-ball.gif" style="width: 12px; height: 12px;" alt="o"></big><b><font size="+1"><big> 4.1 Nouveaux objets <span style="font-family: Terminal;"></span>&nbsp;</big></font></b></p>
358
359 <p class="MsoNormal">Il s'agissait d'ajouter de nouveaux objets
360 intermédiaires de travail, comme le vecteur ou le cylindre :</p>
361
362 <ul style="margin-top: 0cm;" type="square"><li class="MsoNormal" style="">le
363      cercle défini par&nbsp;un
364       centre, un
365       rayon et une
366       normale,</li><li class="MsoNormal" style="">la
367      sphère définie par&nbsp;un
368       centre et&nbsp;un
369       rayon.<br></li></ul>Il était p aussi&nbsp;associer&nbsp;
370 les objets intermédiaires aux objets géométriques venant du
371 composant GEOM de SALOME :<br><ul style="margin-top: 0cm;" type="square"><li class="MsoNormal" style="">un
372      cercle,</li><li class="MsoNormal" style="">une
373      sphère,</li><li class="MsoNormal" style="">un
374      cylindre.</li></ul> <p><big><img src="green-ball.gif" style="width: 12px; height: 12px;" alt="o"></big><b><font size="+1"><big> 4.2 Associations prédéfinies <span style="font-family: Terminal;"></span>&nbsp;</big></font></b></p><p class="MsoNormal">La deuxième évolution consiste à améliorer les associations
375 des modèles de blocs prédéfinis en calculant automatiquement des associations
376 implicites, les fonctions concernées sont les suivantes:</p>
377
378 <ul style="margin-top: 0cm;" type="square"><li class="MsoNormal" style="">ajouter
379      une grille cylindrique .</li><li class="MsoNormal" style="">ajouter
380      une grille sphérique.</li><li class="MsoNormal" style="">ajouter
381      un cylindre, un tuyau.</li><li class="MsoNormal" style="">ajouter
382      l&#8217;intersection de 2 cylindres ou de 2 tuyaux.</li><li class="MsoNormal" style="">faire
383      de même pour toutes les nouvelles fonctions : ecorces et portions de sphères.</li></ul>
384
385 <p class="MsoNormal">Pour chaque arête (sphérique) concernée, on associera un arc de cercle.</p><p class="MsoNormal">Il est inutile d'associer laes faces, SMESH est capable de mailler si les arêtes sont associées.</p><p class="MsoNormal"><big><span style="font-weight: bold;">Implémentation</span></big>&nbsp;</p><p class="MsoNormal">Rappelons que l'objet&nbsp;Shape de HexaBlock est constitué :</p><ul><li>D'une chaine de caractère (b_rep) qui permet de décrire toute forme de GEOM</li><li>De deux paramètres <span style="font-style: italic;">debut</span> et <span style="font-style: italic;">fin</span> compris entre 0 et 1 permettant de délimiter la ligne décrite par la b-rep quand c'en est une</li></ul><p class="MsoNormal">Deux opérations sont nécessaires&nbsp; :</p><ol><li>&nbsp;créer un cercle au moyen de GEOM,</li><li>découper ce cercle en arcs de cercle qui seront associés aux arêtes concernées.</li></ol><p class="MsoNormal"><span style="font-weight: bold;">Opération 1 </span>:
386 Le cercle à créer est en fait un arc de cercle orienté de 360
387 degrés.&nbsp; Il est en effet nécessaire de définir une origine. GEOM
388 permet de&nbsp;générer finir un tel
389 cercle, à partir duquel HexaBlock définira des arcs au moyen des
390 paramètres <span style="font-style: italic;">debut</span> et <span style="font-style: italic;">fin</span> des shapes :</p><p class="MsoNormal">Cette action est assurée par la fonction <span style="font-weight: bold;">geom_create_circle</span>
391 qui génère la brep du cercle à partir de son&nbsp;centre, de son rayon,
392 de son vecteur normal, du&nbsp; vecteur Ox qui permet de définir son
393 origine.</p><br><span style="font-weight: bold;"></span><table style="width: 80%; text-align: left; margin-left: auto; margin-right: auto; font-family: monospace;" border="1" cellpadding="2" cellspacing="2">
394 <tbody>
395
396 <tr><td><span style="font-family: monospace;"></span><span style="font-family: monospace;"></span><span style="font-family: monospace;">void <span style="font-weight: bold;">geom_create_circle</span> (double* centre, double rayon, Vector* normale,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
397 double* ox, string&amp; brep)<br>{<br>&nbsp;&nbsp; gp_Pnt gp_center (centre [dir_x], centre [dir_y], centre [dir_z]);<br>&nbsp;&nbsp;
398 gp_Vec gp_ox&nbsp;&nbsp;&nbsp;&nbsp; (ox&nbsp;&nbsp;&nbsp;&nbsp;
399 [dir_x], ox&nbsp;&nbsp;&nbsp;&nbsp; [dir_y], ox&nbsp;&nbsp;&nbsp;&nbsp;
400 [dir_z]);<br>&nbsp;&nbsp; gp_Vec gp_norm&nbsp;&nbsp; (normale-&gt;getDx(), normale-&gt;getDy(), normale-&gt;getDz());<br><br>&nbsp;&nbsp; <span style="font-weight: bold;">gp_Ax2</span>&nbsp; gp_axes (gp_center, gp_norm, gp_ox);<br>&nbsp;&nbsp; <span style="font-weight: bold;">gp_Circ</span> gp_circ (gp_axes,&nbsp;&nbsp; rayon);<br><br>&nbsp;&nbsp; TopoDS_Edge&nbsp;&nbsp;&nbsp; geom_circ = <span style="font-weight: bold;">BRepBuilderAPI_MakeEdge</span>(gp_circ).Edge();<br>&nbsp;&nbsp; ostringstream&nbsp; stream_shape;<br>&nbsp;&nbsp; <span style="font-weight: bold;">BRepTools::Write</span>(geom_circ, stream_shape);<br><br>&nbsp;&nbsp; brep = stream_shape.str();<br>}</span><span style="font-family: monospace;"></span></td></tr></tbody>
401 </table><br>GEOM permet de définir un tel cercle (calsse <span style="font-style: italic;">gp_Circ</span>)&nbsp; à partir d'un systemes d'axes 2D (classe <span style="font-style: italic;">gp_Ax2</span> ) &nbsp;et d'un rayon. Ce cercle esr ensuite transformé en forme&nbsp;<span style="font-style: italic;">TopoDS_Shape</span> qui est l'objet GEOM que l'on maniplule habituellement losque l'on procède aux associations. Plus précisément en <span style="font-style: italic;">TopoDS_Edge</span> &nbsp;au moyen de&nbsp;<span style="font-style: italic;">BRepBuilderAPI_MakeEdge</span><span style="font-family: monospace;"></span>. Enfin l'objet est&nbsp; transformé en chaine de caractères de format Brep via <span style="font-style: italic;">ostringstream</span>.<br><br><span style="font-weight: bold;">Opération 2 </span>:
402 On dispose d'une b-rep&nbsp; décrivant un arc de cercle de 360 degrés.
403 Il est aisé de définir proportionnellement pour chacun des edges
404 constituant la ligne associée à la portion de cercle les paramètres
405 début et fin par rapport aux angles de départ et d'arrivée de chaque
406 arc. Cette opération fut d'ailleurs réalisée lors de la préservarion
407 des associations lors d'un "cut". On réutilisera donc la fonction <span style="font-style: italic;">Elements::cutAssociation(...) </span>moyennant quelques aménagements.<br><p class="MsoNormal"></p><p><big><img src="green-ball.gif" style="width: 12px; height: 12px;" alt="o"></big><b><font size="+1"><big> 4.3&nbsp;Propagation des associations <span style="font-family: Terminal;"></span>&nbsp;</big></font></b></p><p class="MsoNormal"><br>La troisième évolution consiste à améliorer la propagation
408 automatique des associations, les fonctions concernées sont les suivantes:</p>
409
410 <ul style="margin-top: 0cm;" type="disc"><li class="MsoNormal" style="">fusionner
411      ou déconnecter des sommets, des arêtes, des quadrangles :</li><ul style="margin-top: 0cm;" type="circle"><li class="MsoNormal" style="">s&#8217;il
412       y a des associations, ne pas les perdre,</li></ul><li class="MsoNormal" style="">prismer
413      un ou des quadrangles :</li><ul style="margin-top: 0cm;" type="circle"><li class="MsoNormal" style="">s&#8217;il
414       y a des associations dans la direction de l&#8217;extrusion, les propager,</li></ul><li class="MsoNormal" style="">ajouter
415      des hexaèdres par translation, par rotation, par homothétie ou par
416      symétries :</li><ul style="margin-top: 0cm;" type="circle"><li class="MsoNormal" style="">si
417       les hexaèdres sources ont une association, alors les propager,</li></ul><li class="MsoNormal" style="">faire
418      de même pour la fonction «révolution» du lot 2.</li></ul>
419
420 <p class="MsoNormal"><o:p></o:p></p>
421
422 <p class="MsoNormal">Ces trois évolutions seront implémentées dans le moteur.
423 Seule le première évolution (création de sphères ou cercles) sera implémentée
424 dans la partie interactive. </p><br><br><img src="red-ball.gif" style="width: 12px; height: 12px;" alt="o">&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-weight: bold;">Implémentation :</span><br><br><br>En
425 ce qui concerne les associations propagées par les transformations, la
426 fonction de base de l'implémentation est transfo_brep. <br>Cette fonction reprend la matrice du modèle de blocs et l'applique à la shape décrite par la brep.<br><br><table style="text-align: left; margin-left: auto; margin-right: auto; width: 859px; height: 65px;" border="1" cellpadding="2" cellspacing="2"><tbody><tr><td style="width: 80%;"><span style="font-family: monospace;">// ====================================================== transfo_brep<br>void transfo_brep (string&amp; brep, Matrix* matrice, string&amp; trep)<br>{<br>&nbsp;&nbsp; BRep_Builder&nbsp; builder;<br>&nbsp;&nbsp; TopoDS_Shape&nbsp; shape_orig;<br>&nbsp;&nbsp; ostringstream stream_shape;<br>&nbsp;&nbsp; gp_Trsf&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; transfo;<br><br>&nbsp;&nbsp;
427 double&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
428 a11,a12,a13,a14, a21,a22,a23,a24, a31,a32,a33,a34;<br>&nbsp;&nbsp; matrice-&gt;getCoeff (a11,a12,a13,a14, a21,a22,a23,a24, a31,a32,a33,a34);<br>&nbsp;&nbsp; transfo.SetValues (a11,a12,a13,a14, a21,a22,a23,a24, a31,a32,a33,a34, <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
429 Epsil2, Epsil2);<br><br>&nbsp;&nbsp; istringstream stream_brep (brep);<br>&nbsp;&nbsp; BRepTools::Read&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (shape_orig, stream_brep, builder);<br>&nbsp;&nbsp; <br>&nbsp;&nbsp; BRepBuilderAPI_Transform brep_transfo (shape_orig, transfo, Standard_True);<br>&nbsp;&nbsp; TopoDS_Shape result = brep_transfo.Shape();<br><br>&nbsp;&nbsp; BRepTools::Write (result, stream_shape);<br>&nbsp;&nbsp; trep = stream_shape.str();<br>}<br></span><span style="font-family: monospace;"></span></td></tr></tbody></table><br><br>Pour la fonction de prismQuads, on utilise une variante simplifiée : <br><br><table style="text-align: left; margin-left: auto; margin-right: auto; width: 859px; height: 65px;" border="1" cellpadding="2" cellspacing="2"><tbody><tr><td style="width: 80%;"><span style="font-family: monospace;">// ====================================================== translate_brep<br>void translate_brep (string&amp; brep, double dir[], string&amp; trep)<br>{<br>&nbsp;&nbsp; gp_Trsf&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; transfo;<br>&nbsp;&nbsp; BRep_Builder&nbsp; builder;<br>&nbsp;&nbsp; TopoDS_Shape&nbsp; orig;<br>&nbsp;&nbsp; ostringstream stream_shape;<br><br>&nbsp;&nbsp;
430 gp_Vec&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
431 vecteur&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (dir [dir_x], dir [dir_y],
432 dir [dir_z]);<br>&nbsp;&nbsp; transfo.SetTranslation&nbsp;&nbsp;&nbsp; (vecteur);<br>&nbsp;&nbsp; istringstream stream_brep (brep);<br>&nbsp;&nbsp; BRepTools::Read&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (orig, stream_brep, builder);<br>&nbsp;&nbsp; <br>&nbsp;&nbsp; TopLoc_Location&nbsp; loc_orig&nbsp;&nbsp; = orig.Location();<br>&nbsp;&nbsp; gp_Trsf&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; trans_orig = loc_orig.Transformation();<br>&nbsp;&nbsp; TopLoc_Location&nbsp; loc_result (transfo * trans_orig);<br>&nbsp;&nbsp; TopoDS_Shape&nbsp;&nbsp;&nbsp;&nbsp; result = orig.Located (loc_result);<br><br>&nbsp;&nbsp; BRepTools::Write (result, stream_shape);<br>&nbsp;&nbsp; trep = stream_shape.str();<br>}<br></span><span style="font-family: monospace;"></span></td></tr></tbody></table><br><br>Pour la fonction de prismQuads, on utilise une variante simplifiée : <br><br><br><br><img src="red-ball.gif" style="width: 12px; height: 12px;" alt="o">&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-weight: bold;">Propagation des associations pour les transformations :</span><span style="font-weight: bold;"></span><br><br><br>L'exemple donné est makeScale <br><br><table style="text-align: left; margin-left: auto; margin-right: auto; width: 859px; height: 65px;" border="1" cellpadding="2" cellspacing="2"><tbody><tr><td style="width: 80%;"><span style="font-family: monospace;"># ======================================================= make_grid</span><br style="font-family: monospace;"><span style="font-family: monospace;">def make_grid (doc) :</span><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; ori&nbsp; = doc.addVertex ( 0, 0, 0)</span><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; vz&nbsp;&nbsp; = doc.addVector ( 0, 0, 1)</span><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; vx&nbsp;&nbsp; = doc.addVector ( 1 ,0, 0)</span><br style="font-family: monospace;"><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; dr = 1</span><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; da = 360</span><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; dl = 1</span><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; nr = 1</span><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; na = 6</span><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; nl = 1</span><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; grid = doc.makeCylindrical (ori, vx,vz, dr,da,dl, nr,na,nl, False)</span><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; return grid</span><br style="font-family: monospace;"><br style="font-family: monospace;"><span style="font-family: monospace;"># ======================================================= test_scale</span><br style="font-family: monospace;"><span style="font-family: monospace;">def test_scale () :</span><br style="font-family: monospace;"><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; doc&nbsp; = hexablock.addDocument()</span><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; grid = make_grid (doc)</span><br style="font-family: monospace;"><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; dest&nbsp;&nbsp; = doc.addVertex (15, 0, 0)</span><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; grid2&nbsp; = doc.makeScale (grid, dest, 0.5)</span><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; return doc</span></td></tr></tbody></table><br><br><table style="width: 859px; height: 65px; text-align: left; margin-left: auto; margin-right: auto;" border="1" cellpadding="2" cellspacing="2"><tbody><tr><td style="width: 80%;"><img style="width: 701px; height: 568px;" alt="transfo" src="transfo.png"></td></tr></tbody></table><br>ss<br><br><br><img src="red-ball.gif" style="width: 12px; height: 12px;" alt="o">&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-weight: bold;">Propagation des associations pour la fonction prism</span><span style="font-weight: bold;">Quads</span><br><br>Pour la fonction prismQuads :<br><br><br><br><table style="text-align: left; margin-left: auto; margin-right: auto; width: 737px; height: 297px;" border="1" cellpadding="2" cellspacing="2"><tbody><tr><td style="width: 80%;"><span style="font-family: monospace;"># ========================================================== test_prism</span><br style="font-family: monospace;"><span style="font-family: monospace;">def test_prism () :</span><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; doc&nbsp; = hexablock.addDocument()</span><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; nr = 1</span><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; na = 6</span><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; nl = 1</span><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; grid = make_grid (doc, nr, na, nl)</span><br style="font-family: monospace;"><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; liste = [ ]</span><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; for nx in range (nr) :</span><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for ny in range (na) :</span><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cell = grid.getQuadIJ (nx, ny, nl)</span><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; liste.append (cell);</span><br style="font-family: monospace;"><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; axis = doc.addVector (1, 1, 1);</span><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; bloc = doc.prismQuads&nbsp; (liste, axis, 3)</span><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; return doc</span></td></tr></tbody></table><br><br><span style="font-weight: bold;"></span><table style="text-align: left; margin-left: auto; margin-right: auto; font-family: monospace; width: 909px; height: 535px;" border="1" cellpadding="2" cellspacing="2">
433 <tbody>
434
435 <tr><td><span style="font-family: monospace;"></span><span style="font-family: monospace;"></span><span style="font-family: monospace;"><br><br><br><br><br></span><div style="text-align: center;"><span style="font-family: monospace;"><img style="width: 498px; height: 403px;" alt="Prisme" src="prism.png"></span><br><span style="font-family: monospace;"></span></div><span style="font-family: monospace;"><br><br><br></span><span style="font-family: monospace;"></span></td></tr></tbody>
436 </table><br><br><br><img src="red-ball.gif" style="width: 12px; height: 12px;" alt="o">&nbsp;&nbsp;&nbsp; <span style="font-weight: bold;">Propagation des associations pour la fonction revolutionQuads</span><br><br><br>Pour la fonction revolutionQuads <br><br><br><br><table style="text-align: left; margin-left: auto; margin-right: auto; width: 737px; height: 297px;" border="1" cellpadding="2" cellspacing="2"><tbody><tr><td style="width: 80%;"><span style="font-family: monospace;"># ========================================================== test_revolution<br>def test_revolution () :<br>&nbsp;&nbsp;&nbsp; doc&nbsp; = hexablock.addDocument()<br>&nbsp;&nbsp;&nbsp; nr = 1<br>&nbsp;&nbsp;&nbsp; na = 6<br>&nbsp;&nbsp;&nbsp; nl = 1<br>&nbsp;&nbsp;&nbsp; grid = make_grid (doc, nr, na, nl)<br><br>&nbsp;&nbsp;&nbsp; liste = [ ]<br>&nbsp;&nbsp;&nbsp; for nx in range (nr) :<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for ny in range (na) :<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cell = grid.getQuadIJ (nx, ny, nl)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print " ... cell = ", cell<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; liste.append (cell);<br></span>ss<br><br><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; center = doc.addVertex (0, -10, 0);<br>&nbsp;&nbsp;&nbsp; axis&nbsp;&nbsp; = doc.addVector (1, 0, 0);<br>&nbsp;&nbsp;&nbsp; angles = [5, 10, 15, 20, 30, 20, 15, 10, 5 ]<br></span>ss<br><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; bloc = doc.revolutionQuads&nbsp; (liste, center, axis, angles);<br>&nbsp;&nbsp;&nbsp; return doc<br></span><span style="font-family: monospace;"></span></td></tr></tbody></table><br><br><br><br><table style="width: 734px; height: 484px; text-align: left; margin-left: auto; margin-right: auto;" border="1" cellpadding="2" cellspacing="2"><tbody><tr><td style="width: 80%;"><img style="width: 474px; height: 383px;" alt="Macaroni" src="macaroni.png" align="middle"></td></tr></tbody></table><br><br><br><br><br><p><a href="index.html#DebutPage">Retour au début</a></p>
437 <hr width="100%">
438 <p><br></p><br><p><br>
439 &nbsp;
440 <br>
441 &nbsp;
442 <br>
443 &nbsp;
444 <br>
445 &nbsp;
446 <br>
447 &nbsp;
448 </p>
449 </body></html>